diff --git a/client/clients/rrnetboot.s b/client/clients/rrnetboot.s index 144b6a7..ea907aa 100644 --- a/client/clients/rrnetboot.s +++ b/client/clients/rrnetboot.s @@ -31,6 +31,10 @@ jsr print_cr .endmacro + .macro nb65call arg + ldy arg + jsr NB65_DISPATCH_VECTOR + .endmacro .ifndef NB65_API_VERSION_NUMBER .define EQU = @@ -47,7 +51,11 @@ .import timer_vbl_handler .import nb65_dispatcher .import ip65_process - + .import get_filtered_input + .import filter_text + .import filter_dns + + .import print_dotted_quad .import print_hex .import print_ip_config .import ok_msg @@ -59,11 +67,11 @@ .import copymem .importzp copy_src .importzp copy_dest - + .import get_filtered_input .import __DATA_LOAD__ .import __DATA_RUN__ .import __DATA_SIZE__ - + .import cfg_tftp_server tftp_dir_buffer = $6000 .data @@ -115,7 +123,13 @@ init: jsr $e3bf ;initialize zero page - + ;set some funky colours + LDA #$05 ;green + STA $D020 ;background + LDA #$00 ;black + STA $D021 ;background + lda #$1E + jsr print_a ;relocate our r/w data ldax #__DATA_LOAD__ @@ -142,16 +156,31 @@ init: jsr copymem .endif - ldax #startup_msg +ldax #init_msg + jsr print + + nb65call #NB65_INITIALIZE + +main_menu: + jsr cls + ldax #netboot65_msg jsr print + ldax #main_menu_msg + jsr print + jsr print_ip_config + jsr print_cr @get_key: jsr get_key cmp #KEYCODE_F1 - beq @tftp_boot - cmp #KEYCODE_F3 - + bne @not_tftp + jmp @tftp_boot + @not_tftp: + cmp #KEYCODE_F3 beq @exit_to_basic + cmp #KEYCODE_F7 + beq @change_config + jmp @get_key @@ -159,27 +188,47 @@ init: ldax #$fe66 ;do a wam start jmp exit_cart_via_ax -@tftp_boot: - - ldax #init_msg - jsr print - - ldy #NB65_INITIALIZE - jsr NB65_DISPATCH_VECTOR - - bcc :+ - print_failed - jsr print_errorcode - jmp bad_boot -: - - print_ok - - jsr print_ip_config - - ldax #press_a_key_to_continue +@change_config: + jsr cls + ldax #netboot65_msg jsr print - jsr get_key + ldax #config_menu_msg + jsr print + ldax #current + jsr print + ldax #tftp_server + jsr print + ldax #cfg_tftp_server + jsr print_dotted_quad + jsr print_cr + ldax #enter_new_tftp_server + jsr print + jsr print_cr + ldax #filter_dns + jsr get_filtered_input + bcs @no_server_entered + stax nb65_param_buffer + jsr print_cr + ldax #resolving + jsr print + ldax #nb65_param_buffer + nb65call #NB65_DNS_RESOLVE + bcs @resolve_error + ldax #nb65_param_buffer + stax copy_src + ldax #cfg_tftp_server + stax copy_dest + ldax #4 + jsr copymem +@no_server_entered: + jmp main_menu + +@resolve_error: + print_failed + jsr wait_for_keypress + jmp main_menu + +@tftp_boot: jsr setup_param_buffer_for_tftp_call @@ -196,8 +245,7 @@ init: jsr print_cr ldax #nb65_param_buffer - ldy #NB65_TFTP_DIRECTORY_LISTING - jsr NB65_DISPATCH_VECTOR + nb65call #NB65_TFTP_DIRECTORY_LISTING bcs @dir_failed @@ -238,8 +286,7 @@ init: @file_downloaded_ok: ;get ready to bank out - ldy #NB65_DEACTIVATE - jsr NB65_DISPATCH_VECTOR + nb65call #NB65_DEACTIVATE ;check whether the file we just downloaded was a BASIC prg lda nb65_param_buffer+NB65_TFTP_POINTER @@ -273,8 +320,7 @@ exit_cart_via_ax: print_errorcode: ldax #error_code jsr print - ldy #NB65_GET_LAST_ERROR - jsr NB65_DISPATCH_VECTOR + nb65call #NB65_GET_LAST_ERROR jsr print_hex jmp print_cr @@ -282,7 +328,7 @@ print_errorcode: setup_param_buffer_for_tftp_call: ldx #3 - lda #$ff ;255.255.255.255 = broadcast address + lda cfg_tftp_server,x : sta nb65_param_buffer+NB65_TFTP_IP,x dex @@ -290,9 +336,7 @@ setup_param_buffer_for_tftp_call: rts bad_boot: - ldax #press_a_key_to_continue - jsr print - jsr get_key + jsr wait_for_keypress jmp $fe66 ;do a wam start download: ;AX should point at filename to download @@ -307,9 +351,8 @@ download: ;AX should point at filename to download jsr print_cr jsr setup_param_buffer_for_tftp_call - ldy #NB65_TFTP_DOWNLOAD ldax #nb65_param_buffer - jsr NB65_DISPATCH_VECTOR + nb65call #NB65_TFTP_DOWNLOAD bcc :+ ldax #tftp_download_fail_msg @@ -324,17 +367,29 @@ download: ;AX should point at filename to download clc rts +wait_for_keypress: + ldax #press_a_key_to_continue + jsr print + jsr get_key + rts + cfg_get_configuration_ptr: - ldy #NB65_GET_IP_CONFIG ldax #nb65_param_buffer - jmp NB65_DISPATCH_VECTOR + nb65call #NB65_GET_IP_CONFIG + rts .rodata -startup_msg: +netboot65_msg: .byte "NETBOOT65 - C64 NETWORK BOOT CLIENT V0.4",13 -.byte "F1=TFTP BOOT, F3=BASIC",13 .byte 0 +main_menu_msg: +.byte "F1: TFTP BOOT F3: BASIC",13 +.byte "F7: CONFIG",13,13 +.byte 0 + +config_menu_msg: +.byte "NETBOOT65 CONFIGURATION",13,0 downloading_msg: .asciiz "DOWNLOADING " @@ -352,6 +407,16 @@ tftp_download_ok_msg: error_code: .asciiz "ERROR CODE: " +current: +.byte "CURRENT ",0 +enter_new_tftp_server: +.byte"ENTER " + +new_tftp_server: + .byte "NEW " +tftp_server: +.byte "TFTP SERVER: ",0 + tftp_dir_filemask: .asciiz "*.PRG" @@ -364,6 +429,9 @@ no_files_on_server: press_a_key_to_continue: .byte "PRESS A KEY TO CONTINUE",13,0 +resolving: + .byte "RESOLVING ",0 + 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/drivers/c64inputs.s b/client/drivers/c64inputs.s index 79ba3fe..e24eb6a 100644 --- a/client/drivers/c64inputs.s +++ b/client/drivers/c64inputs.s @@ -1,13 +1,132 @@ .export get_key +.export get_filtered_input +.export filter_text +.export filter_ip +.export filter_dns +.importzp copy_src +.include "../inc/common.i" .code +allowed_ptr=copy_src ;reuse zero page + ;use C64 Kernel ROM function to read a key ;inputs: none ;outputs: A contains ASCII value of key just pressed get_key: jsr $ffe4 - cmp #0 beq get_key rts - \ No newline at end of file + + +;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input +;====================================================================== +;Input a string and store it in GOTINPUT, terminated with a null byte. +;x:a is a pointer to the allowed list of characters, null-terminated. +;max # of chars in y returns num of chars entered in y. +;====================================================================== + + +; Main entry +get_filtered_input: + sty MAXCHARS + stax allowed_ptr + + ;Zero characters received. + lda #$00 + sta INPUT_Y + +;Wait for a character. +INPUT_GET: + jsr get_key + sta LASTCHAR + + cmp #$14 ;Delete + beq DELETE + + cmp #$0d ;Return + beq INPUT_DONE + + ;Check the allowed list of characters. + ldy #$00 +CHECKALLOWED: + lda (allowed_ptr),y ;Overwritten + beq INPUT_GET ;Reached end of list (0) + + cmp LASTCHAR + beq INPUTOK ;Match found + + ;Not end or match, keep checking + iny + jmp CHECKALLOWED + +INPUTOK: + lda LASTCHAR ;Get the char back + ldy INPUT_Y + sta GOTINPUT,y ;Add it to string + jsr $ffd2 ;Print it + + inc INPUT_Y ;Next character + + ;End reached? + lda INPUT_Y + cmp MAXCHARS + beq INPUT_DONE + + ;Not yet. + jmp INPUT_GET + +INPUT_DONE: + ldy INPUT_Y + beq no_input + lda #$00 + sta GOTINPUT,y ;Zero-terminate + clc + ldax #GOTINPUT + rts +no_input: + sec + rts +; Delete last character. +DELETE: + ;First, check if we're at the beginning. If so, just exit. + lda INPUT_Y + bne DELETE_OK + jmp INPUT_GET + + ;At least one character entered. +DELETE_OK: + ;Move pointer back. + dec INPUT_Y + + ;Store a zero over top of last character, just in case no other characters are entered. + ldy INPUT_Y + lda #$00 + sta GOTINPUT,y + + ;Print the delete char + lda #$14 + jsr $ffd2 + + ;Wait for next char + jmp INPUT_GET + + +;================================================= +;Some example filters +;================================================= + +filter_text: + .byte ",+!#$%&'()* " +filter_dns: +.byte " -ABCDEFGHIJKLMNOPQRSTUVWXYZ" +filter_ip: +.byte "1234567890.",0 + +;================================================= +.bss +MAXCHARS: .res 1 +LASTCHAR: .res 1 +INPUT_Y: .res 1 +GOTINPUT: .res 40 + diff --git a/client/examples/dasm_example.asm b/client/examples/dasm_example.asm index 75fe3f7..3f2e1cf 100644 --- a/client/examples/dasm_example.asm +++ b/client/examples/dasm_example.asm @@ -84,37 +84,16 @@ found_nb65_signature ;print out the current configuration nb65call #NB65_PRINT_IP_CONFIG -;test out DNS resolution: - - ldaxi #test_hostname - stax nb65_param_buffer+NB65_DNS_HOSTNAME - - nb65call #NB65_PRINT_ASCIIZ - - print #space_colon_space - - ldaxi #nb65_param_buffer - nb65call #NB65_DNS_RESOLVE - bcc .no_dns_error - print #dns_lookup_failed_msg - print_cr - jsr print_errorcode - jmp reset_after_keypress -.no_dns_error - - ldaxi #nb65_param_buffer+NB65_DNS_HOSTNAME_IP - nb65call #NB65_PRINT_DOTTED_QUAD - print_cr ;now set up for the nb65callback test ldaxi #64 ;listen on port 64 stax nb65_param_buffer+NB65_UDP_LISTENER_PORT ldaxi #udp_nb65callback - stax nb65_param_buffer+NB65_UDP_LISTENER_nb65callBACK + stax nb65_param_buffer+NB65_UDP_LISTENER_CALLBACK ldaxi #nb65_param_buffer nb65call #NB65_UDP_ADD_LISTENER - bcc .add_listener_ok + bcc .add_listener_ok print #failed jsr print_errorcode jmp reset_after_keypress @@ -240,8 +219,6 @@ error_code dc.b "ERROR CODE: $",0 press_a_key_to_continue dc.b "PRESS A KEY TO CONTINUE",13,0 failed dc.b "FAILED ", 0 ok dc.b "OK ", 0 -test_hostname dc.b "RETROHACKERS.COM",0 ;this should be an A record -dns_lookup_failed_msg dc.b "DNS LOOKUP FAILED", 0 recv_from dc.b"RECEIVED FROM: ",0 listening dc.b "LISTENING ON UDP PORT 64",13,0 reply_sent dc.b "REPLY SENT.",0 diff --git a/client/inc/commonprint.i b/client/inc/commonprint.i index 48da5fd..3573f43 100644 --- a/client/inc/commonprint.i +++ b/client/inc/commonprint.i @@ -11,9 +11,10 @@ .export init_msg .export print .export print_decimal + .export print_dotted_quad .import cs_driver_name .importzp copy_src - +.import cfg_tftp_server ;reuse the copy_src zero page var pptr = copy_src .bss @@ -125,6 +126,12 @@ print_ip_config: : jsr print_dotted_quad jsr print_cr + ldax #tftp_server_msg + jsr print + ldax #cfg_tftp_server + jsr print_dotted_quad + jsr print_cr + ldax #dhcp_server_msg jsr print jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear @@ -278,11 +285,14 @@ dns_server_msg: dhcp_server_msg: .byte "DHCP SERVER : ", 0 +tftp_server_msg: +.byte "TFTP SERVER : ", 0 + dhcp_msg: .byte "DHCP",0 init_msg: - .byte "INIT ",0 + .byte " INITIALIZING ",0 failed_msg: .byte "FAILED", 0 diff --git a/client/ip65/dns.s b/client/ip65/dns.s index fb6b7d4..a231877 100644 --- a/client/ip65/dns.s +++ b/client/ip65/dns.s @@ -183,13 +183,12 @@ dns_set_hostname: ; outputs: ; carry flag is set if there was an error, clear otherwise ; dns_ip: set to the ip address of the hostname (if no error) -dns_resolve: +dns_resolve: lda hostname_was_dotted_quad beq @hostname_not_dotted_quad clc rts ;we already set dns_ip when copying the hostname @hostname_not_dotted_quad: - ldax #dns_in stax udp_callback lda #53 @@ -245,6 +244,7 @@ dns_resolve: jmp @dns_polling_loop @complete: + lda #53 ldx dns_client_port_low_byte jsr udp_remove_listener @@ -260,8 +260,7 @@ dns_resolve: sec ;signal an error rts -send_dns_query: - +send_dns_query: ldax dns_msg_id inx adc #0 @@ -316,10 +315,11 @@ send_dns_query: ldax #dns_server_port ; set destination port stax udp_send_dest_port ldax #output_buffer - jsr udp_send + jsr udp_send bcs @error_on_send lda #dns_query_sent sta dns_state + rts @error_on_send: sec diff --git a/client/ip65/function_dispatcher.s b/client/ip65/function_dispatcher.s index 1733f6b..81c8821 100644 --- a/client/ip65/function_dispatcher.s +++ b/client/ip65/function_dispatcher.s @@ -108,9 +108,11 @@ nb65_dispatcher: stax $314 ;previous IRQ handler cli sta irq_handler_installed_flag -irq_handler_installed: jsr ip65_init jmp dhcp_init +irq_handler_installed: + clc + rts : cpy #NB65_GET_IP_CONFIG