{ *************************************************************************** * * * SAMPLE 1 * * LOOP BACK TEST PROGRAM * * * * This program uses the loop back feature of the 16450 chip to transmit * * a sequence of characters and in turn receive them. No external jumpers * * are required to run this program. * * * * * *************************************************************************** } USES Crt; CONST RECEIVE = 0; { Receiver buffer register } TRANSMIT = 0; { Transmitter holding register } L_DIVISOR = 0; { Divisor latch, least significant byte } U_DIVISOR = 1; { Divisor latch, most significant byte } INT_ENB = 1; { Interrupt enable register } INT_ID = 2; { Interupt identification register } LINE_CTRL = 3; { Line control register } MODEM_CTRL = 4; { Modem control register } LINE_STAT = 5; { Line status register } MODEM_STAT = 6; { Modem status register } function AskForBaseAddress(OldOne : String) : Word; const Msg : string[3] = '0'; var NewOne, Success, Dummy, Error : Word; AddrInputPosX, AddrInputPosY : Word; begin if (OldOne = 'OLD') then OldOne := Msg; WriteLn('Please enter the Base Address (100-3F8) for your card (in hex)'); WriteLn('or press ENTER for ', OldOne, '. '); Write('>'); AddrInputPosX := WhereX; AddrInputPosY := WhereY; repeat GotoXY(AddrInputPosX, AddrInputPosY); ClrEol; Readln(Msg); Val('$' + Msg, NewOne, Error); if ((NewOne <= $3F8) AND (NewOne >= $100)) then begin Success := 1; Dummy := NewOne; end else if (Msg = '') then begin GotoXY(AddrInputPosX, AddrInputPosY); WriteLn(OldOne); Msg := OldOne; Success := 1; Val('$' + Msg, Dummy, Error); end; until (Success = 1); AskForBaseAddress := Dummy; end; { ************************************************************************** * * * PROCEDURE initialize - Performs the setup and initialization of the * * 16450 chip. * * * * * ************************************************************************** } PROCEDURE initialize(Address : word); VAR ch : INTEGER; BEGIN { First, set up the divisor latches for 9600 baud. A divisor of 12 is required since the 1.8432 clock is used. The upper divisor is set to 0 and the lower to 12. } port[Address + LINE_CTRL] := $80; { Set DLAB high for Divisor latch enable } port[Address + L_DIVISOR] := 12; { Load lower latch with 12 } port[Address + U_DIVISOR] := 0; { Load upper latch with 0 } { Now set the line control register for the following communications protocol bit0, bit1 = 1 -- character is eight bits bit2 = 0 -- one stop bit bit3 = 0 -- no parity is enabled bit4 = 0 -- doesn't matter with parity disabled bit5 = 0 -- doesn't matter with parity disabled bit6 = 0 -- disable break control bit7 = 0 -- DLAB bit, 0 disables divisor latches } port[Address + LINE_CTRL] := $03; { Enable the loop back feature of the chip with bit 4 of modem control register, now all transmitted characters will be looped back to the receiver, without external connections. } port[Address + MODEM_CTRL] := $10; { these inputs are to just insure that both the receiver buffer register and receiver shift register are clear. } delay(50); ch := port[Address + RECEIVE]; { clear rx registers } delay(50); ch := port[Address + RECEIVE]; END; { *********************************************************** * * * Transmit the letters 'A' through 'Z', and in turn, * * receive the characters, and check if the correct char * * is received. The program will print an error message * * for each bad character received. If no errors occur, * * the program will indicate so at the end of program * * execution. * * * *********************************************************** } VAR ch : CHAR; ch1, flag : INTEGER; Address : word; BEGIN ClrScr; WriteLn(' Sample One: Internal Loopback test'); WriteLn; WriteLn('This program uses the loop back feature of the 16450 chip to transmit'); WriteLn('a sequence of characters and in turn receive them. No external jumpers'); WriteLn('are required to run this program.'); WriteLn; WriteLn; WriteLn; Address := AskForBaseAddress('350'); while (Port[Address] = $FF) do begin GotoXY(1, 12); WriteLn('Your card was not located at the assigned Base Address. Please re-enter.'); GotoXY(1, 9); Address := AskForBaseAddress('OLD'); end; ClrScr; WriteLn; WriteLn; WriteLn; WriteLn('Board Configuration:'); WriteLn; WriteLn('All remaining jumper settings are irrelevant'); WriteLn; WriteLn; WriteLn; WriteLn('Press ENTER to continue.'); ReadLn; ClrScr; delay(0); { initialize the Borland delay function } initialize(Address); { setup the 16450 chip } flag := 0; FOR ch := 'A' TO 'Z' DO BEGIN port[Address + TRANSMIT] := ord(ch); REPEAT ch1 := port[Address + LINE_STAT]; { send the char } UNTIL ((ch1 AND 1) <> 0); { check if bit 1 is a 1, if so, data is ready } ch1 := port[Address + RECEIVE]; { read the input char } { check if char received is the one we sent } IF (ch1 <> ord(ch)) THEN BEGIN WriteLn('error with character',ch,', received char ',chr(ch1),'.'); flag := 1; END; END; IF (flag = 0) THEN { then no errors occured } BEGIN WriteLn('All characters were transmitted without error. '); END END.