From 6af3f250f43e936b59460eb606e14d509444536b Mon Sep 17 00:00:00 2001 From: jonnosan Date: Fri, 24 Apr 2009 22:37:22 +0000 Subject: [PATCH] git-svn-id: http://svn.code.sf.net/p/netboot65/code@126 93682198-c243-4bdb-bd91-e943c89aac3b --- client/inc/nb65_constants.i | 3 + client/ip65/function_dispatcher.s | 7 + client/ip65/udp.s | 16 ++- client/nb65/Makefile | 5 +- client/nb65/d64_upload.s | 211 ++++++++++++++++++------------ client/nb65/nb65_c64.s | 56 +++----- client/test/test_cart_api.s | 5 +- dist/make_dist.rb | 2 +- server/bin/tftp_only_server.rb | 8 +- 9 files changed, 180 insertions(+), 133 deletions(-) diff --git a/client/inc/nb65_constants.i b/client/inc/nb65_constants.i index a625476..ce4f622 100644 --- a/client/inc/nb65_constants.i +++ b/client/inc/nb65_constants.i @@ -30,6 +30,7 @@ NB65_DEACTIVATE EQU $0F ;inputs: none, outputs: none (removes cal NB65_UDP_ADD_LISTENER EQU $10 ;inputs: AX points to a UDP listener parameter structure, outputs: none 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_UDP_REMOVE_LISTENER EQU $13 ;inputs: AX contains UDP port number that listener will be removed from 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 @@ -92,5 +93,7 @@ NB65_ERROR_TRANSMISSION_REJECTED_BY_PEER EQU $83 NB65_ERROR_INPUT_TOO_LARGE EQU $84 NB65_ERROR_DEVICE_FAILURE EQU $85 NB65_ERROR_ABORTED_BY_USER EQU $86 +NB65_ERROR_LISTENER_NOT_AVAILABLE EQU $87 +NB65_ERROR_NO_SUCH_LISTENER EQU $88 NB65_ERROR_OPTION_NOT_SUPPORTED EQU $FE NB65_ERROR_FUNCTION_NOT_SUPPORTED EQU $FF diff --git a/client/ip65/function_dispatcher.s b/client/ip65/function_dispatcher.s index 3d6ca59..ea273cb 100644 --- a/client/ip65/function_dispatcher.s +++ b/client/ip65/function_dispatcher.s @@ -29,6 +29,7 @@ .import dns_set_hostname .import udp_callback .import udp_add_listener +.import udp_remove_listener .import ip_inp .import udp_inp .import udp_send @@ -277,8 +278,14 @@ ip_configured: tax pla jmp udp_send +: + + cpy #NB65_UDP_REMOVE_LISTENER + bne :+ + jmp udp_remove_listener : + cpy #NB65_DEACTIVATE bne :+ ldax jmp_old_irq+1 diff --git a/client/ip65/udp.s b/client/ip65/udp.s index 3027840..db5f313 100644 --- a/client/ip65/udp.s +++ b/client/ip65/udp.s @@ -1,9 +1,14 @@ ;UDP (user datagram protocol) functions .include "../inc/common.i" +.ifndef NB65_API_VERSION_NUMBER + .define EQU = + .include "../inc/nb65_constants.i" +.endif ;.import dbg_dump_udp_header + .import ip65_error .export udp_init .export udp_process @@ -130,8 +135,10 @@ udp_process: : dex bpl @checkport -@drop: - sec +@drop: + lda #NB65_ERROR_NO_SUCH_LISTENER + sta ip65_error + sec rts @handle: @@ -182,7 +189,10 @@ udp_add_listener: clc rts @full: -@busy: +@busy: + lda #NB65_ERROR_LISTENER_NOT_AVAILABLE + sta ip65_error + sec sec rts diff --git a/client/nb65/Makefile b/client/nb65/Makefile index b1a46b2..f48abe5 100644 --- a/client/nb65/Makefile +++ b/client/nb65/Makefile @@ -60,10 +60,11 @@ utherboot.dsk: utherboot.pg2 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 + cp d64_upload.prg ../../server/boot/ 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 index a4fbc14..b3d2b13 100644 --- a/client/nb65/d64_upload.s +++ b/client/nb65/d64_upload.s @@ -10,6 +10,8 @@ .import print_a .import get_key +.import get_filtered_input +.import filter_dns .macro cout arg lda arg jsr print_a @@ -22,7 +24,8 @@ track: .res 1 sector: .res 1 sectors_in_track: .res 1 - + error_buffer: .res 128 + command_buffer: .res 128 sector_buffer: .res 256 nb65_param_buffer: .res $20 @@ -102,7 +105,7 @@ init: jsr NB65_DISPATCH_VECTOR bcc :+ print #failed - jsr print_errorcode + jsr print_nb65_errorcode jmp bad_boot : print #ok @@ -112,28 +115,38 @@ init: ; main program goes here: ; - jsr open_drive_channels - bcs @error - - jsr move_to_first_sector - ldax #test_file + +@send_1_image: + lda #$93 ;cls + jsr print_a + print #signon_message + jsr move_to_first_sector + print #enter_filename + ldax #filter_dns ;this is pretty close to being a filter for legal chars in file names as well + jsr get_filtered_input + bcs @no_filename_entered stax nb65_param_buffer+NB65_TFTP_FILENAME + lda #15 + jsr open_channel + print #position_cursor_for_track_display ldax #send_next_block stax nb65_param_buffer+NB65_TFTP_POINTER ldax #nb65_param_buffer call #NB65_TFTP_CALLBACK_UPLOAD bcc :+ - jmp print_errorcode + print_cr + print #failed + jmp print_nb65_errorcode : - - rts -@error: - pha - print #drive_error - print #error_code - pla - call #NB65_PRINT_HEX + lda #15 ; filenumber 15 - command channel + jsr $FFC3 ; call CLOSE + print_cr + print #ok + print #press_a_key_to_continue + jsr get_key + jmp @send_1_image ;done! so go again +@no_filename_entered: rts @@ -144,8 +157,13 @@ send_next_block: lda track cmp #36 beq @past_last_track + print #position_cursor_for_track_display jsr print_current_sector jsr read_sector + lda #$30 + cmp error_buffer + bne @was_an_error +@after_error_check: jsr move_to_next_sector bcc @not_last_sector ldax #$100 @@ -160,10 +178,15 @@ send_next_block: ldax #$0000 rts +@was_an_error: + print #position_cursor_for_error_display + print #drive_error + print_cr + jsr print_current_sector + print #error_buffer + jmp @after_error_check print_current_sector: - lda #$13 ;home - jsr print_a print #track_no lda track jsr byte_to_ascii @@ -183,22 +206,57 @@ print_current_sector: print_cr rts -open_drive_channels: - LDA #cname_end-cname - LDX #cname + +;open whatever channel is in A +.bss + channel_number: .res 1 +.code +open_channel: + sta channel_number + LDA #0 ;zero length filename JSR $FFBD ; call SETNAM - LDA #$02 ; file number 2 - LDX $BA ; last used device number - BNE @skip + LDA channel_number ; file number LDX #$08 ; default to device 8 -@skip: - LDY #$02 ; secondary address 2 + LDA channel_number ; secondary address 2 JSR $FFBA ; call SETLFS - JSR $FFC0 ; call OPEN - bcc @opened_ok + JSR $FFC0 ; call OPEN + beq @no_error + pha + print #error_opening_channel + lda channel_number + call #NB65_PRINT_HEX + pla + jsr print_a_as_errorcode +@no_error: rts -@opened_ok: + + +;send ASCIIZ string in AX to channel Y +send_string_to_channel: + sty channel_number + stax temp_ptr + ldx channel_number + jsr $ffc9 ;CHKOUT + ldy #0 +@send_one_byte: + lda (temp_ptr),y + bne @done + jsr $ffd2 ; call CHROUT (send byte through command channel) + beq @error + jmp @send_one_byte +@done: + ldx #0 ;send output to screen again + jsr $ffc9 ;CHKOUT + rts +@error: +pha + print #error_sending_to_channel + lda channel_number + call #NB65_PRINT_HEX + jsr $ffb7 ;READST + jsr print_a_as_errorcode + + jsr get_key rts dump_sector: @@ -222,24 +280,12 @@ read_sector: 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 - + ldax command_buffer + ldy #15 + jsr send_string_to_channel jsr check_error_channel - + lda #2 + jsr open_channel LDX #$02 ; filenumber 2 JSR $FFC6 ; call CHKIN (file 2 now used as input) @@ -254,55 +300,31 @@ read_sector: INY BNE @loop ; next byte, end when 256 bytes are read @close: - LDA #$0F ; filenumber 15 + LDA #$02 ; filenumber 2 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) + sta error_buffer,y + iny JMP @loop ; next byte @eof: -@close: - LDA #$0F ; filenumber 15 - JSR $FFC3 ; call CLOSE - + lda #0 + sta error_buffer,y LDX #$00 ; filenumber 0 = keyboard JSR $FFC6 ; call CHKIN (keyboard now input device again) RTS - + bad_boot: print #press_a_key_to_continue restart: @@ -310,7 +332,16 @@ restart: jmp $fce2 ;do a cold start -print_errorcode: +print_a_as_errorcode: + pha + lda #' ' + jsr print_a + print #error_code + pla + call #NB65_PRINT_HEX + rts + +print_nb65_errorcode: print #error_code call #NB65_GET_LAST_ERROR call #NB65_PRINT_HEX @@ -459,7 +490,7 @@ move_to_next_sector: .rodata error_code: - .asciiz "ERROR CODE: $" + .byte "ERROR CODE: $",0 press_a_key_to_continue: .byte "PRESS A KEY TO CONTINUE",13,0 @@ -479,16 +510,26 @@ sector_no: signon_message: .byte "D64 UPLOADER V0.1",13,0 - + +enter_filename: +.byte "SEND AS: ",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 - + error_opening_channel: + .byte "ERROR OPENING CHANNEL $",0 + error_sending_to_channel: + .byte "ERROR SENDING TO CHANNEL $",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: +position_cursor_for_track_display: +; .byte $13,13,13,13,13,13,13,13,13,13,13," SENDING ",0 +.byte $13,13,13,"SENDING ",0 +position_cursor_for_error_display: + .byte $13,13,13,13,"LAST ",0 +disk_error: + \ No newline at end of file diff --git a/client/nb65/nb65_c64.s b/client/nb65/nb65_c64.s index e813f20..57e7200 100644 --- a/client/nb65/nb65_c64.s +++ b/client/nb65/nb65_c64.s @@ -180,15 +180,18 @@ ldax #init_msg jsr print_errorcode jsr wait_for_keypress jmp exit_to_basic - -main_menu: + +print_main_menu: lda #21 ;make sure we are in upper case sta $d018 jsr cls ldax #netboot65_msg jsr print ldax #main_menu_msg - jsr print + jmp print + +main_menu: + jsr print_main_menu jsr print_ip_config jsr print_cr @@ -201,7 +204,11 @@ main_menu: cmp #KEYCODE_F3 beq @exit_to_basic cmp #KEYCODE_F5 - beq @util_menu + bne @not_util_menu + jsr print_main_menu + jsr print_arp_cache + jmp @get_key +@not_util_menu: cmp #KEYCODE_F7 beq @change_config @@ -211,27 +218,6 @@ main_menu: ldax #$fe66 ;do a wam start jmp exit_cart_via_ax -@util_menu_header: - jsr cls - ldax #netboot65_msg - jsr print - ldax #util_menu_msg - jsr print - rts -@util_menu: - jsr @util_menu_header -@get_key_util_menu: - jsr get_key - cmp #KEYCODE_F1 - bne @not_arp_cache - jsr @util_menu_header - jsr print_arp_cache - jmp @get_key_util_menu - @not_arp_cache: - cmp #KEYCODE_F7 - beq main_menu - jmp @get_key_util_menu - @change_config: jsr cls @@ -544,31 +530,25 @@ cfg_get_configuration_ptr: .rodata netboot65_msg: -.byte "NETBOOT65 - C64 NETWORK BOOT CLIENT V0.4",13 +.byte "NETBOOT65 - C64 NETWORK BOOT CLIENT V0.9",13 .byte 0 main_menu_msg: -.byte 13," MAIN MENU",13,13 +.byte 13," MAIN MENU",13,13 .byte "F1: TFTP BOOT F3: BASIC",13 -.byte "F5: UTILITIES F7: CONFIG",13,13 -.byte 0 - -util_menu_msg: -.byte 13," UTILITIES",13,13 -.byte "F1: ARP TABLE",13 -.byte " F7: MAIN MENU",13,13 +.byte "F5: ARP TABLE F7: CONFIG",13,13 .byte 0 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 +.byte "F1: IP ADDRESS F2: NETMASK",13 +.byte "F3: GATEWAY F4: DNS SERVER",13 +.byte "F5: TFTP SERVER F6: RESET TO DEFAULT",13 .byte "F7: MAIN MENU",13,13 .byte 0 downloading_msg: .asciiz "DOWNLOADING " -getting_dir_listing_msg: .asciiz "FETCHING TFTP DIRECTORY FOR " +getting_dir_listing_msg: .asciiz "FETCHING DIR FOR " tftp_dir_listing_fail_msg: .byte "DIR LISTING FAILED",13,0 diff --git a/client/test/test_cart_api.s b/client/test/test_cart_api.s index 5130a30..bef12f3 100644 --- a/client/test/test_cart_api.s +++ b/client/test/test_cart_api.s @@ -138,7 +138,10 @@ init: ldax #nb65_param_buffer+NB65_DNS_HOSTNAME_IP call #NB65_PRINT_DOTTED_QUAD print_cr - + + ldax #64 + call #NB65_UDP_REMOVE_LISTENER ;should generate an error since there is no listener on port 64 + jsr print_errorcode ;tftp send test diff --git a/dist/make_dist.rb b/dist/make_dist.rb index 17d2bad..a6888d2 100644 --- a/dist/make_dist.rb +++ b/dist/make_dist.rb @@ -19,7 +19,7 @@ end #["client/nb65/nb65_rrnet.bin","c64/"], ["client/nb65/nb65_c64_ram.prg","c64/"], ["client/nb65/nb65_std_cart.bin","c64/"], -["client/nb65/d64_upload.prg","boot/"], +#["client/nb65/d64_upload.prg","boot/"], ["server/lib/tftp_server.rb","lib"], ["server/bin/tftp_only_server.rb","bin/tftp_server.rb"], ["server/bin/import_ags_games.rb","bin"], diff --git a/server/bin/tftp_only_server.rb b/server/bin/tftp_only_server.rb index a3e67fb..c3117ce 100644 --- a/server/bin/tftp_only_server.rb +++ b/server/bin/tftp_only_server.rb @@ -16,8 +16,10 @@ $:.unshift(lib_path) unless $:.include?(lib_path) require 'tftp_server' bootfile_dir=File.expand_path(File.dirname(__FILE__)+'/../boot') -tftp_server=Netboot65TFTPServer.new(bootfile_dir) -tftp_server.start +tftp_server_69=Netboot65TFTPServer.new(bootfile_dir,69) +tftp_server_69.start +tftp_server_6502=Netboot65TFTPServer.new(bootfile_dir,6502) +tftp_server_6502.start begin loop do @@ -26,5 +28,5 @@ begin rescue Interrupt log_msg "got interrupt signal - shutting down" end -tftp_server.shutdown +tftp_server_6502.shutdown log_msg "shut down complete."