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

  1. (**************************************************************************)
  2. (*                                                                        *)
  3. (*                     Copyright (c) 1988, 1989                           *)
  4. (*                      by Stony Brook Software                           *)
  5. (*                               and                                      *)
  6. (*                        Copyright (c) 1990                              *)
  7. (*                       by Brian R. Anderson                             *)
  8. (*                        All rights reserved.                            *)
  9. (*                                                                        *)
  10. (**************************************************************************)
  11.  
  12. IMPLEMENTATION MODULE CommPort [7];
  13.  
  14.    FROM SYSTEM IMPORT
  15.       ADR, BYTE, WORD, ADDRESS;
  16.  
  17.    FROM Storage IMPORT
  18.       ALLOCATE, DEALLOCATE;
  19.  
  20.    FROM DosCalls IMPORT
  21.       DosOpen, AttributeSet, DosDevIOCtl, DosClose, DosRead, DosWrite;
  22.  
  23.  
  24.    TYPE
  25.       CP = POINTER TO CHAR;
  26.  
  27.    VAR
  28.       pn : CARDINAL;
  29.       Handle : ARRAY [0..3] OF CARDINAL;
  30.       BufIn : ARRAY [0..3] OF CP;
  31.       BufOut : ARRAY [0..3] OF CP;
  32.       BufStart : ARRAY [0..3] OF CP;
  33.       BufLimit : ARRAY [0..3] OF CP;
  34.       BufSize : ARRAY [0..3] OF CARDINAL;
  35.       Temp : ARRAY [1..1024] OF CHAR;   (* size of OS/2's serial queue *)
  36.  
  37.  
  38.    PROCEDURE CheckPort (portnum : CARDINAL) : BOOLEAN;
  39.    (* Check for a valid port number and open the port if it not alredy open *)
  40.  
  41.       CONST
  42.          PortName : ARRAY [0..3] OF ARRAY [0..4] OF CHAR =
  43.             [['COM1', 0C], ['COM2', 0C], ['COM3', 0C], ['COM4', 0C]];
  44.  
  45.       VAR
  46.          Action : CARDINAL;
  47.  
  48.       BEGIN
  49.          (* check the port number *)
  50.          IF portnum > 3 THEN
  51.             RETURN FALSE;
  52.          END;
  53.  
  54.          (* attempt to open the port if it is not already open *)
  55.          IF Handle[portnum] = 0 THEN
  56.             IF DosOpen(ADR(PortName[portnum]), Handle[portnum], Action, 0,
  57.              AttributeSet{}, 1, 12H, 0) # 0 THEN
  58.                RETURN FALSE;
  59.             END;
  60.          END;
  61.          RETURN TRUE;
  62.       END CheckPort;
  63.  
  64.  
  65.  
  66.    PROCEDURE InitPort (portnum : CARDINAL; speed : BaudRate; data : DataBits;
  67.                          stop : StopBits; check : Parity) : CommStatus;
  68.    (* Initialize a port *)
  69.  
  70.       CONST
  71.          Rate : ARRAY BaudRate OF CARDINAL =
  72.                    [110, 150, 300, 600, 1200, 2400, 4800, 9600, 19200];
  73.          TransParity : ARRAY Parity OF BYTE = [2, 1, 0];
  74.  
  75.       TYPE
  76.          LineChar =  RECORD
  77.                         bDataBits : BYTE;
  78.                         bParity : BYTE;
  79.                         bStopBits : BYTE;
  80.                      END;
  81.  
  82.       VAR
  83.          LC : LineChar;
  84.  
  85.       BEGIN
  86.          (* Check the port number *)
  87.          IF NOT CheckPort(portnum) THEN
  88.             RETURN InvalidPort;
  89.          END;
  90.  
  91.          (* Set the baud rate *)
  92.          IF DosDevIOCtl(0, ADR(Rate[speed]), 41H, 1, Handle[portnum]) # 0 THEN
  93.             RETURN InvalidParameter;
  94.          END;
  95.  
  96.          (* set the characteristics *)
  97.          LC.bDataBits := BYTE(data);
  98.          IF stop = 1 THEN
  99.             DEC (stop);    (* 0x00 = 1 stop bits;    0x02 = 2 stop bits *)
  100.          END;
  101.          LC.bStopBits := BYTE(stop);
  102.          LC.bParity := TransParity[check];
  103.  
  104.          IF DosDevIOCtl(0, ADR(LC), 42H, 1, Handle[portnum]) # 0 THEN
  105.             RETURN InvalidParameter;
  106.          END;
  107.  
  108.          RETURN Success;
  109.       END InitPort;
  110.  
  111.  
  112.    PROCEDURE StartReceiving (portnum, bufsize : CARDINAL) : CommStatus;
  113.    (* Start receiving characters on a port *)
  114.       BEGIN
  115.          IF NOT CheckPort(portnum) THEN
  116.             RETURN InvalidPort;
  117.          END;
  118.          IF BufStart[portnum] # NIL THEN
  119.             RETURN AlreadyReceiving;
  120.          END;
  121.          ALLOCATE (BufStart[portnum], bufsize);
  122.          BufIn[portnum] := BufStart[portnum];
  123.          BufOut[portnum] := BufStart[portnum];
  124.          BufLimit[portnum] := BufStart[portnum];
  125.          INC (BufLimit[portnum]:ADDRESS, bufsize - 1);
  126.          BufSize[portnum] := bufsize;
  127.          RETURN Success;
  128.       END StartReceiving;
  129.  
  130.  
  131.    PROCEDURE StopReceiving (portnum : CARDINAL) : CommStatus;
  132.    (* Stop receiving characters on a port *)
  133.       BEGIN
  134.          IF NOT CheckPort(portnum) THEN
  135.             RETURN InvalidPort;
  136.          END;
  137.          IF BufStart[portnum] # NIL THEN
  138.             DEALLOCATE (BufStart[portnum], BufSize[portnum]);
  139.             BufLimit[portnum] := NIL;
  140.             BufIn[portnum] := NIL;
  141.             BufOut[portnum] := NIL;
  142.             BufSize[portnum] := 0;
  143.          END;
  144.          DosClose(Handle[portnum]);
  145.          Handle[portnum] := 0;
  146.          RETURN Success;
  147.       END StopReceiving;
  148.  
  149.  
  150.    PROCEDURE GetChar (portnum : CARDINAL; VAR ch : CHAR) : CommStatus;
  151.    (* Get a character from the comm port *)
  152.  
  153.       VAR
  154.          status : CARDINAL;
  155.          read : CARDINAL;
  156.          que : RECORD
  157.                   ct : CARDINAL;
  158.                   sz : CARDINAL;
  159.                END;
  160.          i : CARDINAL;
  161.  
  162.       BEGIN
  163.          IF BufStart[portnum] = NIL THEN
  164.             RETURN NotReceiving;
  165.          END;
  166.          IF NOT CheckPort(portnum) THEN
  167.             RETURN InvalidPort;
  168.          END;
  169.          status := DosDevIOCtl (ADR (que), 0, 68H, 1, Handle[portnum]);
  170.          IF (status = 0) AND (que.ct # 0) THEN
  171.             status := DosRead (Handle[portnum], ADR (Temp), que.ct, read);
  172.             IF (status # 0) OR (read = 0) THEN
  173.                RETURN NotReceiving;
  174.             END;
  175.             FOR i := 1 TO read DO
  176.                BufIn[portnum]^ := Temp[i];
  177.                IF BufIn[portnum] = BufLimit[portnum] THEN
  178.                   BufIn[portnum] := BufStart[portnum];
  179.                ELSE
  180.                   INC (BufIn[portnum]:ADDRESS);
  181.                END;
  182.                IF BufIn[portnum] = BufOut[portnum] THEN
  183.                   RETURN BufferOverflow;
  184.                END;
  185.             END;
  186.          END;
  187.  
  188.          IF BufIn[portnum] = BufOut[portnum] THEN
  189.             RETURN NoCharacter;
  190.          END;
  191.          ch := BufOut[portnum]^;
  192.          IF BufOut[portnum] = BufLimit[portnum] THEN
  193.             BufOut[portnum] := BufStart[portnum];
  194.          ELSE
  195.             INC (BufOut[portnum]:ADDRESS);
  196.          END;
  197.          RETURN Success;
  198.       END GetChar;
  199.  
  200.  
  201.    PROCEDURE SendChar (portnum : CARDINAL; ch : CHAR;
  202.                          modem : BOOLEAN) : CommStatus;
  203.    (* send a character to the comm port *)
  204.  
  205.       VAR
  206.          wrote : CARDINAL;
  207.          status : CARDINAL;
  208.          commSt : CHAR;
  209.  
  210.       BEGIN
  211.          IF NOT CheckPort(portnum) THEN
  212.             RETURN InvalidPort;
  213.          END;
  214.          status := DosDevIOCtl (ADR (commSt), 0, 64H, 1, Handle[portnum]);
  215.          IF (status # 0) OR (commSt # 0C) THEN
  216.             RETURN TimeOut;
  217.          ELSE
  218.             status := DosWrite(Handle[portnum], ADR(ch), 1, wrote);
  219.             IF (status # 0) OR (wrote # 1) THEN
  220.                RETURN TimeOut;
  221.             ELSE
  222.                RETURN Success;
  223.             END;
  224.          END;
  225.       END SendChar;
  226.  
  227.  
  228. BEGIN   (* module initialization *)
  229.    (* nothing open yet *)
  230.    FOR pn := 0 TO 3 DO
  231.       Handle[pn] := 0;
  232.       BufStart[pn] := NIL;
  233.       BufLimit[pn] := NIL;
  234.       BufIn[pn] := NIL;
  235.       BufOut[pn] := NIL;
  236.       BufSize[pn] := 0;
  237.    END;
  238. END CommPort.
  239.