diff --git a/client/clients/Makefile b/client/clients/Makefile index 808ba9e..c267a8f 100644 --- a/client/clients/Makefile +++ b/client/clients/Makefile @@ -13,8 +13,9 @@ INCFILES=\ IP65LIB=../ip65/ip65.lib -C64NETLIB=../drivers/c64net.lib -APPLE2NETLIB=../drivers/apple2net.lib +C64PROGLIB=../drivers/c64prog.lib +C64NB65LIB=../drivers/c64nb65.lib +APPLE2PROGLIB=../drivers/apple2prog.lib BOOTA2.PG2=../../server/boot/BOOTA2.PG2 @@ -33,23 +34,23 @@ rrnetboot.o: rrnetboot.s $(INCFILES) %.o: %.s $(INCFILES) $(AS) $(AFLAGS) $< -rrnetboot.bin: rrnetboot.o $(IP65LIB) $(C64NETLIB) $(INCFILES) ../cfg/rrbin.cfg - $(LD) -m rrnetboot.map -vm -C ../cfg/rrbin.cfg -o rrnetboot.bin $< $(IP65LIB) $(C64NETLIB) +rrnetboot.bin: rrnetboot.o $(IP65LIB) $(C64NB65LIB) $(INCFILES) ../cfg/rrbin.cfg + $(LD) -m rrnetboot.map -vm -C ../cfg/rrbin.cfg -o rrnetboot.bin $< $(IP65LIB) $(C64NB65LIB) ruby fix_cart.rb rrnetboot.bin 8193 -64nicboot.bin: 64nicboot.o $(IP65LIB) $(C64NETLIB) $(INCFILES) ../cfg/rrbin.cfg - $(LD) -C ../cfg/rrbin.cfg -o 64nicboot.bin $< $(IP65LIB) $(C64NETLIB) +64nicboot.bin: 64nicboot.o $(IP65LIB) $(C64NB65LIB) $(INCFILES) ../cfg/rrbin.cfg + $(LD) -C ../cfg/rrbin.cfg -o 64nicboot.bin $< $(IP65LIB) $(C64NB65LIB) ruby fix_cart.rb 64nicboot.bin 8192 -utherboot.pg2: utherboot.o $(IP65LIB) $(APPLE2NETLIB) $(INCFILES) ../cfg/a2language_card.cfg - $(LD) -m utherboot.map -C ../cfg/a2language_card.cfg -o utherboot.pg2 $< $(IP65LIB) $(APPLE2NETLIB) +utherboot.pg2: utherboot.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2language_card.cfg + $(LD) -m utherboot.map -C ../cfg/a2language_card.cfg -o utherboot.pg2 $< $(IP65LIB) $(APPLE2PROGLIB) utherboot.dsk: utherboot.pg2 ripxplore.rb --init AppleDos utherboot.dsk -a utherboot.pg2 -t AppleBinary ripxplore.rb utherboot.dsk -a hello -t Applesoft -$(BOOTA2.PG2): bootmenu.o $(IP65LIB) $(APPLE2NETLIB) $(INCFILES) ../cfg/a2language_card.cfg - $(LD) -m bootmenu.map -C ../cfg/a2language_card.cfg -o $(BOOTA2.PG2) $< $(IP65LIB) $(APPLE2NETLIB) +$(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) clean: rm -f *.o diff --git a/client/clients/rrnetboot.s b/client/clients/rrnetboot.s index ea907aa..5dfef02 100644 --- a/client/clients/rrnetboot.s +++ b/client/clients/rrnetboot.s @@ -45,7 +45,6 @@ .include "../inc/c64keycodes.i" .import cls - .import get_key .import beep .import exit_to_basic .import timer_vbl_handler @@ -54,7 +53,8 @@ .import get_filtered_input .import filter_text .import filter_dns - + .import print_arp_cache + .import print_dotted_quad .import print_hex .import print_ip_config @@ -169,7 +169,7 @@ main_menu: jsr print jsr print_ip_config jsr print_cr - + @get_key: jsr get_key cmp #KEYCODE_F1 @@ -178,6 +178,8 @@ main_menu: @not_tftp: cmp #KEYCODE_F3 beq @exit_to_basic + cmp #KEYCODE_F5 + beq @util_menu cmp #KEYCODE_F7 beq @change_config @@ -188,6 +190,24 @@ main_menu: ldax #$fe66 ;do a wam start jmp exit_cart_via_ax +@util_menu: + jsr cls + ldax #netboot65_msg + jsr print + ldax #util_menu_msg + jsr print +@get_key_util_menu: + jsr get_key + cmp #KEYCODE_F1 + bne @not_arp_cache + 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 ldax #netboot65_msg @@ -262,7 +282,10 @@ main_menu: ldax #tftp_dir_buffer jsr select_option_from_menu - + bcc @tftp_filename_set + lda #21 ;switch back to upper case + sta $d018 + jmp main_menu @tftp_filename_set: jsr download bcc @file_downloaded_ok @@ -352,7 +375,8 @@ download: ;AX should point at filename to download jsr setup_param_buffer_for_tftp_call ldax #nb65_param_buffer - nb65call #NB65_TFTP_DOWNLOAD + nb65call #NB65_TFTP_DOWNLOAD + bcc :+ ldax #tftp_download_fail_msg @@ -370,9 +394,19 @@ download: ;AX should point at filename to download wait_for_keypress: ldax #press_a_key_to_continue jsr print - jsr get_key +@loop: + jsr $ffe4 + beq @loop rts +get_key: +@loop: + jsr NB65_PERIODIC_PROCESSING_VECTOR + jsr $ffe4 + beq @loop + rts + + cfg_get_configuration_ptr: ldax #nb65_param_buffer nb65call #NB65_GET_IP_CONFIG @@ -385,7 +419,12 @@ netboot65_msg: .byte 0 main_menu_msg: .byte "F1: TFTP BOOT F3: BASIC",13 -.byte "F7: CONFIG",13,13 +.byte "F5: UTILITIES F7: CONFIG",13,13 +.byte 0 + +util_menu_msg: +.byte "F1: ARP TABLE",13 +.byte " F7: MAIN MENU",13,13 .byte 0 config_menu_msg: diff --git a/client/drivers/Makefile b/client/drivers/Makefile index d6bebf6..d4eded6 100644 --- a/client/drivers/Makefile +++ b/client/drivers/Makefile @@ -11,22 +11,25 @@ AFLAGS= DRIVERS=\ - apple2net.lib \ - c64net.lib \ + apple2prog.lib \ + c64prog.lib \ + c64nb65.lib \ all: $(DRIVERS) -apple2net.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o - ar65 a apple2net.lib $^ +apple2prog.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o + ar65 a $@ $^ -c64net.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o - ar65 a c64net.lib $^ +c64prog.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o + ar65 a $@ $^ + +c64nb65.lib: c64print.o rr-net.o c64timer_nb65.o c64kernal.o c64inputs.o + ar65 a $@ $^ clean: rm -f *.o - rm -f apple2net.lib - rm -f c64net.lib + rm -f *.lib distclean: clean rm -f *~ diff --git a/client/drivers/c64timer.s b/client/drivers/c64timer.s index f13adcb..1304de6 100644 --- a/client/drivers/c64timer.s +++ b/client/drivers/c64timer.s @@ -2,46 +2,43 @@ ; ; the timer should be a 16-bit counter that's incremented by about ; 1000 units per second. it doesn't have to be particularly accurate. -; this C64 implementation requires the routine timer_vbl_handler be called 60 times per second .include "../inc/common.i" .export timer_init .export timer_read - .export timer_vbl_handler .code - .bss - current_time_value: .res 2 - .code - -;reset timer to 0 -;inputs: none -;outputs: none +; initialize timers timer_init: - ldax #0 - stax current_time_value + lda #$80 ; stop timers + sta $dd0e + sta $dd0f + + ldax #999 ; timer A to 1000 cycles + stax $dd04 + + ldax #$ffff ; timer B to max cycles + stax $dd06 + + lda #$81 ; timer A in continuous mode + sta $dd0e + + lda #$c1 ; timer B to count timer A underflows + sta $dd0f + + rts + + +; return the current value +timer_read: + lda $dd07 ; cia counts backwards, return inverted value + eor #$ff + tax + lda $dd06 + eor #$ff rts -;read the current timer value -; inputs: none -; outputs: AX = current timer value (roughly equal to number of milliseconds since the last call to 'timer_init') -timer_read: - ldax current_time_value - rts -; tick over the current timer value - should be called 60 times per second -; inputs: none -; outputs: none (all registers preserved, by carry flag can be modified) -timer_vbl_handler: - pha - lda #$11 - adc current_time_value - sta current_time_value - bcc :+ - inc current_time_value+1 -: - pla - rts \ No newline at end of file diff --git a/client/drivers/c64timer_nb65.s b/client/drivers/c64timer_nb65.s new file mode 100644 index 0000000..5f721e9 --- /dev/null +++ b/client/drivers/c64timer_nb65.s @@ -0,0 +1,50 @@ +; timer routines +; +; the timer should be a 16-bit counter that's incremented by about +; 1000 units per second. it doesn't have to be particularly accurate. +; this C64 implementation requires the routine timer_vbl_handler be called 60 times per second +; this is for use in the NB65 ROM, where we also install an IRQ handler +; for normal userland programs where it is known what else is going on with the timer , +; use "c64timer.s" routines instead + + .include "../inc/common.i" + + + .export timer_init + .export timer_read + .export timer_vbl_handler + + + .bss + current_time_value: .res 2 + + .code + +;reset timer to 0 +;inputs: none +;outputs: none +timer_init: + ldax #0 + stax current_time_value + rts + +;read the current timer value +; inputs: none +; outputs: AX = current timer value (roughly equal to number of milliseconds since the last call to 'timer_init') +timer_read: + ldax current_time_value + rts + +; tick over the current timer value - should be called 60 times per second +; inputs: none +; outputs: none (all registers preserved, by carry flag can be modified) +timer_vbl_handler: + pha + lda #$11 + adc current_time_value + sta current_time_value + bcc :+ + inc current_time_value+1 +: + pla + rts \ No newline at end of file diff --git a/client/inc/commonprint.i b/client/inc/commonprint.i index 3573f43..fa9c2aa 100644 --- a/client/inc/commonprint.i +++ b/client/inc/commonprint.i @@ -12,15 +12,20 @@ .export print .export print_decimal .export print_dotted_quad + .export print_arp_cache + .import arp_cache + .importzp ac_size + .import cs_driver_name .importzp copy_src .import cfg_tftp_server ;reuse the copy_src zero page var pptr = copy_src + .bss temp_bin: .res 1 temp_bcd: .res 2 - +temp_ptr: .res 2 .code .macro print_driver_init ldax #cs_driver_name @@ -68,23 +73,7 @@ print_ip_config: jsr print jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear ;first 6 bytes of cfg_get_configuration_ptr is MAC address - stax pptr - ldy #0 -@one_mac_digit: - tya ;just to set the Z flag - pha - beq @dont_print_colon - lda #':' - jsr print_a -@dont_print_colon: - pla - tay - lda (pptr),y - jsr print_hex - iny - cpy #06 - bne @one_mac_digit - + jsr print_mac jsr print_cr ldax #ip_address_msg @@ -144,6 +133,7 @@ print_ip_config: rts + print: sta pptr stx pptr + 1 @@ -160,6 +150,51 @@ print: @done_print: rts +print_arp_cache: + ldax #arp_cache_header + jsr print + ldax #arp_cache + stax temp_ptr + lda #ac_size +@print_one_arp_entry: + pha + lda #'$' + jsr print_a + lda temp_ptr+1 + jsr print_hex + lda temp_ptr + jsr print_hex + lda #' ' + jsr print_a + + ldax temp_ptr + jsr print_mac + lda #' ' + jsr print_a + ldax temp_ptr + clc + adc #6 + bcc :+ + inx +: + stax temp_ptr + jsr print_dotted_quad + ldax temp_ptr + clc + adc #4 + bcc :+ + inx +: + stax temp_ptr + jsr print_cr + pla + sec + sbc #1 + + bne @print_one_arp_entry + clc + rts + ;print the 4 bytes pointed at by AX as dotted decimals print_dotted_quad: @@ -188,7 +223,26 @@ print_dotted_quad: jsr print_decimal rts - + +;print 6 bytes printed at by AX as a MAC address +print_mac: + stax pptr + ldy #0 +@one_mac_digit: + tya ;just to set the Z flag + pha + beq @dont_print_colon + lda #':' + jsr print_a +@dont_print_colon: + pla + tay + lda (pptr),y + jsr print_hex + iny + cpy #06 + bne @one_mac_digit + rts print_decimal: ;print byte in A as a decimal number pha sta temp_bin ;save @@ -294,6 +348,9 @@ dhcp_msg: init_msg: .byte " INITIALIZING ",0 +arp_cache_header: + .byte " MEM MAC IP",13,0 + failed_msg: .byte "FAILED", 0 diff --git a/client/inc/menu.i b/client/inc/menu.i index 0b25367..bce2620 100644 --- a/client/inc/menu.i +++ b/client/inc/menu.i @@ -23,6 +23,7 @@ get_current_byte: .res 4 ;on entry, AX should point to the list of null terminated option strings to be selected from ;on exit, AX points to the selected string +;carry is set of QUIT was selected, clear otherwise select_option_from_menu: stax options_table_pointer @@ -261,6 +262,9 @@ select_option_from_menu: sec sbc #$e1 bcc @get_keypress ;if we have underflowed, it wasn't a valid option + cmp #$10 ;Q + beq @quit + cmp #OPTIONS_PER_PAGE-1 beq @got_valid_option bpl @get_keypress ;if we have underflowed, it wasn't a valid option @@ -277,10 +281,13 @@ select_option_from_menu: jsr @move_to_current_option ldax get_current_byte+1 - + clc rts - +@quit: + sec + rts + @forward_one_page: clc lda last_page_flag @@ -322,6 +329,6 @@ select_option_from_menu: .rodata select_from_following_options: .byte "SELECT ONE OF THE FOLLOWING OPTIONS:",13,0 navigation_instructions: .byte 13,"ARROW KEYS NAVIGATE BETWEEN MENU PAGES",13 -.byte "/ TO JUMP ",13 +.byte "/ TO JUMP or Q to QUIT",13 .byte 0 jump_to_prompt: .byte "JUMP TO:",0 diff --git a/client/ip65/arp.s b/client/ip65/arp.s index 36dbe79..926a367 100644 --- a/client/ip65/arp.s +++ b/client/ip65/arp.s @@ -6,11 +6,12 @@ .export arp_lookup .export arp_process .export arp_add - + .export arp_calculate_gateway_mask .export arp_ip .export arp_mac .export arp_cache - + .exportzp ac_size + .import eth_inp .import eth_inp_len .import eth_outp @@ -20,7 +21,7 @@ .import eth_set_my_mac_src .import eth_set_proto .importzp eth_proto_arp - + .import cfg_mac .import cfg_ip .import cfg_netmask @@ -28,8 +29,7 @@ .import timer_read .import timer_timeout - - + .segment "IP65ZP" : zeropage ap: .res 2 @@ -82,9 +82,12 @@ arp_init: lda #0 ldx #(6+4)*ac_size - 1 ; clear cache -: sta arp_cache,x +: + sta arp_cache,x dex bpl :- + +arp_calculate_gateway_mask: lda #$ff ; counter for netmask length - 1 sta gw_last @@ -221,10 +224,10 @@ arp_lookup: ; find arp_ip in the cache ; clc returns pointer to entry in (ap) -findip: - ldax #arp_cache - stax ap +findip: + ldax #arp_cache + stax ap ldx #ac_size @compare: ; compare cache entry ldy #ac_ip @@ -237,7 +240,7 @@ findip: cpy #ac_ip + 4 bne :- - clc ; return + clc ; return rts @next: ; next entry @@ -335,7 +338,7 @@ arp_process: lda #arp_idle sta arp_state - + rts @@ -353,7 +356,8 @@ arp_add: : lda arp,y ; move to top as well? sta (ap),y dey - bpl :- + bpl :- + rts @add: @@ -364,25 +368,22 @@ arp_add: ac_add_source: stax ap - ldx #9 ; make space in the arp cache : - - lda arp_cache + 60,x + lda arp_cache + 60,x sta arp_cache + 70,x - lda arp_cache + 50,x + lda arp_cache + 50,x sta arp_cache + 60,x lda arp_cache + 40,x sta arp_cache + 50,x - lda arp_cache + 30,x sta arp_cache + 40,x lda arp_cache + 20,x sta arp_cache + 30,x lda arp_cache + 10,x sta arp_cache + 20,x - lda arp_cache,x + lda arp_cache,x sta arp_cache + 10,x dex diff --git a/client/ip65/dhcp.s b/client/ip65/dhcp.s index ab90938..b7887ae 100644 --- a/client/ip65/dhcp.s +++ b/client/ip65/dhcp.s @@ -26,7 +26,7 @@ MAX_DHCP_MESSAGES_SENT=12 ;timeout after sending 12 messages will be about 1 .import cfg_gateway .import cfg_dns - .import arp_init + .import arp_calculate_gateway_mask .import ip65_process @@ -407,7 +407,7 @@ dhcp_in: @finished_unpacking_dhcp_options: - jsr arp_init ;we have modified our netmask, so we need to recalculate gw_test + jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test lda dhcp_state cmp #dhcp_bound beq :+ @@ -461,6 +461,7 @@ send_dhcprequest: jsr udp_send bcs :+ ;if we didn't send the message we probably need to wait for an ARP reply to come back. lda #dhcp_bound ;technically, we should wait till we get a DHCPACK message. but we'll assume success - sta dhcp_state + sta dhcp_state + rts : rts diff --git a/client/test/Makefile b/client/test/Makefile index df42ff4..dffa7f4 100644 --- a/client/test/Makefile +++ b/client/test/Makefile @@ -6,8 +6,10 @@ AFLAGS= IP65LIB=../ip65/ip65.lib -C64NETLIB=../drivers/c64net.lib -APPLE2NETLIB=../drivers/apple2net.lib + +C64PROGLIB=../drivers/c64prog.lib +C64PNB65LIB=../drivers/c64nb65.lib +APPLE2PROGLIB=../drivers/apple2prog.lib INCFILES=\ ../inc/common.i\ @@ -21,10 +23,10 @@ INCFILES=\ $(AS) $(AFLAGS) $< %.prg: %.o $(IP65LIB) $(C64NETLIB) $(INCFILES) ../cfg/c64prg.cfg - $(LD) -m $*.map -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64NETLIB) + $(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64PROGLIB) %.pg2: %.o $(IP65LIB) $(APPLE2NETLIB) $(INCFILES) ../cfg/a2bin.cfg - $(LD) -m $*.map -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2NETLIB) + $(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2PROGLIB) ip65test.dsk: testdns.pg2 testdottedquad.pg2 ripxplore.rb --init BeautifulBoot ip65test.dsk -a testdns.pg2 -t AppleBinary diff --git a/client/test/testdns.s b/client/test/testdns.s index 36554b4..42195d5 100644 --- a/client/test/testdns.s +++ b/client/test/testdns.s @@ -9,7 +9,8 @@ .import dns_ip .import dns_status .import cfg_get_configuration_ptr - + + .import __CODE_LOAD__ .import __CODE_SIZE__ .import __RODATA_SIZE__ @@ -43,9 +44,9 @@ init: jsr print_cr jsr print_ip_config - + jsr print_arp_cache init_ip_via_dhcp - + jsr print_arp_cache ; jsr overwrite_with_hardcoded_dns_server jsr print_ip_config