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

  1. ;History:2,18
  2. version    equ    6
  3.  
  4.     include    defs.asm
  5.  
  6. ;/* PC/FTP Packet Driver source, conforming to version 1.05 of the spec,
  7. ;*  for the 3-Com 3C503 interface card.
  8. ;*  Robert C Clements, K1BC, 14 February, 1989
  9. ;*  Portions (C) Copyright 1988, 1989 Robert C Clements
  10. ;*
  11. ;  Copyright, 1988-1992, Russell Nelson, Crynwr Software
  12.  
  13. ;   This program is free software; you can redistribute it and/or modify
  14. ;   it under the terms of the GNU General Public License as published by
  15. ;   the Free Software Foundation, version 1.
  16. ;
  17. ;   This program is distributed in the hope that it will be useful,
  18. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. ;   GNU General Public License for more details.
  21. ;
  22. ;   You should have received a copy of the GNU General Public License
  23. ;   along with this program; if not, write to the Free Software
  24. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  
  26. code    segment    word public
  27.     assume    cs:code, ds:code
  28.  
  29. ; Stuff specific to the 3-Com 3C503 Ethernet controller board
  30. ; WD version in C by Bob Clements, K1BC, May 1988 for the KA9Q TCP/IP package
  31. ; 3Com version based on WD8003E version in .ASM, also by Bob Clements, dated
  32. ;  19 August 1988.  The WD and 3Com cards both use the National DS8390.
  33.  
  34. ; Symbol prefix "EN" is for Ethernet, National chip
  35. ; Symbol prefix "E33" is for _E_thernet, _3_Com 50_3_
  36. ; Symbol prefix "E33G" is for registers in the Gate array ASIC.
  37.  
  38. ; The E33 registers - For the ASIC on the 3C503 card:
  39. ; Offsets from the board's base address, which can be set by
  40. ; jumpers to be one of the following 8 values (hex):
  41. ;  350, 330, 310, 300, 2E0, 2A0, 280, 250
  42. ; Factory default address is 300H.
  43. ; The card occupies a block of 16 I/O addresses.
  44. ; It also occupies 16 addresses at base+400 through base+40F.
  45. ; These high-addressed registers are in the ASIC.
  46. ; Recall that the normal PC I/O decoding is only 10 bits. The 11'th
  47. ; bit (400H) can be used on the same card for additional registers.
  48. ; This offset requires word, not byte, arithmetic
  49. ; on the DX register for the setport macro. Current SETPORT is OK.
  50.  
  51. ; The card can also be jumpered to have the shared memory disabled
  52. ; or enabled at one of four addresses: C8000, CC000, D8000 or DC000.
  53.  
  54. ; The card can be operated using direct I/O instructions or by
  55. ; using the PC's DMA channels instead of the shared memory.  We don't
  56. ; use DMA because it's slow on an AT.
  57.  
  58. ; Blocks of I/O addresses:
  59.  
  60. E33GA        equ    400h    ; Registers in the gate array.
  61. E33_SAPROM    equ    000h    ; Window on station addr prom (if
  62.                 ; E33G_CNTRL bits 3,2 = 0,1
  63.  
  64. ; These appear at Base+0 through Base+0F when bits 3,2 of
  65. ; E33G_CNTRL are 0,0.
  66.  
  67. EN_OFF        equ    0h
  68.  
  69. ENDCFG_BM8    equ    48h
  70.  
  71.     include    8390.inc
  72.  
  73. ; Registers in the 3-Com custom Gate Array
  74.  
  75. E33G_STARTPG    equ E33GA+00h    ; Start page, must match EN0_STARTPG
  76. E33G_STOPPG    equ E33GA+01h    ; Stop  page, must match EN0_STOPPG
  77. E33G_NBURST    equ E33GA+02h    ; Size of DMA burst before relinquishing bus
  78. E33G_IOBASE    equ E33GA+03h    ; Bit coded: where I/O regs are jumpered.
  79.                 ; (Which you have to know already to read it)
  80. E33G_ROMBASE    equ E33GA+04h    ; Bit coded: Where/whether EEPROM&DPRAM exist
  81. E33G_GACFR    equ E33GA+05h    ; Config/setup bits for the ASIC GA
  82. E33G_CNTRL    equ E33GA+06h    ; Board's main control register
  83. E33G_STATUS    equ E33GA+07h    ; Status on completions.
  84. E33G_IDCFR    equ E33GA+08h    ; Interrupt/DMA config register
  85.                 ; (Which IRQ to assert, DMA chan to use)
  86. E33G_DMAAH    equ E33GA+09h    ; High byte of DMA address reg
  87. E33G_DMAAL    equ E33GA+0ah    ; Low byte of DMA address reg
  88. E33G_VP2    equ E33GA+0bh    ; Vector pointer - for clearing RAM select
  89. E33G_VP1    equ E33GA+0ch    ;  on a system reset, to re-enable EPROM.
  90. E33G_VP0    equ E33GA+0dh    ;  3Com says set this to Ctrl-Alt-Del handler
  91. E33G_FIFOH    equ E33GA+0eh    ; FIFO for programmed I/O data moves ...
  92. E33G_FIFOL    equ E33GA+0fh    ; .. low byte of above.
  93.  
  94. ; Bits in E33G_CNTRL register:
  95.  
  96. ECNTRL_RESET    equ    001h    ; Software reset of the ASIC and 8390
  97. ECNTRL_THIN    equ    002h    ; Onboard thin-net xcvr enable
  98. ECNTRL_SAPROM    equ    004h    ; Map the station address prom
  99. ECNTRL_DBLBFR    equ    020h    ; FIFO configuration bit
  100. ECNTRL_OUTPUT    equ    040h    ; PC-to-3C503 direction if 1
  101. ECNTRL_INPUT    equ    000h    ; PC-to-3C503 direction if 0
  102. ECNTRL_START    equ    080h    ; Start the DMA logic
  103.  
  104. ; Bits in E33G_STATUS register:
  105.  
  106. ESTAT_DPRDY    equ    080h    ; Data port (of FIFO) ready
  107. ESTAT_UFLW    equ    040h    ; Tried to read FIFO when it was empty
  108. ESTAT_OFLW    equ    020h    ; Tried to write FIFO when it was full
  109. ESTAT_DTC    equ    010h    ; Terminal Count from PC bus DMA logic
  110. ESTAT_DIP    equ    008h    ; DMA In Progress
  111.  
  112. ; Bits in E33G_GACFR register:
  113.  
  114. EGACFR_NORM    equ    049h    ; Enable 8K shared mem, no DMA TC int
  115. EGACFR_EPROM    equ    041h    ; Disable 8K shared mem.
  116. EGACFR_IRQOFF    equ    0c9h    ; Above, and disable 8390 IRQ line
  117.  
  118. ; Shared memory management parameters
  119.  
  120. SM_TSTART_PG    equ    020h    ; First page of TX buffer
  121. SM_RSTART_PG    equ    026h    ; Starting page of RX ring
  122. SM_RSTOP_PG    equ    040h    ; Last page +1 of RX ring
  123.  
  124. ; End of 3C503 parameter definitions
  125.  
  126. pause_    macro
  127. ;    jmp    $+2
  128. ;
  129. ; The reason for the pause_ macro is to establish a minimum time between
  130. ; accesses to the card hardware. The assumption is that the fetch and execution
  131. ; of the jmp $+2 instruction will provide this time. In a fast cache machine
  132. ; this may be a false assumption. In a fast cache machine, there may be 
  133. ; NO REAL TIME DIFFERENCE between the two I/O instruction streams below:
  134. ;
  135. ;    in    al,dx        in    al,dx
  136. ;    jmp    $+2
  137. ;    in    al,dx        in    al,dx
  138. ;
  139. ; To establish a minimum delay, an I/O instruction must be used. A good rule of
  140. ; thumb is that ISA I/O instructions take ~1.0 microseconds and MCA I/O
  141. ; instructions take ~0.5 microseconds. Reading the NMI Status Register (0x61)
  142. ; is a good way to pause on all machines.
  143. ;
  144. ; The National 8390 Chip (NIC) requires 4 bus clocks between successive
  145. ; chip selects (National DP8390 Data Sheet Addendum, June 1990 -- it took them
  146. ; long enough to figure this out and tell everyone) or the NIC behaves badly.
  147. ; Therefor one I/O instruction should be inserted between each successive
  148. ; NIC I/O instruction that could occur 'back - to - back' on a fast cache
  149. ; machine.
  150. ;   - gft - 910529
  151. ;
  152.     push    ax
  153.     in    al, 61h
  154.     pop    ax
  155. ;
  156. endm
  157.  
  158. ram_enable    macro
  159.     setport    E33G_GACFR    ; Make sure gate array is set up and
  160.     mov al,    EGACFR_NORM    ;  the RAM is enabled (not EPROM)
  161.     out dx,    al        ; ..
  162.     endm
  163.  
  164. rom_enable    macro
  165.     setport    E33G_GACFR    ; Make sure gate array is set up and
  166.     mov al,    EGACFR_EPROM    ;  the EPROM is enabled (not RAM)
  167.     out dx,    al        ; ..
  168.     endm
  169.  
  170. reset_8390    macro
  171.     loadport        ; First, pulse the board reset
  172.     setport    E33G_CNTRL
  173.     mov    al,thin_bit        ; Thick or thin cable bit
  174.     or    al,ECNTRL_RESET
  175.     out    dx,al            ; Turn on board reset bit
  176.     mov    al,thin_bit        ; Thick or thin cable bit
  177.     out    dx,al            ; Turn off board reset bit
  178.     call    do_reset
  179.     loadport
  180.     endm
  181.  
  182. terminate_board    macro
  183.     endm
  184.  
  185. ; The following three values may be overridden from the command line.
  186. ; If they are omitted from the command line, these defaults are used.
  187. ; The shared memory base is set by a jumper.  We read it from the
  188. ; card and set up accordingly.
  189.  
  190.     public    int_no, io_addr, thin_not_thick
  191. int_no        db    2,0,0,0        ; Interrupt level
  192. io_addr        dw    0300h,0        ; I/O address for card (jumpers)
  193. thin_not_thick    dw    -1,-1        ; -1 means auto, non-zero means thin net
  194.     public    mem_base
  195. mem_base    dw    00000h,0    ; Shared memory addr (jumpers)
  196. ; (Not changeable by software in 3C503)    ; (0 if disabled by jumpers)
  197. thin_bit    db    0
  198.  
  199.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  200. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  201. driver_type    db    12        ;from the packet spec
  202. driver_name    db    '3C503',0    ;name of the driver.
  203. driver_function    db    2
  204. parameter_list    label    byte
  205.     db    1    ;major rev of packet driver
  206.     db    9    ;minor rev of packet driver
  207.     db    14    ;length of parameter list
  208.     db    EADDR_LEN    ;length of MAC-layer address
  209.     dw    GIANT    ;MTU, including MAC headers
  210.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  211.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  212.     dw    0    ;(# of successive xmits) - 1
  213. int_num    dw    0    ;Interrupt # to hook for post-EOI
  214.             ;processing, 0 == none,
  215.  
  216.     extrn    is_186: byte        ;=0 if 808[68], =1 if 80[1234]86.
  217.     extrn    is_286: byte        ;=0 if 808[68], =1 if 80[234]86.
  218.  
  219.     include    popf.asm
  220.     include    movemem.asm
  221.  
  222. block_output:
  223. ;enter with cx = byte count, ds:si = buffer location, ax = buffer address
  224.     assume    ds:nothing
  225.     cmp    mem_base,0        ;memory or I/O?
  226.     je    block_o            ;I/O.
  227.     mov    es,mem_base        ; Set up ES:DI at the shared RAM
  228.     mov    di,ax            ; ..
  229.     loadport            ; Set up for address of TX buffer.
  230.     ram_enable            ; Make sure the RAM is actually there.
  231.     call    movemem
  232.     loadport
  233.     rom_enable
  234.     clc
  235.     ret
  236.  
  237. block_o:
  238.     loadport
  239.     setport    E33G_DMAAL
  240.     out    dx,al
  241.     setport    E33G_DMAAH
  242.         mov     al,ah
  243.         out     dx,al
  244.  
  245.     setport    E33G_CNTRL
  246.     mov    al,thin_bit
  247.     or    al,ECNTRL_OUTPUT or ECNTRL_START ;start dma, write to board.
  248.     out    dx,al
  249.  
  250.     cmp    is_186,0
  251.     je    block_o_88
  252.  
  253.     .286
  254.     setport    E33G_STATUS
  255. block_o_186_0:
  256.     jcxz    block_o_2        ;if there is none, exit.
  257.     in    al,dx            ;wait for the FIFO to be ready.
  258.     test    al,ESTAT_DPRDY
  259.     je    block_o_186_0
  260.     setport    E33G_FIFOH        ;now get ready to read data.
  261.     cmp    cx,8            ;do we have eight more to do?
  262.     jb    block_o_186_1        ;no, do them one by one.
  263.     outsw                ;yes, output eight all at once.
  264.     outsw
  265.     outsw
  266.     outsw
  267.     sub    cx,8            ;reduce the count by what we write.
  268.     setport    E33G_STATUS        ;go back to the status bit.
  269.     jmp    block_o_186_0
  270. block_o_186_1:
  271.     rep    outsb            ;output less than 8 bytes.
  272.     jmp    short block_o_2
  273.     .8086
  274.  
  275.  
  276. block_o_88:
  277.     loadport
  278.     setport    E33G_STATUS
  279. block_o_88_0:
  280.     jcxz    block_o_2        ;if there is none, exit.
  281.     in    al,dx            ;wait for the FIFO to be ready.
  282.     test    al,ESTAT_DPRDY
  283.     je    block_o_88_0
  284.     setport    E33G_FIFOH        ;now get ready to read data.
  285.     cmp    cx,8            ;do we have eight more to do?
  286.     jb    block_o_88_1        ;no, do them one by one.
  287.     lodsw                ;yes, output eight all at once.
  288.     out    dx,ax
  289.     lodsw
  290.     out    dx,ax
  291.     lodsw
  292.     out    dx,ax
  293.     lodsw
  294.     out    dx,ax
  295.     sub    cx,8            ;reduce the count by what we write.
  296.     setport    E33G_STATUS        ;go back to the status bit.
  297.     jmp    block_o_88_0
  298. block_o_88_1:
  299.     lodsb                ;output less than 8 bytes.
  300.     out    dx,al
  301.     loop    block_o_88_1
  302. block_o_2:
  303.     loadport
  304.     setport    E33G_CNTRL
  305.     mov    al,thin_bit        ;stop dma.
  306.     out    dx,al
  307.     ret
  308.  
  309.  
  310. block_input:
  311. ;enter with cx = byte count, es:di = buffer location, ax = board address.
  312.     cmp    mem_base,0        ; memory or I/O
  313.     je    block_i            ; I/O
  314.     push    ax
  315.     loadport
  316.     ram_enable
  317.     pop    ax
  318.     push    ds
  319.     assume    ds:nothing
  320.     mov    ds,mem_base        ; ds:si points at first byte to move
  321.     mov    si,ax
  322.  
  323.     add    ax,cx            ; Find the end of this frame.
  324.     cmp    ah,byte ptr cs:sm_rstop_ptr ; Over the top of the ring?
  325.     jb    rcopy_one_piece        ; Go move it
  326.  
  327. rcopy_wrap:
  328. ; Copy in two pieces due to buffer wraparound.
  329.     mov    ah,byte ptr cs:sm_rstop_ptr ; Compute length of first part
  330.     xor    al,al
  331.     sub    ax,si            ;  as all of the pages up to wrap point
  332.     sub    cx,ax            ; Move the rest in second part
  333.     push    cx            ; Save count of second part
  334.     mov    cx,ax            ; Count for first move
  335.     call    rcopy_subr
  336.     mov    si,SM_RSTART_PG*256    ; Offset to start of first receive page
  337.     pop    cx            ; Bytes left to move
  338. rcopy_one_piece:
  339.     call    rcopy_subr
  340.     pop    ds
  341.     loadport
  342.     rom_enable
  343.     ret
  344.  
  345.  
  346. rcopy_subr:
  347.     shr    cx,1            ; convert byte count to word count
  348.     rep    movsw
  349.     jnc    rcv_wrap_even        ; odd byte left over?
  350.     lodsw                ;   yes, word fetch
  351.     stosb                ;   and byte store
  352. rcv_wrap_even:
  353.     ret
  354.  
  355. block_i:
  356.     assume    ds:code
  357.     loadport
  358.     setport    E33G_DMAAL
  359.     out    dx,al
  360.     setport    E33G_DMAAH
  361.         mov     al,ah
  362.         out     dx,al
  363.  
  364.     setport    E33G_CNTRL
  365.     mov    al,thin_bit
  366.     or    al,ECNTRL_INPUT or ECNTRL_START ;start dma, read from board.
  367.     out    dx,al
  368.  
  369.     cmp    is_186,0
  370.     je    block_i_88
  371.  
  372.     .286
  373.     setport    E33G_STATUS
  374. block_i_186_0:
  375.     jcxz    block_i_2        ;if there is none, exit.
  376.     in    al,dx            ;wait for the FIFO to be ready.
  377.     test    al,ESTAT_DPRDY
  378.     je    block_i_186_0
  379.     setport    E33G_FIFOH        ;now get ready to read data.
  380.     cmp    cx,8            ;do we have eight more to do?
  381.     jb    block_i_186_1        ;no, do them one by one.
  382.     insw                ;yes, input eight all at once.
  383.     insw
  384.     insw
  385.     insw
  386.     sub    cx,8            ;reduce the count by what we read.
  387.     setport    E33G_STATUS        ;go back to the status bit.
  388.     jmp    block_i_186_0
  389. block_i_186_1:
  390.     rep    insb            ;input less than 8 bytes.
  391.     jmp    short block_i_2
  392.     .8086
  393.  
  394.  
  395. block_i_88:
  396.     loadport
  397.     setport    E33G_STATUS
  398. block_i_88_0:
  399.     jcxz    block_i_2        ;if there is none, exit.
  400.     in    al,dx            ;wait for the FIFO to be ready.
  401.     test    al,ESTAT_DPRDY
  402.     je    block_i_88_0
  403.     setport    E33G_FIFOH        ;now get ready to read data.
  404.     cmp    cx,8            ;do we have eight more to do?
  405.     jb    block_i_88_1        ;no, do them one by one.
  406.     in    ax,dx            ;yes, input eight all at once.
  407.     stosw
  408.     in    ax,dx
  409.     stosw
  410.     in    ax,dx
  411.     stosw
  412.     in    ax,dx
  413.     stosw
  414.     sub    cx,8            ;reduce the count by what we write.
  415.     setport    E33G_STATUS        ;go back to the status bit.
  416.     jmp    block_i_88_0
  417. block_i_88_1:
  418.     in    al,dx            ;input less than 8 bytes.
  419.     stosb
  420.     loop    block_i_88_1
  421. block_i_2:
  422.     loadport
  423.     setport    E33G_CNTRL
  424.     mov    al,thin_bit        ;stop dma.
  425.     out    dx,al
  426.     ret
  427.  
  428.  
  429.  
  430.     include    8390.asm
  431.  
  432.     public    usage_msg
  433. usage_msg    label    byte
  434. db "usage: 3C503 [options] <packet_int_no> <hardware_irq> <io_addr> <cable_type>",CR,LF
  435. db "Default for <cable_type> is automatic detection.  Use 0 to force AUI,",CR,LF
  436. db "1 to force on-board transceiver.",CR,LF,'$'
  437.  
  438.     public    copyright_msg
  439. copyright_msg    db    "Packet driver for 3-Com 3C503, version "
  440.         db    '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF
  441.         db    "Portions Copyright 1989, Robert C. Clements, K1BC",CR,LF,'$'
  442.  
  443. cfg_err_msg    db    "The int_no parameter must be between 2 and 5.",CR,LF,'$'
  444. mem_busted_msg    db    "Shared RAM on 3C503 card is defective or there is an address conflict.",CR,LF,'$'
  445. no_network_msg    db    "Check network connector - no network connection detected.",CR,LF,'$'
  446.  
  447. int_no_name    db    "Interrupt number ",'$'
  448. io_addr_name    db    "I/O port ",'$'
  449. mem_base_name    db    "Memory address ",'$'
  450.  
  451. thin_msg    db    "Using the built-in transceiver (thinwire)",CR,LF,'$'
  452. thick_msg    db    "Using the external transceiver (thickwire)",CR,LF,'$'
  453.  
  454.  
  455.     extrn    set_recv_isr: near
  456.  
  457. ;enter with si -> argument string, di -> word to store.
  458. ;if there is no number, don't change the number.
  459.     extrn    get_number: near
  460.  
  461. ;enter with dx -> name of word, di -> dword to print.
  462.     extrn    print_number: near
  463.  
  464. ;-> the assigned Ethernet address of the card.
  465.     extrn    rom_address: byte
  466.  
  467.     public    parse_args
  468. parse_args:
  469. ;exit with nc if all went well, cy otherwise.
  470.     mov    di,offset int_no    ; May override interrupt channel
  471.     call    get_number
  472.     mov    di,offset io_addr    ; May override I/O address
  473.     call    get_number
  474.     mov    di,offset thin_not_thick    ; May override thick/thin cable flag
  475.     call    get_number
  476.     mov    ax,thin_not_thick    ; Now make the right bit
  477.     cmp    ax,0
  478.     je    parse_thin1        ; If zero, leave bit off
  479.     mov    al,ECNTRL_THIN        ; Else the bit for the card
  480. parse_thin1:
  481.     mov    thin_bit,al        ; Save for setting up the card
  482.  
  483.     clc
  484.     ret
  485.  
  486. do_reset:
  487.     assume    ds:code
  488.     loadport            ; Re-establish I/O base after dx mods
  489.     setport E33G_CNTRL        ; Switch control bits to turn off SA PROM
  490.     mov al,    thin_bit
  491.     out dx,    al            ; Turn off SA PROM windowing
  492.     ret
  493.  
  494. init_card:
  495. ; Now get the board's physical address from on-board PROM into rom_address
  496. ;exit with cy, dx -> error if something went wrong.
  497.     assume    ds:code
  498.     loadport
  499.  
  500.     cli                ; Protect the E33G_CNTRL contents
  501.     setport E33G_CNTRL        ; Switch control bits to enable SA PROM
  502.     mov al,    thin_bit
  503.     or al,    ECNTRL_SAPROM
  504.     out dx,    al            ; ..
  505.     setport    E33_SAPROM        ; Where the address prom is
  506.  
  507.     movseg    es,cs
  508.     mov di,    offset rom_address
  509.     mov cx,    EADDR_LEN        ; Set count for loop
  510. ini_addr_loop:
  511.     in al,    dx            ; Get a byte of address
  512.     stosb                ; Feed it to caller
  513.     inc    dx            ; Next byte at next I/O port
  514.     loop    ini_addr_loop        ; Loop over six bytes
  515.  
  516.     loadport            ; Re-establish I/O base after dx mods
  517.     setport E33G_CNTRL        ; Switch control bits to turn off SA PROM
  518.     mov al,    thin_bit
  519.     out dx,    al            ; Turn off SA PROM windowing
  520.     sti                ; Ok for E33G_CNTRL to change now
  521. ; Point the "Vector Pointer" registers off into the boonies so we
  522. ; don't get the shared RAM disabled on us while we're using it.
  523. ; Ideally a warm boot should reset this too, to get to ROM on this card,
  524. ; but I don't know a guaranteed way to determine that value.
  525.     setport    E33G_VP2
  526.     mov al,    0ffh            ; Point this at the ROM restart location
  527.     out dx,    al            ;  of ffff0h.
  528.     setport E33G_VP1
  529.     out dx,    al
  530.     xor al,    al
  531.     setport E33G_VP0
  532.     out dx,    al
  533. ;Make sure shared memory is jumpered on. Find its address.
  534.     setport E33G_ROMBASE        ; Point at rom/ram cfg reg
  535.     xor    bx,bx
  536.     in al,    dx            ; Read it
  537.     test al,0f0h            ; Any bits on?
  538.     je    memcfg_3        ; no - using I/O.
  539. memcfg_1:
  540.     mov bx,    0c800h-16*SM_TSTART_PG    ; Build mem segment here
  541.     test al,0c0h            ; DC00 or D800?
  542.     je    memcfg_2        ; No
  543.     add bx,    01000h            ; Yes, make Dx00
  544. memcfg_2:
  545.     test al,0a0h            ; DC00 or CC00?
  546.     je    memcfg_3
  547.     add bx,    00400h            ; Yes, make xC00
  548. memcfg_3:
  549.     mov mem_base,bx            ; Remember segment addr of memory
  550.     or    bx,bx
  551.     je    mem_works        ; don't test the memory if we use I/O.
  552. ; Set up Gate Array's Config Reg to enable and size the RAM.
  553.     setport    E33G_GACFR        ; Make sure gate array is set up and
  554.     mov al,    EGACFR_IRQOFF        ;  the RAM is enabled (not EPROM)
  555.     out dx,    al            ; ..
  556. ; Check the card's memory
  557.     mov ax,    mem_base        ; Set segment of the shared memory
  558.     add ax,    16*SM_TSTART_PG        ;  which starts 2000h up from "base"
  559.     mov cx,    2000h            ; Length of RAM to test
  560.     call    memory_test        ; Check it out
  561.     jz    mem_works        ; Go if it's OK
  562.     mov dx,    offset mem_busted_msg
  563.     stc                ; Go report failure if it's bad
  564.     ret
  565. mem_works:
  566. ; Set up control of shared memory, buffer ring, etc.
  567.     loadport
  568.     setport    E33G_STARTPG        ; Set ASIC copy of rx's first buffer page
  569.     mov al,    SM_RSTART_PG
  570.     out dx,    al
  571.     setport    E33G_STOPPG        ;  and ASIC copy of rx's last buffer page + 1
  572.     mov al,SM_RSTOP_PG
  573. ;    mov al,    byte ptr sm_rstop_ptr
  574.     out dx,    al
  575. ; Set up interrupt/DMA control register in ASIC.
  576. ; For now, we won't use the DMA, so B0-B3 are zero.
  577.     xor ah,    ah            ; Get the interrupt level from arg line
  578.     mov al,    int_no            ; ..
  579.     cmp al,    9            ; If converted to 9, make back into 2
  580.     jne    get_irq1        ; Not 9
  581.     mov al,    2            ; Card thinks it's IRQ2
  582. get_irq1:                ; Now should have level in range 2-5
  583.     sub ax,    2            ; Make 0-3 for tables
  584.     cmp ax,    5-2            ; In range?
  585.     jna    get_irq2
  586.     mov    dx,offset cfg_err_msg    ; If not, can't configure.
  587.     stc
  588.     ret
  589. get_irq2:
  590.     xor cx,    cx            ; Make the bit for the ASIC
  591.     mov cl,    al            ; Shift count
  592.     mov al,    10h            ; Bit for irq2
  593.     shl al,    cl            ; Shift over as needed.
  594.     setport    E33G_IDCFR        ; Point at ASIC reg for IRQ level
  595.     out dx,    al            ; Set the bit
  596.     setport    E33G_NBURST        ; Set burst size to 8
  597.     mov al,    8
  598.     out dx,    al            ; ..
  599.     setport    E33G_DMAAH        ; Set up transmit bfr in DMA addr
  600.     mov al,    SM_TSTART_PG
  601.     out dx,    al
  602.     xor ax,    ax
  603.     setport E33G_DMAAL
  604.     out dx,    al
  605.     clc
  606.     ret
  607.  
  608.  
  609. test_packet    label    byte
  610.     db    EADDR_LEN dup(?)
  611.     db    EADDR_LEN dup(?)
  612.     db    00h,2eh            ;A 46 in network order
  613.     db    0,0            ;DSAP=0 & SSAP=0 fields
  614.     db    0f3h,0            ;Control (Test Req + P bit set)
  615.  
  616.     public    print_parameters
  617. print_parameters:
  618.     assume    ds:code
  619.  
  620.     cmp    thin_not_thick,-1
  621.     je    autosense
  622.     jmp    send_test_exit
  623.  
  624. autosense:
  625. ;but on *this* adapter, try sending a test packet.
  626.  
  627. ;first try with the AUI port.
  628.     mov    thin_bit,0
  629.  
  630.     mov    si,offset rom_address    ;set the destination address.
  631.     movseg    es,cs
  632.     mov    di,offset test_packet
  633.     repmov    EADDR_LEN
  634.     mov    si,offset rom_address    ;set the source address.
  635.     repmov    EADDR_LEN
  636.  
  637. send_test:
  638.     loadport            ;store the current thin_bit to the board.
  639.     setport    E33G_CNTRL
  640.     mov    al,thin_bit
  641.     out    dx,al
  642.  
  643.     mov    ax,18            ;wait a little while for the powerdown/up to take effect.
  644.     call    set_timeout
  645. send_test_power:
  646.     call    do_timeout
  647.     jne    send_test_power
  648.  
  649.     mov    cx,6            ;try six times
  650. send_test_again:
  651.     push    cx
  652.     mov    cx,60
  653.     mov    si,offset test_packet
  654.     call    send_pkt
  655.     pop    cx
  656.  
  657.     mov    ax,3
  658.     call    set_timeout
  659.  
  660.     loadport
  661.     setport    EN0_ISR
  662. send_test_wait:
  663.     in    al,dx
  664.     test    al,ENISR_TX or ENISR_TX_ERR    ;did it finish?
  665.     jne    send_test_done
  666.  
  667.     call    do_timeout
  668.     jnz    send_test_wait
  669.     jmp    short send_test_loop
  670.  
  671. send_test_done:
  672.     mov    al,0ffh            ;clear all interrupts.
  673.     out    dx,al
  674.  
  675.     loadport
  676.     setport    EN0_TSR
  677.     in    al,dx            ;get the transmit status
  678.     test    al,ENTSR_COLL16 or ENTSR_CRS or ENTSR_FU    ;any problems?
  679.     je    send_test_exit        ;no, it worked.
  680.  
  681. send_test_loop:
  682.     loop    send_test_again
  683.  
  684. ;it failed all six times.  Try again on a different interface.
  685.     cmp    thin_bit,0        ;did we already try internal xcvr?
  686.     jne    send_test_fail        ;yes, we can't send any packets!
  687.  
  688.     mov    thin_bit,ECNTRL_THIN
  689.     jmp    send_test
  690.  
  691. send_test_fail:
  692.     mov    dx,offset no_network_msg
  693.     mov    ah,9
  694.     int    21h
  695.  
  696. send_test_exit:
  697.     mov di,    offset int_no        ; May override interrupt channel
  698.     mov dx,    offset int_no_name    ; Message for it
  699.     call    print_number
  700.     mov di,    offset io_addr        ; May override I/O address
  701.     mov dx,    offset io_addr_name    ; Message for it
  702.     call    print_number
  703.     add    mem_base,16*SM_TSTART_PG
  704.     mov di,    offset mem_base        ; Read off the card.
  705.     mov dx,    offset mem_base_name    ; Message for it
  706.     call    print_number
  707.     sub    mem_base,16*SM_TSTART_PG
  708.     mov    dx,offset thin_msg
  709.     cmp    thin_bit,0        ; May override thick/thin cable flag
  710.     jne    print_parameters_1
  711.     mov    dx,offset thick_msg
  712. print_parameters_1:
  713.     mov    ah,9
  714.     int    21h
  715.     ret
  716.  
  717.     include memtest.asm
  718.  
  719. code    ends
  720.  
  721.     end
  722.