w5100 works in MAC RAW mode

git-svn-id: http://svn.code.sf.net/p/netboot65/code@294 93682198-c243-4bdb-bd91-e943c89aac3b
This commit is contained in:
jonnosan 2010-12-28 11:59:56 +00:00
parent bc8b9c5ee9
commit 853194a292
8 changed files with 469 additions and 345 deletions

Binary file not shown.

Binary file not shown.

View File

@ -26,7 +26,7 @@ apple2prog.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o a2charconv.o
c64rrnet.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o c64_vt100.o cs8900a.o
ar65 a $@ $^
c64wiznet.lib: w5100.o c64print.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o c64_vt100.o w5100_udp.o
c64wiznet.lib: w5100.o c64print.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o c64_vt100.o
ar65 a $@ $^

View File

@ -12,6 +12,7 @@
DEFAULT_W5100_BASE = $DF20
;DEBUG = 1
.export eth_init
.export eth_rx
.export eth_tx
@ -22,25 +23,30 @@ DEFAULT_W5100_BASE = $DF20
.import eth_outp
.import eth_outp_len
.import timer_init
.import arp_init
.import ip_init
.import cfg_init
.importzp eth_dest
.importzp eth_src
.importzp eth_type
.importzp eth_data
.export w5100_init
.export w5100_read_reg
.export w5100_write_reg
.export w5100_ip65_init
.export w5100_read_register
.export w5100_write_register
; .export w5100_get_current_register
; .export w5100_select_register
; .export w5100_read_next_byte
; .export w5100_write_next_byte
.import cfg_mac
.import cfg_ip
.import cfg_netmask
.import cfg_gateway
.export icmp_ping
.export icmp_echo_ip
.export ip_init
.export ip_process
.import ip65_error
.import ip65_error
.segment "IP65ZP" : zeropage
@ -65,8 +71,11 @@ eth_init:
w5100_init:
stx set_hi+2
stx set_lo+2
stx read_data_reg+2
stx write_data_reg+2
stx get_hi+2
stx get_lo+2
stx w5100_read_next_byte+2
stx w5100_write_next_byte+2
stx read_mode_reg+2
stx write_mode_reg+2
tax
@ -74,12 +83,13 @@ w5100_init:
stx write_mode_reg+1
inx
stx set_hi+1
stx get_hi+1
inx
stx set_lo+1
stx get_lo+1
inx
stx read_data_reg+1
stx write_data_reg+1
stx w5100_read_next_byte+1
stx w5100_write_next_byte+1
lda #$80 ;reset
jsr write_mode_reg
@ -95,11 +105,11 @@ w5100_init:
bne @error ;make sure if we write to mode register without bit 7 set,
;the value persists.
ldax #$0016
jsr set_register_address
jsr w5100_select_register
ldx #$00 ;start writing to reg $0016 - Interrupt Mask Register
@loop:
lda w5100_config_data,x
jsr write_data_reg
jsr w5100_write_next_byte
inx
cpx #$06
bne @loop
@ -110,22 +120,36 @@ w5100_init:
@mac_loop:
lda cfg_mac,x
jsr write_data_reg
jsr w5100_write_next_byte
inx
cpx #$06
bne @mac_loop
jsr set_ip_params
;set up socket 0 for MAC RAW mode
;set up socket 0 for MAC RAW mode , no autoinc, no ping
lda #$11 ;set indirect - no autoincrement, no automatic ping response
jsr write_mode_reg
ldax #W5100_RMSR ;rx memory size (each socket)
ldy #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
;if this is changed, change the mask in eth_rx as well!
jsr w5100_write_register
ldax #W5100_TMSR ;rx memory size (each socket)
ldy #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
;if this is changed, change the mask in eth_tx as well!
jsr w5100_write_register
ldax #W5100_S0_MR
ldy #W5100_MODE_IP_RAW
jsr w5100_write_reg
ldy #W5100_MODE_MAC_RAW
jsr w5100_write_register
;open socket 0
ldax #W5100_S0_CR
ldy #W5100_CMD_OPEN
jsr w5100_write_reg
jsr w5100_write_register
clc
rts
@ -133,6 +157,30 @@ w5100_init:
sec
rts ;
;initialize the ip65 stack for the w5100 ethernet adaptor
;inputs: AX=base address for w5100 i/o
;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:
stax w5100_addr
jsr cfg_init ;copy default values (including MAC address) to RAM
ldax w5100_addr
jsr w5100_init ; initialize ethernet driver
bcc @ok
lda #KPR_ERROR_DEVICE_FAILURE
sta ip65_error
rts
@ok:
jsr timer_init ; initialize timer
jsr arp_init ; initialize arp
jsr ip_init ; initialize ip, icmp, udp, and tcp
clc
rts
;receive a packet
;inputs: none
;outputs:
@ -142,6 +190,153 @@ w5100_init:
; and eth_inp_len contains the length of the packet
eth_rx:
ldax #W5100_S0_RX_RSR0
jsr w5100_read_register
sta eth_inp_len+1
ldax #W5100_S0_RX_RSR1
jsr w5100_read_register
sta eth_inp_len
bne @got_data
lda eth_inp_len+1
bne @got_data
sec
rts
@got_data:
lda #$8D ;opcode for STA
sta next_eth_packet_byte
ldax #eth_inp
sta eth_ptr_lo
stx eth_ptr_hi
lda #2
sta byte_ctr_lo
lda #0
sta byte_ctr_hi
.ifdef DEBUG
.import print_hex
.import print_cr
lda eth_inp_len+1
jsr print_hex
lda eth_inp_len
jsr print_hex
.endif
;read the 2 byte frame length
jsr @get_current_rx_rd
jsr @mask_and_adjust_rx_read
.ifdef DEBUG
lda rx_rd_ptr+1 ;DEBUG
jsr print_hex ;DEBUG
lda rx_rd_ptr ;DEBUG
jsr print_hex ;DEBUG
.endif
ldax rx_rd_ptr
jsr w5100_read_register
sta eth_inp_len+1 ;high byte of frame length
.ifdef DEBUG
jsr print_hex ;DEBUG
.endif
jsr @inc_rx_rd_ptr
ldax rx_rd_ptr
jsr w5100_read_register
sta eth_inp_len ;lo byte of frame length
.ifdef DEBUG
jsr print_hex ;DEBUG
jsr print_cr ;DEBUG
.endif
;now copy the rest of the frame to the eth_inp buffer
@get_next_byte:
jsr @inc_rx_rd_ptr
ldax rx_rd_ptr
jsr w5100_read_register
jsr next_eth_packet_byte
inc byte_ctr_lo
bne :+
inc byte_ctr_hi
:
lda byte_ctr_lo
cmp eth_inp_len
bne @get_next_byte
lda byte_ctr_hi
cmp eth_inp_len+1
bne @get_next_byte
.ifdef DEBUG
;print first 40 bytes of frame
ldy #0
@print_loop:
tya
pha
lda eth_inp,y
jsr print_hex
pla
tay
iny
cpy #40
bne @print_loop
jsr print_cr ;DEBUG
.endif
;update the RX RD pointer past the frame we just read
jsr @get_current_rx_rd
clc
lda rx_rd_ptr
adc eth_inp_len
sta rx_rd_ptr
lda rx_rd_ptr+1
adc eth_inp_len+1
tay
ldax #W5100_S0_RX_RD0
jsr w5100_write_register
ldy rx_rd_ptr
ldax #W5100_S0_RX_RD1
jsr w5100_write_register
ldax #W5100_S0_CR
ldy #W5100_CMD_RECV
jsr w5100_write_register
;now adjust the input length to remove the 2 byte header length
sec
lda eth_inp_len
sbc #2
sta eth_inp_len
bcs :+
dec eth_inp_len
:
clc
rts
@inc_rx_rd_ptr:
inc rx_rd_ptr
bne :+
inc rx_rd_ptr+1
@mask_and_adjust_rx_read:
lda rx_rd_ptr+1
and #$0F
clc
adc #$60
sta rx_rd_ptr+1
:
rts
@get_current_rx_rd:
ldax #W5100_S0_RX_RD0
jsr w5100_read_register
sta rx_rd_ptr+1
ldax #W5100_S0_RX_RD1
jsr w5100_read_register
sta rx_rd_ptr
rts
; send a packet
;inputs:
@ -151,60 +346,102 @@ eth_rx:
; if there was an error sending the packet then carry flag is set
; otherwise carry flag is cleared
eth_tx:
inc $d020
sec
lda #$AD ;opcode for LDA
sta next_eth_packet_byte
ldax #eth_outp
sta eth_ptr_lo
stx eth_ptr_hi
lda #0
sta byte_ctr_lo
sta byte_ctr_hi
jsr @get_current_tx_wr
jmp @calculate_tx_wr_ptr
@send_next_byte:
jsr next_eth_packet_byte
tay
ldax tx_wr_ptr
jsr w5100_write_register
inc byte_ctr_lo
bne :+
inc byte_ctr_hi
:
inc tx_wr_ptr
bne :+
inc tx_wr_ptr+1
@calculate_tx_wr_ptr:
lda tx_wr_ptr+1
and #$0F
clc
adc #$40
sta tx_wr_ptr+1
:
lda byte_ctr_lo
cmp eth_outp_len
bne @send_next_byte
lda byte_ctr_hi
cmp eth_outp_len+1
bne @send_next_byte
;all bytes copied, now adjust the tx write ptr and SEND
jsr @get_current_tx_wr
clc
lda tx_wr_ptr
adc eth_outp_len
sta tx_wr_ptr
lda tx_wr_ptr+1
adc eth_outp_len+1
tay
ldax #W5100_S0_TX_WR0
jsr w5100_write_register
ldy tx_wr_ptr
ldax #W5100_S0_TX_WR1
jsr w5100_write_register
ldax #W5100_S0_CR
ldy #W5100_CMD_SEND
jsr w5100_write_register
clc
rts
@get_current_tx_wr:
ldax #W5100_S0_TX_WR0
jsr w5100_read_register
sta tx_wr_ptr+1
ldax #W5100_S0_TX_WR1
jsr w5100_read_register
sta tx_wr_ptr
rts
advance_eth_ptr:
inc eth_ptr_lo
bne :+
inc eth_ptr_hi
:
rts
; read one of the W5100 registers
; inputs: AX = register number to read
; outputs: A = value of nominated register
; y is overwritten
w5100_read_reg:
jsr set_register_address
jmp read_data_reg
w5100_read_register:
jsr w5100_select_register
jmp w5100_read_next_byte
; write to one of the W5100 registers
; inputs: AX = register number to read
; inputs: AX = register number to write
; Y = value to write to register
; outputs: none
w5100_write_reg:
jsr set_register_address
w5100_write_register:
jsr w5100_select_register
tya
jmp write_data_reg
set_ip_params:
ldax #W5100_GAR0
jsr set_register_address
ldx #0
@gateway_loop:
lda cfg_gateway,x
jsr write_data_reg
inx
cpx #$04
bne @gateway_loop
ldx #0
@netmask_loop:
lda cfg_netmask,x
jsr write_data_reg
inx
cpx #$04
bne @netmask_loop
ldax #W5100_SIPR0
jsr set_register_address
ldx #0
@ip_loop:
lda cfg_ip,x
jsr write_data_reg
inx
cpx #$04
bne @ip_loop
rts
icmp_ping:
ip_init:
ip_process:
rts
jmp w5100_write_next_byte
.rodata
@ -220,28 +457,65 @@ w5100_config_data:
.segment "SELF_MODIFIED_CODE"
set_register_address:
;
; select one of the W5100 registers for subsequent read or write
; inputs: AX = register number to select
; outputs: none
w5100_select_register:
set_hi:
stx $FFFF ;WIZNET_ADDR_HI
set_lo:
sta $FFFF ;WIZNET_ADDR_LO
rts
read_data_reg:
; return which W5100 register the next read or write will access
; inputs: none
; outputs: AX = selected register number
w5100_get_current_register:
get_hi:
ldx $FFFF ;WIZNET_ADDR_HI
get_lo:
lda $FFFF ;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)
w5100_read_next_byte:
lda $FFFF ;WIZNET_DATA
rts
write_data_reg:
; write value to previously selected W5100 register
; inputs: A = value to write to selected register
; outputs: none (although W5100 register pointer auto incremented)
w5100_write_next_byte:
sta $FFFF ;WIZNET_DATA
rts
read_mode_reg:
lda $FFFF ;WIZNET_BASE
rts
write_mode_reg:
sta $FFFF ;WIZNET_BASE
rts
next_eth_packet_byte:
lda $FFFF ;eth_packet
jmp advance_eth_ptr
eth_ptr_lo=next_eth_packet_byte+1
eth_ptr_hi=next_eth_packet_byte+2
.bss
temp: .res 1
icmp_echo_ip:
w5100_addr: .res 2
byte_ctr_lo: .res 1
byte_ctr_hi: .res 1
tx_wr_ptr: .res 2
rx_rd_ptr: .res 2
;-- LICENSE FOR w5100a.s --
; The contents of this file are subject to the Mozilla Public License

View File

@ -354,7 +354,7 @@ ok_msg:
.byte "OK", 0
dns_lookup_failed_msg:
.byte "DNS lookup failed", 0
.byte "DNS LOOKUP FAILED", 0
error_code:
.asciiz "error code: "

View File

@ -33,25 +33,29 @@ ETHOBJS= \
xmodem.o \
url.o \
arithmetic.o\
ip.o \
icmp.o \
udp.o
all: ip65.lib ip65_tcp.lib ip65_wiznet.lib
ip65.lib: $(ETHOBJS) function_dispatcher.s ip.s icmp.s udp.o
ip65.lib: $(ETHOBJS) function_dispatcher.s
$(AS) $(AFLAGS) function_dispatcher.s
$(AS) $(AFLAGS) ip.s
$(AS) $(AFLAGS) icmp.s
ar65 a ip65.lib $(ETHOBJS) function_dispatcher.o ip.o icmp.o udp.o
ar65 a ip65.lib $(ETHOBJS) function_dispatcher.o
ip65_tcp.lib: tcp.o $(ETHOBJS) function_dispatcher.s ip.s tcp.s icmp.s udp.o
ip65_tcp.lib: tcp.o $(ETHOBJS) function_dispatcher.s tcp.s
$(AS) $(AFLAGS) function_dispatcher.s -DTCP -DAPI_VERSION=2
$(AS) $(AFLAGS) ip.s -DTCP
$(AS) $(AFLAGS) icmp.s -DTCP
ar65 a ip65_tcp.lib $(ETHOBJS) function_dispatcher.o ip.o tcp.o icmp.o udp.o
ar65 a ip65_tcp.lib $(ETHOBJS) function_dispatcher.o tcp.o
ip65_wiznet.lib: $(ETHOBJS) function_dispatcher.s
$(AS) $(AFLAGS) function_dispatcher.s
ar65 a ip65_wiznet.lib $(ETHOBJS) function_dispatcher.o
$(AS) $(AFLAGS) function_dispatcher.s -DTCP -DAPI_VERSION=2
$(AS) $(AFLAGS) ip.s -DTCP
$(AS) $(AFLAGS) icmp.s -DTCP
ar65 a ip65_wiznet.lib $(ETHOBJS) function_dispatcher.o tcp.o
clean:
rm -f *.o

View File

@ -34,6 +34,7 @@
ap: .res 2
ARP_TIMEOUT_MS=100
.bss
@ -211,10 +212,10 @@ arp_lookup:
jsr timer_read ; read current timer value
clc
adc #<1000 ; set timeout to now + 1000 ms
adc #<ARP_TIMEOUT_MS ; set timeout to now + ARP_TIMEOUT_MS
sta arptimeout
txa
adc #>1000
adc #>ARP_TIMEOUT_MS
sta arptimeout + 1
@notimeout:

View File

@ -6,23 +6,19 @@
.import exit_to_basic
.import cfg_get_configuration_ptr
.import copymem
.importzp copy_src
.importzp copy_dest
.import copymem
.importzp copy_src
.importzp copy_dest
.import icmp_echo_ip
.import icmp_ping
.import get_key
.import w5100_read_register
.import w5100_write_register
.import w5100_select_register
.import w5100_get_current_register
.import w5100_read_next_byte
.import w5100_write_next_byte
.import w5100_ip65_init
.import dns_set_hostname
.import dns_resolve
.import dns_ip
.import dns_status
.import __CODE_LOAD__
.import __CODE_SIZE__
.import __RODATA_SIZE__
.import __DATA_SIZE__
.segment "STARTUP" ;this is what gets put at the start of the file on the C64
@ -43,72 +39,79 @@ basicstub:
.code
init:
; jsr wait_for_keypress
init_ip_via_dhcp
; jsr wait_for_keypress
ldax #$DE00
jsr probe_for_w5100
bcc @found
ldax #$DF00
jsr probe_for_w5100
bcc @found
ldax #$DF20
jsr probe_for_w5100
bcc @found
ldax #no_wiznet
jmp print
rts
@found:
jsr dhcp_init
@skip:
jsr print_ip_config
; jsr wait_for_keypress
;
; rts
;
; jsr wait_for_keypress
; jsr dhcp_init
rts
; jsr print_ip_config
print_driver_init
jsr ip65_init
jsr print_cr
; print_driver_init
; jsr ip65_init
; jsr print_cr
; jsr wiznet_dump
jsr ping_test
jsr ping_test_2
; ldax #W5100_S0_RX_RSR0
; jsr dump_current_register
; jsr wait_for_keypress
; jsr dump_current_register
ldax #sending
jsr print
jsr wait_for_keypress
jsr send_frame
jsr wiznet_dump
jsr dump_current_register
@wait_for_frame:
ldax #W5100_S0_RX_RSR0
jsr w5100_read_register
bne :+
jsr w5100_read_next_byte
bne :+
inc $d020
; jsr dump_current_register
; jsr wiznet_dump
jmp @wait_for_frame
ldax #hostname_1
jsr do_dns_query
bcs :+
jsr ping_test_3
:
jsr dump_frame
rts
ldx #$0
ping_test:
ldx #$3
:
lda ping_dest,x
lda #5
jsr w5100_write_next_byte
inx
inc $d021
cpx #$4
bne :-
jsr dump_current_register
jsr wiznet_dump
lda dhcp_server,x
sta icmp_echo_ip,x
dex
bpl :-
jmp do_ping
ping_test_2:
ldx #$3
:
lda cfg_gateway,x
sta icmp_echo_ip,x
dex
bpl :-
jmp do_ping
ping_test_3:
ldx #$3
:
lda dns_ip,x
sta icmp_echo_ip,x
dex
bpl :-
jmp do_ping
do_ping:
ldax #pinging
jsr print
@ -124,176 +127,20 @@ init:
@error:
jmp print_errorcode
dump_current_register:
jsr w5100_get_current_register
print_ax_hex:
pha
txa
rts
probe_for_w5100:
stax w5100_addr
ldax #probing
jsr print
lda w5100_addr+1
jsr print_hex
lda w5100_addr
jsr print_hex
pla
jmp print_hex
send_frame:
ldax #test_frame_length
stax tx_length
lda #0
sta byte_count
sta byte_count+1
ldax #$4000
stax tx_ptr
@write_one_byte:
ldy tx_ptr
lda test_frame,y
tay
ldax tx_ptr
jsr w5100_write_register
inc byte_count
bne :+
inc byte_count+1
:
inc tx_ptr
bne :+
inc tx_ptr+1
:
lda byte_count
cmp tx_length
bne @write_one_byte
tay
ldax #W5100_S0_TX_WR1
jsr w5100_write_register
ldax #W5100_S0_CR
ldy #W5100_CMD_SEND_MAC
jsr w5100_write_register
lda #$40
sta register_page
jsr dump_wiznet_register_page
jmp wait_for_keypress
dump_frame:
jsr print_cr
jsr wiznet_dump
ldax #W5100_S0_RX_RSR0
jsr w5100_read_register
sta rx_length+1
jsr w5100_read_next_byte
sta rx_length
ldx rx_length+1
jsr print_ax_hex
; jsr wait_for_keypress
jsr print_cr
lda #0
sta byte_count
sta byte_count+1
ldax #$6000
stax rx_ptr
@read_one_byte:
ldax rx_ptr
jsr w5100_read_register
jsr print_hex
inc byte_count
bne :+
inc byte_count+1
:
inc rx_ptr
bne :+
inc rx_ptr+1
:
lda byte_count
cmp rx_length
bne @read_one_byte
lda byte_count+1
cmp #4
beq @done
cmp rx_length+1
bne @read_one_byte
@done:
jsr print_cr
jsr dump_current_register
jsr print_cr
ldax rx_length
jsr print_hex
jmp wait_for_keypress
wiznet_dump:
lda #0
sta register_page
jsr dump_wiznet_register_page
lda #$4
sta register_page
jsr dump_wiznet_register_page
jsr wait_for_keypress
jmp print_cr
dump_wiznet_register_page:
sta register_page
lda #0
sta current_register
jsr print_cr
@one_row:
lda current_register
cmp #$40
beq @done
lda register_page
jsr print_hex
lda current_register
jsr print_hex
lda #':'
jsr print_a
lda #' '
jsr print_a
lda #0
sta current_byte_in_row
@dump_byte:
lda current_register
ldx register_page
jsr w5100_read_register
jsr print_hex
lda #' '
jsr print_a
inc current_register
inc current_byte_in_row
lda current_byte_in_row
cmp #08
bne @dump_byte
jsr print_cr
jmp @one_row
@done:
jsr print_cr
rts
ldax w5100_addr
jmp w5100_ip65_init
wait_for_keypress:
lda #0
@ -303,45 +150,43 @@ wait_for_keypress:
jsr get_key
rts
do_dns_query:
pha
jsr print
lda #' '
jsr print_a
lda #':'
jsr print_a
lda #' '
jsr print_a
pla
jsr dns_set_hostname
jsr dns_resolve
bcc :+
ldax #dns_lookup_failed_msg
jsr print
sec
rts
:
ldax #dns_ip
jsr print_dotted_quad
jsr print_cr
clc
rts
.rodata
ms: .byte " MS",13,0
pinging: .byte "PINGING ",13,10,0
sending: .byte "SENDING ",13,10,0
pinging: .byte "PINGING ",0
hello: .byte "HELLO WORLD!",13,10,0
sock_0: .byte "SOCKET 0 ",0
read: .byte "READ",0
write_addr: .byte "WRITE"
addr: .byte " ADDRESS : ",0
ping_dest: .byte 10,5,1,1
test_frame:
.byte $ff,$ff,$ff,$ff,$ff,$ff
.byte $01,$02,$03,$04,$05,$06,$07,$08
.byte $11,$12,$13,$14,$15,$16,$17,$18
.byte $21,$22,$23,$24,$25,$26,$27,$28
.byte $31,$32,$33,$34,$35,$36,$37,$38
.byte $ff,$ff,$ff,$ff,$ff,$ff
.byte $ff,$ff,$ff,$ff,$ff,$ff
.byte $01,$02,$03,$04,$05,$06,$07,$08
.byte $11,$12,$13,$14,$15,$16,$17,$18
.byte $21,$22,$23,$24,$25,$26,$27,$28
.byte $31,$32,$33,$34,$35,$36,$37,$38
test_frame_length=*-test_frame
no_wiznet: .byte "NO W5100 FOUND",13,10,0
probing: .byte "LOOKING FOR W5100 AT $",0
ping_ip: .byte 10,5,1,84
hostname_1: .byte "JAMTRONIX.COM",0
.bss
rx_length: .res 2
rx_ptr: .res 2
byte_count: .res 2
tx_length: .res 2
tx_ptr: .res 2
current_register:.res 1
current_byte_in_row: .res 1
register_page: .res 1
w5100_addr: .res 2
;-- LICENSE FOR test_ping.s --