diff --git a/client/carts/Makefile b/client/carts/Makefile index 7f423ef..888683c 100644 --- a/client/carts/Makefile +++ b/client/carts/Makefile @@ -11,7 +11,6 @@ INCFILES=\ ../inc/kipper_constants.i\ ../inc/version.i\ -TCP_INCFILES=../inc/gopher.i ../inc/telnet.i ../inc/ping.i IP65LIB=../ip65/ip65.lib IP65TCPLIB=../ip65/ip65_tcp.lib @@ -19,9 +18,12 @@ IP65TCPLIB=../ip65/ip65_tcp.lib C64PROGLIB=../drivers/c64prog.lib C64NB65LIB=../drivers/c64nb65.lib -all: kipperkart.bin kipperkart_rr.bin netboot.bin +all: kipperkart.bin kipperkart_rr.bin netboot.bin kipperterm.bin -kipperkart.o: kipperkart.s $(INCFILES) $(TCP_INCFILES) +kipperkart.o: kipperkart.s $(INCFILES) ../inc/ping.i ../inc/disk_transfer.i ../inc/sidplay.i + $(AS) $(AFLAGS) -o $@ $< + +kipperterm.o: kipperterm.s $(INCFILES) ../inc/gopher.i ../inc/telnet.i $(AS) $(AFLAGS) -o $@ $< %.o: %.s $(INCFILES) @@ -38,7 +40,12 @@ kipperkart.bin: kipperkart.o $(IP65TCPLIB) $(C64NB65LIB) $(INCFILES) ../cfg/c64_ $(LD) -m kipperkart.map -vm -C ../cfg/c64_16kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64NB65LIB) ruby fix_cart.rb $@ 16384 ruby dupe_cart.rb kipperkart.bin kipperkart_29c040.bin 32 - + +kipperterm.bin: kipperterm.o $(IP65TCPLIB) $(C64NB65LIB) $(INCFILES) ../cfg/c64_16kcart.cfg + $(LD) -m kipperterm.map -vm -C ../cfg/c64_16kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64NB65LIB) + ruby fix_cart.rb $@ 16384 + ruby dupe_cart.rb kipperterm.bin kipperterm_29c040.bin 32 + kipperkart_rr.bin: kipperkart.bin cp crt8040.obj rrnet_header.bin cat rrnet_header.bin kipperkart.bin > kipperkart_rr.bin diff --git a/client/carts/kipperkart.s b/client/carts/kipperkart.s index a8522bc..da7dbab 100644 --- a/client/carts/kipperkart.s +++ b/client/carts/kipperkart.s @@ -33,10 +33,10 @@ KEY_BACK_IN_HISTORY=KEYCODE_F3 KEY_NEW_SERVER=KEYCODE_F5 - - .include "../inc/gopher.i" - .include "../inc/telnet.i" .include "../inc/ping.i" + .include "../inc/sidplay.i" + + .include "../inc/disk_transfer.i" .import cls .import beep @@ -49,7 +49,6 @@ .import filter_text .import filter_dns .import filter_ip - .import print_arp_cache .import arp_calculate_gateway_mask .import parse_dotted_quad .import dotted_quad_value @@ -95,7 +94,10 @@ kipper_param_buffer = $6000 directory_buffer = $6020 - .data + +.bss +temp_ptr: .res 2 +.segment "SELF_MODIFIED_CODE" call_downloaded_prg: jsr $0000 ;overwritten when we load a file @@ -204,29 +206,40 @@ main_menu: @get_key: jsr get_key_ip65 cmp #KEYCODE_F1 - bne @not_tftp + bne @not_f1 jmp @tftp_boot - @not_tftp: + @not_f1: cmp #KEYCODE_F2 - bne @not_disk + bne @not_f2 jmp disk_boot - @not_disk: + @not_f2: cmp #KEYCODE_F3 bne @not_f3 - jmp net_apps_menu + .byte $92 ; fixme @not_f3: cmp #KEYCODE_F4 - bne @not_download_d64 + bne @not_f4 jmp d64_download -@not_download_d64: +@not_f4: cmp #KEYCODE_F5 - bne @not_util_menu - jsr print_main_menu - jsr print_arp_cache - jmp @get_key -@not_util_menu: + bne @not_f5 + jmp netplay_sid +@not_f5: + + cmp #KEYCODE_F6 + bne @not_f6 + jsr cls + lda #14 + jsr print_a ;switch to lower case + ldax #ping_header + jsr print + jsr ping_loop + jmp exit_ping + +@not_f6: + cmp #KEYCODE_F7 beq @change_config @@ -415,7 +428,7 @@ cmp #KEYCODE_F7 tftp_boot_failed: jsr wait_for_keypress return_to_main: - jmp main_menu + jmp error_handler file_downloaded_ok: ldax kipper_param_buffer+KPR_TFTP_POINTER @@ -457,6 +470,8 @@ exit_cart_via_ax: jmp call_downloaded_prg get_tftp_directory_listing: + stax temp_ptr +@get_listing: stax kipper_param_buffer+KPR_TFTP_FILENAME ldax #directory_buffer @@ -504,33 +519,34 @@ get_tftp_directory_listing: bne @look_for_trailing_zero ; got trailing zero - ldax #tftp_dir_filemask+1 ;skip the leading '$' + ldax temp_ptr + clc + adc #1 ;skip the leading '$' + bcc :+ + inx +: stax copy_src ldax #$07 jsr copymem ldax get_value_of_axy+1 - jmp get_tftp_directory_listing + jmp @get_listing @not_directory_name: ldax get_value_of_axy+1 clc rts - @dir_failed: ldax #dir_listing_fail_msg jsr print - jsr print_errorcode - jsr print_cr - - ldax #tftp_file - jmp @tftp_filename_set - + sec + rts + @no_files_on_server: ldax #no_files jsr print - - jmp tftp_boot_failed + sec + rts disk_boot: .import io_read_catalogue @@ -550,8 +566,6 @@ disk_boot: : ;switch to lower case charset -; lda #23 -; sta $d018 ldax #directory_buffer @@ -593,6 +607,41 @@ disk_boot: ldax io_load_address jmp boot_into_file +error_handler: + jsr print_errorcode + jsr print_cr + jsr wait_for_keypress + jmp main_menu + +netplay_sid: + + ldax #sid_filemask + jsr get_tftp_directory_listing + bcc @sid_filename_set + jmp error_handler +@sid_filename_set: + ;AX now points to filename + stax kipper_param_buffer+KPR_TFTP_FILENAME + ldax #$1000 ;load address + stax kipper_param_buffer+KPR_TFTP_POINTER + jsr download2 + + + bcc :+ + jmp error_handler +: + + jsr cls + ldax kipper_param_buffer+KPR_TFTP_FILESIZE + stax sidfile_length + ldax kipper_param_buffer+KPR_TFTP_POINTER + jsr load_sid + jsr play_sid + + + jmp main_menu + + d64_download: ldax #d64_filemask @@ -601,73 +650,10 @@ d64_download: jmp main_menu @d64_filename_set: ;AX now points to filename - .byte $92 + jsr download_d64 jmp main_menu -net_apps_menu: - jsr cls - ldax #netboot65_msg - jsr print - ldax #net_apps_menu_msg - jsr print -@get_key: - jsr get_key_ip65 - cmp #KEYCODE_ABORT - bne @not_abort - jmp main_menu -@not_abort: - cmp #KEYCODE_F1 - bne @not_telnet - jsr cls - lda #14 - jsr print_a ;switch to lower case - ldax #telnet_header - jsr print - jmp telnet_main_entry -@not_telnet: - cmp #KEYCODE_F2 - bne @not_gopher - jsr cls - lda #14 - jsr print_a ;switch to lower case - ldax #gopher_header - jsr print - jsr prompt_for_gopher_resource ;only returns if no server was entered. - jmp exit_gopher -@not_gopher: - - cmp #KEYCODE_F3 - bne @not_gopher_floodgap_com - jsr cls - lda #14 - jsr print_a ;switch to lower case - - ldax #gopher_initial_location - sta resource_pointer_lo - stx resource_pointer_hi - ldx #0 - jsr select_resource_from_current_directory - jmp exit_gopher -@not_gopher_floodgap_com: - - cmp #KEYCODE_F5 - bne @not_ping - jsr cls - lda #14 - jsr print_a ;switch to lower case - ldax #ping_header - jsr print - jsr ping_loop - jmp exit_ping -@not_ping: - - cmp #KEYCODE_F7 - bne @not_main - jmp main_menu -@not_main: - jmp @get_key - bad_boot: @@ -679,10 +665,11 @@ download: ;AX should point at filename to download ldax #$0000 ;load address will be first 2 bytes of file we download (LO/HI order) stax kipper_param_buffer+KPR_TFTP_POINTER +download2: ldax #downloading_msg jsr print ldax kipper_param_buffer+KPR_TFTP_FILENAME - jsr print + jsr print_ascii_as_native jsr print_cr ldax #kipper_param_buffer @@ -724,24 +711,23 @@ cfg_get_configuration_ptr: rts exit_ping: -exit_telnet: -exit_gopher: lda #142 jsr print_a ;switch to upper case lda #$05 ;petscii for white text jsr print_a - jmp net_apps_menu + jmp main_menu .rodata netboot65_msg: -.byte 13,"KIPPERNET V" +.byte 13,"KIPPERKART V" .include "../inc/version.i" .byte 13,0 main_menu_msg: .byte 13,"MAIN MENU",13,13 .byte "F1: TFTP BOOT F2: DISK BOOT",13 -.byte "F3: NET APPS F4: DOWNLOAD D64",13 -.byte "F5: ARP TABLE F7: CONFIG",13,13 +.byte "F3: UPLOAD D64 F4: DOWNLOAD D64",13 +.byte "F5: SID NETPLAY F6: PING",13 +.byte "F7: CONFIG",13,13 .byte 0 @@ -753,22 +739,10 @@ config_menu_msg: .byte "F7: MAIN MENU",13,13 .byte 0 - -net_apps_menu_msg: -.byte 13,"NET APPS",13,13 -.byte "F1: TELNET F2: GOPHER ",13 -.byte "F3: GOPHER (FLOODGAP.COM)",13 -.byte "F5: PING F7: MAIN MENU",13,13 -.byte 0 - cant_boot_basic: .byte "BASIC FILE EXECUTION NOT SUPPORTED",13,0 -gopher_initial_location: -.byte "1gopher.floodgap.com",$09,"/",$09,"gopher.floodgap.com",$09,"70",$0D,$0A,0 ping_header: .byte "ping",13,0 -gopher_header: .byte "gopher",13,0 -telnet_header: .byte "telnet",13,0 file_read_error: .asciiz "ERROR READING FILE" autoexec_filename: .byte "AUTOEXEC.PRG",0 @@ -801,8 +775,8 @@ tftp_dir_filemask: d64_filemask: .asciiz "$/*.d64" -tftp_file: - .asciiz "BOOTC64.PRG" +sid_filemask: + .asciiz "$/*.sid" no_files: .byte "NO FILES",13,0 @@ -810,3 +784,4 @@ no_files: resolving: .byte "RESOLVING ",0 +remote_host: .byte "HOSTNAME (LEAVE BLANK TO QUIT)",13,": ",0 diff --git a/client/carts/kipperterm.s b/client/carts/kipperterm.s new file mode 100644 index 0000000..b6abd96 --- /dev/null +++ b/client/carts/kipperterm.s @@ -0,0 +1,455 @@ +; ############# +; KIPPER TERM - Telnet/Gopher client for C64 +; jonno@jamtronix.com + + .macro print_failed + ldax #failed_msg + jsr print + jsr print_cr + .endmacro + + .macro print_ok + ldax #ok_msg + jsr print + jsr print_cr + .endmacro + + .macro kippercall arg + ldy arg + jsr KPR_DISPATCH_VECTOR + .endmacro + +.ifndef KPR_API_VERSION_NUMBER + .define EQU = + .include "../inc/kipper_constants.i" +.endif + .include "../inc/common.i" + .include "../inc/c64keycodes.i" + .include "../inc/menu.i" + + KEY_NEXT_PAGE=KEYCODE_F7 + KEY_PREV_PAGE=KEYCODE_F1 + KEY_SHOW_HISTORY=KEYCODE_F2 + KEY_BACK_IN_HISTORY=KEYCODE_F3 + KEY_NEW_SERVER=KEYCODE_F5 + + + .include "../inc/gopher.i" + .include "../inc/telnet.i" + + .import cls + .import beep + .import exit_to_basic + .import timer_vbl_handler + .import kipper_dispatcher + .import ip65_process + .import ip65_init + .import get_filtered_input + .import filter_text + .import filter_dns + .import filter_ip + .import arp_calculate_gateway_mask + .import parse_dotted_quad + .import dotted_quad_value + .import parse_integer + .import print_integer + .import get_key_ip65 + .import cfg_ip + .import cfg_netmask + .import cfg_gateway + .import cfg_dns + .import cfg_tftp_server + + .import print_ascii_as_native + .import print_dotted_quad + .import print_hex + .import print_errorcode + .import print_ip_config + .import ok_msg + .import failed_msg + .import init_msg + .import ip_address_msg + .import netmask_msg + .import gateway_msg + .import dns_server_msg + .import tftp_server_msg + .import press_a_key_to_continue + + .import print_a + .import print_cr + .import print + .import copymem + .importzp copy_src + .importzp copy_dest + .import get_filtered_input + .import __DATA_LOAD__ + .import __DATA_RUN__ + .import __DATA_SIZE__ + .import __SELF_MODIFIED_CODE_LOAD__ + .import __SELF_MODIFIED_CODE_RUN__ + .import __SELF_MODIFIED_CODE_SIZE__ + + .import cfg_tftp_server + kipper_param_buffer = $6000 + directory_buffer = $6020 + + +.bss +temp_ptr: .res 2 +.segment "SELF_MODIFIED_CODE" + + +.segment "CARTRIDGE_HEADER" +.word init ;cold start vector +.word $FE47 ;warm start vector +.byte $C3,$C2,$CD,$38,$30 ; "CBM80" +.byte "KIPPER" ; API signature +jmp kipper_dispatcher ; KPR_DISPATCH_VECTOR : entry point for KIPPER functions +jmp ip65_process ;KPR_PERIODIC_PROCESSING_VECTOR : routine to be periodically called to check for arrival of ethernet packets +jmp timer_vbl_handler ;KPR_VBL_VECTOR : routine to be called during each vertical blank interrupt + +.code + + + +init: + + ;first let the kernal do a normal startup + sei + jsr $fda3 ;initialize CIA I/O + jsr $fd50 ;RAM test, set pointers + jsr $fd15 ;set vectors for KERNAL + jsr $ff5B ;init. VIC + cli ;KERNAL init. finished + + ;set some funky colours + + LDA #$04 ;purple + + STA $D020 ;border + LDA #$00 ;black + STA $D021 ;background + lda #$05 ;petscii for white text + jsr print_a + +;relocate our r/w data + ldax #__DATA_LOAD__ + stax copy_src + ldax #__DATA_RUN__ + stax copy_dest + ldax #__DATA_SIZE__ + jsr copymem + + +;relocate the self-modifying code (if necessary) + ldax #__SELF_MODIFIED_CODE_LOAD__ + stax copy_src + ldax #__SELF_MODIFIED_CODE_RUN__ + stax copy_dest + ldax #__SELF_MODIFIED_CODE_SIZE__ + jsr copymem + + ldax #netboot65_msg + jsr print + ldax #init_msg+1 + jsr print + + kippercall #KPR_INITIALIZE + bcc init_ok + print_failed + jsr print_errorcode + jsr wait_for_keypress + jmp exit_to_basic + +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 + jmp print + +init_ok: + +main_menu: + jsr print_main_menu + jsr print_ip_config + jsr print_cr + +@get_key: + jsr get_key_ip65 + cmp #KEYCODE_F1 + bne @not_f1 + jsr cls + lda #14 + jsr print_a ;switch to lower case + ldax #telnet_header + jsr print + jmp telnet_main_entry + + @not_f1: + cmp #KEYCODE_F3 + bne @not_f3 + jsr cls + lda #14 + jsr print_a ;switch to lower case + ldax #gopher_header + jsr print + jsr prompt_for_gopher_resource ;only returns if no server was entered. + jmp exit_gopher + @not_f3: + + cmp #KEYCODE_F5 + bne @not_f5 + jsr cls + lda #14 + jsr print_a ;switch to lower case + + ldax #gopher_initial_location + sta resource_pointer_lo + stx resource_pointer_hi + ldx #0 + jsr select_resource_from_current_directory + jmp exit_gopher +@not_f5: + + cmp #KEYCODE_F7 + beq @change_config + + jmp @get_key + +@change_config: + jsr cls + ldax #netboot65_msg + jsr print + ldax #config_menu_msg + jsr print + jsr print_ip_config + jsr print_cr +@get_key_config_menu: + jsr get_key_ip65 + cmp #KEYCODE_ABORT + bne @not_abort + jmp main_menu +@not_abort: + cmp #KEYCODE_F1 + bne @not_ip + ldax #new + jsr print + ldax #ip_address_msg + jsr print + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_ip_address_entered + jsr parse_dotted_quad + bcc @no_ip_resolve_error + jmp @change_config +@no_ip_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_ip + stax copy_dest + ldax #4 + jsr copymem +@no_ip_address_entered: + jmp @change_config + +@not_ip: + cmp #KEYCODE_F2 + bne @not_netmask + ldax #new + jsr print + ldax #netmask_msg + jsr print + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_netmask_entered + jsr parse_dotted_quad + bcc @no_netmask_resolve_error + jmp @change_config +@no_netmask_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_netmask + stax copy_dest + ldax #4 + jsr copymem +@no_netmask_entered: + jmp @change_config + +@not_netmask: + cmp #KEYCODE_F3 + bne @not_gateway + ldax #new + jsr print + ldax #gateway_msg + jsr print + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_gateway_entered + jsr parse_dotted_quad + bcc @no_gateway_resolve_error + jmp @change_config +@no_gateway_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_gateway + stax copy_dest + ldax #4 + jsr copymem + jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test +@no_gateway_entered: + jmp @change_config + + +@not_gateway: + cmp #KEYCODE_F4 + bne @not_dns_server + ldax #new + jsr print + ldax #dns_server_msg + jsr print + jsr print_cr + ldax #filter_ip + ldy #20 + jsr get_filtered_input + bcs @no_dns_server_entered + jsr parse_dotted_quad + bcc @no_dns_resolve_error + jmp @change_config +@no_dns_resolve_error: + ldax #dotted_quad_value + stax copy_src + ldax #cfg_dns + stax copy_dest + ldax #4 + jsr copymem +@no_dns_server_entered: + + jmp @change_config + +@not_dns_server: + cmp #KEYCODE_F5 + bne @not_tftp_server + ldax #new + jsr print + ldax #tftp_server_msg + jsr print + jsr print_cr + ldax #filter_dns + ldy #40 + jsr get_filtered_input + bcs @no_server_entered + stax kipper_param_buffer + jsr print_cr + ldax #resolving + jsr print + ldax #kipper_param_buffer + kippercall #KPR_DNS_RESOLVE + bcs @resolve_error + ldax #kipper_param_buffer + stax copy_src + ldax #cfg_tftp_server + stax copy_dest + ldax #4 + jsr copymem +@no_server_entered: + jmp @change_config + +@not_tftp_server: + + +cmp #KEYCODE_F6 + bne @not_reset + jsr ip65_init ;this will reset everything + jmp @change_config +@not_reset: +cmp #KEYCODE_F7 + bne @not_main_menu + jmp main_menu + +@not_main_menu: + jmp @get_key_config_menu + + +@resolve_error: + print_failed + jsr wait_for_keypress + jsr @change_config + + + + + +wait_for_keypress: + ldax #press_a_key_to_continue + jsr print +@loop: + jsr $ffe4 + beq @loop + rts + +get_key: +@loop: + jsr KPR_PERIODIC_PROCESSING_VECTOR + jsr $ffe4 + beq @loop + rts + + +cfg_get_configuration_ptr: + ldax #kipper_param_buffer + kippercall #KPR_GET_IP_CONFIG + rts + +exit_telnet: +exit_gopher: + lda #142 + jsr print_a ;switch to upper case + lda #$05 ;petscii for white text + jsr print_a + jmp main_menu +.rodata + +netboot65_msg: +.byte 13,"KIPPERTERM V" +.include "../inc/version.i" +.byte 13,0 +main_menu_msg: +.byte 13,"MAIN MENU",13,13 +.byte "F1: TELNET F3: GOPHER ",13 +.byte "F5: GOPHER (FLOODGAP.COM)",13 +.byte " 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 DEFAULT",13 +.byte "F7: MAIN MENU",13,13 +.byte 0 + +gopher_initial_location: +.byte "1gopher.floodgap.com",$09,"/",$09,"gopher.floodgap.com",$09,"70",$0D,$0A,0 + +gopher_header: .byte "gopher",13,0 +telnet_header: .byte "telnet",13,0 + +current: +.byte "CURRENT ",0 + +new: +.byte"NEW ",0 + +resolving: + .byte "RESOLVING ",0 + diff --git a/client/cfg/c64_16kcart.cfg b/client/cfg/c64_16kcart.cfg index e0d661e..227720c 100644 --- a/client/cfg/c64_16kcart.cfg +++ b/client/cfg/c64_16kcart.cfg @@ -4,7 +4,7 @@ MEMORY { IP65ZP: start = $20, size = $13, type = rw, define = yes; #this cart replaces BASIC so ok to use that space HEADER: start = $8000, size = $18, file = %O; DEFAULTS: start = $8018, size = $1E, file = %O; - ROM: start = $8036, size = $3FC8, define = yes, file = %O; + ROM: start = $8036, size = $3FCA, 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 diff --git a/client/drivers/c64_disk_access.s b/client/drivers/c64_disk_access.s index 0cd63b8..6245c00 100644 --- a/client/drivers/c64_disk_access.s +++ b/client/drivers/c64_disk_access.s @@ -12,6 +12,7 @@ .export io_sector_no .export io_track_no .export io_read_sector +.export io_write_sector .export io_read_catalogue .export io_read_catalogue_ex .export io_read_file @@ -34,6 +35,7 @@ CHKIN = $ffc6 CHKOUT = $ffc9 CHRIN = $ffcf CHROUT = $ffd2 +CLRCHN = $ffcc CLALL = $FFE7 CLOSE = $ffc3 OPEN = $ffc0 @@ -144,16 +146,11 @@ read_file_callback: io_read_file_with_callback: stax sector_buffer_address + jsr CLALL jsr parse_filename jsr SETNAM - lda io_device_no - beq @drive_id_set - clc - adc #07 ;so 01->08, 02->09 etc - sta drive_id -@drive_id_set: - + jsr set_drive_id lda #$02 ; file number 2 ldx drive_id ldy #02 ; secondary address 2 @@ -209,12 +206,7 @@ io_read_file_with_callback: @empty_sector: @close: - lda #$02 ; filenumber 2 - jsr CLOSE - ldx #$00 ;keyboard now used as input - jsr CHKIN - clc - rts + jmp close_filenumber_2 @device_error: lda #KPR_ERROR_DEVICE_FAILURE sta ip65_error @@ -332,8 +324,113 @@ extended_catalogue_flag_set: jsr write_byte_to_buffer rts +set_drive_id: + lda io_device_no + beq @drive_id_set + clc + adc #07 ;so 01->08, 02->09 etc + sta drive_id +@drive_id_set: + rts -;routine to read a sector +;routine to write a sector +;cribbed from http://codebase64.org/doku.php?id=base:writing_a_sector_to_disk (credited to "Graham") +;inputs: +; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9)) +; io_sector_no - set to sector number to be written +; io_track_no - set to track number to be written (only lo byte is used) +; AX - address of buffer to to write to sector +; outputs:; on errror, carry flag is set. +io_write_sector: + stax sector_buffer_address + jsr set_drive_id + jsr CLALL + lda #$32 ;"2" + jsr make_user_command + lda #1 + ldx #cname + jsr SETNAM + lda #02 + ldx drive_id + ldy #02 + jsr SETLFS + jsr OPEN + bcs @error + + lda #7 + ldx #bpname + jsr SETNAM + lda #15 + ldx drive_id + ldy #15 + jsr SETLFS + jsr OPEN + bcs @error + + jsr check_error_channel + lda #$30 + cmp error_buffer + bne @error + + ldx #$02 ; filenumber 2 + jsr CHKOUT ; file 2 now used as output + + ldax sector_buffer_address + stax buffer_ptr + ldy #0 +: + lda (buffer_ptr),y ;get next byte in sector + jsr CHROUT ;write it out + iny + bne :- + + ldx #$0F ; filenumber 15 + jsr CHKOUT ; file 15 now used as output + + ldy #$00 +: + lda command_buffer,y + beq :+ + jsr CHROUT ;write byte to command channel + iny + bne :- +: + + lda #$0d ; carriage return, required to start command + jsr CHROUT ;write it out + jsr check_error_channel + lda #$30 + cmp error_buffer + bne @error + +@close: + jsr close_filenumbers_2_and_15 + jsr CLRCHN + clc + rts + +@error: + lda #KPR_ERROR_DEVICE_FAILURE + sta ip65_error + jsr @close + sec + rts + + +close_filenumbers_2_and_15: + lda #15 ; filenumber 15 + jsr CLOSE +close_filenumber_2: + lda #$02 ; filenumber 2 + jsr CLOSE + ldx #$00 ; filenumber 0 = keyboard + jsr CHKIN ;(keyboard now input device again) + clc + rts + +;routine to read a sector (credited to "Graham") ;cribbed from http://codebase64.org/doku.php?id=base:reading_a_sector_from_disk ;inputs: ; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9)) @@ -346,14 +443,10 @@ extended_catalogue_flag_set: io_read_sector: stax sector_buffer_address - lda io_device_no - beq @drive_id_set - clc - adc #07 ;so 01->08, 02->09 etc - sta drive_id -@drive_id_set: - jsr make_read_sector_command - ldax command_buffer + jsr set_drive_id + jsr CLALL + lda #$31 ;"1" + jsr make_user_command lda #1 ldx #cname @@ -394,14 +487,7 @@ io_read_sector: iny bne @loop ; next byte, end when 256 bytes are read @close: - lda #15 ; filenumber 15 - jsr CLOSE - lda #$02 ; filenumber 2 - jsr CLOSE - ldx #$00 ; filenumber 0 = keyboard - jsr CHKIN ;(keyboard now input device again) - clc - rts + jmp close_filenumbers_2_and_15 @error: lda #KPR_ERROR_DEVICE_FAILURE sta ip65_error @@ -443,15 +529,18 @@ check_error_channel: JSR CHKIN ;(keyboard now input device again) rts -make_read_sector_command: -;fill command buffer with command to read in track & sector +make_user_command: +;fill command buffer with "U " command, where "x" is passed in via A +;i.e. A=1 makes command to read in track & sector +;A=2 makes command to write track & sector ;returns length of command in Y + pha ldy #0 lda #85 ;"U" sta command_buffer,y iny - lda #$31 ;"1" + pla sta command_buffer,y iny lda #$20 ;" " @@ -524,4 +613,5 @@ byte_to_ascii: rts .rodata -cname: .byte '#' \ No newline at end of file +cname: .byte '#' +bpname: .byte "B-P 2 0" \ No newline at end of file diff --git a/client/drivers/c64charconv.s b/client/drivers/c64charconv.s index 0486f37..b1ee56a 100644 --- a/client/drivers/c64charconv.s +++ b/client/drivers/c64charconv.s @@ -24,7 +24,7 @@ ascii_to_petscii_table: .byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f .byte $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf -.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$5f +.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$a4 .byte $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f .byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$df .byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f diff --git a/client/examples/Makefile b/client/examples/Makefile index ae6dab2..3f17818 100644 --- a/client/examples/Makefile +++ b/client/examples/Makefile @@ -14,7 +14,7 @@ INCFILES=\ ../inc/commonprint.i\ ../inc/net.i\ -all: upnatom.prg upnatom.d64 httpd.d64 raster.prg sidplay.prg sidplay_zigzag.prg +all: upnatom.prg upnatom.d64 httpd.d64 raster.prg sidplay.prg sidplay_zigzag.prg irc.d64 %.o: %.s $(AS) $(AFLAGS) $< @@ -41,9 +41,9 @@ upnatom.d64: upnatom.prg url.cfg httpd.prg: httpd.asm $(DA) httpd.asm -ohttpd.prg -httpd.d64: httpd.prg url.cfg - cp httpd.prg autoexec.prg - ripxplore.rb --init CbmDos httpd.d64 -a autoexec.prg +%.d64: %.prg + cp $*.prg autoexec.prg + ripxplore.rb --init CbmDos $*.d64 -a autoexec.prg clean: rm -f *.o *.pg2 *.prg *.map upnatom.d64 diff --git a/client/examples/irc.s b/client/examples/irc.s new file mode 100644 index 0000000..b4196c2 --- /dev/null +++ b/client/examples/irc.s @@ -0,0 +1,303 @@ + +.include "../inc/common.i" + +.ifndef KPR_API_VERSION_NUMBER + .define EQU = + .include "../inc/kipper_constants.i" +.endif + +print_a = $ffd2 + +.import ascii_to_native + +.macro kippercall function_number + ldy function_number + jsr KPR_DISPATCH_VECTOR +.endmacro + +.zeropage +temp_buff: .res 2 +pptr: .res 2 + +.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 + +init: + + .import cls + jsr cls + lda #14 + jsr print_a ;switch to lower case + + ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in) +look_for_signature: + stax temp_buff + ldy #5 +@check_one_byte: + lda (temp_buff),y + cmp kipper_signature,y + bne @bad_match + dey + bpl @check_one_byte + jmp @found_kipper_signature + +@bad_match: + ldax #kipper_api_not_found_message + jsr print + rts +@found_kipper_signature: + ldax #init_msg + jsr print + kippercall #KPR_INITIALIZE + bcc @init_ok + jsr print_cr + ldax #failed_msg + jsr print + jsr print_cr + jsr print_errorcode + jmp reset_after_keypress +@init_ok: +;if we got here, we have found the KIPPER API and initialised the IP stack + jsr print_ok + jsr print_cr + ldax #connecting_msg + jsr print + jsr connect_to_irc + bcc @connect_ok + jsr print_errorcode + jmp reset_after_keypress +@connect_ok: + + jsr print_ok + jsr print_cr + jsr send_nick + jsr send_user + jsr send_join + +@endless_loop: + jsr KPR_PERIODIC_PROCESSING_VECTOR + jmp @endless_loop + +print_ok: +ldax #ok_msg +jmp print + +reset_after_keypress: + ldax #press_a_key_to_continue + jsr print +@wait_key: + jsr $f142 ;not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD) + beq @wait_key + jmp $fce2 ;do a cold start + +print_errorcode: + ldax #error_code + jsr print + kippercall #KPR_GET_LAST_ERROR + kippercall #KPR_PRINT_HEX + jmp print_cr + + +print: + sta pptr + stx pptr + 1 + +@print_loop: + ldy #0 + lda (pptr),y + beq @done_print + jsr print_a + inc pptr + bne @print_loop + inc pptr+1 + bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-) +@done_print: + rts + +print_cr: + lda #13 + jmp print_a + + +connect_to_irc: + ldax #irc_server + stax param_buffer + ldax #param_buffer + kippercall #KPR_DNS_RESOLVE + bcs @exit + + ;IP address now set + ldax irc_port + stax param_buffer+KPR_TCP_PORT + ldax #irc_callback + stax param_buffer+KPR_TCP_CALLBACK + ldax #param_buffer + kippercall #KPR_TCP_CONNECT + +@exit: + rts + +send_nick: + ldx #0 +: + lda nick_msg,x + beq :+ + sta command_buffer,x + inx + bne :- +: + ldy #0 +: + lda nick,y + beq :+ + sta command_buffer,x + iny + inx + bne :- +: + +add_crlf_and_send_command: + lda #13 + sta command_buffer,x + inx + lda #10 + sta command_buffer,x + inx + txa + ldx #0 + stax param_buffer+KPR_TCP_PAYLOAD_LENGTH + ldax #command_buffer + stax param_buffer+KPR_TCP_PAYLOAD_POINTER + ldax #param_buffer + kippercall #KPR_SEND_TCP_PACKET + rts + +send_user: + ldax #user_msg_length + stax param_buffer+KPR_TCP_PAYLOAD_LENGTH + ldax #user_msg + stax param_buffer+KPR_TCP_PAYLOAD_POINTER + ldax #param_buffer + kippercall #KPR_SEND_TCP_PACKET + rts + +send_join: + ldx #0 +: + lda join_msg,x + beq :+ + sta command_buffer,x + inx + bne :- +: + ldy #0 +: + lda irc_channel,y + beq :+ + sta command_buffer,x + iny + inx + bne :- +: + + jmp add_crlf_and_send_command + +irc_callback: + ldax #param_buffer + kippercall #KPR_GET_INPUT_PACKET_INFO + lda param_buffer+KPR_PAYLOAD_LENGTH+1 + cmp #$ff + bne @not_eof + rts +@not_eof: + ldax param_buffer+KPR_PAYLOAD_POINTER + stax pptr + ldax param_buffer+KPR_PAYLOAD_LENGTH + stax input_length +: + +@print_loop: + ldy #0 + lda (pptr),y + jsr ascii_to_native + jsr print_a + dec input_length + lda input_length + cmp #$ff + bne :+ + dec input_length+1 + lda input_length + cmp #$ff + beq @done_print +: + inc pptr + bne @print_loop + inc pptr+1 + bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-) +@done_print: + rts + +.bss +param_buffer: .res 20 +command_buffer: .res 256 +input_length: .res 2 + +.data + +irc_server: + ;.byte "irc.newnet.net",0 + .byte "jamtronix.com",0 +irc_port: + .word 6667 +irc_channel: + .byte "#foo",0 + + +nick_msg: + .byte "NICK ",0 + +nick: + .byte "kipper_nick2",0 + +join_msg: + .byte "JOIN ",0 + +user_msg: + .byte "USER kipper 0 unused :A Kipper User",13,10 +user_msg_length=*-user_msg + +kipper_api_not_found_message: + .byte "ERROR - KIPPER API NOT FOUND.",13,0 + +failed_msg: + .byte "FAILED", 0 + +ok_msg: + .byte "OK", 0 +init_msg: + .byte "INITIALIZING ",0 + connecting_msg: + .byte "CONNECTING ",0 + +press_a_key_to_continue: + .byte "PRESS A KEY TO CONTINUE",13,0 + +kipper_signature: +.byte $4B,$49,$50,$50,$45,$52 ; "KIPPER" + +error_code: + .asciiz "ERROR CODE: " + diff --git a/client/examples/upnatom.s b/client/examples/upnatom.s index a285f20..546384c 100644 --- a/client/examples/upnatom.s +++ b/client/examples/upnatom.s @@ -1,9 +1,9 @@ .include "../inc/common.i" -.ifndef NB65_API_VERSION_NUMBER +.ifndef KPR_API_VERSION_NUMBER .define EQU = - .include "../inc/nb65_constants.i" + .include "../inc/kipper_constants.i" .endif print_a = $ffd2 @@ -76,9 +76,9 @@ LIGHT_GRAY = 15 beq @loop .endmacro -.macro nb65call function_number +.macro kippercall function_number ldy function_number - jsr NB65_DISPATCH_VECTOR + jsr KPR_DISPATCH_VECTOR .endmacro .zeropage @@ -103,32 +103,29 @@ basicstub: init: - ldax #NB65_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in) - jsr look_for_signature - bcc @found_nb65_signature - - ldax #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 + ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in) +look_for_signature: + stax temp_buff + ldy #5 +@check_one_byte: + lda (temp_buff),y + cmp kipper_signature,y + bne @bad_match + dey + bpl @check_one_byte + jmp @found_kipper_signature -@nb65_signature_not_found: - ldax #nb65_api_not_found_message +@bad_match: + ldax #kipper_api_not_found_message jsr print +@loop: + jmp @loop rts -@found_nb65_signature: +@found_kipper_signature: - lda NB65_API_VERSION - cmp #02 - bpl @version_ok - ldax #incorrect_version - jsr print - jmp reset_after_keypress -@version_ok: ldax #init_msg jsr print - nb65call #NB65_INITIALIZE + kippercall #KPR_INITIALIZE bcc @init_ok jsr print_cr ldax #failed_msg @@ -138,15 +135,15 @@ init: jmp reset_after_keypress @init_ok: -;if we got here, we have found the NB65 API and initialised the IP stack +;if we got here, we have found the KIPPER API and initialised the IP stack ;try and load the config file ldax #read_url_file_param_buffer - nb65call #NB65_FILE_LOAD + kippercall #KPR_FILE_LOAD bcs @use_default_url clc lda #0 - ldy read_url_file_param_buffer+NB65_FILE_ACCESS_FILESIZE + ldy read_url_file_param_buffer+KPR_FILE_ACCESS_FILESIZE sta feed_url,y ;put a zero at the end of the URL @use_default_url: @@ -164,34 +161,34 @@ init: ;copy our music data up to a temp buffer (in case it gets overwritten by ;one of the other unpacking moves) ldax #musicdata+2 ;skip over the 2 byte address - stax nb65_param_buffer+NB65_BLOCK_SRC + stax param_buffer+KPR_BLOCK_SRC ldax #download_buffer - stax nb65_param_buffer+NB65_BLOCK_DEST + stax param_buffer+KPR_BLOCK_DEST ldax #musicdata_size-2 ;don't copy the 2 byte address - stax nb65_param_buffer+NB65_BLOCK_SIZE - ldax #nb65_param_buffer - nb65call #NB65_BLOCK_COPY + stax param_buffer+KPR_BLOCK_SIZE + ldax #param_buffer + kippercall #KPR_BLOCK_COPY ;copy our font data and the sprite data to $2000..$2fff ldax #charset_font - stax nb65_param_buffer+NB65_BLOCK_SRC + stax param_buffer+KPR_BLOCK_SRC ldax #$2000 - stax nb65_param_buffer+NB65_BLOCK_DEST + stax param_buffer+KPR_BLOCK_DEST ldax #MUSIC_BASE - stax nb65_param_buffer+NB65_BLOCK_SIZE - ldax #nb65_param_buffer - nb65call #NB65_BLOCK_COPY + stax param_buffer+KPR_BLOCK_SIZE + ldax #param_buffer + kippercall #KPR_BLOCK_COPY ;should now be now safe to copy the music data back down ;copy our music data to $1000..$1fff ldax #download_buffer - stax nb65_param_buffer+NB65_BLOCK_SRC + stax param_buffer+KPR_BLOCK_SRC ldax #MUSIC_BASE - stax nb65_param_buffer+NB65_BLOCK_DEST + stax param_buffer+KPR_BLOCK_DEST ldax #musicdata_size-2 ;don't copy the 2 byte address - stax nb65_param_buffer+NB65_BLOCK_SIZE - ldax #nb65_param_buffer - nb65call #NB65_BLOCK_COPY + stax param_buffer+KPR_BLOCK_SIZE + ldax #param_buffer + kippercall #KPR_BLOCK_COPY lda #$18 ; use charset at $2000 sta VIC_MEMORY_CTRL @@ -217,21 +214,21 @@ init: ;copy KERNAL to the RAM underneath, in case any ip65 routines need it ldax #$e000 - stax nb65_param_buffer+NB65_BLOCK_SRC - stax nb65_param_buffer+NB65_BLOCK_DEST + stax param_buffer+KPR_BLOCK_SRC + stax param_buffer+KPR_BLOCK_DEST ldax #$1FFF - stax nb65_param_buffer+NB65_BLOCK_SIZE - ldax #nb65_param_buffer - nb65call #NB65_BLOCK_COPY + stax param_buffer+KPR_BLOCK_SIZE + ldax #param_buffer + kippercall #KPR_BLOCK_COPY - ;copy NB65 cart to the RAM underneath, so we can swap it out and modify the IRQ vector + ;copy KIPPER cart to the RAM underneath, so we can swap it out and modify the IRQ vector ldax #$8000 - stax nb65_param_buffer+NB65_BLOCK_SRC - stax nb65_param_buffer+NB65_BLOCK_DEST + stax param_buffer+KPR_BLOCK_SRC + stax param_buffer+KPR_BLOCK_DEST ldax #$4000 - stax nb65_param_buffer+NB65_BLOCK_SIZE - ldax #nb65_param_buffer - nb65call #NB65_BLOCK_COPY + stax param_buffer+KPR_BLOCK_SIZE + ldax #param_buffer + kippercall #KPR_BLOCK_COPY lda #$35 ;we turn off the BASIC and KERNAL rom here, so we can overwrite the IRQ vector at $fffe @@ -260,13 +257,13 @@ init: @download_feed: ldax #feed_url - stax nb65_param_buffer+NB65_URL + stax param_buffer+KPR_URL ldax #download_buffer - stax nb65_param_buffer+NB65_URL_DOWNLOAD_BUFFER + stax param_buffer+KPR_URL_DOWNLOAD_BUFFER ldax #download_buffer_length - stax nb65_param_buffer+NB65_URL_DOWNLOAD_BUFFER_LENGTH - ldax #nb65_param_buffer - nb65call #NB65_DOWNLOAD_RESOURCE + stax param_buffer+KPR_URL_DOWNLOAD_BUFFER_LENGTH + ldax #param_buffer + kippercall #KPR_DOWNLOAD_RESOURCE bcs @download_feed ;if at first we don't succeed, try try again @@ -282,7 +279,7 @@ init: @endless_loop: - jsr NB65_PERIODIC_PROCESSING_VECTOR + jsr KPR_PERIODIC_PROCESSING_VECTOR lda scroll_state beq @download_feed jmp @endless_loop @@ -310,21 +307,6 @@ reset_input_buffer: stax current_input_ptr rts -;look for NB65 signature at location pointed at by AX -look_for_signature: - stax temp_buff - ldy #3 -@check_one_byte: - lda (temp_buff),y - cmp nb65_signature,y - bne @bad_match - dey - bpl @check_one_byte - clc - rts -@bad_match: - sec - rts ;set up the tune @@ -560,17 +542,17 @@ setup_static_scroll_text: jsr get_a cmp #'i' bne @not_ip - lda #NB65_CFG_IP + lda #KPR_CFG_IP jmp @loaded_offset @not_ip: cmp #'g' bne @not_gateway - lda #NB65_CFG_GATEWAY + lda #KPR_CFG_GATEWAY jmp @loaded_offset @not_gateway: cmp #'d' bne @not_dns - lda #NB65_CFG_DNS_SERVER + lda #KPR_CFG_DNS_SERVER jmp @loaded_offset @not_dns: cmp #'f' @@ -588,7 +570,7 @@ setup_static_scroll_text: @loaded_offset: sta param_offset - nb65call #NB65_GET_IP_CONFIG + kippercall #KPR_GET_IP_CONFIG adc param_offset bcc :+ inx @@ -689,16 +671,16 @@ reset_after_keypress: print_errorcode: ldax #error_code jsr print - nb65call #NB65_GET_LAST_ERROR - nb65call #NB65_PRINT_HEX + kippercall #KPR_GET_LAST_ERROR + kippercall #KPR_PRINT_HEX jmp print_cr -update_nb65_counters_irq: +update_KPR_counters_irq: start_irq - jsr NB65_VBL_VECTOR + jsr KPR_VBL_VECTOR jmp exit_from_irq @@ -711,10 +693,10 @@ play_music_irq: emit_titles: ldax #download_buffer - nb65call #NB65_PARSER_INIT + kippercall #KPR_PARSER_INIT @next_title: ldax #title - nb65call #NB65_PARSER_SKIP_NEXT + kippercall #KPR_PARSER_SKIP_NEXT bcs @done jsr emit_tag_contents @@ -835,7 +817,7 @@ raster_jump_table: .word pixel_scroll_irq .byte $0,$30 - .word update_nb65_counters_irq + .word update_KPR_counters_irq .byte $0,$80 .word play_music_irq @@ -886,19 +868,17 @@ url_config_file: .byte "URL.CFG",0 read_url_file_param_buffer: - .word url_config_file ;NB65_FILE_ACCESS_FILENAME + .word url_config_file ;KPR_FILE_ACCESS_FILENAME .word feed_url ;B65_FILE_ACCESS_POINTER - .word $0000 ;NB65_FILE_ACCESS_FILESIZE - should be filled in - .byte $00 ;NB65_FILE_ACCESS_DEVICE + .word $0000 ;KPR_FILE_ACCESS_FILESIZE - should be filled in + .byte $00 ;KPR_FILE_ACCESS_DEVICE title: .byte "",0 -nb65_api_not_found_message: - .byte "ERROR - NB65 API NOT FOUND.",13,0 -incorrect_version: - .byte "ERROR - NB65 API MUST BE AT LEAST VERSION 2.",13,0 +kipper_api_not_found_message: + .byte "ERROR - KIPPER API NOT FOUND.",13,0 failed_msg: .byte "FAILED", 0 @@ -913,8 +893,8 @@ init_msg: press_a_key_to_continue: .byte "PRESS A KEY TO CONTINUE",13,0 -nb65_signature: -.byte $4E,$42,$36,$35 ; "NB65" - API signature +kipper_signature: +.byte $4B,$49,$50,$50,$45,$52 ; "KIPPER" error_code: .asciiz "ERROR CODE: " @@ -938,10 +918,10 @@ temp_bcd: .res 2 scroll_state: .res 1 -nb65_param_buffer: .res $20 +param_buffer: .res $20 download_buffer: -download_buffer_length=8000 +download_buffer_length=12000 .res download_buffer_length .res 10 ;filler diff --git a/client/inc/commonprint.i b/client/inc/commonprint.i index 82f31a7..a83060d 100644 --- a/client/inc/commonprint.i +++ b/client/inc/commonprint.i @@ -13,7 +13,6 @@ .export print_ascii_as_native .export print_integer .export print_dotted_quad - .export print_arp_cache .export mac_address_msg .export ip_address_msg .export netmask_msg @@ -181,52 +180,6 @@ print_ascii_as_native: 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: sta pptr diff --git a/client/inc/disk_transfer.i b/client/inc/disk_transfer.i new file mode 100644 index 0000000..7354459 --- /dev/null +++ b/client/inc/disk_transfer.i @@ -0,0 +1,168 @@ + +.import io_track_no +.import io_sector_no +.import io_write_sector + + +.segment "APP_SCRATCH" + track: .res 1 + sector: .res 1 + errors: .res 1 + sectors_in_track: .res 1 + sector_buffer_address: .res 2 + +;the io_* an tftp_* routines both use the 'output_buffer' so we lose the data in the second sector +;therefore we need to copy the data to here before we use it + sector_buffer: .res 512 + +.code +download_d64: + stax kipper_param_buffer+KPR_TFTP_FILENAME + jsr cls + ldax #downloading_msg + jsr print_ascii_as_native + ldax kipper_param_buffer+KPR_TFTP_FILENAME + jsr print_ascii_as_native + jsr reset_counters_to_first_sector + ldax #write_next_block + stax kipper_param_buffer+KPR_TFTP_POINTER + ldax #kipper_param_buffer + kippercall #KPR_TFTP_CALLBACK_DOWNLOAD + bcc :+ + jsr print_cr + print_failed + jsr print_errorcode + jsr print_cr +: + print_ok + ldax #press_a_key_to_continue + jsr print + jsr get_key + rts + + +save_sector: + ldax #position_cursor_for_track_display + jsr print + jsr print_current_sector + + lda track + sta io_track_no + + lda sector + sta io_sector_no + + ldax sector_buffer_address + jsr io_write_sector + bcc :+ + inc errors +: + jmp move_to_next_sector + +write_next_block: +;tftp download callback routine +;AX will point at block to be written (prepended with 2 bytes indicating block length) + clc + adc #02 ;skip the 2 byte length at start of buffer + bcc :+ + inx +: + stax copy_src + ldax #sector_buffer + stax copy_dest + stax sector_buffer_address + ldax #$200 + jsr copymem + + + + + jsr save_sector + + bcc @not_last_sector + rts +@not_last_sector: + inc sector_buffer_address+1 + jsr save_sector + rts + +@past_last_track: + rts + + +print_current_sector: + ldax #track_no + jsr print_ascii_as_native + lda track + jsr print_hex + ldax #sector_no + jsr print_ascii_as_native + lda sector + jsr print_hex + ldax #errors_msg + jsr print_ascii_as_native + lda errors + jsr print_hex + jsr print_cr + rts + + +reset_counters_to_first_sector: + ldx #1 + stx track + dex + stx sector + stx errors + 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 #31 + 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 + +track_no: + .byte "TRACK $",0 + +sector_no: + .byte " SECTOR $",0 +errors_msg: + .byte " ERRORS $",0 +position_cursor_for_track_display: +.byte $13,13,13,0 + diff --git a/client/inc/kipper_constants.i b/client/inc/kipper_constants.i index a411215..ea98eca 100644 --- a/client/inc/kipper_constants.i +++ b/client/inc/kipper_constants.i @@ -115,11 +115,6 @@ KPR_PAYLOAD_LENGTH EQU $08 ;2 byte length of payload o ; in a TCP connection, if the length is $FFFF, this actually means "end of connection" KPR_PAYLOAD_POINTER EQU $0A ;2 byte pointer to payload of packet (after all headers) -;offsets in ICMP listener parameter structure -KPR_ICMP_LISTENER_TYPE EQU $00 ;ICMP type -KPR_ICMP_LISTENER_CALLBACK EQU $01 ;2 byte address of routine to call when ICMP packet of specified type arrives - - ;offsets in URL download structure ;inputs: KPR_URL EQU $00 ;2 byte pointer to null terminated URL (NB - must be ASCII not "native" string) diff --git a/client/inc/sidplay.i b/client/inc/sidplay.i new file mode 100644 index 0000000..380b604 --- /dev/null +++ b/client/inc/sidplay.i @@ -0,0 +1,278 @@ +.import copymem +.import ascii_to_native +.importzp copy_src +.importzp copy_dest + +.code + +load_sid: + stax sidfile_address + stax copy_src + + ldy #1 + lda (copy_src),y + cmp #'S' ;make sure the file starts with 'PSID' or 'RSID' + beq @ok + sec + rts +@ok: + ldy #7 + lda (copy_src),y + sta header_length + + inc header_length + inc header_length + + tay + ;y now points to the start of the real c64 file + lda (copy_src),y + sta copy_dest + iny + lda (copy_src),y + sta copy_dest+1 + + ldy #$0a + lda (copy_src),y + sta init_song_handler+2 + iny + lda (copy_src),y + sta init_song_handler+1 + iny + lda (copy_src),y + sta play_song_handler+2 + iny + lda (copy_src),y + sta play_song_handler+1 + + ldy #$0f + lda (copy_src),y + sta number_of_songs + + ldy #$11 + lda (copy_src),y + sta default_song + + ldy #$16 + jsr print_ascii_string + + ldy #$36 + jsr print_ascii_string + ldy #$56 + jsr print_ascii_string + + ldax #songs + jsr print + + lda number_of_songs + jsr print_hex + jsr print_cr + + + ldax #load_address + jsr print + lda copy_dest+1 + jsr print_hex + lda copy_dest + jsr print_hex + jsr print_cr + + ldax #play_address + jsr print + lda play_song_handler+2 + jsr print_hex + lda play_song_handler+1 + jsr print_hex + jsr print_cr + + + ldax #init_address + jsr print + lda init_song_handler+2 + jsr print_hex + lda init_song_handler+1 + jsr print_hex + jsr print_cr + + ldax sidfile_address + stax copy_src + + + clc + lda sidfile_address + adc header_length + pha + lda sidfile_address+1 + adc #0 + tax + pla + stax copy_src + sec + lda sidfile_length + sbc header_length + pha + lda sidfile_length+1 + sbc #0 + tax + pla + jsr copymem + + clc + rts + +play_sid: + + lda default_song + sta current_song + jsr init_song + jsr install_irq_handler + jsr print_current_song +@keypress_loop: + jsr get_key_ip65 + cmp #KEYCODE_ABORT + bne @not_abort + jsr remove_irq_handler + jsr reset_sid + rts + +@not_abort: + + cmp #KEYCODE_DOWN + bne @not_down + dec current_song + bne :+ + inc current_song +: + jmp @reset_song +@not_down: + + + + cmp #KEYCODE_UP + bne @not_up + lda current_song + cmp number_of_songs + beq :+ + inc current_song +: + jmp @reset_song +@not_up: + jmp @keypress_loop + +@reset_song: + jsr print_current_song + lda current_song + jsr init_song + jmp @keypress_loop + + +print_current_song: + + ldax #song_number + jsr print + lda current_song + jsr print_hex + rts +reset_sid: + lda #$00 + sta $D404 + sta $D40B + sta $D412 + sta $D418 + rts + +remove_irq_handler: + ldax jmp_old_irq+1 + sei ;don't want any interrupts while we fiddle with the vector + stax $314 ;previous IRQ handler + cli + rts + +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 + cli + rts + +irq_handler: + + + lda $d012 + cmp #100 + bne irq_handler + + + inc $d020 + jsr play_song + dec $d020 + + jmp jmp_old_irq + + +print_ascii_string: +: + lda (copy_src),y + beq :+ + jsr ascii_to_native + jsr print_a + iny + bne :- + : + jmp print_cr + + + +.segment "APP_SCRATCH" +number_of_songs: .res 1 +default_song: .res 1 +sidfile_address: .res 2 +header_length: .res 1 +sidfile_length: .res 2 +current_song: .res 1 +.rodata + +songs: + .byte "SONGS $",0 +error: + .byte "ERROR",13,0 +load_address: + .byte "LOAD ADDRESS $",0 +play_address: + .byte "PLAY ADDRESS $",0 +init_address: + .byte "INIT ADDRESS $",0 + +song_number: + .byte 19,17,17,17,17,17,17,17,"CURRENT SONG NUMBER $",0 + +.segment "SELF_MODIFIED_CODE" + + +init_song: + lda $01 + pha + lda #$35 + sta $01 + lda current_song +init_song_handler: + jsr $ffff + pla + sta $01 + rts + + +play_song: + lda $01 + pha + lda #$35 + sta $01 +play_song_handler: + jsr $ffff + pla + sta $01 + rts +jmp_old_irq: + jmp $ffff + diff --git a/client/tcp_test.bat b/client/tcp_test.bat index 6b80aad..245992e 100644 --- a/client/tcp_test.bat +++ b/client/tcp_test.bat @@ -1 +1 @@ -start c:\temp\WinVICE-2.1\x64.exe -cart16 nb65\kippernet.bin \ No newline at end of file +start c:\temp\WinVICE-2.1\x64.exe -cart16 carts\kipperkart.bin \ No newline at end of file diff --git a/client/test/test_disk_io.s b/client/test/test_disk_io.s index 0ff5c74..c7c0ee0 100644 --- a/client/test/test_disk_io.s +++ b/client/test/test_disk_io.s @@ -12,6 +12,8 @@ .import io_sector_no .import io_track_no .import io_read_sector +.import io_write_sector + .import io_read_file_with_callback .import io_read_file .import io_filename @@ -62,6 +64,82 @@ init: sta $d018 + + ;test we can write sector to default desk + + ldx #$00 +@fill_sector_loop: + txa + sta sector_buffer,x + inx + bne @fill_sector_loop + + lda #$01 + sta io_track_no + lda #$01 + sta io_sector_no + ldax #write_sector + jsr print + lda io_sector_no + jsr print_hex + jsr print_cr + ldax #sector_buffer + jsr io_write_sector + + bcc :+ + jsr print_error_code + rts +: + + + + inc io_sector_no + ldax #write_sector + jsr print + lda io_sector_no + jsr print_hex + jsr print_cr + ldax #sector_buffer + jsr io_write_sector + + bcc :+ + jsr print_error_code + rts +: + + inc io_sector_no + ldax #write_sector + jsr print + lda io_sector_no + jsr print_hex + jsr print_cr + ldax #sector_buffer + jsr io_write_sector + + bcc :+ + jsr print_error_code + rts +: + + + + ;test we can read a sector from default desk + ldax #read_sector + jsr print + + lda #$01 + sta io_track_no + lda #$03 + sta io_sector_no + ldax #sector_buffer + jsr io_read_sector + bcc :+ + jsr print_error_code + rts +: + + jsr dump_sector + ;test we can read the catalogue ldax #read_catalogue jsr print @@ -310,6 +388,12 @@ dump_sector: +write_sector: + .byte "WRITING SECTOR",0 + +read_sector: + .byte "READING SECTOR",13,0 + read_catalogue: .byte "READING CATALOGUE",13,0 diff --git a/client/test/test_ping.s b/client/test/test_ping.s index a11c567..360ab76 100644 --- a/client/test/test_ping.s +++ b/client/test/test_ping.s @@ -60,7 +60,6 @@ init: jsr print_integer ldax #ms jsr print - jsr print_arp_cache rts @error: jmp print_errorcode diff --git a/client/test/testdns.s b/client/test/testdns.s index 42195d5..ece7a14 100644 --- a/client/test/testdns.s +++ b/client/test/testdns.s @@ -44,9 +44,7 @@ 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 diff --git a/doc/kipper_api_technical_reference.doc b/doc/kipper_api_technical_reference.doc new file mode 100644 index 0000000..f9c3239 Binary files /dev/null and b/doc/kipper_api_technical_reference.doc differ diff --git a/doc/nb65_api_technical_reference.doc b/doc/nb65_api_technical_reference.doc deleted file mode 100644 index bcbf073..0000000 Binary files a/doc/nb65_api_technical_reference.doc and /dev/null differ