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

  1. version        equ     4
  2.  
  3. ;******************************************************************************;
  4. ;*                                                                            *;
  5. ;*     File: tiara.asm                                                        *;
  6. ;*     Auth: Brian Fisher                                                     *;
  7. ;*           Queens University                                                *;
  8. ;*           Computing and Communications Services                            *;
  9. ;*           Rm 2-50 Dupuis Hall                                              *;
  10. ;*           Kingston Ontario                                                 *;
  11. ;*                                                                            *;
  12. ;*     Date: January 24 1990                                                  *;
  13. ;*                                                                            *;
  14. ;*     Purp: (3C501) Packet driver for tiara Ethernet Card.                   *;
  15. ;*                                                                            *;
  16. ;*============================================================================*;
  17. ;*     Revs: January 25 1990   V 1.6.0 Clean up code and document.            *;
  18. ;*           Feb     24 1991   V 1.8.2 Gets IRQ and I/O info from MCH POS regs*;
  19. ;*                                                                            *;
  20. ;*============================================================================*;
  21. ;*                                                                            *;
  22. ;*     Thanks, Mehdi Safipour, of tiara Computer Systems, who supplied the    *;
  23. ;*     programming manual and examples.                                       *;
  24. ;*                                                                            *;
  25. ;*============================================================================*;
  26. ;*                                                                            *;
  27. ;*     Logic -                                                                *;
  28. ;*                                                                            *;
  29. ;*     Initialization - classic, by-the-book initialization, with one         *;
  30. ;*     exception:  The manual didn't mention the fact that receive            *;
  31. ;*     interrupts will not always work unless the receive buffer is           *;
  32. ;*     vacuumed.                                                              *;
  33. ;*                                                                            *;
  34. ;*     Byte/Word I/O mode was determined by code ruthlessly copied from       *;
  35. ;*     NI5010.ASM, auth: Russ Nelson.                                         *;
  36. ;*                                                                            *;
  37. ;*     Transmit-no surprises, data goes whoosh!                               *;
  38. ;*                                                                            *;
  39. ;*     Receive-interrupt driven receive makes upcalls to inform the ULP of    *;
  40. ;*     its status.  The 16 byte ethernet header is copied from the card to    *;
  41. ;*     a temporary buffer, to determine the ether-type.  Recv_find is called  *;
  42. ;*     to acquire a buffer from the ULP.  If no buffer, the packet is dropped.*;
  43. ;*     If a buffer is acquired, the packet is copied into it, and recv_copy   *;
  44. ;*     informs the ULP that the data is there.                                *;
  45. ;*                                                                            *;
  46. ;******************************************************************************;
  47. ;
  48.  
  49. DLCR_XMIT_STAT EQU     0        ;NICE I/O Register offsets
  50. DLCR_RECV_STAT EQU     1
  51. DLCR_XMIT_MASK EQU     2
  52. DLCR_RECV_MASK EQU     3
  53. DLCR_XMIT_MODE EQU     4
  54. DLCR_RECV_MODE EQU     5
  55. DLCR_CONFIG    EQU     6
  56. DLCR_RBNK      EQU     7
  57. DLCR_NODE_ID   EQU     8
  58. DLCR_TDR_LOW   EQU     0eh
  59. DLCR_TDR_HIGH  EQU     0FH
  60. BMPR_MEM_PORT  EQU     8
  61. BMPR_PKT_LEN   EQU     10
  62. PROM_ID        EQU     18H
  63. TMST           EQU     80h
  64. TMT_OK         EQU     80h
  65. BUF_EMPTY      EQU     40h
  66. card_disable   equ     82h        ; written to DLCR_CONFIG to disable card
  67. card_enable    equ     02h        ; written to DLCR_CONFIG to enable card
  68. clear_status   equ     00000111B    ; used to clear status info
  69. ;                      !!!!!!!!
  70. ;                      !!!!!!!+--------CLEAR BUS WRITE ERROR
  71. ;                      !!!!!!+---------CLEAR 16 COLLISION
  72. ;                      !!!!!+----------CLEAR COLLISION
  73. ;                      !!!!+-----------RES
  74. ;                      !!!+------------NC
  75. ;                      !!+-------------NC
  76. ;                      !+--------------NC
  77. ;                      +---------------NC
  78. ;
  79. no_tx_irqs      equ     0              ; written to clear transmit IRQs
  80. clr_rcv_status  equ     0CFh           ; clears receive status
  81. en_rcv_irqs     equ     10000000B      ; enable receive interrupts
  82. ;
  83. ;                      !!!!!!!!--------
  84. ;                      !!!!!!!+--------ENABLE OVERFLOW
  85. ;                      !!!!!!+---------ENABLE CRC
  86. ;                      !!!!!+----------ENABLE ALIGN
  87. ;                      !!!!+-----------ENABLE SHORT PKT
  88. ;                      !!!+------------DISABLE REMOTE RESET
  89. ;                      !!+-------------RESERVED
  90. ;                      !+--------------RESERVED
  91. ;                      +---------------ENABLE PKT READY
  92. ;
  93. xmit_mode       equ     00000010B
  94. ;                       !!!!!!!!---------ENABLE CARRIER DETECT
  95. ;                       !!!!!!!+---------DISABLE LOOPBACK
  96. ;
  97. ;
  98. recv_mode       equ     00000010B                 ; set receive mode
  99. ;
  100. ;                       !!!!!!!!---------ACCEPT ALL PACKETS
  101. ;                       !!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND
  102. ;                       !!!!!!+----------BROADCAST PACKETS
  103. ;                       !!!!!+-----------DISABLE REMOTE RESET
  104. ;                       !!!!+------------DISABLE SHORT PACKETS
  105. ;                       !!!+-------------USE 6 BYTE ADDRESS
  106. ;                       !!+--------------NC
  107. ;                       !+---------------NC
  108. ;                       +----------------DISABLE CRC TEST MODE
  109.  
  110. debug    = 0
  111.  
  112.     include defs.asm
  113.  
  114. code segment word public
  115.     assume  cs:code, ds:code
  116.  
  117.     public  int_no
  118. int_no    db      3,0,0,0            ;must be four bytes long for get_number
  119. io_adr    dw    300h,0            ; default I/O address
  120.     extrn    is_186: byte        ;=0 if 808[68], =1 if 80[123]86.
  121.  
  122.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  123. driver_class    db      BLUEBOOK,IEEE8023,0    ;from the packet spec
  124. driver_type    db      1        ;from the packet spec
  125. driver_name    db      'tiara',0    ;name of the driver.
  126. driver_function    db    2
  127. parameter_list    label    byte
  128.     db    1    ;major rev of packet driver
  129.     db    9    ;minor rev of packet driver
  130.     db    14    ;length of parameter list
  131.     db    EADDR_LEN    ;length of MAC-layer address
  132.     dw    GIANT    ;MTU, including MAC headers
  133.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  134.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  135.     dw    0    ;(# of successive xmits) - 1
  136. int_num    dw    0    ;Interrupt # to hook for post-EOI
  137.             ;processing, 0 == none,
  138.  
  139.     public  rcv_modes
  140. rcv_modes    dw    7        ;number of receive modes in our table.
  141.         dw    0               ;There is no mode zero
  142.         dw    rcv_mode_1
  143.         dw    0
  144.         dw    rcv_mode_3
  145.         dw    0        ;haven't set up perfect filtering yet.
  146.         dw    0
  147.         dw    rcv_mode_6
  148.  
  149.  
  150. ;
  151. ;      Receive Packet Header Buffer: Required because addresses and e-type
  152. ;      must be read from tiara card before upcall to find a buffer can be
  153. ;      made.  Need the number of bytes, and the e-type for the call...
  154. ;
  155. ether_buff    db    EADDR_LEN  dup(?)
  156.         db    EADDR_LEN  dup(?)
  157. ether_type    db    4 dup(?)
  158. usr_ptr        dd    ?                 ; temp storage or recv_buff ptr
  159.  
  160. writebport  macro   from_base,value
  161.     mov    dx,cs:[io_adr]        ; write byte value to port
  162.     add    dx,from_base
  163.     mov    al,value
  164.     out    dx,al
  165.     endm
  166.  
  167. ;sends $ terminated string to screen
  168. print$ macro   string
  169.     mov    ah,9
  170.     mov    dx,offset &string&    ; print $ terminated string
  171.     int    21h
  172.     endm
  173.  
  174. mark           = 0F90h                 ; marker debug pos on screen 25
  175.  
  176. marker  macro   st,nd
  177.   IF  debug NE 0                       ; do marker if debug <> 0
  178.       pushf                            ; show 2 char marker on
  179.       push es                          ; 25th line, 1st column
  180.       push ax
  181.       mov  ax,0B800h
  182.       mov  es,ax
  183.       mov  al,'&st&'
  184.       mov  byte ptr es:[mark],al
  185.       mov  al,byte ptr es:[mark+1]     ; get color value
  186.       inc  al
  187.       and  al,0Fh
  188.       or   al,1
  189.       mov  byte ptr es:[mark+1],al     ; advance it to show activity
  190.       mov  al,'&nd'
  191.       mov  byte ptr es:[mark+2],al
  192.       mov  al,byte ptr es:[mark+3]
  193.       inc  al
  194.       and  al,0Fh
  195.       or   al,1
  196.       mov  byte ptr es:[mark+3],al
  197.       pop  ax
  198.       pop  es
  199.       popf
  200.     ENDIF
  201.   endm
  202.  
  203.     include    timeout.asm
  204.  
  205.     public bad_command_intercept
  206. bad_command_intercept:
  207. ;called with ah=command, unknown to the skeleton.
  208. ;exit with nc if okay, cy, dh=error if not.
  209.     mov    dh,BAD_COMMAND
  210.     stc
  211.     ret
  212.  
  213.     public    as_send_pkt
  214. ; The Asynchronous Transmit Packet routine.
  215. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  216. ;   interrupts possibly enabled.
  217. ; Exit with nc if ok, or else cy if error, dh set to error number.
  218. ;   es:di and interrupt enable flag preserved on exit.
  219. as_send_pkt:
  220.     ret
  221.  
  222.     public    drop_pkt
  223. ; Drop a packet from the queue.
  224. ; Enter with es:di -> iocb.
  225. drop_pkt:
  226.     assume    ds:nothing
  227.     ret
  228.  
  229.     public    xmit
  230. ; Process a transmit interrupt with the least possible latency to achieve
  231. ;   back-to-back packet transmissions.
  232. ; May only use ax and dx.
  233. xmit:
  234.     assume    ds:nothing
  235.     ret
  236.  
  237.  
  238.     public    send_pkt
  239. send_pkt:
  240. ;enter with ds:si -> packet, cx = packet length.
  241. ;exit with nc if ok, pr else cy if error, dh set to error number.
  242.  
  243.               assume  ds:nothing
  244.               marker  T,X
  245.  
  246.   if 1
  247.               mov     ax,18
  248.               call    set_timeout
  249.               mov     dx,cs:[io_adr]
  250.               add     dx,BMPR_PKT_LEN
  251. wait_tmt:
  252.               in      al,dx        ; read count register until timeout...
  253.               or      al,al
  254.               jz      send_ok
  255.               call    do_timeout
  256.               jnz     wait_tmt
  257.               mov     dh,CANT_SEND
  258.               stc
  259.               ret
  260. send_ok:
  261.   endif
  262.  
  263.               cmp     cx,RUNT                 ; big enough?
  264.               jae     send_runt_ok
  265.               mov     cx,RUNT                 ; at least runt!
  266. send_runt_ok:
  267.               cmp     cx,GIANT                ; small enough?
  268.               jbe     send_size_ok
  269.               mov     dh,NO_SPACE
  270.               stc                             ; Error
  271.               ret
  272. send_size_ok:
  273. ;
  274. ;      8086/8088 byte mode send
  275. ;
  276.               mov     ax,cx
  277.               inc     cx
  278.               shr     cx,1                    ; words to send
  279.  
  280.               mov     dx,cs:[io_adr]
  281.               add     dx,BMPR_MEM_PORT
  282.               cmp     cs:is_186,0  ; use BYTE or WORD mode?
  283.               jne     send_w_mode
  284.               out     dx,al
  285.               xchg    ah,al
  286.               out     dx,al
  287.  xb:
  288.               lodsw                           ; load word, ind ds:si
  289.               out     dx,al
  290.               xchg    ah,al
  291.               out     dx,al
  292.               loop    xb                      ; set packet length (byte mode)
  293.               jmp     wait_tmt_ok
  294. send_w_mode:
  295.               out     dx,ax
  296.               .286
  297.               rep    outsw
  298.               .8086
  299. wait_tmt_ok:
  300.               mov     dx,cs:[io_adr]    ;tell the board that we've loaded one packet.
  301.               add     dx,BMPR_PKT_LEN
  302.               mov     al,TMST + 1
  303.               out     dx,al
  304.  
  305.               clc
  306.               ret
  307.  
  308.     public  set_address
  309. set_address:
  310. ;enter with ds:si -> Ethernet address,CX = length of address.
  311. ;exit with nc if okay, or cy, dh=error if any errors.
  312.     assume    ds:nothing
  313.     mov    dh,CANT_SET
  314.     stc
  315.     ret
  316.  
  317.  
  318. rcv_mode_1:
  319.     writebport    DLCR_RECV_MODE,0    ; don't receive any packets
  320.     ret
  321.  
  322.  
  323. rcv_mode_3:
  324.     writebport    DLCR_RECV_MODE,2    ; receive mine, broads, and multis.
  325.     ret
  326.  
  327.  
  328. rcv_mode_6:
  329.     writebport    DLCR_RECV_MODE,3    ; receive all packets.
  330.     ret
  331.  
  332.  
  333.     public  set_multicast_list
  334. set_multicast_list:
  335. ;enter with ds:si ->list of multicast addresses, ax = number of addresses,
  336. ;  cx = number of bytes.
  337. ;return nc if we set all of them, or cy,dh=error if we didn't.
  338.     mov     dh,NO_MULTICAST
  339.     stc
  340.     ret
  341.  
  342.     public    terminate
  343. terminate:
  344.     writebport    DLCR_RECV_MODE,0    ; don't receive any packets
  345.     ret
  346.  
  347.     public  reset_interface
  348. reset_interface:                       ;reset the interface.
  349.     assume  ds:code
  350.     ret
  351.  
  352. ;called when we want to determine what to do with a received packet.
  353. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  354.     extrn   recv_find: near
  355.  
  356. ;called after we've copied the packet into the buffer.
  357. ;enter with ds:si ->the packet, cx = length of the packet.
  358.     extrn   recv_copy: near
  359.  
  360.     extrn   count_in_err: near
  361.     extrn   count_out_err: near
  362.  
  363.     public  recv
  364. recv:
  365. ;called from the recv isr.  All registers have been saved, and ds=cs.
  366. ;Upon exit, the interrupt will be acknowledged.
  367.  
  368.     assume  ds:code
  369.     marker  R,X
  370.  
  371. ;clear receive masks to prevent further IRQs
  372.  
  373.     writebport    DLCR_RECV_MASK,0
  374. recv_0:
  375.     mov     ax,cs
  376.     mov     ds,ax
  377.     writebport      DLCR_RECV_STAT,clr_rcv_status
  378.  
  379. ;are there any packets to read?
  380.  
  381.     mov     dx,cs:[io_adr]
  382.     add     dx,DLCR_RECV_MODE
  383.     in      al,dx
  384.     test    al,BUF_EMPTY
  385.     jz      recv_1                    ; 0 if at least one valid pkt..
  386.     jmp     recv_99
  387.  
  388. ;yes, read out a receive packet...
  389.  
  390. recv_1:
  391.               cmp     cs:is_186,0
  392.               jne     recv11
  393.               jmp     read_b_mode
  394. ;
  395. ;        read packet out in word mode
  396. ;
  397. recv11:
  398.     mov    dx,cs:[io_adr]    ; get status and reserved byte
  399.     add    dx,BMPR_MEM_PORT
  400.     in    ax,dx
  401.     in    ax,dx                           ; get packet size
  402.     push    ax
  403.                     ;read first 16 bytes from receive buffer into ether_buff
  404.     mov    ax,cs
  405.     mov    es, ax
  406.     mov    di,offset ether_buff
  407.     mov    cx,16/2                            ; word mode, remember...
  408.     .286
  409.     rep    insw            ; read words into ether_buff
  410.     .8086
  411.  
  412. ;
  413. ;      If the sender is myself, ignore the packet.  This allows async
  414. ;      send/receive without messing up...
  415. ;
  416.     mov    si,offset ether_buff+EADDR_LEN       ; we want the SOURCE
  417.     mov    di,offset my_address
  418.     mov    cx,EADDR_LEN/2
  419.     repe    cmpsw
  420.     jne    not_mine
  421.     jmp    word_flush                      ; mine, so flush it
  422. ;
  423. ;      cx = length, es:di = pointer to ethertype
  424. ;
  425. not_mine:
  426.     pop    cx
  427.     push    cx
  428.     mov    di,offset ether_type
  429.     mov    ax,cs
  430.     mov    es,ax            ; es:di -> ether type, cx = size# bytes
  431.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  432.     mov    ax, es:[di]
  433.     xchg    ah, al
  434.     cmp     ax, 1500
  435.     ja    BlueBookPacket
  436.     inc    di            ;set di to 802.2 header
  437.     inc    di
  438.     mov    dl, IEEE8023
  439. BlueBookPacket:
  440.     call    recv_find        ; got a buffer?
  441.     mov    ax,es
  442.     or    ax,di            ; pointer zero?
  443.     je    word_flush        ; no pointer, discard data
  444. ;
  445. ;      es:di -> users buffer, do copy...
  446. ;      ds:si -> source of copy
  447. ;
  448.     mov    cs:[usr_ptr.segm],es; save ULP pointer
  449.     mov    cs:[usr_ptr.offs],di
  450.     mov    ax,cs
  451.     mov    ds,ax
  452.     mov    si,offset ether_buff    ; copy header to users buffer
  453.     mov    cx,16/2            ; 8 words to copy
  454.     rep    movsw
  455.     mov    dx,cs:[io_adr]        ;copy rest of data to user
  456.     add    dx,BMPR_MEM_PORT    ; buffer in es:di ->
  457.     pop    cx
  458.     push    cx
  459.     sub    cx,16
  460.     shr    cx,1
  461.     .286
  462.     rep    insw            ; read word, store at es:di ->
  463.     .8086
  464.     jnc    word_even
  465.     in    ax,dx
  466.     stosb
  467. word_even:
  468.     pop    cx            ;call recv_copy to say copy done
  469.     lds    si,cs:[usr_ptr]
  470.     call    recv_copy
  471.     jmp    recv_0            ; go get another packet
  472. word_flush:
  473.     mov    dx,cs:[io_adr]
  474.     add    dx,BMPR_MEM_PORT
  475.     pop    cx
  476.     sub    cx,16            ; adjust word count
  477.     shr    cx,1
  478. word_f:
  479.     in    ax,dx
  480.     loop    word_f
  481.     jmp    recv_0
  482. ;
  483. ;             go see of any more packets comming....
  484. ;
  485. ;             READ in BYTE MODE
  486. ;
  487. read_b_mode:
  488.     mov    dx,cs:[io_adr]    ;get status and reserved byte
  489.     add    dx,BMPR_MEM_PORT
  490.     in    al,dx        ; vacuum status and reserved
  491.     in    al,dx
  492.     in    al,dx        ; get packet size
  493.     xchg    al,ah        ; low byte in ah
  494.     in    al,dx        ; get packet size
  495.     xchg    al,ah        ; fix size ah/al order
  496.     push    ax        ; keep number of bytes
  497.     ;      read first 16 bytes from receive buffer into ether_buff
  498.     mov    ax,cs
  499.     mov    es,ax
  500.     mov    di,offset ether_buff
  501.     mov    cx,16            ; byte mode, 16 byte header
  502. rdb:
  503.     in    al,dx            ; read 16 bytes into ether_buff
  504.     stosb
  505.     loop    rdb
  506. ;
  507. ;      If the sender is myself, ignore the packet.
  508. ;
  509.     mov    si,offset ether_buff+EADDR_LEN       ; we want the SOURCE
  510.     mov    di,offset my_address
  511.     mov    cx,EADDR_LEN/2
  512.     repe    cmpsw
  513.     jne    not_mineb
  514.     jmp    byte_flush                  ; mine, so flush it
  515. ;
  516. ;      cx = length, es:di = pointer to ethertype
  517. ;
  518. not_mineb:
  519.     pop    cx
  520.     push    cx
  521.     mov    di,offset ether_type
  522.     mov    ax,cs
  523.     mov    es,ax             ; es:di -> ether type, cx = size#bytes
  524.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  525.     mov    ax, es:[di]
  526.     xchg    ah, al
  527.     cmp     ax, 1500
  528.     ja    BlueBookPacket1
  529.     inc    di            ;set di to 802.2 header
  530.     inc    di
  531.     mov    dl, IEEE8023
  532. BlueBookPacket1:
  533.     call    recv_find                   ; got a buffer?
  534.     mov    ax,es
  535.     or    ax,di                       ; pointer zero?
  536.     je    byte_flush                  ; no pointer, discard data
  537. ;
  538. ;      es:di -> users buffer, do copy...
  539. ;      ds:si -> source of copy
  540. ;
  541.     mov    cs:[usr_ptr.segm],es    ; save ULP pointer
  542.     mov    cs:[usr_ptr.offs],di
  543.     mov    ax,cs
  544.     mov    ds,ax
  545.     mov    si,offset ether_buff        ; copy header to users buffer
  546.     mov    cx,16/2            ; 16 bytes in header to copy
  547.     rep    movsw
  548.     mov    dx,cs:io_adr     ; copy rest of data to users
  549.     add    dx,BMPR_MEM_PORT            ; buffer in es:di ->
  550.     pop    cx
  551.     push    cx
  552.     sub    cx,16
  553. cpyb:
  554.     in    al,dx            ; read byte
  555.     stosb                ; store at es:di ->
  556.     loop    cpyb
  557.     pop    cx            ; call recv_copy to say copy done
  558.     lds    si,cs:[usr_ptr]
  559.     call    recv_copy
  560.     jmp    recv_0            ; go get another packet...
  561. byte_flush:
  562.     mov    dx,cs:io_adr
  563.     add    dx,BMPR_MEM_PORT
  564.     pop    cx
  565.     sub    cx,16            ; adjust byte count header
  566. byte_f:
  567.     in    al,dx
  568.     loop    byte_f
  569.     jmp    recv_0            ; go to see if any more packets comming...
  570. recv_99:
  571. ;      receive ok, restore recive mask and exit
  572. ;
  573.     writebport    DLCR_RECV_MASK,en_rcv_irqs
  574.     ret
  575.  
  576.  
  577.     public    timer_isr
  578. timer_isr:
  579. ;if the first instruction is an iret, then the timer is not hooked
  580.     iret
  581.  
  582. ;any code after this will not be kept.  Buffers used by the program, if any,
  583. ;are allocated from the memory between end_resident and end_free_mem.
  584.     public end_resident,end_free_mem
  585. end_resident    label    byte
  586. end_free_mem    label    byte
  587.  
  588. io_adr_msg    db    "I/O Base Address: ",'$'
  589. int_no_msg    db    "Interrupt Level: ",'$'
  590. no_card_msg    db    "INIT: No card at I/O address specified",CR,LF,'$'
  591.  
  592.     public  usage_msg
  593. usage_msg   db  "usage: tiara [options] <packet_int_no> <hardware_irq> <io_adr>",CR,LF,'$'
  594.  
  595.     public  copyright_msg
  596. copyright_msg    label    byte
  597.  db CR,LF
  598.  db "tiara:  Driver for tiara Card, Version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version, CR,LF
  599.  db "         - for PC, PC-AT, and Micro Channel (IBM tm)",CR,LF
  600.  db "portions Copyright 1993, Crynwr Software",CR,LF
  601.  db "portions - Copyright 1990, 1991 Queens University",CR,LF
  602.  db "    Written by Brian Fisher",CR,LF
  603.  db CR,LF,'$'
  604.  
  605.     extrn   set_recv_isr: near
  606. ;enter with si-> argument string,di->wword to store.
  607. ;if there is no number, don't change  the number.
  608.  
  609. ;enter with si -> argument string, di -> word to store.
  610. ;if there is no number, don't change the number.
  611.     extrn   get_number: near
  612.  
  613. ;enter with dx -> name of word, di -> dword to print.
  614.     extrn    print_number: near
  615.  
  616. ;-> the assigned Ethernet address of the card.
  617.     extrn    rom_address: byte
  618.  
  619. ;-> the current Ethernet address of the card.
  620.     extrn    my_address: byte
  621.  
  622.     public  parse_args
  623. parse_args:
  624. ;      parse  hardware interrupt number and I/O base address from the
  625. ;      command line.
  626. ;
  627.     mov    di,offset int_no    ; interrupt level?
  628.     call    get_number
  629.     jc    _parse_exit
  630.     mov    di,offset io_adr    ; first comes the I/O base address
  631.     call    get_number
  632. _parse_exit:
  633.     clc
  634.     ret
  635.  
  636.     public etopen
  637. etopen:
  638.     writebport    DLCR_CONFIG,card_disable    ; disable etherstar
  639.     writebport    DLCR_XMIT_STAT,clear_status    ; clr xmit status
  640.     writebport    DLCR_XMIT_MASK,no_tx_irqs    ; disable xmit IRQ's
  641.     writebport    DLCR_RECV_STAT,clr_rcv_status    ; clear rcv status
  642.     writebport    DLCR_RECV_MASK,en_rcv_irqs    ; enable rcv IRQ's
  643.     writebport    DLCR_XMIT_MODE,xmit_mode    ; set xmit mode
  644.     writebport    DLCR_RECV_MODE,recv_mode    ; set receive mode
  645.     writebport    DLCR_RBNK,020h    ;turn on IDR8-IDR15.
  646.  
  647. ;
  648. ;      Set Node ID:
  649. ;
  650.     movseg    es,cs
  651.     mov    di,offset rom_address
  652.     mov    cx,EADDR_LEN        ; calc base of I/O regs for node id
  653.     mov    bx,cs:io_adr
  654.     mov    dx,bx
  655.     add    bx,DLCR_NODE_ID
  656.     add    dx,PROM_ID        ; and base of PROM for copy
  657.     mov    ah,0ffh            ;start with all bits set.
  658. etopen0:
  659.     in    al,dx            ; read byte of factory address
  660.     stosb
  661.     and    ah,al            ;remove any bits that are zeroes.
  662.     xchg    bx,dx
  663.     out    dx,al            ; write to register
  664.     xchg    bx,dx
  665.     inc    dx
  666.     inc    bx
  667.     loop    etopen0            ; until copy is done...
  668. ;
  669. ;       Verify card address is not all 1's
  670. ;
  671.         cmp     ah,-1
  672.         jne     etopen0a
  673.         jmp     etopen_nocard           ;   all 1's, no card found
  674. etopen0a:
  675. ;
  676. ;      Verify card exists by comparing address to PROM
  677. ;
  678.     mov    cx,EADDR_LEN
  679. etopen1:
  680.     dec    dx
  681.     dec    bx
  682.     in    al,dx
  683.     xchg    bx,dx
  684.     mov    ah,al
  685.     in    al,dx
  686.     xchg    bx,dx
  687.     cmp    al,ah
  688.     jne    etopen_nocard        ; no card found
  689.     loop    etopen1
  690.  
  691.     writebport    DLCR_RBNK,028h    ;turn on BMR8-BMR15
  692.     writebport    DLCR_CONFIG,card_enable
  693.     call    set_recv_isr                ; install receive IRQ routine
  694.  
  695.     mov    al, int_no        ; Get board's interrupt vector
  696.     add    al, 8
  697.     cmp    al, 8+8            ; Is it a slave 8259 interrupt?
  698.     jb    set_int_num        ; No.
  699.     add    al, 70h - 8 - 8        ; Map it to the real interrupt.
  700. set_int_num:
  701.     xor    ah, ah            ; Clear high byte
  702.     mov    int_num, ax        ; Set parameter_list int num.
  703.  
  704.     clc
  705.     ret
  706. etopen_nocard:
  707.     mov    dx,offset no_card_msg    ; couldn't verify card exists...
  708.     stc
  709.     ret
  710.  
  711.     public    print_parameters
  712. print_parameters:
  713. ;echo our command-line parameters
  714.     mov    di,offset int_no    ; interrupt level.
  715.     mov    dx,offset int_no_msg
  716.     call    print_number
  717.     mov    di,offset io_adr    ; now comes the I/O base address
  718.     mov    dx,offset io_adr_msg
  719.     call    print_number
  720.     ret
  721.  
  722. code    ends
  723.  
  724.     end
  725.