diff --git a/client/drivers/w5100.s b/client/drivers/w5100.s index cdbc0ad..e00ab52 100644 --- a/client/drivers/w5100.s +++ b/client/drivers/w5100.s @@ -45,8 +45,10 @@ WIZNET_DATA_REG = WIZNET_BASE+3 .export w5100_ip65_init .export w5100_read_register - .export w5100_write_register + .export w5100_select_register + .export w5100_write_register + .export w5100_set_ip_config .export tcp_connect .export tcp_connect_ip .export tcp_callback @@ -55,7 +57,7 @@ WIZNET_DATA_REG = WIZNET_BASE+3 .export tcp_send .export tcp_send_keep_alive .export tcp_close - + .export tcp_connected .export tcp_connect_remote_port .export tcp_remote_ip @@ -464,7 +466,7 @@ tcp_listen: ;now wait for the status to change to 'established' @listen_loop: - inc $d020 +; inc $d020 jsr ip65_process jsr check_for_abort_key bcc @no_abort @@ -897,7 +899,7 @@ jmp_to_callback: ;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: +w5100_set_ip_config: ldax #W5100_GAR0 jsr w5100_select_register ldx #0 @@ -924,7 +926,10 @@ setup_tcp_socket: inx cpx #$04 bne @ip_loop - + rts + +setup_tcp_socket: + jsr w5100_set_ip_config ldax #W5100_S1_PORT0 jsr w5100_select_register lda tcp_local_port+1 diff --git a/client/ip65/config.s b/client/ip65/config.s index 052adac..eadc5bb 100644 --- a/client/ip65/config.s +++ b/client/ip65/config.s @@ -3,20 +3,22 @@ .include "../inc/common.i" - .export cfg_mac - .export cfg_mac_default - .export cfg_ip - .export cfg_netmask - .export cfg_gateway - .export cfg_dns - .export cfg_tftp_server - .export cfg_get_configuration_ptr - .export cfg_init - .export cfg_default_drive - .export dhcp_server - .import copymem - .importzp copy_src - .importzp copy_dest +.export cfg_mac +.export cfg_mac_default +.export cfg_ip +.export cfg_netmask +.export cfg_gateway +.export cfg_dns +.export cfg_tftp_server +.export cfg_get_configuration_ptr +.export cfg_init +.export cfg_default_drive +.export cfg_size + +.export dhcp_server +.import copymem +.importzp copy_src +.importzp copy_dest .code ;return a pointer to where the IP configuration is kept @@ -61,7 +63,7 @@ cfg_size=cfg_end_defaults-cfg_mac_default+1 cfg_mac: .res 6 ;mac address to be assigned to local machine cfg_ip: .res 4 ;ip address of local machine (will be overwritten if dhcp_init is called) -cfg_netmask: .res 4, 0; netmask of local network (will be overwritten if dhcp_init is called) +cfg_netmask: .res 4; netmask of local network (will be overwritten if dhcp_init is called) cfg_gateway: .res 4 ;ip address of router on local network (will be overwritten if dhcp_init is called) cfg_dns: .res 4; ip address of dns server to use (will be overwritten if dhcp_init is called) dhcp_server: .res 4 ;will be set address of dhcp server that configuration was obtained from diff --git a/client/wiznet/Makefile b/client/wiznet/Makefile index 64b8927..8fc9069 100644 --- a/client/wiznet/Makefile +++ b/client/wiznet/Makefile @@ -24,9 +24,12 @@ all: ip65 drivers\ cartheader.prg \ wiztest.prg \ wizboot.prg \ + telnetd.bin \ + telnetd.prg \ bootc64.prg \ -%.o: %.s $(INCFILES) +%.o: %.s $(INCFILES) timestamp.rb + ruby timestamp.rb > timestamp.i $(AS) $(AFLAGS) $< @@ -34,21 +37,20 @@ all: ip65 drivers\ $(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65WIZNETLIB) $(C64WIZNETLIB) -kipperwizdisk.d64: ../carts/kkwiz.prg ../kipperterm2/kt2wiz.prg - ripxplore.rb --init CbmDos $@ -a ../carts/kkwiz.prg - ripxplore.rb $@ -a ../kipperterm2/addresses.txt -t C64Seq - ripxplore.rb $@ -a ../kipperterm2/abe -t C64Prg - ripxplore.rb $@ -a ../kipperterm2/kt2wiz.prg -t C64Prg - ripxplore.rb $@ -a ../examples/webnoter.prg -t C64Prg - cp $@ ../../server/boot/ - wizboot.bin: wizboot.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64_8kcart.cfg $(LD) -m wizboot.map -vm -C ../cfg/c64_8kcart.cfg -o $@ $< $(IP65WIZNETLIB) $(C64WIZNETLIB) ruby ../carts/fix_cart.rb $@ 8192 wizboot.prg: wizboot.bin cartheader.prg - cat cartheader.prg wizboot.bin > wizboot.prg + cat cartheader.prg wizboot.bin > $@ +telnetd.bin: telnetd.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64_8kcart.cfg + $(LD) -m telnetd.map -vm -C ../cfg/c64_8kcart.cfg -o $@ $< $(IP65WIZNETLIB) $(C64WIZNETLIB) + ruby ../carts/fix_cart.rb $@ 8192 + +telnetd.prg: telnetd.bin cartheader.prg + cat cartheader.prg telnetd.bin > $@ + clean: rm -f *.o *.bin *.map *.prg *.pg2 *.dsk *.d64 @@ -62,5 +64,6 @@ drivers: make -C ../drivers all bootc64.prg: - cp wizboot.prg ../../server/boot/bootc64.prg + cp telnetd.prg ../../server/boot/bootc64.prg +# cp wizboot2.prg ../../server/boot/bootc64.prg # cp wiztest.prg ../../server/boot/bootc64.prg \ No newline at end of file diff --git a/client/wiznet/commonprint.i b/client/wiznet/commonprint.i index 612cefe..7e32057 100644 --- a/client/wiznet/commonprint.i +++ b/client/wiznet/commonprint.i @@ -7,7 +7,6 @@ .export print_hex .export print_ip_config - .export dhcp_msg .export ok_msg .export failed_msg .export init_msg @@ -310,54 +309,51 @@ print_errorcode: .rodata hexdigits: -.byte "0123456789abcdef" +.byte "0123456789ABCDEF" interface_type: -.byte "interface : ",0 +.byte "INTERFACE : ",0 mac_address_msg: -.byte "mac address : ", 0 +.byte "MAC ADDRESS : ", 0 ip_address_msg: -.byte "ip address : ", 0 +.byte "IP ADDRESS : ", 0 netmask_msg: -.byte "netmask : ", 0 +.byte "NETMASK : ", 0 gateway_msg: -.byte "gateway : ", 0 +.byte "GATEWAY : ", 0 dns_server_msg: -.byte "dns server : ", 0 +.byte "DNS SERVER : ", 0 dhcp_server_msg: -.byte "dhcp server : ", 0 +.byte "DHCP SERVER : ", 0 tftp_server_msg: -.byte "tftp server : ", 0 - -dhcp_msg: - .byte "dhcp",0 +.byte "TFTP SERVER : ", 0 init_msg: - .byte " initializing ",0 + .byte " INITIALIZING ",0 +dns_lookup_failed_msg: + .byte "DNS LOOKUP " failed_msg: - .byte "failed", 0 + .byte "FAILED", 0 ok_msg: - .byte "ok", 0 + .byte "OK", 0 + -dns_lookup_failed_msg: - .byte "dns lookup failed", 0 - error_code: - .asciiz "error code: " + .asciiz "ERROR CODE: " press_a_key_to_continue: - .byte "press a key to continue",10,0 + .byte "PRESS A KEY TO CONTINUE",13,0 diff --git a/client/wiznet/kipperwizdisk.d64 b/client/wiznet/kipperwizdisk.d64 index 1d4f3f9..c521e10 100644 Binary files a/client/wiznet/kipperwizdisk.d64 and b/client/wiznet/kipperwizdisk.d64 differ diff --git a/client/wiznet/telnetd.s b/client/wiznet/telnetd.s new file mode 100644 index 0000000..424d4d8 --- /dev/null +++ b/client/wiznet/telnetd.s @@ -0,0 +1,338 @@ +; ############# +; +; jonno@jamtronix.com - June 2011 +; Telnet server cartridge +; + +TELNET_PORT=6400 + .include "../inc/common.i" + .include "commonprint.i" + + .import ip65_init + .import dhcp_init + .import w5100_set_ip_config + .import cls + .import beep + .import exit_to_basic + .import timer_vbl_handler + .import get_key_ip65 + .import cfg_mac + .import cfg_size + .import cfg_ip + .import cfg_netmask + .import cfg_gateway + .import cfg_dns + .import cfg_tftp_server + .import cfg_get_configuration_ptr + .import ip65_process + .import copymem + .import tcp_listen + .import tcp_callback + .import tcp_send + .import tcp_send_data_len + .import tcp_inbound_data_length + .import tcp_inbound_data_ptr + .import tcp_connected + .importzp copy_src + .importzp copy_dest + buffer_ptr=copy_dest + .import __DATA_LOAD__ + .import __DATA_RUN__ + .import __DATA_SIZE__ + .import __SELF_MODIFIED_CODE_LOAD__ + .import __SELF_MODIFIED_CODE_RUN__ + .import __SELF_MODIFIED_CODE_SIZE__ + + + CINV=$314 ;vector to IRQ interrupt routine + ISTOP=$328;vector to kernal routine to check if STOP key pressed + KEYD=$277 ;input keyboard buffer + NDX=$C6 ;number of keypresses in buffer + XMAX=$289 ;max keypresses in buffer + STKEY=$91 ;last key pressed + +.segment "CARTRIDGE_HEADER" +.word cold_init ;cold start vector +.word warm_init ;warm start vector +.byte $C3,$C2,$CD,$38,$30 ; "CBM80" +.byte $0,$0,$0 ;reserved for future use +.byte $0,$0,$0 ;reserved for future use +.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: + +;relocate our r/w data + ldax #__DATA_LOAD__ + stax copy_src + ldax #__DATA_RUN__ + stax copy_dest + ldax #__DATA_SIZE__ + jsr copymem + ldax #__SELF_MODIFIED_CODE_LOAD__ + stax copy_src + ldax #__SELF_MODIFIED_CODE_RUN__ + stax copy_dest + ldax #__SELF_MODIFIED_CODE_SIZE__ + jsr copymem + + + ;copy KERNAL to RAM so we can patch it + + + ldax #startup_msg + jsr print + + jsr ip65_init + + bcs init_failed + jsr dhcp_init + bcc init_ok +init_failed: + + jsr print_errorcode + jsr print_ip_config +flash_forever: + inc $d020 + jmp flash_forever +init_ok: + +;install our new IRQ handler + sei + ldax CINV + stax old_tick_handler + ldax #tick_handler + stax CINV + +;install our new STOP handler + + ldax ISTOP + stax old_stop_handler + ldax #stop_handler +; stax ISTOP + + cli + +start_listening: + + ldax #telnet_callback + stax tcp_callback + ldax #listening + jsr print + ldax #cfg_ip + jsr print_dotted_quad + ldax #port + jsr print + + + ;we need to copy BASIC as well since swapping KERNAL forces swap of BASIC + ldax #$A000 + stax copy_src + stax copy_dest + ldax #$2000 + jsr copymem + + ldax #$E000 + stax copy_src + stax copy_dest + ldax #$2000 + jsr copymem + + ;now intercept calls to $E716 + ;we do this instead of using the $326 vector because the BASIC + ;'READY' loop calls $E716 directly rather than calling $FFD2 + lda #$4C ;JMP + sta $e716 + ldax #new_charout + stax $e717 + + + ;swap out BASIC & KERNAL + lda #$35 + sta $01 + + + ldax #TELNET_PORT + jsr tcp_listen + ldax #term_setup_string_length + sta tcp_send_data_len + ldax #term_setup_string + jsr tcp_send + + + + jmp $E397 + +wait_for_keypress: + ldax #press_a_key_to_continue + jsr print +@loop: + jsr $ffe4 + beq @loop + rts + +get_key: +@loop: + jsr $ffe4 + beq @loop + rts + + +tick_handler: ;called at least 60hz via $314 + inc jiffy_count + lda jiffy_count + cmp #$06 ;about 100ms + bne @done + lda #0 + sta jiffy_count + lda tcp_connected + beq @done + jsr ip65_process +@done: + jmp (old_tick_handler) + + +telnet_callback: + lda tcp_inbound_data_length+1 + cmp #$ff + bne @not_eof + ldax #connection_closed + jsr print + + jmp start_listening + +@not_eof: + ldax tcp_inbound_data_ptr + stax buffer_ptr + ldy #0 + +@next_byte: + ldx NDX + cpx XMAX + beq @done + + lda (buffer_ptr),y +; cmp #$03 ;is ^C? +; bne @not_ctrl_c +; inc break_flag +; jmp @key_done +@not_ctrl_c: + inc NDX + sta KEYD,x +@key_done: + iny + cpy tcp_inbound_data_length + bne @next_byte + @done: + rts + +new_charout: + pha ;original $e716 code we patched over + sta $d7 ;original $e716 code we patched over + stx temp_x + sty temp_y + sta output_buffer + pha + ldax #1 + sta tcp_send_data_len + ldax #output_buffer + jsr tcp_send + pla + ldx temp_x + ldy temp_y + jmp $e719 ;after the code we patched + +stop_handler: + lda break_flag + beq @no_stop + lda #$7f + sta STKEY + lda #0 + sta break_flag +@no_stop: + jmp (old_stop_handler) + +.bss +old_tick_handler: .res 2 +old_stop_handler: .res 2 +temp_x : .res 1 +temp_y : .res 1 +output_buffer: .res 64 + +.data +jiffy_count: .byte 0 +break_flag: .byte 0 + +.rodata + +startup_msg: +.byte 147 ;cls +;.byte 14 ;lower case +.byte 142 ;upper case +.byte 13,"TELNETD " +.include "../inc/version.i" +.include "timestamp.i" +.byte 13 +.byte 0 +listening: +.byte 13,"LISTENING ON " +.byte 0 +port: +.byte ":" +.if (TELNET_PORT > 999 ) +.byte <(((TELNET_PORT / 1000) .mod 10) + $30) +.endif +.if TELNET_PORT>99 +.byte <(((TELNET_PORT / 100 ) .mod 10) + $30) +.endif +.byte <(((TELNET_PORT / 10 ) .mod 10) + $30) +.byte <(((TELNET_PORT ) .mod 10) + $30) +.byte 13 +.byte "HIT RUN/STOP TO ABORT" +.byte 0 + +connection_closed: +.byte 13,"CONNECTION CLOSED",13,0 + +term_setup_string: + .byte 142 ;upper case + .byte 147 ;cls +term_setup_string_length=*-term_setup_string + +;we need a 'dummy' segment here - some drivers use this segment (e.g. wiznet), some don't (e.g. rr-net) +;if we don't declare this, we get an 'undefined segment' error when linking to a driver that doesn't use it. +.segment "SELF_MODIFIED_CODE" + +;-- LICENSE FOR wizboot.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 wizboot. +; +; The Initial Developer of the Original Code is Jonno Downes, +; jonno@jamtronix.com. +; Portions created by the Initial Developer are Copyright (C) 2011 +; Jonno Downes. All Rights Reserved. +; -- LICENSE END -- diff --git a/client/wiznet/wizboot.s b/client/wiznet/wizboot.s index 02b8828..e50be4a 100644 --- a/client/wiznet/wizboot.s +++ b/client/wiznet/wizboot.s @@ -14,12 +14,14 @@ .import tftp_load_address .import tftp_download .import tftp_callback_vector - + .import w5100_set_ip_config .import cls .import beep .import exit_to_basic .import timer_vbl_handler .import get_key_ip65 + .import cfg_mac + .import cfg_size .import cfg_ip .import cfg_netmask .import cfg_gateway @@ -29,11 +31,10 @@ .import dns_ip .import dns_set_hostname .import dns_resolve - - + .import ip65_process .import copymem - .importzp copy_src - .importzp copy_dest + .importzp copy_src + .importzp copy_dest .import get_filtered_input .import __DATA_LOAD__ .import __DATA_RUN__ @@ -44,6 +45,8 @@ SCNKEY=$FF9F ;Query keyboard - put matrix code into $00CB & status of shift keys $028D + IP_CONFIG_SNAPSHOT=$200 + .bss tmp_load_address: .res 2 shift_pressed_on_bootup : .res 1 @@ -142,7 +145,14 @@ flash_forever: inc $d020 jmp flash_forever init_ok: - + ;stash the IP config we just got somewhere that other WizNet apps can get it + ldax #cfg_mac + stax copy_src + ldax #IP_CONFIG_SNAPSHOT + stax copy_dest + ldax #cfg_size + jsr copymem + lda shift_pressed_on_bootup bne @skip_resolving_tftp_hostname @@ -264,34 +274,39 @@ get_key: .rodata wizboot_msg: -.byte 147,14,13,"wiznet cart - v" +.byte 147 ;cls +;.byte 14 ;lower case +.byte 142 ;upper case +.byte 13," WIZNET CART - V" .include "../inc/version.i" - +.include "timestamp.i" .byte 13 -.byte 13," hold c= for basic / shift for lan boot",13,13 +.byte 13," HOLD C= FOR BASIC / SHIFT FOR LAN BOOT",13,13 .byte 0 -downloading_msg: .byte 13,"downloading ",0 +downloading_msg: .byte 13,"DOWNLOADING ",0 tftp_download_fail_msg: - .byte "download failed", 13, 0 + .byte "DOWNLOAD FAILED", 13, 0 tftp_download_ok_msg: - .byte 13,"download ok", 13, 0 + .byte 13,"DOWNLOAD OK", 13, 0 tftp_file: - .asciiz "bootc64.prg" + .asciiz "BOOTC64.PRG" resolving_tftp_hostname: - .byte "resolving " + .byte "RESOLVING " tftp_hostname: - .asciiz "jamtronix.com" + .asciiz "JAMTRONIX.COM" .data new_tftp_callback_vector: jsr $ffff lda #'.' jmp print_a - + + + ;we need a 'dummy' segment here - some drivers use this segment (e.g. wiznet), some don't (e.g. rr-net) ;if we don't declare this, we get an 'undefined segment' error when linking to a driver that doesn't use it. .segment "SELF_MODIFIED_CODE" diff --git a/client/wiznet/wizboot2.s b/client/wiznet/wizboot2.s index 75f0bfe..505222e 100644 --- a/client/wiznet/wizboot2.s +++ b/client/wiznet/wizboot2.s @@ -3,6 +3,29 @@ .import cfg_get_configuration_ptr .include "../inc/commonprint.i" +.include "../drivers/w5100.i" + +IP_CONFIG_SNAPSHOT=$200 + +.import copymem +.importzp copy_src +.importzp copy_dest +.import ip_init +.import arp_init +.import timer_init +.import cfg_mac +.import cfg_size +.import url_download +.import url_download_buffer +.import url_download_buffer_length + + +.import __DATA_LOAD__ +.import __DATA_RUN__ +.import __DATA_SIZE__ +.import __SELF_MODIFIED_CODE_LOAD__ +.import __SELF_MODIFIED_CODE_RUN__ +.import __SELF_MODIFIED_CODE_SIZE__ .segment "STARTUP" ;this is what gets put at the start of the file on the C64 @@ -22,15 +45,61 @@ basicstub: init: - ldax #hello + ;copy IP parameters & MAC address that we stashed in the 'stage 1' loader + + ldax #IP_CONFIG_SNAPSHOT + stax copy_src + ldax #cfg_mac + stax copy_dest + ldax #cfg_size + jsr copymem + + jsr timer_init ; initialize timer + jsr arp_init ; initialize arp + jsr ip_init ; initialize ip, icmp, udp, and tcp + + ldax #download_buffer + stax url_download_buffer + ldax #download_buffer_length + stax url_download_buffer_length + ldax #banner jsr print -: - inc $d020 - jmp :- + ldax #initial_resource_file + jsr get_resource_file + +@loop: + jmp @loop + rts -.data -hello: .byte "hello world!",0 +get_resource_file: + stax resource_file + ldax #retrieving + jsr print_ascii_as_native + ldax resource_file + jsr print_ascii_as_native + ldax resource_file + jsr url_download + bcc @download_ok + print_failed + jsr print_errorcode + rts +@download_ok: + ldax #download_buffer + jsr print_ascii_as_native + rts + +.rodata +banner: +.byte 147 ;cls +.byte 14 ;lower case +.byte "wIZnET lOADER - sTAGE 2",13,0 +retrieving: .asciiz "Fetch " +initial_resource_file: .byte "http://jamtronix.com/c64files.txt",0 +.bss +resource_file: .res 2 +download_buffer: .res 8192 +download_buffer_length=*-download_buffer ;-- LICENSE FOR wizboot2.s -- ; The contents of this file are subject to the Mozilla Public License