diff --git a/client/basic/Makefile b/client/basic/Makefile index 62c3a66..3034cf7 100644 --- a/client/basic/Makefile +++ b/client/basic/Makefile @@ -20,7 +20,8 @@ all: ip65 kipperbas.d64 bails.d64 kipperbasv20.prg ip65: make -C ../ip65 all -%.o: %.s $(INCFILES) +%.o: %.s $(INCFILES) timestamp.rb + ruby timestamp.rb > timestamp.i $(AS) $(AFLAGS) $< %.prg: %.o $(IP65LIB) $(C64RRNETLIB) $(INCFILES) ../cfg/kipperbas.cfg @@ -36,12 +37,13 @@ bails.d64: bails.prg # ripxplore.rb $@ -I CbmDos -a kipperbas.prg ripxplore.rb $@ -a bails.prg -kipperbas.d64: kipperbas.prg +kipperbas.d64: kipperbas.prg chat # ripxplore.rb -r -e kbload $@ -o kbload # ripxplore.rb -r -e kbapp $@ -o kbapp -# ripxplore.rb $@ -I CbmDos -a kipperbas.prg - ripxplore.rb $@ -a kipperbas.prg - + ripxplore.rb $@ -I CbmDos -a kipperbas.prg +# ripxplore.rb $@ -a kipperbas.prg + cp chat autoexec.bas +# ripxplore.rb $@ -a autoexec.bas -t C64Prg clean: rm -f *.o *.bin *.map *.prg diff --git a/client/basic/bails.d64 b/client/basic/bails.d64 index 83a7710..0bd5f6b 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 ef41e21..7689374 100644 Binary files a/client/basic/kipperbas.d64 and b/client/basic/kipperbas.d64 differ diff --git a/client/basic/kipperbas.s b/client/basic/kipperbas.s index d7c2441..21655f4 100644 --- a/client/basic/kipperbas.s +++ b/client/basic/kipperbas.s @@ -211,8 +211,11 @@ install_new_vectors_loop: rts welcome_banner: -.incbin "welcome_banner.txt" -.byte 0 +.byte " *** KIPPER BASIC 1.21" +.include "timestamp.i" +.byte " ***" + +.byte 13,0 end: .res 1 end_of_loader: @@ -1457,7 +1460,8 @@ tcpblat_keyword: jmp @store_error evaluate: - lda $00 + + lda #$00 sta $0D ;set string flag to not string jsr CHRGET cmp #$E3 ; PING keyword diff --git a/client/carts/Makefile b/client/carts/Makefile index 32684f5..82e4826 100644 --- a/client/carts/Makefile +++ b/client/carts/Makefile @@ -33,6 +33,7 @@ all: ip65 drivers\ kippergo.prg \ kippergo_rr.bin \ kkwiz_rr.bin \ + telnetd.prg \ kipperdisk.d64 \ kipperkart.o: kipperkart.s $(INCFILES) ../inc/ping.i ../inc/disk_transfer.i ../inc/sidplay.i ../inc/config_menu.i @@ -45,6 +46,7 @@ kippergo.o: kippergo.s $(INCFILES) ../inc/gopher.i ../inc/telnet.i ../inc/config $(AS) $(AFLAGS) -o $@ $< %.o: %.s $(INCFILES) + ruby timestamp.rb > timestamp.i $(AS) $(AFLAGS) $< kipperkart.prg: kipperkart.bin c64_cart_ram_header.prg @@ -120,6 +122,13 @@ kkwiz_rr.bin: kkwiz.bin cat rrnet_header.bin kkwiz.bin > kkwiz_rr.bin ruby fix_cart.rb $@ 32768 cp kkwiz_rr.bin ../wiznet/ + +telnetd.bin: telnetd.o $(IP65TCPLIB) $(C64RRNETLIB) $(INCFILES) ../cfg/c64_8kcart.cfg + $(LD) -m telnetd.map -vm -C ../cfg/c64_8kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64RRNETLIB) + ruby ../carts/fix_cart.rb $@ 8192 + +telnetd.prg: telnetd.bin cartheader.prg + cat cartheader.prg telnetd.bin > $@ d64_upload.d64: d64_upload.prg cp d64_upload.prg ../../server/boot/ diff --git a/client/carts/cartheader.s b/client/carts/cartheader.s new file mode 100644 index 0000000..f49c65c --- /dev/null +++ b/client/carts/cartheader.s @@ -0,0 +1,54 @@ + +.include "../inc/common.i" + +.import copymem +.importzp copy_src +.importzp copy_dest + +.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: + +;copy BASIC to RAM + ldax #$A000 + stax copy_src + stax copy_dest + ldax #$2000 + jsr copymem + +;copy cart data from end of file to $8000 (RAM) + ldax #cart_data + stax copy_src + ldax #$8000 + stax copy_dest + ldax #$2000 + jsr copymem + +;swap out the cartridge (also swaps out BASIC) + + lda $01 + and #$fe ;reset bit 0 + sta $01 + +;execute the cartridge from RAM + jmp ($8002) + + +.bss + +cart_data: ;this should point to where the cart data gets appended. + .res $2000 \ No newline at end of file diff --git a/client/carts/telnetd.s b/client/carts/telnetd.s new file mode 100644 index 0000000..9846b00 --- /dev/null +++ b/client/carts/telnetd.s @@ -0,0 +1,366 @@ +; ############# +; +; jonno@jamtronix.com - June 2011 +; Telnet server cartridge +; + +TELNET_PORT=6400 + .include "../inc/common.i" + .include "../inc/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_state + .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 + + INIT_MAGIC_VALUE=$C7 +.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: + lda #INIT_MAGIC_VALUE + cmp init_flag + bne @real_init + jmp $fe5e ; contine on to real RESTORE routine +@real_init: + sta init_flag + + + ;we need to set up BASIC as well + jsr $e453 ;set BASIC vectors + jsr $e3bf ;initialize zero page + +;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 + + +;set normal BASIC colour + LDA #$0e ;light blue + STA $D020 ;border + LDA #$06 ;dark blue + STA $D021 ;background + lda #$9a + jsr print_a + + ;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 + jsr print_cr + +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 #$8000 + stax copy_src + stax copy_dest + ldax #$4000 + 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 + lda sending_flag + bne @done + inc jiffy_count + lda jiffy_count + cmp #$06 ;about 100ms + bne @done + lda #0 + sta jiffy_count + lda tcp_state + 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 + sta sending_flag + ldax #output_buffer + jsr tcp_send + dec sending_flag + 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 $91 + lda #0 + sta break_flag +@no_stop: + jmp (old_stop_handler) + +.bss +init_flag: .res 1 +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 +sending_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/carts/timestamp.rb b/client/carts/timestamp.rb new file mode 100644 index 0000000..a061cf9 --- /dev/null +++ b/client/carts/timestamp.rb @@ -0,0 +1 @@ +puts Time.now.strftime(".byte \" (%Y-%m-%d)\"") \ No newline at end of file diff --git a/client/drivers/w5100.s b/client/drivers/w5100.s index 68cb16c..f04e10f 100644 --- a/client/drivers/w5100.s +++ b/client/drivers/w5100.s @@ -57,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_state .export tcp_connect_remote_port .export tcp_remote_ip @@ -160,9 +160,9 @@ eth_init: sta WIZNET_ADDR_LO lda #W5100_CMD_OPEN sta WIZNET_DATA_REG - - lda #0 - sta tcp_connected + + lda #tcp_cxn_state_closed + sta tcp_state clc rts @@ -203,7 +203,7 @@ eth_rx: ;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 + lda tcp_state beq @no_tcp jsr tcp_rx @@ -479,7 +479,9 @@ tcp_listen: jsr w5100_read_register cmp #W5100_STATUS_SOCK_ESTABLISHED bne @listen_loop - inc tcp_connected + + lda #tcp_cxn_state_established + sta tcp_state ;copy the remote IP address & port number ldax #W5100_S1_DIPR0 @@ -557,7 +559,9 @@ tcp_connect: jmp @set_error_and_exit @ok: - inc tcp_connected + lda #tcp_cxn_state_established + sta tcp_state + clc rts @error: @@ -751,8 +755,8 @@ tcp_rx: cmp #W5100_STATUS_SOCK_ESTABLISHED beq @connected_but_no_data ;no longer connected - lda #0 - sta tcp_connected + lda #tcp_cxn_state_closed + sta tcp_state lda #$ff sta tcp_inbound_data_length @@ -938,7 +942,7 @@ setup_tcp_socket: sta WIZNET_DATA_REG lda #0 - sta tcp_connected + sta tcp_state ldax #W5100_S1_MR ldy #W5100_MODE_TCP @@ -1011,7 +1015,7 @@ eth_ptr_hi=next_eth_packet_byte+2 rx_rd_ptr: .res 2 tcp_local_port: .res 2 -tcp_connected: .res 1 +tcp_state: .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 @@ -1027,6 +1031,11 @@ tcp_inbound_data_ptr: .res 2 tcp_connect_remote_port: .res 2 tcp_remote_ip = tcp_connect_ip +tcp_cxn_state_closed = 0 +tcp_cxn_state_listening = 1 ;(waiting for an inbound SYN) +tcp_cxn_state_syn_sent = 2 ;(waiting for an inbound SYN/ACK) +tcp_cxn_state_established = 3 ; + ;-- LICENSE FOR w5100a.s -- ; The contents of this file are subject to the Mozilla Public License diff --git a/client/ip65/udp.s b/client/ip65/udp.s index cabbb71..7a4ebe9 100644 --- a/client/ip65/udp.s +++ b/client/ip65/udp.s @@ -135,9 +135,7 @@ udp_process: bpl @checkport @drop: - lda #KPR_ERROR_NO_SUCH_LISTENER - sta ip65_error - sec + sec rts @handle: diff --git a/client/wiznet/Makefile b/client/wiznet/Makefile index 874edb8..ecc6925 100644 --- a/client/wiznet/Makefile +++ b/client/wiznet/Makefile @@ -28,6 +28,7 @@ all: ip65 drivers\ telnetd.prg \ wizbobcart.prg \ kt2wiz.d64 \ + wiztest.d64 \ bootc64.prg \ %.o: %.s $(INCFILES) timestamp.rb @@ -46,6 +47,9 @@ wizboot.bin: wizboot.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64_8 wizboot.prg: wizboot.bin cartheader.prg cat cartheader.prg wizboot.bin > $@ +telnetd.o: ../carts/telnetd.s $(INCFILES) timestamp.rb + $(AS) $(AFLAGS) ../carts/telnetd.s -o telnetd.o + 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 @@ -60,6 +64,9 @@ wizbobcart.bin: wizbobcart.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) wizbob wizbobcart.prg: wizbobcart.bin cartheader.prg cat cartheader.prg wizbobcart.bin > $@ +wiztest.d64: wiztest.prg + ripxplore.rb -I CbmDos -a wiztest.prg $@ + clean: rm -f *.o *.bin *.map *.prg *.pg2 *.dsk *.d64 @@ -77,7 +84,7 @@ kt2wiz.d64: bootc64.prg: - cp wizbobcart.prg ../../server/boot/bootc64.prg +# cp wizbobcart.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 + cp wiztest.prg ../../server/boot/bootc64.prg \ No newline at end of file diff --git a/client/wiznet/wiztest.s b/client/wiznet/wiztest.s index 8e1bee3..2ac58a5 100644 --- a/client/wiznet/wiztest.s +++ b/client/wiznet/wiztest.s @@ -7,16 +7,18 @@ WIZNET_BASE=$DE04 -;WIZNET_BASE=$DF20 WIZNET_MODE_REG = WIZNET_BASE WIZNET_ADDR_HI = WIZNET_BASE+1 WIZNET_ADDR_LO = WIZNET_BASE+2 WIZNET_DATA_REG = WIZNET_BASE+3 -TEST_LOOPS=$1F +TEST_LOOPS=$FF TX_BUFFER_START_PAGE=$40 +TIMER_POSITION_ROW=5 +TIMER_POSITION_COL=15 +TIMER_POSITION=$400+TIMER_POSITION_ROW*40+TIMER_POSITION_COL ; load A/X macro .macro ldax arg @@ -56,43 +58,262 @@ basicstub: .word 0 init: + - lda $de01 - eor #$01 - sta $de01 ;enable clock port + ;set funky colours + lda #$06 ; + sta $D020 ;border + lda #$00 ;dark blue + sta $D021 ;background + + + ldax #banner + jsr print + + lda $de01 + ora #1 ;turn on clockport + sta $de01 - lda #147 ;cls - jsr print_a - lda #142 ;go to upper case mode - jsr print_a lda #$80 ;reset sta WIZNET_MODE_REG lda WIZNET_MODE_REG beq @reset_ok - jmp @error ;writing a byte to the MODE register with bit 7 set should reset. + ;writing a byte to the MODE register with bit 7 set should reset. ;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 +@error: + ldax #not_found + jsr print + lda #>WIZNET_MODE_REG + jsr print_hex + lda #WIZNET_MODE_REG + jsr print_hex + lda #WIZNET_MODE_REG - jsr print_hex - lda #