From 25aaee5a663cbd597df76ac0a8bfa18f5cc2b502 Mon Sep 17 00:00:00 2001 From: jonnosan Date: Mon, 9 Aug 2010 12:05:15 +0000 Subject: [PATCH] git-svn-id: http://svn.code.sf.net/p/netboot65/code@265 93682198-c243-4bdb-bd91-e943c89aac3b --- client/Makefile | 14 +- client/basic/kipperbas.d64 | Bin 174848 -> 174848 bytes client/basic/kipperbas.s | 298 +++++++++++++++++++++++++++++++++---- client/ip65/tcp.s | 6 + client/ip65/telnet.s | 2 +- doc/CHANGES.txt | 3 + 6 files changed, 295 insertions(+), 28 deletions(-) diff --git a/client/Makefile b/client/Makefile index a7bbbbe..ff7f533 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,10 +1,10 @@ TARGET=c64 -.PHONY: ip65 drivers test clean distclean carts examples +.PHONY: ip65 drivers test clean distclean carts examples basic kipperterm2 -all: ip65 drivers test carts examples +all: ip65 drivers test carts examples basic kipperterm2 ip65: make -C ip65 all @@ -20,16 +20,26 @@ test: carts: make -C carts all + +basic: + make -C basic all + +kipperterm2: + make -C kipperterm2 all clean: make -C ip65 clean make -C drivers clean make -C test clean make -C carts clean + make -C kipperterm2 clean + make -C basic clean distclean: make -C ip65 distclean make -C drivers clean make -C test distclean make -C carts distclean + make -C kipperterm2 distclean + make -C basic distclean rm -f *~ diff --git a/client/basic/kipperbas.d64 b/client/basic/kipperbas.d64 index c064736e5065a94a5477a99f4dfe403d444b7bbc..951fc3d5b9c6c549618f9592338e75ae463cf286 100644 GIT binary patch literal 174848 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 literal 174848 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 +@skip: jsr CHROUT iny bne @done @@ -547,10 +562,9 @@ get_ip_parameter: jsr dns_resolve bcc @ok @error: - ldax #dns_error - jsr print - sec - rts + ldax #address_resolution + jmp print_error + @ok: ldax #dns_ip ldx #4 @@ -562,11 +576,16 @@ get_ip_parameter: bne @copy_dns_ip rts -print_dotted_quad: + +reset_string: ldy #string_buffer sty current_output_ptr+1 + rts + +print_dotted_quad: + jsr reset_string jsr emit_dotted_quad make_null_terminated_and_print: lda #0 @@ -575,10 +594,7 @@ make_null_terminated_and_print: jmp print print_mac: - ldy #string_buffer - sty current_output_ptr+1 + jsr reset_string jsr emit_mac jmp make_null_terminated_and_print @@ -619,6 +635,22 @@ emit_hex: jsr emit_a pla rts + +print_hex: + jsr reset_string + jsr emit_hex + jmp make_null_terminated_and_print + +print_error: + jsr print + ldax #error + jsr print + lda ip65_error + jsr print_hex + jsr print_cr + jsr set_error + sec + rts get_optional_byte: jsr CHRGOT @@ -631,6 +663,7 @@ get_optional_byte: rts @eol: jmp $AF08 ;SYNTAX ERROR + ipcfg_keyword: ldax #interface_type @@ -692,8 +725,8 @@ dhcp_keyword: @init_failed: jsr set_error - ldax #dhcp_error - jmp print + ldax #dhcp + jmp print_error @init_ok: jmp clear_error rts @@ -819,9 +852,9 @@ tfget_keyword: jsr tftp_download after_tftp_xfer: bcc @no_error - ldax #tftp_error + ldax #tftp @error_set: - jsr print + jsr print_error @no_error: jsr close_file jmp set_error @@ -944,6 +977,198 @@ tftp_upload_callback: ldax bytes_read rts +skip_comma_get_integer: + jsr CHRGOT + jsr CHKCOM ;make sure next char is a comma (and skip it) +get_integer: + jsr CHRGOT + beq @eol + jsr FRMNUM + jsr GETADR + ldax LINNUM +@no_param: + rts +@eol: + jmp $AF08 ;SYNTAX ERROR + + +make_tcp_connection: + ldax #tcp_connect_ip + jsr get_ip_parameter + bcc @no_error + rts +@no_error: + jsr skip_comma_get_integer + jsr tcp_connect + bcc :+ +@connect_error: + ldax #connect + jmp print_error + +: + ldax #connected_msg + jsr print + lda #0 + sta connection_closed + clc + rts + +netcat_keyword: + ldax #netcat_callback + stax tcp_callback + jsr make_tcp_connection + bcc @main_polling_loop + rts + +@main_polling_loop: + jsr timer_read + txa + adc #$20 ;32 x 1/4 = ~ 8seconds + sta netcat_timeout +@wait_for_keypress: + jsr timer_read + cpx netcat_timeout + bne @no_timeout + jsr tcp_send_keep_alive + jmp @main_polling_loop +@no_timeout: + jsr ip65_process + lda connection_closed + beq @not_disconnected + ldax #disconnected + jsr print + rts +@not_disconnected: + + jsr get_key_if_available + beq @wait_for_keypress + + ldx #1 + stx tcp_send_data_len + dex + stx tcp_send_data_len+1 + + sta transfer_buffer + +@send_char: + + ldax #transfer_buffer + jsr tcp_send + bcs @error_on_send + jmp @main_polling_loop + +@error_on_send: + ldax #transmission + jmp print_error + + +netcat_callback: + lda tcp_inbound_data_length+1 + cmp #$ff + bne @not_eof + lda #1 + sta connection_closed + rts +@not_eof: + + ldax tcp_inbound_data_ptr + stax temp2 + lda tcp_inbound_data_length + sta buffer_length + lda tcp_inbound_data_length+1 + sta buffer_length+1 + +@next_byte: + ldy #0 + lda (temp2),y + jsr print_a + inc temp2 + bne :+ + inc temp2+1 +: + lda buffer_length+1 + beq @last_page + lda buffer_length + bne @not_end_of_page + dec buffer_length+1 +@not_end_of_page: + dec buffer_length + jmp @next_byte +@last_page: + dec buffer_length + beq @finished + + jmp @next_byte + +@finished: + + rts + + +tcpconnect_keyword: + lda #0 + sta data_arrived_flag + ldax #tcpconnect_callback + stax tcp_callback + jmp make_tcp_connection + +tcpconnect_callback: + inc data_arrived_flag + ldax #transfer_buffer + stax copy_dest + ldax tcp_inbound_data_ptr + stax copy_src + lda tcp_inbound_data_length + ldx tcp_inbound_data_length+1 + beq @short_packet + cpx #$ff + bne @not_end_packet + inc data_arrived_flag + rts +@not_end_packet: + lda #$ff +@short_packet: + +set_input_string: + pha + lda #'I' + sta VARNAM + lda #'N'+$80 + sta VARNAM+1 + jsr safe_getvar + ldy #0 + pla + pha + sta (VARPNT),y + iny + lda #transfer_buffer + sta (VARPNT),y + pla + beq :+ + ldx #0 + jsr copymem +: + rts + +poll_keyword: + ldax #$FFFF + jsr set_result_code + lda #0 + sta data_arrived_flag + jsr set_input_string + jsr ip65_process + lda ip65_error + beq @no_error + jmp set_error +@no_error: + lda data_arrived_flag + ldx #0 + jmp set_result_code + + .rodata vectors: .word crunch @@ -984,17 +1209,33 @@ dhcp_server_msg: tftp_server_msg: .byte "TFTP SERVER : ", 0 -dns_error: -.byte "ADDRESS RESOLUTION ERROR",0 +address_resolution: +.byte "ADDRESS RESOLUTION",0 + get_msg: .byte "GETTING ",0 put_msg: .byte "PUTTING ",0 -tftp_error: -.byte "TFTP ERROR",0 -dhcp_error: -.byte "DHCP INITIALIZATION ERROR",13,0 +tftp: +.byte "TFTP",0 +dhcp: +.byte "DHCP",0 + +connect: +.byte "CONNECT",0 + +transmission: +.byte "TRANSMISSION",0 + +error: +.byte " ERROR $",0 + +disconnected: +.byte "DIS" +connected_msg: +.byte "CONNECTED",13,0 + keywords: .byte "IF",$E0 ;our dummy 'IF' entry takes $E0 .byte "IPCFG",$E1 @@ -1005,12 +1246,13 @@ keywords: .byte "GATEWAY",$E6 .byte "DNS",$E7 .byte "TFTP",$E8 - .byte "TFGET",$E9 - .byte "TF",$A1,$E9 ;since BASIC will replace GET with A1 + .byte "TF",$A1,$E9 ;TFGET - BASIC will replace GET with A1 .byte "TFPUT",$EA - + .byte "NETCAT",$EB + .byte "TCPC",$91,"NECT",$EC ; TCPCONNECT BASIC will replace ON with 91 + .byte "POLL",$ED .byte $00 ;end of list -HITOKEN=$EB +HITOKEN=$EE ; ; Table of token locations-1 @@ -1027,6 +1269,9 @@ E7: .word dns_keyword-1 E8: .word tftp_keyword-1 E9: .word tfget_keyword-1 EA: .word tfput_keyword-1 +EB: .word netcat_keyword-1 +EC: .word tcpconnect_keyword-1 +ED: .word poll_keyword-1 .segment "SELF_MODIFIED_CODE" @@ -1062,4 +1307,7 @@ ping_counter: .res 1 string_buffer: .res 128 transfer_buffer: .res 256 file_opened: .res 1 - \ No newline at end of file +connection_closed: .res 1 +netcat_timeout: .res 1 +buffer_length: .res 1 +data_arrived_flag: .res 1 \ No newline at end of file diff --git a/client/ip65/tcp.s b/client/ip65/tcp.s index 2406c7f..f00b92d 100644 --- a/client/ip65/tcp.s +++ b/client/ip65/tcp.s @@ -281,6 +281,12 @@ tcp_connect: sec ;signal an error rts @got_a_response: + lda tcp_state + cmp #tcp_cxn_state_closed + bne @was_accepted + sec ;if we got here, then the other side sent a RST or FIN, so signal an error to the caller + rts +@was_accepted: tcp_connection_established: ;inc the sequence number to cover the SYN we have sent ldax #tcp_connect_sequence_number diff --git a/client/ip65/telnet.s b/client/ip65/telnet.s index a63dab4..cd28f02 100644 --- a/client/ip65/telnet.s +++ b/client/ip65/telnet.s @@ -181,7 +181,7 @@ telnet_connect: @error_on_send: ldax #transmission_error jsr print - jsr print_errorcode + jmp print_errorcode ;tcp callback - will be executed whenever data arrives on the TCP connection diff --git a/doc/CHANGES.txt b/doc/CHANGES.txt index 63ec927..f0787c1 100644 --- a/doc/CHANGES.txt +++ b/doc/CHANGES.txt @@ -1,5 +1,8 @@ + v1.0.33 - FIX: gracefully close the TCP connection when a telnet connection is aborted by user keystroke + - FIX: telnet client was reprocessing last received packet after an error (including user abort) + - FIX: was not signalling an error when a RST or FIN was sent back to tcp_connect v1.0.32 - CHANGE: when loading cart images from disk, set default drive for cart image to be whatever drive the cart