[Back to COMM SWAG index] [Back to Main SWAG index] [Original]

    {
     *  Interface unit for the X00 device driver. This unit supports all
     *  comm fossil calls needed to do most communication tasks.
     *
     *  Author  Gordon Tackett
     *  Date    01-31-91
     *
     *  $Revision:   1.0  $
    }

    {$IFDEF LOCAL}

    Program X00;

    {$ELSE}

    Unit X00;

    Interface

    {$ENDIF}

    Uses Dos;

    Type

      {
      * Driver Information Block.
      *    This record holds all of the current settings from the
      *    X00 driver after a call to funciton $1B
      }
      DvrInfo = Record
          Size  : Word;
          Spec  : byte;
          Rev   : Byte;
          ID    : Pointer;
          Ibuf  : Word;
          Iavl  : Word;
          OBuf  : Word;
          Oavl  : Word;
          Width : Byte;
          Height: Byte;
          Baud  : Byte;
        End;

      {
      * Timer Fuctions & Pointers
      *    This procedure type is used to define a pointer the the procedure
      *    that may be sent to the X00 driver for calling during a timer
      *    tick. These procedures must be declared far
      }
      TimerFunction = Procedure;
      TimerFunctionPtr = ^TimerFunction;

      {
      *  X00 Driver object
      *    This is the main object for this module. It has all the interface
      *    routines and data needed to call all the major functions of the
      *    X00 device driver.
      }
      X00Dvr = Object
        Port        : Word;
        Baud        : Word;
        Size        : Word;
        Parity      : Char;
        Stops       : Word;
        Status      : Word;
        MaxFuncs    : Word;
        RevLevel    : Word;
        CtrlCFlags  : Byte;
        CurInfo     : DvrInfo;

        Constructor Init(Prt,Bd,Sz : Word; Prty : Char; StpBts : Word);
        Function    GetLastStatus : Word;
        Function    GetInfoSize : Word;
        Function    GetInfoSpec : Word;
        Function    GetInfoRev  : Word;
        Function    GetInfoId   : Pointer;
        Function    GetInfoIbuf : Word;
        Function    GetInfoIavl : Word;
        Function    GetInfoOBuf : Word;
        Function    GetInfoOAvl : Word;
        Function    GetInfoCrtW : Word;
        Function    GetInfoCrtH : Word;
        Function    GetInfoBaud : Word;
        Function    GetPort     : Word;
        Function    GetBaud     : Word;
        Function    GetSize     : Word;
        Function    GetParity   : Char;
        Function    GetStops    : Word;
        Function    GetMaxFuncs : Word;
        Function    GetRevLevel : Word;

        Procedure   SetBaud(Bd,Sz : Word; Prty : Char; StpBts : Word);
        Procedure   TxChar(Ch : Char);
        Function    RxChar : Char;
        Function    GetStatus : Word;
        Procedure   InitFossil;
        Procedure   DeinitFossil;
        Procedure   DropDTR;
        Procedure   RaseDTR;
        Procedure   SystemTimerParams(Var TicksPerSec,MsPerTick : Word);
        Procedure   FlushBuffer;
        Procedure   PurgeOutputBuffer;
        Procedure   PurgeInputBuffer;
        Procedure   TxCharNoWait(Ch : Char);
        Function    RXPeekChar(Var Ch : Char) : Boolean;
        Function    KBPeekChar(Var Ch : Word) : Boolean;
        Function    KBRead : Word;
        Procedure   FlowControl(XONCTS : Byte);
        Procedure   CtrlCChkOn;
        Procedure   CtrlCChkOff;
        Procedure   XmitOff;
        Procedure   XmitOn;
        Procedure   GotoXY(X,Y : Word);
        Procedure   GetCursorLoc(Var X,Y : Word);
        Procedure   AnsiWriteChar(Ch : Char);
        Procedure   EnableWatchDog;
        Procedure   DisableWatchDog;
        Procedure   WriteChar(Ch : Char);
        Function    InsertTimerFunction(TF : TimerFunctionPtr) : Boolean;
        Function    DeleteTimerFunction(TF : TimerFunctionPtr) : Boolean;
        Procedure   Reboot(Tp : Boolean);
        Procedure   RecvBuffer(Buffer : Pointer; Var Sz : Word);
        Procedure   SendBuffer(Buffer : Pointer; Sz : Word);
        Procedure   StopBreak;
        Procedure   GetInfo;
        {7e}
        {7f}
      End;

    Const
      OutputBuffEmpty    = $4000;
      OutputBuffNotFull  = $2000;
      InputBuffOverrun   = $0200;
      CharInInputBuff    = $0100;
      CarrierDetect      = $0080;
      TxXonXoff          = $01;
      TXCts              = $02;
      RxXonXoff          = $03;

    Var
      Comm1 : X00Dvr;
      Comm2 : X00Dvr;

    {$IFNDEF LOCAL}

    Implementation

    {$ENDIF}

    Var
      Regs : Registers; { register structure used in X00 calls}

    Const
      CommVect = $14;          {X00 interrupt vector}

    {
    *  Init - set up object and init port.
    * This routine will clear unused bytes to 0 and will init the
    * X00 fossil driver to the baud,size,parity,and stops as needed
    * by the user application.
    -----------------------------------------------------------------------------}
    Constructor X00Dvr.Init(Prt,Bd,Sz : Word; Prty : Char; StpBts : Word);
      Begin
        Port := Prt;
        CtrlCFlags := 0;
        InitFossil;
        If MaxFuncs = 0 Then
            Exit;
        SetBaud(Bd,Sz,Prty,StpBts);
      End;

    {
    * Get Last Status
    *
    * Interface function to get a copy of the status word storied in the
    * object body.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetLastStatus : Word;
      Begin
        GetLastStatus := Status;
      End;

    {
    * Get Information Size
    *
    * Interface function to get a copy of the word size from the info block.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoSize : Word;
      Begin
        GetInfoSize := CurInfo.Size;
      End;

    {
    * Get Information Specification
    *
    * Interface function to get a copy of the fossil interface spec supported
    * by this driver.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoSpec : Word;
      Begin
        GetInfoSpec := CurInfo.Spec;
      End;

    {
    * Get Information Revision
    *
    * Interface function to get a copy of the fossil document revision supported
    * by this driver.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoRev : Word;
      Begin
        GetInfoRev := CurInfo.Rev;
      End;

    {
    * Get Information ID
    *
    * Interface function to get a copy of the pointer to the ascii
    * string containing the name of the driver.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoId : Pointer;
      Begin
        GetInfoId := CurInfo.Id;
      End;

    {
    * Get Information Input Buffer Size
    *
    * Interface function to get a copy of the size of the input buffer
    * in bytes.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoIbuf : Word;
      Begin
        GetInfoIBuf := CurInfo.IBuf;
      End;

    {
    * Get Information Input Buffer Avaliable
    *
    * Interface function to get a copy of the amount of input buffer that is
    * avaliable for use.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoIavl : Word;
      Begin
        GetInfoIavl := CurInfo.Iavl;
      End;

    {
    * Get Information Output Buffer Size
    *
    * Interface function to get a copy of the size of the output buffer
    * in bytes.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoOBuf : Word;
      Begin
        GetInfoOBuf := CurInfo.OBuf;
      End;

    {
    * Get Information Output Buffer Avaliable
    *
    * Interface function to get a copy of the amount of Output buffer that is
    * avaliable for use.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoOAvl : Word;
      Begin
        GetInfoOAvl := CurInfo.OAvl;
      End;

    {
    * Get Information Current CRT Width
    *
    * Interface function to get a copy of the width of the CRT
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoCrtW : Word;
      Begin
        GetInfoCrtW := CurInfo.Width;
      End;

    {
    * Get Information Current CRT Height
    *
    * Interface funciton to get a copy of the height of the CRT
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoCrtH : Word;
      Begin
        GetInfoCrtH := CurInfo.Height;
      End;

    {
    * Get Information Current Baud Rate
    *
    * Interface function to get a copy of the current baud rate as returned
    * in the curinfo structure.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetInfoBaud : Word;
      Begin
        GetInfoBaud := CurInfo.Baud;
      End;

    {
    * Get the port number
    *
    * Interface function to return the port number that was used to call
    * the constructor Init. Once this constructor is called the port value
    * can't be changed.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetPort : Word;
      Begin
        GetPort := Port;
      End;

    {
    * Get the Baud Rate
    *
    * Interface function that is used to get the last baud rate sent to
    * this object from an application. This may not be the current correct
    * baud rate.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetBaud : Word;
      Begin
        GetBaud := Baud;
      End;

    {
    * Get the Word Size
    *
    * Interface function that is used to get the last word size sent to
    * this object from an application. This is always correct
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetSize : Word;
      Begin
        GetSize := Size;
      End;

    {
    * Get the Parity
    *
    * Interface function that is used to get the last parity value that was
    * sent to this object from an application. this is always correct.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetParity : Char;
      Begin
        GetParity := Parity;
      End;

    {
    * Get Stop Bits
    *
    * Interface function that is used to get the last number of stop bits
    * that was sent to this object from an application. This is always correct.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetStops : Word;
      Begin
        GetStops := Stops;
      End;

    {
    * Get Maximum Function
    *
    * Interface function to return the maximum functions supported
    * by this fossil driver.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetMaxFuncs : Word;
      Begin
        GetMaxFuncs := MaxFuncs;
      End;

    {
    * Get Fossil Rev
    *
    * Interface function to return the revision level of the fossil
    * that is in use.
    -----------------------------------------------------------------------------}
    Function X00Dvr.GetRevLevel : Word;
      Begin
        GetRevLevel := RevLevel;
      End;

    {
    * Set Baud Rate
    *
    * BaudRate code in AL:
    * Bits [7:5] 000 = 19200, 001 = 38400, 010 = 300, 011 = 600, 100 = 1200,
    * 101 = 2400, 110 = 4800, 111 = 9600. Parity: [4:3] 00 or 10 = none,
    * 01 = odd, 11 = even. StopBits: [2:2] 0 = 1, 1 = 2
    * CharLength: 5 bits plus value [1:0] Support for [4:0] = 00011 required of
    * driver, others optional
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.SetBaud(Bd,Sz : Word; Prty : Char; StpBts : Word);
      Var
        Bits : Word;
      Begin
        Baud := Bd;
        Size := Sz;
        Parity := Prty;
        Stops := StpBts;

        Regs.Dx := Port;

        Case Baud of
            300 : Bits := 2;
            600 : Bits := 3;
           1200 : Bits := 4;
           2400 : Bits := 5;
           4800 : Bits := 6;
           9600 : Bits := 7;
          19200 : Bits := 0;
          38400 : Bits := 1;
        Else
          Exit;
        End;

        Bits := Bits Shl 2;
        If Parity = 'E' Then
          Bits := Bits + 3
        Else if Parity = 'O' Then

    {  c¾îºD�B6´= Bits + 1;}

        Bits := Bits Shl 1;
        If Stops = 2 then
          Bits := Bits + 1;
        Bits := Bits Shl 2;
        Case Size Of
          6 : Bits := Bits + 1;
          7 : Bits := Bits + 2;
          8 : Bits := Bits + 3;
        Else
          Bits := Bits + 3;
        End;

        Regs.Al := Bits;
        Regs.Ah := $00;
        Intr(CommVect,Regs);
        Status := Regs.AX;
      End;

    {
    * Transmit Character
    *
    * Character is queued for transmission. If there is room in the transmitter
    * buffer when this call is made, the character will be stored and control
    * returned to caller. If the buffer is full, the driver will wait for room.
    * This can be dangerous when used in combination with flow control (see
    * Function 0Fh)
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.TxChar(Ch : Char);
      Begin
        Regs.al := Ord(Ch);
        Regs.Ah := $01;
        Regs.Dx := Port;
        Intr(CommVect,Regs);
        Status := Regs.AX;
      End;

    {
    * Receive Character
    *
    * The next character in the input ring buffer is returned to the caller. If
    * none available, the driver will wait for input.
    -----------------------------------------------------------------------------}
    Function  X00Dvr.RxChar : Char;
      Begin
        Regs.Dx := Port;
        Regs.Ah := $02;
        Intr(CommVect,Regs);
        RxChar := Char(Regs.Al);
      End;

    {
    * Get Status
    *
    * Bits are:
    * AH[6:6] 1 = Output buffer empty
    * AH[5:5] 1 = Output buffer not full
    * AH[1:1] 1 = Input buffer overrun
    * AH[0:0] 1 = Characters in input buffer
    * AL[7:7] 1 = Carrier Detect signal
    * AL[3:3] 1 = Always (never 0)
    -----------------------------------------------------------------------------}
    Function  X00Dvr.GetStatus : Word;
      Begin
        Regs.Dx := Port;
        REgs.Ah := $03;
        Intr(CommVect,Regs);
        GetStatus := Regs.Ax;
        Status := Regs.AX;
      End;

    {
    * Init Fossil Driver
    *
    * Required before I/O can take place on comm port.  When DX = 00FFh,  then
    * any initialization needed to make the keyboard/display available for FOSSIL
    * use should be performed.  BX = 4F50h signals that ES:CX points to a flag
    * byte in the application that the driver should increment when its
    * keyboard routines detect a Ctl-C.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.InitFossil;
      Begin
        Regs.Dx := Port;
        Regs.Ah := $04;
        Regs.Bx := 0;
        Intr(CommVect,Regs);
        If Regs.Ax <> $1954 Then
          Begin
            MaxFuncs := 0;
            RevLevel := 0;
          End
        Else
          Begin
            MaxFuncs := Regs.Bl;
            RevLevel := Regs.Bh;
          End;
      End;

    {
    * De-Init Fossil Driver
    *
    * Disengages driver from comm port. Should be done when operations on the
    * port are complete.  IF DX = 00FFh, then the initialization that was
    * performed when FOSSIL function 04h with DX = 00FFh should be undone.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.DeinitFossil;
      Begin
        If MaxFuncs < $05 Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $05;
        Intr(CommVect,Regs);
      End;

    {
    * Drop Dtr Line
    *
    * Used to control Data Terminal Ready signal line on com port. This line
    * usually has some effect on modem operation (most modems will drop
    * carrier if DTR is lowered, for example).
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.DropDTR;
      Begin
        If MaxFuncs < $06 Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $06;
        Regs.Al := 0;
        Intr(CommVect,Regs);
      End;

    {
    * Rase Dtr Line
    *
    * Used to control Data Terminal Ready signal line on com port. This line
    * usually has some effect on modem operation (most modems will drop
    * carrier if DTR is lowered, for example).
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.RaseDTR;
      Begin
        If MaxFuncs < $06 Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $06;
        Regs.Al := 1;
        Intr(CommVect,Regs);
      End;

    {
    * Get System Timming Parameters
    *
    * Returns statistics needed to do some critical timing in any MS-DOS system.
    * The interrupt number in AL can be used to intercept a timer interrupt
    * that happens (AH) times per second. DX is essentially 1000/AH. Function
    * 16h is the preferred way to install timer tick code. AH and DX should
    * be accurate for the 16h timer tick.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.SystemTimerParams(Var TicksPerSec,MsPerTick : Word);
      Begin
        If MaxFuncs < $07 Then
            Exit;
        Regs.Ah := $07;
        Intr(CommVect,Regs);
        TicksPerSec := Regs.Ah;
        MsPerTick := Regs.Dx;
      End;

    {
    * Flush Output Buffer
    *
    * This is used to wait for all output to complete. If flow control is active
    * it is possible for this code never to return control to the caller. (See
    * function 0Fh)
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.FlushBuffer;
      Begin
        If MaxFuncs < $08 Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $08;
        Intr(CommVect,Regs);
      End;

    {
    * Purge Output Buffer
    *
    * Zero the output buffer. Returns to the caller immediately. Characters
    * that have not been transmitted yet are lost.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.PurgeOutputBuffer;
      Begin
        If MaxFuncs < $09 Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $09;
        Intr(CommVect,Regs);
      End;

    {
    * Purge Input Buffer
    *
    * Zeroes the input buffer. If any flow control restraint has been employed
    * (dropping RTS or transmitting XOFF) the port will be "released" (by doing
    * the reverse, raising RTS or sending XON). Returns to caller immediately.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.PurgeInputBuffer;
      Begin
        If MaxFuncs < $0A Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $0A;
        Intr(CommVect,Regs);
      End;

    {
    * Transmit Character without wait
    *
    * Character is queued for transmission. If there is room in the transmitter
    * buffer when this call is made, the character will be stored and control
    * returned to caller with AX=1. If the buffer is full, control is returned
    * to caller with AX=0. This allows the application to make its own decisions
    * on how to deal with "buffer full".
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.TxCharNoWait(Ch : Char);
      Begin
        Repeat
        If MaxFuncs < $0B Then
            Exit;
          Regs.Dx := Port;
          Regs.Ah := $0B;
          Regs.Al := Ord(Ch);
          Intr(CommVect,Regs);
        Until (Regs.Ax <> 0);
      End;

    {
    * Keyboard Peek Character
    *
    * The next character in the input ring buffer is returned to the caller. If
    * none available, the driver returns a value of FFFFH. This "read" does not
    * actually remove a character from the input buffer!
    -----------------------------------------------------------------------------}
    Function  X00Dvr.RXPeekChar(Var Ch : Char) : Boolean;
      Begin
        If MaxFuncs < $0C Then
          c¾îºD�B6Q|   Regs.DX := Port;
        Regs.AH := $0C;
        Intr(CommVect,Regs);
        Ch := Char(Regs.AL);
        If Regs.AX = $FFFF Then
            RxPeekChar := False
        Else
            RxPeekChar := True;
      End;

    {
    * Keyboard Peek Character
    *
    * The next character in the keyboard buffer is returned to the caller. If
    * none available, the driver returns a value of FFFFH. This "read" does not
    * actually remove a character from the input buffer! For function keys, IBM
    * PC scan codes must be returned.
    -----------------------------------------------------------------------------}
    Function  X00Dvr.KBPeekChar(Var Ch : Word) : Boolean;
      Begin
        If MaxFuncs < $0D Then
            Exit;
        Regs.DX := Port;
        Regs.AH := $0D;
        Intr(CommVect,Regs);
        Ch := Regs.AX;
        If Regs.AX = $FFFF Then
            KBPeekChar := False
        Else
            KBPeekChar := True;
      End;

    {
    * Keyboard Read Character
    *
    * Return the next character from the keyboard buffer. Wait for a keystroke
    * if the buffer is empty. For function keys, IBM PC scan codes are required.
    -----------------------------------------------------------------------------}
    Function X00Dvr.KBRead : Word;
      Begin
        If MaxFuncs < $0E Then
            Exit;
        Regs.AH := $0E;
        Intr(CommVect,Regs);
        KBRead := Regs.AX;
      End;

    {
    * Flow Control
    *
    * AL[0:0] 1= enables remote to restrain FOSSIL transmitter using XON/XOFF;
    * AL[1:1] 1= enables modem restraint of FOSSIL transmitter using CTS and
    *            FOSSIL restraint of modem using RTS
    * AL[3:3] 1= enables FOSSIL to restrain remote using XON/XOFF.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.FlowControl(XONCTS : Byte);
      Begin
        If MaxFuncs < $0F Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $0F;
        Regs.Al := XonCTS;
        Intr(CommVect,Regs);
      End;

    {
    * Ctrl C Checking On
    *
    * AL[0:0] 1 = enable/disable CtlC/CtlK check (driver will set internal flag
    *             which is returned by this function when it detects a CtlC/CtlK).
    * AL[1:1] 1 = stop transmitter
    *         0 = release previous stop
    *             This is used primarily for programs that can't trust XON/XOFF
    *             at FOSSIL level (such as BBS software).
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.CtrlCChkOn;
      Begin
        If MaxFuncs < $10 Then
            Exit;
        Regs.Dx := Port;
        Regs.AH := $10;
        CtrlCFlags := CtrlCFlags Or 1;
        Regs.AL := CtrlCFlags;
        Intr(CommVect,Regs);
      End;

    {
    * Ctrl C Checking Off
    *
    * AL[0:0] 1 = enable/disable CtlC/CtlK check (driver will set internal flag
    *             which is returned by this function when it detects a CtlC/CtlK).
    * AL[1:1] 1 = stop transmitter
    *         0 = release previous stop
    *             This is used primarily for programs that can't trust XON/XOFF
    *             at FOSSIL level (such as BBS software).
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.CtrlCChkOff;
      Begin
        If MaxFuncs < $10 Then
            Exit;
        Regs.Dx := Port;
        Regs.AH := $10;
        CtrlCFlags := CtrlCFlags And Not 1;
        Regs.AL := CtrlCFlags;
        Intr(CommVect,Regs);
      End;

    {
    * Transmitter On
    *
    * AL[0:0] 1 = enable/disable CtlC/CtlK check (driver will set internal flag
    *             which is returned by this function when it detects a CtlC/CtlK).
    * AL[1:1] 1 = stop transmitter
    *         0 = release previous stop
    *             This is used primarily for programs that can't trust XON/XOFF
    *             at FOSSIL level (such as BBS software).
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.XmitOn;
      Begin
        If MaxFuncs < $10 Then
            Exit;
        Regs.Dx := Port;
        Regs.AH := $10;
        CtrlCFlags := CtrlCFlags And Not 2;
        Regs.AL := CtrlCFlags;
        Intr(CommVect,Regs);
      End;

    --- FD 1.99c
     * Origin: If you clone around you'll end up talking to yourself! (1:105/324.1)

    Ä Turbo Pascal ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PASCAL Ä
    Msg  : 351 of 400
    From : Gordon Tackett                      1:105/324.1          01 Apr 91  10:44
    To   : Roland Frederic                     2:292/500.0
    Subj : BBS Program in TP. Part 5 of 5
    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
    {
    * Transmitter Off
    *
    * AL[0:0] 1 = enable/disable CtlC/CtlK check (driver will set internal flag
    *             which is returned by this function when it detects a CtlC/CtlK).
    * AL[1:1] 1 = stop transmitter
    *         0 = release previous stop
    *             This is used primarily for programs that can't trust XON/XOFF
    *             at FOSSIL level (such as BBS software).
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.XmitOff;
      Begin
        If MaxFuncs < $10 Then
            Exit;
        Regs.Dx := Port;
        Regs.AH := $10;
        CtrlCFlags := CtrlCFlags Or 2;
        Regs.AL := CtrlCFlags;
        Intr(CommVect,Regs);
      End;

    {
    * Goto XY
    *
    * Identical to IBM PC BIOS INT 10h, subfunction 02h. FOSSIL should do
    * sanity checks but software should not assume that that is the case.
    -----------------------------------------------------------------------------}
    Procedure  X00Dvr.GotoXY(X,Y : Word);
      Begin
        If MaxFuncs < $11 Then
            Exit;
        Regs.Dh := Lo(Y-1);
        Regs.Dl := Lo(X-1);
        Regs.AH := $11;
        Intr(CommVect,Regs);
      End;

    {
    * Get Cursor Location
    *
    * Identical to IBM PC BIOS INT 10h, subfunction 03h.
    -----------------------------------------------------------------------------}
    Procedure  X00Dvr.GetCursorLoc(Var X,Y : Word);
      Begin
        If MaxFuncs < $12 Then
            Exit;
        Regs.AH := $12;
        Intr(CommVect,Regs);
        Y := Regs.Dh + 1;
        X := Regs.Dl + 1;
      End;

    {
    * Ansi Write Character
    *
    * ANSI processing is a requirement of this call. It therefore should not be
    * considered re-entrant, since DOS might be used (via ANSI.SYS)
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.AnsiWriteChar(Ch : Char);
      Begin
        If MaxFuncs < $13 Then
            Exit;
        Regs.Al := Ord(Ch);
        Regs.AH := $13;
        Intr(CommVect,Regs);
      End;

    {
    * Enable Watch Dog
    *
    * FOSSIL will force the system to reboot if Carrier Detect on the specified
    * port drops while "watchdog" is ON. It is not necessary for the port to
    * be "active" (Function 04h) for this function to be used.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.EnableWatchDog;
      Begin
        If MaxFuncs < $14 Then
            Exit;
        Regs.AL := 1;
        Regs.Dx := Port;
        Regs.Ah := $14;
        Intr(CommVect,Regs);
      End;

    {
    * disable Watch Dog
    *
    * FOSSIL will force the system to reboot if Carrier Detect on the specified
    * port drops while "watchdog" is ON. It is not necessary for the port to
    * be "active" (Function 04h) for this function to be used.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.DisableWatchDog;
      Begin
        If MaxFuncs < $14 Then
            Exit;
        Regs.AL := 0;
        Regs.Dx := Port;
        Regs.Ah := $14;
        Intr(CommVect,Regs);
      End;

    {
    * Write Character
    *
    * Write character to screen using re-entrant code. ANSI processing may
    * not be assumed. This call may be used by DOS device drivers.
    -----------------------------------------------------------------------------}
    Procedure  X00Dvr.WriteChar(Ch : Char);
      Begin
        If MaxFuncs < $15 Then
            Exit;
        Regs.AL := Ord(Ch);
        Regs.AH := $15;
        Intr(CommVect,Regs);
      End;

    {
    * Insert Timer Function
    *
    * Allows FOSSIL to manage timer tick chain, which provides some measure of
    * security over just snagging the interrupt. Use "insert" instead of
    * grabbing the vector and "remove" in place of restoring it.
    -----------------------------------------------------------------------------}
    Function X00Dvr.InsertTimerFunction(TF : TimerFunctionPtr) : Boolean;
      Begin
        If MaxFuncs < $16 Then
            Exit;
        Regs.AH := $16;
        Regs.AL := 1;
        Regs.ES := Seg(TF^);
        Regs.Dx := Ofs(TF^);
        Intr(CommVect,Regs);
        If Regs.Ax = 0 Then
            InsertTimerFunction := True
        Else
            InsertTimerFunction := False;
      End;

    Function X00Dvr.DeleteTimerFunction(TF : TimerFunctionPtr) : Boolean;
      Begin
        I�ÎîºD�B6ñ9 < $16 Then
            Exit;
        Regs.AH := $16;
        Regs.AL := 0;
        Regs.ES := Seg(TF^);
        Regs.Dx := Ofs(TF^);
        Intr(CommVect,Regs);
        If Regs.Ax = 0 Then
            DeleteTimerFunction := True
        Else
            DeleteTimerFunction := False;
      End;

    {
    * Reboot
    *
    * Provides a machine-independent way for a "troubled" application to reset
    * the system. Some machines may not support both "flavors" of bootstrap,
    * in which case the setting of AL will not have any effect.
    -----------------------------------------------------------------------------}
    Procedure  X00Dvr.Reboot(Tp : Boolean);
      Begin
        If MaxFuncs < $17 Then
            Exit;
        Regs.AH := $17;
        Regs.Al := 0;
        If Tp Then
          Regs.Al := 1;
        Intr(CommVect,Regs);
        WriteLn('System Error - Unable to ReBoot');
        While (True) Do;
      End;

    {
    * Receive Buffer
    *
    * Transfer as many characters as are available into the specified user
    * buffer, up to the maximum specified in CX. ES and DI will not be modified
    * by this call. The actual number of characters transferred will be in AX.
    * This function does not wait for more characters to become available if the
    * number in CX exceeds the number of characters currently stored.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.RecvBuffer(Buffer : Pointer; Var Sz : Word);
      Begin
        If MaxFuncs < $18 Then
            Exit;
        If (Self.GetStatus And $0100) = 0 Then
          Begin
            Size := 0;
            Exit;
          End;
        Regs.Dx := Port;
        Regs.Es := Seg(Buffer^);
        Regs.Di := Ofs(Buffer^);
        Regs.Cx := Sz;
        Regs.Ah := $18;
        Intr(CommVect,Regs);
        Size := Regs.Ax;
      End;

    {
    * Send Buffer
    *
    * Transfer as many characters as will fit, from the specified user buffer
    * into the output buffer, up to the maximum specified in CX. ES and DI
    * will not be modified by this call. The actual number of characters
    * transferred will be in AX.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.SendBuffer(Buffer : Pointer; Sz : Word);
      Var
        Cptr   : ^Char;
        I     : Integer;
      Begin
        If MaxFuncs < $19 Then
            Exit;
        Cptr  := Buffer;
        Regs.Dx := Port;
        Regs.Es := Seg(Buffer^);
        Regs.Di := Ofs(Buffer^);
        Regs.Cx := Sz;
        Regs.Ah := $19;
        Intr(CommVect,Regs);
        If Regs.Ax <> Sz Then
          Begin
            Regs.Di := Regs.Di + Regs.Ax;
            Cptr := Ptr(Regs.Es, Regs.Di);
            For I := Regs.Ax To Sz Do
              Begin
                Self.TxChar(Cptr^);
                Cptr := Ptr(Seg(Cptr^),Ofs(Cptr^) + 1);
              End;
          End;
      End;

    {
    * Stop Break
    *
    * Used for special applications such as certain high speed modems. Resets
    * all transmit flow control restraints (such as an XOFF received from remote)
    * Init (Function 4) or UnInit (Function 5) will stop an in-progress Break.
    * Note: the application must determine the "length" of the BREAK.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.StopBreak;
      Begin
        If MaxFuncs < $1A Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $1A;
        Regs.Al := 0;
        Intr(CommVect,Regs);
      End;

    {
    * Send Break
    *
    * Used for special applications such as certain high speed modems. Resets
    * all transmit flow control restraints (such as an XOFF received from remote)
    * Init (Function 4) or UnInit (Function 5) will stop an in-progress Break.
    * Note: the application must determine the "length" of the BREAK.
    -----------------------------------------------------------------------------}
    Procedure X00Dvr.SendBreak;
      Begin
        If MaxFuncs < $1A Then
            Exit;
        Regs.Dx := Port;
        Regs.Ah := $1A;
        Regs.Al := 1;
        Intr(CommVect,Regs);
      End;

    {
    * Get Info Block
    *
    * Get The Info Block Record from Fossil to usable memory. An Info Block is:
    *
    * Offset 0 (word) = Structure size
    *        2 (byte) = FOSSIL spec version
    *        3 (byte) = Driver rev level
    *        4 (dwrd) = Pointer to ASCII ID
    *        8 (word) = Input buffer size
    *       0A (word) = Bytes avail (input)
    *       0C (word) = Output buffer size
    *       0E (word) = Bytes avail (output)
    *       10 (byte) = Screen width, chars
    *       11 (byte) = Screen height, chars
    *       12 (byte) = Baud rate mask
    *                   (See call 00h)
    -----------------------------------------------------------------------------}
    Procedure  X00Dvr.GetInfo;
      Begin
        If MaxFuncs < $1B Then
            Exit;
        Regs.Cx := Sizeof(CurInfo);
        Regs.Es := Seg(CurInfo);
        Regs.Di := Ofs(CurInfo);
        Regs.Dx := Port;
        Regs.Ax := $1B;
        Intr(CommVect,Regs);
      End;

    {
    *
    *
    * Used to install user appendages into the INT 14h dispatcher.  Appendage
    * codes 80h - BF are supported.  Codes 80h - 83h are reserved.  The error
    * return,  BH = 00h and AX = 1954h, should mean that another appendage
    * has already been installed with the code specified in AL.  The appendage
    * will be entered via a far call whenever INT 14h call is made with AL
    * equal to the appendage code.  The appendage should return to the INT
    * 14h dispatcher via a far return.  The INT 14h dispatcher should not modify
    * any registers prior to making the far call to the appendage and after the
    * appendage returns control to the dispatcher.
    -----------------------------------------------------------------------------}
    {7E}
    {
    *
    *
    * Used to remove a user appendage that was installed using function 7Fh. An
    * error return means that either the entry point specified in ES:DX did
    * not match the entry point currently in the dispatcher table for the code
    * given in AL,  or that no entry for the code given in AL currently exits.
    -----------------------------------------------------------------------------}

    {7F}

    {$IFDEF LOCAL}
    Var
      t1,t2,t3 : Word;
    Begin
      Comm1.Init(0,2400,8,'N',2);
    {$ENDIF}
    End.

    --- FD 1.99c
     * Origin: If you clone around you'll end up talking to yourself! (1:105/324.1)

[Back to COMM SWAG index] [Back to Main SWAG index] [Original]