home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / PASCAL / PCL4P30.ZIP / XYPACKET.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1992-01-18  |  11.0 KB  |  405 lines

  1. (*********************************************)
  2. (*                                           *)
  3. (*  This program is donated to the Public    *)
  4. (*  Domain by MarshallSoft Computing, Inc.   *)
  5. (*  It is provided as an example of the use  *)
  6. (*  of the Personal Communications Library.  *)
  7. (*                                           *)
  8. (*********************************************)
  9.  
  10.  
  11. { $DEFINE DEBUG}
  12.  
  13. unit xypacket;
  14.  
  15. interface
  16.  
  17. type BufferType = array[0..1023] of Byte;
  18.  
  19. Function TxPacket(Port:Integer;
  20.                   PacketNbr:Word;
  21.                   PacketSize:Word;
  22.               Var Buffer:BufferType;
  23.                   CRCflag:Boolean):Boolean;
  24. Function RxPacket(Port:Integer;
  25.                   PacketNbr:Word;
  26.               Var PacketSize:Word;
  27.               Var Buffer:BufferType;
  28.                   CRCflag:Boolean;
  29.               Var EOTflag:Boolean):Boolean;
  30. Function RxStartup(Port:Integer;
  31.               Var CRCflag:Boolean):Boolean;
  32. Function TxStartup(Port:Integer;
  33.               Var CRCflag:Boolean):Boolean;
  34. Function TxEOT(Port:Integer):Boolean;
  35.  
  36.  
  37. implementation
  38.  
  39. uses PCL4P,term_io,crc,hex_io,crt;
  40.  
  41.  
  42. const ONESECOND = 18;
  43.       MAXTRY = 3;
  44.       LIMIT = 20;
  45.  
  46. const SOH = $01;
  47.       STX = $02;
  48.       EOT = $04;
  49.       ACK = $06;
  50.       NAK = $15;
  51.       CAN = $18;
  52.  
  53. Function TxPacket(Port:Integer;         (* Port # [0..3] *)
  54.                   PacketNbr:Word;       (* Packet # [0,1,2,...] *)
  55.                   PacketSize:Word;      (* Packet size [128,1024] *)
  56.               Var Buffer:BufferType;    (* 1K character buffer *)
  57.                   CRCflag:Boolean)      (* use CRC flag *)
  58.                 : Boolean;              (* successfull *)
  59. Label 999;
  60. Var
  61.   I         : Integer;
  62.   Code      : Integer;
  63.   CheckSum  : Word;
  64.   Attempt   : Word;
  65.   PacketType: Byte;
  66. Begin
  67.   (* better be 128 or 1024 packet length *)
  68.   if PacketSize = 1024
  69.       then PacketType := STX
  70.       else PacketType := SOH;
  71.   PacketNbr := PacketNbr and $00ff;
  72.   (* make up to MAXTRY attempts to send this packet *)
  73.   for Attempt := 1 to MAXTRY do
  74.     begin
  75.       (* send SOH/STX  *)
  76.       PutChar(Port,PacketType);
  77.       (* send packet # *)
  78.       PutChar(Port,PacketNbr);
  79.       (* send 1's complement of packet *)
  80.       PutChar(Port,255-PacketNbr);
  81.       (* send data *)
  82.       CheckSum := 0;
  83.       for i := 0 to PacketSize - 1 do
  84.         begin
  85.           PutChar(Port,Buffer[i]);
  86.           (* update checksum *)
  87.           if CRCflag then CheckSum := UpdateCRC(CheckSum, Buffer[i])
  88.           else CheckSum := CheckSum + Buffer[i];
  89.         end;
  90. {$IFDEF DEBUG}
  91. write('<Checksum=$');
  92. WriteHexWord(CheckSum);
  93. write('>');
  94. {$ENDIF}
  95.       (* send checksum *)
  96.       if CRCflag then
  97.         begin
  98.           (* send 2 byte CRC *)
  99.           PutChar(Port, (CheckSum shr 8) and $00ff );
  100.           PutChar(Port, CheckSum and $00ff );
  101.         end
  102.       else (* not CRCflag *)
  103.         begin
  104.           (* send one byte checksum *)
  105.           PutChar(Port,CheckSum );
  106.         end;
  107.       (* wait for receivers ACK *)
  108.       Code := GetChar(Port,10*ONESECOND);
  109.       if Code = CAN then
  110.          begin
  111.             WriteLn('Canceled by remote');
  112.             TxPacket := FALSE;
  113.             Goto 999;
  114.           end;
  115.       if Code = ACK then
  116.           begin
  117.             TxPacket := TRUE;
  118.             Goto 999
  119.           end;
  120.       if Code <> NAK then
  121.           begin
  122.             WriteLn('Out of sync');
  123.             TxPacket := FALSE;
  124.             Goto 999;
  125.           end;
  126.     end; (* end for *)
  127.   (* can't send packet ! *)
  128.   Writeln('Packet timeout for port ',Port);
  129.   TxPacket := FALSE;
  130.  999: end; (* end -- TxPacket *)
  131.  
  132. Function RxPacket(Port:Integer;           (* Port # 0..3 *)
  133.                   PacketNbr:Word;         (* Packet # [0,1,2,...] *)
  134.               Var PacketSize:Word;        (* Packet size (128 or 1024) *)
  135.               Var Buffer:BufferType;      (* 1K buffer *)
  136.                   CRCflag:Boolean;        (* use CRC flag *)
  137.               Var EOTflag:Boolean)        (* EOT was received *)
  138.                   :Boolean;               (* success / failure *)
  139. Label 999;
  140. Var
  141.   I            : Integer;
  142.   Code         : Integer;
  143.   Attempt      : Word;
  144.   RxPacketNbr  : Word;
  145.   RxPacketNbrC : Word;
  146.   CheckSum     : Word;
  147.   RxCheckSum   : Word;
  148.   RxCheckSum1  : Word;
  149.   RxCheckSum2  : Word;
  150.   PacketType   : Byte;
  151. begin
  152.   PacketNbr := PacketNbr AND $00ff;
  153.   for Attempt := 1 to MAXTRY do
  154.     begin
  155.       (* wait for SOH / STX *)
  156.       Code := GetChar(Port,10*ONESECOND);
  157.       if Code = -1 then
  158.         begin
  159.           WriteLn('Timed out waiting for sender');
  160.           RxPacket := FALSE;
  161.           Goto 999
  162.         end;
  163.       case Code of
  164.         SOH: begin
  165.                (* 128 byte buffer incoming *)
  166.                PacketType := SOH;
  167.                PacketSize := 128
  168.              end;
  169.         STX: begin
  170.                (* 1024 byte buffer incoming *)
  171.                PacketType := STX;
  172.                PacketSize := 1024;
  173.              end;
  174.         EOT: begin
  175.                (* all packets have been sent *)
  176.                PutChar(Port,ACK);
  177.                EOTflag := TRUE;
  178.                RxPacket := TRUE;
  179.                goto 999
  180.              end;
  181.         CAN: begin
  182.                (* sender has canceled ! *)
  183.                SayError(Port,'Canceled by remote');
  184.                RxPacket := FALSE;
  185.              end;
  186.         else
  187.             begin
  188.               (* error ! *)
  189.               Write('Expecting SOH/STX/EOT/CAN not $');
  190.               WriteHexByte(Code);
  191.               Writeln;
  192.               RxPacket := FALSE;
  193.             end;
  194.       end;
  195.       (* receive packet # *)
  196.       Code := GetChar(Port,ONESECOND);
  197.       if Code = -1 then
  198.         begin
  199.           WriteLn('timed out waiting for packet #');
  200.           goto 999;
  201.         end;
  202.       RxPacketNbr := $00ff and Code;
  203.       (* receive 1's complement *)
  204.       Code := GetChar(Port,ONESECOND);
  205.       if Code =-1 then
  206.         begin
  207.           WriteLn('timed out waiting for complement of packet #');
  208.           RxPacket := FALSE;
  209.           Goto 999
  210.         end;
  211.       RxPacketNbrC := $00ff and Code;
  212.       (* receive data *)
  213.       CheckSum := 0;
  214.       for i := 0 to PacketSize - 1 do
  215.         begin
  216.           Code := GetChar(Port,ONESECOND);
  217.           if Code = -1 then
  218.             begin
  219.               WriteLn('timed out waiting for data for packet #');
  220.               RxPacket := FALSE;
  221.               Goto 999
  222.             end;
  223.           Buffer[i] := Code;
  224.           (* compute CRC or checksum *)
  225.           if CRCflag
  226.             then CheckSum := UpdateCRC(CheckSum,Code)
  227.             else CheckSum := (CheckSum + Code) AND $00ff;
  228.         end;
  229.       (* receive CRC/checksum *)
  230.       if CRCflag then
  231.         begin
  232.           (* receive 2 byte CRC *)
  233.           Code := GetChar(Port,ONESECOND);
  234.           if Code =-1 then
  235.             begin
  236.               WriteLn('timed out waiting for 1st CRC byte');
  237.               RxPacket := FALSE;
  238.               Goto 999
  239.             end;
  240.           RxCheckSum1 := Code AND $00ff;
  241.           Code := GetChar(Port,ONESECOND);
  242.           if Code =-1 then
  243.             begin
  244.               WriteLn('timed out waiting for 2nd CRC byte');
  245.               RxPacket := FALSE;
  246.               Goto 999
  247.             end;
  248.           RxCheckSum2 := Code AND $00ff;
  249.           RxCheckSum := (RxCheckSum1 SHL 8) OR RxCheckSum2;
  250.         end
  251.       else
  252.         begin
  253.           (* receive one byte checksum *)
  254.           Code := GetChar(Port,ONESECOND);
  255.           if Code = -1 then
  256.             begin
  257.               WriteLn('timed out waiting for checksum');
  258.               RxPacket := FALSE;
  259.               Goto 999
  260.              end;
  261.           RxCheckSum := Code AND $00ff;
  262.         end;
  263. {$IFDEF DEBUG}
  264. write('<Checksum: Received=$');
  265. WriteHexWord(RxCheckSum);
  266. write(', Computed=$');
  267. WriteHexWord(CheckSum);
  268. write('>');
  269. {$ENDIF}
  270.      (* packet # and checksum OK ? *)
  271.      if (RxCheckSum=CheckSum) and (RxPacketNbr=PacketNbr) then
  272.        begin
  273.          (* ACK the packet *)
  274.          PutChar(Port,ACK);
  275.          RxPacket := TRUE;
  276.          Goto 999
  277.        end;
  278.      (* bad packet *)
  279.      WriteMsg('Bad Packet',1);
  280.      PutChar(Port,NAK)
  281.    end;
  282.    (* can't receive packet *)
  283.    SayError(Port,'RX packet timeout');
  284.    RxPacket := FALSE;
  285. 999: end; (* end -- RxPacket *)
  286.  
  287. Function TxStartup(Port:Integer;
  288.                Var CRCflag:Boolean):Boolean;
  289. Label 999;
  290. Var
  291.   Code : Integer;
  292.   I : Integer;
  293.   Result : Boolean;
  294. Begin
  295.   (* clear Rx buffer *)
  296.   Code := SioRxFlush(Port);
  297.   (* wait for receivers start up NAK or 'C' *)
  298.   for i := 1 to LIMIT do
  299.     begin
  300.       if KeyPressed then
  301.         begin
  302.           SayError(Port,'Aborted by user');
  303.           Result := FALSE;
  304.           Goto 999
  305.         end;
  306.       Code := GetChar(Port,3*ONESECOND);
  307.       if Code <> -1  then
  308.         begin
  309.          (* received a byte *)
  310.          if Code = NAK then
  311.            begin
  312.              CRCflag := FALSE;
  313.              Result := TRUE;
  314.              Goto 999
  315.           end;
  316.         if Code = Ord('C') then
  317.           begin
  318.             CRCflag := TRUE;
  319.             Result := TRUE;
  320.             Goto 999
  321.           end
  322.         end
  323.       end;
  324.   (* no response *)
  325.   SayError(Port,'No response from receiver');
  326.   TxStartup := FALSE;
  327. 999:
  328.   TxStartup := Result;
  329. {$IFDEF DEBUG}
  330.   write('<TxStartup ');
  331.   if Result then writeln('successfull>')
  332.   else writeln('fails>');
  333. {$ENDIF}
  334. end; (* end -- TxStartup *)
  335.  
  336.  
  337. Function RxStartup(Port:Integer;
  338.                Var CRCflag:Boolean)
  339.                  : Boolean;
  340. Label 999;
  341. Var
  342.   I : Integer;
  343.   Code : Integer;
  344.   Result : Boolean;
  345. Begin
  346.   (* clear Rx buffer *)
  347.   Code := SioRxFlush(Port);
  348.   (* Send NAKs or 'C's *)
  349.   for I := 1 to LIMIT do
  350.     begin
  351.       if KeyPressed then
  352.         begin
  353.           SayError(Port,'Canceled by user');
  354.           Result := FALSE;
  355.           Goto 999
  356.         end;
  357.       (* stop attempting CRC after 1st 4 tries *)
  358.       if CRCflag and (i=5) then  CRCflag := FALSE;
  359.       (* tell sender that I am ready to receive *)
  360.       if CRCflag
  361.          then PutChar(Port,Ord('C'))
  362.          else PutChar(Port,NAK);
  363.       Code := GetChar(Port,3*ONESECOND);
  364.       if Code <> -1 then
  365.         begin
  366.           (* no error -- must be incoming byte -- push byte back onto queue ! *)
  367.           Code := SioUnGetc(Port,Code);
  368.           Result := TRUE;
  369.           Goto 999
  370.         end;
  371.     end; (* for i *)
  372.   (* no response *)
  373.   SayError(Port,'No response from sender');
  374.   Result := FALSE;
  375. 999:
  376.   RxStartup := Result;
  377. {$IFDEF DEBUG}
  378.   write('<RxStartup ');
  379.   if Result then writeln('successfull>')
  380.   else writeln('fails>');
  381. {$ENDIF}
  382. end; (* end -- RxStartup *)
  383.  
  384. Function TxEOT(Port:Integer):Boolean;
  385. Label 999;
  386. Var
  387.   I    : Integer;
  388.   Code : Integer;
  389. Begin
  390.   for I := 0 to 10 do
  391.     begin
  392.       PutChar(Port,EOT);
  393.       (* await response *)
  394.       Code := GetChar(Port,3*ONESECOND);
  395.       if Code = ACK then
  396.         begin
  397.           TxEOT := TRUE;
  398.           Goto 999
  399.         end
  400.     end; (* end -- for I) *)
  401.   TxEOT := FALSE;
  402. 999: end; (* end -- TxEOT *)
  403.  
  404. end.
  405.