git-svn-id: http://svn.code.sf.net/p/netboot65/code@201 93682198-c243-4bdb-bd91-e943c89aac3b

This commit is contained in:
jonnosan 2009-10-05 03:01:58 +00:00
parent 07028be070
commit 8ef5101463
16 changed files with 159 additions and 115 deletions

View File

@ -16,9 +16,9 @@ IP65LIB=../ip65/ip65.lib
IP65TCPLIB=../ip65/ip65_tcp.lib
C64PROGLIB=../drivers/c64prog.lib
C64NB65LIB=../drivers/c64nb65.lib
#C64NB65LIB=../drivers/c64nb65.lib
all: kipperkart.bin kipperkart_rr.bin netboot.bin kipperterm.bin
all: kipperkart.bin kipperkart_rr.bin netboot.bin kipperterm.bin kipperkart.prg
kipperkart.o: kipperkart.s $(INCFILES) ../inc/ping.i ../inc/disk_transfer.i ../inc/sidplay.i
$(AS) $(AFLAGS) -o $@ $<
@ -29,6 +29,9 @@ kipperterm.o: kipperterm.s $(INCFILES) ../inc/gopher.i ../inc/telnet.i
%.o: %.s $(INCFILES)
$(AS) $(AFLAGS) $<
kipperkart.prg: kipperkart.bin c64_cart_ram_header.prg
cat c64_cart_ram_header.prg kipperkart.bin > kipperkart.prg
%.prg: %.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
$(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB)
@ -36,13 +39,13 @@ netboot.bin: netboot.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64_8kcart.cf
$(LD) -m netboot.map -vm -C ../cfg/c64_8kcart.cfg -o $@ $< $(IP65LIB) $(C64PROGLIB)
ruby fix_cart.rb $@ 8192
kipperkart.bin: kipperkart.o $(IP65TCPLIB) $(C64NB65LIB) $(INCFILES) ../cfg/c64_16kcart.cfg
$(LD) -m kipperkart.map -vm -C ../cfg/c64_16kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64NB65LIB)
kipperkart.bin: kipperkart.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64_16kcart.cfg
$(LD) -m kipperkart.map -vm -C ../cfg/c64_16kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64PROGLIB)
ruby fix_cart.rb $@ 16384
ruby dupe_cart.rb kipperkart.bin kipperkart_29c040.bin 32
kipperterm.bin: kipperterm.o $(IP65TCPLIB) $(C64NB65LIB) $(INCFILES) ../cfg/c64_16kcart.cfg
$(LD) -m kipperterm.map -vm -C ../cfg/c64_16kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64NB65LIB)
kipperterm.bin: kipperterm.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64_16kcart.cfg
$(LD) -m kipperterm.map -vm -C ../cfg/c64_16kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64PROGLIB)
ruby fix_cart.rb $@ 16384
ruby dupe_cart.rb kipperterm.bin kipperterm_29c040.bin 32

View File

@ -23,13 +23,22 @@ basicstub:
.word 0
init:
;turn off BASIC
lda $01
and #$FE ;mask out bit 0
sta $01
;now relocate the cart
ldax #cart_data
stax copy_src
ldax #$8000
stax copy_dest
ldax #$2000
ldax #$4000
jsr copymem
jmp ($8000) ;cold start vector
jmp ($8002) ;warm start vector
;copy memory
;inputs:
@ -68,6 +77,4 @@ copymem:
;this is where the cart data will be appended to:
cart_data:

View File

@ -92,7 +92,7 @@
.import cfg_tftp_server
kipper_param_buffer = $6000
directory_buffer = $6020
directory_buffer = $4020
.bss
@ -101,7 +101,7 @@ temp_ptr: .res 2
call_downloaded_prg:
jsr $0000 ;overwritten when we load a file
jmp init
jmp cold_init
get_value_of_axy: ;some more self-modifying code
lda $ffff,y
@ -109,19 +109,18 @@ get_value_of_axy: ;some more self-modifying code
.segment "CARTRIDGE_HEADER"
.word init ;cold start vector
.word $FE47 ;warm start vector
.word cold_init ;cold start vector
.word warm_init ;warm start vector
.byte $C3,$C2,$CD,$38,$30 ; "CBM80"
.byte "KIPPER" ; API signature
jmp kipper_dispatcher ; KPR_DISPATCH_VECTOR : entry point for KIPPER functions
jmp ip65_process ;KPR_PERIODIC_PROCESSING_VECTOR : routine to be periodically called to check for arrival of ethernet packets
jmp timer_vbl_handler ;KPR_VBL_VECTOR : routine to be called during each vertical blank interrupt
.byte $0,$0,$0 ;reserved for future use
.code
init:
cold_init:
;first let the kernal do a normal startup
sei
@ -130,7 +129,8 @@ init:
jsr $fd15 ;set vectors for KERNAL
jsr $ff5B ;init. VIC
cli ;KERNAL init. finished
warm_init:
;set some funky colours
LDA #$04 ;purple
@ -215,12 +215,14 @@ main_menu:
@not_f2:
cmp #KEYCODE_F3
bne @not_f3
.byte $92 ; fixme
bne @not_f3
jsr upload_d64
jmp main_menu
@not_f3:
cmp #KEYCODE_F4
bne @not_f4
jmp d64_download
jsr d64_download
jmp main_menu
@not_f4:
cmp #KEYCODE_F5
@ -460,7 +462,7 @@ boot_into_file:
ldax #cant_boot_basic
jsr print
jsr wait_for_keypress
jmp init
jmp warm_init
@not_a_basic_file:
ldax kipper_param_buffer
@ -750,6 +752,8 @@ autoexec_filename: .byte "AUTOEXEC.PRG",0
downloading_msg: .byte "DOWN"
loading_msg: .asciiz "LOADING "
uploading_msg: .byte "UPLOADING ",0
getting_dir_listing_msg: .byte "FETCHING DIRECTORY",13,0
dir_listing_fail_msg:

View File

@ -106,7 +106,7 @@ temp_ptr: .res 2
.byte "KIPPER" ; API signature
jmp kipper_dispatcher ; KPR_DISPATCH_VECTOR : entry point for KIPPER functions
jmp ip65_process ;KPR_PERIODIC_PROCESSING_VECTOR : routine to be periodically called to check for arrival of ethernet packets
jmp timer_vbl_handler ;KPR_VBL_VECTOR : routine to be called during each vertical blank interrupt
.byte $0,$0,$0 ;reserved for future use
.code

View File

@ -13,7 +13,7 @@ AFLAGS=
DRIVERS=\
apple2prog.lib \
c64prog.lib \
c64nb65.lib \
# c64nb65.lib \
all: $(DRIVERS)
@ -24,8 +24,8 @@ apple2prog.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o a2charconv.o
c64prog.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o
ar65 a $@ $^
c64nb65.lib: c64print.o rr-net.o c64timer_nb65.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o
ar65 a $@ $^
#c64nb65.lib: c64print.o rr-net.o c64timer_nb65.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o
# ar65 a $@ $^
clean:
rm -f *.o

View File

@ -678,11 +678,6 @@ print_errorcode:
update_KPR_counters_irq:
start_irq
jsr KPR_VBL_VECTOR
jmp exit_from_irq
play_music_irq:
; inc BORDER_COLOR
@ -816,8 +811,6 @@ raster_jump_table:
.byte $0,$20
.word pixel_scroll_irq
.byte $0,$30
.word update_KPR_counters_irq
.byte $0,$80
.word play_music_irq
@ -857,6 +850,7 @@ scroll_template:
feed_url:
.byte "http://static.cricinfo.com/rss/livescores.xml",0
.byte "http://search.twitter.com/search.atom?q=kipper",0
;leave space for whatever we read in from disk
.repeat 128

View File

@ -2,6 +2,7 @@
.import io_track_no
.import io_sector_no
.import io_write_sector
.import io_read_sector
.segment "APP_SCRATCH"
@ -11,7 +12,7 @@
sectors_in_track: .res 1
sector_buffer_address: .res 2
;the io_* an tftp_* routines both use the 'output_buffer' so we lose the data in the second sector
;the io_* and tftp_* routines both use the 'output_buffer' so we lose the data in the second sector
;therefore we need to copy the data to here before we use it
sector_buffer: .res 512
@ -28,6 +29,7 @@ download_d64:
stax kipper_param_buffer+KPR_TFTP_POINTER
ldax #kipper_param_buffer
kippercall #KPR_TFTP_CALLBACK_DOWNLOAD
after_tftp_transfer:
bcc :+
jsr print_cr
print_failed
@ -41,6 +43,54 @@ download_d64:
rts
upload_d64:
ldax #enter_filename
jsr print
kippercall #KPR_INPUT_HOSTNAME ;the 'hostname' filter is pretty close to being a filter for legal chars in file names as well
bcc :+
rts
:
stax kipper_param_buffer+KPR_TFTP_FILENAME
jsr cls
;switch to lower case charset
lda #23
sta $d018
ldax #uploading_msg
jsr print
ldax kipper_param_buffer+KPR_TFTP_FILENAME
jsr print
jsr reset_counters_to_first_sector
ldax #read_next_block
stax kipper_param_buffer+KPR_TFTP_POINTER
ldax #kipper_param_buffer
kippercall #KPR_TFTP_CALLBACK_UPLOAD
jmp after_tftp_transfer
read_next_block:
;tftp upload callback routine
;AX will point to address to fill
stax sector_buffer_address
lda track
cmp #36
beq @past_last_track
jsr read_sector
jsr move_to_next_sector
bcc @not_last_sector
ldax #$100
rts
@not_last_sector:
inc sector_buffer_address+1
ldax sector_buffer_address
jsr read_sector
jsr move_to_next_sector
ldax #$200
rts
@past_last_track:
ldax #$0000
rts
save_sector:
ldax #position_cursor_for_track_display
jsr print
@ -58,7 +108,27 @@ save_sector:
inc errors
:
jmp move_to_next_sector
read_sector:
ldax #position_cursor_for_track_display
jsr print
jsr print_current_sector
lda track
sta io_track_no
lda sector
sta io_sector_no
ldax sector_buffer_address
jsr io_read_sector
bcc :+
inc errors
:
jmp move_to_next_sector
write_next_block:
;tftp download callback routine
;AX will point at block to be written (prepended with 2 bytes indicating block length)
@ -73,10 +143,6 @@ write_next_block:
stax sector_buffer_address
ldax #$200
jsr copymem
jsr save_sector
bcc @not_last_sector
@ -165,4 +231,6 @@ errors_msg:
.byte " ERRORS $",0
position_cursor_for_track_display:
.byte $13,13,13,0
position_cursor_for_error_display:
.byte $13,13,13,0
enter_filename: .asciiz "FILENAME: "

View File

@ -8,7 +8,6 @@ KPR_API_VERSION_NUMBER EQU $01
KPR_CART_SIGNATURE EQU $8009
KPR_DISPATCH_VECTOR EQU $800f
KPR_PERIODIC_PROCESSING_VECTOR EQU $8012
KPR_VBL_VECTOR EQU $8015
;function numbers
;to make a function call:

View File

@ -160,7 +160,6 @@ play_sid:
@reset_song:
jsr print_current_song
lda current_song
jsr init_song
jmp @keypress_loop
@ -198,7 +197,8 @@ install_irq_handler:
irq_handler:
lda play_song_handler+2
beq :+
lda $d012
cmp #100
bne irq_handler
@ -207,7 +207,7 @@ irq_handler:
inc $d020
jsr play_song
dec $d020
:
jmp jmp_old_irq
@ -273,6 +273,7 @@ play_song_handler:
pla
sta $01
rts
jmp_old_irq:
jmp $ffff

View File

@ -1 +1 @@
.byte "0.9.30"
.byte "0.9.35"

View File

@ -51,32 +51,13 @@ buffer_ptr= copy_dest
.data
jmp_old_irq:
jmp $0000
irq_handler_installed_flag:
.byte 0
ip_configured_flag:
.byte 0
.code
irq_handler:
jsr KPR_VBL_VECTOR
jmp jmp_old_irq
install_irq_handler:
ldax $314 ;previous IRQ handler
stax jmp_old_irq+1
sei ;don't want any interrupts while we fiddle with the vector
ldax #irq_handler
stax $314 ;previous IRQ handler
sta irq_handler_installed_flag
cli
rts
set_tftp_params:
ldx #$03
:
@ -121,22 +102,17 @@ kipper_dispatcher:
bne ip_configured
jsr ip65_init
bcs init_failed
jsr install_irq_handler
jsr dhcp_init
bcc dhcp_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)
dhcp_ok:
lda #1
sta ip_configured_flag
irq_handler_installed:
clc
init_failed:
rts
ip_configured:
lda irq_handler_installed_flag
bne irq_handler_installed
jsr install_irq_handler
clc
rts
:
@ -310,13 +286,8 @@ ip_configured:
cpy #KPR_DEACTIVATE
;nothing to do now we don't use IRQ
bne :+
ldax jmp_old_irq+1
sei ;don't want any interrupts while we fiddle with the vector
stax $314 ;previous IRQ handler
lda #0
sta irq_handler_installed_flag
cli
clc
rts
:

18
dist/make_dist.rb vendored
View File

@ -12,19 +12,20 @@ VERSION_FILE=File.expand_path(File.dirname(__FILE__)+"/version_number.txt")
VERSION_INC_FILE=File.expand_path(File.dirname(__FILE__)+"/../client/inc/version.i")
version_string=File.open(VERSION_FILE).read
["","c64","lib","bin","boot","doc","inc","examples"].each do |dir_suffix|
["","c64","lib","bin","boot","doc","inc"].each do |dir_suffix|
dir_path="#{WORKING_DIR}/#{dir_suffix}"
Dir.mkdir(dir_path) unless File.exist?(dir_path)
end
[
#["client/nb65/utherboot.dsk","a2/"],
["client/nb65/set_ip_config.rb","bin/"],
["client/carts/set_ip_config.rb","bin/"],
#["client/nb65/nb65_rrnet.bin","c64/"],
["client/nb65/nb65_c64_ram.prg","c64/"],
["client/nb65/nb65_std_cart.bin","c64/"],
["client/nb65/nb65_tcp_cart.bin","c64/"],
["client/nb65/nb65_tcp_cart_rr.bin","c64/"],
["client/carts/kipperkart.prg","c64/"],
["client/carts/kipperkart.bin","c64/"],
["client/carts/kipperkart_rr.bin","c64/"],
["client/carts/kipperterm.bin","c64/"],
["client/carts/netboot.bin","c64/"],
["client/nb65/d64_upload.prg","boot/"],
["client/examples/upnatom.prg","boot/"],
["server/lib/tftp_server.rb","lib"],
@ -37,10 +38,9 @@ end
["doc/netboot65.html","doc/index.html"],
#["doc/README.Apple2.html","doc"],
["doc/README.C64.html","doc"],
["doc/nb65_api_technical_reference.doc","doc"],
["doc/kipper_api_technical_reference.doc","doc"],
["client/inc/common.i","inc"],
["client/inc/nb65_constants.i","inc"],
["client/examples/dasm_example.asm","examples/"],
["client/inc/kipper_constants.i","inc"],
["client/examples/upnatom.d64","c64/"],
#["client/nb65/d64_upload.s","examples/"],
#["client/nb65/nb65_skeleton.s","examples/"],

View File

@ -1 +1 @@
0.9.30
0.9.35

View File

@ -1,6 +1,6 @@
<h1>NETBOOT65 FOR THE C64</h1>
<h1>NETBOOT FOR THE C64</h1>
There are 2 major 'flavours' of the NB65 client, the major difference being whether the cart supports UDP only (but allows access to BASIC), or UDP + TCP (but loses access to BASIC). The
There are 2 major 'flavours' of clients, the major difference being whether the cart supports UDP only (but allows access to BASIC), or UDP + TCP (but loses access to BASIC). The
reason for this is the UDP only version of the client fits into an 8KB cartridge, whereas the TCP code pushes the cartridge size up to 16KB, and the upper half of a 16KB cartridge sits in the same
memory location as BASIC.
<p>
@ -15,10 +15,10 @@ Within the major flavours, there are also variations in media - the majority of
<table>
<tr><th>filename</th><th>flavour</th><th>media</th><th>command to use in VICE</th></tr>
<tr><td>nb65_c64_ram.prg</td><td>UDP only (+ BASIC)</td><td>RAM</td><td> x64.exe nb65_c64_ram.prg</td></tr>
<tr><td>nb65_std_cart.bin</td><td>UDP only (+ BASIC)</td><td>standard 8KB cart</td><td>x64.exe -cart8 nb65_std_cart.bin</td></tr>
<tr><td>nb65_tcp_cart.bin</td><td>UDP/TCP (no BASIC)</td><td>standard 16KB cart</td><td>x64.exe -cart16 nb65_tcp_cart.bin</td></tr>
<tr><td>nb65_tcp_cart_rr.bin</td><td>UDP/TCP (no BASIC)</td><td>Retro Replay cart image</td><td>x64.exe -cartrr nb65_tcp_cart_rr.bin</td></tr>
<tr><td>netboot.bin</td><td>UDP only (+ BASIC)</td><td>standard 8KB cart</td><td>x64.exe -cart8 netboot.bin</td></tr>
<tr><td>kipperkart.bin</td><td>UDP/TCP (no BASIC)</td><td>standard 16KB cart</td><td>x64.exe -cart16 kipperkart.bin</td></tr>
<tr><td>kipperterm.bin</td><td>telnet &amp; gopher client</td><td>standard 16KB cart</td><td>x64.exe -cart16 kipperterm.bin</td></tr>
<tr><td>kipperkart_rr.bin</td><td>UDP/TCP (no BASIC)</td><td>Retro Replay cart image</td><td>x64.exe -cartrr kipperkart_rr.bin</td></tr>
</table>
@ -28,17 +28,12 @@ When the cartridge starts, it will attempt to configure the IP stack via DHCP. I
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.
<p>
Once the IP stack is initialised, an attempt to boot from disk will take place (on the 16KB image only - see <a href="#autoexec">autoexec</a> section for more). If this fails, or the 8KB cartridge is being used,
the "main menu" screen will be displayed. There are slight variations between the menus shown on the 2 "flavours".
<h3>Main Menu - UDP only carts</h3>
<ul>
<li>F1 : TFTP BOOT. This will query a TFTP server for a list of PRG files, and allow the selection of a file to be downloaded and executed. Most 'single load' applications should work</li>
<li>F3 : BASIC. This will exit to BASIC (with IP stack still configured, so NB65 aware apps can be loaded from disk and run)</li>
<li>F5 : ARP TABLE. This will show a table of the current mapping of IP and MAC addresses </li>
<li>F7 : CONFIG. This brings up a menu where the IP configuration can be modified. Changes made here will be persistent until the next reboot.</li>
</ul>
<h3>Main Menu - UDP/TCP carts</h3>
<h2>NETBOOT - UDP only cart</h2>
Once the IP stack is initialised, an attempt to boot from the network will take place. a TFTP server will be queried for a list of PRG files, and then a menu appears allowing the selection of a file to be downloaded and executed. Most 'single load' applications should work</li>
<h2>KIPPERKART - UDP/TCP cart</h2>
<ul>
<li>F1 : TFTP BOOT. This will query a TFTP server for a list of PRG files, and allow the selection of a file to be downloaded and executed. This version of TFTP BOOT is restricted to running only
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).
@ -47,12 +42,19 @@ the "main menu" screen will be displayed. There are slight variations between th
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).
</li>
<li>F3 : NET APPS. This will bring up another menu of network-orientated applications (see below for more details).
<li>F5 : ARP TABLE. This will show a table of the current mapping of IP and MAC addresses </li>
<li>F3 : UPLOAD D64. TBD</li>
<li>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.</li>
<li>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.</li>
<li>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.</li>
<li>F7 : CONFIG. This brings up a menu where the IP configuration can be modified. Changes made here will be persistent until the next reboot.</li>
</ul>
<h3>Net Apps - UDP/TCP carts</h3>
<a name="autoexec"><h2>AUTOEXEC</h2></a>
Once the 16KB cartridge image has initialised the IP stack, it will look for a file called "autoexec.prg" on the default drive. If this file is found it will be loaded (using the load address specified by the first 2
bytes of the file) and executed. NB - since BASIC is not available only 100% Machine Language programs can be executed, although if there is a BASIC stub consisting of a single line that does a SYS
call, the target of the SYS call will be used as the address to start execution from.
<h2>KIPPERTERM cart</h2>
<ul>
<li>F1 : TELNET. You will be prompted to enter a hostname, a port number, and a connection mode. Connection mode is either
<ul>
@ -62,13 +64,12 @@ the "main menu" screen will be displayed. There are slight variations between th
<li>Line - Data is converted to/from ASCII, but each line of input can be edited and is not sent until the RETURN key is pressed.</li>
</ul>
Once a connection is made, it can be terminated by hitting RUN/STOP
<li>F2 : GOPHER. You will be prompted to enter the hostname (only - no port number can be specified) of a gopher server, and the gopher client will be launched connecting to the specified server.
<li>F3 : GOPHER.FLOODGAP.COM. This will launch the Gopher client, and connect to the gopher portal at gopher://gopher.floodgap.com/</li>
<li>F5 : 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.</li>
<li>F7 : MAIN MENU. This will return to the main menu.</li>
<li>F3 : GOPHER. You will be prompted to enter the hostname (only - no port number can be specified) of a gopher server, and the gopher client will be launched connecting to the specified server.
<li>F5 : GOPHER.FLOODGAP.COM. This will launch the Gopher client, and connect to the gopher portal at gopher://gopher.floodgap.com/</li>
<li>F7 : CONFIG. This brings up a menu where the IP configuration can be modified. Changes made here will be persistent until the next reboot.</li>
</ul>
<h3>Gopher Client - UDP/TCP carts</h3>
<h3>Gopher Client</h3>
Once a gopher resource is loaded, the following keys are active:
<ul>
<li>SPACE, F7 or down arrow : scroll down to next page
@ -83,10 +84,6 @@ starting with a highlighted letter (e.g. the first link on a page will have an i
the 2nd link on a page will have an inverse "B" next to it etc). Press the letter assigned to the link
to load up that resource.
<a name="autoexec"><h2>AUTOEXEC</h2></a>
Once the 16KB cartridge image has initialised the IP stack, it will look for a file called "autoexec.prg" on the default drive. If this file is found it will be loaded (using the load address specified by the first 2
bytes of the file) and executed. NB - since BASIC is not available only 100% Machine Language programs can be executed, although if there is a BASIC stub consisting of a single line that does a SYS
call, the target of the SYS call will be used as the address to start execution from.
<h2>IP CONFIGURATION</h2>
There is a script in the "bin" folder called "set_ip_config.rb" that can be used to modify the MAC address and IP config details in the cart image before

View File

@ -84,7 +84,7 @@ netboot65 is a project to support network booting Commodore 64 computers. It is
<li>a server (written in <a href=http://www.ruby-lang.org/>ruby</a> for maximum portability) that provides a TFTP server with some proprietary extensions to allow clients to request a directory listing.
<li>clients (currently <!--available as a disk image for Apple ][, and either--> a cartridge or a standalone prg file for C64) that initialises an IP stack, acquires an IP address via DHCP, queries the local LAN for a TFTP server,
and then allows a program file to be downloaded via TFTP and executed. Currently only 'single load' programs are supported, but many old games and utility programs can be run in this way.
<li>the NB65 API (currently for C64 only) that allows for IP aware applications to be developed without being tied to a specific MAC address, IP address or network device, as is the case with most existing
<li>the KIPPER API (currently for C64 only) that allows for IP aware applications to be developed without being tied to a specific MAC address, IP address or network device, as is the case with most existing
IP libraries for 6502 computers.
</ul>
</p>
@ -96,7 +96,7 @@ IP libraries for 6502 computers.
<ul>
<li><a href=README.C64.html>C64 documentation</a>
<!--<li><a href=README.Apple2.html>Apple ][ documentation</a>-->
<li><a href="nb65_api_technical_reference.doc">NB65 API Technical Reference (word doc)</a>
<li><a href="kipper_api_technical_reference.doc">KIPPER API Technical Reference (word doc)</a>
</ul>