123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 |
- ( Low-level MAC actions JCB 13:23 08/24/10)
- ================================================================
- Initialization:
- mac-cold
- Packet reception and reading:
- mac-fullness
- mac-inoffset
- mac@
- macc@
- mac@n
- mac-consume
- Packet construction and transmission:
- mac-pkt-begin
- mac-pkt-,
- mac-pkt-c,
- mac-pkt-d,
- mac-pkt-2,
- mac-pkt-3,
- mac-pkt-,0
- mac-pkt-s,
- mac-pkt-src
- packetout-off
- mac!
- macc!
- mac-complete
- mac-checksum
- mac-send
- ================================================================
- ( NE2K JCB 10:23 11/08/10)
- : ne2sel
- false ether_cs_n ! ;
- : ne2unsel
- true ether_cs_n ! ;
- : ne2a ( a -- )
- pb_a ! ;
- : ne2rc@ ( a -- u ) \ NE2 byte reg read
- true ether_bhe_n !
- true ether_aen !
- ne2sel
- ne2a
- false pb_rd_n !
- \ pause144
- pb_d @ h# ff and
- true pb_rd_n !
- \ false ether_aen !
- \ ne2unsel
- ;
- : ne2rc! ( u a -- )
- \ over hex2 s" -> " type dup hex2 cr
- true ether_bhe_n !
- ne2sel
- ne2a
- pb_d !
- d# 0 ddir !
- false pb_wr_n !
- true pb_wr_n !
- \ ne2unsel
- d# 1 ddir !
- ;
- : ne2r! ( u a -- )
- over d# 8 rshift over 1+ ne2rc! ne2rc! ;
- : ne2r. \ dump registers
- d# 16 0do
- d# 1000 0do pause144 loop
- i hex2 space
- i ne2rc@ hex4 cr
- loop
- ;
- h# 00 constant ne2-CR
- h# 01 constant ne2-PSTART
- h# 01 constant ne2-PAR0
- h# 03 constant ne2-PAR2
- h# 05 constant ne2-PAR4
- h# 01 constant ne2-CR9346
- h# 02 constant ne2-PSTOP
- h# 03 constant ne2-BNRY
- h# 04 constant ne2-TSR
- h# 04 constant ne2-TPSR
- h# 05 constant ne2-TBCR0
- h# 05 constant ne2-NCR
- h# 06 constant ne2-CPR
- h# 06 constant ne2-TBCR1
- h# 07 constant ne2-ISR
- h# 07 constant ne2-CURR
- h# 08 constant ne2-RSAR0
- h# 08 constant ne2-CRDA0
- h# 09 constant ne2-RSAR1
- h# 09 constant ne2-CRDA1
- h# 0A constant ne2-RBCR0
- h# 0B constant ne2-RBCR1
- h# 0C constant ne2-RSR
- h# 0C constant ne2-RCR
- h# 0D constant ne2-TCR
- h# 0D constant ne2-CNTR0
- h# 0E constant ne2-DCR
- h# 0E constant ne2-CNTR1
- h# 0F constant ne2-IMR
- h# 0F constant ne2-CNTR2
- h# 10 constant ne2-RDMAPORT
- h# 14 constant ne2-MIIEEP
- h# 15 constant ne2-TR
- h# 17 constant ne2-GPOC
- h# 17 constant ne2-GPI
- h# 1F constant ne2-RSTPORT
- : ne2-page0 h# 22 ne2-CR ne2rc! ;
- : ne2-page1 h# 62 ne2-CR ne2rc! ;
- : ne2-clrisr \ clear the ISR
- h# ff ne2-ISR ne2rc! ;
- : ne2r.2
- s" Page 0" type cr
- ne2-page0
- ne2r.
- s" Page 1" type cr
- ne2-page1
- ne2r.
- ne2-page0 ;
- ( The MII interface JCB 12:47 11/09/10)
- h# 08 constant MII_EEP_MDO
- h# 04 constant MII_EEP_MDI
- h# 01 constant MII_EEP_MDC
- : eep-on ( u ) ne2-MIIEEP ne2rc@ or ne2-MIIEEP ne2rc! ;
- : eep-off ( u ) invert ne2-MIIEEP ne2rc@ and ne2-MIIEEP ne2rc! ;
- : miix ( u c -- u ) \ Send c bit data u
- tuck
- d# 16 swap - lshift
- swap
- 0do
- MII_EEP_MDO over 0< if
- eep-on
- else
- eep-off
- then
- MII_EEP_MDC eep-on \ clock up
- 2*
- ne2-MIIEEP ne2rc@ MII_EEP_MDI and if 1+ then
- MII_EEP_MDC eep-off \ clock down
- loop
- ;
- : phy@ ( a -- u )
- h# ffff d# 16 miix drop
- h# ffff d# 16 miix drop
- h# 0d0 d# 9 miix drop
- d# 5 miix drop
- h# 0 d# 1 miix drop
- h# 0 d# 16 miix
- ;
- : phy! ( u a -- )
- h# ffff d# 16 miix drop
- h# ffff d# 16 miix drop
- h# 0b0 d# 9 miix drop
- d# 5 miix drop
- h# 2 d# 2 miix drop
- d# 16 miix drop
- ;
- : phy.
- d# 32 0do
- i hex2 space i phy@ hex4 cr
- loop
- cr
- ;
- : phy-cold
- \ h# b000 d# 0 phy!
- h# 0800 d# 0 phy!
- s" PHY power down for 2.5s" type cr
- d# 2500000. sleepus
- \ h# 1200 d# 0 phy!
- h# 0000 d# 0 phy!
- exit
- sleep1
- sleep1
- sleep1
- sleep1
- sleep1
- sleep1
- \ h# 6030 d# 30 phy!
- phy. sleep1
- cr
- phy.
- ;
- : mac-cold ( ethaddr -- )
- false RESET_TRIGGER !
- sleep1
- true RESET_TRIGGER !
- sleep1
- true pb_rd_n !
- true pb_wr_n !
- true ether_cs_n !
- false ether_aen !
- true ether_bhe_n !
- d# 0 pb_a !
- d# 1 ddir !
- \ d# 4 0do ne2-RSTPORT ne2rc@ ne2-RSTPORT ne2rc! sleep1 loop
- phy-cold
- \ Wait for TR RST_B to go low and GPI link up
- s" TR GPI" type cr
- begin
- ne2-TR ne2rc@ hex2 d# 3 spaces
- ne2-GPI ne2rc@ hex2 d# 3 spaces
- sleep.1
- cr
- ne2-TR ne2rc@ d# 2 and 0=
- ne2-GPI ne2rc@ d# 1 and 0<> and
- until
- \ Wait for TR RST_B to go low
- \ begin
- \ sleep1
- \ ne2-TR ne2rc@ dup hex2 cr
- \ d# 2 and 0=
- \ until
- true if
- h# 21 ne2-CR ne2rc! \ Stop the NIC, abort DMA, page 0
- h# 00 ne2-DCR ne2rc! \ Selects byte-wide DMA transfers
- h# 00 ne2-RBCR0 ne2rc! \ Load data byte count for remote DMA
- h# 00 ne2-RBCR1 ne2rc!
- h# 20 ne2-RCR ne2rc! \ Temporarily set receiver to monitor mode
- h# 02 ne2-TCR ne2rc! \ Transmitter set to internal loopback mode
- \ Initialize Receive Buffer Ring: Boundary Pointer
- \ (BNDRY), Page Start (PSTART), and Page Stop
- \ (PSTOP)
- h# 46 ne2-PSTART ne2rc!
- h# 46 ne2-BNRY ne2rc!
- h# 80 ne2-PSTOP ne2rc!
- h# ff ne2-ISR ne2rc! \ Clear Interrupt Status Register (ISR) by writing 0FFh to it.
- h# 01 ne2-IMR ne2rc! \ Initialize interrupt mask
- h# 61 ne2-CR ne2rc! \ Stop the NIC, abort DMA, page 1
- h# 12 d# 1 ne2rc! \ Set Physical Address
- h# 34 d# 2 ne2rc!
- h# 56 d# 3 ne2rc!
- h# 77 d# 4 ne2rc!
- h# 77 d# 5 ne2rc!
- h# 77 d# 6 ne2rc!
- d# 16 d# 8 do \ Set multicast address
- h# 00 i ne2rc!
- loop
- h# 47 ne2-CURR ne2rc! \ Initialize CURRent pointer
- h# 22 ne2-CR ne2rc! \ Start the NIC, Abort DMA, page 0
- h# 10 ne2-GPOC ne2rc! \ Select media interface
- s" GPI = " type ne2-GPI ne2rc@ hex2 cr
- h# 00 ne2-TCR ne2rc! \ Transmitter full duplex
- h# 04 ne2-RCR ne2rc! \ Enable receiver and set accept broadcast
- else
- h# 21 ne2-CR ne2rc! \ Stop the NIC, abort DMA, page 0
- sleep.1
- h# 00 ne2-DCR ne2rc! \ Selects word-wide DMA transfers
- h# 00 ne2-RBCR0 ne2rc! \ Load data byte count for remote DMA
- h# 00 ne2-RBCR1 ne2rc!
- h# 20 ne2-RCR ne2rc! \ Temporarily set receiver to monitor mode
- h# 02 ne2-TCR ne2rc! \ Transmitter set to internal loopback mode
- h# 40 ne2-TPSR ne2rc! \ Set Tx start page
- \ Initialize Receive Buffer Ring: Boundary Pointer
- \ (BNDRY), Page Start (PSTART), and Page Stop
- \ (PSTOP)
- h# 46 ne2-PSTART ne2rc!
- h# 46 ne2-BNRY ne2rc!
- h# 80 ne2-PSTOP ne2rc!
- h# ff ne2-ISR ne2rc! \ Clear Interrupt Status Register (ISR) by writing 0FFh to it.
- h# 01 ne2-IMR ne2rc! \ Initialize interrupt mask
- h# 61 ne2-CR ne2rc! \ Stop the NIC, abort DMA, page 1
- sleep.1
- h# 12 d# 1 ne2rc! \ Set Physical Address
- h# 34 d# 2 ne2rc!
- h# 56 d# 3 ne2rc!
- h# 77 d# 4 ne2rc!
- h# 77 d# 5 ne2rc!
- h# 77 d# 6 ne2rc!
- d# 16 d# 8 do \ Set multicast address
- h# ff i ne2rc!
- loop
- h# 47 ne2-CURR ne2rc! \ Initialize CURRent pointer
- h# 20 ne2-CR ne2rc! \ DMA abort, page 0
- h# 10 ne2-GPOC ne2rc! \ Select media interface
- s" GPI = " type ne2-GPI ne2rc@ hex2 cr
- h# 1c ne2-RCR ne2rc! \ Enable receiver and set accept broadcast
- h# 00 ne2-TCR ne2rc! \ Transmitter full duplex
- h# ff ne2-ISR ne2rc! \ Clear Interrupt Status Register (ISR) by writing 0FFh to it.
- h# 22 ne2-CR ne2rc! \ Start the NIC, Abort DMA, page 0
- then
- ;
- : NicCompleteDma
- h# 22 ne2-CR ne2rc! \ Complete remote DMA
- ;
- : maca ( a -- ) \ set DMA address a
- dup d# 8 rshift ne2-RSAR1 ne2rc! ne2-RSAR0 ne2rc! ;
- : mac1b \ set DMA transfer for 1 byte
- h# 01 ne2-RBCR0 ne2rc!
- h# 00 ne2-RBCR1 ne2rc! ;
- : mac2b \ set DMA transfer for 2 bytes
- h# 02 ne2-RBCR0 ne2rc!
- h# 00 ne2-RBCR1 ne2rc! ;
- : macc@ ( a -- u )
- maca mac1b
- h# 0a ne2-CR ne2rc! \ running, DMA read
- ne2-RDMAPORT ne2rc@
- NicCompleteDma ;
- : macc! ( u a -- )
- maca mac1b
- h# 12 ne2-CR ne2rc! \ running, DMA write
- ne2-RDMAPORT ne2rc! ;
- : mac@ ( a -- u )
- maca mac2b
- h# 0a ne2-CR ne2rc! \ running, DMA read
- ne2-RDMAPORT ne2rc@ d# 8 lshift ne2-RDMAPORT ne2rc@ or
- NicCompleteDma ;
- : mac! ( u a -- )
- maca mac2b
- h# 12 ne2-CR ne2rc! \ running, DMA write
- dup d# 8 rshift ne2-RDMAPORT ne2rc! ne2-RDMAPORT ne2rc! ;
- : mac-dump ( a u -- )
- bounds
- begin
- 2dup u>
- while
- dup h# f and 0= if
- cr dup hex4 [char] : emit space
- then
- dup mac@ hex4 space
- 2+
- repeat 2drop cr ;
- variable currpkt
- : mac-inoffset ( u -- u ) \ compute offset into current incoming packet
- currpkt @ +
- dup 0< if
- h# 8000 -
- h# 4600 +
- then
- ;
- : mac@n ( n addr -- d0 .. dn )
- swap 0do dup mac@ swap 2+ loop drop ;
- ( words for constructing packet data JCB 07:01 08/20/10)
- variable writer
- : mac-pkt-begin h# 4000 writer ! ;
- : bump ( n -- ) writer +! ;
- : mac-pkt-c, ( n -- ) writer @ macc! d# 1 bump ;
- : mac-pkt-, ( n -- ) writer @ mac! d# 2 bump ;
- : mac-pkt-d, ( d -- ) mac-pkt-, mac-pkt-, ;
- : mac-pkt-2, ( n0 n1 -- ) swap mac-pkt-, mac-pkt-, ;
- : mac-pkt-3, rot mac-pkt-, mac-pkt-2, ;
- : mac-pkt-,0 ( n -- ) 0do d# 0 mac-pkt-, loop ;
- : mac-pkt-s, ( caddr u -- )
- 0do
- dup c@
- mac-pkt-c,
- 1+
- loop
- drop
- ;
- : mac-pkt-src ( n offset -- ) \ copy n words from incoming+offset
- swap 0do
- dup mac-inoffset mac@ mac-pkt-,
- 2+
- loop
- drop
- ;
- : mac-pkt-complete ( -- length ) \ set up size
- writer @ h# 4000 -
- \ h# 4000 over mac-dump
- dup ne2-TBCR0 ne2r! ;
- : mac-checksum ( addr nwords -- sum )
- d# 0 swap
- 0do
- over mac@ ( addr sum v )
- +1c
- swap 2+ swap
- loop
- nip
- invert
- ;
- : mac-snap
- s" CR PSTART PSTOP BNRY TSR NCR CPR ISR CRDA0 CRDA1 - - RSR CNTR0 CNTR1 CNTR2" type cr
- d# 16 0do
- i ne2rc@ hex2 d# 5 spaces
- loop
- ;
- : mac-fullness ( -- f )
- ether_irq @ if
- ne2-BNRY ne2rc@ 1+ ne2-CPR ne2rc@ <> dup if
- \ mac-snap
- ne2-BNRY ne2rc@ 1+ d# 8 lshift d# 4 + currpkt !
- \ s" currpkt=" type currpkt @ hex4 space
- \ currpkt @ d# 4 - macc@ hex2
- \ cr
- \ currpkt @ d# 4 - d# 16 mac-dump
- else
- ne2-clrisr
- then
- else
- false
- then
- ;
- : mac-consume ( -- ) \ finished with current packet, move on
- ne2-BNRY ne2rc@ 1+ d# 8 lshift 1+ macc@ \ next pkt
- 1- ne2-BNRY ne2rc!
- ;
- variable ne2cold
- : mac-send
- ne2cold @ 0= if
- h# 21 ne2-CR ne2rc!
- h# 22 ne2-CR ne2rc!
- true ne2cold !
- then
- h# 40 ne2-TPSR ne2rc!
- h# 26 ne2-CR ne2rc! \ START
- ;
- : packetout-off \ compute offset in output packet
- h# 4000 + ;
- : nicwork
- \ ISA mode
- \ begin
- s" TR= " type h# 15 ne2rc@ hex2 space
- s" ether_irq=" type ether_irq @ hex1 space
- s" ISR=" type ne2-ISR ne2rc@ hex2 space
- cr
- \ again
- false if
- h# 0000 ne2-RSAR0 ne2r!
- cr
- d# 16 0do
- ne2-RDMAPORT ne2rc@ hex2 space
- loop
- cr
- then
- s" CR PSTART PSTOP BNRY TSR NCR CPR ISR CRDA0 CRDA1 - - RSR CNTR0 CNTR1 CNTR2" type cr
- begin
- d# 16 0do
- i ne2rc@ hex2 d# 5 spaces
- loop
- ether_irq @ hex1
- cr
- sleep1
- ne2-CPR ne2rc@ h# 47 <>
- until
- \ h# 4700 h# 100 mac-dump
- \ cr
- \ h# 0947 h# 4700 mac!
- \ h# 4700 h# 100 mac-dump
- ;
|