diff --git a/CHANGES.txt b/CHANGES.txt index 51256ec..3ce69f8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,5 @@ + - bugfix - NB65 API not setting "ip initialized" flag correct, hence extra DHCP inits occuring + 0.9.8 - created stubs for TCP functions - split nb65 cart images into 8k (UDP only - green) & 16k (UDP+TCP - purple) images diff --git a/client/cfg/c64_16kcart.cfg b/client/cfg/c64_16kcart.cfg index 31b11fa..b6b0bd1 100644 --- a/client/cfg/c64_16kcart.cfg +++ b/client/cfg/c64_16kcart.cfg @@ -1,13 +1,13 @@ # CA65 config for a 16KB cart MEMORY { - IP65ZP: start = $A3, size = $0E, type = rw, define = yes; + IP65ZP: start = $A3, size = $11, type = rw, define = yes; HEADER: start = $8000, size = $18, file = %O; DEFAULTS: start = $8018, size = $1E, file = %O; ROM: start = $8036, size = $3FC8, define = yes, file = %O; RAM: start = $C010, size = $0fE0, define = yes; RAM2: start = $0334, size = $CB, define = yes; #extra scratch area - Tape I/O buffer - + RAM3: start = $0800, size = $7800, define = yes; #scratch area for apps embedded in cart to use } SEGMENTS { @@ -17,6 +17,7 @@ SEGMENTS { RODATA: load = ROM, run=ROM, type = ro; DATA: load = ROM, run = RAM, type = rw, define = yes; BSS: load = RAM, type = bss; + APP_SCRATCH: load = RAM3, type = bss; TCP_VARS: load = RAM2, type = bss; IP65ZP: load = IP65ZP, type = zp; } diff --git a/client/cfg/c64prg.cfg b/client/cfg/c64prg.cfg index a9ef89f..9fb881b 100644 --- a/client/cfg/c64prg.cfg +++ b/client/cfg/c64prg.cfg @@ -10,7 +10,8 @@ SEGMENTS { DATA: load = RAM, type = rw,define = yes; RODATA: load = RAM, type = ro,define = yes; IP65_DEFAULTS: load = RAM, type = rw,define = yes; - BSS: load = RAM, type = bss; + BSS: load = RAM, type = bss; + APP_SCRATCH: load = RAM, type = bss; ZEROPAGE: load = ZP, type = zp; IP65ZP: load = IP65ZP, type = zp; EXEHDR: load = DISCARD, type = ro; diff --git a/client/drivers/c64inputs.s b/client/drivers/c64inputs.s index bd3b68a..469ee14 100644 --- a/client/drivers/c64inputs.s +++ b/client/drivers/c64inputs.s @@ -3,6 +3,7 @@ .export filter_text .export filter_ip .export filter_dns +.export filter_number .export check_for_abort_key .export get_key_if_available .importzp copy_src @@ -73,6 +74,11 @@ INPUT_GET: cmp #$0d ;Return beq INPUT_DONE + ;End reached? + lda INPUT_Y + cmp MAXCHARS + beq INPUT_GET + ;Check the allowed list of characters. ldy #$00 CHECKALLOWED: @@ -94,10 +100,6 @@ INPUTOK: inc INPUT_Y ;Next character - ;End reached? - lda INPUT_Y - cmp MAXCHARS - beq INPUT_DONE ;Not yet. jmp INPUT_GET @@ -145,9 +147,11 @@ DELETE_OK: filter_text: .byte ",+!#$%&'()* " filter_dns: -.byte " -ABCDEFGHIJKLMNOPQRSTUVWXYZ" +.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ" filter_ip: -.byte "1234567890.",0 +.byte "." +filter_number: +.byte "1234567890",0 ;================================================= .bss diff --git a/client/examples/dumb_telnet.asm b/client/examples/dumb_telnet.asm new file mode 100644 index 0000000..ee67e37 --- /dev/null +++ b/client/examples/dumb_telnet.asm @@ -0,0 +1,207 @@ +;NB65 API example in DASM format (http://www.atari2600.org/DASM/) + processor 6502 + + include "../inc/nb65_constants.i" + + ;useful macros + mac ldax + lda [{1}] + ldx [{1}]+1 + endm + + mac ldaxi + lda #<[{1}] + ldx #>[{1}] + endm + + mac stax + sta [{1}] + stx [{1}]+1 + endm + + mac cout + lda [{1}] + jsr print_a + endm + + mac print_cr + cout #13 + jsr print_a + endm + + mac nb65call + ldy [{1}] + jsr NB65_DISPATCH_VECTOR + endm + + mac print + + ldaxi [{1}] + ldy #NB65_PRINT_ASCIIZ + jsr NB65_DISPATCH_VECTOR + endm + + +;some routines & zero page variables +print_a equ $ffd2 +temp_ptr equ $FB ; scratch space in page zero + + +;start of code +;NO BASIC stub! needs to be direct booted via TFTP + org $1000 + + ldaxi #NB65_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in) + jsr look_for_signature + bcc found_nb65_signature + + ldaxi #NB65_RAM_STUB_SIGNATURE ;where signature should be in a RAM stub + jsr look_for_signature + bcs nb65_signature_not_found + jsr NB65_RAM_STUB_ACTIVATE ;we need to turn on NB65 cartridge + jmp found_nb65_signature + +nb65_signature_not_found + ldaxi #nb65_api_not_found_message + jsr print_ax + rts + +found_nb65_signature + + lda NB65_API_VERSION + cmp #02 + bpl .version_ok + print incorrect_version + jmp reset_after_keypress +.version_ok + print #initializing + nb65call #NB65_INITIALIZE + bcc .init_ok + print_cr + print #failed + print_cr + jsr print_errorcode + jmp reset_after_keypress +.init_ok + +;if we got here, we have found the NB65 API and initialised the IP stack +;print out the current configuration + nb65call #NB65_PRINT_IP_CONFIG +;prompt for a hostname, then resolve to an IP address +.get_hostname + print #remote_host + nb65call #NB65_INPUT_HOSTNAME + bcc .host_entered + ;if no host entered, then bail. + jmp reset_after_keypress +.host_entered + stax nb65_param_buffer + print_cr + print #resolving + ldax nb65_param_buffer + nb65call #NB65_PRINT_ASCIIZ + print_cr + ldaxi #nb65_param_buffer + nb65call #NB65_DNS_RESOLVE + bcc .resolved_ok + print #failed + print_cr + jsr print_errorcode + jmp .get_hostname +.resolved_ok +.get_port + print #remote_port + nb65call #NB65_INPUT_PORT_NUMBER + bcc .port_entered + ;if no port entered, then assume port 23 + ldaxi #23 +.port_entered + stax nb65_param_buffer+NB65_TCP_PORT + ldaxi #tcp_callback + stax nb65_param_buffer+NB65_TCP_CALLBACK + print #connecting + ldaxi #nb65_param_buffer + nb65call #NB65_TCP_CONNECT + bcc .connect_ok + print_cr + print #failed + jsr print_errorcode + jmp .get_hostname +.connect_ok + print #ok +.loop_forever + jsr NB65_PERIODIC_PROCESSING_VECTOR + jmp .loop_forever + + +;tcp callback - will be executed whenever data arrives on the TCP connection +tcp_callback + .byte $92 + rts + +;look for NB65 signature at location pointed at by AX +look_for_signature subroutine + 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 + +print_ax subroutine + stax temp_ptr + ldy #0 +.next_char + lda (temp_ptr),y + beq .done + jsr print_a + iny + jmp .next_char +.done + rts + +get_key + jsr $ffe4 + cmp #0 + beq get_key + rts + +reset_after_keypress + print #press_a_key_to_continue + jsr get_key + jmp $fce2 ;do a cold start + + +print_errorcode + print #error_code + nb65call #NB65_GET_LAST_ERROR + nb65call #NB65_PRINT_HEX + print_cr + rts + + + +;constants +nb65_api_not_found_message dc.b "ERROR - NB65 API NOT FOUND.",13,0 +incorrect_version dc.b "ERROR - NB65 API MUST BE AT LEAST VERSION 2.",13,0 + +nb65_signature dc.b $4E,$42,$36,$35 ; "NB65" - API signature +initializing dc.b "INITIALIZING ",13,0 +error_code dc.b "ERROR CODE: $",0 +resolving dc.b "RESOLVING ",0 +connecting dc.b "CONNECTING ",0 +remote_host dc.b "REMOTE HOST - BLANK TO QUIT",13,": ",0 +remote_port dc.b "REMOTE PORT - BLANK FOR TELNET DEFAULT",13,": ",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 + +;variables +nb65_param_buffer DS.B $20 diff --git a/client/test/test_gopher.s b/client/inc/gopher.i similarity index 75% rename from client/test/test_gopher.s rename to client/inc/gopher.i index 964af3c..3fd0d8b 100644 --- a/client/test/test_gopher.s +++ b/client/inc/gopher.i @@ -1,24 +1,24 @@ - .include "../inc/common.i" - .include "../inc/commonprint.i" - .include "../inc/net.i" - .include "../inc/char_conv.i" - .include "../inc/c64keycodes.i" +; C64 gopher browser +; july 2009 - jonno @ jamtronix.com +; this contains the key gopher rendering routines +; to use: +; 1) include this file +; 2) include these other files: +; .include "../inc/common.i" +; .include "../inc/commonprint.i" +; .include "../inc/net.i" +; .include "../inc/char_conv.i" +; .include "../inc/c64keycodes.i" +; 3) define a routine called 'exit_gopher' - .import get_key +; .import get_key .import get_key_if_available - .import __CODE_LOAD__ - .import __CODE_SIZE__ - .import __RODATA_SIZE__ - .import __DATA_SIZE__ - .import mul_8_16 .importzp acc16 - .importzp copy_src .importzp copy_dest .import copymem - .import tcp_connect .import tcp_send .import tcp_send_data_len @@ -39,31 +39,7 @@ ; pointer for moving through buffers buffer_ptr: .res 2 ; source pointer - - -.segment "STARTUP" ;this is what gets put at the start of the file on the C64 - - .word basicstub ; load address - - -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 - -.segment "EXEHDR" ;this is what gets put an the start of the file on the Apple 2 - .addr __CODE_LOAD__-$11 ; Start address - .word __CODE_SIZE__+__RODATA_SIZE__+__DATA_SIZE__+4 ; Size - jmp init - - + .data get_next_byte: lda $ffff @@ -76,9 +52,9 @@ get_next_byte: current_resource_history_entry: .byte 0 -.bss +.segment "APP_SCRATCH" -DISPLAY_LINES=24 +DISPLAY_LINES=22 page_counter: .res 1 MAX_PAGES = 50 page_pointer_lo: .res MAX_PAGES @@ -104,34 +80,20 @@ resource_hostname: .res RESOURCE_HOSTNAME_MAX_LENGTH resource_port: .res 2 resource_selector: .res 160 resource_selector_length: .res 1 +displayed_resource_type: .res 1 + RESOURCE_HISTORY_ENTRIES=8 resource_history: .res $100*RESOURCE_HISTORY_ENTRIES +input_buffer: + .res 16000 + .code -init: - - lda #14 - jsr print_a ;switch to lower case - - jsr print_cr - init_ip_via_dhcp - jsr print_ip_config - - jsr prompt_for_gopher_resource - bcs @use_default_start_page - rts -@use_default_start_page: - ldax #initial_location - sta resource_pointer_lo - stx resource_pointer_hi - ldx #0 - jsr select_resource - rts +;display whatever is in the buffer either as plain text or gopher text display_resource_in_buffer: - ldax #input_buffer stax get_next_byte+1 @@ -146,7 +108,7 @@ display_resource_in_buffer: ; lda page_counter ; jsr print_hex - jsr print_resource_description +; jsr print_resource_description ldx page_counter lda get_next_byte+1 sta page_pointer_lo,x @@ -154,10 +116,33 @@ display_resource_in_buffer: sta page_pointer_hi,x inc page_counter + + lda displayed_resource_type + cmp #'0' + bne @displayed_resource_is_directory + +;if this is a text file, just convert ascii->petscii and print to screen +@show_one_char: + jsr get_next_byte + tax ;this both sets up X as index into ascii_to_petscii_table, and sets Z flag + bne :+ + lda #1 + sta this_is_last_page + jmp @get_keypress +: + + lda ascii_to_petscii_table,x + jsr print_a + lda $d6 + cmp #DISPLAY_LINES + bmi @show_one_char + jmp @end_of_current_page + +@displayed_resource_is_directory: + lda #0 sta resource_counter - - + @next_line: jsr get_next_byte cmp #'.' @@ -176,6 +161,7 @@ display_resource_in_buffer: ;if we got here, we know not what it is jmp @skip_to_end_of_line @standard_resource: + pha ldx resource_counter sta resource_type,x sec @@ -186,17 +172,27 @@ display_resource_in_buffer: sbc #0 ;in case there was an overflow on the low byte sta resource_pointer_hi,x inc resource_counter - lda $d3 + + lda $d3 ;are we at the start of the current line? beq :+ jsr print_cr : - lda #18 + pla ;get back the resource type +; cmp #'1' +; beq @resource_is_a_dir +; lda #'-' +; jmp @print_resource_indicator +;@resource_is_a_dir: +; lda #'+' +;@print_resource_indicator: +; jsr print_a + lda #18 ;inverse mode on jsr print_a lda resource_counter clc adc #'a'-1 jsr print_a - lda #146 + lda #146 ;inverse mode off jsr print_a lda #' ' jsr print_a @@ -216,6 +212,8 @@ display_resource_in_buffer: jsr get_next_byte cmp #$0A bne @skip_to_end_of_line + + lda $d3 cmp #0 beq :+ @@ -223,7 +221,10 @@ display_resource_in_buffer: : lda $d6 cmp #DISPLAY_LINES - bmi @next_line + bpl @end_of_current_page + jmp @next_line + +@end_of_current_page: lda #0 sta this_is_last_page @done: @@ -246,8 +247,10 @@ display_resource_in_buffer: beq @back_in_history cmp #KEYCODE_F3 beq @back_in_history - cmp #KEYCODE_ABORT - + cmp #KEYCODE_F5 + beq @prompt_for_new_server + + cmp #KEYCODE_ABORT beq @quit ;if fallen through we don't know what the keypress means, go get another one and #$7f ;turn off the high bit @@ -260,7 +263,7 @@ display_resource_in_buffer: @valid_resource: tax dex - jsr select_resource + jsr select_resource_from_current_directory @not_a_resource: jmp @get_keypress @back_in_history: @@ -270,16 +273,21 @@ display_resource_in_buffer: stx current_resource_history_entry txa jsr load_resource_from_history - jmp display_resource_in_buffer + jsr load_resource_into_buffer + jmp display_resource_in_buffer @show_history: - jmp show_history + jsr show_history + jmp display_resource_in_buffer @go_next_page: lda this_is_last_page bne @get_keypress - jmp @do_one_page +@prompt_for_new_server: + jsr prompt_for_gopher_resource ;that routine only returns if no server was entered. + jmp display_resource_in_buffer + @quit: - rts + jmp exit_gopher @go_prev_page: ldx page_counter dex @@ -299,14 +307,16 @@ display_resource_in_buffer: ;get a gopher resource ;X should be the selected resource number ;the resources selected should be loaded into resource_pointer_* - -select_resource: +select_resource_from_current_directory: lda resource_pointer_lo,x sta buffer_ptr lda resource_pointer_hi,x sta buffer_ptr+1 ldy #0 ldx #0 + + lda (buffer_ptr),y + sta displayed_resource_type @skip_to_next_tab: iny beq @done_skipping_over_tab @@ -314,6 +324,7 @@ select_resource: cmp #$09 bne @skip_to_next_tab @done_skipping_over_tab: + ;should now be pointing at the tab just before the selector @copy_selector: iny @@ -429,7 +440,11 @@ show_history: sec sbc #1 bne @show_one_entry - + jsr print_cr + ldax #any_key_to_continue + jsr print + jsr get_key + rts ;load the 'current_resource' into the buffer @@ -444,8 +459,9 @@ load_resource_into_buffer: ldax #resource_hostname jsr dns_set_hostname - bcs @error + bcs :+ jsr dns_resolve +: bcs @error ldx #3 ; save IP address just retrieved @@ -468,6 +484,7 @@ load_resource_into_buffer: jsr print ldax #resource_selector jsr print + jsr print_cr ldx #0 stx download_flag stx dl_loop_counter @@ -507,6 +524,14 @@ gopher_download_callback: bne @not_end_of_file lda #1 sta download_flag + + ;put a zero byte at the end of the file (in case it was a text file) + ldax tcp_buffer_ptr + stax copy_dest + lda #0 + tay + sta (copy_dest),y + rts @not_end_of_file: @@ -561,9 +586,13 @@ print_resource_description: ; jsr print_hex ; jsr print_cr - ldax #gopher + ldax #server jsr print ldax #resource_hostname + + jsr print + jsr print_cr + ldax #selector jsr print ldax #resource_selector jsr print @@ -591,8 +620,9 @@ prompt_for_gopher_resource: sta resource_selector_length+1 lda #1 sta resource_selector_length + lda #'1' + sta displayed_resource_type jsr print_cr - clc jmp add_resource_to_history_and_display @no_server_entered: sec @@ -603,30 +633,21 @@ page_header: port_no: .byte "PORT NO ",0 history: -.byte "gopher history ",13,0 -gopher: -.byte "gopher://",0 +.byte "GOPHER HISTORY ",13,0 cr_lf: .byte $0D,$0A error: -.byte "error - code ",0 -resolving: -.byte "resolving ",0 +.byte "ERROR - CODE ",0 connecting: -.byte "connecting ",0 +.byte "CONNECTING ",0 retrieving: -.byte "retrieving ",0 +.byte "RETRIEVING ",0 gopher_server: -.byte "gopher server:",0 - -initial_location: -.byte "1gopher.floodgap.com",$09,"/",$09,"gopher.floodgap.com",$09,"70",$0D,$0A,0 -.byte "1luddite",$09,"",$09,"retro-net.org",$09,"70",$0D,$0A,0 -;.byte "1luddite",$09,"/luddite/",$09,"retro-net.org",$09,"70",$0D,$0A,0 +.byte "GOPHER " +server: +.byte "SERVER :",0 +selector: +.byte "SELECTOR :",0 +any_key_to_continue: +.byte "PRESS ANY KEY TO CONTINUE",0 -.bss -input_buffer: - .res 8000 -;.incbin "rob_gopher.txt" -;.incbin "retro_gopher.txt" -;.byte 0 diff --git a/client/inc/nb65_constants.i b/client/inc/nb65_constants.i index ffb646b..234fd76 100644 --- a/client/inc/nb65_constants.i +++ b/client/inc/nb65_constants.i @@ -32,9 +32,9 @@ NB65_GET_INPUT_PACKET_INFO EQU $11 ;inputs: AX points to a UDP/TCP packet pa 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_TCP_CONNECT EQU $14 ;inputs: AX points to a TCP connect parameter structure, outputs: A = connection # +NB65_TCP_CONNECT EQU $14 ;inputs: AX points to a TCP connect parameter structure, outputs: none NB65_SEND_TCP_PACKET EQU $15 ;inputs: AX points to a TCP send parameter structure, outputs: none packet is sent -NB65_TCP_CLOSE_CONNECTION EQU $16 ;inputs: A = connection # to close, outputs: none +NB65_TCP_CLOSE_CONNECTION EQU $16 ;inputs: none outputs: none NB65_TFTP_SET_SERVER EQU $20 ;inputs: AX points to a TFTP server parameter structure, outputs: none NB65_TFTP_DOWNLOAD EQU $22 ;inputs: AX points to a TFTP transfer parameter structure, outputs: TFTP param structure updated with @@ -53,6 +53,9 @@ NB65_PRINT_DOTTED_QUAD EQU $82 ;inputs: AX=pointer to 4 bytes that will NB65_PRINT_IP_CONFIG EQU $83 ;no inputs, no outputs, prints to screen current IP configuration +NB65_INPUT_HOSTNAME EQU $90 ;no inputs, outputs: AX = pointer to hostname (which may be IP address). +NB65_INPUT_PORT_NUMBER EQU $91 ;no inputs, outputs: AX = port number entered ($0000..$FFFF) + NB65_GET_LAST_ERROR EQU $FF ;no inputs, outputs A EQU error code (from last function that set the global error value, not necessarily the ;last function that was called) diff --git a/client/ip65/Makefile b/client/ip65/Makefile index c270aa3..c7915ce 100644 --- a/client/ip65/Makefile +++ b/client/ip65/Makefile @@ -16,7 +16,6 @@ ETHOBJS= \ cs8900a.o \ eth.o \ arp.o \ - ip.o \ icmp.o \ udp.o \ ip65.o \ @@ -27,22 +26,20 @@ ETHOBJS= \ dottedquad.o \ output_buffer.o\ tftp.o \ - tcp.o \ arithmetic.o\ - function_dispatcher.o \ all: ip65.lib ip65_tcp.lib -ip65.lib: $(ETHOBJS) +ip65.lib: $(ETHOBJS) function_dispatcher.s ip.s $(AS) $(AFLAGS) function_dispatcher.s $(AS) $(AFLAGS) ip.s - ar65 a ip65.lib $^ + ar65 a ip65.lib $(ETHOBJS) function_dispatcher.o ip.o -ip65_tcp.lib: tcp.o $(ETHOBJS) - $(AS) $(AFLAGS) function_dispatcher.s -DTCP +ip65_tcp.lib: tcp.o $(ETHOBJS) function_dispatcher.s ip.s tcp.s + $(AS) $(AFLAGS) function_dispatcher.s -DTCP -DAPI_VERSION=2 $(AS) $(AFLAGS) ip.s -DTCP - ar65 a ip65_tcp.lib $^ + ar65 a ip65_tcp.lib $(ETHOBJS) function_dispatcher.o ip.o tcp.o clean: rm -f *.o diff --git a/client/ip65/function_dispatcher.s b/client/ip65/function_dispatcher.s index 5fe7512..615b113 100644 --- a/client/ip65/function_dispatcher.s +++ b/client/ip65/function_dispatcher.s @@ -37,6 +37,7 @@ .import udp_send_dest .import udp_send_dest_port .import udp_send_len + .import copymem .import cfg_mac .import cfg_tftp_server @@ -45,7 +46,7 @@ ;reuse the copy_src zero page location nb65_params = copy_src - +buffer_ptr= copy_dest .data @@ -123,9 +124,9 @@ nb65_dispatcher: 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 -dhcp_ok: irq_handler_installed: clc init_failed: @@ -135,6 +136,7 @@ ip_configured: lda irq_handler_installed_flag bne irq_handler_installed jsr install_irq_handler + clc rts : @@ -399,6 +401,101 @@ ip_configured: rts : +;these are the API "version 2" functions + +.ifdef API_VERSION +.if (API_VERSION>1) + + .segment "TCP_VARS" + port_number: .res 2 + .code + + cpy #NB65_TCP_CONNECT + bne :+ + .import tcp_connect + .import tcp_callback + .import tcp_connect_ip + ldy #3 +@copy_dest_ip: + lda (nb65_params),y + sta tcp_connect_ip,y + dey + bpl @copy_dest_ip + + ldy #NB65_TCP_CALLBACK + lda (nb65_params),y + sta tcp_callback + iny + lda (nb65_params),y + sta tcp_callback+1 + + ldy #NB65_TCP_PORT+1 + lda (nb65_params),y + tax + dey + lda (nb65_params),y + jmp tcp_connect + +: + + + +.import filter_dns +.import get_filtered_input +.import filter_number + cpy #NB65_INPUT_HOSTNAME + bne :+ + ldy #40 ;max chars + ldax #filter_dns + jmp get_filtered_input +: + +cpy #NB65_INPUT_PORT_NUMBER + bne :+ + .import mul_8_16 + .import acc16 + + ldy #5 ;max chars + ldax #filter_number + jsr get_filtered_input + bcs @no_port_entered + + ;AX now points a string containing port number + + stax buffer_ptr + lda #0 + sta port_number + sta port_number+1 + tay +@parse_port: + lda (buffer_ptr),y + cmp #$1F + bcc @end_of_port ;any control char should be treated as end of port field + ldax port_number + stax acc16 + lda #10 + jsr mul_8_16 + ldax acc16 + stax port_number + lda (buffer_ptr),y + sec + sbc #'0' + clc + adc port_number + sta port_number + bcc @no_rollover + inc port_number+1 +@no_rollover: + iny + bne @parse_port +@end_of_port: + ldax port_number + clc +@no_port_entered: + rts +: +.endif +.endif cpy #NB65_GET_LAST_ERROR bne :+ diff --git a/client/nb65/nb65_c64.s b/client/nb65/nb65_c64.s index 6cdd5a3..4fa1e5e 100644 --- a/client/nb65/nb65_c64.s +++ b/client/nb65/nb65_c64.s @@ -43,7 +43,11 @@ .include "../inc/common.i" .include "../inc/c64keycodes.i" .include "../inc/menu.i" - + +.if (BANKSWITCH_SUPPORT=$03) + .include "../inc/char_conv.i" + .include "../inc/gopher.i" +.endif .import cls .import beep .import exit_to_basic @@ -102,14 +106,13 @@ exit_cart: sta $0001 ;turns off ordinary cartridge by modifying HIRAM/LORAM (this will also bank out BASIC) .endif -get_value_of_axy: ;some more self-modifying code - lda $ffff,y - rts - call_downloaded_prg: jsr $0000 ;overwritten when we load a file jmp init +get_value_of_axy: ;some more self-modifying code + lda $ffff,y + rts .segment "CARTRIDGE_HEADER" @@ -117,7 +120,11 @@ call_downloaded_prg: .word $FE47 ;warm start vector .byte $C3,$C2,$CD,$38,$30 ; "CBM80" .byte $4E,$42,$36,$35 ; "NB65" - API signature -.byte $01 ;NB65_API_VERSION +.if (BANKSWITCH_SUPPORT=$03) +.byte $02 ;NB65_API_VERSION 2 requires 16KB cart +.else +.byte $01 ;NB65_API_VERSION 1 (in an 8KB cart) +.endif .byte BANKSWITCH_SUPPORT ; jmp nb65_dispatcher ; NB65_DISPATCH_VECTOR : entry point for NB65 functions jmp ip65_process ;NB65_PERIODIC_PROCESSING_VECTOR : routine to be periodically called to check for arrival of ethernet packets @@ -213,10 +220,19 @@ main_menu: bne @not_tftp jmp @tftp_boot @not_tftp: -.if !(BANKSWITCH_SUPPORT=$03) - cmp #KEYCODE_F3 - beq @exit_to_basic + + cmp #KEYCODE_F3 + .if (BANKSWITCH_SUPPORT=$03) + bne @not_f3 + jsr cls + lda #14 + jsr print_a ;switch to lower case + jsr prompt_for_gopher_resource ;only returns if no server was entered. + jmp exit_gopher + .else + beq @exit_to_basic .endif +@not_f3: cmp #KEYCODE_F5 bne @not_util_menu jsr print_main_menu @@ -515,7 +531,6 @@ cmp #KEYCODE_F7 exit_cart_via_ax: sta call_downloaded_prg+1 stx call_downloaded_prg+2 - jmp exit_cart print_errorcode: @@ -577,7 +592,13 @@ cfg_get_configuration_ptr: ldax #nb65_param_buffer nb65call #NB65_GET_IP_CONFIG rts - + +.if (BANKSWITCH_SUPPORT=$03) +exit_gopher: + lda #142 + jsr print_a ;switch to upper case + jmp main_menu +.endif .rodata netboot65_msg: diff --git a/client/test/Makefile b/client/test/Makefile index 150558a..b3dde21 100644 --- a/client/test/Makefile +++ b/client/test/Makefile @@ -42,7 +42,7 @@ all: \ test_tcp.prg: test_tcp.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg $(LD) -m test_tcp.map -vm -C ../cfg/c64prg.cfg -o test_tcp.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB) -gopher_browser.prg: gopher_browser.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg +gopher_browser.prg: gopher_browser.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg ../inc/gopher.i $(LD) -m gopher_browser.map -vm -C ../cfg/c64prg.cfg -o gopher_browser.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB) diff --git a/client/test/retro_gopher.txt b/client/test/retro_gopher.txt deleted file mode 100644 index 109117b..0000000 --- a/client/test/retro_gopher.txt +++ /dev/null @@ -1,16 +0,0 @@ -i WELCOME TO THE RETRONET GOPHER HOLE! error.host 1 -i error.host 1 -i _____ _____ _____ _____ _____ error.host 1 -i | __ | __|_ _| __ | | error.host 1 -i ,,, | -| __| | | | -| | | error.host 1 -i o^.^o |__|__|_____| |_| |__|__|_____| error.host 1 -i \"/ _____ _____ _____ _________ error.host 1 -i / ;; | | | __|_ _| / n___n \ error.host 1 -i~( )) | | | | __| | | ==/ (o) \== error.host 1 -i `L L |_|___|_____| |_| |_______| error.host 1 -i error.host 1 -1luddite /luddite/ retro-net.org 70 -1wgoodf /wgoodf/ retro-net.org 70 -1arfink /arfink/ retro-net.org 70 -1rsayers /rsayers/ retro-net.org 70 -. diff --git a/client/test/rob_gopher.txt b/client/test/rob_gopher.txt deleted file mode 100644 index 27ec906..0000000 --- a/client/test/rob_gopher.txt +++ /dev/null @@ -1,40 +0,0 @@ -igopher. error.host 1 -i ___ _ ___ error.host 1 -i| _ \ ___ | |__ / __| __ _ _ _ ___ _ _ ___ error.host 1 -i| / / _ \ | '_ \ \__ \ / _` | | || | / -_) | '_| (_-< error.host 1 -i|_|_\ \___/ |_.__/ |___/ \__,_| \_, | \___| |_| /__/ error.host 1 -i |__/ error.host 1 -i .com error.host 1 -i error.host 1 -iServer Info error.host 1 -0About this server /serverinfo.txt robsayers.com 7070 -7Search This Server (experiemental) /localsearch robsayers.com 70 -0Server Update /uptime.sh robsayers.com 70 -0Tail of server log /log.sh robsayers.com 70 -i error.host 1 -iPersonal error.host 1 -0About Me /aboutme.txt robsayers.com 70 -1Pics /pics robsayers.com 70 -0Latest Twitter Updates /twitter.txt robsayers.com 70 -0My GPG/PGP Public Key /pubkey.asc robsayers.com 70 -i error.host 1 -iGopher error.host 1 -0Why am I running gopher? /whygopher.txt robsayers.com 70 -1RedGopher - Ruby Gopher Client /redgopher robsayers.com 70 -0Search Engine Design Notes /searchengine.txt robsayers.com 70 -gXKCD Comic comic mentioning Gopher /not_enough_work.png robsayers.com 70 -1Links to other Gopher Sites /world gopher.floodgap.com 70 -i error.host 1 -iMisc. Geeky things error.host 1 -1My Tandy Model 100 /model100 robsayers.com 70 -0My Computers /computers.txt robsayers.com 70 -0Why Public Domain /why_public_domain.txt robsayers.com 70 -1Programs I have released /programs robsayers.com 70 -1Collection of Programming PDFs /documents robsayers.com 70 -12009 RetroChallenge /retrochallenge robsayers.com 70 -i error.host 1 -i error.host 1 -i error.host 1 -i error.host 1 -i error.host 1 -. diff --git a/doc/nb65_api_technical_reference.doc b/doc/nb65_api_technical_reference.doc index 5643bd9..fb757ed 100644 Binary files a/doc/nb65_api_technical_reference.doc and b/doc/nb65_api_technical_reference.doc differ