(* Release 3.10 *) (*-------------------------------------------------------------------------* * * * COMMUTIL.MOD - COMMS Toolkit utility functions * * * * COPYRIGHT (C) 1988..1992 Clarion Software Corporation. * * All Rights Reserved * * * *--------------------------------------------------------------------------*) IMPLEMENTATION MODULE CommUtil; (*%F _OS2*) IMPORT ComSetup,Filenames,FIO,FTSupport,IO,Kermit,Lib,MenuLib,MPRINTF,RS232, ScriptProcessor,SPRINTF,Str,SYSTEM,Term,Timer,Window,WXModem,XModem,YModem; FROM Window IMPORT Color; FROM ScriptProcessor IMPORT ScriptStates; CONST BuffSize = 1024; MaxHistory = 128; Template = Window.WinDef(0,0,0,0,Yellow,Black,TRUE,FALSE,FALSE,TRUE,Window.SingleFrame,LightGray,Black); TYPE Addr = RECORD CASE :BOOLEAN OF TRUE : a : ADDRESS; | FALSE : Offset, Segment : CARDINAL; | END; END; VAR LastC,OldChar : CHAR; Log,Prn : FIO.File; Continue : PROC; LastClock : Timer.ClockRec; CRReceived : BOOLEAN; BuffPtr,HistPtr : CARDINAL; CBuffer : ARRAY[0..BuffSize-1] OF CHAR; Buffer : ARRAY[0..260] OF CHAR; History : ARRAY[0..MaxHistory] OF CHAR; (*................................................*) PROCEDURE Read(VAR c:CHAR); BEGIN IF ReadAgain THEN c:=OldChar; ReadAgain:=FALSE; RETURN; END; FuncKeyTyped := NotRecognised; c := IO.RdKey(); IF (c<>CHR(13)) AND ((c<' ') OR (c>'~')) THEN IF c=0C THEN c := IO.RdKey(); CASE ORD(c) OF 72 : FuncKeyTyped:=Cup; | 80 : FuncKeyTyped:=Cdown; | 75 : FuncKeyTyped:=Cleft; | 77 : FuncKeyTyped:=Cright; | 82 : FuncKeyTyped:=InsertKey; | 83 : FuncKeyTyped:=DeleteKey; | 15 : FuncKeyTyped:=BackTab; | 71 : FuncKeyTyped:=HomeKey; | 79 : FuncKeyTyped:=EndKey; | 73 : FuncKeyTyped:=PageUp; | 81 : FuncKeyTyped:=PageDown; | 59..68 : FuncKeyTyped:=FKey; c:=CHR(ORD(c)-58); | ELSE FuncKeyTyped:=AltKey; END; ELSIF c=CHR(8) THEN FuncKeyTyped := BackSpace; ELSIF c=3C THEN FuncKeyTyped := Etx; ELSIF c=CHR(27) THEN FuncKeyTyped := Escape; ELSIF c=CHR(127) THEN FuncKeyTyped := Del; ELSIF c=CHR(9) THEN FuncKeyTyped := Tab; END; END; END Read; (*........................................*) PROCEDURE TwoDigits(c:CARDINAL); BEGIN IO.WrChar(CHR((c DIV 10)+48)); IO.WrChar(CHR((c MOD 10)+48)); END TwoDigits; (*...............................................*) PROCEDURE StatusLine(which:StatusFields); VAR Drive,Ext : ARRAY[0..3] OF CHAR; Path : ARRAY[0..80] OF CHAR; Name : ARRAY[0..12] OF CHAR; BEGIN Window.Use(StatW); CASE which OF logo : Window.GotoXY(1,1); IO.WrStr(' JPI-Comms Toolkit 3.0 ³ ') | carrier : Window.GotoXY(26,1); IF RS232.CarrierDetect() THEN IO.WrStr('DCD ³ '); ELSE IO.WrStr(' ³ '); END; | script : Name:=''; IF ScriptFile[0]<>0C THEN IF Filenames.ParseFilename(ScriptFile,Drive,Path,Name,Ext) THEN Drive:=''; Path:=''; Filenames.MakeFilename(Drive,Path,Name,Ext,Name); END; END; Window.GotoXY(32,1); MPRINTF.PrintF1('%-12s ³ ',Name); | capture : Name:=''; Window.GotoXY(47,1); IF CaptureFile[0]<>0C THEN IF Filenames.ParseFilename(CaptureFile,Drive,Path,Name,Ext) THEN Drive:=''; Path:=''; Filenames.MakeFilename(Drive,Path,Name,Ext,Name); END; END; MPRINTF.PrintF1('%-12s ³ ',Name); | emul : Window.GotoXY(62,1); CASE Term.Emulation() OF Term.EmVT100 : IO.WrStr('VT100 ³ ') | Term.EmVT52 : IO.WrStr('VT52 ³ ') | Term.EmANSI : IO.WrStr('ANSI ³ ') | END; | time : IF LastClock.Seconds<>Timer.Clock.Seconds THEN Window.GotoXY(70,1); TwoDigits(Timer.Clock.Hours); IO.WrStr(':'); TwoDigits(Timer.Clock.Minutes); IO.WrStr('.'); TwoDigits(Timer.Clock.Seconds); END; | END; Window.Use(TermW); END StatusLine; (*................................................*) PROCEDURE CheckHistory(VAR s:ARRAY OF CHAR):BOOLEAN; VAR hc,c : CHAR; HistLnth,Lnth : CARDINAL; BEGIN Lnth := Str.Length(s); HistLnth:=HistPtr; IF (HistLnth0 DO DEC(Lnth); DEC(HistLnth); IF CAP(s[Lnth])<>CAP(History[HistLnth]) THEN RETURN(FALSE); END; END; HistPtr := 0; RETURN TRUE; END CheckHistory; (*.............................................*) PROCEDURE GetHistoryString(VAR s:ARRAY OF CHAR):CARDINAL; VAR Lnth : CARDINAL; BEGIN IF HistPtr>10 THEN Lnth:=10; ELSE Lnth:=HistPtr; END; Lib.Move(ADR(History[HistPtr-Lnth]),ADR(s),Lnth); s[Lnth] := 0C; HistPtr := 0; CRReceived := FALSE; RETURN Lnth; END GetHistoryString; (*.............................................*) PROCEDURE StoreHistory(c:CHAR); BEGIN IF HistPtr0C) AND (c<>CHR(26)) THEN IF c=CHR(8) THEN IF BuffPtr>0 THEN DEC(BuffPtr); END; IF HistPtr>0 THEN DEC(HistPtr); END; ELSE IF (c=CHR(10)) AND (LastC<>CHR(13)) THEN StoreChar(CHR(13)); END; StoreHistory(c); LastC := c; CBuffer[BuffPtr] := c; INC(BuffPtr); IF BuffPtr=BuffSize THEN IF LogMode=OpenLogging THEN FIO.WrBin(Log,CBuffer,HalfBuffer); END; Lib.Move(ADR(CBuffer[HalfBuffer]),ADR(CBuffer),HalfBuffer); BuffPtr := HalfBuffer; END; END; END; END StoreChar; (*................................................*) PROCEDURE FlushBuffer; BEGIN IF BuffPtr>0 THEN IF LogMode=OpenLogging THEN FIO.WrBin(Log,CBuffer,BuffPtr); END; BuffPtr := 0; END; END FlushBuffer; (*................................................*) PROCEDURE SetLogMode(Cmd:LogCommands); BEGIN CASE Cmd OF OpenLogging : IF LogMode=CloseLogging THEN Log := FIO.Open(CaptureFile); IF FIO.IOresult()=0 THEN FIO.Seek(Log,FIO.Size(Log)) ELSE Log := FIO.Create(CaptureFile) END; FlushBuffer; LogMode := OpenLogging; StatusLine(capture); END; | CloseLogging : IF LogMode<>CloseLogging THEN FlushBuffer; FIO.Close(Log); LogMode := CloseLogging; CaptureFile := ''; StatusLine(capture); END; | SuspendLogging : IF LogMode=OpenLogging THEN FlushBuffer; LogMode:=Cmd; END; | ResumeLogging : IF LogMode=SuspendLogging THEN FlushBuffer; LogMode:=OpenLogging; END; | END; END SetLogMode; (*................................................*) PROCEDURE Screen(Ch:CHAR); VAR i,oldx : CARDINAL; BEGIN oldx := Window.WhereX(); Ch := CHR(CARDINAL(BITSET(ORD(Ch))*BITSET(7FH))); StoreChar(Ch); IF Printing AND (Ch<>CHR(10)) THEN FIO.WrChar(Prn,Ch); END; WrChar(Ch); END Screen; (*................................................*) PROCEDURE Printer(OnOff:BOOLEAN); BEGIN IF OnOff THEN IF NOT Printing THEN Prn := FIO.Open('PRN:'); Printing:=TRUE; END ELSIF Printing THEN FIO.Close(Prn); Printing:=FALSE; END; END Printer; (*................................................*) PROCEDURE ErrorMessage(s:ARRAY OF CHAR); CONST EscapeMsg = ' - Press '; ErrTemplate = Window.WinDef(0,0,0,0,White,Red,TRUE,FALSE,FALSE,TRUE,Window.SingleFrame,White,Red); VAR c : CHAR; ErrWinDef : Window.WinDef; ErrWin : Window.WinType; x,y,Lnth : CARDINAL; BEGIN Lnth := Str.Length(s)+Str.Length(EscapeMsg)+4; x := Window.WhereX(); y := Window.WhereY(); Window.ConvertCoords(Window.Used(),x,y,x,y); IF x+Lnth>79 THEN x:=80-Lnth; END; IF y+3>23 THEN y:=21; END; ErrWinDef := ErrTemplate; ErrWinDef.Foreground := Colors.ErrFore; ErrWinDef.Background := Colors.ErrBack; ErrWinDef.FrameFore := Colors.ErrFrFore; ErrWinDef.FrameBack := Colors.ErrFrBack; WITH ErrWinDef DO X1:=x; Y1:=y; X2:=x+Lnth-1; Y2:=y+2; END; ErrWin := Window.Open(ErrWinDef); Window.GotoXY(2,1); IO.WrStr(s); IO.WrStr(EscapeMsg); c := IO.RdKey(); Window.Close(ErrWin); END ErrorMessage; (*................................................*) PROCEDURE SendString(s:ARRAY OF CHAR); VAR c : CHAR; i,p,Lnth : CARDINAL; BEGIN i:=0; p:=0; Lnth:=Str.Length(s); WHILE i='@') AND (c<='_') THEN c:=CHR(ORD(c)-64); END; ELSIF c='|' THEN c := CHR(13); ELSIF c='~' THEN IF p>0 THEN RS232.SerialWrite(FTSupport.FBuff,p); END; p:=0FFFFH; Lib.Delay(500); END; IF p=0FFFFH THEN p:=0; ELSE FTSupport.FBuff[p]:=c; INC(p); END; END; IF p>0 THEN RS232.SerialWrite(FTSupport.FBuff,p); END; END SendString; (*............................................*) PROCEDURE TransmitMacro(MacroNo:CARDINAL); BEGIN SendString(ComSetup.Setup.Macros[MacroNo]); END TransmitMacro; (*............................................*) PROCEDURE SelectFile(MenuX,MenuY:CARDINAL; Title,Wild:ARRAY OF CHAR;VAR f:ARRAY OF CHAR):INTEGER; TYPE ExtName = ARRAY[0..3] OF CHAR; VAR Menu : MenuLib.MenuRec; Result : INTEGER; Cnt,Base,Choice, MenuItems : INTEGER; List : ARRAY[0..99] OF FIO.PathTail; Ext : ARRAY[0..99] OF ExtName; Temp : ARRAY[0..14] OF CHAR; (*. . . . . . . . . . . . . . . . . . . . . . . . .*) PROCEDURE SortList; (* Ok, I know.. A horrible little bubblesort - good enough for this*) (* job though.. *) VAR i,Max : CARDINAL; Swapped : BOOLEAN; Temp : FIO.PathTail; BEGIN Max:=Cnt-1; Swapped:=TRUE; WHILE (Max>0) AND (Swapped) DO i:=0; Swapped:=FALSE; WHILE i0 THEN Temp:=List[i]; List[i]:=List[i+1]; List[i+1]:=Temp; Swapped := TRUE; END; INC(i); END; DEC(Max); END; END SortList; (*. . . . . . . . . . . . . . . . . . . . . . . . .*) PROCEDURE GetList(VAR Wild:ARRAY OF CHAR):CARDINAL; VAR Found,GotExt : BOOLEAN; i,Lnth,ExtLnth : CARDINAL; Entry : FIO.DirEntry; c : CHAR; BEGIN Cnt := 0; Found := FIO.ReadFirstEntry(Wild,FIO.FileAttr{},Entry); WHILE Found DO i:=0; GotExt:=FALSE; ExtLnth:=0; List[Cnt] := Entry.Name; Lnth := Str.Length(List[Cnt]); WHILE i0 THEN SortList; END; RETURN Cnt; END GetList; (*. . . . . . . . . . . . . . . . . . . . . . . . .*) PROCEDURE FillMenu; VAR i : INTEGER; BEGIN Menu.NumUsed := 0; i:=0; WHILE (Base+i0 THEN IF Cnt>8 THEN MenuItems:=8; ELSE MenuItems:=Cnt; END; Base:=0; MenuLib.InitMenu(Menu,Title,MenuX,MenuY,14); Menu.EscapeOK := TRUE; Menu.ExitOnChar := TRUE; Menu.PageKeysOK := (Cnt>8); FillMenu; MenuLib.DispMenu(Menu); LOOP Choice := MenuLib.MenuDrive(Menu); IF Choice>=0 THEN Filenames.MakeFilename('','',List[Base+Choice],Ext[Base+Choice],f); Result := Choice; EXIT; ELSIF (Choice=-2) THEN (* PageUp *) IF (Base>0) THEN IF Base>=8 THEN DEC(Base,8); ELSE Base:=0; END; FillMenu; MenuLib.RepaintMenu(Menu); END; ELSIF (Choice=-3) THEN (* PageDn *) IF (Base+8Cnt THEN Base:=Cnt-8; END; FillMenu; MenuLib.RepaintMenu(Menu); END; ELSE Result:=Choice; EXIT (* escape *) END; END; MenuLib.KillMenu(Menu); RETURN Result; ELSE RETURN -999; (* no files! *) END; END SelectFile; (*................................................*) PROCEDURE ReadLine(VAR s:ARRAY OF CHAR; Max:CARDINAL); VAR Ch : CHAR; Showit,FirstTime : BOOLEAN; cx,x,y,Lnth : CARDINAL; Temps : ARRAY[0..90] OF CHAR; BEGIN Lib.Fill(ADR(Temps),SIZE(Temps),' '); Lib.Move(ADR(s),ADR(Temps),Str.Length(s)); x:=Window.WhereX(); y:=Window.WhereY(); Lnth:=Str.Length(s); cx:=0; Showit:=TRUE; FirstTime:=TRUE; REPEAT IF Showit THEN Window.GotoXY(x,y); IO.WrStr(Temps); Showit := FALSE; END; IF cx>Lnth THEN cx:=Lnth END; Window.GotoXY(x+cx,y); Read(Ch); CASE FuncKeyTyped OF NotRecognised : IF (((Ch=' ') AND SpacesOK) OR ((Ch>' ') AND (Ch<='~'))) AND (cx0) THEN Lib.Fill(ADR(Temps),SIZE(Temps),' '); Lnth := 0; Showit := TRUE; END; IF cx0 THEN DEC(cx); END; | Cright : IF cx0 THEN Showit := TRUE; DEC(cx); Lib.Move(ADR(Temps[cx+1]),ADR(Temps[cx]),Max-cx-1); Temps[Max-1] := ' '; DEC(Lnth); END; | END; (* cases *) FirstTime := FALSE; UNTIL Ch = CHR(13); Temps[Lnth] := 0C; Lib.Move(ADR(Temps),ADR(s),Lnth+1); SpacesOK := FALSE; END ReadLine; (*.........................................................*) PROCEDURE PushBack(c:CHAR); BEGIN OldChar := c; ReadAgain := TRUE; END PushBack; (*.........................................................*) PROCEDURE ReadString(x,y:CARDINAL;Title,Prompt:ARRAY OF CHAR;VAR Result:ARRAY OF CHAR); VAR Def : Window.WinDef; Win : Window.WinType; BEGIN Def := Template; WITH Def DO X1:=x; Y1:=y; X2:=X1+69; Y2:=Y1+2; Foreground := Colors.PromptFore; Background := Colors.PromptBack; FrameFore := Colors.PromptFrFore; FrameBack := Colors.PromptFrBack; END; Win := Window.Open(Def); IF Title[0]<>0C THEN Window.SetTitle(Win,Title,Window.LeftUpperTitle); END; Window.TextColor(Colors.PromptFore); Window.GotoXY(1,1); IO.WrStr(Prompt); Window.TextColor(Colors.PromptHigh); ReadLine(Result,HIGH(Result)+1); Window.Close(Win); END ReadString; (*........................................*) PROCEDURE PrepareTransferMenu(VAR Menu:MenuLib.MenuRec; Download:BOOLEAN); VAR Title : ARRAY[0..20] OF CHAR; BEGIN IF Download THEN Title := 'Download Menu'; ELSE Title := 'Upload Menu'; END; MenuLib.InitMenu(Menu,Title,1,1,18); Menu.EscapeOK := TRUE; Menu.ExitOnChar := TRUE; IF NOT Download THEN MenuLib.AddOption(Menu,' A - ASCII '); END; MenuLib.AddOption(Menu,' X - Xmodem '); MenuLib.AddOption(Menu,' W - WXmodem '); MenuLib.AddOption(Menu,' Y - Ymodem '); MenuLib.AddOption(Menu,' B - Batch Ymodem '); MenuLib.AddOption(Menu,' K - Kermit '); IF Download THEN MenuLib.AddOption(Menu,' G - Ymodem-g '); END; MenuLib.DispMenu(Menu); END PrepareTransferMenu; (*................................................*) PROCEDURE DoUpload; VAR Selection : INTEGER; Result : CARDINAL; DoIt : BOOLEAN; Menu : MenuLib.MenuRec; BEGIN PrepareTransferMenu(Menu,FALSE); REPEAT Selection := MenuLib.MenuDrive(Menu); IF Selection<0 THEN DoIt := TRUE ELSE TransferFile[0]:=0C; ReadString(2,Selection+3,'',' File? ',TransferFile); DoIt := TransferFile[0]<>0C; END; UNTIL DoIt; MenuLib.KillMenu(Menu); CASE Selection OF -1 : (* escape *); | 0 : Result := FTSupport.ASCIISend(TransferFile); | 1 : Result := XModem.XModemSend(TransferFile); | 2 : Result := WXModem.WXModemSend(TransferFile); | 3 : Result := YModem.YModemSend(TransferFile); | 4 : Result := YModem.YModemBatchSend(TransferFile); | 5 : Result := Kermit.KermitSend(TransferFile); | END; END DoUpload; (*................................................*) PROCEDURE DoDownload; VAR Selection : INTEGER; Result : CARDINAL; DoIt : BOOLEAN; Menu : MenuLib.MenuRec; BEGIN PrepareTransferMenu(Menu,TRUE); REPEAT Selection := MenuLib.MenuDrive(Menu); IF Selection<0 THEN DoIt := TRUE; ELSE DoIt := TRUE; IF Selection<3 THEN TransferFile[0]:=0C; ReadString(2,Selection+3,'',' File? ',TransferFile); DoIt := TransferFile[0]<>0C; END; END; UNTIL DoIt; MenuLib.KillMenu(Menu); CASE Selection OF -1 : ; | 0 : Result := XModem.XModemReceive(TransferFile); | 1 : Result := WXModem.WXModemReceive(TransferFile); | 2 : Result := YModem.YModemReceive(TransferFile); | 3 : Result := YModem.YModemBatchReceive() | 4 : Result := Kermit.KermitReceive(); | 5 : Result := YModem.YModemGReceive() | END; END DoDownload; (*................................................*) PROCEDURE InitUtil; BEGIN (* Default IO routines *) WrChar := IO.WrChar; ScriptFile:=''; CaptureFile:=''; LogMode := CloseLogging; HistPtr := 0; BuffPtr := 0; Printing := FALSE; CRReceived := FALSE; LastClock.Seconds := 0FFFFH; LastC:=0C; END InitUtil; (*............................................*) PROCEDURE IsColor () : BOOLEAN ; VAR R : SYSTEM.Registers ; BEGIN R.AH := 15 ; Lib.Intr(R,10H) ; RETURN (R.AL <> 0)AND(R.AL<> 2)AND(R.AL <> 5)AND(R.AL <> 6)AND(R.AL <> 7) ; END IsColor ; CONST ColorColorDef = ColorDef(LightGray,Black, (* TermFore/Back *) White,Blue, (* StatFore/Back *) White,Blue, (* GenFore/Back *) White,Blue, (* GenFrFore/Back *) LightCyan,Black, (* PromptFore/Back *) Yellow, (* PromptHigh *) LightGray,Black, (* PromptFrFore/Back *) White,Red, (* ErrFore/Back *) White,Red, (* ErrFrFore/Back *) Yellow,Black, (* MacroFore/Back *) LightGray,Black, (* MacroFrFore/Back *) White,Blue, (* MacroHighFore/Back *) LightCyan,Black, (* MacroLowFore/Back *) LightCyan,Black, (* FTStatFore/Back *) LightGray,Black, (* FTStatFrFore/Back *) Yellow,Red, (* FTStatHigh/Bar *) LightCyan,Black, (* MenuFore/Back *) LightGray,Black, (* MenuFrFore/Back *) Yellow,Black, (* MenuHighFore/Back *) White,Blue, (* MenuSelFore/Back *) Yellow,Blue); (* MenuHSelFore/Back *) MonoColorDef = ColorDef(LightGray,Black, (* TermFore/Back *) Black,LightGray, (* StatFore/Back *) Black,LightGray, (* GenFore/Back *) White,Blue, (* GenFrFore/Back *) LightGray,Black, (* PromptFore/Back *) White, (* PromptHigh *) LightGray,Black, (* PromptFrFore/Back *) White,Black, (* ErrFore/Back *) White,Black, (* ErrFrFore/Back *) White,Black, (* MacroFore/Back *) LightGray,Black, (* MacroFrFore/Back *) Blue,Black, (* MacroHighFore/Back *) LightGray,Black, (* MacroLowFore/Back *) LightGray,Black, (* FTStatFore/Back *) LightGray,Black, (* FTStatFrFore/Back *) Yellow,Red, (* FTStatHigh/Bar *) White,Black, (* MenuFore/Back *) LightGray,Black, (* MenuFrFore/Back *) White,Black, (* MenuHighFore/Back *) Blue,Black, (* MenuSelFore/Back *) Blue,Black); (* MenuHSelFore/Back *) (*............................................*) PROCEDURE Alarm; VAR i : CARDINAL; BEGIN FOR i:=0 TO 7 DO Lib.Sound(300); Lib.Delay(50); Lib.NoSound; Lib.Delay(50); Lib.Sound(300); Lib.Delay(50); Lib.NoSound; Lib.Delay(300); END; END Alarm; (*...............................................*) BEGIN (* CommUtil *) IF IsColor() THEN Colors := ColorColorDef; ELSE Colors := MonoColorDef; END; WITH Colors DO MenuLib.MenuColors.NormFore := MenuFore; MenuLib.MenuColors.NormBack := MenuBack; MenuLib.MenuColors.FrameFore := MenuFrFore; MenuLib.MenuColors.FrameBack := MenuFrBack; MenuLib.MenuColors.HighFore := MenuHighFore; MenuLib.MenuColors.HighBack := MenuHighBack; MenuLib.MenuColors.SelFore := MenuSelFore; MenuLib.MenuColors.SelBack := MenuSelBack; MenuLib.MenuColors.HSelFore := MenuHSelFore; MenuLib.MenuColors.HSelBack := MenuHSelBack; END; SpacesOK := FALSE; ReadAgain := FALSE; END CommUtil. (*%E*) (*%T _OS2*) (* OS/2 version *) IMPORT ComSetup,Filenames,FIO,FTSupport,IO,Kermit,Lib,MenuLib,MPRINTF, RS232,ScriptProcessor,SPRINTF,Str,SYSTEM,Term,Timer,Vio,Window, WXModem,XModem,YModem; FROM Window IMPORT Color; FROM ScriptProcessor IMPORT ScriptStates; CONST BuffSize = 1024; MaxHistory = 128; Template = Window.WinDef(0,0,0,0,Yellow,Black,TRUE,FALSE,FALSE,TRUE,Window.SingleFrame,LightGray,Black); TYPE Addr = RECORD CASE :BOOLEAN OF TRUE : a : ADDRESS; | FALSE : Offset, Segment : CARDINAL; | END; END; VAR LastC,OldChar : CHAR; Log,Prn : FIO.File; Continue : PROC; LastClock : Timer.ClockRec; CRReceived : BOOLEAN; BuffPtr,HistPtr : CARDINAL; CBuffer : ARRAY[0..BuffSize-1] OF CHAR; Buffer : ARRAY[0..260] OF CHAR; History : ARRAY[0..MaxHistory] OF CHAR; (*................................................*) PROCEDURE Read(VAR c:CHAR); BEGIN IF ReadAgain THEN c:=OldChar; ReadAgain:=FALSE; RETURN; END; FuncKeyTyped := NotRecognised; c := IO.RdKey(); IF (c<>CHR(13)) AND ((c<' ') OR (c>'~')) THEN IF c=0C THEN c := IO.RdKey(); CASE ORD(c) OF 72 : FuncKeyTyped:=Cup; | 80 : FuncKeyTyped:=Cdown; | 75 : FuncKeyTyped:=Cleft; | 77 : FuncKeyTyped:=Cright; | 82 : FuncKeyTyped:=InsertKey; | 83 : FuncKeyTyped:=DeleteKey; | 15 : FuncKeyTyped:=BackTab; | 71 : FuncKeyTyped:=HomeKey; | 79 : FuncKeyTyped:=EndKey; | 73 : FuncKeyTyped:=PageUp; | 81 : FuncKeyTyped:=PageDown; | 59..68 : FuncKeyTyped:=FKey; c := CHR(ORD(c)-58); | ELSE FuncKeyTyped:=AltKey; END; ELSIF c=CHR(8) THEN FuncKeyTyped := BackSpace; ELSIF c=3C THEN FuncKeyTyped := Etx; ELSIF c=CHR(27) THEN FuncKeyTyped := Escape; ELSIF c=CHR(127) THEN FuncKeyTyped := Del; ELSIF c=CHR(9) THEN FuncKeyTyped := Tab; END; END; END Read; (*........................................*) PROCEDURE TwoDigits(c:CARDINAL); BEGIN IO.WrChar(CHR((c DIV 10)+48)); IO.WrChar(CHR((c MOD 10)+48)); END TwoDigits; (*...............................................*) PROCEDURE StatusLine(which:StatusFields); VAR Drive,Ext : ARRAY[0..3] OF CHAR; Path : ARRAY[0..80] OF CHAR; Name : ARRAY[0..12] OF CHAR; BEGIN Window.Use(StatW); CASE which OF logo : Window.GotoXY(1,1); IO.WrStr(' JPI-Comms Toolkit 3.0 ³ '); | carrier : Window.GotoXY(26,1); IF RS232.CarrierDetect() THEN IO.WrStr('DCD ³ '); ELSE IO.WrStr(' ³ '); END; | script : Name:=''; IF ScriptFile[0]<>0C THEN IF Filenames.ParseFilename(ScriptFile,Drive,Path,Name,Ext) THEN Drive:=''; Path:=''; Filenames.MakeFilename(Drive,Path,Name,Ext,Name); END; END; Window.GotoXY(32,1); MPRINTF.PrintF1('%-12s ³ ',Name); | capture : Name:=''; Window.GotoXY(47,1); IF CaptureFile[0]<>0C THEN IF Filenames.ParseFilename(CaptureFile,Drive,Path,Name,Ext) THEN Drive:=''; Path:=''; Filenames.MakeFilename(Drive,Path,Name,Ext,Name); END; END; MPRINTF.PrintF1('%-12s ³ ',Name); | emul : Window.GotoXY(62,1); CASE Term.Emulation() OF Term.EmVT100 : IO.WrStr('VT100 ³ '); | Term.EmVT52 : IO.WrStr('VT52 ³ '); | Term.EmANSI : IO.WrStr('ANSI ³ '); | END; | time : IF LastClock.Seconds<>Timer.Clock.Seconds THEN Window.GotoXY(70,1); TwoDigits(Timer.Clock.Hours); IO.WrStr(':'); TwoDigits(Timer.Clock.Minutes); IO.WrStr('.'); TwoDigits(Timer.Clock.Seconds); END; | END; Window.Use(TermW); END StatusLine; (*................................................*) PROCEDURE CheckHistory(VAR s:ARRAY OF CHAR):BOOLEAN; VAR hc,c : CHAR; HistLnth,Lnth : CARDINAL; BEGIN Lnth := Str.Length(s); HistLnth:=HistPtr; IF (HistLnth0 DO DEC(Lnth); DEC(HistLnth); IF CAP(s[Lnth])<>CAP(History[HistLnth]) THEN RETURN(FALSE); END; END; HistPtr := 0; RETURN TRUE; END CheckHistory; (*.............................................*) PROCEDURE GetHistoryString(VAR s:ARRAY OF CHAR):CARDINAL; VAR Lnth : CARDINAL; BEGIN IF HistPtr>10 THEN Lnth:=10; ELSE Lnth:=HistPtr; END; Lib.Move(ADR(History[HistPtr-Lnth]),ADR(s),Lnth); s[Lnth] := 0C; HistPtr := 0; CRReceived := FALSE; RETURN Lnth; END GetHistoryString; (*.............................................*) PROCEDURE StoreHistory(c:CHAR); BEGIN IF HistPtr0C) AND (c<>CHR(26)) THEN IF c=CHR(8) THEN IF BuffPtr>0 THEN DEC(BuffPtr); END; IF HistPtr>0 THEN DEC(HistPtr); END; ELSE IF (c=CHR(10)) AND (LastC<>CHR(13)) THEN StoreChar(CHR(13)); END; StoreHistory(c); LastC := c; CBuffer[BuffPtr] := c; INC(BuffPtr); IF BuffPtr=BuffSize THEN IF LogMode=OpenLogging THEN FIO.WrBin(Log,CBuffer,HalfBuffer); END; Lib.Move(ADR(CBuffer[HalfBuffer]),ADR(CBuffer),HalfBuffer); BuffPtr := HalfBuffer; END; END; END; END StoreChar; (*................................................*) PROCEDURE FlushBuffer; BEGIN IF BuffPtr>0 THEN IF LogMode=OpenLogging THEN FIO.WrBin(Log,CBuffer,BuffPtr); END; BuffPtr := 0; END; END FlushBuffer; (*................................................*) PROCEDURE SetLogMode(Cmd:LogCommands); BEGIN CASE Cmd OF OpenLogging : IF LogMode=CloseLogging THEN Log := FIO.Open(CaptureFile); IF FIO.IOresult()=0 THEN FIO.Seek(Log,FIO.Size(Log)) ELSE Log := FIO.Create(CaptureFile) END; FlushBuffer; LogMode := OpenLogging; StatusLine(capture); END; | CloseLogging : IF LogMode<>CloseLogging THEN FlushBuffer; FIO.Close(Log); LogMode := CloseLogging; CaptureFile := ''; StatusLine(capture); END; | SuspendLogging : IF LogMode=OpenLogging THEN FlushBuffer; LogMode:=Cmd END; | ResumeLogging : IF LogMode=SuspendLogging THEN FlushBuffer; LogMode:=OpenLogging END; | END; END SetLogMode; (*................................................*) PROCEDURE Screen(Ch:CHAR); VAR i,oldx : CARDINAL; BEGIN oldx := Window.WhereX(); Ch := CHR(CARDINAL(BITSET(ORD(Ch))*BITSET(7FH))); StoreChar(Ch); IF Printing AND (Ch<>CHR(10)) THEN FIO.WrChar(Prn,Ch); END; WrChar(Ch); END Screen; (*................................................*) PROCEDURE Printer(OnOff:BOOLEAN); BEGIN IF OnOff THEN IF NOT Printing THEN Prn := FIO.Open('PRN:'); Printing:=TRUE END ELSIF Printing THEN FIO.Close(Prn); Printing:=FALSE; END; END Printer; (*................................................*) PROCEDURE ErrorMessage(s:ARRAY OF CHAR); CONST EscapeMsg = ' - Press '; ErrTemplate = Window.WinDef(0,0,0,0,Window.White,Window.Red,TRUE,FALSE,FALSE,TRUE,Window.SingleFrame,Window.White,Window.Red); VAR c : CHAR; ErrWinDef : Window.WinDef; ErrWin : Window.WinType; x,y,Lnth : CARDINAL; BEGIN Lnth := Str.Length(s)+Str.Length(EscapeMsg)+4; x := Window.WhereX(); y := Window.WhereY(); Window.ConvertCoords(Window.Used(),x,y,x,y); IF x+Lnth>79 THEN x:=80-Lnth; END; IF y+3>23 THEN y:=21; END; ErrWinDef := ErrTemplate; ErrWinDef.Foreground := Colors.ErrFore; ErrWinDef.Background := Colors.ErrBack; ErrWinDef.FrameFore := Colors.ErrFrFore; ErrWinDef.FrameBack := Colors.ErrFrBack; WITH ErrWinDef DO X1:=x; Y1:=y; X2:=x+Lnth-1; Y2:=y+2; END; ErrWin := Window.Open(ErrWinDef); Window.GotoXY(2,1); IO.WrStr(s); IO.WrStr(EscapeMsg); c := IO.RdKey(); Window.Close(ErrWin); END ErrorMessage; (*................................................*) PROCEDURE SendString(s:ARRAY OF CHAR); VAR c : CHAR; i,p,Lnth : CARDINAL; BEGIN i:=0; p:=0; Lnth:=Str.Length(s); WHILE i='@') AND (c<='_') THEN c:=CHR(ORD(c)-64); END; ELSIF c='|' THEN c := CHR(13); ELSIF c='~' THEN IF p>0 THEN RS232.SerialWrite(FTSupport.FBuff,p); END; p:=0FFFFH; Lib.Delay(500); END; IF p=0FFFFH THEN p:=0 ELSE FTSupport.FBuff[p]:=c; INC(p) END; END; IF p>0 THEN RS232.SerialWrite(FTSupport.FBuff,p); END; END SendString; (*............................................*) PROCEDURE TransmitMacro(MacroNo:CARDINAL); BEGIN SendString(ComSetup.Setup.Macros[MacroNo]); END TransmitMacro; (*............................................*) PROCEDURE SelectFile(MenuX,MenuY:CARDINAL; Title,Wild:ARRAY OF CHAR;VAR f:ARRAY OF CHAR):INTEGER; TYPE ExtName = ARRAY[0..3] OF CHAR; VAR Menu : MenuLib.MenuRec; Result : INTEGER; Cnt,Base,Choice, MenuItems : INTEGER; List : ARRAY[0..99] OF FIO.PathTail; Ext : ARRAY[0..99] OF ExtName; Temp : ARRAY[0..14] OF CHAR; (*. . . . . . . . . . . . . . . . . . . . . . . . .*) PROCEDURE SortList; (* Ok, I know.. A horrible little bubblesort - good enough for this job though.. *) VAR i,Max : CARDINAL; Swapped : BOOLEAN; Temp : FIO.PathTail; BEGIN Max:=Cnt-1; Swapped:=TRUE; WHILE (Max>0) AND (Swapped) DO i:=0; Swapped:=FALSE; WHILE i0 THEN Temp:=List[i]; List[i]:=List[i+1]; List[i+1]:=Temp; Swapped := TRUE; END; INC(i); END; DEC(Max); END; END SortList; (*. . . . . . . . . . . . . . . . . . . . . . . . .*) PROCEDURE GetList(VAR Wild:ARRAY OF CHAR):CARDINAL; VAR Found,GotExt : BOOLEAN; i,Lnth,ExtLnth : CARDINAL; Entry : FIO.DirEntry; c : CHAR; BEGIN Cnt := 0; Found := FIO.ReadFirstEntry(Wild,FIO.FileAttr{},Entry); WHILE Found DO i:=0; GotExt:=FALSE; ExtLnth:=0; List[Cnt] := Entry.Name; Lnth := Str.Length(List[Cnt]); WHILE i0 THEN SortList; END; RETURN Cnt; END GetList; (*. . . . . . . . . . . . . . . . . . . . . . . . .*) PROCEDURE FillMenu; VAR i : INTEGER; BEGIN Menu.NumUsed := 0; i:=0; WHILE (Base+i0 THEN IF Cnt>8 THEN MenuItems:=8; ELSE MenuItems:=Cnt; END; Base:=0; MenuLib.InitMenu(Menu,Title,MenuX,MenuY,14); Menu.EscapeOK := TRUE; Menu.ExitOnChar := TRUE; Menu.PageKeysOK := (Cnt>8); FillMenu; MenuLib.DispMenu(Menu); LOOP Choice := MenuLib.MenuDrive(Menu); IF Choice>=0 THEN Filenames.MakeFilename('','',List[Base+Choice],Ext[Base+Choice],f); Result := Choice; EXIT ELSIF (Choice=-2) THEN (* PageUp *) IF (Base>0) THEN IF Base>=8 THEN DEC(Base,8); ELSE Base:=0; END; FillMenu; MenuLib.RepaintMenu(Menu); END ELSIF (Choice=-3) THEN (* PageDn *) IF (Base+8Cnt THEN Base:=Cnt-8; END; FillMenu; MenuLib.RepaintMenu(Menu); END ELSE Result:=Choice; EXIT; (* escape *) END; END; MenuLib.KillMenu(Menu); RETURN Result ELSE RETURN -999 (* no files! *) END; END SelectFile; (*................................................*) PROCEDURE ReadLine(VAR s:ARRAY OF CHAR; Max:CARDINAL); VAR Ch : CHAR; Showit,FirstTime : BOOLEAN; cx,x,y,Lnth : CARDINAL; Temps : ARRAY[0..90] OF CHAR; BEGIN Lib.Fill(ADR(Temps),SIZE(Temps),' '); Lib.Move(ADR(s),ADR(Temps),Str.Length(s)); x := Window.WhereX(); y := Window.WhereY(); Lnth:=Str.Length(s); cx:=0; Showit:=TRUE; FirstTime:=TRUE; REPEAT IF Showit THEN Window.GotoXY(x,y); IO.WrStr(Temps); Showit := FALSE; END; IF cx>Lnth THEN cx:=Lnth; END; Window.GotoXY(x+cx,y); Read(Ch); CASE FuncKeyTyped OF NotRecognised : IF (((Ch=' ') AND SpacesOK) OR ((Ch>' ') AND (Ch<='~'))) AND (cx0) THEN Lib.Fill(ADR(Temps),SIZE(Temps),' '); Lnth := 0; Showit := TRUE; END; IF cx0 THEN DEC(cx); END; | Cright : IF cx0 THEN Showit := TRUE; DEC(cx); Lib.Move(ADR(Temps[cx+1]),ADR(Temps[cx]),Max-cx-1); Temps[Max-1] := ' '; DEC(Lnth); END; | END; (*CASE*) FirstTime := FALSE; UNTIL Ch = CHR(13); Temps[Lnth] := 0C; Lib.Move(ADR(Temps),ADR(s),Lnth+1); SpacesOK := FALSE; END ReadLine; (*.........................................................*) PROCEDURE PushBack(c:CHAR); BEGIN OldChar := c; ReadAgain := TRUE; END PushBack; (*.........................................................*) PROCEDURE ReadString(x,y:CARDINAL; Title,Prompt:ARRAY OF CHAR;VAR Result:ARRAY OF CHAR); VAR Def : Window.WinDef; Win : Window.WinType; BEGIN Def := Template; WITH Def DO X1:=x; Y1:=y; X2:=X1+69; Y2:=Y1+2; Foreground := Colors.PromptFore; Background := Colors.PromptBack; FrameFore := Colors.PromptFrFore; FrameBack := Colors.PromptFrBack; END; Win := Window.Open(Def); IF Title[0]<>0C THEN Window.SetTitle(Win,Title,Window.LeftUpperTitle); END; Window.TextColor(Colors.PromptFore); Window.GotoXY(1,1); IO.WrStr(Prompt); Window.TextColor(Colors.PromptHigh); ReadLine(Result,HIGH(Result)+1); Window.Close(Win); END ReadString; (*........................................*) PROCEDURE PrepareTransferMenu(VAR Menu:MenuLib.MenuRec; Download:BOOLEAN); VAR Title : ARRAY[0..20] OF CHAR; BEGIN IF Download THEN Title := 'Download Menu' ELSE Title := 'Upload Menu' END; MenuLib.InitMenu(Menu,Title,1,1,18); Menu.EscapeOK := TRUE; Menu.ExitOnChar := TRUE; IF NOT Download THEN MenuLib.AddOption(Menu,' A - ASCII '); END; MenuLib.AddOption(Menu,' X - Xmodem '); MenuLib.AddOption(Menu,' W - WXmodem '); MenuLib.AddOption(Menu,' Y - Ymodem '); MenuLib.AddOption(Menu,' B - Batch Ymodem '); MenuLib.AddOption(Menu,' K - Kermit '); IF Download THEN MenuLib.AddOption(Menu,' G - Ymodem-g '); END; MenuLib.DispMenu(Menu); END PrepareTransferMenu; (*................................................*) PROCEDURE DoUpload; VAR Selection : INTEGER; Result : CARDINAL; DoIt : BOOLEAN; Menu : MenuLib.MenuRec; BEGIN PrepareTransferMenu(Menu,FALSE); REPEAT Selection := MenuLib.MenuDrive(Menu); IF Selection < 0 THEN DoIt := TRUE ELSE TransferFile[0]:=0C; ReadString(2,Selection+3,'',' File? ',TransferFile); DoIt := TransferFile[0] # 0C; END; UNTIL DoIt; MenuLib.KillMenu(Menu); CASE Selection OF -1 : (* escape *); | 0 : Result := FTSupport.ASCIISend(TransferFile); | 1 : Result := XModem.XModemSend(TransferFile); | 2 : Result := WXModem.WXModemSend(TransferFile); | 3 : Result := YModem.YModemSend(TransferFile); | 4 : Result := YModem.YModemBatchSend(TransferFile); | 5 : Result := Kermit.KermitSend(TransferFile); | END; END DoUpload; (*................................................*) PROCEDURE DoDownload; VAR Selection : INTEGER; Result : CARDINAL; DoIt : BOOLEAN; Menu : MenuLib.MenuRec; BEGIN PrepareTransferMenu(Menu,TRUE); REPEAT Selection := MenuLib.MenuDrive(Menu); IF Selection<0 THEN DoIt := TRUE ELSE DoIt := TRUE; IF Selection<3 THEN TransferFile[0]:=0C; ReadString(2,Selection+3,'',' File? ',TransferFile); DoIt := TransferFile[0]<>0C; END; END; UNTIL DoIt; MenuLib.KillMenu(Menu); CASE Selection OF -1 : ; | 0 : Result := XModem.XModemReceive(TransferFile); | 1 : Result := WXModem.WXModemReceive(TransferFile); | 2 : Result := YModem.YModemReceive(TransferFile); | 3 : Result := YModem.YModemBatchReceive() | 4 : Result := Kermit.KermitReceive(); | 5 : Result := YModem.YModemGReceive() | END; END DoDownload; (*................................................*) PROCEDURE InitUtil; BEGIN (* Default IO routines *) WrChar := IO.WrChar; ScriptFile:=''; CaptureFile:=''; LogMode := CloseLogging; HistPtr := 0; BuffPtr := 0; Printing := FALSE; CRReceived := FALSE; LastClock.Seconds := 0FFFFH; LastC:=0C; END InitUtil; (*............................................*) PROCEDURE IsColor () : BOOLEAN ; VAR m : Vio.MODEINFO; r : CARDINAL; BEGIN m.b := SIZE(m); r := Vio.GetMode(m,0); RETURN NOT (2 IN BITSET(m.type)); END IsColor ; CONST ColorColorDef = ColorDef(LightGray,Black,White,Blue,White,Blue,White,Blue,LightCyan,Black,Yellow,LightGray,Black,White,Red, White,Red,Yellow,Black,LightGray,Black,White,Blue,LightCyan,Black,LightCyan,Black,LightGray,Black, Yellow,Red,LightCyan,Black,LightGray,Black,Yellow,Black,White,Blue,Yellow,Blue); MonoColorDef = ColorDef(LightGray,Black,Black,LightGray,Black,LightGray,Black,LightGray,LightGray,Black,White,LightGray, Black,White,Black,White,Black,White,Black,LightGray,Black,Blue,Black,LightGray,Black,LightGray, Black,LightGray,Black,White,Black,LightGray,Black,LightGray,Black,White,Black,Blue,Black,Blue,Black); (*...............................................*) PROCEDURE Alarm; VAR i : CARDINAL; BEGIN FOR i:=0 TO 7 DO Lib.Speaker(300,50); Lib.Delay(50); Lib.Speaker(300,50); Lib.Delay(300); END; END Alarm; (*...............................................*) BEGIN (* CommUtil *) IF IsColor() THEN Colors := ColorColorDef ELSE Colors := MonoColorDef END; WITH Colors DO MenuLib.MenuColors.NormFore := MenuFore; MenuLib.MenuColors.NormBack := MenuBack; MenuLib.MenuColors.FrameFore := MenuFrFore; MenuLib.MenuColors.FrameBack := MenuFrBack; MenuLib.MenuColors.HighFore := MenuHighFore; MenuLib.MenuColors.HighBack := MenuHighBack; MenuLib.MenuColors.SelFore := MenuSelFore; MenuLib.MenuColors.SelBack := MenuSelBack; MenuLib.MenuColors.HSelFore := MenuHSelFore; MenuLib.MenuColors.HSelBack := MenuHSelBack; END; SpacesOK := FALSE; ReadAgain := FALSE; END CommUtil. (*%E*)