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

  1. version    equ    5
  2. ;History:77,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.  
  23.     include    defs.asm
  24.  
  25. code    segment    word public
  26.     assume    cs:code, ds:code
  27.  
  28. ;*****************************************************************************
  29. ;
  30. ;    NE1000 controller board offsets
  31. ;    IO port definition (BASE in io_addr)
  32. ;*****************************************************************************
  33. NE_DATAPORT    EQU    10h        ; NE1000 Port Window.
  34. NE_RESET    EQU    1fh        ; Issue a read for reset
  35. EN_OFF        equ    0h
  36.  
  37.     include    8390.inc
  38.  
  39. ; Shared memory management parameters
  40.  
  41. SM_TSTART_PG    EQU    20h        ; First page of TX buffer
  42. SM_RSTART_PG    EQU    26h        ; start at page 26
  43. SM_RSTOP_PG    EQU    40h        ; end at page 40
  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
  73.     pop    ax
  74. ;
  75. endm
  76.  
  77. reset_8390    macro
  78.     loadport
  79.     setport    NE_RESET
  80.     in    al,dx
  81.     longpause
  82.     out    dx,al        ; should set command 21, 80
  83.     endm
  84.  
  85. terminate_board    macro
  86.     endm
  87.  
  88.     public    int_no, io_addr
  89. int_no        db    3,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    53        ;from the packet spec
  95. driver_name    db    'NE1000',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. ;    Special case Block input routine. Used on extra memory
  113. ;    space for board ID etc. DMA count is set X2,
  114. ;    CX = byte count, es:si = buffer location, ax = buffer address
  115. ;
  116. sp_block_input:
  117. ;    Nothing special needed for NE-1000.
  118. ;
  119. ;    Block input routine
  120. ;    CX = byte count, es:di = buffer location, ax = buffer address
  121.  
  122.     public    block_input
  123. block_input:
  124.     push    ax        ; save buffer address
  125.     loadport
  126.     setport EN_CCMD
  127.     pause_
  128.     mov    al,ENC_NODMA+ENC_PAGE0+ENC_START
  129.     out    dx,al
  130.     mov    ax,cx            ;get the count to be output.
  131.     setport    EN0_RCNTLO    ; remote byte count 0
  132.     pause_
  133.     out    dx,al
  134.     setport    EN0_RCNTHI
  135.     pause_
  136.     mov    al,ah
  137.     out    dx,al
  138.     pop    ax        ; get our page back
  139.     setport    EN0_RSARLO
  140.     pause_
  141.     out    dx,al        ; set as hi address
  142.     setport    EN0_RSARHI
  143.     pause_
  144.     mov    al,ah
  145.     out    dx,al
  146.     setport EN_CCMD
  147.     pause_
  148.     mov    al,ENC_RREAD+ENC_START    ; read and start
  149.     out    dx,al
  150.     setport    NE_DATAPORT
  151.     pause_
  152.     cmp    is_186,0
  153.     jnz    read_186
  154. read_loop:
  155.     in    al,dx        ; get a byte
  156.     stosb            ; save it
  157.     loop    read_loop
  158.     ret
  159. read_186:
  160.     .286
  161.     rep    insb
  162.     .8086
  163.     ret
  164. ;
  165. ;    Block output routine
  166. ;    CX = byte count, ds:si = buffer location, ax = buffer address
  167.  
  168. block_output:
  169.     assume    ds:nothing
  170.     push    ax        ; save buffer address
  171.     inc    cx        ; make even
  172.     and    cx,0fffeh
  173.     loadport
  174.     setport EN_CCMD
  175.     pause_
  176.     mov    al,ENC_NODMA+ENC_START
  177.     out    dx,al        ; stop & clear the chip
  178.     setport    EN0_RCNTLO    ; remote byte count 0
  179.     pause_
  180.     mov    al,cl
  181.     out    dx,al
  182.     setport    EN0_RCNTHI
  183.     pause_
  184.     mov    al,ch
  185.     out    dx,al
  186.     pop    ax        ; get our page back
  187.     setport    EN0_RSARLO
  188.     pause_
  189.     out    dx,al        ; set as lo address
  190.     setport    EN0_RSARHI
  191.     pause_
  192.     mov    al,ah
  193.     out    dx,al
  194.     setport EN_CCMD
  195.     pause_
  196.     mov    al,ENC_RWRITE+ENC_START    ; write and start
  197.     out    dx,al
  198.     setport    NE_DATAPORT
  199.     pause_
  200.     cmp    is_186,0
  201.     jnz    write_186
  202. write_loop:
  203.     lodsb            ; get a byte
  204.     out    dx,al        ; save it
  205.     loop    write_loop
  206.     jmp    short block_output_1
  207. write_186:
  208.     .286
  209.     rep    outsb
  210.     .8086
  211. block_output_1:
  212.     mov    cx,0
  213.     setport    EN0_ISR
  214. tx_check_rdc:
  215.     in    al,dx
  216.     test    al,ENISR_RDC    ; dma done ???
  217.     jnz    tx_start
  218.     loop    tx_check_rdc
  219.     stc
  220.     ret
  221. tx_start:
  222.     clc
  223.     ret
  224.  
  225.  
  226.     include    8390.asm
  227.  
  228.     public    usage_msg
  229. usage_msg    db    "usage: NE1000 [options] <packet_int_no> <hardware_irq> <io_addr>",CR,LF,'$'
  230.  
  231.     public    copyright_msg
  232. copyright_msg    db    "Packet driver for NE1000, version "
  233.         db    '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF,'$'
  234.  
  235. int_no_name    db    "Interrupt number ",'$'
  236. io_addr_name    db    "I/O port ",'$'
  237.  
  238.     extrn    set_recv_isr: near
  239.  
  240. ;enter with si -> argument string, di -> word to store.
  241. ;if there is no number, don't change the number.
  242.     extrn    get_number: near
  243.  
  244. ;enter with dx -> name of word, di -> dword to print.
  245.     extrn    print_number: near
  246.  
  247.     public    parse_args
  248. parse_args:
  249. ;exit with nc if all went well, cy otherwise.
  250.     mov    di,offset int_no
  251.     call    get_number
  252.     mov    di,offset io_addr
  253.     call    get_number
  254.     clc
  255.     ret
  256.  
  257.     extrn    etopen_diagn: byte
  258.  
  259. bad_addr_msg    label    byte
  260.  db "The Ethernet address of this card is invalid, because it has the",CR,LF
  261.  db "multicast bit set.  We will reset that bit and continue...",CR,LF,'$'
  262.  
  263. init_card:
  264. ;get the board data. This is (16) bytes starting at remote
  265. ;dma address 0. Put it in a buffer called board_data.
  266.  
  267.     mov    cx,10h        ; get 16 bytes,
  268.     movseg    es,ds
  269.     mov    di,offset board_data
  270.     mov    ax,0        ; from address 0
  271.     call    sp_block_input
  272.  
  273.     push    ds              ; Copy from card's address to current address
  274.     pop     es
  275.  
  276.     test    board_data,1        ;did the fools pick their own OUI?
  277.     je    init_card_1        ;no.
  278.  
  279.     and    board_data,not 1    ;reset the multicast bit,
  280.     mov    dx,offset bad_addr_msg
  281.     mov    ah,9
  282.     int    21h
  283.  
  284. init_card_1:
  285.  
  286.     mov si, offset board_data    ; address is at start
  287.     mov di, offset rom_address
  288.     mov cx, EADDR_LEN       ; Copy one address length
  289.     rep     movsb           ; ..
  290.  
  291.     clc
  292.     ret
  293.  
  294.     public    print_parameters
  295. print_parameters:
  296. ;echo our command-line parameters
  297.     mov    di,offset int_no
  298.     mov    dx,offset int_no_name
  299.     call    print_number
  300.     mov    di,offset io_addr
  301.     mov    dx,offset io_addr_name
  302.     call    print_number
  303.     ret
  304.  
  305. code    ends
  306.  
  307.     end
  308.