home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
PROTOCOL
/
WXTRM305.ZIP
/
WXTERM.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-08-12
|
14KB
|
528 lines
PROGRAM wxterm;
{$S+,R+,D+,L+,V-,B+}
USES Dos,CRT,TURBO3; {3.04}
{
Scott Murphy
77 So. Adams St. #301
Denver, CO 80209
Compuserve 70156,263
Defaults, help screen and hot keys improved. Ran thru Pascal
Formatter, changed to a two file program. Changed to Ver: 3.01
12-05-87 L.B. Neal, Sunnyvale, CA.
}
{**************************************************************}
{ Jun 1990. Upgraded to Turbo Pascal 5.0/5.5. Ver:3.04 }
{ Aug 1991. Corrected several items. New version is 3.05. }
{ L.B. Neal, Sunnyvale,CA. }
{**************************************************************}
CONST
Version = '3.05 '; { 12-AUG-91 Another look}
BELL_FREQ = 440; {frequency for bell sound}
BELL_DELAY = 100; {duration of bell sound}
DEFAULT_BAUD = 2400; {Serial port speed at start-up}
RECV_BUF_SIZE = 4097; {this may be changed to whatever size you need}
Buffer_End = RECV_BUF_SIZE-1; { safety margin }
ComPort : Byte = 1;
WxExit : Boolean = False; {3.05}
TYPE
bigstring = STRING[80]; {general purpose}
cset = SET OF 0..127;
parity_set = (none, even); {readability and expansion}
VAR
AsyncVector: Pointer;
xtnd : Boolean;
a : Byte;
c, i : Integer;
ch : Char;
regs: Registers; { 3.04 }
INVLIST : Integer;
Buffer_Head, Buffer_Tail,Buffer_Count: Integer;
recv_buffer : ARRAY[1..RECV_BUF_SIZE] OF Byte;
speed : Integer; {I don't know the top speed these
routines will handle}
dbits : 7..8; {only ones most people use}
stop_bits : 1..2; {does anyone use 2?}
parity : parity_set; {even and none are the common ones}
Cport: String[4]; {3.04}
Base: Word; {3.04}
Async_Irq: Word; {3.04}
OutPort: Word; {3.04}
junk: Char; {3.04}
PassStrg: BigString; {3.04}
wcol,wrow: Integer; {3.04}
{$R-,S-}
{$F+} { MUST be a FAR Procedure 3.04 }
PROCEDURE async_isr; Interrupt;
BEGIN
Inline($FA); {CLI} {3.05}
Recv_Buffer[Buffer_Head] := Port[Base];
IF (Buffer_Head = Buffer_End) THEN
Buffer_Head := 1
ELSE
INC(Buffer_Head);
INC(Buffer_Count);
Inline($FB); {STI} {3.05}
Port[$20] := $20;
END;
{$F-}
PROCEDURE DoBorder(FstCol,FstRow,LstCol,LstRow : Integer);
VAR i,thisrow,width,height,column: Integer; horiz: String[90];
BEGIN
Window(FstCol,FstRow,LstCol,LstRow);
ClrScr;
thisrow := 2;
width := (LstCol-FstCol)-2;
height := (LstRow-FstRow)-1;
column := Width+2;
FOR i := 1 to width DO horiz[i] := #205;
horiz[0] := Char(width);
Gotoxy(1,1); Write(Chr(201));
Write(horiz);
Write(Chr(187));
FOR i := 1 TO height DO
BEGIN
Gotoxy(1,thisrow); Write(Chr(186));
Gotoxy(column,thisrow); Write(Chr(186));
INC(thisrow);
END;
Gotoxy(1,thisrow); Write(CHR(200));
Write(horiz);
Write(#188);
END;
FUNCTION Carrier:Boolean;
BEGIN
Carrier := (port[base+6] AND 128) <> 0;
END;
FUNCTION Wcgetc: Byte; { 3.04 }
BEGIN
INLINE($FA); {suspend interrupts}
wcgetc := Recv_Buffer[buffer_Tail];
IF Buffer_Tail < Buffer_End THEN { 3.04 safer this way }
INC(Buffer_Tail)
ELSE
Buffer_Tail := 1;
DEC(Buffer_Count);
INLINE($FB); {resume interrupts}
Port[$20] := $20; {3.05}
END;
PROCEDURE send(c:Byte);
BEGIN
WHILE (port[outport] AND 32) = 0 DO {NOP};
port[base] := c;
END;
PROCEDURE set_baud(r:integer);
VAR a:byte; rw:word;
BEGIN
IF (r >= 300) AND (r <= 9600) THEN
BEGIN
IF r = 2400 THEN rw := 48
ELSE IF r = 1200 THEN rw := 96
ELSE IF r = 9600 THEN rw := 6 { really 19200 baud }
ELSE IF r = 300 THEN rw := 384;
a := port[base+3] OR 128;
port[base+3] := a;
port[base] := lo(rw);
port[base+1] := hi(rw);
port[base+3] := a AND 127;
END
ELSE
BEGIN
Writeln('Invalid Baud Rate = ', r); { 2.0i }
Halt(1);
END;
END;
procedure dump;
begin
Inline($FA); {CLI}
buffer_head := 1;
buffer_tail := 1;
buffer_count := 0;
Inline($FB); {STI}
Port[$20] := $20; {3.05}
end;
procedure remove_port;
var i,m : Word;
begin
inline($FA); {CLI}
i := port[$21];
m := 1 SHL Async_Irq;
port[$21] := i OR m;
port[base+2] := 0;
port[base+4] := port[base+4] AND 1;
inline($FB); {STI}
Port[$20] := $20; {3.05}
end;
procedure term_ready(s:Boolean);
var x:byte;
begin
x := port[base+4] and $FE;
if s then x := x+1;
port[base+4] := x;
end;
PROCEDURE iport1;
BEGIN
CASE comport OF
1 : begin
base := $3f8; Async_Irq := 4; cport := 'COM1:';
end;
2 : begin
base := $2f8; Async_Irq := 3; cport := 'COM2:';
end;
3 : begin
base := $3E8; Async_Irq := 4; cport := 'COM3:';
end;
4 : begin
base := $2E8; Async_Irq := 3; cport := 'COM4:';
end;
ELSE
WriteLn('Invalid Comport:',comport);
Halt(1);
END; {case}
outport := Base+5;
END;
procedure iport;
var i,m:Integer;
BEGIN
If (Port[base+2] and $00F8) <> 0 Then
begin
writeln('Illegal com port number:',cport);
halt(1); {3.05}
end
else
begin
buffer_Head := 1;
buffer_Tail := 1;
buffer_Count := 0;
port[base+3]:= $03;
with regs do
begin
ah := $25; al := async_irq+8;
ds := cseg;
dx := ofs(async_isr); msdos(regs);
end;
inline($FA);
i := port[base+5];
i := port[base];
i := port[$21];
m := (1 shl Async_Irq) xor $00FF;
port[$21] := i and m;
port[base+1] := $01;
i := port[base+4];
port[base+4] := i or $08;
term_ready(true);
inline($FB);
Port[$20] := $20; {3.05}
end;
end;
PROCEDURE break; {send a break}
VAR a, b : Byte;
BEGIN
a := Port[base+3];
b := (a AND $7F) OR $40;
Port[base+3] := b;
Delay(750);
Port[base+3] := a;
END;
FUNCTION exists(fname:bigstring): Boolean;
VAR f : FILE;
BEGIN
Assign(f, fname);
{$I-} Reset(f); {$I+}
IF IOResult = 0 THEN
BEGIN
exists := True;
Close(f);
END
ELSE
exists := False
END;
PROCEDURE supcase(VAR s);
VAR ss:bigstring ABSOLUTE s; i:Integer;
BEGIN
FOR i := 1 TO Length(ss) DO ss[i] := UpCase(ss[i])
END;
PROCEDURE processcom;
VAR c,cnt: Byte;
BEGIN
IF Buffer_Count > 0 THEN {Safety net 3.04 }
BEGIN
c := WcGetc;
IF c < 13 THEN
BEGIN
CASE c OF
10 : Write(Chr(c)); {3.05}
9 : FOR cnt := WhereX TO (WhereX DIV 8+1)* 8 DO Write(' ');
7 : BEGIN {bell}
Sound(BELL_FREQ);
Delay(BELL_DELAY);
NoSound
END;
12 : ClrScr;
END;
END
ELSE
Write(Chr(c)); { Full IBM char set now - 3.03}
END;
END;
{$R+,S+}
{$I WXTMXFER.INC}
CONST MASTER_FILE_NAME = 'WXTERM.MST';
TYPE
MasterRec = RECORD
mdbits : 7..8;
mparity :parity_set;
mstop_bits : 1..2;
mcom_port: Byte;
mspeed : Integer;
END;
VAR
msrecord : MasterRec;
msfile : FILE OF MasterRec;
PROCEDURE setup; {initialize most stuff - you may want to replace this}
VAR err: Integer; {3.05}
BEGIN
WITH msrecord DO
BEGIN
Assign(msfile, MASTER_FILE_NAME);
IF exists(MASTER_FILE_NAME) THEN
BEGIN
Reset(msfile);
Read(msfile, msrecord)
END
ELSE
BEGIN
Rewrite(msfile);
mdbits := 8; {Chg 3.01}
mparity := NONE; {Chg 3.01}
mstop_bits := 1; {Chg 3.01}
mcom_port := comport;
mspeed := DEFAULT_BAUD;
Write(msfile, msrecord);
END;
{$I-} Close(msfile); {$I+} err := IoResult; {3.05}
dbits := mdbits;
parity := mparity;
stop_bits := mstop_bits;
speed := mspeed;
ComPort := mcom_port;
END;
END;
PROCEDURE GetParms;
VAR p: string[4]; yn,cp,ans: Char; junk: integer;
BEGIN
GotoXy(3,2); Write('Current Parameters:');
Gotoxy(3,3); Write('Baud Rate:', speed:6);
Gotoxy(3,4); Write('Data Bits:', dbits:6);
Gotoxy(3,5); Write('Stop Bits:', stop_bits:6);
CASE parity OF
even : p := 'EVEN';
none : p := 'NONE';
ELSE
p := '????'
END;{case}
Gotoxy(3,6); Write('Parity : ', p:6); {3.05}
Gotoxy(3,7); Write('Comm Port: ', Comport);
Gotoxy(3,9); Write('Change(Y/N)?');
REPEAT
ans := Upcase(ReadKey);
UNTIL (ans = 'Y') OR (ans = 'N');
IF ans = 'Y' THEN {3.05}
BEGIN
Gotoxy(3,10); Write('Baud Rate 3)00 1)200 2)400 <cr> to keep.'); {Chd 3.01}
REPEAT
ans := ReadKey;
UNTIL ans IN['1'..'3',#13];
IF ans IN['1'..'3'] THEN val(ans,comport,junk);
Gotoxy(3,11); Write('New Data Bits[7/8] <cr> to keep.'); {Chd 3.05}
REPEAT
ans := ReadKey;
UNTIL ans IN['7','8',#13];
IF ans IN['7','8'] THEN val(ans,dbits,junk);
Gotoxy(3,12); Write('New Stop Bits[1/2] <cr> to keep.'); {Chd 3.01}
REPEAT {3.05}
ans := ReadKey;
UNTIL ans IN['1','2',#13];
IF ans IN['1','2'] THEN val(ans,stop_bits,junk);
Gotoxy(3,13); Write('New Parity E or N <cr> to keep:'); {Chd 3.01}
REPEAT
ans := ReadKey;
UNTIL ans IN['E','N',#13];
IF (ans = 'E') THEN
parity := even
ELSE
IF (ans = 'N') THEN parity := none;
Gotoxy(3,14); Write('New com port 1..4 or <cr> to keep.'); {Chd 3.05}
REPEAT
cp := Upcase(Readkey);
UNTIL cp IN['1'..'4',#13];
IF cp IN['1'..'4'] THEN Comport := ORD(cp)-48;
GotoXY(3,15); {3.05}
Write('Save changes[Y/N]?'); {Chd 3.01}
REPEAT
yn := Upcase(Readkey);
UNTIL (yn = 'Y') OR (yn = 'N');
IF yn = 'Y' THEN
BEGIN
WITH msrecord DO
BEGIN
mdbits := dbits;
mparity := parity;
mstop_bits := stop_bits;
mspeed := speed;
mcom_port := Comport;
Reset(msfile);
Write(msfile, msrecord);
Close(msfile);
END;
END;
END;
END;
PROCEDURE NewParms;
BEGIN
DoBorder(15,3,60,23);
GetParms;
ClrScr;
Window(1,1,80,24);
Set_Baud(speed);
END;
BEGIN
IF Mem[$0000:$0449] = 7 THEN TextMode(MONO) ELSE TextMode(CO80);
DirectVideo := False; {3.04}
CheckBreak := False; {3.04}
CheckSnow := False; {3.04}
ClrScr;
Window(1,25,80,25); {statusline}
Gotoxy(1,1);
Write(' WXTERM:'+Version+' Mode: <Home> for help');
setup;
iport1;
GetIntVec(Async_Irq+8, AsyncVector);
iport;
Set_Baud(speed);
term_ready(True);
{WxExit := False;} {3.05 now typed constant}
GotoXY(19,1); {3.05}
IF carrier THEN Write('On-Line/Ready ') ELSE Write('Off-Line/Ready'); {3.05}
Window(1,1,80,24);
{Gotoxy(1,1);} {3.05 redundant}
{$R-,S-}
WHILE NOT WxExit DO { our main program loop }
BEGIN
WHILE Buffer_Count > 0 DO Processcom; {3.04}
wcol := WhereX; wrow := WhereY; {3.05 moved here}
DEC(wcol); {3.05 moved here}
IF keypressed THEN
BEGIN
a := ORD(Readkey);
IF a = 0 THEN
BEGIN
a := ORD(Readkey);
CASE a OF
81 : recv_wcp; {PgDn - now is more standard 3.05}
45 : BEGIN { alt-X}
DoBorder(20,18,60,22);
Gotoxy(13,2); Write('─── WXTERM ───');
Gotoxy(4,3); Write('Do you really want to exit(Y/N)?');
REPEAT
ch := Upcase(Readkey);
UNTIL (ch = 'Y') OR (ch = 'N');
IF ch = 'Y' THEN
WxExit := True
ELSE
BEGIN
Clrscr; Window(1,1,80,24);
GotoXY(wcol,wrow);
END;
END;
73 : send_wcp; {PgUp - now is more to standard 3.05}
35 : BEGIN { alt-H }
WriteLn('─── WXTERM ───');
WriteLn('Disconnecting');
term_ready(False);
Delay(500);
term_ready(True);
IF Carrier THEN { 3.04 added }
WriteLn('Oops! Hangup Failed!')
ELSE
BEGIN
wcol := WhereX; wrow := WhereY;
Window(1,25,80,25);
Gotoxy(19,1);
Write('Off-Line/Ready');
Window(1,1,80,24);
Gotoxy(wcol,wrow);
END;
END;
46 : ClrScr; {alt-C}
48 : Break; {alt-B}
25 : BEGIN NewParms; GotoXY(wcol,wrow); END; {3.05} {alt-P}
71 : BEGIN {Home}
DoBorder(34,3,78,10);
Gotoxy(3,2); Write('Rcv WXmodem <PGDN> Send WXmodem <PGUP>');
Gotoxy(3,3); Write('Exit ALT-X Hangup ALT-H ');
Gotoxy(3,4); Write('Send Break ALT-B ClrSrn ALT-C ');
Gotoxy(3,5); Write(' Change Comm Params. ALT-P ');
Gotoxy(3,7); Write(' <Press any key to continue> ');
REPEAT UNTIL (KeyPressed);
junk := ReadKey;
BEGIN ClrScr; Window(1,1,80,24); Gotoxy(wcol,wrow); END;
END;
END; {case}
END {if extended key}
ELSE {not extended}
Send(a);
END;{if KeyPressed}
END;{while not wxexit}
{$R+,S+}
remove_port;
SetIntVec(Async_irq+8, AsyncVector);
NormVideo;
Window(1,1,80,25); { Added 3.03 }
ClrScr; { Added 3.01 }
END.