home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NCSATELN / TEL23SRC.ZIP / NET / ENET / UOFI.M86 < prev    next >
Encoding:
Text File  |  1990-05-23  |  15.7 KB  |  777 lines

  1. ;************************************************************************;
  2. ;*                                                                      *;
  3. ;*                                    *;
  4. ;*    Interlan Ni5210/Ni9210 Ethernet Driver Software            *;
  5. ;*                                    *;
  6. ;*   Rev   Author    Date      Description                    *;
  7. ;*   ---   ------    ----      -----------                              *;
  8. ;************************************************************************;
  9.  
  10. ;==============( description )============================================
  11.  
  12. ;          NIDRLnn.M86    The   "real"  82586  device  driver  logic   whose
  13. ;                         workings are, for the  most  part,  independent of
  14. ;                         which  network  interface  products are supported.
  15. ;                         The last two digits are undefined and  used during
  16. ;                         development as a file version number.
  17. ;
  18. ;                    NIDRLnn.M86 establishes data area definition by 
  19. ;                         including NIDRD.M86 with NIDR_DATA_DECL = FALSE.
  20. ;
  21.     name IPXDRIVERMODULE 
  22.  
  23. %set (NISH_DATA_DECL,0)            ; only define data areas
  24.                  
  25. $include (..\h\nishd.inc)        ; shared with product interfaces
  26. $include (..\h\assert.equ)
  27.  
  28.  
  29. $include (..\h\side.inc)
  30.  
  31. ;==============( data definition )===================================
  32.  
  33.  
  34. %set (NIDR_DATA_DECL,0)            ; only define data areas
  35.  
  36. $include (..\h\nidrd.inc)        ; data declare file    
  37.  
  38.  
  39. ;==============( test whw )=========================================
  40.  
  41.  
  42.  
  43.     public    ReStart586, RUStart, RUSuspend
  44.  
  45.     ;
  46.     ; The following routines are declared public to aid in debugging:
  47.     ;
  48.  
  49.     public    Wait586, Command586, IssueCA
  50.     public    Configure586, ProcessFRInt, ReturnReceivedBuffer
  51.     public    ProcessCXInt, TransmitPacket
  52.     public    InputLoop,  unmaskint, SetUpReads, InitTxBuffs
  53.  
  54.  
  55. %rcode_seg
  56.  
  57.     Even
  58.  
  59. InitialSCP    db    0        ; 16 bit bus
  60.         db    5 dup (0)
  61.         dw    ISCP
  62.         dw    0
  63.  
  64. ; Initial ISCP
  65.         dw    1
  66.         dw    SCB
  67.         dw    0, 0
  68.  
  69. ;
  70. ; Ethernet Configuration
  71. ;
  72.         public    ConfigNormal    ; allow external reference
  73. Config_4_Normal    dw    0,8002h,0,40Ch,2E00h,6000h,0F200h,0h,40h
  74.  
  75. $Eject
  76.  
  77. ;
  78. ;    RUStart
  79. ;
  80. ;    Checks the status of the Receiver and if there are enough
  81. ;    resources, starts the receiver.  
  82. ;
  83. ;    This code is a critical section since in the 3COM port it can
  84. ;    be called from both base and interrupt level.
  85. ;
  86. ;    Called by :
  87. ;        AT_Isr
  88. ;        PC_Isr
  89. ;        ReStart586
  90. ;        SetUpReads
  91. ;        WrRxFilter
  92. ;
  93.     Assume    cs: %CGroup, ds: NiMemSeg, es: NiMemSeg 
  94.  
  95. RUStart        proc    near
  96.  
  97.  
  98.         mov    al, byte ptr SCB.SCBStatus
  99.         and    al, 70h            ; strip out RUS
  100.         cmp    al, 40h            ; ready ?
  101.         je    NoStart
  102.  
  103.         mov    bx, FDHead        ; must have 2 fd's and RDB's to start
  104.         cmp    [bx].FDCommand, 8000h    ; is this the last FD?
  105.         je    NoStart            ; if e, yes - return
  106.  
  107.         mov    si, RBDHead        
  108.         cmp    si, EndOfQue        ; check for 1st RBD
  109.         je    NoStart
  110.     
  111.         cmp    [si].BDLink, EndOfQue    ; check for 2nd RBD
  112.         je    NoStart
  113.     
  114.         push    ds
  115.         %get_dataseg
  116.         mov    ds, ax
  117.  
  118.         inc     ds: RxStartCount    ; update counter
  119.  
  120.     ; SCB errors counters are managed by the 586 chip, so we just need
  121.     ; to copy them.  We do so every time the receiver needs to be restarted
  122.  
  123.         mov    ax, SCB.RUNTerror
  124.         mov    ds: PacketRxTooSmallCount, ax
  125.         mov    ax, es: SCB.CRCerror
  126.         mov    ds: ChecksumErrorCount, ax
  127.         mov    ax, es: SCB.NRerror
  128.         mov    ds: RxLostCount, ax
  129.     
  130.         pop    ds
  131.  
  132.         mov    DummyRBD.BufSize, 8000h    ; 0 length RBD with EL at EOL
  133.         mov    DummyRBD.BDlink, EndOfQue ; dummy link
  134.         mov    [bx].RBDOffset, si
  135.         call    wait586
  136.         jnz    NoStart
  137.     
  138.         mov    SCB.RFAOffset, bx
  139.         mov    SCB.SCBCommand, 10h    ; ru start
  140.         call    IssueCA
  141. NoStart:
  142.         ret
  143. RUStart    endp
  144.  
  145. $Eject
  146. ;
  147. ; Configure586 must run disabled!
  148. ;    Called by :
  149. ;        ReStart586
  150. ;        DriverInitialize
  151.  
  152.     Assume    cs: %CGroup, ds: NiMemSeg, es: NiMemSeg, ss: Nothing
  153.  
  154. Configure586    proc    near
  155.  
  156.         mov    ax, cs
  157.         mov    ds, ax
  158.  
  159.         lea    si, InitialScp        ;Set up SCP and ISCP
  160.         mov    di, es: SCP
  161.         mov    cx, SCPLen/2
  162.       rep    movsw
  163.         lea    di, ISCP
  164.         mov    cx, ISCPLen/2
  165.       rep    movsw
  166.  
  167.         mov    ax, es
  168.         mov    ds, ax
  169.  
  170.         xor    ax, ax
  171.         mov    bx, ax
  172.         call    Command586
  173.  
  174.         call    Wait586
  175.         push    ds
  176.  
  177.         mov    ax, cs
  178.         mov    ds, ax
  179.  
  180.         mov    si, ConfigPointer
  181.         mov    cx, size ConfigNormal / 2
  182.         lea    di, CommandBuff
  183.         mov    bx, di
  184.     rep    movsw
  185.         pop    ds
  186.  
  187.         mov    ax, 100h        ;do command
  188.         call    Command586
  189.  
  190. WaitCC:
  191.         mov    ax, [bx]
  192.         test    ax, 8000h        ;command complete?
  193.         jz    WaitCC
  194.  
  195.         xor    ax, ax
  196.         mov    di, bx
  197.         stosw                ;set up ia command
  198.         mov    [di], 8001h
  199.         inc    di
  200.         inc    di
  201.         stosw
  202.  
  203.         mov    ax, cs            ; DS -> code segment
  204.         mov    ds, ax
  205.  
  206.         lea    si, DNodeAddress
  207.         movsw
  208.         movsw
  209.         movsw
  210.  
  211.         mov    ax, es
  212.         mov    ds, ax
  213.  
  214.         mov    ax, 100h
  215.         call    Command586
  216.         ret
  217.  
  218. Configure586    endp
  219. $Eject
  220.                  
  221.                  
  222. ;
  223. ;   Driver Initialization Code follows.  In the Novell environment this 
  224. ;   segment is thrown away after shell installation is complete. 
  225. ;   When running in a 3COM environment, driver initialization code 
  226. ;   can not be thrown away since it is not executed until initialization 
  227. ;   is requested by 3Com programs (ie. initialization is not done at 
  228. ;   load time).
  229. ;
  230.  
  231. %initnet_seg
  232.                  
  233.     public    %SideDriverInitialize 
  234.                  
  235. ;    Driver Initialize Segment Data area
  236.  
  237. NodeIdAddress    dw    0
  238.  
  239. %if (%NI5210) then (
  240. OldInterrupt    dd    0    ; 9210 contains old vector in ISR
  241. ) fi
  242.  
  243. NiNotFoundMsg        db    'Ni9210 not found at I/O address. - Check Jumpers.$'
  244. NiMemNotFoundMsg    db    'Ni9210 memory not found - Check Jumpers.$'
  245.  
  246.  
  247. $Eject
  248. ;   Driver Initialize 
  249. ;   assumes: 
  250. ;        DS, ES are set to CGroup (== CS)
  251. ;     DI points to where to stuff my address (if NOT running as Novell srvr)
  252. ;        Interrupts are ENABLED 
  253. ;        The Real Time Ticks variable is being set, and the 
  254. ;        entire AES system is initialized. 
  255. ;   returns: 
  256. ;        If initialization is done OK: 
  257. ;             AX has a 0
  258. ;        If board malfunction: 
  259. ;             AX gets offset (in CGroup) of '$'-terminated error string
  260.     Assume    cs: %CGroup, ds: %DGroup, es: NiMemSeg
  261.                  
  262. %SideDriverInitialize 
  263. &    proc   near 
  264.  
  265.     cld
  266.  
  267.     mov    NodeIdAddress, di    ; Save address for ether node address
  268.     mov    MaxPhysPacketSize, 1024
  269.     mov    ReadWriteCycles, 100
  270.     mov    cs: DataGp, ds
  271.  
  272.     call    GetMachType        ; returns machine type in AL
  273.     mov    MachineType, al
  274.  
  275.     xor    ah,ah
  276.     %trace_x(IBM Machine ID:  ,ax)
  277.  
  278. Get_Configuration:
  279.     call    GetConfig        ; initialize NI configuration params
  280.     or    ax, ax
  281.     jz    Display
  282.     jmp    DIExit
  283.  
  284. Display:
  285.  
  286.     call    WriteConfig        ; display configuration params
  287.  
  288.     lea    ax, Config_4_Normal
  289.     mov    ConfigPointer,ax
  290. ;
  291. ;    verify that the NI card exists
  292. ;
  293. NiExists:
  294.     %GetNiPort(6)        ; Read ethernet rom check id (00, 55)
  295.     in    al, dx        ; al should contain 00
  296.     mov    ah, al        ; store in high byte
  297.  
  298.     %GetNiPort(7)
  299.     in    al, dx        ; al should contain 55
  300.     cmp    ax, 0055h
  301.     je    ZeroCounters
  302.  
  303.     lea    ax, NiNotFoundMsg
  304.     jmp    DIExit
  305.  
  306. ZeroCounters:
  307.     xor    ax, ax                ; zero counters
  308.     mov    TotalTxPacketCount, ax
  309.     mov    TotalTxPacketCount+2, ax
  310.     mov    TotalRxPacketCount, ax
  311.     mov    TotalRxPacketCount+2, ax
  312.     mov    NoECBAvailableCount, ax
  313.     mov    PacketTxTooSmallCount, ax
  314.     mov    PacketRxOverflowCount, ax
  315.     mov    PacketRxTooBigCount, ax
  316.     mov    PacketRxTooSmallCount, ax
  317.     mov    PacketTxMiscErrorCount, ax
  318.     mov    PacketRxMiscErrorCount, ax
  319.     mov    RetryTxCount, ax
  320.     mov    ChecksumErrorCount, ax
  321.     mov    HardwareRxMismatchCount, ax
  322.     mov    NotNetwarePacketCount, ax
  323.     mov    Restart586Count, ax
  324.     mov    RxStartCount, ax
  325.     mov    RxLostCount, ax
  326.  
  327. ;
  328. ;    Calculate the number of transmit buffers.  Note that 3COM
  329. ;    does not have as great a need for transmit buffers as does
  330. ;    Novell.
  331. ;
  332.     cmp    NiMemSize, 8
  333.     jne    MemSize16
  334.  
  335.     mov    Memend, 1fffh        ; set values for 8k memory
  336.     mov    TmpSCP, 1FF6h
  337.     mov    NumTxBuffs,1
  338.     jmp    short MemSizeDone
  339.  
  340. MemSize16:
  341.     cmp    NiMemSize,16
  342.     jne    MemSize64
  343.  
  344.     mov    Memend, 3fffh        ; set values for 16K memory
  345.     mov    TmpSCP, 3FF6h
  346.     mov    NumTxBuffs,2
  347.     jmp    short MemSizeDone
  348. ;
  349. MemSize64:
  350.     mov    Memend,0FFFFh
  351.     mov    TmpSCP, 0FFF6h
  352.     mov    NumTxBuffs,4
  353.  
  354. MemSizeDone:
  355.     mov    ax, NumTxBuffs
  356.     %trace_x(Transmit buffers:,NumTxBuffs)
  357.  
  358.     mov    es, NiMemLoc            ; ES -> NI buffer memory
  359.  
  360. ClearMemory:
  361.     xor    ax, ax
  362.     mov    di, ax
  363.     mov    cx, Memend
  364.     shr    cx, 1
  365.  
  366.     rep stosw
  367.  
  368.     mov    cx, TmpSCP
  369.     mov    SCP, cx
  370.  
  371. ResetCard:
  372.     %GetNiPort(0)                ; Reset Ni5210 586
  373.     out    dx, al
  374.  
  375.     call    SetNodeAddress            ; set DNodeAddress
  376.  
  377. Set_Vector:
  378.     cli
  379.     mov    ax, NiIRQ            ; interrupt line number
  380.     mov    bx, Offset %CGroup: AT_Isr    ; handler address
  381.     call    SetInterruptVector
  382.     mov    SlavePICUsed, al
  383.  
  384.     xor    ah,ah
  385.     %trace_x(Slave PIC usage: ,ax)
  386.  
  387.     mov    es, NiMemLoc            ; ES -> NiMemSeg
  388.     mov    cx, es                ; DS -> NiMemSeg
  389.     mov    ds, cx
  390.  
  391.     call    Configure586
  392.  
  393.     call    InitTxBuffs
  394.  
  395.     call    SetUpReads
  396.  
  397.     mov    DeadMan, DeadManTimeOut        ;init Deadman Counter
  398.     mov    TransmitFlag, FALSE
  399.  
  400.     sti
  401.  
  402.     %get_dataseg
  403.     mov    ds, ax                ; DS -> DGroup
  404.     mov    es, ax                ; ES -> DGroup
  405.  
  406.     xor    ax, ax                ; enable network connection
  407.     %GetNiPort(3)
  408.     out    dx, al
  409.  
  410.     lea    si, DNodeAddress
  411.     mov    di, NodeIdAddress
  412.  
  413.     movsw
  414.     movsw
  415.     movsw
  416.  
  417.     mov    es, NiMemLoc
  418.     call    unmaskint            ; unmask device interrupts
  419.  
  420.     xor    ax, ax
  421.     mov    cx, 1            ; transport time
  422.  
  423. DIExit:
  424.     ret
  425.  
  426. %SideDriverInitialize endp 
  427. ;
  428. ;
  429. ;    Set Interrupt Vector
  430. ;
  431. ;    Inputs:
  432. ;        ax - Interrupt Request Number (1-11)
  433. ;        bx - Interrupt Handler's Address
  434. ;
  435. ;    Returns:
  436. ;        al - non-zero if the driver needs to do an extra EOI
  437. ;
  438. ;    Modified:
  439. ;        NiVector  - Interrupt vector address
  440. ;        NiMask    - PIC mask to disable interrupts
  441. ;        NiUnmask  - PIC mask to enable interrupts
  442. ;        OldInterrupt  - Address of former handler for this interrupt
  443. ;
  444. ;    Called by:
  445. ;        DriverInitialize
  446. ;
  447. ;    Logic:
  448. ;
  449. ;    if (SlavePICUsed)        -- for int levels 2, 8-15
  450. ;        if (irq == 2)
  451. ;            NiVector = 71h;
  452. ;        else    NiVector = irq + 68h;
  453. ;    else    NiVector = irq + 8;
  454. ;
  455. ;    if (SlavePICUsed)
  456. ;        Level_7_Vector = 77h;
  457. ;    else    Level_7_Vector = 15;
  458. ;
  459. ;    get and set level 7 isr, ni5210 isr, and timer isr;
  460. ;    
  461. ;    NiMask = 2 ^ NiIRQ;
  462. ;    NiUnmask = NOT ( 2 ^ NiIRQ );
  463. ;
  464.  
  465. SetInterruptVector proc    near
  466.  
  467.     push    bp
  468.     mov    bp, sp
  469.     sub    sp, local_siz
  470.  
  471.     mov    ISRptr[bp], bx        ; save ISR handler's address
  472.  
  473.     xor    bx, bx
  474.     mov    bl, false        ; determine if the 2nd PIC is being used
  475.  
  476.     cmp    MachineType, MachID_AT    ; if machine is an AT or PS/2
  477.     jg    SIV00
  478.  
  479.     cmp    ax, 2            ; ... and if IRQ is 2 ...
  480.     jne    Slave_10
  481.  
  482.     mov    bl, true
  483.     jmp    SIV00
  484.     
  485. Slave_10:
  486.     cmp    ax, 8            ; ... or IRQ is 8 - 15
  487.     jl    SIV00
  488.  
  489.     mov    bl, true        ; the slave PIC is in use
  490.  
  491. SIV00:
  492.     mov    word ptr PICboolean[bp], bx ; save slave PIC boolean
  493.  
  494.     cmp    bl, true        ; compute vector number
  495.     jne    SIV10
  496.  
  497.     cmp    ax, 2
  498.     jne    SIV05
  499.  
  500.     mov    NiVector, 71h        ;  AT's IRQ2 => IRQ9
  501.     jmp    get_7_vector
  502.  
  503. SIV05:
  504.     add    ax, 68h            ; 70h == 2nd PIC's interrupt base
  505.     mov    NiVector, ax
  506.     jmp    get_7_vector
  507.  
  508. SIV10:
  509.     add    ax, 08h            ; 8 is 1st PIC's interrupt base
  510.     mov    NiVector, ax
  511.     
  512. get_7_vector:
  513.  
  514.     mov    ax, NiVector        ; get vector
  515.     push    es            ; Save buffer segment
  516.     mov    ah, 35h         ; Get old vector
  517.     int    21h
  518.  
  519.     mov    Word Ptr cs:Oldinterrupt, bx
  520.     mov    Word Ptr cs:OldInterrupt + 2, es
  521.  
  522.     pop    es
  523.     mov    dx, ISRptr[bp]        ; get ISR's address
  524.     mov    ah, 25h            ; Set new vector
  525.     int    21h
  526.  
  527.  
  528. ;
  529. ;    need to compute mask, unmask values
  530. ;
  531.     mov    cl, byte ptr NiIRQ    ; Interrupt number
  532.     mov    ah, 0FEH     
  533.     mov    al, 01H
  534.     rol    ah, cl 
  535.     rol    al, cl
  536.     mov    NiMask, al          ; interrupt mask value
  537.     mov    NiUnmask, ah        ; interrupt unmask value
  538.  
  539. SIV40:  
  540.     mov    ax, word ptr PICboolean[bp] ; fetch Slave PIC boolean
  541.  
  542.     mov    sp, bp
  543.     pop    bp
  544.     ret
  545.  
  546. SetInterruptVector    endp
  547.  
  548. ;------------------------------------------------------------------- GetConfig
  549. ;
  550. ;    Intialize configuration parameters (i/o base, interrupt level, etc)
  551. ;    for the NI card.  In case an error of some sort is encountered,
  552. ;    the Novell version returns the address of an error string and the 
  553. ;    3COM version returns an error number.
  554. ;
  555. ;       This procedure will search thru the slots for Our Adapter. When
  556. ;    found, we will read the information contained in the POS registers
  557. ;    and enable the card.
  558. ;
  559. ;    Called by:
  560. ;        DriverInitialize
  561. ;
  562. ;    Modifies:
  563. ;        NiMemLoc, NiIRQ, NiPort, Ni9210IntPort, 
  564. ;        NiMemSize, Ni9210BusArb, Ni9210Master
  565. ;
  566. ;    Returns:
  567. ;        ax:    0     =    all okay
  568. ;            nonzero    =    error, references error descriptor
  569. ;
  570. ;-----------------------------------------------------------------------------
  571. IRQ_TABLE    db    9            ; Interrupt Value 0
  572.         db    10            ; Interrupt Value 1
  573.         db    11            ; Interrupt Value 2
  574.         db    3            ; Interrupt Value 3
  575.  
  576.     Assume    cs: %CGroup, ds: %DGroup, es: NiMemSeg
  577.  
  578. GetConfig    proc    near
  579.  
  580.         mov    bx, %SideCard
  581.         mov    cx, 8
  582. Get_05:
  583. ;                        ; Select a Adapter
  584. ;                        ; 0,7,6,5,4,3,2,1
  585.         mov    ax, cx
  586.         or    ax, 08h
  587.         mov    dx, ADPTR_BD
  588.         out    dx, al
  589. ;
  590.         mov    dx, POSBASE + POS0
  591.         in    al, dx
  592.         xchg    ah, al
  593.         add    dx, POS1
  594.         in    al, dx
  595. ;                        ; Check for our ID
  596.         cmp    ax, NI9210_ID
  597.         jne    Get_10
  598.         dec    bx
  599.         jz    Get_15
  600. Get_10:
  601.         loop    Get_05
  602.         lea    ax,NiNotFoundMsg
  603.         jmp    Get_50
  604. Get_15:                        ; found our Adapter
  605.         and    cl,7
  606.         mov    Ni9210Slot,cl
  607. ;                        ; Save Rest of POS data
  608.         mov    di,Offset %DGroup:OldPOSData
  609.         mov    dx,POSBASE
  610.         mov    cx,8
  611. ;
  612.         %get_dataseg            ; ES -> DGroup
  613.         mov    es, ax
  614.  
  615. Get_20:                        ; Get the POS Data
  616.         insb
  617.  
  618.         inc    dx
  619.         loop    Get_20
  620. ;
  621. ;                        ; Get Ni9210 I/O Address
  622.         xor    ax,ax
  623.         mov    al,OldPOSData[POS3]
  624.         shl    ax,5
  625.         mov    NiPort,ax
  626.         add    ax,16            ; set up Interrupt Register address
  627.         mov    Ni9210IntPort,ax
  628. ;                        ; Get Ni9210 IRQ
  629.         mov    bl,OldPOSData[POS2]
  630.         and    bx,IRQMASK
  631.         shr    bx,1
  632.         mov    al,IRQ_TABLE[bx]
  633.         xor    ah,ah
  634.         mov    NiIRQ,ax
  635. ;                        ; Get Memory Address
  636.         xor    al,al
  637.         xor    bl,bl
  638.         mov    ah,OldPOSData[POS5]
  639.         mov    bh,OldPOSData[POS4]
  640.         and    bx,0E000h
  641.         shl    ax,5
  642.         shr    bx,3
  643.         or    ax,bx
  644.         mov    NiMemLoc,ax
  645.  
  646. ;                        ; get Memory Size and Bus info
  647.         mov    al,OldPosData[POS2]    ; This Driver run's as Slave
  648.         test    al,BMASEN
  649.         jz    Get_30
  650. ;                        ; We Don't want Bus Master
  651.         and    al,NOT BMASEN
  652.         or    al,MEM16K        ; We will assume from Master to Slave
  653. ;                        ; the static memory is 16K.
  654.         mov    dx,POSBASE + POS2
  655.         out    dx,al
  656.         %slow
  657.         mov    OldPosData[POS2],al
  658. ;                        ; Use Static Memory OnBoard 
  659. Get_30:                        ;
  660.         mov    Ni9210Master,FALSE
  661.         and    ax,BUSARB
  662.         shr    ax,4
  663.         mov    Ni9210BusArb,al
  664.         mov    NiMemSize,64
  665.         mov    Memend,0FFFFh
  666.         test    OldPOSData[POS2],MEM16K; Get Memory Size
  667.         jz    Get_40
  668.         mov    NiMemSize,16
  669.         mov    Memend,3FFFh
  670. ;                        ; enable the card
  671. Get_40:
  672.         mov    al,OldPosData[POS2]
  673.         or    al,CARDENA
  674.         mov    dx,POSBASE + POS2
  675.         out    dx,al
  676.         %slow
  677.         xor    ax,ax            ; Success !!!!!
  678. ;                        ; disable setup
  679. Get_50:
  680.         push    ax
  681.         mov    dx,ADPTR_BD
  682.         xor    ax,ax
  683.         out    dx,al
  684.         pop    ax
  685.  
  686.         %trace_x(I/O base:        ,NiPort)
  687.         %trace_x(Int Port:        ,Ni9210IntPort)
  688.         %trace_x(Interrupt line:  ,NiIRQ)
  689.         %trace_x(Memory base:     ,NiMemLoc)
  690.         %trace_x(Memory size (k): ,NiMemSize)
  691.  
  692.         ret
  693.  
  694. GetConfig    endp
  695.  
  696. ;--------------------------------------------------------------- WriteConfig
  697. ;
  698. ;    Display the board's configuration parameters (in a micro channel
  699. ;    environment).
  700. ;
  701. ;---------------------------------------------------------------------------
  702.  
  703. ASCII_TABLE    db    '0123456789ABCDEF'
  704.  
  705. WriteConfig    proc    near
  706. ;                        ; Set up IRQ Level
  707.         mov    dx,NiIRQ
  708.         mov    cl,10
  709.         mov    di,Offset CIRQL + 2
  710.         pushf
  711.         std
  712. ;
  713. Write_10:
  714.         mov    ax,dx
  715.         div    cl
  716.         mov    dl,al
  717.         mov    bl,ah
  718.         xor    bh, bh
  719.         mov    al,ASCII_TABLE[bx]
  720.         stosb    
  721. ;
  722.         mov    ax,dx
  723.         div    cl
  724.         mov    dl,al
  725.         mov    bl,ah
  726.         xor    bh, bh
  727.         mov    al,ASCII_TABLE[bx]
  728.         stosb    
  729. ;
  730. Write_15:
  731. ;                        ; Write I/O Address
  732.         push    NiPort
  733.         mov    di,Offset CIOl + 3
  734.         mov    cl,16
  735. Write_20:
  736.         pop    ax
  737.         xor    dx,dx
  738.         or    ax,ax
  739.         jz    Write_25
  740. ;
  741.         div    cx
  742.         push    ax
  743.         and    dl,0Fh
  744.         mov    bx,dx
  745.         mov    al,ASCII_TABLE[bx]
  746.         stosb
  747.         jmp    short Write_20
  748. ;
  749. Write_25:
  750.         mov    di,Offset CMEMl + 3
  751.         push    NiMemLoc
  752. Write_30:
  753.         pop    ax
  754.         xor    dx,dx
  755.         or    ax,ax
  756.         jz    Write_35
  757. ;
  758.         div    cx
  759.         push    ax
  760.         and    dl,0Fh
  761.         mov    bx,dx
  762.         mov    al,ASCII_TABLE[bx]
  763.         stosb
  764.         jmp    short Write_30
  765. ;
  766. Write_35:
  767.         popf
  768.         ret
  769. ;
  770. WriteConfig    endp
  771.  
  772.     end
  773.