Unit Comm; {***************************************************************************} {* Parts from p. 585 Complete Turbo Pascal 3rd ed. {***************************************************************************} interface {***************************************************************************} {***************************************************************************} Function InChar: char; Function InStat: boolean; Procedure OutChar(Ch: char); Procedure OutStr(SendStr: string); Procedure SetupSerialPort(Baud: integer); {$F+}Procedure ShutdownSerialPort;{$F-} implementation {***************************************************************************} {***************************************************************************} uses Dos, Crt, Glob; const Com1Int = 12; RBR = $3F8; THR = $3F8; LCR = $3FB; IER = $3F9; MCR = $3FC; LSR = $3FD; DLL = $3F8; DLM = $3F9; DLAB = $80; NoParity = 0; Bits8 = $03; DTR = $01; RTS = $02; Out2 = $08; OCW1 = $21; OCW2 = $20; IRQ4 = $10; type CircularBuffer = array[0..1023] of char; var Buffer: CircularBuffer; LastRead, LastSaved: integer; OldVector: Pointer; Procedure EnableInterrupts; {***************************************************************************} inline($FB); Procedure Incoming(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: word); interrupt; {***************************************************************************} begin EnableInterrupts; if LastSaved >= 1023 then LastSaved := 0 else Inc(LastSaved); Buffer[LastSaved] := char(Port[RBR]); Port[OCW2] := $20; end; Function InStat: boolean; {***************************************************************************} begin if LastSaved <> LastRead then InStat := true else InStat := false; end; Function InChar: char; {***************************************************************************} begin if LastRead >= 1023 then LastRead := 0 else LastRead := Succ(LastRead); InChar := Buffer[LastRead]; end; Procedure OutChar(Ch: char); {***************************************************************************} begin Port[THR] := Byte(Ch); end; Procedure OutStr(SendStr: string); {***************************************************************************} var Index: byte; begin for Index := 1 to length(SendStr) do OutChar(SendStr[Index]); end; Procedure SetupSerialPort(Baud: integer); {***************************************************************************} var Divisor: word; begin Divisor := 115200 div Baud; LastRead := 0; LastSaved := 0; Port[IER] := 0; GetIntVec(Com1Int, OldVector); ExitProc := @ShutdownSerialPort; SetIntVec(Com1Int, @Incoming); Port[LCR] := Port[LCR] or DLAB; Port[DLL] := Lo(Divisor); Port[DLM] := Hi(Divisor); Port[LCR] := Bits8 or NoParity; Port[MCR] := DTR or RTS or Out2; Port[OCW1] :=Port[OCW1] and (not IRQ4); DumByte := Port[RBR]; DumByte := Port[LSR]; Port[IER] := $01; end; {$F+} Procedure ShutdownSerialPort; {***************************************************************************} begin Port[IER] := 0; Port[OCW1] := Port[OCW1] or IRQ4; Port[MCR] := 0; SetIntVec(Com1Int, OldVector); end; {$F-} {***************************************************************************} {***************************************************************************} {***************************************************************************} begin end.