From b65824fee44dbf38947561d07aef574c38a5b1b9 Mon Sep 17 00:00:00 2001 From: jonnosan Date: Sat, 15 Jan 2011 00:34:09 +0000 Subject: [PATCH] clean up ip65 build git-svn-id: http://svn.code.sf.net/p/netboot65/code@306 93682198-c243-4bdb-bd91-e943c89aac3b --- client/Makefile | 2 - client/basic/Makefile | 6 +- client/basic/bails.d64 | Bin 174848 -> 174848 bytes client/basic/kipperbas.d64 | Bin 174848 -> 174848 bytes client/basic/kipperbasv20.s | 1658 +++++++++++++++++++++++++++++++ client/cfg/a2bin.cfg | 6 +- client/cfg/kipperbasv20.cfg | 26 + client/cfg/vic20prg.cfg | 24 +- client/drivers/Makefile | 16 +- client/drivers/lan91c96.s | 75 ++ client/inc/version.i | 2 +- client/ip65/Makefile | 6 +- client/ip65/ip65.s | 2 +- client/ip65/sntp.s | 210 ---- client/kipperterm2/timestamp.i | 2 +- client/test/Makefile | 38 +- client/test/test_lancegs.s | 47 + client/test/test_sntp.s | 215 ---- client/test/test_vic20.s | 24 +- client/test/testdns.s | 1 - client/wiznet/kipperwizdisk.d64 | Bin 174848 -> 174848 bytes dist/make_dist.rb | 3 +- dist/make_dist_ip65.rb | 19 +- dist/version_number.txt | 2 +- doc/ip65.html | 16 +- 25 files changed, 1892 insertions(+), 508 deletions(-) create mode 100644 client/basic/kipperbasv20.s create mode 100644 client/cfg/kipperbasv20.cfg create mode 100644 client/drivers/lan91c96.s delete mode 100644 client/ip65/sntp.s create mode 100644 client/test/test_lancegs.s delete mode 100644 client/test/test_sntp.s diff --git a/client/Makefile b/client/Makefile index 3099b42..67e88a1 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,5 +1,3 @@ -TARGET=c64 - .PHONY: ip65 drivers test clean distclean kipperterm2 examples carts basic wiznet diff --git a/client/basic/Makefile b/client/basic/Makefile index e676dab..62c3a66 100644 --- a/client/basic/Makefile +++ b/client/basic/Makefile @@ -13,8 +13,9 @@ INCFILES=\ IP65LIB=../ip65/ip65_tcp.lib C64RRNETLIB=../drivers/c64rrnet.lib +VIC20RRNETLIB=../drivers/vic20rrnet.lib -all: ip65 kipperbas.d64 bails.d64 +all: ip65 kipperbas.d64 bails.d64 kipperbasv20.prg ip65: make -C ../ip65 all @@ -24,6 +25,9 @@ ip65: %.prg: %.o $(IP65LIB) $(C64RRNETLIB) $(INCFILES) ../cfg/kipperbas.cfg $(LD) -m $*.map -vm -C ../cfg/kipperbas.cfg -o $*.prg $(AFLAGS) $< $(IP65LIB) $(C64RRNETLIB) + +kipperbasv20.prg: kipperbasv20.o $(IP65LIB) $(VIC20RRNETLIB) $(INCFILES) ../cfg/kipperbasv20.cfg + $(LD) -m kipperbasv20.map -vm -C ../cfg/kipperbasv20.cfg -o kipperbasv20.prg $(AFLAGS) $< $(IP65LIB) $(VIC20RRNETLIB) bails.d64: bails.prg diff --git a/client/basic/bails.d64 b/client/basic/bails.d64 index 27ce14386da2d6d7c25c5169cfbf1340f456f3ef..db8a795ed286b3973eb116dcce04a4993f3f0917 100644 GIT binary patch delta 7950 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 C5A=5c delta 7868 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 diff --git a/client/basic/kipperbas.d64 b/client/basic/kipperbas.d64 index 9e4d311aafca285a47c7f7dcc986199cbf8e8465..89e9b3656cbe735ef651fdaed894b4349c2df4eb 100644 GIT binary patch literal 174848 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 Kpuqn+f&T!d7{)gM delta 8579 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 + 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 $C700 ;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 $C7E7 + +;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 $CEFF ;will generate SYNTAX ERROR if not +@ok: + jsr CHRGOT + ldx $61 ;result of expression : 0 means false + bne @expression_was_true + jmp $C93B ;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 $C8A0 ;do a GOTO +@not_numeric: + pla + pla ;pop the return address off the stack + jsr CHRGOT + jmp execute_a ;execute current token + + + +find_var: + sta VARNAM + stx VARNAM+1 + jsr safe_getvar + ldy #0 + rts + +set_connection_state: + lda #'C'+$80 + ldx #'O'+$80 + jsr find_var + tya + sta (VARPNT),y + iny + lda connection_state + sta (VARPNT),y + +set_error: + lda #'E'+$80 + ldx #'R'+$80 + sta VARNAM+1 + jsr find_var + lda #0 + sta (VARPNT),y + iny + lda ip65_error + sta (VARPNT),y + + rts + + +;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 dns_set_hostname + + bcs @error + jsr dns_resolve + bcc @ok +@error: + ldax #address_resolution + jmp print_error + +@ok: + ldax #dns_ip + ldx #4 +@copy_dns_ip: + lda dns_ip,y + sta (temp2),y + iny + dex + bne @copy_dns_ip + 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_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 + jsr set_error + 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 $CF08 ;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 + + ldax #dns_server_msg + jsr print + ldax #cfg_dns + jsr print_dotted_quad + jsr print_cr + + + ldax #dhcp_server_msg + jsr print + ldax #dhcp_server + jsr print_dotted_quad + jsr print_cr + + ldax #tftp_server_msg + jsr print + ldax #cfg_tftp_server + jsr print_dotted_quad + jsr print_cr + +clear_error: + lda #0 + sta ip65_error + jmp set_error + +dhcp_keyword: + jsr dhcp_init + bcc @init_ok + jsr ip65_init ;if DHCP failed, then reinit the IP stack (which will reset IP address etc that DHCP messed with to default values) + +@init_failed: + jsr set_error + ldax #dhcp + jmp print_error +@init_ok: + jmp clear_error + rts + +mac_keyword: + jsr extract_string + ldy #2 +: + lda transfer_buffer,y + sta cfg_mac_default+3,y + dey + bpl:- + jsr ip65_init + 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 #dns_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 #$18 ;RUN/STOP? + beq @done + lda ping_counter + beq @ping_loop + dec ping_counter + cmp #1 + bne @ping_loop +@done: + jsr print_cr + jmp set_error +@error: + lda #'!' + jmp @print_and_loop + + +myip_keyword: + ldax #cfg_ip + jmp get_ip_parameter + +dns_keyword: + ldax #cfg_dns + jmp get_ip_parameter + +gateway_keyword: + ldax #cfg_gateway + jmp get_ip_parameter + +netmask_keyword: + ldax #cfg_netmask + jmp get_ip_parameter + +tftp_keyword: + ldax #cfg_tftp_server + jmp get_ip_parameter + + +tf_param_setup: + jsr print + jsr extract_string + ldax #transfer_buffer + stax tftp_filename + jsr print + lda #' ' + jsr print_a + lda #'(' + jsr print_a + ldax #cfg_tftp_server + jsr print_dotted_quad + lda #')' + jsr print_a + + jsr print_cr + + ldx #$03 +: + lda cfg_tftp_server,x + sta tftp_ip,x + dex + bpl :- + rts + +tfget_keyword: + ldax #get_msg + jsr tf_param_setup + ldax #tftp_download_callback + jsr tftp_set_callback_vector + lda #0 + sta file_opened +;make file output name + lda #'@' + sta string_buffer + lda #':' + sta string_buffer+1 + ldy #$FF +@loop: + iny + lda transfer_buffer,y + sta string_buffer+2,y + bne @loop + iny + iny + lda #',' + sta string_buffer,y + iny + lda #'P' + sta string_buffer,y + iny + lda #',' + sta string_buffer,y + iny + lda #'W' + sta string_buffer,y + iny + sta string_length + + jsr tftp_download +after_tftp_xfer: + bcc @no_error + ldax #tftp +@error_set: + jsr print_error +@no_error: + jsr close_file + jmp set_error + +close_file: + lda #$02 ; filenumber 2 + jsr $FFC3 ; call CLOSE + rts + +open_file: + ;A,X,Y set up ready for a call to SETNAM for file #2 + jsr $FFBD ; call SETNAM + lda #$02 ; file number 2 + ldx $BA ; last used drive + + ldy #$02 ; secondary address 2 + jsr $FFBA ; call SETLFS + + jmp $FFC0 ; call OPEN + + +tftp_download_callback: + + ;buffer pointed at by AX now contains "tftp_data_block_length" bytes + stax temp + + lda #'.' + jsr print_a + lda file_opened + bne @already_opened + lda string_length + ldx #string_buffer + jsr open_file + +@already_opened: + + ldx #$02 ; filenumber 2 = output file + jsr $FFC9 ; call CHKOUT + +@copy_one_byte: + lda tftp_data_block_length + bne @not_done + lda tftp_data_block_length+1 + beq @done + +@not_done: + ldy #2 ;we want to skip the first 2 bytes in the buffer + lda (temp),y + jsr $ffd2 ;write byte + inc temp + bne :+ + inc temp+1 +: + lda tftp_data_block_length + dec tftp_data_block_length + cmp #0 + bne @copy_one_byte + dec tftp_data_block_length+1 + jmp @copy_one_byte +@done: + + ldx #$00 ; filenumber 0 = console + jmp $FFC9 ; call CHKOUT + + +tfput_keyword: + ldax #put_msg + jsr tf_param_setup + + lda param_length + ldx #transfer_buffer + jsr open_file + bcs @error + lda $90 ;get ST + beq @ok +@error: + + ldx #4 ;"FILE NOT FOUND" error + jmp $C437 ;error +@ok: + ldax #tftp_upload_callback + jsr tftp_set_callback_vector + jsr tftp_upload + jmp after_tftp_xfer + + +tftp_upload_callback: + stax copy_dest + lda #'.' + jsr print_a + lda #0 + sta bytes_read + sta bytes_read+1 + + ldx #$02 ; filenumber 2 = output file + jsr $FFC6 ; call CHKIN (file 2 now used as input) +@loop: + jsr $FFCF ; call CHRIN (get a byte from file) + ldy #0 + sta (copy_dest),y + inc copy_dest + bne :+ + inc copy_dest+1 +: + inc bytes_read + bne :+ + inc bytes_read+1 +: + lda bytes_read+1 + cmp #2 + beq @done + jsr $FFB7 ; call READST (read status byte) + beq @loop ; nonzero mean either EOF or read error + +@done: + ldx #$00 ; filenumber 0 = console + jsr $FFC6 ; call CHKIN (console now used as input) + ldax bytes_read + 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 $CF08 ;SYNTAX ERROR + + +make_tcp_connection: + lda #0 + sta connection_state + jsr set_connection_state + ldax #tcp_connect_ip + jsr get_ip_parameter + bcc @no_error + rts +@no_error: + jsr skip_comma_get_integer + jsr tcp_connect + bcc :+ +@connect_error: + ldax #connect + jmp print_error +: + ldax #connected_msg + jsr print + lda #1 + sta connection_state + lda #0 + sta ip65_error + jsr set_connection_state + clc + rts + +netcat_keyword: + lda $CC + sta cursor_state + lda #$0 + sta $CC ;enable blinking cursor + ldax #netcat_callback + stax tcp_callback + jsr make_tcp_connection + bcs @exit + + ;is there an optional parameter? + ldx #0 + jsr get_optional_byte + stx netcat_mode +@main_polling_loop: + + jsr timer_read + txa + adc #$20 ;32 x 1/4 = ~ 8seconds + sta netcat_timeout +@wait_for_keypress: + jsr timer_read + cpx netcat_timeout + bne @no_timeout + jsr tcp_send_keep_alive + jmp @main_polling_loop +@no_timeout: + jsr ip65_process + lda connection_state + bne @not_disconnected +@disconnected: + ldax #disconnected + jsr print +@exit: + lda cursor_state + sta $CC + rts +@not_disconnected: + + lda netcat_mode + beq @not_line_mode + + lda #$00 + sta string_length + +;process inbound ip packets while waiting for a keypress +@read_line: + lda $cb ;current key pressed + cmp #$18 ;RUN/STOP? + beq @runstop + jsr ip65_process + lda connection_state + beq @disconnected + + jsr $f142 ;not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD) + + beq @read_line + + cmp #$14 ;Delete + beq @delete + + cmp #$0d ;Return + beq @input_done + + ;End reached? + ldy string_length + cpy #$FF + beq @read_line + + jsr $ffd2 ;Print it + jsr native_to_ascii + sta transfer_buffer,y ;Add it to string + + inc string_length + + ;Not yet. + jmp @read_line + + +@delete: + ;First, check if we're at the beginning. + lda string_length + bne @delete_ok + jmp @read_line + + ;At least one character entered. +@delete_ok: + ;Move pointer back. + dec string_length + + ;Print the delete char + lda #$14 + jsr $ffd2 + + ;Wait for next char + jmp @read_line + +@input_done: + jsr reset_cursor + lda #$0d + jsr $ffd2 ;print a newline + ldy string_length + lda #$0d + sta transfer_buffer,y + iny + lda #$0a + sta transfer_buffer,y + iny + sty tcp_send_data_len + jmp @send_buffer +@not_line_mode: + + ;is there anything in the input buffer? + lda $c6 ;NDX - chars in keyboard buffer + bne :+ + jmp @wait_for_keypress +: + lda #0 + sta tcp_send_data_len + sta tcp_send_data_len+1 +@get_next_char: + lda $cb ;current key pressed + cmp #$18 ;RUN/STOP? + bne @not_runstop +@runstop: + lda #0 + sta $cb ;overwrite "current key pressed" else it's seen by the tcp stack and the close aborts + lda cursor_state + sta $CC + + jmp tcp_close +@not_runstop: + jsr $ffe4 ;getkey - 0 means no input + tax + beq @no_more_input + txa + + ldy tcp_send_data_len + sta transfer_buffer,y + inc tcp_send_data_len + jmp @get_next_char +@no_more_input: +@send_buffer: + ldax #transfer_buffer + jsr tcp_send + bcs @error_on_send + jmp @main_polling_loop + +@error_on_send: + lda cursor_state + sta $CC + + ldax #transmission + jmp print_error + +reset_cursor: + lda $cf ;0 means last cursor blink set char to be reversed + beq @done + lda $ce ;original value of cursor char + ldx $287 ;original colour + ldy #$0 ;blink phase + sty $cf + jsr $ea13 ;restore char & colour +@done: + rts +netcat_callback: + jsr reset_cursor + lda tcp_inbound_data_length+1 + cmp #$ff + bne @not_eof + lda #0 + sta connection_state + rts +@not_eof: + + ldax tcp_inbound_data_ptr + stax temp2 + lda tcp_inbound_data_length + sta buffer_length + lda tcp_inbound_data_length+1 + sta buffer_length+1 + +@next_byte: + lda $cb ;current key pressed + cmp #$18 ;RUN/STOP? + beq @finished + + ldy #0 + lda (temp2),y + ldx netcat_mode + beq @no_transform + jsr ascii_to_native +@no_transform: + jsr print_a + inc temp2 + bne :+ + inc temp2+1 +: + lda buffer_length+1 + beq @last_page + lda buffer_length + bne @not_end_of_page + dec buffer_length+1 +@not_end_of_page: + dec buffer_length + jmp @next_byte +@last_page: + dec buffer_length + beq @finished + + jmp @next_byte + +@finished: + + rts + + +tcpconnect_keyword: + ldax #tcpconnect_callback + stax tcp_callback + jmp make_tcp_connection + +tcpconnect_callback: + + ldax #transfer_buffer + stax copy_dest + ldax tcp_inbound_data_ptr + stax copy_src + lda tcp_inbound_data_length + ldx tcp_inbound_data_length+1 + beq @short_packet + cpx #$ff + bne @not_end_packet + lda #0 + sta connection_state + rts +@not_end_packet: + lda #$ff +@short_packet: + +set_input_string: + pha + lda #'I' + ldx #'N'+$80 + jsr find_var + ldy #0 + pla + pha + sta (VARPNT),y + iny + lda #transfer_buffer + sta (VARPNT),y + pla + beq :+ + ldx #0 + jsr copymem +: + rts + +poll_keyword: + lda #0 + jsr set_input_string + jsr set_connection_state + jsr ip65_process + lda ip65_error + beq @no_error + jmp set_error +@no_error: + jmp set_connection_state + +tcplisten_keyword: + lda #0 + sta connection_state + sta ip65_error + ldax #tcpconnect_callback + stax tcp_callback + jsr get_integer + jsr tcp_listen + bcs :+ + inc connection_state +: + jmp set_connection_state + +tcpsend_keyword: + jsr extract_string + ldy param_length + sty tcp_send_data_len + ldy #0 + sty tcp_send_data_len+1 + ldax #transfer_buffer + jsr tcp_send + jmp set_connection_state + +tcpclose_keyword: + lda #0 + sta connection_state + jsr tcp_close + jmp set_connection_state + +tcpblat_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 + ldy #$00 +@loop: + jsr READST + bne @eof ; either EOF or read error + jsr CHRIN + sta transfer_buffer,y + iny + bne @loop + ldax #$100 + stax tcp_send_data_len + ldax #transfer_buffer + jsr tcp_send + bcs @error_stored + ldy #0 + jmp @loop +@eof: + and #$40 ; end of file? + beq @readerror + lda #$00 + sty tcp_send_data_len + sta tcp_send_data_len+1 + ldax #transfer_buffer + jsr tcp_send + bcs @error_stored + +@close: + lda #0 +@store_error: + sta ip65_error +@error_stored: + lda #$02 ; filenumber 2 + jsr CLOSE + ldx #$00 ; filenumber 0 = keyboard + jsr CHKIN ;keyboard now input device again + jmp set_error + +@error: + lda #KPR_ERROR_DEVICE_FAILURE + jmp @store_error +@readerror: + lda #KPR_ERROR_FILE_ACCESS_FAILURE + jmp @store_error + +evaluate: + lda $00 + sta $0D ;set string flag to not string + jsr CHRGET + cmp #$E3 ; PING keyword + bne @done + + jsr CHRGET ;take PING command off stack + + ldax #icmp_echo_ip + jsr get_ip_parameter + lda #$00 + sta $0D ;set string flag to not string + + bcs @error + jsr icmp_ping + bcc @no_error +@error: + lda #$ff + tax +@no_error: + tay + txa + jmp $D395 ;signed 16 bit number to floating point + rts + +@done: + jsr CHRGOT + jmp $CE8D ;inside original EVAL routine + +.rodata +vectors: + .word crunch + .word list + .word execute + .word evaluate +; 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 +hexdigits: +.byte "0123456789ABCDEF" + +pinging: +.byte"PINGING ",0 +interface_type: +.byte $12,"INTERFACE",$92,13,0 + +mac_address_msg: +.byte $12,"MAC ADDRESS",$92,13,0 + +ip_address_msg: +.byte $12,"IP ADDRESS",$92,13,0 + +netmask_msg: +.byte $12,"NETMASK",$92,13,0 + +gateway_msg: +.byte $12,"GATEWAY",$92,13,0 + +dns_server_msg: +.byte $12,"DNS SERVER",$92,13,0 + +dhcp_server_msg: +.byte $12,"DHCP SERVER",$92,13,0 + +tftp_server_msg: +.byte $12,"TFTP SERVER",$92,13,0 + +address_resolution: +.byte "ADDRESS RESOLUTION",0 + +get_msg: +.byte "GETTING ",0 +put_msg: +.byte "PUTTING ",0 + +tftp: +.byte "TFTP",0 +dhcp: +.byte "DHCP",0 + +connect: +.byte "CONNECT",0 + +transmission: +.byte "TRANSMISSION",0 + +error: +.byte " ERROR $",0 + +disconnected: +.byte 13,"DIS" +connected_msg: +.byte "CONNECTED",13,0 + +keywords: + .byte "IF",$E0 ;our dummy 'IF' entry takes $E0 + .byte "IPCFG",$E1 + .byte "DHCP",$E2 + .byte "PING",$E3 + .byte "MYIP",$E4 + .byte "NETMASK",$E5 + .byte "GATEWAY",$E6 + .byte "DNS",$E7 + .byte "TFTP",$E8 + .byte "TF",$A1,$E9 ;TFGET - BASIC will replace GET with A1 + .byte "TFPUT",$EA + .byte "NETCAT",$EB + .byte "TCPC",$91,"NECT",$EC ; TCPCONNECT - BASIC will replace ON with $91 + .byte "POLL",$ED + .byte "TCP",$9B,"EN",$EE ;TCPLISTEN - BASIC will replace LIST with $9b + .byte "TCPS",$80,$EF ;TCPSEND - BASIC will replace END with $80 + .byte "TCP",$A0,$F0 ;TCPLOSE - BASIC will replace CLOSE with $A0 + .byte "TCPBLAT",$F1 + .byte "MAC",$F2 + .byte $00 ;end of list +HITOKEN=$F3 + +; +; Table of token locations-1 +; +token_routines: +E0: .word if_keyword-1 +E1: .word ipcfg_keyword-1 +E2: .word dhcp_keyword-1 +E3: .word ping_keyword-1 +E4: .word myip_keyword-1 +E5: .word netmask_keyword-1 +E6: .word gateway_keyword-1 +E7: .word dns_keyword-1 +E8: .word tftp_keyword-1 +E9: .word tfget_keyword-1 +EA: .word tfput_keyword-1 +EB: .word netcat_keyword-1 +EC: .word tcpconnect_keyword-1 +ED: .word poll_keyword-1 +EE: .word tcplisten_keyword-1 +EF: .word tcpsend_keyword-1 +FO: .word tcpclose_keyword-1 +F1: .word tcpblat_keyword-1 +F2: .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 +oldeval: .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 + + +.bss +netcat_mode: .res 1 +bytes_read: .res 2 +string_length: .res 1 +param_length: .res 1 +ip_string: .res 15 +netmask_string: .res 15 +dns_string: .res 15 +gateway_string: .res 15 + temp_bin: .res 1 +temp_bcd: .res 2 +ping_counter: .res 1 +string_buffer: .res 128 +transfer_buffer: .res 256 +file_opened: .res 1 +connection_state: .res 1 +netcat_timeout: .res 1 +buffer_length: .res 2 +cursor_state: .res 1 diff --git a/client/cfg/a2bin.cfg b/client/cfg/a2bin.cfg index d2d2176..7303024 100644 --- a/client/cfg/a2bin.cfg +++ b/client/cfg/a2bin.cfg @@ -7,14 +7,14 @@ MEMORY { } SEGMENTS { EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM,run=RAM, type = ro, define = yes; + STARTUP: load = RAM,run=RAM, type = ro, define = yes, optional=yes; CODE: load = RAM, run=RAM, type = ro, define = yes; RODATA: load = RAM, run=RAM, type = ro , define = yes; IP65_DEFAULTS: load = RAM, run=RAM, type = ro , define = yes; DATA: load = RAM, run=RAM, type = rw , define = yes; BSS: load=RAM, type = bss, define = yes; - TCP_VARS: load = RAM, type = bss; - APP_SCRATCH: load = RAM, type = bss; + TCP_VARS: load = RAM, type = bss, optional=yes; + APP_SCRATCH: load = RAM, type = bss , optional=yes; ZEROPAGE: load = ZP, type = zp; IP65ZP: load = IP65ZP, type = zp; } diff --git a/client/cfg/kipperbasv20.cfg b/client/cfg/kipperbasv20.cfg new file mode 100644 index 0000000..7416480 --- /dev/null +++ b/client/cfg/kipperbasv20.cfg @@ -0,0 +1,26 @@ + +MEMORY { + IP65ZP: start = $A3, size = $12, type = rw; + STARTRAM: start = $11FF, size = $1000, file = %O; + MAINRAM: start = $4000, size = $3FC9, define = yes, file = %O; + HIRAM: start = $A000, size = $1fE0; +} + SEGMENTS { + STARTUP: load = STARTRAM, type = rw; + MAINSTART: load = MAINRAM, type = rw; + + IP65_DEFAULTS: load = MAINRAM, type = ro; + CODE: load = MAINRAM, type = ro; + SELF_MODIFIED_CODE: load = MAINRAM, type = rw; + RODATA: load = MAINRAM, type = ro; + DATA: load = MAINRAM, type = rw, define = yes; + HTTP_VARS: load = MAINRAM, type = rw, define = yes; + BSS: load = MAINRAM, type = bss; + + IP65ZP: load = IP65ZP, type = zp; + + ZEROPAGE: load = IP65ZP, type = zp; + + TCP_VARS: load = HIRAM, type = bss; + + } diff --git a/client/cfg/vic20prg.cfg b/client/cfg/vic20prg.cfg index 83e2c0b..7c6c198 100644 --- a/client/cfg/vic20prg.cfg +++ b/client/cfg/vic20prg.cfg @@ -1,23 +1,23 @@ #assumes a fully expanded VIC 20 -MEMORY { - ZP: start = $02, size = $1A, type = rw ; - IP65ZP: start = $5f, size = $10, type = rw; +MEMORY { + ZP: start = $02, size = $1A, type = rw ; + IP65ZP: start = $5f, size = $10, type = rw; RAM: start = $11FF, size = $6e00, file = %O; -} -SEGMENTS { - STARTUP: load = RAM, type = ro ,define = yes, optional=yes; - CODE: load = RAM, type = ro,define = yes; +} +SEGMENTS { + STARTUP: load = RAM, type = ro ,define = yes, optional=yes; + CODE: load = RAM, type = ro,define = yes; DATA: load = RAM, type = rw,define = yes; SELF_MODIFIED_CODE: load = RAM, type = rw,define = yes, optional=yes; - VIC_DATA: load = RAM, type = rw,align = $800, optional=yes; + VIC_DATA: load = RAM, type = rw,align = $800, optional=yes; RODATA: load = RAM, type = ro,define = yes, optional=yes; IP65_DEFAULTS: load = RAM, type = rw,define = yes, optional=yes; BSS: load = RAM, type = bss, optional=yes; # SAFE_BSS: load = RAM3000, type = bss, optional=yes; - APP_SCRATCH: load = RAM, type = bss, optional=yes; - ZEROPAGE: load = ZP, type = zp, optional=yes; + APP_SCRATCH: load = RAM, type = bss, optional=yes; + ZEROPAGE: load = ZP, type = zp, optional=yes; IP65ZP: load = IP65ZP, type = zp, optional=yes; TCP_VARS: load = RAM, type = bss, optional=yes; HTTP_VARS: load = RAM, type = bss, optional=yes; - -} + +} diff --git a/client/drivers/Makefile b/client/drivers/Makefile index b34b02b..69d3774 100644 --- a/client/drivers/Makefile +++ b/client/drivers/Makefile @@ -10,19 +10,27 @@ AFLAGS= $(AS) $(AFLAGS) $< +# a2uther.lib Apple //, with an Uthernet card (cs8900a chipset) in slot #3 +# a2lancegs.lib Apple //, with a LANceGS card (lan91c96) +# c64rrnet.lib C64 with RR-NET or clone at $de0x +# c64wiznet.lib C64 with Wiznet W5100 addressed at $df2x +# vic20rrnet.lib C64 with RR-NET or clone at $980x + DRIVERS=\ - apple2prog.lib \ + a2uther.lib \ + a2lancegs.lib \ c64rrnet.lib \ c64wiznet.lib \ vic20rrnet.lib \ - all: $(DRIVERS) +a2lancegs.lib: a2print.o lan91c96.o a2timer.o a2kernal.o a2input.o a2charconv.o + ar65 a $@ $^ -apple2prog.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o a2charconv.o cs8900a.o +a2uther.lib: a2print.o uthernet.o a2timer.o a2kernal.o a2input.o a2charconv.o cs8900a.o ar65 a $@ $^ c64rrnet.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o cbm_disk_access.o petscii_charconv.o c64_vt100.o cs8900a.o @@ -31,9 +39,7 @@ c64rrnet.lib: c64print.o rr-net.o c64timer.o c64kernal.o c64inputs.o cbm_disk_ac c64wiznet.lib: w5100.o c64print.o c64timer.o c64kernal.o c64inputs.o cbm_disk_access.o petscii_charconv.o c64_vt100.o ar65 a $@ $^ - vic20rrnet.lib: vic20print.o vic20-rr-net.o vic20timer.o vic20input.o cbm_disk_access.o petscii_charconv.o cs8900a.o - ar65 a $@ $^ diff --git a/client/drivers/lan91c96.s b/client/drivers/lan91c96.s new file mode 100644 index 0000000..b6529cc --- /dev/null +++ b/client/drivers/lan91c96.s @@ -0,0 +1,75 @@ +; Ethernet driver for W5100 W5100 chip +; + +.ifndef KPR_API_VERSION_NUMBER + .define EQU = + .include "../inc/kipper_constants.i" +.endif + +.include "../inc/common.i" + + .export eth_init + .export eth_rx + .export eth_tx + .export eth_driver_name + + .import eth_inp + .import eth_inp_len + .import eth_outp + .import eth_outp_len + + + .code + +;initialize the ethernet adaptor +;inputs: none +;outputs: carry flag is set if there was an error, clear otherwise +eth_init: + sec ;FIX ME ! + rts + + +;receive a packet +;inputs: none +;outputs: +; if there was an error receiving the packet (or no packet was ready) then carry flag is set +; if packet was received correctly then carry flag is clear, +; eth_inp contains the received packet, +; and eth_inp_len contains the length of the packet +eth_rx: + sec ;FIX ME ! + rts + + +; send a packet +;inputs: +; eth_outp: packet to send +; eth_outp_len: length of packet to send +;outputs: +; if there was an error sending the packet then carry flag is set +; otherwise carry flag is cleared +eth_tx: + sec ;FIX ME ! + rts + + +.rodata +eth_driver_name: + .asciiz "LANceGS (91C96)" + +; 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 ip65. +; +; The Initial Developer of the Original Code is <## TBD ##> +; Portions created by the Initial Developer is Copyright (C) 2010 +; All Rights Reserved. +; -- LICENSE END -- diff --git a/client/inc/version.i b/client/inc/version.i index 27e2123..99e6447 100644 --- a/client/inc/version.i +++ b/client/inc/version.i @@ -1 +1 @@ -.byte "1.0.36" +.byte "1.0.38" diff --git a/client/ip65/Makefile b/client/ip65/Makefile index 9b10f1d..b856361 100644 --- a/client/ip65/Makefile +++ b/client/ip65/Makefile @@ -3,6 +3,11 @@ LD=ld65 AFLAGS= +# ip65.lib : minimal IP stack (UDP only) +# ip65_tcp.lib : full featured TCP/IP stack +# ip65_wiznet.lib : hybrid stack for use with the w5100 chip : UDP,ICMP & ARP is done on host, TCP is on w5100 + + %.o: %.c $(CC) -c $(CFLAGS) $< @@ -26,7 +31,6 @@ ETHOBJS= \ dottedquad.o \ output_buffer.o\ tftp.o \ - sntp.o \ parser.o \ string_utils.o \ telnet.o \ diff --git a/client/ip65/ip65.s b/client/ip65/ip65.s index 0f4540b..3f47618 100644 --- a/client/ip65/ip65.s +++ b/client/ip65/ip65.s @@ -52,7 +52,7 @@ ip65_error: .res 1 ;last error code ;outputs: AX set to a pseudo-random 16 bit number ip65_random_word: jsr timer_read ;sets AX -; adc $d018 ;on a c64, this is the raster register + adc $9004 ;on a VIC 20, this is the raster register adc $d41b; on a c64, this is a 'random' number from the SID pha adc ip65_ctr_arp diff --git a/client/ip65/sntp.s b/client/ip65/sntp.s deleted file mode 100644 index 948f23d..0000000 --- a/client/ip65/sntp.s +++ /dev/null @@ -1,210 +0,0 @@ -; Simple Network Time Protocol implementation - per RFC 2030 - -MAX_SNTP_MESSAGES_SENT=8 -.include "../inc/common.i" -.ifndef KPR_API_VERSION_NUMBER - .define EQU = - .include "../inc/kipper_constants.i" -.endif - - .export sntp_ip - .export sntp_utc_timestamp - .export sntp_get_time - - .import ip65_process - .import ip65_error - - - .import udp_add_listener - .import udp_remove_listener - - .import udp_callback - .import udp_send - - .import udp_inp - .import output_buffer - .importzp udp_data - - .import udp_send_dest - .import udp_send_src_port - .import udp_send_dest_port - .import udp_send_len - .import check_for_abort_key - .import timer_read - - .segment "IP65ZP" : zeropage - - - .data - sntp_ip: .byte $ff,$ff,$ff,$ff ;can be set to ip address of server that will be queried via sntp (default is a local LAN broadcast) - - .bss - -; sntp packet offsets -sntp_inp = udp_inp + udp_data - -sntp_server_port=123 -sntp_client_port=55123 - -sntp_utc_timestamp: .res 4 ; will be set to seconds (only) part of utc timestamp (seconds since 00:00 on Jan 1, 1900) - -; sntp state machine -sntp_initializing = 1 ; initial state -sntp_query_sent = 2 ; sent a query, waiting for a response -sntp_completed = 3 ; got a good response - -sntp_timer: .res 1 -sntp_loop_count: .res 1 -sntp_break_polling_loop: .res 1 - -sntp_state: .res 1 -sntp_message_sent_count: .res 1 - - - .code - -; query an sntp server for current UTC time -; inputs: -; sntp_ip must point to an SNTP server -; outputs: -; carry flag is set if there was an error, clear otherwise -; sntp_utc_timestamp: set to the number of seconds (seconds since 00:00 on Jan 1, 1900) - timezone is UTC -sntp_get_time: - ldax #sntp_in - stax udp_callback - ldax #sntp_client_port - jsr udp_add_listener - bcc :+ - rts -: - - lda #sntp_initializing - sta sntp_state - lda #0 ;reset the "message sent" counter - sta sntp_message_sent_count - - jsr send_sntp_query - -@sntp_polling_loop: - lda sntp_message_sent_count - adc #1 - sta sntp_loop_count ;we wait a bit longer between each resend -@outer_delay_loop: - lda #0 - sta sntp_break_polling_loop - jsr timer_read - stx sntp_timer ;we only care about the high byte - -@inner_delay_loop: - jsr ip65_process - jsr check_for_abort_key - bcc @no_abort - lda #KPR_ERROR_ABORTED_BY_USER - sta ip65_error - rts -@no_abort: - - lda sntp_state - cmp #sntp_completed - beq @complete - - lda sntp_break_polling_loop - bne @break_polling_loop - jsr timer_read - cpx sntp_timer ;this will tick over after about 1/4 of a second - beq @inner_delay_loop - - dec sntp_loop_count - bne @outer_delay_loop - -@break_polling_loop: - jsr send_sntp_query - inc sntp_message_sent_count - lda sntp_message_sent_count - cmp #MAX_SNTP_MESSAGES_SENT-1 - bpl @too_many_messages_sent - jmp @sntp_polling_loop - -@complete: - - ldax #sntp_client_port - jsr udp_remove_listener - rts - -@too_many_messages_sent: -@failed: - ldax #sntp_client_port - jsr udp_remove_listener - lda #KPR_ERROR_TIMEOUT_ON_RECEIVE - sta ip65_error - sec ;signal an error - rts - - - -send_sntp_query: - - lda #$1B ;LI=00, VN=011,MODE=011 - stax output_buffer - lda #$0 - ldx #$30 ;pad remainder of query packet with 0 bytes - stx udp_send_len - sta udp_send_len+1 -: - sta output_buffer+1,x - dex - bpl :- - ldax #sntp_client_port - stax udp_send_src_port - ldax #sntp_server_port - stax udp_send_dest_port - ldx #3 ; set destination address -: lda sntp_ip,x - sta udp_send_dest,x - dex - bpl :- - - ldax #output_buffer - jsr udp_send - bcs @error_on_send - lda #sntp_query_sent - sta sntp_state -@error_on_send: - rts - - -sntp_in: - - ldx #3 - ldy #0 -: - lda sntp_inp+$28,x ;the 'transmit' timestamp (in big end order) - sta sntp_utc_timestamp,y - iny - dex - bpl :- - - inc sntp_break_polling_loop - lda #sntp_completed - sta sntp_state - rts - - -;-- LICENSE FOR sntp.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 ip65. -; -; The Initial Developer of the Original Code is Jonno Downes, -; jonno@jamtronix.com. -; Portions created by the Initial Developer are Copyright (C) 2009 -; Jonno Downes. All Rights Reserved. -; -- LICENSE END -- diff --git a/client/kipperterm2/timestamp.i b/client/kipperterm2/timestamp.i index 26472d8..b440265 100644 --- a/client/kipperterm2/timestamp.i +++ b/client/kipperterm2/timestamp.i @@ -1 +1 @@ -.byte "2011-01-08" +.byte "2011-01-15" diff --git a/client/test/Makefile b/client/test/Makefile index 4ec62ad..5ad2717 100644 --- a/client/test/Makefile +++ b/client/test/Makefile @@ -11,8 +11,10 @@ IP65TCPLIB=../ip65/ip65_tcp.lib C64RRNETLIB=../drivers/c64rrnet.lib C64WIZNETLIB=../drivers/c64wiznet.lib IP65WIZNETLIB=../ip65/ip65_wiznet.lib -APPLE2PROGLIB=../drivers/apple2prog.lib -VIC20RRNETLIB=../drivers/vic20rrnet.lib +A2UTHERLIB=../drivers/a2uther.lib +A2LANCEGSLIB=../drivers/a2lancegs.lib +VIC20RRNETLIB=../drivers/vic20rrnet.lib + INCFILES=\ ../inc/common.i\ @@ -34,15 +36,15 @@ all: \ testdottedquad.pg2 \ testdottedquad.prg \ test_tcp.prg \ - test_xmodem.prg \ + test_xmodem.prg \ test_vic20.prg \ test_httpd.prg \ test_parser.prg \ test_ping.prg \ - test_sntp.prg \ test_get_url.prg \ - test_wiznet.prg \ - test_parse_querystring.prg \ + test_wiznet.prg \ + test_parse_querystring.prg \ + test_lancegs.pg2 \ # test_xmodem.d64 \ # httpd_test.d64 \ # ip65test.dsk \ @@ -86,19 +88,21 @@ test_ping.prg: test_ping.o $(IP65TCPLIB) $(C64RRNETLIB) $(INCFILES) ../cfg/c64pr 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 - - -test_cifs.prg: test_cifs.o $(IP65TCPLIB) $(C64RRNETLIB) $(INCFILES) ../cfg/c64prg.cfg - $(LD) -m test_cifs.map -vm -C ../cfg/c64prg.cfg -o test_cifs.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64RRNETLIB) - -test_vic20.prg: test_vic20.o $(IP65TCPLIB) $(VIC20RRNETLIB) $(INCFILES) ../cfg/vic20prg.cfg - $(LD) -m test_vic20.map -vm -C ../cfg/vic20prg.cfg -o test_vic20.prg $(AFLAGS) $< $(IP65TCPLIB) $(VIC20RRNETLIB) - -%.pg2: %.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2bin.cfg - $(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2PROGLIB) +test_cifs.prg: test_cifs.o $(IP65TCPLIB) $(C64RRNETLIB) $(INCFILES) ../cfg/c64prg.cfg + $(LD) -m test_cifs.map -vm -C ../cfg/c64prg.cfg -o test_cifs.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64RRNETLIB) + + +test_vic20.prg: test_vic20.o $(IP65TCPLIB) $(VIC20RRNETLIB) $(INCFILES) ../cfg/vic20prg.cfg + $(LD) -m test_vic20.map -vm -C ../cfg/vic20prg.cfg -o test_vic20.prg $(AFLAGS) $< $(IP65TCPLIB) $(VIC20RRNETLIB) + + +%.pg2: %.o $(IP65LIB) $(A2UTHERLIB) $(INCFILES) ../cfg/a2bin.cfg + $(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(A2UTHERLIB) + +test_lancegs.pg2: test_lancegs.o $(IP65LIB) $(A2LANCEGSLIB) $(INCFILES) ../cfg/a2bin.cfg + $(LD) -C ../cfg/a2bin.cfg -o test_lancegs.pg2 $(AFLAGS) $< $(IP65LIB) $(A2LANCEGSLIB) httpd_test.d64: test_httpd.prg index.html file1.html diff --git a/client/test/test_lancegs.s b/client/test/test_lancegs.s new file mode 100644 index 0000000..16ca16c --- /dev/null +++ b/client/test/test_lancegs.s @@ -0,0 +1,47 @@ + .include "../inc/common.i" + .include "../inc/commonprint.i" + .include "../inc/net.i" + + .import cfg_get_configuration_ptr + .import copymem + .importzp copy_src + .importzp copy_dest + + + .import __CODE_LOAD__ + .import __CODE_SIZE__ + .import __RODATA_SIZE__ + .import __DATA_SIZE__ + +.segment "EXEHDR" ;this is what gets put an the start of the file on the Apple 2 + .addr __CODE_LOAD__-$11 ; Start address + .word __CODE_SIZE__+__RODATA_SIZE__+__DATA_SIZE__+4 ; Size + jmp init + +.code + +init: + jsr print_cr + init_ip_via_dhcp + jsr print_ip_config + jsr print_cr + rts + +;-- LICENSE FOR test_ping.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 ip65. +; +; The Initial Developer of the Original Code is Jonno Downes, +; jonno@jamtronix.com. +; Portions created by the Initial Developer are Copyright (C) 2009 +; Jonno Downes. All Rights Reserved. +; -- LICENSE END -- diff --git a/client/test/test_sntp.s b/client/test/test_sntp.s deleted file mode 100644 index 4281618..0000000 --- a/client/test/test_sntp.s +++ /dev/null @@ -1,215 +0,0 @@ - .include "../inc/common.i" - .include "../inc/commonprint.i" - .include "../inc/net.i" - - .import exit_to_basic - .import cfg_get_configuration_ptr - .import dns_set_hostname - .import dns_resolve - .import dns_ip - .import dns_status - .import sntp_ip - .import sntp_utc_timestamp - .import sntp_get_time - - .import __CODE_LOAD__ - .import __CODE_SIZE__ - .import __RODATA_SIZE__ - .import __DATA_SIZE__ - - - .segment "STARTUP" ;this is what gets put at the start of the file on the C64 - - .word basicstub ; load address - -basicstub: - .word @nextline - .word 2003 - .byte $9e - .byte <(((init / 1000) .mod 10) + $30) - .byte <(((init / 100 ) .mod 10) + $30) - .byte <(((init / 10 ) .mod 10) + $30) - .byte <(((init ) .mod 10) + $30) - .byte 0 -@nextline: - .word 0 - -.segment "EXEHDR" ;this is what gets put an the start of the file on the Apple 2 - .addr __CODE_LOAD__-$11 ; Start address - .word __CODE_SIZE__+__RODATA_SIZE__+__DATA_SIZE__+4 ; Size - jmp init - -.code - -init: - - jsr test_vlb - jsr print_cr - init_ip_via_dhcp - jsr print_ip_config - - ldax #time_server_msg - jsr print - ldax #time_server_host - jsr print - jsr print_cr - ldax #time_server_host - jsr dns_set_hostname - bcs @dns_error - jsr dns_resolve - bcs @dns_error - ldx #3 ; set destination address -: lda dns_ip,x - sta sntp_ip,x - dex - bpl :- - - - ldax #sending_query - jsr print - ldax #sntp_ip - jsr print_dotted_quad - jsr print_cr - jsr sntp_get_time - bcc @ok - ldax #sntp_error - jmp @print_error -@ok: - ldy #3 -: - lda sntp_utc_timestamp,y - jsr print_hex - dey - bpl :- - jmp exit_to_basic - -@dns_error: - ldax #dns_error -@print_error: - jsr print - jsr print_errorcode - jmp exit_to_basic - - -.bss -vla: .res 4 -vlb: .res 4 -quotient: .res 4 -remainder: .res 4 - -.code -div_32_32: - lda #0 - sta remainder - sta remainder+1 - sta remainder+2 - sta remainder+3 - ldx #32 -@loop: - asl vla - rol vla+1 - rol vla+2 - rol vla+3 - - rol remainder - rol remainder+1 - rol remainder+2 - rol remainder+3 - - sec - lda remainder+0 - sbc vlb+0 - sta remainder+0 - - lda remainder+1 - sbc vlb+1 - sta remainder+1 - - lda remainder+2 - sbc vlb+2 - sta remainder+2 - - lda remainder+3 - sbc vlb+3 - sta remainder+3 - - bcs @next - lda remainder - adc vlb - sta remainder - - lda remainder+1 - adc vlb+1 - sta remainder+1 - - lda remainder+2 - adc vlb+2 - sta remainder+2 - - lda remainder+3 - adc vlb+3 - sta remainder+3 -@next: - rol quotient - rol quotient+1 - rol quotient+2 - rol quotient+3 - dex - bpl @loop - rts - .rodata - -test_vlb: - ldx #7 -: - lda divs,x - sta vla,x - dex - bpl :- - - jsr div_32_32 - .byte $92 - - - - -time_server_msg: - .byte "TIME SERVER : ",0 - -time_server_host: - .byte "202.174.101.10",0 - .byte "1.AU.POOL.SNTP.ORG",0 - -sending_query: - .byte "SENDING SNTP QUERY TO ",0 -sntp_error: - .byte "ERROR DURING SNTP QUERY",13,0 - -dns_error: - .byte "ERROR RESOLVING HOSTNAME",13,0 - - divs: - .byte $02,$30,$00,$00 - .byte $05,$00,$00,$00 - - - - -;-- LICENSE FOR test_sntp.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 ip65. -; -; The Initial Developer of the Original Code is Jonno Downes, -; jonno@jamtronix.com. -; Portions created by the Initial Developer are Copyright (C) 2009 -; Jonno Downes. All Rights Reserved. -; -- LICENSE END -- diff --git a/client/test/test_vic20.s b/client/test/test_vic20.s index df23063..524b667 100644 --- a/client/test/test_vic20.s +++ b/client/test/test_vic20.s @@ -41,18 +41,22 @@ init: jsr print jsr print_ip_config - jsr beep -@loop: - jsr timer_seconds - cmp last_seconds - beq @loop - sta last_seconds - jsr print_hex - jsr check_for_abort_key - bcc @loop -; jsr get_key_if_available +; jsr beep +;@loop: +; jsr timer_seconds +; cmp last_seconds ; beq @loop +; sta last_seconds +; jsr print_hex +; jsr check_for_abort_key +; bcc @loop +@loop2: + + jsr get_key_if_available + beq @loop2 jsr print_hex + jsr check_for_abort_key + bcc @loop2 rts diff --git a/client/test/testdns.s b/client/test/testdns.s index b0394bd..5d9e0d6 100644 --- a/client/test/testdns.s +++ b/client/test/testdns.s @@ -111,7 +111,6 @@ overwrite_with_hardcoded_dns_server: .rodata -buffer1: .res 256 hostname_1: .byte "SLASHDOT.ORG",0 ;this should be an A record diff --git a/client/wiznet/kipperwizdisk.d64 b/client/wiznet/kipperwizdisk.d64 index 88a0e9f9ce9c5ff491433055998e536d6ad6720e..c66a5430e81fca61283dd727bed85fd86ee88fc1 100644 GIT binary patch delta 20016 zcmajH349bq`ae89ouhM4Ai)tiNjgRCB`RbRBGaUWWfwnUy zdfHKBmB<}Js8h50?x~6Pq@A6SI~nRSA+n+d@0HIwFAX(kE|4F8lpDEUyR`gN2#R*m1Y4Vm1 z%Adn*6bqyM~)1^H*|nUHfhB z1GYVFo7a-Q-!|-kO+9EU0qmenec4ummX~enE4GqX7|Jp2BXoM-YsS-e zz!o@YE4T^&$g13;+zdQB4%jSTN+DA;IkMkoEzTqFbV|PcHtky=LvH(RQi0x~G4QV3 zekEshjkgn5u2{5q<6AcRSDX6{8*R0@LpDXFZ>A^P6p0?Qfy38qG+?8LZ1k{=oXU+H zVzf|v)22nmAwx(cmlZGJEk#;cTgWDQOc-U@bOsF_)AqR`wYpg$7OZFE;frnBg?cP|0Nv zf`{5_^M!1C-m*m#pkUE8gluEFWjteCJ`%90ui4tce!3d4wI8-=u7pU7O-#HlqLT|* zqIZb54PhqI-As15i>TN3Y_n@eqWtL{96&S^Hy#ns-TE z7P)qb|7x;#auqMuU#A@R+RIn0U#Xms|InA~DKG8A_4xn6{LsMM`g_bl|3&kka$6rR z=jzJ`PEY&qp-&kEbNX^U#sc>sn9N~Jj-zchce{Cs;9zx0B=&2z#6ee;~^(O$JTJJrARsx5OyP<^d5l&AG2!CsA;pm6k3 zdb(3wHjE6Ib35#@{zRx(-WTH1VIZ*22_&q{xX>^IQ_k(j^}Tzav-T5bKB%7IYWFj` zXH2yrXJntV{&U|Po@sAa>BbUeuc--Zv$Qpu&}0iGX%}1BE1Fn4q4cyEKiqw|R7pcw zNv@q(s+ejgl{R)E{NOw-UOODHADk}mG_I762bCMpy?@nEbzG@$e5r1G$>dZ){fdT_ zz;KT*ZL;N`$+MOKdt50@e|)JpZ8#J8SZzF(XbP5h9Z?#*OPGm#S8iJ`Vd`}zAJ|A@ zEHz>Av})fOJf&M=T)8Hds%^bOf_4QoTw1{H`c|Wfx{|u*HV1~K{=7s%7 zSR&~*yDf*&1;oV~SrNv|!+5JW$;$_(*=rr1+6nZShA+wgLPAClx*OJwVr6C9Qwi%Qhn<8GBXULM?>v7-bQ6_jx=^s7r`#riXr)NIw zaX;d*V(ll=M?LPxJmS5xt;Nprl}ey|h4O>k|7xz6%V3i6n59dY5n=NvS}ZAXhRk!= z!elbPQ5O>v7o@06^)dk}v%E~d(4I1!!WPmfY$2IWf2;x)|Xq9%lJ}EP0)kUzdM8lVH!w)-txa&AH;D5lp7(J?y$jFDe_25#p7% z4bJ1qol~mflq=%U98zo$k_9*Or1 zri^=PlxNw;XO>P~ogq61aD5UxY*2;TAwM&K+l`ILpG*#ntI8!0jjI}T8J{p8Y&)Hc z*_UlFtA1^D=D^*V`p5fr;59#$qNGH^D^j9~LC-wfia6XSim z#5dh?Ab}eoH(t-}NIBwH>bwWZ`UY}HzI7;fP4fB%G5v8;%If7qxxA!9ekINOG7#j~ zhjQb%H{?r0xd90+dLNk#<2Kq<@2hC8t0oy`SkBZWxpBHdH?Iy?O_Gn3>dMf{fF`e0 zm&Y)BD(&7w`nZ0;iG7zi>Itll8-hy6`vl1V9}JglZ;(@lb5~`3)S$cp`1*#98-kV) zaM42^Kb*Vo=3d~gv_UlqWYI1*!Zmumejuv#17fgI2F}eq>gqi9WSBDy=u{m##em8` z4d-s;?vSVEapO}L8VHGuw7fo#TQX?tK`60RyC5F&$0iB^re8KuCaBIl?yAM0|LX+p z`grelO<4IJC5YJfw4^+zkMTR{f#?;?c&-9vHa8|h6lBK;u5{K$y$AV6xhe?sWnN7Z z=&QV%D)`a_a%?|770DTCf@ocjb6lk5tnzB`&iyv9jbt&^39!E{DCkZj%a9pK%E1J{F1 z{{CdGeANxyHGLTpP#pgoW%*?&kN!8x08rU}1DDf9W#fONuz^0mfg7A38>q1xB@w*j zFkZ&eQ9<|UAhU#+sg4TzQ2(*UKbt%t<rG;C%9$QQW|OziM*F)8eh`m7%&6)TKd) zO*|y;8pRFfa^>(Sd_u;11Lb7>)ygO@Up`>{K&&nkN#Cf;EyIEtAJG}9CH%?-Z>1Dw|RC!?Mak3Jo$h$f3aR48k_{}FHH$*t?fa}`RN{O)M3 zAhmv*sBXZ*V>*{}#&F{juGQ(wcaP!jCgb%oK4F_<1qdX@An{Hm6XeJkuJ|88D7IfIB&C9fUJ<&Hh#SK}mKyhP&# zcY>grB_A)5cb*^zp2WyxX4C1@WZ_2tPvlLvVk&=2vEYR9Ri#oPzcrQ{I-zR~XY|z9 zT9;U*x&cg4smfw~e9QvVE!4|aNngeg%nkXRkDDo<%IAJb3hhzMbbK3`DW4w4)pH@) zJ)WzIpV?FrS0$4P9JwO#rK$v_oW9s5kseK?awEyD!;Sv~dFceMpKEd*vmMnE^koKh z>*4B5DBs4tQhrGDSe+7ypIuJ!16Q19MHuB>pF=Z3U*`y2?XKunV?u|`~Sp+Of|%DcF{=%2I5A9XYJaIM z8n5nZi+(B&uQCQ8XWS&g?B_|+Ga@%!9y5t6&1&CN6;~H;m6#&xxF&)N%Q5-TB(Bf( zcX_L63-5lDSIuT0ZzkLJ0W*$WRX6(D)W$YVsN>0d&sgFjjcu}dGB<&nAWxo*nYDVG ziS5~<0%A3*X=Y!#88zjE0n`#nsu>rTB;q-UcJYg9>vwdg^5Zr)pnB z2V3GpSO2ELztw06P0%ucN|Vj(nPL`Sd?qwryNVoq1{L;9HmiHvv_!?~HIpR9i@{DK z(8crH)ZJ}9#nncAyn8Pnllfgfv9da7!q+0m;cR!)v&t%C!ZV%?nhk)n8^9ZYhr0oB znpNqi*OU?Zi_CbIl|+a%2A|dqM+tD3;`vQ`j?sOw4%F3bY9f{dU6`%f_qdSYsx~Ef z%*= z@okvIOnLcKF1PR2XVFW<^Mx8bb%O8hl$6I|sN`q)#i`sK3oVIsLWi=7PV8XK)Dw2g zVH{OVbaU9fB`oPYk@V-3GP<zxk;-W(plkA+qB@CU}baq;M^!<+M?OH2HM2@t9N+{8iD!%AZ zMze94!eRy4JA+#~caI!0S(3GXgVWpFYwv7VxY|3~YnQb{PL^&}upWjoaXFhC)Kzs+ z8QrDVE>+!lBR3>z^=6d@vBp=+58TK}T&Dc~jodZ;EGd{7E?@2R#&-A2c8T^3y0d~_ zQzf0#P7cdg&E&4jePHwHPvfHL;ABp__`v2*c@46{#@izp=?RLFte~X);@wK7$j+Hu zZ|;IzIg=aeYW6;F$kJOJSrS&4gqbW8U}4xkaeZAKhU_YHFVR(DNU|`jt_+7bErGnW zMSN^aC|*nU7PCH<)c1DgOQASyKvz8PPcncI7EXo<|MhBfPp z2L1L`;pnFwtHau}`hpOb$T!d8uFe0fxprQ=_WkL~E?Mf7yJdM>I3~-PznA5nS={K! z`ub7t3Dal7>e?`UHmusi^trHF5~eklw6L!ztQLojwWZz__SwR}u~WJKY;Gy%lpmPQ zjqdTvR`TcPRYw?J+$V9+NfrCcug~WCaO35F%;pAMXGzCu>lMW0)hB}RQY-{kC{>#q zoeulr#aFiaHU!VE3A3V{Q@~vl_vh!yb@GA&?zz7Gx6vztZfh`dCG=yWR|b_f?^bcj zHcJLw!OP}3+#k$boqYcsE;luyHW~lu1K}c)AU86|!!J}NsqgZ>zw_e#@+Wh+e#Rkj167u*+B4YESUkOn{*b z$3b=ZHh&VS--bT!fABc<0wUjj6E~#axms)?ytwv-I)39xzWGdZ^?(Y?C1rTzBrkF= z$UAQ024tRVj;8E6$pch9;ItMc56kb~#O20YG69jzbGczDOSUQ3c@K%pw~;J)!d$NJ z+?4HL;sjsYz?e`vy)VQ*{2%hZfAHj8)qkDWvv57twR__SrpF{P|;JL@-(uG{V-s^UROj^RHCblFaPlmA?*M)JK zG*Oqldm%T-;tH#e21A|EZzJWbalQNzpt5-pH>Ah99dvbzyRgL@ADGZqE4Em&!HPE1HH_jeb=^XH{M=89cilP94)RtX)WnV*`YS9?t#({Qx+>9d={+INvn;aVD2 zp92DA$=XIqGbor7iRiE%e?NdS6TAJP+YSc{R%W&hzw-E$;hU>P*d3 zcFL=la03~`r7iA1v|z=pY9Y}&vF{E@Aj*@`FIEkPnbL1~_XTFM>NmXa0$)6m#mI0q zImZwZlqcA>+l_|9%})AM*j)i7lXtx!bYAazo)2-+{sx89v44!nXUZ6MngFutMP^-i zfmZ&xZ}@`Ba~JqV#23|d!S*Px#e=`|yi{B|W;7X^X_o!laedtbJ?#lcvm1{Ec81#@ z4{AbSceuSQ7)?HAIj2>cX^tko1M7s2XRGc9&lR@Qb`J)*2qTb{rQ84)EMc1N08lc# zhhvxb`8t4%-bjM_Wj^LM8NJa6(Qem)F-Hl2dWhBl##|!+>LFSK7;}aI*rO^l4*VEk z-2u|SL0RMt#vog}#x;Vp3{Ad&9yhSB?&QK1E&9dP+F3)8rh?r~1gGDR8svlXxNBXD zcC`i*w0}!fC4e=B)qUX-wCoG3`@<#s848Q! z`ok=e>ks?<;XqT^h~$pl#Ui<5cXjx~U6I_qVQXf5ES9@Bj99LpZA*KHgu8>eBM!kM zhklI#qa-P3^m(Z`QR~i`bvJX@Tt8M-q1hp*UbNkat>9bWl zN>~y^{`<{b|Hb$`_QvPYpIv7vYAj+sym8I1v{e&W*hL8-DQMBGb>=35qf;xM)nRsB z)JLe=8O+pHU?=%gu$thzSQn?dg4LM`a=|U!9h063>mYR5tasd^KRxn;EyHI!nh3yRTBnt1=qp%JID7<<;m&-jZ zAD)l+{V@6De6GK(RSodfL<-IaPkdEyAztm9f+MvwCgd$=c}!5Oe=(S)jjF?Cihd7h zl#hJRZ)rf&g}MYV*T}bK3V6T7*ToxR+w(nkRq-KJd{?$D;I4Ar^D+p=59Oc|t8+_RmBi@uvS!5|PSYXfyy3v08>L+-$4d9xqViLWyQB|@~=%^^|0 zIpE92d*jh1bcOa=q@Gt&QFB1*3fVjEycmK6n~n3;C1E;HK1!&3C_eqI}_Hu2hkZgEDl!Dj{} z+DUP0ZsG~?lezMkW!!LAil21u?KUY)fLz=gsbxo@7kIUnZwIlH>I-~3=zTy^{8pf{ zllKl@^|F)qZY2kUc3D^V%wS!rK8QbGitOOE^oW;r$jz`8m%`j6y%)2*e$4cAu6F>M zK<~rd7dor`Q!q0fT9eJox$72mD=;v_Sboe9GGG_XIPlr;(lElg%wW`=Ous4&0a|7& z5W7sgu^yS=urTGvmUFJFGBezXALCY<{;_hDW_%1(;Uk*#k)$SlB$w^tt}r90wq+OB zC!;w`UkSTkWhe5(VX|1Be-}4=>YgU`P|p1<%os{V}^*BsFO)R0|EC%DtS^K7%M>uk-;gk$ul%?)Jd)e;Ty?qdi^XhN)H zqJQO;9*9hVk5_r!v2pJK|1zsOuRVGz3s~LUeiw0}Z`La_PNvsF42CuF=j4Aw<|J6#OcYp!UVDrj|%}XQ~4=8!<^E$NY@Jxm} z4O!^yXZFD7K@a0y@@Ak3$JO=@?4~TR_nnf4cX!`Rfvh+{+B&henaiHsazNhE$Yu9r zvWF-cZzE#7$xBvn*K-%;CsuF+l2#a^BY&4wK$rgK0JJ%;LzkpfP-jw>Y-#UkE!vXV z6EB6ZiZW7v8s)rS%j(P6RSyYI++ofuzy2V1LuOC&WMV2cTp_ngE_;;wLu$`Nv&NGn&-naplAQS%_q9wO8a~0U#l@ zNsmnl63Y@mmc|AocWfYMZuMuW6E#Cb=_KLK0`f{HjymJy+zPI5G13Zd^^PG&XZQ)Ze+-f_ z^;CyMBXOWR!RtHn@EGYgBLNwtv0)t>Q`=l|8ZP(m$o4S^G(TIHYAk_>t$PV`5*;t^ zt$-(YyxdX2^~#U+z$s`2(vwhQc0Gv|>P$U*G(Vdfy1onkO{KTFu7Z)w@I~Z48@T?i zu&vJYsVSP?w4!=dtMSwnWg2A>BR>-{hr$9QwZxjEiJ+zCQ&A&%!P5ti@qf zQr}*S>vW1b+V1j=v6H@I{Y%K`v1IC4a>Fg&eHKtLbQaWwD8lvE$tGk#}u*;rcaR0mtCNXrHFS z58hd;CAJ2WwQsFbeWCnnC70n!l(ZC8kib&{9Bp^NzWBhE(#I!knh1A^l7!5N@AAP; zk_35z879mhAk0V>cRAB$#xx(ukiee7>hGC^Hvm&NYujTq4Z*q$`6M;Jv$ndB$wzr7 z#&uG_YOft&52V{`t@c2iy*Aw*_;GD*oIMa-Tl?eMz!z(4qiX{nt*!k6Vm@A%1POnn zOIS%D;#i30JQL+NOyL)pq`oc0m;AdzC60byC_z|=la^fduB)IV-<~8iK6=6SDC|YM z*jQ9D);@2XT_Oo%$-$f9B`K%lQ4206OU9DqIS8RXb&KDkcG^N&W&sXblY|VWgeWIP z^6lcP{Kz=F*nf^5**Rfj=Eczob|u9-fts9d&Z!4t{xGjfk1I|@UU18Jb)vnPqm%96 zaf%&`xhL7lGvi3+5{$i`jg8RG6gwh27Z#tLWRHHgM4e!V@-m>j z6hs)(5Fg19KN&|_#Q zU^Ji7n?KW=KhKKO5&oqkuy7XWf1x9MsUw`$o6oRjJ(!igf(5g3CJ@_Lrnq=lltr^( zAsm!1G1-i!ZWnsm3ZUaZ)5?)61T81`p^_&aRFJ8rL?W_N)e%Q)pWzGL4w+rF{DzEQI`-5nK> z2M~v^L3~8BYb=|#Z)Jfx+wLo{*WSd;WwyPj(OqCyHG5WkG)dew5#Y#dyB<(0ni!a4 zkFs#uO?D%kHXhrN`i@->r+wp{6k7_TBU7;nPPG$bJ#h3Gqddn>ZkeRcVQZp|)!X$o z@z(FwgnG;lYmdd#+S_Bx<1IVlX>E4I({7m*nPUf)5R0dMIT2wrjKkJIte~$2Fy)$Q z_sz1OE;iAbcK0khmWBI$C<8|Lf!+Nf#z#2uA9nXgtYo4e+ui@PV`aGYmEp$9Fa>V1 zXC+{HoVEyv8;-Y&(Mchb9-;fpUi&YQs{Pzv`-MFgp))kYc%b^?@VfZGDVuKkMu<*d zC^6HA>dcS{JFpWeHzQ<L3YLzk9MbHPBazrdlf> z?JE^?jsAzLzCIo3hwVK;@X+kce+vxDD!c%WcWJ}HT5@BZiS%9d!Yt5T!iK2i{ zV~5?1@i=Hf0)C^oWHP7>*1Mnson{A=PR~lT2l`8Nh8?5O8||=MsFHOu`b)H-b6RUI;>N%6DDLOsW(w^&s03i zi`UOR4@ zUtok(zd&bGG|~dfh&HM-5Qz}Y)73c?pM73@avE%PCRVMb60s*<{An6U%%Nh!^h)2i zwDtgvd`m-7jj%m{st0Jus%2q)6;9vtG>tq>x6GxdU6r8}Ey8-xnKblc)EfFJdUfdM zXy4E;(JMp$(LD+}MOfe*3PRs9@>oU2Fmx7G(Jw3cr|4Mpnv5PP>MRTty*<=FI$8PI z_cW~)DYnzO6!6-4Y+U0%ohflu!gPkuMUya%WaU5Ni_?@}x*p)Q^fF#65s{6EfoaN5 zK&T|Q-Okv?mG6sUWF+0A7SL$AIveKHQ9wIpQ!z3XPe>&qKmQ!J+$GPzh-UP=zeDgv_p!<|S` zjq-^>=yQWmQH+pUgx@q&`IV>H-c>L&vZ_X1Tcf!qfKFizT~R|<)*yG_IeMqyUWVUZ zkeda@!_C5+PCW1-zgx$@hV&Pz2B>$}gvzul_3cwPK;;h@EOnvIEaReteTBRT&W9jCHl#mmZkp;MgIX6W-V4u$7dfC#Lw4gQ4KAw zfeC@*M#1-zKtFT1KX)igyfclZDbc=yyPrVh8Kj(vDo23>Ra*b41MxdDU63>dZ>RTAu>Nv3}*h;dJ%oim&3qqwnsT+R@J$@{B+Ych^`>A(Na*ZO}?&(AX+VphReY@Y$ex38{&ewi#WdSLW(q>m6A`fFGY zW)C#0`kBM`xx*FHg0Wq2T{{K)>C<;!%JyzLTyWHW(=1_*vm zVtZ|pew>aJ*GTMq{q^GZe>t?1iV2QzyT@JPsWWZ-lV{_-o{jf;Ha_4X%Vs0l!S3;u zc*I+083o2PzB6}6NoaPoPpAkd?gF?%>#%firZ&?*d5{8euSZ-k3ufs;Z5C=Eg!Bje z3gu(=8w!>KfrXYo3m*>s$0+!407F^eO(#94AP3^ktc)qK-<8~=!}Jds&cd;;-Gd(b zkVpNK2cKcfo(Da+c=x3bcp?va#Ex0m-g!}+jZBG$Jk73@^y*c(Q6W|0A&+=!mW~`E zRcXN8^N^={6~Nk8UXIZ+Ye)bKWTYdF;vo;<)vH(<#j@G|HMTKgc4&Mw69>fKkow$f zMrS1rcX=fl4;Pp?rkztv)vMTf#`uK{)TN7*q)dUkE?w+7g?z_UsXpxSJ>sD*kGssH zW?3Hf_#X4n$35;RJmlxlqy|YhE--mPw49M_{uzne0Nu`!e_p#9{ak% zX7km@J?H#Ff%=5!T$50BEq%gM1O^S`#SbQ|=v0C)pv$9{c}ifjy7_zV}PzYuDSedfcxNrV8(n^)^T=fo$Ex2J-c;3NNb&jd73zh;;==Nk@E=#N$OjzqI9bSm%>N>~ z9+*%6?QoxUfP<)mo_DBc9Y{^cHX%D^Z3!SzM=J{FSrf~Sv3HzxAUh`NK=&xb$=>H3 z$d389gJsA3+fmW9)@t-acFcJ;^Qfca-wtHQ{M*r$9dj9BmrfbkG3__y{12+<9V|O0 ziYJqMr$bV+B|ST)(}C=mPRFspFOK$XNzaZ!Zp;r3`cALFPY!y#7kRrE*6Y^}-Rl@1 zxWK$1jCJbwBNNvBD*+?qh9q{|*Mq}g2j8ubd8k3bXG;J7WU zf$cEKePe^%fS~K^f2ssdEx6XeVOIvuFAkQ0)9FA4PN$>x7l(S$QTu~Kz2vC<$>q>f zaDa>y9N@tP*Oh_;7*cTl!#V_hWE}!Oqk}_F!RbUd1kTraws32V6rA`q;3;7Zn5DuR znzV){uZe8%K>QURwZh}u;GrpN+^K8e#V7Nk30u0dD^4r=UgSVS9mm*pR+;Uy&W0keVmfo$Ej!KWI5Zd60&lv&h{&$uB;sPr3<7w z>EC+=EKYi&7kL*pLi=X(PIo`&9`x+W%R%qHPUPjFcRwe~%jx4pUQQq9mMmxG7OPV= zIk%)bRnED^;>4!>6x)>XA$IlcqJzAg-;%g2F9*XQFDIMPYQEA5YRzekT5~3&rsw7K z0a5+ql?ILAtF0zGeJM_C!?07c6Bf$$2L5b2ZUPVXT773Dv7fPN)r8Ic8=M zDQjrz8p^GKXG-5XK#Ey(@){bqX1AK+EH*Jy;j`n`bm!$1-eg#cF&GDb?L{bGOjfjcFSxe}aAT@l1z&bNip~GaovGFf2uXdkknN5vz~6g;i+*F%1N^-g zP^|4ltXBwI;G;KQGQK%Z}HcoA6#KQDsPSk?gsN7jMi^JQ5F`f-va0Q6p9 zWE}`b>HynRRxZX#2riQBM1)%OyaUL8F+He14?yvBkKk4XwrlJZA}?a5i@G}p8U)>v zjJ$&}z*@Fg-NT+bBTUYEbRNTYLCSrB1Hg(QRV^8GuxG1oKBaP&o;9es5n zcZqiULUHlJ%S9`{w-bq6*@Do%SAg)gFVuzS6Jo;KD=^{3cgv2Ibbh*J#{^->PA_eT zTDzq4D-T8{f-Y?%6G1PsJOp%Z62|L^2q^jmmWUw45)t%yutbD%vl*c!8n=ng10I$q|6KJx8O`t)jO_TJL5%qvTdr9g+fo4nUivq1z0suA1j(z}tNzz|OS3ez(b1W+N%hAsw4W)QkWj1+~KIyf*Y zkupJCCy+;k>}0&;s&XINet} zfiTEP%uDD%XDAB}jI`)jb&#`tfHV4)N}Rr{^}h>HXR2QrO~d`>MEgKzG%h=(RlH+~ zI?%aikaNp5PF!pwgPh{1C8+Az4c9oWSa(k5EFI*;Np{qdjzJ6;@$hS$Ms|aF)Dk&( z7nd(Pc5`X-*_|XPxQ_~0MYqxx!Tl!N&0Z5|Kv08%@2Eg-x>efvnt;D*5fCCr1@(xa z<*M)5eedg6F{3YiU2q=}Dk>_PKak(r&0RU9^;VYqU|-5|2ZZd@?$GH1Qgs`tzYU23 z@0Gx2aS4&r6>fO8>sBKZLWm+0LJ+fVW8o$lH{K~O7XKi(v2=#_>@1x@P~W%HR|VZU z47icb@PR$o6&>FEksWu@x@aP46$?D zx0aoDR7^Bb0h82bdiS!LYVv|dS1nf(Vq=*)|Pa`)n!QfwB+{g{eS?c(0B13F$ znm{sc>&jz*+vXR!u93Sc$sja>=!C4ZCwZ6FITSs>oY8P7mP(PG-s!)#OGa8BJ^btXa^A0H^=0h+wMW=qKP<(^&w5mrG^t=_*wS;JY5sXg5_k%UBt0m+6-g=41X0PW#{o|LPf&~ zh7-C9C$NlivlL3ykozT1-GiJ&z@<;E8Yi9Jd7L3N=4JrP1gy&3D8_s2j?JMv0qJD@ za$xWe-4V()UIUHSjc^Cwf4lg{J3{lc0pKG|OJ#gK$@l;imogr&V>)?;H4|BzCAY`A zEE%iytj{RVtben-N5hGo$Jh5E%}hNjk^uokBN zEuDqN+U{sbH&_DBjLUJ311B`tAGceK-cdJL7agN>BYq^t5ngY%A6%tj?%uf!RZL@iO_vNQEgp=9Ph(;C@{YU}~;*jlom``Q$FfCHocAfAo^sr6q#9 z&|T#ntYHnb@cNyh0&NWPgp<7{-E7c+?)XV$zn!TX*IE(0(x0_15ujK##~lVanjS)khoJ= z|Mt3f8sc{*tiQ1CTeeo1wH{v1O67@_1)B@%6GOo&UhIEYsIDsh%vACF<)Jd8E}>3X zeQH+&LBsdUf!pwA)SOhd^LQ|)DyaaAu&BUwkag$8-QAHSmb@6pi@sKD&S z9cMJsz+pW&Ea%t7)q}(Gq;<)s0jnF_lvvF-#aAa)SiZwTf1kA7B{jg4_g~n@{tG+J zz+Rs{XI(GM6fU4_?B9o%w~B}KokH)Rkm|$=%TINKm5gd!fPP{!*?An$w_Afb+7IO& tsAN=M&@03tztF_Z?#na}l`0unl%_%^M8|StVPkE}=6&4P4g0xE{|{krMFIc- delta 19860 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 fN+z6 Ethernet driver - CS8900A + CS8900A (RR-NET/Uthernet) + Wiznet W5100 + - - Ethernet interface - RR-Net / TFE - Uthernet - Host computer - C64/C128 - Apple ][ + C64/C128 + Apple ][ + VIC-20 + @@ -162,6 +161,7 @@ IP65 is a TCP/IP stack for 6502 based computers.
   Release	Maintainer	Changes
   -------	----------	-------
+  2011-01-15	Jonno Downes	drivers for Wiznet W5100 ethernet, VIC-20 host
   2009-12-23	Jonno Downes	TCP and telnet bugfixes, vt100 emulation, XMODEM support
   2009-10-31	Jonno Downes	Added Web Application Server functions
   2009-08-02	Jonno Downes	More TCP functionality, includes telnet