program soft2; { 2.0A 11/8/86 } { Full screen save to scrolling buffer - control characters now mapped } { to grave hex 60. } { Bug fix to CTRLN from user line - theuser now set false before keystrokes } { echoed to SOFTfsm. } { ZSLOOP set from DOS time routine so only one version for IBM PCs } { 2.0-B 17 Nov 1986 see CL40:SOFT-2.0-B } const {$I ISO.CST } {$I SOFT.CST } {$I SSMP.CST } { WARNING -- the following eight strings extend beyond column 80 } titlemsg = ' SOFT 2.2 :: '; {2.0E} copymsg = ' Copyright (C) 1987, The University of Newcastle upon Tyne, England '; {2.0B+} blankmsg = ' '; help1msg = ' To enter terminal mode : ESC "0" (or RETURN) '; help2msg = ' To change the settings : Use the arrow keys (or ^H, ^J, ^K, ^L) '; help3msg = ' To exit from this program : ESC "6" '; help4msg = ' To save settings to disk : ESC "8" '; help5msg = ' To restore default settings : ESC "9" '; maxfield = 6; { Number of user settable fields in SETUP mode } { The following re-ordered for version 2.1 3/3/1987 } iterm = 1; { Index for base terminal type SOFT or ANSI } ipause = 2; { " " auto-pause switch } isave = 3; { " " full screen mode (SSMP) save } ilog = 4; { " " log device : off, file or printer } ipad = 5; { " " PAD type auto, JNT, X28 or other } ispeed = 6; { " " line speed : default or 300 - 9600 } padcol = 0; padtop = 19; padbottom= 23; maxstack = 5; { stacked terminal types (up to 4), plus 1 } type {$I ISO.TYP } {$I HARDWARE.TYP } {$I SOFT.TYP } {$I SSMP.TYP } rawfile = file of byte; {DOS} configtype = array [1..maxfield] of byte; keytype = array [character] of character; stacktype = 1..maxstack; setuptype = record {DOS} F : character; {DOS} P : configtype; {DOS} S1, S2, S3, S4, S5 : string30; {DOS} Q : keytype {DOS} end; {DOS} setfiletype = file of setuptype; {DOS} btext = file of byte; {DOS} { ****** Global variables local to module SOFT2 ****** } var logf : btext; { Text file to write logged data to } {DOS} ftemp : rawfile; { File of bytes for chain to TNX } {DOS} chaintnx : boolean; { TRUE => chain to TEKtronix graphics } {DOS} cmdline : string[35]; { Command line on invocation of SOFT } {DOS} times : word; { Soft timer for reading receive buffer} {DOS} setupfile : setfiletype; { Record to contain setup configuration} {DOS} keymap : keytype; { Array of key assignments for SOFT } oldilog, { Previous log device code (to close it) } padset : byte; { PAD type set by SETUP or PAD.PAS } maxcode, { Array of maximum code values for config } codes : configtype; { Current code values for configuration } softflag, { Flag for first entry to SOFT } junk, { JUNK variable for unused function results } logon, { Logging device on / off } cmdsdisplayed : boolean; { Flag if PAD commands already displayed } padbreak, { PAD command to send a break } bgnsession, { PAD command to start SSMP session } endsession, { PAD command to end SSMP session } bgnframe, { PAD command to start SSMP frame } endframe : string30; { PAD command to end SSMP frame } setupflag : boolean; { Flag for entry to SETUP } termtype : zeustype; { The current terminal type } termpointer : stacktype; { Pointer to next free position in } termstack : array [stacktype] of zeustype; { stack of terminal types } resume : boolean; { TRUE => can resume an SSMP session } { ********** PROCEDURES DECLARED IN OTHER MODULES ********** } {$I DRIVERS.EXT } {$I ISO6429.EXT } {$I SSMP.EXT } {$I SOFT.EXT } {$I PAD.EXT } { ********** PROCEDURES SHARED WITH OTHER MODULES ********** } {#PUBLIC TRMTYP -- Returns zeustype for driver module } function TRMTYP : zeustype; begin TRMTYP := termtype end; {#PUBLIC chainsoft -- true if command line present on SOFT } function chainsoft : boolean; begin chainsoft := false; chainsoft := length(cmdline) <> 0 {DOS} end; { firstsoft } {#PUBLIC firstsoft -- true on first call from soft } function firstsoft : boolean; begin firstsoft := softflag; softflag := false end; { firstsoft } {#PUBLIC NEWTERMINAL -- Set a new terminal type, stack previous type } procedure NEWTERMINAL(t : zeustype); { t sets new terminal type } begin termstack[termpointer] := termtype; { Stack current type } termpointer := termpointer + 1; termtype := t { New terminal type } end; { NEWTERMINAL } {#PUBLIC OLDTERMINAL -- Unstack previous terminal type } procedure OLDTERMINAL(var t : zeustype); { t set to old terminal type } begin if (termpointer > 1) then begin termpointer := termpointer - 1; t := termstack[termpointer] { Flag to calling module } end else t := typeSOFT; { Drop off stack => SOFT } termtype := t { Flag to THIS module } end; { OLDTERMINAL } {#PUBLIC SETRESUME -- set flag to allow resumption of SSMP session } procedure SETRESUME(t : boolean); { t TRUE => can resume SSMP session } begin resume := t end; { SETRESUME } {#PUBLIC ENQRESUME -- test resume setting for SSMP session } function ENQRESUME : boolean; { TRUE if SSMP session can be resumed } begin ENQRESUME := resume end; { ENQRESUME } {#PUBLIC PUTC -- send a character to the serial line } procedure PUTC(c : character); { c : character to send } begin repeat until ZLRDY; ZLPUT(c) end; { PUTC } {#PUBLIC SENDSTRING -- send a string to the host } procedure SENDSTRING(s : string30); { s : string to send, ~ terminates } var i : smallint; c : character; ctrl : boolean; begin i := 1; ctrl := false; c := ord(s[i]); while (c <> TILDE) do begin if ctrl then begin { Wait mod for v 2.1 } if (c >= DIG0) and (c <= DIG9) then ZSWAIT(100*(c-DIG0)) else begin if (c = GREATER) then c := TILDE else if (c >= CAPA) and (c <= CAPZ) then c := c - 64 else if (c >= LETA) and (c <= LETZ) then c := c - 96; putc(c) end; ctrl := false end else begin if (c = CARET) then ctrl := true else putc(c) end; i := i + 1; c := ord(s[i]) end end; { SENDSTRING } {#PUBLIC TXBGNSESSION -- send the echo off comand string to PAD } procedure TXBGNSESSION; var c : character; begin SENDSTRING(bgnsession) end; { TXBGNSESSION } {#PUBLIC TXENDSESSION -- send the echo on command string to PAD } procedure TXENDSESSION; begin SENDSTRING(endsession) end; { TXENDSESSION } {#PUBLIC TXBGNFRAME -- send the start of frame string to PAD } procedure TXBGNFRAME; begin SENDSTRING(bgnframe) end; {TXBGNFRAME } {#PUBLIC TXENDFRAME -- send the end of frame string to PAD } procedure TXENDFRAME; begin SENDSTRING(endframe) end; {TXENDFRAME } {#PUBLIC TXPADBREAK -- send the defined break string to PAD } procedure TXPADBREAK; begin {2.0B+} if (padbreak[1] = '~') then ZLBRK else SENDSTRING(padbreak); ZSWAIT(100) end; { TXPADBREAK } {#PUBLIC PUTSTR -- display a string on the screen } procedure PUTSTR(s : string30); { s : string to display, ~ terminates } var i : word; displaying : boolean; begin i := 1; displaying := true; while displaying do begin if (ord(s[i]) <> TILDE) then ZSPUT(ord(s[i])) else displaying := false; if (i < 30) then i := i + 1 else displaying := false end end; { PUTSTR } {#PUBLIC autopad -- TRUE for autopad recognition } function autopad : boolean; begin autopad := (codes[ipad] = 1) end; { autopad } {#PUBLIC autopuase -- TRUE for auto pausing } function autopause : boolean; begin autopause := (codes[ipause] = 2) end; { autopause } {#PUBLIC logchar -- Writes c to log device if global logon is true } procedure logchar(c : character); begin { if (c = SHARP) then c := POUND; Special for office } if logon and (codes[ilog] <> 1) then write(logf,c) {DOS} end; { logchar } {#PUBLIC logging -- TRUE if logon } function logging : boolean; begin logging := logon {logging := false for systems without log device } end; { logging } {#PUBLIC copytobuffer -- true if want to copyscreen to scrolling buffer } function copytobuffer : boolean; begin copytobuffer := (codes[isave] = 1) end; { copytobuffer } {#PUBLIC lastinsetup -- true if last in setup mode } function lastinsetup : boolean; begin lastinsetup := setupflag; setupflag := false end; { lastinsetup } {#PUBLIC setpadcmds -- Loads various PAD specific commands for SSMP } procedure setpadcmds(pad : smallint); { pad : identifies PAD type } begin case pad of 0, 1 : begin { JNT-PAD } bgnsession := '~ '; endsession := '~ '; bgnframe := '^PE~ '; endframe := '~ '; padbreak := '^PB~ ' end; 2 : begin { X.28-PAD } bgnsession := '^PSET 2:0^M~ '; endsession := '^PSET 2:1^M~ '; bgnframe := '~ '; endframe := '~ '; padbreak := '^PINT^M~ ' end; 3 : begin { NUNET } bgnsession := '^PSSMP=ON^M~ '; endsession := '^PSSMP=OFF^M~ '; bgnframe := '~ '; endframe := '~ '; padbreak := '^PAB^M~ ' { 2.1 } end; 4 : begin { DIRECT } bgnsession := '~ '; endsession := '~ '; bgnframe := '~ '; endframe := '~ '; padbreak := '~ ' end end { case }; if (pad = 0) then padbreak := '^PAB^M~ '; padset := pad end; { setpadcmds } {#PUBLIC setprint -- set print logging on or off } procedure setprint(var printcode : byte; onoff : boolean); begin if (printcode >= 1) and (printcode <= maxcode[ilog]) then {DOS} codes[ilog] := printcode; {DOS} {DOS} logon := onoff; {DOS} if (codes[ilog] <> oldilog) then {DOS} begin {DOS} case codes[ilog] of {DOS} 1 : close(logf); {DOS} 2 : begin {DOS} if (oldilog <> 1) then close(logf); {DOS} assign(logf,'PRN'); {DOS} rewrite(logf) {DOS} end; {DOS} 3 : begin {DOS} if (oldilog <> 1) then close(logf); {DOS} assign(logf,'SOFT.LOG'); {DOS} append(logf) {DOS} end {DOS} end { case ilog }; {DOS} oldilog := codes[ilog] {DOS} end; {DOS} printcode := codes[ilog] {DOS} end; { setprint } {#PUBLIC fkeymap -- function does same job as array mapping } function fkeymap(keycode : character) : character; begin fkeymap := keymap[keycode] end; {#PUBLIC fmapkey -- function does inverse array mapping } function fmapkey(keycode : character) : character; var key : character; found, notthere : boolean; begin key := 0; found := false; notthere := false; repeat if (keymap[key] = keycode) then found := true else if (key < 255) then key := key + 1 else notthere := true until found or notthere; if found then fmapkey := key else fmapkey := 0 end; { **************** END OF SHARED PROCEDURES ******************* } { readstr -- read string from keyboard, simple editing, terminates ~ } procedure readstr(var s : string30; var c : character); { s : string result, ~ terminates } var i : smallint; stopping, new : boolean; oldcol : coltype; begin oldcol := ZSCOL; new := false; stopping := false; i := 1; repeat repeat ZSUPDT(false) until ZKDATA; c := ZKGET; if (c > 127) then c := c - 128; if ((c = CTRLH) or (c = DEL)) and (i > 1) then begin ZSGOXY(ZSCOL-1,ZSROW); ZSPUT(BLANK); ZSGOXY(ZSCOL-1,ZSROW); i := i - 1 end else if (c = CTRLX) or (c = CTRLU) then begin new := true; ZSGOXY(ZSCOL-i+1,ZSROW); ZSWIN(0,65,0,maxrow); ZSERAL; s := ' '; i := 1 end else if (c >= BLANK) and (c < DEL) then begin if not new then begin ZSERAL; new := true end; s[i] := chr(c); ZSPUT(ord(s[i])); i := i + 1 end else stopping := true until stopping; { 2.0-B truncate trailing blanks off pad strings } if new then begin if (i > 1) then i := i - 1; while (i > 1) and (s[i] = ' ') do i := i - 1; { Find last non-blank } if ((i > 1) or (s[1] <> ' ')) { Empty string } and (i < 30) then i := i + 1; { String too long } s[i] := chr(TILDE) end end; { readstr } { dispadsmds -- display the current PAD command strings } procedure dispadcmds; begin junk := ZSSETG(DEFAULTREND); ZSGOXY(padcol,padtop); PUTSTR('Session start sequence : ~ '); putstr(bgnsession); ZSGOXY(padcol,padtop+1); PUTSTR('Session end sequence : ~ '); putstr(endsession); ZSGOXY(padcol,padtop+2); PUTSTR('Frame start sequence : ~ '); putstr(bgnframe); ZSGOXY(padcol,padtop+3); PUTSTR('Frame end sequence : ~ '); putstr(endframe); ZSGOXY(padcol,padtop+4); { Must <= padbottom } PUTSTR('PAD break sequence : ~ '); putstr(padbreak); cmdsdisplayed := true end; { dispadcmds } { erapadcmds -- erase the currently displayed PAD commands from screen } procedure erapadcmds; var row : rowtype; begin if cmdsdisplayed then begin ZSWIN(padcol,padcol+65,padtop,padbottom); {2.0C} junk := ZSSETG(DEFAULTREND); ZSCLR; { 2.1 } cmdsdisplayed := false; ZSWIN(0,maxcol,0,maxrow); {2.0C} end end; { erapadcmds } { getpadcmds -- read in new set of PAD commands } procedure getpadcmds; var n : byte; c : character; begin junk := ZSSETG(DEFAULTREND); ZSWIN(padcol,padcol+65,padtop,padbottom); {2.0C} n := 1; repeat ZSGOXY(padcol+26,18+n); case n of 1 : readstr(bgnsession,c); 2 : readstr(endsession,c); 3 : readstr(bgnframe,c); 4 : readstr(endframe,c); 5 : readstr(padbreak,c) end; { case } if (c = CTRLK) then n := n - 1 else if (c = CTRLJ) or (c = CTRLM) then n := n + 1 until (n < 1) or (n > 5); {2.0B} ZSWIN(0,maxcol,0,maxrow); {2.0C} end; { getpadcmds } { setdefaults -- set defaults vaules for soft terminal configuration } procedure setdefaults; var key : character; begin { Default settings } codes[ipause] := 1; { Auto pause } codes[isave] := 1; { SSMP copy } codes[ilog] := 1; { NOLOG } codes[iterm] := 1; { SOFT type } codes[ipad] := 1; { Auto PAD } codes[ispeed] := 1; { NOCHANGE } setpadcmds(4); {2.0C} for key := 0 to 255 do keymap[key] := key { Defaults 1 - 1 } end; { setdefaults } procedure readconfig; {DOS} var setupitem : setuptype; {DOS} begin {DOS} if not EOF(setupfile) then {DOS} begin {DOS} read(setupfile,setupitem); {DOS} if (setupitem.F = CTRLZ) then {DOS} begin {DOS} with setupitem do {DOS} begin {DOS} codes := P; {DOS} bgnsession := S1; {DOS} endsession := S2; {DOS} bgnframe := S3; {DOS} endframe := S4; {DOS} padbreak := S5; {DOS} keymap := Q {DOS} end {DOS} end {DOS} end; {DOS} close(setupfile) {DOS} end; { readconfig } {DOS} { getconfig -- read in configuration file for soft terminal if possible } procedure getconfig; begin setdefaults; { In case setup file not present } if fstat('SOFTSET.$$$') then {DOS} begin {DOS} assign(setupfile,'SOFTSET.$$$'); {DOS} reset(setupfile); {DOS} readconfig; {DOS} if (codes[iterm] = 1) then newterminal(typeSOFT) else {DOS} if (codes[iterm] = 2) then newterminal(typeISO6429); {DOS} erase(setupfile) { dispose of temporary file } {DOS} end else {DOS} if fstat('\SOFT.SET') then {DOS} begin {DOS} assign(setupfile,'\SOFT.SET'); {DOS} reset(setupfile); {DOS} readconfig {DOS} end {DOS} {2.2} end; { getconfig } { writeconfig -- write soft terminal configuration to file } procedure writeconfig(filename : string); {DOS} var setupitem : setuptype; {DOS} begin {DOS} assign(setupfile,filename); {DOS} rewrite(setupfile); {DOS} with setupitem do {DOS} begin {DOS} F := CTRLZ; {DOS} P := codes; {DOS} S1 := bgnsession; {DOS} S2 := endsession; {DOS} S3 := bgnframe; {DOS} S4 := endframe; {DOS} S5 := padbreak; {DOS} Q := keymap {DOS} end; {DOS} write(setupfile,setupitem); {DOS} close(setupfile) {DOS} end; { writeconfig } {DOS} { SETUP -- terminal setup procedure } procedure SETUP; var oldfield, field, code, device : byte; c : character; col : coltype; speed : integer; finished, ok : boolean; hasgr : highlight; termtype : zeustype; name : string10; { dispsetting -- display field and code by highlighting or pointing } procedure dispsetting(field, code : byte; onoff, format : boolean); const head = 11; var line : byte; begin if (code = 0) then line := head else line := head + 1 + code; ZSGOXY((field-1)*13,line); if format or (hasgr <> CONCEALED) then begin if onoff and (hasgr <> CONCEALED) then junk := ZSSETG(hasgr) else junk := ZSSETG(DEFAULTREND); case field of iterm : case code of 0 : putstr(' EMULATOR ~ '); 1 : putstr(' SOFT ~ '); 2 : putstr(' ISO6429 ~ '); 3 : putstr(' TNX ~ ') end { case 3 }; ipause : case code of 0 : putstr(' PAUSING ~ '); 1 : putstr(' NOPAUSE ~ '); 2 : putstr(' PAUSE ~ ') end { case 1 }; isave : case code of 0 : putstr(' FS IMAGE ~ '); 1 : putstr(' NOERASE ~ '); 2 : putstr(' ERASE ~ ') end { case 2 }; ilog : case code of 0 : putstr(' LOGGING ~ '); 1 : putstr(' NOLOG ~ '); 2 : putstr(' PRINTER ~ '); 3 : putstr(' SOFT.LOG ~ ') end { case ilog }; ipad : case code of 0 : putstr(' PAD TYPE ~ '); 1 : putstr(' AUTO ~ '); 2 : putstr(' JNT-PAD ~ '); 3 : putstr(' X.28 ~ '); 4 : putstr(' DIRECT ~ '); 5 : putstr(' HOLD ~ '); 6 : putstr(' SET ~ ') end { case 4 }; ispeed : case code of 0 : putstr(' SPEED ~ '); 1 : putstr(' NOCHANGE ~ '); 2 : putstr(' 9600 ~ '); 3 : putstr(' 4800 ~ '); 4 : putstr(' 2400 ~ '); 5 : putstr(' 1200 ~ '); 6 : putstr(' 600 ~ '); 7 : putstr(' 300 ~ '); 8 : putstr(' 75/1200 ~ ') end { case 5 }; end { outer case } end; { else } if (hasgr = CONCEALED) then begin ZSGOXY((field-1)*13,line); if onoff then ZSPUT(GREATER) else ZSPUT(BLANK) end else end; { dispsetting } { printat -- display string on given row } procedure printat(row : rowtype; s : string80); var col : coltype; begin ZSGOXY(0,row); for col := 0 to 79 do ZSPUT(ord(s[col+1])) end; { printat } { formatscreen -- display the fields and settings for first time } procedure formatscreen; var tfield, tcode : byte; begin erapadcmds; { In case still displayed, the rest is overwritten } for tfield := 1 to maxfield do for tcode := 0 to maxcode[tfield] do if (tcode = codes[tfield]) then dispsetting(tfield,tcode,true,true) else dispsetting(tfield,tcode,false,true); if codes[ipad] = maxcode[ipad]-1 { HOLD } then dispadcmds; {2.1 moved} oldfield := 1; field := 1; code := codes[field]; dispsetting(field,0,true,false); dispsetting(field,codes[field],true,false) end; { formatscreen } begin { main body of procedure SETUP } junk := ZKSETK(KCSRUP,CTRLK); junk := ZKSETK(KCSRDOWN,CTRLJ); junk := ZKSETK(KCSRLEFT,CTRLH); junk := ZKSETK(KCSRRIGHT,CTRLL); cmdsdisplayed := false; maxcode[ipause] := 2; maxcode[isave] := 2; maxcode[ilog] := 1; maxcode[ilog] := 3; {DOS} maxcode[iterm] := 2; maxcode[iterm] := 3; {DOS} maxcode[ipad] := 6; if ZLSPD(75,1200,false) { Test if 75/1200 available } then maxcode[ispeed] := 8 else maxcode[ispeed] := 7; setupflag := true; termtype := typeSETUP; if ZSSETG(NEGATIVEIMAGE) then hasgr := NEGATIVEIMAGE else if ZSSETG(BOLD) then hasgr := BOLD else if ZSSETG(UNDERSCORED) then hasgr := UNDERSCORED else hasgr := CONCEALED; ZSWIN(0,maxcol,0,maxrow); junk := ZSSETG(DEFAULTREND); ZSCLR; ZSTITL(blankmsg); { Blank out top line i.e. 25 th line if present } junk := ZSSETG(BOLD); printat(0,titlemsg); ZDESC(name); ZSGOXY(41,0); for col := 1 to 10 do ZSPUT(ord(name[col])); junk := ZSSETG(DEFAULTREND); printat(1,copymsg); ZSGOXY(0,2); for col := 0 to maxcol do ZSPUT(UNDERLINE); printat(4,help1msg); printat(5,help2msg); printat(6,help3msg); printat(7,help4msg); printat(8,help5msg); formatscreen; repeat { until SETUP achieved } ok := true; { Must assume true in case can't set speed from SOFT } finished := false; repeat { until user has finished } if (field <> oldfield) then begin dispsetting(oldfield,0,false,false); oldfield := field; dispsetting(field,0,true,false); dispsetting(field,codes[field],true,false) end else if (code <> codes[field]) then begin dispsetting(field,codes[field],false,false); codes[field] := code; dispsetting(field,codes[field],true,false) end; repeat until ZKDATA; c := ZKGET; { To test the timing loop for ZSWAIT } if (c = CTRLG) then begin ZSWAIT(10000); ZSBELL end else if (c = CTRLM) then finished := true else if (c = ESC) then begin repeat until ZKDATA; c := ZKGET; if (c = DIG6) then begin oldterminal(termtype); finished := true end else if (c = DIG8) then writeconfig('\SOFT.SET') else {DOS} {2.2} if (c = DIG9) then begin getconfig; { 2.1 setdefaults; } formatscreen end else if (c = DIG0) then finished := true end; if (c = CTRLH) then begin if (field > 1) then field := field - 1 else field := maxfield; code := codes[field] end else if (c = CTRLL) then begin if (field < maxfield) then field := field + 1 else field := 1; code := codes[field] end else if (c = CTRLJ) then begin if (code < maxcode[field]) then code := code + 1 else code := 1 end else if (c = CTRLK) then begin if (code > 1) then code := code - 1 else code := maxcode[field] end; if (field = ipad) then begin if (code = (maxcode[ipad]-1)) then dispadcmds { HOLD } else if (code = maxcode[ipad]) then { SET } begin dispadcmds; { Display the setting before going to read new PAD cmds } dispsetting(field,codes[field],false,false); codes[field] := code; dispsetting(field,codes[field],true,false); getpadcmds; { Read in the new PAD commands } code := code - 1 { Back to HOLD setting for PAD } end else erapadcmds end until finished; if (termtype <> typeEXIT) then begin device := codes[ilog]; setprint(device,logging); case codes[ispeed] of 1 : { NOCHANGE }; 2 : ok := ZLSPD(9600,9600,true); 3 : ok := ZLSPD(4800,4800,true); 4 : ok := ZLSPD(2400,2400,true); 5 : ok := ZLSPD(1200,1200,true); 6 : ok := ZLSPD(600,600,true); 7 : ok := ZLSPD(300,300,true); 8 : ok := ZLSPD(75,1200,true) end; case codes[ipad] of 1 : setpadcmds(0); { Auto PAD defaults } 2 : setpadcmds(1); { JNT PAD selected } 3 : setpadcmds(2); { PSS PAD selected } 4 : setpadcmds(4); { DIRECT PAD selected } 5 : ; { Leave settings } 6 : codes[ipad] := 5 { And leave set next time } end; if ok then begin { get ready for terminal emulator mode } case codes[iterm] of 1 : begin termtype := typeSOFT; newterminal(termtype) end; 2 : begin termtype := typeISO6429; newterminal(termtype) end; 3 : begin if fstat('TNX.EXE') then termtype := typeTNX else {DOS} if fstat('A:TNX.EXE')then termtype := typeTNX; {DOS} if (termtype = typeTNX) then newterminal(termtype) end end; { case } ZSWIN(0,maxcol,0,maxrow); junk := ZSSETG(DEFAULTREND); ZSCLR end else ZSBELL end until ok end; { SETUP } { init -- Call procedures to initialise environment } procedure init; var name : string30; begin ZSINIT; ZKINIT; ZLINIT end; { init } { finish -- Call procedures to restore previous environment } procedure finish; begin ZLEND; ZKEND; ZSEND end; { finish } begin { Body of module SOFT2.PAS } chaintnx := false; { Default is no chain } {DOS} getcomm(cmdline); { Read in command line } {DOS} termpointer := 1; { Stack pointer for terminals } termtype := typeEXIT; { Bottom of stack is EXIT } newterminal(typeSETUP); { Default enter SETUP mode } getconfig; { Defaults from file } softflag := true; oldilog := 1; logon := false; init; { Initialise driver code } ZLXCTL(true); { Enable X-on X-off code } psetmode(KRESTART,QUESTION); junk := ZKSETK(KRESTART,QUESTION); psetmode(KSUSPEND,GREATER); junk := ZKSETK(KSUSPEND,GREATER); psetmode(KINTHOST,EXCLAM); junk := ZKSETK(KINTHOST,EXCLAM); initkeybuffer; {2.0C} { These code segments could be overlayed } repeat case termtype of typeSOFT : SOFT; { Scroll buffer, line re-entry etc. } typeTRANST : ISO6429; { Identify with ISO6429 on PCs } typeISO6429 : ISO6429; { Subset ISO6429 terminal + some VT100 } typeSSMP : SSMP; { SSMP terminal emulator } typeSETUP : SETUP; { Contained within this module } typeEXIT : ; { The End! } typeTNX : begin {DOS} chaintnx := true; {DOS} termtype := typeEXIT {DOS} end {DOS} end { case }; { If NUNET PAD discovered set the padbreak string back to ^PAB } { NB PAD type not reset to AUTO because SSMP session re-entry } { Would then lose the PAD type. } if (padset = 3) then padbreak := '^PAB^M~ ' until (termtype = typeEXIT); softexit; { Zap the buffers maintained by module SOFT } if chaintnx then {DOS} begin {DOS} assign(ftemp,'ZLDATA.$$$'); {DOS} rewrite(ftemp); {DOS} times := 0; {DOS} repeat {DOS} if ZLDATA then {DOS} begin {DOS} write(ftemp,ZLGET); {DOS} times := 0 {DOS} end else times := times + 1 {DOS} until (times > 10000); {DOS} close(ftemp); {DOS} writeconfig('SOFTSET.$$$') {DOS} end; {DOS} junk := ZSSETG(DEFAULTREND); {2.0A+} ZSCLR; {2.0A+} finish; if chaintnx then {DOS} begin {DOS} if fstat('TNX.EXE') then chain('TNX.EXE SOFT.EXE') else {DOS} if fstat('A:TNX.EXE') then chain('A:TNX.EXE SOFT.EXE') {DOS} end {DOS} end. { SOFT2 Module }