home *** CD-ROM | disk | FTP | other *** search
- (*$R-,V-,S-*)
-
-
- CONST
- progname : STRING = ''; { the name of the main program - 14 chars max }
- seatalk: BOOLEAN = TRUE; { display of messages toggle }
- rawblk: INTEGER = 0;
- ackless : INTEGER = 0;
-
- TYPE
- zeros = RECORD
- flen,
- fstamp: LONGINT;
- fnam: ARRAY[0..16] OF BYTE;
- prog: ARRAY[0..14] OF BYTE;
- noacks: BYTE;
- fill: ARRAY[0..86] OF BYTE
- END;
- secbuf = ARRAY[0..127] OF BYTE;
-
- VAR
- outblk, ackblk, blksnt, ackst, ackrep,
- numnak, chktec, toterr, slide, ackseen: INTEGER;
- starttime, endtime: LONGINT;
-
- CONST
- crctab: ARRAY[0..255] OF WORD =(
- $0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7,
- $8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef,
- $1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6,
- $9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de,
- $2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485,
- $a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d,
- $3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4,
- $b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc,
- $48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823,
- $c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b,
- $5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12,
- $dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a,
- $6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41,
- $edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49,
- $7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70,
- $ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78,
- $9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f,
- $1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067,
- $83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e,
- $02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256,
- $b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d,
- $34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405,
- $a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c,
- $26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634,
- $d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab,
- $5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3,
- $cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a,
- $4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92,
- $fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9,
- $7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1,
- $ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8,
- $6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0
- );
-
- FUNCTION Com_GetC(tenths: INTEGER): INTEGER;
-
- VAR
- n: INTEGER;
-
- BEGIN
- tenths := (tenths DIV 10);
- Async_Receive_With_Timeout(tenths,n);
- IF (n >= 256) THEN
- Com_GetC := -1
- ELSE
- Com_GetC := (n AND $00FF)
- END;
-
- PROCEDURE Com_PutC(b: BYTE);
-
- BEGIN
- Async_Send(Chr(b))
- END;
-
- PROCEDURE Com_Flush;
-
- BEGIN
- Async_Flush_Output_Buffer
- END;
-
- FUNCTION Com_Peek: INTEGER;
-
- BEGIN
- Com_Peek := Ord(Async_Peek(0))
- END;
-
- FUNCTION UpdCrc(cp: BYTE; crc: INTEGER): INTEGER;
- BEGIN
- UpdCrc := (crctab[((crc SHR 8) AND 255)] XOR (crc SHL 8) XOR cp)
- END;
-
-
- PROCEDURE Message(s: STRING; n: INTEGER);
-
- BEGIN
- WRITE(#13,'SeaLink - ',s:25);
- IF (n >= 0) THEN
- WRITE(' [ ',n:3,' ] ')
- ELSE
- WRITE('':9)
- END;
-
- FUNCTION FromAsciiZ(VAR a): STRING;
-
- VAR
- s: STRING;
- ar: ARRAY[0..255] OF CHAR ABSOLUTE a;
- p: WORD;
-
- BEGIN
- p := 0;
- WHILE (ar[p] <> #0) AND (p <= 255) DO
- BEGIN
- s[p+1] := ar[p];
- Inc(p)
- END;
- s[0] := Chr(p);
- FromAsciiZ := s
- END;
-
- PROCEDURE ToAsciiZ(VAR a; s: STRING; maxlen: INTEGER);
-
- VAR
- ar: ARRAY[0..255] OF CHAR ABSOLUTE a;
- p: WORD;
-
- BEGIN
- IF (maxlen < 0) THEN
- maxlen := 0;
- IF (maxlen > 255) THEN
- maxlen := 255;
- IF (Length(s) > maxlen) THEN
- s[0] := Chr(maxlen);
- FillChar(ar,maxlen,0);
- Move(s[1],ar[0],Length(s))
- END;
-
- FUNCTION TimerSet(tenths: INTEGER): LONGINT;
-
- VAR
- h,m,s,hn: WORD;
-
- BEGIN
- GetTime(h,m,s,hn);
- TimerSet := (LONGINT(h)*36000)+(LONGINT(m)*600)+(LONGINT(s)*10)+(LONGINT(tenths))+(LONGINT(hn) DIV 10)
- END;
-
- FUNCTION TimeUp(time: LONGINT): BOOLEAN;
-
- BEGIN
- TimeUp := (TimerSet(0) >= time)
- END;
-
- PROCEDURE AckChk;
-
- VAR
- c: INTEGER;
-
- BEGIN
- ackrep := 0;
- c := Com_GetC(20);
- WHILE (c >= 0) DO
- BEGIN
- IF (KeyPressed) THEN
- IF (ReadKey IN [^[,^X]) THEN
- BEGIN
- numnak := 50;
- Exit
- END;
- IF (ackst = 3) OR (ackst = 4) THEN
- BEGIN
- slide := 0;
- IF (rawblk = (c XOR $FF)) THEN
- BEGIN
- rawblk := outblk - ((outblk - rawblk) AND $FF);
- IF (rawblk >= 0) AND (rawblk <= outblk) AND (rawblk > outblk - 128) THEN
- BEGIN
- IF (ackst = 3) THEN
- BEGIN
- IF (ackblk <= rawblk) THEN
- ackblk := rawblk;
- slide := 1;
- Inc(ackseen);
- IF (ackless <> 0) AND (ackseen > 10) THEN
- BEGIN
- ackless := 0;
- Message('Overdrive disengaged',0)
- END;
- Message('ACK',rawblk)
- END
- ELSE
- BEGIN
- IF (rawblk < 0) THEN
- outblk := 0
- ELSE
- outblk := rawblk;
- IF (numnak < 4) THEN
- slide := 1
- ELSE
- slide := 0;
- Message('NAK',rawblk)
- END;
- ackrep := 1
- END
- END;
- ackst := 0;
- Exit
- END;
- IF (ackst = 1) OR (ackst = 2) THEN
- BEGIN
- rawblk := c;
- Inc(ackst,2)
- END;
- IF (ackst = 0) OR (slide = 0) THEN
- BEGIN
- IF (c = 6) THEN
- BEGIN
- IF (slide = 0) THEN
- BEGIN
- Inc(ackblk);
- ackrep := 1;
- Message('ACK',ackblk)
- END;
- ackst := 1;
- numnak := 0
- END
- ELSE IF (c = Ord('C')) OR (c = 21) THEN
- BEGIN
- IF (chktec > 1) THEN
- IF (c = 21) THEN
- chktec := 0
- ELSE
- chktec := 1;
- Com_Flush;
- Delay(6);
- IF (slide = 0) THEN
- BEGIN
- outblk := ackblk + 1;
- ackrep := 1;
- Message('NAK',ackblk+1)
- END;
- ackst := 2;
- Inc(numnak);
- IF (blksnt <> 0) THEN
- Inc(toterr)
- END
- END;
- IF (ackst = 5) THEN
- ackst := 0;
- c := Com_GetC(20)
- END
- END;
-
- FUNCTION GetBlock(VAR buf: secbuf): STRING;
-
- VAR
- ourcrc, hiscrc, c, n, timeout: INTEGER;
-
- BEGIN
- ourcrc := 0;
- IF (ackless = 0) THEN
- timeout := 1
- ELSE
- timeout := 20;
- FOR n := 0 TO 127 DO
- BEGIN
- c := Com_GetC(10);
- IF (c = -1) THEN
- BEGIN
- GetBlock := 'Short';
- Exit
- END;
- IF (chktec <> 0) THEN
- ourcrc := UpdCrc(c,ourcrc)
- ELSE
- ourcrc := ourcrc + c;
- buf[n] := BYTE(c)
- END;
- IF (chktec <> 0) THEN
- BEGIN
- c := Com_GetC(10);
- ourcrc := UpdCrc(c,ourcrc);
- c := Com_GetC(10);
- ourcrc := UpdCrc(c,ourcrc);
- IF (ourcrc = 0) THEN
- GetBlock := ''
- ELSE
- GetBlock := 'CRC';
- Exit
- END;
- ourcrc := ourcrc AND $FF;
- hiscrc := Com_GetC(1) AND $FF;
- IF (hiscrc = ourcrc) THEN
- GetBlock := ''
- ELSE
- GetBlock := 'Check'
- END;
-
- PROCEDURE SendAck(acknak, blknum: INTEGER);
-
- BEGIN
- IF (acknak <> 0) THEN
- Com_PutC(6)
- ELSE IF (chktec <> 0) THEN
- Com_PutC(Ord('C'))
- ELSE
- Com_PutC(21);
- Com_PutC(BYTE(blknum));
- Com_PutC(BYTE(blknum XOR $FF))
- END;
-
- PROCEDURE RxSeaLink(path: STRING; overdrive: BOOLEAN);
-
- LABEL
- nakblock, ackblock, nextblock, blockstart, endrcv, abort;
-
- VAR
- sr: SearchRec;
- c, tries, blknum, inblk, endblk, n: INTEGER;
- t1, left: LONGINT;
- f: FILE;
- zero: zeros;
- name, pname, stat, why: STRING;
- buff: secbuf;
-
- BEGIN
- IF (path[Length(path)] <> '\') THEN
- path := path + '\';
- Assign(f,path+'-TMPFILE.$$$');
- {$I-} ReWrite(f,WORD(1)); {$I+}
- IF (IOresult <> 0) THEN
- BEGIN
- Message('Cannot create '+path+'-TMPFILE.$$$',-1);
- Exit
- END;
- stat := 'Init';
- blknum := 0;
- tries := -10;
- chktec := 1;
- toterr := 0;
- endblk := 0;
- ackless := 0;
- FillChar(zero,128,0);
- starttime := TimerSet(0);
- IF (Com_Peek = 1) THEN
- GOTO nextblock;
- nakblock:
- IF (blknum > 1) THEN
- Inc(toterr);
- Inc(tries);
- IF (tries > 10) THEN
- BEGIN
- Message('Too many errors',-1);
- GOTO abort
- END;
- IF (tries = 0) THEN
- chktec := 0;
- SendAck(0,blknum);
- Message('NAK '+stat,blknum);
- IF (ackless <> 0) AND (toterr > 20) THEN
- BEGIN
- ackless := 0;
- Message('Overdrive disengaged',-1)
- END;
- GOTO nextblock;
- ackblock:
- IF (ackless = 0) THEN
- Message('ACK',blknum-1)
- ELSE IF ((blknum MOD 10) = 0) THEN
- Message('Got block',blknum);
- nextblock:
- stat := '';
- IF (NOT (Async_Carrier_Detect)) THEN
- BEGIN
- Message('Lost carrier',-1);
- GOTO abort
- END;
- IF (KeyPressed) THEN
- IF (ReadKey IN [^X,^[]) THEN
- BEGIN
- Message('Aborted by operator',-1);
- GOTO abort
- END;
- t1 := timerset(30);
- WHILE (NOT (TimeUp(t1))) DO
- BEGIN
- c := Com_GetC(0);
- IF (c = 4) AND ((endblk = 0) OR (endblk = blknum)) THEN
- GOTO endrcv;
- IF (c = 1) THEN
- BEGIN
- inblk := Com_GetC(5);
- IF (Com_GetC(5) = (inblk XOR $FF)) THEN
- GOTO blockstart
- END
- END;
- stat := 'Time';
- GOTO nakblock;
- blockstart:
- c := blknum AND $FF;
- IF (inblk = 0) AND (blknum <= 1) THEN
- BEGIN
- why := GetBlock(buff);
- IF (why = '') THEN
- BEGIN
- SendAck(1,inblk);
- Move(buff,zero,128);
- left := zero.flen;
- name := FromAsciiZ(zero.fnam);
- pname := FromAsciiZ(zero.prog);
- ackless := (zero.noacks) AND (BYTE(overdrive));
- IF (left > 0) THEN
- endblk := (left + 127) DIV 128 + 1;
- IF (noacks <> 0) THEN
- Message('Overdrive engaged',-1)
- ELSE
- Message('Overdrive engaged',-1);
- IF (endblk <> 0) AND (seatalk) THEN
- BEGIN
- WRITELN;
- WRITELN('Receiving ',endblk-1,' blocks of ',name,' from ',pname);
- END;
- blknum := 1;
- GOTO ackblock
- END
- ELSE
- BEGIN
- stat := why;
- GOTO nakblock
- END
- END
- ELSE IF (inblk = c) THEN
- BEGIN
- why := GetBlock(buff);
- IF (why = '') THEN
- BEGIN
- IF (ackless = 0) THEN
- SendAck(1,inblk);
- {$I-} BlockWrite(f,buff,128); {$I+}
- left := left - 128;
- IF (IOresult <> 0) THEN
- BEGIN
- Message('Write error (disk full?)',-1);
- Delay(1000);
- GOTO abort
- END;
- tries := 0;
- Inc(blknum);
- GOTO ackblock
- END
- ELSE
- BEGIN
- stat := why;
- GOTO nakblock
- END
- END
- ELSE IF (inblk < c) OR (inblk > c + 100) THEN
- BEGIN
- why := GetBlock(buff);
- SendAck(1,inblk);
- stat := 'Dup';
- GOTO ackblock
- END
- ELSE
- GOTO nextblock;
- endrcv:
- SendAck(0,blknum);
- Message('NAK EOT',-1);
- IF (Com_GetC(20) <> 4) THEN
- GOTO nakblock;
- SendAck(1,blknum);
- Message('ACK EOT',-1);
- endtime := zero.flen DIV ((TimerSet(0) - starttime) DIV 10);
- abort:
- IF (zero.fstamp > 0) THEN
- BEGIN
- SetFtime(f,zero.fstamp);
- IF (DosError <> 0) THEN
- Message('Unable to date file',-1)
- END;
- {$I-} Close(f); {$I+}
- IF (IOresult = 0) AND (blknum > 1) THEN
- BEGIN
- FindFirst(path+name,AnyFile,sr);
- IF (DosError = 0) THEN
- name[1] := '-';
- {$I-} Rename(f,name); {$I+}
- IF (IOresult <> 0) THEN
- Message('Unable to rename file',-1)
- END;
- IF (blknum = 0) THEN
- Message('No file received',-1)
- END;
-
- PROCEDURE ShipBlk(VAR blk: secbuf; blknum: INTEGER);
-
- VAR
- n, crc: INTEGER;
-
- BEGIN
- crc := 0;
- Com_PutC(1);
- Com_PutC(BYTE(blknum));
- Com_PutC(BYTE(blknum) XOR $FF);
- FOR n := 0 TO 127 DO
- BEGIN
- IF (chktec <> 0) THEN
- crc := UpdCrc(blk[n],crc)
- ELSE
- crc := crc + blk[n];
- Com_PutC(blk[n])
- END;
- IF (chktec <> 0) THEN
- BEGIN
- crc := UpdCrc(0,crc);
- crc := UpdCrc(0,crc);
- Com_PutC(BYTE(crc SHR 8));
- Com_PutC(BYTE(crc) AND $FF)
- END
- ELSE
- Com_PutC(BYTE(crc))
- END;
-
- PROCEDURE SendBlk(VAR f: FILE; blknum: INTEGER);
-
- VAR
- buff: secbuf;
- blkloc: LONGINT;
-
- BEGIN
- IF (blknum <> (blksnt+1)) THEN
- BEGIN
- blkloc := LONGINT(blknum-1) * LONGINT(128);
- {$I-} Seek(f,blkloc); {$I+}
- IF (IOresult <> 0) THEN
- Message('Error seeking block',blknum-1)
- END;
- blksnt := blknum;
- FillChar(buff,128,0);
- {$I-} BlockRead(f,buff,128); {$I+}
- IF (IOresult <> 0) THEN
- Message('Error reading block',blknum);
- ShipBlk(buff,blknum)
- END;
-
- PROCEDURE TxSeaLink(pathname: STRING; overdrive: BOOLEAN);
-
- LABEL
- abort1;
-
- VAR
- f: FILE;
- t1: LONGINT;
- endblk: INTEGER;
- sr: SearchRec;
- zero: zeros;
- buff: secbuf;
-
- BEGIN
- IF (pathname <> '') THEN
- BEGIN
- FindFirst(pathname,Archive,sr);
- IF (DosError <> 0) THEN
- BEGIN
- Message('No file found',-1);
- Exit
- END;
- FillChar(zero,128,0);
- WITH sr,zero DO
- BEGIN
- flen := Size;
- fstamp := Time;
- IF (overdrive) THEN
- noacks := 1;
- Move(Name[1],fnam[0],Length(Name));
- IF (Length(progname) >= 14) THEN
- Move(progname[1],prog[0],14)
- ELSE
- Move(progname[1],prog[0],Length(progname));
- Move(zero,buff,128)
- END;
- Assign(f,pathname);
- {$I-} Reset(f,WORD(1)); {$I+}
- IF (IOresult <> 0) THEN
- BEGIN
- Message('Unable to open file',-1);
- Exit
- END;
- endblk := INTEGER((zero.flen + 127) DIV 128) + 1;
- IF (seatalk) THEN
- BEGIN
- WRITELN;
- WRITELN('Ready to send ',endblk-1,' blocks of ',sr.name)
- END
- END
- ELSE
- endblk := 0;
- outblk := 1;
- ackblk := -1;
- blksnt := 0;
- slide := 0;
- ackst := 0;
- numnak := 0;
- toterr := 0;
- ackrep := 0;
- ackseen := 0;
- chktec := 2;
- ackless := BYTE(overdrive);
- t1 := TimerSet(300);
- Message('Waiting',-1);
- WHILE (ackblk < endblk) DO
- BEGIN
- IF (NOT (Async_Carrier_Detect)) THEN
- BEGIN
- Message('Lost carrier',-1);
- GOTO abort1
- END;
- IF (KeyPressed) THEN
- IF (ReadKey IN [^X,^[]) THEN
- BEGIN
- Message('Aborted by operator',-1);
- GOTO abort1
- END;
- IF (TimeUp(t1)) THEN
- BEGIN
- Message('Fatal timeout',-1);
- GOTO abort1
- END;
- IF ((slide <> 0) AND (outblk <= (ackblk + 6))) OR
- ((slide = 0) AND (outblk <= (ackblk + 1))) THEN
- BEGIN
- IF (outblk < endblk) THEN
- BEGIN
- IF (outblk > 0) THEN
- SendBlk(f,outblk)
- ELSE
- ShipBlk(buff,0);
- IF (ackrep <> 0) THEN
- Message('Sending block',outblk);
- IF (ackless <> 0) AND (slide <> 0) THEN
- BEGIN
- IF ((outblk MOD 10) = 0) THEN
- Message('Passing block',outblk);
- ackblk := outblk
- END
- END
- ELSE IF (outblk = endblk) THEN
- BEGIN
- Com_PutC(4);
- IF (ackrep <> 0) THEN
- Message('Sending EOT',-1)
- END;
- Inc(outblk);
- t1 := TimerSet(30)
- END;
- ackchk;
- IF (numnak > 10) THEN
- BEGIN
- Message('Too many errors',-1);
- GOTO abort1
- END
- END;
- Message('End of file',-1);
- abort1:
- IF (endblk <> 0) THEN
- BEGIN
- {$I-} Close(f); {$I+}
- IF (IOresult <> 0) THEN
- {null};
- endtime := zero.flen DIV ((TimerSet(0) - starttime) DIV 10)
- END
- ELSE
- BEGIN
- FOR endblk := 1 TO 5 DO
- Com_PutC(4);
- FOR endblk := 1 TO 5 DO
- Com_PutC(24)
- END
- END;
-
-
- PROCEDURE RxSeaLink;
-
- BEGIN
- GetSeaLink;
- Delay(3000)
- END;
-
- PROCEDURE TxSeaLink;
-
- BEGIN
- PutSeaLink;
- Delay(3000)
- END;
-