home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / os2pm / datalink.mod < prev    next >
Text File  |  2020-01-01  |  6KB  |  210 lines

  1. IMPLEMENTATION MODULE DataLink;  (* Sends and Receives Packets for PCKermit *)
  2.  
  3.    FROM ElapsedTime IMPORT
  4.       StartTime, GetTime;
  5.  
  6.    FROM Screen IMPORT
  7.       ClrScr, WriteString, WriteLn;
  8.  
  9.    FROM PMWIN IMPORT
  10.       MPARAM, WinPostMsg;
  11.  
  12.    FROM Shell IMPORT
  13.       ChildFrameWindow, comport;
  14.  
  15.    FROM CommPort IMPORT
  16.       CommStatus, GetChar, SendChar;
  17.  
  18.    FROM PAD IMPORT
  19.       PacketType, yourNPAD, yourPADC, yourEOL;
  20.  
  21.    FROM KH IMPORT
  22.       COM_OFF;
  23.  
  24.    FROM SYSTEM IMPORT
  25.       BYTE;
  26.  
  27.    IMPORT ASCII;
  28.  
  29.  
  30.    CONST
  31.       MAXtime = 100;   (* hundredths of a second -- i.e., one second *)
  32.       MAXsohtrys = 100;
  33.       DL_BadCS = 1;
  34.       DL_NoSOH = 2;
  35.  
  36.  
  37.    TYPE
  38.       SMALLSET = SET OF [0..7];   (* BYTE *)
  39.  
  40.    VAR
  41.       ch : CHAR;
  42.       status : CommStatus;
  43.       MP1, MP2 : MPARAM;
  44.  
  45.  
  46.    PROCEDURE Delay (t : CARDINAL);
  47.    (* delay time in milliseconds *)
  48.  
  49.       VAR
  50.          tmp : LONGINT;
  51.  
  52.       BEGIN
  53.          tmp := t DIV 10;
  54.          StartTime;
  55.          WHILE GetTime() < tmp DO
  56.          END;
  57.       END Delay;
  58.  
  59.  
  60.    PROCEDURE ByteAnd (a, b : BYTE) : BYTE;
  61.       BEGIN
  62.          RETURN BYTE (SMALLSET (a) * SMALLSET (b));
  63.       END ByteAnd;
  64.  
  65.  
  66.    PROCEDURE Char (c : INTEGER) : CHAR;
  67.    (* converts a number 0-95 into a printable character *)
  68.       BEGIN
  69.          RETURN (CHR (CARDINAL (ABS (c) + 32)));
  70.       END Char;
  71.  
  72.  
  73.    PROCEDURE UnChar (c : CHAR) : INTEGER;
  74.    (* converts a character into its corresponding number *)
  75.       BEGIN
  76.          RETURN (ABS (INTEGER (ORD (c)) - 32));
  77.       END UnChar;
  78.  
  79.  
  80.    PROCEDURE FlushUART;
  81.    (* ensure no characters left in UART holding registers *)
  82.       BEGIN
  83.          Delay (500);
  84.          REPEAT
  85.             status := GetChar (comport - COM_OFF, ch);
  86.          UNTIL status = NoCharacter;
  87.       END FlushUART;
  88.  
  89.  
  90.    PROCEDURE SendPacket (s : PacketType);
  91.    (* Adds SOH and CheckSum to packet *)
  92.  
  93.       VAR
  94.          i : CARDINAL;
  95.          checksum : INTEGER;
  96.  
  97.       BEGIN
  98.          Delay (10);   (* give host a chance to catch its breath *)
  99.          FOR i := 1 TO yourNPAD DO
  100.             status := SendChar (comport - COM_OFF, yourPADC, FALSE);
  101.          END;
  102.          status := SendChar (comport - COM_OFF, ASCII.soh, FALSE);
  103.          i := 1;
  104.          checksum := 0;
  105.          WHILE s[i] # 0C DO
  106.             INC (checksum, ORD (s[i]));
  107.             status := SendChar (comport - COM_OFF, s[i], FALSE);
  108.             INC (i);
  109.          END;
  110.          checksum := checksum + (INTEGER (BITSET (checksum) * {7, 6}) DIV 64);
  111.          checksum := INTEGER (BITSET (checksum) * {5, 4, 3, 2, 1, 0});
  112.          status := SendChar (comport - COM_OFF, Char (checksum), FALSE);
  113.          IF yourEOL # 0C THEN
  114.             status := SendChar (comport - COM_OFF, yourEOL, FALSE);
  115.          END;
  116.       END SendPacket;
  117.  
  118.  
  119.    PROCEDURE ReceivePacket (VAR r : PacketType) : BOOLEAN;
  120.    (* strips SOH and checksum -- returns status: TRUE = good packet     *)
  121.    (* received;  FALSE = timed out waiting for packet or checksum error *)
  122.  
  123.       VAR
  124.          sohtrys : INTEGER;
  125.          i, len : INTEGER;
  126.          ch : CHAR;
  127.          checksum : INTEGER;
  128.          mycheck, yourcheck : CHAR;
  129.  
  130.       BEGIN
  131.          sohtrys := MAXsohtrys;
  132.          REPEAT
  133.             StartTime;
  134.             REPEAT
  135.                status := GetChar (comport - COM_OFF, ch);
  136.             UNTIL (status = Success) OR (GetTime() > MAXtime);
  137.             ch := CHAR (ByteAnd (ch, 177C));   (* mask off MSB *)
  138.             (* skip over up to MAXsohtrys padding characters, *)
  139.             (* but allow only MAXsohtrys/10 timeouts          *)
  140.             IF status = Success THEN
  141.                DEC (sohtrys);
  142.             ELSE
  143.                DEC (sohtrys, 10);
  144.             END;
  145.          UNTIL (ch = ASCII.soh) OR (sohtrys <= 0);
  146.  
  147.          IF ch = ASCII.soh THEN
  148.             (* receive rest of packet *)
  149.             StartTime;
  150.             REPEAT
  151.                status := GetChar (comport - COM_OFF, ch);
  152.             UNTIL (status = Success) OR (GetTime() > MAXtime);
  153.             ch := CHAR (ByteAnd (ch, 177C));
  154.             len := UnChar (ch);
  155.             r[1] := ch;
  156.             checksum := ORD (ch);
  157.             i := 2;   (* on to second character in packet -- after LEN *)
  158.             REPEAT
  159.                StartTime;
  160.                REPEAT
  161.                   status := GetChar (comport - COM_OFF, ch);
  162.                UNTIL (status = Success) OR (GetTime() > MAXtime);
  163.                ch := CHAR (ByteAnd (ch, 177C));
  164.                r[i] := ch;   INC (i);
  165.                INC (checksum, (ORD (ch)));
  166.             UNTIL (i > len);
  167.             (* get checksum character *)
  168.             StartTime;
  169.             REPEAT
  170.                status := GetChar (comport - COM_OFF, ch);
  171.             UNTIL (status = Success) OR (GetTime() > MAXtime);
  172.             ch := CHAR (ByteAnd (ch, 177C));
  173.             yourcheck := ch;
  174.             r[i] := 0C;
  175.             checksum := checksum +
  176.                             (INTEGER (BITSET (checksum) * {7, 6}) DIV 64);
  177.             checksum := INTEGER (BITSET (checksum) *  {5, 4, 3, 2, 1, 0});
  178.             mycheck := Char (checksum);
  179.             IF mycheck = yourcheck THEN   (* checksum OK *)
  180.                RETURN TRUE;
  181.             ELSE   (* ERROR!!! *)
  182.                MP1.W1 := DL_BadCS;   MP1.W2 := 0;
  183.                MP2.L := 0;
  184.                WinPostMsg (ChildFrameWindow, WM_DL, MP1, MP2);
  185.                RETURN FALSE;
  186.             END;
  187.          ELSE
  188.             MP1.W1 := DL_NoSOH;   MP1.W2 := 0;
  189.             MP2.L := 0;
  190.             WinPostMsg (ChildFrameWindow, WM_DL, MP1, MP2);
  191.             RETURN FALSE;
  192.          END;
  193.       END ReceivePacket;
  194.  
  195.  
  196.    PROCEDURE DoDLMsg (mp1, mp2 [VALUE] : MPARAM);
  197.    (* Process DataLink Messages *)
  198.       BEGIN
  199.          CASE CARDINAL (mp1.W1) OF
  200.             DL_BadCS:
  201.                WriteString ("Bad Checksum");   WriteLn;
  202.          |  DL_NoSOH:
  203.                WriteString ("No SOH");   WriteLn;
  204.          ELSE
  205.             (* Do Nothing *)
  206.          END;
  207.       END DoDLMsg;
  208.  
  209. END DataLink.
  210.