diff --git a/client/basic/bails.d64 b/client/basic/bails.d64 index bd7db88..9807d69 100644 Binary files a/client/basic/bails.d64 and b/client/basic/bails.d64 differ diff --git a/client/basic/kipperbas.d64 b/client/basic/kipperbas.d64 index f7c4f27..9940325 100644 Binary files a/client/basic/kipperbas.d64 and b/client/basic/kipperbas.d64 differ diff --git a/client/drivers/w5100.i b/client/drivers/w5100.i index cf562b6..e9c8257 100644 --- a/client/drivers/w5100.i +++ b/client/drivers/w5100.i @@ -210,4 +210,20 @@ W5100_MODE_IP_RAW = $03 W5100_MODE_MAC_RAW = $04 W5100_MODE_PPPOE = $05 +;status +W5100_STATUS_SOCK_CLOSED = $00 +W5100_STATUS_SOCK_INIT = $13 +W5100_STATUS_SOCK_LISTEN = $14 +W5100_STATUS_SOCK_SYNSENT= $15 +W5100_STATUS_SOCK_SYNRECV= $16 +W5100_STATUS_SOCK_ESTABLISHED = $17 +W5100_STATUS_SOCK_FIN_WAIT = $18 +W5100_STATUS_SOCK_CLOSING = $1A +W5100_STATUS_SOCK_TIME_WAIT = $1B +W5100_STATUS_SOCK_CLOSE_WAIT = $1C +W5100_STATUS_SOCK_LAST_ACK = $1D +W5100_STATUS_SOCK_UDP = $22 +W5100_STATUS_SOCK_IPRAW = $32 +W5100_STATUS_SOCK_MACRAW = $42 +W5100_STATUS_SOCK_PPPOE = $5F diff --git a/client/drivers/w5100.s b/client/drivers/w5100.s index 9110498..8001a43 100644 --- a/client/drivers/w5100.s +++ b/client/drivers/w5100.s @@ -24,6 +24,8 @@ DEFAULT_W5100_BASE = $DF20 .import eth_outp_len .import timer_init + .import timer_read + .import arp_init .import ip_init .import cfg_init @@ -32,14 +34,28 @@ DEFAULT_W5100_BASE = $DF20 .importzp eth_src .importzp eth_type .importzp eth_data + .importzp copy_src .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 + + .export tcp_connect + .export tcp_connect_ip + .export tcp_callback + .export tcp_send_data_len + .export tcp_send_string + .export tcp_send + .export tcp_send_keep_alive + .export tcp_close + + + .export tcp_connect_remote_port + .export tcp_remote_ip + .export tcp_listen + + .export tcp_inbound_data_ptr + .export tcp_inbound_data_length .import cfg_mac .import cfg_ip @@ -47,7 +63,8 @@ DEFAULT_W5100_BASE = $DF20 .import cfg_gateway .import ip65_error - + .import ip65_process + .import check_for_abort_key .segment "IP65ZP" : zeropage @@ -73,9 +90,11 @@ w5100_init: stx set_lo+2 stx get_hi+2 stx get_lo+2 + stx inc_hi+2 + stx inc_lo+2 - stx w5100_read_next_byte+2 - stx w5100_write_next_byte+2 + stx read_register+2 + stx write_register+2 stx read_mode_reg+2 stx write_mode_reg+2 tax @@ -84,12 +103,16 @@ w5100_init: 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 w5100_read_next_byte+1 - stx w5100_write_next_byte+1 + stx read_register+1 + stx write_register+1 lda #$80 ;reset jsr write_mode_reg @@ -98,10 +121,10 @@ w5100_init: ;after a reset, mode register is zero ;therefore, if there is a real W5100 at the specified address, ;we should be able to write a $80 and read back a $00 - lda #$03 ;set indirect + autoincrement + lda #$11 ;set indirect mode, no autoinc, no auto PING jsr write_mode_reg jsr read_mode_reg - cmp #$03 + cmp #$11 bne @error ;make sure if we write to mode register without bit 7 set, ;the value persists. ldax #$0016 @@ -109,7 +132,7 @@ w5100_init: ldx #$00 ;start writing to reg $0016 - Interrupt Mask Register @loop: lda w5100_config_data,x - jsr w5100_write_next_byte + jsr write_reg_and_inc inx cpx #$06 bne @loop @@ -120,16 +143,12 @@ w5100_init: @mac_loop: lda cfg_mac,x - jsr w5100_write_next_byte + jsr write_reg_and_inc inx cpx #$06 bne @mac_loop - - ;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 - + ;set up socket 0 for MAC RAW mode ldax #W5100_RMSR ;rx memory size (each socket) ldy #$0A ;sockets 0 & 1 4KB each, other sockets 0KB @@ -150,6 +169,9 @@ w5100_init: ldax #W5100_S0_CR ldy #W5100_CMD_OPEN jsr w5100_write_register + + lda #0 + sta tcp_connected clc rts @@ -190,6 +212,20 @@ w5100_ip65_init: ; and eth_inp_len contains the length of the packet eth_rx: + ;eth_rx will get called in the main polling loop + ;we shoe horn a check for data on the TCP socket here + ;if we do get TCP data, we will call the TCP callback routine + ;but we hide all of this from the ip65 stack proper. + lda tcp_connected + beq @no_tcp + + jsr tcp_rx + bcc @no_tcp ;if we didn't get any TCP traffic, go check for a raw ethernet packet + ;eth_inp and eth_inp_len are not valid, so leave carry flag set to indicate no ethernet frame data + rts + +@no_tcp: + ldax #W5100_S0_RX_RSR0 jsr w5100_read_register sta eth_inp_len+1 @@ -213,40 +249,18 @@ eth_rx: 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: @@ -267,22 +281,6 @@ eth_rx: 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 @@ -432,7 +430,7 @@ advance_eth_ptr: ; y is overwritten w5100_read_register: jsr w5100_select_register - jmp w5100_read_next_byte + jmp read_register ; write to one of the W5100 registers ; inputs: AX = register number to write @@ -441,9 +439,482 @@ w5100_read_register: w5100_write_register: jsr w5100_select_register tya - jmp w5100_write_next_byte + jmp write_register + + +;listen for an inbound tcp connection +;this is a 'blocking' call, i.e. it will not return until a connection has been made +;inputs: +; AX: destination port (2 bytes) +; tcp_callback: vector to call when data arrives on this connection +;outputs: +; carry flag is set if an error occured, clear otherwise +tcp_listen: + + stax tcp_local_port + jsr setup_tcp_socket + ldax #W5100_S1_CR + ldy #W5100_CMD_LISTEN + jsr w5100_write_register + + ;now wait for the status to change to 'established' +@listen_loop: + inc $d020 + jsr ip65_process + jsr check_for_abort_key + bcc @no_abort + lda #KPR_ERROR_ABORTED_BY_USER + sta ip65_error + sec + rts +@no_abort: + ldax #W5100_S1_SR + jsr w5100_read_register + cmp #W5100_STATUS_SOCK_ESTABLISHED + bne @listen_loop + inc tcp_connected + + ;copy the remote IP address & port number + ldax #W5100_S1_DIPR0 + jsr w5100_select_register + ldx #0 +@ip_loop: + jsr read_reg_and_inc + sta tcp_remote_ip,x + inx + cpx #$04 + bne @ip_loop + + ldax #W5100_S1_DPORT0 + jsr w5100_select_register + jsr read_reg_and_inc + sta tcp_connect_remote_port+1 + jsr read_reg_and_inc + sta tcp_connect_remote_port + + clc + rts + + +;make outbound tcp connection +;inputs: +; tcp_connect_ip: destination ip address (4 bytes) +; AX: destination port (2 bytes) +; tcp_callback: vector to call when data arrives on this connection +;outputs: +; carry flag is set if an error occured, clear otherwise +tcp_connect: + stax tcp_remote_port + jsr timer_read ;get a pseudo random value + sta tcp_local_port+1 + inc tcp_local_port + + + jsr setup_tcp_socket + + + ;set the destination IP address + ldax #W5100_S1_DIPR0 + jsr w5100_select_register + ldx #0 +@remote_ip_loop: + lda tcp_connect_ip,x + jsr write_reg_and_inc + inx + cpx #$04 + bne @remote_ip_loop + ldx #0 + +;W5100 register address is now W5100_S1_DPORT0, so set the destination port + lda tcp_remote_port+1 + jsr write_reg_and_inc + lda tcp_remote_port + jsr write_reg_and_inc + + ldax #W5100_S1_CR + ldy #W5100_CMD_CONNECT + jsr w5100_write_register + + ;now wait for the status to change to 'established' +@connect_loop: + ldax #W5100_S1_SR + jsr w5100_read_register + cmp #W5100_STATUS_SOCK_CLOSED + beq @error + cmp #W5100_STATUS_SOCK_ESTABLISHED + beq @ok + + jsr check_for_abort_key + bcc @connect_loop + lda #KPR_ERROR_ABORTED_BY_USER + jmp @set_error_and_exit + +@ok: + inc tcp_connected + clc + rts +@error: + lda #KPR_ERROR_CONNECTION_CLOSED +@set_error_and_exit: + sta ip65_error + sec + rts + +;send a string over the current tcp connection +;inputs: +; tcp connection should already be opened +; AX: pointer to buffer - data up to (but not including) +; the first nul byte will be sent. max of 255 bytes will be sent. +;outputs: +; carry flag is set if an error occured, clear otherwise +tcp_send_string: + stax tcp_send_data_ptr + stax copy_src + lda #0 + tay + sta tcp_send_data_len + sta tcp_send_data_len+1 + lda (copy_src),y + bne @find_end_of_string + rts ; if the string is empty, don't send anything! +@find_end_of_string: + lda (copy_src),y + beq @done + inc tcp_send_data_len + iny + bne @find_end_of_string +@done: + ldax tcp_send_data_ptr + ;now we can fall through into tcp_send + +;send tcp data +;inputs: +; tcp connection should already be opened +; tcp_send_data_len: length of data to send (exclusive of any headers) +; AX: pointer to buffer containing data to be sent +;outputs: +; carry flag is set if an error occured, clear otherwise +tcp_send: + stax tcp_send_data_ptr + + ;are we connected? + ldax #W5100_S1_SR + jsr w5100_read_register + cmp #W5100_STATUS_SOCK_ESTABLISHED + beq @ok + + lda #KPR_ERROR_CONNECTION_CLOSED + sta ip65_error + sec + rts +@ok: + + + lda #$AD ;opcode for LDA + sta next_eth_packet_byte + + 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 #$50 + sta tx_wr_ptr+1 +: + + lda byte_ctr_lo + cmp tcp_send_data_len + bne @send_next_byte + lda byte_ctr_hi + cmp tcp_send_data_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 tcp_send_data_len + sta tx_wr_ptr + lda tx_wr_ptr+1 + adc tcp_send_data_len+1 + tay + ldax #W5100_S1_TX_WR0 + jsr w5100_write_register + ldy tx_wr_ptr + ldax #W5100_S1_TX_WR1 + jsr w5100_write_register + ldax #W5100_S1_CR + ldy #W5100_CMD_SEND + jsr w5100_write_register + + clc + rts + +@get_current_tx_wr: + ldax #W5100_S1_TX_WR0 + jsr w5100_read_register + sta tx_wr_ptr+1 + ldax #W5100_S1_TX_WR1 + jsr w5100_read_register + sta tx_wr_ptr + rts + +;send an empty ACK packet on the current connection +;inputs: +; none +;outputs: +; carry flag is set if an error occured, clear otherwise + +tcp_send_keep_alive: + ;are we connected? + ldax #W5100_S1_SR + jsr w5100_read_register + cmp #W5100_STATUS_SOCK_ESTABLISHED + beq @ok + + lda #KPR_ERROR_CONNECTION_CLOSED + sta ip65_error + sec + rts +@ok: + ldax #W5100_S1_CR + ldy #W5100_CMD_SEND_KEEP + jsr w5100_write_register + clc + rts + + + + +;close the current connection +;inputs: +; none +;outputs: +; carry flag is set if an error occured, clear otherwise +tcp_close: + + ldax #W5100_S1_CR + ldy #W5100_CMD_DISCONNECT + jsr w5100_write_register + clc + rts + + +;poll the TCP socket +;if there is data available, call the user supplied TCP callback +;inputs: +; none +;outputs: +; carry flag is set if there was data, clear otherwise +tcp_rx: + + ;is there data? + ldax #W5100_S1_RX_RSR0 + jsr w5100_read_register + sta tcp_inbound_data_length+1 + ldax #W5100_S1_RX_RSR1 + jsr w5100_read_register + sta tcp_inbound_data_length + bne @got_data + lda tcp_inbound_data_length+1 + bne @got_data + + ;are we connected? + ldax #W5100_S1_SR + jsr w5100_read_register + cmp #W5100_STATUS_SOCK_ESTABLISHED + beq @connected_but_no_data + ;no longer connected + lda #0 + sta tcp_connected + + lda #$ff + sta tcp_inbound_data_length + sta tcp_inbound_data_length+1 + jsr jmp_to_callback ;let the caller see the connection has closed + sec ;don't poll the MAC RAW socket, else it may clobber the output buffer + rts +@connected_but_no_data: + clc ;no data - go check the MAC RAW socket + rts +@got_data: + lda #$8D ;opcode for STA + sta next_eth_packet_byte + + ldax #eth_inp+$36 ;we will write to the location that TCP data would appear if this was a raw eth frame, + ;14 bytes of ethernet header + ;20 bytes of IP header + ;20 bytes of TCP header + + stax tcp_inbound_data_ptr + sta eth_ptr_lo + stx eth_ptr_hi + lda #0 + sta byte_ctr_lo + sta byte_ctr_hi + + lda tcp_inbound_data_length+1 + cmp #4 ;don't allow more than $4FF bytes at once ($1279) since we are writing to a 1500 byte + bmi :+ + lda #4 + sta tcp_inbound_data_length+1 +: + + ;now copy the data just arrived to the eth_inp buffer + jsr @get_current_rx_rd + jsr @mask_and_adjust_rx_read +@get_next_byte: + + ldax rx_rd_ptr + jsr w5100_read_register + jsr next_eth_packet_byte + + jsr @inc_rx_rd_ptr + + inc byte_ctr_lo + bne :+ + inc byte_ctr_hi +: + + lda byte_ctr_lo + cmp tcp_inbound_data_length + bne @get_next_byte + lda byte_ctr_hi + cmp tcp_inbound_data_length+1 + bne @get_next_byte + + +;update the RX RD pointer past the frame we just read + jsr @get_current_rx_rd + clc + lda rx_rd_ptr + adc tcp_inbound_data_length + sta rx_rd_ptr + lda rx_rd_ptr+1 + adc tcp_inbound_data_length+1 + tay + ldax #W5100_S1_RX_RD0 + jsr w5100_write_register + ldy rx_rd_ptr + + ldax #W5100_S1_RX_RD1 + jsr w5100_write_register + ldax #W5100_S1_CR + ldy #W5100_CMD_RECV + jsr w5100_write_register + + + jsr jmp_to_callback ;let the caller see the connection has closed + sec ;don't poll the MAC RAW socket, else it may clobber the output buffer + 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 #$70 + sta rx_rd_ptr+1 +: + rts + +@get_current_rx_rd: + ldax #W5100_S1_RX_RD0 + jsr w5100_read_register + sta rx_rd_ptr+1 + ldax #W5100_S1_RX_RD1 + jsr w5100_read_register + sta rx_rd_ptr + rts + +jmp_to_callback: + jmp (tcp_callback) + + +;copy the IP65 configuration to the the w5100 onchip configuration +;we assume MAC has been configured already via eth_init, but IP +;address etc may not be known when the w5100 was initialised (e.g. +;if using DHCP). +setup_tcp_socket: + ldax #W5100_GAR0 + jsr w5100_select_register + ldx #0 +@gateway_loop: + lda cfg_gateway,x + jsr write_reg_and_inc + inx + cpx #$04 + bne @gateway_loop + ldx #0 +@netmask_loop: + lda cfg_netmask,x + jsr write_reg_and_inc + inx + cpx #$04 + bne @netmask_loop + + ldax #W5100_SIPR0 + jsr w5100_select_register + ldx #0 +@ip_loop: + lda cfg_ip,x + jsr write_reg_and_inc + inx + cpx #$04 + bne @ip_loop + + ldax #W5100_S1_PORT0 + jsr w5100_select_register + lda tcp_local_port+1 + jsr write_reg_and_inc + lda tcp_local_port + jsr write_reg_and_inc + + lda #0 + sta tcp_connected + + ldax #W5100_S1_MR + ldy #W5100_MODE_TCP + jsr w5100_write_register + + ;open socket 1 + ldax #W5100_S1_CR + ldy #W5100_CMD_OPEN + jsr w5100_write_register + rts + +write_reg_and_inc: + jsr write_register + jmp inc_register + +read_reg_and_inc: + jsr read_register + jmp inc_register + .rodata eth_driver_name: .asciiz "WIZNET 5100" @@ -481,18 +952,28 @@ get_lo: ; 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: +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) -w5100_write_next_byte: +write_register: sta $FFFF ;WIZNET_DATA rts +inc_register: +inc_lo: + inc $FFFF ;WIZNET_ADDR_LO + bne :+ +inc_hi: + inc $FFFF ;WIZNET_ADDR_HI +: + rts + + read_mode_reg: lda $FFFF ;WIZNET_BASE rts @@ -507,6 +988,8 @@ next_eth_packet_byte: eth_ptr_lo=next_eth_packet_byte+1 eth_ptr_hi=next_eth_packet_byte+2 + + .bss w5100_addr: .res 2 byte_ctr_lo: .res 1 @@ -514,9 +997,25 @@ eth_ptr_hi=next_eth_packet_byte+2 tx_wr_ptr: .res 2 rx_rd_ptr: .res 2 - - - +tcp_local_port: .res 2 + +tcp_connected: .res 1 + +tcp_connect_ip: .res 4 ;ip address of remote server to connect to +tcp_callback: .res 2 ;vector to routine to be called when data is received over tcp connection + +tcp_remote_port: .res 2 ;temp space for holding port to listen on or connect to +tcp_send_data_len: .res 2 +tcp_send_data_ptr = eth_ptr_lo + + +tcp_inbound_data_ptr: .res 2 +tcp_inbound_data_length: .res 2 + +tcp_connect_remote_port: .res 2 +tcp_remote_ip = tcp_connect_ip + + ;-- LICENSE FOR w5100a.s -- ; The contents of this file are subject to the Mozilla Public License ; Version 1.1 (the "License"); you may not use this file except in diff --git a/client/ip65/Makefile b/client/ip65/Makefile index 41528e3..ba0fcdf 100644 --- a/client/ip65/Makefile +++ b/client/ip65/Makefile @@ -52,10 +52,10 @@ ip65_tcp.lib: tcp.o $(ETHOBJS) function_dispatcher.s tcp.s ar65 a ip65_tcp.lib $(ETHOBJS) function_dispatcher.o tcp.o ip65_wiznet.lib: $(ETHOBJS) function_dispatcher.s - $(AS) $(AFLAGS) function_dispatcher.s -DTCP -DAPI_VERSION=2 - $(AS) $(AFLAGS) ip.s -DTCP + $(AS) $(AFLAGS) function_dispatcher.s + $(AS) $(AFLAGS) ip.s $(AS) $(AFLAGS) icmp.s -DTCP - ar65 a ip65_wiznet.lib $(ETHOBJS) function_dispatcher.o tcp.o + ar65 a ip65_wiznet.lib $(ETHOBJS) function_dispatcher.o clean: rm -f *.o diff --git a/client/ip65/icmp.s b/client/ip65/icmp.s index c3ae190..71db15e 100644 --- a/client/ip65/icmp.s +++ b/client/ip65/icmp.s @@ -369,6 +369,7 @@ icmp_ping: jsr timer_read ; read current timer value stax ping_timer @loop_during_arp_lookup: + jsr ip65_process ldax ping_timer adc #50 ; set timeout to now + 50 ms diff --git a/client/ip65/tcp.s b/client/ip65/tcp.s index 771db04..a289f65 100644 --- a/client/ip65/tcp.s +++ b/client/ip65/tcp.s @@ -126,7 +126,7 @@ tcp_callback: .res 2 ;vector to routine to be called when data is received over tcp_flags: .res 1 tcp_fin_sent: .res 1 -tcp_listen_port: .res 1 +tcp_listen_port: .res 2 tcp_inbound_data_ptr: .res 2 ;pointer to data just recieved over tcp connection tcp_inbound_data_length: .res 2 ;length of data just received over tcp connection @@ -387,7 +387,7 @@ tcp_close: rts -tcp_send_string: + ;send a string over the current tcp connection ;inputs: ; tcp connection should already be opened @@ -395,7 +395,7 @@ tcp_send_string: ; the first nul byte will be sent. max of 255 bytes will be sent. ;outputs: ; carry flag is set if an error occured, clear otherwise - +tcp_send_string: stax tcp_send_data_ptr stax copy_src lda #0 @@ -414,14 +414,16 @@ tcp_send_string: @done: ldax tcp_send_data_ptr ;now we can fall through into tcp_send -tcp_send: + + ;send tcp data ;inputs: ; tcp connection should already be opened ; tcp_send_data_len: length of data to send (exclusive of any headers) ; AX: pointer to buffer containing data to be sent ;outputs: -; carry flag is set if an error occured, clear otherwise +; carry flag is set if an error occured, clear otherwise +tcp_send: stax tcp_send_data_ptr diff --git a/client/ip65/telnet.s b/client/ip65/telnet.s index cd28f02..26c1774 100644 --- a/client/ip65/telnet.s +++ b/client/ip65/telnet.s @@ -29,6 +29,7 @@ .import ip65_process .import get_key_if_available .import get_filtered_input + .import check_for_abort_key .import ok_msg .import failed_msg .import print @@ -93,6 +94,12 @@ telnet_connect: @main_polling_loop: + jsr check_for_abort_key + bcc @no_abort + jsr tcp_close + jmp @disconnected + +@no_abort: jsr timer_read txa adc #$20 ;32 x 1/4 = ~ 8seconds @@ -107,6 +114,7 @@ telnet_connect: jsr ip65_process lda connection_closed beq @not_disconnected +@disconnected: ldax #disconnected jsr print rts diff --git a/client/kipperterm2/Makefile b/client/kipperterm2/Makefile index 2066aab..ce7d755 100644 --- a/client/kipperterm2/Makefile +++ b/client/kipperterm2/Makefile @@ -12,12 +12,14 @@ INCFILES=\ ../inc/version.i\ IP65LIB=../ip65/ip65.lib - IP65TCPLIB=../ip65/ip65_tcp.lib - C64RRNETLIB=../drivers/c64rrnet.lib +IP65WIZNETLIB=../ip65/ip65_wiznet.lib +C64WIZNETLIB=../drivers/c64wiznet.lib + + +all: ip65 drivers kipperterm2.prg kipperterm2wiz.prg kipperterm2.d64 -all: kipperterm2.prg kipperterm2.d64 kipperterm2.o: kipperterm2.s $(INCFILES) ../inc/telnet.i ../inc/config_menu.i ../inc/gopher.i $(AS) $(AFLAGS) -o $@ $< @@ -29,8 +31,14 @@ kipperterm2.o: kipperterm2.s $(INCFILES) ../inc/telnet.i ../inc/config_menu.i .. $(LD) -m $*.map -vm -C ../cfg/c64fullprg.cfg -o $*.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64RRNETLIB) ruby ../carts/set_ip_config.rb $@ mac auto -kipperterm2.d64: kipperterm2.prg addresses.txt abe.bas +kipperterm2wiz.prg: kipperterm2.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64fullprg.cfg + $(LD) -m kipperterm2wiz.map -vm -C ../cfg/c64fullprg.cfg -o kipperterm2wiz.prg $(AFLAGS) $< $(IP65WIZNETLIB) $(C64WIZNETLIB) + cp kipperterm2wiz.prg ../../server/boot/autoexec.prg + + +kipperterm2.d64: kipperterm2.prg kipperterm2wiz.prg addresses.txt abe.bas ripxplore.rb --init CbmDos $@ -a kipperterm2.prg + ripxplore.rb $@ -a kipperterm2wiz.prg -t C64Prg ripxplore.rb $@ -a 80columns -t C64Prg ripxplore.rb $@ -a addresses.txt -t C64Seq ripxplore.rb $@ -a abe -t C64Prg @@ -41,3 +49,9 @@ clean: distclean: clean rm -f *~ + +ip65: + make -C ../ip65 all + +drivers: + make -C ../drivers all diff --git a/client/test/test_wiznet.s b/client/test/test_wiznet.s index 2b0592f..415e935 100644 --- a/client/test/test_wiznet.s +++ b/client/test/test_wiznet.s @@ -1,23 +1,36 @@ - .include "../inc/common.i" - .include "../inc/commonprint.i" - .include "../inc/net.i" - .include "../drivers/w5100.i" + .include "../inc/common.i" + .include "../inc/commonprint.i" + .include "../inc/net.i" + .include "../drivers/w5100.i" + + .import exit_to_basic + + .import cfg_get_configuration_ptr + .import copymem + .importzp copy_src + .importzp copy_dest + .import icmp_echo_ip + .import icmp_ping + .import get_key_ip65 + .import w5100_ip65_init + .import w5100_read_register + .import dns_set_hostname + .import dns_resolve + .import dns_ip + .import dns_status - .import exit_to_basic - - .import cfg_get_configuration_ptr - .import copymem - .importzp copy_src - .importzp copy_dest - .import icmp_echo_ip - .import icmp_ping - .import get_key - .import w5100_ip65_init - - .import dns_set_hostname - .import dns_resolve - .import dns_ip - .import dns_status + .import tcp_connect + .import tcp_connect_ip + .import tcp_callback + .import tcp_send_string + .import tcp_close + .import tcp_inbound_data_ptr + .import tcp_inbound_data_length + .import tcp_connect_remote_port + .import tcp_remote_ip + .import tcp_listen + .importzp acc16 + .import cmp_16_16 .segment "STARTUP" ;this is what gets put at the start of the file on the C64 @@ -39,8 +52,8 @@ basicstub: .code init: - -; jsr wait_for_keypress + + ldax #$DE00 jsr probe_for_w5100 bcc @found @@ -54,34 +67,150 @@ init: jmp print rts -@found: - jsr dhcp_init +@found: + jsr dhcp_init + lda #0 + jsr dump_wiznet_register_page + lda #4 + jsr dump_wiznet_register_page @skip: jsr print_ip_config -; jsr wait_for_keypress -; -; rts -; -; jsr wait_for_keypress -; jsr dhcp_init -; jsr print_ip_config -; print_driver_init -; jsr ip65_init -; jsr print_cr jsr ping_test jsr ping_test_2 + jsr tcp_listen_test + ldax #hostname_1 jsr do_dns_query bcs :+ jsr ping_test_3 + jsr tcp_test : rts + + +tcp_listen_test: + ldax #tcp_callback_routine + stax tcp_callback + ldax #listening + jsr print + ldax #80 + + jsr tcp_listen + bcc :+ + ldax #error + jsr print + lda ip65_error + jsr print_hex + jsr print_cr + rts +: + + ldax #connection_from + jsr print + ldax #tcp_remote_ip + jsr print_dotted_quad + lda #':' + jsr print_a + ldax tcp_connect_remote_port + jsr print_integer + jsr print_cr + jmp send_tcp_data + +tcp_test: + + ldax #tcp_callback_routine + stax tcp_callback + + ;send without connecting - should get an error + ldax #http_string1 + jsr tcp_send_string + bcc :+ + ldax #error + jsr print + lda ip65_error + jsr print_hex + jsr print_cr +: + ldx #$3 +: + lda dns_ip,x + sta tcp_connect_ip,x + dex + bpl :- + ldax #connecting + jsr print + + ldax #tcp_connect_ip + jsr print_dotted_quad + jsr print_cr + + + ldax #80 ;port number + + jsr tcp_connect + bcc @no_error + ldax #error + jsr print + lda ip65_error + jsr print_hex + jsr print_cr + lda #0 + jsr dump_wiznet_register_page + lda #5 + jsr dump_wiznet_register_page + + rts +@no_error: + +send_tcp_data: + lda #0 + sta cxn_closed + + ldax #sending + jsr print + ldax #http_string1 + jsr print + ldax #http_string1 + jsr tcp_send_string + bcc @ok1 + +@error: + ldax #error + jsr print + lda ip65_error + jsr print_hex + jsr print_cr +@done: + lda #0 + jsr dump_wiznet_register_page + lda #5 + jsr dump_wiznet_register_page + + rts + + @ok1: + ldax #sending + jsr print + ldax #http_string2 + jsr print + ldax #http_string2 + jsr tcp_send_string + bcs @error +@poll_loop: + jsr ip65_process + lda cxn_closed + beq @poll_loop + jsr tcp_close + ldax #EOF + jsr print + + jmp @done ping_test: ldx #$3 @@ -147,28 +276,33 @@ wait_for_keypress: sta $c6 ;set the keyboard buffer to be empty ldax #press_a_key_to_continue jsr print - jsr get_key + jsr get_key_ip65 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 + 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 + lda #0 + jsr dump_wiznet_register_page + lda #5 + jsr dump_wiznet_register_page + + sec + rts : ldax #dns_ip jsr print_dotted_quad @@ -176,17 +310,121 @@ do_dns_query: clc rts + +dump_wiznet_register_page: + sta register_page + lda #0 + sta current_register + jsr print_cr + +@one_row: + lda current_register + cmp #$20 + 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 + + +tcp_callback_routine: + + lda tcp_inbound_data_length + cmp #$ff + bne @not_end_of_file + lda #1 + sta cxn_closed + rts + +@not_end_of_file: + lda #14 + jsr print_a ;switch to lower case + + ldax tcp_inbound_data_ptr + stax get_next_byte+1 + + lda #0 + sta byte_counter + sta byte_counter+1 + +@print_one_byte: + jsr get_next_byte + jsr ascii_to_native + + jsr print_a + inc get_next_byte+1 + bne :+ + inc get_next_byte+2 +: + + inc byte_counter + bne :+ + inc byte_counter+1 +: + ldax byte_counter + stax acc16 + ldax tcp_inbound_data_length + jsr cmp_16_16 + bne @print_one_byte + + rts + +get_next_byte: + lda $ffff + rts + .rodata ms: .byte " MS",13,0 pinging: .byte "PINGING ",0 +connecting: .byte "CONNECTING ",0 +sending: .byte "SENDING ",0 hello: .byte "HELLO WORLD!",13,10,0 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 +error: .byte "ERROR $",0 +ok: .byte "OK",13,0 +EOF: .byte "CONNECTION CLOSED",13,0 +listening: .byte "LISTENING ON PORT 80",13,0 +http_string1: .byte "GET ",0 +connection_from: .byte "CONNECTION FROM ",0 +http_string2: .byte "/ HTTP/1.0",13,10,13,10,0 .bss w5100_addr: .res 2 +current_register:.res 1 +current_byte_in_row: .res 1 +register_page: .res 1 +cxn_closed: .res 1 +byte_counter: .res 2 + ;-- LICENSE FOR test_ping.s --