ntr2000.386

Warning: This file has been marked up for HTML

page ,130
;
; $name: NTR2000.386
; $version: 7
; $date_modified: 12181998 
; $description: Novell Token-Ring Driver Code for NetWare 386  
; $owner:  ODI LAN Driver Manager
; Copyright (c) 1990 - 1998 Novell, Inc. All Rights Reserved.

; THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND 
; TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE
; AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS
; THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS 
; TO DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S 
; SAMPLE CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE 
; DISTRIBUTION RIGHTS TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE
; AS A COMPONENT OF DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO 
; OBLIGATIONS TO DEVELOPER OR DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS 
; CODE.
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( History, TOKEN/HISTORY )
;
;       Novell Token-Ring Driver Code for NetWare 386.
;       This driver must be loaded after MSM.NLM and TOKENMSM.NLM.
;
;       Written by:     DFS
;       Date:           November, 1990
;
;***********************************************************************
;
; History Log:
;
; 09-03-91 dfs  Converted to NLM.(Version 3.20)
;
; 12-09-92 dfs  Changed custom keyword 'MEM1' to MEM0' for shared RAM
;               override so OS wouldn't get confused(Version 3.21).
;
; 12-14-92 dfs  Set InterruptResetLevel to 2 if 9(Version 3.22).
;
; 01-05-93 dfs  Changed short name from TOKEN to NTR2000.
;
; 01-05-93 dfs  Added support for DriverEnableInterrupt/DriverDisableInterrupt.
;
; 03-03-93 dfs  - Rearranged stat counters to match spec.
;               - Reset adapter at AES only.(Version 3.23)
;
; 03-11-93 dfs  - Rearranged stat counters to match spec.
;               - Did not allow bridge enable if in 8K non paged mode.
;
; 03-19-93 dfs  - Removed 4K Max Packet Size Limit.
;               - Added CLI to DriverCallBack to avoid reentrancy.
;
; 03-30-93 dfs  - Critical sectioned DriverCallBack to avoid using CLI.
;               - Took out zeroing of ECX in AdapterErrorISR.
;
; 04-01-93 dfs  - Went back to InterruptTimeCallBack(Sorry DCBs).
;               - Didn't chop off maximum packet size by 2.
;
; 05-17-93 dfs  - Added STI/NOP/CLI to beginning of DriverShutdown
;                 to fix NetWare for OS/2 bug. This allows a previous
;                 pending interrupt on this adapter to get processed
;                 before we reset the adapter. Otherwise DriverISR
;                 gets called after the adapter is reset, the shared
;                 interrupt test fails, and the PIC doesn't get EOI'd.
;                 (Version 3.24)
;
; 09-13-93 dfs  - Used AES instead of Callback to attempt rescheduling
;                 again during delays.
;               - Used MSMGetMicroTimer for 50ms reset delay.
;                 (Version 3.25)
;
; 10-15-93 dfs  - Removed all the STIs and CLIs.  The driver was hanging in
;                 NT because the Interrupts were disabled during a call to
;                 MSMGetMicroTimer.  This would not let the time update
;                 (Infinite loop).
;                 (Version 3.26)
;
; 02-11-94 RTY  - Added code To DriverDisableInterrupt to set the
;                 NIC_INTERRUPTED_BIT in the MLIDStatusFlag if the Interrupt
;                 was ours.  This fixed a problem with DriverReset that was
;                 occuring in NT because DriverISR can not be executed while
;                 DriverReset is executing.  We were waiting for an event
;                 to occur in DriverISR that would never happen.
;                 (Version 3.27)
;
; 03-09-94 akw  - Modified rty's fix above on 2-11-94.  Since adding critical
;                 sectioning code to the MSM and TSM, the server driver was
;                 essentially looking like the NT driver.  However, we needed
;                 to re-arm the global interrupts for our case to work.
;               - SPD #60070 fix where a beaconing ring condition caused the
;                 adapter to reset with wrong error message.  Fixed to wait
;                 around with correct error message.
;               - Added Richard Jones' in-depth look at fast-path ram size
;                 issue.  Decreased size from 3xxx to 2434.
;               - Changed DriverISRs interrupt reason loop to a bunch of
;                 tests and if none of the tests are true, we return the ARB
;                 instead of running off the end of the table as before.
;               - Reset the MLIDStatusFlag to NOT NIC_INTERRUPTED_BIT each
;                 time to ensure we actually waited for the event to occur.
;                 Previously the bit would remain set, and would cause
;                 erroneous error conditions to occur because the driver
;                 would say the adapter was OK, when in fact it never waited
;                 long enough to open on the wire or initialize fast path.
;                 SPD #55610 & SPD #55578 fixed.
;               - Added HSM_SPEC_VERSION string.
;               - Uncommented the code that zeros out shared-ram if shared-ram
;                 size is greater than 8k and set to paging.
;               - Added transmit timeout code because we were seeing cases
;                 where the driver was never getting the next TCB from queue.
;                 (Version 3.28)
;
; 07-11-94 rcp  - Commented out code which checked to see if Interrupt's
;                 were Disabled in DriverDisableInterrupt routine, because
;                 Spurious Interrupts were occurring.
;                 (Version 3.29)
;
; 08-16-94 akw  - Fixed bug where the MMIO address was getting clobbered in
;                 the AdapterCheckISR routine when calling WaitForEvent.
;                 (Version 3.30)
;
; 09-01-94 jcp  - Fixed function DriverCallBack to clean up Tx Queue. It needs
;                 to call TokenTSMGetNextSend after using Reset. (Version 3.31)
;
; 09-09-94 jcp  - Inserted a flag to avoid sending packet before reset (or
;                 Init) is completed.  Increased the timeout timer from 2 sec.
;                 to 5 sec. (Version 3.32)
;
; 10-17-94 jcp  Version 3.50    (Post NetWare 4.10 release)
;               - Fixed cable disconnect problem.  This bug has caused the card
;                 to disable its interrupt line.
;
;               - Fixed beaconing problem.  The driver should not reset the
;                 hardware when its in beaconing stage.
;
; 10-19-94 jcp  Version 3.50
;               - Added code to print out a message when the customer is using
;                 1990 BIOS (Bad).
;
; 11-14-94 jcp  Version 3.50
;               - Removed 0 dup(0).
;
; 05-02-95 tnl   Version 3.51
;      - Removed outdated APIs from DRIVER.INC and makefile.
;
; 06-07-95 tnl   Version 3.51
;      - Changed wording of bogus ErrorRAMFailedMessage string.
;
; 08-04-95 jcp   Version 3.52
;      - Trap under heavy load at SuperLab.  According to IBM, the NIC
;        chip has some design faults, it needs to allocate extra 4K
;        buffer to prevent this condition.
;
; 09-18-95 MPK  Version 3.53
;       Made changes to make code compatable with 3.3 specification.  
;       Includes changes to DriverConfigTemplate (versions and Scatter
;       gap count,  Also added changes to intialization, to determine
;       BUS by use of NBI calls
;
; 02-06-96 tnl   Version 3.54
;      - Add NBI code to DriverInit MCA path to make driver HIN
;        aware.
;      - Modify config table template to init MlidSlot field to -1
;        in accordance with 3.3 spec.
;
; 02-14-96 tnl   Version 3.54
;      - Modify DriverInit to call MSMScheduleAESCallBack in the
;        proper order as prescribed by the spec.
;
; 03-28-96 tnl   Version 3.55
;      - Modify DriverInit to call MSMReturnDriverResources 
;        correctly as defined by the 3.3 spec. SPD #121143.
;
; 05-17-96 tnl   Version 3.56
;      - Modify DriverInit to not call MSMSetHardwareInterrupt
;        until right before DriverReset. SPD 126109.
;
; 06-05-96 tnl   Version 3.57
;      - Modify DriverShutdown to call MSMYieldWithDelay rather
;        than do an explicit sti. SPD 127892.
;
; 06-26-96 tnl   Version 3.58
;      - Modify DriverInit to no longer set MCA bit in MLIDFlags;
;        this bit has been obsoleted. SPD 129778.
;
; 07-09-96 tnl   Version 3.59
;      - Modify WaitForEvent to use MSMGetCurrentTime instead of
;        MSMGetMicroTimer to work around problems with MicroTimer
;        on 486 machines. Also changed code that calls WaitForEvent
;        to pass in a 1/18s tick value instead of microsecond value.
;        This isn't the most elegant work around but it seems to
;        take care of the problem.  See SPD 130758.
;
;
; 11-01-96 PM   Modified DriverParameterBlock structure to add the following
;      fields immediately after DriverDisableInterrupt field in
;               accordance with 3.31 specs.:
;         - DriverISR2Ptr - Null entry
;         - DriverReserved2 - Null entry
;         - HSMSpecVerString - pointer to spec version string
;         - DriverPriorityQueuePtr - Null entry
;         - DriverDisableInterrupt2Ptr - Null entry
;
; 11-01-96 PM   Modified Config Table template to change the following in
;               accordance with 3.31 specs. :
;         - changed MLIDCFG_MinorVersion from 13 to 14
;         - splited up MLIDReserved field that follows
;         -  MLIDCFG_SGCount into the following fields:
;            - MLIDReserved1
;            - MLIDPrioritySup
;            - MLIDReserved2
;         - changed MLIDIOCfgMajorVersion from 00 to 01
;
; 11-13-96 PM   Modified DriverReset and DriverShutdown routines to add
;               operation scope parameter.
;
; 07-03-97 JCJ  Version 3.61
;               Changed MLIDBusTag to 0 if found bus type is ISA. SPD#160760
;
; 15-18-97 JCJ  Version 3.62
;               SHUTDOWN bit of MSMStatusFlags is checked in RxISR(ARBRequestISR)
;               routine. This ensures that adapter will not interrupt for a
;               packet reception if the driver is in a process of shutting
;               down. SPD # 161461
;
; 11-14-97 AYD   Version 3.63
;      Initialized the uninitialized fields in DriverConfigTemplate.
;
; 12-17-97 JRT  Version 3.64
;               Initialized the uninitilaized fields in AdapterOptions.
;               SPD #173871.
;
; 12-18-97 WTT   The last four fields in the AdapterOptions structure 
;      AdapterOptionDefinitionStructure were not being initialized.
;      Change the code to initalize those fields to zero.
;      SPD 174351
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        name    Token-RingDriver
        title   Token-Ring LAN Driver

DEBUG   equ     0

include driver.inc

NoTxLimit       equ     -1
UseFastCalls    equ     -1
UseNBICalls   equ   -1

        subttl  Token-Ring Structures and Equates
;
;***********************************************************************\
;                                                                       *
; TOKEN-RING Structures and Equates.                                    *
;                                                                       *
;***********************************************************************/
;
;
;***************************************************************\
;                                                               *
; TCB Driver Workspace equates.                                 *
;                                                               *
;***************************************************************/
;
TCBWorkSpace    struc
TCBLink         dd      0               ; TCB Link field.
TCBCorrelator   db      0               ; TCB Correlator Save Area.
TCBWorkSpace    ends
;
;***************************************************************\
;                                                               *
; Token Ring Equate Values.                                     *
;                                                               *
;***************************************************************/
;
DEFAULT_RAM_SEGMENT     equ     0D8h    ; Default Shared RAM Segment.
INIT_TIMEOUT_IN_TICKS   equ     03*18   ; DIR.Initialize Timeout (03 Seconds).
MAX_INIT_RETRIES        equ     02      ; DIR.Initialize Re-Try Value.
DIR_INIT_WAIT_IN_TICKS  equ     02      ; DIR.Initialize Adapter Release Wait Time.
SHARED_RAM_LOWER_LIMIT  equ     0A0000h ; Minimum Value for SHARED RAM Segment.
ADAPTER_CHECK_TIMEOUT   equ     250/54+01       ; Hardware Adapter Check Timeout.
;
;***************************************************************\
;                                                               *
; MLIDStatusFlag -- Token-Ring Card State Flag Equates.         *
;                                                               *
;***************************************************************/
;
IGNORE_INTERRUPTS_BIT   equ     80h     ; Bit 7 - Ignore ALL Interrupts.
NIC_INTERRUPTED_BIT     equ     40h     ; Bit 6 - Interrupt Happened.
RE_INIT_ADAPTER_BIT     equ     20h     ; Bit 5 - Re-Initialize Adapter.
DIR_READ_LOG_BIT        equ     10h     ; Bit 4 - DIR.Read.Log in order.
DIR_FUNCTIONAL_BIT      equ     08h     ; Bit 3 - DIR.Set.Functional.Address.
ADAPTER_RESET_BIT       equ     04h     ; Bit 2 - Adapter Being Held Reset.
TX_IN_PROCESS_BIT       equ     02h     ; Bit 1 - Transmit In Process.
SRB_IS_BUSY_BIT         equ     01h     ; Bit 0 - SRB Is Busy.
;
;***************************************************************\
;                                                               *
; Adapter Control Region Structure.                             *
;                                                               *
;***************************************************************/
;
AdapterControlRegion    struc
                                db      1E00h dup (00)  ;   Adapter Bios Area For RPL
RAMRelocationRegister           db      00,00           ; 1E00
WriteRegionBase                 db      00,00           ; 1E02
WriteWindowOpenRegister         db      00,00           ; 1E04
WriteWindowCloseRegister        db      00,00           ; 1E06
IntStatusToPC                   db      00,00           ; 1E08
IntStatusToAdapter              db      00,00           ; 1E0A
TimerControlRegister            db      00,00           ; 1E0C
TimerValueRegister              db      00,00           ; 1E0E
                                db      08 Dup (00)     ; 1E10 Reserved
RAMPageRegister                 db      00,00           ; 1E18
                                db      0E6h dup (00)   ; 1E1A Reserved
NodeAddressOffset               db      030h dup (00)   ; 1F00
SignatureOffset                 db      070h dup (00)   ; 1F30
;AdapterIDOffset                db      0 dup (0)       ; 1FA0 ;JCP, 941114.
AdapterControlRegion    ends

AdapterIDOffset         equ     offset SignatureOffset + 70h ; JCP, 941114.
;
;***************************************************************\
;                                                               *
; Adapter Control Region for Read/Write/Reset MMIO Register.    *
;                                                               *
;***************************************************************/
;
MMIOWriteStructure      struc

STOREOffset     db      20h dup (00)            ; 00h
ANDOffset       db      20h dup (00)            ; 20h
;OROffset       db      0   dup (00)            ; 40h, JCP, 941114.

MMIOWriteStructure      ends

OROffset        equ     offset ANDOffset + 20h  ; JCP, 941114.

;
;***************************************************************\
;                                                               *
; IntStatusToAdapter -- PC To Adapter Interrupt Status          *
;                       HIGH Byte Bit Values.                   *
;                                                               *
;***************************************************************/
;
PC_PARITY_ERROR_BIT     equ     80h     ; Bit 7 - Parity Error In Shared RAM
PC_TIMER_EXPIRED_BIT    equ     40h     ; Bit 6 - Expiration Of Timer Count
PC_ACCESS_VIOLATION_BIT equ     20h     ; Bit 5 - Access Violation
;
;***************************************************************\
;                                                               *
; IntStatusToAdapter -- PC To Adapter Interrupt Status          *
;                       LOW Byte Bit Values.                    *
;                                                               *
;***************************************************************/
;
BRIDGE_FORWARD          equ     40h     ; Bit 6 - Bridge Frame Forward Request
COMMAND_IN_SRB          equ     20h     ; Bit 5 - Command In SRB
RESPONSE_IN_ASB         equ     10h     ; Bit 4 - Response In ASB
SRB_FREE                equ     08h     ; Bit 3 - SRB Free Request
ASB_FREE                equ     04h     ; Bit 2 - ASB Free Request
ARB_FREE                equ     02h     ; Bit 1 - ARB Free
SSB_FREE                equ     01h     ; Bit 0 - SSB Free
;
;***************************************************************\
;                                                               *
; IntStatusToPC --      Adapter To PC Interrupt Status          *
;                       HIGH Byte Bit Values.                   *
;                                                               *
;***************************************************************/
;
NMI_DISABLED_BIT        equ     80h     ; Bit 7 - NMI Disabled
INTERRUPT_ENABLE_BIT    equ     40h     ; Bit 6 - Interrupt Enable
PARITY_ERROR_BIT        equ     20h     ; Bit 5 - Parity Error In Shared RAM
TIMER_EXPIRED_BIT       equ     10h     ; Bit 4 - Expiration Of Timer Count
ADAPTER_ERROR_BIT       equ     08h     ; Bit 3 - Adapter Check
RAM_VIOLATION_BIT       equ     04h     ; Bit 2 - Shared RAM Access Violation
;
;***************************************************************\
;                                                               *
; IntStatusToPC --      Adapter To PC Interrupt Status          *
;                       LOW Byte Bit Values.                    *
;                                                               *
;***************************************************************/
;
IMPL_RECEIVED_BIT       equ     80h     ; Bit 7 - IMPL Received
ADAPTER_CHECK_BIT       equ     40h     ; Bit 6 - Adapter Check
SRB_RESPONSE_BIT        equ     20h     ; Bit 5 - SRB Response
ASB_FREE_BIT            equ     10h     ; Bit 4 - ASB Free
ARB_COMMAND_BIT         equ     08h     ; Bit 3 - ARB Command
SSB_RESPONSE_BIT        equ     04h     ; Bit 2 - SSB Response
BRIDGE_FORWARD_BIT      equ     02h     ; Bit 1 - Bridge Frame Frwd Complete

;
;***************************************************************\
;                                                               *
; RAMPageRegister Equates.                                      *
;                                                               *
;***************************************************************/
;
PAGING_ACTIVE_FLAG      equ     0C0h            ; Paging Active Flag.
DEFAULT_PAGE_MASK       equ     16*1024-01      ; Page Size Mask.
;
;***************************************************************\
;                                                               *
; RAMRelocationRegister LOW Byte Bit Values.                    *
;                                                               *
;***************************************************************/
;
ALTERNATE_IPL           equ     01h     ; Bit 0 - Alternate IPL
PARTIAL_RESET           equ     80h     ; Bit 7 - Partial Reset
SHARED_RAM_MASK         equ     0Ch     ; Shared RAM Size Mask.
SHARED_RAM_8K           equ     00h     ; Shared RAM Size = 08k
SHARED_RAM_16K          equ     04h     ; Shared RAM Size = 16k
SHARED_RAM_32K          equ     08h     ; Shared RAM Size = 32k
SHARED_RAM_64K          equ     0Ch     ; Shared RAM Size = 64k
;
;***************************************************************\
;                                                               *
; TimerControlRegister HIGH Byte Bit Values.                    *
;                                                               *
;***************************************************************/
;
TIMER_INTERRUPT         equ     80h     ; Bit 7 - INT PC When TVR = 0000
TIMER_RELOAD            equ     40h     ; Bit 6 - Auto Reload Of Count
TIMER_ENABLE            equ     20h     ; Bit 5 - Enable Timer, Start Count
TIMER_OVERRUN           equ     10h     ; Bit 4 - Timer Overrun
;
;***************************************************************\
;                                                               *
; AdapterRequestBlock Command Code Equates.                     *
;                                                               *
;***************************************************************/
;
ARB_SIZE                equ     28      ; 28 Size Of ARB in Shared RAM.
ARB_RECEIVED_DATA       equ     81h     ; 81h - Received Data
ARB_TRANSMIT_DATA       equ     82h     ; 82h - Transmit Data Request
ARB_DLC_STATUS          equ     83h     ; 83h - DLC Status
ARB_RING_STATUS_CHANGE  equ     84h     ; 84h - Ring Status Change
;
;***************************************************************\
;                                                               *
; ARB 84h - Ring Status Change Structure.                       *
;                                                               *
;***************************************************************/
;
ARBRingStatus   struc

RingCommandCode db      ARB_RING_STATUS_CHANGE  ;00 ARB Command Code
                db      05 dup (00)             ;01 ARB RESERVED
RingNewStatus   db      00, 00                  ;06 ARB New Ring Status

ARBRingStatus   ends
;
;***************************************************************\
;                                                               *
; RingNewStatus Bit Values.                                     *
;                                                               *
;***************************************************************/
;
RING_SIGNAL_LOSS        equ     0080h   ; Bit 07 - Signal Loss
RING_HARD_ERROR         equ     0040h   ; Bit 06 - Hard Error
RING_SOFT_ERROR         equ     0020h   ; Bit 05 - Soft Error
RING_TX_BEACON          equ     0010h   ; Bit 04 - Transmit Beacon
RING_LOBE_WIRE_FAULT    equ     0008h   ; Bit 03 - Lobe Wire Fault
RING_AUTO_REMOVE        equ     0004h   ; Bit 02 - Auto Remove Error 01
RING_REMOVE_RECEIVED    equ     0001h   ; Bit 00 - Remove Received
RING_COUNTER_OVERFLOW   equ     8000h   ; Bit 15 - Counter Overflow
RING_SINGLE_STATION     equ     4000h   ; Bit 14 - Single Station
RING_RECOVERY           equ     2000h   ; Bit 13 - Ring Recovery
;
;***************************************************************\
;                                                               *
; ARB 81h - Received Data Structure.                            *
;                                                               *
;***************************************************************/
;
ARBReceivedData         struc

ARBRxCommandCode        db      ARB_RECEIVED_DATA       ; 00 ARB Command Code
                        db      03 dup (00)     ; 01 ARB RESERVED
;ARBRxStationID         dw      00 dup (0000)   ; 04 Station ID, JCP, 941114.
ARBRxSAP                db      00              ; 04 Service Access Point (SAP) Num
ARBRxLinkStation        db      00              ; 05 Link Station         (LS)  Num
ARBRxFirstBuffer        db      00, 00          ; 06 First Receive Buffer @
ARBRxLanHeaderLength    db      00              ; 08 LAN Header Length
ARBRxHeaderLength       db      00              ; 09 DLC Header Length
ARBRxFrameLength        db      00, 00          ; 10 Entire Frame Length
ARBRxMessageType        db      00              ; 12 Message Type

ARBReceivedData         ends

ARBRxStationID          equ     offset ARBRxSAP ; JCP, 941114.
;
;***************************************************************\
;                                                               *
; ARBRxMessageType Equates.                                     *
;                                                               *
;***************************************************************/
;
ARB_MAC_FRAME           equ     02      ; 02 MAC  Frame
ARB_I_FRAME             equ     04      ; 04 I    Frame
ARB_UI_FRAME            equ     06      ; 06 UI   Frame
ARB_XID_POLL_FRAME      equ     08      ; 08 XID  Command  Poll
ARB_XID_NOTPOLL_FRAME   equ     10      ; 10 XID  Command  Not Poll
ARB_XID_FINAL_FRAME     equ     12      ; 12 XID  Response Final
ARB_XID_NOTFINAL_FRAME  equ     14      ; 14 XID  Response Not Final
ARB_TEST_FINAL_FRAME    equ     16      ; 16 TEST Response Final
ARB_TEST_NOTFINAL_FRAME equ     18      ; 18 TEST Response Not Final
ARB_UNIDENTIFIED_FRAME  equ     20      ; 20 Other Or Unidentified
;
;***************************************************************\
;                                                               *
; ARB 82h - Transmit Data Request Structure.                    *
;                                                               *
;***************************************************************/
;
ARBTransmitData         struc

ARBTxCommandCode        db      ARB_TRANSMIT_DATA       ;00 ARB Command Code
ARBTxCorrelator         db      00              ; 01 Transmit Command Correlator
                        db      02 dup (00)     ; 02 ARB RESERVED
;ARBTxStationID         dw      00 dup (0000)   ; 04 Station ID, JCP, 941114.
ARBTxSAP                db      00              ; 04 Service Access Point (SAP) Num
ARBTxLinkStation        db      00              ; 05 Link Station         (LS)  Num
ARBTxDHBAddress         db      00, 00          ; 06 DHB Address

ARBTransmitData         ends

ARBTxStationID          equ     offset ARBTxSAP ; JCP, 941114.

;
;***************************************************************\
;                                                               *
; ARB 83h - DLC Status Structure.                               *
;                                                               *
;***************************************************************/
;
ARBDLCStatus    struc

ARBDLCCommandCode       db      ARB_DLC_STATUS  ; 00 ARB Command Code
                        db      03 dup (00)     ; 01 ARB RESERVED
;ARBDLCStationID        dw      00 dup (0000)   ; 04 Station ID, JCP, 941114.
ARBDLCSAP               db      00              ; 04 Service Access Point (SAP) Num
ARBDLCLinkStation       db      00              ; 05 Link Station         (LS)  Num
ARBDLCStat              db      00, 00          ; 06 Status
ARBDLCFrameReject       db      05 dup (00)     ; 08 Frame Reject Data
ARBDLCNewAccess         db      00              ; 13 New Access Priority
ARBDLCRingAddress       db      06 dup (00)     ; 14 Physical Ring Address
ARBDLCRemoteSAP         db      00              ; 20 Remote Station SAP Value

ARBDLCStatus    ends

ARBDLCStationID         equ     offset ARBDLCSAP ; JCP, 941114
;
;***************************************************************\
;                                                               *
; Adapter Status Block Structure.                               *
;                                                               *
;***************************************************************/
;
ASB             struc

ASBCommandCode  db      00              ; 00 ASB Command Code
ASBCorrelator   db      00              ; 01 ASB Correlator
ASBReturnCode   db      00              ; 02 ASB Return Code
                db      00              ; 03 ASB RESERVED
;ASBStationID   dw      00 dup (0000)   ; 04 ASB Station ID, JCP, 941114.
ASBSAP          db      00              ; 04 ASB Service Access Point (SAP) Num
ASBLinkStation  db      00              ; 05 ASB Link Station         (LS)  Num
;ASBFrameLength db      00 dup (00)     ; 06 ASB Frame Length     (ARB 82), JCP, 941114
ASBRxBuffer     db      00, 00          ; 06 ASB Receive Buffer @ (ARB 81)
ASBHeaderLength db      00              ; 08 ASB Header Length    (ARB 82)
ASBRemoteSAP    db      00              ; 09 ASB Remote SAP Value (ARB 82)

ASB             ends

ASBStationID    equ     offset ASBSAP           ; JCP, 941114
ASBFrameLength  equ     offset ASBRxBuffer      ; JCP, 941114.
;
;***************************************************************\
;                                                               *
; DLC.Status Appendage Queue Element Structure.                 *
;                                                               *
;***************************************************************/
;
DLCQueue        struc

DLCQLink                dd      00000000        ; 00 Next DLC.Status Structure @
DLCQStatusAppendage     dd      00000000        ; 04 DLC.Status Appendage @
DLCQStatusMask          dw      0000            ; 08 DLC.Status Mask Value
DLCQParameter           db      00              ; 10 DLC.Status User Parameter Value
DLCQStatusSAPID         db      00              ; 11 DLC.Status SAP ID

DLCQueue        ends
;
;***************************************************************\
;                                                               *
; DIR.Initialize SRB Response Structure.                        *
;                                                               *
;***************************************************************/
;
DIRInitialize   struc

DIRInitCommandCode      db      SRB_INIT_COMPLETE       ;00 Command Code (DIR.Initialize Complete)
DIRInitStatus           db      00              ; 01 DIR.Initialize Status
                        db      04 dup (00)     ; 02 RESERVED
DIRInitErrorCode        db      00, 00          ; 06 Bring Up Code
DIRInitNodeAddress      db      00, 00          ; 08 Shared RAM Address of Adapter Node @
DIRInitMicrocodeLevel   db      00, 00          ; 10 Shared RAM Address of Microcode Level
DIRInitAdapterAddress   db      00, 00          ; 12 Shared RAM Address of Adapter Addresses
DIRInitAdapterParmsAddr db      00, 00          ; 14 Shared RAM Address of Adapter Parameters
DIRInitMACBuffer        db      00, 00          ; 16 Shared RAM Address of Adapter MAC Buffer

DIRInitialize   ends
;
;***************************************************************\
;                                                               *
; DIRInitErrorCode Equates.                                     *
;                                                               *
;***************************************************************/
;
INIT_SUCCESSFUL         equ     00h     ; 00h Successful
INIT_DIAG_FAILED        equ     20h     ; 20h Diagnostics Could Not Execute
INIT_ROM_ERROR          equ     22h     ; 22h ROM/BIOS Diagnostics Failed
INIT_RAM_ERROR          equ     24h     ; 24h Shared RAM Diagnoistics Failed
INIT_INSTRUCTION_ERROR  equ     26h     ; 26h Processor Instruction Test Failed
INIT_INTERRUPT_ERROR    equ     28h     ; 28h Processor Interrupt Test Failed
INIT_INTERFACE_ERROR    equ     2Ah     ; 2Ah Shared RAM I/F Reg Diags Failed
INIT_PROTOCOL_ERROR     equ     2Ch     ; 2Ch Protocol Handler Diagnostics Failed
INIT_ADAPTER_ERROR      equ     40h     ; 40h Adapter Timer Failed
INIT_WRITE_ERROR        equ     42h     ; 42h Cannot Write to Shared RAM
INIT_READ_ERROR         equ     44h     ; 44h Reading Shared RAM Caused An Interrupt
INIT_WRITE_INT_ERROR    equ     46h     ; 46h Writing Shared RAM DID NOT Cause Interrupt
INIT_TIMED_OUT          equ     48h     ; 48h Initialization Timed Out
;
;***************************************************************\
;                                                               *
; DIR.Initialize Equates.                                       *
;                                                               *
;***************************************************************/
;
INIT_16_MBPS            equ     01h     ;INIsta - 01 1 ==> 16 Mbps; 0 ==> 04 Mbps
INIT_DEFAULT_RAM_ADDR   equ     0D800h  ;Shared RAM Default Address
INIT_DEFAULT_RAM_SIZE   equ     4000h   ;Default Shared Ram Size = 16k
INIT_MMIO_SIZE          equ     2000h   ;BIOS/MMIO Domain Size = 8k
INIT_FAST_PATH          equ     20h     ; Fast Path Transmit supported
INIT_MULTIPORT_BRIDGE   equ     10h     ; Multiport Bridge supported
INIT_UTIL_MEASURE       equ     08h     ; Ring utilization supported
;
;***************************************************************\
;                                                               *
; DIRInitAdapterParmsAddr Structure.                            *
;                                                               *
;***************************************************************/
;
ParmsStructure  struc
ParmsPhysAddr           dd      0               ; 00 Adapter Physical Addr
ParmsUPNodeAddr         db      6 dup (0)       ; 04 Next Active Upstream Node Addr
ParmsUPPhysAddr         dd      0               ; 0A Next Active Upstream Phys Addr
ParmsPollAddr           db      6 dup (0)       ; 0E Last Poll Addr
                        dw      0               ; 14 Reserved
ParmsAccPriority        dw      0               ; 16 Transmit Access Priority
ParmsSourceClass        dw      0               ; 18 Source Class Authority
ParmsAttCode            dw      0               ; 1A Last Attention Code
ParmsSourceAddress      db      6 dup (0)       ; 1C Last Source Address
ParmsBeaconType         dw      0               ; 22 Last Beacon Type
ParmsMajorVector        dw      0               ; 24 Last Major Vector
ParmsNetwStatus         dw      0               ; 26 Network Status
ParmsSoftError          dw      0               ; 28 Soft Error Timer Value
ParmsFEError            dw      0               ; 2A Front End Error Counter
ParmsLocalRing          dw      0               ; 2C Number of the Ring
ParmsMonError           dw      0               ; 2E Monitor Error Code
ParmsBeaconTransmit     dw      0               ; 30 Beacon Transmit Type
ParmsBeaconReceive      dw      0               ; 32 Beacon Receive Type
ParmsFrameCorrel        dw      0               ; 34 Frame Correlator Save
ParmsBeaconNAUN         db      6 dup (0)       ; 36 Beaconing Station NAUN
                        dd      0               ; 3C Reserved
ParmsBeaconPhys         dd      0               ; 40 Beaconing Station Phys Addr

ParmsStructure  ends
;
;***************************************************************\
;                                                               *
; Configure Fast Path RAM SRB structure.                        *
;                                                               *
;***************************************************************/
;
ConfigFastPathStructure struc

FPCommand               db      12h             ; 00 Command
                        db      0               ; 01 reserved
FPRetcode               db      0               ; 02 Set by adapter on return
                        db      5 dup (0)       ; 03 reserved
FPRAMSize               dw      0               ; 08 RAM size to Allocate
FPBufferSize            db      02h, 00h        ; 10 Size of Tx buffers(512)

ConfigFastPathStructure ends
;
;***************************************************************\
;                                                               *
; Configure Fast Path RAM Return SRB structure.                 *
;                                                               *
;***************************************************************/
;
ConfigFastPathResponse  struc

FPRCommand              db      12h             ; 00 Command
                        db      0               ; 01 reserved
FPRRetcode              db      0               ; 02 Return code for this command
                        db      5 dup (0)       ; 03 reserved
FPRFastPathXmit         dw      0               ; 08 Offset to Tx control area
FPRSRBAddress           dw      0               ; 10 Offset for next SRB addr

ConfigFastPathResponse  ends
;
;***************************************************************\
;                                                               *
; Fast Path Transmit Control Area structure.                    *
;                                                               *
;***************************************************************/
;
FastPathControlArea     struc

FPBufferCount           dw      0               ; 00 Number of buffers
FPFreeQHead             dw      0               ; 02 Offset to first free buffer
FPFreeQTail             dw      0               ; 04 Offset to last free buffer
FPAdapterQTail          dw      0               ; 06 offset to next expected
                                                ;    first buffer of frame.
FPCBufferSize           dw      0               ; 08 Size in bytes of each buffer
                                                ;    including the buffer header
FPCompletionQTail       dw      0               ; 10 Offset to last completed buffer
                        db      4 dup (0)       ; 12 reserved

FastPathControlArea     ends
;
;***************************************************************\
;                                                               *
; Fast Path Transmit Buffer Structure.                          *
;                                                               *
;***************************************************************/
;
FastPathTxBuffer        struc

FPTxCommand             db      0ah             ; 00 Transmit command code.
FPTxCorrelator          db      00h             ; 01 Transmit correlator(0-127)
FPTxRETCODE             db      00h             ; 02 Return Code for this command
                        db      00h             ; 03 reserved
FPTxSTATIONID           dw      0000h           ; 04 ID of station to tx this frame
FPTxFrameLength         dw      0000h           ; 06 Total amount of data in all
                                                ;    the buffers of the frame
FPTxHeaderLength        db      00h             ; 08 Length of the Frame Header
FPTxRSAPValue           db      00h             ; 09 DSAP value
                        dw      0000h           ; 10 reserved
FPTxLastBuffer          dw      0000h           ; 12 Offset in shared RAM to NEXT.BUFFER
                                                ;    field of the last buffer of the frame
FPTxFramePointer        dw      0000h           ; 14 reserved for the adapter
FPTxNextBuffer          dw      0000h           ; 16 Offset to NEXT.BUFFER field in the next
                                                ;    buffer in the free tx buffer queue
FPTxStatus              db      00h             ; 18 reserved for the adapter
FPTxStrippedFS          db      00h             ; 19 Final status returned from
                                                ;    frame stripping process
FPTxBufferLength        dw      0000h           ; 20 Length of the frame data
                                                ;    in this buffer
;FPTxFrameData          db      0 dup (0)       ; 22 The frame data to be transmitted, JCP, 941114.

FastPathTxBuffer        ends

FPTxFrameData           equ     offset FPTxBufferLength + 2     ; JCP, 941114.

;
;***************************************************************\
;                                                               *
; DIR.Open.Adapter SRB Structure.                               *
;                                                               *
;***************************************************************/
;
OpenAdapterStructure    struc

OpenCommandCode         db      SRB_OPEN_ADAPTER        ; 00 Command Code
                        db      00                      ; 01 RESERVED
OpenReturnCode          db      SRB_NOT_PROCESSED       ; 02 Return Code
                        db      05 dup (00)             ; 03 RESERVED
OpenOptions             db      HIGH OPEN_OPTIONS, LOW OPEN_OPTIONS     ; 08 Open Options
OpenNodeAddress         db      06 dup (00)             ; 10 Node Address
OpenGroupAddress        dd      OPEN_GROUP_ADDRESS      ; 16 Group Address
OpenFunctionalAddr      dd      OPEN_FUNCTIONAL_ADDR    ; 20 Functional Address = 00 80 00 00
OpenRxBuffers           db      HIGH OPEN_RX_BUFFERS,LOW OPEN_RX_BUFFERS; 24 Number of Receive  Buffers
OpenRxLength            db      HIGH OPEN_RX_LENGTH,LOW OPEN_RX_LENGTH  ; 26 Length of Receive  Buffers
OpenTxLength            db      HIGH OPEN_TX_LENGTH,LOW OPEN_TX_LENGTH  ; 28 Length of Transmit Buffers
OpenTxBuffers           db      OPEN_TX_BUFFERS         ; 30 Number of Transmit Buffers
                        db      00                      ; 31 RESERVED
OpenMaximumSAPs         db      OPEN_MAX_SAPS           ; 32 Maximum Number of SAPs
OpenMaxLinkStations     db      OPEN_LINK_STATIONS      ; 33 Maximum Number of Link Stations
OpenMaxGroupSAPs        db      OPEN_MAX_GROUP_SAPS     ; 34 Maximum Number of Group SAPs
OpenMaxMembers          db      OPEN_MAX_MEMBERS        ; 35 Maximum Member Per Group SAP
OpenGroupOneT1          db      OPEN_GROUP_ONE_T1       ; 36 DLC Timer T1, Group 01
OpenGroupOneT2          db      OPEN_GROUP_ONE_T2       ; 37 DLC Timer T2, Group 01
OpenGroupOneTi          db      OPEN_GROUP_ONE_TI       ; 38 DLC Timer Ti, Group 01
OpenGroupTwoT1          db      OPEN_GROUP_TWO_T1       ; 39 DLC Timer T1, Group 02
OpenGroupTwoT2          db      OPEN_GROUP_TWO_T2       ; 40 DLC Timer T2, Group 02
OpenGroupTwoTi          db      OPEN_GROUP_TWO_TI       ; 41 DLC Timer Ti, Group 02
OpenProductID           db      18 dup (00)             ; 42 Product ID

OpenAdapterStructure    ends
;
;***************************************************************\
;                                                               *
; OpenOptions Bit Values.                                       *
;                                                               *
;***************************************************************/
;
WRAP_INTERFACE_OPTION   equ     0080h   ; Bit 07 - Wrap Interface
DIS_HARD_ERROR_OPTION   equ     0040h   ; Bit 06 - Disable Hard Error
DIS_SOFT_ERROR_OPTION   equ     0020h   ; Bit 05 - Disable Soft Error
PASS_ADAPTER_MAC_OPTION equ     0010h   ; Bit 04 - Pass Adapter MAC Frames
PASS_ATTEN_MAC_OPTION   equ     0008h   ; Bit 03 - Pass Attention MAC Frames
RETURN_OPEN_OPTION      equ     0002h   ; Bit 01 - Return Open Parameters
PASS_BEACON_MAC_OPTION  equ     0001h   ; Bit 00 - Pass Beacon MAC Frames
CONTENDER_OPTION        equ     8000h   ; Bit 15 - Contender
;
;***************************************************************\
;                                                               *
; OpenAdapterStructure Default Equates.                         *
;                                                               *
;***************************************************************/
;
OPEN_FUNCTIONAL_ADDR    equ     00008000h       ; 20 Functional Address = 00 80 00 00
OPEN_GROUP_ADDRESS      equ     00000000h       ; 16 Group Address
OPEN_MAX_MEMBERS        equ     00              ; 35 Maximum Member Per Group SAP
OPEN_MAX_GROUP_SAPS     equ     00              ; 34 Maximum Number of Group SAPs
OPEN_LINK_STATIONS      equ     00              ; 33 Maximum Number of Link Stations
OPEN_MAX_SAPS           equ     01              ; 32 Maximum Number of SAPs
OPEN_RX_BUFFERS         equ     08              ; 24 Number of Receive  Buffers
OPEN_TX_BUFFERS         equ     02              ; 29 Number of Transmit Buffers
OPEN_OPTIONS            equ     DIS_SOFT_ERROR_OPTION * 256     ; 08 Open Options
OPEN_GROUP_ONE_TI       equ     25              ; 38 DLC Timer Ti, Group 01 (  1 -   2 Seconds)
OPEN_GROUP_TWO_TI       equ     125             ; 41 DLC Timer Ti, Group 02 (  5 -  10 Seconds)
OPEN_GROUP_ONE_T1       equ     05              ; 36 DLC Timer T1, Group 01 (200 - 400 Mills)
OPEN_GROUP_TWO_T1       equ     25              ; 39 DLC Timer T1, Group 02 (  1 -   2 Seconds)
OPEN_GROUP_ONE_T2       equ     01              ; 37 DLC Timer T2, Group 01 ( 40 -  80 Mills)
OPEN_GROUP_TWO_T2       equ     10              ; 40 DLC Timer T2, Group 02 (400 - 800 Mills)
OPEN_RX_LENGTH          equ     320             ; 26 Length of Receive  Buffers
OPEN_TX_LENGTH          equ     2048            ; 28 Length of Transmit Buffers
;
;***************************************************************\
;                                                               *
; DIR.Open.Adapter SRB Response Structure.                      *
;                                                               *
;***************************************************************/
;
OpenSRB         struc

OpenSRBCommandCode      db      SRB_OPEN_ADAPTER        ; 00 Command Code (DIR.Open.Adapter)
                        db      00              ; 01 RESERVED
OpenSRBReturnCode       db      00              ; 02 Return Code
                        db      03 dup (00)     ; 03 RESERVED
OpenSRBErrorCode        dw      0000            ; 06 Open Error Code (If OPRret = 07h)
OpenASBAddress          dw      0000            ; 08 Shared RAM ASB Address
OpenSRBAddress          dw      0000            ; 10 Shared RAM SRB Address
OpenARBAddress          dw      0000            ; 12 Shared RAM ARB Address
OpenSSBAddress          dw      0000            ; 14 Shared RAM SSB Address

OpenSRB         ends
;
;***************************************************************\
;                                                               *
; OpenSRBErrorCode Equates.                                     *
;                                                               *
;***************************************************************/
;
OPEN_ERROR_LOBE_TEST    equ     10h             ; 10 Lobe Media Test
OPEN_ERROR_INSERTION    equ     20h             ; 20 Physical Insertion
OPEN_ERROR_ADDRESS      equ     30h             ; 30 Address Verification
OPEN_ERROR_ROLL_CALL    equ     40h             ; 40 Roll Call Poll
OPEN_ERROR_REQUEST      equ     50h             ; 50 Request Parameters

OPEN_ERROR_FUNCTION     equ     01h             ; 01 Function Failure
OPEN_ERROR_SIGNAL_LOSS  equ     02h             ; 02 Signal Loss
OPEN_ERROR_WIRE_FAULT   equ     03h             ; 03 Wire Fault
OPEN_ERROR_FREQUENCY    equ     04h             ; 04 Frequency Error
OPEN_ERROR_TIMEOUT      equ     05h             ; 05 Timeout
OPEN_ERROR_RING         equ     06h             ; 06 Ring Failure
OPEN_ERROR_BEACONING    equ     07h             ; 07 Ring Beaconing
OPEN_ERROR_NODE         equ     08h             ; 08 Duplicate Node Addr
OPEN_ERROR_PARM_REQUEST equ     09h             ; 09 Parameter Request
OPEN_ERROR_REMOVED      equ     0Ah             ; 10 Remove Received
OPEN_ERROR_IMPL_FORCED  equ     0Bh             ; 11 IMPL Force Received
;
;***************************************************************\
;                                                               *
; DLC.Open.SAP SRB Structure.                                   *
;                                                               *
;***************************************************************/
;
DLCOpenSAPSRB   struc

DLCOpenCommandCode      db      SRB_DLC_RESET           ; 00 Command Code
                        db      00                      ; 01 RESERVED
DLCOpenReturnCode       db      SRB_NOT_PROCESSED       ; 02 Return Code
                        db      00                      ; 03 RESERVED
DLCOpenStationID        dw      00                      ; 04 SAP  Station ID
DLCOpenTimerT1          db      DLC_OPEN_TIMER_T1       ; 06 DLC Timer T1, Response    Timer
DLCOpenTimerT2          db      DLC_OPEN_TIMER_T2       ; 07 DLC Timer T2, Acknowledge Timer
DLCOpenTimerTi          db      DLC_OPEN_TIMER_TI       ; 08 DLC Timer Ti, Inactivity  Timer
DLCOpenMaxOut           db      DLC_OPEN_TX_WO_ACK      ; 09 Max Xmits Without A Receive ACK
DLCOpenMaxIn            db      DLC_OPEN_RX_WO_ACK      ; 10 Max Receives Without a Xmit ACK
DLCOpenMaxOutIncr       db      DLC_OPEN_MAX_WINDOW_INC ; 11 Dynamic Window Increment Value
DLCOpenMaxRetryCount    db      DLC_OPEN_MAX_RETRIES    ; 12 Max Retry Count (N2 Value)
                        db      00                      ; 13 Max Number of SAPs for a Group SAP
DLCOpenMaxIField        db      HIGH DLC_OPEN_MAX_IFIELD,LOW DLC_OPEN_MAX_IFIELD
DLCOpenSAP              db      DLC_OPEN_SAP            ; 16 SAP Value To Be Assigned
DLCOpenSAPOptions       db      DLC_OPEN_SAP_OPTIONS    ; 17 SAP Options
DLCOpenStationCount     db      DLC_OPEN_LINK_STATIONS  ; 18 Number of Link Stations to Reserve
                        db      00                      ; 19 Number of Entries in GSAP List
DLCOpenSAPSRB   ends
;
;***************************************************************\
;                                                               *
; DLCOpenSAPOptions Bit Values.                                 *
;                                                               *
;***************************************************************/
;
DLC_OPEN_SAP_MASK       equ     0E0h            ; Priority Mask Field.
DLC_OPEN_SAP_01         equ     020h            ; Priority 01.
DLC_OPEN_SAP_XIDS       equ     08h             ; Bit 3 - XIDs Passed To Appl
DLC_OPEN_SAP_INDIVIDUAL equ     04h             ; Bit 2 - Individual SAP
DLC_OPEN_SAP_GROUP      equ     02h             ; Bit 1 - Group      SAP
DLC_OPEN_SAP_GROUP_SAP  equ     01h             ; Bit 0 - SAP is Member of Group SAP
;
;***************************************************************\
;                                                               *
; DLCOpenSAP Equates.                                           *
;                                                               *
;***************************************************************/
;
DLC_OPEN_LINK_STATIONS  equ     00      ; 18 Number of Link Stations to Reserve
DLC_OPEN_SAP_OPTIONS    equ     DLC_OPEN_SAP_INDIVIDUAL ; 17 SAP Options
DLC_OPEN_SAP            equ     0E0h    ; 16 SAP Value To Be Assigned
DLC_OPEN_TIMER_T1       equ     00      ; 06 DLC Timer T1, Response    Timer
DLC_OPEN_TIMER_T2       equ     00      ; 07 DLC Timer T2, Acknowledge Timer
DLC_OPEN_TIMER_TI       equ     00      ; 08 DLC Timer Ti, Inactivity  Timer
DLC_OPEN_STATION_ID     equ     00      ; 05 Link Station ID
DLC_OPEN_MAX_IFIELD     equ     600     ; 14 Max Receive I-Field Length
DLC_OPEN_MAX_RETRIES    equ     08      ; 12 Max Retry Count (N2 Value)
DLC_OPEN_MAX_WINDOW_INC equ     01      ; 11 Dynamic Window Increment Value
DLC_OPEN_RX_WO_ACK      equ     01      ; 10 MAX Receives Without a Xmit ACK
DLC_OPEN_TX_WO_ACK      equ     02      ; 09 Max Xmits Without A Receive ACK
;
;***************************************************************\
;                                                               *
; Program Option Select Equates.                                *
;                                                               *
;***************************************************************/
;
TOKEN_ID_LO             equ     001h    ; POS Reg 00 ID LOW  Byte; 01 = 16/4; 00 = Adapter/A
TOKEN_ID_HI             equ     0E0h    ; POS Reg 01 ID High Byte; POS Register 01
CARD_ENABLE_BIT         equ     001h    ; POS Reg 02 Card Enable Bit
POS_IO_PORT             equ     0100h   ; Program Option Select I/O Port @
PRIMARY_ADAPTER_BIT     equ     001h    ; POS Reg 03 Pri(0)/Alt(1) Adapter Bit
SLOT_0                  equ     08h     ; Slot 00 Start Value (Bit 3 MUST Be On)
MAXIMUM_SLOTS           equ     0Fh     ; Maximum Slot Number
SLOT_SELECT_REG         equ     96h     ; POS Slot Select Register
;
;***************************************************************\
;                                                               *
; RCB -- Receive Buffer Format For ARB 81h -- Recieve Data.     *
;                                                               *
;***************************************************************/
;
RCB             struc
;JCP, 941114    dw      00 dup (0000)   ; 00 RESERVED (First Buffer Only)

RCBNextBuffer   dw      0000            ; 00 Next Buffer @
                db      00              ; 02 RESERVED
RCBFrameStatus  db      00              ; 03 Receive Frame Status (FS)
RCBBufferLength dw      0000            ; 04 Buffer Length
;RCBFrameData   db      00 dup (00)     ; 06 Frame Data, JCP, 941114.

RCB             ends

RCBFrameData    equ     offset RCBBufferLength + 2      ; JCP, 941114.

;
;***************************************************************\
;                                                               *
; RCBFrameStatus Equates (Last Buffer Only).                    *
;                                                               *
;***************************************************************/
;
RCB_ADDRESS_RECOGNIZED  equ     88h     ; 88 Address Recongnized Indicator
RCB_FRAME_COPIED        equ     44h     ; 44 Frame Copied Indicator
;
;***************************************************************\
;                                                               *
; System Request Block/ System Status Block Structure.          *
;                                                               *
;***************************************************************/
;
SRB     struc

SRBCommand              db      00              ; 00 Command
SRBCMDCorrelate         db      00              ; 01 CMD.Correlate
SRBReturnCode           db      00              ; 02 Return Code
                        db      00              ; 03 Reserved
;SRBStationID           dw      00 dup (0000)   ; 04 Station ID, JCP, 941114
SRBServiceAccessPoint   db      00              ; 04 Service Access Point (SAP) Num
SRBLinkStation          db      00              ; 05 Link Station         (LS)  Num
SRBFunctionalAddress    dd      00000000        ; 06 DIR.Set.Functional.Address Value

SRB     ends

SRBStationID            equ     offset SRBServiceAccessPoint ;JCP, 941114.

SRB_SIZE                equ     28      ;28 Size of SRB in Shared RAM
SSB_SIZE                equ     20      ;28 Size of SSB in Shared RAM
;
;***************************************************************\
;                                                               *
; SRBCommand Equates.                                           *
;                                                               *
;***************************************************************/
;
SRB_DIR_INTERRUPT       equ     00h     ; 00 DIR.Interrupt              **
SRB_DIR_MODIFY_PARMS    equ     01h     ; 01 DIR.Modify.Open.Parms      **
SRB_DIR_RESTORE_PARMS   equ     02h     ; 02 DIR.Restore.Open.Parms     **
SRB_OPEN_ADAPTER        equ     03h     ; 03 DIR.Open.Adapter           **
SRB_CLOSE_ADAPTER       equ     04h     ; 04 DIR.Close.Adapter          **
SRB_DIR_SET_GROUP_ADDR  equ     06h     ; 06 DIR.Set.Group.Address      **
SRB_DIR_SET_FUNC_ADDR   equ     07h     ; 07 DIR.Set.Functional.Address **
SRB_DIR_READ_LOG        equ     08h     ; 08 DIR.Read.Log               **
SRB_SET_BRIDGE          equ     09h     ; 09 Set.Bridge.Parameter       **
SRB_TX_DIR_FRAME        equ     0Ah     ; 0A XMT.DIR.Frame              **
SRB_TX_I_FRAME          equ     0Bh     ; 0B XMT.I.Frame                **
SRB_CONFIGURE_BRIDGE    equ     0Ch     ; 0C DIR.Configure.Bridge.RAM   **
SRB_TX_UI_FRAME         equ     0Dh     ; 0D XMT.UI.Frame               **
SRB_TX_XID_COMMAND      equ     0Eh     ; 0E XMT.XID.Command            **
SRB_TX_XID_RESPONSE     equ     0Fh     ; 0F XMT.XID.Response.Final     **
SRB_TX_XID_NO_RESPONSE  equ     10h     ; 10 XMT.XID.Response.Not.Final **
SRB_TX_TEST_FRAME       equ     11h     ; 11 XMT.TEST.Frame             **
SRB_DLC_RESET           equ     14h     ; 14 DLC.Reset                  **
SRB_DLC_OPEN_SAP        equ     15h     ; 15 DLC.Open.SAP               **
SRB_DLC_CLOSE_SAP       equ     16h     ; 16 DLC.Close.SAP              **
SRB_DLC_REALLOC_SAP     equ     17h     ; 17 DLC.Reallocate.SAP         **
SRB_DLC_OPEN_STATION    equ     19h     ; 19 DLC.Open.Station           **
SRB_DLC_CLOSE_STATION   equ     1Ah     ; 1A DLC.Close.Station          **
SRB_DLC_CONNECT_STATION equ     1Bh     ; 1B DLC.Connect.Station        **
SRB_DLC_MODIFY          equ     1Ch     ; 1C DLC.Modify                 **
SRB_DLC_FLOW_CONTROL    equ     1Dh     ; 1D DLC.Flow.Control           **
SRB_DLC_STATISTICS      equ     1Eh     ; 1E DLC.Statistics             **
SRB_INIT_COMPLETE       equ     80h     ; 80 DIR.Initialize Complete    **
SRB_INVALID             equ     0FFh    ; FF INVALID Command Code       **
;
;***************************************************************\
;                                                               *
; SRBReturnCode Equates.                                        *
;                                                               *
;***************************************************************/
;
SRB_SUCCESSFUL          equ     00h     ; 00 Successful
SRB_INVALID_COMMAND     equ     01h     ; 01 Invalid Command Code
SRB_DUPLICATE_COMMAND   equ     02h     ; 02 Duplicate Command
SRB_ALREADY_OPEN        equ     03h     ; 03 Adapter Already Open
SRB_ADAPTER_NOT_OPEN    equ     04h     ; 04 Adapter Not Open
SRB_NO_PARMS            equ     05h     ; 05 Required Parms Not Provided
SRB_INVALID_OPTIONS     equ     06h     ; 06 Options Invalid Or Incompatible
SRB_COMMAND_CANCELLED   equ     07h     ; 07 Comm Cancelled, Disaster Struck
SRB_UNAUTHORIZED        equ     08h     ; 08 Unauthorized Access Priority
SRB_NOT_INITIALIZED     equ     09h     ; 09 Adapter Not Initialized
SRB_CANCELLED_BY_USER   equ     0Ah     ; 0A Comm Cancelled By User
SRB_CANCELLED_CLOSED    equ     0Bh     ; 0B Comm Cancelled, Adapter Closed
SRB_COMPLETE_CLOSED     equ     0Ch     ; 0C Command Complete, Adapter Closed
SRB_INVALID_BRIDGE      equ     0Dh     ; 0D Invalid Bridge Parms, Parm Not Set
SRB_INVALID_RAM_SEG     equ     14h     ; 14 Invalid Shared RAM Segment
SRB_NO_BUFFERS          equ     20h     ; 20 Lost Data, No Buffers
SRB_NOT_ENOUGH_BUFFERS  equ     21h     ; 21 Lost Data, Not Enough Buffers
SRB_TX_ERROR            equ     22h     ; 22 Error On Frame Xmit - Check PCFe
SRB_FRAME_ERROR         equ     23h     ; 23 Frame Or Strip Error
SRB_MAC_ERROR           equ     24h     ; 24 Unauthorized Mac Frame
SRB_TOO_MANY_COMMANDS   equ     25h     ; 25 Maximum Commands Exceeded
SRB_BAD_CORRELATOR      equ     26h     ; 26 Unrecognized Command Correlator
SRB_LINK_NOT_TXING      equ     27h     ; 27 Link No Longer Transmitting
SRB_BAD_FRAME_LENGTH    equ     28h     ; 28 Invalid Transmit Frame Length
SRB_BAD_BRIDGE_PARM     equ     2Dh     ; 2D Bridge Parameters Not Set
SRB_RX_BUFFER_NOT_OPEN  equ     30h     ; 30 Inadequate RCV Buffers For Open
SRB_INVALID_NODE        equ     32h     ; 32 Invalid Node Address
SRB_INVALID_RX_LENGTH   equ     33h     ; 33 Invalid Receive Buffer Length
SRB_INVALID_TX_LENGTH   equ     34h     ; 34 Invalid Transmit Buffer Length
SRB_INVALID_STATION_ID  equ     40h     ; 40 Invalid Station ID
SRB_PROTOCOL_ERROR      equ     41h     ; 41 Protocol Error - Link Not Xmitting
SRB_PARM_MAXED_OUT      equ     42h     ; 42 Parameter Exceeded Maximum Allowed
SRB_INVALID_SAP         equ     43h     ; 43 Invalid SAP.Val
SRB_BAD_HEADER_LENGTH   equ     44h     ; 44 Invalid Header Length
SRB_GROUP_IN_BAD_SAP    equ     45h     ; 45 Group Member In Bad SAP
SRB_NO_RESOURCES        equ     46h     ; 46 Resources Not Available
SRB_SAP_LINK_OPENED     equ     47h     ; 47 SAP Has Link Stations Opened
SRB_CANNOT_CLOSE_GROUP  equ     48h     ; 48 Group SAP Cannot Close
SRB_GROUP_MAX_MEMBERS   equ     49h     ; 49 Group SAP Reached Max Members
SRB_SEQ_ERROR_CLOSED    equ     4Ah     ; 4A Seq Error - DLC Close In Process
SRB_CLOSED              equ     4Bh     ; 4B Closed W/O Remote Ack
SRB_SEQ_ERROR           equ     4Ch     ; 4C Seq Error - Outstanding Comms
SRB_BAD_LS_CONNECTION   equ     4Dh     ; 4D Unsuccessful LS Connection
SRB_MEMBER_NOT_IN_GROUP equ     4Eh     ; 4E Member SAP Not In Group SAP List
SRB_BAD_REMOTE_ADDR     equ     4Fh     ; 4F Invalid Remote Address
SRB_NOT_PROCESSED       equ     0FEh    ; FE Command NOT Processed
SRB_IN_PROCESS          equ     0FFh    ; FF Command In Process
;
;***************************************************************\
;                                                               *
; Source Routing Driver Send Control EQUates; ESI = 0000 0000.  *
;                                                               *
;***************************************************************/
;
ROUTING_LOAD            equ     00                      ; AL = 00 ==> EBX = Board Number to LOAD
ROUTING_UNLOAD          equ     ROUTING_LOAD+01         ; AL = 01 ==> EBX = Board Number to UNLOAD
ROUTING_CLEAR           equ     ROUTING_UNLOAD+01       ; AL = 02 ==> EBX = Board Number to CLEAR
ROUTING_DEFAULT_BROAD   equ     ROUTING_CLEAR+01        ; AL = 03 ==> AH = DEFault   Broadcast Route
ROUTING_GENERAL_BROAD   equ     ROUTING_DEFAULT_BROAD+01; AL = 04 ==> AH = GENERAL   Broadcast Route
ROUTING_MULTICAST       equ     ROUTING_GENERAL_BROAD+01; AL = 05 ==> AH = MULTICAST Broadcast Route
ROUTING_RESPONSE        equ     ROUTING_MULTICAST+01    ; AL = 06 ==> AH = Broadcasted Response Type
ROUTING_TIMEOUT         equ     ROUTING_RESPONSE+01     ; AL = 07 ==> AH = Last Rcv Time Timeout
ROUTING_REMOVE_NODE     equ     ROUTING_TIMEOUT+01      ; AL = 08 ==> EDI = Address of NODE to REMOVE
ROUTING_MAX_REQUEST     equ     ROUTING_REMOVE_NODE+01  ; AL = Maximum Request Code
;
;***************************************************************\
;                                                               *
; Token-Ring Interrupt Level Equates.                           *
;                                                               *
;***************************************************************/
;
ADAPTER_IRQ_2           equ     00      ; 00 = IRQ 02
ADAPTER_IRQ_3           equ     01      ; 01 = IRQ 03
ADAPTER_IRQ_6           equ     02      ; 02 = IRQ 06 (PC Bus) IRQ 10 (Microchannel)
ADAPTER_IRQ_7           equ     03      ; 03 = IRQ 07 (PC Bus) IRQ 11 (Microchannel)
ADAPTER_IRQ_MASK        equ     03      ;      IRQ Mask For IN  AL,A20h Read
;
;***************************************************************\
;                                                               *
; Token-Ring PIO Register Equates.                              *
;                                                               *
;***************************************************************/
;
PRIMARY_PIO             equ     0A20h   ; A24 BIOS/MMIO Switches  IGNORED
SECONDARY_PIO           equ     0A24h   ; A20 BIOS/MMIO Switches  IGNORED
RESET_IRQ_PORT          equ     02F0h   ; 2Fn IGNORED            Reset IRQ (Shared)

MMIOPortStructure       struc
ReadMMIO                db      00      ; 00 Read BIOS/MMIO Switches PIO Offset
AdapterReset            db      00      ; 01 Adapter Reset           PIO Offset
ReleaseAdapterReset     db      00      ; 02 Release Adapter Reset   PIO Offset
ResetIRQ                db      00      ; 03 Reset IRQ (Hog)         PIO Offset
MMIOPortStructure       ends
;
;***********************************************************************\
;                                                                       *
; MicroChannelSignature -- Token-Ring Signature for Micro Channel       *
;                       -- MARS63X4518                                  *
;                          Located At 1F30 Offset Into The MMIO Segment *
;                                                                       *
;***********************************************************************/
;
MicroChannelSignature   struc   ;   Token-Ring Signature for Micro Channel
          db    'M'/16,'M'-'M'/16*16
          db    'A'/16,'A'-'A'/16*16
          db    'R'/16,'R'-'R'/16*16
          db    'S'/16,'S'-'S'/16*16
          db    '6'/16,'6'-'6'/16*16
          db    '3'/16,'3'-'3'/16*16
          db    'X'/16,'X'-'X'/16*16
          db    '4'/16,'4'-'4'/16*16
          db    '5'/16,'5'-'5'/16*16
          db    '1'/16,'1'-'1'/16*16
          db    '8'/16,'8'-'8'/16*16
MicroChannelSignature   ends    ;   Token-Ring Signature for Micro Channel
;
;***********************************************************************\
;                                                                       *
; PCSignature   -- Token-Ring Signature for PC Bus                      *
;               -- PICO6110990                                          *
;               Located At 1F30 Offset Into The MMIO Segment            *
;                                                                       *
;***********************************************************************/
;
PCSignature     struc           ;   Token-Ring Signature for PC Bus
          db    'P'/16,'P'-'P'/16*16
          db    'I'/16,'I'-'I'/16*16
          db    'C'/16,'C'-'C'/16*16
          db    'O'/16,'O'-'O'/16*16
          db    '6'/16,'6'-'6'/16*16
          db    '1'/16,'1'-'1'/16*16
          db    '1'/16,'1'-'1'/16*16
          db    '0'/16,'0'-'0'/16*16
          db    '9'/16,'9'-'9'/16*16
          db    '9'/16,'9'-'9'/16*16
          db    '0'/16,'0'-'0'/16*16
PCSignature     ends            ;   Token-Ring Signature for PC Bus
;
;***************************************************************\
;                                                               *
; TransmitBufferStructure -- Token-Ring Transmit Buffer Format. *
;                                                               *
;***************************************************************/
;
TransmitBufferStructure struc
TxAccessControl         db      00              ; 00 Physical Control Field 00
TxFrameControl          db      FC_NON_MAC_FRAME ; 01 Physical Control Field 01
TxDestNodeAddress       db      06 dup (00)     ; 02 Destination Address
TxSourceNodeAddress     db      06 dup (00)     ; 08 Source Node Address
;TxRoutingInfo          db      00 dup (00)     ; 14 Routing Information (Optional)
TxDSAP                  db      DEFAULT_TX_DSAP ; 14 Destination SAP
TxSSAP                  db      DEFAULT_TX_SSAP ; 15 Source      SAP
TxControlByte           db      DEFAULT_TX_CTRL ; 16 Control Byte 01 (UI Frame)
;TxData                 db      00 dup (00)     ; 17 Frame Data Field, JCP 941114.
TransmitBufferStructure ends
                                                ; JCP, 941114 *Begin*
TxData                  equ     offset TxControlByte + 1
TxRoutingInfo           equ     offset TxDSAP
                                                ; JCP, 941114 *End*
;
;***************************************************************\
;                                                               *
; TxDSAP, SSAP, ControlByte DLC Control Field Equates.          *
;                                                               *
;***************************************************************/
;
TX_8022_SNAP            equ     03AAAAh         ;    IP Standard DLC Header Dest, Source SAP
TX_SNAP_HEADER_SIZE     equ     08              ;    IP Standard Header Size
TX_MAC_FRAME_PID        equ     0FFFFFFh        ;    MAC Frame Protocol ID
DEFAULT_TX_DSAP         equ     DLC_OPEN_SAP    ; E0 Destination SAP
DEFAULT_TX_SSAP         equ     DEFAULT_TX_DSAP ; E0 Source      SAP
DEFAULT_TX_CTRL         equ     03h             ; 03 Control Byte 03 (UI Frame)
;
;***************************************************************\
;                                                               *
; TxAccessControl Equates.                                      *
;                                                               *
;***************************************************************/
;
AC_PRIORITY_MASK        equ     0E0h    ; AC E0 Priority Indicator Mask
AC_BUSY_FRAME           equ     10h     ; AC 10 1==> Busy Frame
AC_ACTIVE_MONITOR       equ     08h     ; AC 08 1==> Active Monitor
AC_RESERVATION_MASK     equ     07h     ; AC 07 Priority Res Mask
;
;***************************************************************\
;                                                               *
; TxFrameControl Equates.                                       *
;                                                               *
;***************************************************************/
;
FC_MAC_FRAME            equ     80h     ; FC 80 1==> Not Frame Format 1
FC_NON_MAC_FRAME        equ     40h     ; FC 40 1==> Non-MAC Frame
FC_RING_POLL_RESPONSE   equ     06h     ; FC 06 Ring Poll Response
FC_RING_POLL_REQUEST    equ     05h     ; FC 05 Ring Poll Request
FC_RING_PURGE           equ     04h     ; FC 04 Ring Purge
FC_MONITOR_CONTENTION   equ     03h     ; FC 03 Monitor Contention
FC_BEACON               equ     02h     ; FC 02 Beacon
FC_EXPRESS_MAC          equ     01h     ; FC 01 Xpress MAC
FC_DEFAULT_MAC_PID      equ     0FFh    ;       Default Protocol ID For MAC Frames
FC_MAC_FIELD_MASK       equ     0Fh     ; FC 0F MAC Field Mask
;
;***************************************************************\
;                                                               *
; TxRoutingInfo -- 14 Routing Information Field EQUates.        *
;                                                               *
;***************************************************************/
;
SOURCE_DIRECTION_IND    equ     80h     ;    Direction Indicator (TxRoutingInfo+01)
SOURCE_ROUTING_BIT      equ     80h     ; 80 TxSourceNodeAddress Bit for Routing Field
SOURCE_GENERAL_BROAD    equ     080h    ; 80 General Broadcast  Mask
SOURCE_LIMITED_BROAD    equ     0C0h    ; C0 Limited Broadcast  Mask
SOURCE_LARGEST_FRAME    equ     70h     ; 70 Largest Frame Size Maks
SOURCE_MAX_SIZE         equ     18      ;    Max Routing Info Size
SOURCE_SIZE_MASK        equ     1Fh     ;    Routing Size Mask
;
;***************************************************************\
;                                                               *
; MediaID eqautes.                                              *
;                                                               *
;***************************************************************/
;
TokenMediaID8022        equ     04      ; 802.2 Media ID.
TokenMediaIDSNAP        equ     11      ; SNAP On 802.2 Media ID.
RAMPageRange0           equ     8196/16 ; 110 Memory    00 Range
;RAMPageRange0          equ     (65536/4096) * 256      ; 110 Memory    00 Range
RAMPageRange1           equ     8196/16 ; 116 Memory    01 Range
;
;***************************************************************\
;                                                               *
; Configuration Table equates.                                  *
;                                                               *
;***************************************************************/
;
TOKEN_MODE_FLAGS        equ     RealDriverBit+DriverSupportsMulticastBit+DriverSupportsRawModeBit

ifdef BROUTER
;
;***************************************************************\
;                                                               *
; Brouter status bits.                                          *
;                                                               *
;***************************************************************/
;
TWO_WAY_SR              equ     00000000000000010000000000000000b
THREE_WAY_SR            equ     00000000000000100000000000000000b
STE_FILTER              equ     00000000001000000000000000000000b
VARIABLE_BR_NUM         equ     00000000010000000000000000000000b
SR_SUPPORT              equ     00000000100000000000000000000000b
TRANS_DA_AND_SA_SUPPORT equ     10010000000000000000000000000000b
TRANS_DA_SUPPORT        equ     10100000000000000000000000000000b
SR_AND_TRANS_SUPPORT    equ     11000000000000000000000000000000b
TRANS_SUPPORT           equ     10000000000000000000000000000000b

BROUTER_STATUS          equ     SR_SUPPORT OR VARIABLE_BR_NUM OR TWO_WAY_SR
;
;***************************************************************\
;                                                               *
; Bridge SRB Response structure.                                *
;                                                               *
;***************************************************************/
;
BridgeSRB       struc

BSRBCommand             db      0ch             ; SRB command.
                        db      0               ; Reserved.
BSRBReturnCode          db      0               ; Return code.
                        db      5 dup (0)       ; Reserved.
BSRBTxOffset            dw      0               ; Offset to bridge Tx control.
BSRBSRBAddress          dw      0               ; Offset to new SRB.

BridgeSRB       ends
;
;***************************************************************\
;                                                               *
; Bridge Transmit Control Area                                  *
;                                                               *
;***************************************************************/
;
BridgeTCA       struc

                        db      2 dup (0)       ; Reserved.
BTCAInputCount          db      0               ; Buffers in use by PC.
BTCAOutputCount         db      0               ; Buffers Tx'd by adapter.
BTCAReturnCount         db      0               ; Buffers returned to PC.
                        db      0               ; Reserved.
BTCAMaxBuffers          dw      0               ; Total bridge Tx Buffers.
BTCANextBuffer          dw      0               ; Next Available Buffer.
BTCAOldBuffer           dw      0               ; Next Buffer to transmit.
                        db      4 dup (0)       ; Reserved.

BridgeTCA       ends
;
;***************************************************************\
;                                                               *
; Bridge Transmit Buffer.                                       *
;                                                               *
;***************************************************************/
;
BridgeTransmitBuffer    struc

;BTBLastBuffer          dw      0 dup (0)       ; Address of Last Buffer + 2. JCP, 941114.
BTBFrameLength          dw      0               ; Length of frame.
BTBBufferPointer        dw      0               ; Offset to next buffer.
BTBXmitControl          db      0               ; Control bits.
BTBStripFS              db      0               ; Reserved(FS byte on complete).
BTBBufferLength         dw      0               ; Length of data in this buffer.
                                                ; JCP, 941114 *Begin*
;BTBFrameData           db      0 dup (0)       ; Frame Data.
;BTBNumberBuffers       db      0 dup (0)       ; Number of buffers in frame.

BridgeTransmitBuffer    ends

BTBLastBuffer           equ     offset BTBFrameLength
BTBFrameData            equ     offset BTBBufferLength + 2
BTBNumberBuffers        equ     offset BTBBufferLength + 2
                                                ; JCP, 941114 *End*
endif

        subttl  Driver Adapter Data Space
        page
;
;***********************************************************************\
;                                                                       *
; Start of the Driver Virtual Adapter structure for Token-Ring.         *
;                                                                       *
;***********************************************************************/
;
                                                                ;JCP
GenericVariableBegin    equ     offset TotalTxPacketCount       ;941114 *Begin*
GenericVariableEnd      equ     offset CustomVariableCount
CustomVariableBegin     equ     offset BadCorrelatorCount
CustomVariableEnd       equ     offset VectorToTheStrings       ;941114 *End*

DriverAdapterDataSpace  struc

ARBSaveArea             db      ARB_SIZE dup (00)       ; ARB Save Area For ASB Response Codes.
TCBInProcess            dd      00000000        ; TCB in Process.
MLIDStatusFlag          db      00              ; Token-Ring Card State Flag.
InterruptResetLevel     dd      00000000        ; Interrupt Reset Register.
BoardNumber             dd      00000000        ; Token Ring Number: 0 = PRImary; 1 = ALTernate.
AbsoluteMMIOAddress     dd      00000000        ; BIOS/MMIO Domain Absolute Address.
PageSize                dd      4000h           ; Default to 16K.
PagingMask              db      0C0h            ; Used for Tx overflow test.
PageSizeMask            db      0FFh            ; Page Size Mask.
InitRetryCounter        db      00              ; DIR.Init/DIR.Open.Adapter Re-Try Counter.
SendQueueHead           dd      00000000        ; Driver Send Queue Head.
SendQueueTail           dd      00000000        ; Driver Send Queue Tail.
TxStartTime             dd      00000000        ; Used to detect timeouts.
TxInProcessHead         dd      00000000        ; Xmit In Process Queue Head.
FunctionalAddress       dd      00000000        ; Current functional address.
FirstRxBuffer           dd      00000000        ; Save First Rx Buffer
CurrentECB              dd      00000000        ; Save current Rx ECB.
RCBFragments            dd      00000000        ; Fragments for current RCB.
RCBSize                 dd      00000000        ; Size of current fragment.
RxBufferSize            dd      00000000        ; Size of current Rx Buffer.
LastErrorMessage        dd      00000000        ; Kept to stop repeating message.
CheckAlertTimer         dd      00000000        ; Check alert after open flag.
InitStatus              db      00              ; DIRInitStatus value.
TxCorrelator            db      00              ; Fast Path Correlator
CompletionQHead         dd      00000000        ; Adapter Completion Q Head.
TxBuffersUsed           db      00              ; Bridge mode variable
TotalBytes              dd      00000000        ; Total Rx bytes.
SizeMessage             dd      Size16KMessage  ; Pointer to size message.
SendMessage             dd      00000000        ; Pointer to Send type message.
InDriverReset           dd      00000000
OpeningAdapter          dd      0
DriverSendPointer       dd      0
;
;***************************************************************\
;                                                               *
; InterruptVectorTable --       Interrupt Vector Table.         *
;                               ORDER MUST NOT CHANGE!          *
;                                                               *
;***************************************************************/
;
StartOfInterruptVectorTable     dd      0               ; JCP, 941114
;InterruptVectorTable           dd      0 dup (?)       ; JCP, 941114
                dd      AdapterErrorISR                 ; Machine Check or Timeout.
                dw      ADAPTER_ERROR_BIT               ; Adapter Status Bit.
                dw      0ffffh                          ; No Page Value.
                dd      OFFSET AdapterCheckMessage      ; Alert Message.

                dd      AdapterCheckISR                 ; Adapter Check.
                dw      ADAPTER_CHECK_BIT SHL 8         ; Adapter Status Bit.
                dw      0ffffh                          ; No Page Value.
                dd      OFFSET AdapterCheckMessage      ; Alert Message.

                dd      InvalidASBISR                   ; Invalid ASB Routine.
                dw      ASB_FREE_BIT SHL 8              ; Adapter Status Bit.
                db      00                              ; Page Provided.
ASBPageValue    db      00                              ; ASB Page Register.
ASBBaseAddress  dd      00000000                        ; ASB Base Address.

                dd      SRBResponseISR                  ; SRB Response Routine.
                dw      SRB_RESPONSE_BIT SHL 8          ; Adapter Status Bit.
                db      00                              ; Page Provided.
SRBPageValue    db      00                              ; SRB Page Register.
SRBBaseAddress  dd      00000000                        ; SRB Base Address.

                dd      FastTxComplete                  ; Fast Send Complete
                dw      BRIDGE_FORWARD_BIT SHL 8        ; Bridge forward bit.
                db      00                              ; Page Provided.
TxPageValue     db      0                               ; Fast Path Page.
TxBaseAddress   dd      0                               ; Fast Path Tx Buffer.

                dd      ARBRequestISR                   ; ARB Request Routine.
                dw      ARB_COMMAND_BIT SHL 8           ; Adapter Status Bit.
                db      00                              ; Page Provided.
ARBPageValue    db      00                              ; ARB Page Register.
ARBBaseAddress  dd      00000000                        ; ARB Base Address.

                dd      SSBResponseISR                  ; SSB Response Routine.
                dw      SSB_RESPONSE_BIT SHL 8          ; Adapter Status Bit.
                db      00                              ; Page Provided.
SSBPageValue    db      00                              ; SSB Page Register.
SSBBaseAddress  dd      00000000                        ; SSB Base Address.


                dd      ARBReturn                       ; End Of Table.
                dw      0FFFFh                          ; Any Status Bit.
                db      00
                db      00
                dd      00000000

AdapterParmsPageValue   db      00
AdapterParmsAddr        dd      00000000
                                                        ; JCP.
MicrocodeLevelPageValue db      00                      ; 941019 *Begin*
MicrocodeLevelAddr      dd      00000000                ;
AdapterMicroCodeLevel   db      5 dup(0)                ;
MicroCodeLevel          db      7, 8, 0, 6, 4           ;
                        db      2, 4, 5, 5, 0           ; 941019 *End*

TxLastBuffer    dd      0                       ; Fast Path Last Buffer.
TxBufferSpace   dd      0                       ; Fast Path Buffer Space.
TxCurrentBuffer dd      0                       ; Fast Path current buffer.
TxCurrentTCB    dd      0                       ; Fast Path TCB.
TxFragmentCount dd      0                       ; Fast Path Fragments.

BrouterState    dd      0                       ; if BROUTER
BConfigCommand  db      0ch                     ; DIR.CONFIG.BRIDGE.RAM
                db      0                       ; Reserved.
                db      0                       ; Return code.
                db      5 dup (0)               ; Reserved.
;;              db      HIGH ((4202*4)+14+7)/8  ; BTX size(upper).
;;              db      LOW ((4202*4)+14+7)/8   ; BTX size(lower).
                db      HIGH ((4202*5)+14+7)/8  ; BTX size(upper).      ;;
                db      LOW ((4202*5)+14+7)/8   ; BTX size(lower).      ;;

BParmsCommand   db      09h                     ; DIR.SET.BRIDGE.PARMS
                db      0                       ; Reserved.
                db      0                       ; Return code.
                db      3 dup (0)               ; Reserved.
BParmsSRing     dw      0                       ; Source Ring Number.
BParmsTRing     dw      0                       ; Target Ring Number.
BParmsBNumber   dw      0                       ; Individual Bridge Number.
BParmsPBits     db      0                       ; Number of Partition bits.
BParmsCopySTE   db      1                       ; Discard single-route broad.
                db      4                       ; Max Access Priority.
;
;***************************************************************\
;                                                               *
; DIROpenAdapter -- DIR.Open.Adapter SRB Image.                 *
;                                                               *
;***************************************************************/
;

StartOfDIROpenAdapter   db      0                       ; JCP, 941114.
;DIROpenAdapter         db      0 dup (0)               ; JCP, 941114.
        db      SRB_OPEN_ADAPTER                        ; 00 Command Code (03)
        db      00                                      ; 01 RESERVED (00)
        db      SRB_NOT_PROCESSED                       ; 02 Return Code (0FEh)
        db      05 dup (00)                             ; 03 RESERVED (00 00 00 00 00)
        db      HIGH OpenOptions, LOW OpenOptions       ; 08 Open Options (2000h)
        db      06 dup (00)                             ; 10 Node Address (00 00 00 00 00 00)
        dd      OPEN_GROUP_ADDRESS                      ; 16 Group Address (0000 0000)
        dd      OPEN_FUNCTIONAL_ADDR                    ; 20 Functional Address (0000 8000)
        db      HIGH OPEN_RX_BUFFERS, LOW OPEN_RX_BUFFERS       ; 24 Number of Receive  Buffers (0008)
        db      HIGH OPEN_RX_LENGTH, LOW OPEN_RX_LENGTH         ; 26 Length of Receive  Buffers (0320)
        db      00, 00                                  ; 28 Length of Transmit Buffers (0000)
        db      OPEN_TX_BUFFERS                         ; 30 Number of Transmit Buffers (02)
        db      00                                      ; 31 RESEVED (00)
        db      OPEN_MAX_SAPS                           ; 32 Maximum Number of SAPs (01)
        db      0                                       ; 33 Maximum Number of Link Stations
        db      0                                       ; 34 Maximum Number of Group SAPs
        db      0                                       ; 35 Maximum Member Per Group SAP
        db      0                                       ; 36 DLC Timer T1, Group 01
        db      0                                       ; 37 DLC Timer T2, Group 01
        db      0                                       ; 38 DLC Timer Ti, Group 01
        db      0                                       ; 39 DLC Timer T1, Group 02
        db      0                                       ; 40 DLC Timer T2, Group 02
        db      0                                       ; 41 DLC Timer Ti, Group 02
        db      18 dup (00)                             ; 42 Product ID

ConfigFastPath  db      12h                     ; 00 Command
                db      00h                     ; 01 reserved
                db      00h                     ; 02 Set by adapter on return
                db      5 dup (0)               ; 03 reserved
ConfigRAMSize   dw      0                       ; 08 RAM size to allocate
                db      02h, 00h                ; 10 Size of Tx buffers(512)
;
;***************************************************************\
;                                                               *
; Common configuration table values needed during send and      *
; interrupt processing.                                         *
;                                                               *
;***************************************************************/
;
CommonNodeAddress       db      6 dup (0)       ; Adapter Node Address.
CommonMemoryDecode0     dd      0               ; Shared RAM Absolute Address.
CommonLinearMemory0     dd      0               ; Logical Shared RAM.
CommonIOPort            dw      0               ; Adapter Base I/O port.
CommonMaximumSize       dd      0               ; Maximum Packet Size.
CommonLineSpeed         dw      4               ; Default to 4 MBps.
SharedRAMRelative       dd      0               ; Shared RAM Relative Address.
;
;***********************************************************************\
;                                                                       *
;       Error Counters.                                                 *
;                                                                       *
;***********************************************************************/
;
StatisticsVersion       db      03, 00
GenericVariableCount    dw      (GenericVariableEnd-GenericVariableBegin)/4
NotSupportedMask0       dd      00001011111110000000000000000000b

;GenericVariableBegin           db      0 dup (?)       ; JCP, 941114
        TotalTxPacketCount      dd      0               ; 0 - Used by MSM
        TotalRxPacketCount      dd      0               ; 0 - Used by MSM
        NoECBAvailableCount     dd      0               ; 0 - Used by MSM
        PacketTxTooBigCount     dd      0               ; 0 - Used by MSM
        PacketTxTooSmallCount   dd      0               ; 1 - Not used
        PacketRxOverflowCount   dd      0               ; 0 - used by driver
        PacketRxTooBigCount     dd      0               ; 1 - Not used
        PacketRxTooSmallCount   dd      0               ; 1 - Not used
        PacketTxMiscErrorCount  dd      0               ; 1 - Not used
        PacketRxMiscErrorCount  dd      0               ; 1 - Not used
        RetryTxCount            dd      0               ; 1 - Not used
        ChecksumErrorCount      dd      0               ; 1 - Not used
        HardwareRxMismatchCount dd      0               ; 1 - Not used
        TotalTxOKByteCountLow   dd      0               ; 0 - Used by MSM
        TotalTxOKByteCountHigh  dd      0               ; 0 - Used by MSM
        TotalRxOKByteCountLow   dd      0               ; 0 - Used by MSM

        TotalRxOKByteCountHigh  dd      0               ; 0 - Used by MSM
        TotalGroupAddrTxCount   dd      0               ; 0 - Used by MSM
        TotalGroupAddrRxCount   dd      0               ; 0 - Used by MSM
        AdapterResetCount       dd      0               ; 0 - Used by driver
        AdapterOprTimeStamp     dd      0               ; 0 - Used by MSM
        QDepth                  dd      0               ; 0 - Used by MSM

        ACErrorCount            dd      0               ; 0 - Used by driver
        AbortDelimiterCount     dd      0               ; 0 - Used by driver
        BurstErrorCount         dd      0               ; 0 - Used by driver
        FrameCopiedErrorCount   dd      0               ; 0 - Used by driver
        FrequencyErrorCount     dd      0               ; 0 - Used by driver
        InternalErrorCount      dd      0               ; 0 - Used by driver
        LastRingStatus          dd      0               ; 0 - Used by driver
        LineErrorCount          dd      0               ; 0 - Used by driver
        LostFrameCount          dd      0               ; 0 - Used by driver
        TokenErrorCount         dd      0               ; 0 - Used by driver

        NotSupportedMask1       dd      00001111111111111111111111111111b

        UpstreamNodeHighDword   dd      0               ; 0 - Used by driver
        UpstreamNodeLowWord     dd      0               ; 0 - Used by driver
        LastRingID              dd      0               ; 0 - Used by driver
        LastBeaconType          dd      0               ; 0 - Used by driver
;GenericVariableEnd             db      0 dup (?)       ; JCP, 941114

CustomVariableCount             dw      (CustomVariableEnd - CustomVariableBegin) / 4

;CustomVariableBegin             db      0 dup (?) ; JCP, 941114.
        BadCorrelatorCount      dd      0          ; Bad Correlator
        UnknownARBCount         dd      0          ; Unknown ARB Request
        QDepthEqualTwo          dd      0
        DriverSendCount         dd      0
        CardIsDead              dd      0
        TxFreeCountZero         dd      0
        TxFreeCountZeroAndReset dd      0
;CustomVariableEnd               db      0 dup (?) ; JCP, 941114.

VectorToTheStrings      dd      OFFSET DiagnosticsStrings

AlignDEndVA             db      (4 - OFFSET (AlignDEndVA and 3)) and 3 dup (0)  ; Align 4 for MOVSD

DriverAdapterDataSpace  ends
                                                ;JCP, 941114. *Begin*
InterruptVectorTable    equ     offset StartOfInterruptVectorTable + 4
DIROpenAdapter          equ     offset StartOfDIROpenAdapter + 1
                                                ;JCP, 941114. *End*
        subttl  OSDATA Variables
        page
;
;***********************************************************************\
;                                                                       *
;       <<<<< End of the driver data area structure  >>>>>              *
;                                                                       *
;       The following variables are common to all virtual adapters      *
;       and all virtual boards.                                         *
;                                                                       *
;***********************************************************************/
;
        assume  cs: OSCODE, ds: OSDATA, es: OSDATA, ss: OSDATA

OSDATA  segment rw public 'DATA'

HSMSPEC                 db      'HSM_SPEC_VERSION: 3.31',0
;
;***********************************************************************\
;                                                                       *
; Statistic Diagnostic Strings.                                         *
;                                                                       *
;***********************************************************************/
;
DiagnosticsStrings      dw      (EndOfStrings-DiagnosticsStrings)

BadCorrelatorMessage            db      'Bad Correlator Count', 00
UnknownARBMessage               db      'Unknown ARB Requests', 00
QDepthAndDriverResetMessage     db      'Tx Queue Depth greater than zero.',00
DriverSendCountMessage          db      'Clean up TxQueue after DriverReset', 00
CardIsDeadMsg                   db      'Network Card requires reset', 00
TxFreeCountMsg                  db      'Waiting for the adapter to respond',00
TxFreeCountResetMsg             db      'Adapter is not responding, Reset adapter',00
                                db      0,0
EndOfStrings    equ     $
;
;***************************************************************\
;                                                               *
; Driver Parameter Block to pass to MSM.                        *
;                                                               *
;***************************************************************/
;
        align   4
DriverParameterBlock            label   dword
DriverParameterSize             dd      DriverParameterBlockSize
DriverStackPointer              dd      0
DriverModuleHandle              dd      0
DriverBoardPointer              dd      0
DriverAdapterPointer            dd      0
DriverConfigTemplatePtr         dd      DriverConfigTemplate
DriverFirmwareSize              dd      0
DriverFirmwareBuffer            dd      0
DriverNumKeywords       dd      (TokenKeywordTextLen-TokenKeywordText) / 4
DriverKeywordText               dd      TokenKeywordText
DriverKeywordTextLen            dd      TokenKeywordTextLen
DriverProcessKeywordTab         dd      TokenProcessKeywordTab
DriverAdapterDataSpaceSize      dd      SIZE DriverAdapterDataSpace
DriverAdapterTemplate           dd      DriverAdapterDataSpaceTemplate
DriverStatisticsTable           dd      StatisticsVersion
DriverEndOfChainFlag            dd      0
DriverSendWantsECBs             dd      0
DriverMaxMulticast              dd      20
DriverNeedsBelow16Meg           dd      0
DriverAESPtr                    dd      offset DriverCallBack
DriverCallBackPtr               dd      0
DriverISRPtr                    dd      offset DriverISR
DriverMulticastChangePtr        dd      offset DriverMulticastChange
DriverPollPtr                   dd      0
DriverResetPtr                  dd      offset DriverReset
DriverSendPtr                   dd      offset DriverSend
DriverShutdownPtr               dd      offset DriverShutdown
DriverTxTimeoutPtr              dd      0
DriverPromiscuousChangePtr      dd      0
DriverStatisticsChangePtr       dd      0
DriverRxLookAheadChangePtr      dd      0
ifdef BROUTER
DriverManagementPtr             dd      offset DriverManagement
else
DriverManagementPtr             dd      0
endif
DriverEnableInterruptPtr        dd      offset DriverEnableInterrupt
DriverDisableInterruptPtr       dd      offset DriverDisableInterrupt
DriverISR2Ptr         dd   0
DriverReserved2         dd   0
HSMSpecVerString      dd   offset HSMSPEC
DriverpriorityQueuePtr      dd   0
DriverDisableInterrupt2Ptr   dd   0
DriverParameterBlockSize        equ     $ - DriverParameterBlock
;
;***********************************************************************\
;                                                                       *
; Copy of Virtual Adapter Data area to be copied at initialization.     *
;                                                                       *
;***********************************************************************/

DriverAdapterDataSpaceTemplate  DriverAdapterDataSpace  <>

;DriverConfigTemplate    db      0 dup (?)      ; JCP, 941114
DriverConfigTemplate     label   byte           ; JCP, 941114
        db      'HardwareDriverMLID        '    ; [ebx].MLIDCFG_Signature
        db      01                              ; [ebx].MLIDCFG_MajorVersion
        db      14                              ; [ebx].MLIDCFG_MinorVersion
        db      6 dup (0ffh)                    ; [ebx].MLIDNodeAddress
        dw      0000010001001001b               ; [ebx].MLIDModeFlags
        dw      0000                            ; [ebx].MLIDBoardNumber
        dw      0000                            ; [ebx].MLIDBoardInstance
        dd      2048                            ; [ebx].MLIDMaximumSize
        dd      00000000                        ; [ebx].MLIDMaxRecvSize
        dd      00000000                        ; [ebx].MLIDRecvSize
        dd      00000000                        ; [ebx].MLIDCardName
        dd      DriverNICShortName              ; [ebx].MLIDShortName
        dd      00000000                        ; [ebx].MLIDFrameType
        dw      0000                            ; [ebx].MLIDReserved0
        dw      TokenMediaID8022                ; [ebx].MLIDFrameID
        dw      1                               ; [ebx].MLIDTransportTime
        dd      00000000                        ; [ebx].MLIDRouteHandler
        dw      0004                            ; [ebx].MLIDLineSpeed
        dw      0000                            ; [ebx].MLIDLookAheadSize
        db      02                              ; [ebx].MLIDCFG_SGCount
      db      00                               ; [ebx].MLIDReserved1
      dw      0000                     ; [ebx].MLIDPrioritySup
      dd      00000000                        ; [ebx].MLIDReserved2
        db      00                              ; [ebx].MLIDMajorVersion
        db      00                              ; [ebx].MLIDMinorVersion
        dw      0000000000000000b               ; [ebx].MLIDFlags
        dw      0000                            ; [ebx].MLIDSendRetries
        dd      00000000                        ; [ebx].MLIDLink
        dw      IOShareInterrupt0Bit            ; [ebx].MLIDSharingFlags
        dw      0FFFFh                          ; [ebx].MLIDSlot
        dw      PRIMARY_PIO, 4, 0, 0            ; [ebx].MLIDIOPortsAndLengths
        dd      0                               ; [ebx].MLIDMemoryDecode0
        dw      RAMPageRange0                   ; [ebx].MLIDLength0
        dd      0                               ; [ebx].MLIDMemoryDecode1
        dw      RAMPageRange1                   ; [ebx].MLIDLength1
        db      3, 0FFh                         ; [ebx].MLIDInterrupt
        db      0FFh, 0FFh                      ; [ebx].MLIDDMAUsage
        dd      00000000                        ; [ebx].MLIDResourceTag
        dd      00000000                        ; [ebx].MLIDConfiguration
        dd      00000000                        ; [ebx].MLIDCommandString
        db      18 dup (0)                      ; [ebx].MLIDLogicalName
        dd      00000000                        ; [ebx].MLIDLinearMemory0
        dd      00000000                        ; [ebx].MLIDLinearMemory1
        dw      0000                            ; [ebx].MLIDChannelNumber
        dd      00000000                        ; [ebx].MLIDBusTag
        db      01                             ; [ebx].MLIDIOCfgMajorVersion
        db      00                              ; [ebx].MLIDIOCfgMinorVersion

Message         DriverNICShortName,     'NTR2000'

if UseNBICalls

;
;***********************************************************************\
;                                                                       *
; Parameters required by NBI Calls                              *
;                                                                       *
;***********************************************************************/
;

CFG_BUFFER_SIZE   equ   8
ConfigBuffer   db   CFG_BUFFER_SIZE dup (0)
ProductID   db   TOKEN_ID_LO, TOKEN_ID_HI

endif

;
;***********************************************************************\
;                                                                       *
; Parameters required by ParseDriverParameters.                         *
;                                                                       *
;***********************************************************************/
;
SlotsWithMyBoardCount   dd      0
SlotsWithMyBoard        dd      8 dup (0)
IOPort0Data             dd      2, 0A20h, 0A24h

;;971217 Begin
;;AdapterOptions  AdapterOptionDefinitionStructure        <SlotsWithMyBoardCount, IOPort0Data,,,,,,,,>
AdapterOptions AdapterOptionDefinitionStructure <SlotsWithMyBoardCount,IOPort0Data,0,0,0,0,0,0,0,0,0,0,0,0>
;;971217 End
;
;***************************************************************\
;                                                               *
; Custom Keywords.                                              *
;                                                               *
;***************************************************************/
;
DebugText               db      '-D'            ; Break into debugger keyword.
DebugTextLen            equ     $-DebugText

LinkStationsText        db      'LS'            ; Link Stations keyword.
LinkStationsTextLen     equ     $-LinkStationsText OR T_NUMBER
                        dd      0               ; Min link station value.
                        dd      0ffh            ; Max link station value.

MaxSAPsText             db      'SAPS'          ; Maximum SAPs keyword.
MaxSAPsTextLen          equ     $-MaxSAPsText OR T_NUMBER
                        dd      0               ; Min SAPs value.
                        dd      125             ; Max SAPs value.

TxBuffersText           db      'TBC'           ; Tx Buffers keyword.
TxBuffersTextLen        equ     $-TxBuffersText OR T_NUMBER
                        dd      1               ; Min Tx Buffers.
                        dd      2               ; Max Tx Buffers.

TxBufferLenText         db      'TBZ'           ; Tx Buffer Length keyword.
TxBufferLenTextLen      equ     $-TxBufferLenText OR T_NUMBER
                        dd      0               ; Min Tx Buffer Size.
                        dd      4202            ; Max Tx Buffer Size.

Mem1Text                db      'MEM0'          ; Shared RAM keyword.
Mem1TextLen             equ     $-Mem1Text OR T_HEX_NUMBER
                        dd      0               ; Min Shared RAM value.
                        dd      100000h         ; Max Shared RAM value.

TokenKeywordText        dd      DebugText       ; First Keyword.
                        dd      LinkStationsText
                        dd      MaxSAPsText
                        dd      TxBuffersText
                        dd      TxBufferLenText
                        dd      Mem1Text
TokenKeywordTextLen     dd      DebugTextLen    ; First Keywords length.
                        dd      LinkStationsTextLen
                        dd      MaxSAPsTextLen
                        dd      TxBuffersTextLen
                        dd      TxBufferLenTextLen
                        dd      Mem1TextLen
TokenProcessKeywordTab  dd      DebugRoutine    ; First Keyword routine.
                        dd      LinkStationsRoutine
                        dd      MaxSAPsRoutine
                        dd      TxBuffersRoutine
                        dd      TxBufferLenRoutine
                        dd      Mem1Routine
;
;***************************************************************\
;                                                               *
; Temporary storage for Custom Keyword Routines.                *
;                                                               *
;***************************************************************/
;
LinkStationsValue       db      OPEN_LINK_STATIONS
MaxSAPsValue            db      OPEN_MAX_SAPS
TxBuffersValue          db      OPEN_TX_BUFFERS
TxBufferLenValue        dw      0
        align   04
;
;***************************************************************\
;                                                               *
; ARBJumpTable -- ARB Jump Table.                               *
;                                                               *
;***************************************************************/
;
        public ARBJumpTable
ARBJumpTable    dd      ARBReceiveDataRoutine   ; ARB 81 -- Receive Data
                dd      ARBTransmitDataRequest  ; ARB 82 -- Transmit Data Request
                dd      InvalidARBEntry         ; ARB 83 -- DLC Status
                dd      ARBRingStatusRoutine    ; ARB 84 -- Ring Status
ifdef BROUTER
                dd      ARBReceiveDataRoutine   ; ARB 85 -- Receive Bridge Data
else
                dd      InvalidARBEntry         ; ARB 85 -- Invalid ARB Request
endif
;
;***************************************************************\
;                                                               *
; InitScreenID -- Screen ID Save Area.                          *
;                                                               *
;***************************************************************/
;
InitScreenID            dd      00000000        ; Screen ID Save Area
SNAP8022Header          db      0AAh, 0AAh, 03h ; 802.2 SNAP Header
;
;***************************************************************\
;                                                               *
; RAMSizeTable -- Shared RAM Size Look Up Table.                *
;                                                               *
;***************************************************************/
;
RAMSizeTable    db      08192/4096      ; RAMRelocationRegister+01 = 00 ==> 08k = 02h
                db      16384/4096      ; RAMRelocationRegister+01 = 02 ==> 16k = 04h
                db      32768/4096      ; RAMRelocationRegister+01 = 04 ==> 32k = 08h
                db      65536/4096      ; RAMRelocationRegister+01 = 06 ==> 64k = 10h
;
;***************************************************************\
;                                                               *
; TransmitSizeTable -- Transmit Buffer Size Look Up Tables.     *
;                                                               *
;***************************************************************/
;
TransmitSizeTable4Mb    dw      4464    ; 1FAA = 0Bh
                        dw      4464    ; 1FAA = 0Ch
                        dw      4464    ; 1FAA = 0Dh
                        dw      4096    ; 1FAA = 0Eh
                        dw      2048    ; 1FAA = 0Fh

TransmitSizeTable16Mb   dw      17960   ; 1FAC = 0Bh
                        dw      16384   ; 1FAC = 0Ch
                        dw      08192   ; 1FAC = 0Dh
                        dw      04096   ; 1FAC = 0Eh
                        dw      02048   ; 1FAC = 0Fh

Tx16MbTableSize equ   $-TransmitSizeTable16Mb   ; Maximum Table Size
;
;***************************************************************\
;                                                               *
; TxDIRFrame -- XMIT.DIR.Frame SRB Image.                       *
;                                                               *
;***************************************************************/
;
TxDIRFrame      db      SRB_TX_DIR_FRAME,00,SRB_NOT_PROCESSED,00,00,00
;
;***************************************************************\
;                                                               *
; MicroChannel/PC Bus -- Token-Ring Signature Work Area.        *
;                                                               *
;***************************************************************/
;
MicroChannelBus MicroChannelSignature   <>      ;Micro Channel Signature
PCBus           PCSignature <>                  ;PC Bus Signature
;
;***************************************************************\
;                                                               *
; Message equates.                                              *
;                                                               *
;***************************************************************/
;
CR                      equ     13
LF                      equ     10
;
;***************************************************************\
;                                                               *
; ASCII Error Messages.                                         *
;                                                               *
;***************************************************************/
;
ErrorFindingCardMessage db      050, 0, 'The board cannot be found.', 0dh, 0ah, 0
ErrorRAMFailedMessage   db      226, 0, 'The ROM and shared RAM address overlap.', 0dh, 0ah
                        db      '             (Please check the ROM switch settings and', 0dh, 0ah
                        db      '              RAM address [MEM0] on the command line.)', 0dh, 0ah, 0
ErrorInitializingNIC    db      206, 0, 'An interrupt failed to occur during initialization.', 0dh, 0ah, 0
ErrorEPROM              db      207, 0, 'Warning: Please check your adapter EPROM.  If the number is', 0dh, 0ah
                        db      '        74F9325 & 74F9326 or 25F9523 & 25F9524, please replace them.', 0dh, 0ah, 0
AdapterCheckMessage     db      238, 0, 'The adapter check caused the adapter to deregister.', 0dh, 0ah
                        db      '                Error code = %x.', CR, LF, 0

DIROpenFailedMessage    db      201, 0, 'DIR.OPEN.ADAPTER error code = %x.', 0dh, 0ah
DIROpenDuplicateMessage db      233, 0, 'The adapter detected a duplicate station during the insertion process.', 0dh, 0ah
                        db      '                Error code = %x.', CR, LF, 0
DIROpenRemoveMessage    db      234, 0, 'The adapter received a Remove MAC Frame during the insertion process.', 0dh, 0ah
                        db      '                Error code = %x.', CR, LF, 0
DIROpenLobeWireMessage  db      235, 0, 'The adapter cable was disconnected during the insertion process.', 0ah, 0dh
                        db      '                Error code = %x.', CR, LF, 0
DIROpenBeaconMessage    db      236, 0, 'The ring was beaconing during the insertion process.', 0dh, 0ah
                        db      '                Error code = %x.', CR, LF, 0

AutoRemoveMessage       db      241, 0, 'The Auto Removal process reset the adapter.', 0dh, 0ah
                        db      '                Ring status = %x.', CR, LF, 0
LobeWireAtBoardMessage  db      239, 0, 'Cable is disconnected at the board. Board is resetting.', 0dh, 0ah
                        db      '                Ring status = %x.', CR, LF, 0
LobeWireAtMAUMessage    db      240, 0, 'Cable is disconnected at the MAU. Board is resetting.', 0dh, 0ah
                        db      '                Ring status = %x.', CR, LF, 0
RemoveMACFrameMessage   db      242, 0, 'The Remove MAC Frame process shut down the adapter.', 0dh, 0ah
                        db      '                Ring status = %x.', CR, LF, 0
RingBeaconMessage       db      237, 0, 'The adapter is beaconing.', 0dh, 0ah
                        db      '                Ring status = %x.', CR, LF, 0

AlertCorrectedMessage   db      243, 0, 'The adapter alert condition was corrected.', CR, LF, 0
AdapterDataRateMessage  db      'Token-Ring Adapter %d Data Rate = %d MBps.', 0dh, 0ah, 0
Size8KMessage           db      'Shared RAM size = 8KB.', 0dh, 0ah, 0
Size16KMessage          db      'Shared RAM size = 16KB.', 0dh, 0ah, 0
Size32KMessage          db      'Shared RAM size = 32KB.', 0dh, 0ah, 0
Size64KMessage          db      'Shared RAM size = 64KB.', 0dh, 0ah, 0
FastPathMessage         db      'Token-Ring Adapter supports Fast Path Transmits.', 0dh, 0ah, 0
NoFastPathMessage       db      'Max Packet Size forced to 2048 bytes.', 0dh, 0ah
                        db      'Change Shared RAM size to 16K, 32K or 64K to enable Fast Path Transmits.', 0dh, 0ah, 0
if NoTxLimit
MaxSizeMessage          db      'Max Packet Size = %d', 0dh, 0ah, 0
endif

ifdef BROUTER
BridgeConfigMessage     db      'DIR.CONFIG.BRIDGE.RAM error code = %x.', CR, LF, 0
BridgeParmsMessage      db      'DIR.SET.BRIDGE.PARMS error code = %x.', CR, LF, 0
endif

LevelErrorMsg           db      150, 00, 'TokenTSM.NLM Assembly HSM Interface Level is %d.', CR, LF
                        db               'This HSM needs Level 230.', CR, LF, 0

OSDATA  ends

        subttl -- DriverMulticastChange --
        page
OSCODE  segment er public 'CODE'
if DEBUG
        extrn   OutChar: near
endif
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverMulticastChange, TOKEN/API/MULTI )
;
; Name:         DriverMulticastChange
;
; Description:  This routine save will the 32-bit functional address contained
;               in EDX and set a flag so that the next time the SRB is free,
;               the new functional address will be passed to the adapter.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     N/A
;               EDX     32-bit functional address
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are in any state.
;
; On Return:    EAX     Destroyed
;               EBX     Destroyed
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the tokenmsm media module.
;               It can be called at process or interrupt time.
;
; See Also:     TOKENTSM\TokenTSMAddMulticastAddress
;               TOKENTSM\TokenTSMDeleteMulticastAddress
;               TOKENTSM\TokenTSMUpdateMulticast
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
DriverMulticastChange   proc

if DEBUG
        push    eax
        mov     al, 'F'
        call    OutChar
        pop     eax
endif
        mov     [ebp].FunctionalAddress, edx            ; Save address.
        or      [ebp].MLIDStatusFlag, DIR_FUNCTIONAL_BIT        ; Set flag
        jmp     CheckNextSRBCommand                     ; and see if we
                                                        ; can send it out.
DriverMulticastChange   endp

ifdef BROUTER

DriverManagement        proc

if DEBUG
        push    eax
        mov     al, 'M'
        call    OutChar
        pop     eax
endif
        mov     eax, NoSuchHandles              ; EAX = Possible error code.
        cmp     dword ptr [esi].RProtocolID+0, 'UORB'
        jne     DriverManagementExit
        cmp     word ptr [esi].RProtocolID+4, 'ET'
        jne     short DriverManagementExit

        mov     ax, [esi].BrouterRequestCode
        cmp     ax, BrouterSupport              ; BrouterSupportRequest?
        je      short ReturnBrouterStatus       ; Jump if so.

        cmp     ax, SelectSRBridging
        mov     eax, BadParameters              ; EAX = Possible error code.
        jne     short DriverManagementExit

        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        mov     al, [ebx].RAMRelocationRegister+01      ; AL = Shared RAM Size Mask.
        and     al, SHARED_RAM_MASK             ; AL = Shared RAM Size(0ch).
        cmp     al, SHARED_RAM_8K               ; 8K?
        mov     eax, NoSuchHandles
        je      short DriverManagementExit

        mov     eax, [esi].SRBServiceHandler    ; non-zero: do SRB
        mov     [ebp].BrouterState, eax

        mov     al, [esi].SRPartitionSize
        mov     [ebp].BParmsPBits, al
        mov     ax, [esi].SRBridgeNumber
        xchg    al, ah
        mov     [ebp].BParmsBNumber, ax
        mov     ax, [esi].SRRingInNumber
        xchg    al, ah
        mov     [ebp].BParmsSRing, ax
        mov     ax, [esi].SRRingOutNumber
        xchg    al, ah
        mov     [ebp].BParmsTRing, ax
        mov     al, [esi].SRFilterSTE
        xor     al, 1
        mov     [ebp].BParmsCopySTE, al
        jmp     GoToReset                       ;JCP.

ReturnBrouterStatus:
        mov     dword ptr [esi].BrouterSupportStatus, BROUTER_STATUS
        xor     eax, eax

DriverManagementExit:
        ret

DriverManagement        endp

endif

ifdef BROUTER
        public  DriverSendBridge
        align   16
DriverSendBridge        proc
if DEBUG
        push    eax
        mov     al, 'B'
        call    OutChar
        pop     eax
endif

        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        mov     al, [ebp].TxPageValue
        mov     [ebx].RAMPageRegister, al       ; Set new page.
        mov     edi, [ebp].TxBaseAddress
        or      edi, edi                        ; Bridge Open yet?
        je      DriverSendNotOpen               ; Jump if not.
;
; EDI -> Bridge Transmit Control Area. Get First Transmit Buffer.
;
        movzx   edx, [edi].BTCANextBuffer
        or      edx, edx                        ; Control Area Open?
        je      DriverSendNotOpen               ; Get out if not.

        mov     [ebp].TxLastBuffer, edx         ; Save for Next Buffer.
        xchg    dh, dl                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, dh       ; Set new Window Page.
        and     dh, [ebp].PageSizeMask          ; Mask off page bits.
        add     edx, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
;
; EDX -> First Fast Path Transmit Buffer. Fill out necessary info.
;
        mov     eax, [esi].TCBDataLen           ; EAX = Total frame size.
        xchg    ah, al                          ; Convert to IBM format.
        mov     [edx-BTBBufferPointer].BTBFrameLength, ax
        mov     [edx-BTBBufferPointer].BTBXmitControl, 0

        mov     [ebp].TxBufferSpace, OPEN_RX_LENGTH-8   ; Save bytes left in buffer.
        mov     [ebp].TxCurrentTCB, esi
        mov     [ebp].TxCurrentBuffer, edx      ; Save Current Tx Buffer.
;
; Copy TCB header to first buffer.
;
        lea     edi, [edx-BTBBufferPointer].BTBFrameData        ; EDI -> Buffer Data Area.
        mov     ebx, esi                        ; EBX -> TCB.
        mov     ecx, [ebx].TCBMediaHeaderLen    ; ECX = Media Header Len.
        lea     esi, [ebx].TCBMediaHeader       ; ESI -> Media Header.
        sub     [ebp].TxBufferSpace, ecx        ; Update bytes left.

        mov     eax, ecx
        shr     ecx, 2                          ; ECX = dwords.
        rep     movsd                           ; Copy dwords.
        mov     ecx, eax
        and     ecx, 3                          ; ECX = bytes.
        rep     movsb                           ; Copy bytes.

        mov     [ebp].TxBuffersUsed, 1

        mov     ebx, [ebx].TCBFragStrucPtr      ; EBX -> Fragment Count.
        mov     eax, [ebx]                      ; EAX = Fragment Count.
        add     ebx, 4                          ; EBX -> Fist Frag Desc.
        mov     [ebp].TxFragmentCount, eax      ; Save fragment count.
DriverSendBridgeLoop:
        mov     esi, [ebx].FragmentOffset       ; ESI -> Frag offset.
        mov     ecx, [ebx].FragmentLength       ; ECX = Fragment Length.
        mov     eax, [ebp].TxBufferSpace        ; EAX = Dest space left.
DriverSendBridgeFragRet:
        cmp     ecx, eax                        ; Do we have enough space?
        ja      DriverSendBridgeFrag            ; Jump if not.

        sub     eax, ecx                        ; EAX = Space left.
        mov     [ebp].TxBufferSpace, eax        ; Save for later.

        mov     eax, ecx
        shr     ecx, 2                          ; ECX = dwords.
        rep     movsd                           ; Copy dwords.
        mov     ecx, eax
        and     ecx, 3                          ; ECX = bytes.
        rep     movsb                           ; Copy bytes.

        mov     eax, [ebp].TxBufferSpace
        add     ebx, size FragmentStructure     ; EBX -> Next Descriptor.
        dec     [ebp].TxFragmentCount           ; Any fragments left?
        jne     DriverSendBridgeLoop            ; Jump if so.

        mov     eax, OPEN_RX_LENGTH-8           ; EAX = Max Frame Data Size.
        sub     eax, [ebp].TxBufferSpace        ; EAX = Size of this buffer.
        mov     edx, [ebp].TxCurrentBuffer
        xchg    ah, al                          ; Convert to IBM format.
        mov     [edx-BTBBufferPointer].BTBBufferLength, ax      ; Store buffer length.
        mov     [edx-BTBBufferPointer].BTBXmitControl, 1        ; Last buffer.

        movzx   ecx, [edx-BTBBufferPointer].BTBBufferPointer    ; CX = offset of next buffer.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.

        mov     al, [ebp].TxPageValue
        mov     [ebx].RAMPageRegister, al       ; Set new page.
        mov     edi, [ebp].TxBaseAddress        ; EDI -> Tx Control Area

        mov     al, [edi].BTCAInputCount
        add     al, [ebp].TxBuffersUsed
        mov     [edi].BTCANextBuffer, cx
        mov     [edi].BTCAInputCount, al

        mov     [ebx].OROffset.IntStatusToAdapter+01, BRIDGE_FORWARD
        mov     esi, [ebp].TxCurrentTCB
        MSMGetCurrentTime                       ; EAX = Current Time.
        mov     [ebp].TxStartTime, eax          ; Store it for later.

        jmp     TokenTSMFastSendComplete
;
; Fragment will not fit into Tx buffer. Fill in rest and get new Tx buffer.
;
DriverSendBridgeFrag:
        mov     edx, ecx
        sub     edx, eax                        ; EDX = Bytes left.
        mov     ecx, eax
        shr     ecx, 2                          ; ECX = Dwords to copy.
        rep     movsd                           ; Copy dwords.
        mov     ecx, eax
        and     ecx, 3                          ; ECX = Bytes to copy.
        rep     movsb                           ; Copy bytes.

        mov     ecx, edx                        ; ECX = bytes to copy.
        mov     edx, [ebp].TxCurrentBuffer      ; EDX -> Current Buffer.
        mov     eax, OPEN_RX_LENGTH-8
        xchg    ah, al                          ; Convert to IBM format.
        mov     [edx-BTBBufferPointer].BTBBufferLength, ax
        mov     [edx-BTBBufferPointer].BTBXmitControl, 0
        movzx   edx, [edx-BTBBufferPointer].BTBBufferPointer ; DX = offset of next buffer.

        mov     [ebp].TxLastBuffer, edx         ; Save for FPTxLastBuffer.
        xchg    dh, dl                          ; Convert to Intel format.
        push    ebx                             ; Save Frag Desc.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        mov     [ebx].RAMPageRegister, dh       ; Set new Window Page.
        pop     ebx                             ; Restore Frag Desc.
        and     dh, [ebp].PageSizeMask          ; Mask off page bits.
        add     edx, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].TxCurrentBuffer, edx
        inc     [ebp].TxBuffersUsed

        lea     edi, [edx-BTBBufferPointer].BTBFrameData        ; EDI -> Buffer Data Area.
        mov     eax, OPEN_RX_LENGTH-8           ; EAX = Space left.
        mov     [ebp].TxBufferSpace, eax        ; Save current space left.
        jmp     DriverSendBridgeFragRet         ; Continue copy.

DriverSendBridge        endp
endif

DriverSendNotOpen:
        inc     [ebp].MSMTxFreeCount            ; Free up resource.
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        jmp     TokenTSMFastSendComplete        ; Jump if not.

        align   16
DriverSendFastPath      proc

if DEBUG
        push    eax
        mov     al, 'F'
        call    OutChar
        pop     eax
endif

ifdef BROUTER
        cmp     [ebp].BrouterState, 0
        jne     DriverSendBridge
endif

        cmp     [ebp].CompletionQHead, 0        ; Fast Path Opened?
        je      DriverSendNotOpen               ; Jump if not.

        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        mov     al, [ebp].TxPageValue
        mov     [ebx].RAMPageRegister, al       ; Set new page.
        mov     edi, [ebp].TxBaseAddress
;
; EDI -> Fast Path Transmit Control Area. Get First Transmit Buffer.
;
        movzx   edx, [edi].FPFreeQHead          ; EDX = &Q Head.

        mov     [ebp].TxLastBuffer, edx         ; Save for FPTxLastBuffer.
        xchg    dh, dl                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, dh       ; Set new Window Page.
        and     dh, [ebp].PageSizeMask          ; Mask off page bits.
        add     edx, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
;
; EDX -> First Fast Path Transmit Buffer. Fill out necessary info.
;
        mov     [edx-FPTxNextBuffer].FPTxCommand, SRB_TX_DIR_FRAME
        mov     al, [ebp].TxCorrelator
        mov     [edx-FPTxNextBuffer].FPTxCorrelator, al
        inc     al                              ; Set new correlator.
        and     al, 7fh                         ; Set to 0-127.
        mov     [ebp].TxCorrelator, al
        mov     [edx-FPTxNextBuffer].FPTxSTATIONID, 0   ; Set to Direct Station.
        mov     eax, [esi].TCBDataLen           ; EAX = Total frame size.
        xchg    ah, al                          ; Convert to IBM format.
        mov     [edx-FPTxNextBuffer].FPTxFrameLength, ax

        mov     [ebp].TxBufferSpace, 512-22     ; Save bytes left in buffer.
        mov     [ebp].TxCurrentTCB, esi
        mov     [ebp].TxCurrentBuffer, edx      ; Save Current Tx Buffer.
;
; Copy TCB header to first buffer.
;
        lea     edi, [edx-FPTxNextBuffer].FPTxFrameData ; EDI -> Buffer Data Area.
        mov     ebx, esi                        ; EBX -> TCB.
        mov     ecx, [ebx].TCBMediaHeaderLen    ; ECX = Media Header Len.
        lea     esi, [ebx].TCBMediaHeader       ; ESI -> Media Header.
        sub     [ebp].TxBufferSpace, ecx        ; Update bytes left.

        mov     eax, ecx
        shr     ecx, 2                          ; ECX = dwords.
        rep     movsd                           ; Copy dwords.
        mov     ecx, eax
        and     ecx, 3                          ; ECX = bytes.
        rep     movsb                           ; Copy bytes.

        mov     ebx, [ebx].TCBFragStrucPtr      ; EBX -> Fragment Count.
        mov     eax, [ebx]                      ; EAX = Fragment Count.
        add     ebx, 4                          ; EBX -> Fist Frag Desc.
        mov     [ebp].TxFragmentCount, eax      ; Save fragment count.

DriverSendFastPathLoop:
        mov     esi, [ebx].FragmentOffset       ; ESI -> Frag offset.
        mov     ecx, [ebx].FragmentLength       ; ECX = Fragment Length.
        mov     eax, [ebp].TxBufferSpace        ; EAX = Dest space left.
DriverSendFragRet:
        cmp     ecx, eax                        ; Do we have enough space?
        ja      DriverSendFastPathFrag          ; Jump if not.

        sub     eax, ecx                        ; EAX = Space left.
        mov     [ebp].TxBufferSpace, eax        ; Save for later.

        mov     eax, ecx
        shr     ecx, 2                          ; ECX = dwords.
        rep     movsd                           ; Copy dwords.
        mov     ecx, eax
        and     ecx, 3                          ; ECX = bytes.
        rep     movsb                           ; Copy bytes.

        mov     eax, [ebp].TxBufferSpace
        add     ebx, size FragmentStructure     ; EBX -> Next Descriptor.
        dec     [ebp].TxFragmentCount           ; Any fragments left?
        jne     DriverSendFastPathLoop          ; Jump if so.

        mov     eax, 512-22                     ; EAX = Max Frame Data Size.
        sub     eax, [ebp].TxBufferSpace        ; EAX = Size of this buffer.
        mov     edx, [ebp].TxCurrentBuffer
        xchg    ah, al                          ; Convert to IBM format.
        mov     [edx-FPTxNextBuffer].FPTxBufferLength, ax       ; Store buffer length.

        movzx   ecx, [edx-FPTxNextBuffer].FPTxNextBuffer        ; CX = offset of next buffer.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.

        mov     al, [ebp].TxPageValue
        mov     [ebx].RAMPageRegister, al       ; Set new page.
        mov     edi, [ebp].TxBaseAddress        ; EDI -> Tx Control Area

        movzx   edx, [edi].FPFreeQHead          ; EDX = &Q Head.
        xchg    dh, dl                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, dh       ; Set new Window Page.
        and     dh, [ebp].PageSizeMask          ; Mask off page bits.
        add     edx, [ebp].SharedRAMRelative    ; Add Shared RAM Base.

        mov     eax, [ebp].TxLastBuffer         ; AX = Offset of last buffer.
        mov     [edx-FPTxNextBuffer].FPTxLastBuffer, ax ; Store last buffer.

        mov     al, [ebp].TxPageValue
        mov     [ebx].RAMPageRegister, al       ; Set new page.
        mov     [edi].FPFreeQHead, cx           ; Update queue head.

        mov     [ebx].OROffset.IntStatusToAdapter+01, BRIDGE_FORWARD
        mov     esi, [ebp].TxCurrentTCB

if DEBUG
        push    eax
        mov     al, 'f'
        call    OutChar
        pop     eax
endif

        MSMGetCurrentTime                       ; EAX = Current Time.
        mov     [ebp].TxStartTime, eax          ; Store it for later.
        jmp     TokenTSMFastSendComplete
;
; Fragment will not fit into Tx buffer. Fill in rest and get new Tx buffer.
;
DriverSendFastPathFrag:
        mov     edx, ecx
        sub     edx, eax                        ; EDX = Bytes left.
        mov     ecx, eax
        shr     ecx, 2                          ; ECX = Dwords to copy.
        rep     movsd                           ; Copy dwords.
        mov     ecx, eax
        and     ecx, 3                          ; ECX = Bytes to copy.
        rep     movsb                           ; Copy bytes.

        mov     ecx, edx                        ; ECX = bytes to copy.
        mov     edx, [ebp].TxCurrentBuffer      ; EDX -> Current Buffer.
        mov     eax, 512-22
        xchg    ah, al                          ; Convert to IBM format.
        mov     [edx-FPTxNextBuffer].FPTxBufferLength, ax
        movzx   edx, [edx-FPTxNextBuffer].FPTxNextBuffer        ; DX = offset of next buffer.

        mov     [ebp].TxLastBuffer, edx         ; Save for FPTxLastBuffer.
        xchg    dh, dl                          ; Convert to Intel format.
        push    ebx                             ; Save Frag Desc.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        mov     [ebx].RAMPageRegister, dh       ; Set new Window Page.
        pop     ebx                             ; Restore Frag Desc.
        and     dh, [ebp].PageSizeMask          ; Mask off page bits.
        add     edx, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].TxCurrentBuffer, edx

        lea     edi, [edx-FPTxNextBuffer].FPTxFrameData ; EDI -> Buffer Data Area.
        mov     eax, 512-22                     ; EAX = Space left.
        mov     [ebp].TxBufferSpace, eax        ; Save current space left.
        jmp     DriverSendFragRet               ; Continue copy.


DriverSendFastPath      endp
        subttl -- DriverSend --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverSend, TOKEN/API/SEND )
;
; Name:         DriverSend
;
; Description:  This routine will transfer the packet described in the
;               TCB to the NIC and initiate the send if the SRB is free.
;               Otherwise the TCB will be queued.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ TCB
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the MSM media module.
;               It is called at process or interrupt time.
;
; See Also:     TOKENTSM\TokenTSMDriverSend
;               TOKENTSM\MediaSend8022Over8025
;               TOKENTSM\MediaSend8022Snap
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
DriverSendInReset:
        inc     [ebp].MSMTxFreeCount
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        jmp     TokenTSMFastSendComplete

        align   16
DriverSend      proc
if DEBUG
        push    eax
        mov     al, 'S'
        call    OutChar
        pop     eax
endif

ifdef BROUTER
        cmp     [ebp].BrouterState, 0
        jne     DriverSendBridge
endif

        cmp     [ebp].InDriverReset, 0
        jne     DriverSendInReset

        cmp     [ebp].OpeningAdapter, 0         ;Opening adapter ?
        jne     DriverSendInReset

        mov     [esi].TCBDriverWS.TCBLink, 0    ; Set Link to end of queue.
;
;***************************************************************\
;                                                               *
; Check to see if the card is still using the SRB.              *
;                                                               *
;***************************************************************/
;
        test    [ebp].MLIDStatusFlag, DIR_READ_LOG_BIT OR DIR_FUNCTIONAL_BIT OR TX_IN_PROCESS_BIT OR SRB_IS_BUSY_BIT
        jnz     short DriverSendSRBIsBusy       ; Jump if SRB is busy.

DriverStartSend:
;
;***************************************************************\
;                                                               *
; ESI -> TCB and SRB is free to use.                            *
;                                                               *
;***************************************************************/
;
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        movzx   ecx, [ebx].RAMPageRegister      ; CL = Old Page Register.
        mov     al, [ebp].SRBPageValue          ; AL = New Page Register.
        mov     [ebx].RAMPageRegister, al       ; Set new Page Register.
        mov     edi, [ebp].SRBBaseAddress       ; EDI -> SRB buffer.

        mov     [ebp].TCBInProcess, esi         ; Save TCB for later.

        or      [ebp].MLIDStatusFlag, TX_IN_PROCESS_BIT ; Set Sending flag.
        lea     esi, TxDIRFrame                 ; ESI -> SRB Image.
        rept    SRB_SIZE/04
        movsd                                   ; Copy Image to Card.
        endm
;
;***************************************************************\
;                                                               *
; Set the SRB Busy and exit.                                    *
;                                                               *
;***************************************************************/
;
        mov     [ebx].OROffset.IntStatusToAdapter+01, COMMAND_IN_SRB
        or      [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Set SRB Busy Flag.
        mov     [ebx].RAMPageRegister, cl               ; Restore old page.
        ret
;
;***************************************************************\
;                                                               *
; The SRB is Busy; Enqueue The Send For Later Processing.       *
;                                                               *
;***************************************************************/
;
DriverSendSRBIsBusy:

        cmp     [ebp].SendQueueHead, 0          ; Send Queue Empty?

        mov     eax, [ebp].SendQueueTail        ; EAX = TCB from tail.
        mov     [ebp].SendQueueTail, esi        ; Tail -> Our TCB.

        jnz     short QueueNotEmpty             ; Jump if not empty.
        lea     eax, [ebp-TCBDriverWS-TCBLink].SendQueueHead
QueueNotEmpty:
        mov     [eax].TCBDriverWS.TCBLink, esi  ; Link TCB to TAIL.

        jmp     CheckNextSRBCommand             ; Check if SRB freed yet.

DriverSend      endp
        subttl -- DriverISR --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverISR, TOKEN/API/ISR )
;
; Name:         DriverISR
;
; Description:  This routine handles packet reception and transmit complete
;               interrupts.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     0 if interrupt was ours
;               EBX     Destroyed
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Destroyed
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the MSM.
;               It is called at interrupt time.
;
; See Also:     MSM\MSMInterruptProcedure
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        public  DriverISR
        align   16
DriverISR       proc

if DEBUG
        push    eax
        mov     al, 'Q'
        call    OutChar
        pop     eax
endif
;
;***************************************************************\
;                                                               *
; It Is My Interrupt; Use Table Look Up To Find The Reason.     *
;                                                               *
;***************************************************************/
;
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        movzx   ecx, word ptr [ebx].IntStatusToPC
        lea     esi, [ebp].InterruptVectorTable ; ESI = Interrupt Vector Table.

        test    ecx, ADAPTER_ERROR_BIT
        jnz     InterruptFound

        add     esi, 12                         ; ESI -> Next Interrupt Entry.
        test    ecx, ADAPTER_CHECK_BIT SHL 8
        jnz     InterruptFound

        add     esi, 12                         ; ESI -> Next Interrupt Entry.
        test    ecx, ASB_FREE_BIT SHL 8
        jnz     InterruptFound

        add     esi, 12                         ; ESI -> Next Interrupt Entry.
        test    ecx, SRB_RESPONSE_BIT SHL 8
        jnz     InterruptFound

        add     esi, 12                         ; ESI -> Next Interrupt Entry.
        test    ecx, BRIDGE_FORWARD_BIT SHL 8
        jnz     InterruptFound

        add     esi, 12                         ; ESI -> Next Interrupt Entry.
        test    ecx, ARB_COMMAND_BIT SHL 8
        jnz     InterruptFound

        add     esi, 12                         ; ESI -> Next Interrupt Entry.
        test    ecx, SSB_RESPONSE_BIT SHL 8
        jnz     InterruptFound

        add     esi, 12                         ; ESI -> Next Interrupt Entry.

InterruptFound:

        mov     eax, [esi+4]                    ; EAX = Bit Mask compare.
        and     eax, ecx                        ; ECX = Interrupt Reason Bits.
        or      [ebp].MLIDStatusFlag, NIC_INTERRUPTED_BIT ; Signal that int happened.
;
;***************************************************************\
;                                                               *
; Interrupt Reason Found; Disable the card and issue EOI.       *
;                                                               *
;***************************************************************/
;
        not     eax                             ; AX = Reverse the Bit
        and     al, NOT (INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT) ; Disable Card.
        mov     word ptr [ebx].IntStatusToPC.ANDOffset, ax

        test    [ebp].MLIDStatusFlag, IGNORE_INTERRUPTS_BIT     ; Ignore Interrupts?
        jnz     short DontCallISR               ; Don't Call Second Level Routine.

        mov     edx, [esi]                      ; EDX = Routine Address.

        movzx   eax, [ebx].RAMPageRegister      ; AL = Old PAGE Register.
        push    eax                             ; Save to restore later.

        mov     cx, [esi+6]                     ; CH = Possible Page.
        mov     esi, [esi+8]                    ; ESI -> MMIO Base/Message.
        or      cl, cl                          ; Page switch needed?
        jnz     short CallSecondaryRoutine      ; Jump if not.

        mov     [ebx].RAMPageRegister, ch       ; Set new page.
CallSecondaryRoutine:
;
;***********************************************************************\
;                                                                       *
; Call the second Level Routine.                                        *
;                                                                       *
;***********************************************************************<
;                                                                       *
; On Entry:                     On Exit:                                *
;       EAX = Not Used                  EAX = Destroyed                 *
;       EBX = @ BIOS/MMIO Domain        EBX = @ BIOS/MMIO Domain        *
;       ECX = Not Used                  ECX = Destroyed                 *
;       EDX = Not Used                  EDX = Destroyed                 *
;       EBP = @ Adapter Data Space      EBP = @ Adapter Data Space      *
;       ESI = Shared RAM/Error Message  ESI = Destroyed                 *
;       EDI = Not Used                  EDI = Destroyed                 *
;       Interrupts Enabled              Interrupts in any state         *
;                                                                       *
;***********************************************************************/
;
        call    edx                             ; Call second level routine.

        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX = BIOS/MMIO Domain @.
        pop     dword ptr [ebx].RAMPageRegister ; Restore Page register.
;
;***************************************************************\
;                                                               *
; We need to Issue PIO to Re-Arm The Interrupt.                 *
;                                                               *
;***************************************************************/
;
DontCallISR:
        mov     edx, [ebp].InterruptResetLevel  ; DX = 2Fn; n = IRQ Level.
        out     dx, al                          ; Re-Arm Global Interrupt.
ISRServiceEvents:
if not  UseFastCalls
        MSMServiceEvents                        ; Service Any Completed TCBs.
endif
if DEBUG
        push    eax
        mov     al, 'i'
        call    OutChar
        pop     eax
endif
        sub     eax, eax                        ; EAX = EOI Issued.
        ret                                     ; Exit ISR.

DriverISR       endp
        subttl  -- DriverDisableInterrupt --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverDisableInterrupt, TOKEN/API/DISINT )
;
; Name:         DriverDisableInterrupt
;
; Description:  This routine will disable the adapters ability to
;               interrupt the host.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Preserved
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Preserved
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the MSM.
;
; See Also:     DriverEnableInterrupt
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
DriverDisableInterrupt  proc

if DEBUG
        push    eax
        mov     al, '{'
        call    OutChar
        pop     eax
endif
        test    [ebp].MLIDStatusFlag, ADAPTER_RESET_BIT
        jnz     short NotMyInterruptGetOut      ; Jump if reset is held.

        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        movzx   ecx, word ptr [ebx].IntStatusToPC

;       test    cl, INTERRUPT_ENABLE_BIT        ; Interrupts Enabled?
;       jz      short NotMyInterrupt            ; Jump if not.

        test    cx, 0ff00h+PARITY_ERROR_BIT+TIMER_EXPIRED_BIT+RAM_VIOLATION_BIT+ADAPTER_ERROR_BIT
        jz      short NotMyInterrupt            ; Jump if no valid status bits.

        cmp     [ebp].InDriverReset, 0
        jnz     InDriverResetCase

        mov     ecx, NOT (INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT) ; Disable Card.
        mov     word ptr [ebx].IntStatusToPC.ANDOffset, cx

        xor     eax, eax
        ret

NotMyInterrupt:
        mov     ecx, NOT (INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT) ; Disable Card.
        mov     word ptr [ebx].IntStatusToPC.ANDOffset, cx

NotMyInterruptGetOut:
        or      al, 1                           ; AL > 00; Not our Interrupt.
        ret

InDriverResetCase:

        mov     ecx, NOT (INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT) ; Disable Card.
        mov     word ptr [ebx].IntStatusToPC.ANDOffset, cx

        or      [ebp].MLIDStatusFlag, NIC_INTERRUPTED_BIT ; Signal that int happened.
        mov     edx, [ebp].InterruptResetLevel  ; DX = 2Fn; n = IRQ Level.
        mov     al, cl
        out     dx, al                          ; Re-Arm Global Interrupt.

        xor     eax, eax
        ret

DriverDisableInterrupt  endp

        subttl  -- DriverEnableInterrupt --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverEnableInterrupt, TOKEN/API/ENINT )
;
; Name:         DriverEnableInterrupt
;
; Description:  This routine will enable the adapters ability to
;               interrupt the host.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Preserved
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Preserved
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the MSM.
;
; See Also:     DriverDisableInterrupt
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
DriverEnableInterrupt   proc

if DEBUG
        push    eax
        mov     al, '}'
        call    OutChar
        pop     eax
endif
        test    [ebp].MLIDStatusFlag, ADAPTER_RESET_BIT
        jnz     short EnableInterruptExit       ; Jump if reset is held.
        test    [ebp].MSMStatusFlags, SHUTDOWN  ; Board shutdown?
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        jnz     short EnableInterruptExit       ; Jump if so.
        mov     [ebx].IntStatusToPC.OROffset, INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT

EnableInterruptExit:

        ret

DriverEnableInterrupt   endp

        align   16
FastTxComplete  proc

if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'b'
        call    OutChar
        pop     eax
endif
ifdef BROUTER
        cmp     [ebp].BrouterState, 0
        jne     BridgeTxComplete
endif

        movzx   edx, [esi].FPCompletionQTail    ; EDX = Adapters Tail.
        movzx   eax, [esi].FPCompletionQTail    ; 8-bit quirk.
        cmp     eax, edx                        ; Same value?
        jne     FastTxComplete                  ; Try again if not.

        mov     ecx, [ebp].CompletionQHead
FastTxCompleteLoop:
        cmp     edx, ecx
        je      short FastTxNextSend            ; Jump out if so.

        inc     [ebp].MSMTxFreeCount            ; Free Tx resource.
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        xchg    ch, cl                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, ch       ; Set new Window Page.
        and     ch, [ebp].PageSizeMask          ; Mask off page bits.
        add     ecx, [ebp].SharedRAMRelative    ; Add Shared RAM Base.

        movzx   eax, [ecx-FPTxNextBuffer].FPTxNextBuffer        ; EAX = Tx completed.
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, ah       ; Set new Window Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.

        movzx   ecx, [eax-FPTxNextBuffer].FPTxLastBuffer

        mov     al, [ebp].TxPageValue           ; Switch back to Control Page.
        mov     [ebx].RAMPageRegister, al       ; Set new page.
        mov     [esi].FPFreeQTail, cx           ; Update Free Queue Tail.

        mov     [ebp].CompletionQHead, ecx      ; Update Our Completion Head.
        jmp     short FastTxCompleteLoop

FastTxNextSend:
        call    TokenTSMGetNextSend             ; Any more TCB's?
        jnz     CheckNextSRBCommand             ; Jump if so.
        push    ebp
        call    DriverSendFastPath
        pop     ebp
        jmp     short FastTxNextSend

ifdef BROUTER
BridgeTxComplete:
        mov     al, [esi].BTCAOutputCount
        cmp     al, [esi].BTCAReturnCount
        je      FastTxNextSend

        movzx   edx, [esi].BTCAOldBuffer        ; EDX = offset of first buffer.
BridgeTxCompleteLoop:
        xchg    dh, dl                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, dh       ; Set new window page.
        and     dh, [ebp].PageSizeMask          ; Mask off page bits.
        add     edx, [ebp].SharedRAMRelative    ; Add Shared RAM base.

        movzx   ecx, [edx-BTBBufferPointer].BTBLastBuffer
        xchg    ch, cl                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, ch       ; Set new window page.
        and     ch, [ebp].PageSizeMask          ; Mask off page bits.
        add     ecx, [ebp].SharedRAMRelative    ; Add Shared RAM base.

        inc     [ebp].MSMTxFreeCount            ; Free Tx resource.
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        movzx   edx, [ecx-BTBBufferPointer].BTBBufferPointer
;       mov     cl, [ecx-BTBBufferPointer].BTBNumberBuffers ;JCP, 941114.
        mov     cl, byte ptr [ecx-BTBBufferPointer].BTBNumberBuffers ;JCP, 941114.
        mov     ch, [ebp].TxPageValue           ; Switch to Transmit Control
        mov     [ebx].RAMPageRegister, ch       ;  Area Page.
        mov     al, [esi].BTCAReturnCount
        add     al, cl
        mov     [esi].BTCAReturnCount, al
        mov     [esi].BTCAOldBuffer, dx
        cmp     al, [esi].BTCAOutputCount
        je      FastTxNextSend
        jmp     BridgeTxCompleteLoop

endif

FastTxComplete  endp
        subttl -- AdapterErrorISR --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( AdapterErrorISR, TOKEN/INTERNAL/ADAPERR )
;
; Name:         AdapterErrorISR
;
; Description:  This routine handles Token-Ring error interrupts.
;
; On Entry:     EAX     N/A
;               EBX     @ BIOS/MMIO Domain @
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Error Message
;               EDI     N/A
;
;               Note:   Interrupts are enabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts enabled.
;
; Remarks:      This routine is called by the DriverISR.
;               It is called at interrupt time.
;
; See Also:     DriverISR
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
AdapterErrorISR proc    near
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'c'
        call    OutChar
        pop     eax
endif
        mov     eax, ADAPTER_CHECK_BIT SHL 8
;;;;    mov     ecx, ADAPTER_CHECK_TIMEOUT * 55000
        mov     ecx, ADAPTER_CHECK_TIMEOUT
        push    ebx                             ; save MMIO address
        lea     ebx, [ebx].IntStatusToPC        ; EBX -> Event Word.
        call    WaitForEvent                    ; Wait For Card To Post Adapter Check.
        pop     ebx                             ; restore MMIO address
        jnz     short AdapterCheckISR           ; Jump if Software Is Dead.
        mov     ecx, 8000h                      ; Adapter unable to respond.
        jmp     short SoftwareDied
AdapterCheckISR:
        mov     eax, dword ptr [ebx].WriteWindowCloseRegister
        xchg    ah, al                          ; AX = RAM Relative Offset.
        movzx   eax, ax                         ; EAX = RAM Relative Offset.
        mov     [ebx].RAMPageRegister, ah       ; Set new page.
        and     ah, [ebp].PageSizeMask          ; Mask off Page Bits.
        add     eax, [ebp].SharedRAMRelative    ; EAX = Shared RAM Address.

        mov     ecx, [eax+00]                   ; EDX = Adapter Check Reason Code.
        xchg    ch, cl                          ; Convert DWORD to
        rol     ecx, 16                         ;  Intel format.
        xchg    ch, cl
SoftwareDied:
        or      [ebp].MLIDStatusFlag, RE_INIT_ADAPTER_BIT
;
;***************************************************************\
;                                                               *
; Send Fatal Alert.                                             *
;       ESI -> Error Message.                                   *
;       ECX = Error Code.                                       *
;                                                               *
;***************************************************************/
;
        call    UpdateAlertStats                ; Update proper stats.
        lea     esi, AdapterCheckMessage        ; ESI -> Error message.
        jmp     MSMAlertFatal                   ; Send message and return.
;
;***************************************************************\
;                                                               *
; Invalid ASB Interrupt.                                        *
; ESI -> ASB Base Address.                                      *
;                                                               *
;***************************************************************/
;
InvalidASBISR:
        movzx   edx, [esi].ASBReturnCode                ; EDX = Return Code.
        mov     [esi].ASBReturnCode, SRB_INVALID        ; Set Return Code.
        ret
AdapterErrorISR endp
        page
        public  ARBRequestISR
        subttl -- ARBRequestISR --
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( ARBRequestISR, TOKEN/INTERNAL/ARBREQ )
;
; Name:         ARBRequestISR
;
; Description:  This routine handles Token-Ring ARB Request interrupts.
;
; On Entry:     EAX     N/A
;               EBX     @ BIOS/MMIO Domain @
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Shared RAM ARB
;               EDI     N/A
;
;               Note:   Interrupts are enabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts enabled.
;
; Remarks:      This routine is called by the DriverISR.
;               It is called at interrupt time.
;
; See Also:     DriverISR
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
ARBRequestISR   proc    near
;
;***************************************************************\
;                                                               *
; Save ARB, return ARB and jump to ARB handler routine.         *
;                                                               *
;***************************************************************/
;
;JCJ 15-October-1997  SHUTDOWN bit of MSMStatusFlags is checked in RxISR routine.
;                     This ensures that adapter will not interrupt for a packet
;                     reception if the driver is in a process of shutting down.
;                     SPD # 161461
        test    [ebp].MSMStatusFlags, SHUTDOWN
        je      short ProcessARB
        ret
ProcessARB:
;JCJ 15-October-1997  End of SPD # 161461

        movzx   eax, byte ptr [esi+0]           ;  AL = ARB Command Code.
        mov     ecx, SIZE ARBSaveArea / 04      ; ECX = ARB Save Area Size.
        lea     edi, [ebp].ARBSaveArea          ; EDI -> ARB Save Area.
 rep    movsd                                   ; Save the ARB.
        mov     [ebx].OROffset.IntStatusToAdapter+01, ARB_FREE
        mov     [ebp].ARBSaveArea.ASBReturnCode, cl     ; Return Code = 00.
        mov     [ebp].ARBSaveArea.ASBCommandCode, ARB_RECEIVED_DATA
        shl     al, 02                          ; EAX = ARB Command Code * 04.
        cmp     eax, (5 * 4)                    ; Valid ARB address?
ifdef BROUTER
        ja      InvalidARBEntry                 ; Jump if so.
else
        jae     InvalidARBEntry                 ; Jump if so.
endif
        or      eax, eax                        ; ARB=00-80h?
        je      InvalidARBEntry                 ; Jump if so.
        jmp     (ARBJumpTable-04)[eax]          ; Jump to the Routine.
;
;***************************************************************\
;                                                               *
; Process ARB 81h -- Receive Data.                              *
; Pass look ahead pointer to MSM and let MSM verify frame type  *
; and reception type.                                           *
;                                                               *
;***************************************************************/
;
        public  ARBReceiveDataRoutine
ARBReceiveDataRoutine:
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'd'
        call    OutChar
        mov     al, '1'
        call    OutChar
        pop     eax
endif
        mov     edi, eax                        ; Save ARB Jump Table offset.
        movzx   eax, word ptr [ebp].ARBSaveArea.ARBRxFirstBuffer
        xchg    ah, al                          ; EAX -> Offset of 1st Buffer.
        mov     [ebx].RAMPageRegister, ah       ; Set new page.
        and     ah, [ebp].PageSizeMask          ; Mask Page Bits.
        add     eax, [ebp].SharedRAMRelative    ; EAX -> 1st Rx Buffer.

        lea     esi, [eax].RCBFrameData+02      ; ESI -> Packet data.
        add     eax, 2                          ; Point past reserved.
        mov     [ebp].FirstRxBuffer, eax        ; Save pointer.
        movzx   ecx, word ptr [ebp].ARBSaveArea.ARBRxFrameLength
        xchg    ch, cl                          ; ECX = Entire Frame Length.
ifdef BROUTER
        cmp     [ebp].BrouterState, 0
        je      short ARBGetRCB
;
; In bridge mode. Check if it came from SRA.
;
        cmp     edi, (4 * 5)                    ; ARB 85h?
        jne     short ARBCheckForExplorer
;
; Came in from SRA, subtract CRC length.
;
        sub     ecx, 4
        jmp     short ARBGetRCB
;
; Didn't come from SRA. Discard if its an explorer.
;
ARBCheckForExplorer:
        test    byte ptr [esi].TxSourceNodeAddress, 80h
        je      short ARBGetRCB                 ; No RI field. Accept it.
;       test    [esi].TxRoutingInfo, 80h        ; JCP, 941114.
        test    byte ptr [esi].TxRoutingInfo, 80h ; JCP, 941114.
        jne     ReturnASBResponse               ; Explorer. Chuck it.
ARBGetRCB:
endif
        xor     eax, eax                        ; No Errors.
        call    TokenTSMGetRCB                  ; Get RCB for this packet.
;
;***************************************************************\
;                                                               *
; ESI -> ECB.                                                   *
; EDI -> Where in the ECB to copy remainder of packet into.     *
; EBX == Offset in packet to continue copying.                  *
; EAX == 0 if successful.                                       *
; Zero flag clear if successful.                                *
;                                                               *
;***************************************************************/
;
        mov     [ebp].ARBSaveArea.ASBReturnCode, SRB_NO_BUFFERS
        jnz     ReturnASBResponse               ; Jump if we don't want it.

        mov     [ebp].ARBSaveArea.ASBReturnCode, al     ; ASB Return Code = OK.
;
;***************************************************************\
;                                                               *
; ARB 81h - Move the first buffer into the ECB.                 *
;                                                               *
;***************************************************************/
;
        mov     [ebp].TotalBytes, ecx           ; Save for later.
        mov     [ebp].CurrentECB, esi           ; Save ECB.
        mov     eax, [edi]                      ; EAX = Frag Count.
        mov     [ebp].RCBFragments, eax         ; Store Frag count for later.
        add     edi, 4                          ; EDI -> 1st Frag Structure.

        mov     eax, [ebp].FirstRxBuffer        ; EAX -> 1st Rx Buffer.

        movzx   edx, [eax].RCBBufferLength      ; EDX = Buffer Length(IBM).
        xchg    dh, dl                          ; Convert to Intel format.
        sub     edx, ebx                        ; Subtract skip value.
        lea     esi, [eax][ebx].RCBFrameData    ; ESI -> Rx Buffer + Skip.
        mov     [ebp].RxBufferSize, edx         ; Save buffer size.

        mov     ebx, edi                        ; EBX -> 1st Frag structure.
        mov     edi, [ebx+0]                    ; EDI -> Frag offset.
        mov     ecx, [ebx+4]                    ; ECX =  Frag size.
        mov     [ebp].RCBSize, ecx              ; Save size.

        cmp     ecx, edx                        ; Too much?
        jg      RCBFragmentTooBig               ; Jump if so.
        sub     [ebp].RxBufferSize, ecx         ; Subtract copy amount.
        sub     [ebp].TotalBytes, ecx
        js      ReadNextFragOverrun
        mov     eax, ecx                        ; Save size.
        shr     ecx, 2                          ; Copy dwords.
        rep     movsd
        mov     cl, al                          ; CL = bytes.
        and     cl, 03                          ; Copy left over bytes.
        rep     movsb
        add     ebx, 8                          ; EBX -> Next Frag struct.
        dec     [ebp].RCBFragments              ; More RCB fragments?
        jne     short RxGetNextFragment         ; Jump if so.
ReturnRCBToMSM:
        mov     esi, [ebp].CurrentECB           ; ESI -> ECB.
if      UseFastCalls
        push    ebp
        call    TokenTSMFastRcvComplete         ; Give ECB back to LSL.
        pop     ebp
else
        call    TokenTSMRcvComplete             ; Give ECB back to LSL.
endif
;
;***************************************************************\
;                                                               *
; Give ASB Response to The Adapter.                             *
;                                                               *
;***************************************************************/
;
ReturnASBResponse:

        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        mov     al, [ebp].ASBPageValue          ; AL = ASB Page Value.
        mov     [ebx].RAMPageRegister, al       ; Set new page.
        mov     edi, [ebp].ASBBaseAddress       ; EDI -> ASB Base Address.

        test    word ptr [ebx].IntStatusToPC, (ADAPTER_CHECK_BIT SHL 8) + ADAPTER_ERROR_BIT
        jnz     short ASBReceiveDataExit        ; Exit if any Errors.
        cmp     [edi].ASBReturnCode, SRB_IN_PROCESS     ; ASB Free?
        jnz     ReturnASBResponse               ; Loop if not.
        lea     esi, [ebp].ARBSaveArea          ; ESI -> ASB Skeleton.

        movsd                                   ; Build The ASB Response.
        movsd
        movsd
        mov     [ebx].OROffset.IntStatusToAdapter+01, RESPONSE_IN_ASB
ASBReceiveDataExit:
        ret

ReadNextFragOverrun:
        add     ecx, [ebp].TotalBytes           ; ECX = bytes left.
        rep     movsb                           ; Copy remaining bytes.
        jmp     ReturnRCBToMSM                  ; We're finished.

RxGetNextFragment:
        mov     edi, [ebx+0]                    ; EDI -> ECB Buffer.
        mov     ecx, [ebx+4]                    ; ECX = Buffer size.
        mov     [ebp].RCBSize, ecx              ; Save size.
        mov     edx, [ebp].RxBufferSize         ; EDX = Leftover in Rx Buffer.
        or      edx, edx                        ; Any left in current buffer?
        jne     short RxNextCopy                ; Jump if so.
RxGetNextRxBuffer:
        mov     eax, [ebp].FirstRxBuffer        ; EAX = current buffer.
        movzx   eax, [eax].RCBNextBuffer        ; EAX = Next Buffer relative.
        xchg    al, ah                          ; Swap to intel.
        or      eax, eax                        ; Any more buffers?
        jz      ReturnRCBToMSM                  ; Finished. Return ECB.
        mov     esi, [ebp].AbsoluteMMIOAddress  ; ESI = BIOS/MMIO Domain @.
        mov     [esi].RAMPageRegister, ah       ; Set new page.
        and     ah, [ebp].PageSizeMask          ; AH = Relative Page.
        add     eax, [ebp].SharedRAMRelative    ; EAX -> New Buffer.
        movzx   edx, [eax].RCBBufferLength      ; EDX =  Rx Buffer size.
        xchg    dh, dl                          ; Convert to intel format
        mov     [ebp].RxBufferSize, edx         ; Save buffer size.
        lea     esi, [eax].RCBFrameData         ; ESI -> Rx Buffer.
        mov     [ebp].FirstRxBuffer, eax        ; Save current buffer.
RxNextCopy:
        cmp     ecx, edx                        ; Too much?
        jg      short RCBFragmentTooBig         ; Jump if so.

        sub     [ebp].RxBufferSize, ecx         ; Subtract copy amount.
        mov     eax, ecx                        ; Save size.
        sub     [ebp].TotalBytes, ecx
        js      ReadNextFragOverrun
        shr     ecx, 2                          ; Copy dwords.
        rep     movsd
        mov     cl, al                          ; CL = bytes.
        and     cl, 03                          ; Copy left over bytes.
        rep     movsb

        add     ebx, 8                          ; EBX -> Next Frag Structure.
        dec     [ebp].RCBFragments              ; Any more fragments?
        je      ReturnRCBToMSM                  ; Jump if not.
        jmp     short RxGetNextFragment         ; Jump if so.
;
;***************************************************************\
;                                                               *
; ECB fragment larger than Rx Buffer. Copy using Rx Buffer size.*
;                                                               *
;***************************************************************/
;
RCBFragmentTooBig:
        mov     ecx, edx                        ; ECX = Rx Buffer Size.
        sub     [ebp].RCBSize, edx              ; Update RCB Size.
        mov     eax, ecx                        ; Save it.
        sub     [ebp].TotalBytes, ecx
        js      ReadNextFragOverrun
        shr     ecx, 2                          ; Copy dwords.
        rep     movsd
        mov     cl, al                          ; CL = bytes.
        and     cl, 3                           ; Copy left over bytes.
        rep     movsb

        mov     ecx, [ebp].RCBSize              ; ECX = New RCB size.
        jmp     short RxGetNextRxBuffer         ; Try it again.
;
;***************************************************************\
;                                                               *
; We received an invalid ARB.                                   *
;                                                               *
;***************************************************************/
;
InvalidARBEntry:
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'd'
        call    OutChar
        mov     al, '0'
        call    OutChar
        pop     eax
endif
        inc     [ebp].UnknownARBCount           ; Update Statistic counter.
        jmp     ReturnASBResponse               ; Set up ASB.
;
;***************************************************************\
;                                                               *
; Process ARB 82h -- Transmit Data Request.                     *
;                                                               *
;***************************************************************/
;
InvalidTransmitARB:
if DEBUG
        int     3
endif
        inc     [ebp].BadCorrelatorCount        ; Update Statistic counter.
        jmp     ReturnASBResponse               ; Set up ASB.

ARBTransmitDataRequest:
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'd'
        call    OutChar
        mov     al, '2'
        call    OutChar
        pop     eax
endif
;
;***************************************************************\
;                                                               *
; ARB 82h - First see if we can set another SRB.                *
;                                                               *
;***************************************************************/
;
        and     [ebp].MLIDStatusFlag, NOT TX_IN_PROCESS_BIT
        call    CheckNextSRBCommand             ; Check for MORE SRB Commands.
;
;***************************************************************\
;                                                               *
; ARB 82h - Search for TCB with matching Correlator.            *
;                                                               *
;***************************************************************/
;
        mov     bl, [ebp].ARBSaveArea.ARBTxCorrelator   ; BL = Correlator Value.
        lea     ecx, [ebp-TCBDriverWS-TCBLink].TxInProcessHead
FindTCBLoop:
        mov     edx, ecx                        ; EDX -> Prev TCB.
        mov     ecx, [ecx].TCBDriverWS.TCBLink  ; ECX -> Next TCB.
        or      ecx, ecx
        jz      InvalidTransmitARB              ; Jump if end of queue.
        cmp     bl, [ecx].TCBDriverWS.TCBCorrelator     ; Correlator Match?
        jnz     FindTCBLoop                     ; Check next TCB if not.
        mov     [ebp].ARBSaveArea.ASBCommandCode, SRB_TX_DIR_FRAME
        mov     eax, [ecx].TCBDriverWS.TCBLink  ; Unlink from
        mov     [edx].TCBDriverWS.TCBLink, eax  ;  TxInProcessHead queue.
;
;***************************************************************\
;                                                               *
; ARB 82h - ECX -> TCB; Prepare to Move The Data.               *
;                                                               *
;***************************************************************/
;
        movzx   eax, word ptr [ebp].ARBSaveArea.ARBTxDHBAddress

        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebx].RAMPageRegister, ah       ; Set new page of Tx Buffer.
        and     ah, [ebp].PageSizeMask          ; Mask Page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM base.
        mov     edi, eax                        ; EDI -> Tx Buffer.
;
;***************************************************************\
;                                                               *
; ARB 82h - Move the header into the Shared RAM Tx Buffer.      *
;                                                               *
;***************************************************************/
;
        mov     edx, ecx                        ; EDX -> TCB.
        lea     esi, [edx].TCBMediaHeader       ; ESI -> TCB Header.
        mov     ecx, [edx].TCBMediaHeaderLen    ; ECX =  Header Length.

        cmp     [ebp].PageSizeMask, 0ffh        ; Paging?
        jnz     short MoveHeaderToPagedBuffers  ; Jump if Paging is Active.

        mov     al, cl                          ; Move The Data. AL = count.
        and     al, 03                          ; AL = count MOD 4.
        shr     ecx, 2                          ; ECX = count / 4.
        rep     movsd                           ; Move DWORDs.
        mov     cl, al                          ; ECX = count MOD 4.
        rep     movsb                           ; Move remaining bytes.
TxMoveFragments:
;
;***************************************************************\
;                                                               *
; ARB 82h - Move the fragments into the Shared RAM Tx Buffer.   *
;                                                               *
;***************************************************************/
;
        mov     ebx, [edx].TCBFragStrucPtr      ; EBX -> Fragment Count.
        mov     ecx, [ebx]                      ; ECX = Number of Fragments.
        add     ebx, 4                          ; EBX -> Fragment Descriptors.
        or      ecx, ecx
        jz      short EverythingDone            ; Jump if no fragments.
TxMoveFragmentLoop:
        push    ecx                             ; Save Fragment count.
        mov     ecx, [ebx+04]                   ; ECX = Size of Fragment
        mov     esi, [ebx+00]                   ; ESI = Fragment offset.

        cmp     [ebp].PageSizeMask, 0ffh                ; Paging?
        jnz     short MoveFragmentToPagedBuffers        ; Jump if Paging is Active.

        mov     al, cl                          ; Move The Data. AL = count.
        and     al, 03                          ; AL = count MOD 4.
        shr     ecx, 2                          ; ECX = count / 4.
        rep     movsd                           ; Move DWORDs.
        mov     cl, al                          ; ECX = count MOD 4.
        rep     movsb                           ; Move remaining bytes.
TxMoveNextFragment:

        pop     ecx                             ; ECX = Fragment count.
        add     ebx, 08                         ; EBX -> Next Fragment descriptor.
        loop    short TxMoveFragmentLoop        ; Copy next fragment.

EverythingDone:
        mov     eax, [edx].TCBDataLen           ; EAX = Data length
        xchg    ah, al
        mov     word ptr [ebp].ARBSaveArea.ASBFrameLength, ax

        mov     esi, edx                        ; ESI -> TCB.
        MSMGetCurrentTime                       ; EAX = Current Time.
        mov     [ebp].TxStartTime, eax          ; Store it for later.

if      UseFastCalls
        push    ebp
        call    TokenTSMFastSendComplete        ; Give it back to TCB.
        pop     ebp
else
        call    TokenTSMSendComplete            ; Give it back to TCB.
endif
        inc     [ebp].MSMTxFreeCount            ; NIC ready for packet?
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        jmp     ReturnASBResponse               ; Finished. Setup ASB.

MoveHeaderToPagedBuffers:
        push    offset TxMoveFragments          ; Return to this offset.
        jmp     MoveDataToPagedBuffers          ; Move the Header.
MoveFragmentToPagedBuffers:
        push    offset TxMoveNextFragment       ; Return to this offset.
        jmp     MoveDataToPagedBuffers          ; Move the Fragment.
;
;***************************************************************\
;                                                               *
; Process ARB 84h -- Ring.Status.Change                         *
;                                                               *
;***************************************************************/
;
ARBRingStatusRoutine:
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'd'
        call    OutChar
        mov     al, '3'
        call    OutChar
        pop     eax
endif
        movzx   ecx, word ptr [ebp].ARBSaveArea.RingNewStatus
        xchg    ch, cl                          ; AX = DLC/Ring.Status Code.
        mov     [ebp].LastRingStatus, ecx       ; Update Statistics.

        test    ch, RING_HARD_ERROR OR RING_TX_BEACON OR RING_LOBE_WIRE_FAULT OR RING_AUTO_REMOVE OR RING_REMOVE_RECEIVED
        jnz     short GenerateRingAlert         ; Jump if alert needed.
        test    cl, RING_SINGLE_STATION/256     ; Single Station Status.
        jnz     ARBReturn                       ; Exit if so.

        cmp     [ebp].LastErrorMessage, 0       ; Previous Alert cleared?
        je      ARBReturn                       ; Jump if not.
        mov     [ebp].LastErrorMessage, 0       ; Clear error message.
        lea     esi, AlertCorrectedMessage      ; ESI -> Message.
        call    UpdateAlertStats                ; Update proper stats.
        jmp     MSMAlertWarning                 ; Queue Alert and exit.

GenerateRingAlert:                              ; JCP, 941017 *Begin*
        lea     esi, LobeWireAtBoardMessage     ; ESI -> Lobe Wire message.
        test    ch, RING_LOBE_WIRE_FAULT        ; Removed from board?
        jnz     short ReInitSendRingAlert       ; Jump if so.

        lea     esi, RemoveMACFrameMessage      ; ESI -> Remove message.
        test    ch, RING_REMOVE_RECEIVED        ; Remove MAC Frame Error?
        jnz     short ReInitSendRingAlert       ; Jump if so.

        lea     esi, AutoRemoveMessage          ; ESI -> Auto Remove message.
        test    ch, RING_AUTO_REMOVE            ; Auto Remove Error?
        jnz     short ReInitSendRingAlert       ; Jump if so.

        lea     esi, RingBeaconMessage          ; ESI -> Tx Beacon message.
        test    ch, RING_TX_BEACON              ; Tx Beacon Error?
        jnz     SendRingAlert                   ; Jump if so.

;       jnz     RingAlertBeacon                 ; Jump if so.
;
;       lea     esi, AutoRemoveMessage          ; ESI -> Auto Remove message.
;       test    ch, RING_AUTO_REMOVE            ; Auto Remove Error?
;       jnz     short ReInitSendRingAlert       ; Jump if so.
;
;       lea     esi, LobeWireAtBoardMessage     ; ESI -> Lobe Wire message.
;       test    ch, RING_SIGNAL_LOSS            ; Removed from board?
;       jnz     short ReInitSendRingAlert       ; Jump if so.
                                                ; JCP, 941017 *End*
        lea     esi, RingBeaconMessage          ; if RING_RECOVERY && RING_HARD_ERROR
        test    cl, RING_RECOVERY/256           ; then don't reset, just wait around
        jnz     RingAlertBeacon                 ; because ring is beaconing.

        lea     esi, LobeWireAtMAUMessage       ; Disconnected at MAU.

ReInitSendRingAlert:
        or      [ebp].MLIDStatusFlag, RE_INIT_ADAPTER_BIT

SendRingAlert:
        cmp     esi, [ebp].LastErrorMessage     ; Same as last error?
        je      ARBReturn                       ; Jump if so.
        mov     [ebp].LastErrorMessage, esi     ; Save it for next time.
        mov     [ebp].CheckAlertTimer, 8        ; Check alert after 16 secs.
        call    UpdateAlertStats                ; Update proper stats.
        jmp     MSMAlertFatal                   ; Send Alert and exit.

RingAlertBeacon:
        mov     dl, [ebx].RAMPageRegister       ; AL = Old PAGE Register.
        mov     al, [ebp].AdapterParmsPageValue
        mov     [ebx].RAMPageRegister, al
        mov     edi, [ebp].AdapterParmsAddr     ; EDI -> Adapter parms.
        movzx   eax, [edi].ParmsBeaconTransmit  ; EAX = Tx beacon type.
        cmp     eax, 00000200h                  ; Type 2(Signal Loss)?
        je      ReInitSendRingAlert             ; Reset adapter if so.
        jmp     SendRingAlert                   ; Just send alert.

ARBReturn:
        ret

ARBRequestISR   endp
        subttl -- SRBResponseISR --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( SRBResponseISR, TOKEN/INTERNAL/SSBRESP )
;
; Name:         SRBResponseISR
;
; Description:  This routine handles Token-Ring SRB Response interrupts.
;
; On Entry:     EAX     N/A
;               EBX     @ BIOS/MMIO Domain @
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Shared RAM SRB
;               EDI     N/A
;
;               Note:   Interrupts are enabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the DriverISR.
;               It is called at interrupt time.
;
; See Also:     DriverISR
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
SRBResponseISR  proc    near
        mov     ecx, [ebp].TCBInProcess         ; ECX -> TCB In Process.
        or      ecx, ecx
        mov     [ebp].TCBInProcess, 0           ; Clear TCB In Process.
        jz      short ProcessSRBCommandCode     ; Jump if no TCB.
;
;***************************************************************\
;                                                               *
; Complete the In Process TCB.                                  *
;                                                               *
;***************************************************************/
;
        xchg    ecx, esi                        ; ESI -> TCB, ECX -> SRB.
if      UseFastCalls
        push    ebp
        push    ecx
        call    TokenTSMFastSendComplete        ; Give TCB back MSM.
        pop     ecx
        pop     ebp
else
        call    TokenTSMSendComplete            ; Give TCB back MSM.
endif
        inc     [ebp].MSMTxFreeCount            ; Ready for another packet.
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        mov     esi, ecx                        ; ESI -> Shared RAM SRB.
;
;***************************************************************\
;                                                               *
; Process the SRB Command Code.                                 *
;                                                               *
;***************************************************************/
;
ProcessSRBCommandCode:
        and     [ebp].MLIDStatusFlag, NOT SRB_IS_BUSY_BIT       ; Free the SRB.

        cmp     [esi].SRBCommand, SRB_DIR_READ_LOG
        jnz     short CheckForDIROpenAdapter    ; Jump if not DIRReadLog.
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'e'
        call    OutChar
        mov     al, '0'
        call    OutChar
        pop     eax
endif
;
;***************************************************************\
;                                                               *
; SRB 08h - ReadDIRLog.                                         *
;                                                               *
;***************************************************************/
;
        xor     eax, eax                        ; EAX = 0000 0000.

        mov     al, [esi+06+00]                 ; AL = Line Errors.
        add     [ebp].LineErrorCount, eax       ; Update stats.
        mov     al, [esi+06+01]                 ; AL = Internal Errors.
        add     [ebp].InternalErrorCount, eax   ; Update stats.
        mov     al, [esi+06+02]                 ; AL = Burst Errors.
        add     [ebp].BurstErrorCount, eax      ; Update stats.
        mov     al, [esi+06+03]                 ; AL = AC Errors.
        add     [ebp].ACErrorCount, eax         ; Update stats.
        mov     al, [esi+06+04]                 ; AL = Abort Delimiters.
        add     [ebp].AbortDelimiterCount, eax  ; Update stats.
        mov     al, [esi+06+06]                 ; AL = Lost Frames.
        add     [ebp].LostFrameCount, eax       ; Update stats.
        mov     al, [esi+06+07]                 ; AL = Receive Congestion.
        add     [ebp].PacketRxOverflowCount, eax
        mov     al, [esi+06+08]                 ; AL = Frame Copied Errors.
        add     [ebp].FrameCopiedErrorCount, eax
        mov     al, [esi+06+09]                 ; AL = Frequency Errors.
        add     [ebp].FrequencyErrorCount, eax  ; Update stats.
        mov     al, [esi+06+10]                 ; AL = Token Errors.
        add     [ebp].TokenErrorCount, eax      ; Update stats.

        jmp     CheckNextSRBCommand             ; See if SRB is free.

CheckForDIROpenAdapter:
        cmp     [esi].SRBCommand, SRB_OPEN_ADAPTER
ifdef BROUTER
        jnz     CheckConfigureBridge            ; Check Bridge if not Open.
else
        jnz     CheckNextSRBCommand             ; Exit if not OpenAdapter.
endif
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'e'
        call    OutChar
        mov     al, '1'
        call    OutChar
        pop     eax
endif
;
;***************************************************************\
;                                                               *
; SRB 03h - DIROpenAdapter.                                     *
;                                                               *
;***************************************************************/
;
        mov     [ebp].OpeningAdapter, 0         ; Opening adapter ? JCP, 941017.
        movzx   ecx, [esi].OpenSRBErrorCode     ; ECX = Error Code.
        xchg    ch, cl                          ; Convert to intel format.
        cmp     [esi].OpenSRBReturnCode, 0      ; Error Opening Adapter?
        mov     eax, [esi]
        jnz     DIROpenAdapterError             ; Jump if so.

;       mov     [ebp].OpeningAdapter, 0         ; Opening adapter ? JCP, 941017
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.

        movzx   eax, [esi].OpenASBAddress       ; EAX = ASB Offset.
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebp].ASBPageValue, ah          ; Store Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].ASBBaseAddress, eax       ; Store ASB Base Address.

        movzx   eax, [esi].OpenSRBAddress       ; EAX = SRB Offset.
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebp].SRBPageValue, ah          ; Store Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].SRBBaseAddress, eax       ; Store SRB Base Address.

        movzx   eax, [esi].OpenARBAddress       ; EAX = ARB Offset.
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebp].ARBPageValue, ah          ; Store Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].ARBBaseAddress, eax       ; Store ARB Base Address.

        movzx   eax, [esi].OpenSSBAddress       ; EAX = SSB Offset.
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebp].SSBPageValue, ah          ; Store Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].SSBBaseAddress, eax       ; Store SSB Base Address.

ifdef BROUTER
        cmp     [ebp].BrouterState, 0           ; BROUTER enabled?
        je      short DIROpenCheckFastPath      ; Jump if not

        mov     edi, [ebp].SRBBaseAddress       ; EDX -> SRB offset.
        mov     ah, [ebp].SRBPageValue          ; Switch to SRB page.
        mov     [ebx].RAMPageRegister, ah
        mov     ecx, 15                         ; Copy SetBridgeParms.
        lea     esi, [ebp].BParmsCommand
        rep     movsb

        mov     [ebx].IntStatusToAdapter+01, COMMAND_IN_SRB
        or      [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Set busy flag.

        jmp     short DIROpenSetFunctional
DIROpenCheckFastPath:
endif
        test    [ebp].InitStatus, INIT_FAST_PATH        ; Fast Path?
        je      short DIROpenSetFunctional              ; Jump if not.

        mov     al, [ebp].TxPageValue
        mov     [ebx].RAMPageRegister, al               ; Set new page.
        mov     edi, [ebp].TxBaseAddress
        movzx   eax, [edi].FPCompletionQTail            ; Save Completion
        mov     [ebp].CompletionQHead, eax              ;  Queue Tail.
        mov     [ebp].TxCorrelator, 0                   ; Init correlator.

DIROpenSetFunctional:
;;      or      [ebp].MLIDStatusFlag, DIR_FUNCTIONAL_BIT
        call    TokenTSMUpdateMulticast
        call    UpdateAlertStats                ; Update proper stats.
        cmp     [ebp].LastErrorMessage, 0       ; Previous alert occured?
        je      CheckNextSRBCommand             ; Jump if not.
        mov     [ebp].LastErrorMessage, 0       ; Clear previous alert.
        lea     esi, AlertCorrectedMessage      ; ESI -> Message.
        call    MSMAlertWarning                 ; Queue message.
        jmp     CheckNextSRBCommand             ; Check For SRB Busy.
;
;***************************************************************\
;                                                               *
; SRB 03h - DIROpenAdapter failed.                              *
;                                                               *
;***************************************************************/
;
DIROpenAdapterError:
        cmp     [esi].SRBReturnCode, SRB_COMMAND_CANCELLED
        mov     ch, cl                          ; Save error code.
        lea     esi, DIROpenFailedMessage       ; ESI -> Error message.
        jnz     short DIROpenSendAlert          ; Jump if no error codes.
;
;***************************************************************\
;                                                               *
; ECX contains a valid Error Code. Find out what happened.      *
;                                                               *
;***************************************************************/
;
        and     cl, 0Fh                         ; Mask error code.

        lea     esi, DIROpenDuplicateMessage    ; ESI -> Duplicate message.
        cmp     cl, OPEN_ERROR_NODE             ; Duplicate Station?
        jz      short DIROpenSendAlert          ; Jump if so.

        lea     esi, DIROpenRemoveMessage       ; ESI -> Remove message.
        cmp     cl, OPEN_ERROR_REMOVED          ; Remove MAC?
        jz      short DIROpenReInitAdapter      ; Jump if so.

        lea     esi, DIROpenLobeWireMessage     ; ESI -> Lobe Wire message.
        cmp     cl, OPEN_ERROR_FUNCTION         ; Lobe Wire Fault?
        jz      short DIROpenReInitAdapter      ; Jump if so.

        lea     esi, DIROpenFailedMessage       ; ESI -> Failed message.
        cmp     cl, OPEN_ERROR_BEACONING        ; Ring Beaconing?
        jnz     short DIROpenSendAlert          ; Jump if not.
        lea     esi, DIROpenBeaconMessage       ; ESI -> Beaconing message.

DIROpenReInitAdapter:
        or      [ebp].MLIDStatusFlag, RE_INIT_ADAPTER_BIT

DIROpenSendAlert:
        movzx   ecx, ch                         ; ECX = Error code.
        cmp     esi, [ebp].LastErrorMessage     ; Same as last error message?
        je      CheckNextSRBCommand             ; Jump if so.
        mov     [ebp].LastErrorMessage, esi     ; Save message pointer.
        mov     [ebp].CheckAlertTimer, 8        ; Check alert after 16 secs.
        call    UpdateAlertStats                ; Update proper stats.
        push    offset CheckNextSRBCommand      ; Return to this routine.
        jmp     MSMAlertWarning                 ; Send Alert and exit.

ifdef BROUTER
CheckConfigureBridge:
        cmp     [esi].SRBCommand, SRB_CONFIGURE_BRIDGE
        jnz     CheckSetBridge                  ; Jump if not config bridge.

if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'e'
        call    OutChar
        mov     al, '2'
        call    OutChar
        pop     eax
endif
        movzx   ecx, [esi].BSRBReturnCode       ; ECX = Error Code.
        xchg    ch, cl                          ; Convert to intel format.
        or      ecx, ecx                        ; Successful?
        movzx   edi, [esi].BSRBTxOffset
        movzx   eax, [esi].BSRBSRBAddress       ; EAX = offset of new SRB.
        lea     esi, BridgeConfigMessage        ; ESI -> Alert Message.
        jne     DIROpenReInitAdapter            ; Jump if not.

        mov     ecx, edi
        xchg    ch, cl
        mov     [ebp].TxPageValue, ch
        and     ch, [ebp].PageSizeMask
        add     ecx, [ebp].CommonLinearMemory0
        mov     [ebp].TxBaseAddress, ecx

        xchg    ah, al                          ; AX = SRB Offset.
        mov     [ebp].SRBPageValue, ah          ; Save SRB Page.
        mov     [ebx].RAMPageRegister, ah       ; Set new page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].CommonLinearMemory0  ; Add Base Offset.
        mov     [ebp].SRBBaseAddress, eax       ; Store SRB Base Address.

        mov     ecx, SIZE OpenAdapterStructure / 04     ; Copy OpenAdapter
        mov     edi, eax                                ;  Image to SRB.
        lea     esi, [ebp].DIROpenAdapter
 rep    movsd

        lea     edi, [eax].OpenNodeAddress              ; Fill in OpenAdapter
        lea     esi, [ebp].CommonNodeAddress            ;  Node Address.
        movsd
        movsw
        mov     [ebx].IntStatusToAdapter+01, COMMAND_IN_SRB
        or      [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Set busy flag.

        jmp     CheckNextSRBCommand

CheckSetBridge:
        cmp     [esi].SRBCommand, SRB_SET_BRIDGE
        jnz     CheckNextSRBCommand             ; Exit if not Set bridge.

if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'e'
        call    OutChar
        mov     al, '3'
        call    OutChar
        pop     eax
endif
        movzx   ecx, [esi].BSRBReturnCode       ; ECX = Error Code.
        xchg    ch, cl                          ; Convert to intel format.
        or      ecx, ecx                        ; Successful?
        lea     esi, BridgeParmsMessage         ; ESI -> Alert Message.
        jne     DIROpenReInitAdapter            ; Jump if not.

        jmp     CheckNextSRBCommand
endif

SRBResponseISR  endp

        align   16
UpdateAlertStats        proc

if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'f'
        call    OutChar
        pop     eax
endif
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        mov     dl, [ebx].RAMPageRegister       ; AL = Old PAGE Register.
        mov     al, [ebp].AdapterParmsPageValue
        mov     [ebx].RAMPageRegister, al
        mov     edi, [ebp].AdapterParmsAddr     ; EDI -> Adapter parms.
        mov     eax, dword ptr [edi].ParmsUPNodeAddr+0
        mov     [ebp].UpstreamNodeHighDword, eax
        movzx   eax, word ptr [edi].ParmsUPNodeAddr+4
        mov     [ebp].UpstreamNodeLowWord, eax
        movzx   eax, [edi].ParmsLocalRing
        mov     [ebp].LastRingID, eax
        movzx   eax, [edi].ParmsBeaconType
        mov     [ebp].LastBeaconType, eax
        mov     [ebx].RAMPageRegister, dl
        ret

UpdateAlertStats        endp

        subttl -- SSBResponseISR --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( SSBResponseISR, TOKEN/INTERNAL/SSBRESP )
;
; Name:         SSBResponseISR
;
; Description:  This routine handles Token-Ring SSB Response interrupts.
;
; On Entry:     EAX     N/A
;               EBX     @ BIOS/MMIO Domain @
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Shared RAM SSB
;               EDI     N/A
;
;               Note:   Interrupts are enabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts enabled.
;
; Remarks:      This routine is called by the DriverISR.
;               It is called at interrupt time.
;
; See Also:     DriverISR
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
SSBResponseISR  proc    near            ;Token-Ring SSB Response Interrupt
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'g'
        call    OutChar
        pop     eax
endif
        mov     [ebx].OROffset.IntStatusToAdapter+01, SSB_FREE
        ret

SSBResponseISR  endp                    ;Token-Ring SSB Response Interrupt
        subttl -- CheckNextSRBCommand --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( CheckNextSRBCommand, TOKEN/INTERNAL/CHECKSRB )
;
; Name:         CheckNextSRBCommand
;
; Description:  This routine will check the status of the SRB. If it is
;               busy, it will check its status. If its not in process, it
;               will exit. Otherwise see if we need to send another command
;               to the adapter in the following order:
;                       1) New Functional Address.
;                       2) Read Error Log.
;                       3) A transmit queued within the driver is ready.
;                       4) Check MSM's transmit queue.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are in any state.
;
; On Return:    EAX     0
;               EBX     @ BIOS/MMIO Domain
;               ECX     Destroyed
;               EDX     @ Shared RAM SRB
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the Driver.
;               It is called at process or interrupt time.
;
; See Also:
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
CheckNextSRBCommand     proc
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'h'
        call    OutChar
        pop     eax
endif
        mov     ebx, [ebp].AbsoluteMMIOAddress          ; EBX -> BIOS/MMIO.
        movzx   ecx, [ebx].RAMPageRegister              ; CL = Current Page.
        mov     al, [ebp].SRBPageValue                  ; AL = SRB Page.
        mov     [ebx].RAMPageRegister, al               ; Set new page.
        mov     edx, [ebp].SRBBaseAddress               ; EDX -> RAM SRB.
;
;***************************************************************\
;                                                               *
; Exit immediately if there is nothing to do!                   *
;                                                               *
;***************************************************************/
;
        test    [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT OR DIR_FUNCTIONAL_BIT OR DIR_READ_LOG_BIT
        jnz     short ServiceSRB
        test    [ebp].MLIDStatusFlag, TX_IN_PROCESS_BIT ; SRB must be free.
        jz      short CheckForAnotherSend               ; Jump if no send in process.

CheckNextSRBExit:
        mov     [ebx].RAMPageRegister, cl       ; CL = OLD Page Register Value
        ret                                             ; Return if Nothing
;
;***************************************************************\
;                                                               *
; One of four conditions are present:                           *
;       1) SRB is busy.                                         *
;               (Exit immediately if command is not in process).*
;       2) DIRSetFunctionAddress has been requested.            *
;               (Setup SRB if it is free and exit).             *
;       3) DIRReadLog has been requested.                       *
;               (Setup SRB if it is free and exit).             *
;                                                               *
;***************************************************************/
;
ServiceSRB:
        test    [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Is SRB Busy?
        jz      short CheckFunctionalAddressFlag        ; Jump if not.
        cmp     [edx].SRBReturnCode, SRB_IN_PROCESS     ; In Process?
        jnz     CheckNextSRBExit                        ; Exit if it is not.
;
;***************************************************************\
;                                                               *
; The SRB has Returned an In-Process Return Code.               *
;                                                               *
;***************************************************************/
;
        mov     edi, [ebp].TCBInProcess         ; EDI -> Waiting TCB.
        or      edi, edi                        ; TCBs waiting?
        je      short CheckFunctionalAddressFlag
        mov     [ebp].TCBInProcess, 0           ; No TCB waiting.
        lea     eax, [ebp].TxInProcessHead      ; EAX -> In Process Q.
EndOfQueueLoop:
        mov     esi, eax                        ; ESI -> Previous TCB.
        mov     eax, [eax].TCBDriverWS.TCBLink  ; EAX -> Next TCB.
        or      eax, eax                        ; End of Queue?
        jnz     EndOfQueueLoop                  ; Look For End of Queue.
        mov     [esi].TCBDriverWS.TCBLink, edi  ; EnQueue to Queue Tail.
        mov     [edi].TCBDriverWS.TCBLink, eax
        mov     al, [edx].SRBCMDCorrelate       ; Save Correlator Value.
        mov     [edi].TCBDriverWS.TCBCorrelator, al
        and     [ebp].MLIDStatusFlag, NOT SRB_IS_BUSY_BIT
CheckFunctionalAddressFlag:
        test    [ebp].MLIDStatusFlag, DIR_FUNCTIONAL_BIT OR DIR_READ_LOG_BIT
        jnz     short SetFunctionalOrReadLog

        test    [ebp].MLIDStatusFlag, TX_IN_PROCESS_BIT ; SRB must be free.
        jnz     CheckNextSRBExit                        ; Exit if TxInProcess.
;
;***************************************************************\
;                                                               *
; Check the Wait Queue for More SRB Commands.                   *
;                                                               *
;***************************************************************/
;
CheckForAnotherSend:
        mov     [ebx].RAMPageRegister, cl       ; Restore Page.
        test    [ebp].InitStatus, INIT_FAST_PATH
        jne     short CheckSendsExit

        mov     esi, [ebp].SendQueueHead        ; ESI -> Internal send queue.
        or      esi, esi                        ; Any sends on queue.
        jz      short CheckMSMsQueue            ; Jump if not.

        mov     eax, [esi].TCBDriverWS.TCBLink  ; EAX -> Next TCB.
        mov     [esi].TCBDriverWS.TCBLink, 0    ; ESI is unlinked.
        mov     [ebp].SendQueueHead, eax        ; Head -> Next TCB.

        jmp     DriverStartSend                 ; Start the send.

CheckMSMsQueue:

        call    TokenTSMGetNextSend             ; Any more TCB's?
        jz      DriverSend                      ; Jump if so.
CheckSendsExit:
        ret                                     ; Return if nothing to send.

SetFunctionalOrReadLog:

        test    [ebp].MLIDStatusFlag, DIR_FUNCTIONAL_BIT
        jz      short FunctionalAddressNotSet
;
;***************************************************************\
;                                                               *
; Set DIR.Set.Functional.Address.                               *
;                                                               *
;***************************************************************/
;
        and     [ebp].MLIDStatusFlag, NOT DIR_FUNCTIONAL_BIT    ; Reset flag.
        mov     eax, [ebp].FunctionalAddress            ; EAX = Functional
        or      eax, OPEN_FUNCTIONAL_ADDR               ;  address.
        mov     [edx].SRBFunctionalAddress, eax         ; Store into image.

        mov     [edx].SRBCommand, SRB_DIR_SET_FUNC_ADDR ; Set Command Code.
        mov     [edx].SRBReturnCode, SRB_NOT_PROCESSED  ; Set Return Code.
        mov     [ebx].OROffset.IntStatusToAdapter+01, COMMAND_IN_SRB
        or      [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Set Busy flag.
        jmp     CheckNextSRBExit

FunctionalAddressNotSet:
;
;***************************************************************\
;                                                               *
; Set the DIR.Read.Log Function.                                *
;                                                               *
;***************************************************************/
;
        and     [ebp].MLIDStatusFlag, NOT DIR_READ_LOG_BIT      ; Reset flag.
        mov     [edx].SRBCommand, SRB_DIR_READ_LOG      ; Set Command Code.
        mov     [edx].SRBReturnCode, SRB_NOT_PROCESSED  ; Set Return Code.
        mov     [ebx].OROffset.IntStatusToAdapter+01, COMMAND_IN_SRB
        or      [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Set Busy flag.
        jmp     CheckNextSRBExit

CheckNextSRBCommand     endp
        subttl -- MoveDataToPagedBuffers --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( MoveDataToPagedBuffers, TOKEN/INTERNAL/MOVEDATA )
;
; Name:         MoveDataToPagedBuffers
;
; Description:  This routine transfers data pointed to by ESI to DHB address
;               pointed to by EDI checking for page overflows and moves data
;               in sections if a transfer is going to cross a 16k boundary.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     Number of Bytes to Move
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Source Data
;               EDI     @ Current Transmit Buffer
;
;               Note:   Interrupts are in any state.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     0
;               EDX     Preserved
;               EBP     Preserved
;               ESI     @ Next Source Data
;               EDI     @ Next Transmit Buffer
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by ARBRequestISR.
;               It is called at interrupt time.
;
; See Also:     DriverISR
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
MoveDataToPagedBuffers  proc
if DEBUG
        push    eax
        mov     al, 'I'
        call    OutChar
        mov     al, 'i'
        call    OutChar
        pop     eax
endif
;
;***************************************************************\
;                                                               *
; Paging Is Active - Check For Page Overflow.                   *
;                                                               *
;***************************************************************/
;
MoveDataLoop:
        lea     eax, 00[edi][ecx]               ; EAX -> End of Dest.
        sub     eax, [ebp].SharedRAMRelative    ; Subtract Base Address.
        test    ah, [ebp].PagingMask            ; Page OverFlow?
        jnz     short MoveDataPageOverflow      ; Jump if so.
MoveDataInDWORDs:
        mov     al, cl                          ; Move The Data. AL = count.
        and     al, 03                          ; AL = count MOD 4.
        shr     ecx, 2                          ; ECX = count / 4.
        rep     movsd                           ; Move DWORDs.
        mov     cl, al                          ; ECX = count MOD 4.
        rep     movsb                           ; Move remaining bytes.
        ret
;
;***************************************************************\
;                                                               *
; The transfer will cross a 16K(4000h) boundary.                *
; EAX = End of destination - Base address.                      *
;                                                               *
; Example :     EDI  = 000D8800h                                *
;               ECX  = 00006000h                                *
;               Base = 000D8000h                                *
;               EAX = (D8800h + 6000h) - D8000h = 0006800h      *
;                                                               *
;***************************************************************/
;
MoveDataPageOverflow:
        push    ebx                             ; Save EBX.
        sub     eax, ecx                        ; EAX = Bytes not in this page.
        mov     ebx, [ebp].PageSize             ; EBX = 4000h/8000h.
        sub     ebx, eax                        ;     - EAX.
        xchg    ebx, ecx                        ; ECX = EBX.
        sub     ebx, ecx                        ; EBX = Total Bytes - ECX.
;
;***************************************************************\
;                                                               *
; Example:      ECX = 4000h - (6800h - 6000h) = 3800h           *
;               EBX = 6000h - 3800h = 2800h                     *
;                                                               *
;***************************************************************/
;
        mov     al, cl                          ; Move The Data. AL = count.
        and     al, 03                          ; AL = count MOD 4.
        shr     ecx, 2                          ; ECX = count / 4.
        rep     movsd                           ; Move DWORDs.
        mov     cl, al                          ; ECX = count MOD 4.
        rep     movsb                           ; Move remaining bytes.
;
;***************************************************************\
;                                                               *
; Adjust EDI and ECX to fill next page.                         *
; Example:      EDI = DC000h - 4000h = D8000h                   *
;               ECX = EBX = 2800h                               *
;                                                               *
;***************************************************************/
;
        sub     edi, [ebp].PageSize             ; EDI -> RAM Base.
        mov     ecx, ebx                        ; ECX = EBX.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        mov     eax, [ebp].PageSize             ; EAX = Page Size
        shr     eax, 8                          ;  / 256.
        pop     ebx                             ; Restore EBX.
        jmp     short MoveDataLoop              ; Go move more data.

MoveDataToPagedBuffers  endp
        subttl -- DriverCallBack --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverCallBack, TOKEN/API/CALLBACK )
;
; Name:         DriverCallBack
;
; Description:  This routine sets a flag to issue a DIR.READ.LOG command
;               the next time an SRB is free.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the MSM.
;               After this call returns, the MSM will schedule another
;               Call Back.
;               It is called at interrupt time.
;
; Note:         Fixed this function to clean up Tx Queue.  It needs to call
;               TokenTSMGetNextSend after using DriverReset. (JCP, 940901)
;
; See Also:     MSM\MSMCallBackProcedure
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
        align   16
DriverCallBack  proc

if DEBUG
        push    eax
        mov     al, 'C'
        call    OutChar
        pop     eax
endif
        cmp     [ebp].InDriverReset, 0          ;In Reset Mode ?
        jnz     short ExitDriverCallBack        ;Non-Zero, Yes.

        cmp     [ebp].OpeningAdapter, 0         ;Opening adapter ?
        jnz     short ExitDriverCallBack        ;Non-Zero, Yes.

        mov     ecx, [ebp].TxStartTime          ;Any transmits active?
        jecxz   short CheckQDepth               ;Jump if not.

        MSMGetCurrentTime                       ;EAX = Current Time.
        sub     eax, ecx                        ;EAX = Current Time - TxStartTime.

;        cmp     eax, 36                         ;More than 2 seconds passed?
        cmp     eax, 90                         ;More than 5 seconds passed?
        jg      short GoToResetAndCounter       ;Process timeout if so.

        test    [ebp].MLIDStatusFlag, RE_INIT_ADAPTER_BIT
        jnz     short GoToReset

ResumeAction:
        or      [ebp].MLIDStatusFlag, DIR_READ_LOG_BIT  ; Force a Read Log.
        dec     [ebp].CheckAlertTimer           ;Decrement flag.
        jne     CheckNextSRBCommand             ;Check for clear SRB.

        cmp     [ebp].LastErrorMessage, 0       ;Previous alert occured?
        je      CheckNextSRBCommand             ;Jump if not.

        mov     [ebp].LastErrorMessage, 0       ;Clear previous alert.
        lea     esi, AlertCorrectedMessage      ;ESI -> Message.
        call    UpdateAlertStats                ;Update proper stats.
        call    MSMAlertWarning                 ;Queue message.
        jmp     CheckNextSRBCommand

ExitDriverCallBack:                             ;
        mov     [ebp].TxStartTime, 0            ;Set Tx no longer active.
        ret                                     ;Return.

;***************************************************************\
;                                                               *
; Transmit has been hanging around too long, reset adapter.     *
;                                                               *
;***************************************************************/

DidntGetTxCompleteInterrupt:

if DEBUG
        push    eax
        mov     al, 'X'
        call    OutChar
        pop     eax
endif

CheckQDepth:
        test    [ebp].MLIDStatusFlag, RE_INIT_ADAPTER_BIT
        jnz     short GoToReset                 ;Non-zero, reset the card.

        cmp     [ebp].QDepth, 1                 ;Packet in Tx Queue ?
        jb      short ResumeAction              ;Below, Don't care.

        cmp     [ebp].QDepth, 2                 ;Packet in Tx Queue ?
        jz      short StartQueuedTwo            ;Equal, Increment counter.

StartQueued:
        cmp     [ebp].MSMTxFreeCount, 0         ;Any more resources ?
        jnz     short DoNotIncCounter           ;Non-zero, yes.

        inc     [ebp].TxFreeCountZero           ;Increment counter.

DoNotIncCounter:
        MSMGetCurrentTime                       ;EAX = Current Time.
        mov     [ebp].TxStartTime, eax          ;Store it for later.
        jmp     short ResumeAction              ;Continue the action.

GoToResetAndCounter:
        inc     [ebp].TxFreeCountZeroAndReset   ;Increment counter.

GoToReset:
   inc     [ebp].CardIsDead                ;Network card is dead.
        mov   eax, OP_SCOPE_ADAPTER
        call    DriverReset                     ;Hard reset the card.

        call    TokenTSMGetNextSend             ;Any more TCB's?
        jnz     short DoNotSend                 ;Jump if so.

        inc     [ebp].DriverSendCount           ;Increment counter.
        push    ebp                             ;Save EBP.
        call    [ebp].DriverSendPointer         ;Send packet.
;       call    DriverSend
        pop     ebp                             ;Retrieve EBP.

DoNotSend:
        mov     [ebp].TxStartTime, 0            ;Set Tx no longer active.
        jmp     CheckNextSRBCommand             ;

StartQueuedTwo:
        inc     [ebp].QDepthEqualTwo            ;Increment counter.
        jmp     short StartQueued               ;Start queue.

DriverCallBack  endp
        subttl -- DriverInit --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverInit, TOKEN/API/INIT )
;
; Name:         DriverInit
;
; Description:  This routine will call TokenTSMRegisterHSM,
;               MSMParseDriverParameters, MSMRegisterHardwareOptions,
;               MSMSetHardwareInterrupt, MSMRegisterMLID, initialize
;               variables in the Adapter Data Space and reset/initialize
;               the card.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     N/A
;               EDX     N/A
;               EBP     N/A
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are enabled.
;
; On Return:    EAX     0 if successful(otherwise it points to error message)
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Preserved
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the OS at load time.
;               It is called at process time.
;
; See Also:     MSM\MSMParseDriverParameters
;               MSM\MSMRegisterHardwareOptions
;               MSM\MSMSetHardwareInterrupts
;               MSM\MSMRegisterMLID
;               MSM\MSMScheduleIntTimeCallBack
;               MSM\MSMScheduleAESCallBack
;               MSM\MSMEnablePolling
;               DriverReset
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
DriverInit      proc
        CPush
;
;***************************************************************\
;                                                               *
; Fill in Driver Parameter Block fields.                        *
;                                                               *
;***************************************************************/
;
        mov     DriverStackPointer, esp                 ; Fill in stack ->.
        lea     esi, DriverParameterBlock               ; ESI -> Parm block.
        call    TokenTSMRegisterHSM                     ; Get EBX.
        jnz     DriverInitError                         ; Jump if error.

        call    TokenTSMGetASMHSMIFLevel
        cmp     eax, 230
        mov     ecx, eax
        lea     eax, LevelErrorMsg
        jb      DriverInitResetError            ; Jump if wrong TSM level.
;
;***************************************************************\
;                                                               *
; Find out if we are executing on a Micro-channel bus.          *
;       EAX =   00 if ISA, 01 if MCA or 02 if EISA.             *
;                                                               *
;***************************************************************/
;
;
;  09/14/95 MPK Spec 3.3 changes
;
   push    ebx                              ; Save EBX we will need it
        mov     esi,-1                           ; Set Parameter for call
S33_Bus_Scan:
        call    MSMScanBusInfo                   ; Find out about Bus
        cmp     eax,ODI_NBI_SUCCESSFUL           ; are we done?
   jne     S33_Bus_Scan_Done                ; Yes, exit

; Are we dealing with MCA?
        cmp     ecx,ODI_BUSTYPE_MCA              ; is this MCA, 
   jne     S33_Bus_Scan_Cont                ; no, then look for ISA
        pop     ebx                              ; Yes, then place tag in param table
   mov     [ebx].MLIDBusTag,edx             ; Tag in edx goes into location
        jmp     DriverInitMCA                    ; Jump on to checking

;If not, are we dealing with ISA?
S33_Bus_Scan_Cont:
        cmp     ecx,ODI_BUSTYPE_ISA              ; is this ISA, 
   jne     S33_Bus_Scan                     ; no, then keep looking
        pop     ebx                              ; Yes, then place tag in param table
;JCJ 03-July-97 SPD#160760
        mov     [ebx].MLIDBusTag, 00             ; All legacy ISA drivers have BusTag0
;JCJ 03-July-97
        push    ebx                              ; Keep BX straight
        jmp     S33_Bus_Scan                     ; Keep cycling (for completeness)

S33_Bus_Scan_Done:
        pop     ebx                              ; Now we can restore EBX for good
;
;  09/14/95 MPK Spec 3.3 changes End

;        MSMGetHardwareBusType           ; EAX = Bus Type.
;        test    al, 01                  ; Micro-Channel?
;        jnz     DriverInitMCA           ; Jump if so.
;
;***************************************************************\
;                                                               *
; The following code is executed if Bus type if ISA or EISA.    *
; Let MSM Parse the command line.                               *
;                                                               *
;***************************************************************/
;
        mov     eax, NeedsIOPort0Bit OR CAN_SET_NODE_ADDRESS
        lea     ecx, AdapterOptions
        call    MSMParseDriverParameters
        jnz     DriverInitError                         ; Jump if error.
;
;***************************************************************\
;                                                               *
; Release Adapter Reset to Prepare to Read MMIO Area.           *
;                                                               *
;***************************************************************/
;
        movzx   edx, [ebx].MLIDIOPortsAndLengths        ; EAX = I/O Base.
        lea     edx, [edx].ReleaseAdapterReset  ; EDX = Release Reset Port.
        out     dx, al                          ; Release Adapter Reset.
        mov     ecx, 0FC01h                     ; ECX = Segment Mask
        dec     edx                             ; EDX = Setup Read 1 Port.
        dec     edx
;
;***************************************************************\
;                                                               *
; Decode the Interrupt Level and the BIOS/MMIO Domain Address.  *
;                                                               *
;***************************************************************/
;
        in      al, dx                  ; AL = BIOS/MMIO & Interrupt Jumper.
        and     ch, al                  ; ECX = BIOS/MMIO Domain * 02.
        and     al, 03                  ; Mask out BIOS/MMIO.
        mov     ah, al                  ; AH = Interrupt Level.
        shl     al, 01                  ; AL = Interrupt Level * 02.
        or      al, ah                  ; AL = Interrupt Level 00, 02, 06, or 07.
        or      al, 02                  ; AL = Interrupt Level 02, 02, 06, or 07.

        mov     [ebx].MLIDInterrupt, al ; Save Interrupt Level.
        ror     cx, 01                  ; ECX = BIOS/MMIO Jumper / 2.
        shl     ecx, 04                 ; ECX = BIOS/MMIO Domain Absolute.

        mov     [ebx].MLIDMemoryDecode1, ecx
;
;***************************************************************\
;                                                               *
; Check For Default Shared RAM Address.                         *
;                                                               *
;***************************************************************/
;
        mov     eax, [ebx].MLIDMemoryDecode0    ; EAX = Shared RAM in Config.
        or      eax, eax                        ; Shared RAM specified?
        jnz     short SharedRAMSet              ; Jump if so.
        mov     al, DEFAULT_RAM_SEGMENT + LOW PRIMARY_PIO
        sub     al, byte ptr [ebx].MLIDIOPortsAndLengths
        shl     eax, 03*04                      ; EAX -> Default Shared RAM.
        mov     [ebx].MLIDMemoryDecode0, eax    ; Save Shared RAM address.
SharedRAMSet:

        lea     esi, [ecx].RAMRelocationRegister + 01
        lea     edi, [ebx].MLIDLength0
        mov     ecx, 1                          ; Read 1 byte.
        call    MSMReadPhysicalMemory
        mov     cl, byte ptr [ebx].MLIDLength0
        and     ecx, SHARED_RAM_MASK
        shr     ecx, 02
        mov     ch, [ecx].RAMSizeTable
        xor     cl, cl
        mov     [ebx].MLIDLength0, cx

;
;***************************************************************\
;                                                               *
; Let MSM Register the hardware options.                        *
;                                                               *
;***************************************************************/
;
        call    MSMRegisterHardwareOptions
        cmp     eax, 1                                  ; New Frame?
        je      DriverInitExit                          ; Exit if so
        ja      DriverInitError                         ; Jump if error.
;
;***************************************************************\
;                                                               *
; Initialize Common hardware variables.                         *
;                                                               *
;***************************************************************/
;
        movzx   eax, [ebx].MLIDInterrupt        ; EAX = Interrupt Level.
        cmp     al, 9
        jne     short SetInterruptReset
        mov     al, 2
SetInterruptReset:
        add     eax, RESET_IRQ_PORT             ; EAX = Re-Arm Interrupt Port.
        mov     [ebp].InterruptResetLevel, eax  ; Save Reset Level.

        mov     esi, OFFSET PCBus               ; ESI -> PC Bus Signature.
;
;***************************************************************\
;                                                               *
; Both ISA/EISA and MCA bus initializations end up here.        *
; EBX -> Config Table(Frame Data Space)                         *
; EBP -> Adapter Data Space.                                    *
; ESI -> Bus Signature string.                                  *
;                                                               *
;***************************************************************/
;
DriverInitReEntry:
        movzx   eax, [ebx].MLIDIOPortsAndLengths        ; EAX = Base I/O Port.
        mov     [ebp].CommonIOPort, ax          ; Save in adapters memory.
        sub     al, LOW PRIMARY_PIO             ; AL = 0h or 4h.
        jz      short AdapterPIOSet             ; Jump if Primary Adapter.
        inc     [ebp].BoardNumber               ; BoardNumber = 1.
AdapterPIOSet:

        mov     edi, [ebx].MLIDLinearMemory1    ; EDI -> Absolute BIOS/MMIO.
        mov     [ebp].AbsoluteMMIOAddress, edi  ; Save it.

        mov     ecx, SIZE MicroChannelSignature ; ECX = Bus Signature Size.
;
;***************************************************************\
;                                                               *
; Compare the Signature in ESI with The MMIO Signature at 1F30h *
;                                                               *
;***************************************************************/
;
        lea     edx, [edi].SignatureOffset-02   ; EDX -> Signature - 2.
VerifySignatureLoop:
        inc     edx                             ; Read Even Bytes.
        inc     edx
        lodsb                                   ; AL = Next Compare Value.
        sub     al, 00[edx]                     ; AL = AL - Signature Value.
        and     al, 15                          ; Isolate Low Order Nibble.
        loopz short VerifySignatureLoop         ; Loop if Valid.
ErrorFindingSlot:
        mov     eax, offset ErrorFindingCardMessage     ; EAX->Error Message.
        jnz     DriverInitResetError                    ; Exit init.
;
;***************************************************************\
;                                                               *
; Verify that Shared RAM is on the correct Boundary.            *
;                                                               *
;***************************************************************/
;
        mov     edx, [ebx].MLIDMemoryDecode0    ; EDX -> Shared RAM Segment.
VerifySharedRAM:
        mov     ecx, SHARED_RAM_MASK            ; CL = RAM Size Mask(0Ch)
        and     cl, [edi].RAMRelocationRegister + 01
        shr     ecx, 02                 ; ECX = Shared RAM Size / 04.
        mov     cl, [ecx].RAMSizeTable  ; ECX = Shared RAM Size from table.
        shl     ecx, 03*04              ; ECX = Shared RAM Size.
        dec     ecx                     ; ECX = Shared RAM Size - 1.
        test    edx, ecx                ; Boundaries crossed?
ErrorRAMFailed:
        mov   eax,OFFSET ErrorRAMFailedMessage  ; ESI -> Error Message.
ErrorFindingCard:
        jnz   DriverInitResetError      ; Incorrect Boundary Jump.
;
;***************************************************************\
;                                                               *
; Check for BIOS/MMIO Domain and Shared RAM OVERLAP.            *
;                                                               *
;***************************************************************/
;
        mov     [ebp].CommonMemoryDecode0, edx  ; Save in adapters memory.
        mov     eax, [ebx].MLIDLinearMemory0    ; EAX -> Logical Shared RAM.
        mov     [ebp].CommonLinearMemory0, eax  ; Save for later.
        mov     [ebp].SharedRAMRelative, eax    ; Save it for later.
        sub     edx, [ebx].MLIDMemoryDecode1    ; EDX = Shared RAM - BIOS/MMIO.
        jnc     short CheckRAMBoundary          ; Jump if Shared RAM > BIOS/MMIO.
        neg     edx                             ; EDX = BIOS/MMIO - Shared RAM.
        inc     ecx                             ; ECX = Shared RAM Size.
        cmp     edx, ecx                        ; SharedRAM - BIOS/MMIO > 16K?
        jc      ErrorRAMFailed                  ; Jump if not.
CheckRAMBoundary:
        cmp     edx, RAMPageRange1 * 16         ; SharedRAM - BIOS/MMIO > 08k?
        jc      ErrorRAMFailed                  ; Jump if not.
;
;***************************************************************\
;                                                               *
; Read the Adapter's Encoded Address (Burned In Address).       *
;                                                               *
;***************************************************************/
;
        sub     eax, eax                        ; EAX = 0000 0000.
        lea     ecx, (SIZE MLIDNodeAddress)[eax]        ; ECX = Node Size.
        lea     esi, [edi].NodeAddressOffset
        lea     edi, [ebx].MLIDNodeAddress      ; EDI -> Config.
        cmp     dword ptr [edi], -1             ; Node Address Entered?
        jnz     short NodeAddressSet            ; Jump if so.
CopyNodeAddressLoop:
        lodsb                                   ; AL = Even Byte From MMIO.
        shl     eax, 03*04                      ; Shift it to MSB of EAX.
        inc     esi                             ; Skip odd byte.
        lodsb                                   ; AL = Next Byte From MMIO.
        and     al, 15                          ; AL = Isolated Nibble.
        or      al, ah                          ; AL = Combined Node Address.
        stosb                                   ; Store into config.
        inc     esi                             ; Skip odd byte.
        loop    CopyNodeAddressLoop             ; Copy next byte.

NodeAddressSet:
        mov     eax, dword ptr [ebx].MLIDNodeAddress            ; Save into
        mov     dword ptr [ebp].CommonNodeAddress, eax          ;  adapters
        mov     eax, dword ptr [ebx].MLIDNodeAddress+2          ;  data
        mov     dword ptr [ebp].CommonNodeAddress+2, eax        ;  space.
;
;***************************************************************\
;                                                               *
; Add the Hardware Options.                                     *
;                                                               *
;***************************************************************/
;
;
;***************************************************************\
;                                                               *
; Initialize DIROpenAdapter Structure and MSMTxFreeCount.       *
; Copy Custom Keyword values in appropriate field in case       *
; they were changed on the command line.                        *
;                                                               *
;***************************************************************/
;
        mov     al, LinkStationsValue
        mov     [ebp].DIROpenAdapter.OpenMaxLinkStations, al
        mov     al, MaxSAPsValue
        mov     [ebp].DIROpenAdapter.OpenMaximumSAPs, al
        movzx   eax, TxBuffersValue
        mov     [ebp].DIROpenAdapter.OpenTxBuffers, al
        inc     eax
        mov     [ebp].MSMTxFreeCount, eax
        mov     ax, TxBufferLenValue
        xchg    al, ah
        mov     word ptr [ebp].DIROpenAdapter.OpenTxLength, ax
;
;***************************************************************\
;                                                               *
; ReturnCustom Keyword values to defaults in case Driver Init   *
; is re-entered.                                                *
;                                                               *
;***************************************************************/
;
        mov     LinkStationsValue, OPEN_LINK_STATIONS
        mov     MaxSAPsValue, OPEN_MAX_SAPS
        mov     TxBuffersValue, OPEN_TX_BUFFERS
        mov     TxBufferLenValue, 0
;
;***************************************************************\
;                                                               *
; Initialize and Open Token-Ring adapter.                       *
;                                                               *
;***************************************************************/
;
        mov     eax, [ebx].MLIDMaximumSize      ; Initialize Common Max Size
ife NoTxLimit
        cmp     eax, 4202                       ; Over max that we want?
        jbe     short DriverInitMaximumSize     ; Jump if not.
        mov     eax, 4202                       ; Restrict max packet size.
DriverInitMaximumSize:
endif
        mov     [ebp].CommonMaximumSize, eax    ;  before reset.
;
;***************************************************************\
;                                                               *
; Let MSM Set the Hardware Interrupt.                           *
;                                                               *
;***************************************************************/
;
;SPD 126109 Moved this call from right after MSMRegisterHardwareOptions
;to here.

        call    MSMSetHardwareInterrupt
        jnz     DriverInitError                         ; Jump if error.

   push    ebx
        mov   eax, OP_SCOPE_ADAPTER
        call    DriverReset                     ; Reset NIC.
        pop     ebx
        mov     [ebp].AdapterResetCount, 0      ; Set back to zero.
        or      eax, eax                        ; Reset Successful?
        jnz     DriverInitResetError            ; Exit if error reseting.
        mov     DriverSendPtr, offset DriverSend
        mov     [ebp].DriverSendPointer, offset DriverSend
        test    [ebp].InitStatus, INIT_FAST_PATH
        je      short DriverInitSuccessful
        mov     DriverSendPtr, offset DriverSendFastPath
        mov     [ebp].DriverSendPointer, offset DriverSendFastPath
;
;***************************************************************\
;                                                               *
; Token-Ring Adapter Initialization complete.                   *
;                                                               *
;***************************************************************/
;
DriverInitSuccessful:

        mov     ax, [ebp].CommonLineSpeed       ; AX = Line Speed.
        mov     [ebx].MLIDLineSpeed, ax         ; Store into config table.
        mov     eax, [ebp].CommonMaximumSize    ; EAX = Max Packet Size.
        mov     [ebx].MLIDMaximumSize, eax      ; Store into config table.

        call    MSMRegisterMLID                         ; Register MLID.
        jnz     short DriverInitError                   ; Jump if error.

        mov     eax, 18 * 4                             ; Schedule call back
        call    MSMScheduleAESCallBack
        jnz     short DriverInitError                   ; Jump if error.

        lea     esi, AdapterDataRateMessage             ; ESI -> Message.
        movzx   edx, word ptr [ebx].MLIDLineSpeed       ; EDX = Parameter #1.
        mov     ecx, [ebp].BoardNumber                  ; ECX = board Number.
        call    MSMPrintString                          ; Output Message.

        mov     esi, [ebp].SizeMessage                  ; ESI -> Message
        call    MSMPrintString                          ; Output Message.

if NoTxLimit
        lea     esi, MaxSizeMessage                     ; ESI -> Message.
        mov     ecx, [ebp].CommonMaximumSize            ; ECX = Parm1.
        call    MSMPrintString
endif

        mov     esi, [ebp].SendMessage                  ; ESI -> Message.
        or      esi, esi                                ; Valid Message?
        je      short DriverInitExit                    ; Jump if not.
        call    MSMPrintString                          ; Display it.

DriverInitExit:
        call    CheckMicroCodeLevel             ;JCP, 941019.
        xor     eax, eax
        CPop
        ret

DriverInitErrorPopEBX:
   pop   ebx

DriverInitResetError:
        push    eax                             ; Save error message.
        push    ecx
        call    MSMReturnDriverResources        ; Return resources.
        pop     ecx
        pop     eax                             ; EAX -> Error message.
DriverInitError:
        mov     esi, eax                        ; ESI -> Error message.
        call    MSMPrintString                  ; Display message
        or      eax, 1
        CPop
        ret
;
;***************************************************************\
;                                                               *
; On The Micro-Channel, the Shared RAM Segment                  *
; is in A22/A26 PIO.                                            *
;                                                               *
;***************************************************************/
;
DriverInitMCA:

if UseNBICalls

   mov   esi, -1            ; ESI = ScanSequence
   mov   ebx, offset ProductID      ; EBX -> ProductID   
   xor   edx, edx         ; Start with zero cards found.

ScanSlots:
   push   edx            ; Save card count 
   mov   eax, 2            ; EAX = ProductIDLength
   mov   ecx, ODI_BUSTYPE_MCA      ; ECX = BusType
   call   MSMSearchAdapter             ; Let MSM scan for us
   pop   edx            ; Get card count back
   jnz   short DoneScanningSlots      ; Jump if no more cards found
        mov     SlotsWithMyBoard[edx * 4], ecx  ; Save slot # (HIN) into table.
   inc   edx            ; Count it
        jmp     short ScanSlots                 ; Keep looking.

DoneScanningSlots:
   mov   esi, edx         ; ESI = # of cards found

else

        xor     esi, esi                        ; Start with zero cards found.
        mov     cl, SLOT_0 - 1                  ; 3rd bit must be set.
                                                ; Start with slot 0.
ScanSlots:
        inc     cl                              ; Goto next slot.
        cmp     cl, MAXIMUM_SLOTS               ; Are we done.
        ja      short DoneScanningSlots         ; Jump if so.

        mov     al, cl                          ; AL = POS Slot Number.
        out     SLOT_SELECT_REG, al             ; Select card Slot.

        mov     edx, POS_IO_PORT                ; Get IO port for first reg.
        in      al, dx                          ; Get High byte of signature.
        cmp     al, TOKEN_ID_LO                 ; High byte Valid?
        ja      ScanSlots                       ; Jump if not.

        inc     edx                             ; EDX = POS Reg 01.
        in      al, dx                          ; Get Low byte of signature.
        cmp     al, TOKEN_ID_HI                 ; AL = Valid Token-Ring ID?
        jnz     ScanSlots                       ; Jump if not.
        inc     edx                             ; EDX = POS Reg 02.
        in      al, dx                          ; Read Card Enabled Bit.
        test    al, CARD_ENABLE_BIT             ; Card Enabled?
        jz      ScanSlots                       ; jump if not.

        movzx   eax, cl                         ; EAX = Slot number.
        btr     eax, 3                          ; Zero out bit 3.
        inc     eax                             ; Slots are one relative.
        mov     SlotsWithMyBoard[esi * 4], eax  ; Save slot # into table.
        inc     esi                             ; Bump board found count.

        jmp     short ScanSlots                 ; Keep looking.

DoneScanningSlots:
        xor     al, al
        out     SLOT_SELECT_REG, al             ; Deselect card.

endif

        or      esi, esi                        ; Any boards found?
        mov     eax, offset ErrorFindingCardMessage     ; EAX->Error Message.
        jz      DriverInitResetError                    ; Exit if not.

        mov     SlotsWithMyBoardCount, esi      ; Records boards found.
;
;***************************************************************\
;                                                               *
; Let MSM Parse the command line.                               *
;                                                               *
;***************************************************************/
;
        mov     eax, NeedsIOSlotBit OR CAN_SET_NODE_ADDRESS
        lea     ecx, AdapterOptions
        call    MSMParseDriverParameters
        jnz     DriverInitError                         ; Jump if error.
;
;***************************************************************\
;                                                               *
; Use the slot choosen by ParseDriverParameters to determine    *
; Memory base, I/O base and interrupt number.                   *
;                                                               *
;***************************************************************/
;

if UseNBICalls

   push   ebx            ; Save cfg table ptr.
   movzx   edx, [ebx].MLIDSlot      ; EDX = Slot (HIN) to use.
   call   MSMGetInstanceNumberMapping   ; Get UniqueID/BusTag back.
   jnz   DriverInitErrorPopEBX      ; Jump if error.
                  ; EBX = UniqueID 
                  ; ECX = BusTag
   mov   edi, offset ConfigBuffer   ; EDI -> ConfigBuffer
   mov   esi, CFG_BUFFER_SIZE      ; ESI = ConfigBufferSize (8)
   call   MSMGetCardConfigInfo      ; Get our config info
   pop   ebx            ; EBX -> ConfigTable
   jnz   DriverInitResetError         ; 

   mov   al, [edi+3]         ; AL = Primary/Alternate Bit.
   
else

        movzx   eax, [ebx].MLIDSlot             ; EAX = Slot to use.
        dec     eax                             ; 0 Relative it.
        bts     eax, 3                          ; PS/2 needs bit 3 set.
        out     SLOT_SELECT_REG, al             ; Select the card slot.

        mov     edx, POS_IO_PORT + 3            ; EDX = POS Reg 03 Port.
        in      al, dx                          ; AL = Primary/Alternate Bit.

endif

        and     al, PRIMARY_ADAPTER_BIT         ; 00 for Primary; 01 for Alt.
        shl     al, 02                          ; 00 for Primary; 04 for Alt.
        add     al, LOW PRIMARY_PIO             ; 20 for Primary; 24 for Alt.

        movzx   edx, al                         ; EDX = 20h or 24h.
        or      edx, 0A00h                      ; EDX = 0A20h or 0A24h.
        mov     [ebx].MLIDIOPortsAndLengths, dx ; Store in config table.

ife UseNBICalls
        xor     al, al
        out     SLOT_SELECT_REG, al             ; Deselect POS's.
endif

;
;***************************************************************\
;                                                               *
; Decode the Interrupt Level and the BIOS/MMIO Domain Address.  *
;                                                               *
;***************************************************************/
;
        mov     ecx, 0FC01h                     ; ECX = Segment Mask.
        in      al, dx                          ; AL = BIOS/MMIO & Int Jumper.
        and     ch, al                          ; CH = 0FCh AND AL.
        and     al, 03                          ; Mask out BIOS/MMIO.
        mov     ah, al                          ; AH = Interrupt Level.
        shl     al, 01                          ; AL = Interrupt Level * 02.
        or      al, ah                          ; AL = Level 00, 02, 06, or 07
        or      al, 02                          ; AL = Level 02, 02, 06, or 07
        cmp     al, 06                          ; Level 02 or 03?
        jb      short MCAInterruptSet           ; Jump if so.
        add     al, 04                          ; Adjust to 10 or 11.
MCAInterruptSet:
        mov     [ebx].MLIDInterrupt, al         ; AL = Interrupt Level.

        ror     cx, 01                          ; ECX = Domain @ / 2.
        shl     ecx, 04                         ; ECX -> Absolute BIOS/MMIO.
        mov     [ebx].MLIDMemoryDecode1, ecx    ; Save into config.

        sub     eax, eax                        ; EAX = 0000 0000.
        inc     edx                             ; EDX = Setup Read 2 Port.
        inc     edx
        in      al, dx                          ; AL = Shared RAM Segment.
        and     al, 0FEh                        ; Turn Off Low Order Bit.
        rol     eax, 03*04                      ; EAX -> Shared RAM Segment.
        mov     [ebx].MLIDMemoryDecode0 , eax   ; Save into config.

        lea     esi, [ecx].RAMRelocationRegister + 01
        lea     edi, [ebx].MLIDLength0
        mov     ecx, 1                          ; Read 4 bytes.
        call    MSMReadPhysicalMemory
        mov     cl, byte ptr [ebx].MLIDLength0
        and     ecx, SHARED_RAM_MASK
        shr     ecx, 02
        mov     ch, [ecx].RAMSizeTable
        xor     cl, cl
        mov     [ebx].MLIDLength0, cx
;
;***************************************************************\
;                                                               *
; Let MSM Register the hardware options.                        *
;                                                               *
;***************************************************************/
;
        call    MSMRegisterHardwareOptions
        cmp     eax, 1                                  ; New Frame?
        je      DriverInitExit                          ; Exit if so
        ja      DriverInitError                         ; Jump if error.
        mov     [ebp].InterruptResetLevel, RESET_IRQ_PORT

        lea     esi, MicroChannelBus            ; ESI -> MCA Signature.
        jmp     DriverInitReEntry               ; Finish intialization.

CheckMicroCodeLevel:                            ; JCP.
        push    esi                             ; 941019 *Begin*
        lea     esi, [ebp].AdapterMicroCodeLevel ; ESI -> Our MicroCode.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO.
        mov     dl, [ebx].RAMPageRegister       ; AL = Old PAGE Register.
        mov     al, [ebp].MicrocodeLevelPageValue
        mov     [ebx].RAMPageRegister, al
        mov     edi, [ebp].MicrocodeLevelAddr   ; EDI -> MicroCode Location.
        add     edi, 4                          ; EDI + 4 -> MicroCode Level.
        mov     ecx, 5                          ; Copy 5 values.

NextNumber:
        mov     al, byte ptr [edi]              ; Get the values.
        and     al, 0Fh                         ; Zero out upper 4 bits.
        mov     byte ptr [esi], al              ; Store it.
        inc     edi                             ; Increment EDI.
        inc     esi                             ; Increment ESI.
        loop    short NextNumber                ; Loop.

        mov     ecx, 5
        lea     esi, [ebp].AdapterMicroCodeLevel ; ESI -> Our MicroCode.
        lea     edi, [ebp].MicroCodeLevel       ; EDI -> Error MicroCode.
        repz    cmpsb                           ; Same Micro code level ?
        jz      short SameMicroLevel            ; Zero, Yes.

        mov     ecx, 5
        lea     esi, [ebp].AdapterMicroCodeLevel ; ESI -> Our MicroCode.
        lea     edi, [ebp].MicroCodeLevel       ; EDI -> Error MicroCode.
        add     edi, 5
        repz    cmpsb                           ; Same Micro code level ?
        jz      short SameMicroLevel            ; Zero, Yes.

ExitCheckMicroCodeLevel:
        mov     [ebx].RAMPageRegister, dl       ; Restore the Page.
        pop     esi                             ; Retrieve ESI.
        ret

SameMicroLevel:
        lea     esi, ErrorEPROM                 ; ESI -> Message
        call    MSMPrintString                  ; Output Message.
        jmp     short ExitCheckMicroCodeLevel   ; 941019 *End*
                                                ; JCP.
DriverInit      endp
        subttl -- DriverReset --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverReset, TOKEN/API/RESET )
;
; Name:         DriverReset
;
; Description:  This routine will reset and initialize the NIC, test RAM
;               and issue DIR.Initialize and DIR.Open.Adapter.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     0 if successful(otherwise points to error message)
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Destroyed
;
;               Flags:
;
;               Note:   Interrupts disabled.
;
; Remarks:      This routine is called by the MSM media module.
;               It is called at process time.
;
; See Also:     TOKENTSM\TokenTSMReset
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
AlreadyInDriverReset:
        xor     eax, eax
        ret

DriverReset     proc    near            ;Initialize Token-Ring Card

   cmp   eax, OP_SCOPE_ADAPTER
   je   ResetAdapter

   xor   eax, eax
   ret

ResetAdapter:   
if DEBUG
        push    eax
        mov     al, 'R'
        call    OutChar
        pop     eax
endif
        cmp     [ebp].InDriverReset, 0
        jne     AlreadyInDriverReset
        inc     [ebp].InDriverReset

        inc     [ebp].AdapterResetCount ; Inc stat counter.
        mov     [ebp].InitRetryCounter, MAX_INIT_RETRIES
ResetNICLoop:
   mov   eax, OP_SCOPE_ADAPTER
        call    DriverShutdown          ; Shutdown card.
;
;***************************************************************\
;                                                               *
; Set the Adapter up For Paging if Paging is specified.         *
;                                                               *
;***************************************************************/
;
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        mov     al, [ebx].RAMRelocationRegister+01      ; AL = Shared RAM Size Mask.
        and     al, SHARED_RAM_MASK             ; AL = Shared RAM Size(0ch).

        mov     [ebp].SizeMessage, offset Size8KMessage
        mov     ah, 100h-1                      ; Disable paging for 8K & 64K.
;       mov     ah, 20h-1
        cmp     al, SHARED_RAM_8K               ; 8K?
        je      short SetPageMask               ; Jump if so.
        mov     [ebp].SizeMessage, offset Size64KMessage
;       mov     ah, 100h-1                      ; Disable paging for 8K & 64K.
        cmp     al, SHARED_RAM_64K              ; 64K?
        je      short SetPageMask               ; Jump if so.
        mov     [ebx].RAMPageRegister, PAGING_ACTIVE_FLAG
        mov     [ebp].SizeMessage, offset Size32KMessage
        mov     ah, 80h-1
        mov     [ebp].PageSize, 8000h           ; Use 32K Page Size.
        mov     [ebp].PagingMask, 80h
        cmp     al, SHARED_RAM_32K              ; 32K?
        je      short SetPageMask               ; Jump if so.
        mov     [ebp].SizeMessage, offset Size16KMessage
        mov     [ebp].PageSize, 4000h           ; Use 16K Page Size.
        mov     [ebp].PagingMask, 0C0h
        mov     ah, 40h-1                       ; Must be 16K
SetPageMask:
        mov     [ebp].PageSizeMask, ah          ; Save Page Size Mask.

        mov     eax, [ebp].CommonMemoryDecode0  ; EAX -> Shared RAM Absolute.
        shr     eax, 03*04                      ; AL = Shared RAM Segment.
        mov     [ebx].RAMRelocationRegister, al ; Set MMIO registers.
        and     [ebx].RAMRelocationRegister+01, NOT PARTIAL_RESET
   and     [ebp].MLIDStatusFlag, NOT NIC_INTERRUPTED_BIT
        mov     [ebx].IntStatusToPC.OROffset, INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT
;
;***************************************************************\
;                                                               *
; Wait for DIR.Initialize Complete Interrupt.                   *
;                                                               *
;***************************************************************/
;
        push    ecx
        mov     eax, NIC_INTERRUPTED_BIT
;;;;    mov     ecx, INIT_TIMEOUT_IN_TICKS * 55000
   mov     ecx, INIT_TIMEOUT_IN_TICKS
        lea     ebx, [ebp].MLIDStatusFlag       ; EBX = Adapter Flag Byte.
        call    WaitForEvent                    ; Wait For DIR.Initialize.
        pop     ecx
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        jnz     short NICInitComplete           ; Jump if it happened.
ErrorInvalidCommandCode:
        mov     al, INIT_TIMED_OUT              ; DIR.Initialize TimedOut.
NICInitFailed:
        dec     [ebp].InitRetryCounter          ; Try it again.
        jnz     ResetNICLoop
;
;***************************************************************\
;                                                               *
; The DIR.Initialize FAILED; Return With Error Code In AX.      *
;                                                               *
;***************************************************************/
;
        or      [ebp].MLIDStatusFlag, RE_INIT_ADAPTER_BIT
        lea     eax, ErrorInitializingNIC       ; EAX -> Error message.
        mov     [ebp].InDriverReset, 0
        ret                                     ; Return with error.
;
;***************************************************************\
;                                                               *
; Process DIR.Initialize Complete Interrupt.                    *
;                                                               *
;***************************************************************/
;
NICInitComplete:
        mov     eax, dword ptr [ebx].WriteRegionBase

        xchg    ah, al                          ; AX = SRB Offset.
        movzx   eax, ax                         ; EAX = SRB Offset.
        mov     [ebp].SRBPageValue, ah          ; Save SRB Page.
        mov     [ebx].RAMPageRegister, ah       ; Set new page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].CommonLinearMemory0  ; Add Base Offset.
        mov     [ebp].SRBBaseAddress, eax       ; Store SRB Base Address.

        cmp     [eax].DIRInitCommandCode, SRB_INIT_COMPLETE
        jnz     ErrorInvalidCommandCode         ; Jump if Invalid Command Code.
        mov     edx, eax                        ; EDX -> SRB.

        mov     al, [edx].DIRInitStatus         ; AL = Initialization status.
        mov     [ebp].InitStatus, al

        lea     edi, TransmitSizeTable4Mb       ; EDI -> 4 MBps Table.
        lea     esi, [ebx].AdapterIDOffset+0ah  ; ESI -> 4Mbps DHB size.
        test    [edx].DIRInitStatus, INIT_16_MBPS       ; 16 MBps?
        jz      short DataRateDetermined                ; Jump if not.
;
;***************************************************************\
;                                                               *
; Calculate the data rate and the maximum Transmit Buffer Size. *
;                                                               *
;***************************************************************/
;
        mov     [ebp].CommonLineSpeed, 16       ; Set Line Speed to 16MBps.
        lea     edi, TransmitSizeTable16Mb      ; EDI -> 16 MBps Table.
        add     esi, 2                          ; ESI -> 16 MBps AIP DHB Size.
DataRateDetermined:
        movzx   eax, word ptr [edx].DIRInitAdapterParmsAddr
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebp].AdapterParmsPageValue, ah ; Store Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].AdapterParmsAddr, eax     ; Store SSB Base Address.

                                                ; JCP
                                                ; 941019, *Begin*
        movzx   eax, word ptr [edx].DIRInitMicrocodeLevel
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebp].MicrocodeLevelPageValue, ah ; Store Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].MicrocodeLevelAddr, eax   ; Store MicroCode Base Address.
                                                ; 941019, *End*

        movzx   eax, byte ptr [esi]             ; AL = DHB Size Available.
        and     al, 15                          ; Save 4 lower bits.
        sub     al, 16-Tx16MbTableSize/02       ; AL = Maximum DHB Size Flag.
        jnc     short ValidTransmitSize         ; Jump if valid.
        sub     eax, eax                        ; EAX = Maximum DHB Size.
;
;***************************************************************\
;                                                               *
; Calculate the Transmit Buffer Size.                           *
;                                                               *
;***************************************************************/
;
ValidTransmitSize:
        mov     [ebp].MSMTxFreeCount, 2         ; Assume 2 simult Tx's.
        movzx   ecx, word ptr 00[eax * 02][edi] ; ECX = Max Board Frame Size.
        movzx   eax, word ptr [ebp].DIROpenAdapter.OpenTxLength
        xchg    ah, al                          ; EAX = Max User Frame Size.
        mov     esi, [ebp].CommonMaximumSize    ; ESI = Maximum LSL Size.
        lea     esi, [esi+06]                   ; ESI = LSL Size + Overhead.
if NoTxLimit
        test    [ebp].InitStatus, INIT_FAST_PATH        ; Fast Path supported?
        jne     short CommonSizeOK                      ; Jump if not.
        cmp     esi, 4202+6
        jbe     short CommonSizeOK
        mov     esi, 4202+6
CommonSizeOK:
endif
        or      eax, eax                        ; User Size entered?
        jnz     short DontUseLSLsMaxSize        ; Jump if so.
        mov     eax, esi                        ; EAX = LSL Max Size.
DontUseLSLsMaxSize:
        cmp     eax, ecx                        ; EAX < Adapter Size?
        jb      short DontUseAdaptersMaxSize    ; Jump if so.
        mov     eax, ecx                        ; EAX = Adapters Max.
DontUseAdaptersMaxSize:
        cmp     eax, esi                        ; EAX < User Max Size?
        jb      short DontUseUsersMaxSize       ; Jump if so.
        mov     eax, esi                        ; EAX = Users Max Size.
DontUseUsersMaxSize:
;;      test    byte ptr [ebx].RAMRelocationRegister+01, SHARED_RAM_MASK
        mov     cl, byte ptr [ebx].RAMRelocationRegister+01
        and     cl, SHARED_RAM_MASK
        cmp     cl, SHARED_RAM_8K
        jnz     short RAMNot8k                  ; Jump if not 8k Shared RAM.
        mov     [ebp].DIROpenAdapter.OpenTxBuffers, 01  ; Use only one buffer.
        mov     [ebp].MSMTxFreeCount, 01        ; Driver can handle 1 Tx.
        cmp     eax, 2048                       ; EAX < 2048?
        jc      short RAMNot8k                  ; Jump if so.
        mov     eax, 2048                       ; EAX = Max size for 8K RAM.
RAMNot8k:
        lea     ecx, [eax-6]                    ; ECX = Max Size - Overhead.
        and     al, 0F8h                        ; EAX on an 8 Byte Boundary.
        xchg    ah, al                          ; AX = High Low Format
        mov     word ptr [ebp].DIROpenAdapter.OpenTxLength, ax
        mov     [ebp].CommonMaximumSize, ecx

        mov     al, [edx].DIRInitErrorCode+01   ; AL = DIR.Init Error Code.
        or      al, [edx].DIRInitErrorCode      ; Successful?
        jnz     NICInitFailed                   ; Jump if not.
;
;***************************************************************\
;                                                               *
; Perform Shared RAM Read/Write Test.                           *
;                                                               *
;***************************************************************/
;
        mov     eax, (055h SHL 16)+(0AAh SHL 8)+0FFh    ; EAX = Test Pattern.
TestMemoryLoop:
        mov     ecx, SIZE OpenAdapterStructure / 04
        mov     edi, edx                        ; EDI -> SRB.
 rep    stosd                                   ; Write the pattern.
        mov     ecx, SIZE OpenAdapterStructure / 04
        mov     edi, edx                        ; EDI -> SRB.
 repz   scasd                                   ; Compare it with pattern.
        jnz     ErrorTestingRAM                 ; Jump if not equal.
        ror     eax, 04                         ; Shift pattern.
        cmp     al, 0FFh                        ; All bytes tested?
        jnz     TestMemoryLoop                  ; Loop if not.
;
;***************************************************************\
;                                                               *
; Shared RAM Works Fine. Check For Zeroing Top 512 Bytes        *
;                                                               *
;***************************************************************/
;
        mov     cl, byte ptr [ebx].RAMRelocationRegister+01
        and     cl, SHARED_RAM_MASK
        cmp     cl, SHARED_RAM_8K
        jz      short TimeToOpenAdapter         ; Jump if 8k Shared RAM.
;;
;; DFS 02-18-92 - This code zero's out uninitialized RAM on adapter
;; to prevent parity errors if we ever debug into this area. Since
;; having the adapter shared RAM size at 8K causes a page fault under
;; v3.2 of the OS(edi points to second 8K of adapter RAM at this point),
;; we took it out. This is OK since neither the host or adapter software
;; reads or writes to this area.
;;
;; AKW 04-04-94 - Since the Token-Ring spec says we MUST initialize this
;; area of RAM if we are in 16 or 32k mode (paging), we re-enabled this
;; code in both the server and client drivers to do so.  If in 8k mode,
;; we skip around this code still.
;;
        movzx   eax, byte ptr [ebx].AdapterIDOffset+06
        and     al, 15                          ; AL = Available Shared RAM.
        sub     al, 0Bh                         ; Top 512 Reserved?
        jnz     short TimeToOpenAdapter         ; Jump if not.
        mov     ecx, 512/04                     ; ECX = DWord Count.
  rep   stosd                                   ; Zero Top 512 of Shared RAM.
;
;***************************************************************\
;                                                               *
; Issue DIR.Open.Adapter                                        *
;                                                               *
;***************************************************************/
;
TimeToOpenAdapter:
        mov     word ptr [ebx].IntStatusToPC.ANDOffset, cx
        mov     [ebx].IntStatusToPC.OROffset, INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT

        mov     al, [ebp].SRBPageValue
        mov     [ebx].RAMPageRegister, al

ifdef BROUTER
        cmp     [ebp].BrouterState, 0           ; Activate bridge?
        jne     OpenBridge                      ; Jump if so.
endif

        test    [ebp].InitStatus, INIT_FAST_PATH        ; Fast Path supported?
        mov     [ebp].SendMessage, 0
        je      FastPathChecked                         ; Jump if not.

        and     [ebp].InitStatus, NOT INIT_FAST_PATH
        cmp     [ebp].SizeMessage, offset Size8KMessage ; 8K RAM size?
        mov     [ebp].SendMessage, offset NoFastPathMessage
        je      FastPathChecked                         ; Jump if so.

        mov     [ebp].SendMessage, offset FastPathMessage

;****************************************************************************\
;
; The following is an excerpt from an E-mail sent by Richard Jones...
;
;  -Max frame size at 16MB wire speed is 17960 bytes.
;  -The shared RAM area is configured in multiple buffers, each minimum of 30
;  bytes to max of 2048 bytes.  IBM recommends 512 byte buffers (so we use
;  512 byte buffers).
;  -Each buffer has a 22 byte link header, with the rest available for packet
;  data.  In our case of 512 byte buffers, we have 490 bytes for data in each
;  buffer.
;  -Total shared RAM area allocated must be an exactly on buffer size (512
;  bytes in our case) aligned plus an additional 16 bytes for a control area.
;  -The adapter firmware will not straddle any buffers over a 16K page of
;  shared RAM space.  Therefore, since there is a 16 byte control area at the
;  beginning and 17960 is greater than 16K, we must add one more 512 byte
;  buffer to make up for the lost 496 bytes (512-16) that is just before the
;  16K boundery.
;  -The shared RAM area is allocated in 8 byte blocks.
;
;  Therefore, the following calculations apply:
;
;  17960/(512-22) = 36.65  (that is 36.65 - 512 byte buffers).
;  Even alignment means round up to 37 buffers.
;  Now add one extra buffer to make up for the 496 lost bytes at the 16K page
;  boundery => 38 buffers.
;  There are 64 - 8 byte blocks in one 512 byte buffer, so 38*64 = 2432
;  blocks.
;  Now we need an additional 16 byte control area (2 more blocks) => 2434
;  blocks!
;
;  So we should put the following values in the DIR.CONFIG.FAST.PATH.RAM
;  command (0x12 command code)  RAM_SIZE = 2434 and BUFFER_SIZE = 512.
;
;  Note by Jasper Pan: The calculation is correct, but it will trap under heavy
;  (950804)            load at SuperLab.  According to IBM, the NIC chip has
;             some design faults, it needs to allocate extra 4K buffer
;             to prevent this condition.  Therefore, the calculation
;             should be => (16 + 512 + ((4096+512) * 5)) / 8.
;
;****************************************************************************/

if NoTxLimit
;       mov     eax, 2434         ;Removed by JCP, 950804.
   mov     eax, (16 + 512 + ((4096+512) * 5)) / 8
else
        mov     eax, (16 + 512 + ((4096+512) * 4)) / 8
endif
        xchg    al, ah
        mov     [ebp].ConfigRAMSize, ax
        lea     esi, [ebp].ConfigFastPath
        mov     edi, [ebp].SRBBaseAddress
        mov     ecx, SIZE ConfigFastPathStructure / 04
        rep     movsd
        and     [ebp].MLIDStatusFlag, NOT NIC_INTERRUPTED_BIT
        mov     [ebx].IntStatusToAdapter+01, COMMAND_IN_SRB

        mov     eax, NIC_INTERRUPTED_BIT
;;;;    mov     ecx, INIT_TIMEOUT_IN_TICKS * 55000
        mov     ecx, INIT_TIMEOUT_IN_TICKS * 55000
        lea     ebx, [ebp].MLIDStatusFlag       ; EBX = Adapter Flag Byte.
        call    WaitForEvent                    ; Wait For DIR.Initialize.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        jz      short FastPathChecked           ; Jump if it happened.

        mov     edx, [ebp].SRBBaseAddress       ; EDX->SRB.
        cmp     [edx].FPRRetcode, 0             ; Fast Path enabled?
        jne     short FastPathChecked           ; Jump if not.

        or      [ebp].InitStatus, INIT_FAST_PATH
if NoTxLimit
        mov     eax, 4096 * 5
        mov     ecx, [ebp].CommonMaximumSize
        xor     edx, edx
        div     ecx
        mov     edx, [ebp].SRBBaseAddress       ; EDX->SRB.
        mov     [ebp].MSMTxFreeCount, eax
else
        mov     [ebp].MSMTxFreeCount, 4
endif
        movzx   eax, [edx].FPRFastPathXmit      ; EAX = Tx Offset.
        xchg    ah, al                          ; Convert to Intel format.
        mov     [ebp].TxPageValue, ah           ; Store Page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].SharedRAMRelative    ; Add Shared RAM Base.
        mov     [ebp].TxBaseAddress, eax        ; Store ARB Base Address.

        movzx   eax, [edx].FPRSRBAddress        ; EAX = offset of new SRB.
        xchg    ah, al                          ; AX = SRB Offset.
        mov     [ebp].SRBPageValue, ah          ; Save SRB Page.
        mov     [ebx].RAMPageRegister, ah               ; Set new page.
        and     ah, [ebp].PageSizeMask          ; Mask off page bits.
        add     eax, [ebp].CommonLinearMemory0  ; Add Base Offset.
        mov     [ebp].SRBBaseAddress, eax       ; Store SRB Base Address.

FastPathChecked:
        mov     word ptr [ebx].IntStatusToPC.ANDOffset, 0
        mov     edx, [ebp].SRBBaseAddress
        mov     [ebx].IntStatusToPC.OROffset, INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT

        mov     ecx, SIZE OpenAdapterStructure / 04     ; Copy OpenAdapter
        mov     edi, edx                                ;  Image to SRB.
        lea     esi, [ebp].DIROpenAdapter
 rep    movsd

        lea     edi, [edx].OpenNodeAddress              ; Fill in OpenAdapter
        lea     esi, [ebp].CommonNodeAddress            ;  Node Address.
        movsd
        movsw
        mov     MLIDStatusFlag[ebp], cl                 ; Clear state flag.
        mov     [ebx].IntStatusToAdapter+01, COMMAND_IN_SRB
        or      [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Set busy flag.
        mov     [ebx].RAMPageRegister, cl               ; Zero out Page.
        mov     [ebp].OpeningAdapter, -1                ;Opening adapter ?

        sub     eax, eax                                ; Good Return.
        mov     [ebp].InDriverReset, eax
        ret

ifdef BROUTER
OpenBridge:
        and     [ebp].InitStatus, NOT INIT_FAST_PATH
        mov     word ptr [ebx].IntStatusToPC.ANDOffset, 0
        mov     edx, [ebp].SRBBaseAddress
        mov     [ebx].IntStatusToPC.OROffset, INTERRUPT_ENABLE_BIT+NMI_DISABLED_BIT

        mov     ecx, 10 / 02                            ; Copy ConfigBridge
        mov     edi, edx                                ;  Image to SRB.
        lea     esi, [ebp].BConfigCommand
        rep     movsw

        mov     MLIDStatusFlag[ebp], cl                 ; Clear state flag.
        mov     [ebx].IntStatusToAdapter+01, COMMAND_IN_SRB
        or      [ebp].MLIDStatusFlag, SRB_IS_BUSY_BIT   ; Set busy flag.
        mov     [ebx].RAMPageRegister, cl               ; Zero out Page.
        sub     eax, eax                                ; Good Return.
        mov     [ebp].InDriverReset, eax
        ret

endif
;
;***************************************************************\
;                                                               *
; The Shared RAM Read/Write Test Failed.                        *
;                                                               *
;***************************************************************/
;
ErrorTestingRAM:
        mov     [ebp].InDriverReset, 0
        lea     eax, ErrorRAMFailedMessage      ; ESI -> Error Message.
        ret
DriverReset     endp

        subttl -- WaitForEvent --
        page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( WaitForEvent, TOKEN/INTERNAL/WAIT4EV )
;
; Name:         WaitForEvent
;
; Description:  This routine will wait for a specified time period for
;               an event to occur. The high word of EAX should contain
;               the ticks to wait and the low word of EAX should contain
;               a bit(s) which need to be set in the memory location
;               pointed to by EBX.
;
; On Entry:     EAX     Event Bit to wait for
;               EBX     @ Event Word
;               ECX     Time to Wait/Event Bit(s)
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are in any state.
;
; On Return:    EAX     0 if Timeout
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Preserved
;               EBP     Preserved
;               ESI     Preserved
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts enabled.
;
; Remarks:      This routine is called by AdapterErrorISR, DriverReset and
;               DriverShutdown.
;               It is called at process or interrupt time.
;
; See Also:     AdapterErrorISR
;               DriverReset
;               DriverShutdown
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
WaitForEvent    proc
if DEBUG
        push    eax
        mov     al, 'W'
        call    OutChar
        pop     eax
endif
        push    edi                             ; Save EDI.
        push    edx
        push    esi
        mov     esi, ecx                        ; CX = Event Bit(s).
        mov     ecx, eax                        ; ECX = Bit to wait for.
;;;     call    MSMGetMicroTimer                ; EAX = Current us.
   MSMGetCurrentTime         ; EAX = Current tick.
        neg     eax
        mov     edi, eax                        ; EDI = -Start time.
WaitForEventLoop:
        test    cx, [ebx]                       ; Is Software Bit Set?
        jnz     short WaitForEventExit          ; Exit if so.
        push    ecx
        push    esi
        call    MSMYieldWithDelay               ; Let other processes execute.
        pop     esi
        pop     ecx
;;;;;   call    MSMGetMicroTimer                ; EAX = Current Time.
   MSMGetCurrentTime         ; EAX = Current Time.
        add     eax, edi                        ; EAX = us elapsed.
        cmp     eax, esi                        ; More than max us?
        jb      WaitForEventLoop                ; Loop if not.
        sub     eax, eax                        ; Timeout has occured.
WaitForEventExit:
        pop     esi
        pop     edx
        pop     edi                             ; Restore EDI.
        ret

WaitForEvent    endp
        subttl -- DriverShutdown --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverShutdown, TOKEN/API/SHUTDOWN )
;
; Name:         DriverShutdown
;
; Description:  This routine will reset the adapter and return any TCB's
;               queued by driver.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     0 if Permanent Shutdown
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     0 if successful
;               EBX     Preserved
;               ECX     Preserved
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Preserved
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the MSM media module.
;               It is called at process time.
;
; See Also:     TOKENTSM\TokenTSMShutdown
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
DriverShutdown  proc
   cmp   eax, OP_SCOPE_ADAPTER
   je   ShutdownAdapter

   xor   eax, eax
        ret

ShutdownAdapter:      
        mov     [ebp].CompletionQHead, 0        ; Disable Fast Path.
        mov     ebx, [ebp].AbsoluteMMIOAddress  ; EBX -> BIOS/MMIO Domain.
        or      ebx, ebx                        ; Valid Address?
        jz      short ReturnAllTCBs             ; Jump if not.
        mov     MLIDStatusFlag[ebp], IGNORE_INTERRUPTS_BIT
    call   MSMYieldWithDelay      ; Clear ints
        mov     [ebx].IntStatusToPC.ANDOffset, 255-INTERRUPT_ENABLE_BIT-NMI_DISABLED_BIT
;
;***************************************************************\
;                                                               *
; Pull the Adapter Reset Line and Wait For At Least 50 Mills.   *
;                                                               *
;***************************************************************/
;
        mov     al, ALTERNATE_IPL               ; AL = Alternate IPL Bit.
        and     al, [ebx].RAMRelocationRegister+01      ; Read RRR into AL.
        or      al, PARTIAL_RESET               ; Set Partial Reset Bit.

        movzx   edx, [ebp].CommonIOPort         ; EDX = Base I/O Port.
        inc     edx                             ; EDX = Reset Latch Port.
        mov     [ebp].MLIDStatusFlag, ADAPTER_RESET_BIT
        out     dx, al                          ; Hold > 50 ms.


;;;     push    eax                             ; Save RRR register.
;;;     mov     eax, DIR_INIT_WAIT_IN_TICKS SHL 16
;;;     call    WaitForEvent                    ; Wait for Adapter to Settle.
;;;     pop     eax                             ; Restore RRR register.

        mov     esi, eax                        ; Save EAX.
        call    MSMGetMicroTimer                ; EAX = 1us counter value.
        neg     eax
        mov     edi, eax                        ; EDI = -EAX.
DriverShutdownWait:
        call    MSMYieldWithDelay               ; Let other processes process.
        call    MSMGetMicroTimer                ; Get new 1ms counter.
        add     eax, edi                        ; EAX = ms expired.
        cmp     eax, 50000                      ; 50ms?
        jb      DriverShutdownWait              ; Jump if not.
        mov     eax, esi                        ; Restore EAX.
        movzx   edx, [ebp].CommonIOPort         ; EDX = Base I/O Port.
        add     edx, 2                          ; EDX = Release Reset Port.
;
;***************************************************************\
;                                                               *
; Release the Adapter Reset.                                    *
;                                                               *
;***************************************************************/
;
;;;     inc     edx                             ; EDX = Release Reset Port.
        out     dx, al                          ; Release Adapter Reset.
        mov     [ebx].RAMRelocationRegister+01, al      ; Set Partial Reset.
ReturnAllTCBs:
        mov     MLIDStatusFlag[ebp], IGNORE_INTERRUPTS_BIT
;
;***************************************************************\
;                                                               *
; Return TCB In Process.                                        *
;                                                               *
;***************************************************************/
;
        mov     esi, [ebp].TCBInProcess         ; ESI -> TCB in Process.
        mov     [ebp].TCBInProcess, 0           ; No more TCB in process.
        or      esi, esi                        ; Valid TCB?
        jz      ReturnTCBsInQueue               ; Jump if not.
if      UseFastCalls
        push    ebp
        call    TokenTSMFastSendComplete        ; Return it.
        pop     ebp
else
        call    TokenTSMSendComplete            ; Return it.
endif
        inc     [ebp].MSMTxFreeCount            ; NIC ready for packet?
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
;
;***************************************************************\
;                                                               *
; Return TCB in Send Queue.                                     *
;                                                               *
;***************************************************************/
;
ReturnTCBsInQueue:

        mov     esi, [ebp-TCBDriverWS-TCBLink].SendQueueHead

ReturnNextTCB:
        or      esi, esi                        ; ESI = End of Queue?
        jz      short ReturnTxInProcess         ; Jump if so.

        mov     edi, [esi].TCBDriverWS.TCBLink  ; EDI -> Next ECB.

        push    ebp
        push    edi                             ; Save next ECB.
        call    TokenTSMFastSendComplete        ; Return to MSM.
        pop     esi                             ; ESI -> Next ECB in queue.
        pop     ebp

        inc     [ebp].MSMTxFreeCount            ; NIC ready for packet?
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        jmp     short ReturnNextTCB             ; Return next TCB.

ReturnTxInProcess:
        mov     esi, [ebp].TxInProcessHead
ReturnTxInProcessLoop:
        or      esi, esi
        jz      short ReturnTCBExit
        mov     edi, [esi].TCBDriverWS.TCBLink

        push    ebp
        push    edi                             ; Save next ECB.
        call    TokenTSMFastSendComplete        ; Return to MSM.
        pop     esi                             ; ESI -> Next ECB in queue.
        pop     ebp

        inc     [ebp].MSMTxFreeCount            ; NIC ready for packet?
        mov     [ebp].TxStartTime, 0            ; Zero out Tx Start time.
        jmp     ReturnTxInProcessLoop           ; Return next TCB.


ReturnTCBExit:
        xor     eax, eax                        ; Good return code.
        mov     [ebp].SendQueueHead, eax
        mov     [ebp].TxInProcessHead, eax
        ret

DriverShutdown  endp
        subttl  -- DriverRemove --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverRemove, TOKEN/API/REMOVE )
;
; Name:         DriverRemove
;
; Description:  This routine call the MSM to return our resources.
;
; On Entry:     EAX     N/A
;               EBX     N/A
;               ECX     N
;               EDX     N/A
;               EBP     N/A
;               ESI     N/A
;               EDI     N/A
;
;               Note:   Interrupts are in any state.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Destroyed
;               EBP     Preserved
;               ESI     Preserved
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the OS at unload.
;               It is called at process time.
;
; See Also:     MSM\MSMDriverRemove
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
DriverRemove    proc

        CPush
        mov     eax, DriverModuleHandle
        call    MSMDriverRemove
        CPop
        ret

DriverRemove    endp
        subttl -- Debug Routine --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DebugRoutine, TOKEN/INTERNAL/DEBUG )
;
; Name:         DebugRoutine
;
; Description:  This routine will point EAX to the start of the code
;               segment and switch to debugger mode.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Keyword on Command Line
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Preserved
;               EDX     Preserved
;               EBP     Preserved
;               ESI     Preserved
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved but were enabled.
;
; Remarks:      This routine is called by the MSM.
;               It is called at process time.
;
; See Also:     MSM\MSMInitializeDriver
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
DebugRoutine    proc

        lea     eax, DriverMulticastChange      ; EAX -> Beginning of CS.
        ret                                     ; Return.

DebugRoutine    endp
        subttl -- LinkStationsRoutine --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( LinkStationsRoutine, TOKEN/INTERNAL/LINKSTA )
;
; Name:         LinkStationsRoutine
;
; Description:  This routine will scan command line for hex value to use for
;               DLC_MAX_STA field in DIR.OPEN.ADAPTER image.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Keyword on Command Line
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Preserved
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the MSM.
;               It is called at process time.
;
; See Also:     MSM\MSMInitializeDriver
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
LinkStationsRoutine     proc

        mov     LinkStationsValue, al           ; Save it until DriverInit.
        ret

LinkStationsRoutine     endp
        subttl -- MaxSAPsRoutine --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( MaxSAPsRoutine, TOKEN/INTERNAL/MAXSAP )
;
; Name:         MaxSAPsRoutine
;
; Description:  This routine will scan the command line for hex value to
;               use for DLC_MAX_SAP field in DIR.OPEN.ADAPTER image.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Keyword on Command Line
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Preserved
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the MSM.
;               It is called at process time.
;
; See Also:     MSM\MSMInitializeDriver
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
MaxSAPsRoutine          proc

        mov     MaxSAPsValue, al                ; Save it until DriverInit.
        ret

MaxSAPsRoutine          endp
        subttl -- TxBuffersRoutine --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( TxBuffersRoutine, TOKEN/INTERNAL/TXBUFFS )
;
; Name:         TxBuffersRoutine
;
; Description:  This routine will scan command line for hex value to use
;               for NUM_DHB field in DIR.OPEN.ADAPTER image.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Keyword on Command Line
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Preserved
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the MSM.
;               It is called at process time.
;
; See Also:     MSM\MSMInitializeDriver
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
TxBuffersRoutine        proc

        mov     TxBuffersValue, al              ; Save it until DriverInit.
        ret

TxBuffersRoutine        endp

Mem1Routine     proc

        mov     [ebx].MLIDMemoryDecode0, eax
        ret

Mem1Routine     endp

        subttl -- TxBuffersLenRoutine --
        page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( TxBufferLenRoutine, TOKEN/INTERNAL/TXLEN )
;
; Name:         TxBufferLenRoutine
;
; Description:  This routine will scan the command line for hex value to
;               use for DHB_LENGTH field in DIR.OPEN.ADAPTER image.
;
; On Entry:     EAX     N/A
;               EBX     @ Frame Data Space
;               ECX     N/A
;               EDX     N/A
;               EBP     @ Adapter Data Space
;               ESI     @ Keyword on Command Line
;               EDI     N/A
;
;               Note:   Interrupts are disabled.
;
; On Return:    EAX     Destroyed
;               EBX     Preserved
;               ECX     Destroyed
;               EDX     Preserved
;               EBP     Preserved
;               ESI     Destroyed
;               EDI     Preserved
;
;               Flags:
;
;               Note:   Interrupts preserved.
;
; Remarks:      This routine is called by the MSM.
;               It is called at process time.
;
; See Also:     MSM\MSMInitializeDriver
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
TxBufferLenRoutine      proc

        mov     TxBufferLenValue, ax            ; Save it until DriverInit.
        ret

TxBufferLenRoutine      endp

OSCODE  ends

        end