home *** CD-ROM | disk | FTP | other *** search
- program iterm;
-
- { Scott Murphy
- 77 So. Adams St. #301
- Denver, CO 80209
- Compuserve 70156,263 }
-
- Const
- VERSION = '1.5';
- SAVE_BUF_SIZE = 2048; {size of text save buffer}
- BELL_FREQ = 440; {frequncy for bell sound}
- BELL_DELAY = 100; {duration of bell sound}
- DEFAULT_BAUD = 1200; {Serial port speed at start-up}
-
- type
- bigstring = string[80]; {general purpose}
- cset = set of 0..127;
- var
- SaveText : 0..1; {flag for saving text to disk}
- SaveOpen : boolean; {flag for open textsave file}
- SaveBuffer : array[1..SAVE_BUF_SIZE] of char;
- SavePtr : integer;
- SaveFile : file of char;
- DiscardSet : set of 0..127;
- exit,
- xtnd : boolean;
- a : byte;
- c,i : integer;
- PrevLine : string[40];
- CurrLine : string[40];
- LineIndex : integer;
- ch : char;
-
- {$C-}
-
-
- {$I ITRMPORT.INC}
- {$I ITRMMISC.INC}
- {$I ITRMWIND.INC}
-
- (******** ITRMXFER.INC ********)
- const
- SOH = 1; {Start Of Header}
- EOT = 4; {End Of Transmission}
- ACK = 6; {ACKnowledge}
- NAK = $15; {Negative AcKnowledge}
- CAN = $18; {CANcel}
- MAXERRS = 10; {Maximum allowed errors}
- L = 0;
- H = 1;
- type
- bytevec130 = array[1..133] of byte;
-
- {*** variables used as globals in this source segment
- (actually global to whole source) ***}
- var
- checksum : byte;
- sector : bytevec130;
- fname : bigstring;
- response : string[1];
- f : stream;
- crcval,db,sb : integer;
- p : parity_set;
-
- procedure purge;
- begin
- while cgetc(1) <> -1 do
- ;
- end;
-
- procedure ShowCrt(sec, try, tot : integer);
- type
- str3 = string[3];
- var
- i : integer;
-
- function ToString(n : integer) : str3;
- var
- s : str3;
- begin
- str(n,s);
- ToString := s
- end;
- begin
- status(0,concat('Blk:', ToString(sec),
- ' Try:', ToString(try){,
- ' Errs:', ToString(tot)}))
- end;
-
-
- procedure updcrc(a : byte);
- begin
- inline( $8A/$46/$04/ {MOV AL,[BP+04]}
- $8B/$1E/crcval/ {MOV BX,crcval}
- $B9/$08/$00/ {MOV CX,0008}
- {loop0} $D0/$E0/ {SHL AL,1}
- $D1/$D3/ {RCL BX,1}
- $73/$04/ {JNC loop1}
- $81/$F3/$21/$10/ {XOR BX,$1021}
- {loop1} $E2/$F4/ {LOOP loop0}
- $89/$1E/crcval) {MOV crcval,BX}
- end;
-
- procedure SaveCommStatus;
- begin
- p := parity;
- db := dbits;
- sb := stop_bits;
- dbits := 8;
- parity := none;
- stop_bits := 1;
- update_uart
- end;
-
- procedure recv_wcp;
- {receive a file using Ward Christensen's checksum protocol}
- label
- 99;
- var
- j, firstchar, sectnum, sectcurr,
- toterr, errors, sectcomp : integer;
- ErrorFlag : boolean;
- begin
- status(2, 'RECV XMODEM');
- ErrorFlag := TRUE;
- SaveCommStatus;
- OpenTemp(1,3,80,8,2);
- repeat
- write('Enter a filename for download file (<cr> to abort): ');
- readln(fname);
- supcase(fname);
- if length(fname) > 0 then
- if exists(fname) then
- begin
- write(fname, ' Exists. OK to overwrite it (Y/N)? ');
- readln(response);
- if upcase(response) = 'Y' then
- ErrorFlag := FALSE;
- end
- else ErrorFlag := FALSE
- until (not ErrorFlag) or (length(fname) = 0);
- CloseTemp;
- if length(fname) > 0 then
- f := fopen(fname,'w');
- if length(fname) = 0 then
- writeln(#13,#10,'ITERM --- user aborted receive.')
- else if f = NIL then
- writeln(#13,#10,'ITERM --- could not open ',fname, ' Aborting receive.');
- if (f = NIL) or (length(fname) = 0) then
- goto 99;
- writeln('Ready to receive ', fname);
- sectnum := 0;
- errors := 0;
- toterr := 0;
- ShowCrt(0,0,0);
- send(ord('C')); {request CRC}
- repeat
- ErrorFlag := FALSE;
- repeat
- firstchar := cgetc(10)
- until (firstchar = SOH) or (firstchar = EOT) or (firstchar = -1);
- if firstchar = -1 then
- ErrorFlag := TRUE;
- if firstchar = SOH then
- begin
- sectcurr := cgetc(1);
- sectcomp := cgetc(1);
- if (sectcurr + sectcomp) = 255 then
- begin
- if sectcurr = (sectnum + 1) then
- begin
- crcval := 0;
- checksum := 0;
- for j := 1 to 128 do
- begin
- sector[j] := cgetc(1);
- updcrc(sector[j]);
- checksum := checksum + sector[j]
- end;
- sector[129] := cgetc(1);
- sector[130] := cgetc(1);
- updcrc(sector[129]);
- updcrc(sector[130]);
- if crcval = 0 then
- begin
- send(ACK);
- errors := 0;
- sectnum := sectcurr;
- ShowCrt(sectnum, errors, toterr);
- for j := 1 to 128 do
- write(f^,sector[j])
- end
- else
- ErrorFlag := TRUE
- end
- else
- if sectcurr = sectnum then
- begin
- purge;
- send(ACK)
- end
- else
- ErrorFlag := TRUE
- end
- else
- ErrorFlag := TRUE
- end;
- if ErrorFlag then
- begin
- errors := errors + 1;
- if sectnum > 0 then
- toterr := succ(toterr);
- purge;
- ShowCrt(sectnum, errors, toterr);
- send(NAK)
- end
- until (firstchar = EOT) or (errors = MAXERRS);
- if (firstchar = EOT) and (errors < MAXERRS) then
- begin
- send(ACK);
- close(f^);
- dispose(f);
- writeln('DONE.')
- end
- else begin
- send(CAN);
- writeln('ABORTING: Error limit exceeded or unrecoverable error.');
- close(f^);
- erase(f^);
- dispose(f)
- end;
- 99:
- status(0,' ');
- status(2,'On-Line/Ready');
- dbits := db;
- parity := p;
- stop_bits := sb;
- update_uart;
- end;
-
- procedure SendAscii;
- var
- f : stream;
- b : byte;
- fname : bigstring;
- c : integer;
- begin
- OpenTemp(10,5,60,12,2);
- repeat
- Write('Filename to transmit? ');
- readln(fname);
- f := fopen(fname, 'r');
- if f = NIL then
- begin
- Writeln('Can''t open: ',fname);
- WriteLn('Please try a different spelling, drive or disk.');
- WriteLn
- end
- until (f <> NIL) or (Length(fname) = 0);
- CloseTemp;
- if f <> NIL then
- begin
- Status(0,'Sending ASCII');
- OpenTemp(1,3,80,20,1);
- b := 0;
- while (not eof(f^)) and (b <> 26)do
- begin
- read(f^,b);
- if (b <> 26) and (b <> 10) then
- begin
- send(b);
- c := cgetc(1);
- if c = 19 then
- while cgetc(0) <> 17 do ;
- if c <> -1 then
- write(chr(c and $7F));
- if c = 13 then
- writeln
- end
- end;
- CloseTemp;
- close(f^);
- dispose(f);
- Status(0,' ')
- end
- end;
-
- procedure send_wcp;
- Label
- 99;
- Var
- UserKey : char;
- c, sectnum, errors : integer;
- bflag : boolean;
-
- function ReadBlock : integer;
- Var
- i, j : integer;
- begin
- FillChar(sector, 133, ^Z);
- sector[1] := SOH;
- sector[2] := sectnum;
- sector[3] := 255 - sectnum;
- crcval := 0;
- i := 4;
- while (not eof(f^)) and (i < 132) do
- begin
- read(f^, sector[i]);
- updcrc(sector[i]);
- i := succ(i)
- end;
- for j := i to 131 do
- updcrc(sector[j]);
- updcrc(0); updcrc(0);
- sector[132] := hi(crcval);
- sector[133] := lo(crcval);
- ReadBlock := i - 4
- end;
-
- procedure SendBlock;
- Var i : integer;
- begin
- for i := 1 to 133 do
- send(sector[i])
- end;
-
- begin
- status(2, 'SEND XMODEM');
- SaveCommStatus;
- OpenTemp(1,3,80,8,2);
- repeat
- write('Enter a filename for upload file (<cr> to abort): ');
- readln(fname);
- supcase(fname);
- if length(fname) > 0 then
- begin
- bflag := exists(fname);
- if not bflag then
- begin
- writeln('Could not open file ',fname);
- writeln('(Spelling or drive designation wrong?)');
- writeln
- end
- end
- until bflag or (length(fname) = 0);
- CloseTemp;
- if length(fname) = 0 then
- goto 99;
- f := fopen(fname,'r');
- writeln(^M, ^J, 'Transmitting file: ',fname);
- writeln(LongFileSize(f^):6:0,' bytes, ',int(LongFileSize(f^)/133.0)+1:4:0,' Blocks');
- writeln('Approximate time to send:',
- (int(LongFileSize(f^)/133.0)+1)*22.1666667/speed:6:2,
- ' minutes at',speed:5,' bps.');
- sectnum := 1;
- errors := 0;
- ShowCrt(0,0,0);
- UserKey := #0;
- repeat
- c := cgetc(1);
- if keypressed then read(kbd, UserKey)
- until (c <> -1) or (UserKey = ^X);
- if UserKey = ^X then goto 99;
- UserKey := #0;
- purge;
- while (ReadBlock > 0) and (errors <= MAXERRS) do
- begin
- errors := 0;
- repeat
- ShowCrt(sectnum, errors, 0);
- SendBlock;
- repeat
- c := cgetc(0);
- if KeyPressed then read(kbd,UserKey);
- until (c <> -1) or (UserKey = ^X);
- if UserKey = ^X then goto 99;
- if c = ACK then
- sectnum := sectnum + 1
- else
- errors := errors + 1
- until (c = ACK) or (errors = MAXERRS)
- end;
- errors := 0;
- repeat
- send(EOT);
- repeat
- c := cgetc(10);
- if KeyPressed then read(kbd,UserKey);
- until (c <> -1) or (UserKey = ^X);
- if UserKey = ^X then goto 99;
- if c = NAK then errors := errors + 1
- until (c = ACK) or (errors = MAXERRS);
- 99:
- close(f^);
- dispose(f);
- if UserKey = ^X then
- begin
- WriteLn(^M,^J,'Cancelling transmission of ',fname, ' at your request');
- repeat
- send(CAN);
- purge
- until cgetc(1) = -1
- end;
- status(0,' ');
- status(2,'On-Line/Ready');
- dbits := db;
- parity := p;
- stop_bits := sb;
- update_uart
- end;
-
- (******** END ITERMXFER.INC **********)
-
- {$I ITRMDIAL.INC}
- {$I ITRMSAVE.INC}
-
-
- begin
- ClrScr;
- InitWindow(StatWin,1,1,80,2);
- InitWindow(TermWin,1,3,80,25);
- CurrentWin := TermWin;
- UsePermWindow(TermWin);
- status(1,'ITERM ver: ' + VERSION);
- status(2,'Initializing');
- CurrLine := '';
- PrevLine := '';
- LineIndex := 1;
- SaveText := 0;
- SaveOpen := FALSE;
- SavePtr := 1;
- DiscardSet := [];
- InitPhn;
- setup;
- set_up_recv_buffer;
- remove_port;
- setup;
- set_up_recv_buffer;
- exit := false;
- GotoXY(1,1);
- status(2,'Off-Line/Ready');
- while not exit do
- begin
- if keypressed then
- begin
- scan(xtnd, a);
- if xtnd then
- case a of
- 19 : {alt-R}
- recv_wcp;
- 45 : {alt-X}
- begin
- OpenTemp(20,18,60,22,1);
- writeln('───ITERM───');
- write('Do you really want to exit (Y/N)? ');
- readln(ch);
- if upcase(ch) = 'Y' then
- exit := TRUE;
- CloseTemp
- end;
- 67 : {F9}
- begin
- SaveText := 1 - SaveText;
- if SaveText = 1 then
- begin
- Status(3, 'Text save: ON');
- if not SaveOpen then
- InitSaveFile
- end
- else
- Status(3, 'Text Save: OFF')
- end;
- 68 : {F10}
- if SaveOpen then
- begin
- SaveOpen := FALSE;
- SaveText := 0;
- status(3,'Closing save file');
- for i := 1 to SavePtr do
- write(SaveFile, SaveBuffer[i]);
- close(SaveFile);
- Status(3, 'Text Save: OFF')
- end;
- 31 : {alt-S}
- send_wcp;
- 32 : {alt-D}
- auto_dial;
- 35 : {alt-H}
- begin
- writeln('───ITERM───');
- status(2,'Disconnecting');
- term_ready(FALSE);
- delay(500);
- term_ready(TRUE);
- status(2,'Off-Line/Ready')
- end;
- 46 : {alt-C}
- ClrScr;
- 48 : {alt-B}
- break;
- 25 : {alt-P}
- NewParms;
- 59 : {F1}
- if phones[CurPhone].paced then
- SendPaced(phones[CurPhone].id + #13)
- else
- StrSend(phones[CurPhone].id + #13);
- 60 : {F2}
- if phones[CurPhone].paced then
- SendPaced(phones[CurPhone].pw + #13)
- else
- StrSend(phones[CurPhone].pw + #13);
- 61 : {F3}
- SendPaced(PrevLine);
- 77 : {Cursor Right}
- begin
- if LineIndex <= length(PrevLine) then
- send(ord(PrevLine[LineIndex]));
- LineIndex := LineIndex + 1
- end;
- 72 : {Cursor up}
- PushPage;
- 80 : {Cursor Down}
- PopPage;
- 65 : {F7}
- SendAscii;
- end {case}
- else if a = 13 then
- begin
- PrevLine := CurrLine;
- Currline := '';
- LineIndex := 1;
- send(a)
- end
- else
- begin
- CurrLine := CurrLine + chr(a);
- send(a)
- end
- end; {if KeyPressed}
- c := cgetc(0);
- if not (c in DiscardSet) then
- case c of
- -1 : begin
- end; {no action}
- 9 : {tab}
- begin
- for c := WhereX to (WhereX div 8 + 1)*8 do
- write(' ');
- c := 9
- end;
- 7 : {bell}
- begin
- sound(BELL_FREQ);
- delay(BELL_DELAY);
- NoSound
- end;
- 12 : {form-feed}
- ClrScr;
- else write(chr(c and $7F));
- end; {case}
- if (c <> -1) and (SaveText = 1) and (not (c in DiscardSet)) then
- DiskBuffer(chr(c));
- end; {while not exit}
- remove_port;
- if cflag then
- begin
- status(3,'Updating ITERM.PHN');
- rewrite(phfile);
- for c := 1 to MAXPHONES do
- write(phfile, phones[c]);
- close(phfile)
- end;
- if SaveOpen then
- begin
- status(3,'Closing save file');
- for i := 1 to SavePtr do
- write(SaveFile, SaveBuffer[i]);
- close(SaveFile)
- end
- end.