home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_GEN
/
BBSKIT31.ZIP
/
TERM.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-01-06
|
19KB
|
679 lines
{
Term.Pas
A sample terminal program for BBSkit.
Version 1.2; updated for BBSkit 3.0.
Written by Steve Madsen
This program also includes a couple of "features" for debugging. Compile
with the symbol DEBUG defined for the extras. They are:
Press Alt-D in terminal mode for a dump of the UART registers and some
other useful stuff.
Press Alt-I to retrigger the interrupts. This generally restarts a
stopped transmission if there is a problem with the interrupt handler.
May have to hit it a few times, though.
Press F2 to output a >200 character string.
-Dx command line switch lets you open two ports at once. The second
port is COMx and runs at the same bps rate (to start with) as the
standard port. You must Alt-X out of both ports to quit the program.
Switch between them with Left Alt-F1 and Left Alt-F2.
NOTE: intended to be compiled using the registered version of BBSkit. If
you wish to recompile with a demo copy, remove the space before the $ in
the following $DEFINE.
}
{ $DEFINE DEMO}
PROGRAM Term12;
{$X+}
{$M 16384, 0, 131072}
{$DEFINE NOBSP}
Uses CRT, DOS, VC, Protocol, BBSkit, Comm, Util, MTask;
Const
MaxEmu = 4;
Emulations : Array[1..MaxEmu] of String = ('TTY', 'ANSI', 'VT100', 'VT52');
Type
TTerm = object(TBBS)
Baud : Longint;
Capture : Boolean;
Comport : Byte;
TermFlags : TTermMode;
ExitCh : Char;
Printer : Boolean;
Template : Byte;
CONSTRUCTOR Init(IComport : Byte; IBaud : Longint);
PROCEDURE Run; VIRTUAL;
DESTRUCTOR Done; VIRTUAL;
PROCEDURE Baudrate;
PROCEDURE DebugInfo;
PROCEDURE DOSShell;
PROCEDURE Download;
PROCEDURE Emulation;
PROCEDURE EnterAnswerMode;
PROCEDURE EnterOriginateMode;
PROCEDURE Help(var Cmd : Char);
PROCEDURE ReInitModem;
PROCEDURE Status(Msg : String);
PROCEDURE ToggleBackspace;
PROCEDURE ToggleCapture;
PROCEDURE ToggleDuplex;
PROCEDURE TogglePrinter;
PROCEDURE ToggleShowControls;
PROCEDURE Upload;
end;
Var
TaskID : Word;
TaskResult : Word;
Term : TTerm;
Param : Word;
{$IFDEF DEBUG}
DebugTerm : TTerm;
{$ENDIF}
{********************************************************************}
PROCEDURE Usage;
begin
WriteLn('Term usage:');
WriteLn;
WriteLn(ProgramName, ' <comport> <baudrate> [-o]');
WriteLn;
WriteLn(' <comport> can be 1, 2, 3 or 4.');
WriteLn(' <baudrate> can be 300, 600, 1200, 2400, 4800, 9600, 19200,');
WriteLn(' 38400, 57600, or 115200.');
WriteLn;
WriteLn(' -o starts Term without sending the init string');
{$IFDEF DEBUG}
WriteLn;
WriteLn(' -dx opens debug port COMx at same speed. Must be last parameter!');
{$ENDIF}
WriteLn;
WriteLn('example: ', ProgramName, ' 2 2400 { com2, at 2400 bps }');
WriteLn(' ', ProgramName, ' 1 9600 { com1, at 9600 bps }');
end;
{--------------------------------------------------------------------}
PROCEDURE StartATerm(var AtPort); FAR;
begin
if (Word(AtPort) = 0) then
begin
Term.Init(StrToInt(ParamStr(1)), StrToInt(ParamStr(2)));
Term.Run;
Term.Done;
{$IFDEF DEBUG}
end
else
begin
DebugTerm.Init(StrToInt(Copy(ParamStr(ParamCount), 3, 1)), StrToInt(ParamStr(2)));
DebugTerm.Run;
DebugTerm.Done;
{$ENDIF}
end;
end;
{--------------------------------------------------------------------}
CONSTRUCTOR TTerm.Init(IComport : Byte; IBaud : Longint);
begin
TBBS.Init;
{$IFDEF DEBUG}
AllowVCSwitching(True);
{$ELSE}
AllowVCSwitching(False);
{$ENDIF}
Comport := IComport;
Baud := IBaud;
SetPortRoutines(Comport, FOSSIL);
if (not OpenPort(Comport)) then
begin
vcWriteLn('Can''t open comport.');
Halt(1);
end;
SetBpsRate(Comport, Baud);
SetFlowControl(PortIdx, False, False);
SetParity(PortIdx, NoParity);
SetWordLength(PortIdx, 8);
SetStopBits(PortIdx, 1);
TermFlags.Duplex := Full;
TermFlags.ShowControls := False;
TermFlags.Backspace := #8;
Capture := False;
Printer := False;
SetInput(True, False);
ClrScr;
Template := 1;
Status('');
if (ParamCount < 3) or (Lower(ParamStr(3)) <> '-o') then
EnterOriginateMode;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.Run;
Const
BigString = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'+
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'+
'cccccccccccccccccccccccccccccccccccccccccccccccccccccccc'+
'dddddddddddddddddddddddddddddddddddddddddddddddddddddddd';
begin
Repeat
ExitCh := TerminalMode(TermFlags);
if (ExitCh = #59) then
Help(ExitCh); { F1 = help }
case ExitCh of
{$IFDEF DEBUG}
#60 : begin
SendString(PortIdx, BigString);
Status(IntToStr(PortArray[PortIdx].OutUsed));
end;
#32 : DebugInfo;
#23 : ReInitModem;
{$ENDIF}
#48 : Baudrate;
#36 : DOSShell;
#81 : Download;
#50 : Emulation;
#30 : EnterAnswerMode;
#24 : EnterOriginateMode;
#35 : begin
Hangup;
Status('');
end;
#20 : ToggleBackspace;
#46 : ToggleCapture;
#18 : ToggleDuplex;
#25 : TogglePrinter;
#31 : ToggleShowControls;
#73 : Upload;
end;
Until (ExitCh = #45); { Alt-X = quit }
end;
{--------------------------------------------------------------------}
DESTRUCTOR TTerm.Done;
Var
Online : Boolean;
begin
Online := Carrier(PortIdx);
ClosePort(not Online);
Window(1, 1, 80, TextScreenMaxY);
TextColor(LightGray);
TextBackground(Black);
ClrScr;
TBBS.Done;
if (Online) and (InCommandLine('-D') = 0) then
WriteLn('Warning: DTR not lowered since you are still online.');
end;
{--------------------------------------------------------------------}
{
* We can just double the rate for any step up, *except* for the step
* from 38400 to 57600.
}
PROCEDURE TTerm.Baudrate;
begin
if (Baud <> 38400) then
begin
Baud := Baud SHL 1;
if (Baud > 115200) then
Baud := 300;
end
else
Baud := 57600;
SetBpsRate(Comport, Baud);
Status('');
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.DebugInfo;
FUNCTION BinaryByte(Value : Byte) : String;
Var
Strn : String;
Idx : Word;
begin
Strn := '';
Idx := $1;
Repeat
if (Value AND Idx = Idx) then
Strn := '1' + Strn
else
Strn := '0' + Strn;
Idx := Idx SHL 1;
Until (Idx = $100);
BinaryByte := Strn;
end;
begin
vcWriteLn('');
vcWrite (' Port: COM' + IntToStr(PortIdx));
vcWrite (' Status flags: ' + BinaryByte(PortArray[Comport].StatusFlg));
vcWriteLn(' Error flags: ' + BinaryByte(PortArray[Comport].ErrorFlg));
vcWrite (' IER: ' + BinaryByte(Port[PortArray[Comport].PortAddr + IER]));
vcWrite (' IIR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + IIR]));
vcWriteLn(' LCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + LCR]));
vcWrite (' MCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + MCR]));
vcWrite (' LSR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + LSR]));
vcWriteLn(' MSR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + MSR]));
vcWrite (' SCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + SCR]));
vcWrite (' OCW1: ' + BinaryByte(Port[OCW1]));
vcWriteLn(' OCW2: ' + BinaryByte(Port[OCW2]));
vcWrite ('OutUsed: ' + Left(IntToStr(PortArray[Comport].OutUsed), 4));
vcWriteLn(' InUsed: ' + IntToStr(PortArray[Comport].InUsed));
vcWriteLn('');
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.DOSShell;
begin
SaveScreen;
if (GetEnv('COMSPEC') = '') then
Exec('\COMMAND.COM', '')
else
Exec(GetEnv('COMSPEC'), '');
RestoreScreen;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.Download;
Var
Ch : Char;
Fname : String;
Err : TError;
begin
OpenWindow(3, 3, 50, 15, White, Blue, SingleLine, 'Download');
vcWriteLn('Receive mode: [X]modem, Xmodem-[C]RC,');
{$IFNDEF DEMO}
vcWriteLn(' Xmodem-[1]K, [Y]modem,');
vcWrite(' Ymodem-[G]? ');
{$ELSE}
vcWrite(' Xmodem-[1]K? ');
{$ENDIF}
Ch := UpCase(ReadKey);
vcWriteLn(Ch);
{$IFNDEF DEMO}
if (Pos(Ch, 'XC1YG') > 0) then
{$ELSE}
if (Pos(Ch, 'XC1') > 0) then
{$ENDIF}
begin
case Ch of
'X',
'C',
'1' : begin
vcWriteLn('');
vcWrite('Receive file: ');
ReadLn(Fname);
if (Fname = '') then
begin
CloseWindow;
Exit;
end;
case Ch of
'X' : Err := ReceiveXmodem(Checksum, Fname);
'C' : Err := ReceiveXmodem(CRC, Fname);
'1' : Err := ReceiveXmodem(OneK, Fname);
end;
end;
{$IFNDEF DEMO}
'Y',
'G' : begin
vcWriteLn('');
vcWrite('Batch receive to path: ');
vcReadLn(Fname);
if (Fname = '') then
begin
CloseWindow;
Exit;
end;
case Ch of
'Y' : Err := ReceiveYmodem(Normal, Fname);
'G' : Err := ReceiveYmodem(Streaming, Fname);
end;
end;
{$ENDIF}
end;
case Err of
NoError : Status('Last Transfer GOOD');
TimeOut : Status('Transfer Timeout');
TooManyErrors : Status('Too Many Errors');
Aborted : Status('Aborted by User');
DiskError : Status('Disk Error');
NoCarrier : Status('Carrier Lost');
FileExists : Status('File Already Exists');
end;
end;
CloseWindow;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.Emulation;
begin
if (Exist('STD.EML')) then
begin
Inc(Template);
if (Template > MaxEmu) then
Template := 1;
LoadEmulationLib(Emulations[Template], 'STD.EML');
Status('');
end
else
Status('No STD.EML');
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.EnterAnswerMode;
begin
Status('');
OpenWindow(20, 3, 40, 3, White, Blue, SingleLine, '');
vcWrite(' Switching To Answer Mode');
if (not SendAT('ATS0=1')) then
Status('Modem Not Responding');
CloseWindow;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.EnterOriginateMode;
begin
Status('');
OpenWindow(20, 3, 40, 3, White, Blue, SingleLine, '');
vcWrite(' Switching To Originate Mode');
if (not SendAT('ATS0=0M1L1E1')) then
Status('Modem Not Responding');
CloseWindow;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.Help(var Cmd : Char);
Var
Ch : Char;
begin
OpenWindow(5, 3, 72, 12, White, Blue, SingleLine, 'Help');
SetWindowTitle('Term Help');
GotoXY(1, 2);
vcWriteLn(' Alt-A Auto-answer mode Alt-B Toggle baudrate');
vcWriteLn(' Alt-C Toggle capture buffer Alt-E Toggle duplex');
vcWriteLn(' Alt-H Hangup Alt-J Jump to DOS');
vcWriteLn(' Alt-M Emulation Alt-O Originate mode');
vcWriteLn(' Alt-P Toggle printer Alt-S Toggle "show controls"');
vcWriteLn(' Alt-T Toggle backspace key Alt-X Exit');
vcWriteLn('');
vcWriteLn(' PgUp Upload file(s) PgDn Download file(s)');
Ch := ReadKey;
if (Ch = #0) then
Cmd := ReadKey;
CloseWindow;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.ReInitModem;
Var
Save : Byte;
begin
Save := Port[PortArray[PortIdx].PortAddr + IER];
Port[PortArray[PortIdx].PortAddr + IER] := $00;
Port[PortArray[PortIdx].PortAddr + IER] := Save;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.Status(Msg : String);
Var
Fore, Back : Byte;
SX, SY : Byte;
ScrEnd : Byte;
begin
Fore := GetTextColor;
Back := GetTextBackground;
SX := WhereX;
SY := WhereY;
ScrEnd := Hi(WindMax);
Window(1, 1, 80, 1);
TextBackground(Blue);
ClrScr;
TextColor(Yellow);
vcWrite(' Term ');
TextColor(White);
case TermFlags.Duplex of
Full : vcWrite('Full Duplex ');
Half : vcWrite('Half Duplex ');
Chat : vcWrite('Chat Duplex ');
end;
vcWrite(Right(IntToStr(Baud), 6) + 'bps ');
vcWrite('COM' + IntToStr(Comport) + ' ');
if (Carrier(Comport)) then
vcWrite('Carrier ')
else
vcWrite(' ');
if (Capture) then
vcWrite('Cap ')
else
vcWrite(' ');
if (Printer) then
vcWrite('Prn ')
else
vcWrite(' ');
vcWrite(Left(Emu.Key, 8));
if (Msg = '') then
Msg := 'F1 = Help';
GotoXY(80 - Length(Msg), 1);
vcWrite(Msg);
Window(1, 2, 80, TextScreenMaxY);
TextColor(Fore);
TextBackground(Back);
GotoXY(SX, SY);
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.ToggleBackspace;
begin
if (TermFlags.Backspace = #8) then
begin
TermFlags.Backspace := #127;
Status('Backspace is RUB');
end
else
begin
TermFlags.Backspace := #8;
Status('Backspace is ^H');
end;
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.ToggleCapture;
Var
Cap : String;
begin
Capture := not Capture;
if (Capture) then
begin
OpenWindow(5, 3, 45, 5, White, Blue, SingleLine, 'Capture to File');
GotoXY(1, 2);
vcWrite(' Filename: ');
ReadLn(Cap);
if (Cap = '') then
Cap := 'SESSION.TXT';
SetCaptureFile(Cap);
CloseWindow;
end;
SetCaptureStatus(Capture);
Status('');
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.ToggleDuplex;
begin
case TermFlags.Duplex of
Full : TermFlags.Duplex := Half;
Half : TermFlags.Duplex := Chat;
Chat : TermFlags.Duplex := Full;
end;
Status('');
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.TogglePrinter;
begin
Printer := not Printer;
SetPrinter(Printer);
Status('');
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.ToggleShowControls;
begin
TermFlags.ShowControls := not TermFlags.ShowControls;
if (TermFlags.ShowControls) then
Status('Show Controls ON')
else
Status('Show Controls OFF');
end;
{--------------------------------------------------------------------}
PROCEDURE TTerm.Upload;
Var
Ch : Char;
Fname : String;
FInfo : SearchRec;
Err : TError;
begin
OpenWindow(3, 3, 50, 15, White, Blue, SingleLine, 'Upload');
vcWriteLn('Send mode: [X]modem, Xmodem-[C]RC,');
{$IFNDEF DEMO}
vcWriteLn(' Xmodem-[1]K, [Y]modem,');
vcWrite(' Ymodem-[G]? ');
{$ELSE}
vcWrite(' Xmodem-[1]K? ');
{$ENDIF}
Ch := UpCase(ReadKey);
vcWriteLn(Ch);
{$IFNDEF DEMO}
if (Pos(Ch, 'XC1YG') > 0) then
{$ELSE}
if (Pos(Ch, 'XC1') > 0) then
{$ENDIF}
begin
case Ch of
'X',
'C',
'1' : begin
vcWriteLn('');
vcWrite('File to send: ');
ReadLn(Fname);
if (Fname = '') then
begin
CloseWindow;
Exit;
end;
vcWriteLn('');
case Ch of
'X' : Err := SendXmodem(Checksum, Fname);
'C' : Err := SendXmodem(CRC, Fname);
'1' : Err := SendXmodem(OneK, Fname);
end;
end;
{$IFNDEF DEMO}
'Y',
'G' : begin
vcWriteLn('');
vcWriteLn('Batch send: enter a blank line when done.');
vcWriteLn('');
ClearBatch;
Repeat
vcWrite('Send file: ');
vcReadLn(Fname);
if (Fname <> '') then
AddBatch(Fname);
Until (Fname = '');
if (FilesInBatch > 0) then
begin
case Ch of
'Y' : Err := SendYmodem(Normal);
'G' : Err := SendYmodem(Streaming);
end;
end
else
begin
CloseWindow;
Exit;
end;
end;
{$ENDIF}
end;
case Err of
NoError : Status('Last Transfer GOOD');
Timeout : Status('Transfer Timeout');
TooManyErrors : Status('Too Many Errors');
Aborted : Status('Aborted by User');
DiskError : Status('Disk Error');
NoCarrier : Status('Carrier Lost');
FileExists : Status('File Already Exists');
end;
end;
CloseWindow;
end;
{********************************************************************}
BEGIN
CheckBreak := False;
if (ParamCount = 0) or (Pos('?', ParamStr(1)) <> 0) then
Usage
else
begin
Param := 0;
Create_Task(StartATerm, Param, 8192, TaskID, TaskResult);
Switch_Task;
if (InCommandLine('-D') <> 0) then
begin
Param := 1;
Create_Task(StartATerm, Param, 8192, TaskID, TaskResult);
end;
while (Number_Of_Tasks > 2) do { loop until all terms shutdown }
Switch_Task;
end;
END.