diff --git a/client/basic/bails.d64 b/client/basic/bails.d64 index e3bee18..1f7a57a 100644 Binary files a/client/basic/bails.d64 and b/client/basic/bails.d64 differ diff --git a/client/basic/kipperbas.d64 b/client/basic/kipperbas.d64 index 42f5ede..c3d9d73 100644 Binary files a/client/basic/kipperbas.d64 and b/client/basic/kipperbas.d64 differ diff --git a/client/carts/Makefile b/client/carts/Makefile index 7237ab0..0a3339a 100644 --- a/client/carts/Makefile +++ b/client/carts/Makefile @@ -17,7 +17,7 @@ IP65TCPLIB=../ip65/ip65_tcp.lib C64RRNETLIB=../drivers/c64rrnet.lib -all: kipperkart.bin kipperkart_rr.bin netboot.bin kipperterm.bin kipperkart.prg kipperterm.prg kipperterm_rr.bin kippergo.bin kipperkart.prg kippergo.prg kippergo_rr.bin kipperdisk.d64 +all: bobcart.bin kipperkart.bin kipperkart_rr.bin netboot.bin kipperterm.bin kipperkart.prg kipperterm.prg kipperterm_rr.bin kippergo.bin kipperkart.prg kippergo.prg kippergo_rr.bin kipperdisk.d64 kipperkart.o: kipperkart.s $(INCFILES) ../inc/ping.i ../inc/disk_transfer.i ../inc/sidplay.i ../inc/config_menu.i $(AS) $(AFLAGS) -o $@ $< @@ -84,6 +84,11 @@ kipperdisk.d64: kipperkart.prg kipperterm.prg kipperkart.prg kippergo.prg ripxplore.rb $@ -a kipperterm.prg ripxplore.rb $@ -a kippergo.prg cp $@ ../../server/boot/ + +bobcart.bin: bobcart.o $(IP65TCPLIB) $(C64RRNETLIB) $(INCFILES) ../cfg/c64_8kcart.cfg + $(LD) -m bobcart.map -vm -C ../cfg/c64_8kcart.cfg -o $@ $< $(IP65TCPLIB) $(C64RRNETLIB) + ruby fix_cart.rb $@ 8192 + d64_upload.d64: d64_upload.prg cp d64_upload.prg ../../server/boot/ diff --git a/client/carts/bobcart.s b/client/carts/bobcart.s new file mode 100644 index 0000000..f2536d6 --- /dev/null +++ b/client/carts/bobcart.s @@ -0,0 +1,1661 @@ + +.include "../inc/common.i" +;.ifndef KPR_API_VERSION_NUMBER +; .define EQU = +; .include "../inc/kipper_constants.i" +;.endif + + +HTTPD_TIMEOUT_SECONDS=5 ;what's the maximum time we let 1 connection be open for? + +;DEBUG=1 + +VARTAB = $2D ;BASIC variable table storage +ARYTAB = $2F ;BASIC array table storage +FREETOP = $33 ;bottom of string text storage area +MEMSIZ = $37 ;highest address used by BASIC +VARNAM = $45 ;current BASIC variable name +VARPNT = $47 ; pointer to current BASIC variable value + +SETNAM = $FFBD +SETLFS = $FFBA +LOAD = $FFD5 +OPEN = $FFC0 +CHKIN = $FFC6 +READST = $FFB7 ; read status byte +CHRIN = $FFCF ; get a byte from file +CLOSE = $FFC3 +MEMTOP = $FE25 +TXTPTR = $7A ;BASIC text pointer +IERROR = $0300 +ICRUNCH = $0304 ;Crunch ASCII into token +IQPLOP = $0306 ;List +IGONE = $0308 ;Execute next BASIC token + +CHRGET = $73 +CHRGOT = $79 +CHROUT = $FFD2 +GETBYT = $B79E ;BASIC routine +GETPAR = $B7EB ;Get a 16,8 pair of numbers +CHKCOM = $AEFD +NEW = $A642 +CLR = $A65E +NEWSTT = $A7AE +GETVAR = $B0E7 ;find or create a variable +FRMEVL = $AD9E ;evaluate expression +FRESTR = $B6A3 ;free temporary string +FRMNUM = $AD8A ;get a number +GETADR = $B7F7 ;convert number to 16 bit integer +INLIN = $A560 ; read a line from keyboard + +VALTYP=$0D ;00=number, $FF=string + +LINNUM = $14 ;Number returned by GETPAR + +crunched_line = $0200 ;Input buffer + +.import copymem +.importzp copy_src +.importzp copy_dest +.import ip65_init +.import cfg_get_configuration_ptr +.import ip65_process +.import ip65_error +.import cfg_ip +.import cfg_dns +.import cfg_gateway +.import cfg_netmask +.import icmp_ping +.import icmp_echo_ip +.import dotted_quad_value +.import parse_dotted_quad + +.import print_a +.import print_cr +.import cfg_mac +.import cfg_mac_default +.import eth_driver_name +.import get_key_if_available +.import timer_read +.import native_to_ascii +.import ascii_to_native + +.import http_parse_request +.import http_get_value +.import http_variables_buffer + +.import tcp_inbound_data_ptr +.import tcp_inbound_data_length +.import tcp_send_data_len +.import tcp_send +.import check_for_abort_key +.import tcp_connect_remote_port +.import tcp_remote_ip +.import tcp_listen +.import tcp_callback +.import tcp_close + +.import __DATA_LOAD__ +.import __DATA_RUN__ +.import __DATA_SIZE__ +.import __SELF_MODIFIED_CODE_LOAD__ +.import __SELF_MODIFIED_CODE_RUN__ +.import __SELF_MODIFIED_CODE_SIZE__ + +temp_ptr =copy_src +temp=copy_src +temp2=copy_dest + +;.zeropage +;temp: .res 2 +;temp2: .res 2 +pptr=temp_ptr +.segment "CARTRIDGE_HEADER" +.word init ;cold start vector +.word $FE47 ;warm start vector +.byte $C3,$C2,$CD,$38,$30 ; "CBM80" + +.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 + + +;we need to set up BASIC as well + jsr $e453 ;set BASIC vectors + jsr $e3bf ;initialize zero page + + + +;make some room for extra RAM + + ldax #$6000 + stax MEMSIZ + + ldax #welcome_banner + jsr print + lda #$90 ;'rest of banner + ldy #$E4 + +;print rest of startup banner + JSR $E42D + +;relocate our r/w data + ldax #__DATA_LOAD__ + stax copy_src + ldax #__DATA_RUN__ + stax copy_dest + ldax #__DATA_SIZE__ + jsr copymem + + ldax #__SELF_MODIFIED_CODE_LOAD__ + stax copy_src + ldax #__SELF_MODIFIED_CODE_RUN__ + stax copy_dest + ldax #__SELF_MODIFIED_CODE_SIZE__ + jsr copymem + + + ldx #5 ;Copy CURRENT vectors +@copy_old_vectors_loop: + lda ICRUNCH,x + sta oldcrunch,x + dex + bpl @copy_old_vectors_loop + + ldx #5 ;Copy CURRENT vectors +install_new_vectors_loop: + lda vectors,x + sta ICRUNCH,x + dex + bpl install_new_vectors_loop + +;copy error handlers: + ldax IERROR + stax olderror + ldax #error_handler + stax IERROR + + ;BASIC keywords installed, now bring up the ip65 stack + + jsr ip65_init + bcc @init_ok + ldax #@no_nic + jsr print +@reboot: + jsr $e453 ;reset vectors + jsr $e3bf ;init BASIC + jsr $a644 ;NEW + jmp $e39d +@no_nic: + .byte 13,"RR-NET NOT FOUND",13,0 + +@init_ok: + + jsr $A644 ;do a "NEW" + jmp $A474 ;"READY" prompt +; rts ;so BASIC will LOAD & RUN INDEX.BAS + +welcome_banner: +.byte $93,$0d," **** C64 BASIC ON BAILS" +.byte 0 + + +safe_getvar: ;if GETVAR doesn't find the desired variable name in the VARTABLE, a routine at $B11D will create it + ;however that routine checks if the low byte of the return address of the caller is $2A. if it is, + ;it assumes the caller is the routine at $AF28 which just wants to get the variable value, and + ;returns a pointer to a dummy 'zero' pointer. + ;so if user code that is calling GETVAR happens to be compiled to an address $xx28, it will + ;trigger this check, and not create a new variable, which (from painful experience) will create + ;a really nasty condition to debug! + ;so vector to GETVAR via here, so the return address seen by $B11D is here, and never $xx28 + jsr GETVAR + rts +.code + + +; CRUNCH -- If this is one of our keywords, then tokenize it +; +crunch: + jsr jmp_crunch ;First crunch line normally + ldy #05 ;Offset for KERNAL + ;Y will contain line length+5 +@loop: + sty temp + jsr isword ;Are we at a keyword? + bcs @gotcha +@next: + jsr nextchar + bne @loop ;Null byte marks end + sta crunched_line-3,Y ;00 line number + lda #$FF ;'tis what A should be + rts ;Buh-bye + +; Insert token and crunch line +@gotcha: + ldx temp ;If so, A contains opcode + sta crunched_line-5,X +@move: + inx + lda crunched_line-5,Y + sta crunched_line-5,X ;Move text backwards + beq @next + iny + bpl @move + + +; ISWORD -- Checks to see if word is +; in table. If a word is found, then +; C is set, Y is one past the last char +; and A contains opcode. Otherwise, +; carry is clear. +; +; On entry, TEMP must contain current +; character position. +; +isword: + ldx #00 +@loop: + ldy temp +@loop2: + lda keywords,x + beq @notmine + cmp #$E0 + bcs @done ;Tokens are >=$E0 + cmp crunched_line-5,Y + bne @next + iny ;Success! Go to next char + inx + bne @loop2 +@next: + inx + lda keywords,x ;Find next keyword + cmp #$E0 + bcc @next + inx + bne @loop ;And check again +@notmine: + clc +@done: + rts + + +; NEXTCHAR finds the next char +; in the buffer, skipping +; spaces and quotes. On +; entry, TEMP contains the +; position of the last spot +; read. On exit, Y contains +; the index to the next char, +; A contains that char, and Z is set if at end of line. + +nextchar: + ldy temp +@loop: + iny + lda crunched_line-5,Y + beq @done + cmp #$8F ;REM + bne @cont + lda #00 +@skip: + sta temp2 ;Find matching character +@loop2: + iny + lda crunched_line-5,Y + beq @done + cmp temp2 + bne @loop2 ;Skip to end of line + beq @loop +@cont: + cmp #$20 ;space + beq @loop + cmp #$22 ;quote + beq @skip +@done: + rts + + +; +; LIST -- patches the LIST routine +; to list our new tokens correctly. +; + +list: + cmp #$E0 + bcc @notmine ;Not my token + cmp #HITOKEN + bcs @notmine + bit $0F ;Check for quote mode + bmi @notmine + sec + sbc #$DF ;Find the corresponding text + tax + sty $49 + ldy #00 +@loop: + dex + beq @done +@loop2: + iny + lda keywords,y + cmp #$E0 + bcc @loop2 + iny + bne @loop +@done: + lda keywords,y + cmp #$91 ;is it "ON"? + bne @not_on + lda #'O' + jsr CHROUT + lda #'N' + bne @skip + +@not_on: + cmp #$9B ;is it "LIST"? + + bne @not_list + lda #'L' + jsr CHROUT + lda #'I' + jsr CHROUT + lda #'S' + jsr CHROUT + lda #'T' + bne @skip +@not_list: + lda keywords,y + bmi @out ;is it >=$80? +@skip: + jsr CHROUT + iny + bne @done +@out: + cmp #$E0 ;It might be BASIC token + bcs @cont + ldy $49 +@notmine: + and #$FF + jmp (oldlist) +@cont: + ldy $49 + jmp $A700 ;Normal exit + + + +; +; EXECUTE -- if this is one of our new +; tokens, then execute it. +execute: + jsr CHRGET +execute_a: + php + cmp #':' ;is it a colon? + beq execute;if so, skip over and go to next token + cmp #$8B ;is it 'IF'? + bne @not_if + lda #$E0 ;our dummy IF token +@not_if: + cmp #$E0 + bcc @notmine + cmp #HITOKEN + bcs @notmine + plp + jsr @disp + jmp NEWSTT +@disp: + eor #$E0 + asl ;multiply by 2 + tax + lda token_routines+1,x + pha + lda token_routines,x + pha + jmp CHRGET ;exit to routine (via RTS) +@notmine: + plp + cmp #0 ;reset flags + jmp $A7E7 + +;the standard BASIC IF routine calls the BASIC EXECUTE routine directly, +;without going through the vector. That means an extended keyword following THEN +;will lead to a syntax error. So we have to reimpliment IF here +;this is taken from TransBASIC - The Transactor, vol 5, Issue 04 (March 1985) page 34 +if_keyword: + jsr FRMEVL ;evaluate expression + jsr CHRGOT + cmp #$89 ;is next token GOTO? + beq @ok + lda #$A7 ;is next token THEN + jsr $AEFF ;will generate SYNTAX ERROR if not +@ok: + jsr CHRGOT + ldx $61 ;result of expression : 0 means false + bne @expression_was_true + jmp $A93B ;go to REM implementation - skips rest of line +@expression_was_true: + bcs @not_numeric;CHRGOT clears carry flag if current char is a number + jmp $A8A0 ;do a GOTO +@not_numeric: + pla + pla ;pop the return address off the stack + jsr CHRGOT + jmp execute_a ;execute current token + + + +;emit the 4 bytes pointed at by AX as dotted decimals +emit_dotted_quad: + sta pptr + stx pptr + 1 + ldy #0 + lda (pptr),y + jsr emit_decimal + lda #'.' + jsr emit_a + + ldy #1 + lda (pptr),y + jsr emit_decimal + lda #'.' + jsr emit_a + + ldy #2 + lda (pptr),y + jsr emit_decimal + lda #'.' + jsr emit_a + + ldy #3 + lda (pptr),y + jsr emit_decimal + + rts + +emit_decimal: ;emit byte in A as a decimal number + pha + sta temp_bin ;save + sed ; Switch to decimal mode + lda #0 ; Ensure the result is clear + sta temp_bcd + sta temp_bcd+1 + ldx #8 ; The number of source bits + : + asl temp_bin+0 ; Shift out one bit + lda temp_bcd+0 ; And add into result + adc temp_bcd+0 + sta temp_bcd+0 + lda temp_bcd+1 ; propagating any carry + adc temp_bcd+1 + sta temp_bcd+1 + dex ; And repeat for next bit + bne :- + + cld ;back to binary + + pla ;get back the original passed in number + bmi @emit_hundreds ; if N is set, the number is >=128 so emit all 3 digits + cmp #10 + bmi @emit_units + cmp #100 + bmi @emit_tens +@emit_hundreds: + lda temp_bcd+1 ;get the most significant digit + and #$0f + clc + adc #'0' + jsr emit_a + +@emit_tens: + lda temp_bcd + lsr + lsr + lsr + lsr + clc + adc #'0' + jsr emit_a +@emit_units: + lda temp_bcd + and #$0f + clc + adc #'0' + jsr emit_a + + rts + +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 + + +extract_string: + jsr FRMEVL + jsr FRESTR ;if not string, will create type mismatch error + sta param_length + tay + lda #0 + sta transfer_buffer,y + dey +@loop: + lda ($22),y + sta transfer_buffer,y + dey + bpl @loop + jmp FRESTR ;free up the temp string created by FRMEVL + +;get a string value from BASIC command, turn into a 32 bit IP address,save it in the 4 bytes pointed at by AX +get_ip_parameter: + stax temp2 + jsr extract_string + ldax #transfer_buffer + jsr parse_dotted_quad + + bcc @ok +@error: + ldax #address_resolution + jmp print_error + +@ok: + ldax #dotted_quad_value + ldx #4 +@copy_dotted_quad_value: + lda dotted_quad_value,y + sta (temp2),y + iny + dex + bne @copy_dotted_quad_value + rts + + +reset_string: + ldy #string_buffer + sty current_output_ptr+1 + rts + +print_dotted_quad: + jsr reset_string + jsr emit_dotted_quad +make_null_terminated_and_print: + lda #0 + jsr emit_a + ldax #string_buffer + jmp print + +print_integer: +sta $63 +stx $62 +jmp $bdd1 ;BASIC routine + +print_decimal: + jsr reset_string + jsr emit_decimal + jmp make_null_terminated_and_print + +print_mac: + jsr reset_string + jsr emit_mac + jmp make_null_terminated_and_print + +;print 6 bytes printed at by AX as a MAC address +emit_mac: + stax pptr + ldy #0 +@one_mac_digit: + tya ;just to set the Z flag + pha + beq @dont_print_colon + lda #':' + jsr emit_a +@dont_print_colon: + pla + tay + lda (pptr),y + jsr emit_hex + iny + cpy #06 + bne @one_mac_digit + rts + +emit_hex: + pha + pha + lsr + lsr + lsr + lsr + tax + lda hexdigits,x + jsr emit_a + pla + and #$0F + tax + lda hexdigits,x + jsr emit_a + pla + rts + +print_hex: + jsr reset_string + jsr emit_hex + jmp make_null_terminated_and_print + +print_error: + jsr print + ldax #error + jsr print + lda ip65_error + jsr print_hex + jsr print_cr + sec + rts + +get_optional_byte: + jsr CHRGOT + beq @no_param ;leave X as it was + jsr CHKCOM ;make sure next char is a comma (and skip it) + jsr CHRGOT + beq @eol + jsr GETBYT +@no_param: + rts +@eol: + jmp $AF08 ;SYNTAX ERROR + +ipcfg_keyword: + + ldax #interface_type + jsr print + + ldax #eth_driver_name + jsr print + jsr print_cr + + ldax #mac_address_msg + jsr print + ldax #cfg_mac + jsr print_mac + jsr print_cr + + ldax #ip_address_msg + jsr print + ldax #cfg_ip + jsr print_dotted_quad + jsr print_cr + + ldax #netmask_msg + jsr print + ldax #cfg_netmask + jsr print_dotted_quad + jsr print_cr + + ldax #gateway_msg + jsr print + ldax #cfg_gateway + jsr print_dotted_quad + jsr print_cr + + + + rts + + + +ping_keyword: + ldax #icmp_echo_ip + jsr get_ip_parameter + bcc @no_error + rts +@no_error: + + ;is there an optional parameter? + ldx #3 + jsr get_optional_byte + stx ping_counter + + ldax #pinging + jsr print + ldax #icmp_echo_ip + jsr print_dotted_quad + jsr print_cr + +@ping_loop: + jsr icmp_ping + bcs @error + lda #'.' +@print_and_loop: + jsr print_a + lda $cb ;current key pressed + cmp #$3F ;RUN/STOP? + beq @done + dec ping_counter + bne @ping_loop +@done: + jmp print_cr +@error: + lda #'!' + jmp @print_and_loop + + +myip_keyword: + ldax #cfg_ip + jmp get_ip_parameter + +gateway_keyword: + ldax #cfg_gateway + jmp get_ip_parameter + +netmask_keyword: + ldax #cfg_netmask + jmp get_ip_parameter + +mac_keyword: + jsr extract_string + ldy #2 +: + lda transfer_buffer,y + sta cfg_mac_default+3,y + dey + bpl:- + jsr ip65_init + rts + + +skip_comma_get_integer: + jsr CHRGOT + jsr CHKCOM ;make sure next char is a comma (and skip it) +get_integer: + jsr CHRGOT + beq @eol + jsr FRMNUM + jsr GETADR + ldax LINNUM +@no_param: + rts +@eol: + jmp $AF08 ;SYNTAX ERROR + + +hook_keyword: + jsr extract_string + ldax #transfer_buffer + jsr skip_comma_get_integer + stax handler_address + jsr find_hook + bcc @existing_entry + + lda hooks + cmp #MAX_HOOKS + bmi @got_space + ldx #$10 ;OUT OF MEMORY + jmp $A437 ;print error +@got_space: + clc + lda #0 + adc hooks + adc hooks + adc hooks + adc hooks + adc hooks + adc hooks + tay + inc hooks + @existing_entry: + ;y now points to free slot in hook table + lda transfer_buffer + sta hook_table,y + lda transfer_buffer+1 + sta hook_table+1,y + lda param_length + sta hook_table+2,y + lda hash + sta hook_table+3,y + lda handler_address + sta hook_table+4,y + lda handler_address+1 + sta hook_table+5,y + rts + + +goto: + sta $14 + sta $39 + stx $15 + stx $3a + + jmp $a8a3 ;GOTO keyword + + +find_hook: + jsr calc_hash + ldy #0 + ldx hooks + beq @done +@compare_one_entry: + lda transfer_buffer + cmp hook_table,y + bne @nope + lda transfer_buffer+1 + cmp hook_table+1,y + bne @nope + lda param_length + cmp hook_table+2,y + bne @nope + lda hash + cmp hook_table+3,y + bne @nope +;found it! + clc + rts +@nope: + dex + beq @done + iny + iny + iny + iny + iny + iny + + bne @compare_one_entry +@done: + sec + rts + +calc_hash: + clc + lda #0 + ldy param_length + beq @done +@loop: + adc transfer_buffer,y + dey + bne @loop +@done: + sta hash + rts + + +yield_keyword: + jsr flush_keyword + jsr tcp_close + .ifdef DEBUG + dec $d020 + .endif + jmp httpd_start + +gosub: + +bang_keyword: + jsr extract_string + lda sent_header + bne :+ + jsr send_header +: + ldy #0 + sty string_ptr +@loop: + lda transfer_buffer,y + jsr xmit_a + inc string_ptr + ldy string_ptr + cpy param_length + bne @loop + rts + + + +got_http_request: + jsr http_parse_request + ldax #path + jsr print + lda #$02 + jsr http_get_value + stax copy_src + jsr print + jsr print_cr + ldy #0 +@copy_path: + lda (copy_src),y + beq @done + sta transfer_buffer,y + iny + bne @copy_path +@done: + sty string_length + lda #0 + sta transfer_buffer,y + sty param_length + sty tmp_length + clc + lda #'P' + sta VARNAM + lda #'A'+$80 + jmp @set_var_value +@copy_vars: + iny + lda (copy_src),y + beq @last_var + tax ;var name + iny + clc + tya + adc copy_src + sta copy_src + bcc :+ + inc copy_src+1 +: + ldy #0 +: + lda (copy_src),y + beq @end_of_var + iny + bne :- +@end_of_var: + sty tmp_length + clc + stx VARNAM + lda #$80 +@set_var_value: + sta VARNAM+1 + jsr safe_getvar + ldy #0 + lda tmp_length + sta (VARPNT),y + iny + lda copy_src + sta (VARPNT),y + iny + lda copy_src+1 + sta (VARPNT),y + ldy tmp_length + jmp @copy_vars + + + @last_var: + + jsr find_hook + bcc @got_hook + ldax default_line_number + jmp goto + @got_hook: + lda hook_table+4,y + ldx hook_table+5,y + jmp goto + + +;start a HTTP server +;this routine will stay in an endless loop that is broken only if user press the ABORT key (runstop on a c64) +;inputs: +; none +;outputs: +; none +httpd_start: + ldx top_of_stack + txs + ldax #listening + jsr print + ldax #cfg_ip + jsr print_dotted_quad + lda #':' + jsr print_a + ldax httpd_port_number + jsr print_integer + jsr print_cr + lda #0 + sta $dc08 ;make sure TOD clock is started + +@listen: + jsr tcp_close + ldax httpd_io_buffer + stax tcp_buffer_ptr + ldax #http_callback + stax tcp_callback + ldax httpd_port_number + + jsr tcp_listen + bcs @abort_key_pressed + +@connect_ok: +.ifdef DEBUG + inc $d020 +.endif + ldax #connection_from + jsr print + ldax #tcp_remote_ip + jsr print_dotted_quad + lda #':' + jsr print_a + ldax tcp_connect_remote_port + + jsr print_integer + jsr print_cr + lda #0 + sta connection_closed + sta found_eol + clc + lda $dc09 ;time of day clock: seconds (in BCD) + sed + adc #HTTPD_TIMEOUT_SECONDS + cmp #$60 + bcc @timeout_set + sec + sbc #$60 +@timeout_set: + cld + sta connection_timeout_seconds + +@main_polling_loop: + jsr ip65_process + jsr check_for_abort_key + bcc @no_abort +@abort_key_pressed: + lda #0 + sta error_handling_mode + ldx #$1E ;break + jmp $e38b ;print error message, warm start BASIC + +@no_abort: + lda found_eol + bne @got_eol + + lda $dc09 ;time of day clock: seconds + + cmp connection_timeout_seconds + beq @connection_timed_out + lda connection_closed + beq @main_polling_loop +@connection_timed_out: +.ifdef DEBUG + dec $d020 +.endif + jmp @listen + +@got_eol: + + jsr reset_output_buffer + + ldy #$FF +: + iny + lda status_ok,y + sta status_code_buffer,y + bne :- + + ldy #$FF +: + iny + lda text_html,y + sta content_type_buffer,y + bne :- + + sta sent_header + + ldax httpd_io_buffer + jmp got_http_request + +http_callback: + lda tcp_inbound_data_length+1 + cmp #$ff + bne @not_eof + inc connection_closed +@done: + rts +@not_eof: + lda found_eol + bne @done + +;copy this chunk to our input buffer + ldax tcp_buffer_ptr + stax copy_dest + ldax tcp_inbound_data_ptr + stax copy_src + ldax tcp_inbound_data_length + jsr copymem + +;increment the pointer into the input buffer + clc + lda tcp_buffer_ptr + adc tcp_inbound_data_length + sta tcp_buffer_ptr + sta temp_ptr + lda tcp_buffer_ptr+1 + adc tcp_inbound_data_length+1 + sta tcp_buffer_ptr+1 + sta temp_ptr+1 + +;put a null byte at the end (assumes we have set temp_ptr already) + lda #0 + tay + sta (temp_ptr),y + +;look for CR or LF in input + sta found_eol + ldax httpd_io_buffer + stax get_next_byte+1 + +@look_for_eol: + jsr get_next_byte + cmp #$0a + beq @found_eol + cmp #$0d + bne @not_eol +@found_eol: + inc found_eol + rts +@not_eol: + cmp #0 + bne @look_for_eol + rts + + + +reset_output_buffer: + ldax httpd_io_buffer + sta xmit_a_ptr+1 + stx xmit_a_ptr+2 + lda #0 + sta output_buffer_length + sta output_buffer_length+1 + rts + + +send_buffer: + ldax output_buffer_length + stax tcp_send_data_len + ldax httpd_io_buffer + jsr tcp_send + jmp reset_output_buffer + + +emit_string: + stax temp_ptr + ldy #0 +@next_byte: + lda (temp_ptr),y + beq @done + jsr xmit_a + iny + bne @next_byte +@done: + rts + + + +httpd_keyword: + jsr get_integer + stax httpd_port_number + jsr skip_comma_get_integer + stax default_line_number + inc error_handling_mode + tsx + stx top_of_stack + jmp httpd_start + +status_keyword: + jsr extract_string + ldy #$FF +@loop: + iny + lda transfer_buffer,y + sta status_code_buffer,y + bne @loop + rts + + +type_keyword: + jsr extract_string + ldy #$FF +@loop: + iny + lda transfer_buffer,y + sta content_type_buffer,y + bne @loop + rts + +send_header: + inc sent_header + ldax #http_version + jsr emit_string + ldax #status_code_buffer + jsr emit_string + ldax #crlf + jsr emit_string + ldax #content_type + jsr emit_string + ldax #content_type_buffer + jsr emit_string + ldax #end_of_header + jmp emit_string + + +flush_keyword: + + lda output_buffer_length + bne :+ + ldx output_buffer_length+1 + bne :+ + rts +: + jmp send_buffer + + +xsend_keyword: + + jsr extract_string + + ldx #transfer_buffer + lda param_length + jsr SETNAM + lda #$02 ; file number 2 + ldx $BA ; last used device number + bne @skip + ldx #$08 ; default to device 8 +@skip: + ldy #$02 ; secondary address 2 + jsr SETLFS + jsr OPEN + bcs @error ; if carry set, the file could not be opened + ldx #$02 ; filenumber 2 + jsr CHKIN + +@loop: + jsr CHRIN + sta tmp_a + jsr READST + bne @eof ; either EOF or read error + lda sent_header + bne :+ + jsr send_header +: + lda tmp_a + jsr xmit_a + jmp @loop +@eof: + and #$40 ; end of file? + beq @error + lda tmp_a + jsr xmit_a + +@close_handles: + lda #$02 ; filenumber 2 + jsr CLOSE + ldx #$00 ; filenumber 0 = keyboard + jsr CHKIN ;keyboard now input device again + rts + + + @error: + + lda #$00 ; no filename + tax + tay + jsr SETNAM + lda #$0f ;file number 15 + ldx $ba ;drive number + ldy #$0f ; secondary address 15 (error channel) + jsr SETLFS + jsr OPEN + LDX #$0F ; filenumber 15 + JSR CHKIN ;(file 15 now used as input) + LDY #$00 +@error_loop: + JSR READST ;(read status byte) + BNE @error_eof ; either EOF or read error + JSR CHRIN ;(get a byte from file) + sta error_buffer,y + iny + + JMP @error_loop ; next byte +@error_eof: + lda #0 + sta error_buffer,y + LDX #$00 ; filenumber 0 = keyboard + JSR CHKIN ;(keyboard now input device again) + + + jsr @close_handles + jmp create_error + +create_error: + lda sent_header + bne @header_sent + ldy #$FF +: + iny + lda status_error,y + sta status_code_buffer,y + bne :- + jsr send_header + +@header_sent: + ldax #error_start + jsr emit_string + ldax #system_error + jsr print + lda $3a ;current line number + ldx $39 + sta $62 + stx $63 + ldx #$90 ;exponent to 16 + sec + jsr $bc49 ;pad out flp acc + jsr $bddf ;convert to string + jsr $b487 ;move string descriptor into flp acc + jsr $b6a6 ;get text pointer into $22/$23 + tay + lda #0 + sta ($22),y + lda $22 + ldx $23 + jsr emit_string + jsr emit_br + ldax #line_number + jsr print + lda $22 + ldx $23 + jsr print + jsr print_cr + ldax #error_buffer + jsr emit_string + ldax #error_buffer + jsr print + jmp yield_keyword + +emit_br: + ldax #br + jmp emit_string + +error_handler: + ldy error_handling_mode + bne @send_error_to_browser + jmp (olderror) +@send_error_to_browser: + txa + asl a + tax + lda $a326,x ; fetch address from table of error messages + sta $22 + lda $a327,x ; fetch address from table of error messages + sta $23 + ldy #0 +@one_char: + lda ($22),y + pha + and #$7f + sta error_buffer,y + iny + pla + bpl @one_char + lda #0 + sta error_buffer,y + jmp create_error + +.rodata +vectors: + .word crunch + .word list + .word execute + +hexdigits: +.byte "0123456789ABCDEF" + +CR=$0D +LF=$0A + +error_start: +.byte "

SYSTEM ERROR


" +line_number: +.byte " LINE NUMBER: ",0 +br: +.byte "
",CR,LF,0 + +listening: +.byte"LISTENING ON ",0 + +pinging: +.byte"PINGING ",0 +interface_type: +.byte "INTERFACE : ",0 + +mac_address_msg: +.byte "MAC ADDRESS : ", 0 + +ip_address_msg: +.byte "IP ADDRESS : ", 0 + +netmask_msg: +.byte "NETMASK : ", 0 + +gateway_msg: +.byte "GATEWAY : ", 0 + + +address_resolution: +.byte "ADDRESS RESOLUTION",0 + + +connect: +.byte "CONNECT",0 + +error: +.byte " ERROR $",0 + +disconnected: +.byte 13,"DIS" +connected_msg: +.byte "CONNECTED",13,0 + + +path: + .byte "PATH: ",0 + +http_version: + .byte "HTTP/1.0 ",0 + +status_ok: + .byte "200 OK",0 +status_error: + .byte "500 " +system_error: + .byte "SYSTEM ERROR",0 +content_type: + .byte "Content-Type: ",0 +text_html: + .byte "text/html",0 + +end_of_header: + .byte CR,LF + .byte "Connection: Close",CR,LF + .byte "Server: BoB_httpd/0.c64",CR,LF +crlf: + .byte CR,LF,0 + +connection_from: .byte "CONNECTION FROM ",0 + + +; Keyword list +; Keywords are stored as normal text, +; followed by the token number. +; All tokens are >$80, +; so they easily mark the end of the keyword +keywords: + .byte "IF",$E0 ;our dummy 'IF' entry takes $E0 + .byte "IPCFG",$E1 + .byte "PING",$E3 + .byte "MYIP",$E4 + .byte "NETMASK",$E5 + .byte "GATEWAY",$E6 + .byte "HOOK",$E8 + .byte "YIELD",$E9 + .byte "XS",$80,$EA ;BASIC will replace 'END' with $80 + .byte "!",$EB + .byte "HTTPD",$EC + .byte "TYPE",$ED + .byte "STATUS",$EE + .byte "FLUSH",$EF + .byte "MAC",$F0 + .byte $00 ;end of list +HITOKEN=$F1 + +; +; Table of token locations-1 +; +token_routines: +E0: .word if_keyword-1 +E1: .word ipcfg_keyword-1 +E2: .word ipcfg_keyword-1 ;dummy +E3: .word ping_keyword-1 +E4: .word myip_keyword-1 +E5: .word netmask_keyword-1 +E6: .word gateway_keyword-1 +E7: .word ipcfg_keyword-1 ;dummy +E8: .word hook_keyword-1 +E9: .word yield_keyword-1 +EA: .word xsend_keyword-1 +EB: .word bang_keyword-1 +EC: .word httpd_keyword-1 +ED: .word type_keyword-1 +EE: .word status_keyword-1 +EF: .word flush_keyword-1 +F0: .word mac_keyword-1 + +.segment "SELF_MODIFIED_CODE" + + +jmp_crunch: .byte $4C ;JMP +oldcrunch: .res 2 ;Old CRUNCH vector +oldlist: .res 2 +oldexec: .res 2 +olderror: .res 2 + +emit_a: +current_output_ptr=emit_a+1 + sta $ffff + inc string_length + inc current_output_ptr + bne :+ + inc current_output_ptr+1 +: + rts + +MAX_HOOKS=10 + +hook_table: +.res MAX_HOOKS*6 +;format is: +; $00/$01 first 2 chars of hook name +; $02 length of name +; $03 hash of name +; $04/$05 line number that hook handler starts at + +hooks: .byte 0 +error_handling_mode: .byte 0 + +.bss +string_length: .res 1 +param_length: .res 1 +tmp_length: .res 1 +temp_bin: .res 1 +temp_bcd: .res 2 +ping_counter: .res 1 +http_buffer: .res 256 +string_buffer: .res 128 +transfer_buffer: .res 256 +handler_address: .res 2 +hash: .res 1 +string_ptr: .res 1 +default_line_number: .res 2 +found_eol: .byte 0 +connection_closed: .byte 0 +output_buffer_length: .res 2 +connection_timeout_seconds: .byte 0 +tcp_buffer_ptr: .res 2 +buffer_size: .res 1 +temp_x: .res 1 +sent_header: .res 1 +tmp_a: .res 1 +error_buffer: .res 80 +top_of_stack: .res 1 +.segment "TCP_VARS" + +__httpd_io_buffer: .res 1024 ;temp buffer for storing inbound requests. +content_type_buffer: .res 128 +status_code_buffer: .res 128 + +.segment "HTTP_VARS" + +httpd_io_buffer: .word __httpd_io_buffer +httpd_port_number: .word 80 + + +get_next_byte: + lda $ffff + inc get_next_byte+1 + bne @skip + inc get_next_byte+2 +@skip: + rts + + +xmit_a: + +xmit_a_ptr: + sta $ffff + inc xmit_a_ptr+1 + bne :+ + inc xmit_a_ptr+2 +: + inc output_buffer_length + bne :+ + inc output_buffer_length+1 + lda output_buffer_length+1 + cmp #2 + bne :+ + stx temp_x + jsr send_buffer + ldx temp_x +: + rts + + +;-- LICENSE FOR bails.s -- +; The contents of this file are subject to the Mozilla Public License +; Version 1.1 (the "License"); you may not use this file except in +; compliance with the License. You may obtain a copy of the License at +; http://www.mozilla.org/MPL/ +; +; Software distributed under the License is distributed on an "AS IS" +; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +; License for the specific language governing rights and limitations +; under the License. +; +; The Original Code is netboot65. +; +; The Initial Developer of the Original Code is Jonno Downes, +; jonno@jamtronix.com. +; Portions created by the Initial Developer are Copyright (C) 2009,2010 +; Jonno Downes. All Rights Reserved. +; -- LICENSE END -- diff --git a/client/cfg/c64_8kcart.cfg b/client/cfg/c64_8kcart.cfg index cd85017..672eac2 100644 --- a/client/cfg/c64_8kcart.cfg +++ b/client/cfg/c64_8kcart.cfg @@ -7,6 +7,9 @@ MEMORY { DEFAULTS: start = $8009, size = $1F, file = %O; ROM: start = $8028, size = $1FC9, 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 = $0200, size = $58, define = yes; #extra scratch area - Tape I/O buffer + RAM4: start = $6000, size = $3FC9, define = yes; #scratch area for apps embedded in cart to use } @@ -14,8 +17,18 @@ SEGMENTS { CARTRIDGE_HEADER: load = HEADER, type = ro; IP65_DEFAULTS: load = DEFAULTS, type = ro; CODE: load = ROM, type = ro; + RODATA: load = ROM, run=ROM, type = ro; DATA: load = ROM, run = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss; + IP65ZP: load = IP65ZP, type = zp; -} + + SELF_MODIFIED_CODE: load = ROM, run = RAM2, type = rw, define = yes; + + APP_SCRATCH: load = RAM4, type = bss; + TCP_VARS: load = RAM4, type = bss; + HTTP_VARS: load=ROM, run = RAM3, type = rw,define = yes; + + } diff --git a/client/drivers/Makefile b/client/drivers/Makefile index 1f17bcb..1800b83 100644 --- a/client/drivers/Makefile +++ b/client/drivers/Makefile @@ -26,7 +26,7 @@ apple2prog.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o a2charconv.o c64rrnet.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o c64_vt100.o cs8900a.o ar65 a $@ $^ -c64wiznet.lib: w5100.o c64print.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o c64_vt100.o +c64wiznet.lib: w5100.o c64print.o c64timer.o c64kernal.o c64inputs.o c64_disk_access.o c64charconv.o c64_vt100.o w5100_udp.o ar65 a $@ $^ diff --git a/client/drivers/w5100.s b/client/drivers/w5100.s index f2a9f37..7d1b2b6 100644 --- a/client/drivers/w5100.s +++ b/client/drivers/w5100.s @@ -10,10 +10,13 @@ .include "w5100.i" +DEFAULT_W5100_BASE = $DF20 + .export eth_init .export eth_rx .export eth_tx .export eth_driver_name + .import eth_inp .import eth_inp_len .import eth_outp @@ -24,21 +27,24 @@ .importzp eth_type .importzp eth_data + .export w5100_init .export w5100_read_reg .export w5100_write_reg - .import cfg_mac + .import cfg_ip + .import cfg_netmask + .import cfg_gateway + + .export icmp_ping + .export icmp_echo_ip + .export ip_init + .export ip_process .import ip65_error .segment "IP65ZP" : zeropage - -W5100_BASE = $DF20 -W5100_ADDR_HI = W5100_BASE+1 -W5100_ADDR_LO = W5100_BASE+2 -W5100_DATA = W5100_BASE+3 - + .code @@ -46,45 +52,74 @@ W5100_DATA = W5100_BASE+3 ;initialize the ethernet adaptor ;inputs: none ;outputs: carry flag is set if there was an error, clear otherwise +;this implementation uses a default address for the w5100, and can be +;called as a 'generic' eth driver init function +;w5100 aware apps can use w5100_init and pass in a different +;base address eth_init: + ldax #DEFAULT_W5100_BASE + +;initialize the w5100 ethernet adaptor +;inputs: AX=base address for w5100 i/o +;outputs: carry flag is set if there was an error, clear otherwise +w5100_init: + stx set_hi+2 + stx set_lo+2 + stx read_data_reg+2 + stx write_data_reg+2 + stx read_mode_reg+2 + stx write_mode_reg+2 + tax + stx read_mode_reg+1 + stx write_mode_reg+1 + inx + stx set_hi+1 + inx + stx set_lo+1 + inx + stx read_data_reg+1 + stx write_data_reg+1 + + lda #$80 ;reset - sta W5100_BASE - lda W5100_BASE + jsr write_mode_reg + jsr read_mode_reg bne @error ;writing a byte to the MODE register with bit 7 set should reset. ;after a reset, mode register is zero ;therefore, if there is a real W5100 at the specified address, ;we should be able to write a $80 and read back a $00 lda #$03 ;set indirect + autoincrement - sta W5100_BASE - lda W5100_BASE + jsr write_mode_reg + jsr read_mode_reg cmp #$03 bne @error ;make sure if we write to mode register without bit 7 set, ;the value persists. - lda #$00 - sta W5100_ADDR_HI - lda #$16 - sta W5100_ADDR_LO + ldax #$0016 + jsr set_register_address ldx #$00 ;start writing to reg $0016 - Interrupt Mask Register @loop: - lda w5100_config_data,x - sta W5100_DATA + lda w5100_config_data,x + jsr write_data_reg inx cpx #$06 bne @loop lda #$09 - sta W5100_ADDR_LO + jsr set_lo ldx #$00 ;start writing to reg $0009 - MAC address + @mac_loop: lda cfg_mac,x - sta W5100_DATA + jsr write_data_reg inx cpx #$06 bne @mac_loop + jsr set_ip_params + ;set up socket 0 for MAC RAW mode ldax #W5100_S0_MR - ldy #W5100_MODE_MAC_RAW + ldy #W5100_MODE_IP_RAW jsr w5100_write_reg ;open socket 0 @@ -116,32 +151,65 @@ eth_rx: ; if there was an error sending the packet then carry flag is set ; otherwise carry flag is cleared eth_tx: - + inc $d020 sec rts ; read one of the W5100 registers ; inputs: AX = register number to read ; outputs: A = value of nominated register +; y is overwritten w5100_read_reg: - stx W5100_ADDR_HI - sta W5100_ADDR_LO - lda W5100_DATA - rts + jsr set_register_address + jmp read_data_reg ; write to one of the W5100 registers ; inputs: AX = register number to read ; Y = value to write to register ; outputs: none -w5100_write_reg: - stx W5100_ADDR_HI - sta W5100_ADDR_LO - sty W5100_DATA +w5100_write_reg: + jsr set_register_address + tya + jmp write_data_reg + + +set_ip_params: + ldax #W5100_GAR0 + jsr set_register_address + ldx #0 +@gateway_loop: + lda cfg_gateway,x + jsr write_data_reg + inx + cpx #$04 + bne @gateway_loop + ldx #0 +@netmask_loop: + lda cfg_netmask,x + jsr write_data_reg + inx + cpx #$04 + bne @netmask_loop + ldax #W5100_SIPR0 + jsr set_register_address + ldx #0 +@ip_loop: + lda cfg_ip,x + jsr write_data_reg + inx + cpx #$04 + bne @ip_loop rts +icmp_ping: +ip_init: +ip_process: + rts + + .rodata eth_driver_name: - .asciiz "W5100 5100" + .asciiz "WIZNET 5100" w5100_config_data: .byte $00 ;no interrupts .byte $0f ;400ms retry (default) @@ -149,7 +217,32 @@ w5100_config_data: .byte $08 ;# of timeouts .byte $55 ;4 sockets @2K each, tx/rx .byte $55 - + +.segment "SELF_MODIFIED_CODE" + + +set_register_address: +set_hi: + stx $FFFF ;WIZNET_ADDR_HI +set_lo: + sta $FFFF ;WIZNET_ADDR_LO + rts +read_data_reg: + lda $FFFF ;WIZNET_DATA + rts +write_data_reg: + sta $FFFF ;WIZNET_DATA + rts +read_mode_reg: + lda $FFFF ;WIZNET_BASE + rts + write_mode_reg: + sta $FFFF ;WIZNET_BASE + rts + .bss + temp: .res 1 + icmp_echo_ip: + ;-- LICENSE FOR w5100a.s -- ; The contents of this file are subject to the Mozilla Public License ; Version 1.1 (the "License"); you may not use this file except in diff --git a/client/ip65/Makefile b/client/ip65/Makefile index b6c9db9..987d812 100644 --- a/client/ip65/Makefile +++ b/client/ip65/Makefile @@ -16,7 +16,6 @@ ETHOBJS= \ timer.o \ eth.o \ arp.o \ - udp.o \ ip65.o \ printf.o \ debug.o \ @@ -36,25 +35,29 @@ ETHOBJS= \ arithmetic.o\ -all: ip65.lib ip65_tcp.lib +all: ip65.lib ip65_tcp.lib ip65_wiznet.lib -ip65.lib: $(ETHOBJS) function_dispatcher.s ip.s icmp.s +ip65.lib: $(ETHOBJS) function_dispatcher.s ip.s icmp.s udp.o $(AS) $(AFLAGS) function_dispatcher.s $(AS) $(AFLAGS) ip.s $(AS) $(AFLAGS) icmp.s - ar65 a ip65.lib $(ETHOBJS) function_dispatcher.o ip.o icmp.o + ar65 a ip65.lib $(ETHOBJS) function_dispatcher.o ip.o icmp.o udp.o -ip65_tcp.lib: tcp.o $(ETHOBJS) function_dispatcher.s ip.s tcp.s icmp.s +ip65_tcp.lib: tcp.o $(ETHOBJS) function_dispatcher.s ip.s tcp.s icmp.s udp.o $(AS) $(AFLAGS) function_dispatcher.s -DTCP -DAPI_VERSION=2 $(AS) $(AFLAGS) ip.s -DTCP $(AS) $(AFLAGS) icmp.s -DTCP - ar65 a ip65_tcp.lib $(ETHOBJS) function_dispatcher.o ip.o tcp.o icmp.o + ar65 a ip65_tcp.lib $(ETHOBJS) function_dispatcher.o ip.o tcp.o icmp.o udp.o + +ip65_wiznet.lib: $(ETHOBJS) function_dispatcher.s + $(AS) $(AFLAGS) function_dispatcher.s + ar65 a ip65_wiznet.lib $(ETHOBJS) function_dispatcher.o clean: rm -f *.o rm -f ip65.lib rm -f ip65_tcp.lib - + rm -f ip65_wiznet.lib distclean: clean diff --git a/client/ip65/config.s b/client/ip65/config.s index 75df927..052adac 100644 --- a/client/ip65/config.s +++ b/client/ip65/config.s @@ -43,7 +43,7 @@ cfg_init: jmp copymem .segment "IP65_DEFAULTS" -cfg_mac_default: .byte $00, $80, $10, $6d, $76, $30 ;mac address to be assigned to local machine +cfg_mac_default: .byte $00, $80, $10, $00, $51, $00 ;mac address to be assigned to local machine cfg_ip_default: .byte 192, 168, 1, 64 ;ip address of local machine (will be overwritten if dhcp_init is called) ;cfg_ip_default: .byte 0,0,0,0 ;ip address of local machine (will be overwritten if dhcp_init is called) cfg_netmask_default: .byte 255, 255, 255, 0; netmask of local network (will be overwritten if dhcp_init is called) diff --git a/client/ip65/icmp.s b/client/ip65/icmp.s index e9ee499..c3ae190 100644 --- a/client/ip65/icmp.s +++ b/client/ip65/icmp.s @@ -357,7 +357,7 @@ icmp_send_echo: ;outputs: ; carry flag - set if no response, otherwise AX is time (in miliseconds) for host to respond icmp_ping: - + lda #0 ;reset the "packet sent" counter sta icmp_echo_cnt @send_one_message: @@ -377,7 +377,7 @@ icmp_ping: : jsr timer_timeout - bcs @loop_during_arp_lookup + bcs @loop_during_arp_lookup jsr icmp_send_echo bcc @message_sent_ok ;still can't send? then give up diff --git a/client/test/Makefile b/client/test/Makefile index 3389c5d..b62d89a 100644 --- a/client/test/Makefile +++ b/client/test/Makefile @@ -7,16 +7,12 @@ AFLAGS= IP65LIB=../ip65/ip65.lib - +IP65WIZNETLIB=../ip65/ip65_wiznet.lib IP65TCPLIB=../ip65/ip65_tcp.lib - C64RRNETLIB=../drivers/c64rrnet.lib - C64WIZNETLIB=../drivers/c64wiznet.lib - APPLE2PROGLIB=../drivers/apple2prog.lib - INCFILES=\ ../inc/common.i\ ../inc/commonprint.i\ @@ -82,8 +78,8 @@ test_get_url.prg: test_get_url.o $(IP65TCPLIB) $(C64RRNETLIB) $(INCFILES) ../cfg test_ping.prg: test_ping.o $(IP65TCPLIB) $(C64RRNETLIB) $(INCFILES) ../cfg/c64prg.cfg $(LD) -m test_ping.map -vm -C ../cfg/c64prg.cfg -o test_ping.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64RRNETLIB) -test_wiznet.prg: test_wiznet.o $(C64WIZNETLIB) $(IP65TCPLIB) $(INCFILES) ../cfg/c64prg.cfg - $(LD) -m test_wiznet.map -vm -C ../cfg/c64prg.cfg -o test_wiznet.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64WIZNETLIB) +test_wiznet.prg: test_wiznet.o $(C64WIZNETLIB) $(IP65WIZNETLIB) $(INCFILES) ../cfg/c64prg.cfg + $(LD) -m test_wiznet.map -vm -C ../cfg/c64prg.cfg -o test_wiznet.prg $(AFLAGS) $< $(IP65WIZNETLIB) $(C64WIZNETLIB) cp test_wiznet.prg ../../server/boot/autoexec.prg diff --git a/client/test/test_wiznet.s b/client/test/test_wiznet.s index a975158..aae26cf 100644 --- a/client/test/test_wiznet.s +++ b/client/test/test_wiznet.s @@ -8,7 +8,6 @@ .import copymem .importzp copy_src .importzp copy_dest - .import icmp_echo_ip .import icmp_ping .import get_key @@ -37,10 +36,11 @@ basicstub: .code init: - jsr print_cr init_ip_via_dhcp - jsr print_ip_config +; jsr print_ip_config jsr print_cr + + lda #0 sta register_page jsr dump_wiznet_register_page @@ -110,7 +110,6 @@ dump_wiznet_register_page: jmp @one_row @done: jsr print_cr - jsr wait_for_keypress rts wait_for_keypress: