home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / src / aquila.asm < prev    next >
Assembly Source File  |  1995-06-25  |  18KB  |  763 lines

  1. version    equ    0
  2. ;History:303,1
  3.  
  4.     page    55,120
  5.     TITLE    Aquila Ethernet PC/TCP Packet Driver
  6. ;**********************************************************************
  7. ;
  8. ;    Aquila Communications, Inc. AQ-PCE 1xx PC/TCP Packet Driver
  9. ;    Copyright (c) Aquila Communications, Inc. 1989
  10. ;    All Rights Reserved
  11. ;
  12. ;    Author: Barry I. Kelman
  13. ;
  14. ;    Revision History:
  15. ;
  16. ;        11/7/89  bik    Adapted from Novell Shell Driver
  17. ;               11/30/89  bik   V1.0 Release
  18. ;
  19. ;*********************************************************************
  20.  
  21.  
  22.     include    defs.asm
  23.  
  24. ; I/O ports
  25.  
  26. EthRSel        equ    0
  27. EthRSelOdd    equ    1
  28. EthDSel        equ    8
  29. EthDSelOdd    equ    9
  30. EthCtlReg    equ    0eh
  31.  
  32. ;these registers are accessible only through EthRsel and EthRSelOdd
  33. DLCR_XMIT_STAT    equ    0
  34. DLCR_XMIT_MASK    equ    1
  35. DLCR_RECV_STAT    equ    2
  36. DLCR_RECV_MASK    equ    3
  37. DLCR_XMIT_MODE    equ    4
  38. DLCR_RECV_MODE    equ    5
  39. DLCR_ENABLE      equ    6
  40. DLCR_TDR_LOW    equ    7
  41. DLCR_NODE_ID    equ    8        ;(EthCtlBMP must be reset)
  42. DLCR_TDR_HIGH    equ    0fh
  43.  
  44. ;these registers are accessible only through EthDSel and EthDSelOdd
  45. ;that fact is indicated by the high bit being set.  The setreg macro
  46. ;takes care of selecting EthDSel and EthDSelOdd as needed.
  47. BMPR_MEM_PORT    equ    8000h        ;We never use this.
  48. BMPR_PKT_LEN_LO    equ    8002h        ;(EthCtlBMP must be set)
  49. BMPR_PKT_LEN_HI    equ    8003h        ;(EthCtlBMP must be set)
  50. BMPR_DMA_ENABLE    equ    8004h        ;(EthCtlBMP must be set)
  51.  
  52. ;DLCR_XMIT_STAT bits:
  53. EthTxBusWrErr    equ    00000001b
  54. EthTx16Col    equ    00000010b
  55. EthTxCol    equ    00000100b
  56. EthTxUndrFlow    equ    00001000b
  57. EthTxShort    equ    00010000b
  58. EthTxXmitRcvd    equ    00100000b
  59. EthTxNetBsy    equ    01000000b
  60. EthTxOk        equ    10000000b
  61. TxInterruptMask    equ    EthTxBusWrErr or EthTx16Col or EthTxUndrFlow
  62.  
  63. ;DLCR_RECV_STAT bits:
  64. EthRxOvrFlow    equ    00000001b
  65. EthRxCRCErr    equ    00000010b
  66. EthRxAlignErr    equ    00000100b
  67. EthRxShort    equ    00001000b
  68. EthRxRmtRst    equ    00010000b
  69. EthRxBusRdErr    equ    01000000b
  70. EthRxRdy    equ    10000000b
  71. EthRxErrors     equ     01000111b
  72. RxInterruptMask        equ    EthRxRdy or EthRxErrors
  73.  
  74. ;DLCR_XMIT_MODE bits:
  75. EthDisCar    equ    00000001b
  76. EthLoopN    equ    00000010b
  77. EthTestMode    equ    00000100b
  78. EthChipTest    equ    00001000b
  79.  
  80. ;DLCR_RECV_MODE bits:
  81. EthAcceptNone    equ    00000000b
  82. EthAcceptMult3    equ    00000001b
  83. EthAcceptNorm    equ    00000010b
  84. EthAcceptAll    equ    00000011b
  85. EthEnaRemRst    equ    00000100b
  86. EthEnaShort    equ    00001000b
  87. EthAdrSize    equ    00010000b
  88. EthBufFull    equ    00100000b
  89. EthBufEmpty    equ    01000000b
  90. EthTest        equ    10000000b
  91.  
  92. ;BMPR_DMA_ENABLE bits:
  93. EthDMAWrt       equ     00000001b
  94. EthDMARd    equ     00000010b
  95. EthDMADis       equ     00000000b
  96.  
  97. ;DLCR_ENABLE bits:
  98. DLCR_ENABLEN    equ    10000000b    ;true if disabled.
  99.  
  100. ;BMPR_PKT_LEN_LO bit:
  101. EthXmitStart    equ    08000h
  102.  
  103. ;EthCtlReg bits:
  104. EthCtlReset    equ    00000000b
  105. EthCtlBProm    equ    00000000b    ;Boot Rom enabled, controller reset
  106. EthCtlBPNoRes    equ    10000000b    ;Boot Rom enabled.
  107. EthCtlBMP    equ    10000001b    ;Buffer Memory Pointer enabled.
  108. EthCtlIDProm    equ    00000010b    ;ID PROM enabled.
  109. EthCtlHBDis    equ    00000100b    ;High byte disabled (116 only).
  110.  
  111. setreg    macro    reg, map
  112.     setport    EthCtlReg
  113.     mov     al, (reg and 7fffh)*8 or EthCtlBMP
  114.     out     dx, al            ;switch to length high byte reg
  115.   if     (reg and 8001h) eq 0000h
  116.     setport    EthRSel
  117.   elseif (reg and 8001h) eq 0001h
  118.     setport    EthRSelOdd
  119.   elseif (reg and 8001h) eq 8000h
  120.     setport    EthDSel
  121.   else    ;(reg and 8001h) eq 8001h
  122.     setport    EthDSelOdd
  123.   endif
  124.     endm
  125.  
  126.  
  127. code    segment    word public
  128.     assume    cs:code, ds:code
  129.  
  130.     public    int_no
  131. int_no        db    3,0,0,0        ;must be four bytes long for get_number.
  132. io_addr        dw    0360h,0        ; I/O address for card (jumpers)
  133. base_addr    dw      0d000h,0    ; base segment for board (jumper set)
  134.  
  135.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  136. driver_class    db    BLUEBOOK, IEEE8023, 0;from the packet spec
  137. driver_type    db    52        ;from the packet spec
  138. driver_name    db    'Aquila',0    ;name of the driver.
  139. driver_function    db    2
  140. parameter_list    label    byte
  141.     db    1            ;major rev of packet driver
  142.     db    9            ;minor rev of packet driver
  143.     db    14            ;length of parameter list
  144.     db    EADDR_LEN        ;length of MAC-layer address
  145.     dw    GIANT            ;MTU, including MAC headers
  146.     dw    MAX_MULTICAST * EADDR_LEN;buffer size of multicast addrs
  147.     dw    0            ;(# of back-to-back MTU rcvs) - 1
  148.     dw    0            ;(# of successive xmits) - 1
  149. int_num    dw    0            ;Interrupt # to hook for post-EOI
  150.                     ;processing, 0 == none,
  151.  
  152.     public  rcv_modes
  153. rcv_modes    dw    7        ;number of receive modes in our table.
  154.         dw    0               ;There is no mode zero
  155.         dw    rcv_mode_1
  156.         dw    0
  157.         dw    rcv_mode_3
  158.         dw    0        ;haven't set up perfect filtering yet.
  159.         dw    0
  160.         dw    rcv_mode_6
  161.  
  162.     even
  163.  
  164. RemainPacketLength    dw    ?    ;remaining after we read the header.
  165.  
  166. TxInProgress        db    0
  167.  
  168. ;-> the assigned address of the card.
  169.     extrn    rom_address: byte
  170.  
  171. ;-> the current address of the card.
  172.     extrn    my_address: byte
  173.  
  174. NodeAddress         db      6 dup(0)
  175.  
  176.     even
  177. bxSave      dw      0
  178.  
  179. EthHeaderStructure    struc
  180.     PH_DAdr        db    6 dup (?)
  181.     PH_SAdr        db    6 dup (?)
  182.     PH_length    dw    ?,?,?,?    ; max possible packet type.
  183. EthHeaderStructure    ends
  184.  
  185.     even
  186. EthHeaderBuf    EthHeaderStructure <>
  187.  
  188. even
  189.  
  190.     include    timeout.asm
  191.     include    movemem.asm
  192.  
  193.     public bad_command_intercept
  194. bad_command_intercept:
  195. ;called with ah=command, unknown to the skeleton.
  196. ;exit with nc if okay, cy, dh=error if not.
  197.     mov    dh,BAD_COMMAND
  198.     stc
  199.     ret
  200.  
  201.     public    as_send_pkt
  202. ; The Asynchronous Transmit Packet routine.
  203. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  204. ;   interrupts possibly enabled.
  205. ; Exit with nc if ok, or else cy if error, dh set to error number.
  206. ;   es:di and interrupt enable flag preserved on exit.
  207. as_send_pkt:
  208.     ret
  209.  
  210.     public    drop_pkt
  211. ; Drop a packet from the queue.
  212. ; Enter with es:di -> iocb.
  213. drop_pkt:
  214.     assume    ds:nothing
  215.     ret
  216.  
  217.     public    xmit
  218. ; Process a transmit interrupt with the least possible latency to achieve
  219. ;   back-to-back packet transmissions.
  220. ; May only use ax and dx.
  221. xmit:
  222.     assume    ds:nothing
  223.     ret
  224.  
  225.  
  226.     public    send_pkt
  227. send_pkt:
  228. ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
  229. ;  (only if the high-performance bit is set in driver_function)
  230. ;enter with ds:si -> packet, cx = packet length.
  231. ;if we're a high-performance driver, es:di -> upcall.
  232. ;exit with nc if ok, or else cy if error, dh set to error number.
  233.     assume    ds:nothing
  234.  
  235.     cmp     cx, GIANT
  236.     ja    send_pkt_toobig
  237.     cmp     TxInProgress, 0
  238.     je      TxNoErrs
  239.     mov    ax,18
  240.     call    set_timeout
  241. TxLoop:
  242.     loadport
  243.     setreg    DLCR_XMIT_STAT
  244.     in    al, dx            ;get xmit stat
  245.     out    dx, al            ;clear error bits
  246. ;Check for transmitter available
  247.     test    al, EthTxOk
  248.     jne    TxLoopEnd
  249.     call    do_timeout        ;don't wait forever.
  250.     jne    TxLoop
  251.     mov    dh,CANT_SEND        ;give up with an error.
  252.     stc
  253.     ret
  254. TxLoopEnd:
  255.  
  256.     mov     TxInProgress, 0
  257.     test    al, EthTxBusWrErr OR EthTx16Col OR EthTxUndrFlow
  258.     jz      TxNoErrs
  259.     call    count_out_err
  260. TxNoErrs:
  261.     mov     es, base_addr
  262.     xor     di, di
  263.     push    cx
  264.     call    movemem
  265.     pop    cx
  266.     cmp    cx,RUNT
  267.     ja    TxLenOk
  268.     mov    cx,RUNT
  269. TxLenOk:
  270.     or    cx, EthXmitStart    ;or in start bit
  271.     loadport
  272.     setport    EthCtlReg
  273.     mov     al, (BMPR_PKT_LEN_LO and 7fffh)*8 or EthCtlHBDis or EthCtlBMP
  274.     out     dx, al            ;switch to length low byte reg
  275.     setport    EthDSel
  276.     mov     al, cl            ;send low byte
  277.     out    dx, al            ;start backup going
  278.     setreg    BMPR_PKT_LEN_HI
  279.     mov     al, ch            ;send high byte
  280.     out    dx, al            ;start backup going
  281.     mov    TxInProgress, -1    ;set xmit in progress
  282.     clc
  283. HandleTxInterrupt:
  284.     ret
  285. send_pkt_toobig:
  286.     mov    dh,NO_SPACE
  287.     stc
  288.     ret
  289.  
  290.  
  291.     public    set_address
  292. set_address:
  293. ;enter with ds:si -> Ethernet address, CX = length of address.
  294. ;exit with nc if okay, or cy, dh=error if any errors.
  295.     mov    dh,CANT_SET
  296.     stc
  297.     ret
  298.  
  299. ;for some reason, the following routine doesn't work after the driver is setup,
  300. ;but it works at initialization time.  So, we arrange things so that it's only
  301. ;called when it works.  Oh well.
  302. set_address_0:
  303.     assume    ds:nothing
  304.     loadport
  305.     setport    EthCtlReg
  306.     mov     al, DLCR_ENABLE*8 or EthCtlIDProm
  307.     out     dx, al            ;set control reg to access ID Prom
  308.                     ; leave HW Reset on
  309.     setport    EthRSel            ;disable controller while setting node
  310.     in    al,dx
  311.     push    ax            ;remember whether it was disabled.
  312.  
  313.     mov    al, DLCR_ENABLEN
  314.     out    dx, al
  315.  
  316.     mov     bx, DLCR_NODE_ID*8
  317.     mov    cx, EADDR_LEN
  318. set_node_addr_1:
  319.     loadport
  320.     setport    EthCtlReg        ;get node port offset
  321.     mov    al,bl
  322.     or    al,EthCtlIDProm
  323.     out     dx, al            ;set up control reg
  324.     setport    EthRSel            ;assume an even port number.
  325.     test    bx, 1*8            ;is the port number odd?
  326.     jz      set_node_addr_2
  327.     setport    EthRSelOdd
  328. set_node_addr_2:
  329.     lodsb                ;loop to move node in
  330.     out    dx, al
  331.     add    bx, 1*8            ;advance to the next DLCR.
  332.     loop    set_node_addr_1
  333.  
  334.     loadport
  335.     setport    EthCtlReg
  336.     mov     al, DLCR_ENABLE*8
  337.     or    al,EthCtlIDProm
  338.     out     dx, al            ;set control reg to access ID Prom
  339.                     ; leave HW Reset on
  340.     setport    EthRSel            ;restore original conditions...
  341.     pop    ax
  342.     out    dx,al
  343.  
  344.     clc
  345.     ret
  346.  
  347.  
  348. rcv_mode_1:
  349.     mov    bl,EthAcceptNone    ; don't receive any packets
  350.     jmp    short    rcv_mode_set
  351.  
  352. rcv_mode_3:
  353.     mov    bl,EthAcceptNorm    ; receive mine, broads, and multis.
  354.     jmp    short    rcv_mode_set
  355.  
  356. rcv_mode_6:
  357.     mov    bl,EthAcceptAll        ; receive all packets.
  358. rcv_mode_set:
  359.     loadport
  360.     setreg    DLCR_RECV_MODE
  361.     mov    al,bl
  362.     out    dx,al
  363.     ret
  364.  
  365.  
  366.     public    set_multicast_list
  367. set_multicast_list:
  368. ;enter with ds:si ->list of multicast addresses, ax = number of addresses,
  369. ;  cx = number of bytes.
  370. ;return nc if we set all of them, or cy,dh=error if we didn't.
  371.     mov    dh,NO_MULTICAST
  372.     stc
  373.     ret
  374.  
  375.  
  376.     public    terminate
  377. terminate:
  378.     ret
  379.  
  380.     public    reset_interface
  381. reset_interface:
  382. ;reset the interface.
  383.     assume    ds:code
  384.     ret
  385.  
  386.  
  387. ;called when we want to determine what to do with a received packet.
  388. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  389.     extrn    recv_find: near
  390.  
  391. ;called after we have copied the packet into the buffer.
  392. ;enter with ds:si ->the packet, cx = length of the packet.
  393.     extrn    recv_copy: near
  394.  
  395. ;call this routine to schedule a subroutine that gets run after the
  396. ;recv_isr.  This is done by stuffing routine's address in place
  397. ;of the recv_isr iret's address.  This routine should push the flags when it
  398. ;is entered, and should jump to recv_exiting_exit to leave.
  399. ;enter with ax = address of routine to run.
  400.     extrn    schedule_exiting: near
  401.  
  402. ;recv_exiting jumps here to exit, after pushing the flags.
  403.     extrn    recv_exiting_exit: near
  404.  
  405.     extrn    count_in_err: near
  406.     extrn    count_out_err: near
  407.  
  408.     public    recv
  409. recv:
  410. ;called from the recv isr.  All registers have been saved, and ds=cs.
  411. ;Upon exit, the interrupt will be acknowledged.
  412.     assume    ds:code
  413.     loadport
  414.     setreg    DLCR_RECV_STAT
  415.     in    al, dx            ;get recv stat
  416.     and     al, RxInterruptMask
  417.     out    dx, al            ;clear error bits
  418.  
  419.     setreg    DLCR_RECV_MASK
  420.     xor    ax, ax
  421.     out    dx, al            ;mask recv ints
  422.  
  423. ;
  424. ;    HANDLE THE RECEIVE INTERRUPTS
  425. ;
  426.  
  427. CheckForReceiveInterrupt:
  428.     loadport
  429.     setreg    DLCR_RECV_MODE
  430.     in    al, dx
  431.     test    al, EthBufEmpty        ;Is the buffer empty?
  432.     jz      GotRecvPacket        ;no, go read the packet in.
  433.     jmp    ExitDriverISR
  434.  
  435. RxErrIgnore:
  436.     call    count_in_err
  437.     jmp    RxIgnore
  438.  
  439. ;
  440. ;    Got a Receive Packet - Read in Control Byte & Length
  441. ;
  442. GotRecvPacket:
  443.     setreg    DLCR_RECV_STAT
  444.     mov    al, EthRxRdy
  445.     out     dx, al            ;clear rx rdy bit
  446.     setport    EthCtlReg
  447.     mov     al, EthCtlBMP
  448.     out     dx, al            ;zero address to chip
  449.     mov    ds, base_addr        ;buffer segment in DS
  450.     assume  ds: nothing
  451.     mov    ax, ds:[0]        ;get control byte
  452.     mov    cx, ds:[0]        ;get length
  453.     test     al, EthRxErrors
  454.     jnz    RxErrIgnore        ;check for errors
  455.     cmp    cx, size EthHeaderStructure
  456.     jb    RxErrIgnore        ;packet too short
  457.     cmp    cx, GIANT
  458.     ja    RxErrIgnore        ;or too long
  459.  
  460.     sub    cx, size EthHeaderStructure
  461.     mov    RemainPacketLength, cx    ;remember how much more we have to read.
  462.  
  463.     xor    si, si            ;doesn't *really* matter where we start.
  464.     mov     bx, cs
  465.     mov    es, bx
  466.     mov    di, offset EthHeaderBuf
  467.     assume    es:code
  468.     mov    cx, size EthHeaderStructure/2
  469.     rep    movsw            ;move header into work buffer
  470.     mov    ds,bx
  471.     assume  ds:code
  472.  
  473.     mov    di,offset EthHeaderBuf.PH_SAdr
  474.     mov    si,offset my_address
  475.     mov    cx,EADDR_LEN/2
  476.     repe    cmpsw            ;make sure it's not from us
  477.     jz    RxNotOursIgnore        ;ignore our own broadcasts.
  478.  
  479.     mov    di,offset EthHeaderBuf.PH_length
  480.  
  481.     mov    cx,RemainPacketLength    ;get the length of the packet back.
  482.     add    cx, size EthHeaderStructure
  483.  
  484.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  485.     mov    ax, es:[di]
  486.     xchg    ah, al
  487.     cmp     ax, 1500
  488.     ja    BlueBookPacket
  489.     inc    di            ;set di to 802.2 header
  490.     inc    di
  491.     mov    dl, IEEE8023
  492. BlueBookPacket:
  493.     call    recv_find        ;look up our type.
  494.     assume    es:nothing
  495.  
  496.     mov     ax, es
  497.     or      ax, di
  498.     jnz    GotCompletePacketECB    ;got one - go fill it up
  499.  
  500. RxNotOursIgnore:
  501.     call    count_in_err        ;none available - inc error count
  502.     mov    cx, RemainPacketLength
  503. RxIgnore:
  504.     mov    ds, base_addr
  505.     assume    ds:nothing
  506.     xor    si, si
  507.     shr     cx, 1
  508.     rep    lodsw
  509.     jnc     RxIgnReload
  510.     lodsb
  511. RxIgnReload:
  512.     movseg    ds,cs
  513.     jmp    CheckForReceiveInterrupt;go check for more.
  514.  
  515. GotCompletePacketECB:
  516.     assume    ds:code
  517.  
  518.     push    es            ;remember where the packet is going.
  519.     push    di
  520.  
  521.     mov     si, offset EthHeaderBuf
  522.     mov     cx, size EthHeaderStructure/2
  523.     rep    movsw            ;move header to FTP Buf
  524.  
  525.     mov    cx, RemainPacketLength
  526.     mov     ds, base_addr
  527.     assume    ds:nothing
  528.     xor     si, si
  529.     shr     cx, 1
  530.     rep    movsw            ;move rest of packet
  531.     jnc     IncTotRx
  532.     movsb
  533. IncTotRx:
  534.     pop    si
  535.     pop    ds
  536.     assume    ds:nothing
  537.  
  538.     mov    cx,RemainPacketLength    ;get the length of the packet back.
  539.     add    cx, size EthHeaderStructure
  540.  
  541.     call    recv_copy
  542.     mov     ax, cs
  543.     mov     ds, ax
  544.     assume  ds: code
  545.     jmp    CheckForReceiveInterrupt
  546.  
  547. ExitDriverISR:
  548.     assume  ds: code
  549.     loadport
  550.     setreg    DLCR_XMIT_MASK
  551.     mov    al, TxInterruptMask
  552.     out    dx, al            ;restore it
  553.     setreg    DLCR_RECV_MASK
  554.     mov    al, RxInterruptMask
  555.     out    dx, al            ;restore it
  556.     setport    EthCtlReg
  557.     mov     al, EthCtlBMP
  558.     out     dx, al
  559.  
  560.     ret
  561.  
  562.     public    timer_isr
  563. timer_isr:
  564. ;if the first instruction is an iret, then the timer is not hooked
  565.     iret
  566.  
  567. ;any code after this will not be kept.  Buffers used by the program, if any,
  568. ;are allocated from the memory between end_resident and end_free_mem.
  569.     public end_resident,end_free_mem
  570. end_resident    label    byte
  571. end_free_mem    label    byte
  572.  
  573.     extrn    set_recv_isr: near
  574.     extrn    maskint: near
  575.  
  576. ;enter with si -> argument string, di -> word to store.
  577. ;if there is no number, don't change the number.
  578.     extrn    get_number: near
  579.  
  580. ;enter with dx -> name of word, di -> dword to print.
  581.     extrn    print_number: near
  582.  
  583.     public    usage_msg
  584. usage_msg    db    "usage: aquila [options] <packet_int_no> <hardware_irq> <io_addr> <base_addr>",CR,LF,'$'
  585.  
  586.     public    copyright_msg
  587. copyright_msg    db    "Packet driver for the Aquila, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF
  588.     db    "Copyright (C) Aquila Communications, Inc., 1989. ",CR,LF
  589.     db    "All Rights Reserved.",CR,LF, '$'
  590.  
  591. no_prom_msg    db    "The address PROM does not appear to be at that memory address",CR,LF,'$'
  592. no_io_msg    db    "Unable to read/write I/O ports",CR,LF,'$'
  593. addr_bad_msg    db    "Memory address should be less than 65536.",CR,LF,'$'
  594.  
  595.  
  596.     public    parse_args
  597. parse_args:
  598.     mov    di,offset int_no
  599.     call    get_number
  600.     mov    di,offset io_addr
  601.     call    get_number
  602.     mov    di,offset base_addr
  603.     call    get_number
  604.     clc
  605.     ret
  606.  
  607.  
  608.     public    etopen
  609. etopen:
  610. ;
  611. ;    INITIALIZE TRANSMIT QUEUE AND RX-HOLD LIST POINTERS
  612. ;
  613.     assume    ds:code
  614.     mov    al,int_no
  615.     call    maskint            ;disable these interrupts.
  616.  
  617.     cmp    base_addr.offs,0    ;low word of segment can't be zero.
  618.     je    etopen_1
  619.     cmp    base_addr.segm,0    ;high word of segment must be zero.
  620.     je    etopen_2
  621. etopen_1:
  622.     mov    dx,offset addr_bad_msg
  623.     stc
  624.     ret
  625. etopen_2:
  626.  
  627.     loadport
  628.     setport    EthCtlReg
  629.     mov     al, DLCR_ENABLE*8 or EthCtlIDProm
  630.     out     dx, al            ;set control reg to access ID Prom
  631.                     ; leave HW Reset on
  632.     setport    EthRSel            ;disable controller while setting node
  633.     mov    al, DLCR_ENABLEN
  634.     out    dx, al
  635.  
  636.     mov    ds, base_addr
  637.     assume  ds: nothing
  638.  
  639.     xor    si, si            ;set DS:SI to node address prom
  640.     mov    ax, [si]
  641.     or    ax, ax            ;Check for Aquila's manufacturer code.
  642.     jnz    SetRandomJmp1        ;not there -- give up.
  643.     cmp    byte ptr [si+2],084h
  644.     je    InitNodeAddr        ;...
  645. SetRandomJmp1:
  646.     mov    dx,offset no_prom_msg
  647.     movseg    ds,cs
  648.     jmp     InitHwErr
  649.  
  650. InitNodeAddr:
  651.     mov     ax, cs            ;move the address over.
  652.     mov    es, ax
  653.     mov    di, offset rom_address    ;set ES:DI to point to cs:rom_address
  654.     mov    cx,EADDR_LEN/2
  655.     rep    movsw
  656.  
  657.     movseg    ds,cs
  658.     assume    ds:code
  659.     mov    si,offset rom_address
  660.     call    set_address_0
  661.  
  662.     push    cs
  663.     pop     es
  664.     assume  es: code
  665.  
  666.     loadport
  667.     setreg    DLCR_XMIT_STAT
  668.     in      al, dx
  669.     out     dx, al            ;clear xmit interrupts at controller
  670.     setreg    DLCR_RECV_STAT
  671.     in      al, dx
  672.     out     dx, al            ;clear recv interrupts at controller
  673.     setreg    DLCR_XMIT_MASK
  674.     mov     cx, 50
  675. init_hw_1:
  676.     in    al,61h
  677.     loop    init_hw_1        ;wait >15 usec
  678.     xor    ax, ax
  679.     out    dx, al
  680.     in    al, dx            ;make sure that we read the same thing
  681.     cmp    al, ah            ;  we just wrote.
  682.     jne    InitHwErr1
  683.     setreg    DLCR_RECV_MASK
  684.     xor    ax, ax
  685.     out    dx, al
  686.     in    al, dx
  687.     cmp    al, ah
  688.     je      InitHwSetCtl
  689. InitHwErr1:
  690.     mov    dx,offset no_io_msg
  691. InitHwErr:
  692.     stc
  693.     ret
  694.  
  695. InitHwSetCtl:
  696.     setreg    BMPR_DMA_ENABLE
  697.     mov    ax, EthDMAWrt or EthDMARd
  698.     out    dx, al
  699.     setreg    DLCR_XMIT_MODE
  700.     mov    al, EthLoopN
  701.     out    dx, al
  702.     setreg    DLCR_RECV_MODE
  703.     mov    al, EthAcceptNorm
  704.     out    dx, al
  705.     setreg    DLCR_ENABLE
  706.     xor    ax, ax
  707.     out    dx, al            ;enable the controller
  708.     mov     cx, 500
  709. init_hw_2:
  710.     in    al,61h
  711.     loop    init_hw_2        ; wait > 120 usec
  712.     setreg    DLCR_XMIT_MASK
  713.     mov    al, TxInterruptMask
  714.     out     dx, al            ;set real interrupt masks
  715.     setreg    DLCR_RECV_MASK
  716.     mov    al, RxInterruptMask
  717.     out     dx, al
  718.     setreg    DLCR_XMIT_MODE
  719.     mov    al, EthLoopN
  720.     out    dx, al
  721.  
  722. ;
  723. ; Now hook in our interrupt
  724. ;
  725.     call    set_recv_isr
  726.  
  727.     sti
  728.  
  729.     mov    al, int_no        ; Get board's interrupt vector
  730.     add    al, 8
  731.     cmp    al, 8+8            ; Is it a slave 8259 interrupt?
  732.     jb    set_int_num        ; No.
  733.     add    al, 70h - 8 - 8        ; Map it to the real interrupt.
  734. set_int_num:
  735.     xor    ah, ah            ; Clear high byte
  736.     mov    int_num, ax        ; Set parameter_list int num.
  737.  
  738.     clc
  739.     ret
  740.  
  741.  
  742. int_no_name    db    "Interrupt number ",'$'
  743. io_addr_name    db    "I/O port ",'$'
  744. base_addr_name    db    "Memory address ",'$'
  745.  
  746.  
  747.     public    print_parameters
  748. print_parameters:
  749.     mov    di,offset int_no
  750.     mov    dx,offset int_no_name
  751.     call    print_number
  752.     mov    di,offset io_addr
  753.     mov    dx,offset io_addr_name
  754.     call    print_number
  755.     mov    di,offset base_addr
  756.     mov    dx,offset base_addr_name
  757.     call    print_number
  758.     ret
  759.  
  760. code    ends
  761.  
  762.     end
  763.