{
   MEGALS.PAS
   MegaLink protocol for Pascal.  UNTESTED.  Had no docs.
   Written: 05-16-90
   Copyright (c)1990, Eric J. Givler, All Rights Reserved.
}
PROCEDURE SendMEGALink;
(*  Paul Meiners *)
{ receive an initial C 00 FF as opening NAK }

CONST  EM  = ^Y;             { MegaLink Block Id }
       RS  = #$1E;           { Request Status    }
       SYN = ^V;             { Synchronize       }
       DLE = ^P;             { Data Link Escape  }
     { SUB = ^Z;               CP/M EOF (CPMEOF) }

VAR cs : ARRAY512;
    i,
    j  : integer;
    temp : string[5];

   PROCEDURE MakeMegaHeader(var sector : blocktype);
   { Name of transmitting program, as a null terminated string
     starts at 25 for 15 }
   var size : longint;
          i : integer;
       host : String[15];
   begin
      host := 'NBBS';
      FillChar(sector,SizeOf(sector),CHR(0));
      size := FileSize(WorkFile);
      Move(size,sector,SizeOf(size));
      GetFtime(WorkFile,size);
      Move(size,sector[4],SizeOf(size));
      for i := 1 to length(filename) do sector[7+i] := byte(filename[i]);
      for i := 1 to length(host) do sector[24+i] := ord(host[i]);
   end;

BEGIN (* SendMEGALink *)
   Assign(WorkFile,filename);
   {$I-} Reset(WorkFile,1); {$I+}
   If IOResult <> 0 Then Exit;
   MakeMegaHeader(sector);
   blocknum := 0;
   repeat
      Send(SOH);
      Send(CHR(blocknum));
      Send(CHR(blocknum XOR 255));
      FOR i := 0 to lastbyte DO Send(CHR(sector[i]));
      crc := 0;
      crca( sector, SizeOf(sector), crc);
      Send(CHR(Hi(crc)));
      Send(CHR(Lo(crc)));
      PurgeLine;
   until (readline(10) = ORD(ACK));
   PurgeLine;                          (* actually receive ACK 00 FF *)
   
   blocknum := 1;
   str((FileSize(WorkFile) DIV 512):5,temp);
   WriteLn('File open: ' + temp + ' MEGALink blocks.');
   cs.Len := 512;
   repeat
      counter := 0;
      FillChar(cs.longstring, SizeOf(cs.longstring),CPMEOF);
      {$I-} BlockRead(WorkFile,cs.longstring,Sizeof(cs.longstring),result); {$I+}
      IF IOResult <> 0 then begin
         WriteLn('Error reading File: CANCELLED');
         Send(CAN); Send(CAN);
         Close(WorkFile);
         Exit;
      end;
      repeat
         Write(cr,'Sending block: ',blocknum);
         Send(EM);
         Send(CHR(blocknum));
         Send(CHR(blocknum XOR 255));
         FOR j := 1 to 512 do begin
            IF (cs.LongString[j] = XON) then begin
               Send(CHR(byte(DLE) XOR 64));
               Send(CHR(byte(XON) XOR 64));
            end else if (cs.LongString[i] = XOFF) then begin
               Send(CHR(byte(DLE) XOR 64));
               Send(CHR(byte(XON) XOR 64));
            end else Send(cs.LongString[i]);
         end;
         calc_crc32(cs);
         Send(CHR(Hi(crc_reg_hi)));
         Send(CHR(Lo(crc_reg_hi)));
         Send(CHR(Hi(crc_reg_lo)));
         Send(CHR(Lo(crc_reg_lo)));
         PurgeLine;
         inc(counter);
      UNTIL (readline(10) = ORD(ACK)) OR (counter = retrymax);
      PurgeLine;
      inc(blocknum);
    UNTIL EOF(WorkFile) OR (counter = retrymax) OR (NOT Carrier);

end;