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

  1. version    equ    0
  2. ;History:78,1
  3.  
  4. ;  The following people have contributed to this code: David Horne, Eric
  5. ;  Henderson, and Bob Clements.
  6.  
  7. ;  Copyright, 1988-1992, Russell Nelson, Crynwr Software
  8.  
  9. ;   This program is free software; you can redistribute it and/or modify
  10. ;   it under the terms of the GNU General Public License as published by
  11. ;   the Free Software Foundation, version 1.
  12. ;
  13. ;   This program is distributed in the hope that it will be useful,
  14. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;   GNU General Public License for more details.
  17. ;
  18. ;   You should have received a copy of the GNU General Public License
  19. ;   along with this program; if not, write to the Free Software
  20. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.     include    defs.asm
  23.  
  24. code    segment    word public
  25.     assume    cs:code, ds:code
  26.  
  27. ;*****************************************************************************
  28. ;
  29. ;    es3210 controller board offsets
  30. ;    IO port definition (BASE in io_addr)
  31. ;*****************************************************************************
  32. NE_RESET    equ    04h        ;board control bits.
  33. EBASE        equ    10h
  34. EN_OFF        equ    20h
  35. NE_DATAPORT    equ    60h        ; es3210 Port Window.
  36.  
  37.     include    8390.inc
  38.  
  39. ; Shared memory management parameters
  40.  
  41. SM_TSTART_PG    equ    000h    ; First page of TX buffer
  42. SM_RSTART_PG    equ    006h    ; Starting page of RX ring
  43. SM_RSTOP_PG    equ    040h    ; Last page +1 of RX ring
  44.  
  45. pause_    macro
  46. ;    jmp    $+2
  47. ;
  48. ; The reason for the pause_ macro is to establish a minimum time between
  49. ; accesses to the card hardware. The assumption is that the fetch and execution
  50. ; of the jmp $+2 instruction will provide this time. In a fast cache machine
  51. ; this may be a false assumption. In a fast cache machine, there may be 
  52. ; NO REAL TIME DIFFERENCE between the two I/O instruction streams below:
  53. ;
  54. ;    in    al,dx        in    al,dx
  55. ;    jmp    $+2
  56. ;    in    al,dx        in    al,dx
  57. ;
  58. ; To establish a minimum delay, an I/O instruction must be used. A good rule of
  59. ; thumb is that ISA I/O instructions take ~1.0 microseconds and MCA I/O
  60. ; instructions take ~0.5 microseconds. Reading the NMI Status Register (0x61)
  61. ; is a good way to pause on all machines.
  62. ;
  63. ; The National 8390 Chip (NIC) requires 4 bus clocks between successive
  64. ; chip selects (National DP8390 Data Sheet Addendum, June 1990 -- it took them
  65. ; long enough to figure this out and tell everyone) or the NIC behaves badly.
  66. ; Therefor one I/O instruction should be inserted between each successive
  67. ; NIC I/O instruction that could occur 'back - to - back' on a fast cache
  68. ; machine.
  69. ;   - gft - 910529
  70. ;
  71.     push    ax
  72.     in    al, 61h            ;EISA bus requires more delay.
  73.     in    al, 61h
  74.     pop    ax
  75. ;
  76. endm
  77.  
  78. reset_8390    macro
  79.     loadport
  80.     setport    NE_RESET
  81.     mov    al,4            ;reset the board.
  82.     out    dx,al
  83.     longpause
  84.     mov    al,1            ;unreset the board.
  85.     out    dx,al
  86.  
  87.     endm
  88.  
  89. terminate_board    macro
  90.     endm
  91.  
  92.     public    int_no, io_addr, mem_base
  93. int_no        db    2,0,0,0        ;must be four bytes long for get_number.
  94. io_addr        dw    0300h,0        ; I/O address for card
  95. mem_base    dw    00000h,0    ; Shared memory addr
  96.  
  97.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  98. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  99. driver_type    dw    54        ;from the packet spec
  100. driver_name    db    'es3210',0    ;name of the driver.
  101. driver_function    db    2
  102. parameter_list    label    byte
  103.     db    1    ;major rev of packet driver
  104.     db    9    ;minor rev of packet driver
  105.     db    14    ;length of parameter list
  106.     db    EADDR_LEN    ;length of MAC-layer address
  107.     dw    GIANT    ;MTU, including MAC headers
  108.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  109.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  110.     dw    0    ;(# of successive xmits) - 1
  111. int_num    dw    0    ;Interrupt # to hook for post-EOI
  112.             ;processing, 0 == none,
  113.  
  114.     include    movemem.asm
  115.  
  116. ;
  117. ;    Block input routine
  118. ;    CX = byte count, es:di = buffer location, ax = buffer address
  119.  
  120.     public    block_input
  121. block_input:
  122.     .386
  123.     push    ds
  124.     push    eax
  125.     assume    ds:nothing
  126.     mov    ds,mem_base        ; ds:si points at first byte to move
  127.     mov    si,ax
  128.  
  129.     add    ax,cx            ; Find the end of this frame.
  130.     cmp    ah,byte ptr cs:sm_rstop_ptr ; Over the top of the ring?
  131.     jb    rcopy_one_piece        ; Go move it
  132.  
  133. rcopy_wrap:
  134. ; Copy in two pieces due to buffer wraparound.
  135.     mov    ah,byte ptr cs:sm_rstop_ptr ; Compute length of first part
  136.     xor    al,al
  137.     sub    ax,si            ;  as all of the pages up to wrap point
  138.     sub    cx,ax            ; Move the rest in second part
  139.     push    cx            ; Save count of second part
  140.     mov    cx,ax            ; Count for first move
  141.     shr    cx,2            ; convert byte count to dword count
  142.     rep    movsd
  143.     mov    si,SM_RSTART_PG*256    ; Offset to start of first receive page
  144.     pop    cx            ; Bytes left to move
  145. rcopy_one_piece:
  146. ;transfer all complete dwords.
  147.     push    cx
  148.     shr    cx,2            ; convert byte count to dword count
  149.     rep    movsd
  150.     pop    cx
  151.  
  152. ;now take take of any trailing words and/or bytes.
  153.     lodsd
  154.  
  155.     test    cx,2
  156.     je    rcopy_one_word
  157.     stosw
  158.     shr    eax,16
  159. rcopy_one_word:
  160.  
  161.     test    cx,1
  162.     je    rcopy_one_byte
  163.     stosb
  164. rcopy_one_byte:
  165.  
  166.     pop    eax
  167.     pop    ds
  168.     .8086
  169.     ret
  170.  
  171. ;
  172. ;    Block output routine
  173. ;    CX = byte count, ds:si = buffer location, ax = buffer address
  174.  
  175. block_output:
  176.     assume    ds:nothing
  177.     .386
  178.     mov    es,mem_base        ; Set up ES:DI at the shared RAM
  179.     mov    di,ax            ; ..
  180.     add    cx,3            ;round up to next highest dword.
  181.     shr    cx,2
  182.     rep    movsd
  183.     clc
  184.     .8086
  185.     ret
  186.  
  187.  
  188.     include    8390.asm
  189.  
  190.     public    usage_msg
  191. usage_msg    db    "usage: es3210 [options] <packet_int_no> <hardware_irq> <io_addr> <mem_base>",CR,LF,'$'
  192. no_board_msg    db    "No es3210 detected.",CR,LF,'$'
  193. io_addr_funny_msg    label    byte
  194.         db    "No es3210 detected, continuing anyway.",CR,LF,'$'
  195.  
  196.     public    copyright_msg
  197. copyright_msg    db    "Packet driver for es3210, version "
  198.         db    '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF,'$'
  199.  
  200. int_no_name    db    "Interrupt number ",'$'
  201. io_addr_name    db    "I/O port ",'$'
  202. mem_base_name    db    "Memory address ",'$'
  203.  
  204.     extrn    is_386: byte        ;=0 if 80[12]8[68], =1 if 80[34]86.
  205.  
  206.     extrn    set_recv_isr: near
  207.  
  208. ;enter with si -> argument string, di -> word to store.
  209. ;if there is no number, don't change the number.
  210.     extrn    get_number: near
  211.  
  212. ;enter with dx -> name of word, di -> dword to print.
  213.     extrn    print_number: near
  214.  
  215.     public    parse_args
  216. parse_args:
  217. ;exit with nc if all went well, cy otherwise.
  218.     mov    di,offset int_no
  219.     call    get_number
  220.     mov    di,offset io_addr
  221.     call    get_number
  222.     mov    di,offset mem_base
  223.     call    get_number
  224.  
  225.     cmp    io_addr,-1        ;Did they ask for auto-detect?
  226.     je    find_board
  227.  
  228.     call    detect_board        ;no, just verify its existance.
  229.     je    find_board_found
  230.  
  231.     mov    dx,offset io_addr_funny_msg
  232.     mov    ah,9
  233.     int    21h
  234.  
  235.     jmp    find_board_found
  236.  
  237. find_board:
  238.     mov    io_addr,0c80h        ;Search for the Ethernet address.
  239.     mov    io_addr+2,0
  240. find_board_0:
  241.     call    detect_board
  242.     je    find_board_found
  243. find_board_again:
  244.     add    io_addr,1000h        ;not at this port, try another.
  245.     jnc    find_board_0
  246.  
  247.     mov    dx,offset no_board_msg    ;Tell them that we can't find it.
  248.     mov    ah,9
  249.     int    21h
  250.  
  251.     stc
  252.     ret
  253. find_board_found:
  254.     clc
  255.     ret
  256.  
  257.     extrn    etopen_diagn: byte
  258.  
  259. init_card:
  260. ;get the board data. This is (16) bytes starting at remote
  261. ;dma address 0. Put it in a buffer called board_data.
  262.     assume    ds:code
  263.  
  264.     or    endcfg,ENDCFG_WTS
  265.  
  266.     movseg    es,ds
  267.     mov    di,offset board_data
  268.  
  269.     .386
  270.     loadport            ; Get our Ethernet address base.
  271.     setport    EBASE
  272.     mov    cx,EADDR_LEN
  273. read_address_1:
  274.     insb                ; get a byte of the eprom address
  275.     inc    dx            ; next register
  276.     loop    read_address_1        ; go back for rest
  277.     .8086
  278.  
  279.     push    ds              ; Copy from card's address to current address
  280.     pop     es
  281.  
  282.     mov si, offset board_data    ; address is at start
  283.     mov di, offset rom_address
  284.     mov cx, EADDR_LEN       ; Copy one address length
  285.     rep     movsb           ; ..
  286.  
  287.     clc
  288.     ret
  289.  
  290.     public    print_parameters
  291. print_parameters:
  292. ;echo our command-line parameters
  293.     mov    di,offset int_no
  294.     mov    dx,offset int_no_name
  295.     call    print_number
  296.     mov    di,offset io_addr
  297.     mov    dx,offset io_addr_name
  298.     call    print_number
  299.     mov    di,offset mem_base
  300.     mov    dx,offset mem_base_name
  301.     call    print_number
  302.     ret
  303.  
  304. detect_board:
  305. ;test to see if a board is located at io_addr.
  306. ;return nz if not.
  307.     loadport
  308.     setport    EBASE
  309.     in    al,dx            ;Check for Interlan's prefix word.
  310.     cmp    al,2
  311.     jne    detect_board_exit
  312.  
  313.     setport    EBASE+1
  314.     in    al,dx
  315.     cmp    al,7
  316.     jne    detect_board_exit
  317.  
  318.     setport    EBASE+EADDR_LEN        ;first byte following should be 0
  319.     in    al,dx
  320.     cmp    al,0
  321.     jne    detect_board_exit
  322.  
  323.     setport    EBASE+EADDR_LEN+1    ;second byte should be 55h
  324.     in    al,dx
  325.     cmp    al,55h
  326. detect_board_exit:
  327.     ret
  328.  
  329. code    ends
  330.  
  331.     end
  332.