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

  1. version    equ    0
  2. ;History:201,1
  3. ;Mon Feb 22 15:40:28 1993 es
  4.  
  5. ;  The following people have contributed to this code: David Horne, Eric
  6. ;  Henderson, and Bob Clements.
  7.  
  8. ;  Copyright, 1988-1992, Russell Nelson, Crynwr Software
  9.  
  10. ;   This program is free software; you can redistribute it and/or modify
  11. ;   it under the terms of the GNU General Public License as published by
  12. ;   the Free Software Foundation, version 1.
  13. ;
  14. ;   This program is distributed in the hope that it will be useful,
  15. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;   GNU General Public License for more details.
  18. ;
  19. ;   You should have received a copy of the GNU General Public License
  20. ;   along with this program; if not, write to the Free Software
  21. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23.     include    defs.asm
  24.  
  25. code    segment    word public
  26.     assume    cs:code, ds:code
  27.  
  28. ;*****************************************************************************
  29. ;
  30. ;    Mylex LNE390 controller board offsets
  31. ;    IO port definition (BASE in io_addr)
  32. ;*****************************************************************************
  33. NE_RESET    equ    0c84h        ;board control bits.
  34. NE_CONFIG    equ    0c90h        ;configuration register
  35. EBASE        equ    16h        ;Ethernet address starts here.
  36. EN_OFF        equ    0h        ;8390 starts here
  37.  
  38.     include    8390.inc
  39.  
  40. ; Shared memory management parameters
  41.  
  42. SM_TSTART_PG    equ    000h    ; First page of TX buffer
  43. SM_RSTART_PG    equ    006h    ; Starting page of RX ring
  44. SM_RSTOP_PG    equ    080h    ; Last page +1 of RX ring
  45.  
  46. pause_    macro
  47. ;    jmp    $+2
  48. ;
  49. ; The reason for the pause_ macro is to establish a minimum time between
  50. ; accesses to the card hardware. The assumption is that the fetch and execution
  51. ; of the jmp $+2 instruction will provide this time. In a fast cache machine
  52. ; this may be a false assumption. In a fast cache machine, there may be 
  53. ; NO REAL TIME DIFFERENCE between the two I/O instruction streams below:
  54. ;
  55. ;    in    al,dx        in    al,dx
  56. ;    jmp    $+2
  57. ;    in    al,dx        in    al,dx
  58. ;
  59. ; To establish a minimum delay, an I/O instruction must be used. A good rule of
  60. ; thumb is that ISA I/O instructions take ~1.0 microseconds and MCA I/O
  61. ; instructions take ~0.5 microseconds. Reading the NMI Status Register (0x61)
  62. ; is a good way to pause on all machines.
  63. ;
  64. ; The National 8390 Chip (NIC) requires 4 bus clocks between successive
  65. ; chip selects (National DP8390 Data Sheet Addendum, June 1990 -- it took them
  66. ; long enough to figure this out and tell everyone) or the NIC behaves badly.
  67. ; Therefor one I/O instruction should be inserted between each successive
  68. ; NIC I/O instruction that could occur 'back - to - back' on a fast cache
  69. ; machine.
  70. ;   - gft - 910529
  71. ;
  72.     push    ax
  73.     in    al, 61h            ;EISA bus requires more delay.
  74.     in    al, 61h
  75.     pop    ax
  76. ;
  77. endm
  78.  
  79. reset_8390    macro
  80.     loadport
  81.     setport    NE_RESET
  82.     mov    al,0            ;reset the board.
  83.     out    dx,al
  84.     longpause
  85.     mov    al,1            ;unreset the board.
  86.     out    dx,al
  87.  
  88.     endm
  89.  
  90. terminate_board    macro
  91.     loadport
  92.     setport    NE_RESET
  93.     mov    al,0            ;reset the board.
  94.     out    dx,al
  95.     setport    NE_CONFIG
  96.     in    ax,dx
  97.     and    ax,not 3700h        ;turn of xcvr, memory, and ints.
  98.     out    dx,ax
  99.     endm
  100.  
  101.     public    int_no, io_addr, mem_base
  102. int_no        db    ?,0,0,0        ;must be four bytes long for get_number.
  103. io_addr        dw    ?,0        ; I/O address for card
  104. mem_base    dw    ?,0        ; Shared memory addr
  105.  
  106.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  107. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  108. driver_type    dw    95        ;from the packet spec
  109. driver_name    db    'LNE390',0    ;name of the driver.
  110. driver_function    db    2
  111. parameter_list    label    byte
  112.     db    1    ;major rev of packet driver
  113.     db    9    ;minor rev of packet driver
  114.     db    14    ;length of parameter list
  115.     db    EADDR_LEN    ;length of MAC-layer address
  116.     dw    GIANT    ;MTU, including MAC headers
  117.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  118.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  119.     dw    0    ;(# of successive xmits) - 1
  120. int_num    dw    0    ;Interrupt # to hook for post-EOI
  121.             ;processing, 0 == none,
  122.  
  123.     include    movemem.asm
  124.  
  125.     even
  126. ;
  127. ;    Block input routine
  128. ;    CX = byte count, es:di = buffer location, ax = buffer address
  129.  
  130.     public    block_input
  131. block_input:
  132.     .386
  133.     push    ds
  134.     push    eax
  135.     assume    ds:nothing
  136.     mov    ds,mem_base        ; ds:si points at first byte to move
  137.     mov    si,ax
  138.  
  139.     add    ax,cx            ; Find the end of this frame.
  140.     cmp    ah,byte ptr cs:sm_rstop_ptr ; Over the top of the ring?
  141.     jb    rcopy_one_piece        ; Go move it
  142.  
  143. rcopy_wrap:
  144. ; Copy in two pieces due to buffer wraparound.
  145.     mov    ah,byte ptr cs:sm_rstop_ptr ; Compute length of first part
  146.     xor    al,al
  147.     sub    ax,si            ;  as all of the pages up to wrap point
  148.     sub    cx,ax            ; Move the rest in second part
  149.     push    cx            ; Save count of second part
  150.     mov    cx,ax            ; Count for first move
  151.     shr    cx,2            ; convert byte count to dword count
  152.     rep    movsd
  153.     mov    si,SM_RSTART_PG*256    ; Offset to start of first receive page
  154.     pop    cx            ; Bytes left to move
  155. rcopy_one_piece:
  156. ;transfer all complete dwords.
  157.     push    cx
  158.     shr    cx,2            ; convert byte count to dword count
  159.     rep    movsd
  160.     pop    cx
  161.  
  162. ;now take take of any trailing words and/or bytes.
  163.     lodsd
  164.  
  165.     test    cx,2
  166.     je    rcopy_one_word
  167.     stosw
  168.     shr    eax,16
  169. rcopy_one_word:
  170.  
  171.     test    cx,1
  172.     je    rcopy_one_byte
  173.     stosb
  174. rcopy_one_byte:
  175.  
  176.     pop    eax
  177.     pop    ds
  178.     .8086
  179.     ret
  180.  
  181. ;
  182. ;    Block output routine
  183. ;    CX = byte count, ds:si = buffer location, ax = buffer address
  184.  
  185. block_output:
  186.     assume    ds:nothing
  187.     .386
  188.     mov    es,mem_base        ; Set up ES:DI at the shared RAM
  189.     mov    di,ax            ; ..
  190.     add    cx,3            ;round up to next highest dword.
  191.     shr    cx,2
  192.     rep    movsd
  193.     clc
  194.     .8086
  195.     ret
  196.  
  197.  
  198.     include    8390.asm
  199.  
  200.     public    usage_msg
  201. usage_msg    db    "usage: mylex [options] <packet_int_no> <int_level> <io_addr> <mem_base>",CR,LF,'$'
  202. no_board_msg    db    "No Mylex LNE390 detected.",CR,LF,'$'
  203. bad_memory_msg    db    "This adapter must be addressed at 0xd000 or 0xe000",CR,LF,'$'
  204. no_network_msg    db    "Check network connector - no network connection detected.",CR,LF,'$'
  205. tp_xcvr_msg    db    "Using Twisted Pair (10BaseT) transceiver",CR,LF,'$'
  206. bnc_xcvr_msg    db    "Using BNC (10Base2) transceiver",CR,LF,'$'
  207. aui_xcvr_msg    db    "Using AUI transceiver",CR,LF,'$'
  208.  
  209.     public    copyright_msg
  210. copyright_msg    db    "Packet driver for Mylex, version "
  211.         db    '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF,'$'
  212.  
  213. int_no_name    db    "Interrupt number ",'$'
  214. io_addr_name    db    "I/O port ",'$'
  215. mem_base_name    db    "Memory address ",'$'
  216.  
  217.     extrn    is_386: byte        ;=0 if 80[12]8[68], =1 if 80[34]86.
  218.  
  219.     extrn    set_recv_isr: near
  220.  
  221. ;enter with si -> argument string, di -> word to store.
  222. ;if there is no number, don't change the number.
  223.     extrn    get_number: near
  224.  
  225. ;enter with dx -> name of word, di -> dword to print.
  226.     extrn    print_number: near
  227.  
  228. irq_table    db    15, 12, 11, 10, 9, 7, 5, 3
  229.  
  230.     public    parse_args
  231. parse_args:
  232. ;exit with nc if all went well, cy otherwise.
  233.     .386
  234.     mov    cx,0fh
  235. eisa_search:
  236.     mov    dx,cx            ;move it into the first nibble.
  237.     shl    dx,12
  238.     or    dx,0c80h
  239.   if 0
  240.     in    eax,dx
  241.     cmp    eax,11009835h
  242.   else
  243.     in    ax,dx            ;look for the manufacturer's ID
  244.     cmp    ax,9835h
  245.     jne    eisa_search_1
  246.     add    dx,2
  247.     in    ax,dx
  248.     cmp    ax,1100h
  249.   endif
  250.     je    eisa_found
  251. eisa_search_1:
  252.     loop    eisa_search
  253.  
  254.     mov    dx,offset no_board_msg
  255.     stc
  256.     ret
  257.  
  258. eisa_found:
  259.     .8086
  260.     and    dx,0f000h
  261.     mov    io_addr,dx
  262.  
  263.     loadport
  264.     setport    NE_RESET
  265.     mov    al,1
  266.     out    dx,al
  267.  
  268.     setport    NE_CONFIG        ;point to configuration register.
  269.     in    ax,dx
  270.     mov    bx,ax
  271.     and    ax,7
  272.     mov    mem_base,0e000h
  273.     cmp    ax,2
  274.     je    eisa_memory_ok
  275.     mov    mem_base,0d000h
  276.     cmp    ax,6
  277.     je    eisa_memory_ok
  278.     mov    dx,offset bad_memory_msg
  279.     stc
  280.     ret
  281. eisa_memory_ok:
  282.  
  283.     mov    cl,3
  284.     shr    bx,cl
  285.     and    bx,7
  286.     mov    bl,irq_table[bx]
  287.     mov    int_no,bl
  288.  
  289.     clc
  290.     ret
  291.  
  292.     extrn    etopen_diagn: byte
  293.  
  294. init_card:
  295. ;get the board data. This is (16) bytes starting at remote
  296. ;dma address 0. Put it in a buffer called board_data.
  297.     assume    ds:code
  298.  
  299.     or    endcfg,ENDCFG_WTS
  300.  
  301.     movseg    es,ds
  302.     mov    di,offset board_data
  303.  
  304.     .386
  305.     loadport            ; Get our Ethernet address base.
  306.     setport    EBASE
  307.     mov    cx,EADDR_LEN
  308. read_address_1:
  309.     insb                ; get a byte of the eprom address
  310.     inc    dx            ; next register
  311.     loop    read_address_1        ; go back for rest
  312.     .8086
  313.  
  314.     push    ds              ; Copy from card's address to current address
  315.     pop     es
  316.  
  317.     mov si, offset board_data    ; address is at start
  318.     mov di, offset rom_address
  319.     mov cx, EADDR_LEN       ; Copy one address length
  320.     rep     movsb           ; ..
  321.  
  322.     clc
  323.     ret
  324.  
  325. test_packet    label    byte
  326.     db    EADDR_LEN dup(?)
  327.     db    EADDR_LEN dup(?)
  328.     db    00h,2eh            ;A 46 in network order
  329.     db    0,0            ;DSAP=0 & SSAP=0 fields
  330.     db    0f3h,0            ;Control (Test Req + P bit set)
  331.  
  332. iface_bit    db    4        ;start with AUI.
  333.  
  334.     public    print_parameters
  335. print_parameters:
  336. ;but on *this* adapter, try sending a test packet.
  337.  
  338. ;first try with the AUI port.
  339.     mov    si,offset rom_address    ;set the destination address.
  340.     movseg    es,cs
  341.     mov    di,offset test_packet
  342.     movsw
  343.     movsw
  344.     movsw
  345.     mov    si,offset rom_address    ;set the source address.
  346.     movsw
  347.     movsw
  348.     movsw
  349.  
  350. send_test:
  351.     loadport            ;store the current thin_bit to the board.
  352.     setport    NE_CONFIG
  353.     in    ax,dx
  354.     and    ax,not 700h
  355.     or    ax,3000h        ;enable memory and interrupts.
  356.     or    ah,iface_bit
  357.     out    dx,ax
  358.  
  359.     mov    ax,18            ;wait a little while for the powerdown/up to take effect.
  360.     call    set_timeout
  361. send_test_power:
  362.     call    do_timeout
  363.     jne    send_test_power
  364.  
  365.     mov    cx,6            ;try six times
  366. send_test_again:
  367.     push    cx
  368.     mov    cx,60
  369.     mov    si,offset test_packet
  370.     call    send_pkt
  371.     pop    cx
  372.  
  373.     mov    ax,3
  374.     call    set_timeout
  375.  
  376.     loadport
  377.     setport    EN0_ISR
  378. send_test_wait:
  379.     in    al,dx
  380.     test    al,ENISR_TX or ENISR_TX_ERR    ;did it finish?
  381.     jne    send_test_done
  382.  
  383.     call    do_timeout
  384.     jnz    send_test_wait
  385.     jmp    short send_test_loop
  386.  
  387. send_test_done:
  388.     mov    al,0ffh            ;clear all interrupts.
  389.     out    dx,al
  390.  
  391.     loadport
  392.     setport    EN0_TSR
  393.     in    al,dx            ;get the transmit status
  394.     test    al,ENTSR_COLL16 or ENTSR_CRS or ENTSR_FU    ;any problems?
  395.     je    send_test_exit        ;no, it worked.
  396.  
  397. send_test_loop:
  398.     loop    send_test_again
  399.  
  400. ;it failed all six times.  Try again on a different interface.
  401.     shr    iface_bit,1
  402.     cmp    iface_bit,0        ;did we try them all?
  403.     je    send_test_fail        ;yes, we can't send any packets!
  404.  
  405.     jmp    send_test
  406.  
  407. send_test_fail:
  408.     mov    dx,offset no_network_msg
  409.     mov    ah,9
  410.     int    21h
  411.  
  412.     mov    iface_bit,1
  413.     jmp    send_test_exit
  414.  
  415. send_test_exit:
  416. ;echo our command-line parameters
  417.     mov    di,offset int_no
  418.     mov    dx,offset int_no_name
  419.     call    print_number
  420.     mov    di,offset io_addr
  421.     mov    dx,offset io_addr_name
  422.     call    print_number
  423.     mov    di,offset mem_base
  424.     mov    dx,offset mem_base_name
  425.     call    print_number
  426.     mov    dx,offset tp_xcvr_msg
  427.     cmp    iface_bit,1
  428.     je    print_parameters_1
  429.     mov    dx,offset bnc_xcvr_msg
  430.     cmp    iface_bit,2
  431.     je    print_parameters_1
  432.     mov    dx,offset aui_xcvr_msg
  433. print_parameters_1:
  434.     mov    ah,9
  435.     int    21h
  436.     ret
  437.  
  438. code    ends
  439.  
  440.     end
  441.