                          FRYERS Driver Utility               page 1 

                           FRYERS Function Definitions
                                    04/05/06

        FRYERS.COM  (MSDOS/Win3.1x)

        The FRYERS.COM driver (MSDOS TSR) is a memory resident driver 
        that is loaded once into the computer after it is turned on. It 
        remains resident until the computer is turned off (or re-booted). 
        The driver attaches to the existing bios driver in the system. 
        The driver may be enabled or disabled via a selection control.

        The new driver supports the standard INT 14H calling format, but 
        adds its own extensions to handle the added features. The driver 
        provides the ability to handle interrupts on incoming data so 
        that it won't be lost, and greater control over the details of 
        the data handling at the system level through the interrupt 
        control function. Version 2 also adds in the Frye Instrument 
        Packet Protocol procedure.

        The ASCII protocol function calls (01xx through 03xx and FF01 
        through FF06) should not be used when the packet protocol mode is 
        enabled. Select the proper mode before using the associated 
        function. The packet function calls should only be used when the 
        packet protocol mode has been enabled (see function FF10).  

        The FRYERS.COM TSR is used with MSDOS programs and Win3.1x 
        (16bit) programs that communicate with FIPP based Fonix 
        instruments. 


        FRYERS16.DLL  (Win3.1x)

        A helper DLL called FRYERS16.DLL provides 16bit Windows support 
        for programming environments that do not have access to MSDOS 
        interrupts. The FRYERS16.DLL helper requires that the FRYERS.COM 
        driver is already loaded into the system before it can be used. 
        The FRYERS16.DLL library is simply a wrapper around the MSDOS 
        interrupt call that allows a program to call the FRYERS.COM 
        driver as a library procedure. 


        FRYERS32.DLL  (Win95/WinNT)

        The FRYERS32.DLL library is a 32bit Windows driver that can be 
        used by Win95 and WinNT programs to communicate with FIPP based 
        Fonix Instruments. FRYERS32 does not use the FRYERS.COM driver, 
        and FRYERS.COM does not need to be installed on the system. 
        FRYERS32.DLL uses Windows API calls to communicate with the FIPP 
        based Fonix instruments.

        Note: Not all Fryers functions are supported in the FRYERS32.DLL
        library see the reference notes for specific limitations.





                          FRYERS Driver Utility               page 2 

        Supported Driver Usage:

        Environment - Driver
           MSDOS    - FRYERS.COM
           Win3.1x  - FRYERS.COM   [+FRYERS16.DLL <- optional]
           Win95    - FRYERS32.DLL (32bit programs only)
           WinNT    - FRYERS32.DLL (32bit programs only)

        The 16 bit Fryers drivers are provided for MSDOS (PC compatible) 
        and Win3.1x usage. Windows 3.1x programs may also use the helper 
        FRYERS16.DLL if they do not have direct access to interrupt 
        calls. New applications for Windows95(tm) and WindowsNT(tm) 
        target platforms should be written as 32 bit applications to use 
        the 32 bit FRYERS32.DLL library. 

        Unsupported Usage:

        Fryers is not supported in WinNT 16 bit operation, nor is Fryers 
        supported in the MSDOS emulation mode of WinNT. WinNT does not 
        provide the system support in 16 bit mode that Fryers needs to 
        run reliably. 

        FRYERS.COM can run in the emulated MSDOS environment in Win95, 
        and in the 16 bit Windows environment of Win95. FRYERS.COM cannot 
        run reliably in the emulated MSDOS environment of WinNT or 
        Win3.1x. FRYERS32.DLL will only run as a 32bit Windows 
        environment. FRYERS32.DLL will not run under Win32S. 
        -----------------------------------------------------------------

        Standard function calls:                                  (ASCII)

        These functions conform to the standard INT 14 function calls  
        for information passed to and from the function. Actual internal 
        operation will vary depending on configuration of the driver. 

          Enter with   |       Description             | Return with
        -----------------------------------------------------------------
        @ AH=00        | Initialize the selected port  | AX=status
          DX=port      | Return with status in AX      |
        -----------------------------------------------------------------
        @ AH=01        | Send char in AL out port      | AL=data
          DX=port      | Return send status in AH      | AH=send status
          AL=data      |                               |     
        -----------------------------------------------------------------
        @ AH=02        | Read char into AL from port   | AL=data
          DX=port      | Return Receive status in AH   | AH=recv status
        -----------------------------------------------------------------
        @ AH=03        | Read port status into AX      | AX=status
          DX=port      |                               |
        -----------------------------------------------------------------
        @Win32 supported function 
        Note: although functions 01, 02, and 03 are supported in the 32 
        bit DLL, the status return flags are not fully compatible.




                          FRYERS Driver Utility               page 3 

        Extended Function calls:                                  (ASCII)

        These functions provide an extension to the standard IBM function 
        calls to service the interrupt based ASCII I/O drivers. 

        The ASCII protocol function calls (01xx through 03xx and FF01
        through FF06) should not be used when the packet protocol mode is 
        enabled. Select the proper mode before using the associated 
        function. The packet function calls should only be used when the 
        packet protocol mode has been enabled (see function FF10).  

          Enter with   |       Description              | Return with
        -----------------------------------------------------------------
        @ AX=FF00      | Read/enable the selected port  | AL=condition
          DL=port      | CH=0 read port condition only  | 
          CH=set/read  | CH=nz set port condition       |
          CL=en/dis    | CL=0 disable   CL=nz enable    |
        -----------------------------------------------------------------
          AX=FF01      | Write selected uart register   | No changes
          DL=port      | CH=uart reg to write (0-6)     | 
          CH=register  | CL=data to write to reg        |     
          CL=data      |                                |
        -----------------------------------------------------------------
          AX=FF02      | Read selected uart register    | AL=data
          DL=port      | CH=uart reg to read (0-6)      | 
          CH=register  |                                |     
        -----------------------------------------------------------------
        @ AX=FF06      | Flush receive interrupt buffer | No changes
          DL=port      |                                | 
        -----------------------------------------------------------------
        @ AX=FF07      | Timer select/control           | AL=multiplier
        * DL=port      | CH=0 initialize timer          | (CH=0 only)
          CH=select    | CH=1 init send tick count      |     
           CL=data     | CH=2 init recv tick count      |
        ** BX=tick cnt | CH=3 delay for tick count      | AX=tick timer
                       | CH=4 get/set tick timer **     | (if CH=4&CL=0)
        -----------------------------------------------------------------
        @@AX=FF0F      | Delete port resources          | AL=condition
          DL=port      | CL=0 read port condition only  | 
          CL=set/read  | CL=nz delete the port          | 
        -----------------------------------------------------------------
        *Timing problems in 0FF07 prior to V2.60 on fast cpus
        **New for V4.10 CH=4 sets/gets port tick timer (see FF17,CH=3)
        @Win32 supported function   @@Win32 function only













                          FRYERS Driver Utility               page 4 

        Packet Function calls:                                     (FIPP)

        These functions are an extension to the standard calls to manage 
        the Frye Instrument Packet Protocol communication. The extensions 
        are accessed by calling the function with AH set to 0FFH and the 
        desired function number in AL.

        The packet function calls should only be used when the packet 
        protocol mode has been enabled (see function FF10).  The ASCII 
        protocol function calls (01xx through 03xx and FF01 through FF06) 
        should not be used when the packet protocol mode is enabled. 
        Select the proper mode before using the associated function.

          Enter with   |       Description             | Return with
        -----------------------------------------------------------------
        @ AX=FF10      | Change selected port to packet| AL=condition
          DL=port      | CH=0 read port condition only | 
          CH=set/read  | CH=nz set port condition      |
          CL=en/dis    | CL=0 packetOff CL=nz packetOn |
        -----------------------------------------------------------------
        @ AX=FF11      | Send command packet to target | AL=status flags
          DL=port      | 16bit: DS:BX=pointer to array | AH=error flags
          DS:BX/EBX=ptr| 32bit: EBX=pointer to array   | CX=words sent
          CX=size      | CX=size of data array (words) |
        -----------------------------------------------------------------
        @ AX=FF12      | Read response packet buffer   | AL=status flags   
          DL=port      | 16bit: DS:BX=pointer to array | AH=error flags    
          DS:BX/EBX=ptr| 32bit: EBX=pointer to array   | CX=words read
          CX=max size  | CX=max size of dest in words  |
        -----------------------------------------------------------------
        @ AX=FF13      | Read packet transfer status   | AL=status flags 
          DL=port      |                               | AH=error flags  
                       |                               | CX=control flags  
                       |                               | BX=timer count
                       |                               | DL=uart errors
        -----------------------------------------------------------------
        @ AX=FF14      | Reset packet transfer port    | No changes 
          DL=port      |                               | 
        -----------------------------------------------------------------
        @ AX=FF15      | (Re)Send data packet to target| AL=status flags
          DL=port      | (send data buffer)            | AH=error flags
                       |                               | CX=words sent  
        -----------------------------------------------------------------
        @ AX=FF16      | Clear receive ready flag      | AL=status flags
          DL=port      |                               | AH=error flags
        -----------------------------------------------------------------
        @ AX=FF17      | Get/Set packet time-outs      | AX=time-out 
          DL=port      | CL=0 read val, CL=nz set val  |     value      
          CH=select    | CH=0 poll T/O, CH=1 rsp T/O   | BX=internal T/O
          CL=set/read  | CH=2 rcv  T/O, CH=3 gen timer |     value            
          BX=data      | CH=4 tick resolution          |                 
        -----------------------------------------------------------------
        @Win32 supported function 




                          FRYERS Driver Utility               page 5 

        Extended Packet Function calls:                            (FIPP)

        These functions are an extension to the standard Frye Instrument 
        Packet Protocol function calls. They also allow use of the 
        interrupt calls in protected mode (Windows/DPMI) by providing an 
        alternate access mechanism which avoids segment/selector issues. 
        This avoids requiring a custom DPMI interface for the interrupt.

        The extended packet function calls should only be used when the 
        packet protocol mode is enabled (see function FF10).  The ASCII 
        protocol function calls (01xx through 03xx and FF01 through FF06) 
        should not be used when the packet protocol mode is enabled. 
        Select the proper mode before using the associated function.

          Enter with   |       Description             | Return with
        -----------------------------------------------------------------
        @ AX=FF20      | Load data to send buffer      | AL=status flags
          DL=port      |  (not sent to target)         | AH=error flags
          DS:BX/EBX=ptr| DS:BX or EBX=pointer to array | CX=words loaded 
          CX=Size      | CX=array size in words        | CX=words loaded 
        -----------------------------------------------------------------
        @ AX=FF21      | Read from send packet buffer  | AL=status flags   
          DL=port      |  (flags not affected)         | AH=error flags    
          DS:BX/EBX=ptr| DS:BX or EBX=pointer to array | CX=words read
          CX=max size  | CX=Max size of dest in words  | 
        -----------------------------------------------------------------
        @ AX=FF22      | Read from rcv packet buffer   | AL=status flags   
          DL=port      |  (ready flag not cleared)     | AH=error flags    
          DS:BX/EBX=ptr| DS:BX or EBX=pointer to array | CX=words read
          CX=max size  | CX=Max size of dest in words  | 
        -----------------------------------------------------------------
        @ AX=FF23      | Indexed write to send buffer  | AL=status flags   
          DL=port      |  (flags not affected)         | AH=error flags    
          CX=index     | CX=Index into packet buffer   | 
          BX=data      | BX=data to write to buffer    | 
        -----------------------------------------------------------------
        @ AX=FF24      | Indexed write to rcv buffer   | AL=status flags   
          DL=port      |  (flags not affected)         | AH=error flags    
          CX=index     | CX=Index to packet buffer     | 
          BX=data      | BX=data to write to buffer    | 
        -----------------------------------------------------------------
        @ AX=FF25      | Indexed read from send buffer | AL=status flags   
          DL=port      |  (flags not affected)         | AH=error flags    
          CX=index     | CX=index into packet buffer   | BX=cmd# in buf
                       |                               | CX=data count
                       |                               | DX=data word
        -----------------------------------------------------------------
        @ AX=FF26      | Indexed read from rcv buffer  | AL=status flags   
          DL=port      |  (flags not affected)         | AH=error flags    
          CX=index     | CX=index into packet buffer   | BX=rsp# in buf
                       |                               | CX=data count
                       |                               | DX=data word
        -----------------------------------------------------------------
        @Win32 supported function 



                          FRYERS Driver Utility               page 6 

        Misc Extended Function calls:

        These are new functions, or functions that don't fit under the 
        normal function headers. See the description of the function for 
        further explanation of their use.

          Enter with   |       Description              | Return with
        -----------------------------------------------------------------
          AX=FF04      | Read/Set RTS control line      |AL=condition
          DL=port      | CH=0 read flag condition only  | 
          CH=set/read  | CH=nz set flag                 |
          CL=en/dis    | CL=0 disable   CL=nz enable    |
        -----------------------------------------------------------------
          AX=FF05      | Read/Set DTR control line      |AL=condition
          DL=port      | CH=0 read flag condition only  | 
          CH=set/read  | CH=nz set flag                 |
          CL=en/dis    | CL=0 disable   CL=nz enable    |
        -----------------------------------------------------------------
          AX=FF08      | Read/Set CTS flow control      |AL=condition
          DL=port      | CH=0 read flag condition only  | 
          CH=set/read  | CH=nz set flag                 |
          CL=en/dis    | CL=0 disable   CL=nz enable    | (New in V2.80)
        -----------------------------------------------------------------
          AX=FF09      | Save/Restore UART registers    |DX=uart base 
          DL=port      | CH=0   CL=0  =Save internal    |CX=data length
          CH=ext/int   | CH=0   CL=NZ =Restore internal |SI:BX=buffer 
          CL=Rst/Save  | CH=NZ  CL=0  =Save external    |
          DS:BX=data   | CH=NZ  CL=NZ =Restore external | (New in V3.00)
        -----------------------------------------------------------------
          AX=FF0A      | Get/Set port configuration     |AH=new int (FF)
          DL=port      | CH=0  Read port configuration  |AL=prev int num  
          CH=set/read  | CH=NZ Set port configuration   |DI=prev uart adr
          CL=new int   |   CL=interrupt (0-15)          |SI=prev mask adr 
          BX=uart base |   BX=uart base adr (0-1,adr)   |DL=prev mask val 
                       |                                |DH=prev HWI adr
                       | (New in V3.07)                 | BX=new uart adr
        -----------------------------------------------------------------
        @ AX=FF18      | Get/Set packet buffer size     | AX=buffer size    
          DL=port      | CL=0 read value                | 
          CH=select    | CL=nz set value                | 
          CL=set/read  | CH=0 set packet buffer size    | 
          BX=data      | CH=1 read packet buffer size   | (New in V2.02)
        -----------------------------------------------------------------
        @Win32 supported function 













                          FRYERS Driver Utility               page 7 

          Enter with   |       Description              | Return with
        -----------------------------------------------------------------
        @ AX=FF19      | Get/Set poll error count       |AX=poll err cnt
          DL=port      | CL=0 read value                |BL=Abaud err cnt         
          CL=set/read  | CL=nz set value                |BH=pkt retry cnt
          BX=data      | (New in V2.11)                 |CX=pkt status
                       |                                |SI=cmd good cnt
                       |                                |DI=cmd fail cnt  
        -----------------------------------------------------------------
        @ AX=FF1A      | Read/Set Poll Quick Terminate  |AL=condition
          DL=port      | CH=0 read flag condition only  |BX=auto QT cnt 
          CH=set/read  | CH=nz set flag                 |CX=man QT cnt
          CL=en/dis    | CL=0 disable   CL=nz enable    |DX=QT fail cnt 
                       | (New in V3.20)                 |SI=poll send cnt 
                       |                                |DI=poll fail cnt  
        -----------------------------------------------------------------
        @ AX=FF1B      | Automatic packet baudrate sel  |BX=baudrate  
          DL=port      | BX=0:autobaud                  |AX=init status
          BX=baudrate  | BX=NZ:set specific baudrate    |CX=pkt control
                       | (New in V4.00)                 |DX=port used 
        -----------------------------------------------------------------
        @ AX=FF1C      | Read/Set Skip Poll flag        |AL=condition
          DL=port      | CH=0 read flag condition only  | 
          CH=set/read  | CH=nz set flag                 |
          CL=en/dis    | CL=0 disable   CL=nz enable    | (New in V4.00)
        -----------------------------------------------------------------
        @ AX=FF1F      | Debug Information              | <unknown>
        -----------------------------------------------------------------
        @Win32 supported function 



          Enter with   |       Description              | Return with
        -----------------------------------------------------------------
        @ AX=FFFD      | Get Version String             |AX=string char
          DL=port      | CX=index into string (0=length)|CX=index
          CX=index     | (New in V4.10)                 |
        -----------------------------------------------------------------
        @ AX=FFFE      | Get Long Version               |AX=short Vnum
          DL=port      | SI:DI=dest string (16bit)      |BX=long Vnum    
          SI:DI=dest16 | EDI=dest string (32bit)        |DX=FFFF
          EDI=dest32   |     (SI=1 or SI=2)             |CL=string length
                       | (New in V2.70)                 | DI=code seg/16
                       |                                | DI=unknown/32 
        -----------------------------------------------------------------
        @ AX=FFFF      | Return Short Ver & chk int     |(AL)AX=version
          DX=port      |(only AL return prior to V2.20) |BX=status
                       |(CX/BX status fixed in V3.00)   |ES:SI=Sign-on/16    
                       |ES:SI/ESI returns the sign-on   |ESI=Sign-on/32
                       |string address.                 |DX=0FFFFH     
                       |CX ret value unknown in 32bit   |DI=baudclk
                       |BX status def diff in 32bit     |CX=intaddr/16
        -----------------------------------------------------------------
        @Win32 supported function 



                          FRYERS Driver Utility               page 8 

        -----------------------------------------------------------------
        Initialize the port (Function 00xx)            (16/ASCII/FIPP/32)

        The specified port is initialized to the parameters given by this 
        function. The receive interrupt buffer is flushed, and the (uart) 
        error status bits are cleared. If called when interrupt or packet 
        mode is enabled, previous port configuration is restored when 
        interrupt or packet mode is disabled.

        Entry: AH=00H    AL=parameters    DX=Port#   
        Return: AX=status   

        Parameter byte:
           7       6       5         4       3       2       1       0
         -----------------------   -------------   -----   -------------
                   |                     |           |           |
               Baudrate    (@IBM)     Parity      Stopbits  Byte Length
              000 - 19200  (110)     00 - none    0 - one   00 - 5 bits
              001 - 28800  (150)     01 - odd     1 - two   01 - 6 bits
              010 - 38400  (300)     11 - even              10 - 7 bits 
              011 - 57600  (600)     10 - n/a               11 - 8 bits
              100 - 115200 (1200)                         
              101 - 2400   (In IBM mode: 000=110 baud, 001=150 baud,)
              110 - 4800   (010=300 baud, 011=600 baud. 19200, 28800,)
              111 - 9600   (38400, 57600, 115200 are only selectable) 
                           (if Fryers driver is enabled. See AX=0FF00H) 
                           (@IBM mode is not supported in 32bit driver)
                            
        Note: In version 2 of FRYERS.COM there is a change in the 
        baudrate select over the standard IBM definition. When the Fryers 
        driver is enabled the 110, 150, 300, and 600 baud selects are 
        replaced with 19200, 28800, 38400, and 57600 baud. In V4.00 
        115200 baud was added to the list (replacing 1200 baud). 
        The older IBM definition is not supported in the 32bit driver.

        The packet Autobaud function only supports 9600, 19200, 28800, 
        38400, and 57600 baud. Autobaud is driven from an internal
        table (See function $FF1B).

        See the next page for the returned status word definitions.

















                          FRYERS Driver Utility               page 9 

        Status word:   (Returns same information as function call 03)

        16bit version:

          Register AL:
            Bit 7 - Carrier is being detected (DCD) 
            Bit 6 - Ring signal is being detected (RI)
            Bit 5 - Data set ready is being detected (DSR)
            Bit 4 - Clear to send is being detected (CTS)
            Bit 3 - DCD has changed states (^DCD)
            Bit 2 - RI has changed from on to off (^RI)
            Bit 1 - DSR has changed states (^DSR)
            Bit 0 - CTS has changed states (^CTS)

          Register AH:
            Bit 7 - Time out (Function error due to time-out) 
            Bit 6 - Transmitter shift register is empty
          * Bit 5 - Transmitter holding register is empty
            Bit 4 - Break has been detected 
            Bit 3 - Framing error has occurred
            Bit 2 - Parity error has occurred
            Bit 1 - Overrun error has occurred
          * Bit 0 - Data has been received (waiting to be read)

        32bit version:

        The uart status is not fully supported in the 32 bit version of 
        the Fryers driver. Only those bits marked with "*" are valid. 
        Other bits may return a value of zero register EAX. If there was 
        an initialization error with the port EAX will return -1.



























                          FRYERS Driver Utility               page 10 

        -----------------------------------------------------------------
        Send character out port (Function 01xx)            (16/ASCII/32)

        Entry: AH=01H    AL=data    DX=Port#     

        Return: AH=send status   


        Send status byte:

          Register AH:
          * Bit 7 - Time out (Function error due to time-out) 
            Bit 6 - Transmitter shift register is empty
            Bit 5 - Transmitter holding register is empty
            Bit 4 - Break has been detected 
            Bit 3 - Framing error has occurred
            Bit 2 - Parity error has occurred
            Bit 1 - Overrun error has occurred
            Bit 0 - Data has been received (waiting to be read)

        This function causes the data provided in register AL to be sent 
        out the selected port. The status register is not cleared by this 
        operation (though it is updated). To clear the error bits, use 
        the status read function (03). If the port is not ready, it will 
        wait until it is, or the function times out (See the timer 
        function).

        Note: Do not use this function when packet mode is enabled. If 
        interrupt mode is enabled, the data will be sent via the FRYERS 
        routines. If interrupt mode is not enabled, data will be sent via 
        the code in the original INT14 function before Fryers was loaded.

        * In the 32 bit version of Fryers, the status flags except 
        timeout are not valid. If there was an initialization error with 
        the port, EAX will return a value of -1.






















                          FRYERS Driver Utility               page 11 

        -----------------------------------------------------------------
        Receive character from port (Function 02xx)        (16/ASCII/32)

        Entry: AH=02H    AL=XX    DX=Port#   

        Return: AH=Receive status    AL=data


        Receive status byte:

          Register AH:
          * Bit 7 - Time out (Function error due to time-out) 
            Bit 6 - <unknown>
            Bit 5 - <unknown>
            Bit 4 - Break has been detected 
            Bit 3 - Framing error has occurred
            Bit 2 - Parity error has occurred
            Bit 1 - Overrun error has occurred
            Bit 0 - <unknown>

        This function reads in the data from the selected port into 
        register AL.  The status register is not cleared by this 
        operation (though it is updated). To clear the error bits, use 
        the status read function (03). If there is no data waiting to be 
        read the function will wait until there is, or it times out (See 
        the timer function).

        Note: Do not use this function when packet mode is enabled. If 
        interrupt mode is enabled, the data will be received via the 
        FRYERS routines. If interrupt mode is not enabled, data will be 
        received via the code in the original INT14 function before 
        Fryers was loaded (typically this will not be interrupt based, so 
        data may be lost).

        * In the 32 bit version of Fryers, the status flags except 
        timeout are not valid. If there was an initialization error with 
        the port, EAX will return a value of -1.




















                          FRYERS Driver Utility               page 12 

        -----------------------------------------------------------------
        Return port status (Function 03xx)                 (16/ASCII/32)
        Entry: AH=03H    AL=XX    DX=Port#   

        Return: AX=status   

        Status word:

          Register AL:
            Bit 7 - Carrier is being detected (DCD) 
            Bit 6 - Ring signal is being detected (RI)
            Bit 5 - Data set ready is being detected (DSR)
            Bit 4 - Clear to send is being detected (CTS)
            Bit 3 - DCD has changed states (^DCD)
            Bit 2 - RI has changed from on to off (^RI)
            Bit 1 - DSR has changed states (^DSR)
            Bit 0 - CTS has changed states (^CTS)

          Register AH:
          * Bit 7 - Time out (Function error due to time-out) 
            Bit 6 - Transmitter shift register is empty
          * Bit 5 - Transmitter holding register is empty
            Bit 4 - Break has been detected 
            Bit 3 - Framing error has occurred
            Bit 2 - Parity error has occurred
            Bit 1 - Overrun error has occurred
          * Bit 0 - Data has been received (waiting to be read)

        This function returns the current status information of the 
        selected port. The error bits of the status register will be 
        cleared after this function is performed.

        Note: Do not use this function when packet mode is enabled. If 
        interrupt mode is enabled, the status will be obtained via the 
        FRYERS routines. If interrupt mode is not enabled, the status 
        will be obtained from the code in the original INT14 function 
        before Fryers was loaded.

        32bit version:

        The uart status is not fully supported in the 32 bit version of 
        the Fryers driver. Only those bits marked with "*" are valid. 
        Other bits may return a value of zero register EAX. If there was 
        an initialization error with the port EAX will return -1.













                          FRYERS Driver Utility               page 13 

        -----------------------------------------------------------------
        Enable the selected port (Function 0FF00)      (16/ASCII/FIPP/32)

        Entry: AH=0FFH    AL=00H      DL=Port#   
               CH=0:read              CH=NZ:set
               CL=n/a                 CL=NZ:enable CL=0:disable

        Return: 16bit: AL=Port select condition
                32bit: EAX=Port select condition (-1=failed)

        If CH = zero the current condition of the selected port will be 
        returned in register AL (enabled or disabled). If CH = non-zero, 
        then CL will control the enable or disable of the selected port. 

        16bit: If CL is zero, then the port will be disabled, and control 
          will be returned to the original system drivers. The interrupts 
          will be restored to the original system values, but the uart 
          parameters - baudrate, parity, word length, etc. - will remain 
          as is. If CL is non-zero, the driver will be enabled. 
          Interrupts and buffers for the port will be initialized.  
         
        32bit: If CL is zero, then the port thread will be released, and 
          control will be returned to the original system drivers. The 
          port will be restored to the original configuration. If CL is 
          non-zero, the driver will be enabled. The port thread and the 
          buffers for the selected port will be initialized.  

        Note: If you turn off the port by calling this function while the 
        packet mode is enabled it will automatically disable the packet 
        mode as well. This is the same as turning off the packet mode 
        followed by immediately turning off the port. This is an 
        acceptable method of quickly shutting down Fryers operation on 
        exit from a program.

        16bit notes: 
        When you select the port (enable interrupt mode operation) with 
        this command, the current uart registers are saved to an internal 
        buffer. When you disable the interrupt mode operation, the 
        original uart register contents are restored. Note that if the 
        port init function (00xx) was called after the interrupts were 
        enabled, disabling the interrupt mode will restore the previous 
        register values. ie The current register values will be 
        discarded. If you re-enable interrupt mode again, you must re-
        init the port if you wish to restore the uart initialization 
        values again. When the interrupt mode is enabled, the 
        initialization values in the uart registers will be used as they 
        existed before the interrupt mode was enabled.

        32bit notes:
        When you select the port with this command, the last known 
        baudrate or default baudrate will be used. When you turn off the 
        port, control of the port is returned to Windows.





                          FRYERS Driver Utility               page 14 

        -----------------------------------------------------------------
        Write direct to selected port uart (Function 0FF01)    (16/ASCII)

        Entry: AH=0FFH    AL=01H    CH=register    CL=data   DL=Port#   

        Return: No registers changed

        This function writes the data byte provided in CL into the uart 
        register specified in CH. This allows direct access to the uart 
        while still performing the operation through the standard INT 14 
        interrupt, thus allowing a degree of isolation from the hardware, 
        while still being able to have direct access to it. Care should 
        be used in the operation of this function though since it may 
        conflict with the operation of the driver.


        Refer to the uart technical manual for a complete description of 
        the registers and operation.

        Note: Do not use this function when packet mode is enabled. 

        This function is not supported in the 32 bit Fryers driver
        (register EAX will return a value of -1).

        -----------------------------------------------------------------
        Read direct from selected port uart (Function 0FF02)   (16/ASCII)

        Entry: AH=0FFH    AL=02H    CH=register    DL=Port#   

        Return: AL=data    

        This function reads the data from the specified uart register 
        into AL. This allows direct access to the uart while still 
        performing the operation through the standard INT 14 interrupt, 
        thus allowing a degree of isolation from the hardware, while 
        still being able to have direct access to it. Care should be used 
        in the operation of this function though since it may conflict 
        with the operation of the driver.

        Refer to the uart technical manual for a complete description of 
        the registers and operation.

        Note: Do not use this function when packet mode is enabled. 

        This function is not supported in the 32 bit Fryers driver
        (register EAX will return a value of -1).











                          FRYERS Driver Utility               page 15 

        -----------------------------------------------------------------
        Set/reset RTS (Function 0FF04H)                        (16/ASCII)

        Entry: AH=0FFH    AL=04H    DL=Port#   
               CH=0:read RTS        CH=NZ:write RTS    
               CL=n/a               CL=NZ:set  CL=Z:clear

        Return: AL = RTS value     

        This function controls the uart RTS line. When register CH is 
        zero, the current RTS setting is returned in register AL. If CH 
        is non-zero, then the RTS line will be set to the value provided 
        in register CL. If CL is zero, the RTS line will be cleared to 
        the off condition. If CL is non-zero, the RTS line will be set 
        on. DL selects the port that is controlled. If RTS is on, AL will 
        be returned as a non-zero value. If RTS is off AL will be 
        returned as a zero value.


        Refer to the uart technical manual for a complete description of 
        the registers and operation.

        Note: Do not use this function when packet mode is enabled. 

        This function is not supported in the 32 bit Fryers driver
        (register EAX will return a value of -1).
        -----------------------------------------------------------------
        Set/reset DTR (Function 0FF05H)                        (16/ASCII)

        Entry: AH=0FFH    AL=05H    DL=Port#
               CH=0:read DTR        CH=NZ:write DTR    
               CL=n/a               CL=NZ:set  CL=Z:clear

        Return: AL = DTR value     

        This function controls the uart DTR line. When register CH is 
        zero, the current DTR setting is returned in register AL. If CH 
        is non-zero, then the DTR line will be set to the value provided 
        in register CL. If CL is zero, the DTR line will be cleared to 
        the off condition. If CL is non-zero, the DTR line will be set 
        on. DL selects the port that is controlled. If DTR is on, AL will 
        be returned as a non-zero value. If DTR is off AL will be 
        returned as a zero value.

        Refer to the uart technical manual for a complete description of 
        the registers and operation.

        Note: Do not use this function when packet mode is enabled. 

        This function is not supported in the 32 bit Fryers driver
        (register EAX will return a value of -1).






                          FRYERS Driver Utility               page 16 

        -----------------------------------------------------------------
        Flush receive interrupt buffer (Function 0FF06H)    (16/ASCII/32)

        Entry: AH=0FFH    AL=06H    DL=Port#

        Return: No Registers changed

        This function flushes the specified receive interrupt buffer, and 
        clears the uart status error bits. As a side effect, if a stop 
        transmission request was previously sent (CTS off) the internal 
        stop transmission condition flag will be cleared. The CTS line 
        will not be changed however. 


        Refer to the 8259 interrupt controller manual, and the IBM DOS 
        technical manual for more description on the serial interrupts 
        and the interrupt masks.

        Note: Do not use this function when packet mode is enabled. 

        This function only clears the buffers in 32 bit mode, the CTS 
        control handshake is not implemented.



































                          FRYERS Driver Utility               page 17 

        -----------------------------------------------------------------
        ASCII Timer Control (Function 0FF07H)          (16/ASCII/FIPP/32)

        Entry: AH=0FFH    AL=07H    DL=Port#
               CL=data    CH=timer selection (0-3)

        Return: If CH=0 then AL=tick timer multiplier
                No other registers affected

        If CH = 0 the ASCII tick timer multiplier value will be 
        initialized. Normally this does not need to be done as the value 
        is initialized when Fryers is first loaded into the system. It 
        may however be desirable to change the tick multiplier to suit a 
        value other then 10ms. If a value of zero is passed in CL the 
        ASCII tick multiplier will not be changed. If a non-zero value 
        between 1 and 255 is passed in CL, and CH=1, 2 or 3, the timer
        selected will have the value passed multiplied by the selected 
        tick multiplier value in milliseconds. The current ASCII tick 
        timer multiplier value will be returned in AL. Note that 
        regardless of the tick timer multiplier setting selected, the 
        tick timer has a tolerance of +-55 milliseconds in the 16bit 
        driver, and +-1ms in the 32bit driver.

        If CH = 1, the time-out tick value for the send function (01) 
        will be set to the value in CL. The value provided in register CL 
        is the count in tick increments (10ms default) that will be used 
        when the send function is waiting for activity.  The value only 
        needs to be changed when the time-out value is desired to be 
        changed. The time-out has a tolerance of +-55 milliseconds in the 
        16bit driver, and +-1ms in the 32bit driver.

        If CH = 2, the receive time-out value will be set to the value in 
        CL. The value provided in register CL is the count in tick 
        increments (10ms default) that will be used when the receive 
        function is waiting for activity.  The value only needs to be 
        changed when the time-out value is desired to be changed. The 
        time-out has a tolerance of +-55 milliseconds in the 16bit 
        driver, and +-1ms in the 32bit driver.

        If CH = 3, then a delay for the period of time specified in CL 
        tick increments (default = 10ms times CL) will occur, after which 
        the function will return control to the caller. The delay time 
        has a tolerance of +-55 milliseconds in the 16bit driver, and +-
        1ms in the 32bit driver.

        Starting with V4.10 if CL=0, the selected register is not 
        affected, the current setting is returned in AX (except for CH=3 
        where passing CL=0 is undefined - it does a minimal delay). 

        Note: Send and receive time-out values have no effect on packet 
        mode transmissions, nor when interrupt mode (see FF00) is 
        disabled. They are only for interrupt based ASCII transmissions. 
        See function FF17 for packet mode timing selections. 




                          FRYERS Driver Utility               page 18 

        -----------------------------------------------------------------
        Set/reset CTS control (Function 0FF08H)                (16/ASCII)

        Entry: AH=0FFH    AL=08H      DL=Port#
               CH=0:read CTS control  CH=NZ:write CTS control   
               CL=n/a                 CL=NZ:set   CL=Z:clear

        Return: AL = CTS flag     

        This function controls the CTS flow control when using the fryers 
        driver. It has no effect in IBM mode (fryers disabled). When 
        register CH is zero, the current CTS flag setting is returned in 
        register AL. If CH is non-zero, then the CTS flag will be set to 
        the value provided in register CL. If CL is zero, the CTS flag 
        will be cleared to the off condition (disable flow control). 
        If CL is non-zero, the CTS flag will be set on (enable flow 
        control). DL selects the port that is controlled. If the CTS flag 
        is on, AL will be returned as a non-zero value. If CTS flag is 
        off AL will be returned as a zero value.

        Note: Do not use this function when packet mode is enabled. 

        This function is not supported in the 32 bit Fryers driver
        (register EAX will return a value of -1).

































                          FRYERS Driver Utility               page 19 

        -----------------------------------------------------------------
        Save/Restore UART registers (Function 0FF09H)     (16/ASCII/FIPP)

        Entry: AH=0FFH    AL=09H    DL=0 - Port #1     DL=1 - Port #2   
               CH=regs/buf          CL=read/set
               DS:BX=external buffer to transfer data (only when CH=NZ)

        Return: DX=uart I/O port base address
                CX=buffer data length in bytes 
                SI:BX=Seg:Ofs of internal uart save buffer 
                DI,AX=destroyed 

        This function allows the uart registers to be saved and restored.
        This function can be called at any time, but keep in mind that it 
        may cause serious problems if the restore is called after the 
        uart has been initialized. There is only one level of save 
        allowed internally. If you call the save again, any previously 
        saved values will be replaced. So be careful. You can use the 
        buffer copy feature to read/write the buffer contents to an 
        external buffer if you wish. 

        If register CH is zero and CL is zero, the contents of the UART 
        registers are saved to an buffer inside fryers. If CH is zero and 
        CL is non-zero, the contents of the internal buffer are written 
        to the uart registers. DL selects which port the action occurs.

        If CH is non-zero and CL is zero, the internal buffer contents 
        will be copied to an external buffer located at DS:BX. If CH is 
        non-zero and CL is non-zero, then the data located at DS:BX will 
        be copied to the internal buffer. This can be used to extend the 
        buffering capability beyond the single level provided internally.
        Use this function with care since restoring the uart registers 
        may disrupt the operation of the serial port.

        This function is not supported in the 32 bit Fryers driver
        (register EAX will return a value of -1).





















                          FRYERS Driver Utility               page 20 

        -----------------------------------------------------------------
        Get/Set port Configuration (Function 0FF0A)       (16/ASCII/FIPP)

        Entry: AH=0FFH    AL=0AH    DL=0 - Port #1     DL=1 - Port #2   
               CH=set/read    CL=interrupt number; 0-15 (0=default)
               BX=Uart base address (0=default, 1=alternate) 
                  (BX is needed only when CH=NZ)  

        Return: AH=0 current configuration being read
                AL=Current interrupt number
                DI=Current UART base address 
                SI=Current interrupt Mask register address
                DL=Current interrupt Mask bit
                DH=Current hardware interrupt physical address 
          If selecting new uart configuration, also returns:
                  AH=0FFH error (bad parameters passed)
                  AH=1-15 new interrupt number that was selected  
                  BX=base address of selected uart.  
                  CX=Destroyed

        If CH is zero, the current port configuration is returned. If CH 
        is non-zero, it is assumed that the registers contain the 
        information needed to select the new port configuration.

        When reading the configuration, AH will always return zero. When 
        selecting a new configuration, AH will return the selected 
        interrupt number, or a 0FFH value if bad parameters were passed. 
        If AH returns 0FFH, it means that the new port configuration was 
        rejected, and the current configuration will be retained.

        AL always returns the current configuration value. If a new 
        configuration is being selected, AL will return the interrupt 
        number that was in use prior to the new configuration.

        When selecting a new configuration, CL must contain the new 
        interrupt number to be used. If a value of zero is passed, the 
        default interrupt for the port will be used (IRQ4 for COM1, IRQ3 
        for COM2). Additionally, only some interrupts can be used since 
        some of the interrupts are used by the existing PC hardware. 

          WARNING! You MUST understand and be aware of the UART interrupt 
          mechanism if you are going to be using this function. The 
          interrupt number selection must match up with the serial port 
          interrupt IRQ number for the UART. Failure to match the number 
          will cause the system to lockup. Make SURE you have it right.

        Register DI returns the current UART base IO address. If a new 
        UART configuration is being selected, the value is the base 
        address in use prior to the new configuration.

        Register SI returns the current interrupt controller mask 
        register IO address. If a new port configuration is being 
        selected, the value is the mask register address in use prior to 
        the new configuration.



                          FRYERS Driver Utility               page 21 

        Register DL returns the current mask bit to use with the 
        interrupt controller mask register. If a new port configuration 
        is being selected, the value is the mask bit in use prior to the 
        new configuration.

        Register DH returns the current UART hardware interrupt physical 
        address. If a new port configuration is being selected, the value 
        is the address in use prior to the new configuration.

        When reading the current configuration, register BX is not used. 
        When selecting a new port configuration, the new base address for 
        the UART is passed in register BX. If zero (0) is passed in BX, 
        the standard default UART base address will be used for the 
        configuration. If one (1) is passed in register BX, the alternate 
        default UART base address will be used for the configuration. 
        (Port #1 standard = COM1, Port #1 alternate = COM3, Port #2 
        standard = COM2, Port #2 alternate = COM4).

        If register BX contains any value other than a 0 or 1, it is 
        assumed to be a valid base address for the UART. WARNING! You 
        MUST select a valid and proper base address for the UART, or the 
        system will lock up. The UART base address selected must be the 
        same physical UART that you selected the IRQ interrupt number 
        for. Failure to properly configure the system will cause it to 
        lock up. On return, BX will contain the actual base address of 
        the selected UART. 
         
        Warning! Be very careful! Incorrectly selecting the UARTs will 
        cause nasty things to happen. You must disable the Fryers 
        extended features before switching ports (see function 0FF00H). 
        This function will refuse to select the new uart if you have not 
        turned the Fryers extended features off first. 

        It is IMPERATIVE that you understand the UART port configuration 
        process before using this function. Incorrectly configuring the 
        ports may cause the driver to not work or lockup the system. 


        This function is not supported in the 32 bit Fryers driver
        (register EAX will return a value of -1).

















                          FRYERS Driver Utility               page 22 

        -----------------------------------------------------------------
        Delete the selected port (Function 0FF0F)         (ASCII/FIPP/32)

        Entry: AH=0FFH    AL=0FH      DL=Port#   
               CL=0:ret status        CL=NZ:delete port

        Return: 32bit: AL=Port status (0=unallocated, 1=allocated)

        If CL = zero the current condition of the selected port will be 
        returned in register AL (enabled or disabled). If CL = non-zero, 
        the selected port will be closed and all resources disposed. 
        This allows another application to gain access to the port if it 
        so desires. 

        You do not need to call this function if you are shuting down 
        your application. It will automatically be called on program 
        termination. 

        Note that this call is similar to the FF00 call except that all 
        resources related to the port are discarded. The Fryers DLL 
        itself will not be discarded. That is up to your application 
        which loads the DLL. If your application does discard the DLL, 
        you should release the resources first, however the DLL itself 
        will attempt to insure that all resources are released before it 
        shuts down.

        Once the port resources have been released with this function, 
        you can reattach the port by calling the FF00 function as you 
        normally would to attach the port. 

        Note: If you turn off the port by calling this function while the 
        packet mode is enabled it will automatically disable the packet 
        mode as well. This is the same as turning off the packet mode 
        followed by immediately turning off the port. 

        When you select the port with this command, the last known 
        baudrate or default baudrate will be used. When you turn off the 
        port, control of the port is returned to Windows.

        Note: This function only exists in the 32 bit Fryers DLL driver.

















                          FRYERS Driver Utility               page 23 

        -----------------------------------------------------------------
        Enable packet control (Function 0FF10)               (16/FIPP/32)

        Entry: AH=0FFH    AL=10H    DL=Port#
               CH=0:read              CH=NZ:set
               CL=n/a                 CL=NZ:enable CL=0:disable

        Return: AL=Port select condition
                BX,CX,DX,SI,DI=unknown

        If CH = zero, the current condition of the selected port packet 
        control will be returned in register CL (enabled or disabled). If 
        CH = non-zero, then CL will control the enable or disable of the 
        selected port. 

        16bit driver:
          If CL is zero, then the port will be disabled, and control will 
          be returned to the non-packet (ASCII) control configuration   
          (see function 0FF00H). If CL is non-zero, then the packet 
          control driver will be enabled. Interrupts and buffers for the 
          selected port will be initialized for packet operation.  

        32bit driver:
          If CL is zero, then the port will be disabled, and all received   
          data will be discarded (see function 0FF00H). If CL is non-  
          zero, then the packet control driver will be enabled and the     
          port thread and buffers for the selected port will be     
          initialized for packet operation.  

        Note: If you disable the port by calling function FF00 while the 
        packet mode is enabled it will automatically disable the packet 
        mode as well. See function 0FF00 for more information. 
        In 16bit version, DX was returned with the uart base IO address, 
        This was never defined, it was left over debugging code. Don't 
        rely on it, it may go away, and is gone in the 32bit version.

        16bit note:
        When you enable 16bit packet mode operation with this command, 
        the current uart registers are saved to an internal buffer. When 
        you disable the packet mode operation, the original uart register 
        contents are restored. Note that if the port init function (00xx) 
        was called after the packet mode was enabled, disabling the 
        packet mode will restore the previous register values. ie The 
        existing register values will be discarded. If you re-enable the 
        packet mode again, you must re-init the port if you wish to 
        restore the uart initialization values again. When the packet 
        mode is enabled, the initialization values in the uart registers 
        will be used as they existed before the packet mode was enabled.

        32bit note:
        When you enable the 32bit packet mode operation, all that happens 
        is that the port thread starts accepting poll packets and will 
        respond to them when a command is waiting to be sent.




                          FRYERS Driver Utility               page 24 

        -----------------------------------------------------------------
        Send packet out the selected port (Function 0FF11)   (16/FIPP/32)

         
        Entry: AH=0FFH    AL=11H     DL=Port#
               CX=cmd length in words    
             16bit: DS:BX=pointer to array send cmd will be copied from
             32bit: EBX=pointer to array send cmd will be copied from

        Return: AL=packet error flags     AH=packet status flags   
                CX=number words copied to send buffer from array 


        The send command packet function is used to send a command packet 
        to the target machine. On entry DS:BX (EBX for 32bit driver) 
        points to an integer array containing the command to be sent. 
        (Refer to Frye Instrument Packet Protocol command definition.)

        When called the function will test to see if a command is in 
        progress. If there is already a command in progress the send 
        overrun flag will be set and the command will be aborted. (The 
        send command in progress will still continue unaffected other 
        than the send overrun flag being set.)

        Next the data count is checked to insure that the command data 
        will not overflow the internal send buffer (1000 words maximum or 
        less if configured for less). If the size is too big the send 
        overflow flag will be set and the command is aborted. Note: the 
        target machine must be able to accept the amount of data sent or 
        it will reject the packet.

        The procedure then copies command to the send buffer. The 
        checksum will be calculated and added to the end of the command 
        data.  (You do not have to compute the checksum yourself.)

        The send ready flag is cleared to off. Control is then returned 
        to the high-level program. The status flags are returned in 
        register AX (see function 0FF13). The number of words copied from 
        the integer array to the send buffer is returned in CX.

        The internal procedure will wait for the poll request from the 
        target machine, send the command, and collect the response from 
        the target machine in the background.

        Note: although the entry value passed in register CX is not 
        actually used currently by the drivers (the length information is 
        obtained by looking at the command data length), all new programs 
        should pass the total command length (including cmd# and data 
        count words) in register CX. This should be equal to the value in 
        the data count word plus two.







                          FRYERS Driver Utility               page 25 

        -----------------------------------------------------------------
        Read response packet               (Function 0FF12)  (16/FIPP/32)

        Entry: AH=0FFH    AL=12H    DL=Port#
               CX=Max destination buffer length in words    
             16bit: DS:BX=pointer to array rsp will be copied to
             32bit: EBX=pointer to array rsp will be copied to

        Return: AL=packet error flags     AH=packet status flags   
                CX=number data words copied from response buffer

        The read response function copies the response data from the 
        response buffer to an integer array pointed at by register pair 
        DS:BX (EBX in 32bit driver). The number of words copied will be 
        returned in CX. 

        No more than the maximum specified buffer size will be returned. 
        If the response data count is larger than the specified maximum 
        the receive overflow flag will be set on. 

        The receive ready flag will be set on when a response is ready to 
        be read from the response buffer. The receive ready flag will be 
        cleared to an off condition when the response is read.

        If the previous response is not read from the response buffer 
        before a new response is received, the response overrun will be 
        set, and the new response will overwrite the unread response.

        16bit note: 
        The value in register CX is not used in the 16bit driver (the 
        destination array is assumed to be large enough to accept the 
        longest possible response). However, all new programs should pass 
        the allocated size of the destination buffer in words in register 
        CX. This will allow future versions of the driver to test for 
        maximum array size. 

        32bit note:
        The destination buffer size in words must be passed in register 
        CX in the 32bit driver. This is needed to prevent a protection 
        fault from occurring should the destination buffer be to small.
        The destination size is tested before the data is transferred.
















                          FRYERS Driver Utility               page 26 

        -----------------------------------------------------------------
        Read packet status (Function 0FF13)            (16/ASCII/FIPP/32)
         
        Entry: AH=0FFH    AL=13H    DL=Port#
         
        Return: AL=packet error flags     AH=packet status flags   
                CX=packet control flags   
               16bit: 
                DL=uart error flags  DH=current interrupt state
                BX=general purpose timer
               32bit: 
                EDX=unknown
                EBX=general purpose timer
               ------ 
                SI=unknown
                DI=unknown  


        The packet transfer status byte is returned in register AL, the 
        error byte is returned in AH, the control flags in CX. 
        Register BX will contain the current value of the general purpose 
        timer. Registers SI,DI will be returned in an unknown condition.  

        This packet function can be read in ASCII mode, but the only 
        valid packet flag is bit 5 of register AL (NOPKEN) which 
        indicates if the packet mode is enabled or not. The other valid 
        register is BX/EBX which will reutrn the tick timer count. 

        ---
        16bit driver:
        Register DL is returned with the uart error flags. Register DH is 
        returned with the current interrupt state. 

        If the IOEROR flag is set, register DL will contain the uart 
        error flags (uart register five) indicating the error that caused 
        the IOEROR flag to be set. 

        Register DH is primarily for factory testing. It returns the 
        current interrupt state at the time the status function was 
        performed.

        32bit driver:
        Register DX will be returned in an unknown condition.
        ---

        The status information is a snap-shot of the current conditions 
        and flags at the time the status function is performed. 


        For a more detailed definition of the status flags refer to the 
        Frye Instrument Packet interface definition.






                          FRYERS Driver Utility               page 27 

        Error byte:

          Register AL:
            Bit 7 - TXEROR : Bad or no response from target machine
            Bit 6 - NOPOLL : Poll sync not being received
            Bit 5 - NOPKEN : The packet driver is not enabled
            Bit 4 - RCVOVR : New response overwrote old one
            Bit 3 - SNDOVF : Data size given too large to send
            Bit 2 - SNDOVR : New command given before old one sent
            Bit 1 - RCVRDY : Response data waiting to be read
            Bit 0 - SNDRDY : Ready to accept send command

        Status byte:

          Register AH:
            Bit 7 - RTYERR : Time-out on retrying the transfer
            Bit 6 - IOEROR : Communications link failure
            Bit 5 - RSPTOT : Time-out waiting for response
            Bit 4 - RCVTOT : Time-out receiving data
            Bit 3 - RCVOVF : Received data too large for buffer
            Bit 2 - NAKRSP : NAK received as a response
            Bit 1 - POLRSP : Poll received as a response
            Bit 0 - CHKERR : Bad checksum received

        Control word:

          Register CL:
            Bit 7 - PABORT : Packet transfer was aborted
            Bit 6 - AUTOQT : Auto Quick Terminate in progress
            Bit 5 - AUTOBD : Baudrate is incorrect 
            Bit 4 - RCVRSP : Receiving response packet
            Bit 3 - AWTRSP : Waiting for response packet
            Bit 2 - SNDPAK : Sending command packet
            Bit 1 - POLACT : Poll frame is active
            Bit 0 - POLSYN : Poll sync is active

          Register CH:
            Bit 7 - Spare  : not currently used
            Bit 6 - Spare  : not currently used
            Bit 5 - Spare  : not currently used
            Bit 4 - Spare  : not currently used
            Bit 3 - Spare  : not currently used
            Bit 2 - Spare  : not currently used
            Bit 1 - PKFLSH : Packet data stream being flushed
            Bit 0 - BDSEEK : Seeking new baudrate synchronization

        For a more detailed definition of the status flags refer to the 
        Frye Instrument Packet interface definition.









                          FRYERS Driver Utility               page 28 

        -----------------------------------------------------------------
        Reset packet transfer port (Function 0FF14)          (16/FIPP/32)


        Entry: AH=0FFH    AL=14H    DL=Port#
         
        Return: No registers changed


        This will force the packet control back to an idle state no 
        matter what is happening. The function can be used to abort a 
        send command packet function. This command should be avoided 
        unless absolutely needed since it will immediately abort any 
        transfer in progress causing poll synchronization to be lost and 
        forcing time-out procedures to be used to re-synchronize the 
        system. In some circumstances the attached equipment may "lock-
        up" until synchronization has been achieved.








































                          FRYERS Driver Utility               page 29 

        -----------------------------------------------------------------
        Send buffered data packet (Function 0FF15)           (16/FIPP/32)

        Entry: AH=0FFH    AL=15H    DL=Port#
         
        Return: AL=packet error flags     AH=packet status flags   
                CX=Number of data words in send buffer 

        The send buffered command packet function is used to send the 
        data currently in the send buffer to the target machine. The 
        command is assumed to be already in the send buffer. To find out 
        what the current pending or previously sent command function 
        number and data count were you can use the read send buffer 
        command (see 0FF21H).

        When called the function will test to see if a command is in 
        progress. If there is already a command in progress the send 
        overrun flag will be set and the command will be aborted. (The 
        send command in progress will still continue unaffected other 
        than the send overrun flag being set.)

        Next the data count is checked to insure that the command data 
        will not overflow the internal data buffer (1000 words maximum). 
        If the size is too big the send overflow flag will be set and the 
        command is aborted. Note: the target machine must be able to 
        accept the amount of data sent or it will reject the packet. The 
        checksum will be calculated and added to the end of the data. 

        The send flag is cleared to off. Control is then returned to the 
        high-level program. The status flags are returned in register AX 
        (see function 0FF13H). Register CX will be returned with the 
        number of words in the send buffer. 

        The Fryers driver will wait for the poll request from the target 
        machine, send the command, and collect the response from the 
        target machine in the background.





















                          FRYERS Driver Utility               page 30 

        -----------------------------------------------------------------
        Clear receive ready flag (Function 0FF16)            (16/FIPP/32)

        Entry: AH=0FFH    AL=16H    DL=Port#

        Return: AL=packet error flags     AH=packet status flags   


        This function clears the receive ready flag without having to 
        read the receive buffer. It can be used to discard an unwanted 
        response. Only the receive ready flag is affected. The updated 
        status information will be returned in register AX.













































                          FRYERS Driver Utility               page 31 

        -----------------------------------------------------------------
        Get/Set packet time-outs (Function 0FF17)            (16/FIPP/32)

        Entry: AH=0FFH    AL=17H    DL=Port#
               CH=0 - select poll time-out
               CH=1 - select response time-out
               CH=2 - select receive time-out
               CH=3 - select general purpose timer
               CH=4 - set packet timer resolution (V4.10)
               CL=0 - get current value
               CL=nz - set new value
              16bit:
               BX=value to be set (if CL=nz)
              32bit:
               EBX=value to be set (if CL=nz)

        Return:
              16bit:
                AX=current selected value
                BX=internally used value
              32bit:
                EAX=current selected value
                EBX=internally used value

        The packet time-out values can be changed through this function. 
        Register DL contains the port number to be changed. 

        Register CH contains the selector for the time-out to be changed.  
        A value of zero will select the poll time-out, a value of one 
        will select the response wait time-out. A value of two will 
        select the receive time-out. A value of three will cause a 
        general purpose timer to be set or read. New for V4.10, a value 
        of four will select the timer resolution register. This was added 
        for backwards compatibility from the 32bit functionality under 
        the Windows DLL.

        Register CL specifies whether a new time-out value is to be set, 
        or the current value is to be read. If CL is zero the current 
        value is returned in register AX. If CL is non-zero the time-out 
        is updated to the new value in register BX. Note: EAX and EBX are 
        used in the 32bit driver.

        New for V4.10; If CH = 4 the packet timer multiplier value will 
        be initialized. Normally this does not need to be done as the 
        value is initialized when the Fryers program is first loaded into 
        the system. It may however be desirable to change the multiplier 
        to suit a value other then 55ms, in which case a multiplier value 
        can be provided in register BX to change the value (only values 
        in the range of 1ms-255ms are valid). If a value of zero is 
        passed, the timer is not set. The current selected value will be 
        returned in AX (or EAX in the 32bit driver). The actual internal 
        value used will be returned in BX (EBX).





                          FRYERS Driver Utility               page 32 

        The timer resolution in version 4.10 was incorrectly computed. If 
        you have version 4.10, you should replace it with V4.11. There 
        were no known V4.10 drivers released to the field, so this should 
        not be a problem.

        Register BX (EBX) will return the internal time value used. This 
        may be different than the value programmed. Particularly in the 
        16 bit driver which has a 55ms resolution. For CH=4, the returned 
        value will be the internal tick resolution used in mS. 

        The packet time-outs are controlled by the 'packet tick counter'. 
        The packet tick counter has a resolution of approximately 55 
        milliseconds in the 16bit driver. The 32bit driver and has a 
        resolution of +-1ms. The packet tick timer multiplier is 
        adjustable from 1ms to 255ms. Note that setting a timeout value 
        to zero will inhibit the time-out for that selection.

        The general purpose timer can be used by the high-level program 
        to time packet transfer activities. The counter can be set to 
        any value with the set function. It will be incremented once 
        every packet tick time. The counter can be read at anytime with 
        the get function. The timer value is also returned in register 
        BX in the packet status function (function 0FF13H).

        See the Frye Instrument Packet Protocol definition for a more 
        detailed definition of the time-outs.































                          FRYERS Driver Utility               page 33 

        -----------------------------------------------------------------
        Get/Set maximum buffer size (Function 0FF18)         (16/FIPP/32)

        Entry: AH=0FFH    AL=18H    DL=Port#
               CH=0 select send buffer  
               CH=1 select recieve buffer               
               CL=0 get maximum buffer size 
               CL=nz set maximum buffer size  
               BX=new maximum buffer size 
         
        Return: AX=maximum buffer size
                SI=Buffer address *

        The maximum packet buffer size can be changed through this 
        function. Register DL contains the port to be changed. 

        Register CH contains the selector for the buffer to be changed.  
        A value of zero will select the send buffer, and a value of one 
        will select the receive buffer.

        Register CL specifies whether a new maximum buffer size is to be 
        set, or the current maximum size to be read. If CL is zero the 
        current value is returned in register AX. If CL is non-zero the 
        maximum buffer size is updated to the new value in register BX.

        The buffer size is specified in words. See the Frye Instrument 
        Packet Protocol definition for a more detailed definition of the 
        send and receive buffers.

        The Recieve Buffer is shared with ASCII and Packet modes. Setting 
        a buffer size will flush any data that might be in the buffer 
        even if the buffer size doesn't change. 

        * For 32 bit driver, the buffer address is returned in reg SI.























                          FRYERS Driver Utility               page 34 

        -----------------------------------------------------------------
        Get/Set Poll Error Count (Function 0FF19)            (16/FIPP/32)

        Entry: AH=0FFH    AL=19H    DL=Port#
               CL=0 get poll error count
               CL=nz set poll error count
              16bit: BX=new total poll error count (0=clear)
              32bit: EBX=new total poll error count (0=clear)
         
        Return:
                BL=autobaud detect count
                BH=packet retry count
                CX=packet error flags
                SI=commands sent since startup
                DI=commands resent since startup
               16bit: AX=total packet errors since last reset
               32bit: EAX=total packet errors since last reset
                ----------
                DX=unknown  

        The cumulative poll error count can be read or changed through 
        this function. The poll error count is a cumulative count of all 
        poll errors that have occurred since Fryers was loaded and the 
        packet protocol was first enabled. It is reset only when Fryers 
        is reloaded, or by explictly changing the value through this 
        function call. The purpose of the Poll error count function is to 
        provide a debugging tool to determine the condition of the port 
        link while in operation. This function was added in version 2.11 
        of Fryers.

        Register DL contains the port to select. Register CL specifies 
        whether a new poll error count is to be set, or the current poll 
        error count is to be read. If CL is zero the current value is 
        returned in register AX. If CL is non-zero the poll error count 
        is updated to the new value provided in register BX.

        On return, AX will contain the current total packet error count. 
        CX will contain the packet error flags (same as register AX in 
        function $FF13). Register BL will contain the current autobaud 
        synchronization error count. Register BH will contain the current 
        packet retry count.  Register DX will contain an unknown value.

        New with V4.15 and V5.15: Register SI will return the number of 
        commands that have been sent since startup, and DI will return 
        the number of command that have had to be resent due to 
        communication error since startup (this does not count illegal 
        commands). This can be useful for debugging communications 
        problems.









                          FRYERS Driver Utility               page 35 

        -----------------------------------------------------------------
        Set/Reset Auto Quick Terminate (Function 0FF1AH)     (16/FIPP/32)

        Entry: AH=0FFH    AL=1AH    DL=Port#
               CH=0:get auto-release flags    CH=NZ:write Auto-Release 
               CL=n/a                         CL=NZ:set  CL=Z:clear

        Return: AL = Auto-Release flags    
                BX = Auto QT responses sent since startup. 
                CX = Manual QT responses sent since startup. 
                DX = Failed QT responses since startup. 
                SI = Polls sent since startup.
                SI = Failed Polls since startup.

        This function controls the poll auto-release (automatic quick 
        terminate) when using the fryers driver. It has no effect in non-
        packet mode. 

        When register CH is zero, the current poll auto-release flag 
        settings are returned in register AL. If CH is non-zero, the 
        auto-release flag will be set to the value provided in register 
        CL. If CL is zero, the poll auto-release flag will be cleared to 
        the off condition (disable poll auto-release). If CL is one, the 
        auto-release flag will be set on (enable poll auto-release). 

        The only valid values to be passed in CL are 0(off) and 1(on).
        The Poll Auto-Release flag will return a copy of the internal 
        poll auto-release flag in register AL. This flag uses the 
        following bits: 

          Bit 0   indicates the poll auto-release function is enabled. 
          Bit 1   indicates an auto-release in in process. 
          Bit 2   indicates an auto-release cancel operation in progress.
          Bit 3   indicates a manual quick terminate in progress.
          Bit 4,5 failure counter
          Bit 6   <reserved>
          Bit 7   indicates that quick terminate failed.

        The power on default for poll auto-release is disabled.
        When the Poll Auto-Release function is enabled, it causes a 
        Quick-Terminate command to be sent to the attached device in 
        response to a poll. If three ILLegal command responses in a row 
        are received, the Auto-Release command will be automatically 
        disabled. Any valid command that is sent (except for a manual 
        quick terminate command) will reset the failure count. 

        The automatic Quick Terminate function can be enabled (or re-
        enabled) by using the set/reset auto quick terminate command 
        (FF1A). The function can be disabled by either disabling and 
        reenabling the packet operation (FF10), or by using the set/reset 
        auto quick terminate command (FF1A). 






                          FRYERS Driver Utility               page 36 

        Note that you can always use the quick terminate feature to 
        complete a command sequence. This is the preferred way to release 
        the instrument with the new Fryers driver. It eliminates the need 
        for the skip poll delay by providing an automatic skip poll. 

        When in operation, the poll auto-release (auto quick terminate) 
        will automatically release the poll sent by the attached device 
        if there is no command waiting to be sent by the Fryers driver. 
        This causes the device to immediately exit the poll sequence 
        rather than waiting the normal 50ms of time for a no-response 
        from the computer. The Fryers driver (on the computer side) does 
        not expect a response to the Quick Terminate command sent to the 
        attached device. Any response returned other than a POLL or 
        ILLegal command will be ignored. The poll auto-release works just 
        like a skip-poll without the associated delay of the skip-poll. 
        The use of the automatic Quick Terminate can boost the 
        performance of the instrument since it doesn't have to wait the 
        full 50ms to determine that the computer has nothing to send. 

        For earlier versions of Fonix instruments that do not support 
        Quick Terminate, the Fryers driver will monitor the manual Quick 
        Terminate command and if it fails (the instrument returns an 
        ILLCMD), Fryers will perform an automatic skip poll. In most 
        cases this should eliminate the need to perform the default 100ms 
        wait to release the instrument. The automatic skip poll feature 
        was added to V4.12(16bit) and V5.12(32bit) versions of Fryers.

        If the automatic Quick Terminate feature is turned on, and the 
        attached Fonix instrument does not support the feature, the 
        Fryers driver will monitor the results of the Quick Terminate 
        command. If three or more ILLCMD responses to the Quick Terminate 
        command occur, the Fryers driver will turn off the automatic 
        Quick Terminate feature. It needs to do this, otherwise the 
        instrument would never get released because it would be spending 
        all its time responding to the command it does not understand. 

        Bit 7 (the high bit) of the flags will be set when it is 
        determined that the attached instrument does not support the 
        Quick Terminate feature. 

        Since over time, it is possible for an ILLCMD failure to occur 
        normally, any valid command sequence will clear the Quick 
        Terminate counter in order to prevent inadvertent cancellation of 
        the feature. 













                          FRYERS Driver Utility               page 37 

        Note that when switching instruments, it is possible for an 
        ILLCMD sequence to occur that might disable the automatic Quick 
        Terminate feature. Also, it is possible that one attached 
        instrument doesn't support the feature, while another instrument 
        might. If you expect to be switching between different 
        instruments, your program should check on the status of the Quick 
        Terminate to see if it has been turned off and whether you wish 
        it to remain off. Minimal impact to the instrument will occur if 
        you turn on the Quick Terminate feature during an idle period or 
        when you detect an instrument change has occurred. 

        Note that even if the auto Quick Terminate feature has been 
        turned off, you can still send a Quick Terminate command with 
        your program to release the instrument. 


        Register BX will return the Auto QT responses sent since startup. 
        Register CX will return Manual QT responses sent since startup. 
        Register DX will return the Failed QT responses since startup. 
        Register SI will return the Polls sent since startup.
        Register SI will return the Failed Polls since startup.
        The above registers will return information that can be useful 
        for debugging the drivers or an application. 


































                          FRYERS Driver Utility               page 38 

        -----------------------------------------------------------------
        Set Packet Auto-Baud (Function 0FF1BH)               (16/FIPP/32)

        Entry: AH=0FFH    AL=1BH    DL=Port#
               BX=new baudrate to start from  
        Return: BX=0 and AX=0  : successful command, no baud change
                BX=0 and AX=1  : seeking new baudrate 
                BX=0 and AX=-1 : cmd failed, Fryers driver not found
                BX=0 and AX=-2 : cmd failed, Packet mode not enabled
                BX=0 and AX=-3 : cmd failed, bad baudrate given (16 bit)
                BX=0 and AX=NZ : cmd failed, reason unknown
                BX=NZ and AX=unknown : baud changed, new baudrate in BX
                CX=unknown  DX=unknown  SI=unknown  DI=unknown  

        This function controls the packet automatic baudrate selection 
        when using the fryers driver. It has no effect in non-packet mode 
        (fryers disabled).  DL selects the port. BX contains the new 
        baudrate to use. Currently the only valid values are 9600, 19200, 
        28800, 38400, and 57600 (>58000=115200baud). If BX = 0, then the 
        next possible baudrate to try is selected from an internal table.  
        The baudrate will only be changed if the packet control engine 
        has determined that the current baudrate is incorrect.

        If baudrate is changed, BX will return with the new baudrate. If 
        the baudrate was not changed, BX will return with zero. If the 
        command was given in error (packet not enabled, or bad baudrate), 
        AX will be returned as a negative value. If no change occured, AX 
        will be zero. If the baudrate was changed (BX=NZ), then AX will 
        be unknown. (Actually, AX will be the status result from the 
        InitPort command, 00xx, but this is not defined and may change.)
        The AX=-3 fail value is only valid in the 16bit driver. The 32bit 
        driver will just select the next closest baudrate instead. 
        Note: you should still call the $00xx function to set the packet 
        baudrate to the initial value. This function is intended for on-
        going automatic update of the packet baudrate if needed.

        You can watch the AUTOBD flag in the Packet Control flags 
        register to determine if a baudrate change is needed. 
        A simpler way is to just periodically call this command while 
        waiting on the command status (packet ready). If you just 
        periodically call this command in your status loop, it will 
        automatically update the baudrate for you as needed.
        If you need to set the baudrate to a specific value, use the 00xx 
        function (Initialize Port). If you know the baudrate and you have 
        set it properly, you do not need to call this function.

        This mechanism is new with V4.00. The old internal automatic 
        baudrate control was removed due to conflicts with virtual UARTs 
        in protected mode systems such as Windows which were unable to 
        deal with baudrate changes inside the interrupt service routine. 

        Warning: Prior to V4.10 the driver would blow up if any non-valid 
        value was passed in BX. It is recommended that this function not 
        be used with drivers earlier than V4.10 other than with BX=0.



                          FRYERS Driver Utility               page 39 

        -----------------------------------------------------------------
        Set/reset Skip Poll Flag (Function 0FF1CH)           (16/FIPP/32)

        Entry: AH=0FFH    AL=1CH    DL=Port#
               CH=0:get Skip Poll flag       CH=NZ:write Skip Poll flag
               CL=n/a                        CL=NZ:set  CL=Z:clear

        Return: AL = Skip Poll flag     

        This function controls the skip poll flag when using the 
        fryers driver. It has no effect in non-packet mode (fryers 
        disabled). When register CH is zero, the current skip poll flag 
        setting is returned in register AL. If CH is non-zero, then the 
        skip poll flag will be set to the value provided in register CL. 
        If CL is zero, the skip poll flag will be cleared to the off 
        condition (cancel skip poll).  If CL is one, the skip poll flag 
        will be set on (begin skip poll). DL selects the port. If the 
        skip poll flag is on, AL will be returned as a non-zero value. If 
        skip poll flag is off AL will be returned as a zero value. 

        The only valid values to be passed in CL are 0(off) and 1(on).
        The Skip Poll flag will return a copy of the internal skip poll 
        flag. Once the flag has been set, it will only be cleared by 
        either this function clearing it, the port being reset, or a 
        valid poll being received. 

        To perform a skip poll, set the flag and wait for it to clear. 
        When the flag is cleared, it indicates that the poll has been 
        skipped, meaning that the attached instrument will have exited 
        its communications mode and returned to the measurement cycle. 
        A command should not be pending since a pending command will be 
        sent, and the poll flag will be cleared anyway, resulting in the 
        poll not really being skipped.

        The Skip Poll function provides an absolute mechanism to skip a 
        poll from the attached instrument, thus insuring that the poll 
        has really been skipped, and the attached device has thus exited 
        its communications mode so that it can perform the measurement 
        cycle. In the past, this required a time related function that 
        waited for 200 milliseconds to pass. Normally this would insure 
        that the poll would be skipped, but caused a loss of 
        communication time and was only reliable when the poll delay time 
        was within the 200 millisecond time frame. With the ability to 
        change the poll delay time, this may no longer be the case. If 
        you are using long poll delays, you should use the Skip Poll 
        function to insure that the poll really was skipped. Newer 
        programs may wish to use the skip poll function since it is more 
        reliable, and faster. Only the amount of time needed to skip a 
        poll is consumed.

        A better method would be to send a Quick Terminate command 
        instead. The quick terminate command immediately releases the 
        communication link. Check the reference notes for the instrument 
        to determine whether it supports quick terminate.



                          FRYERS Driver Utility               page 40 

        -----------------------------------------------------------------
        Debug Information                (Function 0FF1F)    (16/FIPP/32)

        Entry: AH=0FFH    AL=1FH    DL=Port#

        Return: Unknown
         
        This function is used during debugging of the driver to return 
        information above various internal conditions of the driver 
        during development. The contents of the registers is undefined 
        and changes depending on the development cycle and what is being 
        looked at during the debug process. 

        The call is noted here so that you will know that it exists and 
        that the register contents will be in an unknown condition if you 
        call it.









































                          FRYERS Driver Utility               page 41 

        -----------------------------------------------------------------
        Write only to Send packet buffer (Function 0FF20)    (16/FIPP/32)

        Entry: AH=0FFH    AL=20H    DL=Port#
               CX=number of words in the integer array.
             16bit:
               DS:BX=pointer to an integer array containing the command.  
             32bit:
               EBX=pointer to an integer array containing the command.  

        Return: AL=packet error flags     AH=packet status flags   
                CX=number of words copied to internal send buffer
         
        This function is used to write data into the packet send buffer 
        without sending it. The command loaded into the send packet 
        buffer can then be sent with the re-send function. 

        On entry DS:BX (EBX in the 32bit driver) points to an integer 
        array containing the command to be written to the send packet 
        buffer. Register CX specifies the total number of words in the 
        array. Register CX is returned with the number of words that were 
        copied to the send packet buffer. Register AX is returned with 
        the packet status information flags.

        When called the function will test to see if a command is in 
        progress. If there is already a command in progress the send 
        overrun flag will be set on and the new command will be canceled. 
        (The send command in progress will still continue unaffected 
        other than the send overrun flag being set on.) 

        The size is checked to be within the maximum limit. If the 
        command is too large the send overflow flag will be set. If the 
        send overflow  and send overrun flags were not set on, the 
        procedure then copies the data provided in the integer array to 
        the send packet buffer. Control is then returned to the high-
        level program. Prior to version 4.10, the size was passed as the 
        second word in the data array. Starting with V4.10, the size is 
        expected to be in register CX as well. Actually, the V4.10 driver 
        will still work if the size is not in CX, but I am trying to 
        transition to having the size in register CX to make things a bit 
        safer. (So I don't have to try to peek into a potentially unsafe 
        memory location to get the size information.)


        Note: although the value in register CX is not actually used 
        currently by the drivers (the length information is obtained by 
        looking at the command data length), all new program should pass 
        the total command length (including cmd# and data count words) in 
        register CX. Future releases will be testing the length in RegCX.








                          FRYERS Driver Utility               page 42 

        -----------------------------------------------------------------
        Read the send buffer (Function 0FF21)                (16/FIPP/32)

        Entry: AH=0FFH    AL=21H    DL=Port#
               CX=Maximum length of destination array in words.
             16bit:
               DS:BX=pointer to array send command will be copied to.
             32bit:
               EBX=pointer to array send command will be copied to.  
         
        Return: AL=packet error flags     AH=packet status flags   
                CX=number data words copied from send buffer
                Send array data is copied to destination array.


        The read send buffer function copies the command currently in 
        send buffer to an integer array pointed at by register pair 
        DS:BX (EBX in the 32bit driver). Register CX specifies the 
        maximum number of words that the destination array can accept. 
        The number of words that were copied into the destination array 
        will be returned in register CX. No other flags or conditions 
        will be affected by reading the send buffer.

        The send data buffer can be read at any time. It reflects the 
        data residing in the send data buffer from the last send command. 
        Reading the send data buffer will not affect any command in 
        progress. 

        If the destination buffer is too small to receive the data, the 
        data will not be transferred, and the SNDOVF flag in the status 
        flags will be set. Note that since this is not a transmission 
        error, the TXEROR flag will not be set. Also keep in mind that 
        the SNDOVF flag may get reset if a packet transmission pending.

        16bit note: 
        The value in register CX is not used in the 16bit driver (the 
        destination array is assumed to be large enough to accept the 
        longest possible command). However, all new programs should pass 
        the allocated size of the destination buffer in words in register 
        CX. This will allow future versions of the driver to test for 
        maximum array size. 

        32bit note:
        The destination buffer size in words must be passed in register 
        CX in the 32bit driver. This is needed to prevent a protection 
        fault from occurring should the destination buffer be to small.
        The destination size is tested before the data is transferred.










                          FRYERS Driver Utility               page 43 

        -----------------------------------------------------------------
        Read the response buffer (Function 0FF22)            (16/FIPP/32)
             (non-destructive) 

        Entry: AH=0FFH    AL=22H    DL=Port#
               DS:BX=pointer to array response buffer will be copied to
               CX=Maximum length of destination array in words.
             16bit:
               DS:BX=pointer to array response buffer will be copied to.
             32bit:
               EBX=pointer to array response buffer will be copied to.

        Return: AL=packet error flags     AH=packet status flags   
                CX=number data words copied from response buffer
                Response buffer data is copied to destination array.

        The read response buffer function copies the data currently in 
        response buffer to an integer array pointed at by register pair 
        DS:BX (EBX in the 32bit driver). Register CX specifies the 
        maximum number of words that the destination array can accept. 
        The number of words copied will be returned in CX. This function 
        does not affect the receive ready flag, it will remain in it's 
        current state. 

        The response data buffer can be read at any time. It reflects the 
        data residing in the response buffer from the last response 
        received (or the partial contents of a response currently being 
        received). Reading the response buffer with this function will 
        not clear the receive ready flag to off. Reading the response 
        buffer while the send ready flag is off may cause erroneous data 
        to be read since a response could be in the process of placing 
        data in the response buffer. 

        If the destination buffer is too small to receive the data, the 
        data will not be transferred, and the RCVOVF flag in the status 
        flags will be set. Note that since this is not a transmission 
        error, the TXEROR flag will not be set. Also keep in mind that 
        the RCVOVF flag may get reset if a packet transmission pending.


        16bit note: 
        The value in register CX is not used in the 16bit driver (the 
        destination array is assumed to be large enough to accept the 
        longest possible response). However, all new programs should pass 
        the allocated size of the destination buffer in words in register 
        CX. This will allow future versions of the driver to test for 
        maximum array size. 

        32bit note:
        The destination buffer size in words must be passed in register 
        CX in the 32bit driver. This is needed to prevent a protection 
        fault from occurring should the destination buffer be to small.
        The destination size is tested before the data is transferred.




                          FRYERS Driver Utility               page 44 

        -----------------------------------------------------------------
        Indexed send buffer write (Function 0FF23)           (16/FIPP/32)
         
        Entry: AH=0FFH    AL=23H    DL=Port#
               CX=index into send buffer
               BX=word to be written
         
        Return: AL=packet error flags     AH=packet status flags   

        This function allows an individual word to be written to the send 
        buffer. Register CX contains the index into the send buffer 
        (zero relative to the beginning of the buffer). Register BX 
        contains the data to be written to the send buffer.

        Data cannot be written past the maximum specified buffer size.  
        If the index is larger than the specified maximum, the send 
        checksum word will be written to instead. (Note: this is really 
        pointless since the send checksum is recreated when the command 
        is actually sent.) 

        If a send is in progress at the time the buffer is written to the 
        send overrun flag will be set on. The send in progress will not 
        be affected other than if the written word has not been sent yet 
        the new word will be the one sent.

        The send data buffer can be written to at any time. However it 
        should be noted that if the send ready flag is off it cannot be 
        known what affect to the command in progress writing to the 
        buffer will have.




























                          FRYERS Driver Utility               page 45 

        -----------------------------------------------------------------
        Indexed response buffer write (Function 0FF24)       (16/FIPP/32)
         
        Entry: AH=0FFH    AL=24H    DL=Port#
               CX=index into response buffer
               BX=word to be written
         

        Return: AL=packet error flags     AH=packet status flags   

        This function allows an individual word to be written to the 
        response buffer. Register CX contains the index into the response 
        buffer (relative to the beginning of the buffer). Register BX 
        contains the data to be written to the response buffer.

        Data cannot be written past the maximum specified buffer size.  
        If the index is larger than the specified maximum, the response 
        checksum word will be written to instead. 

        If a response is in progress at the time the response buffer is 
        written to the response overrun flag will be set on. The response 
        may or may not be affected depending upon conditions at the time 
        the word was written. The response buffer should not be written 
        to while a response is being received.

        The response buffer can be written to at any time. However it 
        should be noted that if the send ready flag is off it cannot be 
        known what affect to the command in progress writing to the 
        buffer will have.




























                          FRYERS Driver Utility               page 46 

        -----------------------------------------------------------------
        Indexed send buffer read (Function 0FF25)            (16/FIPP/32)
         
        Entry: AH=0FFH    AL=25H    DL=Port#
               CX=index into send buffer
         

        Return: AL=packet error flags     AH=packet status flags   
                BX=command number in buffer (index 0)
                CX=command data count word in buffer (index 1)
                DX=data word read at indexed location (at index - CX)

        This function allows an individual word to be read from the send 
        buffer. Register CX contains the index into the send buffer 
        (zero relative to the beginning of the buffer). 

        Data cannot be read past the maximum specified buffer size.  If 
        the index is larger than the specified maximum, the send checksum 
        word will be returned instead. 

        The send buffer can be read with the indexed read at any time. An 
        indexed read of the send buffer will not affect any command that 
        might be in progress at the time. 

        The data word read at the index location provided in register CX 
        will be returned in register DX. The command data count word 
        (index location one (1) in buffer) will be returned in register 
        CX. The command number (index location zero (0) in the buffer) 
        will be returned in register BX. This allows testing the contents 
        of the buffer to find out what command is there without having to 
        read the entire buffer.


























                          FRYERS Driver Utility               page 47 

        -----------------------------------------------------------------
        Indexed response buffer read (Function 0FF26)        (16/FIPP/32)
         
        Entry: AH=0FFH    AL=26H    DL=Port#
               CX=index into response buffer
         

        Return: AL=packet error flags     AH=packet status flags   
                BX=response number in buffer (index 0)
                CX=response data count word in buffer (index 1)
                DX=data word read at indexed location (at index - CX)

        This function allows an individual word to be read from the 
        response buffer. Register CX contains the index into the response 
        buffer (zero relative to the beginning of the buffer). 

        Data cannot be read past the maximum specified buffer size.  
        If the index is larger than the specified maximum, the response 
        checksum word will be returned instead. 

        The response buffer can be read with the indexed read at any 
        time. An indexed read of the response buffer will not affect any 
        command that might be in progress at the time. 

        The data word read at the index location provided in register CX 
        will be returned in register DX. The response data count word 
        (index location one (1) in buffer) will be returned in register 
        CX. The response number (index location zero (0) in the buffer) 
        will be returned in register BX. This allows testing the contents 
        of the buffer to find out what response is there without having 
        to read the entire buffer.


























                          FRYERS Driver Utility               page 48 

        Return Version String (Function 0FFFDH)                     (ALL) 

        Returns the version/copyright string of the installed driver.

        Entry: AH=0FFH    AL=FDH    DL=Port#    CX=Index

        Return: AX=Version string character at index in CX
                if CX=0 AX=length of version string
                CX = index;   BX,DX,SI,DI = unknown

        This allows the ability to read the version string without the 
        use of pointers. To find the length of the version string, pass 
        zero in register CX. Register AX will return with the length of 
        the string (number of characters). You can then use a for loop to 
        read the individual characters by passing the desired character 
        index in register CX. 

        The string is a null terminated short Pascal string. That is, 
        there is a length byte at the beginning of the string (first 
        position of the character array), and the final character 
        position is a null. The null is not included in the character 
        count byte at the start of the string. Note that there normally 
        are two CR/LF pairs embedded in the string. This string is simply 
        a copy of the string that is displayed when FRYERS.COM is loaded 
        (it is not displayed in  FRYERS.DLL). The maximum string length 
        that can be copied is 254 characters (a total of 256 characters; 
        string+length+null). 






























                          FRYERS Driver Utility               page 49 

        -----------------------------------------------------------------
        Return Long Version (Function 0FFFEH)                       (ALL) 

        Returns the version/copyright string of the installed driver.

        Entry: AH=0FFH    AL=FEH    DL=Port#
              16bit:
               SI:DI(seg:ofs)=pointer to destination for sign-on string  
               Does not return string if SI=0 
              32bit:
               SI=1 or 2 return string, SI=0 do not return string.
               EDI=pointer to destination for sign-on string (if SI=1).
               EDI=pointer to pointer of destination string (if SI=2).

        Return: AX=Short Version number (in hex) (ie V2.70 = 27H)      
                BX=Long Version number in decimal (ie V2.70 = 270) 
                CL=Length of version/copyright string
                DX=0FFFFH  
                CH=unknown 
              16bit: DI=Code segment of Fryers.com      
                     SI=unknown
              32bit: DI=unknown                         
                     SI=unknown

        16 bits:
        In the 16bit driver, register pair SI:DI (seg:ofs) is passed with 
        the destination address for the sign-on string to be copied to. 
        If SI(seg) is 0, the sign-on string is not returned. 

        32 bits:
        In the 32bit driver, SI is used as a switch. If SI is zero, the 
        string will not be returned. If SI is 1, the string will be 
        copied to the character array pointed at by EDI (EDI is a simple 
        pointer). If SI=2, the string will be copied to the byte array 
        pointed at by the pointer in EDI (EDI is a pointer to a pointer). 
        Values greater than 2 in ESI will be treated as if ESI was 0 (the 
        version string is not copied).

        The string is a null terminated short Pascal string. That is, 
        there is a length byte at the beginning of the string (first 
        position of the character array), and the final character 
        position is a null. The null is not included in the character 
        count byte at the start of the string. Note that there normally 
        are two CR/LF pairs embedded in the string. This string is simply 
        a copy of the string that is displayed when FRYERS.COM is loaded 
        (it is not displayed in  FRYERS.DLL). The maximum string length 
        that can be copied is 254 characters (a total of 256 characters; 
        string+length+null). 









                          FRYERS Driver Utility               page 50 

        Register CL contains the length of the sign-on string. This is 
        always passed back whether the sign-on string is copied or not. 
        If you are uncertain of the amount of memory needed, you can pass 
        SI=0 and look at the string size on CL. However, it is usually 
        simpler to just assume the worst case of 256 characters.

        The old style short Hex version number is returned in AX. A newer 
        long version number, in decimal, is returned in register BX. 
        Register DX always returns 0FFFFH.

        16bit notes: The code segment in Fryers.com is where all the code 
        and data are referenced to. Also note that no segment registers 
        are used here. This is to allow compatibility for protected mode 
        software which disallows passing of segment registers 
        (Windows/DPMI use). Keep in mind that since the FRYERS.COM driver 
        operates in Real mode, the memory location passed in SI:DI must 
        be located in DOS memory (allocated with GlobalDOSAlloc), and 
        must be in the Real mode Seg:Ofs format. Refer to the DPMI 
        document which you can obtain from Intel or Microsoft for more 
        information on using a real mode pointer in protected mode (it 
        requires a pointer translation).




































                          FRYERS Driver Utility               page 51 

        -----------------------------------------------------------------
        Return Short Version (Function 0FFFFH)                      (ALL) 

        Returns version number of the installed driver in register AL.

        Entry: AH=0FFH    AL=FFH    DL=Port#

        Return: AX=Version number (in hex)      
                DX=0FFFFH  
                DI=Baudrate clock value  
               16bit:
                ES:SI=pointer to sign-on string  
                BX=Port interrupt status  
                ES:CX=Hardware interrupt service address for port  
               32bit: 
                ESI=pointer to sign-on string  
                EBX=comm port handle 
                ECX=unknown

        Version 1.xx of FRYERS.COM included the interrupt driven RS232 
        control for ASCII communications.  The extended functions 0FF00H 
        through 0FF07H were provided to allow specialized communications 
        to older Frye Electronics instruments that used the ASCII 
        protocol to communicate.

        Version 2.xx of FRYERS.COM included the new baudrate select 
        extensions to 19200, 28800, 38400, and 57600 baud (see function 
        00H). It also included the new Frye Instrument Packet Protocol 
        (functions 0FF10H through 0FF26H) to allow communications with 
        the newer Frye Electronics instruments.

        Version 2.20 of FRYERS.COM added the ability to see if the 
        hardware interrupts are hooked up as a part of the version test. 
        Prior to V2.20 register DX was ignored. Now DX determines which 
        port to check to see if the interrupt is hooked up. Turning 
        Fryers extensions on automatically hooks up the interrupts.
        The new check was provided because it is potentially possible for 
        other software to steal the interrupt, or to otherwise disrupt 
        it. This test can be used to determine if the interrupt is still 
        connected to fryers or not. This is useful for debugging the 
        problem.

        As an additional assist, DX will now be returned with 0FFFFH in 
        it. This is useful to determine if the FRYERS.COM driver is still 
        around. If DX is returned with a value other than 0FFFFH in it, 
        then the driver is not loaded. No other extended Fryers commands 
        should be given until it is first determined that the FRYERS 
        driver is loaded. Prior to V2.20 of FRYERS.COM, only register AX 
        was affected. To detect version control prior to V2.20 you should 
        look to see if AH=0FFH and AL=10h, AL=20h, or AL=21h. For FIPP 
        use, it must be version 20h or better, and for autobaud use with 
        FIPP it must be 21h or better. For 16bit Windows programs, you 
        should use V4.00 or better, and for 32bit Windows, you should use 
        the FRYERS.DLL library.



                          FRYERS Driver Utility               page 52 

        16 Bit Notes:

        In the 16bit FRYERS.COM driver, register BX is used to indicate 
        the status of the hardware interrupt for the selected port. If 
        the Interrupt has been damaged, BX will return a zero value. If 
        the interrupt is ok, BX will return a non-zero value. The value 
        returned will be the current segment value that should be in the 
        interrupt vector. Registers ES:CX will return the correct value 
        that should be in the hardware interrupt vector when the fryers 
        interrupt and or packet operation has been enabled. While it is 
        possible to take this pointer and re-insert it into the hardware 
        interrupt vector to restore operation, you should find out why it 
        was damaged in the first place, and the driver should be reloaded 
        (normally by rebooting the computer) at the first opportunity. 
        This information was added in version 2.30. 

        Note: originally BX was supposed to return a zero value if the 
        interrupt vector was ok, and a NZ value containing the expected 
        segment that was supposed to be there if the vector was bad. 
        Unfortunately, it was coded incorrectly. Since there is now 
        software out there that uses the function as it is, the 
        documentation was changed to match the action of the code. This 
        changed as of V3.00 of the Fryers software. Early versions of 
        CHAP incorrectly used this function (followed the spec rather 
        than the code), but the problem was never noticed because Chap is 
        self-correcting for such problems. Also, prior to V3.00 register 
        CX returned the interrupt number, not the interrupt address 
        offset. This was corrected in V3.00 and above. 

        Registers ES:SI are returned pointing at the sign-on string. You 
        can use this to find out in more detail the version number and 
        date of the driver. This information was added in version 2.30. 
        Register ES will not contain valid data in protected mode. You 
        should use the Get Long Version function to get a copy of the 
        string in protected mode. 

        In V2.40 and above, register DI contains the baudrate clock that 
        was sent to the Uart. You can use this to determine the last 
        selected baudrate value for the port. It should be noted that if 
        the baudrate was changed externally the value in DI may not be 
        valid. Also, if the value in DI is zero, it means that the Fryers 
        driver has not been told to set a baudrate value yet. You can 
        convert the clock value in DI to the baudrate value by dividing 
        the clock into 115200 (baudrate = 115200/baudclock).

        Finally, please Note that the lowest portion of the version 
        number (hundredths) is not returned by version. To obtain the 
        full number you will have to read it out of the sign-on string, 
        or call the get long version function 0FFFEH.








                          FRYERS Driver Utility               page 53 

        32 Bit notes:

        The 32 bit DLL version of Fryers has the same type of command 
        interface as the 16 bit MSDOS based TSR driver. The main 
        difference is that since the call must be made as a procedure 
        call rather than an interrupt call, the register information is 
        placed in a register declaration structure rather than in actual 
        registers. 

        If you are converting code from 16 bit to 32 bit, there may be 
        little or no changes required depending on how the 16 bit code 
        was implemented. Even where changes are required, they should be 
        limited to rewriting the code that calls the 16 bit interrupt.  
        Refer to the sample code for examples on code that can 
        transparently be compiled for either 16 or 32 bit operation.

        There are several limitations to the DLL approach. The 16bit DLL 
        that is used to interface with FRYERS.COM is limited to not being 
        able to use pointers. This is due to limitations of protected 
        mode programming. In the 32 bit DLL pointers can be used because 
        the problems with selectors goes away in 32 bit (all pointers are 
        simple offsets). 

        The main difference with the 32 bit return values are that the 
        signon string pointer is returned in ESI, and the comport handle 
        will be returned in EBX. ECX is not currently used in 32bit mode.

        Note that in the 16bit driver, BX will always return a non-zero 
        value if the Fryers driver is loaded and ok. Whereas in the 32bit 
        Fryers driver EBX will return a zero value until such time as 
        function FF00 is called to enable the driver. This is related to 
        the need to not hog Windows resources when the driver is not in 
        use. You should always turn off the driver when you exit you 
        application. 

        Special Notes:

        The main difference between 16 bit and 32 bit is that 16 bit uses 
        16 bit registers while 32 bit mode uses 32 bit registers. You 
        should be aware of this because it can cause problems. The Fryers 
        command array still uses 16 bit words, so when coding in 32 bits, 
        you must be careful to properly declare the array and properly 
        handle all transfers into and out of the command array. 

        Also, the register structure that is used to control the Fryers 
        driver uses 32 bit registers in 32 bit mode. Even though the data 
        passed is still only 16 bits of significant, 32 bit registers are 
        used because pointers must be 32 bits in 32 bit operation. This 
        issue may cause problems for you if you are not careful.

        Remember that for many compilers, an integer declaration in 16 
        bit mode is 16 bits long, but an integer declaration in 32 bit 
        mode is 32 bits long. Watch your declaration types and be sure 
        that you are working with the proper type for the task.



                          FRYERS Driver Utility               page 54 

        Example 8086 assembler code for checking version information:

        ;check on the current version of FRYERS.COM installed
        VERCHK:
             MOV DX,0       ;Set DX to port to check (default = 0)
             MOV AX,0FFFFH  ;request version ID
             INT 14H
             CMP AH,0FF     ;If AH=FF, then is either early or not us
             JZ VEARLY
             CMP DX,0FFFFH  ;if DX <> FFFF then definitely not us
             JNZ BADVERS
             CMP AX,22H     ;if version not 22 or better, then not us
             JL  BADVERS
             JMP GOODV      ;Otherwise we are OK
        VEARLY:
             XOR AH,AH      ;Clear AH for return
             CMP AL,21H     ;if greater than 21, it is not us
             JG BADVERS
             CMP AL,10H     ;or if less than 10.
             JL BADVERS

        ;if you need to, you can place a test here for version dependent 
        ;code. Example, programs that use the FIPP protocol require 
        ;V2.00 or better. 
        ;    CMP AL,20H     ;less than V200 is bad for fixed FIPP 
        ;    JL BADVERS
        ;and programs that require the autobaud capability need V2.10 
        ;of better
        ;    CMP AL,21H     ;less than V210 is bad for autobaud FIPP 
        ;    JL BADVERS

             JMP GOODVERS

        ;check on the interrupt status
        INTCHK:
             MOV DX,0       ;Set DX to port to check 
             MOV AX,0FFFFH  ;request version ID
             INT 14H
             OR BX,BX       ;check port status
             JZ BADVERS     ;Z means interrupts not valid
             JMP GOODVERS   ;NZ = interrupts installed and working
        ;if you had previously enabled the Fryers interrupts (see 
        ;function AX=0FF00), and BX comes back Z, then the hardware 
        ;interrupt has been damaged. This is often caused by other 
        ;software stealing it, or a run-away program smashing it.

        GOODVERS:
             OR AX,AX  ;Return carry clear on good version
             RET       ;with version number in AX

        BADVERS:
             STC       ;Return carry set on bad version
             RET




                          FRYERS Driver Utility               page 55 

           Other Useful Information About the FRYERS.COM 16 Bit Driver

        Note: The information presented in this section is meant for the 
        FRYERS.COM 16 bit driver. The 32 bit FRYERS.DLL uses the Windows 
        API functions to communicate, which has different requirements. 

        Uart Register Save buffer format:

        Index : Description
        --------------------------
           0  : Baud Clk Low Byte
           1  : Baud Clk High Byte
           2  : Uart Reg 1 - Interrupt Enables
           3  : Uart Reg 2 - Interrupt ID 
           4  : Uart Reg 3 - Line COntrol
           5  : Uart Reg 4 - Modem Control 
           6  : Uart Reg 5 - Line Status
           7  : Uart Reg 6 - Modem Status

        Uart Base Addresses:
        Com1 Base Address: 03F8H  (Normal Port #1)
        Com2 Base Address: 02F8H  (Normal Port #2)
        Com3 Base Address: 03E8H  (Alternate Port #1)
        Com4 Base Address: 02E8H  (Alternate Port #2)

        Uart Default Interrupts:
        Port #1 Interrupt: IRQ 4 [0CH]  (Normal or Alternate)
        Port #2 Interrupt: IRQ 3 [0BH]  (Normal or Alternate)

        Other interrupts:  IRQ 2 [0AH]  (avoid IRQ2 if possible)
                           IRQ 5 [0DH]
                           IRQ 7 [0FH]

        Selecting Alternate Port Configurations:

        If you change the uart attached to a port (see function 0FF0A), 
        you should first turn off the Fryers extended functions for that 
        port (if it was on), which will automatically restore the uart 
        registers from the previous settings. This is done simply to 
        leave the hardware the way it was when you found it which all 
        well behaved programs should do.

        A warning about selecting alternate uarts and interrupts. If you 
        don't know what you are doing, DON'T DO IT! You can cause the 
        system to hang if you select the wrong thing. Normally COM1 and 
        COM3 use interrupt 0CH (IRQ4). COM2 and COM4 normally use 
        interrupt 0BH (IRQ3). The Interrupts are single ended. That is, 
        only one uart can use the interrupt. You cannot share the 
        interrupt on two active uarts. Some systems allow other 
        interrupts than the default ones to be used with the uarts. You 
        can select the interrupt that you want to use, but be very 
        careful. Selecting the wrong interrupt can cause the system to 
        become erratic or lockup. The interrupt selected must match the 
        uart base address that you have selected. 



                          FRYERS Driver Utility               page 56 

        Fryers only has two fully operational interrupt interfaces. 
        Only two uarts can be selected to operate at any one time. 
        Which of the two available uarts that are used is selected with 
        port register (DX) when calling a function. With the port 
        configuration function (0FF0A), you can select which uart is to 
        be active for the selected port. 

        Fryers is limited to two fully active uarts because adding two 
        more would double the size of the code. Since Fryers is a TSR, it 
        is not nice to use up memory if it is not needed. Thus Fryers has 
        been currently limited to two fully active ports to keep the 
        memory usage at a minimum. 

        When the Fryers extended features are turned off (see function 
        0FF00), operation reverts to the original interrupt 14H driver 
        that was in the system before FRYERS was loaded. 

        SETPORT Program:

        Since older programs that use Fryers don't have the code to 
        re-configure the port, a program is provided called SETPORT that 
        you can use to re-configure a Fryers port immediately after it is 
        loaded. As long as another program doesn't change the 
        configuration, the SETPORT configuration will remain in effect. 
        Note: you should used V1.02 of SETPORT or higher for this to work 
        properly. V1.00 of SETPORT had a bug when dealing with COM3 or 4.
        See the SETPORT.DOC file for more information.

        A Special Note about COM ports and Interrupts (IRQ):

        The Fryers driver will select the default COM port and interrupt 
        for the selected port configuration (COM1 and IRQ4 for port 0
        and COM2 and IRQ3 for port 1). You can select alternate ports if 
        you wish with the port configuration command (function FF0A). 

        Be warned that multiple RS232 cards that share the same interrupt 
        tend to have problems of locking up the computer because of 
        interrupt conflicts. It is generally not recommended to have more 
        than one serial card attached to a specific interrupt. 

        Some RS232 cards will let you select interrupts other than the 
        predefined IRQ3 and IRQ4. Some IRQ numbers are not allowed 
        because they are predefined for use by the computer already. 
        Selecting IRQ0 will cause the default IRQ for the COM port to 
        be used.

        Default COM Ports and Interrupts:

             COM port     Interrupt
                1            4           standard port 0
                2            3           standard port 1
                3            4           alternate port 0 
                4            3           alternate port 1




                          FRYERS Driver Utility               page 57 

        Available Interrupts:

        If you select a different interrupt, make sure that it does not
        conflict with another interrupt already in use. 

             Available                 Unavailable 
             Interrupts                Interrupts

             2   *note2 (video)        0     PC/AT: hardware timer 
             3          (serial)       1     PC/AT: keyboard
             4          (serial)       6     PC/AT: floppy controller
             5   *note1                8     AT: real-time clock 
             7                         13    AT: coprocessor
             9   *note2                14    AT: hard disk
             10
             11
             12
             15

        *note1: On the old style XT, IRQ5 was used for the hard disk and
        should not be used for anything else on an XT. 

        *note2: On the old style PC/XT, interrupts over seven do not 
        exist. The interrupts were extended on the AT through IRQ2.
        Because of this, you must treat IRQ2 carefully on at AT if you 
        decide to use it. 


        IRQ2 and IRQ9:

        The old IRQ2 hardware line was assigned to IRQ9 on the AT. 
        Yet most PC boards still indicate IRQ2 for the selection. 
        The AT bios will attempt to reflect the interrupt to IRQ2 to 
        support software that expects the interrupt to appear on IRQ2. 
        However, if possible, this should be avoided. Since all the 
        interrupts higher than seven must be directed through IRQ2, 
        nasty things can happen if the program does something nasty 
        like disabling the interrupt. This will usually result in the 
        computer being locked up.

        If you are using IRQ2 on an AT computer, you should tell the
        software that you are using IRQ9 so that it will use the proper 
        interrupt instead of relying on the unstable activity of 
        the bios trying to reflect the IRQ9 hardware signal to IRQ2.

        The easiest way to stay out of trouble is to avoid IRQ2 unless 
        you don't have any other choice. Also, to a lesser extent, avoid 
        interrupts 7 and 15 unless they are the only ones left. These 
        interrupts are catch-all interrupts and will receive any 
        uncontrolled system interrupt as well as the interrupt from the 
        hardware device it is attached to. Fryers accounts for this, but 
        it is possible for problems to occur anyway with such 
        uncontrolled behavior.




                          FRYERS Driver Utility               page 58 

        Windows 16 Bit Operation:

        The FRYERS.COM TSR will work under Windows3.1x and Windows95 
        when using 16bit programs. You can load the driver with 
        AUTOEXEC.BAT so that it will always be available. This will be 
        more reliable and effective, but will eat up precious real mode 
        memory even when Fryers is not in use. Alternately, you can 
        create a batch file which loads the Fryers driver then calls your 
        program and call the batch file from Windows rather than calling 
        the program directly. This can be slightly less reliable because 
        the driver will be sitting on top of the hardware emulator rather 
        than below it. However it has the advantage of only taking up 
        real mode memory while the application is running.

        Windows and protected mode operation places limits on what you 
        can do with the Fryers driver. If you are using register based 
        calls only (no pointers being passed), you can call the Fryers 
        interrupt directly. If you will be passing pointers, you must 
        simulate the interrupt call via the DPMI interface. Refer to the 
        DPMI documentation from Intel on how to perform a pointer based 
        interrupt call.

        The Example programs provided by Frye avoid the pointer issue in 
        Windows by not using the pointer based commands. All essential 
        work with Fryers can be done via registers only. 

        If you will be writing for WindowsNT(tm) or Windows95(tm) 32 bit 
        mode, you will not be able to use the FRYERS.COM driver because 
        32 bit Windows does not support software interrupts, or direct 
        calls to real mode. The FRYERS32.DLL library is provided for use 
        with 32 bit Windows programs. The DLL is largely compatible with 
        the FRYERS.COM TSR and FRYERS16.DLL helper library. This should 
        make conversion of software to 32 bits easier.

        We do not warrant Fryers to work under OS/2. It has not been 
        tested. You may be able to get it to work, but it will probably 
        require some tricks, and I don't know what they would entail.

        See the sample code on the programming and technical support 
        information to use Fryers with Windows.

















                          FRYERS Driver Utility               page 59 

        Windows 32 Bit Operation:

        The FRYERS32.DLL driver library will work under Windows95(tm) and 
        WindowsNT(tm) when using 32bit programs. The 32 bit FRYERS32.DLL 
        should be used with new programs written for Win95 and WinNT. It 
        offers better operation under Windows than the 16 bit version, 
        and must be used when writing code to the 32 bit platform. The 32 
        bit driver allows pointers to be used which can reduce the 
        complexity of the code and improve the performance somewhat. The 
        register only method is still supported which allows existing 
        code to be transferred to the 32 bit platform with little or no 
        changes to your code.

        Unlike the 16 bit versions of Fryers. The FRYERS32.DLL does not 
        use the underlying FRYERS.COM supporting TSR. The FRYERS32.DLL 
        uses Windows API calls to perform communication which reduces 
        the hardware dependence of the device driver approach that 
        FRYERS.COM uses. 

        We do not warrant Fryers to work under OS/2. It has not been 
        tested. You may be able to get it to work, but it will probably 
        require some tricks, and I don't know what they would entail.

        See the sample code on the programming and technical support 
        information to use Fryers with Windows.

        Since the 32bit version operates via the standard Windows 
        communications APIs, the over-all timing of the transfer will be 
        slight slower. The exact difference will depend on the platform 
        being used. Typically there will be a delay of up to 10 to 20 
        milliseconds from the time the command is given until it is 
        actually processed. This is caused by the internal threading of 
        Windows. The communications thread operates at the
        THREAD_PRIORITY_TIME_CRITICAL level. This is higher than a normal 
        application process priority so that any packets being transfered 
        will be processed. In order for the thread to not completely hog 
        the system resources, it is put to sleep while waiting for input 
        from the communications port.

        It is possible for other activities in the system to disrupt a 
        communications event. In most cases, the Fryers driver will 
        manage any failure and resend the command. However, it should be 
        kept in mind that this may cause potential problems if you are 
        doing something time critical via the Fryers driver. In general, 
        you should avoid doing activities with the Fryers driver that 
        require critical timing via commands being sent to an attached 
        instrument. Windows cannot support critical real-time activities.
        If you have need for critical real-time operation, you should 
        consider using MSDOS instead.








                          FRYERS Driver Utility               page 60 

        When the communications port thread is not running, it will go to 
        sleep for a five millisecond period, then wake up to see if there 
        is any activity going on. This is a trade-off between application 
        performance and communications performance. A shorter time could 
        cause an application to become sluggish as the cpu would spend a 
        significant amount of time in the communications routines. A 
        longer sleep time would speed up the application, but cause 
        potential loss of packet data coming from the instrument. 

        There is one communications port thread opened for each com port 
        that is selected. In the 16bit mode, there was not a serious 
        problem if you left a port open after you opened it with Fryers. 
        In the 32 bit mode, it becomes much more important that you close 
        the port when you are done with it. In addition to preventing 
        another application from having access to the port, system 
        resources will be used and the thread will be active as long as 
        the port has been opened. 

        Opening a port in 32 bit mode will take longer to perform. It can 
        take Windows up to 250milliseconds to open the port. That should 
        be considered when writing an application. Don't spend a lot of 
        time opening and closing the communication ports. 

        There is also a timer thread running in the DLL for each open 
        port. The timer operates at the THREAD_PRIORITY_TIME_CRITICAL 
        level which will have higher priority than most other threads and 
        processes in the system. However, the actual active time the 
        thread will be alive will be minimal. 

        The time thread sleep time will be set by the Packet timer 
        resolution or the ASCII character timer resolution (depending on 
        which mode the port is currently operating in). The timer thread 
        will wake up just long enough to update the port timer registers 
        and initiate any time related triggers. It will then go back to 
        sleep. As such it has a minimal impact on the system despite its 
        high operating priority.

        Fryers is not re-entrant, that means that it is not "thread-
        safe." If you expect to be communicating with the Fryers Driver 
        from more than one thread or process, you must insure that no 
        thread call interferes with another one that is in process. 

        Fryers passes data via a register structure pointer. The Fryers 
        driver will use the data contained in the registers while 
        processing the call. Thus you must be careful that your program 
        does not change the contents of the register structure while 
        Fryers is using it. The best way to manage the problem is to 
        allocate the register structure on the local stack rather than 
        using a global or class structure that might get inadvertently 
        damaged by some other event. 







                          FRYERS Driver Utility               page 61 

        Other Considerations for 32bit Windows Programming:

        Windows is a multi-tasking operating system. That means other 
        applications can be running in the computer and sharing the cpu 
        and resources. The Fryers driver places a high demand on the 
        system resources in relation to performance. 

        Fryers can run with other applications as long as there is no 
        contention for the serial port resources and doesn't hog cpu time 
        seriously. If you have another application that uses significant 
        high priority cpu cycles (such as a game or video/voice 
        conferencing, or other multi-media applications), it may have a 
        negative effect on the Fryers driver. 

        When writing an application, you should consider the multi-
        tasking aspect of Windows and be friendly to other tasks that are 
        running. That means that if you are sitting in a loop a lot, such 
        as waiting for status from the attached instrument using function 
        call $FF13, you might want to consider releasing your 
        application's time slot to another application while you are 
        waiting. You can do this with the Sleep() command. 

        The example below shows an example function that waits for either 
        a valid packet transfer complete, or an error occurs. While 
        waiting, it puts the application to sleep for ten milliseconds, 
        wakes up to test the status again, and then goes back to sleep. 
        When valid status information is available, the function returns 
        to it's caller. 

        Function PacketReady:word;
        var Regs:F_RegsType;
        Begin
          Repeat
            Regs.AX := $FF13;
            Regs.DX := comport;
            CallFryers(Regs);
            if Regs.AX and $00FD = 0 then
              Sleep(10);
          Until Regs.AX and $00FD <> 0;  
          PacketReady := Regs.AX;
        End;

        If your code needs to update the display or do something else, 
        you may not want to put your application to sleep, however, if 
        the application is not doing anything else, you should consider 
        doing so in order to not waste system resources. 

        Note that when you make a Windows API call that has to wait, 
        Windows will typically automatically go handle any other waiting 
        processes while it is waiting on the API call to complete. You 
        only need to worry about putting the application to sleep when 
        you are waiting on something that Windows doesn't know about. 
        Such as the Fryers Status wait situation. 




                          FRYERS Driver Utility               page 62 

        Doc History:  01/04/89 med (unknown)
                      06/28/89 med (unknown)
                      11/06/89 med (unknown)
                      04/26/90 med (v2.31 Fryers)
                      09/20/90 med (v2.40 Fryers)
                      12/12/90 med (v2.50 Fryers)
                      12/18/90 med (v2.60 Fryers)
                      11/16/92 med (v3.07 Fryers)
                      09/24/93 med (v3.21 Fryers) 
                      10/05/94 med (v4.00 Fryers)
                      12/28/95 med (minor document changes)
                      12/05/96 med (v4.10 Fryers - 16bit rev)
                      07/31/97 med (v5.00 Fryers - Windows 32bit DLL)
                      11/20/97 med (v4.15/v5.15 Fryers)
                      05/20/99 med (minor document changes)
                      07/15/04 med (v5.16 Fryers32)
                      04/05/06 med (minor document changes)








































                          FRYERS Driver Utility               page 63 

        Fryers History:
        03 Oct 1986 - V1.00 first release for 10K/CHIP II software use.
        29 Sep 1987 - V2.00 Frye Packet protocol added.
        10 Nov 1987 - V2.02 first full release of Fryers.
        01 Oct 1988 - V2.04 documentation corrections.
        11 Oct 1988 - V2.05 preliminary auto-baud release.
        03 Feb 1989 - V2.10 full auto-baud release.
        27 Jun 1989 - V2.11 added global poll error counter.
        06 Nov 1989 - V2.20 added driver damage detection.
        20 Nov 1989 - V2.21 added version overload detection.
        25 Apr 1990 - V2.31 improved autobaud operation.
        20 Sep 1990 - V2.40 improved version detection.
        18 Dec 1990 - V2.50 corrected >19200 baud packet operation.
        01 Feb 1992 - V2.51 corrected poll time-out disable bug.
        04 Apr 1991 - V2.52 corrected version command operation.
        22 Apr 1991 - V2.60 corrected timer operation on fast machines.
        30 Jan 1992 - V2.70 added version control for protected mode.
        03 Feb 1992 - V2.71 fixed protected mode version control.
        04 Feb 1992 - V2.72 corrected checksum for two channel operation.
        14 Apr 1992 - V2.80 added RTS/CTS handshake control.
        14 Aug 1992 - V3.00 converted code from SASM to MASM format.
        19 Aug 1992 - V3.01 added uart save/restore function.
        24 Aug 1992 - V3.02 added uart selection capability.
        27 Aug 1992 - V3.03 corrected version cmd to ret HW int addr.
        14 Oct 1992 - V3.04 corrected int mask bit for com1.
        16 Oct 1992 - V3.05 fixed uart selection code (rewrote it).
        09 Nov 1992 - V3.06 fixed long version command to accept nil ptr.
        12 Nov 1992 - V3.07 fixed code for non-default interrupts.
        29 Jul 1993 - V3.20 added quick terminate, fixed port 2 autobaud.
        24 Sep 1993 - V3.21 fixed auto quick terminate cancel problem.
        25 Oct 1993 - V3.22 fixed manual quick terminate operation.
        03 Aug 1994 - V3.23 added get/set quick terminate cmd. 
        05 Oct 1994 - V4.00 changed autobaud (see $FF1B) added skip poll.
        10 Dec 1996 - V4.01 fixed stack bug in autobaud cmd (if bad cmd).
        15 May 1997 - V4.10 minor changes to make compatible with 32bits.
        28 Apr 1997 - V5.00 32bit Windows DLL version (not released).
        15 May 1997 - V5.01 32bit (corrected get version string cmd)
        20 Nov 1997 - V4.15 16bit added debug registers like 32 bit ver.
        20 Nov 1997 - V5.15 32bit added debug registers
        15 Jul 2004 - V5.16 32bit fixed problem with WinXP using char mode.
        Note: The MSDOS tsr (V4.xx) is being left at V4.xx.
        <end>














