    {----------------------------------------------------------------------}
    {   Asynchronous I/O routines of the Split-Screen Server (SSS)         }
    {----------------------------------------------------------------------}
    {                                                                      }
    {  Author:  Philip R. Burns ("PIBASYNC.PAS", from SIG disk)            }
    {  Date:    January, 1985                                              }
    {  Version: 1.0                                                        }
    {  Systems: For MS-DOS on IBM PCs and close compatibles only.          }
    {                                                                      }
    {  Modified (adapted) by HB9CVV                                        }
    {                                                                      }
    {----------------------------------------------------------------------}
    {                                                                      }
    {  Routines:                                                           }
    {                                                                      }
    {     Async_Init             ---    Performs initialization.           }
    {     Async_Open             ---    Sets up COM port                   }
    {     Async_Close            ---    Closes down COM port               }
    {     Async_Buffer_Check     ---    Checks if character in COM buffer  }
    {     Async_Receive          ---    Reads character from COM buffer    }
    {     Async_Send             ---    Transmits char over COM port       }
    {----------------------------------------------------------------------}


    {----------------------------------------------------------------------}
    {                                                                      }
    {                  COMMUNICATIONS HARDWARE ADDRESSES                   }
    {                                                                      }
    {        These are specific to IBM PCs and close compatibles.          }
    {                                                                      }
    {----------------------------------------------------------------------}

  TYPE RegPack =
    RECORD AX, BX, CX, DX, BP, SI, DI, DS, ES, FLAGS : Integer
    END;

  CONST

    UART_THR = $00;                     { offset from base of UART Registers for IBM PC }
    UART_RBR = $00;
    UART_IER = $01;
    UART_IIR = $02;
    UART_LCR = $03;
    UART_MCR = $04;
    UART_LSR = $05;
    UART_MSR = $06;
    UART_DLL = $00;
    UART_DLM = $01;

    I8088_IMR = $21;                    { port address of the Interrupt Mask Register }

    COM_Base : ARRAY[1..6] OF Integer =

    ($03F8, { COM1 }                    { Address of the UART }
    $02F8,                              { COM2 }
    $03E8,                              { COM3 }
    $03E0,                              { COM4 }
    $02F0,                              { COM5 }
    $02E8);                             { COM6 }

    COM_Irq : ARRAY[1..6] OF Integer =

    (4, { COM1 }                        { Interrupt Line for the UART }
    3,                                  { COM2 }
    4,                                  { COM3 }
    3,                                  { COM4 }
    4,                                  { COM5 }
    3);                                 { COM6 }

  CONST

    Async_DSeg_Save : Integer = 0;      { Save DS reg in Code Segment for }
    { interrupt routine               }

    {----------------------------------------------------------------------}
    {                                                                      }
    {                   COMMUNICATIONS BUFFER VARIABLES                    }
    {                                                                      }
    {     The Communications Buffer is implemented as a circular (ring)    }
    {     buffer, or double-ended queue.  The asynchronous I/O routines    }
    {     enter characters in the buffer as they are received.  Higher-    }
    {     level routines may extract characters from the buffer.           }
    {                                                                      }
    {     Note that this buffer is used for input only;  output is done    }
    {     on a character-by-character basis.                               }
    {                                                                      }
    {----------------------------------------------------------------------}

  CONST

    Async_Buffer_Max = 8191;            { Size of Communications Buffer   }
    Async_Loops_Per_Sec = 6500;         { Loops per second -- 4.77 clock  }
    TimeOut = 256;                      { TimeOut value                   }

  VAR
    { Communications Buffer Itself }

    Async_Buffer : ARRAY[0..Async_Buffer_Max] OF Char;

    Async_Open_Flag : Boolean;          { true if Open but no Close         }
    Async_Port : Integer;               { current Open port number (1 or 2) }
    Async_Base : Integer;               { base for current open port        }
    Async_Irq : Integer;                { irq for current open port         }

    Async_Buffer_Overflow : Boolean;    { True if buffer overflow has happened }
    Async_Buffer_Used : Integer;
    Async_MaxBufferUsed : Integer;

    { Async_Buffer empty if Head = Tail    }
    Async_Buffer_Head : Integer;        { Loc in Async_Buffer to put next char }
    Async_Buffer_Tail : Integer;        { Loc in Async_Buffer to get next char }
    Async_Buffer_NewTail : Integer;

    Async_SaveVector_CS : Integer;      { Saved segment of Interrupt routine }
    Async_SaveVector_IP : Integer;      { Saved offset of Interrupt routine }

    Async_Blocked : Boolean;            { TRUE if ^S received, reset by ^Q }

    {----------------------------------------------------------------------}
    {             DOS_Set_Intrpt --- Call DOS to set interrupt vector      }
    {----------------------------------------------------------------------}

  PROCEDURE DOS_Set_Intrpt(v, s, o : Integer);

      {                                                                      }
      {     Procedure:  DOS_Set_Intrpt                                       }
      {                                                                      }
      {     Purpose:    Calls DOS to set interrupt vector                    }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        DOS_Set_Intrpt( v, s, o : Integer );                          }
      {                                                                      }
      {           v --- interrupt vector number to set                       }
      {           s --- segment address of interrupt routine                 }
      {           o --- offset address of interrupt routine                  }
      {                                                                      }
      {      Calls:   MSDOS   (to set interrupt)                             }
      {                                                                      }

    VAR
      Regs : Regpack;

    BEGIN                               { DOS_Set_Intrpt }

      INLINE($FA);                      {  cli        disable interrupts       }
      WITH Regs DO
        BEGIN
          Ax := $3500+(v AND $00FF);
          MsDos(Regs);                  {  DOS function 35 - get vector        }
          Ds := s;
          Dx := o;
          Async_SaveVector_CS := Es;
          Async_SaveVector_IP := Bx;
          Ax := $2500+(v AND $00FF);
          MsDos(Regs);
        END;
      INLINE($FB);                      {  sti        re-enable ints           }

    END { DOS_Set_Intrpt } ;

    {----------------------------------------------------------------------}
    {               Async_Isr --- Interrupt Service Routine                }
    {----------------------------------------------------------------------}

  PROCEDURE Async_Isr;

      {                                                                      }
      {     Procedure:  Async_Isr                                            }
      {                                                                      }
      {     Purpose:    Invoked when UART has received character from        }
      {                 communications line  (asynchronous)                  }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Async_Isr;                                                    }
      {                                                                      }
      {           --- Called asyncronously only!!!!!!                        }
      {                                                                      }
      {     Remarks:                                                         }
      {                                                                      }
      {        This is Michael Quinlan's version of the interrupt handler.   }
      {                                                                      }

    BEGIN                               { Async_Isr }

      {  NOTE: on entry, Turbo Pascal has already PUSHed BP and SP  }

      INLINE(
        { save all registers used }
        $50/                            { PUSH AX }
        $53/                            { PUSH BX }
        $52/                            { PUSH DX }
        $1E/                            { PUSH DS }
        $FB/                            { STI }
        { set up the DS register to point to Turbo Pascal's data segment }
        $2E/$FF/$36/Async_Dseg_Save/    { PUSH CS:Async_Dseg_Save }
        $1F/                            { POP DS }
        { get the incomming character }
        { Async_Buffer[Async_Buffer_Head] := Chr(Port[UART_RBR + Async_Base]); }
        $8B/$16/Async_Base/             { MOV DX,Async_Base }
        $EC/                            { IN AL,DX }
        $8B/$1E/Async_Buffer_Head/      { MOV BX,Async_Buffer_Head }
        $88/$87/Async_Buffer/           { MOV Async_Buffer[BX],AL }

        { if chr=^S THEN Async_Blocked := TRUE
        if chr=^Q THEN Async_Blocked := FALSE }

        $3C/$13/                        { CMP AL,013H }
        $75/$07/                        { JNE Z001 }
        $C6/$06/Async_Blocked/$01/      { MOV Async_Blocked,1 }
        $EB/$09/                        { JMP Z002 }
        {Z001:}
        $3C/$11/                        { CMP AL,011H }
        $75/$05/                        { JNE Z002 }
        $C6/$06/Async_Blocked/$00/      { MOV Async_Blocked,0 }
        {Z002:}

        { Async_Buffer_NewHead := Async_Buffer_Head + 1; }
        $43/                            { INC BX }
        { if Async_Buffer_NewHead > Async_Buffer_Max then
        Async_Buffer_NewHead := 0; }
        $81/$FB/Async_Buffer_Max/       { CMP BX,Async_Buffer_Max }
        $7E/$02/                        { JLE L001 }
        $33/$DB/                        { XOR BX,BX }
        { if Async_Buffer_NewHead = Async_Buffer_Tail then
        Async_Buffer_Overflow := TRUE
        else }
        {L001:}
        $3B/$1E/Async_Buffer_Tail/      { CMP BX,Async_Buffer_Tail }
        $75/$08/                        { JNE L002 }
        $C6/$06/Async_Buffer_Overflow/$01/ { MOV Async_Buffer_Overflow,1 }
        $90/                            { NOP generated by assembler for some reason }
        $EB/$16/                        { JMP SHORT L003 }
        { begin
        Async_Buffer_Head := Async_Buffer_NewHead;
        Async_Buffer_Used := Async_Buffer_Used + 1;
        if Async_Buffer_Used > Async_MaxBufferUsed then 
        Async_MaxBufferUsed := Async_Buffer_Used
        end; }
        {L002:}
        $89/$1E/Async_Buffer_Head/      { MOV Async_Buffer_Head,BX }
        $FF/$06/Async_Buffer_Used/      { INC Async_Buffer_Used }
        $8B/$1E/Async_Buffer_Used/      { MOV BX,Async_Buffer_Used }
        $3B/$1E/Async_MaxBufferUsed/    { CMP BX,Async_MaxBufferUsed }
        $7E/$04/                        { JLE L003 }
        $89/$1E/Async_MaxBufferUsed/    { MOV Async_MaxBufferUsed,BX }
        {L003:}
        { disable interrupts }
        $FA/                            { CLI }
        { Port[$20] := $20; }           { use non-specific EOI }
        $B0/$20/                        { MOV AL,20h }
        $E6/$20/                        { OUT 20h,AL }
        { restore the registers then use IRET to return }
        { the last two POPs are required because Turbo Pascal PUSHes these regs
        before we get control.  The manual doesn't say so, but that is what
        really happens }
        $1F/                            { POP DS }
        $5A/                            { POP DX }
        $5B/                            { POP BX }
        $58/                            { POP AX }
        $5C/                            { POP SP }
        $5D/                            { POP BP }
        $CF)                            { IRET }

    END { Async_Isr } ;

    {----------------------------------------------------------------------}
    {               Async_Init --- Initialize Asynchronous Variables       }
    {----------------------------------------------------------------------}

  PROCEDURE Async_Init;

      {                                                                      }
      {     Procedure:  Async_Init                                           }
      {                                                                      }
      {     Purpose:    Initializes variables                                }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Async_Init;                                                   }
      {                                                                      }
      {     Calls:  None                                                     }
      {                                                                      }

    BEGIN                               { Async_Init }

      Async_DSeg_Save := DSeg;
      Async_Open_Flag := False;
      Async_Buffer_Overflow := False;
      Async_Buffer_Used := 0;
      Async_MaxBufferUsed := 0;
      Async_Blocked := False;

    END { Async_Init } ;

    {----------------------------------------------------------------------}
    {               Async_Close --- Close down communications interrupts   }
    {----------------------------------------------------------------------}

  PROCEDURE Async_Close;

      {                                                                      }
      {     Procedure:  Async_Close                                          }
      {                                                                      }
      {     Purpose:    Resets interrupt system when UART interrupts         }
      {                 are no longer needed.                                }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Async_Close;                                                  }
      {                                                                      }
      {     Calls:  None                                                     }
      {                                                                      }

    VAR
      i : Integer;
      m : Integer;

    BEGIN                               { Async_Close }

      IF Async_Open_Flag THEN
        BEGIN

          { disable the IRQ on the 8259 }

          INLINE($FA);                  { disable interrupts }

          i := Port[I8088_IMR];         { get the interrupt mask register }
          m := 1 SHL Async_Irq;         { set mask to turn off interrupt  }
          Port[I8088_IMR] := i OR m;

          { disable the 8250 data ready interrupt }

          Port[UART_IER+Async_Base] := 0;

          { disable OUT2 on the 8250 }

          Port[UART_MCR+Async_Base] := 0;

          DOS_Set_Intrpt(Async_Irq+8, Async_SaveVector_CS, Async_SaveVector_IP);

          INLINE($FB);                  { enable interrupts }

          { re-initialize our data areas so we know }
          { the port is closed                      }

          Async_Open_Flag := False;

        END;

    END { Async_Close } ;

    {----------------------------------------------------------------------}
    {               Async_Open --- Open communications port                }
    {----------------------------------------------------------------------}

  FUNCTION Async_Open(ComPort : Integer;
                      BaudRate : Integer;
                      Parity : Char;
                      WordSize : Integer;
                      StopBits : Integer) : Boolean;

      {                                                                      }
      {     Function:   Async_Open                                           }
      {                                                                      }
      {     Purpose:    Opens communications port                            }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Flag := Async_Open( ComPort       : Integer;                  }
      {                            BaudRate      : Integer;                  }
      {                            Parity        : Char;                     }
      {                            WordSize      : Integer;                  }
      {                            StopBits      : Integer) : Boolean;       }
      {                                                                      }
      {           ComPort  --- which port (1 or 2)                           }
      {           BaudRate --- Baud rate (110 to 9600)                       }
      {           Parity   --- "E" for even, "O" for odd, "N" for none       }
      {           WordSize --- Bits per character  (5 through 8)             }
      {           StopBits --- How many stop bits  (1 or 2)                  }
      {                                                                      }
      {           Flag returned TRUE if port initialized successfully;       }
      {           Flag returned FALSE if any errors.                         }
      {                                                                      }
      {     Calls:                                                           }
      {                                                                      }
      {        DOS_Set_Intrpt  --- set address of RS232 interrupt routine    }
      {                                                                      }

    CONST                               { Baud Rate Constants }

      Async_Num_Bauds = 8;

      Async_Baud_Table : ARRAY[1..Async_Num_Bauds] OF RECORD
                                                         Baud, Bits : Integer;
                                                       END

                                                       = ((Baud : 110; Bits : $417),
                                                       (Baud : 150; Bits : $300),
                                                       (Baud : 300; Bits : $180),
                                                       (Baud : 600; Bits : $0C0),
                                                       (Baud : 1200; Bits : $060),
                                                       (Baud : 2400; Bits : $030),
                                                       (Baud : 4800; Bits : $018),
                                                       (Baud : 9600; Bits : $00C));

    VAR
      ComBaud, ComParm : Integer;
      i : Integer;
      m : Integer;

    BEGIN                               { Async_Open }

      { If port open, close it down first. }

      IF Async_Open_Flag THEN Async_Close;

      { Choose communications port }

      Async_Port := ComPort;
      Async_Base := COM_Base[ComPort];
      Async_Irq := COM_Irq[ComPort];


      IF (Port[UART_IIR+Async_Base] AND $00F8) <> 0 THEN
        Async_Open := False             { Serial port not installed }
      ELSE
        BEGIN                           { Open the port }

          { Set buffer pointers }

          Async_Buffer_Head := 0;
          Async_Buffer_Tail := 0;
          Async_Buffer_Overflow := False;

          {---------------------------------------------------}
          {    Build the ComParams to init the UART           }
          {---------------------------------------------------}

          { Set up the bits for the baud rate }

          IF BaudRate > 9600 THEN
            BaudRate := 9600
          ELSE IF BaudRate <= 0 THEN
            BaudRate := 300;

          i := 0;

          REPEAT
            i := i+1
          UNTIL ((i >= Async_Num_Bauds) OR
          (BaudRate = Async_Baud_Table[i].Baud));

          ComBaud := Async_Baud_Table[i].Bits;

          { Choose Parity }

          ComParm := $00;               { Assume no parity }
          IF Parity IN ['E', 'e'] THEN
            ComParm := $0018
          ELSE IF Parity IN ['O', 'o'] THEN
            ComParm := $0008;

          { Choose number of data bits }

          WordSize := WordSize-5;

          IF (WordSize < 0) OR (WordSize > 3) THEN
            WordSize := 3;

          ComParm := ComParm OR WordSize;

          { Choose stop bits }

          IF StopBits = 2 THEN
            ComParm := ComParm OR $0004; { default is 1 stop bit }

          DOS_Set_Intrpt(Async_Irq+8, CSeg, Ofs(Async_Isr));

          INLINE($FA);                  { disable interrupts }

          { Set the parity, datalength, stopbits and baudrate }
          { Turn on Divisor Access Latch Bit first            }

          ComParm := ComParm OR $80;
          Port[UART_LCR+Async_Base] := ComParm;
          Port[UART_DLM+Async_Base] := Hi(ComBaud);
          Port[UART_DLL+Async_Base] := Lo(ComBaud);

          { Read the RBR and reset any pending error conditions. }
          { First turn off the Divisor Access Latch Bit to allow }
          { access to RBR, etc.                                  }

          Port[UART_LCR+Async_Base] := Port[UART_LCR+Async_Base] AND $7F;

          { Read the Line Status Register to reset any errors }
          { it indicates                                      }

          i := Port[UART_LSR+Async_Base];

          { Read the Receiver Buffer Register in case it }
          { contains a character                         }

          i := Port[UART_RBR+Async_Base];

          { enable the irq on the 8259 controller }

          i := Port[I8088_IMR];         { get the interrupt mask register }
          m := (1 SHL Async_Irq) XOR $00FF;

          Port[I8088_IMR] := i AND m;

          { enable the data ready interrupt on the 8250 }

          Port[UART_IER+Async_Base] := $01;

          { enable OUT2 on 8250 }

          i := Port[UART_MCR+Async_Base];
          Port[UART_MCR+Async_Base] := i OR $08;


          INLINE($FB);                  { enable interrupts }

          Async_Open := True;
          Async_Open_Flag := True;

        END;

    END { Async_Open } ;

    {----------------------------------------------------------------------}
    {          Async_Buffer_Check --- Check if character in buffer         }
    {----------------------------------------------------------------------}

  FUNCTION Async_Buffer_Check : Boolean;

      {                                                                      }
      {     Function:   Async_Buffer_Check                                   }
      {                                                                      }
      {     Purpose:    Check if character in buffer                         }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Flag := Async_Buffer_Check : Boolean;                         }
      {                                                                      }
      {           Flag returned TRUE if character received in buffer,        }
      {           Flag returned FALSE if no character received.              }
      {                                                                      }
      {     Calls:  None                                                     }
      {                                                                      }
      {     Remarks:                                                         }
      {                                                                      }
      {       This routine only checks if a character has been received      }
      {       and thus can be read; it does NOT return the character.        }
      {       Use Async_Receive to read the character.                       }
      {                                                                      }

    BEGIN                               { Async_Buffer_Check }

      Async_Buffer_Check := (Async_Buffer_Head <> Async_Buffer_Tail);

    END { Async_Buffer_Check } ;

    {----------------------------------------------------------------------}
    {          Async_Receive --- Return character from buffer              }
    {----------------------------------------------------------------------}

  FUNCTION Async_Receive(VAR C : Char) : Boolean;

      {                                                                      }
      {     Function:   Async_Receive                                        }
      {                                                                      }
      {     Purpose:    Retrieve character (if any) from buffer              }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Flag := Async_Receive( Var C: Char ) : Boolean;               }
      {                                                                      }
      {           C --- character (if any) retrieved from buffer;            }
      {                 set to CHR(0) if no character available.             }
      {                                                                      }
      {           Flag returned TRUE if character retrieved from buffer,     }
      {           Flag returned FALSE if no character retrieved.             }
      {                                                                      }
      {     Calls:  None                                                     }
      {                                                                      }

    BEGIN                               { Async_Receive }

      IF Async_Buffer_Head = Async_Buffer_Tail THEN
        BEGIN                           { No character to retrieve }

          Async_Receive := False;
          C := Chr(0);

        END                             { No character available   }

      ELSE
        BEGIN                           { Character available }

          { Turn off interrupts }

          INLINE($FA);                  { CLI --- Turn off interrupts }

          { Get character from buffer }

          C := Async_Buffer[Async_Buffer_Tail];

          { Increment buffer pointer.   If past }
          { end of buffer, reset to beginning.  }

          Async_Buffer_Tail := Async_Buffer_Tail+1;

          IF Async_Buffer_Tail > Async_Buffer_Max THEN
            Async_Buffer_Tail := 0;

          { Decrement buffer use count }

          Async_Buffer_Used := Async_Buffer_Used-1;

          { Turn on interrupts }

          INLINE($FB);                  { STI --- Turn on interrupts }

          { Indicate character successfully retrieved }

          Async_Receive := True;

        END { Character available } ;

      C := Chr(Ord(C) AND $7F);

    END { Async_Receive } ;

    {----------------------------------------------------------------------}
    {          Async_Send --- Send character over communications port      }
    {----------------------------------------------------------------------}

  PROCEDURE Async_Send(C : Char);

      {                                                                      }
      {     Procedure:  Async_Send                                           }
      {                                                                      }
      {     Purpose:    Sends character out over communications port         }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Async_Send( C : Char );                                       }
      {                                                                      }
      {           C --- Character to send                                    }
      {                                                                      }
      {     Calls:  None                                                     }
      {                                                                      }

    VAR
      i : Integer;
      m : Integer;
      Counter : Integer;

    BEGIN                               { Async_Send }

      { Turn on OUT2, DTR, and RTS }

      Port[UART_MCR+Async_Base] := $0B;

      { Wait for CTS using Busy Wait }

      Counter := MaxInt;

      WHILE (Counter <> 0) AND
      ((Port[UART_MSR+Async_Base] AND $10) = 0) DO
        Counter := Counter-1;

      { Wait for Transmit Hold Register Empty (THRE) }

      IF Counter <> 0 THEN Counter := MaxInt;

      WHILE (Counter <> 0) AND
      ((Port[UART_LSR+Async_Base] AND $20) = 0) DO
        Counter := Counter-1;

      { Send the character if port clear }

      IF Counter <> 0 THEN
        BEGIN                           { Send the Character }

          INLINE($FA);                  { CLI --- disable interrupts }

          Port[UART_THR+Async_Base] := Ord(C);

          INLINE($FB);                  { STI --- enable interrupts }

        END                             { Send the Character }

      ELSE                              { Timed Out }
        WriteLn('<<< Com-port character write: TIMEOUT >>>');

    END { Async_Send } ;

    {----------------------------------------------------------------------}
    {     Async_Send_String --- Send string over communications port       }
    {----------------------------------------------------------------------}

  PROCEDURE Async_Send_String(S : MaxString);

      {                                                                      }
      {     Procedure:  Async_Send_String                                    }
      {                                                                      }
      {     Purpose:    Sends string out over communications port            }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Async_Send_String( S : AnyStr );                              }
      {                                                                      }
      {           S --- String to send                                       }
      {                                                                      }
      {     Calls:  Async_Send                                               }
      {                                                                      }

    VAR
      i : Integer;

    BEGIN                               { Async_Send_String }

      FOR i := 1 TO Length(S) DO BEGIN
        Async_Send(S[i]);
        IF (i MOD 80) = 0 THEN Delay(250);
      END;
    END { Async_Send_String } ;

    {----------------------------------------------------------------------}
    {     Async_Purge_Buffer --- Purge communications input buffer         }
    {----------------------------------------------------------------------}

  PROCEDURE Async_Purge_Buffer;

      {                                                                      }
      {     Procedure:  Async_Purge_Buffer                                   }
      {                                                                      }
      {     Purpose:    Purges communications input buffer                   }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Async_Purge_Buffer;                                           }
      {                                                                      }
      {     Calls:  Async_Receive                                            }
      {                                                                      }

    VAR
      C : Char;

    BEGIN                               { Async_Purge_Buffer }

      REPEAT
        Delay(1);
      UNTIL (NOT Async_Receive(C));

    END { Async_Purge_Buffer } ;

    {----------------------------------------------------------------------}
    {      Async_CTS_On --- Check for CTS on                               }
    {----------------------------------------------------------------------}

  FUNCTION Async_CTS_On : Boolean;

      {                                                                      }
      {     Function:   Async_CTS_on                                         }
      {                                                                      }
      {     Purpose:    Looks for CTS line state                             }
      {                                                                      }
      {     Calling Sequence:                                                }
      {                                                                      }
      {        Flag := Async_CTS_On : Boolean;                               }
      {                                                                      }
      {           Flag is set TRUE if CTS is On, else FALSE.                 }
      {                                                                      }
      {     Calls:  None                                                     }
      {                                                                      }

    VAR Tmp : Boolean;

    BEGIN                               { Async_CTS_On }

      Tmp := Odd(Port[UART_MSR+Async_Base] SHR 4);
      Async_CTS_On := Tmp AND (NOT Async_Blocked);

    END { Async_CTS_On } ;

