w5100 driver now uses fixed I/O addresses and autoincrement addressing mode : result is 50% speedup in tftp

git-svn-id: http://svn.code.sf.net/p/netboot65/code@314 93682198-c243-4bdb-bd91-e943c89aac3b
This commit is contained in:
jonnosan 2011-05-29 09:54:23 +00:00
parent 99c9ebf682
commit e58d6e2ced
3 changed files with 98 additions and 136 deletions

View File

@ -10,9 +10,13 @@
.include "w5100.i" .include "w5100.i"
;DEFAULT_W5100_BASE = $DF20 WIZNET_BASE=$DE04
WIZNET_MODE_REG = WIZNET_BASE
WIZNET_ADDR_HI = WIZNET_BASE+1
WIZNET_ADDR_LO = WIZNET_BASE+2
WIZNET_DATA_REG = WIZNET_BASE+3
DEFAULT_W5100_BASE = $DE04
;DEBUG = 1 ;DEBUG = 1
.export eth_init .export eth_init
@ -37,6 +41,7 @@ DEFAULT_W5100_BASE = $DE04
.importzp eth_type .importzp eth_type
.importzp eth_data .importzp eth_data
.importzp copy_src .importzp copy_src
.importzp copy_dest
.export w5100_ip65_init .export w5100_ip65_init
.export w5100_read_register .export w5100_read_register
@ -76,78 +81,45 @@ DEFAULT_W5100_BASE = $DE04
;outputs: carry flag is set if there was an error, clear otherwise ;outputs: carry flag is set if there was an error, clear otherwise
;this implementation uses a default address for the w5100, and can be ;this implementation uses a default address for the w5100, and can be
;called as a 'generic' eth driver init function ;called as a 'generic' eth driver init function
;w5100 aware apps can use w5100_init and pass in a different
;base address
eth_init: eth_init:
lda $de01 lda $de01
eor #$01 eor #$01
sta $de01 sta $de01
ldax #DEFAULT_W5100_BASE
;initialize the w5100 ethernet adaptor
;inputs: AX=base address for w5100 i/o
;outputs: carry flag is set if there was an error, clear otherwise
w5100_init:
stx set_hi+2
stx set_lo+2
stx get_hi+2
stx get_lo+2
stx inc_hi+2
stx inc_lo+2
stx read_register+2
stx write_register+2
stx read_mode_reg+2
stx write_mode_reg+2
tax
stx read_mode_reg+1
stx write_mode_reg+1
inx
stx set_hi+1
stx get_hi+1
stx inc_hi+1
inx
stx set_lo+1
stx get_lo+1
stx inc_lo+1
inx
stx read_register+1
stx write_register+1
lda #$80 ;reset lda #$80 ;reset
jsr write_mode_reg sta WIZNET_MODE_REG
jsr read_mode_reg lda WIZNET_MODE_REG
bne @error ;writing a byte to the MODE register with bit 7 set should reset. bne @error ;writing a byte to the MODE register with bit 7 set should reset.
;after a reset, mode register is zero ;after a reset, mode register is zero
;therefore, if there is a real W5100 at the specified address, ;therefore, if there is a real W5100 at the specified address,
;we should be able to write a $80 and read back a $00 ;we should be able to write a $80 and read back a $00
lda #$11 ;set indirect mode, no autoinc, no auto PING lda #$13 ;set indirect mode, with autoinc, no auto PING
jsr write_mode_reg sta WIZNET_MODE_REG
jsr read_mode_reg lda WIZNET_MODE_REG
cmp #$11 cmp #$13
bne @error ;make sure if we write to mode register without bit 7 set, bne @error ;make sure if we write to mode register without bit 7 set,
;the value persists. ;the value persists.
ldax #$0016 lda #$00
jsr w5100_select_register sta WIZNET_ADDR_HI
lda #$16
sta WIZNET_ADDR_LO
ldx #$00 ;start writing to reg $0016 - Interrupt Mask Register ldx #$00 ;start writing to reg $0016 - Interrupt Mask Register
@loop: @loop:
lda w5100_config_data,x lda w5100_config_data,x
jsr write_reg_and_inc sta WIZNET_DATA_REG
inx inx
cpx #$06 cpx #$06
bne @loop bne @loop
lda #$09 lda #$09
jsr set_lo sta WIZNET_ADDR_LO
ldx #$00 ;start writing to reg $0009 - MAC address ldx #$00 ;start writing to reg $0009 - MAC address
@mac_loop: @mac_loop:
lda cfg_mac,x lda cfg_mac,x
jsr write_reg_and_inc sta WIZNET_DATA_REG
inx inx
cpx #$06 cpx #$06
bne @mac_loop bne @mac_loop
@ -155,25 +127,38 @@ w5100_init:
;set up socket 0 for MAC RAW mode ;set up socket 0 for MAC RAW mode
ldax #W5100_RMSR ;rx memory size (each socket) ldax #W5100_RMSR ;rx memory size (each socket)
ldy #$0A ;sockets 0 & 1 4KB each, other sockets 0KB stx WIZNET_ADDR_HI
sta WIZNET_ADDR_LO
lda #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
;if this is changed, change the mask in eth_rx as well! ;if this is changed, change the mask in eth_rx as well!
jsr w5100_write_register sta WIZNET_DATA_REG
ldax #W5100_TMSR ;rx memory size (each socket) ldax #W5100_TMSR ;rx memory size (each socket)
ldy #$0A ;sockets 0 & 1 4KB each, other sockets 0KB stx WIZNET_ADDR_HI
sta WIZNET_ADDR_LO
lda #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
;if this is changed, change the mask in eth_tx as well! ;if this is changed, change the mask in eth_tx as well!
jsr w5100_write_register sta WIZNET_DATA_REG
ldax #W5100_S0_MR ldax #W5100_S0_MR
ldy #W5100_MODE_MAC_RAW stx WIZNET_ADDR_HI
jsr w5100_write_register sta WIZNET_ADDR_LO
lda #W5100_MODE_MAC_RAW
sta WIZNET_DATA_REG
;open socket 0 ;open socket 0
ldax #W5100_S0_CR
ldy #W5100_CMD_OPEN
jsr w5100_write_register jsr w5100_write_register
ldax #W5100_S0_CR
stx WIZNET_ADDR_HI
sta WIZNET_ADDR_LO
lda #W5100_CMD_OPEN
sta WIZNET_DATA_REG
lda #0 lda #0
sta tcp_connected sta tcp_connected
@ -184,16 +169,12 @@ w5100_init:
rts ; rts ;
;initialize the ip65 stack for the w5100 ethernet adaptor ;initialize the ip65 stack for the w5100 ethernet adaptor
;inputs: AX=base address for w5100 i/o ;inputs: none
;outputs: carry flag is set if there was an error, clear otherwise ;outputs: carry flag is set if there was an error, clear otherwise
;this routine can be called multiple times, with different addresses
;so a W5100 can be detected at different locations
w5100_ip65_init: w5100_ip65_init:
stax w5100_addr
jsr cfg_init ;copy default values (including MAC address) to RAM jsr cfg_init ;copy default values (including MAC address) to RAM
ldax w5100_addr jsr eth_init
jsr w5100_init ; initialize ethernet driver
bcc @ok bcc @ok
lda #KPR_ERROR_DEVICE_FAILURE lda #KPR_ERROR_DEVICE_FAILURE
@ -246,8 +227,8 @@ eth_rx:
lda #$8D ;opcode for STA lda #$8D ;opcode for STA
sta next_eth_packet_byte sta next_eth_packet_byte
ldax #eth_inp ldax #eth_inp
sta eth_ptr_lo stax copy_dest
stx eth_ptr_hi
lda #2 lda #2
sta byte_ctr_lo sta byte_ctr_lo
lda #0 lda #0
@ -267,12 +248,28 @@ eth_rx:
sta eth_inp_len ;lo byte of frame length sta eth_inp_len ;lo byte of frame length
;now copy the rest of the frame to the eth_inp buffer ;now copy the rest of the frame to the eth_inp buffer
;we keep our own copy of RX_RD_PTR in sync, rather than read WIZNET_ADDR registers
;because of issue where reads to WIZNET_ADDR can cause the autoinc ptr to advance erroneously
;when WizNet cart used in a cartridge expander
ldy #0
@get_next_byte: @get_next_byte:
jsr @inc_rx_rd_ptr inc rx_rd_ptr
ldax rx_rd_ptr bne :+
jsr w5100_read_register inc rx_rd_ptr+1
jsr next_eth_packet_byte lda rx_rd_ptr+1
and #$0F
clc
adc #$60
sta rx_rd_ptr+1
sta WIZNET_ADDR_HI
:
lda WIZNET_DATA_REG
sta (copy_dest),y
iny
bne :+
inc copy_dest+1
:
inc byte_ctr_lo inc byte_ctr_lo
bne :+ bne :+
inc byte_ctr_hi inc byte_ctr_hi
@ -434,7 +431,8 @@ advance_eth_ptr:
; y is overwritten ; y is overwritten
w5100_read_register: w5100_read_register:
jsr w5100_select_register jsr w5100_select_register
jmp read_register lda WIZNET_DATA_REG
rts
; write to one of the W5100 registers ; write to one of the W5100 registers
; inputs: AX = register number to write ; inputs: AX = register number to write
@ -443,7 +441,8 @@ w5100_read_register:
w5100_write_register: w5100_write_register:
jsr w5100_select_register jsr w5100_select_register
tya tya
jmp write_register sta WIZNET_DATA_REG
rts
@ -485,7 +484,7 @@ tcp_listen:
jsr w5100_select_register jsr w5100_select_register
ldx #0 ldx #0
@ip_loop: @ip_loop:
jsr read_reg_and_inc lda WIZNET_DATA_REG
sta tcp_remote_ip,x sta tcp_remote_ip,x
inx inx
cpx #$04 cpx #$04
@ -493,9 +492,9 @@ tcp_listen:
ldax #W5100_S1_DPORT0 ldax #W5100_S1_DPORT0
jsr w5100_select_register jsr w5100_select_register
jsr read_reg_and_inc lda WIZNET_DATA_REG
sta tcp_connect_remote_port+1 sta tcp_connect_remote_port+1
jsr read_reg_and_inc lda WIZNET_DATA_REG
sta tcp_connect_remote_port sta tcp_connect_remote_port
clc clc
@ -525,7 +524,7 @@ tcp_connect:
ldx #0 ldx #0
@remote_ip_loop: @remote_ip_loop:
lda tcp_connect_ip,x lda tcp_connect_ip,x
jsr write_reg_and_inc sta WIZNET_DATA_REG
inx inx
cpx #$04 cpx #$04
bne @remote_ip_loop bne @remote_ip_loop
@ -533,9 +532,9 @@ tcp_connect:
;W5100 register address is now W5100_S1_DPORT0, so set the destination port ;W5100 register address is now W5100_S1_DPORT0, so set the destination port
lda tcp_remote_port+1 lda tcp_remote_port+1
jsr write_reg_and_inc sta WIZNET_DATA_REG
lda tcp_remote_port lda tcp_remote_port
jsr write_reg_and_inc sta WIZNET_DATA_REG
ldax #W5100_S1_CR ldax #W5100_S1_CR
ldy #W5100_CMD_CONNECT ldy #W5100_CMD_CONNECT
@ -904,14 +903,14 @@ setup_tcp_socket:
ldx #0 ldx #0
@gateway_loop: @gateway_loop:
lda cfg_gateway,x lda cfg_gateway,x
jsr write_reg_and_inc sta WIZNET_DATA_REG
inx inx
cpx #$04 cpx #$04
bne @gateway_loop bne @gateway_loop
ldx #0 ldx #0
@netmask_loop: @netmask_loop:
lda cfg_netmask,x lda cfg_netmask,x
jsr write_reg_and_inc sta WIZNET_DATA_REG
inx inx
cpx #$04 cpx #$04
bne @netmask_loop bne @netmask_loop
@ -921,7 +920,7 @@ setup_tcp_socket:
ldx #0 ldx #0
@ip_loop: @ip_loop:
lda cfg_ip,x lda cfg_ip,x
jsr write_reg_and_inc sta WIZNET_DATA_REG
inx inx
cpx #$04 cpx #$04
bne @ip_loop bne @ip_loop
@ -929,9 +928,9 @@ setup_tcp_socket:
ldax #W5100_S1_PORT0 ldax #W5100_S1_PORT0
jsr w5100_select_register jsr w5100_select_register
lda tcp_local_port+1 lda tcp_local_port+1
jsr write_reg_and_inc sta WIZNET_DATA_REG
lda tcp_local_port lda tcp_local_port
jsr write_reg_and_inc sta WIZNET_DATA_REG
lda #0 lda #0
sta tcp_connected sta tcp_connected
@ -946,19 +945,13 @@ setup_tcp_socket:
jsr w5100_write_register jsr w5100_write_register
rts rts
write_reg_and_inc:
jsr write_register
jmp inc_register
read_reg_and_inc:
jsr read_register
jmp inc_register
.rodata .rodata
eth_driver_name: eth_driver_name:
.asciiz "WIZNET 5100" .asciiz "WIZNET 5100"
eth_driver_io_base=read_mode_reg+1 eth_driver_io_base:
.word WIZNET_BASE
w5100_config_data: w5100_config_data:
.byte $00 ;no interrupts .byte $00 ;no interrupts
@ -968,7 +961,6 @@ w5100_config_data:
.byte $55 ;4 sockets @2K each, tx/rx .byte $55 ;4 sockets @2K each, tx/rx
.byte $55 .byte $55
.segment "SELF_MODIFIED_CODE"
; ;
; select one of the W5100 registers for subsequent read or write ; select one of the W5100 registers for subsequent read or write
@ -976,9 +968,9 @@ w5100_config_data:
; outputs: none ; outputs: none
w5100_select_register: w5100_select_register:
set_hi: set_hi:
stx $FFFF ;WIZNET_ADDR_HI stx WIZNET_ADDR_HI
set_lo: set_lo:
sta $FFFF ;WIZNET_ADDR_LO sta WIZNET_ADDR_LO
rts rts
; return which W5100 register the next read or write will access ; return which W5100 register the next read or write will access
@ -986,42 +978,13 @@ set_lo:
; outputs: AX = selected register number ; outputs: AX = selected register number
w5100_get_current_register: w5100_get_current_register:
get_hi: get_hi:
ldx $FFFF ;WIZNET_ADDR_HI ldx WIZNET_ADDR_HI
get_lo: get_lo:
lda $FFFF ;WIZNET_ADDR_LO lda WIZNET_ADDR_LO
rts
; read value from previously selected W5100 register
; inputs: none
; outputs: A = value of selected register number (and register pointer auto incremented)
read_register:
lda $FFFF ;WIZNET_DATA
rts
; write value to previously selected W5100 register
; inputs: A = value to write to selected register
; outputs: none (although W5100 register pointer auto incremented)
write_register:
sta $FFFF ;WIZNET_DATA
rts rts
inc_register: .segment "SELF_MODIFIED_CODE"
inc_lo:
inc $FFFF ;WIZNET_ADDR_LO
bne :+
inc_hi:
inc $FFFF ;WIZNET_ADDR_HI
:
rts
read_mode_reg:
lda DEFAULT_W5100_BASE ;WIZNET_BASE
rts
write_mode_reg:
sta DEFAULT_W5100_BASE ;WIZNET_BASE
rts
next_eth_packet_byte: next_eth_packet_byte:
lda $FFFF ;eth_packet lda $FFFF ;eth_packet

View File

@ -62,5 +62,5 @@ drivers:
make -C ../drivers all make -C ../drivers all
bootc64.prg: bootc64.prg:
# cp wizboot.prg ../../server/boot/bootc64.prg cp wizboot.prg ../../server/boot/bootc64.prg
cp wiztest.prg ../../server/boot/bootc64.prg # cp wiztest.prg ../../server/boot/bootc64.prg

View File

@ -6,11 +6,12 @@
;.include "../drivers/w5100.i" ;.include "../drivers/w5100.i"
WIZNET_BASE=$DE04
WIZNET_MODE_REG = $DE04 ;WIZNET_BASE=$DF20
WIZNET_ADDR_HI = $DE05 WIZNET_MODE_REG = WIZNET_BASE
WIZNET_ADDR_LO = $DE06 WIZNET_ADDR_HI = WIZNET_BASE+1
WIZNET_DATA_REG = $DE07 WIZNET_ADDR_LO = WIZNET_BASE+2
WIZNET_DATA_REG = WIZNET_BASE+3
TEST_LOOPS=$1F TEST_LOOPS=$1F
@ -110,7 +111,6 @@ init:
; jmp @exit
ldax #loop ldax #loop
jsr print jsr print
@ -203,7 +203,6 @@ init:
jmp @reset_test_loops jmp @reset_test_loops
@exit: @exit:
jmp $e37b jmp $e37b
@error: @error: