ENC624j6net
- updated source to match the JED from 22Dec2017 - now interrupt support is enabled in driver - ping times improved considerably
This commit is contained in:
@@ -5,7 +5,13 @@ SANA-II Driver for Matze/Scrat ZII IDE LAN CP card
|
|||||||
author: Henryk Richter <henryk.richter@gmx.net>
|
author: Henryk Richter <henryk.richter@gmx.net>
|
||||||
|
|
||||||
|
|
||||||
|
Release Notes:
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- goes along with 21 December 2017 CPLD build, where interrupts are extended
|
||||||
|
- older CPLD builds will lock up Amiga at first interrupt
|
||||||
|
- provisions for swapped address lines 12/13 are in the code
|
||||||
|
- board requires Int6 to be soldered (NOT Int2)
|
||||||
|
|
||||||
Installation:
|
Installation:
|
||||||
-------------
|
-------------
|
||||||
@@ -26,6 +32,8 @@ as argument will then activate the driver for RoadShow.
|
|||||||
Technical notes:
|
Technical notes:
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
(IMPORTANT: not _yet_ true for current CPLD build)
|
||||||
|
|
||||||
Matze's card does selective byte swapping for different areas of the chip within
|
Matze's card does selective byte swapping for different areas of the chip within
|
||||||
the CPLD. This step enables Big Endian reads/writes to the hardware registers. Since
|
the CPLD. This step enables Big Endian reads/writes to the hardware registers. Since
|
||||||
the SRAM would be byte-swapped as well, the latest (WIP) version of the CPLD presents
|
the SRAM would be byte-swapped as well, the latest (WIP) version of the CPLD presents
|
||||||
|
|||||||
Binary file not shown.
@@ -34,6 +34,7 @@ DEBUG EQU 1
|
|||||||
_OPT_BUFFER_SWAP EQU 1 ;perform byte swap on buffer ops (1) or assume native endian (0)
|
_OPT_BUFFER_SWAP EQU 1 ;perform byte swap on buffer ops (1) or assume native endian (0)
|
||||||
_OPT_REG_SWAP EQU 0 ;perform byte swap on register ops (1) or assume native endian (0)
|
_OPT_REG_SWAP EQU 0 ;perform byte swap on register ops (1) or assume native endian (0)
|
||||||
_OPT_ADR_QUIRK EQU 1 ;address lines 12/13 are swapped (1) or linear addressing (0)
|
_OPT_ADR_QUIRK EQU 1 ;address lines 12/13 are swapped (1) or linear addressing (0)
|
||||||
|
_OPT_FLOWCONTROL EQU 1 ;perform flow control on RX (1) or not (0)
|
||||||
|
|
||||||
;
|
;
|
||||||
; options for buffer memory configuration, please reserve some space for private variables
|
; options for buffer memory configuration, please reserve some space for private variables
|
||||||
@@ -56,12 +57,15 @@ PNextPacket EQU PSTART_INIT ;2 Bytes - private "next packet" pointer for RX
|
|||||||
PNextTX EQU PSTART_INIT+2 ;2 Bytes - private "next packet" pointer for TX (init as 0)
|
PNextTX EQU PSTART_INIT+2 ;2 Bytes - private "next packet" pointer for TX (init as 0)
|
||||||
PSigBit EQU PSTART_INIT+4 ;2 Bytes interrupt bit
|
PSigBit EQU PSTART_INIT+4 ;2 Bytes interrupt bit
|
||||||
PSigTask EQU PSTART_INIT+6 ;4 Bytes signaled task
|
PSigTask EQU PSTART_INIT+6 ;4 Bytes signaled task
|
||||||
Punused EQU PSTART_INIT+10 ;
|
PLinkChange EQU PSTART_INIT+10 ;2 Bytes Link Change (Bit0 used right now)
|
||||||
|
Punused EQU PSTART_INIT+12 ;
|
||||||
|
|
||||||
;------------- TX: double buffering --------------------------------
|
;------------- TX: double buffering --------------------------------
|
||||||
PSwapTX EQU $600 ;swap between two TX buffers (one active, one activated after last TX done)
|
PSwapTX EQU $600 ;swap between two TX buffers (one active, one activated after last TX done)
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
ifne DEBUG
|
ifne DEBUG
|
||||||
;
|
;
|
||||||
; these are only for the debug code
|
; these are only for the debug code
|
||||||
@@ -715,6 +719,41 @@ CLOCK_DEF_SET EQU CLOCK_33_SET
|
|||||||
;\1 register offset (without CLEAR offset)
|
;\1 register offset (without CLEAR offset)
|
||||||
;\2 address register of board I/O base
|
;\2 address register of board I/O base
|
||||||
;\3 register with clear mask
|
;\3 register with clear mask
|
||||||
|
ifne _OPT_REG_SWAP
|
||||||
|
|
||||||
|
CLRREG macro
|
||||||
|
rol.w #8,\3
|
||||||
|
move.w \3,\1+CLR_OFFSET(\2)
|
||||||
|
rol.w #8,\3
|
||||||
|
endm
|
||||||
|
;\1 register offset (without SET offset)
|
||||||
|
;\2 address register of board I/O base
|
||||||
|
;\3 register with set mask
|
||||||
|
SETREG macro
|
||||||
|
rol.w #8,\3
|
||||||
|
move.w \3,\1+SET_OFFSET(\2)
|
||||||
|
rol.w #8,\3
|
||||||
|
endm
|
||||||
|
;\1 register offset (e.g. ESTAT)
|
||||||
|
;\2 address register of board I/O base (e.g. a0)
|
||||||
|
;\3 destination register to be written (e.g. d0)
|
||||||
|
READREG macro
|
||||||
|
rol.w #8,\3
|
||||||
|
move.w \1(\2),\3
|
||||||
|
rol.w #8,\3
|
||||||
|
endm
|
||||||
|
;\1 register offset (e.g. ESTAT)
|
||||||
|
;\2 address register of board I/O base (e.g. a0)
|
||||||
|
;\3 soure register copied to HW register (e.g. d0)
|
||||||
|
WRITEREG macro
|
||||||
|
rol.w #8,\3
|
||||||
|
move.w \3,\1(\2)
|
||||||
|
rol.w #8,\3
|
||||||
|
endm
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
CLRREG macro
|
CLRREG macro
|
||||||
move.w \3,\1+CLR_OFFSET(\2)
|
move.w \3,\1+CLR_OFFSET(\2)
|
||||||
endm
|
endm
|
||||||
@@ -737,6 +776,8 @@ WRITEREG macro
|
|||||||
move.w \3,\1(\2)
|
move.w \3,\1(\2)
|
||||||
endm
|
endm
|
||||||
|
|
||||||
|
endc
|
||||||
|
|
||||||
;read with address shuffling or direct from SRAM (affects $2000-$5000)
|
;read with address shuffling or direct from SRAM (affects $2000-$5000)
|
||||||
ifne _OPT_ADR_QUIRK
|
ifne _OPT_ADR_QUIRK
|
||||||
;\1 = address register
|
;\1 = address register
|
||||||
@@ -775,6 +816,10 @@ WRAPINDEX macro
|
|||||||
; | Test/Debug code |
|
; | Test/Debug code |
|
||||||
; | |
|
; | |
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; DEBUG CODE: main function that checks the board, sends a couple of ICMP frames and
|
||||||
|
; receives frames until LMOUSE pressed
|
||||||
|
;
|
||||||
ifne DEBUG
|
ifne DEBUG
|
||||||
ExecBase EQU 4 ; Exec.Base()
|
ExecBase EQU 4 ; Exec.Base()
|
||||||
OpenLibrary EQU -552 ; D0:Base=OpenLibrary(A1:libName,D0:version)
|
OpenLibrary EQU -552 ; D0:Base=OpenLibrary(A1:libName,D0:version)
|
||||||
@@ -876,9 +921,9 @@ opendos:
|
|||||||
beq .noframe ;nothing received
|
beq .noframe ;nothing received
|
||||||
|
|
||||||
;debug: disable recv
|
;debug: disable recv
|
||||||
;move.l _boardbase(pc),a0
|
move.l _boardbase(pc),a0
|
||||||
;moveq #ECON1_RXEN,d0
|
moveq #ECON1_RXEN,d0
|
||||||
;CLRREG ECON1,a0,d0
|
CLRREG ECON1,a0,d0
|
||||||
|
|
||||||
move.l _boardbase(pc),a0
|
move.l _boardbase(pc),a0
|
||||||
lea readframe,a1
|
lea readframe,a1
|
||||||
@@ -1152,7 +1197,7 @@ _enc624j6l_Init:
|
|||||||
|
|
||||||
bsr _enc624j6l_CheckBoard ;preserves all regs
|
bsr _enc624j6l_CheckBoard ;preserves all regs
|
||||||
tst.l d0 ;board reset unsuccessful ?
|
tst.l d0 ;board reset unsuccessful ?
|
||||||
ble.s .err ;-> bail out
|
ble.w .err ;-> bail out
|
||||||
.goon:
|
.goon:
|
||||||
;-------------- configure clockout ----------------------
|
;-------------- configure clockout ----------------------
|
||||||
moveq #ECON1_RXEN,d0 ;no RX, my dear (yet)
|
moveq #ECON1_RXEN,d0 ;no RX, my dear (yet)
|
||||||
@@ -1180,6 +1225,19 @@ _enc624j6l_Init:
|
|||||||
move #RXSTOP_INIT&$fffe,d0
|
move #RXSTOP_INIT&$fffe,d0
|
||||||
WRITEREG ERXTAIL,a0,d0 ;tail pointer in buffer = rx-2, wraparound
|
WRITEREG ERXTAIL,a0,d0 ;tail pointer in buffer = rx-2, wraparound
|
||||||
|
|
||||||
|
ifne _OPT_FLOWCONTROL
|
||||||
|
move #(128<<8)|(32),d0 ;128*96=12288 high water mark, 32*96=3072 low water mark
|
||||||
|
WRITEREG ERXWM,a0,d0
|
||||||
|
moveq #MACON1_RXPAUS,d0
|
||||||
|
SETREG MACON1,a0,d0
|
||||||
|
move #ECON2_AUTOFC,d0
|
||||||
|
SETREG ECON2,a0,d0
|
||||||
|
else
|
||||||
|
move #ECON2_AUTOFC,d0
|
||||||
|
CLRREG ECON2,a0,d0 ;disable automatic flow control
|
||||||
|
endc
|
||||||
|
|
||||||
|
|
||||||
;--------------- TX configuration -----------------------
|
;--------------- TX configuration -----------------------
|
||||||
; no padding, no proprietary header
|
; no padding, no proprietary header
|
||||||
move #MACON2_PADCFG2|MACON2_PADCFG1|MACON2_PADCFG0|MACON2_PHDREN,d0
|
move #MACON2_PADCFG2|MACON2_PADCFG1|MACON2_PADCFG0|MACON2_PHDREN,d0
|
||||||
@@ -1256,6 +1314,9 @@ _enc624j6l_SetOnline:
|
|||||||
SETREG ECON1,a0,d0
|
SETREG ECON1,a0,d0
|
||||||
|
|
||||||
moveq #1,d0
|
moveq #1,d0
|
||||||
|
WRITEREG PLinkChange,a0,d0
|
||||||
|
|
||||||
|
;moveq #1,d0 ;already set, see above
|
||||||
.err
|
.err
|
||||||
rts
|
rts
|
||||||
|
|
||||||
@@ -1321,8 +1382,13 @@ _enc624j6l_EnableInterrupt:
|
|||||||
WRITEREG PSigTask,a0,d0 ;upper two bytes
|
WRITEREG PSigTask,a0,d0 ;upper two bytes
|
||||||
|
|
||||||
; enable interrupt for incoming packet
|
; enable interrupt for incoming packet
|
||||||
move #EIR_PKTIF,d0
|
moveq #-1,d0 ;magic trick: the board enables Interrupts
|
||||||
SETREG EIR,a0,d0
|
lea $4000(a0),a0
|
||||||
|
move.w d0,($4000,a0)
|
||||||
|
lea -$4000(a0),a0
|
||||||
|
|
||||||
|
move #EIE_PKTIE|EIE_INTIE,d0
|
||||||
|
SETREG EIE,a0,d0
|
||||||
|
|
||||||
moveq #1,d0
|
moveq #1,d0
|
||||||
.rts
|
.rts
|
||||||
@@ -1337,9 +1403,6 @@ _enc624j6l_EnableInterrupt:
|
|||||||
; Disable Hardware Interrupt
|
; Disable Hardware Interrupt
|
||||||
;
|
;
|
||||||
; In: A0 - Board base address
|
; In: A0 - Board base address
|
||||||
; A1 - Signal Task - task to receive signal
|
|
||||||
; D0 - Signal Bit - the interrupt will send a signal to the given task (BIT, NOT SIGNAL MASK!!)
|
|
||||||
; D1 - Interrupt mask (pass 0 for now)
|
|
||||||
;
|
;
|
||||||
; Out:
|
; Out:
|
||||||
; D0 <= 0 - failure
|
; D0 <= 0 - failure
|
||||||
@@ -1351,9 +1414,16 @@ _enc624j6l_DisableInterrupt:
|
|||||||
move.l a0,d0
|
move.l a0,d0
|
||||||
beq.s .err
|
beq.s .err
|
||||||
|
|
||||||
|
moveq #0,d0 ;magic trick: the board enables Interrupts
|
||||||
|
lea $4000(a0),a0
|
||||||
|
move.w d0,($4002.l,a0)
|
||||||
|
lea -$4000(a0),a0
|
||||||
|
|
||||||
|
;WRITEREG $8000,a0,d0 ;only with this "sesame"
|
||||||
|
|
||||||
;disables all interrupts
|
;disables all interrupts
|
||||||
move #EIR_CRYPTEN|EIR_MODEXIF|EIR_HASHIF|EIR_AESIF|EIR_LINKIF|EIR_PRDYIF|EIR_PKTIF|EIR_DMAIF|EIR_TXIF|EIR_TXABTIF|EIR_RXABTIF|EIR_PCFULIF,d0
|
move #EIE_INTIE|EIE_PKTIE|EIE_LINKIE|EIE_AESIE|EIE_MODEXIE|EIE_HASHIE|EIE_PRDYIE|EIE_DMAIE|EIE_TXIE|EIE_TXABTIE|EIE_RXABTIE|EIE_PCFULIE,d0
|
||||||
CLRREG EIR,a0,d0
|
CLRREG EIE,a0,d0
|
||||||
|
|
||||||
moveq #0,d0
|
moveq #0,d0
|
||||||
WRITEREG PSigTask+2,a0,d0 ;lower two bytes
|
WRITEREG PSigTask+2,a0,d0 ;lower two bytes
|
||||||
@@ -1384,6 +1454,11 @@ _enc624j6l_IntServer:
|
|||||||
beq.s .rts ;exit quickly when no packet pending
|
beq.s .rts ;exit quickly when no packet pending
|
||||||
;CLRREG EIR,a1,d1 ;clear interrupt bit
|
;CLRREG EIR,a1,d1 ;clear interrupt bit
|
||||||
|
|
||||||
|
move #$C000,d0 ;disable board interrupt until /INT from ENC toggles
|
||||||
|
lea $4000(a1),a1 ;D0: Bit15 = overall board int enable, Bit14 = ignore int until toggle (1)
|
||||||
|
move.w d0,($4000,a1)
|
||||||
|
lea -$4000(a1),a1
|
||||||
|
|
||||||
READREG PSigTask,a1,d0 ;upper two bytes
|
READREG PSigTask,a1,d0 ;upper two bytes
|
||||||
swap d0 ;
|
swap d0 ;
|
||||||
READREG PSigTask+2,a1,d0 ;lower two bytes
|
READREG PSigTask+2,a1,d0 ;lower two bytes
|
||||||
@@ -1664,21 +1739,40 @@ _enc624j6l_TransmitFrame:
|
|||||||
;---------------- parameter check -------------------------------------
|
;---------------- parameter check -------------------------------------
|
||||||
|
|
||||||
move.l a0,d1 ;no base PTR
|
move.l a0,d1 ;no base PTR
|
||||||
beq.s .err ;exit
|
beq.w .err ;exit
|
||||||
|
|
||||||
|
READREG PLinkChange,a0,d1
|
||||||
|
tst d1
|
||||||
|
beq .linkup
|
||||||
|
; link up and configured
|
||||||
|
|
||||||
|
READREG ESTAT,a0,d1 ;Bit 10 is FULL DUPLEX (ESTAT_PHYDPX)
|
||||||
|
bfextu d1{21:1},d1 ;get Bit 10 to Bit 0 (MACON2_FULDPX)
|
||||||
|
READREG MACON2,a0,d2
|
||||||
|
bclr #0,d2 ;clear FDX bit
|
||||||
|
or.l d1,d2 ;set if active
|
||||||
|
WRITEREG MACON2,a0,d2
|
||||||
|
|
||||||
|
moveq #$12,d1 ;half duplex $12
|
||||||
|
btst #0,d2
|
||||||
|
beq.s .nofdx
|
||||||
|
moveq #$15,d1 ;full duplex $15
|
||||||
|
.nofdx:
|
||||||
|
WRITEREG MABBIPG,a0,d1
|
||||||
|
|
||||||
|
moveq #0,d1
|
||||||
|
WRITEREG PLinkChange,a0,d1
|
||||||
|
.linkup:
|
||||||
|
|
||||||
move.l a1,d1 ;no send frame ?
|
move.l a1,d1 ;no send frame ?
|
||||||
beq.s .err ;exit
|
beq.w .err ;exit
|
||||||
|
|
||||||
move.w d0,d4 ;still need length later
|
move.w d0,d4 ;still need length later
|
||||||
addq #1,d0 ;round up
|
addq #7,d0 ;round up
|
||||||
asr.w #1,d0 ;size/2 = words
|
asr.w #3,d0 ;size/8 = words
|
||||||
subq.w #1,d0 ;dbf...
|
subq.w #1,d0 ;dbf...
|
||||||
blt.s .err ;size<2 ? bail out
|
blt.w .err ;size<2 ? bail out
|
||||||
|
|
||||||
moveq #MACON2_FULDPX,d1
|
|
||||||
SETREG MACON2,a0,d1
|
|
||||||
;moveq #$15,d1
|
|
||||||
;WRITEREG MABBIPG,a0,d1
|
|
||||||
|
|
||||||
;------ double-buffered frame copy to send buffer ---------------------
|
;------ double-buffered frame copy to send buffer ---------------------
|
||||||
READREG PNextTX,a0,d2 ;"last written, maybe still pending frame"
|
READREG PNextTX,a0,d2 ;"last written, maybe still pending frame"
|
||||||
@@ -1687,13 +1781,28 @@ _enc624j6l_TransmitFrame:
|
|||||||
WRITEREG PNextTX,a0,d2 ;remember pointer (d2 also for ETXST later)
|
WRITEREG PNextTX,a0,d2 ;remember pointer (d2 also for ETXST later)
|
||||||
|
|
||||||
lea (a0,d2.w),a2 ;write pointer for frame
|
lea (a0,d2.w),a2 ;write pointer for frame
|
||||||
|
swap d4
|
||||||
|
move.w #8,d4
|
||||||
.txcopy:
|
.txcopy:
|
||||||
move (a1)+,d1 ;get word
|
move.l (a1)+,d1
|
||||||
|
move.l (a1)+,d3
|
||||||
|
|
||||||
ifne _OPT_BUFFER_SWAP
|
ifne _OPT_BUFFER_SWAP
|
||||||
rol.w #8,d1 ;swap buffer to Big Endian (if necessary)
|
; byte swap in 16 Bit words
|
||||||
|
rol.w d4,d1
|
||||||
|
rol.w d4,d3
|
||||||
|
swap d1
|
||||||
|
swap d3
|
||||||
|
rol.w d4,d1
|
||||||
|
rol.w d4,d3
|
||||||
|
swap d1
|
||||||
|
swap d3
|
||||||
endc
|
endc
|
||||||
move d1,(a2)+ ;save to SRAM
|
move.l d1,(a2)+ ;save to SRAM
|
||||||
|
move.l d3,(a2)+ ;save to SRAM
|
||||||
|
|
||||||
dbf d0,.txcopy
|
dbf d0,.txcopy
|
||||||
|
swap d4
|
||||||
|
|
||||||
;---------------- wait on last frame ----------------------------------
|
;---------------- wait on last frame ----------------------------------
|
||||||
moveq #100,d3
|
moveq #100,d3
|
||||||
|
|||||||
@@ -90,8 +90,8 @@
|
|||||||
#define BOARD hwb->hwb_boards[0]
|
#define BOARD hwb->hwb_boards[0]
|
||||||
|
|
||||||
/* interrupt (choice here is INTB_EXTER or INTB_PORTS, depending on solder blob */
|
/* interrupt (choice here is INTB_EXTER or INTB_PORTS, depending on solder blob */
|
||||||
/*#define HW_INTSOURCE INTB_EXTER*/
|
#define HW_INTSOURCE INTB_EXTER
|
||||||
#define HW_INTSOURCE INTB_PORTS
|
/*#define HW_INTSOURCE INTB_PORTS*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -704,6 +704,11 @@ PRIVATE REGARGS BOOL read_frame(struct IOSana2Req *req, struct HWFrame *frame)
|
|||||||
{
|
{
|
||||||
d4(("** wmask is 0x%08lx\n", wmask));
|
d4(("** wmask is 0x%08lx\n", wmask));
|
||||||
|
|
||||||
|
/* send packets if any */
|
||||||
|
d2(("*+ do_write\n"));
|
||||||
|
dowritereqs(pb);
|
||||||
|
d2(("*- do_write\n"));
|
||||||
|
|
||||||
/* if no recv is pending then wait for incoming signals */
|
/* if no recv is pending then wait for incoming signals */
|
||||||
if (!hw_recv_pending(pb)) {
|
if (!hw_recv_pending(pb)) {
|
||||||
d2(("**> wait\n"));
|
d2(("**> wait\n"));
|
||||||
@@ -719,10 +724,6 @@ PRIVATE REGARGS BOOL read_frame(struct IOSana2Req *req, struct HWFrame *frame)
|
|||||||
d2(("*- do_read\n"));
|
d2(("*- do_read\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send packets if any */
|
|
||||||
d2(("*+ do_write\n"));
|
|
||||||
dowritereqs(pb);
|
|
||||||
d2(("*- do_write\n"));
|
|
||||||
|
|
||||||
/* handle SANA-II send requests */
|
/* handle SANA-II send requests */
|
||||||
if (recv & portsigmask)
|
if (recv & portsigmask)
|
||||||
|
|||||||
Reference in New Issue
Block a user