From a3557f9a27ff861d7b30785caa98fc024beffe17 Mon Sep 17 00:00:00 2001 From: jonnosan Date: Sun, 8 Mar 2009 10:18:59 +0000 Subject: [PATCH] git-svn-id: http://svn.code.sf.net/p/netboot65/code@42 93682198-c243-4bdb-bd91-e943c89aac3b --- Makefile | 3 + client/cfg/rrbin.cfg | 5 +- client/clients/rrnetboot.s | 62 ++++++++--- client/drivers/Makefile | 2 +- client/drivers/c64inputs.s | 9 ++ client/drivers/c64print.s | 10 +- client/inc/menu.i | 55 ++++++---- client/ip65/tftp.s | 6 +- dist/make_dist_ip65.rb | 26 +++++ doc/ip65.html | 206 +++++++++++++++++++++++++++++++++++++ 10 files changed, 343 insertions(+), 41 deletions(-) create mode 100644 client/drivers/c64inputs.s create mode 100644 dist/make_dist_ip65.rb create mode 100644 doc/ip65.html diff --git a/Makefile b/Makefile index 8a1a7ed..58de413 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,9 @@ clean: dist: ruby dist/make_dist.rb + +dist-ip65: + ruby dist/make_dist_ip65.rb distclean: make -C client distclean diff --git a/client/cfg/rrbin.cfg b/client/cfg/rrbin.cfg index 9909924..7bec11e 100644 --- a/client/cfg/rrbin.cfg +++ b/client/cfg/rrbin.cfg @@ -1,3 +1,6 @@ +# CA65 config for a Retro Replay cartridge +# default is for GAME=1, EXROM=0, + MEMORY { ZP: start = $02, size = $1A, type = rw, define = yes; IP65ZP: start = $5f, size = $10, type = rw, define = yes; @@ -10,7 +13,7 @@ MEMORY { SEGMENTS { CARTRIDGE_HEADER: load = HEADER, type = ro; CODE: load = ROM, type = ro; - RODATA: load = ROM, type = ro; + RODATA: load = ROM, run=ROM, type = ro; DATA: load = ROM, run = RAM, type = rw, define = yes; BSS: load = RAM, type = bss; IP65ZP: load = IP65ZP, type = zp; diff --git a/client/clients/rrnetboot.s b/client/clients/rrnetboot.s index 480333d..3f318a0 100644 --- a/client/clients/rrnetboot.s +++ b/client/clients/rrnetboot.s @@ -12,13 +12,17 @@ .include "../inc/common.i" .include "../inc/commonprint.i" .include "../inc/net.i" - + .include "../inc/menu.i" + .import cls + .import get_key + .import beep + .importzp tftp_filename .import tftp_load_address - .import tftp_ip + .import tftp_ip .import tftp_download - .import cfg_tftp_server + .import tftp_directory_listing .import copymem .importzp copy_src @@ -34,6 +38,8 @@ ;temp_bcd: .res 2 bin_file_jmp: .res 3 +tftp_dir_buffer: .res 2000 + .segment "CARTRIDGE_HEADER" .word init ;cold start vector @@ -55,6 +61,12 @@ init: jsr $e453 ;set BASIC vectors jsr $e3bf ;initialize zero page + ;switch to lower case charset + lda #23 + sta $d018 + + + ldax #startup_msg jsr print @@ -69,27 +81,49 @@ init: init_ip_via_dhcp - - + bcc :+ + jmp bad_boot +: jsr print_ip_config - ldx #3 + ldx #3 : lda cfg_tftp_server,x sta tftp_ip,x dex bpl :- + + ldax #tftp_dir_buffer + stax tftp_load_address + + ldax #getting_dir_listing_msg + jsr print + + ldax #tftp_dir_filemask + stax tftp_filename + jsr print + jsr print_cr + + jsr tftp_directory_listing + bcs @dir_failed + ldax #$0000 ;load address will be first 2 bytes of file we dowload (LO/HI order) stax tftp_load_address + ldax #tftp_dir_buffer + jsr select_option_from_menu + stax tftp_filename + + ldax #downloading_msg jsr print - ldax #tftp_file + + ldax tftp_filename jsr download - bcc @file_downloaded_ok +@dir_failed: jmp bad_boot @file_downloaded_ok: @@ -146,12 +180,14 @@ download: .rodata -startup_msg: .byte "RR-NET NETWORK BOOK CLIENT V0.1",13,0 +startup_msg: .byte "NETBOOT65 - C64 NETWORK BOOK CLIENT V0.1",13,0 downloading_msg: .asciiz "DOWNLOADING " -tftp_file: - .asciiz "BOOTC64.PRG" +getting_dir_listing_msg: .asciiz "FETCHING TFTP DIRECTORY FOR " + +tftp_dir_listing_fail_msg: + .asciiz "DIR LISTING FAILED" tftp_download_fail_msg: .byte "DOWNLOAD FAILED", 13, 0 @@ -159,5 +195,5 @@ tftp_download_fail_msg: tftp_download_ok_msg: .byte "DOWNLOAD OK", 13, 0 - - \ No newline at end of file +tftp_dir_filemask: + .asciiz "*.PRG" diff --git a/client/drivers/Makefile b/client/drivers/Makefile index 4b0e47c..d6bebf6 100644 --- a/client/drivers/Makefile +++ b/client/drivers/Makefile @@ -20,7 +20,7 @@ all: $(DRIVERS) apple2net.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o ar65 a apple2net.lib $^ -c64net.lib: c64print.o rr-net.o c64timer.o c64kernal.o +c64net.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o ar65 a c64net.lib $^ clean: diff --git a/client/drivers/c64inputs.s b/client/drivers/c64inputs.s new file mode 100644 index 0000000..e80363f --- /dev/null +++ b/client/drivers/c64inputs.s @@ -0,0 +1,9 @@ +.export get_key + +.code +get_key: + jsr $ffe4 + cmp #0 + beq get_key + rts + \ No newline at end of file diff --git a/client/drivers/c64print.s b/client/drivers/c64print.s index c7e4a39..988da29 100644 --- a/client/drivers/c64print.s +++ b/client/drivers/c64print.s @@ -1,6 +1,8 @@ .export print_a .export print_cr +.export cls +.export beep .data print_a = $ffd2 @@ -9,5 +11,11 @@ print_a = $ffd2 print_cr: lda #13 - jmp $ffd2 + jmp print_a +cls: + lda #147 ; 'CLR/HOME' + jmp print_a + +beep: + rts \ No newline at end of file diff --git a/client/inc/menu.i b/client/inc/menu.i index 835b307..40c0272 100644 --- a/client/inc/menu.i +++ b/client/inc/menu.i @@ -11,6 +11,10 @@ options_shown_this_page: .res 1 options_table_pointer: .res 2 jump_to_prefix: .res 1 last_page_flag: .res 1 + +get_current_byte: .res 4 + + .code @@ -19,7 +23,13 @@ last_page_flag: .res 1 select_option_from_menu: stax options_table_pointer - stax @get_current_byte+1 + stax get_current_byte+1 +;set the 'LDA' and RTS' opcodes for the 'get current byte' subroutine, which is self-modified-code, hence must be located in RAM not ROM + lda #$ad ;opcode for LDA absolute + sta get_current_byte + lda #$60 ;opcode for RTS + sta get_current_byte+3 + lda #0 sta current_option sta current_option+1 @@ -34,33 +44,30 @@ select_option_from_menu: bne :+ inc number_of_options+1 : - jsr @get_current_byte + jsr get_current_byte bne @count_strings jmp @display_first_page_of_options @skip_past_next_null_byte: jsr @move_to_next_byte - jsr @get_current_byte + jsr get_current_byte bne @skip_past_next_null_byte jsr @move_to_next_byte rts -@get_current_byte: - lda $FFFF ;filled in from above - rts @move_to_next_byte: - inc @get_current_byte+1 + inc get_current_byte+1 bne :+ - inc @get_current_byte+2 + inc get_current_byte+2 : rts ;move the ptr along till it's pointing at the whatever is the value of current_option @move_to_current_option: ldax options_table_pointer - stax @get_current_byte+1 + stax get_current_byte+1 lda #0 sta temp_option_counter sta temp_option_counter+1 @@ -90,8 +97,6 @@ select_option_from_menu: lda #0 sta first_option_this_page sta first_option_this_page+1 -; lda #$D1 -; sta first_option_this_page @print_current_page: @@ -149,13 +154,13 @@ select_option_from_menu: lda #' ' jsr print_a -; lda @get_current_byte+2 +; lda get_current_byte+2 ; jsr print_hex -; lda @get_current_byte+1 +; lda get_current_byte+1 ; jsr print_hex - lda @get_current_byte+1 - ldx @get_current_byte+2 + lda get_current_byte+1 + ldx get_current_byte+2 jsr print jsr print_cr @@ -184,18 +189,20 @@ select_option_from_menu: ldax #jump_to_prompt jsr print lda #'?' + jsr get_key ora #$80 ;set the high bit + sta jump_to_prefix ldax options_table_pointer - stax @get_current_byte+1 + stax get_current_byte+1 lda #0 sta current_option sta current_option+1 @check_if_at_jump_to_prefix: - jsr @get_current_byte + jsr get_current_byte ora #$80 ;set high bit cmp jump_to_prefix beq @at_prefix @@ -204,7 +211,7 @@ select_option_from_menu: bne :+ inc current_option+1 : - jsr @get_current_byte + jsr get_current_byte bne @check_if_at_jump_to_prefix jsr beep ;if we got to the end of the options table without finding the char we want, then sound a beep jmp @jump_to_finished @@ -214,9 +221,7 @@ select_option_from_menu: lda current_option+1 sta first_option_this_page+1 @jump_to_finished: - jmp @print_current_page - - + jmp @print_current_page @print_instructions_and_get_keypress: @@ -231,7 +236,13 @@ select_option_from_menu: : @get_keypress: lda #'?' + jsr get_key + + jsr print_hex +; @fixme: +; jmp @fixme + cmp #'/'+$80 beq @jump_to cmp #$95 @@ -262,7 +273,7 @@ select_option_from_menu: sta current_option+1 jsr @move_to_current_option - ldax @get_current_byte+1 + ldax get_current_byte+1 rts diff --git a/client/ip65/tftp.s b/client/ip65/tftp.s index 8217edf..a524192 100644 --- a/client/ip65/tftp.s +++ b/client/ip65/tftp.s @@ -272,8 +272,7 @@ tftp_in: bne @not_an_error @recv_error: lda #tftp_error - sta tftp_state - + sta tftp_state rts @not_an_error: @@ -296,7 +295,8 @@ tftp_in: @dont_set_load_address: lda tftp_inp+3 ;get the (low byte) of the data block - bmi @recv_error ;if we get to block $80, we've d/led more than 64k! + +; bmi @recv_error ;if we get to block $80, we've d/led more than 64k! cmp tftp_expected_block_number beq :+ jmp @not_expected_block_number diff --git a/dist/make_dist_ip65.rb b/dist/make_dist_ip65.rb new file mode 100644 index 0000000..91d6d47 --- /dev/null +++ b/dist/make_dist_ip65.rb @@ -0,0 +1,26 @@ +gem 'archive-zip' +require 'archive/zip' +require 'ftools' + +WORKING_DIR=File.expand_path(File.dirname(__FILE__)+"/ip65") +SRC_DIR=File.expand_path(File.dirname(__FILE__)+"/../") +["","client","lib","bin","boot",].each do |dir_suffix| + dir_path="#{WORKING_DIR}/#{dir_suffix}" + Dir.mkdir(dir_path) unless File.exist?(dir_path) +end + +[ +["client/clients/utherboot.dsk","client/"], +["server/lib/tftp_server.rb","lib"], +["server/bin/tftp_only_server.rb","bin/tftp_server.rb"], +["server/bin/import_ags_games.rb","bin"], +["server/boot/BOOTA2.PG2","boot"], +["doc/README.txt",""], +].each do |args| + src="#{SRC_DIR}/#{args[0]}" + dest="#{WORKING_DIR}/#{args[1]}" + File.copy(src,dest) +end + +zipfile_name=File.dirname(__FILE__)+"/netboot65-#{Time.now.strftime("%Y-%m-%d")}.zip" +Archive::Zip.archive(zipfile_name, WORKING_DIR) diff --git a/doc/ip65.html b/doc/ip65.html new file mode 100644 index 0000000..9129e57 --- /dev/null +++ b/doc/ip65.html @@ -0,0 +1,206 @@ + + +IP65 - a TCP/IP stack for 6502 computers + + + + + + + +

IP65

+ +

+IP65 is a TCP/IP stack for 6502 based computers. +

+ + +

Status

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ServicesTCPDHCP/DNS/TFTPEcho
TransportUDPICMP
NetworkIP
AddressingARP
Ethernet driverCS8900A
Ethernet interfaceRR-Net / TFEUthernet
Host computerC64/C128Apple ][
+ Green: Working + Yellow: Partial + Red: Unimplemented +
+ + +

Download

+ +Latest release (sourceforge.net)

+ip65-2009-01-22.zip (paradroid.net) + + +

History

+
+  2009-03-08	Added DHCP, DNS, TFTP + moved to sourceforge
+  2009-01-22	Added copymem fix from Jonno Downes. Added MPL license.
+  2008-09-27	Added timeout fix for ineth_tx from David Schmidt.
+  2006-09-20	Fixed checksum calculation for odd packet sizes.
+  2006-02-22	Added fix for sending of packets larger than 256 bytes
+		from Ewen Wannop and Glenn Jones.
+
+ + +

Sample UDP listener source

+ +
+gangedport      = 60064
+
+        jsr ip65_init
+        lda #<gotpacket
+        ldx #>gotpacket
+        sta udp_callback
+        stx udp_callback + 1
+        lda #<gangedport
+        ldx #>gangedport
+        jsr udp_add_listener
+
+main:
+        jsr ip65_process
+        jmp main
+
+gotpacket:
+        sei
+        lda $01
+        pha
+        lda udp_inp
+        sta $01
+
+        lda udp_inp + 1
+        ldx udp_inp + 2
+        sta zp_data
+        stx zp_data + 2
+        ldy udp_inp + 3
+copy:
+        lda udp_inp + 3,y
+        sta (zp_data),y
+        dey
+        bne copy
+
+        pla
+        sta $01
+        cli
+        rts
+
+ +

Links

+ +A Standard for C64 TCP/IP Configuration + + +

License

+ +This project is released under the Mozilla Public License Version 1.1. +For details, please visit http://www.mozilla.org/MPL/. + + +