unit CommDRV; interface const INT = 5; RECEIVE = 0; TRANSMIT = 0; L_DIVISOR = 0; U_DIVISOR = 1; INT_ENB = 1; INT_ID = 2; LINE_CTRL = 3; MODEM_CTRL = 4; LINE_STAT = 5; MODEM_STAT = 6; procedure initCommCard(baseAddr, baudRate : word); procedure writePod(baseAddr : word; message : string); procedure readPod(baseAddr : word; var message : string); implementation uses crt; var dByte : byte; procedure dummy; begin end; { returns negation of contents of on-board 8253 counter } function readtimer : word; var returnval : word; begin asm pushf cli mov al,0h out 43h,al end; dummy; asm in al,40h mov bl,al end; dummy; asm in al,40h mov bh,al not bx popf mov returnval,bx end; readtimer := returnval; end; { computer independent delay used for timout purposes. } procedure comdelay( timer_ticks : word); var stop : longint; cur, prev : word; begin prev := readtimer; stop := prev + timer_ticks; cur := readtimer; while (cur < stop) do begin if (cur < prev) then begin if (stop < $10000) then exit; stop := stop - $10000; end; prev := cur; cur := readtimer; end; end; procedure initCommCard(baseAddr, baudRate : word); var divisor : word; begin { Oscillator frequency is 1.8432MHz, or 1,843,200 Hz The divisor is calculated by dividing the frequency by 16, then dividing again by the baudrate, or --- divisor = (f / 16) / baudrate 1,843,200 / 16 is 115200, so - } divisor := 115200 div baudRate; { tell card we are about to set options } port[baseAddr + LINE_CTRL] := $80; { Load the card with the low and high bytes of the divisor. } port[baseAddr + L_DIVISOR] := lo(divisor); port[baseAddr + U_DIVISOR] := hi(divisor); { set the card the 7 bits of data, even parity and 1 stop bit } port[baseAddr + LINE_CTRL] := $1A; port[baseAddr + MODEM_CTRL] := $00; { clear the receive buffer } delay(50); dByte := port[baseAddr + RECEIVE]; delay(50); dByte := port[baseAddr + RECEIVE]; end; procedure writePod(baseAddr : word; message : string); var x, times : byte; begin { get length of the string to send } x := length(message); { set the card into transmit mode } port[baseAddr + MODEM_CTRL] := $0F; for times := 1 to x do begin { wait until the card is ready to transmit a character } while ((port[baseAddr+LINE_STAT] AND $20) = 0) do; { transmit the character } port[baseAddr+TRANSMIT] := ord(message[times]); end; { wait until the character is transmitted } while ((port[baseAddr+LINE_STAT] AND $20) = 0) do; { transmit a Carriage Return } port[baseAddr+TRANSMIT] := $0D; { wait until CR is transmitted } while ((port[baseAddr+LINE_STAT] AND $20) = 0) do; { wait for the card to come back } while ((port[baseAddr+LINE_STAT] AND $40) = 0) do; { place the card into receive mode } port[baseAddr+MODEM_CTRL] := $0D; end; procedure readPod(baseAddr : word; var message : string); var x : byte; ch : char; retstring : string; timeout : word; begin x := 0; repeat { character location in string is incremented } inc(x); { timeout initialized } timeout := 65535; repeat { decrement our timeout counter } dec(timeout); { wait until the card sees a character or until our counter has timed out. } until ((timeout = 0) OR ((port[baseAddr+LINE_STAT] AND $01) <> 0)); { if it has not timed out, store the character } if (timeout <> 0) then retstring[x] := chr(port[baseAddr + RECEIVE]) { otherwise, return with an error message } else begin message := '??ERROR!'; exit; end; { repeat for fifty characters } until ((retstring[x] = #$0D) OR (x = 50)); { Set the string length } retstring[0] := chr(x); { copy it to the parameter } message := retstring; { and clear the receive buffers } delay(50); dByte := port[baseAddr + RECEIVE]; delay(50); dByte := port[baseAddr + RECEIVE]; end; begin end.