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