home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
turbopas
/
tty.arc
/
TTY.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1988-06-12
|
4KB
|
133 lines
program TTY;
uses
DOS,CRT;
const
RBR = $3F8; {Port address - RX Buffer Register}
THR = $3F8; {Transmit Hold Register}
DLL = $3F8; {Low byte of divisor}
DLM = $3F9; {High Byte of Divisor}
IER = $3F9; {Overlays INT Enable Register}
LCR = $3FB; {Line Control Register}
MCR = $3FC; {Modem Control Register}
LSR = $3FD; {Line Status Register}
BAUD300 = 384; {300 Baud Divisor}
BAUD1200 = 96; {1200 Baud Divisor}
RTS = $02; {Mask for ReadyToSend}
ERBFI = $01; {Mask to enable Receive INT's}
THRE = $20; {Mask for THRE}
TWOSTOP = $04; {Mask for 2 stop bits (110 baud only)}
ONESTOP = $00; {Mask for 1 stop bit}
DTR = $01; {Mask for DTR}
DLAB = $80; {Mask for DLAB}
NOPARITY = $00; {Mask for no parity}
EIGHTBITS = $03; {Mask for 8 bits/char}
OCW1 = $21; {Mask for enable bits for 8259}
OCW2 = $20; {Port for 8259 Commands}
NSEOI = $20; {Non-specific End-Of-Interrupt Command}
OUT2 = $08; {Mask for OUT2}
IRQ4 = $10; {Mask to dis/enable hardware int level 4}
PORT1INT = 12; {Int vector number for IRQ4}
QUEUEMAX = 255; {Max queue subscript, 2^n-1}
var
queue : array [0..QUEUEMAX] of byte; {Circular buffer}
queueIn : integer;
queueOut : integer; {Buffer pointers}
oldVector : pointer; {Storage for old INT vector}
ch : char; {Keyboard Char}
temp : integer;
procedure InterruptsOn; inline($FB); {Turn on interrupts}
{$IFOPT R+} {Don't forget to turn Range Checking on...}
{$DEFINE RANGE}
{$ENDIF}
{$R-}
procedure Port1ISR; Interrupt; {INT Service Routine for port 1}
begin
InterruptsOn;
queueIn := Succ(queueIn) and QUEUEMAX;
if queueIn = queueOut then {Queue full, put pointer back}
queueIn := Pred(queueIn) and QUEUEMAX;
queue[queueIn] := Port[RBR];
Port[OCW2] := NSEOI
end;
{$IFDEF RANGE}
{$R+}
{$ENDIF}
{$F+}
Procedure RestoreIntVec; {Exit proc to restore int vector}
begin {shutoff ints and drop dtr}
Port[IER] := 0; {INTs off at UART}
Port[OCW1] := Port[OCW1] or IRQ4; {INTs off at 8259}
Port[MCR] := 0; {DTR, RTS, OUT2 off}
SetIntVec(PORT1INT,oldVector)
end;
{$F-}
begin
Writeln('GEnie Borland RoundTable Sample Dumb Terminal');
Writeln('Using COM1 at 1200 baud, 8 data bits, no parity, 1 stop bit');
Writeln('Press Alt-X to exit.');
CheckBreak := FALSE;
DirectVideo := TRUE;
queueIn := 0;
queueOut := 0;
Port[IER] := 0; {Disable UART INT's}
{Here's where we take over the comm interrupt}
GetIntVec(PORT1INT,oldVector);
exitProc := Addr(RestoreIntVec);
SetIntVec(PORT1INT,Addr(Port1ISR));
{Initialize the UART}
Port[LCR] := Port[LCR] or DLAB; {Allow access to Divisor}
Port[DLL] := Lo(BAUD1200); {Baud Rate to 1200}
Port[DLM] := Hi(BAUD1200); {Ditto...}
Port[LCR] := EIGHTBITS or ONESTOP or NOPARITY;
Port[MCR] := DTR or RTS or OUT2;
{Turn on INTs at 8259}
Port[OCW1] := Port[OCW1] and not (IRQ4);
if Port[LSR] <> 0 then; {Clear any errors}
if Port[RBR] <> 0 then; {Clear trash from RX buffer}
Port[IER] := ERBFI; {Enable UART RX INTs}
repeat
while queueIN <> queueOut do
begin
temp := Succ(queueOut) and QUEUEMAX;
Write(Char(queue[temp] and $7F)); {Strip Hi Bit}
queueOut := TEMP;
end;
if KeyPressed then
if Port[LSR] and THRE <> 0 then
begin
ch := ReadKey;
if (ch = #0) and KeyPressed then
begin
ch := Readkey;
if ch = #45 then
Halt {Pressed Alt-X, exit}
end
else
Port[THR] := Byte(ch)
end
until FALSE;
end.