diff --git a/client/carts/Makefile b/client/carts/Makefile index be1a3cc..832ac8a 100644 --- a/client/carts/Makefile +++ b/client/carts/Makefile @@ -18,12 +18,15 @@ IP65TCPLIB=../ip65/ip65_tcp.lib C64PROGLIB=../drivers/c64prog.lib #C64NB65LIB=../drivers/c64nb65.lib -all: kipperkart.bin kipperkart_rr.bin netboot.bin kipperterm.bin kipperkart.prg kipperterm.prg +all: kipperkart.bin kipperkart_rr.bin netboot.bin kipperterm.bin kipperkart.prg kipperterm.prg kipperterm_rr.bin kippergo.bin kipperkart.prg kippergo.prg kippergo_rr.bin -kipperkart.o: kipperkart.s $(INCFILES) ../inc/ping.i ../inc/disk_transfer.i ../inc/sidplay.i +kipperkart.o: kipperkart.s $(INCFILES) ../inc/ping.i ../inc/disk_transfer.i ../inc/sidplay.i ../inc/config_menu.i $(AS) $(AFLAGS) -o $@ $< -kipperterm.o: kipperterm.s $(INCFILES) ../inc/gopher.i ../inc/telnet.i +kipperterm.o: kipperterm.s $(INCFILES) ../inc/telnet.i ../inc/config_menu.i + $(AS) $(AFLAGS) -o $@ $< + +kippergo.o: kippergo.s $(INCFILES) ../inc/gopher.i ../inc/telnet.i ../inc/config_menu.i $(AS) $(AFLAGS) -o $@ $< %.o: %.s $(INCFILES) @@ -35,6 +38,9 @@ kipperkart.prg: kipperkart.bin c64_cart_ram_header.prg kipperterm.prg: kipperterm.bin c64_cart_ram_header.prg cat c64_cart_ram_header.prg kipperterm.bin > kipperterm.prg +kippergo.prg: kippergo.bin c64_cart_ram_header.prg + cat c64_cart_ram_header.prg kippergo.bin > kippergo.prg + %.prg: %.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg $(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB) @@ -53,6 +59,22 @@ kipperterm.bin: kipperterm.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64_ ruby fix_cart.rb $@ 16384 ruby dupe_cart.rb kipperterm.bin kipperterm_29c040.bin 32 +kipperterm_rr.bin: kipperterm.bin + cp crt8040.obj rrnet_header.bin + cat rrnet_header.bin kipperterm.bin > kipperterm_rr.bin + ruby fix_cart.rb $@ 32768 + + +kippergo.bin: kippergo.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64_16kcart.cfg + $(LD) -m kippergo.map -vm -C ../cfg/c64_16kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64PROGLIB) + ruby fix_cart.rb $@ 16384 + ruby dupe_cart.rb kippergo.bin kippergo_29c040.bin 32 + +kippergo_rr.bin: kippergo.bin + cp crt8040.obj rrnet_header.bin + cat rrnet_header.bin kippergo.bin > kippergo_rr.bin + ruby fix_cart.rb $@ 32768 + kipperkart_rr.bin: kipperkart.bin cp crt8040.obj rrnet_header.bin cat rrnet_header.bin kipperkart.bin > kipperkart_rr.bin diff --git a/client/carts/kippergo.s b/client/carts/kippergo.s new file mode 100644 index 0000000..7c266f7 --- /dev/null +++ b/client/carts/kippergo.s @@ -0,0 +1,301 @@ +; ############# +; KIPPER GO - Telnet/Gopher client for C64 +; jonno@jamtronix.com + + + .include "../inc/common.i" + .include "../inc/commonprint.i" + .include "../inc/c64keycodes.i" + .include "../inc/menu.i" + .include "../inc/config_menu.i" + + KEY_NEXT_PAGE=KEYCODE_F7 + KEY_PREV_PAGE=KEYCODE_F1 + KEY_SHOW_HISTORY=KEYCODE_F2 + KEY_BACK_IN_HISTORY=KEYCODE_F3 + KEY_NEW_SERVER=KEYCODE_F5 + + .include "../inc/gopher.i" + .include "../inc/telnet.i" + + .import cls + .import beep + .import exit_to_basic + .import ip65_process + .import ip65_init + .import get_filtered_input + .import filter_text + .import filter_dns + .import filter_ip + .import arp_calculate_gateway_mask + .import parse_dotted_quad + .import dotted_quad_value + .import parse_integer + + .import get_key_ip65 + .import cfg_mac + .import dhcp_init + + .import cfg_ip + .import cfg_netmask + .import cfg_gateway + .import cfg_dns + .import cfg_tftp_server + + .import xmodem_receive + + .export telnet_menu + + .import print_a + .import print_cr + .import copymem + .importzp copy_src + .importzp copy_dest + .import get_filtered_input + .import __DATA_LOAD__ + .import __DATA_RUN__ + .import __DATA_SIZE__ + .import __SELF_MODIFIED_CODE_LOAD__ + .import __SELF_MODIFIED_CODE_RUN__ + .import __SELF_MODIFIED_CODE_SIZE__ + + .import cfg_tftp_server + directory_buffer = $6000 + +.bss +;temp_ax: .res 2 + + +.segment "CARTRIDGE_HEADER" +.word cold_init ;cold start vector +.word warm_init ;warm start vector +.byte $C3,$C2,$CD,$38,$30 ; "CBM80" +.byte "KIPTRM" +.byte $0,$0,$0 ;reserved for future use +.byte $0,$0,$0 ;reserved for future use +.byte $0,$0,$0 ;reserved for future use + +.code + + + +cold_init: + + ;first let the kernal do a normal startup + sei + jsr $fda3 ;initialize CIA I/O + jsr $fd50 ;RAM test, set pointers + jsr $fd15 ;set vectors for KERNAL + jsr $ff5B ;init. VIC + cli ;KERNAL init. finished + +warm_init: + ;set some funky colours + + jsr setup_screen + +;relocate our r/w data + ldax #__DATA_LOAD__ + stax copy_src + ldax #__DATA_RUN__ + stax copy_dest + ldax #__DATA_SIZE__ + jsr copymem + + +;relocate the self-modifying code (if necessary) + ldax #__SELF_MODIFIED_CODE_LOAD__ + stax copy_src + ldax #__SELF_MODIFIED_CODE_RUN__ + stax copy_dest + ldax #__SELF_MODIFIED_CODE_SIZE__ + jsr copymem + + ldax #menu_header_msg + jsr print_ascii_as_native + ldax #init_msg+1 + jsr print_ascii_as_native + + jsr ip65_init + bcs init_failed + jsr dhcp_init + bcc init_ok + jsr ip65_init ;if DHCP failed, then reinit the IP stack (which will reset IP address etc that DHCP messed with to cartridge default values) + bcc init_ok +init_failed: + print_failed + jsr print_errorcode + jsr wait_for_keypress + jmp exit_to_basic + +print_main_menu: + jsr cls + ldax #menu_header_msg + jsr print_ascii_as_native + ldax #main_menu_msg + jmp print_ascii_as_native + +init_ok: + +main_menu: + jsr print_main_menu + jsr print_ip_config + jsr print_cr + +@get_key: + jsr get_key_ip65 + cmp #KEYCODE_F1 + bne @not_f1 + jsr cls + ldax #telnet_header + jsr print_ascii_as_native + jmp telnet_main_entry + + @not_f1: + cmp #KEYCODE_F3 + bne @not_f3 + jsr cls + ldax #gopher_header + jsr print_ascii_as_native + jsr prompt_for_gopher_resource ;only returns if no server was entered. + jmp exit_gopher + @not_f3: + + cmp #KEYCODE_F5 + bne @not_f5 + jsr cls + + ldax #gopher_initial_location + sta resource_pointer_lo + stx resource_pointer_hi + ldx #0 + jsr select_resource_from_current_directory + jmp exit_gopher +@not_f5: + + cmp #KEYCODE_F7 + beq @change_config + cmp #KEYCODE_F8 + bne @not_f8 + + jsr cls + ldax #menu_header_msg + jsr print_ascii_as_native + ldax #credits + jsr print_ascii_as_native + ldax #press_a_key_to_continue + jsr print_ascii_as_native + jsr get_key_ip65 + jmp main_menu +@not_f8: + + jmp @get_key + +@change_config: + jsr configuration_menu + jmp main_menu + + + + + +wait_for_keypress: + ldax #press_a_key_to_continue + jsr print_ascii_as_native +@loop: + jsr $ffe4 + beq @loop + rts + +get_key: + jmp get_key_ip65 + +cfg_get_configuration_ptr: + ldax #cfg_mac + rts + + +setup_screen: + ;make sure normal font + lda #$15 + sta $d018 + + LDA #$06 ;blue + + STA $D020 ;border + LDA #$00 ;black + STA $D021 ;background + lda #$05 ;petscii for white text + jsr print_a + + lda #14 + jmp print_a ;switch to lower case + +telnet_menu: + rts + +exit_telnet: +exit_gopher: + jsr setup_screen + jmp main_menu +.rodata + +menu_header_msg: +.byte $13,10,"KipperGo V" +.include "../inc/version.i" +.byte 10,0 +main_menu_msg: +.byte 10,"Main Menu",10,10 +.byte "F1: Telnet F3: Gopher ",10 +.byte "F5: Gopher (floodgap.com)",10 +.byte "F7: Config F8: Credits",10,10 + +.byte 0 + + + +gopher_initial_location: +.byte "1gopher.floodgap.com",$09,"/",$09,"gopher.floodgap.com",$09,"70",$0D,$0A,0 + +gopher_header: .byte "gopher",10,0 +telnet_header: .byte "telnet",10,0 + +current: +.byte "current ",0 + +new: +.byte"new ",0 + +resolving: + .byte "resolving ",0 + + +credits: +.byte 10,"License: Mozilla Public License v1.1",10,"http://www.mozilla.org/MPL/" +.byte 10 +.byte 10,"Contributors:",10 +.byte 10,"Jonno Downes" +.byte 10,"Glenn Holmmer" +.byte 10,"Per Olofsson" +.byte 10,"Lars Stollenwerk" +.byte 10,10 +.byte 0 + +;-- LICENSE FOR kipperterm.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 +; compliance with the License. You may obtain a copy of the License at +; http://www.mozilla.org/MPL/ +; +; Software distributed under the License is distributed on an "AS IS" +; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +; License for the specific language governing rights and limitations +; under the License. +; +; The Original Code is KipperTerm. +; +; The Initial Developer of the Original Code is Jonno Downes, +; jonno@jamtronix.com. +; Portions created by the Initial Developer are Copyright (C) 2009 +; Jonno Downes. All Rights Reserved. +; -- LICENSE END -- diff --git a/client/carts/kipperkart.s b/client/carts/kipperkart.s index 47f955f..192b085 100644 --- a/client/carts/kipperkart.s +++ b/client/carts/kipperkart.s @@ -31,6 +31,7 @@ .include "../inc/sidplay.i" .include "../inc/disk_transfer.i" + .include "../inc/config_menu.i" .import cls .import beep @@ -159,7 +160,7 @@ warm_init: ldax #__SELF_MODIFIED_CODE_SIZE__ jsr copymem - ldax #netboot65_msg + ldax #menu_header_msg jsr print_ascii_as_native ldax #init_msg+1 jsr print_ascii_as_native @@ -174,7 +175,7 @@ warm_init: print_main_menu: jsr cls - ldax #netboot65_msg + ldax #menu_header_msg jsr print_ascii_as_native ldax #main_menu_msg jmp print_ascii_as_native @@ -255,186 +256,8 @@ main_menu: @change_config: - jsr cls -@config_menu: - ldax #netboot65_msg - jsr print_ascii_as_native - ldax #config_menu_msg - jsr print_ascii_as_native - jsr print_ip_config - jsr print_default_drive - jsr print_cr -@get_key_config_menu: - jsr get_key_ip65 - cmp #KEYCODE_ABORT - bne @not_abort + jsr configuration_menu jmp main_menu -@not_abort: - cmp #KEYCODE_F1 - bne @not_ip - ldax #new - jsr print_ascii_as_native - ldax #ip_address_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_ip_address_entered - jsr parse_dotted_quad - bcc @no_ip_resolve_error - jmp @change_config -@no_ip_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_ip - stax copy_dest - ldax #4 - jsr copymem -@no_ip_address_entered: - jmp @change_config - -@not_ip: - cmp #KEYCODE_F2 - bne @not_netmask - ldax #new - jsr print_ascii_as_native - ldax #netmask_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_netmask_entered - jsr parse_dotted_quad - bcc @no_netmask_resolve_error - jmp @change_config -@no_netmask_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_netmask - stax copy_dest - ldax #4 - jsr copymem -@no_netmask_entered: - jmp @change_config - -@not_netmask: - cmp #KEYCODE_F3 - bne @not_gateway - ldax #new - jsr print_ascii_as_native - ldax #gateway_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_gateway_entered - jsr parse_dotted_quad - bcc @no_gateway_resolve_error - jmp @change_config -@no_gateway_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_gateway - stax copy_dest - ldax #4 - jsr copymem - jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test -@no_gateway_entered: - jmp @change_config - - -@not_gateway: - cmp #KEYCODE_F4 - bne @not_dns_server - ldax #new - jsr print_ascii_as_native - ldax #dns_server_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_dns_server_entered - jsr parse_dotted_quad - bcc @no_dns_resolve_error - jmp @change_config -@no_dns_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_dns - stax copy_dest - ldax #4 - jsr copymem -@no_dns_server_entered: - - jmp @change_config - -@not_dns_server: - cmp #KEYCODE_F5 - bne @not_tftp_server - ldax #new - jsr print_ascii_as_native - ldax #tftp_server_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_dns - ldy #40 - jsr get_filtered_input - bcs @no_server_entered - stax kipper_param_buffer - jsr print_cr - ldax #resolving - jsr print_ascii_as_native - ldax #kipper_param_buffer - kippercall #KPR_DNS_RESOLVE - bcs @resolve_error - ldax #kipper_param_buffer - stax copy_src - ldax #cfg_tftp_server - stax copy_dest - ldax #4 - jsr copymem -@no_server_entered: - jmp @change_config - -@not_tftp_server: - - -cmp #KEYCODE_F6 - bne @not_reset - jsr ip65_init ;this will reset everything - jmp @change_config -@not_reset: -cmp #KEYCODE_F7 - bne @not_main_menu - jmp main_menu - -@not_main_menu: - -cmp #'+' - bne @not_plus - inc cfg_default_drive - jmp @config_menu -@not_plus: - -cmp #'-' - bne @not_minus - dec cfg_default_drive - jmp @config_menu - -@not_minus: - - jmp @get_key_config_menu - - -@resolve_error: - print_failed - jsr wait_for_keypress - jsr @change_config - @tftp_boot: ldax #tftp_dir_filemask @@ -731,12 +554,6 @@ exit_ping: jsr print_a jmp main_menu -print_default_drive: - ldax #default_drive - jsr print_ascii_as_native - lda cfg_default_drive - jsr print_hex - jmp print_cr ;init the Time-Of-Day clock - cribbed from http://codebase64.org/doku.php?id=base:initialize_tod_clock_on_all_platforms init_tod: @@ -791,7 +608,7 @@ init_tod: .rodata -netboot65_msg: +menu_header_msg: .byte $13,10,"KipperKart V" .include "../inc/version.i" .byte 10,0 @@ -804,13 +621,7 @@ main_menu_msg: .byte 0 -config_menu_msg: -.byte 10,"Configuration",10,10 -.byte "F1: IP Address F2: Netmask",10 -.byte "F3: Gateway F4: DNS Server",10 -.byte "F5: TFTP Server F6: Reset To Default",10 -.byte "F7: Main Menu +/- Drive #",10,10 -.byte 0 + cant_boot_basic: .byte "BASIC file execution not supported",10,0 @@ -833,8 +644,6 @@ dir_listing_fail_msg: tftp_download_fail_msg: .byte "download failed", 10, 0 -default_drive: -.byte "Use Drive # : $",0 tftp_download_ok_msg: .byte "down" load_ok_msg: diff --git a/client/carts/kipperterm.s b/client/carts/kipperterm.s index 6cb3937..b00433e 100644 --- a/client/carts/kipperterm.s +++ b/client/carts/kipperterm.s @@ -1,5 +1,5 @@ ; ############# -; KIPPER TERM - Telnet/Gopher client for C64 +; KIPPER TERM - Telnet (only) client for C64 ; jonno@jamtronix.com @@ -7,6 +7,7 @@ .include "../inc/commonprint.i" .include "../inc/c64keycodes.i" .include "../inc/menu.i" + .include "../inc/config_menu.i" KEY_NEXT_PAGE=KEYCODE_F7 KEY_PREV_PAGE=KEYCODE_F1 @@ -14,7 +15,7 @@ KEY_BACK_IN_HISTORY=KEYCODE_F3 KEY_NEW_SERVER=KEYCODE_F5 - .include "../inc/gopher.i" + .include "../inc/telnet.i" .import cls @@ -30,7 +31,11 @@ .import parse_dotted_quad .import dotted_quad_value .import parse_integer - + + .import dns_ip + .import dns_resolve + .import dns_set_hostname + .import get_key_ip65 .import cfg_mac .import dhcp_init @@ -40,7 +45,10 @@ .import cfg_gateway .import cfg_dns .import cfg_tftp_server - + + .import xmodem_receive + + .export telnet_menu .import print_a .import print_cr @@ -58,9 +66,6 @@ .import cfg_tftp_server directory_buffer = $6000 -.bss -;temp_ax: .res 2 - .segment "CARTRIDGE_HEADER" .word cold_init ;cold start vector @@ -88,6 +93,9 @@ cold_init: warm_init: ;set some funky colours + lda #0 + sta $dc08 ;set deciseconds - starts TOD going + jsr setup_screen ;relocate our r/w data @@ -107,7 +115,7 @@ warm_init: ldax #__SELF_MODIFIED_CODE_SIZE__ jsr copymem - ldax #netboot65_msg + ldax #menu_header_msg jsr print_ascii_as_native ldax #init_msg+1 jsr print_ascii_as_native @@ -126,7 +134,7 @@ init_failed: print_main_menu: jsr cls - ldax #netboot65_msg + ldax #menu_header_msg jsr print_ascii_as_native ldax #main_menu_msg jmp print_ascii_as_native @@ -136,6 +144,7 @@ init_ok: main_menu: jsr print_main_menu jsr print_ip_config + jsr print_default_drive jsr print_cr @get_key: @@ -148,26 +157,6 @@ main_menu: jmp telnet_main_entry @not_f1: - cmp #KEYCODE_F3 - bne @not_f3 - jsr cls - ldax #gopher_header - jsr print_ascii_as_native - jsr prompt_for_gopher_resource ;only returns if no server was entered. - jmp exit_gopher - @not_f3: - - cmp #KEYCODE_F5 - bne @not_f5 - jsr cls - - ldax #gopher_initial_location - sta resource_pointer_lo - stx resource_pointer_hi - ldx #0 - jsr select_resource_from_current_directory - jmp exit_gopher -@not_f5: cmp #KEYCODE_F7 beq @change_config @@ -175,7 +164,7 @@ main_menu: bne @not_f8 jsr cls - ldax #netboot65_msg + ldax #menu_header_msg jsr print_ascii_as_native ldax #credits jsr print_ascii_as_native @@ -188,177 +177,10 @@ main_menu: jmp @get_key @change_config: - jsr cls - ldax #netboot65_msg - jsr print_ascii_as_native - ldax #config_menu_msg - jsr print_ascii_as_native - jsr print_ip_config - jsr print_cr -@get_key_config_menu: - jsr get_key_ip65 - cmp #KEYCODE_ABORT - bne @not_abort + jsr configuration_menu jmp main_menu -@not_abort: - cmp #KEYCODE_F1 - bne @not_ip - ldax #new - jsr print_ascii_as_native - ldax #ip_address_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_ip_address_entered - jsr parse_dotted_quad - bcc @no_ip_resolve_error - jmp @change_config -@no_ip_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_ip - stax copy_dest - ldax #4 - jsr copymem -@no_ip_address_entered: - jmp @change_config - -@not_ip: - cmp #KEYCODE_F2 - bne @not_netmask - ldax #new - jsr print_ascii_as_native - ldax #netmask_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_netmask_entered - jsr parse_dotted_quad - bcc @no_netmask_resolve_error - jmp @change_config -@no_netmask_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_netmask - stax copy_dest - ldax #4 - jsr copymem -@no_netmask_entered: - jmp @change_config - -@not_netmask: - cmp #KEYCODE_F3 - bne @not_gateway - ldax #new - jsr print_ascii_as_native - ldax #gateway_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_gateway_entered - jsr parse_dotted_quad - bcc @no_gateway_resolve_error - jmp @change_config -@no_gateway_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_gateway - stax copy_dest - ldax #4 - jsr copymem - jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test -@no_gateway_entered: - jmp @change_config - - -@not_gateway: - cmp #KEYCODE_F4 - bne @not_dns_server - ldax #new - jsr print_ascii_as_native - ldax #dns_server_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_ip - ldy #20 - jsr get_filtered_input - bcs @no_dns_server_entered - jsr parse_dotted_quad - bcc @no_dns_resolve_error - jmp @change_config -@no_dns_resolve_error: - ldax #dotted_quad_value - stax copy_src - ldax #cfg_dns - stax copy_dest - ldax #4 - jsr copymem -@no_dns_server_entered: - - jmp @change_config - -@not_dns_server: - cmp #KEYCODE_F5 - bne @not_tftp_server - ldax #new - jsr print_ascii_as_native - ldax #tftp_server_msg - jsr print_ascii_as_native - jsr print_cr - ldax #filter_dns - ldy #40 - jsr get_filtered_input - bcs @no_server_entered - stax temp_ax - jsr print_cr - ldax #resolving - jsr print_ascii_as_native - ldax temp_ax - jsr dns_set_hostname - bcs @resolve_error - jsr dns_resolve - bcs @resolve_error - - ldax #dns_ip - stax copy_src - ldax #cfg_tftp_server - stax copy_dest - ldax #4 - jsr copymem -@no_server_entered: - jmp @change_config - -@not_tftp_server: - - -cmp #KEYCODE_F6 - bne @not_reset - jsr ip65_init ;this will reset everything - jmp @change_config -@not_reset: -cmp #KEYCODE_F7 - bne @not_main_menu - jmp main_menu - -@not_main_menu: - jmp @get_key_config_menu -@resolve_error: - print_failed - jsr wait_for_keypress - jsr @change_config - - - - - wait_for_keypress: ldax #press_a_key_to_continue jsr print_ascii_as_native @@ -368,12 +190,7 @@ wait_for_keypress: rts get_key: -@loop: - jsr KPR_PERIODIC_PROCESSING_VECTOR - jsr $ffe4 - beq @loop - rts - + jmp get_key_ip65 cfg_get_configuration_ptr: ldax #cfg_mac @@ -385,7 +202,7 @@ setup_screen: lda #$15 sta $d018 - LDA #$06 ;blue + LDA #$07 ;yellow STA $D020 ;border LDA #$00 ;black @@ -396,39 +213,196 @@ setup_screen: lda #14 jmp print_a ;switch to lower case +save_screen_settings: + ;save current settings + lda $d018 + sta temp_font + lda $d020 + sta temp_border + lda $d021 + sta temp_text_back + lda $0286 + sta temp_text_fore + + ldx #$27 +@save_page_zero_vars_loop: + lda $cf,x + sta temp_page_zero_vars,x + dex + bne @save_page_zero_vars_loop + + ldax #$400 + stax copy_src + ldax #temp_screen_chars + stax copy_dest + ldax #$400 + jsr copymem + + ldax #$d800 + stax copy_src + ldax #temp_colour_ram + stax copy_dest + ldax #$400 + jmp copymem + +restore_screen_settings: + lda temp_font + sta $d018 + + + lda temp_border + sta $d020 + lda temp_text_back + sta $d021 + lda temp_text_fore + sta $0286 + + ldx #$27 +@restore_page_zero_vars_loop: + lda temp_page_zero_vars,x + sta $cf,x + dex + bne @restore_page_zero_vars_loop + + ldax #temp_screen_chars + stax copy_src + ldax #$400 + stax copy_dest + ldax #$400 + jsr copymem + + ldax #temp_colour_ram + stax copy_src + ldax #$d800 + stax copy_dest + ldax #$400 + jmp copymem + + +telnet_menu: + + jsr save_screen_settings + jsr setup_screen + jsr cls + + + ldax #menu_header_msg + jsr print_ascii_as_native + ldax #telnet_menu_msg + jsr print_ascii_as_native + +@get_menu_option: + jsr get_key + cmp #KEYCODE_F1 + bne :+ + jsr xmodem_download + jmp @exit +: + cmp #KEYCODE_F7 + beq @exit + jmp @get_menu_option +@exit: + jsr restore_screen_settings + rts + +xmodem_download: + ldax #opening_file + jsr print_ascii_as_native + jsr open_dl_file + bcs @error + ldax #ok_msg + jsr print_ascii_as_native + jsr print_cr + ldax #write_byte + jsr xmodem_receive + bcs @error + jsr close_file + + rts +@error: + print_failed + jsr print_errorcode + jsr close_file + jmp wait_for_keypress + +open_dl_file: + lda #fname_end-fname + ldx #fname + + jsr $FFBD ; call SETNAM + lda #$02 ; file number 2 +.import cfg_default_drive + ldx cfg_default_drive + + ldy #$02 ; secondary address 2 + jsr $FFBA ; call SETLFS + + jsr $FFC0 ; call OPEN + bcs @error ; if carry set, the file could not be opened + rts +@error: + sta ip65_error + jsr close_file + sec + rts + +write_byte: + pha + ldx #$02 ; filenumber 2 = output file + jsr $FFC9 ; call CHKOUT + pla + jsr $ffd2 ;write byte + JSR $FFB7 ; call READST (read status byte) + bne @error + ldx #$00 ; filenumber 0 = console + jsr $FFC9 ; call CHKOUT + rts +@error: + lda #KPR_ERROR_FILE_ACCESS_FAILURE + sta ip65_error + jsr close_file + sec + rts + + +close_file: + + lda #$02 ; filenumber 2 + jsr $FFC3 ; call CLOSE + rts + + exit_telnet: exit_gopher: jsr setup_screen jmp main_menu .rodata -netboot65_msg: -.byte 10,"KipperTerm V" +menu_header_msg: +.byte $13,10,"KipperTerm V" .include "../inc/version.i" .byte 10,0 main_menu_msg: .byte 10,"Main Menu",10,10 -.byte "F1: Telnet F3: Gopher ",10 -.byte "F5: Gopher (floodgap.com)",10 +.byte "F1: Telnet ",10 .byte "F7: Config F8: Credits",10,10 .byte 0 -config_menu_msg: -.byte 10,"Configuration",10,10 -.byte "F1: IP Address F2: Netmask",10 -.byte "F3: Gateway F4: DNS Server",10 -.byte "F5: TFTP Server F6: Reset To Default",10 -.byte "F7: Main Menu",10,10 + + +telnet_menu_msg: +.byte 10,10,10 +.byte "F1: D/L File (XMODEM)",10 +.byte "F7: Return",10,10 .byte 0 - -gopher_initial_location: -.byte "1gopher.floodgap.com",$09,"/",$09,"gopher.floodgap.com",$09,"70",$0D,$0A,0 - -gopher_header: .byte "gopher",10,0 telnet_header: .byte "telnet",10,0 +opening_file: +.byte 10,"opening file",10,0 + current: .byte "current ",0 @@ -438,6 +412,10 @@ new: resolving: .byte "resolving ",0 +fname: .byte "@0:XMODEM.TMP,P,W" ; @0: means 'overwrite if existing', ',P,W' is required to make this an output file +fname_end: +.byte 0 + credits: .byte 10,"License: Mozilla Public License v1.1",10,"http://www.mozilla.org/MPL/" .byte 10 @@ -449,6 +427,16 @@ credits: .byte 10,10 .byte 0 +.segment "APP_SCRATCH" + +temp_font: .res 1 +temp_border: .res 1 +temp_text_back: .res 1 +temp_text_fore: .res 1 +temp_page_zero_vars: .res $28 +temp_screen_chars: .res $400 +temp_colour_ram: .res $400 + ;-- LICENSE FOR kipperterm.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/inc/c64keycodes.i b/client/inc/c64keycodes.i index f83d726..2f41234 100644 --- a/client/inc/c64keycodes.i +++ b/client/inc/c64keycodes.i @@ -14,7 +14,7 @@ KEYCODE_F8=$8c KEYCODE_ABORT=$03 ;RUN/STOP .define KEYNAME_ABORT "RUN/STOP" .export KEYCODE_ABORT - +.export KEYCODE_F1 ;-- LICENSE FOR c64keycodes.i -- ; The contents of this file are subject to the Mozilla Public License diff --git a/client/inc/config_menu.i b/client/inc/config_menu.i new file mode 100644 index 0000000..71fd88d --- /dev/null +++ b/client/inc/config_menu.i @@ -0,0 +1,212 @@ + + .import dns_ip + .import dns_resolve + .import dns_set_hostname +.import cfg_default_drive +.bss + temp_ax: .res 2 +.code + +configuration_menu: + jsr cls +@show_config_menu: + ldax #menu_header_msg + jsr print_ascii_as_native + ldax #config_menu_msg + jsr print_ascii_as_native + jsr print_ip_config + jsr print_default_drive + jsr print_cr +@get_key_config_menu: + jsr get_key_ip65 + cmp #KEYCODE_ABORT + bne @not_abort + rts +@not_abort: + cmp #KEYCODE_F1 + bne @not_ip + ldax #new + jsr print_ascii_as_native + ldax #ip_address_msg + jsr print_ascii_as_native + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_ip_address_entered + jsr parse_dotted_quad + bcc @no_ip_resolve_error + jmp configuration_menu +@no_ip_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_ip + stax copy_dest + ldax #4 + jsr copymem +@no_ip_address_entered: + jmp configuration_menu + +@not_ip: + cmp #KEYCODE_F2 + bne @not_netmask + ldax #new + jsr print_ascii_as_native + ldax #netmask_msg + jsr print_ascii_as_native + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_netmask_entered + jsr parse_dotted_quad + bcc @no_netmask_resolve_error + jmp configuration_menu +@no_netmask_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_netmask + stax copy_dest + ldax #4 + jsr copymem +@no_netmask_entered: + jmp configuration_menu + +@not_netmask: + cmp #KEYCODE_F3 + bne @not_gateway + ldax #new + jsr print_ascii_as_native + ldax #gateway_msg + jsr print_ascii_as_native + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_gateway_entered + jsr parse_dotted_quad + bcc @no_gateway_resolve_error + jmp configuration_menu +@no_gateway_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_gateway + stax copy_dest + ldax #4 + jsr copymem + jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test +@no_gateway_entered: + jmp configuration_menu + + +@not_gateway: + cmp #KEYCODE_F4 + bne @not_dns_server + ldax #new + jsr print_ascii_as_native + ldax #dns_server_msg + jsr print_ascii_as_native + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_dns_server_entered + jsr parse_dotted_quad + bcc @no_dns_resolve_error + jmp configuration_menu +@no_dns_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_dns + stax copy_dest + ldax #4 + jsr copymem +@no_dns_server_entered: + + jmp configuration_menu + +@not_dns_server: + cmp #KEYCODE_F5 + bne @not_tftp_server + ldax #new + jsr print_ascii_as_native + ldax #tftp_server_msg + jsr print_ascii_as_native + jsr print_cr + ldax #filter_dns + ldy #40 + jsr get_filtered_input + bcs @no_server_entered + stax temp_ax + jsr print_cr + ldax #resolving + jsr print_ascii_as_native + ldax temp_ax + jsr dns_set_hostname + bcs @resolve_error + jsr dns_resolve + bcs @resolve_error + + ldax #dns_ip + stax copy_src + ldax #cfg_tftp_server + stax copy_dest + ldax #4 + jsr copymem +@no_server_entered: + jmp configuration_menu + +@not_tftp_server: + + +cmp #KEYCODE_F6 + bne @not_reset + jsr ip65_init ;this will reset everything + jmp configuration_menu +@not_reset: +cmp #KEYCODE_F7 + bne @not_main_menu + jmp main_menu + +@not_main_menu: + +cmp #'+' + bne @not_plus + inc cfg_default_drive + jmp @show_config_menu +@not_plus: + +cmp #'-' + bne @not_minus + dec cfg_default_drive + jmp @show_config_menu + +@not_minus: + + jmp @get_key_config_menu + +@resolve_error: + print_failed + jsr wait_for_keypress + jmp configuration_menu + + +print_default_drive: + ldax #default_drive + jsr print_ascii_as_native + lda cfg_default_drive + jsr print_hex + jmp print_cr + +.rodata + +config_menu_msg: +.byte 10,"Configuration",10,10 +.byte "F1: IP Address F2: Netmask",10 +.byte "F3: Gateway F4: DNS Server",10 +.byte "F5: TFTP Server F6: Reset To Default",10 +.byte "F7: Main Menu +/- Drive #",10,10 +.byte 0 + +default_drive: +.byte "Use Drive # : $",0 diff --git a/client/inc/gopher.i b/client/inc/gopher.i index b089f8c..014ab42 100644 --- a/client/inc/gopher.i +++ b/client/inc/gopher.i @@ -85,7 +85,7 @@ dl_loop_counter: .res 2 this_is_last_page: .res 1 -temp_ax: .res 2 +;temp_ax: .res 2 RESOURCE_HOSTNAME_MAX_LENGTH=64 current_resource: diff --git a/client/inc/kipper_constants.i b/client/inc/kipper_constants.i index bf8a634..d8e1083 100644 --- a/client/inc/kipper_constants.i +++ b/client/inc/kipper_constants.i @@ -142,6 +142,7 @@ KPR_ERROR_LISTENER_NOT_AVAILABLE EQU $87 KPR_ERROR_NO_SUCH_LISTENER EQU $88 KPR_ERROR_CONNECTION_RESET_BY_PEER EQU $89 KPR_ERROR_CONNECTION_CLOSED EQU $8A +KPR_ERROR_TOO_MANY_ERRORS EQU $8B KPR_ERROR_FILE_ACCESS_FAILURE EQU $90 KPR_ERROR_MALFORMED_URL EQU $A0 KPR_ERROR_DNS_LOOKUP_FAILED EQU $A1 diff --git a/client/inc/version.i b/client/inc/version.i index 070c1fb..9147b71 100644 --- a/client/inc/version.i +++ b/client/inc/version.i @@ -1 +1 @@ -.byte "1.0.20" +.byte "1.0.24" diff --git a/client/ip65/Makefile b/client/ip65/Makefile index c804602..c6bf3c7 100644 --- a/client/ip65/Makefile +++ b/client/ip65/Makefile @@ -32,6 +32,7 @@ ETHOBJS= \ parser.o \ string_utils.o \ telnet.o \ + xmodem.o \ url.o \ arithmetic.o\ diff --git a/client/ip65/telnet.s b/client/ip65/telnet.s index e6fc28b..7d9de7c 100644 --- a/client/ip65/telnet.s +++ b/client/ip65/telnet.s @@ -15,6 +15,7 @@ .import tcp_connect_ip .import tcp_listen .importzp KEYCODE_ABORT + .importzp KEYCODE_F1 .import tcp_inbound_data_ptr .import tcp_inbound_data_length .import tcp_send @@ -44,6 +45,8 @@ .export telnet_port .export telnet_ip +.import telnet_menu + .segment "IP65ZP" : zeropage ; pointer for moving through buffers @@ -150,8 +153,13 @@ telnet_connect: jsr get_key_if_available beq @wait_for_keypress + cmp #KEYCODE_F1 + bne @not_telnet_menu + jsr telnet_menu + jmp @wait_for_keypress +@not_telnet_menu: tax -; beq @send_char + cmp #KEYCODE_ABORT bne @not_abort @@ -376,7 +384,7 @@ telnet_callback: inc iac_response_buffer_length inc iac_response_buffer_length inc iac_response_buffer_length - +@after_set_iac_response: lda #telnet_state_normal sta telnet_state jmp @byte_processed @@ -414,9 +422,8 @@ telnet_callback: txa cmp #naws_response_length bne :- - - - ;fall through to send back 'will' + + jmp @after_set_iac_response @do_terminaltype: lda #$fb ;WILL @@ -474,7 +481,10 @@ terminal_type_response: .byte $ff ; IAC .byte $f0 ; SE terminal_type_response_length=*-terminal_type_response + + naws_response: + .byte $ff,$fb,$1F ;IAC WILL NAWS .byte $ff ; IAC .byte $fa; SB .byte $1F ; NAWS @@ -487,6 +497,8 @@ naws_response: .byte $f0 ; SE naws_response_length=*-naws_response + + ;variables .segment "APP_SCRATCH" telnet_ip: .res 4 ;ip address of remote server diff --git a/client/ip65/vt100_c64.s b/client/ip65/vt100_c64.s index cd09bfd..e402fbd 100644 --- a/client/ip65/vt100_c64.s +++ b/client/ip65/vt100_c64.s @@ -15,6 +15,9 @@ ; Y = 1 means A contains single character to send to remote host ; Y = 2 means AX points at null terminated string to send to remote host (e.g. an ANSI escape sequence) +;FIXME! - this should be a platform-specific driver + + .include "../inc/common.i" .export vt100_init_terminal diff --git a/client/ip65/xmodem.s b/client/ip65/xmodem.s new file mode 100644 index 0000000..b9722bc --- /dev/null +++ b/client/ip65/xmodem.s @@ -0,0 +1,342 @@ +; XMODEM file transfer + +.include "../inc/common.i" +.ifndef KPR_API_VERSION_NUMBER + .define EQU = + .include "../inc/kipper_constants.i" +.endif + + +XMODEM_BLOCK_SIZE=$80 ;how many bytes (excluding header & checksum) in each block? +XMODEM_TIMEOUT_SECONDS=5 +XMODEM_MAX_ERRORS=10 +SOH = $01 +EOT = $04 +ACK = $06 +NAK = $15 +CAN = $18 + +.export xmodem_receive + +.import ip65_process +.import ip65_error +.import tcp_callback +.import copymem +.importzp copy_src +.importzp copy_dest +.import tcp_send +.import tcp_send_data_len +.import tcp_inbound_data_ptr +.import tcp_inbound_data_length +.import check_for_abort_key +.import print_a +.import print_cr +.import print_ascii_as_native +.import print_hex + +.segment "SELF_MODIFIED_CODE" +got_byte: + jmp $ffff + +next_char: + lda buffer_length + bne @not_eof + lda buffer_length+1 + bne @not_eof + sec + rts +@not_eof: + next_char_ptr=*+1 + lda $ffff + pha + inc next_char_ptr + bne :+ + inc next_char_ptr+1 +: + sec + lda buffer_length + sbc #1 + sta buffer_length + lda buffer_length+1 + sbc #0 + sta buffer_length+1 + pla + clc + + rts + .bss + +original_tcp_callback: .res 2 +getc_timeout_end: .res 1 +getc_timeout_seconds: .res 1 +buffer_length: .res 2 + + .code + +xmodem_receive: +;recieve a file via XMODEM (checksum mode only, not CRC) +;assumes that a tcp connection has already been set up, and that the other end is waiting to start sending +;inputs: AX points to routine to call once for each byte in downloaded file (e.g. save to disk, print to screen, whatever) - byte will be in A +;outputs: none + + + stax got_byte+1 + lda #0 + sta buffer_length + sta buffer_length+1 + sta error_number + sta user_abort + lda #1 + sta expected_block_number + + + ldax tcp_callback + stax original_tcp_callback + ldax #xmodem_receive_callback + stax tcp_callback + jsr send_nak + + +@next_block: + lda #0 + sta block_ptr + sta checksum + ldax #expecting + jsr print_ascii_as_native + + ldax #block_number_msg + jsr print_ascii_as_native + lda expected_block_number + jsr print_hex + jsr print_cr + +@wait_for_block_start: + lda #XMODEM_TIMEOUT_SECONDS + jsr getc + bcc @got_block_start + lda user_abort + beq @no_user_abort + jmp @exit +@no_user_abort: + jsr send_nak + inc error_number + ldax #timeout_msg + jsr print_ascii_as_native + lda error_number + jsr print_hex + jsr print_cr + lda error_number + cmp #XMODEM_MAX_ERRORS + bcc @wait_for_block_start + lda #KPR_ERROR_TOO_MANY_ERRORS + sta ip65_error + jmp @exit +@got_block_start: + cmp #EOT + bne :+ + jsr send_ack + clc + jmp @exit +: + cmp #SOH + bne @wait_for_block_start + + ;now get block number + lda #XMODEM_TIMEOUT_SECONDS + jsr getc + bcc :+ + jsr send_nak + jmp @wait_for_block_start +: + sta actual_block_number + + ;now get block number check + lda #XMODEM_TIMEOUT_SECONDS + jsr getc + bcc :+ + jsr send_nak + jmp @wait_for_block_start +: + adc actual_block_number + cmp #$ff + bne @wait_for_block_start + ldax #receiving + jsr print_ascii_as_native + + ldax #block_number_msg + jsr print_ascii_as_native + lda actual_block_number + jsr print_hex + jsr print_cr + +@next_byte: + lda #XMODEM_TIMEOUT_SECONDS + jsr getc + bcs @exit + ldx block_ptr + sta xmodem_block_buffer,x + adc checksum + sta checksum + + inc block_ptr + lda block_ptr + bpl @next_byte + + ldax #checksum_msg + jsr print_ascii_as_native + lda checksum + jsr print_hex + + lda #'/' + jsr print_a + + lda #XMODEM_TIMEOUT_SECONDS + jsr getc + bcs @exit + sta received_checksum + jsr print_hex + jsr print_cr + + lda received_checksum + cmp checksum + beq @checksum_ok + jsr send_nak + jmp @next_block + +@checksum_ok: + lda expected_block_number + cmp actual_block_number + bne @skip_block_output + + lda #0 + sta block_ptr + +@output_byte: + ldx block_ptr + lda xmodem_block_buffer,x + jsr got_byte + inc block_ptr + lda block_ptr + bpl @output_byte + + inc expected_block_number + +@skip_block_output: + jsr send_ack + jmp @next_block + + clc +@exit: + ldax original_tcp_callback + stax tcp_callback + + rts + +xmodem_receive_callback: + lda tcp_inbound_data_length+1 + cmp #$ff + bne @not_eof + rts +@not_eof: + + ldax tcp_inbound_data_ptr + stax copy_src + ldax #xmodem_stream_buffer + stax copy_dest + stax next_char_ptr + + ldax tcp_inbound_data_length + stax buffer_length + jmp copymem + + +send_nak: + ldax #1 + stax tcp_send_data_len + ldax #nak_packet + jmp tcp_send + +send_ack: + ldax #1 + stax tcp_send_data_len + ldax #ack_packet + jmp tcp_send + + +getc: + sta getc_timeout_seconds + + clc + lda $dc09 ;time of day clock: seconds (in BCD) + sed + adc getc_timeout_seconds + cmp #$60 + bcc @timeout_set + sec + sbc #$60 +@timeout_set: + cld + sta getc_timeout_end + +@poll_loop: +; inc $d021 + jsr next_char + bcs @no_char + rts ;done! +@no_char: + jsr check_for_abort_key + bcc @no_abort + lda #KPR_ERROR_ABORTED_BY_USER + sta ip65_error + inc user_abort + rts +@no_abort: + jsr ip65_process + lda $dc09 ;time of day clock: seconds + cmp getc_timeout_end + bne @poll_loop + sec + rts + + + +.rodata + ack_packet: .byte ACK + nak_packet: .byte NAK + +block_number_msg: .byte " block $",0 +expecting: .byte "expecting",0 +receiving: .byte "receiving",0 +bad_block_number: .byte "bad block number",0 +checksum_msg: .byte "checksum $",0 +timeout_msg: .byte "timeout $",0 + +.segment "APP_SCRATCH" +xmodem_stream_buffer: .res 1600 +xmodem_block_buffer: .res 128 +expected_block_number: .res 1 +actual_block_number: .res 1 +checksum: .res 1 +received_checksum: .res 1 +block_ptr: .res 1 +error_number: .res 1 +user_abort: .res 1 + +;-- LICENSE FOR xmodem.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 +; compliance with the License. You may obtain a copy of the License at +; http://www.mozilla.org/MPL/ +; +; Software distributed under the License is distributed on an "AS IS" +; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +; License for the specific language governing rights and limitations +; under the License. +; +; The Original Code is ip65. +; +; The Initial Developer of the Original Code is Jonno Downes, +; jonno@jamtronix.com. +; Portions created by the Initial Developer are Copyright (C) 2009 +; Jonno Downes. All Rights Reserved. +; -- LICENSE END -- diff --git a/client/test/Makefile b/client/test/Makefile index 6ec3d8b..18d1a7f 100644 --- a/client/test/Makefile +++ b/client/test/Makefile @@ -19,9 +19,9 @@ INCFILES=\ ../inc/net.i\ all: \ + test_getc.prg \ testdns.prg \ test_disk_io.prg \ -# test_disk_io.d64 \ testdns.pg2 \ testtftp.prg \ testtftp.pg2\ @@ -30,6 +30,8 @@ all: \ testdottedquad.pg2\ testdottedquad.prg\ test_tcp.prg \ + test_xmodem.prg \ + test_xmodem.d64 \ test_httpd.prg \ test_parser.prg \ test_ping.prg \ @@ -38,6 +40,7 @@ all: \ test_parse_querystring.prg \ # httpd_test.d64 \ # ip65test.dsk \ +# test_disk_io.d64 \ %.o: %.c $(CC) -c $(CFLAGS) $< @@ -51,6 +54,12 @@ all: \ test_tcp.prg: test_tcp.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg $(LD) -m test_tcp.map -vm -C ../cfg/c64prg.cfg -o test_tcp.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB) +test_xmodem.o: test_xmodem.s ../ip65/xmodem.s + $(AS) $(AFLAGS) $< + +test_xmodem.prg: test_xmodem.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg + $(LD) -m test_xmodem.map -vm -C ../cfg/c64prg.cfg -o test_xmodem.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB) + test_parser.prg: test_parser.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg $(LD) -m test_parser.map -vm -C ../cfg/c64prg.cfg -o test_parser.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB) @@ -81,7 +90,10 @@ test_disk_io.d64: test_disk_io.prg ripxplore.rb --init CbmDos test_disk_io.d64 -a test_disk_io.prg cp screen_prg.bin screen.prg ripxplore.rb test_disk_io.d64 -a screen.prg - + +test_xmodem.d64: test_xmodem.prg + ripxplore.rb --init CbmDos test_xmodem.d64 -a test_xmodem.prg + clean: rm -f *.o *.pg2 *.prg rm -f ip65test.dsk diff --git a/client/test/test_getc.s b/client/test/test_getc.s new file mode 100644 index 0000000..d157cbb --- /dev/null +++ b/client/test/test_getc.s @@ -0,0 +1,196 @@ + +.ifndef KIPPER_API_VERSION_NUMBER + .define EQU = + .include "../inc/kipper_constants.i" +.endif + +.include "../inc/common.i" +.include "../inc/commonprint.i" +.import print_a +.import cfg_get_configuration_ptr +.import io_device_no +.import io_sector_no +.import io_track_no +.import io_read_sector +.import io_write_sector + +.import io_read_file_with_callback +.import io_read_file +.import io_filename +.import io_filesize +.import io_load_address +.import io_callback +.import get_key +.import ip65_error +.import ip65_process +.import io_read_catalogue_ex + +.macro cout arg + lda arg + jsr print_a +.endmacro + + + +.bss + sector_buffer: .res 256 + output_buffer: .res 520 + .export output_buffer +current_byte_in_row: .res 1 +current_byte_in_sector: .res 1 +start_of_current_row: .res 1 + +directory_buffer: .res 4096 + +.segment "STARTUP" ;this is what gets put at the start of the file on the C64 + +.word basicstub ; load address + +basicstub: + .word @nextline + .word 2003 + .byte $9e + .byte <(((init / 1000) .mod 10) + $30) + .byte <(((init / 100 ) .mod 10) + $30) + .byte <(((init / 10 ) .mod 10) + $30) + .byte <(((init ) .mod 10) + $30) + .byte 0 +@nextline: + .word 0 + +init: + lda #14 + jsr print_a ;switch to lower case + lda $dc08 ;read deci-seconds - start clock ticking + sta $dc08 + jsr load_buffer +@loop: + lda #5 ;timeout period + jsr getc + bcs @done + jsr print_a + jmp @loop +@done: + rts + +load_buffer: + ldax #buffer + stax next_char_ptr + ldax #buffer_length + stax buff_length + rts + + +getc: + sta getc_timeout_seconds + + clc + lda $dc09 ;time of day clock: seconds (in BCD) + sed + adc getc_timeout_seconds + cmp #$60 + bcc @timeout_set + sec + sbc #$60 +@timeout_set: + cld + sta getc_timeout_end + +@poll_loop: + jsr ip65_process + jsr next_char + bcs @no_char + rts ;done! +@no_char: + lda $dc09 ;time of day clock: seconds + cmp getc_timeout_end + bne @poll_loop + sec + rts + +next_char: + lda buff_length + bne @not_eof + lda buff_length+1 + bne @not_eof + sec + rts +@not_eof: + next_char_ptr=*+1 + lda $ffff + pha + inc next_char_ptr + bne :+ + inc next_char_ptr+1 +: + sec + lda buff_length + sbc #1 + sta buff_length + lda buff_length+1 + sbc #0 + sta buff_length+1 + pla + clc + + rts + +.rodata +buffer: + .byte "this is a test1!",13 + .byte "this is a test2!",13 + .byte "this is a test3!",13 + .byte "this is a test4!",13 + .byte "this is a test5!",13 + .byte "this is a test6!",13 + .byte "this is a test7!",13 + .byte "this is a test8!",13 + .byte "this is a test9!",13 + .byte "this is a test10!",13 + .byte "this is a test1@",13 + .byte "this is a test2@",13 + .byte "this is a test3@",13 + .byte "this is a test4@",13 + .byte "this is a test5@",13 + .byte "this is a test6@",13 + .byte "this is a test7@",13 + .byte "this is a test8@",13 + .byte "this is a test9@",13 + .byte "this is a test10@",13 + .byte "this is a test1*",13 + .byte "this is a test2*",13 + .byte "this is a test3*",13 + .byte "this is a test4*",13 + .byte "this is a test5*",13 + .byte "this is a test6*",13 + .byte "this is a test7*",13 + .byte "this is a test8*",13 + .byte "this is a test9*",13 + .byte "this is a test10*",13 + +buffer_length=*-buffer + +.bss +getc_timeout_end: .res 1 +getc_timeout_seconds: .res 1 +buff_length: .res 2 + + +;-- LICENSE FOR test_getc.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 +; compliance with the License. You may obtain a copy of the License at +; http://www.mozilla.org/MPL/ +; +; Software distributed under the License is distributed on an "AS IS" +; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +; License for the specific language governing rights and limitations +; under the License. +; +; The Original Code is ip65. +; +; The Initial Developer of the Original Code is Jonno Downes, +; jonno@jamtronix.com. +; Portions created by the Initial Developer are Copyright (C) 2009 +; Jonno Downes. All Rights Reserved. +; -- LICENSE END -- diff --git a/client/test/test_xmodem.s b/client/test/test_xmodem.s new file mode 100644 index 0000000..9968f05 --- /dev/null +++ b/client/test/test_xmodem.s @@ -0,0 +1,252 @@ + .include "../inc/common.i" + .include "../inc/commonprint.i" + .include "../inc/net.i" + +; .include "../ip65/xmodem.s" + + .import parse_dotted_quad + .import dotted_quad_value + + .import tcp_listen + .import tcp_callback + .import ip65_error + .import get_key_ip65 + + .import tcp_connect + .import tcp_connect_ip + + .import tcp_inbound_data_ptr + .import tcp_inbound_data_length + +.import xmodem_receive + + .import tcp_send + .import tcp_send_data_len + .import tcp_send_string + .import tcp_close + .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 + + .word basicstub ; load address + +basicstub: + .word @nextline + .word 2003 + .byte $9e + .byte <(((init / 1000) .mod 10) + $30) + .byte <(((init / 100 ) .mod 10) + $30) + .byte <(((init / 10 ) .mod 10) + $30) + .byte <(((init ) .mod 10) + $30) + .byte 0 +@nextline: + .word 0 + +.segment "EXEHDR" ;this is what gets put an the start of the file on the Apple 2 + .addr __CODE_LOAD__-$11 ; Start address + .word __CODE_SIZE__+__RODATA_SIZE__+__DATA_SIZE__+4 ; Size + jmp init + +.bss +packet_count: .res 1 +.code + +init: + + + lda #14 + jsr print_a ;switch to lower case + + lda #0 + sta $dc08 ;set deciseconds - starts TOD going + jsr print_cr + init_ip_via_dhcp + jsr print_ip_config + + jsr print_cr + + lda #'1' + jsr print_a + + ;connect to port 1000 - xmodem server + + ldax #tcp_callback_routine + stax tcp_callback + ldax tcp_dest_ip + stax tcp_connect_ip + ldax tcp_dest_ip+2 + stax tcp_connect_ip+2 + + lda #0 + sta packet_count + ldax #1000 + jsr tcp_connect + + bcs @error + + lda #'2' + jsr print_a + + ldax #first_message + jsr tcp_send_string + +: + jsr ip65_process + lda packet_count + beq :- + + lda #'3' + jsr print_a + + ldax #start_download + jsr tcp_send_string + bcc :+ +@error: + jsr check_for_error +: + + + jsr open_file + bcc :+ + jmp check_for_error +: + ldax #write_byte + jsr xmodem_receive + jsr close_file + + jsr tcp_close + + lda #'4' + jsr print_a + + rts + + +tcp_callback_routine: + + inc packet_count + rts + + + + +check_for_error: + lda ip65_error + beq @exit + ldax #error_code + jsr print + lda ip65_error + jsr print_hex + jsr print_cr + lda #0 + sta ip65_error +@exit: + rts + + + +@error: + ldax #failed_msg + jsr print + jsr print_cr + rts + +open_file: + lda #fname_end-fname + ldx #fname + + jsr $FFBD ; call SETNAM + lda #$02 ; file number 2 + ldx $BA ; last used device number + bne @skip +.import cfg_default_drive + ldx cfg_default_drive +@skip: + + + ldy #$02 ; secondary address 2 + jsr $FFBA ; call SETLFS + + jsr $FFC0 ; call OPEN + bcs @error ; if carry set, the file could not be opened + + ldx #$02 ; filenumber 2 + jsr $FFC9 ; call CHKOUT (file 2 now used as output) + rts +@error: + sta ip65_error + jsr close_file + sec + rts + +write_byte: + pha + ldx #$02 ; filenumber 2 = output file + jsr $FFC9 ; call CHKOUT + pla + jsr $ffd2 ;write byte + JSR $FFB7 ; call READST (read status byte) + bne @error + ldx #$00 ; filenumber 0 = console + jsr $FFC9 ; call CHKOUT + rts +@error: + lda #KPR_ERROR_FILE_ACCESS_FAILURE + sta ip65_error + jsr close_file + sec + rts + + +close_file: + + lda #$02 ; filenumber 2 + jsr $FFC3 ; call CLOSE + rts + + + .bss + temp_ax: .res 2 + + .rodata + +fname: .byte "@0:XMODEM.TMP,P,W" ; @0: means 'overwrite if existing', ',P,W' is required to make this an output file +fname_end: +.byte 0 +first_message: + .byte "yo!",0 + +start_download: + .byte "R",0 +.data + +tcp_dest_ip: + .byte 10,5,1,102 +; .byte 192,168,160,1 + + + + +;-- LICENSE FOR test_xmodem.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 +; compliance with the License. You may obtain a copy of the License at +; http://www.mozilla.org/MPL/ +; +; Software distributed under the License is distributed on an "AS IS" +; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +; License for the specific language governing rights and limitations +; under the License. +; +; The Original Code is ip65. +; +; The Initial Developer of the Original Code is Jonno Downes, +; jonno@jamtronix.com. +; Portions created by the Initial Developer are Copyright (C) 2009 +; Jonno Downes. All Rights Reserved. +; -- LICENSE END -- diff --git a/dist/make_dist.rb b/dist/make_dist.rb index 690a533..9e24010 100644 --- a/dist/make_dist.rb +++ b/dist/make_dist.rb @@ -24,7 +24,8 @@ end ["client/carts/kipperkart.prg","c64/"], ["client/carts/kipperkart.bin","c64/"], ["client/carts/kipperkart_rr.bin","c64/"], -#["client/carts/kipperterm.bin","c64/"], +["client/carts/kipperterm.bin","c64/"], +["client/carts/kipperterm_rr.bin","c64/"], ["client/carts/netboot.bin","c64/"], ["client/nb65/d64_upload.prg","boot/"], ["client/examples/upnatom.prg","boot/"], diff --git a/dist/version_number.txt b/dist/version_number.txt index 450f88e..321816a 100644 --- a/dist/version_number.txt +++ b/dist/version_number.txt @@ -1 +1 @@ -1.0.20 \ No newline at end of file +1.0.24 \ No newline at end of file diff --git a/doc/CONTRIBUTORS.txt b/doc/CONTRIBUTORS.txt index 7817ad9..e28a7ca 100644 --- a/doc/CONTRIBUTORS.txt +++ b/doc/CONTRIBUTORS.txt @@ -1,6 +1,6 @@ CONTRIBUTORS -Jonno Downes - current maintainer of ip75, layers 4-7 (dhcp,dns,tcp,telnet, http, gopher) -Glenn Holmmer - icmp enhancements, bugfixes +Jonno Downes - current maintainer of ip65, author of layers 4-7 (dhcp,dns,tcp,telnet, http, gopher) +Glenn Holmer - icmp enhancements, bugfixes Per Olofsson - initial creator of ip65, layers 1-3 (eth,arp,ip,icmp,udp) Lars Stollenwerk - vt100 emulation diff --git a/doc/README.C64.html b/doc/README.C64.html index 26ee7b5..976748d 100644 --- a/doc/README.C64.html +++ b/doc/README.C64.html @@ -22,9 +22,9 @@ Within the major flavours, there are also variations in media - the majority of -

USING THE CARTRIDGE

+

USING THE CARTRIDGES

-When the cartridge starts, it will attempt to configure the IP stack via DHCP. If the DHCP config fails (either by timing out, or the user press RUN/STOP) +When one of the cartridge images start, it will attempt to configure the IP stack via DHCP. If the DHCP config fails (either by timing out, or the user press RUN/STOP) then the IP stack will fall back to using the IP configuration built into the cartridge. See the section "IP CONFIGURATION" for info on how to modify the cartridge defaults prior to burning an image.

@@ -42,8 +42,8 @@ Once the IP stack is initialised, an attempt to boot from the network will take pure machine language programs, since BASIC is not available when this cart is active. (NB - programs that are pure M/L except for a BASIC stub consisting of a single SYS call will be executed). -

  • F3 : UPLOAD D64. TBD
  • -
  • F4 : DOWNLOAD D64. A TFTP server is queried for a list of D64 files, which can be selected from a menu. Once a D64 file is selected, it will be downloaded and written to drive #8.
  • +
  • F3 : UPLOAD D64. You will prompted to specify a filename, then the disk in the default drive will be read and sent to the tftp server
  • +
  • F4 : DOWNLOAD D64. A TFTP server is queried for a list of D64 files, which can be selected from a menu. Once a D64 file is selected, it will be downloaded and written to the default drive (usually #8).
  • F5 : SID NETPLAY. A TFTP server is queried for a list of SID files, which can be selected from a menu. Once a SID file is selected, it will be played. Not all SIDs work yet.
  • F6 : PING. You will be prompted for a hostname which will be pinged 3 times, and a response time (in milliseconds) is printed for each ping.
  • F7 : CONFIG. This brings up a menu where the IP configuration can be modified. Changes made here will be persistent until the next reboot.
  • @@ -58,8 +58,7 @@ call, the target of the SYS call will be used as the address to start execution