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

  1. LED_TEST    equ    0
  2.  
  3. ;Kodiak packet driver code.
  4.  
  5. buffer_pointer    dw    ?        ;points to receive buffer.
  6. next_pointer    dw    ?        ;points to next receive packet.
  7.  
  8. ;
  9. ;    a temp buffer for the received header
  10. ;
  11. RCV_HDR_SIZE    equ    26        ; header @4 + 2 ids @6 + protocol @2+8,
  12. rcv_hdr        db    RCV_HDR_SIZE dup(0)
  13.  
  14.     public    int_no
  15. int_no        db    3,0,0,0        ;must be four bytes long for get_number.
  16. io_addr        dw    300h,0
  17.  
  18.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  19. driver_class    db    BLUEBOOK,IEEE8023,0    ;null terminated list of classes.
  20.   ifndef KOMBO
  21. driver_type    db    0        ;from the packet spec
  22. driver_name    db    "Raven ",10 dup(?)    ;name of the driver.
  23.   else
  24. driver_type    db    101        ;from the packet spec
  25. driver_name    db    "Kodiak Kombo",10 dup(?)    ;name of the driver.
  26.   endif
  27. driver_function    db    2
  28.  
  29. parameter_list    label    byte
  30.     db    1    ;major rev of packet driver
  31.     db    9    ;minor rev of packet driver
  32.     db    14    ;length of parameter list
  33.     db    EADDR_LEN    ;length of MAC-layer address
  34.     dw    GIANT    ;MTU, including MAC headers
  35.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  36.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  37.     dw    0    ;(# of successive xmits) - 1
  38. int_num    dw    0    ;Interrupt # to hook for post-EOI
  39.             ;processing, 0 == none,
  40.  
  41. ;-> current address
  42.     extrn    my_address: byte
  43.  
  44. received_ours    db    0
  45.  
  46.     public    rcv_modes
  47. rcv_modes    dw    7        ;number of receive modes in our table.
  48.         dw    0               ;There is no mode zero
  49.         dw    0
  50.         dw    rcv_mode_2
  51.         dw    rcv_mode_3
  52.         dw    0
  53.         dw    rcv_mode_5
  54.         dw    rcv_mode_6
  55.  
  56. cmd_reg        dw    ?        ;copy of the I/O port.
  57. config1_reg    dw    ?        ;copy of the I/O port.
  58. config2_reg    dw    REA_UPDATE_ON or CRC_ERROR_ENABLE or SHORT_FRAME_ENABLE or DRIBBLE_ERROR_ENABLE
  59.   ifdef KOMBO
  60. setup2_reg    db    MODESELECT or COAXDIS
  61.   endif
  62.  
  63. wait_fifo_empty:
  64. ;    Wait for FIFO to be EMPTY. Uses AX,CX,DX
  65.     push    ax
  66.     push    bx
  67.     push    cx
  68.     push    dx
  69.     mov    cx,FIFO_Count        ;wait a while for the fifo to get ready
  70.     loadport
  71.     setport    STAT
  72. wait_fifo_empty_1:
  73.     inw                ;read status register
  74.     test    ax,FIFO_EMPTY        ;check for FIFO EMPTY
  75.     jnz    wait_fifo_empty_2    ;jump when empty detected
  76.     loop    wait_fifo_empty_1    ;keep polling
  77. ;    call    FATAL_ERROR        ;never became EMPTY
  78. wait_fifo_empty_2:
  79.     pop    dx
  80.     pop    cx
  81.     pop    bx
  82.     pop    ax
  83.     ret
  84.  
  85.  
  86.     public bad_command_intercept
  87. bad_command_intercept:
  88. ;called with ah=command, unknown to the skeleton.
  89. ;exit with nc if okay, cy, dh=error if not.
  90.   ifdef KOMBO
  91.     cmp    ah,0e9h
  92.     jne    bad_command_intercept_1
  93.     jmp    autosense
  94. bad_command_intercept_1:
  95.   endif
  96.     mov    dh,BAD_COMMAND
  97.     stc
  98.     ret
  99.  
  100.     public    as_send_pkt
  101. ; The Asynchronous Transmit Packet routine.
  102. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  103. ;   interrupts possibly enabled.
  104. ; Exit with nc if ok, or else cy if error, dh set to error number.
  105. ;   es:di and interrupt enable flag preserved on exit.
  106. as_send_pkt:
  107.     ret
  108.  
  109.     public    drop_pkt
  110. ; Drop a packet from the queue.
  111. ; Enter with es:di -> iocb.
  112. drop_pkt:
  113.     assume    ds:nothing
  114.     ret
  115.  
  116.     public    xmit
  117. ; Process a transmit interrupt with the least possible latency to achieve
  118. ;   back-to-back packet transmissions.
  119. ; May only use ax and dx.
  120. xmit:
  121.     assume    ds:nothing
  122.     ret
  123.  
  124.  
  125. send_pkt_toobig:
  126.     mov    dh,NO_SPACE
  127.     stc
  128.     ret
  129.     public    send_pkt
  130. send_pkt:
  131. ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
  132. ;  (only if the high-performance bit is set in driver_function)
  133. ;enter with ds:si -> packet, cx = packet length.
  134. ;if we're a high-performance driver, es:di -> upcall.
  135. ;exit with nc if ok, or else cy if error, dh set to error number.
  136.     assume    ds:nothing
  137.  
  138.   if LED_TEST
  139.     mov    dx,378h
  140.     mov    al,4
  141.     out    dx,al
  142.   endif
  143.     cmp    cx,GIANT        ; Is this packet too large?
  144.     ja    send_pkt_toobig
  145.  
  146.     cmp    cx,RUNT        ; minimum length for Ether
  147.     jae    oklen
  148.     mov    cx,RUNT        ; make sure size at least RUNT
  149. oklen:
  150.     loadport
  151.     setport    STAT
  152.     mov    ax,1
  153.     call    set_timeout
  154. wait_send:
  155.     inw                ;read status register
  156.     test    ax,TX_ON        ;is the transmitter still on?
  157.     je    wait_send_done
  158.     call    do_timeout
  159.     jnz    wait_send
  160.     mov    dh,CANT_SEND        ;indicate an error.
  161.     stc
  162.     ret
  163. wait_send_done:
  164.     setport    CMD
  165.     mov    ax,cmd_reg
  166.     or    ax,ACK_TX_INT
  167.     outw
  168.  
  169.     push    cx
  170.     mov    ax,TX_AREA_BEG
  171.     call    set_fifo_write
  172.     pop    cx
  173.  
  174. ;The next packet pointer equals the current packet address plus
  175. ;the packet header length plus the packet data length. The
  176. ;address must be adjusted for buffer wrap around. Since the
  177. ;single transmit packet is always loaded at address zero in
  178. ;this version, wrap around can be ignored and the next packet
  179. ;pointer equals 0000 + 18 + data length. Data length refers to
  180. ;the adjusted packet length.
  181.  
  182.     loadport
  183.     setport    BWIND
  184.     mov    ax,cx            ;restore adjusted length
  185.     add    ax,4            ;base address + header length
  186.     xchg    ah,al            ;correct byte order
  187.     outw
  188.  
  189. ;The packet header consists of the Header Command and Packet
  190. ;Status bytes. The Packet Status byte is filled in by the EDLC,
  191. ;and so will be set to zero. The Header Command byte will be
  192. ;set to indicate that this packet is a data packet and is the
  193. ;last (only) packet in the chain. The XmitSuccessEnable bit in
  194. ;the Header Command byte is set so that a successful transmission
  195. ;can be identified simply by reading the TXInt bit in the EDLC
  196. ;status register. This strategy must be modified when transmit
  197. ;packets are chained.
  198.  
  199.     mov    ax,TX_COMMAND + 0*256    ;command, status bytes.
  200.     outw                ;write command, then status
  201.  
  202. ;write the contents of the packet.
  203.  
  204.     call    repouts
  205.  
  206. ; Next Frame header should be NULL.
  207.  
  208.     xor    ax,ax
  209.     outw
  210.     outw
  211.  
  212. ;Load Transmit Pointer Register.
  213.     setport    TXPTR
  214.     mov    ax,TX_AREA_BEG        ;start of transmit buffer
  215.     outw
  216.  
  217. ;initiate the transmission.
  218.  
  219.     setport    CMD
  220.     mov    ax,cmd_reg
  221.     or    ax, TX_ON            ;set bit
  222.     outw                    ;turn on the transmitter
  223.  
  224.   if LED_TEST
  225.     mov    dx,378h
  226.     mov    al,2
  227.     out    dx,al
  228.   endif
  229.     ret                    ; return to caller
  230.  
  231.  
  232.     public    set_address
  233. set_address:
  234. ;enter with ds:si -> Ethernet address, CX = length of address.
  235. ;exit with nc if okay, or cy, dh=error if any errors.
  236.     assume    ds:nothing
  237.     mov    dh,CANT_SET
  238.     stc
  239.     ret
  240.  
  241.  
  242. rcv_mode_2:
  243.     mov    bx,MATCH_ID
  244.     jmp    short set_rcv_mode
  245. rcv_mode_3:
  246.     mov    bx,MATCH_BRDCAST
  247.     jmp    short set_rcv_mode
  248. rcv_mode_5:
  249.     mov    bx,MATCH_MULTICAST
  250.     jmp    short set_rcv_mode
  251. rcv_mode_6:
  252.     mov    bx,MATCH_ALL
  253. set_rcv_mode:
  254.     mov    ax,config1_reg
  255.     and    ax,not 0c000h        ;clear the existing bits.
  256.     or    ax,bx
  257.     mov    config1_reg,ax
  258.     loadport
  259.     setport    CONFIG1
  260.     outw
  261.     ret
  262.  
  263.  
  264.     public    set_multicast_list
  265. set_multicast_list:
  266. ;enter with ds:si ->list of multicast addresses, ax = number of addresses,
  267. ;  cx = number of bytes.
  268. ;return nc if we set all of them, or cy,dh=error if we didn't.
  269.     mov    dh,NO_MULTICAST
  270.     stc
  271.     ret
  272.  
  273.  
  274.     public    terminate
  275. terminate:
  276.     loadport
  277.   ifdef KOMBO
  278.     setport    K2WR
  279.     mov    al,COAXDIS        ;PROM mode, no interrupt, COAX turned off.
  280.     out    dx,al
  281.     mov    ax,RESET_BIT or UTPDIS    ;reset the board, turn off UTP, enter 8-bit mode.
  282.   else
  283.     mov    ax,RESET_BIT        ;reset the board.
  284.   endif
  285.  
  286.     setport    CONFIG2
  287.     outw
  288.  
  289.     ret
  290.  
  291.     public    reset_interface
  292. reset_interface:
  293. ;reset the interface.
  294.     assume    ds:code
  295.     ret
  296.  
  297.  
  298. ;called when we want to determine what to do with a received packet.
  299. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  300.     extrn    recv_find: near
  301.  
  302. ;called after we have copied the packet into the buffer.
  303. ;enter with ds:si ->the packet, cx = length of the packet.
  304.     extrn    recv_copy: near
  305.  
  306. ;call this routine to schedule a subroutine that gets run after the
  307. ;recv_isr.  This is done by stuffing routine's address in place
  308. ;of the recv_isr iret's address.  This routine should push the flags when it
  309. ;is entered, and should jump to recv_exiting_exit to leave.
  310. ;enter with ax = address of routine to run.
  311.     extrn    schedule_exiting: near
  312.  
  313. ;recv_exiting jumps here to exit, after pushing the flags.
  314.     extrn    recv_exiting_exit: near
  315.  
  316.     extrn    count_in_err: near
  317.     extrn    count_out_err: near
  318.  
  319. ;this macro writes the given character to the given row and column on
  320. ;  an CGA.
  321. to_scrn    macro    r, c, ch
  322.     local    black,done
  323.   if 0
  324.     push    bx
  325.     push    es
  326.     mov    bx,0b800h
  327.     mov    es,bx
  328.     mov    bx,es:[r*160+c*2]
  329.     test    bh,1
  330.     jne    black
  331.     mov    bh,07h
  332.     jmp    short done
  333. black:
  334.     mov    bh,70h
  335. done:
  336.     mov    bl,ch
  337.     mov    es:[r*160+c*2],bx
  338.     pop    es
  339.     pop    bx
  340.   endif
  341.     endm
  342.  
  343.  
  344.     public    recv
  345. recv:
  346. ;called from the recv isr.  All registers have been saved, and ds=cs.
  347. ;Upon exit, the interrupt will be acknowledged.
  348.     assume    ds:code
  349.   if LED_TEST
  350.     mov    dx,378h
  351.     mov    al,1
  352.     out    dx,al
  353.   endif
  354.     to_scrn    23,74,'R'
  355.     loadport
  356.     setport    CMD
  357.     mov    ax,cmd_reg        ;get copy of command register
  358.     and    ax,not ENABLE_RX_INT
  359.     mov    cmd_reg,ax        ;keep it.
  360.     outw
  361.  
  362. recv_0:
  363.     loadport
  364.     setport    STAT
  365.     inw                ;get status in AX
  366.  
  367.     test    ax,RX_INT        ;did we get a packet?
  368.     jne    recv_1
  369.     jmp    recv_exit
  370. recv_1:
  371.     and    ax,RX_INT        ;acknowledge the interrupt.
  372.     outw
  373.  
  374.     mov    ax,buffer_pointer
  375.     call    set_fifo_read
  376.  
  377.     loadport
  378.     setport    BWIND            ;get the length of the frame.
  379.  
  380.     mov    cx,RCV_HDR_SIZE        ;read the header in.
  381.     mov    ax,cs
  382.     mov    es,ax
  383.     mov    di,offset rcv_hdr
  384.     call    repins
  385.  
  386.     mov    ah,rcv_hdr[RBUF_SIZE_HI]
  387.     mov    al,rcv_hdr[RBUF_SIZE_LO]
  388.     or    ax,ax            ;end of chain?
  389.     jne    recv_this_one        ;no.
  390.     to_scrn    23,76,'X'
  391.     jmp    recv_exit        ;yes.
  392. recv_this_one:
  393.     mov    next_pointer,ax        ;remember where the next one is.
  394.  
  395. ;did we receive our own broadcast?
  396.     mov    di,offset rcv_hdr+RBUF_NHDR+EADDR_LEN
  397.     mov    si,offset my_address
  398.     mov    cx,EADDR_LEN/2
  399.     repe    cmpsw
  400.     je    recv_our_own        ;yes, we did.
  401.  
  402.     mov    ax,next_pointer
  403.     sub    ax,buffer_pointer    ;compute the length of the frame
  404.     jae    recv_nowrap
  405.     add    ax,RX_AREA_SIZE        ;adjust for wrapping around.
  406. recv_nowrap:
  407.     sub    ax,RBUF_NHDR        ;subtract off the header.
  408.     mov    cx,ax
  409.  
  410.     mov    ah,rcv_hdr[RBUF_STAT]    ;get the status of the frame,
  411.     and    ah,RX_DONE or RX_ERROR    ;  check for errors.
  412.     cmp    ah,RX_DONE
  413.     je    recv_noerrs
  414.  
  415.     mov    ah,rcv_hdr[RBUF_STAT]    ;get the status of the frame,
  416.     call    report_rx_errs
  417.  
  418.     call    count_in_err
  419.  
  420.     to_scrn    23,72,'E'
  421.     jmp    recv_update
  422. recv_our_own:
  423.     to_scrn    23,79,'O'
  424.     inc    received_ours        ;remember that we received it.
  425.     jmp    short recv_update
  426.  
  427. recv_noerrs:
  428.     push    cx
  429.  
  430.     mov    ax,cs            ; Set ds = code
  431.     mov    ds,ax
  432.     mov    es,ax
  433.     assume    ds:code
  434.     mov    di,offset rcv_hdr+RBUF_NHDR+EADDR_LEN+EADDR_LEN
  435.  
  436.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  437.     mov    ax, es:[di]
  438.     xchg    ah, al
  439.     cmp     ax, 1500
  440.     ja    BlueBookPacket
  441.     inc    di            ;set di to 802.2 header
  442.     inc    di
  443.     mov    dl, IEEE8023
  444. BlueBookPacket:
  445.  
  446.     call    recv_find        ; See if type and size are wanted
  447.     pop    cx
  448.  
  449.     mov    ax,es            ; Did recv_find give us a null pointer?
  450.     or    ax,di            ; ..
  451.     je    recv_update_discard    ; If null, don't copy the data
  452.  
  453.     push    cx            ; We will want the count and pointer
  454.     push    es            ;  to hand to client after copying,
  455.     push    di            ;  so save them at this point
  456.  
  457.     push    cx            ;move the receive header in.
  458.     mov    si,offset rcv_hdr + RBUF_NHDR
  459.     mov    cx,(RCV_HDR_SIZE - RBUF_NHDR)/2
  460.     rep    movsw            ;move rest of packet
  461.     pop    cx
  462.  
  463.     sub    cx,RCV_HDR_SIZE - RBUF_NHDR ;subtract off what we've already copied.
  464.     loadport
  465.     setport    BWIND
  466.     call    repins            ;read the rest of the packet in.
  467.  
  468.     pop    si            ; Recover pointer to destination
  469.     pop    ds            ; Tell client it's his source
  470.     pop    cx            ; And it's this long
  471.     assume    ds:nothing
  472.     call    recv_copy        ; Give it to him
  473.     mov     ax, cs
  474.     mov     ds, ax
  475.     assume  ds: code
  476.  
  477.     jmp    short recv_update
  478. recv_update_discard:
  479.     to_scrn    23,73,'D'
  480. recv_update:
  481. ;Are there more interrupts ?
  482.     loadport
  483.     setport    STAT
  484.     in    ax,dx
  485.  
  486. ; Reenable receiver and interrupts.
  487.     test    ax,RX_ON        ;is the receiver still on?
  488.     jnz    DISR_30            ;yes, no need to turn it on.
  489.  
  490. ; Receive unit is off.  Reset the receive buffer pointer and continue.
  491.     setport    RXPTR
  492.     inw
  493.     mov    buffer_pointer,ax
  494. ;    add    PacketRxOverflowCount,1
  495. DISR_30:
  496.  
  497.     loadport            ;indicate that this packet is snarfed.
  498.     setport    RXAREA
  499.     mov    ax,next_pointer
  500.     mov    buffer_pointer,ax
  501.     mov    al,ah
  502.     out    dx,al
  503.  
  504.     to_scrn    23,75,'A'
  505.     jmp    recv_0            ;go back and get more packets.
  506.  
  507. recv_exit:
  508.     loadport
  509.     setport    CMD
  510.     mov    ax,cmd_reg        ;get copy of command register
  511.     or    ax,ENABLE_RX_INT
  512.     mov    cmd_reg,ax        ;keep it.
  513.     outw
  514.  
  515.     to_scrn    23,74,' '
  516.   if LED_TEST
  517.     mov    dx,378h
  518.     mov    al,2
  519.     out    dx,al
  520.   endif
  521.     ret
  522.  
  523.  
  524. report_rx_errs:
  525.     test    ah,8
  526.     je    report_rx_errs_1
  527.     to_scrn    23,71,'s'
  528. report_rx_errs_1:
  529.     test    ah,4
  530.     je    report_rx_errs_2
  531.     to_scrn    23,70,'d'
  532. report_rx_errs_2:
  533.     test    ah,2
  534.     je    report_rx_errs_3
  535.     to_scrn    23,69,'c'
  536. report_rx_errs_3:
  537.     test    ah,1
  538.     je    report_rx_errs_4
  539.     to_scrn    23,68,'o'
  540. report_rx_errs_4:
  541.     ret
  542.  
  543.  
  544. set_fifo_read:
  545.     call    set_fifo_write
  546.     loadport
  547.  
  548. ; Set FIFO to read.
  549.  
  550.     setport    CMD
  551.     mov    ax,cmd_reg        ;get copy of command register
  552.     and    ax,not FIFO_WRITE    ;put the FIFO into read mode.
  553.     or    ax,FIFO_READ
  554.     mov    cmd_reg,ax        ;keep it.
  555.     or    ax,ACK_BUF_INT
  556.     outw
  557.  
  558.     ;
  559.     ; Wait for FIFO to be ready.
  560.     ;
  561. sfr_30:
  562.     inw
  563.     test    ax,BUF_INT
  564.     jz    sfr_30
  565.  
  566.     ret
  567.  
  568.  
  569. set_fifo_write:
  570.     assume    ds:nothing
  571.  
  572.     push    ax
  573.     ;
  574.     ; Read in status.
  575.     ;
  576.     loadport
  577.     setport    STAT
  578.     inw
  579.  
  580.     ;
  581.     ; Is 8005 set for write ?
  582.     ;
  583.     test    ax,FIFO_DIR
  584.     jz    sfw_10
  585.  
  586.     ;
  587.     ; No, set FIFO for write.
  588.     ;
  589.     setport    CMD
  590.     mov    ax,cmd_reg
  591.     and    ax, not FIFO_READ    ;turn FIFO read off
  592.     or    ax, FIFO_WRITE        ;turn FIFO write on
  593.     mov    cmd_reg, ax        ;save modified command register
  594.     outw
  595.  
  596.     setport STAT
  597. sfw_00:
  598.     inw
  599.     test    ax,FIFO_DIR
  600.     jnz    sfw_00
  601. sfw_10:
  602.     ;
  603.     ; Wait for FIFO to be empty.
  604.     ;
  605.     test    ax,FIFO_EMPTY
  606.     jnz    sfw_x
  607.     inw
  608.     jmp    sfw_10
  609. sfw_x:
  610.  
  611.     setport    DMAADR
  612.     pop    ax                ;get load address from AX
  613.     outw                    ;adjust DMA pointer
  614.  
  615.     ret
  616.  
  617.     include    timeout.asm
  618.  
  619.     public    timer_isr
  620. timer_isr:
  621. ;if the first instruction is an iret, then the timer is not hooked
  622.     iret
  623.  
  624. ;any code after this will not be kept after initialization. Buffers
  625. ;used by the program, if any, are allocated from the memory between
  626. ;end_resident and end_free_mem.
  627.     public end_resident,end_free_mem
  628. end_resident    label    byte
  629. end_free_mem    label    byte
  630.  
  631.  
  632.     public    usage_msg
  633. usage_msg    db    "usage: kodiak [options] <packet_int_no> <hardware_irq> <io_addr>",CR,LF,'$'
  634.  
  635.     public    copyright_msg
  636.   ifdef KOMBO
  637. copyright_msg    db    "Packet driver for the Kodiak Kombo, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF
  638.   else
  639. copyright_msg    db    "Packet driver for the Kodiak Raven, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF
  640.   endif
  641.         db    "Portions Copyright Russell Nelson",CR,LF,'$'
  642.  
  643. this_board_msg    db    "This board is a Raven ",'$'
  644. bad_prom_msg    db    "Ethernet address PROM is invalid (check I/O address)",'$'
  645.   ifdef KOMBO
  646. memory_bad_msg    db    "Ethernet buffer memory bad",CR,LF,'$'
  647. int_bad_msg    db    "That interrupt number is not supported,",CR,LF
  648.         db    "Try one of 3,4,7,10,11,12 or 15",CR,LF,'$'
  649. testing_mem_msg    db    "Testing memory.",'$'
  650. xcvr_msgs    dw    tp_xcvr_msg,bnc_xcvr_msg,aui_xcvr_msg,no_xcvr_msg
  651. xcvr_ptr    dw    ?
  652. tp_xcvr_msg    db    "Using Twisted Pair (10BaseT) transceiver",CR,LF,'$'
  653. bnc_xcvr_msg    db    "Using BNC (10Base2) transceiver",CR,LF,'$'
  654. aui_xcvr_msg    db    "Using AUI transceiver",CR,LF,'$'
  655. no_xcvr_msg    db    "Not connected to any cable",CR,LF,'$'
  656.   endif
  657.  
  658. int_no_name    db    "Interrupt number ",'$'
  659. io_addr_name    db    "I/O port ",'$'
  660.  
  661.   ifdef KOMBO
  662. prom_contents    db    16 dup(?)
  663.   else
  664. prom_contents    db    32 dup(?)
  665.   endif
  666.  
  667. ; Sometimes a Kodiak-compatible adapter is used in an embedded system,
  668. ; and that embedded system doesn't have an Ethernet address PROM.  The
  669. ; Ethernet address is included on the packet driver's command line, and
  670. ; is stuffed into the device when the boot PROM is programmed.
  671. no_prom        db    0        ;<>0 if we don't have a prom.
  672.  
  673.   ifdef KOMBO
  674. irq_table    db    0
  675.         db    0
  676.         db    0
  677.         db    1 shl 1        ;3
  678.         db    2 shl 1        ;4
  679.         db    0
  680.         db    0
  681.         db    3 shl 1        ;7
  682.         db    0
  683.         db    0
  684.         db    4 shl 1        ;10
  685.         db    5 shl 1        ;11
  686.         db    6 shl 1        ;12
  687.         db    0
  688.         db    0
  689.         db    7 shl 1        ;15
  690.  
  691.   endif
  692.     extrn    set_recv_isr: near
  693.  
  694. ;enter with si -> argument string, di -> wword to store.
  695. ;if there is no number, don't change the number.
  696.     extrn    get_number: near
  697.  
  698. ;enter with dx -> argument string, di -> wword to print.
  699.     extrn    print_number: near
  700.  
  701. ;-> the Ethernet address of the card.
  702.     extrn    rom_address: byte
  703.  
  704. ;print the character in al.
  705.     extrn    chrout: near
  706.  
  707. ;print a crlf
  708.     extrn    crlf: near
  709.  
  710. ;enter with si -> argument string.
  711. ;skip spaces and tabs.  Exit with si -> first non-blank char.
  712.     extrn    skip_blanks: near
  713.  
  714.     public    parse_args
  715. parse_args:
  716. ;exit with nc if all went well, cy otherwise.
  717.     mov    di,offset int_no
  718.     call    get_number
  719.     mov    di,offset io_addr
  720.     call    get_number
  721.     call    skip_blanks
  722.     cmp    al,CR            ;does an Ethernet address follow?
  723.     je    parse_args_1        ;no.
  724.     inc    no_prom            ;we don't have an Ethernet PROM.
  725. ;enter with ds:si -> Ethernet address to parse, es:di -> place to put it.
  726.     movseg    es,ds
  727.     mov    di,offset rom_address
  728.     call    get_eaddr
  729. parse_args_1:
  730.     clc
  731.     ret
  732.  
  733.  
  734. board_name_list    dw    board_00, board_01, board_11, board_21
  735.         dw    board_02, board_03, board_unk
  736.  
  737. board_00    db    01h, "",0,47
  738. board_01    db    02h, "Quad",0,48
  739. board_11    db    03h, "UTP",0,48
  740. board_21        db      04h, "Quad UTP",0,48
  741. board_02    db    05h, "Media Adaptor",0,49
  742. board_03    db    06h, "286 FileServer",0,55
  743. board_unk    db    -1h, "Unknown",0,48    ;just a guess.
  744.  
  745. wait_27ms:
  746.     mov    ax,1            ;only have to wait 4us.
  747.     call    set_timeout
  748. wait_27ms_1:
  749.     call    do_timeout
  750.     jne    wait_27ms_1
  751.     ret
  752.  
  753.  
  754.     public    etopen
  755. etopen:
  756. ;initialize the driver.  Fill in rom_address with the assigned address of
  757. ;the board.
  758. ;
  759.     cmp    no_prom,0        ;do we even *have* a prom??
  760.     je    have_prom
  761.     jmp    adapter_ok        ;no, don't even *try* to read it.
  762. have_prom:
  763.  
  764.     assume    ds:code
  765.     loadport
  766.   ifdef KOMBO
  767.     setport    K2WR            ;select PROM mode (should already be selected).
  768.     xor    al,al
  769.     out    dx,al
  770.   else
  771.     setport    CONFIG2
  772.     mov    ax,RESET_BIT
  773.     outw
  774.  
  775.     call    wait_27ms
  776.  
  777.     setport    CMD            ; set the fifo direction.
  778.     mov    ax,FIFO_WRITE
  779.     outw
  780.  
  781.     setport    CONFIG1            ;select the address prom.
  782.     mov    ax,ADDR_PROM
  783.     outw
  784.  
  785.     setport    CONFIG2
  786.     mov    ax,config2_reg
  787.     or    ax,WATCH_TIME_DIS    ;kill the watchdog
  788.     outw
  789.   endif
  790.  
  791.     movseg    es,cs
  792.     mov    di,offset prom_contents
  793.   ifdef KOMBO
  794.     setport    0            ;on the Kombo, you change all the
  795.     mov    cx,16            ;  registers to read the PROM.
  796.   else
  797.     mov    cx,32            ;on the Ravens, you read the PROM
  798.     setport    BWIND            ;  through the window.
  799.   endif
  800.     xor    bl,bl            ;zero checksum
  801. etopen_4:
  802.     in    al, dx            ;the prom only has 8 bits...
  803.     add    bl,al            ;accumulate the checksum.
  804.     stosb
  805.   ifdef KOMBO
  806.     inc    dx            ;go to next register.
  807.   endif
  808.     loop    etopen_4
  809.   ifdef KOMBO
  810.     sub    bl,prom_contents[5]    ;the following are not included in the
  811.     sub    bl,prom_contents[6]    ;  checksum, contrary to the spec.
  812.     sub    bl,prom_contents[7]
  813.     sub    bl,prom_contents[14]
  814.     sub    bl,prom_contents[15]
  815.   endif
  816.  
  817.     cmp    bl,0            ;must always be zero
  818.     je    etopen_2        ;go if it is.
  819. etopen_3:
  820.     mov    dx,offset bad_prom_msg
  821.     stc
  822.     ret
  823. etopen_2:
  824.  
  825.   ifdef KOMBO
  826.  
  827.     mov    si,offset prom_contents[8]
  828.     mov    di,offset rom_address    ;set the rom address
  829.     repmov    EADDR_LEN
  830.  
  831.     mov    al,int_no
  832.     mov    bl,al
  833.     and    bx,0fh
  834.     mov    al,irq_table[bx]
  835.     or    al,al
  836.     jne    int_no_ok
  837.     mov    dx,offset int_bad_msg
  838.     stc
  839.     ret
  840. int_no_ok:
  841.     or    setup2_reg,al
  842.  
  843.     loadport
  844.     setport    K2WR            ;select RUN mode, interrupt, and not coax.
  845.     mov    al,setup2_reg
  846.     out    dx,al
  847.  
  848.     setport    CONFIG2
  849.     mov    ax,RESET_BIT
  850.     outw
  851.  
  852.     call    wait_27ms
  853.  
  854.     mov    ax,config2_reg
  855.     or    ax,SELECT_16_BIT    ;16-bit driver.
  856.     outw
  857.  
  858. ;set the initial fifo direction, and enable receive interrupts.
  859.     setport    CMD
  860.     mov    ax,FIFO_WRITE
  861.     mov    cmd_reg,ax        ;keep a copy.
  862.     outw
  863.  
  864.     mov    dx,offset testing_mem_msg
  865.     mov    ah,9
  866.     int    21h
  867.  
  868. adapter_verify:
  869.     mov    al,'.'
  870.     call    chrout
  871.     mov    bx,0aa55h        ;aa55
  872.     xor    si,si
  873.     call    test_memory
  874.     jc    adapter_verify_fail
  875.  
  876.     mov    al,'.'
  877.     call    chrout
  878.  
  879.     mov    bx,055aah        ;55aa
  880.     xor    si,si
  881.     call    test_memory
  882.     jc    adapter_verify_fail
  883.  
  884.     mov    al,'.'
  885.     call    chrout
  886.  
  887.     mov    bx,0            ;incrementing
  888.     mov    si,1
  889.     call    test_memory
  890.     jc    adapter_verify_fail
  891.     jmp    short adapter_ok
  892.  
  893. adapter_verify_fail:
  894.     mov    al,setup2_reg        ;did we already try compatibility?
  895.     test    al,COMPATIBILITY
  896.     jnz    adapter_verify_bad    ;yes, it's bad memory
  897.     or    al,COMPATIBILITY    ;no, try compatibility.
  898.     mov    setup2_reg,al
  899.  
  900.     loadport            ;output it,
  901.     setport    K2WR
  902.     out    dx,al
  903.     jmp    adapter_verify        ;and try again.
  904.  
  905. adapter_verify_bad:
  906.     mov    dx,offset memory_bad_msg
  907.     stc
  908.     ret
  909.   else
  910. ;ensure that the prom has valid contents.
  911.     cmp    prom_contents,0aah    ;first byte must be 0aah.
  912.     jne    etopen_3
  913.     cmp    prom_contents[31],055h    ;last byte must be 055h.
  914.     jne    etopen_3
  915.  
  916.     mov    al,prom_contents[4]    ;get the name of this board.
  917.     mov    bx,offset board_name_list
  918. check_board_name:
  919.     mov    si,[bx]            ;get a pointer to a string.
  920.     add    bx,2
  921.     cmp    byte ptr [si],-1    ;is this the end?
  922.     je    check_board_found
  923.     cmp    al,[si]            ;is this the right one?
  924.     jne    check_board_name
  925. check_board_found:
  926.     inc    si            ;skip the board revision number.
  927.  
  928.     mov    dx,offset this_board_msg
  929.     mov    ah,9
  930.     int    21h
  931.  
  932.     movseg    es,ds            ;copy the driver name to where we need it.
  933.     mov    di,offset driver_name+6    ;skip the "Raven " part...
  934. check_board_copy:
  935.     lodsb
  936.     stosb
  937.     or    al,al
  938.     je    check_board_done_print
  939.     call    chrout            ;print the character.
  940.     jmp    check_board_copy
  941. check_board_done_print:
  942.     lodsb                ;copy the driver type number over
  943.     mov    driver_type,al
  944.  
  945.     mov    rom_address[0],000h    ;Put in Kodiak's high three bytes.
  946.     mov    rom_address[1],080h
  947.     mov    rom_address[2],01bh
  948.     mov    ax,word ptr prom_contents[1] ;copy over the low three bytes.
  949.     mov    word ptr rom_address[3],ax
  950.     mov    al,prom_contents[3]
  951.     mov    rom_address[5],al
  952.   endif
  953.  
  954. adapter_ok:
  955.     call    crlf
  956.  
  957. ;reset again.
  958.     loadport
  959.     setport    CONFIG2
  960.     mov    ax,RESET_BIT
  961.     outw
  962.  
  963.     call    wait_27ms
  964.  
  965. ;set the packet we will accept.
  966.     mov    ax,config2_reg
  967.   ifdef KOMBO
  968.     or    ax,SELECT_16_BIT    ;16-bit driver.
  969.     or    ax,UTPDIS        ;turn off UTP driver.
  970.     mov    config2_reg,ax
  971.   endif
  972.     outw
  973.  
  974. ;re-initialize the command register.
  975.     setport    CMD
  976.   ifdef KOMBO
  977.     mov    ax,cmd_reg
  978.   else
  979.     mov    ax,FIFO_WRITE or ENABLE_RX_INT ;start fifo in write, enable ints
  980.     mov    cmd_reg,ax        ;keep a copy.
  981.   endif
  982.     outw
  983.  
  984. ;Copy the station address from the table to station number zero.
  985. ;We only use station number zero.
  986.     setport    CONFIG1
  987.     xor    al, al            ;select station number zero
  988.     out    dx, al
  989.  
  990.     setport    BWIND
  991.     mov    si,offset rom_address    ;The address we just got from the rom.
  992.     mov    cx,EADDR_LEN
  993. set_address_1:
  994.     lodsb                ;Station address requires byte writes.
  995.     out    dx,al
  996.     loop    set_address_1
  997.  
  998. ;Set the Transmit End Area register.
  999.     setport    CONFIG1
  1000.     mov    al,TEA_REG        ;select transmit end area reg
  1001.     out    dx,al
  1002.     setport    BWIND            ;point to the window.
  1003.     mov    al,TX_AREA_END shr 8    ;start of receive buffer
  1004.     out    dx,al
  1005.  
  1006. ;select station zero address (only), match our address and broadcasts,
  1007. ;and select buffer memory at the BWIND port.
  1008.     setport    CONFIG1
  1009.     mov    ax,MATCH_BRDCAST or ID_0_ENABLE or BUFFER_MEMORY
  1010.     outw
  1011.     mov    config1_reg,ax        ;keep a copy.
  1012.  
  1013. ;Load Receive End Area Register.
  1014.     setport    RXAREA
  1015.     mov    al,RX_AREA_END shr 8        ;REA pointer
  1016.     out    dx,al            ;only output the low 7 bits.
  1017.  
  1018. ;Load Receive Pointer Register.
  1019.     setport    RXPTR
  1020.     mov    ax,RX_AREA_BEG        ;start of receive buffer
  1021.     outw
  1022.     mov    buffer_pointer,ax    ;init packet buffer pointer
  1023.  
  1024. ;Turn receiver on.
  1025.     setport    CMD
  1026.     mov    ax,cmd_reg
  1027.   ifdef KOMBO
  1028.     or    ax,RX_ON or ENABLE_RX_INT
  1029.   else
  1030.     or    ax,RX_ON        ;set bit
  1031.   endif
  1032.     mov    cmd_reg,ax        ;remember it.
  1033.     outw
  1034.  
  1035.     mov    al, int_no        ; Get board's interrupt vector
  1036.     add    al, 8
  1037.     cmp    al, 8+8            ; Is it a slave 8259 interrupt?
  1038.     jb    set_int_num        ; No.
  1039.     add    al, 70h - 8 - 8        ; Map it to the real interrupt.
  1040. set_int_num:
  1041.     xor    ah, ah            ; Clear high byte
  1042.     mov    int_num, ax        ; Set parameter_list int num.
  1043.  
  1044.   ifdef KOMBO
  1045.     movseg    es,ds
  1046.     mov    si,offset rom_address
  1047.     mov    di,offset my_address
  1048.     repmov    EADDR_LEN
  1049.  
  1050.     call    autosense_1
  1051.     and    bl,3
  1052.     xor    bh,bh
  1053.     shl    bx,1
  1054.     mov    dx,xcvr_msgs[bx]
  1055.     mov    xcvr_ptr,dx
  1056.  
  1057.   endif
  1058.     call    set_recv_isr
  1059.  
  1060.     clc
  1061.     ret
  1062.  
  1063.  
  1064.     public    print_parameters
  1065. print_parameters:
  1066. ;echo our command-line parameters
  1067.     mov    di,offset int_no
  1068.     mov    dx,offset int_no_name
  1069.     call    print_number
  1070.     mov    di,offset io_addr
  1071.     mov    dx,offset io_addr_name
  1072.     call    print_number
  1073.   ifdef KOMBO
  1074.     mov    dx,xcvr_ptr
  1075.     mov    ah,9
  1076.     int    21h
  1077.   endif
  1078.     ret
  1079.  
  1080. test_memory:
  1081. ;enter with bx = pattern to write, si = increment for pattern.
  1082.  
  1083. ;set TEA to the end of memory.
  1084.     loadport
  1085.     setport    CONFIG1
  1086.     mov    al,TEA_REG        ;select transmit end area reg
  1087.     out    dx,al
  1088.     setport    BWIND
  1089.     mov    al,0ffh            ;start of receive buffer
  1090.     out    dx,al
  1091.  
  1092. ;write our pattern.
  1093.     xor    ax, ax            ;start at zero.
  1094.     call    set_fifo_write
  1095.     loadport
  1096.     setport    CONFIG1            ;select the buffer memory.
  1097.     mov    ax,BUFFER_MEMORY
  1098.     outw
  1099.  
  1100.     setport    BWIND
  1101.     mov    ax,bx            ;get the pattern word
  1102.     mov    cx,8000h        ;number of words to write
  1103. test_memory_write:
  1104.     outw                ;write our pattern.
  1105.     add    ax,si            ;increment the pattern.
  1106.     loop    test_memory_write
  1107.  
  1108.     xor    ax,ax            ;start at zero again.
  1109.     call    set_fifo_read
  1110.     loadport
  1111.     setport    CONFIG1
  1112.     mov    ax,BUFFER_MEMORY    ;select buffer memory
  1113.     outw                ; execute command
  1114.     setport    BWIND
  1115.     mov    cx,8000h        ;number of words to read
  1116.  
  1117. test_memory_read:
  1118.     inw
  1119.     cmp    ax,bx            ;does it compare correctly?
  1120.     jne    test_memory_fail    ;no, quit.
  1121.     add    bx,si            ;increment the pattern.
  1122.     loop    test_memory_read    ; Otherwise, continue
  1123.     clc
  1124.     ret
  1125.  
  1126. test_memory_fail:
  1127.     stc
  1128.     ret
  1129.  
  1130.     extrn    get_hex: near
  1131.     include    getea.asm
  1132.  
  1133.