home *** CD-ROM | disk | FTP | other *** search
- {
- 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;
- 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.
-