home *** CD-ROM | disk | FTP | other *** search
/ Netware Super Library / Netware Super Library.iso / drivers / nics / pktdrv7 / tiara.asm < prev    next >
Encoding:
Assembly Source File  |  1990-07-27  |  22.8 KB  |  760 lines

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