home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / das_buch / remote / parcrc.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-08-06  |  3.6 KB  |  115 lines

  1. (* ====================================================== *)
  2. (*                      PARCRC.PAS                        *)
  3. (*           Datenübertragung mit CRC-Checksumme          *)
  4. (*         (c) 1993 Ralf Hensmann & DMV-Verlag            *)
  5. (* ====================================================== *)
  6. {$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}
  7. {$M 16384,0,655360}
  8.  
  9. UNIT ParCRC;
  10.  
  11. INTERFACE
  12.  
  13. USES ParData, Crc, Crt;
  14.  
  15.   PROCEDURE SendCRCBuf(VAR Buf; Size : WORD);
  16.   (* SendCRCBuf überträgt einen Block mit anschließendem  *)
  17.   (* CRC-16-Wort. Ist die Übertragung nicht geglückt,     *)
  18.   (* wird wiederholt. Vor dem ersten Aufruf von           *)
  19.   (* SendCRCBuf muß die CRC-Tabelle gesetzt sein.         *)
  20.  
  21.   PROCEDURE ReceiveCRCBuf(VAR Buf; Size : WORD);
  22.   (* ReceiveCRCBuf empfängt einen Block mit anschließendem*)
  23.   (* CRC-Wert. Die Größe muß bekannt sein, da sonst keine *)
  24.   (* fehlerfreie Übertragung möglich ist.                 *)
  25.  
  26. IMPLEMENTATION
  27.  
  28. TYPE
  29.   OS = RECORD            (* oder LongRec aus Unit Objects *)
  30.          o, s : WORD;
  31.        END;
  32.  
  33.   PROCEDURE SendCRCBuf(VAR Buf; Size : WORD);
  34.   VAR
  35.     Answer   : WORD;
  36.     BufPtr   : POINTER;
  37.     Buffer   : ARRAY [0..65530] OF BYTE ABSOLUTE Buf;
  38.     i        : WORD;
  39.   BEGIN
  40.     (* Bei Fehler Abbruch *)
  41.     IF LastResult <> ReadyToTransfer THEN Exit;
  42.     (* in 512-Byte Blöcke zerlegen, um bei Fehlern nicht  *)
  43.     (* ganzen Block neu zu übertragen.                    *)
  44.     i := 0;
  45.     WHILE Size > 512 DO BEGIN
  46.       SendCRCBuf(Buffer[i], 512);
  47.       IF LastResult <> ReadyToTransfer THEN Exit;
  48.       Inc(i, 512);  Dec(Size, 512);
  49.     END;
  50.     (* Adresse normalisieren *)
  51.     BufPtr := @Buffer[i];
  52.     OS(BufPtr).s := OS(BufPtr).s + OS(BufPtr).o SHR 4;
  53.     OS(BufPtr).o := OS(BufPtr).o AND $F;
  54.     (* CRC-Summe berechnen *)
  55.     CRC_16 := 0;
  56.     Build_crc(BufPtr^, Size);
  57.     (* Übertragen *)
  58.     REPEAT
  59.       IF TransferMode = Transfer4 THEN BEGIN
  60.         (* 4-Bit-Übetragung *)
  61.         SendBlock4(BufPtr^, Size);
  62.         SendBlock4(CRC_16, 2);
  63.         ReceiveBlock4(Answer, 2);
  64.       END ELSE BEGIN
  65.         (* 8-Bit-Übertragung *)
  66.         SendBlock(BufPtr^, Size);
  67.         SendBlock(CRC_16, 2);
  68.         ReceiveBlock(Answer, 2);
  69.       END;
  70.     UNTIL (Answer = 0) OR (LastResult <> ReadyToTransfer);
  71.   END;
  72.  
  73.   PROCEDURE ReceiveCRCBuf(VAR Buf; Size : WORD);
  74.   VAR
  75.     Follow   : WORD;
  76.     BufPtr   : POINTER;
  77.     Buffer   : ARRAY [0..65530] OF BYTE ABSOLUTE Buf;
  78.     i        : WORD;
  79.   BEGIN
  80.     IF LastResult <> ReadyToTransfer THEN Exit;
  81.     (* Zerlegen wie oben *)
  82.     i := 0;
  83.     WHILE Size > 512 DO BEGIN
  84.       ReceiveCRCBuf(Buffer[i], 512);
  85.       IF LastResult <> ReadyToTransfer THEN Exit;
  86.       Inc(i, 512);  Dec(Size, 512);
  87.     END;
  88.     (* Adresse normalisieren *)
  89.     BufPtr := @Buffer[i];
  90.     OS(BufPtr).s := OS(BufPtr).s + OS(BufPtr).o SHR 4;
  91.     OS(BufPtr).o := OS(BufPtr).o AND $F;
  92.     REPEAT
  93.       CRC_16 := 0;
  94.       IF TransferMode = Transfer4 THEN BEGIN
  95.         (* 4-Bit-Übetragung *)
  96.         ReceiveBlock4(BufPtr^, Size);
  97.         Build_crc(BufPtr^, Size);
  98.         ReceiveBlock4(Follow, 2);
  99.         CRC_16 := CRC_16 XOR Follow;
  100.         SendBlock4(CRC_16, 2);
  101.       END ELSE BEGIN
  102.         (* 8-Bit-Übetragung *)
  103.         ReceiveBlock(BufPtr^, Size);
  104.         Build_crc(BufPtr^, Size);
  105.         ReceiveBlock(Follow, 2);
  106.         CRC_16 := CRC_16 XOR Follow;
  107.         SendBlock(CRC_16, 2);
  108.       END;
  109.     UNTIL (CRC_16 = 0) OR (LastResult <> ReadyToTransfer);
  110.   END;
  111.  
  112. END.
  113. (* ====================================================== *)
  114. (*                  Ende von PARCRC.PAS                   *)
  115.