;       SCCSID = @(#)atcom.inc  6.13 92/02/22
; ***************************************************************************
; *
; *                       IBM/Microsoft Confidential
; *
; *                 Copyright (c) IBM Corporation  1987, 1990
; *                 Copyright (c) Microsoft Corp.  1987, 1990
; *                           All Rights Reserved
; *
; ***************************************************************************
;
;       Macros, structures and constants for the COM device driver.
;       Some of the constants are dependent on the 16450 serial
;       communications chip.

;       Modification History
;
;       JGT     05/10/88        Remove baud rate table (p587-cpd12)
;
;       YN      05/25/89        MVDM Support - @VDM
;
;       ACW     04/16/91        @PVW Added perfview counters/timers
;
;       YN      08/13/91        CP20D1390 - Bulletin Board Support
;
;       MF      02/21/92        PB732220 - Procom Plus host mode fix (@0001)
;
;       WDM     04/20/94        D82467 - add pvwxport.inc to resolve pvdbh_s

;.xlist
 include pvwxport.inc           ; 82467
;.list

HSEG SEGMENT DWORD PUBLIC 'RESDATA'              ; resident data segment
HSEG ENDS

RSEG SEGMENT DWORD PUBLIC 'RESCODE'              ; resident code segment
RSEG ENDS

DSEG SEGMENT DWORD PUBLIC 'DATA'                 ; swappable data segment
DSEG ENDS

_DATA SEGMENT DWORD PUBLIC 'DATA'
_DATA ENDS

CONST SEGMENT DWORD PUBLIC 'CONST'
CONST ENDS

_BSS  SEGMENT DWORD PUBLIC 'BSS'
_BSS  ENDS

CSEG SEGMENT DWORD PUBLIC 'CODE'              ; swappable code segment
CSEG ENDS

_TEXT SEGMENT DWORD PUBLIC 'CODE'
_TEXT ENDS

DGROUP  GROUP   DSEG,_DATA,CONST,_BSS
CGROUP  GROUP   RSEG
C2GROUP GROUP   CSEG,_TEXT


MAXCOMPORTS     EQU     4

lhlen           equ     12 ; lock handle length (from pgexport.inc)

;**     ALLSTRICT - turn on all strict checking

IFDEF ALLSTRICT
    CISTRICT    EQU     1       ; cominfo
    RPLSTRICT   EQU     1       ; request packet list
    RPTSTRICT   EQU     1       ; request packet type
    RPSTRICT    EQU     1       ; request packet pointer
ENDIF

;**     SIGNATURE assertion check constant
;
;       SIGNATURE is used throughout the com driver in order to
;       perform run time assertion checking.
;

SIGNATURE       EQU     'dg'


;**     min - in with IODELAY
;

min     MACRO   a,b
;       DevIODelay
        IODELAY
        in      a,b
ENDM


;**     mout - out with IODELAY
;

mout    MACRO   a,b
;       DevIODelay
        IODELAY
        out     a,b
ENDM


;**     POPFF - special version of pop flags for i286
;
;       This avoids the pitfalls of the 286 POPF instruction
;       which will sometimes allow an interrupt to come in
;       even if IF is off in both the old and new flags.

POPFF   MACRO
;;LOCAL a
;;      push    cs
;;      push    offset cs:a
;;      iret
;;a:
        popf            ; assume we're running on a 386 with no erratum
ENDM

;**     ReadLSR - read LSR and save in lsrshadow
;
;       moves value into lsrshadow if there was an overrun error,
;       otherwise just 'or' the value into lsrshadow so that errors are
;       not lost.
;
;       INPUT   (ds:si) -> ComInfo
;
;       OUTPUT  (al) = LSR
;
;       USES    al dx
;
;       NOTE    must be called with interupts disabled so we don't get
;               a receive interrupt during lsrshadow update.

ReadLSR MACRO
LOCAL   a
        mov     dx,[si].ci_port
        add     dx,R_LINES              ; (dx) -> LSR
        in      al,dx                   ; (al) =  LSR
        or      [si].ci_lsrshadow,al    ; shadow the contents of the LSR.
                                ; use 'or' so previous errors are not lost

        test    al,LS_OERR
        jz      a                       ; not overrun
        mov     [si].ci_lsrshadow,al    ; shadow the contents of the LSR.
                                ; use 'mov' because the overrun lost any
                                ; previous characters.
a:
ENDM


;**     ComErr - internal error macro for com driver
;
ComErr  MACRO   string,near_or_far
LOCAL   a

        IFB     <string>
                %OUT ComError : missing error string
                .ERR
        ENDIF


        IFDEF   COMDEBUG
                MESSAGES EQU 1          ; debug version always has messages
        ENDIF

        IFDEF   MESSAGES
                DSEG SEGMENT
                        a       DB      '&string'       ; allocate message
                DSEG ENDS

                push    OFFSET DSEG:a           ; push message offset
        ELSE
                push    0                       ; push null message offset
        ENDIF

        IFDEF   COMDEBUG
                int     3
        ENDIF
        if2
            ifndef ComError
                ifb <near_or_far>
                extrn ComError:near
                else
                        EXTRNFAR ComError
            endif
        endif
        endif
        ifb <near_or_far>
        call    ComError
        else
                CALLFAR ComError
        endif
ENDM


;**     DevHelp - macro to call [DevHlp]
;
DevHelp MACRO

        IFDEF   DDEVHELP
                int     3
        ENDIF
        call    [DevHlp]

ENDM


;**     ProcReady - macro to add a request packet to the end of the Ready list
;
;       This code is written as a macro because putting RPs on
;       the Ready list is often done at interrupt time.
;
ProcReady       MACRO   near_or_far

        SaveReg         <si>
        mov     si,OFFSET Ready
        if2
            ifndef LinkRP
                ifb <near_or_far>
                extrn LinkRP:near
                else
                        EXTRNFAR LinkRP
            endif
        endif
        endif
        ifb <near_or_far>
        call    LinkRP
        else
                CALLFAR LinkRP
        endif
        RestoreReg      <si>
ENDM


;**     ChkComInfoPtr - check the validity of the ComInfo pointer
;
;       ChkComInfoPtr is a macro which conditionally assembles
;       to a call if CISTRICT is defined.
;
ChkComInfoPtr   MACRO
        IFDEF   CISTRICT
            if2
                ifndef CheckComInfoPtr
                    extrn CheckComInfoPtr:near
                endif
            endif
            call CheckComInfoPtr
        ENDIF   ; CISTRICT
ENDM


;**     ChkRPType - check the request packet for the type we expect
;
;       ChkRPType is a macro which conditionally assembles
;       to a call if RPTSTRICT is defined.
;
ChkRPType       MACRO   type
LOCAL   a

        IFB     <type>
                %OUT ChkRPType : missing type
                .ERR
        ENDIF

        IFDEF   RPTSTRICT
                pushf
                cmp     es:[di].PktCmd,&type
                je      a

                ComErr  <ChkRPType : unexpected request packet type>

        a:      popf
        ENDIF   ; RPTSTRICT
ENDM


;**     ChkRPPtr - check the validity of the request packet pointer
;
;       ChkRPPtr is a macro which conditionally assembles
;       to a call if RPSTRICT is defined.
;
ChkRPPtr        MACRO
        IFDEF   RPSTRICT
            if2
                ifndef CheckRPPtr
                    extrn CheckRPPtr:near
                endif
            endif
            call CheckRPPtr
        ENDIF   ; RPSTRICT
ENDM


;**     ChkRPLPtr - check the validity of the RP_List pointer
;
;       ChkRPLPtr is a macro which conditionally assembles
;       to a call if RPLSTRICT is defined.
;
ChkRPLPtr       MACRO
        IFDEF   RPLSTRICT
            if2
                ifndef CheckRPLPtr
                    extrn CheckRPLPtr:near
                endif
            endif
            call CheckRPLPtr
        ENDIF   ; RPLSTRICT
ENDM

;**     Call_Strat - Calls the correct strategy routine based on SI
;
;       USES    nothing
;
Call_Strat      MACRO
        local   try2
        local   try3
        local   try4
        local   combine

        push    si
        cmp     si,Com1
        jne      try2
        call    Com1Strat
        jmp     short   combine
try2:
        cmp     si, Com2
        jne     try3
        call    Com2Strat
        jmp     short   combine

try3:
        cmp     si, Com3
        jne     try4
        call    Com3Strat
        jmp     short   combine

try4:   call    Com4Strat

combine:
        pop     si
ENDM

;**     FlushQueue - flush an IO_Queue
;
;       USES    ax
;
FlushQueue      MACRO   IOQ
        IFB     <ioq>
                %OUT "FlushQueue invoked without a queue"
                .ERR
        ENDIF

        ChkComInfoPtr

        mov     ax,[si].&IOQ.ioq_base
        mov     [si].&IOQ.ioq_in,ax
        mov     [si].&IOQ.ioq_out,ax
        mov     [si].&IOQ.ioq_count,0
ENDM


XONequ                  = 11h           ; DC1 ^Q
XOFFequ                 = 13h           ; DC3 ^S

PhysAddr struc
        _lo     dw      (?)     ; low word of a 32-bit pointer
        _hi     dw      (?)     ; high word of a 32-bit pointer
PhysAddr ends


;**     RP_List - definition of a request packet list
;
RP_List STRUC
        rpl_head        DD      0       ; pointer to head of list
        rpl_tail        DD      0       ; pointer to tail of list
        rpl_signature   DW      SIGNATURE
RP_List ENDS


;**     Fill_IOCTL - fills in the IOCTL packet for passing to the strat
;
;       USES    nothing
;
Fill_IOCTL      MACRO dseg,doff,pseg,poff
        mov     [si].ci_req_pack.GIODataPack._hi,dseg
        mov     [si].ci_req_pack.GIODataPack._lo,doff
        mov     [si].ci_req_pack.GIOParaPack._hi,pseg
        mov     [si].ci_req_pack.GIOParaPack._lo,poff
        mov     [si].ci_req_pack.GIOCategory,1
        mov     [si].ci_req_pack.GIOFunction,al
        mov     [si].ci_req_pack.IPcommand,IOCTL_Command
        mov     [si].ci_req_pack.IPlen,size IOCTLPacket
ENDM

;**     Set_Data - Set the data packet address
;
;       USES    nothing
;
Set_Data        MACRO dataseg,dataoff
        mov     [si].ci_req_pack.GIODataPack._hi,dataseg
        mov     [si].ci_req_pack.GIODataPack._lo,dataoff
ENDM

;**     Set_Para - Set the parameter packet address
;
;       USES    nothing
;
Set_Para        MACRO pseg,poff
        mov     [si].ci_req_pack.GIOParaPack._hi,pseg
        mov     [si].ci_req_pack.GIOParaPack._lo,poff
ENDM



;**     INT_Notify - calls the INT notify routines if COM in use by VDM
;
;       USES    nothing
;
INT_NOTIFY      MACRO
        local   no_vdm
        test    [si].ci_vdm_flag,VDM_Flag_InUse
        jz      no_vdm

        SaveReg <ax,bx,dx>
        mov     dl,[si].ci_port_number
        call    Rx_Notify
        call    Tx_Notify
        call    MS_Notify
        RestoreReg <dx,bx,ax>
no_vdm:
ENDM

;**     SET - sets bit(s) in "var" according to bit-mask "bits"
;
;       USES    nothing
;
SET     MACRO   var,bits
        or      var,bits
ENDM

;**     CLR - clear bit(s) in "var" according to bit-mask "bits"
;
;       USES    nothing
;
CLR     MACRO   var,bits
        and     var,NOT bits
ENDM

;**     setDS - sets DS to segname, does ASSUME DS=segname
;
;       USES    nothing
;
setDS   MACRO   segname
        push    ax
        mov     ax,segname
        mov     ds,ax
        pop     ax
        ASSUME  ds:segname
        endm

;**     setES - sets ES to segname, does ASSUME ES=segname
;
;       USES    nothing
;
setES   MACRO   segname
        push    ax
        mov     ax,segname
        mov     es,ax
        pop     ax
        ASSUME  es:segname
        endm


IOCTLPacket     STRUC
        IPlen           DB      ?
        IPunit          DB      ?
        IPcommand       DB      ?
        IPstatus        DW      ?
        IPreserved      DD      ?
        IPQlink         DD      ?
        IPcategory      DB      ?
        IPfunction      DB      ?
        IP@parameter    DD      ?
        IP@data         DD      ?
        IPsfn           DW      ?
IOCTLPacket     ENDS

Flat_Pointer    struc
        fp_offlo        DW      ?
        fp_offhi        DW      ?
        fp_sel          DW      ?
Flat_Pointer    ends

Stack_Data      struc
        old_bp  dw      ?
        old_cs  dd      ?
        old_ip  dd      ?
        ul2     dd      ?
        ul1     dd      ?
        uFunc   dd      ?
Stack_Data      ends

Device_dependant_VCOM_data      struc
        ret_len dw      ?
        num_com dw      ?
        @com1   dw      ?
        @com2   dw      ?
        @com3   dw      ?
        @com4   dw      ?
        @cm1irq dw      ?
        @cm2irq dw      ?
        @cm3irq dw      ?
        @cm4irq dw      ?
Device_dependant_VCOM_data      ends

IDC_Packet      struc
        Command_Flag    dw      ?
        Com_Port_Num    dw      ?
        Com_Port_Addr   dw      ?
        Com_Port_IRQ    dw      ?
        Return_Code     dw      ?
IDC_Packet       ends

;**     Machine Identifiers
;
;       ABIOS_COM          -   Identifies a ABIOS machine
;       NON_ABIOS_COM      -   Identifies a non ABIOS machine
;
;

NON_ABIOS_COM   EQU     1
ABIOS_COM       EQU     0

;**     ESP Adapter specific equates
;

SPACE           EQU     20h
ESPSIG          EQU     0AAh
NULL            EQU     00h

Ad     STRUC
    _address1   DW      0
    _address2   DW      0
    _interrupt1 DB      0
    _interrupt2 DB      0
    _dma1       DB      0
    _dma2       DB      0
    _port1      DW      -1
    _port2      DW      -1
    _port3      DW      -1
    _port4      DW      -1
Ad     ENDS

BUS_MCA         EQU     0
BUS_AT          EQU     1

;**     Queue manifests, sizes and hi/lo water marks
;
;       Due to the implementation of the character queues, they
;       must be declared to be one byte greater than their
;       actual usable size.
;
QI_SIZE         EQU     5121                    ; input  queue size
QO_SIZE         EQU     2049    ;before = 513   ; output queue size
QI_SIZE_EVEN    EQU     QI_SIZE + 1 AND NOT 1   ; even size for word alignment
QO_SIZE_EVEN    EQU     QO_SIZE + 1 AND NOT 1

; high/low water marks for when to send handshake
; when input queue goes above high water, send XOFF and/or drop hardware lines
; when input queue goes below low  water, send XON and/or raise hardware lines
RX_HIGH_HS      EQU     (QI_SIZE-1)-2048 ; RX queue high water mark
RX_LOW_HS       EQU     (QI_SIZE-1)/2    ; RX queue low water mark

; when input queue goes up to this, move data to user buffer
RX_MOVE_PROT    EQU     200             ; protect mode or below 1 meg
RX_MOVE_REAL    EQU     256             ; real   mode and above 1 meg

; when output queue goes down to this, move data from user buffer
TX_MOVE_PROT    EQU     64              ; protect mode or below 1 meg
TX_MOVE_REAL    EQU     0               ; real   mode and above 1 meg

RX_STATE_HOLDING        EQU     1       ; isr has no more room in buffer
                                        ; until consumer removes rx data
RX_STATE_OK             EQU     2       ; isr has room in buffer for rx data

;**     ComInfo.ci_dcb_flags1 definitions
;
F1_DTR_MASK     EQU     00000011b       ; DTR control mask
F1_DTR_DISABLE  EQU     00000000b       ; DTR disable
F1_DTR_ENABLE   EQU     00000001b       ; DTR enable
F1_DTR_FLOW     EQU     00000010b       ; DTR input handshaking
F1_DTR_INVALID  EQU     00000011b       ; DTR invalid mode
F1_OUT_FLOW     EQU     00111000b       ; output handshaking mask
F1_OUT_CTS_FLOW EQU     00001000b       ; output handshaking using CTS
F1_OUT_DSR_FLOW EQU     00010000b       ; output handshaking using DSR
F1_OUT_DCD_FLOW EQU     00100000b       ; output handshaking using DCD

F1_IN_DSR_SENSE EQU     01000000b       ; input  sensitivity using DSR
F1_RESERVED     EQU     10000100b       ; reserved


;**     ComInfo.ci_dcb_flags2 definitions
;
F2_OUT_XO       EQU     00000001b       ; output XON/XOFF
F2_IN_XO        EQU     00000010b       ; input  XON/XOFF

F2_ERR_CHAR     EQU     00000100b       ; error replacement char
F2_NULL_STRIP   EQU     00001000b       ; null stripping
F2_BRK_CHAR     EQU     00010000b       ; break replacement char
F2_FULL_DUP     EQU     00100000b       ; full duplex auto flow control
                                        ; (send data after sending XOFF)

F2_RTS_MASK     EQU     11000000b       ; RTS control mask
F2_RTS_DISABLE  EQU     00000000b       ; RTS disable
F2_RTS_ENABLE   EQU     01000000b       ; RTS enable
F2_RTS_FLOW     EQU     10000000b       ; RTS input handshaking
F2_RTS_TOGGLE   EQU     11000000b       ; RTS toggle on transmit


;**     ComInfo.ci_dcb_flags3 definitions
;
F3_W_INF_TO     EQU     00000001b       ; write infinite timeout

F3_READ_TO_MASK EQU     00000110b       ; read timeout mask
F3_READ_TO_BAD  EQU     00000000b       ; read timeout bad
F3_READ_TO_NORM EQU     00000010b       ; read timeout normal
F3_READ_TO_WFS  EQU     00000100b       ; read timeout wait for something
F3_READ_TO_NW   EQU     00000110b       ; read timeout no wait

F3_FIFO_MASK    EQU     00011000b       ; FIFO mask
F3_FIFO_NA      EQU     00000000b       ; FIFO not available
F3_FIFO_OFF     EQU     00001000b       ; FIFO disabled
F3_FIFO_ON      EQU     00010000b       ; FIFO enabled
F3_FIFO_APO     EQU     00011000b       ; FIFO auto priority override
F3_FIFO_HW_ON   EQU     00010000b       ; FIFO HW is on (either ON or APO)

F3_RX_MASK      EQU     01100000b       ; receive trigger level mask
F3_RX_1         EQU     00000000b       ; receive trigger level 1
F3_RX_4         EQU     00100000b       ; receive trigger level 4
F3_RX_8         EQU     01000000b        ; receive trigger level 8
F3_RX_14        EQU     01100000b       ; receive trigger level 14

F3_TX_16        EQU     10000000b       ; transmit buffer load count = 16

F3_FIFO_ALL     EQU     11111000b       ; all the fifo bits

;**** MVDM Support Equates
VDM_Flag_InUse                  EQU     00000001b
VDM_Flag_notify_the_VCOM_RX     EQU     00000010b
VDM_Flag_notify_the_VCOM_TX     EQU     00000100b
VDM_Flag_Blocked_IOCTL          EQU     00001000b
VDM_Flag_InOut_Handshake_Init   EQU     00010000b
VDM_Flag_No_IRQ_Open            EQU     00100000b

VDM_Max_Tx_Count                EQU     16
VDM_Max_Rx_Count                EQU     16

VDM_Delta_QO_SIZE               EQU     QO_SIZE-VDM_Max_Tx_Count

VDM_TERM_TIMEOUT                EQU     15000 ; 15 sec timeout for termination


;**     ComInfo.ci_hsflag values
;
HS_XOFF_PENDING         EQU     00000001b       ; XOFF needs to be sent
HS_FLOW_OFF_LOCAL       EQU     00000010b
HS_XON_PENDING          EQU     00000100b       ; XON needs to be sent
HS_XOFF_RECEIVED        EQU     00001000b       ; XOFF character received
HS_XOFF_SENT            EQU     00010000b       ; XOFF has been sent
HS_BREAK_SET            EQU     01000000b       ; break has been set
HS_TX_IMMED             EQU     10000000b       ; TxImmed character pending


;**     IOCTL com status definitions
;
; Note: TX_IMMED is maintained in ci_hsflag.  All the other fields are
; calculated only when IOCTL Return Com Status is called.
;
CST_CTS_HOLD    EQU     00000001b       ; TX waiting for CTS to be asserted?
CST_DSR_HOLD    EQU     00000010b       ; TX waiting for DSR to be asserted?
CST_DCD_HOLD    EQU     00000100b       ; TX waiting for DCD to be asserted?
CST_XOFF_HOLD   EQU     00001000b       ; TX waiting, XOff received?
CST_XOFF_SENT   EQU     00010000b       ; TX waiting, XOff transmitted?
CST_BREAK_HOLD  EQU     00100000b       ; TX waiting, break being transmitted?
CST_TX_IMMED    EQU     01000000b       ; char waiting to be transmitted immed?
CST_RX_DSR_HOLD EQU     10000000b       ; RX waiting for DSR to be asserted?


;**     ComInfo.ci_comerr (IOCTL com error) definitions
;
CE_SW_OVERRUN   EQU     00000001b       ; receive SW queue overrun error
CE_HW_OVERRUN   EQU     00000010b       ; receive HW overrun error
CE_RX_PARITY    EQU     00000100b       ; receive parity error
CE_FRAME        EQU     00001000b       ; receive framing error


;**     ComInfo.ci_event (IOCTL com event) definitions
;
EV_RX_CHAR      EQU     00000001b       ; set when any character is received
                                        ; and placed in the input queue.
EV_RESERVED     EQU     00000010b       ; reserved
EV_TX_EMPTY     EQU     00000100b       ; set when the last char in the
                                        ; transmit queue is transmitted
EV_CTS          EQU     00001000b       ; set when the CTS signal changes state
EV_DSR          EQU     00010000b       ; set when the DSR signal changes state
EV_DCD          EQU     00100000b       ; set when the DCD signal changes state
EV_BREAK        EQU     01000000b       ; set when a Break is detected on input
EV_ERR          EQU     10000000b       ; set when an error occurs
                                        ; (parity, framing or HW or SW overrun)
EV_RING         EQU    100000000b       ; set when Ring Indicator is detected


;**     ComInfo.ci_flagx definitions
;
FX_DATA_MOVED           EQU     00000001b       ; data moved (PhysToVirt) in
                                                ; TxInt, so don't move Rx data
                                                ; this interrupt
FX_LAST_CLOSE           EQU     00000010b       ; last close in progress,
                                                ; so discard received data
FX_RTS_DROP_PENDING     EQU     00000100b       ; drop RTS at the first timer
                                                ; tick where the THR and TSR
                                                ; are empty
FX_WAITING_TX_EMPTY     EQU     00001000b
FX_INT_NESTED           EQU     00010000b       ; nested interrupt occured
FX_IN_DSR_OK            EQU     00100000b       ; input DSR mode is off OR
                                                ; DSR was high OR DSR is high
                                        ; this bit MUST be the same as MS_DSR

FX_CHIP_MASK            EQU     11000000b       ; chip type 8250, 16450, 16550A
FX_8250                 EQU     00000000b       ; 8250x (PC chip)
FX_16450                EQU     01000000b       ; 16450 or 16550 (bad FIFO)
FX_16550A               EQU     10000000b       ; 16550A (good FIFO)


;**     ComInfo.ci_flagx definitions
;
FX_XO_FOUND             EQU     00100000b       ; flag used in TxFlowDetect
FX_TX_IN_PROG           EQU     01000000b       ; flag used for Tx'ing
FX_INT_TIME             EQU     10000000b       ; flag used mode switching


;**     ComInfo.ci_Flagx1 definitions
;
FX1_FLUSH_TX_IP  EQU     00000001b       ;;MF flag for TX Flush in progress
FX1_FLUSH_RX_IP  EQU     00000010b       ;;MF flag for RX Flush in progress
FX1_SET_BAUD_IP  EQU     00000100b       ; flag for set baud IOCTL in progress
FX1_PCMCIA_MODEM EQU     00001000b       ; flag to show this is pcmcia modem

;**     ComInfo.ci_eflags definitions
;
; NOTE: bit positions must match SetEnhancedParmeters IOCtl (54H)
;       parameter packet format
EF_POSSIBLE_ENHANCED    EQU     00000001b       ; port CAN run in enhanced mode
EF_MODE_ENHANCED        EQU     00000010b       ; port is NOW in enhanced mode
EF_RX_REQUEST_NOT_PIO   EQU     00000100b       ; port NOT in rx PIO mode
EF_RX_REQUEST_DEF_DMA   EQU     00001000b       ; port DEFINITELY in rx DMA mode
EF_RX_REQUEST_MASK      EQU     00001100b       ;
EF_TX_REQUEST_NOT_PIO   EQU     00010000b       ; port NOT in rx PIO mode
EF_TX_REQUEST_DEF_DMA   EQU     00100000b       ; port DEFINITELY in rx DMA mode
EF_TX_REQUEST_MASK      EQU     00110000b       ;
EF_LAST_RX_WAS_DMA      EQU     01000000b       ; most recent receive for
                                                ; this port was in DMA mode
EF_LAST_TX_WAS_DMA      EQU     10000000b       ; most recent transmit for
                                                ; this port was in DMA mode
EF_GET_MASK             EQU     11000001b

DMA_REQ_DISABLE         EQU     0       ; don't use DMA, use PIO
DMA_REQ_AUTO            EQU     1       ; maybe use DMA
DMA_REQ_DEDICATE        EQU     2       ; definitely use DMA

;**     Cominfo.ci_depth definitions
;
; NOTE: D_BAD is zero so you don't have to test it after incrementing it

D_NONE  EQU     0FDh                    ; no          interrupts in progress
D_FIRST EQU     0FEh                    ; first level interrupt  in progress
D_NEST  EQU     0FFh                    ; nested      interrupt  in progress
D_BAD   EQU     000h                    ; too many    interrupts in progress

;**     ESPInfo.pi_flags values
PIF_CI_NULL     EQU     00000001b       ; ISR found a null ComInfo pointer
PIF_NOT_OPEN    EQU     00000010b       ; ISR got interrupt but port not open
PIF_INSTALLED   EQU     00000100b       ; Pecan already set up
PIF_PECAN_BUSY  EQU     00001000b       ; Pecan busy doing something, don't bother
PIF_DMA_READ    EQU     00010000b
PIF_RESET_MASK  EQU     00100000b
PIF_ONE_HAS_IRQ EQU     01000000b       ; Enhanced port is registered for IRQ
PIF_INT_NESTED  EQU     10000000b       ; ESP is processing nested interrupt

;**     Flags values
F_SHUT_DOWN     EQU     00000001b       ; driver shut down due to internal err
F_ESP_CODE_LOCKED       EQU     00000010b
F_LOCK_CONTIGUOUS       EQU     00000100b

DEV_IDC            EQU  0100000000000000b
INSTALL_CMD        EQU  001h
DEINSTALL_CMD      EQU  000h

;****   Generic Alert Flag values   ************************************
FGA_WRITE_TO_CTS   EQU  0000000000000001b  ; flag write TO event causes
FGA_WRITE_TO_DSR   EQU  0000000000000010b
FGA_WRITE_TO_DCD   EQU  0000000000000100b
FGA_WRITE_TO_XOFF  EQU  0000000000001000b
FGA_RESERVED       EQU  1111111111110000b  ; reserved GA flags

GAS_FLAG_MAX    EQU     8               ; max bit value of allowed GAS flags

;**     Valid baud range and default
;
MINBAUD         EQU     2
MAX_SBAUD       EQU     57600
MAX_EBAUD       EQU     115200
DEFAULT_BAUD    EQU     9600

;**     Hardware clock speed
;
; clock = 115200 = 1C200h
;
CLOCK_RATEHI    EQU     1               ; MSW of clock rate
CLOCK_RATELO    EQU     0C200h          ; LSW of clock rate
CLOCK_RATE      EQU     01C200h
; The bit rate must be within +-.01% of the requested rate.
; so the maximum allowable remainder is 11 (11/115200 = .000095)
MAXREM          EQU     11


 ;**    I/O queue structure
;
IO_Queue        STRUC
        ioq_phys        DB      SIZE PhysAddr DUP (?)
        ioq_page        DW      (?)
        ioq_base        DW      (?)
        ioq_end         DW      (?)
        ioq_in          DW      (?)
        ioq_out         DW      (?)
        ioq_count       DW      (?)
IO_Queue        ENDS

Com1Minor       EQU     0
Com2Minor       EQU     1
Com3Minor       EQU     2
Com4Minor       EQU     3

;**     8250,16450,16550A Serial I/O Chip Port Equates
;

;**     Port addresses
;
R_DATA          EQU     0               ; RX/TX data
R_BAUDL         EQU     R_DATA          ; low byte baud rate divisor
R_BAUDH         EQU     R_DATA+1        ; high byte baud rate divisor
R_INTEN         EQU     1               ; interrupt enable
R_INTID         EQU     2               ; interrupt identification (read only)
R_FIFOC         EQU     2               ; FIFO control (write only)
R_LINEC         EQU     3               ; line control
R_MODMC         EQU     4               ; modem control
R_LINES         EQU     5               ; line status
R_MODMS         EQU     6               ; modem status
R_SCRATCH       EQU     7               ; scratch register

;**     Interrupt enable masks
;
IE_RX           EQU     00000001b       ; read data available
IE_TX           EQU     00000010b       ; transmit buffer empty
IE_LX           EQU     00000100b       ; line status change
IE_MX           EQU     00001000b       ; modem status change

;**     Interrupt identification masks (read only)
;
;       NOTE: The values used for II_*X are encoded so that they
;       can be used as an index to a jump table. They are not used
;       directly but there values are relevant.
;
II_NONE         EQU     00000001b       ; no interrupts pending
II_MASK         EQU     00000110b       ; mask of bits for table jump
II_MX           EQU     00000000b       ; modem status interrupt pending
II_TX           EQU     00000010b       ; TX interrupt pending
II_RX           EQU     00000100b       ; RX interrupt pending
II_LX           EQU     00000110b       ; line status interrupt pending
II_RX_TO        EQU     00001000b       ; RX FIFO timeout

II_RESERVED     EQU     00110000b       ; reserved

II_16550A       EQU     11000000b       ; 16550A indentifier

;**     FIFO Control masks (write only)
;
FF_ENABLE       EQU     00000001b       ; enable FIFO (both rx and tx)
FF_CLEAR_RX     EQU     00000010b       ; clear RX FIFO
FF_CLEAR_TX     EQU     00000100b       ; clear TX FIFO
FF_DMA          EQU     00001000b       ; DMA
FF_RESERVED     EQU     00110000b       ; RESERVED
FF_RX_MASK      EQU     11000000b       ; RX FIFO trigger level mask
FF_RX_1         EQU     00000000b       ; RX FIFO trigger level 1
FF_RX_4         EQU     01000000b       ; RX FIFO trigger level 4
FF_RX_8         EQU     10000000b       ; RX FIFO trigger level 8
FF_RX_14        EQU     11000000b       ; RX FIFO trigger level 14

;**     Line control masks
;
LC_BMASK        EQU     00000011b       ; data bits mask
LC_BITS5        EQU     00000000b       ; 5 data bits
LC_BITS6        EQU     00000001b       ; 6 data bits
LC_BITS7        EQU     00000010b       ; 7 data bits
LC_BITS8        EQU     00000011b       ; 8 data bits

LC_SMASK        EQU     00000100b       ; stop bits mask
LC_STOP1        EQU     00000000b       ; 1 stop bit
LC_STOP2        EQU     00000100b       ; 2 stop bits (1.5 if 5 data bits)

LC_PMASK        EQU     00111000b       ; parity mask
LC_PNONE        EQU     00000000b       ; none parity
LC_PODD         EQU     00001000b       ; odd parity
LC_PEVEN        EQU     00011000b       ; even parity
LC_PMARK        EQU     00101000b       ; mark parity
LC_PSPACE       EQU     00111000b       ; space parity

LC_BREAK        EQU     01000000b       ; transmit break
LC_DLAB         EQU     10000000b       ; divisor latch access bit
LC_MASK         EQU     01111111b       ; documented line control register bits

;**     Values for parity
;
NO_PARITY       EQU     0
ODD_PARITY      EQU     1
EVEN_PARITY     EQU     2
MARK_PARITY     EQU     3
SPACE_PARITY    EQU     4
DEFAULT_PARITY  EQU     NO_PARITY

;**     Values for stop bits
;
ONE_STOP_BIT            EQU     0
ONE_5_STOP_BITS         EQU     1
TWO_STOP_BITS           EQU     2
DEFAULT_STOPBITS        EQU     ONE_STOP_BIT

;**     Values for byte sizes
;
CHAR_5_MASK             EQU     00011111b
CHAR_6_MASK             EQU     00111111b
CHAR_7_MASK             EQU     01111111b
CHAR_8_MASK             EQU     11111111b
DEFAULT_CHAR_MASK       EQU     CHAR_8_MASK
DEFAULT_BYTESIZE        EQU     8

;**     Modem control register masks
;
MC_DTR          EQU     00000001b       ; data terminal ready
MC_RTS          EQU     00000010b       ; request to send
MC_OUT1         EQU     00000100b       ; output 1
MC_OUT2         EQU     00001000b       ; output 2
MC_LOOP         EQU     00010000b       ; loopback mode

;**     Line status register masks
;
LS_DR           EQU     00000001b       ; data ready
LS_OERR         EQU     00000010b       ; overrun error
LS_PERR         EQU     00000100b       ; parity error
LS_FERR         EQU     00001000b       ; framing error
LS_BI           EQU     00010000b       ; break interrupt
LS_THRE         EQU     00100000b       ; TX holding register empty
LS_TSRE         EQU     01000000b       ; TX shift register empty

;**     Modem status register definitions:
;
MS_DCTS         EQU     00000001b       ; delta clear to send
MS_DDSR         EQU     00000010b       ; delta data set ready
MS_TERI         EQU     00000100b       ; trailing edge of ring indicator
MS_DDCD         EQU     00001000b       ; delta receiver line signal detect
MS_CTS          EQU     00010000b       ; clear to send
MS_DSR          EQU     00100000b       ; data set ready
MS_RI           EQU     01000000b       ; ring indicator
MS_DCD          EQU     10000000b       ; receiver line signal detect
MS_DELTAS       EQU     00001111b       ; deltas, not current values

.errnz FX_IN_DSR_OK - MS_DSR

COM_SEG         EQU     40h             ; ROM data segment for COM ports
COM1_PORT       EQU     3f8h            ; port for COM1
COM1_VEC        EQU     4               ; IRQ for COM1
COM2_PORT       EQU     2f8h            ; port for COM2
COM2_VEC        EQU     3               ; IRQ for COM2

DEVICE_ID       EQU     6               ; ABIOS device ID number (to get LID)

BAD_MAX         EQU     1000            ; Maximum number of bad interrupt
                                        ; that can be tolarated
DEINSTALL       EQU     0000h           ; Deinstall the driver if bad int
POST_ERROR      EQU     0001h           ; Post error if bad int
IGNORE_ERROR    EQU     0002h           ; Ignore error even if bad int
AF_RTNLIDPARMS  EQU     01h     ; Return LID Parameter
AF_READDEVPARMS EQU     03h     ; Read Device Parameters
DEVICE_ID       EQU     06h     ; Device ID Number
DEVICE_UNIT     EQU     00h     ; Device Unit Number
RB_LEN          EQU     20h     ; Length of Request Block
CANCEL_ALL_INTS EQU     0EFh            ; Cancel flag for CANCEL fcn
FF_FIFO_SUPPORT EQU     00001000b       ; fifo supported and device present
F_FLAG          EQU     0FFFFh          ; ffffh flag
RC_COMPLETE     EQU     0000h           ; Operation Completed Successfully
PCMCIA_SYSTEM   EQU     01h             ; PCMCIA System
PCMCIA_TEMP_AD1 EQU     0FFF0h          ; ffffh flag
PCMCIA_TEMP_AD2 EQU     0FFF1h          ; ffffh flag
PCMCIA_TEMP_AD3 EQU     0FFF2h          ; ffffh flag
PCMCIA_TEMP_AD4 EQU     0FFF3h          ; ffffh flag

Open_Command    EQU     0Dh     ; command code for open strategy routine
Close_Command   EQU     0Eh     ; command code for close strategy routine
IOCTL_Command   EQU     10h     ; command code for IOCTL strategy routine
req_header      equ     13      ; size of a request block header
NULL            EQU     0

PORT_STANDARD   EQU     0
PORT_ENHANCED   EQU     1

parms   STRUC
cmd_code        db      ?
num_writes      db      ?
num_reads       db      ?
writes          db      5 DUP (?)
reads           db      2 DUP (?)
parms   ENDS

;**     COM information structure
;
;       ComInfo contains all of the information pertaining
;       to a single port.
;
; Initial values for flags:
;
F1_INIT         EQU     F1_DTR_ENABLE
F2_INIT         EQU     F2_RTS_ENABLE
F3_INIT         EQU     F3_READ_TO_NORM

WRITE_TO_INIT   EQU     6000            ; 60 seconds
READ_TO_INIT    EQU     6000            ; 60 seconds

SPACE           EQU     20H
NULL            EQU     00H
ESPSIG          EQU     0AAh                 ; ESP adapter signature

ComInfo STRUC
;**      start of device control block info
;
; WARNING: this must at the top of the ComInfo structure.
; WARNING: this must match the DCB structure exactly.

        ci_dcb_writeto  DW      WRITE_TO_INIT   ; write timeout
        ci_dcb_readto   DW      READ_TO_INIT    ; read  timeout
        ci_dcb_flags1   DB      F1_INIT         ; first  flags byte
        ci_dcb_flags2   DB      F2_INIT         ; second flags byte
        ci_dcb_flags3   DB      F3_INIT         ; third  flags byte
        ci_dcb_ErrChar  DB      0               ; error replacement char
        ci_dcb_BrkChar  DB      0               ; break replacement char
        ci_dcb_XonChar  DB      xonequ          ; XON  character
        ci_dcb_XoffChar DB      xoffequ         ; XOFF character

; end of device control block info

        ci_ier          DB      0               ; word align rest of struc

        ci_signature    DW      SIGNATURE       ; signature ID word
        ci_port         DW      0               ; I/O port, 0 if non-existant
        ci_baud         DD      DEFAULT_BAUD    ; baud rate

        ci_linec        DB      0               ; line control
        ci_bytesize     DB      DEFAULT_BYTESIZE; TX/RX byte size
        ci_parity       DB      DEFAULT_PARITY  ; parity
        ci_stopbits     DB      DEFAULT_STOPBITS; stop bits
        ci_cmask        DB      DEFAULT_CHAR_MASK ; received character mask
        ci_tximm        DB      0               ; transmit immediate character

        ci_irq          DB      0               ; interrupt number
        ci_depth        DB      D_NONE          ; interrupt depth
        ci_isr          DW      (?)             ; interrupt service routine
        ci_visr         DW      (?)             ; vdm interrupt service routine
        ci_badmax       DW      BAD_MAX         ; bad interrupt maximum

        ci_nopens       DW      0               ; number of outstanding opens
        ci_nvdmopens    DW      0               ; number of outstanding vdm opens CP20D1390
        ci_oci_sem      DD      0               ; open/close/ioctl exclusion sem
        ci_oci_sem_own  DD      0               ; oci_sem owner RP address
        ci_comerr       DW      0               ; I/O error
        ci_event        DW      0               ; event flags

        ci_GDTSelRead   DW      0               ; GDT selectors for the user buffer
        ci_GDTSelWrite  DW      0               ; for use in the interrupt routines

        ci_hAdapter     DD      0
        ci_hLDev        DD      0
        ci_hSysName     DD      0

        ci_flagx        DB      0               ; extra flags
        ci_flagx1       DB      0               ; extra flags
        ci_hsflag       DB      0               ; handshake flag
        ci_hhslines     DB      0               ; DTR/RTS bits for handshaking
        ci_outhhslines  DB      0               ; output handshake lines

        ci_lsrshadow    DB      0               ; line  status register shadow
        ci_msrshadow    DB      0               ; modem status register shadow
        ci_port_number  DB      0               ; VDM port number of this CIDA
        ci_LID          DW      0               ; to remember LID on PS/2s
        ci_flagGA       DW      0               ; Log Facility Alert conditons
                                                ; read request packet list
        ci_r_rpl        DD      0               ; head
                        DD      0               ; tail
                        DW      SIGNATURE

                                                ; write request packet list
        ci_w_rpl        DD      0               ; head
                        DD      0               ; tail
                        DW      SIGNATURE

        ci_r_rp         DD      0               ; current read request
        ci_w_rp         DD      0               ; current write request
        ci_r_to_move    DW      0               ; bytes to move to satisfy r_rp
        ci_w_to_move    DW      0               ; bytes to move to satisfy w_rp

        ci_r_to         DW      0               ; r_rp time out
        ci_w_to         DW      0               ; w_rp time out
        ci_r_to_start   DW      0               ; r_rp time out start value
        ci_w_to_start   DW      0               ; w_rp time out start value

        ci_vdm_flag     DB     0                ;VDM information flag
                                                ;VDM BIT 0 - InUse by VDM
                                                ;VDM BIT 1 - notify the VCOM Rx
                                                ;VDM BIT 2 - notify the VCOM Tx
                                                ;VDM BIT 3 - Blocked IOCTL
                                                ;VDM BIT 4-7 RESERVED, set to 0

        ci_vdm_Rx_State DB     0                ;VDM BIT 0&1 - Rx_State
                                                ;VDM BIT 2-7 RESERVED, set to 0

        ci_vdm_Tx_State DB     0                ;VDM BIT 0&1 - Tx_State
                                                ;VDM BIT 2-7 RESERVED, set to 0

        ci_vdm_Rx_Count DB     0                ;VDM count of chars put in Tx
                                                ;VDM Queue since XOFF given to
                                                ;VDM DOS APP

        ci_vdm_Tx_Count DB     0                ;VDM count of chars put in Rx
                                                ;VDM Queue since XOFF sent to
                                                ;VDM device

        ci_vdm_LastMSR  DB     0                ;VDM last MSR given to DOS App
        ci_vdm_LastLSR  DB     0                ;VDM LSR to give to DOS app

        ci_dummy3       DB     0                ;mw put on word boundaries

        ci_qin          DB      SIZE IO_Queue dup (?)
        ci_qin_q        DB      QI_SIZE_EVEN dup (0)

        ci_qout         DB      SIZE IO_Queue dup (?)
        ci_qout_q       DB      QO_SIZE_EVEN dup (0)

        ci_fifobaud     DW     0                ;mw store baud latch values

        ci_sid          DW     0                ;VDM App's Session ID CP20D1390

        ci_vdm_OpenError DW    0                ;VDM Type of error to return to
                                                ;VDM VCOM from Open

        ci_vdm_Blocked_IOCTL DD    0            ;VDM IOCTL/Tx Queue
                                                ;VDM serialization mechanism

                                                ;VDM IOCTL request packet
        ci_req_pack      DB      size IOCTLPacket dup (0)

        ci_qstat         DB      QI_SIZE dup (0)  ;VDM LSRQ
        ci_int_sharing   DB      0               ;supports int. sharing
        ci_int_data      DW      0               ;offset of SharedIntData
        ci_next_COM      DW      0               ;ComInfo of next COM on
                                                ; this IRQ line
        ci_mult_COMs_IRQ DB     0               ;other COM ports are on
                                                ; this IRQ line


        ci_eflags       DB      0

        dummy           DB      0
        ci_rx_request   DB      DMA_REQ_AUTO
        ci_tx_request   DB      DMA_REQ_AUTO
        ;*************************************************************@PVW
        ;************                                     ************@PVW
        ;******          Perfview Data Block                    ******@PVW
        ;**************                                   ************@PVW                 ;@PVW
ifdef PERFVIEW
        ci_Data_Block   DB      SIZE pvdbh_s dup (0)
        ci_Read_Time    dd      0                                    ;@PVW
                        dd      0                                    ;@PVW
        ci_Write_Time   dd      0                                    ;@PVW
                        dd      0                                    ;@PVW
        ci_Num_Reads    dd      0                                    ;@PVW
        ci_Read_Bytes   dd      0                                    ;@PVW
        ci_Num_Writes   dd      0                                    ;@PVW
        ci_Write_Bytes  dd      0                                    ;@PVW
        ci_HW_Overruns  dd      0                                    ;@PVW
        ci_SW_Overruns  dd      0            ;@PVW last item!!! used at init
                                             ;@PVW time to find data_block len

        ;************                                     ************@PVW
        ;*******  If Adding Counters or Timers then see the     ******@PVW
        ;*******  Number_Tmrs_Ctrs EQU. And change Procedure    ******@PVW
        ;*******  Initialize_PerfView_Data to reference last    ******@PVW
        ;*******  data item                                     ******@PVW
        ;*************************************************************@PVW                 ;@PVW
endif ; PERFVIEW
ComInfo ENDS

SharedIntData struc
        si_entry        dw      0               ; offset of IRQ handler
        si_count        db      0               ; number of COM ports on this IRQ
        si_irq          db      0               ; IRQ line
        si_opens        db      0               ; number of open COMs on this IRQ
        si_firstCOM     dw      0               ; ptr. to ComInfo struc
SharedIntData ENDS


;----------------------------------------------------------------------------
;                     ABIOS Request Block   structure
;----------------------------------------------------------------------------
RequestBlock struc

  RBLength        dw      0    ; 00H Length of Request Block
  LogicalID       dw      0    ; 02H Addr of Logical ID
  Unit_ab         dw      0    ; 04H Device Unit Value
  Function_ab     dw      0    ; 06H Function Value
  RBFlags         dw      0    ; 08H ABIOS to ABIOS Call
                  dw      0    ; 0AH Reserved area
  ReturnCode      dw      0    ; 0CH Return Code
  TimeOut_ab      dw      0    ; 0EH Time to wait in seconds
  IntLev          dw      0    ; 10H INT Level/ARB Level
                  dw      0    ; 12H Transmit Buffer Offset
                  dw      0    ; 14H Transmit Buffer Segment
  AddOpStat       dw      0    ; 16H Additional Open Status
  Enhanced_18H    dw      0    ; 18H Enhance Function control
                  db      0    ; 1AH Comp char match 1
                  db      0    ; 1BH Comp char function 1
  EnhArbLev       db      0    ; 1CH Comp char match 2
                  db      0    ; 1DH Comp char function 2
                  db      0    ; 1EH Comp char match 3
                  db      0    ; 1FH Comp char function 3
                  dw      0    ; 20H Reserved Area 20H
                               ;
                  dw      0    ; 22H Receive Buffer Offset
                  dw      0    ; 24H Receive BUffer Segment
                  dw      0    ; 26H Reserved Area
                               ;
  AsyncByte_1     db      0    ; 28H General Data Area Byte 1
  AsyncByte_2     db      0    ; 29H General Data Area Byte 2
  AsyncByte_3     db      0    ; 2AH General Data Area Byte 3
  AsyncByte_4     db      0    ; 2BH General Data Area Byte 4
                               ;
                  dw      0    ; 2CH
                  dw      0    ; 2EH
                  dw      0    ; 30H
                  dw      0    ; 32H
                  dw      0    ; 34H
                  dw      0    ; 36H
                  dw      0    ; 38H
                  dw      0    ; 3AH
                  dw      0    ; 3CH
                  dw      0    ; 3EH
  BinBaudRate     dd      0    ; 40H Binary baud rate
                               ;(if Byte44=0FFH )
  BaudRate        db      0    ; 44H Baud Rate
  Parity          db      0    ; 45H Parity Bit
  StopBits        db      0    ; 46H Stop Bits
  WordLength      db      0    ; 47H Word Length
  BreakI          db      0    ; 48H Break Indicator
  LineStatus      db      0    ; 49H Line Status Register
  ModemStatus     db      0    ; 4AH Modem Status Register
                               ;
  ReturnStat      dw      0    ; 4BH Return Status
  SaveStat        dw      0    ; 4DH Return Status for
                               ;     previous operation
                               ;     when attention interrupt
                  dw      0    ; 4FH Return Code for
                               ;     previous operation
                               ;     when attent interrupt
  CancelFlag      db      0    ; 51H flag for CANCEL ABIOS
                  dw      20 dup(?) ; Work Area

RequestBlock      ends


DCB_SIZE        EQU     ci_dcb_XoffChar-ci_dcb_writeto+1
SELECTOR_MASK   EQU     0FFF8h

LocINFOseg      EQU     2     ;Local Info Seg value for Dev_Hlp CP20D1390

.errnz ci_dcb_writeto
.errnz ci_dcb_XoffChar-10

.errnz rpl_head
.errnz rpl_tail-4
.errnz rpl_signature-8


ESPInfo STRUC
        pi_address      DW      0
        pi_DMA_chan     DB      0
        pi_irq          DB      0
        pi_isr          DW      0
        pi_sid          db      0
        pi_rrindex      db      0
        pi_svcmask      db      0
       pi_flagx        DB      0
       pi_port1        DW      -1
       pi_port2        DW      -1
       pi_DMA_outstanding DW      0
       pi_xfer_count   DW      0
       pi_depth        DB      D_NONE          ; interrupt depth
ESPInfo ENDS



pvw_HW_Overrun  MACRO                               ;@PVW
      LOCAL   exit                                  ;@PVW
.386
      test    ds:[si].ci_Data_Block.dbh_flFlags,RPC_FL_CONFIG ;@PVW PERFVIEW ACTIVE?
      jz      exit                                  ;@PVW NO, EXIT
      inc     ds:[si].ci_HW_Overruns                ;@PVW inc perfview cntr
exit:                                               ;@PVW
.286C                                               ;@PVW
      ENDM ;pvw_HW_Overrun                          ;@PVW

pvw_SW_Overrun  MACRO                               ;@PVW
      LOCAL   exit                                  ;@PVW
.386
      test    ds:[si].ci_Data_Block.dbh_flFlags,RPC_FL_CONFIG ;@PVW PERFVIEW ACTIVE?
      jz      exit                                  ;@PVW NO, EXIT
      inc     ds:[si].ci_SW_Overruns                ;@PVW inc perfview cntr
exit:                                               ;@PVW
.286C                                               ;@PVW
      ENDM ;pvw_SW_Overrun                          ;@PVW


pvw_Read  MACRO   STARTSTOP,CNTRFLAG
        LOCAL   exit
.386
       IFB     <STARTSTOP>                          ;@PVW Flag Blank
           %out Error: Not enough parameters in macro pvw_Read
           .err                                     ;@PVW error
       ENDIF
       test    ds:[si].ci_Data_Block.dbh_flFlags,RPC_FL_CONFIG ;@PVW Active?
       jz      exit                                 ;@PVW no, Exit
       pusha
       push    DS                                   ;@PVW Push Seg of timer
       lea     dx, ds:[si].ci_Read_Time            ;@PVW Push Off of timer
       push    dx                                   ;@PVW
       inc     ds:[si].ci_Data_Block.dbh_ulSem      ;@PVW Indicate timer update
       IFIDN   <STARTSTOP>,<START>                  ;@PVW Req to start timer?
          call  ds:[si].ci_Data_Block.dbh_pfnTmrSub ;@PVW call add Routine
       ELSEIFIDN <STARTSTOP>,<STOP>                 ;@PVW Req to stop timer?
          call  ds:[si].ci_Data_Block.dbh_pfnTmrAdd ;@PVW call stop routine
          IFIDN <CNTRFLAG>,<DOCOUNTERS>             ;@PVW strategy entry?
             xor   edx,edx                          ;@PVW clear edx
             mov   dx,es:[di].IOCount               ;@PVW get bytes read
             add   ds:[si].ci_Read_Bytes,edx        ;@PVW add bytes to total
             inc   ds:[si].ci_Num_Reads             ;@PVW inc number of reads
          ELSEIFIDN <CNTRFLAG>,<VDMCOUNTERS>        ;@PVW VCOM entry
             inc   ds:[si].ci_Read_Bytes            ;@PVW inc bytes read
             inc   ds:[si].ci_Num_Reads             ;@PVW inc number of reads
          ELSEIFNB <CNTRFLAG>                       ;@PVW bad parameter
             %out Error: Bad parameter in macro pvw_Read
             .err                                   ;@PVW error
          ENDIF                                     ;@PVW
       ELSE                                         ;@PVW oops
          %out Error: Bad parameter in macro pvw_Read
          .err                                      ;@PVW error
       ENDIF                                        ;@PVW
       dec     ds:[si].ci_Data_Block.dbh_ulSem      ;@PVW indicate update done
       popa
exit:                                               ;@PVW
.286C                                               ;@PVW
        ENDM ;pvw_Read                              ;@PVW


pvw_Write MACRO   STARTSTOP,CNTRFLAG
        LOCAL   exit
.386
       IFB     <STARTSTOP>                          ;@PVW Flag Blank
           %out Error: Not enough parameters in macro pvw_Write
           .err                                     ;@PVW error
       ENDIF
       test    ds:[si].ci_Data_Block.dbh_flFlags,RPC_FL_CONFIG ;@PVW Active?
       jz      exit                                 ;@PVW no, Exit
       pusha                                        ;@PVW save register we use
       push    DS                                   ;@PVW Push Seg of timer
       lea     dx, ds:[si].ci_Write_Time            ;@PVW Push Off of timer
       push    dx                                   ;@PVW
       inc     ds:[si].ci_Data_Block.dbh_ulSem      ;@PVW Indicate timer update
       IFIDN   <STARTSTOP>,<START>                  ;@PVW Req to start timer?
          call  ds:[si].ci_Data_Block.dbh_pfnTmrSub ;@PVW call add Routine
       ELSEIFIDN <STARTSTOP>,<STOP>                 ;@PVW Req to stop timer?
          call  ds:[si].ci_Data_Block.dbh_pfnTmrAdd ;@PVW call stop routine
          IFIDN <CNTRFLAG>,<DOCOUNTERS>             ;@PVW
             xor   edx,edx                          ;@PVW clear edx
             mov   dx,es:[di].IOCount               ;@PVW get bytes written
             add   ds:[si].ci_Write_Bytes,edx       ;@PVW add bytes to total
             inc   ds:[si].ci_Num_Writes            ;@PVW inc number of writes
          ELSEIFIDN <CNTRFLAG>,<VDMCOUNTERS>        ;@PVW
             inc   ds:[si].ci_Write_Bytes           ;@PVW inc bytes written
             inc   ds:[si].ci_Num_Writes            ;@PVW inc number of writes
          ELSEIFNB <CNTRFLAG>                       ;@PVW bad parameter
             %out Error: Bad parameter in macro pvw_Write
             .err                                   ;@PVW error
          ENDIF                                     ;@PVW
       ELSE                                         ;@PVW oops
          %out Error: Bad parameter in macro pvw_Write
          .err                                      ;@PVW error
       ENDIF                                        ;@PVW
       dec     ds:[si].ci_Data_Block.dbh_ulSem      ;@PVW indicate update done
       popa                                         ;@PVW restore scratch reg
exit:                                               ;@PVW
.286C                                               ;@PVW
        ENDM ;pvw_Write                             ;@PVW


;/*------------------------------------------*/
;/*  Error codes for FailFree                */
;/*------------------------------------------*/

FFF_INITEVERY     EQU   1
FFF_ABIOSLID      EQU   2
FFF_EISACONFIG    EQU   3
FFF_ISAMCACONFIG  EQU   4
FFF_GETPORTS      EQU   5
FFF_CHECKIRQ      EQU   6
FFF_GETGDT        EQU   7
FFF_ASSIGNIRQ     EQU   8
