;----------------------------------------------------------------------------
;             Includes for CNET CN40-BC PCMCIA network card
;----------------------------------------------------------------------------
;           Original code by Bruce Abbott (bhabbott@inhb.co.nz)
;
;    "Some PC oriented eight (8) bit cards may require you read
;     odd-byte I/O address registers at the corresponding even-byte
;     address plus 64K.  There is sufficient I/O address space
;     provided that exceeding I/O address space should not be a problem."
;
;            (extract from Autodoc 'cardresource.doc')
;
; The following information applies to the CNet CN40BC. Other cards could
; be quite different.
;
; Even byte addresses start at $a20000, and are mirrored every 1K.
; Odd byte addresses start at $a30000. By positioning the base I/O address
; 1K below the start of odd addressing, we can access both even and odd
; I/O space using a single CPU Address Register (with 16 bit offsets).
;

IObase      = $10000-$0400+$0300      ; offset to even nic registers
odd         = $10000-IOBase+$0300-1   ; offset to odd nic registers

;---------------------------------------------------------------------------
; The card will be initialised to present its I/O registers at the
; standard peecee I/O offset of $0300. This is acheived by writing a
; value of $20 to the card configuration register. Until this is done
; the I/O registers are invisible!

; NOTE: this information was obtained by disassembling the peecee driver...

Config_Register = $03f8 ; offset to card config register (in attribute memory)

IOat300      = $20      ; configure ISA bus I/O base to $0300

;IOat320    = $21
;IOat340    = $22     ; alternative I/O bases can be set...
;IOat360    = $23

;-----------------------------------------------------------------------
; The CNET CN40-BC uses a controller chip that is compatible with
; National Semiconducter's DS8390. This is the same chip that is
; used in NE1000 and NE2000 ISA bus ethernet cards.

; --------------------- DS8390 registers ------------------------
; registers in bank 0
nic_cr       =  0         ; command register        (r/w) in all banks
nic_pstart   =  1+odd     ; page start               (w)
nic_pstop    =  2         ; page stop                (w)
nic_clda0    =  nic_pstop ; current local dma addr   (r)
nic_bnry     =  3+odd     ; boundary pointer        (r/w)
nic_clda1    =  nic_bnry  ; current local dma addr   (r)
nic_tpsr     =  4         ; transmit page start      (w)
nic_tsr      =  nic_tpsr  ; transmit status register (r)
nic_tbcr0    =  5+odd     ; transmit byte count      (w)
nic_ncr      =  nic_tbcr0 ; number of collisions     (r)
nic_tbcr1    =  6         ; transmit byte count      (w)
nic_fifo     =  nic_tbcr1 ; fifo contents            (r)
nic_isr      =  7+odd     ; interrupt status        (r/w)
nic_rsar0    =  8         ; remote start address     (w)
nic_crda0    =  nic_rsar0 ; current remote DMA addr  (r)
nic_rsar1    =  9+odd     ; remote start address     (w)
nic_crda1    =  nic_rsar1 ; current remote DMA addr  (r)
nic_rbcr0    = 10         ; remote byte count        (w)
nic_rbcr1    = 11+odd     ; remote byte count        (w)
nic_rcr      = 12         ; receive configuration    (w)
nic_rsr      = nic_rcr    ; receive status           (r)
nic_tcr      = 13+odd     ; transmit configuration   (w)
nic_cntr0    = nic_tcr    ; tally counter            (r) frame align errors
nic_dcr      = 14         ; data configuration       (w)
nic_cntr1    = nic_dcr    ; tally counter            (r) crc errors
nic_imr      = 15+odd     ; interrupt mask           (w)
nic_cntr2    = nic_imr    ; tally counter            (r) missed packets

; bank 1 and 2 registers
nic_par0     =  1+odd  ; physical etheraddress   (r/w)
nic_par1     =  2      ; physical etheraddress   (r/w)
nic_par2     =  3+odd  ; physical etheraddress   (r/w)
nic_par3     =  4      ; physical etheraddress   (r/w)
nic_par4     =  5+odd  ; physical etheraddress   (r/w)
nic_par5     =  6      ; physical etheraddress   (r/w)
nic_curr     =  7+odd  ; current page            (r/w)
nic_mar0     =  8      ; multicast etheraddress  (r/w)
nic_mar1     =  9+odd  ; multicast etheraddress  (r/w)
nic_mar2     = 10      ; multicast etheraddress  (r/w)
nic_mar3     = 11+odd  ; multicast etheraddress  (r/w)
nic_mar4     = 12      ; multicast etheraddress  (r/w)
nic_mar5     = 13+odd  ; multicast etheraddress  (r/w)
nic_mar6     = 14      ; multicast etheraddress  (r/w)
nic_mar7     = 15+odd  ; multicast etheraddress  (r/w)

; ASIC registers in the NE2000 card
nic_data     = 16      ;  DMA port  (r/w)  16 bit
nic_rst      = 31+odd  ;  card reset (r=reset, w=not)

; DS8390 command bits
DSCM_STOP    = $01 ; Stop controller
DSCM_START   = $02 ; Start controller
DSCM_TRANS   = $04 ; Transmit packet
DSCM_RREAD   = $08 ; Remote read (read from nic memory to Amiga memory)
DSCM_RWRITE  = $10 ; Remote write (write from Amiga memory to nic memory)
DSCM_NODMA   = $20 ; No Remote DMA present
DSCM_PG0     = $00 ; Select register bank 0
DSCM_PG1     = $40 ; Select register bank 1
DSCM_PG2     = $80 ; Select register bank 2

; tansmit status register values
DSTS_PTX     = $01 ; Successful packet transmit
DSTS_COLL    = $02 ; Packet transmit w/ collision
DSTS_COLL16  = $04 ; Packet had >16 collisions & fail
DSTS_UND     = $20 ; FIFO Underrun on transmission

; interrupt status register values
DSIS_RX      = $01 ; Successful packet reception
DSIS_TX      = $02 ; Successful packet transmission
DSIS_RXE     = $04 ; Packet reception  w/error
DSIS_TXE     = $08 ; Packet transmission  w/error
DSIS_ROVRN   = $10 ; Receiver overrun in the ring
DSIS_CTRS    = $20 ; Diagnostic counters need attn
DSIS_RDC     = $40 ; Remote DMA Complete
DSIS_RESET   = $80 ; Reset Complete

; interrupt mask register values
DSIM_PRXE    = $01 ; Packet received enable
DSIM_PTXE    = $02 ; Packet transmitted enable
DSIM_RXEE    = $04 ; Receive error enable
DSIM_TXEE    = $08 ; Transmit error enable
DSIM_OVWE    = $10 ; Overwrite warning enable
DSIM_CNTE    = $20 ; Counter overflow enable
DSIM_RDCE    = $40 ; Remote DMA complete enable
DSIM_RESET   = $80 ; Reset Complete enable

; Bit numbers for interrupts (same for int status and mask)
DSIB_RX      = 0
DSIB_TX      = 1
DSIB_RXE     = 2
DSIB_TXE     = 3
DSIB_ROVRN   = 4
DSIB_CTRS    = 5
DSIB_RDC     = 6
DSIB_RESET   = 7

INTMASK = $ff&~(DSIM_RESET|DSIM_RDCE) ; all ints except DMA, Reset complete


; data configuration register values
DSDC_WTS     = $01 ; Word Transfer Select
DSDC_BOS     = $02 ; Byte Order Select
DSDC_LAS     = $04 ; Long Address Select
DSDC_BMS     = $08 ; Burst Mode Select
DSDC_AR      = $10 ; Autoinitialize Remote
DSDC_FT0     = $20 ; Fifo Threshold Select
DSDC_FT1     = $40 ; Fifo Threshold Select

; receive status register values
DSRS_RPC     = $01 ; Received Packet Complete

; transmit configuration register values
DSTC_CRC     = $01 ; Inhibit CRC
DSTC_LB0     = $02 ; Encoded Loopback Control
DSTC_LB1     = $04 ; Encoded Loopback Control
DSTC_ATD     = $08 ; Auto Transmit Disable
DSTC_OFST    = $10 ; Collision Offset Enable

; receive configuration register values
DSRC_SEP     = $01 ; Save error packets
DSRC_AR      = $02 ; Accept Runt packets
DSRC_AB      = $04 ; Accept Broadcast packets
DSRC_AM      = $08 ; Accept Multicast packets
DSRC_PRO     = $10 ; Promiscuous physical
DSRC_MON     = $20 ; Monitor mode


;-------------------------------------------------------------------------
; Packet receive header, 1 per each buffer page used in receive packet.
; The nic inserts this in front of the received packet.
;
 STRUCTURE prhdr,0
   BYTE  prhdr_status  ; is this a good packet, same as ds0_rsr
   BYTE  prhdr_nxtpg   ; next page of packet or next packet
   BYTE  prhdr_sz0     ; length (lower byte)
   BYTE  prhdr_sz1     ; length (upper byte)
  LABEL  prhdr_sizeof

;-------------------------------------------------------------------------
; nic has 16K of on-board RAM, from $4000 to $7fff (16 bit address)
;
; Internal DMA operations (ie. tx/rx) require the upper 8 bits of the
; address, as RAM is addressed in 256 byte pages.
;
; DMA to/from the host Amiga ("Remote DMA") requires a 16 bit word-aligned
; address
;

PKTSZ    =  $0600             ; space for biggest ethernet packet (6 pages)

TBUF     =  $4000             ; Starting location of Transmit Buffer
TBUF1    =  $4000+PKTSZ       ; Another Tx Buffer (for double-buffered tx)
RBUF     =  $4000+(PKTSZ*2)   ; Starting location of Receive Ring Buffer
RBUFEND  =  $8000             ; Ending location of Receive Ring Buffer

ETHER_MIN_LEN = 64            ; smallest acceptable packet size
ETHER_MAX_LEN = 1536          ; largest raw packet size

; ethernet packet data sizes (maximum)

ETHERPKT_SIZE = 1500
RAWPKT_SIZE   = 1514

; size of our packet buffer

PKTBUF_SIZE   = 1600   ; actually only need 1536 ?

; ethernet address bytesize

ETHER_ADDR_SIZE = 6

; structure of an ethernet packet

  STRUCTURE etherpacket,0
   STRUCT ether_dest,ETHER_ADDR_SIZE     ;  0 destination address
   STRUCT ether_src,ETHER_ADDR_SIZE      ;  6 originator  address
    WORD  ether_type                     ; 12 packet type
   LABEL  ether_data                     ; 14 user data (up to 1500 bytes)


; our extension to device data

  STRUCTURE device_data,lib_size
    BYTE  dd_flags                             ; various flags
    BYTE  dd_dcr                               ; copy of nic data config reg
    BYTE  dd_rcr                               ; copy of nic rx config reg
    BYTE  dd_imr                               ; copy of nic intmask register
    LONG  dd_overflows                         ; nic rx buffer overflow count
    LONG  dd_errors                            ; bad packets received
    LONG  dd_seglist                           ; device seglist
    APTR  dd_copytobuf                         ; caller's read routine
    APTR  dd_copyfrombuf                       ; caller's write routine
    APTR  dd_cardres                           ; card.resource base
    APTR  dd_cmm                               ; card memory map
   STRUCT dd_romstationaddress,ETHER_ADDR_SIZE ; hardware address from ROM
   STRUCT dd_stationaddress,ETHER_ADDR_SIZE    ; hardware station addr used
   STRUCT dd_readlist,mlh_size                 ; read requests
   STRUCT dd_writelist,mlh_size                ; write requests
   STRUCT dd_eventlist,mlh_size                ; events
   STRUCT dd_cardhandle,cah_sizeof             ; credit card handle
   STRUCT dd_cardstatus,is_size                ; card status interrupt
   STRUCT dd_cardremoved,is_size               ; card removed interrupt
   STRUCT dd_cardinserted,is_size              ; card inserted interrupt
   STRUCT dd_txint,is_size                     ; transmit software interrupt
   STRUCT dd_rxint,is_size                     ; receive software interrupt
    LABEL dd_extsize


; bit definitions for dd_flags

 BITDEF DD,CONFIGURED,4     ; unit is configured
 BITDEF DD,ONLINE,5         ; hardware is initialised
 BITDEF DD,TX,6             ; transmit buffer full

