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

  1. version    equ    4
  2. ;History:76,1 0
  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. ;    NE2000 controller board offsets
  30. ;    IO port definition (BASE in io_addr)
  31. ;*****************************************************************************
  32. NE_DATAPORT    EQU    10h        ; NE2000 Port Window.
  33. NE_RESET    EQU    1fh        ; Issue a read for reset
  34. EN_OFF        equ    0h
  35.  
  36.     include    8390.inc
  37.  
  38. ; Shared memory management parameters
  39.  
  40. SM_TSTART_PG    equ    040h    ; First page of TX buffer
  41. SM_RSTART_PG    equ    046h    ; Starting page of RX ring
  42. SM_RSTOP_PG    equ    080h    ; Last page +1 of RX ring
  43.  
  44. pause_    macro
  45. ;    jmp    $+2
  46. ;
  47. ; The reason for the pause_ macro is to establish a minimum time between
  48. ; accesses to the card hardware. The assumption is that the fetch and execution
  49. ; of the jmp $+2 instruction will provide this time. In a fast cache machine
  50. ; this may be a false assumption. In a fast cache machine, there may be 
  51. ; NO REAL TIME DIFFERENCE between the two I/O instruction streams below:
  52. ;
  53. ;    in    al,dx        in    al,dx
  54. ;    jmp    $+2
  55. ;    in    al,dx        in    al,dx
  56. ;
  57. ; To establish a minimum delay, an I/O instruction must be used. A good rule of
  58. ; thumb is that ISA I/O instructions take ~1.0 microseconds and MCA I/O
  59. ; instructions take ~0.5 microseconds. Reading the NMI Status Register (0x61)
  60. ; is a good way to pause on all machines.
  61. ;
  62. ; The National 8390 Chip (NIC) requires 4 bus clocks between successive
  63. ; chip selects (National DP8390 Data Sheet Addendum, June 1990 -- it took them
  64. ; long enough to figure this out and tell everyone) or the NIC behaves badly.
  65. ; Therefor one I/O instruction should be inserted between each successive
  66. ; NIC I/O instruction that could occur 'back - to - back' on a fast cache
  67. ; machine.
  68. ;   - gft - 910529
  69. ;
  70.     push    ax
  71.     in    al, 61h
  72.     pop    ax
  73. ;
  74. endm
  75.  
  76. reset_8390    macro
  77.     loadport
  78.     setport    NE_RESET
  79.     in    al,dx
  80.     longpause
  81.     out    dx,al        ; should set command 21, 80
  82.  
  83.     endm
  84.  
  85. terminate_board    macro
  86.     endm
  87.  
  88.     public    int_no, io_addr
  89. int_no        db    2,0,0,0        ;must be four bytes long for get_number.
  90. io_addr        dw    0300h,0        ; I/O address for card (jumpers)
  91.  
  92.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  93. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  94. driver_type    dw    54        ;from the packet spec
  95. driver_name    db    'NE2000',0    ;name of the driver.
  96. driver_function    db    2
  97. parameter_list    label    byte
  98.     db    1    ;major rev of packet driver
  99.     db    9    ;minor rev of packet driver
  100.     db    14    ;length of parameter list
  101.     db    EADDR_LEN    ;length of MAC-layer address
  102.     dw    GIANT    ;MTU, including MAC headers
  103.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  104.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  105.     dw    0    ;(# of successive xmits) - 1
  106. int_num    dw    0    ;Interrupt # to hook for post-EOI
  107.             ;processing, 0 == none,
  108.  
  109.     extrn    is_186: byte        ;=0 if 808[68], =1 if 80[123]86.
  110.  
  111. ;
  112. ;    Block input routine
  113. ;    CX = byte count, es:di = buffer location, ax = buffer address
  114.  
  115.     public    block_input
  116. block_input:
  117.     push    ax        ; save buffer address
  118.     loadport
  119.     setport EN_CCMD
  120.     pause_
  121.     mov    al,ENC_NODMA+ENC_PAGE0+ENC_START
  122.     out    dx,al
  123.     setport    EN0_RCNTLO    ; remote byte count 0
  124.     pause_
  125.     mov    al,cl
  126.     out    dx,al
  127.     setport    EN0_RCNTHI
  128.     pause_
  129.     mov    al,ch
  130.     out    dx,al
  131.     pop    ax        ; get our page back
  132.     setport    EN0_RSARLO
  133.     pause_
  134.     out    dx,al        ; set as hi address
  135.     setport    EN0_RSARHI
  136.     pause_
  137.     mov    al,ah
  138.     out    dx,al
  139.     setport EN_CCMD
  140.     pause_
  141.     mov    al,ENC_RREAD+ENC_START    ; read and start
  142.     out    dx,al
  143.     setport    NE_DATAPORT
  144.     pause_
  145.     cmp    is_186,0
  146.     jnz    read_186
  147. read_loop:
  148.     in    al,dx        ; get a byte
  149.     stosb            ; save it
  150.     loop    read_loop
  151.     ret
  152. read_186:
  153.     shr    cx,1        ; word count
  154.     .286
  155.     rep    insw
  156.     .8086
  157.     jnc    read_186_1        ;is there an extra byte?
  158.     in    ax,dx            ;yes, read the next word and store a
  159.     stosb                ;  byte.
  160. read_186_1:
  161.     ret
  162. ;
  163. ;    Block output routine
  164. ;    CX = byte count, ds:si = buffer location, ax = buffer address
  165.  
  166. block_output:
  167.     assume    ds:nothing
  168.     push    ax        ; save buffer address
  169.     inc    cx        ; make even
  170.     and    cx,0fffeh
  171.     loadport
  172.     setport EN_CCMD
  173.     pause_
  174.     mov    al,ENC_NODMA+ENC_START
  175.     out    dx,al        ; stop & clear the chip
  176.     setport    EN0_RCNTLO    ; remote byte count 0
  177.     pause_
  178.     mov    al,cl
  179.     out    dx,al
  180.     setport    EN0_RCNTHI
  181.     pause_
  182.     mov    al,ch
  183.     out    dx,al
  184.     pop    ax        ; get our page back
  185.     setport    EN0_RSARLO
  186.     pause_
  187.     out    dx,al        ; set as lo address
  188.     setport    EN0_RSARHI
  189.     pause_
  190.     mov    al,ah
  191.     out    dx,al
  192.     setport EN_CCMD
  193.     pause_
  194.     mov    al,ENC_RWRITE+ENC_START    ; write and start
  195.     out    dx,al
  196.     setport    NE_DATAPORT
  197.     pause_
  198.     cmp    is_186,0
  199.     jnz    write_186
  200. write_loop:
  201.     lodsb            ; get a byte
  202.     out    dx,al        ; save it
  203.     loop    write_loop
  204.     jmp    short block_output_1
  205. write_186:
  206.     shr    cx,1        ; word count
  207.     .286
  208.     rep    outsw
  209.     .8086
  210. block_output_1:
  211.     mov    cx,0
  212.     setport    EN0_ISR
  213. tx_check_rdc:
  214.     in    al,dx
  215.     test    al,ENISR_RDC    ; dma done ???
  216.     jnz    tx_start
  217.     loop    tx_check_rdc
  218.     stc
  219.     ret
  220. tx_start:
  221.     clc
  222.     ret
  223.  
  224.  
  225.     include    8390.asm
  226.  
  227.     public    usage_msg
  228. usage_msg    db    "usage: NE2000 [options] <packet_int_no> <int_level> <io_addr>",CR,LF,'$'
  229.  
  230.     public    copyright_msg
  231. copyright_msg    db    "Packet driver for NE2000, version "
  232.         db    '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF,'$'
  233.  
  234. int_no_name    db    "Interrupt number ",'$'
  235. io_addr_name    db    "I/O port ",'$'
  236.  
  237.     extrn    set_recv_isr: near
  238.  
  239. ;enter with si -> argument string, di -> word to store.
  240. ;if there is no number, don't change the number.
  241.     extrn    get_number: near
  242.  
  243. ;enter with dx -> name of word, di -> dword to print.
  244.     extrn    print_number: near
  245.  
  246.     public    parse_args
  247. parse_args:
  248. ;exit with nc if all went well, cy otherwise.
  249.     mov    di,offset int_no
  250.     call    get_number
  251.     mov    di,offset io_addr
  252.     call    get_number
  253.     clc
  254.     ret
  255.  
  256.     extrn    etopen_diagn: byte
  257.  
  258. init_card:
  259. ;get the board data. This is (16) bytes starting at remote
  260. ;dma address 0. Put it in a buffer called board_data.
  261.     assume    ds:code
  262.  
  263.     or    endcfg,ENDCFG_WTS
  264.  
  265.     loadport
  266.     mov    al,endcfg
  267.     setport    EN0_DCFG
  268.     pause_
  269.     out    dx,al
  270.  
  271.     mov    cx,10h        ; get 16 bytes,
  272.     movseg    es,ds
  273.     mov    di,offset board_data
  274.  
  275.     setport EN_CCMD
  276.     pause_
  277.     mov    al,ENC_NODMA+ENC_PAGE0+ENC_START
  278.     out    dx,al
  279.     setport    EN0_RCNTLO    ; remote byte count 0
  280.     pause_
  281.     mov    al,20h        ; count is actually doubled.
  282.     out    dx,al
  283.     setport    EN0_RCNTHI
  284.     pause_
  285.     xor    al,al        ; high byte of count is zero.
  286.     out    dx,al
  287.  
  288.     mov    ax,0        ; from address 0
  289.  
  290.     setport    EN0_RSARLO
  291.     pause_
  292.     out    dx,al        ; set as hi address
  293.     setport    EN0_RSARHI
  294.     pause_
  295.     mov    al,ah
  296.     out    dx,al
  297.     setport EN_CCMD
  298.     pause_
  299.     mov    al,ENC_RREAD+ENC_START    ; read and start
  300.     out    dx,al
  301.     setport    NE_DATAPORT
  302.     pause_
  303. sp_read_loop:
  304.     in    al,dx        ; get a byte
  305.     stosb            ; save it
  306.     loop    sp_read_loop
  307.  
  308.     push    ds              ; Copy from card's address to current address
  309.     pop     es
  310.  
  311.     mov si, offset board_data    ; address is at start
  312.     mov di, offset rom_address
  313.     mov cx, EADDR_LEN       ; Copy one address length
  314.     rep     movsb           ; ..
  315.  
  316.     clc
  317.     ret
  318.  
  319.     public    print_parameters
  320. print_parameters:
  321. ;echo our command-line parameters
  322.     mov    di,offset int_no
  323.     mov    dx,offset int_no_name
  324.     call    print_number
  325.     mov    di,offset io_addr
  326.     mov    dx,offset io_addr_name
  327.     call    print_number
  328.     ret
  329.  
  330. code    ends
  331.  
  332.     end
  333.