diff --git a/client/inc/nb65_constants.i b/client/inc/nb65_constants.i index a4e3434..a625476 100644 --- a/client/inc/nb65_constants.i +++ b/client/inc/nb65_constants.i @@ -31,12 +31,13 @@ NB65_UDP_ADD_LISTENER EQU $10 ;inputs: AX points to a UDP listener para NB65_GET_INPUT_PACKET_INFO EQU $11 ;inputs: AX points to a UDP packet parameter structure, outputs: UDP packet structure filled in NB65_SEND_UDP_PACKET EQU $12 ;inputs: AX points to a UDP packet parameter structure, outputs: none packet is sent -NB65_TFTP_DIRECTORY_LISTING EQU $20 ;inputs: AX points to a TFTP parameter structure, outputs: none -NB65_TFTP_DOWNLOAD EQU $21 ;inputs: AX points to a TFTP parameter structure, outputs: TFTP param structure updated with +NB65_TFTP_SET_SERVER EQU $20 ;inputs: AX points to a TFTP server parameter structure, outputs: none +NB65_TFTP_DIRECTORY_LISTING EQU $21 ;inputs: AX points to a TFTP transfer parameter structure, outputs: none +NB65_TFTP_DOWNLOAD EQU $22 ;inputs: AX points to a TFTP transfer parameter structure, outputs: TFTP param structure updated with ;NB65_TFTP_POINTER updated to reflect actual load address (if load address $0000 originally passed in) -NB65_TFTP_CALLBACK_DOWNLOAD EQU $22 ;inputs: AX points to a TFTP parameter structure, outputs: none -NB65_TFTP_UPLOAD EQU $23 ;upload: AX points to a TFTP parameter structure, outputs: none -NB65_TFTP_CALLBACK_UPLOAD EQU $24 ;upload: AX points to a TFTP parameter structure, outputs: none +NB65_TFTP_CALLBACK_DOWNLOAD EQU $23 ;inputs: AX points to a TFTP transfer parameter structure, outputs: none +NB65_TFTP_UPLOAD EQU $24 ;upload: AX points to a TFTP transfer parameter structure, outputs: none +NB65_TFTP_CALLBACK_UPLOAD EQU $25 ;upload: AX points to a TFTP transfer parameter structure, outputs: none NB65_DNS_RESOLVE EQU $30 ;inputs: AX points to a DNS parameter structure, outputs: DNS param structure updated with ;NB65_DNS_HOSTNAME_IP updated with IP address corresponding to hostname. @@ -57,14 +58,16 @@ NB65_CFG_IP EQU $06 ;4 byte local IP address (will be overwritten b NB65_CFG_NETMASK EQU $0A ;4 byte local netmask (will be overwritten by DHCP) NB65_CFG_GATEWAY EQU $0E ;4 byte local gateway (will be overwritten by DHCP) NB65_CFG_DNS_SERVER EQU $12 ;4 byte IP address of DNS server (will be overwritten by DHCP) -NB65_CFG_DHCP_SERVER EQU $16 ;4 byte IP address of DHCP server (will only be set by DHCP initialisation) +NB65_CFG_DHCP_SERVER EQU $16 ;4 byte IP address of DHCP server (will only be set by DHCP initialisation) NB65_DRIVER_NAME EQU $1A ;2 byte pointer to name of driver -;offsets in TFTP parameter structure (used by NB65_TFTP_DIRECTORY_LISTING & NB65_TFTP_DOWNLOAD) -NB65_TFTP_IP EQU $00 ;4 byte IP address of TFTP server -NB65_TFTP_FILENAME EQU $04 ;2 byte pointer to asciiz filename (or filemask in case of NB65_TFTP_DIRECTORY_LISTING) -NB65_TFTP_POINTER EQU $06 ;2 byte pointer to memory location data to be stored in OR address of callback function -NB65_TFTP_FILESIZE EQU $08 ;2 byte file length (filled in by NB65_TFTP_DOWNLOAD, must be passed in to NB65_TFTP_UPLOAD) +;offsets in TFTP transfer parameter structure (used by NB65_TFTP_DIRECTORY_LISTING & NB65_TFTP_DOWNLOAD) +NB65_TFTP_FILENAME EQU $00 ;2 byte pointer to asciiz filename (or filemask in case of NB65_TFTP_DIRECTORY_LISTING) +NB65_TFTP_POINTER EQU $02 ;2 byte pointer to memory location data to be stored in OR address of callback function +NB65_TFTP_FILESIZE EQU $04 ;2 byte file length (filled in by NB65_TFTP_DOWNLOAD, must be passed in to NB65_TFTP_UPLOAD) + +;offsets in TFTP Server parameter structure (used by NB65_TFTP_SET_SERVER) +NB65_TFTP_SERVER_IP EQU $00 ;4 byte IP address of TFTP server ;offsets in DNS parameter structure (used by NB65_DNS_RESOLVE) NB65_DNS_HOSTNAME EQU $00 ;2 byte pointer to asciiz hostname to resolve (can also be a dotted quad string) diff --git a/client/ip65/Makefile b/client/ip65/Makefile index 606fdf3..410aa62 100644 --- a/client/ip65/Makefile +++ b/client/ip65/Makefile @@ -7,8 +7,7 @@ AFLAGS= $(CC) -c $(CFLAGS) $< %.o: %.s - $(AS) $(AFLAGS) $< - + $(AS) $(AFLAGS) $< ETHOBJS= \ copymem.o \ @@ -32,8 +31,7 @@ ETHOBJS= \ all: ip65.lib - -ip65.lib: $(ETHOBJS) +ip65.lib: $(ETHOBJS) ar65 a ip65.lib $^ diff --git a/client/ip65/function_dispatcher.s b/client/ip65/function_dispatcher.s index b3e3de6..3d6ca59 100644 --- a/client/ip65/function_dispatcher.s +++ b/client/ip65/function_dispatcher.s @@ -39,6 +39,7 @@ .import udp_send_len .import copymem .import cfg_mac +.import cfg_tftp_server .importzp copy_src .importzp copy_dest @@ -53,7 +54,10 @@ jmp_old_irq: irq_handler_installed_flag: .byte 0 - + +ip_configured_flag: + .byte 0 + .code irq_handler: @@ -61,19 +65,23 @@ irq_handler: 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: - ldy #NB65_TFTP_IP - lda (nb65_params),y - sta tftp_ip - iny - lda (nb65_params),y - sta tftp_ip+1 - iny - lda (nb65_params),y - sta tftp_ip+2 - iny - lda (nb65_params),y - sta tftp_ip+3 + ldx #$03 +: + lda cfg_tftp_server,x + sta tftp_ip,x + dex + bpl :- ldy #NB65_TFTP_FILENAME lda (nb65_params),y @@ -107,26 +115,27 @@ nb65_dispatcher: cpy #NB65_INITIALIZE bne :+ - lda irq_handler_installed_flag - bne irq_handler_installed + lda ip_configured_flag + bne ip_configured jsr ip65_init bcs init_failed - ;install our 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 + 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 to cartridge default values) + 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) + lda #1 + sta ip_configured_flag dhcp_ok: irq_handler_installed: clc init_failed: rts + +ip_configured: + lda irq_handler_installed_flag + bne irq_handler_installed + jsr install_irq_handler + rts : cpy #NB65_GET_IP_CONFIG @@ -275,12 +284,25 @@ init_failed: 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 : - + cpy #NB65_TFTP_SET_SERVER + bne :+ + ldy #3 +@copy_tftp_server_ip: + lda (nb65_params),y + sta cfg_tftp_server,y + dey + bpl @copy_tftp_server_ip + clc + rts + +: cpy #NB65_TFTP_DIRECTORY_LISTING bne :+ phax diff --git a/client/ip65/ip.s b/client/ip65/ip.s index c72d57d..f28078a 100644 --- a/client/ip65/ip.s +++ b/client/ip65/ip.s @@ -352,6 +352,11 @@ ip_send: ; calculate checksum for a buffer according to the standard IP checksum algorithm +; David Schmidt discovered errors in the original ip65 implementation, and he replaced +; this with an implementation from the contiki project (http://www.sics.se/contiki/) +; when incorporating ip65 into ADTPro (http://adtpro.sourceforge.net/) +; So I have cribbed that version from +; http://adtpro.cvs.sourceforge.net/viewvc/adtpro/adtpro/client/src/ip65/ip.s ;inputs: ; ip_cksum_ptr: points at buffer to be checksummed ; AX: length of buffer to be checksumed @@ -361,68 +366,92 @@ ip_calc_cksum: sta ip_cksum_len ; save length stx ip_cksum_len + 1 - lda #0 - sta cksum - sta cksum + 1 - sta cksum + 2 - - cpx #0 - beq @tail - -: ldx #$80 ; number of bytes / 2 - jsr @calc - inc ip_cksum_ptr + 1 - dec ip_cksum_len + 1 - bne :- - -@tail: - lda ip_cksum_len ; divide length by 2 - lsr - php ; save carry for odd size - tax - - jsr @calc - - plp - bcc @done - - clc - lda (ip_cksum_ptr),y - adc cksum - sta cksum - bcc @done - inc cksum + 1 - bne @done - inc cksum + 2 - -@done: - lda cksum + 2 ; add carries back in - clc - adc cksum - pha - lda cksum + 1 - adc #0 - eor #$ff ; return inverted result - tax - pla - eor #$ff - - rts - -@calc: - ldy #0 ; 1's complement 16-bit sum -@next: - clc - lda (ip_cksum_ptr),y - adc cksum - sta cksum - iny - lda (ip_cksum_ptr),y - adc cksum + 1 - sta cksum + 1 - bcc :+ - inc cksum + 2 -: iny - dex - bne @next - rts + lda #0 + sta cksum + sta cksum+1 + + lda ip_cksum_len+1 + beq chksumlast + +; If checksum is > 256, do the first runs. + ldy #0 + clc +chksumloop_256: + lda (ip_cksum_ptr),y + adc cksum + sta cksum + iny + lda (ip_cksum_ptr),y + adc cksum+1 + sta cksum+1 + iny + bne chksumloop_256 + inc ip_cksum_ptr+1 + dec ip_cksum_len+1 + bne chksumloop_256 + +chksum_endloop_256: + lda cksum + adc #0 + sta cksum + lda cksum+1 + adc #0 + sta cksum+1 + bcs chksum_endloop_256 + +chksumlast: + lda ip_cksum_len + lsr + bcc chksum_noodd + ldy ip_cksum_len + dey + lda (ip_cksum_ptr),y + clc + adc cksum + sta cksum + bcc noinc1 + inc cksum+1 + bne noinc1 + inc cksum +noinc1: + dec ip_cksum_len + +chksum_noodd: + clc + php + ldy ip_cksum_len +chksum_loop1: + cpy #0 + beq chksum_loop1_end + plp + dey + dey + lda (ip_cksum_ptr),y + adc cksum + sta cksum + iny + lda (ip_cksum_ptr),y + adc cksum+1 + sta cksum+1 + dey + php + jmp chksum_loop1 +chksum_loop1_end: + plp + +chksum_endloop: + lda cksum + adc #0 + sta cksum + lda cksum+1 + adc #0 + sta cksum+1 + bcs chksum_endloop + + lda cksum+1 + eor #$ff + tax + lda cksum + eor #$ff + + rts diff --git a/client/nb65/Makefile b/client/nb65/Makefile index cde7fa0..b1a46b2 100644 --- a/client/nb65/Makefile +++ b/client/nb65/Makefile @@ -18,7 +18,7 @@ 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 c64boot.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 nb65_c64_ram.o: nb65_c64.s $(INCFILES) $(AS) -DBANKSWITCH_SUPPORT=0 $(AFLAGS) -o $@ $< @@ -39,6 +39,9 @@ nb65_c64_ram.prg: nb65_c64_ram_header.bin nb65_c64_ram.o $(IP65LIB) $(C64NB65LIB $(LD) -m nb65_c64_ram.map -vm -C ../cfg/rrbin.cfg -o nb65_c64_ram.bin nb65_c64_ram.o $(IP65LIB) $(C64NB65LIB) cat nb65_c64_ram_header.bin nb65_c64_ram.bin> nb65_c64_ram.prg +%.prg: %.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg + $(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB) + nb65_std_cart.bin: nb65_std_cart.o $(IP65LIB) $(C64NB65LIB) $(INCFILES) ../cfg/rrbin.cfg $(LD) -m nb65_std_cart.map -vm -C ../cfg/rrbin.cfg -o $@ $< $(IP65LIB) $(C64NB65LIB) ruby fix_cart.rb $@ 8192 @@ -54,10 +57,13 @@ utherboot.dsk: utherboot.pg2 ripxplore.rb --init AppleDos utherboot.dsk -a utherboot.pg2 -t AppleBinary ripxplore.rb utherboot.dsk -a hello -t Applesoft -c64boot.d64: nb65_c64_ram.prg +c64boot.d64: nb65_c64_ram.prg ripxplore.rb --init CbmDos $@ -a nb65_c64_ram.prg ripxplore.rb $@ -a ..\test\test_cart_api.prg - + +d64_upload.d64: d64_upload.prg + ripxplore.rb --init CbmDos $@ -a d64_upload.prg + $(BOOTA2.PG2): bootmenu.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2language_card.cfg $(LD) -m bootmenu.map -C ../cfg/a2language_card.cfg -o $(BOOTA2.PG2) $< $(IP65LIB) $(APPLE2PROGLIB) diff --git a/client/nb65/d64_upload.s b/client/nb65/d64_upload.s new file mode 100644 index 0000000..09de577 --- /dev/null +++ b/client/nb65/d64_upload.s @@ -0,0 +1,494 @@ +;use the NB65 API to send a d64 disk via TFTP + +.ifndef NB65_API_VERSION_NUMBER + .define EQU = + .include "../inc/nb65_constants.i" +.endif + +.include "../ip65/copymem.s" +.include "../inc/common.i" + +.import print_a +.import get_key +.macro cout arg + lda arg + jsr print_a +.endmacro + +.data +sector_buffer_address: .word sector_buffer + +.bss + current_byte: .res 1 + track: .res 1 + sector: .res 1 + sectors_in_track: .res 1 + + command_buffer: .res 128 + sector_buffer: .res 256 + nb65_param_buffer: .res $20 + + .zeropage + temp_ptr: .res 2 + +.segment "STARTUP" ;this is what gets put at the start of the file on the C64 + +.word basicstub ; load address + +.macro print arg + ldax arg + ldy #NB65_PRINT_ASCIIZ + jsr NB65_DISPATCH_VECTOR +.endmacro + +.macro print_cr + lda #13 + jsr print_a +.endmacro + +.macro call arg + ldy arg + jsr NB65_DISPATCH_VECTOR +.endmacro + +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 + + +;look for NB65 signature at location pointed at by AX +look_for_signature: + stax temp_ptr + ldy #3 +@check_one_byte: + lda (temp_ptr),y + cmp nb65_signature,y + bne @bad_match + dey + bpl@check_one_byte + clc + rts +@bad_match: + sec + rts +init: + + print #signon_message + + ldax #NB65_CART_SIGNATURE ;where signature should be in cartridge + jsr look_for_signature + bcc @found_nb65_signature + + ldax #NB65_RAM_STUB_SIGNATURE ;where signature should be in RAM + jsr look_for_signature + bcc :+ + jmp nb65_signature_not_found +: + jsr NB65_RAM_STUB_ACTIVATE ;we need to turn on NB65 cartridge + +@found_nb65_signature: + + print #initializing + print #nb65_signature + ldy #NB65_INITIALIZE + jsr NB65_DISPATCH_VECTOR + bcc :+ + print #failed + jsr print_errorcode + jmp bad_boot +: + print #ok + print_cr + +; ######################## +; main program goes here: +; + + jsr open_drive_channels + bcs @error + + jsr move_to_first_sector + + ldax #test_file + stax nb65_param_buffer+NB65_TFTP_FILENAME + ldax #send_next_block + stax nb65_param_buffer+NB65_TFTP_POINTER + ldax #nb65_param_buffer + call #NB65_TFTP_CALLBACK_UPLOAD + bcc :+ + jmp print_errorcode +: + + rts +@error: + pha + print #drive_error + print #error_code + pla + call #NB65_PRINT_HEX + rts + + +send_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 print_current_sector + jsr read_sector + jsr move_to_next_sector + bcc @not_last_sector + ldax #$100 + rts +@not_last_sector: + inc sector_buffer_address + jsr read_sector + jsr move_to_next_sector + ldax #$200 + rts +@past_last_track: + ldax #$0000 + rts + + +print_current_sector: + lda #$13 ;home + jsr print_a + print #track_no + lda track + jsr byte_to_ascii + pha + txa + jsr print_a + pla + jsr print_a + print #sector_no + lda sector + jsr byte_to_ascii + pha + txa + jsr print_a + pla + jsr print_a + print_cr + rts + +open_drive_channels: + LDA #cname_end-cname + LDX #cname + JSR $FFBD ; call SETNAM + LDA #$02 ; file number 2 + LDX $BA ; last used device number + BNE @skip + LDX #$08 ; default to device 8 +@skip: + LDY #$02 ; secondary address 2 + JSR $FFBA ; call SETLFS + JSR $FFC0 ; call OPEN + bcc @opened_ok + rts +@opened_ok: + rts + +dump_sector: +;hex dump sector + lda #0 + sta current_byte +@dump_byte: + ldy current_byte + lda sector_buffer,y + call #NB65_PRINT_HEX + inc current_byte + bne @dump_byte +rts + +read_sector: +;routine to read a sector cribbed from http://codebase64.org/doku.php?id=base:reading_a_sector_from_disk +; - requires track and sector values be set first +; sector will be written to address whos value is stored in sector_data +; open the channel file + + + + jsr make_read_sector_command + tya + pha + print #command_buffer + print_cr + pla + LDX #command_buffer + JSR $FFBD ; call SETNAM + LDA #$0F ; file number 15 + LDX $BA ; last used device number + LDY #$0F ; secondary address 15 + JSR $FFBA ; call SETLFS + + JSR $FFC0 ; call OPEN (open command channel and send U1 command) + BCS @error ; if carry set, the file could not be opened + + jsr check_error_channel + + LDX #$02 ; filenumber 2 + JSR $FFC6 ; call CHKIN (file 2 now used as input) + + LDA sector_buffer_address + STA temp_ptr + LDA sector_buffer_address+1 + STA temp_ptr+1 + LDY #$00 +@loop: + JSR $FFCF ; call CHRIN (get a byte from file) + STA (temp_ptr),Y ; write byte to memory + INY + BNE @loop ; next byte, end when 256 bytes are read +@close: + LDA #$0F ; filenumber 15 + JSR $FFC3 ; call CLOSE + LDX #$00 ; filenumber 0 = keyboard + JSR $FFC6 ; call CHKIN (keyboard now input device again) + RTS +@error: + pha + print #drive_error + print #error_code + pla + call #NB65_PRINT_HEX + JMP @close ; even if OPEN failed, the file has to be closed + + +check_error_channel: + LDA #$00 ; no filename + LDX #$00 + LDY #$00 + JSR $FFBD ; call SETNAM + LDA #$0F ; file number 15 + LDX $BA ; last used device number + BNE @skip + LDX #$08 ; default to device 8 +@skip: + LDY #$0F ; secondary address 15 (error channel) + JSR $FFBA ; call SETLFS + + JSR $FFC0 ; call OPEN + + LDX #$0F ; filenumber 15 + JSR $FFC6 ; call CHKIN (file 15 now used as input) + + LDY #$00 +@loop: + JSR $FFB7 ; call READST (read status byte) + BNE @eof ; either EOF or read error + JSR $FFCF ; call CHRIN (get a byte from file) + JSR $FFD2 ; call CHROUT (print byte to screen) + JMP @loop ; next byte + +@eof: +@close: + LDA #$0F ; filenumber 15 + JSR $FFC3 ; call CLOSE + + LDX #$00 ; filenumber 0 = keyboard + JSR $FFC6 ; call CHKIN (keyboard now input device again) + RTS + +bad_boot: + print #press_a_key_to_continue +restart: + jsr get_key + jmp $fce2 ;do a cold start + + +print_errorcode: + print #error_code + call #NB65_GET_LAST_ERROR + call #NB65_PRINT_HEX + print_cr + rts + +nb65_signature_not_found: + + ldy #0 +: + lda nb65_signature_not_found_message,y + beq restart + jsr print_a + iny + jmp :- + + + +make_read_sector_command: +;fill command buffer with command to read in track & sector +;returns length of command in Y + + ldy #0 + lda #85 ;"U" + sta command_buffer,y + iny + lda #$31 ;"1" + sta command_buffer,y + iny + lda #$20 ;" " + sta command_buffer,y + iny + lda #$32 ;"2" - file number + sta command_buffer,y + iny + lda #$20 ;" " + sta command_buffer,y + iny + lda #$30 ;"0" - drive number + sta command_buffer,y + iny + lda #$20 ;" " + sta command_buffer,y + iny + lda track + jsr byte_to_ascii + pha + txa + sta command_buffer,y + pla + iny + sta command_buffer,y + iny + lda #$20 ;" " + sta command_buffer,y + iny + lda sector + jsr byte_to_ascii + pha + txa + sta command_buffer,y + pla + iny + sta command_buffer,y + iny + + lda #0 + sta command_buffer,y ;make it ASCIIZ so we can print it + + rts + +byte_to_ascii: + cmp #30 + bmi @not_30 + ldx #$33 + clc + adc #18 + rts +@not_30: + cmp #20 + bmi @not_20 + ldx #$32 + clc + adc #28 + rts +@not_20: + cmp #10 + bmi @not_10 + ldx #$31 + clc + adc #38 + rts +@not_10: + ldx #$30 + clc + adc #48 + rts + + +move_to_first_sector: + ldx #1 + stx track + dex + stx sector + ldx #21 + stx sectors_in_track + rts + +move_to_next_sector: + inc sector + lda sector + cmp sectors_in_track + beq @move_to_next_track + rts +@move_to_next_track: + lda #0 + sta sector + inc track + lda track + cmp #18 + bne @not_track_18 + lda #19 + sta sectors_in_track + clc + rts +@not_track_18: + cmp #25 + bne @not_track_25 + lda #18 + sta sectors_in_track + clc + rts +@not_track_25: + cmp #25 + bne @not_track_31 + lda #17 + sta sectors_in_track + clc + rts +@not_track_31: + lda track + cmp #36 ;carry will be set if hit track 36 + rts + + +.rodata + +error_code: + .asciiz "ERROR CODE: $" +press_a_key_to_continue: + .byte "PRESS A KEY TO CONTINUE",13,0 + +failed: + .byte "FAILED ", 0 + +ok: + .byte "OK ", 0 + +initializing: + .byte "INITIALIZING ",0 +track_no: + .byte "TRACK ",0 + +sector_no: + .byte " SECTOR ",0 + +signon_message: + .byte "D64 UPLOADER V0.1",13,0 + +drive_error: + .byte "DRIVE ACCESS ERROR - ",0 + nb65_signature_not_found_message: + .byte "NO NB65 API FOUND",13,"PRESS ANY KEY TO RESET", 0 + +nb65_signature: + .byte $4E,$42,$36,$35 ; "NB65" - API signature + .byte ' ',0 ; so we can use this as a string + +test_file: .byte "TEST.D64",0 +cname: .byte 35 ;"#" +cname_end: diff --git a/client/nb65/nb65_c64.s b/client/nb65/nb65_c64.s index eda701b..e813f20 100644 --- a/client/nb65/nb65_c64.s +++ b/client/nb65/nb65_c64.s @@ -392,8 +392,6 @@ cmp #KEYCODE_F7 @tftp_boot: - jsr setup_param_buffer_for_tftp_call - ldax #tftp_dir_buffer stax nb65_param_buffer+NB65_TFTP_POINTER @@ -490,17 +488,6 @@ print_errorcode: jsr print_hex jmp print_cr - -setup_param_buffer_for_tftp_call: - - ldx #3 - lda cfg_tftp_server,x -: - sta nb65_param_buffer+NB65_TFTP_IP,x - dex - bpl :- - rts - bad_boot: jsr wait_for_keypress jmp $fe66 ;do a wam start @@ -516,7 +503,6 @@ download: ;AX should point at filename to download jsr print jsr print_cr - jsr setup_param_buffer_for_tftp_call ldax #nb65_param_buffer nb65call #NB65_TFTP_DOWNLOAD @@ -576,7 +562,7 @@ config_menu_msg: .byte 13," CONFIGURATION",13,13 .byte "F1: IP ADDRESS F2: NETMASK",13 .byte "F3: GATEWAY F4: DNS SERVER",13 -.byte "F5: TFTP SERVER F6: RESET TO DEFAULTS",13,13 +.byte "F5: TFTP SERVER F6: RESET TO DEFAULTS",13 .byte "F7: MAIN MENU",13,13 .byte 0 diff --git a/client/nb65/nb65_skeleton.s b/client/nb65/nb65_skeleton.s new file mode 100644 index 0000000..4821eae --- /dev/null +++ b/client/nb65/nb65_skeleton.s @@ -0,0 +1,155 @@ +;use the NB65 API to send a d64 disk via TFTP + +.ifndef NB65_API_VERSION_NUMBER + .define EQU = + .include "../inc/nb65_constants.i" +.endif + +.include "../ip65/copymem.s" +.include "../inc/common.i" + +.import print_a +.import get_key +.macro cout arg + lda arg + jsr print_a +.endmacro + + .zeropage + temp_ptr: .res 2 + + .bss + nb65_param_buffer: .res $20 + block_number: .res $0 + +.segment "STARTUP" ;this is what gets put at the start of the file on the C64 + +.word basicstub ; load address + +.macro print arg + ldax arg + ldy #NB65_PRINT_ASCIIZ + jsr NB65_DISPATCH_VECTOR +.endmacro + +.macro print_cr + lda #13 + jsr print_a +.endmacro + +.macro call arg + ldy arg + jsr NB65_DISPATCH_VECTOR +.endmacro + +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 + + +;look for NB65 signature at location pointed at by AX +look_for_signature: + stax temp_ptr + ldy #3 +@check_one_byte: + lda (temp_ptr),y + cmp nb65_signature,y + bne @bad_match + dey + bpl@check_one_byte + clc + rts +@bad_match: + sec + rts +init: + + print #signon_message + + ldax #NB65_CART_SIGNATURE ;where signature should be in cartridge + jsr look_for_signature + bcc @found_nb65_signature + + ldax #NB65_RAM_STUB_SIGNATURE ;where signature should be in RAM + jsr look_for_signature + bcc :+ + jmp nb65_signature_not_found +: + jsr NB65_RAM_STUB_ACTIVATE ;we need to turn on NB65 cartridge + +@found_nb65_signature: + + print #initializing + print #nb65_signature + ldy #NB65_INITIALIZE + jsr NB65_DISPATCH_VECTOR + bcc :+ + print #failed + jsr print_errorcode + jmp bad_boot +: + print #ok + print_cr + +; ######################## +; main program goes here: +; + rts + +bad_boot: + print #press_a_key_to_continue +restart: + jsr get_key + jmp $fce2 ;do a cold start + + +print_errorcode: + print #error_code + call #NB65_GET_LAST_ERROR + call #NB65_PRINT_HEX + print_cr + rts + +nb65_signature_not_found: + + ldy #0 +: + lda nb65_signature_not_found_message,y + beq restart + jsr print_a + iny + jmp :- + +.rodata + +error_code: + .asciiz "ERROR CODE: $" +press_a_key_to_continue: + .byte "PRESS A KEY TO CONTINUE",13,0 + +failed: + .byte "FAILED ", 0 + +ok: + .byte "OK ", 0 + +initializing: + .byte "INITIALIZING ",0 + +signon_message: + .byte "NB65 UNNAMED TOOL V0.1",13,0 + + nb65_signature_not_found_message: + .byte "NO NB65 API FOUND",13,"PRESS ANY KEY TO RESET", 0 + +nb65_signature: + .byte $4E,$42,$36,$35 ; "NB65" - API signature + .byte ' ',0 ; so we can use this as a string \ No newline at end of file diff --git a/client/test/Makefile b/client/test/Makefile index cfd6814..5cf2075 100644 --- a/client/test/Makefile +++ b/client/test/Makefile @@ -32,10 +32,10 @@ all: \ %.o: %.s $(AS) $(AFLAGS) $< -%.prg: %.o $(IP65LIB) $(C64NETLIB) $(INCFILES) ../cfg/c64prg.cfg +%.prg: %.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg $(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB) -%.pg2: %.o $(IP65LIB) $(APPLE2NETLIB) $(INCFILES) ../cfg/a2bin.cfg +%.pg2: %.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2bin.cfg $(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2PROGLIB) ip65test.dsk: testdns.pg2 testdottedquad.pg2 testtftp.pg2 diff --git a/client/test/test_cart_api.s b/client/test/test_cart_api.s index 6da65cb..5130a30 100644 --- a/client/test/test_cart_api.s +++ b/client/test/test_cart_api.s @@ -144,12 +144,6 @@ init: ;tftp send test lda #0 sta block_number - lda #$FF - ldx #$03 -: - sta nb65_param_buffer,x ;set TFTP server as broadcast address - dex - bpl :- ldax #test_file stax nb65_param_buffer+NB65_TFTP_FILENAME ldax #tftp_upload_callback @@ -165,12 +159,6 @@ init: ;tftp download callback test lda #0 sta block_number - lda #$FF - ldx #$03 -: - sta nb65_param_buffer,x ;set TFTP server as broadcast address - dex - bpl :- ldax #test_file stax nb65_param_buffer+NB65_TFTP_FILENAME ldax #tftp_download_callback