diff --git a/CHANGES.txt b/CHANGES.txt index cbf346c..226c782 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +0.9.8 + - created stubs for TCP + - split nb65 cart images into 8k (UDP only - green) & 16k (UDP+TCP - purple) images 0.9.7 - tweak directory listing code in server so $ works by itself - client & server updated to support subdirectories (prefixed by $) \ No newline at end of file diff --git a/client/ip65/Makefile b/client/ip65/Makefile index 410aa62..78827f1 100644 --- a/client/ip65/Makefile +++ b/client/ip65/Makefile @@ -27,13 +27,16 @@ ETHOBJS= \ dottedquad.o \ output_buffer.o\ tftp.o \ - function_dispatcher.o \ + function_dispatcher.o \ + -all: ip65.lib +all: ip65.lib ip65_tcp.lib -ip65.lib: $(ETHOBJS) +ip65.lib: tcp_stub.o $(ETHOBJS) ar65 a ip65.lib $^ - + +ip65_tcp.lib: tcp.o $(ETHOBJS) + ar65 a ip65_tcp.lib $^ clean: rm -f *.o diff --git a/client/ip65/ip.s b/client/ip65/ip.s index f28078a..b4e3018 100644 --- a/client/ip65/ip.s +++ b/client/ip65/ip.s @@ -5,7 +5,6 @@ .export ip_calc_cksum .export ip_create_packet .export ip_send - .export ip_inp .export ip_outp .export ip_broadcast @@ -26,7 +25,7 @@ .exportzp ip_proto_tcp .exportzp ip_proto_udp - + .import cfg_mac .import cfg_ip @@ -53,6 +52,9 @@ .import udp_init .import udp_process + + .import tcp_init + .import tcp_process .importzp copy_src @@ -62,8 +64,8 @@ ; checksum ip_cksum_ptr: .res 2 ; pointer to data to be checksummed - - .bss + +.bss ip_cksum_len: .res 2 ; length of data to be checksummed @@ -117,12 +119,12 @@ ip_init: sta bad_addr sta bad_addr + 1 - jsr icmp_init + jsr icmp_init + jsr tcp_init jsr udp_init -; jsr tcp_init rts - + ;process an incoming packet & call the appropriate protocol handler ;inputs: @@ -152,7 +154,7 @@ ip_process: bne :+ jmp udp_process ; jump to udp handler : -tcp_process: +unknown_protocol: sec ; unknown protocol rts diff --git a/client/ip65/tcp.s b/client/ip65/tcp.s new file mode 100644 index 0000000..6550ed5 --- /dev/null +++ b/client/ip65/tcp.s @@ -0,0 +1,24 @@ +;TCP (transmission control protocol) functions + +.include "../inc/common.i" +.ifndef NB65_API_VERSION_NUMBER + .define EQU = + .include "../inc/nb65_constants.i" +.endif + +.import ip65_error + +.export tcp_init +.export tcp_process +.export tcp_add_listener +.export tcp_remove_listener +.export tcp_send + +tcp_add_listener: +tcp_remove_listener: +tcp_send: +tcp_process: +sec +inc $d020 +tcp_init: +rts diff --git a/client/ip65/tcp_stub.s b/client/ip65/tcp_stub.s new file mode 100644 index 0000000..995b812 --- /dev/null +++ b/client/ip65/tcp_stub.s @@ -0,0 +1,16 @@ +;stub functions that allows us to build a UDP only stack by linking in dummy tcp functions + +.export tcp_init +.export tcp_process +.export tcp_add_listener +.export tcp_remove_listener +.export tcp_send + + +tcp_add_listener: +tcp_remove_listener: +tcp_send: +tcp_process: +sec +tcp_init: +rts diff --git a/client/nb65/Makefile b/client/nb65/Makefile index 3dbc34a..5999181 100644 --- a/client/nb65/Makefile +++ b/client/nb65/Makefile @@ -13,20 +13,26 @@ INCFILES=\ IP65LIB=../ip65/ip65.lib +IP65TCPLIB=../ip65/ip65_tcp.lib + C64PROGLIB=../drivers/c64prog.lib C64NB65LIB=../drivers/c64nb65.lib APPLE2PROGLIB=../drivers/apple2prog.lib BOOTA2.PG2=../../server/boot/BOOTA2.PG2 -all: utherboot.dsk $(BOOTA2.PG2) nb65_rrnet.bin nb65_std_cart.bin nb65_c64_ram.prg d64_upload.prg c64boot.d64 d64_upload.d64 - +#all: utherboot.dsk $(BOOTA2.PG2) nb65_rrnet.bin nb65_std_cart.bin nb65_c64_ram.prg d64_upload.prg c64boot.d64 d64_upload.d64 +all: nb65_std_cart.bin nb65_tcp_cart.bin + nb65_c64_ram.o: nb65_c64.s $(INCFILES) $(AS) -DBANKSWITCH_SUPPORT=0 $(AFLAGS) -o $@ $< nb65_std_cart.o: nb65_c64.s $(INCFILES) $(AS) -DBANKSWITCH_SUPPORT=1 $(AFLAGS) -o $@ $< +nb65_tcp_cart.o: nb65_c64.s $(INCFILES) + $(AS) -DBANKSWITCH_SUPPORT=1 -DTCP $(AFLAGS) -o $@ $< + nb65_rrnet.o: nb65_c64.s $(INCFILES) $(AS) -DBANKSWITCH_SUPPORT=2 $(AFLAGS) -o $@ $< @@ -47,6 +53,10 @@ nb65_std_cart.bin: nb65_std_cart.o $(IP65LIB) $(C64NB65LIB) $(INCFILES) ../cfg/r $(LD) -m nb65_std_cart.map -vm -C ../cfg/rrbin.cfg -o $@ $< $(IP65LIB) $(C64NB65LIB) ruby fix_cart.rb $@ 8192 +nb65_tcp_cart.bin: nb65_tcp_cart.o $(IP65TCPLIB) $(C64NB65LIB) $(INCFILES) ../cfg/rrbin.cfg + $(LD) -m nb65_tcp_cart.map -vm -C ../cfg/rrbin.cfg -o $@ $< $(IP65TCPLIB) $(C64NB65LIB) + ruby fix_cart.rb $@ 16384 + nb65_rrnet.bin: nb65_rrnet.o $(IP65LIB) $(C64NB65LIB) $(INCFILES) ../cfg/rrbin.cfg $(LD) -m nb65_rrnet.map -Ln nb65_rr.lab -vm -C ../cfg/rrbin.cfg -o $@ $< $(IP65LIB) $(C64NB65LIB) ruby fix_cart.rb $@ 8193 diff --git a/client/nb65/nb65_c64.s b/client/nb65/nb65_c64.s index 93c5ecc..54696c8 100644 --- a/client/nb65/nb65_c64.s +++ b/client/nb65/nb65_c64.s @@ -141,11 +141,21 @@ init: ;set some funky colours + .ifdef TCP + LDA #$04 ;purple + .else LDA #$05 ;green - STA $D020 ;background + .endif + + STA $D020 ;border LDA #$00 ;black STA $D021 ;background - lda #$1E + .ifdef TCP + lda #$9c ;petscii for purple text + .else + lda #$1E ;petscii for green text + .endif + jsr print_a ;relocate our r/w data @@ -203,8 +213,10 @@ main_menu: bne @not_tftp jmp @tftp_boot @not_tftp: +.ifndef TCP cmp #KEYCODE_F3 beq @exit_to_basic +.endif cmp #KEYCODE_F5 bne @not_util_menu jsr print_main_menu @@ -472,11 +484,19 @@ cmp #KEYCODE_F7 lda nb65_param_buffer+NB65_TFTP_POINTER cmp #01 bne @not_a_basic_file - + lda nb65_param_buffer+NB65_TFTP_POINTER+1 cmp #$08 bne @not_a_basic_file + .ifdef TCP + ldax #cant_boot_basic + jsr print + jsr wait_for_keypress + jmp init + + .else + jsr $e453 ;set BASIC vectors jsr $e3bf ;initialize BASIC jsr $a86e @@ -488,7 +508,8 @@ cmp #KEYCODE_F7 jsr $a659 ; CLR (reset variables) ldax #$a7ae ; jump to BASIC interpreter loop jmp exit_cart_via_ax - + .endif + @not_a_basic_file: ldax nb65_param_buffer+NB65_TFTP_POINTER exit_cart_via_ax: @@ -496,7 +517,7 @@ exit_cart_via_ax: stx call_downloaded_prg+2 jmp exit_cart - + print_errorcode: ldax #error_code jsr print @@ -565,7 +586,11 @@ netboot65_msg: .byte 13,0 main_menu_msg: .byte 13," MAIN MENU",13,13 -.byte "F1: TFTP BOOT F3: BASIC",13 +.byte "F1: TFTP BOOT" +.ifndef TCP +.byte " F3: BASIC" +.endif +.byte 13 .byte "F5: ARP TABLE F7: CONFIG",13,13 .byte 0 @@ -614,6 +639,10 @@ press_a_key_to_continue: resolving: .byte "RESOLVING ",0 + .ifdef TCP +cant_boot_basic: .byte "BASIC FILE EXECUTION NOT SUPPORTED",13,0 + .endif + nb65_ram_stub: ; this gets copied to $C000 so programs can bank in the cartridge .byte $4E,$42,$36,$35 ; "NB65" - API signature diff --git a/client/nb65/nb65_version.i b/client/nb65/nb65_version.i index dc5a63f..a0b445f 100644 --- a/client/nb65/nb65_version.i +++ b/client/nb65/nb65_version.i @@ -1 +1 @@ -.byte "0.9.7" +.byte "0.9.8" diff --git a/server/bin/tftp_cat.rb b/server/bin/tftp_cat.rb new file mode 100644 index 0000000..16e72b2 --- /dev/null +++ b/server/bin/tftp_cat.rb @@ -0,0 +1,21 @@ +# a q&d hack for tftping down a file and dumping it to std-out +# useful for testing the netboot65 tftp server, especially the hacks for directory listings + + +require 'net/tftp' + +def usage + @progname=File.basename($0) + puts "usage: #{@progname} " + puts "specified filename will be downloaded from specified tftp server and dumpt to stdout" + true +end + +number_of_options=ARGV.length +usage && exit unless number_of_options==2 +servername=ARGV[0] +filename=ARGV[1] + +t = Net::TFTP.new(servername) +t.getbinary(filename,$stdout) + diff --git a/server/test/tc_file_list.rb b/server/test/tc_file_list.rb new file mode 100644 index 0000000..f586fe5 --- /dev/null +++ b/server/test/tc_file_list.rb @@ -0,0 +1,65 @@ +lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib") +$:.unshift(lib_path) unless $:.include?(lib_path) + +require 'test/unit' +require 'file_list' + + +BOOT_DIR=File.expand_path(File.dirname(__FILE__)+'/../boot') + +def log_msg(msg) + puts msg +end + +class TestFileList 0,"file list for $*.prg should not be empty") + assert(prg_file_list=~/\000\000$/,"$*.prg file list should end in two zeros") + assert(prg_file_list=~/\.prg/i,"$*.prg file list should contain at least one .prg file") + assert(!(prg_file_list=~/.pg2/i),"$*.prg file list should contain no .pg2 files") + assert(prg_file_list=~/\$\/subdir/i,"$*.prg file list should contain subdirectory") + + pg2_file_list=file_list["$/*.pg2"] + assert(pg2_file_list.length>0,"file list for $*.pg2 should not be empty") + assert(pg2_file_list=~/\000\000$/,"$*.pg2 file list should end in two zeros") + assert(pg2_file_list=~/\.pg2/i,"$*.pg2 file list should contain at least one .pg2 file") + assert(!(pg2_file_list=~/.prg/i),"$*.pg2 file list should contain at no .prg files") + + + puts "PG2 list" + puts pg2_file_list.split(0.chr).join("\n") + + subdir_file_list=file_list["$/subdir/*.prg"] + puts "SUBDIR list" + puts subdir_file_list.split(0.chr).join("\n") + + assert(subdir_file_list.length>0,"file list for $/subdir/*.prg should not be empty") + assert(subdir_file_list=~/\000\000$/,"$/subdir/*.prg file list should end in two zeros") + assert(subdir_file_list=~/\.prg/i,"$/subdir/*.prg file list should contain at least one .prg file") + assert(!(subdir_file_list=~/.pg2/i),"$/subdir/*.prg file list should contain no .pg2 files") + + + empty_subdir_file_list=file_list["$/subdir/empty/*.prg"] + puts "EMPTY SUBDIR list" + puts empty_subdir_file_list.split(0.chr).join("\n") +# assert_equal(2,empty_subdir_file_list.length,"file list for $/subdir/empty/*.prg should be empty") + + filemask="$/subdir/another_subdir/*.pg2" + multiple_subdir_file_list=file_list[filemask] + puts "MULTIPLE SUBDIR list" + puts multiple_subdir_file_list.split(0.chr).join("\n") + + assert(multiple_subdir_file_list.length>2,"file list for #{filemask} should not be empty") + assert(multiple_subdir_file_list=~/\.pg2/i,"#{filemask} file list should contain at least one .prg file") + assert_equal("/",multiple_subdir_file_list.split(0.chr)[0],"first entry file list for #{filemask} should be /") + assert_equal("/subdir",multiple_subdir_file_list.split(0.chr)[1],"first entry file list for #{filemask} should be /subdir") + +# puts file_list["$*.prg"] +# puts file_list["$/subdir/*.prg"] + end +end \ No newline at end of file