WebNoter
-%?mhey %$h, thanks for saying '%$m'!%.
-Your Handle:
-Your Message:
-
-
\ No newline at end of file
diff --git a/client/examples/gamemusic.bin b/client/examples/gamemusic.bin
deleted file mode 100644
index 92a3753..0000000
Binary files a/client/examples/gamemusic.bin and /dev/null differ
diff --git a/client/examples/httpd.asm b/client/examples/httpd.asm
deleted file mode 100644
index 3932013..0000000
--- a/client/examples/httpd.asm
+++ /dev/null
@@ -1,471 +0,0 @@
-;NB65 API example in DASM format (http://www.atari2600.org/DASM/)
- processor 6502
-
- include "../inc/nb65_constants.i"
-
- ;useful macros
- mac ldax
- lda [{1}]
- ldx [{1}]+1
- endm
-
- mac ldaxi
- lda #<[{1}]
- ldx #>[{1}]
- endm
-
- mac stax
- sta [{1}]
- stx [{1}]+1
- endm
-
- mac cout
- lda [{1}]
- jsr print_a
- endm
-
- mac print_cr
- cout #13
- jsr print_a
- endm
-
- mac nb65call
- ldy [{1}]
- jsr NB65_DISPATCH_VECTOR
- endm
-
- mac print
-
- ldaxi [{1}]
- ldy #NB65_PRINT_ASCIIZ
- jsr NB65_DISPATCH_VECTOR
- endm
-
-
-
-protocol_http equ $00
-protocol_gopher equ $01
-
-;some routines & zero page variables
-print_a equ $ffd2
-temp_ptr equ $FB ; scratch space in page zero
-
-
-;start of code
-;NO BASIC stub! needs to be direct booted via TFTP
- org $1000
-
- jsr init_tod
-
- ldaxi #NB65_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in)
- jsr look_for_signature
- bcc found_nb65_signature
-
- ldaxi #NB65_RAM_STUB_SIGNATURE ;where signature should be in a RAM stub
- jsr look_for_signature
- bcs nb65_signature_not_found
- jsr NB65_RAM_STUB_ACTIVATE ;we need to turn on NB65 cartridge
- jmp found_nb65_signature
-
-nb65_signature_not_found
- ldaxi #nb65_api_not_found_message
- jsr print_ax
- rts
-
-found_nb65_signature
-
- lda NB65_API_VERSION
- cmp #02
- bpl .version_ok
- print incorrect_version
- jmp reset_after_keypress
-.version_ok
- print #initializing
- nb65call #NB65_INITIALIZE
- bcc .init_ok
- print_cr
- print #failed
- print_cr
- jsr print_errorcode
- jmp reset_after_keypress
-.init_ok
-
-;if we got here, we have found the NB65 API and initialised the IP stack
-;print out the current configuration
- nb65call #NB65_PRINT_IP_CONFIG
-
-
-
-
-listen_on_port_80
-
- ldaxi #scratch_buffer
- stax tcp_buffer_ptr
- print #waiting
- ldaxi #80 ;port number
- stax nb65_param_buffer+NB65_TCP_PORT
- stx nb65_param_buffer+NB65_TCP_REMOTE_IP
- stx nb65_param_buffer+NB65_TCP_REMOTE_IP+1
- stx nb65_param_buffer+NB65_TCP_REMOTE_IP+2
- stx nb65_param_buffer+NB65_TCP_REMOTE_IP+3
- ldaxi #http_callback
- stax nb65_param_buffer+NB65_TCP_CALLBACK
- ldaxi #nb65_param_buffer
- nb65call #NB65_TCP_CONNECT ;wait for inbound connect
- bcc .connected_ok
- print #error_while_waiting
- jsr print_errorcode
- jmp reset_after_keypress
-.connected_ok
-
- print #ok
- lda #0
- sta connection_closed
- sta found_eol
- clc
- lda $dc09 ;time of day clock: seconds (in BCD)
- sed
- adc #$30
- cmp #$60
- bcc .timeout_set
- sec
- sbc #$60
-.timeout_set:
- cld
- sta connection_timeout_seconds
-
-
-.main_polling_loop
- jsr NB65_PERIODIC_PROCESSING_VECTOR
-
- lda found_eol
- bne .got_eol
-
- lda $dc09 ;time of day clock: seconds
-
- cmp connection_timeout_seconds
- beq .connection_timed_out
-; nb65call #NB65_PRINT_HEX
- lda connection_closed
- beq .main_polling_loop
- jmp listen_on_port_80
-
-.connection_timed_out:
- print #timeout
- jmp listen_on_port_80
-.got_eol:
-
- ;if we have a CR, we have got enough of a request to know if it's a HTTP or gopher request
- lda #"G"
- cmp scratch_buffer
- bne .gopher
- lda #"E"
- cmp scratch_buffer+1
- bne .gopher
- lda #"T"
- cmp scratch_buffer+2
- bne .gopher
- lda #" "
- cmp scratch_buffer+3
- bne .gopher
- lda #protocol_http
- sta protocol
- print #http
- ldx #4
- jmp .copy_selector
-.gopher
- jsr print_a
- lda #protocol_gopher
- sta protocol
- print #gopher
- ldx #0
-
-.copy_selector:
- lda scratch_buffer,x
- cmp #"/"
- bne .copy_one_char
- inx
-.copy_one_char
- lda scratch_buffer,x
- cmp #$20
- bcc .last_char_in_selector
- sta selector,y
- inx
- iny
- bne .copy_one_char
-
-.last_char_in_selector
- lda #0
- sta selector,y
-
- print #selector
-
- ;ldaxi #html_length
- ldaxi #index_html_buffer_length
- stax nb65_param_buffer+NB65_TCP_PAYLOAD_LENGTH
-; ldaxi #html
- ldaxi #index_html_buffer
- stax nb65_param_buffer+NB65_TCP_PAYLOAD_POINTER
- ldaxi #nb65_param_buffer
- nb65call #NB65_SEND_TCP_PACKET
-
- nb65call #NB65_TCP_CLOSE_CONNECTION
-.start_new_connection
- jmp listen_on_port_80
-
-
-
-
-
-;look for NB65 signature at location pointed at by AX
-look_for_signature subroutine
- stax temp_ptr
- ldy #3
-.check_one_byte
- lda (temp_ptr),y
- cmp nb65_signature,y
- bne .bad_match
- dey
- bpl .check_one_byte
- clc
- rts
-.bad_match
- sec
- rts
-
-print_ax subroutine
- stax temp_ptr
- ldy #0
-.next_char
- lda (temp_ptr),y
- beq .done
- jsr print_a
- iny
- jmp .next_char
-.done
- rts
-
-get_key
- jsr $ffe4
- cmp #0
- beq get_key
- rts
-
-reset_after_keypress
- print #press_a_key_to_continue
- jsr get_key
- jmp $fce2 ;do a cold start
-
-
-;init the Time-Of-Day clock - cribbed from http://codebase64.org/doku.php?id=base:initialize_tod_clock_on_all_platforms
-init_tod:
- sei
- lda #0
- sta $d011 ;Turn off display to disable badlines
- sta $dc0e ;Set TOD Clock Frequency to 60Hz
- sta $dc0f ;Enable Set-TOD-Clock
- sta $dc0b ;Set TOD-Clock to 0 (hours)
- sta $dc0a ;- (minutes)
- sta $dc09 ;- (seconds)
- sta $dc08 ;- (deciseconds)
-
- lda $dc08 ;
-.wait_raster
- cmp $dc08 ;Sync raster to TOD Clock Frequency
- beq .wait_raster
-
- ldx #0 ;Prep X and Y for 16 bit
- ldy #0 ; counter operation
- lda $dc08 ;Read deciseconds
-.loop1
- inx ;2 -+
- bne .loop2 ;2/3 | Do 16 bit count up on
- iny ;2 | X(lo) and Y(hi) regs in a
- jmp .loop3 ;3 | fixed cycle manner
-.loop2
- nop ;2 |
- nop ;2 -+
-.loop3
- cmp $dc08 ;4 - Did 1 decisecond pass?
- beq .loop1 ;3 - If not, loop-di-doop
- ;Each loop = 16 cycles
- ;If less than 118230 cycles passed, TOD is
- ;clocked at 60Hz. If 118230 or more cycles
- ;passed, TOD is clocked at 50Hz.
- ;It might be a good idea to account for a bit
- ;of slack and since every loop is 16 cycles,
- ;28*256 loops = 114688 cycles, which seems to be
- ;acceptable. That means we need to check for
- ;a Y value of 28.
-
- cpy #28 ;Did 114688 cycles or less go by?
- bcc .hertz_correct ;- Then we already have correct 60Hz $dc0e value
- lda #$80 ;Otherwise, we need to set it to 50Hz
- sta $dc0e
-.hertz_correct
- lda #$1b ;Enable the display again
- sta $d011
- cli
- rts
-
-
-print_errorcode
- print #error_code
- nb65call #NB65_GET_LAST_ERROR
- nb65call #NB65_PRINT_HEX
- print_cr
- rts
-
-;http callback - will be executed whenever data arrives on the TCP connection
-http_callback
-
- ldaxi #nb65_param_buffer
- nb65call #NB65_GET_INPUT_PACKET_INFO
- lda nb65_param_buffer+NB65_PAYLOAD_LENGTH+1
- cmp #$ff
- bne .not_eof
- lda #1
- sta connection_closed
- rts
-.not_eof
-
- lda #"*"
- jsr print_a
- ldax nb65_param_buffer+NB65_PAYLOAD_POINTER
- stax tcp_inbound_data_ptr
- ldax nb65_param_buffer+NB65_PAYLOAD_LENGTH
- stax tcp_inbound_data_length
-
-;copy this chunk to our input buffer
- ldax tcp_buffer_ptr
- stax nb65_param_buffer+NB65_BLOCK_DEST
- ldax tcp_inbound_data_ptr
- stax nb65_param_buffer+NB65_BLOCK_SRC
- ldax tcp_inbound_data_length
- stax nb65_param_buffer+NB65_BLOCK_SIZE
- ldaxi #nb65_param_buffer
- nb65call #NB65_BLOCK_COPY
-
-
-;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
-
-;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
- ldaxi #scratch_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
-
-
-
-;constants
-nb65_api_not_found_message dc.b "ERROR - NB65 API NOT FOUND.",13,0
-incorrect_version dc.b "ERROR - NB65 API MUST BE AT LEAST VERSION 2.",13,0
-
-nb65_signature dc.b $4E,$42,$36,$35 ; "NB65" - API signature
-initializing dc.b "INITIALIZING ",13,0
-error_code dc.b "ERROR CODE: $",0
-error_while_waiting dc.b "ERROR WHILE "
-waiting dc.b "WAITING FOR CLIENT CONNECTION",13,0
-press_a_key_to_continue dc.b "PRESS ANY KEY TO CONTINUE",0
-mode dc.b " MODE",13,0
-disconnected dc.b 13,"CONNECTION CLOSED",13,0
-failed dc.b "FAILED ", 0
-ok dc.b "OK ", 0
-timeout dc.b 13,"CONNECTION TIMEOUT ",13, 0
-
-transmission_error dc.b "ERROR WHILE SENDING ",0
-http: dc.b "HTTP: ",0
-gopher: dc.b "GOPHER: ",0
-;self modifying code
-get_next_byte
- lda $ffff
- inc get_next_byte+1
- bne .skip
- inc get_next_byte+2
-.skip
- rts
-
-reset_output_buffer
- sta emit_a+1
- stx emit_a+2
- lda #0
- sta output_buffer_length
- sta output_buffer_length+1
- rts
-
-emit_a
- sta $ffff
- inc emit_a+1
- bne .1
- inc emit_a+2
-.1
- inc output_buffer_length
- bne .2
- inc output_buffer_length+1
-.2
- rts
-
-;variables
-protocol ds.b 1
-connection_closed ds.b 1
-connection_timeout_seconds ds.b 1
-found_eol ds.b 1
-nb65_param_buffer DS.B $20
-tcp_buffer_ptr ds.b 2
-scan_ptr ds.b 2
-tcp_inbound_data_ptr ds.b 2
-tcp_inbound_data_length ds.b 2
-output_buffer_length: ds.b 2
-selector: ds.b $100
-scratch_buffer: ds.b $1000
-index_html_buffer: ds.b $1000
-index_html_buffer_length: ds.b 2
-gopher_map_buffer: ds.b $1000
-
-
-
-;-- LICENSE FOR httpd.asm --
-; 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/examples/irc.s b/client/examples/irc.s
deleted file mode 100644
index 4e8accf..0000000
--- a/client/examples/irc.s
+++ /dev/null
@@ -1,324 +0,0 @@
-
-.include "../inc/common.i"
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-print_a = $ffd2
-
-.import ascii_to_native
-
-.macro kippercall function_number
- ldy function_number
- jsr KPR_DISPATCH_VECTOR
-.endmacro
-
-.zeropage
-temp_buff: .res 2
-pptr: .res 2
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- .import cls
- jsr cls
- lda #14
- jsr print_a ;switch to lower case
-
- ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in)
-look_for_signature:
- stax temp_buff
- ldy #5
-@check_one_byte:
- lda (temp_buff),y
- cmp kipper_signature,y
- bne @bad_match
- dey
- bpl @check_one_byte
- jmp @found_kipper_signature
-
-@bad_match:
- ldax #kipper_api_not_found_message
- jsr print
- rts
-@found_kipper_signature:
- ldax #init_msg
- jsr print
- kippercall #KPR_INITIALIZE
- bcc @init_ok
- jsr print_cr
- ldax #failed_msg
- jsr print
- jsr print_cr
- jsr print_errorcode
- jmp reset_after_keypress
-@init_ok:
-;if we got here, we have found the KIPPER API and initialised the IP stack
- jsr print_ok
- jsr print_cr
- ldax #connecting_msg
- jsr print
- jsr connect_to_irc
- bcc @connect_ok
- jsr print_errorcode
- jmp reset_after_keypress
-@connect_ok:
-
- jsr print_ok
- jsr print_cr
- jsr send_nick
- jsr send_user
- jsr send_join
-
-@endless_loop:
- jsr KPR_PERIODIC_PROCESSING_VECTOR
- jmp @endless_loop
-
-print_ok:
-ldax #ok_msg
-jmp print
-
-reset_after_keypress:
- ldax #press_a_key_to_continue
- jsr print
-@wait_key:
- jsr $f142 ;not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD)
- beq @wait_key
- jmp $fce2 ;do a cold start
-
-print_errorcode:
- ldax #error_code
- jsr print
- kippercall #KPR_GET_LAST_ERROR
- kippercall #KPR_PRINT_HEX
- jmp print_cr
-
-
-print:
- sta pptr
- stx pptr + 1
-
-@print_loop:
- ldy #0
- lda (pptr),y
- beq @done_print
- jsr print_a
- inc pptr
- bne @print_loop
- inc pptr+1
- bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-)
-@done_print:
- rts
-
-print_cr:
- lda #13
- jmp print_a
-
-
-connect_to_irc:
- ldax #irc_server
- stax param_buffer
- ldax #param_buffer
- kippercall #KPR_DNS_RESOLVE
- bcs @exit
-
- ;IP address now set
- ldax irc_port
- stax param_buffer+KPR_TCP_PORT
- ldax #irc_callback
- stax param_buffer+KPR_TCP_CALLBACK
- ldax #param_buffer
- kippercall #KPR_TCP_CONNECT
-
-@exit:
- rts
-
-send_nick:
- ldx #0
-:
- lda nick_msg,x
- beq :+
- sta command_buffer,x
- inx
- bne :-
-:
- ldy #0
-:
- lda nick,y
- beq :+
- sta command_buffer,x
- iny
- inx
- bne :-
-:
-
-add_crlf_and_send_command:
- lda #13
- sta command_buffer,x
- inx
- lda #10
- sta command_buffer,x
- inx
- txa
- ldx #0
- stax param_buffer+KPR_TCP_PAYLOAD_LENGTH
- ldax #command_buffer
- stax param_buffer+KPR_TCP_PAYLOAD_POINTER
- ldax #param_buffer
- kippercall #KPR_SEND_TCP_PACKET
- rts
-
-send_user:
- ldax #user_msg_length
- stax param_buffer+KPR_TCP_PAYLOAD_LENGTH
- ldax #user_msg
- stax param_buffer+KPR_TCP_PAYLOAD_POINTER
- ldax #param_buffer
- kippercall #KPR_SEND_TCP_PACKET
- rts
-
-send_join:
- ldx #0
-:
- lda join_msg,x
- beq :+
- sta command_buffer,x
- inx
- bne :-
-:
- ldy #0
-:
- lda irc_channel,y
- beq :+
- sta command_buffer,x
- iny
- inx
- bne :-
-:
-
- jmp add_crlf_and_send_command
-
-irc_callback:
- ldax #param_buffer
- kippercall #KPR_GET_INPUT_PACKET_INFO
- lda param_buffer+KPR_PAYLOAD_LENGTH+1
- cmp #$ff
- bne @not_eof
- rts
-@not_eof:
- ldax param_buffer+KPR_PAYLOAD_POINTER
- stax pptr
- ldax param_buffer+KPR_PAYLOAD_LENGTH
- stax input_length
-:
-
-@print_loop:
- ldy #0
- lda (pptr),y
- jsr ascii_to_native
- jsr print_a
- dec input_length
- lda input_length
- cmp #$ff
- bne :+
- dec input_length+1
- lda input_length
- cmp #$ff
- beq @done_print
-:
- inc pptr
- bne @print_loop
- inc pptr+1
- bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-)
-@done_print:
- rts
-
-.bss
-param_buffer: .res 20
-command_buffer: .res 256
-input_length: .res 2
-
-.data
-
-irc_server:
- ;.byte "irc.newnet.net",0
- .byte "jamtronix.com",0
-irc_port:
- .word 6667
-irc_channel:
- .byte "#foo",0
-
-
-nick_msg:
- .byte "NICK ",0
-
-nick:
- .byte "kipper_nick2",0
-
-join_msg:
- .byte "JOIN ",0
-
-user_msg:
- .byte "USER kipper 0 unused :A Kipper User",13,10
-user_msg_length=*-user_msg
-
-kipper_api_not_found_message:
- .byte "ERROR - KIPPER API NOT FOUND.",13,0
-
-failed_msg:
- .byte "FAILED", 0
-
-ok_msg:
- .byte "OK", 0
-init_msg:
- .byte "INITIALIZING ",0
- connecting_msg:
- .byte "CONNECTING ",0
-
-press_a_key_to_continue:
- .byte "PRESS A KEY TO CONTINUE",13,0
-
-kipper_signature:
-.byte $4B,$49,$50,$50,$45,$52 ; "KIPPER"
-
-error_code:
- .asciiz "ERROR CODE: "
-
-
-
-
-;-- LICENSE FOR irc.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/examples/make_sine_data.rb b/client/examples/make_sine_data.rb
deleted file mode 100644
index 9666bf2..0000000
--- a/client/examples/make_sine_data.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-f=File.open("sine_data.i","w")
-
-TABLE_ENTRIES=0x80
-AMPLITUDE=255
-OFFSET=00
-
-TABLE_ENTRIES.times do |i|
- value=OFFSET+Math.sin(Math::PI*i.to_f/TABLE_ENTRIES.to_f)*AMPLITUDE
- if i%0x08==0
- f<<"\n.byte "
- else
- f<<", "
- end
- f<<"$%02x" % value
-end
-
-f.close
-
-
-#-- LICENSE FOR make_sine_data.rb --
-# 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/examples/powertrain.bin b/client/examples/powertrain.bin
deleted file mode 100644
index b6aa81a..0000000
Binary files a/client/examples/powertrain.bin and /dev/null differ
diff --git a/client/examples/raster.s b/client/examples/raster.s
deleted file mode 100644
index 230b898..0000000
--- a/client/examples/raster.s
+++ /dev/null
@@ -1,293 +0,0 @@
-
-.include "../inc/common.i"
-
-print_a = $ffd2
-
-
-SCREEN_RAM = $0400
-COLOUR_RAM = $d800
-VIC_CTRL_A = $d011
-VIC_RASTER_REG = $d012
-VIC_CTRL_B = $d016
-VIC_MEMORY_CTRL=$d018
-VIC_IRQ_FLAG = $d019
-
-
-IRQ_VECTOR=$314
-
-BORDER_COLOR = $d020
-BACKGROUND_COLOR_0 = $d021
-SCROLL_DELAY=4
-CHARS_PER_LINE = 40
-SCROLL_LINE=12
-SCROLL_RAM = SCREEN_RAM+(SCROLL_LINE*CHARS_PER_LINE)
-
-TOP_BORDER_SCAN_LINES = 50
-
-
-BLACK = 0
-WHITE = 1
-RED = 2
-CYAN = 3
-PURPLE = 4
-GREEN = 5
-BLUE = 6
-YELLOW = 7
-ORANGE = 8
-BROWN = 9
-LIGHT_RED = 10
-DARK_GRAY = 11
-GRAY = 12
-LIGHT_GREEN = 13
-LIGHT_BLUE = 14
-LIGHT_GRAY = 15
-
-
-.macro wait_next_raster
- lda VIC_RASTER_REG
-:
- cmp VIC_RASTER_REG
- beq :-
-.endmacro
-
-.zeropage
-temp_buff: .res 2
-pptr: .res 2
-
-.bss
-
-
-.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
-
-.code
-init:
-
-
- lda #0
- jsr clear_screen
- lda #DARK_GRAY
- sta BORDER_COLOR
- lda #YELLOW
- sta BACKGROUND_COLOR_0
-
-
-
- sei ;disable maskable IRQs
-
- lda #$7f
- sta $dc0d ;disable timer interrupts which can be generated by the two CIA chips
- sta $dd0d ;the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better
- ;stop it.
-
- lda $dc0d ;by reading this two registers we negate any pending CIA irqs.
- lda $dd0d ;if we don't do this, a pending CIA irq might occur after we finish setting up our irq.
- ;we don't want that to happen.
-
- lda #$01 ;this is how to tell the VICII to generate a raster interrupt
- sta $d01a
-
- lda #$00 ;this is how to tell at which rasterline we want the irq to be triggered
- sta VIC_RASTER_REG
-
- ldax IRQ_VECTOR
- stax old_irq
- jsr set_next_irq_jump
- cli ;enable maskable interrupts again
-
- lda #23
-@endless_loop:
- nop
- inc $ff
- inc $400
- tsx
- stx $410
- sta $411
- ldy #$80
-:
- iny
- bne :-
- jmp @endless_loop
-
-
-clear_screen:
-
- ldx #$00
- lda #$41
-
-:
- sta SCREEN_RAM,x
- sta SCREEN_RAM+$100,x
- sta SCREEN_RAM+$200,x
- sta SCREEN_RAM+$300,x
- sta COLOUR_RAM,x
- sta COLOUR_RAM+$100,x
- sta COLOUR_RAM+$200,x
- sta COLOUR_RAM+$300,x
-
- dex
- bne :-
- rts
-
-set_next_irq_jump:
- inc jump_counter
-
- lda jump_counter
- asl
- asl
-load_next_raster_entry:
- tax
- lda raster_jump_table,x ;bit 9 of raster to trigger on
-
- cmp #$ff
- bne not_last_entry
- lda #0
- sta jump_counter
- jmp load_next_raster_entry
-not_last_entry:
- ora #$18 ;turn on bits 3 & 4
- sta VIC_CTRL_A
- lda raster_jump_table+1,x ;bits 0..7 of raster to trigger on
- sta VIC_RASTER_REG
- lda raster_jump_table+2,x ;LSB of IRQ handler
- sta IRQ_VECTOR
- lda raster_jump_table+3,x ;LSB of IRQ handler
- sta IRQ_VECTOR+1
- rts
-
-exit_from_irq:
- jsr set_next_irq_jump
-jmp_to_original_irq_handler:
- lda #$ff ;this is the orthodox and safe way of clearing the interrupt condition of the VICII.
- sta VIC_IRQ_FLAG;if you don't do this the interrupt condition will be present all the time and you end
- ;up having the CPU running the interrupt code all the time, as when it exists the
- ;interrupt, the interrupt request from the VICII will be there again regardless of the
- ;rasterline counter.
-
- old_irq = * + 1 ; Placeholder for self-modifying code
- jmp $ffff
-
-raster_irq:
-
- ldax #synchronised_irq
- stax IRQ_VECTOR
- nop ; waste at least 12 cycles
- nop ; (up to 64 cycles delay allowed here)
- nop
- nop
- nop
- nop
- inc VIC_RASTER_REG ; At this stage, we have already moved to the next line
- lda #1
- sta VIC_IRQ_FLAG ; acknowledge the first raster interrupt
- cli ; enable interrupts (the second interrupt can now occur)
- ldy #9
- dey
- bne *-1 ; delay
- nop ; The second interrupt will occur while executing these
- nop ; two-cycle instructions.
- nop
- nop
- nop
-
- jmp jmp_to_original_irq_handler
-
-synchronised_irq:
-
- ldx VIC_RASTER_REG
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- bit $24 ; 6569, 63 cycles/line
-
- cpx VIC_RASTER_REG ; The comparison cycle is executed CYCLES or CYCLES+1 cycles
- ; after the interrupt has occurred.
- beq :+ ; Delay by one cycle if $d012 hadn't changed.
- ; Now exactly CYCLES+3 cycles have passed since the interrupt
-:
-
- ;now got a stable raster
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- inc BORDER_COLOR
- inc BACKGROUND_COLOR_0
-
- ldx #20
-@loop:
- wait_next_raster
- dex
- bne @loop
- dec BORDER_COLOR
- dec BACKGROUND_COLOR_0
-
-
- jmp exit_from_irq
-
-
-
-.data
-
-raster_jump_table:
- ;format:
- ;offset meaning
- ; $00 BIT 9 OF RASTER TO TRIGGER ON ($00 if bit 8 =0 , $80 if bit 8 =1)
- ; $01 BITS 0..7 OF RASTER TO TRIGGER ON
- ; $02 LSB OF ROUTINE TO JUMP TO
- ; $03 MSB OF ROUTINE TO JUMP TO
- ;table needs to end with a single byte $ff
- ;table needs to be sorted by scanlines
-; .byte $0,$01
-; .word scroll_text_irq
- .byte $0,$81
- .word raster_irq
-
-; .byte $0,$80
-; .word raster_irq
- .byte $ff ;end of list
-
-jump_counter: .byte 0
-
-
-
-
-
-;-- LICENSE FOR raster.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/examples/sidplay.s b/client/examples/sidplay.s
deleted file mode 100644
index 5f9a1b0..0000000
--- a/client/examples/sidplay.s
+++ /dev/null
@@ -1,250 +0,0 @@
-
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-
-.import cfg_get_configuration_ptr
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-.import ascii_to_native
-
-.zeropage
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- lda #14
- jsr print_a
- ldax #included_sid_length
- stax sidfile_length
- ldax #sid_data
- jsr load_sid
- bcc @ok
- ldax #error
- jmp print
-@ok:
- lda default_song
- jsr init_song
- jsr install_irq_handler
-@loop:
- jmp @loop
- rts
-
-load_sid:
- stax sidfile_address
- stax copy_src
-
- ldy #1
- lda (copy_src),y
- cmp #'S' ;make sure the file starts with 'PSID' or 'RSID'
- beq @ok
- sec
- rts
-@ok:
- ldy #7
- lda (copy_src),y
- sta header_length
-
- inc header_length
- inc header_length
-
- tay
- ;y now points to the start of the real c64 file
- lda (copy_src),y
- sta copy_dest
- iny
- lda (copy_src),y
- sta copy_dest+1
-
- ldy #$0a
- lda (copy_src),y
- sta init_song+2
- iny
- lda (copy_src),y
- sta init_song+1
- iny
- lda (copy_src),y
- sta play_song+2
- iny
- lda (copy_src),y
- sta play_song+1
-
- ldy #$0f
- lda (copy_src),y
- sta number_of_songs
-
- ldy #$11
- lda (copy_src),y
- sta default_song
-
- ldy #$16
- jsr print_ascii_string
-
- ldy #$36
- jsr print_ascii_string
- ldy #$56
- jsr print_ascii_string
-
- ldax #songs
- jsr print
-
- lda number_of_songs
- jsr print_hex
- jsr print_cr
-
- ldax #init_address
- jsr print
- lda init_song+2
- jsr print_hex
- lda init_song+1
- jsr print_hex
- jsr print_cr
-
- ldax #play_address
- jsr print
- lda play_song+2
- jsr print_hex
- lda play_song+1
- jsr print_hex
- jsr print_cr
-
- ldax sidfile_address
- stax copy_src
-
-
- clc
- lda sidfile_address
- adc header_length
- pha
- lda sidfile_address+1
- adc #0
- tax
- pla
- stax copy_src
- sec
- lda sidfile_length
- sbc header_length
- pha
- lda sidfile_length+1
- sbc #0
- tax
- pla
- jsr copymem
-
- clc
- rts
-
-
-install_irq_handler:
- ldax $314 ;previous IRQ handler
- stax jmp_old_irq+1
- sei ;don't want any interrupts while we fiddle with the vector
- ldax #irq_handler
- stax $314 ;previous IRQ handler
- sta irq_handler_installed_flag
- cli
- rts
-
-irq_handler:
- lda $d012
- cmp #100
- bne irq_handler
- lda $01
- pha
- lda #$35
- sta $01
-
- inc $d020
- jsr play_song
- dec $d020
-
- pla
- sta $01
- jmp jmp_old_irq
-
-
-print_ascii_string:
-:
- lda (copy_src),y
- beq :+
- jsr ascii_to_native
- jsr print_a
- iny
- bne :-
- :
- jmp print_cr
-
-
-
-.bss
-number_of_songs: .res 1
-default_song: .res 1
-sidfile_address: .res 2
-header_length: .res 1
-sidfile_length: .res 2
-
-.rodata
-
-songs:
- .byte "SONGS $",0
-error:
- .byte "ERROR",13,0
-init_address:
- .byte "LOAD ADDRESS $",0
-play_address:
- .byte "PLAY ADDRESS $",0
-
-sid_data:
- ;.incbin "Melonix.sid"
-; .incbin "Power_Train.sid"
-; .incbin "Y-Out.sid"
-.incbin "outlaw.sid"
-
-included_sid_length=*-sid_data
-.data
-
-irq_handler_installed_flag: .byte 0
-
-init_song:
- jmp $ffff
-play_song:
- jmp $ffff
-jmp_old_irq:
- jmp $ffff
-
-
-
-
-;-- LICENSE FOR sidplay.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/examples/sidplay_zigzag.s b/client/examples/sidplay_zigzag.s
deleted file mode 100644
index 766da15..0000000
--- a/client/examples/sidplay_zigzag.s
+++ /dev/null
@@ -1,122 +0,0 @@
-
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-
-.import cfg_get_configuration_ptr
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-.import ascii_to_native
-
-.zeropage
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-init_song=$1000
-play_song=$1003
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
-
-
- ldax #sid_data+2
- stax copy_src
-
- ldax $4000
- stax copy_dest
-
- jsr copymem
-
-
- ldax $4000
- stax copy_src
-
- ldax $1000
- stax copy_dest
-
- jsr copymem
-
- lda #0
- jsr init_song
- jsr install_irq_handler
-@loop:
- jmp @loop
- rts
-
-
-
- clc
- rts
-
-
-install_irq_handler:
- ldax $314 ;previous IRQ handler
- stax jmp_old_irq+1
- sei ;don't want any interrupts while we fiddle with the vector
- ldax #irq_handler
- stax $314 ;previous IRQ handler
- sta irq_handler_installed_flag
- cli
- rts
-
-irq_handler:
- inc $d020
- jsr play_song
- dec $d020
- jmp jmp_old_irq
-
-
-
-
-.bss
-
-.rodata
-
-sid_data:
- ;.incbin "Melonix.sid"
-; .incbin "Power_Train.sid"
- .incbin "zigzag.prg"
-
-included_sid_length=*-sid_data
-.data
-
-irq_handler_installed_flag: .byte 0
-
-jmp_old_irq:
- jmp $ffff
-
-
-
-
-;-- LICENSE FOR sidplay_zigzag.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/examples/sine_data.i b/client/examples/sine_data.i
deleted file mode 100644
index 052ab2f..0000000
--- a/client/examples/sine_data.i
+++ /dev/null
@@ -1,37 +0,0 @@
-
-.byte $00, $06, $0c, $12, $18, $1f, $25, $2b
-.byte $31, $37, $3d, $44, $4a, $4f, $55, $5b
-.byte $61, $67, $6d, $72, $78, $7d, $83, $88
-.byte $8d, $92, $97, $9c, $a1, $a6, $ab, $af
-.byte $b4, $b8, $bc, $c1, $c5, $c9, $cc, $d0
-.byte $d4, $d7, $da, $dd, $e0, $e3, $e6, $e9
-.byte $eb, $ed, $f0, $f2, $f4, $f5, $f7, $f8
-.byte $fa, $fb, $fc, $fd, $fd, $fe, $fe, $fe
-.byte $ff, $fe, $fe, $fe, $fd, $fd, $fc, $fb
-.byte $fa, $f8, $f7, $f5, $f4, $f2, $f0, $ed
-.byte $eb, $e9, $e6, $e3, $e0, $dd, $da, $d7
-.byte $d4, $d0, $cc, $c9, $c5, $c1, $bc, $b8
-.byte $b4, $af, $ab, $a6, $a1, $9c, $97, $92
-.byte $8d, $88, $83, $7d, $78, $72, $6d, $67
-.byte $61, $5b, $55, $4f, $4a, $44, $3d, $37
-.byte $31, $2b, $25, $1f, $18, $12, $0c, $06
-
-
-;-- LICENSE FOR sine_data.i --
-; 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/examples/spud_letters.spr b/client/examples/spud_letters.spr
deleted file mode 100644
index 38a50ad..0000000
Binary files a/client/examples/spud_letters.spr and /dev/null differ
diff --git a/client/examples/tune.bin b/client/examples/tune.bin
deleted file mode 100644
index 3bdabff..0000000
Binary files a/client/examples/tune.bin and /dev/null differ
diff --git a/client/examples/upnatom.s b/client/examples/upnatom.s
deleted file mode 100644
index c46db49..0000000
--- a/client/examples/upnatom.s
+++ /dev/null
@@ -1,949 +0,0 @@
-
-.include "../inc/common.i"
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-print_a = $ffd2
-
-
-SCREEN_RAM = $0400
-COLOUR_RAM = $d800
-VIC_CTRL_A = $d011
-VIC_RASTER_REG = $d012
-VIC_CTRL_B = $d016
-VIC_MEMORY_CTRL=$d018
-VIC_IRQ_FLAG = $d019
-
-
-IRQ_VECTOR=$fffe
-
-MUSIC_BASE=$1000 ;where we relocate our music routine to
-PLAYER_INIT=0
-PLAYER_PLAY=3
-
-BORDER_COLOR = $d020
-BACKGROUND_COLOR_0 = $d021
-SCROLL_DELAY=4
-CHARS_PER_LINE = 40
-SCROLL_LINE=12
-SCROLL_RAM = SCREEN_RAM+(SCROLL_LINE*CHARS_PER_LINE)
-
-TOP_BORDER_SCAN_LINES = 50
-
-
-BLACK = 0
-WHITE = 1
-RED = 2
-CYAN = 3
-PURPLE = 4
-GREEN = 5
-BLUE = 6
-YELLOW = 7
-ORANGE = 8
-BROWN = 9
-LIGHT_RED = 10
-DARK_GRAY = 11
-GRAY = 12
-LIGHT_GREEN = 13
-LIGHT_BLUE = 14
-LIGHT_GRAY = 15
-
-.macro start_irq
- pha
- txa
- pha
- tya
- pha
-
-.endmacro
-
-
-.macro end_irq
- pla
- tay
- pla
- tax
- pla
-.endmacro
-
-.macro wait_next_raster
- lda VIC_RASTER_REG
-@loop:
- cmp VIC_RASTER_REG
- beq @loop
-.endmacro
-
-.macro kippercall function_number
- ldy function_number
- jsr KPR_DISPATCH_VECTOR
-.endmacro
-
-.zeropage
-temp_buff: .res 2
-pptr: .res 2
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in)
-look_for_signature:
- stax temp_buff
- ldy #5
-@check_one_byte:
- lda (temp_buff),y
- cmp kipper_signature,y
- bne @bad_match
- dey
- bpl @check_one_byte
- jmp @found_kipper_signature
-
-@bad_match:
- ldax #kipper_api_not_found_message
- jsr print
-@loop:
- jmp @loop
- rts
-@found_kipper_signature:
-
- ldax #init_msg
- jsr print
- kippercall #KPR_INITIALIZE
- bcc @init_ok
- jsr print_cr
- ldax #failed_msg
- jsr print
- jsr print_cr
- jsr print_errorcode
- jmp reset_after_keypress
-@init_ok:
-
-;if we got here, we have found the KIPPER API and initialised the IP stack
-
-;try and load the config file
- ldax #read_url_file_param_buffer
- kippercall #KPR_FILE_LOAD
- bcs @use_default_url
- clc
- lda #0
- ldy read_url_file_param_buffer+KPR_FILE_ACCESS_FILESIZE
- sta feed_url,y ;put a zero at the end of the URL
-
-@use_default_url:
- jsr setup_static_scroll_text
-
- lda #0
- jsr clear_screen
- lda #DARK_GRAY
- sta BORDER_COLOR
- lda #YELLOW
- sta BACKGROUND_COLOR_0
-
-
-
- ;copy our music data up to a temp buffer (in case it gets overwritten by
- ;one of the other unpacking moves)
- ldax #musicdata+2 ;skip over the 2 byte address
- stax param_buffer+KPR_BLOCK_SRC
- ldax #download_buffer
- stax param_buffer+KPR_BLOCK_DEST
- ldax #musicdata_size-2 ;don't copy the 2 byte address
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
- ;copy our font data and the sprite data to $2000..$2fff
- ldax #charset_font
- stax param_buffer+KPR_BLOCK_SRC
- ldax #$2000
- stax param_buffer+KPR_BLOCK_DEST
- ldax #MUSIC_BASE
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
- ;should now be now safe to copy the music data back down
- ;copy our music data to $1000..$1fff
- ldax #download_buffer
- stax param_buffer+KPR_BLOCK_SRC
- ldax #MUSIC_BASE
- stax param_buffer+KPR_BLOCK_DEST
- ldax #musicdata_size-2 ;don't copy the 2 byte address
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
- lda #$18 ; use charset at $2000
- sta VIC_MEMORY_CTRL
-
-
- sei ;disable maskable IRQs
-
- lda #$7f
- sta $dc0d ;disable timer interrupts which can be generated by the two CIA chips
- sta $dd0d ;the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better
- ;stop it.
-
- lda $dc0d ;by reading this two registers we negate any pending CIA irqs.
- lda $dd0d ;if we don't do this, a pending CIA irq might occur after we finish setting up our irq.
- ;we don't want that to happen.
-
- lda #$01 ;this is how to tell the VICII to generate a raster interrupt
- sta $d01a
-
- lda #$00 ;this is how to tell at which rasterline we want the irq to be triggered
- sta VIC_RASTER_REG
-
-
- ;copy KERNAL to the RAM underneath, in case any ip65 routines need it
- ldax #$e000
- stax param_buffer+KPR_BLOCK_SRC
- stax param_buffer+KPR_BLOCK_DEST
- ldax #$1FFF
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
- ;copy KIPPER cart to the RAM underneath, so we can swap it out and modify the IRQ vector
- ldax #$8000
- stax param_buffer+KPR_BLOCK_SRC
- stax param_buffer+KPR_BLOCK_DEST
- ldax #$4000
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
-
- lda #$35 ;we turn off the BASIC and KERNAL rom here, so we can overwrite the IRQ vector at $fffe
- sta $01 ;the cpu now sees RAM everywhere except at $d000-$e000, where still the registers of
- ;SID/VICII/etc are visible
-
- jsr setup_sprites
-
- jsr setup_music
-
-
- jsr set_next_irq_jump
- cli ;enable maskable interrupts again
-
-
- lda #3
- sta scroll_state
-;position for the first text
-
- jsr reset_input_buffer
-
- lda #0
- sta scroll_buffer_1 ;set this buffer to be an empty string, in case we try to scroll it
-
-;now download the feed
-@download_feed:
-
- ldax #feed_url
- stax param_buffer+KPR_URL
- ldax #download_buffer
- stax param_buffer+KPR_URL_DOWNLOAD_BUFFER
- ldax #download_buffer_length
- stax param_buffer+KPR_URL_DOWNLOAD_BUFFER_LENGTH
- ldax #param_buffer
- kippercall #KPR_DOWNLOAD_RESOURCE
-
- bcs @download_feed ;if at first we don't succeed, try try again
-
- inc BORDER_COLOR ;little marker of success
-
-
- lda #2
- sta scroll_state
-
- ldax #scroll_buffer_1
- stax current_output_ptr
- jsr emit_titles
-
-
-@endless_loop:
- jsr KPR_PERIODIC_PROCESSING_VECTOR
- lda scroll_state
- beq @download_feed
- jmp @endless_loop
-
-reset_input_buffer:
-
- lda scroll_state
- beq @config_scroller
- dec scroll_state
- cmp #1
- beq @feed_scroller
- cmp #3
- beq @title_scroller
-@config_scroller:
- ldax #scroll_buffer_0
- stax current_input_ptr
- rts
-
-@feed_scroller:
- ldax #scroll_buffer_1
- stax current_input_ptr
- rts
-@title_scroller:
- ldax #static_title
- stax current_input_ptr
- rts
-
-
-
-;set up the tune
-setup_music:
- lda #$00 ;init subtune 0
- jsr MUSIC_BASE+PLAYER_INIT
- rts
-
-setup_sprites:
-
- ;turn on all 8 sprites
- lda #$FF
- sta $d015
-
- ldx #$07
-@setup_sprite:
- ;position each sprite
- txa
- asl
- tay
- lda sprite_x_pos,x
- sta $d000,y ;sprite 0 X pos (LSB)
- lda #0
- sta $d001,y ;sprite 0 Y pos
-
- ;colour sprite 0
- lda #BLUE
- sta $d027,x ;sprite 0 color
-
- ;select bitmap for sprite
- sec
- lda sprite_text,x
- sbc #'A'
- clc
- adc #<($2800/64) ;sprite font should be relocated to $2000
- sta SCREEN_RAM+$03f8,x
- dex
- bpl @setup_sprite
-
- lda sprite_x_msb
- sta $d010
-
- ;turn on multicolor mode for all 8 sprites
- lda #$FF
- sta $d01c
-
- sta sprite_ticker
-
- lda #DARK_GRAY
- sta $d025 ;sprite multicolor register 0
- lda #LIGHT_GRAY
- sta $d026 ;sprite multicolor register 1
-
- rts
-
-
-clear_screen:
-
- ldx #$00
- lda #$20
-
-:
- sta SCREEN_RAM,x
- sta SCREEN_RAM+$100,x
- sta SCREEN_RAM+$200,x
- sta SCREEN_RAM+$300,x
- sta COLOUR_RAM,x
- sta COLOUR_RAM+$100,x
- sta COLOUR_RAM+$200,x
- sta COLOUR_RAM+$300,x
-
- dex
- bne :-
- rts
-
-set_next_irq_jump:
- inc jump_counter
-
- lda jump_counter
- asl
- asl
-load_next_raster_entry:
- tax
- lda raster_jump_table,x ;bit 9 of raster to trigger on
-
- cmp #$ff
- bne not_last_entry
- lda #0
- sta jump_counter
- jmp load_next_raster_entry
-not_last_entry:
- ora #$18 ;turn on bits 3 & 4
- sta VIC_CTRL_A
- lda raster_jump_table+1,x ;bits 0..7 of raster to trigger on
- sta VIC_RASTER_REG
- lda raster_jump_table+2,x ;LSB of IRQ handler
- sta IRQ_VECTOR
- lda raster_jump_table+3,x ;LSB of IRQ handler
- sta IRQ_VECTOR+1
- rts
-
-exit_from_irq:
- jsr set_next_irq_jump
- lda #$ff ;this is the orthodox and safe way of clearing the interrupt condition of the VICII.
- sta VIC_IRQ_FLAG;if you don't do this the interrupt condition will be present all the time and you end
- ;up having the CPU running the interrupt code all the time, as when it exists the
- ;interrupt, the interrupt request from the VICII will be there again regardless of the
- ;rasterline counter.
-
- end_irq
- rti
-
-
-
-scroll_text_irq:
- start_irq
- lda scroll_timer
- bne done_scrolling_message
- lda #SCROLL_DELAY
- sta scroll_timer
- ldx #1
- ldy #0
-scroll_1_char:
- lda SCROLL_RAM,x
- sta SCROLL_RAM,y
- lda SCROLL_RAM+40,x
- sta SCROLL_RAM+40,y
-
- inx
- iny
- cpx #CHARS_PER_LINE
- bne scroll_1_char
-
-
- jsr get_a
- cmp #0
- beq last_char_in_message
- sta SCROLL_RAM+CHARS_PER_LINE-1
- clc
- adc #$80
- sta SCROLL_RAM+CHARS_PER_LINE+40-1
-
- jmp done_scrolling_message
-
-
-last_char_in_message:
- jsr reset_input_buffer
-
-done_scrolling_message:
- dec scroll_timer
-
- jmp exit_from_irq
-
-
-scroll_timer: .byte 1
-scroll_counter: .byte 0
-
-
-pixel_scroll_irq:
- start_irq
- wait_next_raster
-; set X scroll offset
- lda scroll_timer
- clc
- asl
- clc
- and #$07
- sta VIC_CTRL_B
-
- jmp exit_from_irq
-
-move_sprites_irq:
- start_irq
- wait_next_raster
- ldy sprite_ticker
- inc sprite_ticker
-
- ldx #$0e ;7*2
-@position_sprite:
- lda sprite_y_pos,y
- sta $d001,x ;sprite 0 Y pos
-
- ;change colour when the sprite goes off screen
-; cmp #$ff ;are we off the screen?
-; bne @not_off_screen
-; txa
-; pha
-; lsr
-; tax
-; inc $d027,x ;sprite color
-; pla
-; tax
-;@not_off_screen:
-
- txa
- beq @y_set
- dex
- dex
-@mod_y:
- iny
- iny
- iny
- dex
- dex
- bpl @mod_y
-@y_set:
-
- tax
- dex
- dex
- bpl @position_sprite
-
- jmp exit_from_irq
-
-
-setup_static_scroll_text:
- ldax #scroll_buffer_0
- stax current_output_ptr
- ldax #scroll_template
- stax current_input_ptr
-@next_byte:
- jsr get_a
- beq @next_byte
- cmp #'%'
- beq @operator
- pha
- jsr emit_a
- pla
- bne @next_byte
- rts
-
-@operator:
- jsr get_a
- cmp #'i'
- bne @not_ip
- lda #KPR_CFG_IP
- jmp @loaded_offset
-@not_ip:
- cmp #'g'
- bne @not_gateway
- lda #KPR_CFG_GATEWAY
- jmp @loaded_offset
-@not_gateway:
- cmp #'d'
- bne @not_dns
- lda #KPR_CFG_DNS_SERVER
- jmp @loaded_offset
-@not_dns:
- cmp #'f'
- bne @not_feed_url
- ldy #0
-@copy_feed_url_loop:
- lda feed_url,y
- cmp #$20
- bcc @next_byte ;any control char (including CR,LF, and $00) should be treated as end of URL
- jsr emit_a
- iny
- bne @copy_feed_url_loop
-@not_feed_url:
- jmp @next_byte
-
-@loaded_offset:
- sta param_offset
- kippercall #KPR_GET_IP_CONFIG
- adc param_offset
- bcc :+
- inx
-:
- jsr emit_dotted_quad
-
-
- jmp @next_byte
-
-;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
-
-reset_after_keypress:
- ldax #press_a_key_to_continue
- jsr print
-@wait_key:
- jsr $f142 ;not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD)
- beq @wait_key
- jmp $fce2 ;do a cold start
-
-print_errorcode:
- ldax #error_code
- jsr print
- kippercall #KPR_GET_LAST_ERROR
- kippercall #KPR_PRINT_HEX
- jmp print_cr
-
-
-
-
-
-play_music_irq:
-; inc BORDER_COLOR
- start_irq
- jsr MUSIC_BASE+PLAYER_PLAY
-; dec BORDER_COLOR
- jmp exit_from_irq
-
-emit_titles:
- ldax #download_buffer
- kippercall #KPR_PARSER_INIT
-@next_title:
- ldax #title
- kippercall #KPR_PARSER_SKIP_NEXT
- bcs @done
-
- jsr emit_tag_contents
- lda #' '
- jsr emit_a
- lda #'/'
- jsr emit_a
- lda #' '
- jsr emit_a
- jmp @next_title
-@done:
- lda #0
- jsr emit_a
- rts
-
-emit_tag_contents:
- stax temp_buff
- lda #0
- sta string_offset
-@next_byte:
- jsr @get_next_byte
- cmp #0
- beq @done
- cmp #'<'
- beq @done
- cmp #'&'
- beq @entity
- jsr emit_a
- beq @done
- jmp @next_byte
-@entity:
- jsr @get_next_byte
- cmp #'a'
- bne @not_amper
- lda #'&'
- jsr emit_a
-@not_amper:
- cmp #'g'
- bne @not_gt
- lda #'>'
- jsr emit_a
-@not_gt:
- cmp #'l'
- bne @not_lt
- lda #'<'
- jsr emit_a
-@not_lt:
-
-@loop_till_semi_colon:
- jsr @get_next_byte
- cmp #0
- beq @done
- cmp #';'
- bne @loop_till_semi_colon
- jmp @next_byte
-@get_next_byte:
- ldy string_offset
- lda (temp_buff),y
- inc string_offset
-@done:
- 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
-
-print_cr:
- lda #13
- jmp print_a
-
-.data
-
-sprite_ticker: .byte 0
-
-emit_a:
-current_output_ptr=emit_a+1
- sta $ffff
- inc current_output_ptr
- bne :+
- inc current_output_ptr+1
-:
- rts
-
-get_a:
-current_input_ptr=get_a+1
- lda $ffff
- inc current_input_ptr
- bne :+
- inc current_input_ptr+1
-:
- rts
-
-
-raster_jump_table:
- ;format:
- ;offset meaning
- ; $00 BIT 9 OF RASTER TO TRIGGER ON ($00 if bit 8 =0 , $80 if bit 8 =1)
- ; $01 BITS 0..7 OF RASTER TO TRIGGER ON
- ; $02 LSB OF ROUTINE TO JUMP TO
- ; $03 MSB OF ROUTINE TO JUMP TO
- ;table needs to end with a single byte $ff
- ;table needs to be sorted by scanlines
- .byte $0,$01
- .word scroll_text_irq
- .byte $0,$20
- .word pixel_scroll_irq
-
-
- .byte $0,$80
- .word play_music_irq
-
- .byte $80,$05
- .word move_sprites_irq
-
- .byte $ff ;end of list
-
-jump_counter: .byte 0
-
-
-sprite_x_pos:
-.byte $34,$54,$78,$90,$Bb,$Db,$Fb,$1b
-
-sprite_x_msb:
-.byte $80
-
-sprite_y_pos:
-.repeat 128
- .byte 0
-.endrep
-.include "sine_data.i"
-
-;.include "sine_data.i"
-
-
-
-static_title: .byte "up 'n atom - the old skool feed reader!",$20,0
-sprite_text:
-
-.byte "UP\NATOM" ;options are A-Z, "[\]^_"
-
-scroll_template:
-.byte " ip: %i / gateway: %g / dns server %d / polling %f /"
-.byte " ",0
-
-
-feed_url:
-.byte "http://static.cricinfo.com/rss/livescores.xml",0
-.byte "http://search.twitter.com/search.atom?q=kipper",0
-;leave space for whatever we read in from disk
-.repeat 128
-.byte 0
-.endrep
-
-url_config_file:
-
-.byte "URL.CFG",0
-
-read_url_file_param_buffer:
- .word url_config_file ;KPR_FILE_ACCESS_FILENAME
- .word feed_url ;B65_FILE_ACCESS_POINTER
- .word $0000 ;KPR_FILE_ACCESS_FILESIZE - should be filled in
- .byte $00 ;KPR_FILE_ACCESS_DEVICE
-
-
-title:
-.byte "",0
-
-kipper_api_not_found_message:
- .byte "ERROR - KIPPER API NOT FOUND.",13,0
-
-failed_msg:
- .byte "FAILED", 0
-
-ok_msg:
- .byte "OK", 0
-
-
-init_msg:
- .byte " INITIALIZING ",0
-
-press_a_key_to_continue:
- .byte "PRESS A KEY TO CONTINUE",13,0
-
-kipper_signature:
-.byte $4B,$49,$50,$50,$45,$52 ; "KIPPER"
-
-error_code:
- .asciiz "ERROR CODE: "
-
-charset_font:
- .incbin "font16x8.bin"
-sprite_font:
- .incbin "spud_letters.spr"
-musicdata:
-;.incbin "tune.bin"
-.incbin "powertrain.bin"
-musicdata_size=*-musicdata
-
-.segment "SAFE_BSS"
-;we want our variables to start at $3000, out of the way of our music player and the font data
-
-param_offset: .res 1
-
-temp_bin: .res 1
-temp_bcd: .res 2
-
-scroll_state: .res 1
-
-param_buffer: .res $20
-
-download_buffer:
-download_buffer_length=12000
- .res download_buffer_length
-
-.res 10 ;filler
-scroll_buffer_0:
- .res 1000
-
-scroll_buffer_1:
- .res 2000
-
-string_offset: .res 1
-
-
-
-;-- LICENSE FOR upnatom.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/examples/url.cfg b/client/examples/url.cfg
deleted file mode 100644
index 8fa7f64..0000000
--- a/client/examples/url.cfg
+++ /dev/null
@@ -1 +0,0 @@
-http://static.cricinfo.com/rss/livescores.xml
\ No newline at end of file
diff --git a/client/examples/webnoter.s b/client/examples/webnoter.s
deleted file mode 100644
index cb1637f..0000000
--- a/client/examples/webnoter.s
+++ /dev/null
@@ -1,941 +0,0 @@
-
-.include "../inc/common.i"
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-print_a = $ffd2
-
-
-.export musicdata
-.export musicdata_size
-.export sprite_font
-.export html
-.export scroll_template_1
-.export scroll_template_2
-
-.import __DATA6K_LOAD__
-.import __DATA6K_RUN__
-.import __DATA6K_SIZE__
-
-SCREEN_RAM = $0400
-COLOUR_RAM = $d800
-VIC_CTRL_A = $d011
-VIC_RASTER_REG = $d012
-VIC_CTRL_B = $d016
-VIC_MEMORY_CTRL=$d018
-VIC_IRQ_FLAG = $d019
-
-copy_src = $24
-
-
-IRQ_VECTOR=$fffe
-
-MUSIC_BASE=$1000 ;where we relocate our music routine to
-PLAYER_INIT=0
-PLAYER_PLAY=3
-
-BORDER_COLOR = $d020
-BACKGROUND_COLOR_0 = $d021
-SCROLL_DELAY=4
-CHARS_PER_LINE = 40
-SCROLL_LINE=12
-SCROLL_RAM = SCREEN_RAM+(SCROLL_LINE*CHARS_PER_LINE)
-
-TOP_BORDER_SCAN_LINES = 50
-
-
-BLACK = 0
-WHITE = 1
-RED = 2
-CYAN = 3
-PURPLE = 4
-GREEN = 5
-BLUE = 6
-YELLOW = 7
-ORANGE = 8
-BROWN = 9
-LIGHT_RED = 10
-DARK_GRAY = 11
-GRAY = 12
-LIGHT_GREEN = 13
-LIGHT_BLUE = 14
-LIGHT_GRAY = 15
-
-.macro start_irq
- pha
- txa
- pha
- tya
- pha
-
-.endmacro
-
-
-.macro end_irq
- pla
- tay
- pla
- tax
- pla
-.endmacro
-
-.macro wait_next_raster
- lda VIC_RASTER_REG
-@loop:
- cmp VIC_RASTER_REG
- beq @loop
-.endmacro
-
-.macro kippercall function_number
- ldy function_number
- jsr KPR_DISPATCH_VECTOR
-.endmacro
-
-.zeropage
-temp_buff: .res 2
-pptr: .res 2
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge (if cart is banked in)
-look_for_signature:
- stax temp_buff
- ldy #5
-@check_one_byte:
- lda (temp_buff),y
- cmp kipper_signature,y
- bne @bad_match
- dey
- bpl @check_one_byte
- jmp @found_kipper_signature
-
-@bad_match:
- ldax #kipper_api_not_found_message
- jsr print
-@loop:
- jmp @loop
- rts
-@found_kipper_signature:
-
- ldax #init_msg
- jsr print
- kippercall #KPR_INITIALIZE
- bcc @init_ok
- jsr print_cr
- ldax #failed_msg
- jsr print
- jsr print_cr
- jsr print_errorcode
- jmp reset_after_keypress
-@init_ok:
-
-;if we got here, we have found the KIPPER API and initialised the IP stack
-
-
- ;copy our runtime data to where it lives
- ldax #__DATA6K_LOAD__
- stax param_buffer+KPR_BLOCK_SRC
- ldax #__DATA6K_RUN__
- stax param_buffer+KPR_BLOCK_DEST
- ldax #__DATA6K_SIZE__
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
-
-
- ;copy our music data up to a temp buffer (in case it gets overwritten by
- ;one of the other unpacking moves)
- ldax #musicdata+2 ;skip over the 2 byte address
- stax param_buffer+KPR_BLOCK_SRC
- ldax #download_buffer
- stax param_buffer+KPR_BLOCK_DEST
- ldax #musicdata_size-2 ;don't copy the 2 byte address
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
- ;copy our font data and the sprite data to $3000..$3fff
- ldax #charset_font
- stax param_buffer+KPR_BLOCK_SRC
- ldax #$3000
- stax param_buffer+KPR_BLOCK_DEST
- ldax #MUSIC_BASE
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
- ;should now be now safe to copy the music data back down
- ;copy our music data to $1000..$1fff
- ldax #download_buffer
- stax param_buffer+KPR_BLOCK_SRC
- ldax #MUSIC_BASE
- stax param_buffer+KPR_BLOCK_DEST
- ldax #musicdata_size-2 ;don't copy the 2 byte address
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
-
- ldax #scroll_template_1
- jsr setup_static_scroll_text
-
- lda #0
- jsr clear_screen
- lda #DARK_GRAY
- sta BORDER_COLOR
- lda #YELLOW
- sta BACKGROUND_COLOR_0
-
- lda #$1c ; use charset at $3000
- sta VIC_MEMORY_CTRL
-
-
- sei ;disable maskable IRQs
-
- lda #$7f
- sta $dc0d ;disable timer interrupts which can be generated by the two CIA chips
- sta $dd0d ;the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better
- ;stop it.
-
- lda $dc0d ;by reading this two registers we negate any pending CIA irqs.
- lda $dd0d ;if we don't do this, a pending CIA irq might occur after we finish setting up our irq.
- ;we don't want that to happen.
-
- lda #$01 ;this is how to tell the VICII to generate a raster interrupt
- sta $d01a
-
- lda #$00 ;this is how to tell at which rasterline we want the irq to be triggered
- sta VIC_RASTER_REG
-
-
- ;copy KERNAL to the RAM underneath, in case any ip65 routines need it
- ldax #$e000
- stax param_buffer+KPR_BLOCK_SRC
- stax param_buffer+KPR_BLOCK_DEST
- ldax #$1FFF
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
- ;copy KIPPER cart to the RAM underneath, so we can swap it out and modify the IRQ vector
- ldax #$8000
- stax param_buffer+KPR_BLOCK_SRC
- stax param_buffer+KPR_BLOCK_DEST
- ldax #$4000
- stax param_buffer+KPR_BLOCK_SIZE
- ldax #param_buffer
- kippercall #KPR_BLOCK_COPY
-
-
- lda #$35 ;we turn off the BASIC and KERNAL rom here, so we can overwrite the IRQ vector at $fffe
- sta $01 ;the cpu now sees RAM everywhere except at $d000-$e000, where still the registers of
- ;SID/VICII/etc are visible
-
- lda #((SPRITE_FRAMES-1)*8)
- sta sprite_text_frame
- jsr setup_sprites
-
- jsr setup_music
-
-
- jsr set_next_irq_jump
- cli ;enable maskable interrupts again
-
-
-;position for the first text
-
- jsr reset_input_buffer
-
-
-
-start_web_server:
- ldax #httpd_callback
- kippercall #KPR_HTTPD_START ;this will only return if there is an error
- rts
-
-
-reset_input_buffer:
-
- lda new_message
- beq @no_message_yet
- ldax #scroll_template_2
- jsr setup_static_scroll_text
- ldx #0
- stx new_message
-
-@no_message_yet:
- ldax #scroll_buffer
- stax current_input_ptr
- rts
-
-httpd_callback:
- lda #'h'
- kippercall #KPR_HTTPD_GET_VAR_VALUE
- bcs @not_complete_fields
- stax copy_src
- ldy #0
- lda (copy_src),y
- beq @not_complete_fields
-
-@copy_handle_loop:
- lda (copy_src),y
- beq @end_of_handle
- sta handle,y
- iny
- bne @copy_handle_loop
-@end_of_handle:
- lda #0
- sta handle,y
- lda #'m'
- kippercall #KPR_HTTPD_GET_VAR_VALUE
- bcs @not_complete_fields
- stax copy_src
- ldy #0
- lda (copy_src),y
- beq @not_complete_fields
-
-@copy_message_loop:
- lda (copy_src),y
- beq @end_of_message
- sta message_text,y
- iny
- bne @copy_message_loop
-@end_of_message:
- lda #0
- sta message_text,y
- inc new_message
-
-@not_complete_fields:
-
- ldax #html
- ldy #2 ;text/html
- clc
- rts
-
-
-;set up the tune
-setup_music:
- lda #$00 ;init subtune 0
- jsr MUSIC_BASE+PLAYER_INIT
- rts
-
-setup_sprites:
-
- ;turn on all 8 sprites
- lda #$FF
- sta $d015
-
- ldx #$07
-@setup_sprite:
- ;position each sprite
- txa
- asl
- tay
- lda sprite_x_pos,x
- sta $d000,y ;sprite 0 X pos (LSB)
- lda #0
- sta $d001,y ;sprite 0 Y pos
-
- ;colour sprite 0
- lda #BLUE
- sta $d027,x ;sprite 0 color
-
- ;select bitmap for sprite
- dex
- bpl @setup_sprite
-
- lda sprite_x_msb
- sta $d010
-
- ;turn on multicolor mode for all 8 sprites
- lda #$FF
- sta $d01c
-
- sta sprite_ticker
-
- lda #DARK_GRAY
- sta $d025 ;sprite multicolor register 0
- lda #LIGHT_GRAY
- sta $d026 ;sprite multicolor register 1
-
- rts
-
-
-clear_screen:
-
- ldx #$00
- lda #$20
-
-:
- sta SCREEN_RAM,x
- sta SCREEN_RAM+$100,x
- sta SCREEN_RAM+$200,x
- sta SCREEN_RAM+$300,x
- sta COLOUR_RAM,x
- sta COLOUR_RAM+$100,x
- sta COLOUR_RAM+$200,x
- sta COLOUR_RAM+$300,x
-
- dex
- bne :-
- rts
-
-set_next_irq_jump:
- inc jump_counter
-
- lda jump_counter
- asl
- asl
-load_next_raster_entry:
- tax
- lda raster_jump_table,x ;bit 9 of raster to trigger on
-
- cmp #$ff
- bne not_last_entry
- lda #0
- sta jump_counter
- jmp load_next_raster_entry
-not_last_entry:
- ora #$18 ;turn on bits 3 & 4
- sta VIC_CTRL_A
- lda raster_jump_table+1,x ;bits 0..7 of raster to trigger on
- sta VIC_RASTER_REG
- lda raster_jump_table+2,x ;LSB of IRQ handler
- sta IRQ_VECTOR
- lda raster_jump_table+3,x ;LSB of IRQ handler
- sta IRQ_VECTOR+1
- rts
-
-exit_from_irq:
- jsr set_next_irq_jump
- lda #$ff ;this is the orthodox and safe way of clearing the interrupt condition of the VICII.
- sta VIC_IRQ_FLAG;if you don't do this the interrupt condition will be present all the time and you end
- ;up having the CPU running the interrupt code all the time, as when it exists the
- ;interrupt, the interrupt request from the VICII will be there again regardless of the
- ;rasterline counter.
-
- end_irq
- rti
-
-
-
-scroll_text_irq:
- start_irq
- lda scroll_timer
- bne done_scrolling_message
- lda #SCROLL_DELAY
- sta scroll_timer
- ldx #1
- ldy #0
-scroll_1_char:
- lda SCROLL_RAM,x
- sta SCROLL_RAM,y
- lda SCROLL_RAM+40,x
- sta SCROLL_RAM+40,y
-
- inx
- iny
- cpx #CHARS_PER_LINE
- bne scroll_1_char
-
-
- jsr get_a
- cmp #0
- beq last_char_in_message
- sta SCROLL_RAM+CHARS_PER_LINE-1
- clc
- adc #$80
- sta SCROLL_RAM+CHARS_PER_LINE+40-1
-
- jmp done_scrolling_message
-
-
-last_char_in_message:
- jsr reset_input_buffer
-
-done_scrolling_message:
- dec scroll_timer
-
- jmp exit_from_irq
-
-
-scroll_timer: .byte 1
-scroll_counter: .byte 0
-
-
-pixel_scroll_irq:
- start_irq
- wait_next_raster
-; set X scroll offset
- lda scroll_timer
- clc
- asl
- clc
- and #$07
- sta VIC_CTRL_B
-
- jmp exit_from_irq
-
-move_sprites_irq:
- start_irq
- wait_next_raster
-
- inc sprite_ticker
- bne @sprite_not_offscreen
- clc
- lda sprite_text_frame
- adc #8
- cmp #8*SPRITE_FRAMES
- bne @not_last_frame
- lda #0
-@not_last_frame:
- sta sprite_text_frame
- ldx #$07
-@set_sprite_text:
- clc
- txa
- adc sprite_text_frame
- tay
- lda sprite_text,y
- cmp #' '
- bne @not_space
- lda #'`' ;map a space in the sprite text to 0x60,so it ends up with font offset 0x1F after subbing 'A'
-@not_space:
- sec
- sbc #'A'
- clc
- adc #<($3800/64) ;sprite font should be relocated here
- sta SCREEN_RAM+$03f8,x
- dex
- bpl @set_sprite_text
-
-@sprite_not_offscreen:
- ldy sprite_ticker
- ldx #$0e ;7*2
-@position_sprite:
- lda sprite_y_pos,y
- sta $d001,x ;sprite 0 Y pos
-
- ;change colour when the sprite goes off screen
-; cmp #$ff ;are we off the screen?
-; bne @not_off_screen
-; txa
-; pha
-; lsr
-; tax
-; inc $d027,x ;sprite color
-; pla
-; tax
-;@not_off_screen:
-
- txa
- beq @y_set
- dex
- dex
-@mod_y:
- iny
- iny
- iny
- dex
- dex
- bpl @mod_y
-@y_set:
-
- tax
- dex
- dex
- bpl @position_sprite
-
- jmp exit_from_irq
-
-
-setup_static_scroll_text:
- stax current_input_ptr
- lda #0
- sta new_message
- ldax #scroll_buffer
- stax current_output_ptr
-@next_byte:
- jsr get_a
- beq @next_byte
- cmp #'%'
- beq @operator
- pha
- jsr emit_a
- pla
- bne @next_byte
- rts
-
-@operator:
- jsr get_a
- cmp #'m'
- bne @not_message
- ldx #0
-:
- lda message_text,x
- beq @next_byte
- cmp #$20
- bpl @not_ctrl_char
- lda #' '
-@not_ctrl_char:
- jsr emit_a
- inx
- bne :-
-
-@not_message:
- cmp #'h'
- bne @not_handle
- ldx #0
- :
- lda handle,x
- beq @next_byte
- jsr emit_a
- inx
- bne :-
-
-@not_handle:
-
- cmp #'i'
- bne @not_ip
- lda #KPR_CFG_IP
- jmp @loaded_offset
-@not_ip:
- cmp #'g'
- bne @not_gateway
- lda #KPR_CFG_GATEWAY
- jmp @loaded_offset
-@not_gateway:
- cmp #'d'
- bne @not_dns
- lda #KPR_CFG_DNS_SERVER
- jmp @loaded_offset
-@not_dns:
- jmp @next_byte
-
-@loaded_offset:
- sta param_offset
- kippercall #KPR_GET_IP_CONFIG
- adc param_offset
- bcc :+
- inx
-:
- jsr emit_dotted_quad
-
-
- jmp @next_byte
-
-;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
-
-reset_after_keypress:
- ldax #press_a_key_to_continue
- jsr print
-@wait_key:
- jsr $f142 ;not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD)
- beq @wait_key
- jmp $fce2 ;do a cold start
-
-print_errorcode:
- ldax #error_code
- jsr print
- kippercall #KPR_GET_LAST_ERROR
- kippercall #KPR_PRINT_HEX
- jmp print_cr
-
-
-
-
-
-play_music_irq:
-; inc BORDER_COLOR
- start_irq
- jsr MUSIC_BASE+PLAYER_PLAY
-; dec BORDER_COLOR
- jmp exit_from_irq
-
-
-print:
- sta pptr
- stx pptr + 1
-
-@print_loop:
- ldy #0
- lda (pptr),y
- beq @done_print
- jsr print_a
- inc pptr
- bne @print_loop
- inc pptr+1
- bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-)
-@done_print:
- rts
-
-print_cr:
- lda #13
- jmp print_a
-
-.data
-
-sprite_ticker: .byte 0
-
-emit_a:
-current_output_ptr=emit_a+1
- sta $ffff
- inc current_output_ptr
- bne :+
- inc current_output_ptr+1
-:
- rts
-
-get_a:
-current_input_ptr=get_a+1
- lda $ffff
- inc current_input_ptr
- bne :+
- inc current_input_ptr+1
-:
- rts
-
-
-raster_jump_table:
- ;format:
- ;offset meaning
- ; $00 BIT 9 OF RASTER TO TRIGGER ON ($00 if bit 8 =0 , $80 if bit 8 =1)
- ; $01 BITS 0..7 OF RASTER TO TRIGGER ON
- ; $02 LSB OF ROUTINE TO JUMP TO
- ; $03 MSB OF ROUTINE TO JUMP TO
- ;table needs to end with a single byte $ff
- ;table needs to be sorted by scanlines
- .byte $0,$01
- .word scroll_text_irq
- .byte $0,$20
- .word pixel_scroll_irq
-
-
- .byte $0,$80
- .word play_music_irq
-
- .byte $80,$05
- .word move_sprites_irq
-
- .byte $ff ;end of list
-
-jump_counter: .byte 0
-
-.data
-kipper_api_not_found_message:
- .byte "ERROR - KIPPER API NOT FOUND.",13,0
-
-failed_msg:
- .byte "FAILED", 0
-
-ok_msg:
- .byte "OK", 0
-
-
-init_msg:
- .byte " INITIALIZING ",0
-
-press_a_key_to_continue:
- .byte "PRESS A KEY TO CONTINUE",13,0
-
-kipper_signature:
-.byte $4B,$49,$50,$50,$45,$52 ; "KIPPER"
-
-error_code:
- .asciiz "ERROR CODE: "
-
-charset_font:
- .incbin "font16x8.bin"
-sprite_font:
- .incbin "spud_letters.spr"
-
-musicdata:
-.incbin "powertrain.bin"
-musicdata_size=*-musicdata
-
-
-.segment "DATA6K"
-
-
-sprite_x_pos:
-.byte $34,$54,$78,$90,$Bb,$Db,$Fb,$1b
-
-sprite_x_msb:
-.byte $80
-
-sprite_y_pos:
-.repeat 128
- .byte 0
-.endrep
-.include "sine_data.i"
-
-;.include "sine_data.i"
-
-
-html:
- .incbin "form.html"
-.byte 0
-
-scroll_template_1:
-.byte "WebNoter - go to http://%i/ and bang away! -"
-.byte " ",0
-
-scroll_template_2:
-.byte "http://%i/"
-.byte " - %h sez '%m' -"
-.byte " ",0
-
-sprite_text:
-;[\]^_`=0,29?
-.byte "WEBNOTER"
-.byte "A KIPPER"
-.byte " POWERED"
-.byte "PRODUCT "
-.byte "TUNE IS "
-.byte "BY JCH "
-.byte "FROM THE"
-.byte "VIBRANTS"
-.byte "GREETZ ]"
-.byte "ALL AT "
-.byte "DA BEACH"
-.byte "PARTY I["
-SPRITE_FRAMES=(*-sprite_text)/8
-
-
-
-
-
-
-
-
-
-
-
-
-.segment "BSS4K"
-;we want our variables to start at $4000, out of the way of our music player and the font data
-
-handle: .res 256
-message_text: .res 256
-
-new_message:
-.res 1
-message_buffer:
-.res 256
-
-param_offset: .res 1
-
-temp_bin: .res 1
-temp_bcd: .res 2
-
-
-param_buffer: .res $20
-
-.res 10 ;filler
-scroll_buffer:
- .res 1000
-sprite_text_frame: .res 1
-string_offset: .res 1
-
-download_buffer:
-download_buffer_length=6000
- .res download_buffer_length
-
diff --git a/client/inc/a2const.i b/client/inc/a2const.i
deleted file mode 100644
index dc3f132..0000000
--- a/client/inc/a2const.i
+++ /dev/null
@@ -1,551 +0,0 @@
- GOWARM = $00
- GOSTROUT = $03
- USR = $0A
- CHARAC = $0D
- ENDCHR = $0E
- TKN_CNTR = $0F
- EOL_PNTR = $0F
- NUMDIM = $0F
- DIMFLG = $10
- VALTYP = $11
- DATAFLG = $13
- GARFLG = $13
- SUBFLG = $14
- INPUTFLG = $15
- CPRMASK = $16
- SIGNFLG = $16
- HGR_SHAPE = $1A
- HGR_BITS = $1C
- HGR_COUNT = $1D
- MON_CH = $24
- MON_GBASL = $26
- MON_GBASH = $27
- MON_H2 = $2C
- MON_V2 = $2D
- MON_HMASK = $30
- MON_INVFLG = $32
- MON_PROMPT = $33
- MON_A1L = $3C
- MON_A1H = $3D
- MON_A2L = $3E
- MON_A2H = $3F
- LINNUM = $50
- TEMPPT = $52
- LASTPT = $53
- TEMPST = $55
- INDEX = $5E
- DEST = $60
- RESULT = $62
- TXTTAB = $67
- VARTAB = $69
- ARYTAB = $6B
- STREND = $6D
- FRETOP = $6F
- FRESPC = $71
- MEMSIZ = $73
- CURLIN = $75
- OLDLIN = $77
- OLDTEXT = $79
- DATLIN = $7B
- DATPTR = $7D
- INPTR = $7F
- VARNAM = $81
- VARPNT = $83
- FORPNT = $85
- TXPSV = $87
- LASTOP = $87
- CPRTYP = $89
- TEMP3 = $8A
- FNCNAM = $8A
- DSCPTR = $8C
- DSCLEN = $8F
- JMPADRS = $90
- LENGTH = $91
- ARG_EXTENSION = $92
- TEMP1 = $93
- ARYPNT = $94
- HIGHDS = $94
- HIGHTR = $96
- TEMP2 = $98
- TMPEXP = $99
- INDX = $99
- EXPON = $9A
- DPFLG = $9B
- LOWTR = $9B
- EXPSGN = $9C
- FAC = $9D
- DSCTMP = $9D
- VPNT = $A0
- FAC_SIGN = $A2
- SERLEN = $A3
- SHIFT_SIGN_EXT = $A4
- ARG = $A5
- ARG_SIGN = $AA
- SGNCPR = $AB
- FAC_EXTENSION = $AC
- SERPNT = $AD
- STRNG1 = $AB
- STRNG2 = $AD
- PRGEND = $AF
- CHRGET = $B1
- CHRGOT = $B7
- TXTPTR = $B8
- RNDSEED = $C9
- HGR_DX = $D0
- HGR_DY = $D2
- HGR_QUADRANT = $D3
- HGR_E = $D4
- LOCK = $D6
- ERRFLG = $D8
- ERRLIN = $DA
- ERRPOS = $DC
- ERRNUM = $DE
- ERRSTK = $DF
- HGR_X = $E0
- HGR_Y = $E2
- HGR_COLOR = $E4
- HGR_HORIZ = $E5
- HGR_PAGE = $E6
- HGR_SCALE = $E7
- HGR_SHAPE_PNTR = $E8
- HGR_COLLISIONS = $EA
- FIRST = $F0
- SPEEDZ = $F1
- TRCFLG = $F2
- FLASH_BIT = $F3
- TXTPSV = $F4
- CURLSV = $F6
- REMSTK = $F8
- HGR_ROTATION = $F9
-
-M_NEG = $D0C7
-M_EQU = $D0CA
-M_REL = $D0CD
-QT_ERROR = $D353
-QT_IN = $D35B
-QT_BREAK = $D35D
-BLTU = $D393
-BLTU2 = $D39A
-CHKMEM = $D3D6
-REASON = $D3E3
-MEMERR = $D410
-ERROR = $D412
-INLIN = $D52C
-INLIN2 = $D52E
-INCHR = $D553
-PARSE = $D56C
-FNDLIN = $D61A
-FL1 = $D61E
-RTS_1 = $D648
-NEW = $D649
-SCRTCH = $D64B
-CLEAR = $D66A
-CLEARC = $D66C
-STKINI = $D683
-RTS_2 = $D696
-STXTPT = $D697
-LIST = $D6A5
-LIST_0 = $D6DA
-LIST_1 = $D6FE
-LIST_2 = $D702
-LIST_3 = $D724
-GETCHR = $D72C
-LIST_4 = $D734
-FOR = $D766
-STEP = $D7AF
-NEWSTT = $D7D2
-TRACE_ = $D805
-GOEND = $D826
-EXECUTE_STATEMENT=$D828
-COLON_ = $D842
-SYNERR_1 = $D846
-SETDA = $D853
-RTS_3 = $D857
-ISCNTC = $D858
-STOP = $D86E
-END = $D870
-END2 = $D871
-END4 = $D88A
-CONT = $D896
-RTS_4 = $D8AF
-SAVE = $D8B0
-LOAD = $D8C9
-VARTIO = $D8F0
-PROGIO = $D901
-RUN = $D912
-GOSUB = $D921
-GOTO = $D93E
-RTS_5 = $D96A
-POP = $D96B
-UNDERR = $D97C
-SYNERR_2 = $D981
-RETURN = $D984
-DATA = $D995
-ADDON = $D998
-RTS_6 = $D9A2
-DATAN = $D9A3
-REMN = $D9A6
-PULL3 = $D9C5
-IF = $D9C9
-REM = $D9DC
-ONGOTO = $D9EC
-ON_1 = $D9F4
-ON_2 = $D9F8
-RTS_7 = $DA0B
-LINGET = $DA0C
-LET = $DA46
-LET2 = $DA63
-PUTSTR = $DA7B
-PRINT = $DAD5
-PRINT2 = $DAD7
-CRDO = $DAFB
-NEGATE = $DB00
-RTS_8 = $DB02
-NXSPC = $DB2C
-DOSPC = $DB35
-STROUT = $DB3A
-STRPRT = $DB3D
-OUTSP = $DB57
-OUTQUES = $DB5A
-OUTDO = $DB5C
-ERLIN = $DB7F
-INPERR = $DB86
-GET = $DBA0
-INPUT = $DBB2
-NXIN = $DBDC
-READ = $DBE2
-INPFIN = $DC99
-NEXT = $DCF9
-NEXT_1 = $DCFF
-NEXT_2 = $DD02
-GERR = $DD0D
-NEXT_3 = $DD0F
-FRMNUM = $DD67
-CHKNUM = $DD6A
-CHKSTR = $DD6C
-CHKVAL = $DD6D
-JERROR = $DD78
-FRMEVL = $DD7B
-NXOP = $DDD6
-SAVOP = $DDD7
-PREFNC = $DDF6
-SNTXERR = $DE0D
-NOTMATH = $DE35
-GOEX = $DE38
-EXIT = $DE5D
-STRTXT = $DE81
-NOT_ = $DE90
-EQUOP = $DE98
-FN_ = $DEA4
-SGN_ = $DEAB
-PARCHK = $DEB2
-CHKCLS = $DEB8
-CHKOPN = $DEBB
-CHKCOM = $DEBE
-SYNCHR = $DEC0
-SYNERR = $DEC9
-MIN = $DECE
-EQUL = $DED0
-SCREEN = $DEF9
-UNARY = $DF0C
-OR_KWD = $DF4F
-AND_KWD = $DF55
-FALSE = $DF5D
-TRUE = $DF60
-RELOPS = $DF65
-STRCMP = $DF7D
-NUMCMP = $DFB0
-PDL = $DFCD
-NXDIM = $DFD6
-DIM = $DFD9
-PTRGET = $DFE3
-BADNAM = $DFF4
-NAMOK = $DFF7
-ISLETC = $E07D
-C_ZERO = $E09A
-GETARY = $E0ED
-NEG32768 = $E101
-MAKINT = $E102
-MKINT = $E108
-AYINT = $E10C
-MI1 = $E119
-MI2 = $E11B
-ARRAY = $E11E
-SUBERR = $E196
-IQERR = $E199
-JER = $E19B
-FAE_1 = $E253
-GSE = $E269
-GME = $E26C
-FAE_2 = $E26F
-FAE_3 = $E270
-RTS_9 = $E2AC
-MULTIPLY_SUBSCRIPT = $E2AD
-FRE = $E2DE
-GIVAYF = $E2F2
-POS = $E2FF
-SNGFLT = $E301
-ERRDIR = $E306
-UNDFNC = $E30E
-DEF = $E313
-FNC_ = $E341
-FUNCT = $E354
-STR = $E3C5
-STRINI = $E3D5
-STRSPA = $E3DD
-STRLIT = $E3E7
-STRLT2 = $E3ED
-PUTNEW = $E42A
-JERR = $E432
-PUTEMP = $E435
-GETSPA = $E452
-GARBAG = $E484
-CAT = $E597
-MOVINS = $E5D4
-MOVSTR = $E5E2
-FRESTR = $E5FD
-FREFAC = $E600
-FRETMP = $E604
-FRETMS = $E635
-CHRSTR = $E646
-MIDSTR = $E691
-LEN = $E6D6
-GETSTR = $E6DC
-ASC = $E6E5
-GOIQ = $E6F2
-GTBYTC = $E6F5
-GETBYT = $E6F8
-CONINT = $E6FB
-VAL = $E707
-POINT = $E73D
-GTNUM = $E746
-COMBYTE = $E74C
-GETADR = $E752
-PEEK = $E764
-POKE = $E77B
-WAIT = $E784
-RTS_10 = $E79F
-FADDH = $E7A0
-FSUB = $E7A7
-FSUBT = $E7AA
-FADD_1 = $E7B9
-FADD = $E7BE
-FADDT = $E7C1
-FADD_2 = $E7CE
-FADD_3 = $E7FA
-FADD_4 = $E855
-RTS_11 = $E89D
-RTS_12 = $E8D4
-CON_ONE = $E916
-POLY_LOG = $E918
-CON_SQR_HALF = $E930
-CON_SQR_TWO = $E935
-CON_NEG_HALF = $E93A
-CON_LOG_TWO = $E93F
-LOG = $E941
-GIQ = $E948
-LOG_2 = $E94B
-FMULT = $E97F
-FMULTT = $E982
-RTS_13 = $E9E2
-ZERO = $EA31
-JOV = $EA36
-MUL10 = $EA39
-CON_TEN = $EA53
-DIV10 = $EA55
-DIV = $EA5E
-FDIV = $EA66
-FDIVT = $EA69
-SETFOR = $EB27
-MFA = $EB55
-MAF = $EB66
-RTS_14 = $EB71
-SIGN = $EB82
-SIGN1 = $EB86
-SIGN2 = $EB88
-RTS_15 = $EB8F
-SGN = $EB90
-FLOAT = $EB93
-ABS = $EBAF
-FCOMP = $EBB2
-FCOMP2 = $EBB4
-QINT = $EBF2
-RTS_16 = $EC11
-QINT_2 = $EC12
-INT = $EC23
-QINT_3 = $EC40
-RTS_17 = $EC49
-FIN = $EC4A
-FIN_1 = $EC61
-FIN_2 = $EC64
-FIN_3 = $EC66
-FIN_4 = $EC87
-FIN_5 = $EC8A
-FIN_6 = $EC8C
-FIN_10 = $EC98
-FIN_7 = $EC9E
-FIN_8 = $ECA0
-FIN_9 = $ECC1
-ADDACC = $ECD5
-GETEXP = $ECE8
-CON_99999999_9 = $ED0D
-CON_999999999 = $ED12
-CON_BILLION = $ED17
-INPRT = $ED19
-LINPRT = $ED24
-FOUT = $ED34
-FOUT_1 = $ED36
-FOUT_2 = $ED8C
-FOUT_3 = $EE17
-FOUT_4 = $EE57
-FOUT_5 = $EE5A
-FOUT_6 = $EE5F
-CON_HALF = $EE67
-DECTBL = $EE6C
-SQR = $EE8D
-FPWRT = $EE97
-NEGOP = $EED0
-RTS_18 = $EEDA
-CON_LOG_E = $EEDE
-POLY_EXP = $EEE0
-EXP = $EF09
-RTS_19 = $EFA5
-CON_RND_1 = $EFA9
-CON_RND_2 = $EFAD
-RND = $EFAE
-GO_MOVMF = $EFE7
-COS = $EFEA
-SIN = $EFF1
-SIN_1 = $F023
-SIN_2 = $F026
-TAN = $F03A
-TAN_1 = $F062
-CON_PI_HALF = $F069
-CON_PI_DOUB = $F06E
-QUARTER = $F073
-POLY_SIN = $F075
-ATN = $F09E
-RTS_20 = $F0CD
-POLY_ATN = $F0CE
-CALL = $F1D5
-GOERR = $F206
-PLOT = $F225
-HLIN = $F232
-VLIN = $F241
-COLOR = $F24F
-VTAB = $F256
-SPEED = $F262
-TRACE = $F26D
-NORMAL = $F273
-N_I_ = $F279
-N_I_F_ = $F27B
-FLASH = $F280
-HIMEM = $F286
-JMM = $F296
-SETHI = $F299
-LOMEM = $F2A6
-ONERR = $F2CB
-RESUME = $F318
-JSYN = $F32E
-DEL = $F331
-GR = $F390
-TEXT = $F399
-STORE = $F39F
-RECALL = $F3BC
-HGR2 = $F3D8
-HGR = $F3E2
-SETHPG = $F3EA
-HCLR = $F3F2
-BKGND = $F3F6
-HPOSN = $F411
-HPLOT0 = $F457
-LR_1 = $F46E
-LR_2 = $F471
-LR_3 = $F476
-LR_4 = $F478
-LRUDX1 = $F49C
-LRUDX2 = $F49D
-LRUD1 = $F4B3
-LRUD2 = $F4B4
-LRUD3 = $F4C4
-LRUD4 = $F4C8
-UD_1 = $F501
-HLINRL = $F530
-HGLIN = $F53A
-MOVEX = $F57C
-MOVEX2 = $F581
-MSKTBL = $F5B8
-CON_1C = $F5B9
-HFIND = $F5CB
-RTS_22 = $F600
-DRAW0 = $F601
-DRAW1 = $F605
-XDRAW0 = $F65D
-XDRAW1 = $F661
-HFNS = $F6B9
-GGERR = $F6E6
-HCOLOR = $F6E9
-RTS_23 = $F6F5
-COLORTBL = $F6FC
-HPLOT = $F6FE
-ROT = $F721
-SCALE = $F727
-DRWPNT = $F72D
-DRAW = $F769
-XDRAW = $F76F
-SHLOAD = $F775
-HTAB = $F7E7
-
-STACK = $100
-INPUT_BUFFER = $200
-AMPERSAND_VECTOR = $3F5
-KEYBOARD = $C000
-SW_TXTCLR = $C050
-SW_MIXCLR = $C052
-SW_MIXSET = $C053
-SW_LOWSCR = $C054
-SW_HISCR = $C055
-SW_LORES = $C056
-SW_HIRES = $C057
-MON_PLOT = $F800
-MON_HLINE = $F819
-MON_VLINE = $F828
-MON_SETCOL = $F864
-MON_SCRN = $F871
-MON_PREAD = $FB1E
-MON_SETTXT = $FB39
-MON_SETGR = $FB40
-MON_TABV = $FB5B
-MON_HOME = $FC58
-MON_WAIT = $FCA8
-MON_RD2BIT = $FCFA
-MON_RDKEY = $FD0C
-MON_GETLN = $FD6A
-MON_COUT = $FDED
-MON_INPORT = $FE8B
-MON_OUTPORT = $FE95
-MON_WRITE = $FECD
-MON_READ = $FEFD
-MON_READ2 = $FF02
-TOKEN_FOR = $81
-TOKEN_DATA = $83
-TOKEN_POP = $A1
-TOKEN_GOTO = $AB
-TOKEN_GOSUB = $B0
-TOKEN_REM = $B2
-TOKEN_PRINT = $BA
-TOKEN_TAB = $C0
-TOKEN_TO = $C1
-TOKEN_FN = $C2
-TOKEN_SPC = $C3
-TOKEN_THEN = $C4
-TOKEN_AT = $C5
-TOKEN_NOT = $C6
-TOKEN_STEP = $C7
-TOKEN_PLUS = $C8
-TOKEN_MINUS = $C9
-TOKEN_GREATER = $CF
-TOKEN_EQUAL = $D0
-TOKEN_SGN = $D2
-TOKEN_SCRN = $D7
-TOKEN_LEFTSTR = $E8
diff --git a/client/inc/a2keycodes.i b/client/inc/a2keycodes.i
deleted file mode 100644
index b21fc05..0000000
--- a/client/inc/a2keycodes.i
+++ /dev/null
@@ -1,28 +0,0 @@
-KEYCODE_SLASH=('/'+$80)
-KEYCODE_DOWN=$8a
-KEYCODE_UP=$8b
-KEYCODE_LEFT=$88
-KEYCODE_RIGHT=$95
-KEYCODE_ABORT=$9B
-.define KEYNAME_ABORT "ESC"
-.export KEYCODE_ABORT
-
-
-;-- LICENSE FOR a2keycodes.i --
-; 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/inc/c64keycodes.i b/client/inc/c64keycodes.i
deleted file mode 100644
index 2f41234..0000000
--- a/client/inc/c64keycodes.i
+++ /dev/null
@@ -1,36 +0,0 @@
-KEYCODE_SLASH=$2f
-KEYCODE_DOWN=$11
-KEYCODE_UP=$91
-KEYCODE_LEFT=$9d
-KEYCODE_RIGHT=$1d
-KEYCODE_F1=$85
-KEYCODE_F2=$89
-KEYCODE_F3=$86
-KEYCODE_F4=$8a
-KEYCODE_F5=$87
-KEYCODE_F6=$8b
-KEYCODE_F7=$88
-KEYCODE_F8=$8c
-KEYCODE_ABORT=$03 ;RUN/STOP
-.define KEYNAME_ABORT "RUN/STOP"
-.export KEYCODE_ABORT
-.export KEYCODE_F1
-
-;-- LICENSE FOR c64keycodes.i --
-; 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/inc/config_menu.i b/client/inc/config_menu.i
deleted file mode 100644
index 71fd88d..0000000
--- a/client/inc/config_menu.i
+++ /dev/null
@@ -1,212 +0,0 @@
-
- .import dns_ip
- .import dns_resolve
- .import dns_set_hostname
-.import cfg_default_drive
-.bss
- temp_ax: .res 2
-.code
-
-configuration_menu:
- jsr cls
-@show_config_menu:
- ldax #menu_header_msg
- jsr print_ascii_as_native
- ldax #config_menu_msg
- jsr print_ascii_as_native
- jsr print_ip_config
- jsr print_default_drive
- jsr print_cr
-@get_key_config_menu:
- jsr get_key_ip65
- cmp #KEYCODE_ABORT
- bne @not_abort
- rts
-@not_abort:
- cmp #KEYCODE_F1
- bne @not_ip
- ldax #new
- jsr print_ascii_as_native
- ldax #ip_address_msg
- jsr print_ascii_as_native
- jsr print_cr
- ldax #filter_ip
- ldy #20
- jsr get_filtered_input
- bcs @no_ip_address_entered
- jsr parse_dotted_quad
- bcc @no_ip_resolve_error
- jmp configuration_menu
-@no_ip_resolve_error:
- ldax #dotted_quad_value
- stax copy_src
- ldax #cfg_ip
- stax copy_dest
- ldax #4
- jsr copymem
-@no_ip_address_entered:
- jmp configuration_menu
-
-@not_ip:
- cmp #KEYCODE_F2
- bne @not_netmask
- ldax #new
- jsr print_ascii_as_native
- ldax #netmask_msg
- jsr print_ascii_as_native
- jsr print_cr
- ldax #filter_ip
- ldy #20
- jsr get_filtered_input
- bcs @no_netmask_entered
- jsr parse_dotted_quad
- bcc @no_netmask_resolve_error
- jmp configuration_menu
-@no_netmask_resolve_error:
- ldax #dotted_quad_value
- stax copy_src
- ldax #cfg_netmask
- stax copy_dest
- ldax #4
- jsr copymem
-@no_netmask_entered:
- jmp configuration_menu
-
-@not_netmask:
- cmp #KEYCODE_F3
- bne @not_gateway
- ldax #new
- jsr print_ascii_as_native
- ldax #gateway_msg
- jsr print_ascii_as_native
- jsr print_cr
- ldax #filter_ip
- ldy #20
- jsr get_filtered_input
- bcs @no_gateway_entered
- jsr parse_dotted_quad
- bcc @no_gateway_resolve_error
- jmp configuration_menu
-@no_gateway_resolve_error:
- ldax #dotted_quad_value
- stax copy_src
- ldax #cfg_gateway
- stax copy_dest
- ldax #4
- jsr copymem
- jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test
-@no_gateway_entered:
- jmp configuration_menu
-
-
-@not_gateway:
- cmp #KEYCODE_F4
- bne @not_dns_server
- ldax #new
- jsr print_ascii_as_native
- ldax #dns_server_msg
- jsr print_ascii_as_native
- jsr print_cr
- ldax #filter_ip
- ldy #20
- jsr get_filtered_input
- bcs @no_dns_server_entered
- jsr parse_dotted_quad
- bcc @no_dns_resolve_error
- jmp configuration_menu
-@no_dns_resolve_error:
- ldax #dotted_quad_value
- stax copy_src
- ldax #cfg_dns
- stax copy_dest
- ldax #4
- jsr copymem
-@no_dns_server_entered:
-
- jmp configuration_menu
-
-@not_dns_server:
- cmp #KEYCODE_F5
- bne @not_tftp_server
- ldax #new
- jsr print_ascii_as_native
- ldax #tftp_server_msg
- jsr print_ascii_as_native
- jsr print_cr
- ldax #filter_dns
- ldy #40
- jsr get_filtered_input
- bcs @no_server_entered
- stax temp_ax
- jsr print_cr
- ldax #resolving
- jsr print_ascii_as_native
- ldax temp_ax
- jsr dns_set_hostname
- bcs @resolve_error
- jsr dns_resolve
- bcs @resolve_error
-
- ldax #dns_ip
- stax copy_src
- ldax #cfg_tftp_server
- stax copy_dest
- ldax #4
- jsr copymem
-@no_server_entered:
- jmp configuration_menu
-
-@not_tftp_server:
-
-
-cmp #KEYCODE_F6
- bne @not_reset
- jsr ip65_init ;this will reset everything
- jmp configuration_menu
-@not_reset:
-cmp #KEYCODE_F7
- bne @not_main_menu
- jmp main_menu
-
-@not_main_menu:
-
-cmp #'+'
- bne @not_plus
- inc cfg_default_drive
- jmp @show_config_menu
-@not_plus:
-
-cmp #'-'
- bne @not_minus
- dec cfg_default_drive
- jmp @show_config_menu
-
-@not_minus:
-
- jmp @get_key_config_menu
-
-@resolve_error:
- print_failed
- jsr wait_for_keypress
- jmp configuration_menu
-
-
-print_default_drive:
- ldax #default_drive
- jsr print_ascii_as_native
- lda cfg_default_drive
- jsr print_hex
- jmp print_cr
-
-.rodata
-
-config_menu_msg:
-.byte 10,"Configuration",10,10
-.byte "F1: IP Address F2: Netmask",10
-.byte "F3: Gateway F4: DNS Server",10
-.byte "F5: TFTP Server F6: Reset To Default",10
-.byte "F7: Main Menu +/- Drive #",10,10
-.byte 0
-
-default_drive:
-.byte "Use Drive # : $",0
diff --git a/client/inc/disk_transfer.i b/client/inc/disk_transfer.i
deleted file mode 100644
index 3400338..0000000
--- a/client/inc/disk_transfer.i
+++ /dev/null
@@ -1,268 +0,0 @@
-
-.import io_track_no
-.import io_sector_no
-.import io_write_sector
-.import io_read_sector
-
-
-.segment "APP_SCRATCH"
- track: .res 1
- sector: .res 1
- errors: .res 1
- sectors_in_track: .res 1
- sector_buffer_address: .res 2
- output_buffer_address: .res 2
-;the io_* and tftp_* routines both use the 'output_buffer' so we lose the data in the second sector
-;therefore we need to copy the data to here before we use it
- sector_buffer: .res 512
-
-.code
-download_d64:
- stax kipper_param_buffer+KPR_TFTP_FILENAME
- jsr cls
- ldax #downloading_msg
- jsr print_ascii_as_native
- ldax kipper_param_buffer+KPR_TFTP_FILENAME
- jsr print_ascii_as_native
- jsr reset_counters_to_first_sector
- ldax #write_next_block
- stax kipper_param_buffer+KPR_TFTP_POINTER
- ldax #kipper_param_buffer
- kippercall #KPR_TFTP_CALLBACK_DOWNLOAD
-after_tftp_transfer:
- bcc :+
- jsr print_cr
- print_failed
- jsr print_errorcode
- jsr print_cr
-:
- print_ok
- ldax #press_a_key_to_continue
- jsr print
- jsr get_key
- rts
-
-
-upload_d64:
- ldax #enter_filename
- jsr print
- kippercall #KPR_INPUT_HOSTNAME ;the 'hostname' filter is pretty close to being a filter for legal chars in file names as well
- bcc :+
- rts
-:
-
- stax kipper_param_buffer+KPR_TFTP_FILENAME
- jsr cls
- ;switch to lower case charset
- lda #23
- sta $d018
- ldax #uploading_msg
- jsr print
- ldax kipper_param_buffer+KPR_TFTP_FILENAME
- jsr print
- jsr reset_counters_to_first_sector
- ldax #read_next_block
- stax kipper_param_buffer+KPR_TFTP_POINTER
- ldax #kipper_param_buffer
- kippercall #KPR_TFTP_CALLBACK_UPLOAD
- jmp after_tftp_transfer
-
-copy_sector_buffer_to_output_buffer:
- ldax #sector_buffer
- stax copy_src
- ldax output_buffer_address
- stax copy_dest
- ldax #$200
- jmp copymem
-
-read_next_block:
-;tftp upload callback routine
-;AX will point to address to fill
- stax output_buffer_address
- ldax #sector_buffer
- stax sector_buffer_address
-
- lda track
- cmp #36
- beq @past_last_track
- jsr read_sector
- bcc @not_last_sector
- jsr copy_sector_buffer_to_output_buffer
- ldax #$100
- rts
-@not_last_sector:
- inc sector_buffer_address+1
- ldax sector_buffer_address
- jsr read_sector
- jsr copy_sector_buffer_to_output_buffer
- ldax #$200
- rts
-@past_last_track:
- ldax #$0000
- rts
-
-
-save_sector:
- ldax #position_cursor_for_track_display
- jsr print
- jsr print_current_sector
-
- lda track
- sta io_track_no
-
- lda sector
- sta io_sector_no
-
- ldax sector_buffer_address
- jsr io_write_sector
- bcc :+
- inc errors
-:
- jmp move_to_next_sector
-
-
-
-read_sector:
- ldax #position_cursor_for_track_display
- jsr print
- jsr print_current_sector
-
- lda track
- sta io_track_no
-
- lda sector
- sta io_sector_no
-
- ldax sector_buffer_address
- jsr io_read_sector
- bcc :+
- inc errors
-:
- jmp move_to_next_sector
-
-write_next_block:
-;tftp download callback routine
-;AX will point at block to be written (prepended with 2 bytes indicating block length)
- clc
- adc #02 ;skip the 2 byte length at start of buffer
- bcc :+
- inx
-:
- stax copy_src
- ldax #sector_buffer
- stax copy_dest
- stax sector_buffer_address
- ldax #$200
- jsr copymem
- jsr save_sector
-
- bcc @not_last_sector
- rts
-@not_last_sector:
- inc sector_buffer_address+1
- jsr save_sector
- rts
-
-@past_last_track:
- rts
-
-
-print_current_sector:
- ldax #track_no
- jsr print_ascii_as_native
- lda track
- jsr print_hex
- ldax #sector_no
- jsr print_ascii_as_native
- lda sector
- jsr print_hex
- ldax #errors_msg
- jsr print_ascii_as_native
- lda errors
- jsr print_hex
- jsr print_cr
- rts
-
-
-reset_counters_to_first_sector:
- ldx #1
- stx track
- dex
- stx sector
- stx errors
- ldx #21
- stx sectors_in_track
- rts
-
-move_to_next_sector:
- inc sector
- lda sector
- cmp sectors_in_track
- beq @move_to_next_track
- rts
-@move_to_next_track:
- lda #0
- sta sector
- inc track
- lda track
- cmp #18
- bne @not_track_18
- lda #19
- sta sectors_in_track
- clc
- rts
-@not_track_18:
- cmp #25
- bne @not_track_25
- lda #18
- sta sectors_in_track
- clc
- rts
-@not_track_25:
- cmp #31
- bne @not_track_31
- lda #17
- sta sectors_in_track
- clc
- rts
-@not_track_31:
- lda track
- cmp #36 ;carry will be set if hit track 36
- rts
-
-
-.rodata
-
-track_no:
- .byte "TRACK $",0
-
-sector_no:
- .byte " SECTOR $",0
-errors_msg:
- .byte " ERRORS $",0
-position_cursor_for_track_display:
-.byte $13,13,13,0
-position_cursor_for_error_display:
-.byte $13,13,13,0
-enter_filename: .asciiz "FILENAME: "
-
-
-
-;-- LICENSE FOR disk_transfer.i --
-; 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/inc/gopher.i b/client/inc/gopher.i
deleted file mode 100644
index f7ec692..0000000
--- a/client/inc/gopher.i
+++ /dev/null
@@ -1,680 +0,0 @@
-; C64 gopher browser
-; july 2009 - jonno @ jamtronix.com
-; this contains the key gopher rendering routines
-; to use:
-; 1) include this file
-; 2) include these other files:
-; .include "../inc/common.i"
-; .include "../inc/commonprint.i"
-; .include "../inc/net.i"
-; .include "../inc/char_conv.i"
-; .include "../inc/c64keycodes.i"
-; 3) define a routine called 'exit_gopher'
-
-
- .import get_key_if_available
- .import mul_8_16
- .importzp acc16
- .importzp copy_src
- .importzp copy_dest
- .import copymem
- .import ascii_to_native
- .import dns_ip
- .import dns_resolve
- .import dns_set_hostname
- .import ip65_error
- .import cls
- .import get_filtered_input
- .import filter_dns
- .import filter_text
- .importzp screen_current_row
- .importzp screen_current_col
- .import print_a_inverse
-
- .import telnet_port
- .import telnet_ip
- .import telnet_connect
- .import telnet_use_native_charset
-
- .import url_ip
- .import url_port
- .import url_selector
- .import url_resource_type
- .import url_parse
- .import url_download
- .import url_download_buffer
- .import url_download_buffer_length
- .import resource_download
-
-.segment "IP65ZP" : zeropage
-
-; pointer for moving through buffers
-buffer_ptr: .res 2 ; source pointer
-
-.data
-get_next_byte:
- lda $ffff
- inc get_next_byte+1
- bne :+
- inc get_next_byte+2
-:
- rts
-
-
-current_resource_history_entry: .byte 0
-
-.segment "APP_SCRATCH"
-
-DISPLAY_LINES=22
-page_counter: .res 1
-MAX_PAGES = 50
-page_pointer_lo: .res MAX_PAGES
-page_pointer_hi: .res MAX_PAGES
-
-resource_counter: .res 1
-MAX_RESOURCES = DISPLAY_LINES
-
-resource_pointer_lo: .res MAX_RESOURCES
-resource_pointer_hi: .res MAX_RESOURCES
-resource_type: .res MAX_RESOURCES
-
-download_flag: .res 1
-dl_loop_counter: .res 2
-this_is_last_page: .res 1
-
-
-;temp_ax: .res 2
-
-RESOURCE_HOSTNAME_MAX_LENGTH=64
-current_resource:
-resource_hostname: .res RESOURCE_HOSTNAME_MAX_LENGTH
-resource_port: .res 2
-resource_selector: .res 128
-resource_selector_length: .res 1
-displayed_resource_type: .res 1
-
-
-RESOURCE_HISTORY_ENTRIES=8
-resource_history:
-.res $100*RESOURCE_HISTORY_ENTRIES
-
-scratch_buffer_length=GOPHER_BUFFER_SIZE
-scratch_buffer:
- .res scratch_buffer_length
-
-.code
-
-;display whatever is in the buffer either as plain text or gopher text
-
-display_resource_in_buffer:
- ldax #scratch_buffer
- stax get_next_byte+1
-
- lda #0
- sta page_counter
-
-@do_one_page:
- jsr cls
-
-; ldax #page_header
-; jsr print
-; lda page_counter
-; jsr print_hex
-
-; jsr print_resource_description
- ldx page_counter
- lda get_next_byte+1
- sta page_pointer_lo,x
- lda get_next_byte+2
- sta page_pointer_hi,x
- inc page_counter
-
-
- lda displayed_resource_type
- cmp #'0'
- bne @displayed_resource_is_directory
-
-;if this is a text file, just convert ascii->petscii and print to screen
-@show_one_char:
- jsr get_next_byte
- tax ;this sets Z flag
- bne :+
- lda #1
- sta this_is_last_page
- jmp @get_keypress
-:
-
- jsr ascii_to_native
- jsr print_a
- lda screen_current_row
- cmp #DISPLAY_LINES
- bmi @show_one_char
- jmp @end_of_current_page
-
-@displayed_resource_is_directory:
-
- lda #0
- sta resource_counter
-
-@next_line:
- jsr get_next_byte
- cmp #0
- beq @last_line
- cmp #'.'
- bne @not_last_line
-@last_line:
- lda #1
- sta this_is_last_page
- jmp @done
-@not_last_line:
- cmp #'i'
- beq @info_line
- cmp #'0'
- beq @standard_resource
- cmp #'1'
- beq @standard_resource
- cmp #'7'
- beq @standard_resource
- cmp #'8'
- beq @standard_resource
-
- ;if we got here, we know not what it is
- jmp @skip_to_end_of_line
-@standard_resource:
- pha
- ldx resource_counter
- sta resource_type,x
- sec
- lda get_next_byte+1
- sbc #1 ;since "get_next_byte" did the inc, we need to backtrack 1 byte
- sta resource_pointer_lo,x
- lda get_next_byte+2
- sbc #0 ;in case there was an overflow on the low byte
- sta resource_pointer_hi,x
- inc resource_counter
-
- lda screen_current_col ;are we at the start of the current line?
- beq :+
-
- jsr print_cr
-:
- pla ;get back the resource type
-
- lda resource_counter
- clc
- adc #'a'-1
- jsr print_a_inverse
- lda #' '
- jsr print_a
-
-@info_line:
-@print_until_tab:
-@next_byte:
- jsr get_next_byte
- cmp #0
- beq @last_line
-
- cmp #$09
- beq @skip_to_end_of_line
- jsr ascii_to_native
- jsr print_a
- jmp @next_byte
-
-@skip_to_end_of_line:
- jsr get_next_byte
- cmp #0
- beq @last_line
-
- cmp #$0A
- bne @skip_to_end_of_line
-
- lda screen_current_col
- cmp #0
- beq :+
- jsr print_cr
-:
- lda screen_current_row
- cmp #DISPLAY_LINES
- bpl @end_of_current_page
- jmp @next_line
-
-@end_of_current_page:
- lda #0
- sta this_is_last_page
-@done:
-@get_keypress:
- jsr ip65_process ;keep polling the network, so we respond to arps/pings/late packets etc etc
- jsr get_key_if_available
- cmp #' '
- beq @go_next_page
- cmp #KEY_NEXT_PAGE
- beq @go_next_page
- cmp #KEYCODE_DOWN
- beq @go_next_page
- cmp #KEY_PREV_PAGE
- beq @go_prev_page
- cmp #KEYCODE_UP
- beq @go_prev_page
- cmp #KEY_SHOW_HISTORY
- beq @show_history
- cmp #KEYCODE_LEFT
- beq @back_in_history
- cmp #KEY_BACK_IN_HISTORY
- beq @back_in_history
- cmp #KEY_NEW_SERVER
- beq @prompt_for_new_server
-
- cmp #KEYCODE_ABORT
- beq @quit
- ;if fallen through we don't know what the keypress means, go get another one
- and #$7f ;turn off the high bit
- sec
- sbc #$40
- bmi @not_a_resource
- cmp resource_counter
- beq @valid_resource
- bcs @not_a_resource
-@valid_resource:
- tax
- dex
- jsr select_resource_from_current_directory
-@not_a_resource:
- jmp @get_keypress
-@back_in_history:
- ldx current_resource_history_entry
- dex
- beq @get_keypress ;if we were already at start of history, can't go back any further
- stx current_resource_history_entry
- txa
- jsr load_resource_from_history
- jsr load_resource_into_buffer
- jmp display_resource_in_buffer
-@show_history:
- jsr show_history
- jmp display_resource_in_buffer
-@go_next_page:
- lda this_is_last_page
- bne @get_keypress
- jmp @do_one_page
-@prompt_for_new_server:
- jsr prompt_for_gopher_resource ;that routine only returns if no server was entered.
- jmp display_resource_in_buffer
-
-@quit:
- jmp exit_gopher
-@go_prev_page:
- ldx page_counter
- dex
- bne @not_first_page
- jmp @get_keypress
-@not_first_page:
- dex
- dec page_counter
- dec page_counter
-
- lda page_pointer_lo,x
- sta get_next_byte+1
- lda page_pointer_hi,x
- sta get_next_byte+2
- jmp @do_one_page
-
-;get a gopher resource
-;X should be the selected resource number
-;the resources selected should be loaded into resource_pointer_*
-select_resource_from_current_directory:
- lda resource_pointer_lo,x
- sta buffer_ptr
- lda resource_pointer_hi,x
- sta buffer_ptr+1
- ldy #0
- ldx #0
-
- lda (buffer_ptr),y
- sta displayed_resource_type
-
-@skip_to_next_tab:
- iny
- beq @done_skipping_over_tab
- lda (buffer_ptr),y
- cmp #$09
- bne @skip_to_next_tab
-@done_skipping_over_tab:
-
-;should now be pointing at the tab just before the selector
-@copy_selector:
- iny
- lda (buffer_ptr),y
- cmp #09
- beq @end_of_selector
- sta resource_selector,x
- inx
- jmp @copy_selector
-@end_of_selector:
- stx resource_selector_length
- ;terminate with a CR,LF,$00
- lda #$0D
- sta resource_selector,x
- lda #$0A
- sta resource_selector+1,x
- lda #$00
- sta resource_selector+2,x
-
-
- tax
-;should now be pointing at the tab just before the hostname
-@copy_hostname:
- iny
- lda (buffer_ptr),y
- cmp #09
- beq @end_of_hostname
- sta resource_hostname,x
- inx
- jmp @copy_hostname
-
-@end_of_hostname:
- lda #$00
- sta resource_hostname,x
-
-;should now be pointing at the tab just before the port number
- lda #0
- sta resource_port
- sta resource_port+1
-@parse_port:
- iny
- beq @end_of_port
- lda (buffer_ptr),y
- cmp #$1F
- bcc @end_of_port ;any control char should be treated as end of port field
-
- ldax resource_port
- stax acc16
- lda #10
- jsr mul_8_16
- ldax acc16
- stax resource_port
- lda (buffer_ptr),y
- sec
- sbc #'0'
- clc
- adc resource_port
- sta resource_port
- bcc :+
- inc resource_port+1
-:
- jmp @parse_port
-@end_of_port:
-
- lda displayed_resource_type
-
- cmp #'7' ;is it a 'search' resource?
- bne @done
-
- ldax #query
- jsr print
-@get_query_string:
- ldy #32 ;max chars
- ldax #filter_text
- jsr get_filtered_input
- bcs @get_query_string
- stax buffer_ptr
- jsr print_cr
- ldy #0
- ldx resource_selector_length
- lda #09
-@copy_one_char:
- sta resource_selector,x
- inx
- lda (buffer_ptr),y
- beq @done_query_string
- iny
- bne @copy_one_char
-@done_query_string:
- ;terminate with a CR,LF,$00
- lda #$0D
- sta resource_selector,x
- lda #$0A
- sta resource_selector+1,x
- lda #$00
- sta resource_selector+2,x
-
-@done:
-
-add_resource_to_history_and_display:
- ;add this to the resource history
- lda current_resource_history_entry
- cmp #RESOURCE_HISTORY_ENTRIES
- bne @dont_shuffle_down
- ldax #resource_history
- stax copy_dest
- inx ;one page higher up
- stax copy_src
- ldx #(RESOURCE_HISTORY_ENTRIES-1)
- lda #$00
- jsr copymem
- dec current_resource_history_entry
-
-@dont_shuffle_down:
- ldax #current_resource
- stax copy_src
- lda #resource_history
- adc current_resource_history_entry
- sta copy_dest+1
- ldax #$100
- jsr copymem
-
- inc current_resource_history_entry
-
- jsr load_resource_into_buffer
- bcs @error_in_loading
- jmp display_resource_in_buffer
-@error_in_loading:
- jmp print_errorcode
-
-
-;show the entries in the history buffer
-show_history:
-
- jsr cls
- ldax #history
- jsr print
-
- lda current_resource_history_entry
-@show_one_entry:
- pha
- jsr load_resource_from_history
- jsr print_resource_description
- pla
- sec
- sbc #1
- bne @show_one_entry
-get_keypress_then_rts:
- jsr print_cr
- ldax #press_a_key_to_continue
- jsr print
- jsr get_key_ip65
- rts
-
-
-;load the 'current_resource' into the buffer
-load_resource_into_buffer:
- ldax #resolving
- jsr print
- ldax #resource_hostname
- jsr print
- jsr print_cr
- ldax #resource_hostname
- jsr dns_set_hostname
-
- bcs :+
- jsr dns_resolve
-:
- bcc @no_error
- rts
-@no_error:
- ldx #3 ; save IP address just retrieved
-: lda dns_ip,x
- sta url_ip,x
- sta telnet_ip,x
- dex
- bpl :-
-
-
- lda displayed_resource_type
- cmp #'8' ;is it a 'telnet' resource?
- bne @not_telnet_resource
- ldax #connecting
- jsr print
- ldax resource_port
- stax telnet_port
- lda #0
- sta telnet_use_native_charset
-
- ;if the username = '/n', then connect in native mode
- lda resource_selector_length
-
- cmp #2
- bne @not_native
- lda resource_selector
- cmp #'/'
- bne @not_native
- lda resource_selector+1
- cmp #'n'
- bne @not_native
- inc telnet_use_native_charset
-@not_native:
- jsr telnet_connect
- jmp get_keypress_then_rts
-
-@not_telnet_resource:
- ldax resource_port
- stax url_port
- ldax #resource_selector
- stax url_selector
- ldax #scratch_buffer
- stax url_download_buffer
- ldax #scratch_buffer_length
- stax url_download_buffer_length
-
- jmp resource_download
-
-
-
-;retrieve entry specified by A from resource history
-;NB 'A' = 1 means the first entry
-load_resource_from_history:
- clc
- adc #(>resource_history)-1
- sta copy_src+1
- lda # timestamp.i
- $(AS) $(AFLAGS) -o $@ $<
-
-%.o: %.s $(INCFILES)
- $(AS) $(AFLAGS) $<
-
-%.prg: %.o $(IP65LIB) $(C64RRNETLIB) $(INCFILES) ../cfg/c64fullprg.cfg
- $(LD) -m $*.map -vm -C ../cfg/c64fullprg.cfg -o $*.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64RRNETLIB)
- ruby ../carts/set_ip_config.rb $@ mac auto
-
-kt2wiz.prg: kipperterm2.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64fullprg.cfg
- $(LD) -m kt2wiz.map -vm -C ../cfg/c64fullprg.cfg -o kt2wiz.prg $(AFLAGS) $< $(IP65WIZNETLIB) $(C64WIZNETLIB)
- cp kt2wiz.prg ../../server/boot
-
-
-kipperterm2.d64: kipperterm2.prg addresses.txt abe.bas
- c1541 -format kipperterm2,k2 d64 $@ -attach $@ -write kipperterm2.prg -write "addresses.txt" "addresses.txt,s" -write abe
- cp kipperterm2.d64 ../../server/boot
-
-kt2wiz.d64: kt2wiz.prg addresses.txt abe.bas
- c1541 -format kt2wiz,kw d64 $@ -attach $@ -write kt2wiz.prg -write "addresses.txt" "addresses.txt,s" -write abe
- cp kt2wiz.d64 ../wiznet/
-
-clean:
- rm -f *.o *.bin *.map *.prg *.pg2 *.dsk *.d64
-
-distclean: clean
- rm -f *~
-
-ip65:
- make -C ../ip65 all
-
-drivers:
- make -C ../drivers all
diff --git a/client/kipperterm2/TODO.txt b/client/kipperterm2/TODO.txt
deleted file mode 100644
index 18fba8f..0000000
--- a/client/kipperterm2/TODO.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-redo directory listing code (not hardcoded to 1541 disk format)
-scrollback buffer
-log session to disk
-punter protocol
-tftp individual files
-allow changing of default drive from telnet menu
-send dos command to current drive
-
-
diff --git a/client/kipperterm2/abe b/client/kipperterm2/abe
deleted file mode 100644
index 1929f36..0000000
Binary files a/client/kipperterm2/abe and /dev/null differ
diff --git a/client/kipperterm2/abe.bas b/client/kipperterm2/abe.bas
deleted file mode 100644
index cbf0043..0000000
Binary files a/client/kipperterm2/abe.bas and /dev/null differ
diff --git a/client/kipperterm2/addresses.txt b/client/kipperterm2/addresses.txt
deleted file mode 100644
index b65da5a..0000000
--- a/client/kipperterm2/addresses.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-1FLOODGAP GOPHER / GOPHER.FLOODGAP.COM 70
-8JAMTRONIX PETSCIIMATION /n JAMTRONIX.COM 6464
-8ANTIDOTE /n ANTIDOTE.HOPTO.ORG 23
-8EXCALIBUR'S STONE /n BBS.EXCALIBURSSTONE.COM 6400
-8JAMMING SIGNAL /n BBS.JAMMINGSIGNAL.COM 23
-8MAD WORLD /n MADWORLD.BOUNCEME.NET 23
-8REALMS OF MYSTERY /n BBS.PIPESUP.CA 6400
-8RIKTRONICS /n RKBBS.NET 23
-8WIZARD'S REALM /n WIZBBS.DYNDNS.ORG 23
-8COTTONWOOD BBS /n COTTONWOOD.SERVEBBS.COM 23
-8COTTONWOOD II /n COTTONWOOD.SERVEBBS.COM 6400
-8THE HIDDEN /n THE-HIDDEN.HOPTO.ORG 23
-
-.
\ No newline at end of file
diff --git a/client/kipperterm2/kipperterm2.s b/client/kipperterm2/kipperterm2.s
deleted file mode 100644
index 18049d3..0000000
--- a/client/kipperterm2/kipperterm2.s
+++ /dev/null
@@ -1,781 +0,0 @@
-; #############
-; KIPPERTERM 2 - Telnet/Gopher client for C64
-; jonno@jamtronix.com
-
-
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/c64keycodes.i"
- .include "../inc/menu.i"
- .include "../inc/config_menu.i"
-
- KEY_NEXT_PAGE=KEYCODE_F7
- KEY_PREV_PAGE=KEYCODE_F1
- KEY_SHOW_HISTORY=KEYCODE_F2
- KEY_BACK_IN_HISTORY=KEYCODE_F3
- KEY_NEW_SERVER=KEYCODE_F5
-
- XMODEM_IN_TELNET = 1
- GOPHER_BUFFER_SIZE = 2000
- .include "../inc/gopher.i"
- .include "../inc/telnet.i"
-
-
- .import xmodem_iac_escape
- .import io_error_buffer
- .import cls
- .import beep
- .import exit_to_basic
- .import ip65_process
- .import ip65_init
- .import get_filtered_input
- .import filter_text
- .import filter_dns
- .import filter_ip
- .import arp_calculate_gateway_mask
- .import parse_dotted_quad
- .import dotted_quad_value
- .import parse_integer
-
-
- .import xmodem_receive
- .import xmodem_send
-
- .import get_key_ip65
- .import cfg_mac
- .import dhcp_init
-
- .import cfg_ip
- .import cfg_netmask
- .import cfg_gateway
- .import cfg_dns
- .import cfg_tftp_server
-
- .import xmodem_receive
-
- .import tcp_send
- .import tcp_send_data_len
-
- .import io_read_catalogue
- .import io_device_no
- .import io_read_file
- .import io_filename
- .import io_filesize
- .export telnet_menu
-
- .import print_a
- .import print_cr
- .import copymem
- .importzp copy_src
- .importzp copy_dest
- .import get_filtered_input
-
- .import cfg_tftp_server
-
-.bss
-;temp_ax: .res 2
-
-
- .segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
- .word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 10000) .mod 10) + $30)
- .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
-
-.code
-
-
-
-init:
- lda #$36
- sta $01 ;turn off BASIC
- jsr setup_screen
-
- ldax #menu_header_msg
- jsr print_ascii_as_native
- ldax #init_msg+1
- jsr print_ascii_as_native
- ldax #eth_driver_name
- jsr print_ascii_as_native
- lda #' '
- jsr print_a
- lda eth_driver_io_base+1
- jsr print_hex
- lda eth_driver_io_base
- jsr print_hex
- lda #' '
- jsr print_a
- jsr ip65_init
- bcs init_failed
- 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)
- bcc init_ok
-init_failed:
- print_failed
- jsr print_errorcode
- jsr wait_for_keypress
-
- jmp exit_to_basic
-
-print_main_menu:
- jsr cls
- ldax #menu_header_msg
- jsr print_ascii_as_native
- ldax #main_menu_msg
- jmp print_ascii_as_native
-
-init_ok:
-
- lda $ba
- sta cfg_default_drive
-
-main_menu:
- jsr print_main_menu
- jsr print_ip_config
- jsr print_cr
-
-@get_key:
- jsr get_key_ip65
- cmp #KEYCODE_F1
- bne @not_f1
- jsr cls
- ldax #telnet_header
- jsr print_ascii_as_native
- jmp telnet_main_entry
-
- @not_f1:
- cmp #KEYCODE_F3
- bne @not_f3
- jsr cls
- ldax #gopher_header
- jsr print_ascii_as_native
- jsr prompt_for_gopher_resource ;only returns if no server was entered.
- jmp exit_gopher
- @not_f3:
-
- cmp #KEYCODE_F5
- bne @not_f5
- jsr cls
-
- clc
- jsr set_io_device_no
- ldax #address_book_filename
- stax io_filename
- ldax #scratch_buffer
- jsr io_read_file
- bcc @no_error_reading_address_book
- ldax #address_book_fail_msg
- jsr print_ascii_as_native
- jsr print_errorcode
- ldax #address_book_filename
- jsr print_ascii_as_native
- jsr print_cr
- ldax #drive_text
- jsr print
- lda $ba
- ldx #0
- jsr print_integer
- jsr print_cr
-
- ldax #io_error_buffer
- jsr print
-
- jsr wait_for_keypress
- jmp main_menu
-
-@no_error_reading_address_book:
-
-
- lda #'1'
- sta displayed_resource_type
-
-;put a nul byte at end of file
- ldax #scratch_buffer
- stax pptr
- clc
- lda io_filesize
- adc #scratch_buffer
- sta pptr+1
- lda #0
- tay
- sta (pptr),y
- inc $d020
- jsr display_resource_in_buffer
-
- jmp exit_gopher
-@not_f5:
-
- cmp #KEYCODE_F7
- beq @change_config
- cmp #KEYCODE_F8
- bne @not_f8
-
- jsr cls
- ldax #menu_header_msg
- jsr print_ascii_as_native
- ldax #credits
- jsr print_ascii_as_native
- ldax #press_a_key_to_continue
- jsr print_ascii_as_native
- jsr get_key_ip65
- jmp main_menu
-@not_f8:
-
- jmp @get_key
-
-@change_config:
- jsr configuration_menu
- jmp main_menu
-
-
-
-
-
-wait_for_keypress:
- ldax #press_a_key_to_continue
- jsr print_ascii_as_native
-@loop:
- jsr $ffe4
- beq @loop
- rts
-
-get_key:
- jmp get_key_ip65
-
-cfg_get_configuration_ptr:
- ldax #cfg_mac
- rts
-
-
-setup_screen:
- jsr cls
- ;make sure normal font
- lda #$15
- sta $d018
-
- LDA #$06 ;blue
-
- STA $D020 ;border
- LDA #$00 ;black
- STA $D021 ;background
- lda #$05 ;petscii for white text
- jsr print_a
-
- lda #14
- jmp print_a ;switch to lower case
-
-save_screen_settings:
- ;save current settings
- lda $d018
- sta temp_font
- lda $d020
- sta temp_border
- lda $d021
- sta temp_text_back
- lda $0286
- sta temp_text_fore
-
- ldx #$27
-@save_page_zero_vars_loop:
- lda $cf,x
- sta temp_page_zero_vars,x
- dex
- bne @save_page_zero_vars_loop
-
- ldax #$400
- stax copy_src
- ldax #temp_screen_chars
- stax copy_dest
- ldax #$400
- jsr copymem
-
- ldax #$d800
- stax copy_src
- ldax #temp_colour_ram
- stax copy_dest
- ldax #$400
- jmp copymem
-
-restore_screen_settings:
- lda temp_font
- sta $d018
-
-
- lda temp_border
- sta $d020
- lda temp_text_back
- sta $d021
- lda temp_text_fore
- sta $0286
-
- ldx #$27
-@restore_page_zero_vars_loop:
- lda temp_page_zero_vars,x
- sta $cf,x
- dex
- bne @restore_page_zero_vars_loop
-
- ldax #temp_screen_chars
- stax copy_src
- ldax #$400
- stax copy_dest
- ldax #$400
- jsr copymem
-
- ldax #temp_colour_ram
- stax copy_src
- ldax #$d800
- stax copy_dest
- ldax #$400
- jmp copymem
-
-
-telnet_menu:
-
- jsr save_screen_settings
- jsr setup_screen
-
-@show_menu:
-
- jsr cls
-
- ldax #menu_header_msg
- jsr print_ascii_as_native
- ldax #telnet_menu_msg
- jsr print_ascii_as_native
-
-@get_menu_option:
- jsr get_key
- cmp #KEYCODE_F1
- bne :+
- jsr xmodem_download
- jmp @exit
-:
- cmp #KEYCODE_F3
- bne :+
- jsr xmodem_upload
- jmp @exit
-:
- cmp #KEYCODE_F5
- bne :+
-@get_ascii_value:
- ldax #enter_ascii
- jsr print_ascii_as_native
- ldy #3 ;max chars
- ldax #filter_number
- jsr get_filtered_input
- bcs @show_menu
- ;AX now points a string containing 0..999
- .import parse_integer
- jsr parse_integer
- cpx #0
- bne @get_ascii_value
- sta ascii_packet
- lda #1
- stax tcp_send_data_len
- jsr restore_screen_settings ;since we won't return from tcp_send
- ldax #ascii_packet
- jmp tcp_send
-
-
-:
- cmp #KEYCODE_F7
- beq @exit
- jmp @get_menu_option
-@exit:
- jsr restore_screen_settings
- rts
-
-set_io_device_no:
- lda cfg_default_drive
- sec
- sbc #7
- sta io_device_no
- rts
-xmodem_upload:
- jsr set_io_device_no
- lda #0
- sta eof
-
- ldax #directory_buffer
- jsr io_read_catalogue
- bcs @dir_failed
- lda directory_buffer ;get the first byte that was downloaded
- bne :+
- jmp @no_files_on_disk
-:
-
- ldax #directory_buffer
- ldy #0 ;filenames will NOT be ASCII
- jsr select_option_from_menu
- bcc @disk_filename_set
- rts
-
-@dir_failed:
- ldax #dir_listing_fail_msg
-@print_error:
- jsr print_ascii_as_native
- jsr print_errorcode
- jsr print_cr
- jmp wait_for_keypress
-
-@no_files_on_disk:
- ldax #no_files
- jsr print_ascii_as_native
-@wait_keypress_then_return_to_main:
- jmp wait_for_keypress
-
-
-@disk_filename_set:
-
-;open file needs XY=pointer to name, A = length of name
- stax copy_src
- ldy #$ff
-@next_byte:
- iny
- lda (copy_src),y
- bne @next_byte
- tya
- ldx copy_src
- ldy copy_src+1
-
- jsr open_file
- ldax #read_byte
- jsr xmodem_send
- bcc @no_error
- print_failed
- jsr print_errorcode
- jmp :+
-@no_error:
- print_ok
-:
- jsr close_file
- jmp wait_for_keypress
-
-
-read_byte:
- lda eof
- beq @not_eof
- sec
- rts
-@not_eof:
- ldx #$02 ; filenumber 2 = output file
- jsr $FFC6 ; call CHKIN (file 2 now used as input)
-
- jsr $FFCF ; call CHRIN (get a byte from file)
- pha
-
- jsr $FFB7 ; call READST (read status byte)
-
- beq :+ ; either EOF or read error
- inc eof
-:
- ldx #$00 ; filenumber 0 = console
- jsr $FFC6 ; call CHKIN (console now used as input)
-
- pla
- clc
- rts
-
-xmodem_download:
- ldax #opening_file
- jsr print_ascii_as_native
- jsr open_dl_file
- bcs @error
- ldax #ok_msg
- jsr print_ascii_as_native
- jsr print_cr
- ldax #write_byte
- jsr xmodem_receive
- bcs @error
- jsr close_file
- ldax #transfer_complete
- jsr print_ascii_as_native
- ldax #prompt_for_filename
- jsr print_ascii_as_native
-@get_filename:
- ldax #filter_dns
- ldy #40
- jsr get_filtered_input
- bcs @get_filename
- jsr rename_file
-
-
- rts
-@error:
- print_failed
- jsr print_errorcode
- jsr close_file
- jmp wait_for_keypress
-
-open_dl_file:
-
- ;scratch the file first (if it exists)
- ;first copy the "S:"
- ldx #0
-:
- lda scratch_cmd,x
- sta command_buffer,x
- inx
- cmp #':'
- bne :-
- jsr copy_tmp_filename_and_execute_cmd
-
- lda #temp_filename_end-temp_filename
- ldx #temp_filename
-
-
-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
-.import cfg_default_drive
- ldx cfg_default_drive
-
- ldy #$02 ; secondary address 2
- jsr $FFBA ; call SETLFS
-
- jsr $FFC0 ; call OPEN
- bcs @error ; if carry set, the file could not be opened
- rts
-@error:
- sta ip65_error
- jsr close_file
- sec
- rts
-
-write_byte:
- pha
- ldx #$02 ; filenumber 2 = output file
- jsr $FFC9 ; call CHKOUT
- pla
- jsr $ffd2 ;write byte
- JSR $FFB7 ; call READST (read status byte)
- bne @error
- ldx #$00 ; filenumber 0 = console
- jsr $FFC9 ; call CHKOUT
- rts
-@error:
- lda #KPR_ERROR_FILE_ACCESS_FAILURE
- sta ip65_error
- jsr close_file
- sec
- rts
-
-
-close_file:
-
- lda #$02 ; filenumber 2
- jsr $FFC3 ; call CLOSE
- rts
-
-
-rename_file:
-;AX points at new filename
- stax copy_src
- ldx #0
- ;first the "RENAME0:"
-
-:
- lda rename_cmd,x
- sta command_buffer,x
- inx
-
- cmp #':'
- bne :-
-
- ;now the new filename
- ldy #0
-:
- lda (copy_src),y
- beq @end_of_new_filename
- sta command_buffer,x
- inx
- iny
- bne :-
-@end_of_new_filename:
-
- ;now the "="
- lda #'='
- sta command_buffer,x
- inx
-
-copy_tmp_filename_and_execute_cmd:
- ;now the old filename
- ldy #0
-:
- lda temp_filename,y
- cmp #','
- beq @end_of_old_filename
- sta command_buffer,x
- inx
- iny
- bne :-
-@end_of_old_filename:
- txa ;filename length
- ldx #command_buffer
- jsr $FFBD ; call SETNAM
- lda #$0F ; filenumber 15
- ldx cfg_default_drive
- ldy #$0F ; secondary address 15
- jsr $FFBA ; call SETLFS
- jsr $FFC0 ; call OPEN
- lda #$0F ; filenumber 15
- jsr $FFC3 ; call CLOSE
- rts
-
-
-scratch_cmd:
- .byte "S:"
-
-rename_cmd:
- .byte "RENAME:"
-
-exit_telnet:
-exit_gopher:
- jsr setup_screen
- jmp main_menu
-.rodata
-
-menu_header_msg:
-.byte $13,10,"KIPPERTERM 2"
-.byte 10,0
-main_menu_msg:
-.byte 10,"Main Menu",10,10
-.byte "F1: Telnet F3: Gopher ",10
-.byte "F5: Address Book",10
-.byte "F7: Config F8: Credits",10,10
-
-.byte 0
-telnet_menu_msg:
-.byte 10,10,10
-.byte "F1: D/L File (XMODEM)",10
-.byte "F3: U/L File (XMODEM)",10
-.byte "F5: Send ASCII char",10
-.byte "F7: Return",10,10
-.byte 0
-
-
-opening_file:
-.byte 10,"opening file",10,0
-transfer_complete:
-.byte "transfer complete.",10,0
-prompt_for_filename: .byte "save file as?",10,0
-current:
-.byte "current ",0
-
-enter_ascii:
-.byte 10,"ASCII value (0..255)? ",0
-
-byte_sent:
-.byte 10,"byte sent.",0
-
-new:
-.byte"new ",0
-
-resolving:
- .byte "resolving ",0
-
-no_files:
- .byte "no files",10,0
-
-address_book_fail_msg:
- .byte "couldn't open address book",10,0
-
-dir_listing_fail_msg:
- .byte "directory listing failed",10,0
-
-temp_filename:
-.byte "XMODEM.TMP,P,W" ; @ means 'overwrite if existing', ',P,W' is required to make this an output file
-temp_filename_end:
-.byte 0
-
-
-address_book_filename: .byte "ADDRESSES.TXT",0
-
-gopher_header: .byte "gopher",10,0
-telnet_header: .byte "telnet",10,0
-
-drive_text: .byte "drive #",0
-
-
-credits:
-.byte 10,"License: Mozilla Public License v1.1",10,"http://www.mozilla.org/MPL/"
-.byte 10
-.byte 10,"Contributors:",10
-.byte 10,"Jonno Downes"
-.byte 10,"Glenn Holmer"
-.byte 10,"Per Olofsson"
-.byte 10,"Lars Stollenwerk"
-.byte 10,10
-.byte "Build "
-.include "../inc/version.i"
-.byte " ("
-.include "timestamp.i"
-.byte ")"
-.byte 10,10
-
-.byte 0
-
-.segment "APP_SCRATCH"
-
-temp_font: .res 1
-temp_border: .res 1
-temp_text_back: .res 1
-temp_text_fore: .res 1
-temp_page_zero_vars: .res $28
-temp_screen_chars: .res $400
-temp_colour_ram: .res $400
-command_buffer: .res $80
-eof: .res 1
-ascii_packet: .res 1
-
-directory_buffer: .res $400
-
-;we need to reserve space at $2000..$27FF for the VT100 font table
-.segment "FONT_TABLE"
-.res $800
-
-;make a dummy cartdige header so our
-.segment "CARTRIDGE_HEADER"
-.byte "80"
-.byte "KIPTRM"
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-
-;-- LICENSE FOR kipperterm.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 KipperTerm.
-;
-; 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
deleted file mode 100644
index 772ac73..0000000
--- a/client/kipperterm2/timestamp.i
+++ /dev/null
@@ -1 +0,0 @@
-.byte "2013-04-11"
diff --git a/client/tcp_test.bat b/client/tcp_test.bat
deleted file mode 100644
index 245992e..0000000
--- a/client/tcp_test.bat
+++ /dev/null
@@ -1 +0,0 @@
-start c:\temp\WinVICE-2.1\x64.exe -cart16 carts\kipperkart.bin
\ No newline at end of file
diff --git a/client/test/atom_test.xml b/client/test/atom_test.xml
deleted file mode 100644
index 85a62a4..0000000
--- a/client/test/atom_test.xml
+++ /dev/null
@@ -1,242 +0,0 @@
-
-
- tag:search.twitter.com,2005:search/#c64
-
-
- #c64 - Twitter Search
-
-
- since_id removed for pagination.
- 2009-08-10T10:03:59Z
- 15
-
-
- tag:search.twitter.com,2005:3222849162
- 2009-08-10T10:03:59Z
-
- Lately I edited a Firebird music compilation. You can play it by using this player here. Please listen. http://bit.ly/DF8zQ #c64 #chiptune
- Lately I edited a Firebird music compilation. You can play it by using this player here. Please listen. <a href="http://bit.ly/DF8zQ">http://bit.ly/DF8zQ</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23chiptune">#chiptune</a>
- 2009-08-10T10:03:59Z
-
- <a href="http://twitter.com/">web</a>
- en
-
- aka_obi (akaobi)
- http://twitter.com/aka_obi
-
-
-
- tag:search.twitter.com,2005:3222793961
- 2009-08-10T09:57:28Z
-
- Lately I edited a Firebird music compilation. You can play it by using this player here. Have fun. http://bit.ly/DF8zQ #c64 #chiptune
- Lately I edited a Firebird music compilation. You can play it by using this player here. Have fun. <a href="http://bit.ly/DF8zQ">http://bit.ly/DF8zQ</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23chiptune">#chiptune</a>
- 2009-08-10T09:57:28Z
-
- <a href="http://twitter.com/">web</a>
- en
-
- aka_obi (akaobi)
- http://twitter.com/aka_obi
-
-
-
- tag:search.twitter.com,2005:3221757110
- 2009-08-10T07:30:45Z
-
- is listening SID music on the iPhone! http://iphone.vanille.de/sidplayer/ #c64 #sid #iphone #chipmusic #8bit
- is listening SID music on the iPhone! <a href="http://iphone.vanille.de/sidplayer/">http://iphone.vanille.de/sidplayer/</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23sid">#sid</a> <a href="http://search.twitter.com/search?q=%23iphone">#iphone</a> <a href="http://search.twitter.com/search?q=%23chipmusic">#chipmusic</a> <a href="http://search.twitter.com/search?q=%238bit">#8bit</a>
- 2009-08-10T07:30:45Z
-
- <a href="http://twitter.com/">web</a>
- en
-
- chiptune (rez)
- http://twitter.com/chiptune
-
-
-
- tag:search.twitter.com,2005:3205731747
- 2009-08-09T10:16:06Z
-
- Wenn man früher auf dem C64 nur mit S-Mon geproggt hat, dann ist das ScienceFiction! http://bit.ly/RuhAh
- #c64
- Wenn man früher auf dem C64 nur mit S-Mon geproggt hat, dann ist das ScienceFiction! <a href="http://bit.ly/RuhAh">http://bit.ly/RuhAh</a>
- <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a>
- 2009-08-09T10:16:06Z
-
- <a href="http://thecosmicmachine.com/eventbox/">EventBox</a>
- de
-
- wurstgranate (Wurstgranate)
- http://twitter.com/wurstgranate
-
-
-
- tag:search.twitter.com,2005:3205709954
- 2009-08-09T10:13:18Z
-
- http://bit.ly/RuhAh
- #c64
- <a href="http://bit.ly/RuhAh">http://bit.ly/RuhAh</a>
- <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a>
- 2009-08-09T10:13:18Z
-
- <a href="http://thecosmicmachine.com/eventbox/">EventBox</a>
-
-
- wurstgranate (Wurstgranate)
- http://twitter.com/wurstgranate
-
-
-
- tag:search.twitter.com,2005:3205118149
- 2009-08-09T08:59:41Z
-
- http://www.remix64.com/amigacharts.html remix64 #c64 #amiga #charts ! check hybris 2009 :)
- <a href="http://www.remix64.com/amigacharts.html">http://www.remix64.com/amigacharts.html</a> remix64 <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23amiga">#amiga</a> <a href="http://search.twitter.com/search?q=%23charts">#charts</a> ! check hybris 2009 :)
- 2009-08-09T08:59:41Z
-
- <a href="http://twitter.com/">web</a>
- fr
-
- grabule (grabule)
- http://twitter.com/grabule
-
-
-
- tag:search.twitter.com,2005:3194733775
- 2009-08-08T16:35:20Z
-
- http://www.x-formz.com/music/ ultra great remixes of #c64 #amiga musics
- <a href="http://www.x-formz.com/music/">http://www.x-formz.com/music/</a> ultra great remixes of <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23amiga">#amiga</a> musics
- 2009-08-08T16:35:20Z
-
- <a href="http://twitter.com/">web</a>
- eo
-
- grabule (grabule)
- http://twitter.com/grabule
-
-
-
- tag:search.twitter.com,2005:3191289093
- 2009-08-08T09:16:19Z
-
- 8bit-Prodigy really rocks! Praise the SID chip! ;) e.g. http://bit.ly/29WsHg (more at http://bit.ly/jPkYc) via @sv #wakeup_music #c64 #fb
- 8bit-Prodigy really rocks! Praise the SID chip! ;) e.g. <a href="http://bit.ly/29WsHg">http://bit.ly/29WsHg</a> (more at <a href="http://bit.ly/jPkYc">http://bit.ly/jPkYc</a>) via <a href="http://twitter.com/sv">@sv</a> <a href="http://search.twitter.com/search?q=%23wakeup_music">#wakeup_music</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23fb">#fb</a>
- 2009-08-08T09:16:19Z
-
- <a href="http://twitter.com/">web</a>
- en
-
- gesus (gesus)
- http://twitter.com/gesus
-
-
-
- tag:search.twitter.com,2005:3183233498
- 2009-08-07T20:50:04Z
-
- #StreetFighter II running on a #C64. Holy crap does that look bad! http://bit.ly/YgIdZ
- <a href="http://search.twitter.com/search?q=%23StreetFighter">#StreetFighter</a> II running on a <a href="http://search.twitter.com/search?q=%23C64"><b>#C64</b></a>. Holy crap does that look bad! <a href="http://bit.ly/YgIdZ">http://bit.ly/YgIdZ</a>
- 2009-08-07T20:50:04Z
-
- <a href="http://www.tweetdeck.com/">TweetDeck</a>
- en
-
- sidshuman (Sid Shuman)
- http://twitter.com/sidshuman
-
-
-
- tag:search.twitter.com,2005:3183089623
- 2009-08-07T20:39:47Z
-
- @IdleSi Armalyte rocks! My school mate held the high score in CVG magazine way back. Great loading music too. #retro #c64 #sid
- <a href="http://twitter.com/IdleSi">@IdleSi</a> Armalyte rocks! My school mate held the high score in CVG magazine way back. Great loading music too. <a href="http://search.twitter.com/search?q=%23retro">#retro</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23sid">#sid</a>
- 2009-08-07T20:39:47Z
-
- <a href="http://www.tweetdeck.com/">TweetDeck</a>
- en
-
- sevik (Sean Parker)
- http://twitter.com/sevik
-
-
-
- tag:search.twitter.com,2005:3164495376
- 2009-08-06T10:29:54Z
-
- RT: @3typen der #iPhone #App #c64 #sid player für unterwegs http://twitpic.com/cypku wann kommt eigentlich ifrodo?
- RT: <a href="http://twitter.com/3typen">@3typen</a> der <a href="http://search.twitter.com/search?q=%23iPhone">#iPhone</a> <a href="http://search.twitter.com/search?q=%23App">#App</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23sid">#sid</a> player für unterwegs <a href="http://twitpic.com/cypku">http://twitpic.com/cypku</a> wann kommt eigentlich ifrodo?
- 2009-08-06T10:29:54Z
-
- <a href="http://apiwiki.twitter.com/">API</a>
- de
-
- uberguineapig (Guinea Pigz)
- http://twitter.com/uberguineapig
-
-
-
- tag:search.twitter.com,2005:3164476839
- 2009-08-06T10:27:39Z
-
- der #iPhone #App #c64 #sid player für unterwegs http://twitpic.com/cypku wann kommt eigentlich ifrodo?
- der <a href="http://search.twitter.com/search?q=%23iPhone">#iPhone</a> <a href="http://search.twitter.com/search?q=%23App">#App</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23sid">#sid</a> player für unterwegs <a href="http://twitpic.com/cypku">http://twitpic.com/cypku</a> wann kommt eigentlich ifrodo?
- 2009-08-06T10:27:39Z
-
- <a href="http://www.tweetdeck.com/">TweetDeck</a>
- de
-
- 3typen (3typen)
- http://twitter.com/3typen
-
-
-
- tag:search.twitter.com,2005:3152292799
- 2009-08-05T20:30:00Z
-
- Shredz64!!! Guitar Hero for Commodore 64.. wait what? people are still making stuff for Commodore? http://bit.ly/WpM41 #commodore #c64
- Shredz64!!! Guitar Hero for Commodore 64.. wait what? people are still making stuff for Commodore? <a href="http://bit.ly/WpM41">http://bit.ly/WpM41</a> <a href="http://search.twitter.com/search?q=%23commodore">#commodore</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a>
- 2009-08-05T20:30:00Z
-
- <a href="http://www.tweetdeck.com/">TweetDeck</a>
- en
-
- kevireilly (Kevin Reilly)
- http://twitter.com/kevireilly
-
-
-
- tag:search.twitter.com,2005:3152230931
- 2009-08-05T20:26:26Z
-
- ... Disk2 http://tinyurl.com/kwbxth #smashdesigns #ourdarkness #c64 #demoscene
- ... Disk2 <a href="http://tinyurl.com/kwbxth">http://tinyurl.com/kwbxth</a> <a href="http://search.twitter.com/search?q=%23smashdesigns">#smashdesigns</a> <a href="http://search.twitter.com/search?q=%23ourdarkness">#ourdarkness</a> <a href="http://search.twitter.com/search?q=%23c64"><b>#c64</b></a> <a href="http://search.twitter.com/search?q=%23demoscene">#demoscene</a>
- 2009-08-05T20:26:26Z
-
- <a href="http://twitter.com/">web</a>
- en
-
- falingo (Michael)
- http://twitter.com/falingo
-
-
-
- tag:search.twitter.com,2005:3151332602
- 2009-08-05T19:35:28Z
-
- RT @SilwerSurfer: Bauernfeind @3Sat ! #Politik #zensursula #piraten #schäuble #C64
- RT <a href="http://twitter.com/SilwerSurfer">@SilwerSurfer</a>: Bauernfeind <a href="http://twitter.com/3Sat">@3Sat</a> ! <a href="http://search.twitter.com/search?q=%23Politik">#Politik</a> <a href="http://search.twitter.com/search?q=%23zensursula">#zensursula</a> <a href="http://search.twitter.com/search?q=%23piraten">#piraten</a> <a href="http://search.twitter.com/search?q=%23sch%C3%A4uble">#schäuble</a> <a href="http://search.twitter.com/search?q=%23C64"><b>#C64</b></a>
- 2009-08-05T19:35:28Z
-
- <a href="http://twitter.com/">web</a>
- de
-
- emju (EMJU)
- http://twitter.com/emju
-
-
-
diff --git a/client/test/file1.html b/client/test/file1.html
deleted file mode 100644
index 4e65228..0000000
--- a/client/test/file1.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-This is file1
-
\ No newline at end of file
diff --git a/client/test/index.html b/client/test/index.html
deleted file mode 100644
index 83daf07..0000000
--- a/client/test/index.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-This is index.html
-
\ No newline at end of file
diff --git a/client/uthernet/Makefile b/client/uthernet/Makefile
deleted file mode 100644
index b19609b..0000000
--- a/client/uthernet/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-AS=ca65
-LD=ld65
-CFLAGS=-Oirs -t $(TARGET)
-AFLAGS=
-
-INCFILES=\
- ../inc/common.i\
- ../inc/commonprint.i\
- ../inc/net.i\
- ../inc/menu.i\
- ../inc/kipper_constants.i
-
-IP65LIB=../ip65/ip65.lib
-
-APPLE2PROGLIB=../drivers/a2uther.lib
-
-%.o: %.s $(INCFILES) $(APPLE2PROGLIB)
- $(AS) $(AFLAGS) $<
-
-all: utherboot.dsk
-
-#c700_rom.bin: c700_rom.o ../cfg/a2rom.cfg
-# $(LD) -C ../cfg/a2rom.cfg -o $@ c700_rom.o $(APPLE2PROGLIB)
-#
-#bankswitch_eeprom.bin: bankswitch_eeprom.o ../cfg/a2rom.cfg
-# $(LD) -C ../cfg/a2rom.cfg -o $@ bankswitch_eeprom.o $(APPLE2PROGLIB)
-#
-#applewin.exe: c700_rom.bin bankswitch_eeprom.bin patch_applewin.rb
-# ruby patch_applewin.rb
-
-
-utherboot.pg2: utherboot.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2language_card.cfg
- $(LD) -m utherboot.map -C ../cfg/a2language_card.cfg -o $@ $< $(IP65LIB) $(APPLE2PROGLIB)
-
-utherboot.dsk: utherboot.pg2
- ripxplore.rb --init AppleDos utherboot.dsk -a utherboot.pg2 -t AppleBinary
- ripxplore.rb utherboot.dsk -a hello -t Applesoft
-
-
-clean:
- rm -f *.o *.bin *.map *.prg *.pg2 *.dsk *.d64
-
-distclean: clean
- rm -f *~
diff --git a/client/uthernet/bankswitch_eeprom.s b/client/uthernet/bankswitch_eeprom.s
deleted file mode 100644
index 9207238..0000000
--- a/client/uthernet/bankswitch_eeprom.s
+++ /dev/null
@@ -1,51 +0,0 @@
-.segment "C800_0"
-.asciiz "BANK $00"
-.segment "C800_1"
-.asciiz "BANK $01"
-.segment "C800_2"
-.asciiz "BANK $02"
-.segment "C800_3"
-.asciiz "BANK $03"
-.segment "C800_4"
-.asciiz "BANK $04"
-.segment "C800_5"
-.asciiz "BANK $05"
-.segment "C800_6"
-.asciiz "BANK $06"
-.segment "C800_7"
-.asciiz "BANK $07"
-.segment "C800_8"
-.asciiz "BANK $08"
-.segment "C800_9"
-.asciiz "BANK $09"
-.segment "C800_A"
-.asciiz "BANK $0A"
-.segment "C800_B"
-.asciiz "BANK $0B"
-.segment "C800_C"
-.asciiz "BANK $0C"
-.segment "C800_D"
-.asciiz "BANK $0D"
-.segment "C800_E"
-.asciiz "BANK $0E"
-
-
-
-;-- LICENSE FOR bankswitch_eeprom.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/uthernet/c700_rom.s b/client/uthernet/c700_rom.s
deleted file mode 100644
index c1bc679..0000000
--- a/client/uthernet/c700_rom.s
+++ /dev/null
@@ -1,69 +0,0 @@
-.include "../inc/common.i"
-.include "../inc/a2keycodes.i"
-
-.import print_a
-.import print_cr
-
-pptr=$04 ;temp pointer for printing from
-
-
-.segment "C700"
-
-;Autostart 'signature' bytes - make this rom look like a Disk ][ controller card
-.byte $c9,$20,$c9,$00,$c9,$03,$c9,$3c
-
-ldax #hello_world
-jsr print
-
-rts
-
-sta $cfff ;turn of all other expansion ROMs
-sta $c0f4 ;set bank
-ldax #$c800
-
-jsr print
-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
-
-
-hello_world:
- .byte "hello from autostart firmware land!",13,0
-
-
-
-
-
-;-- LICENSE FOR c700_rom.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/uthernet/patch_applewin.rb b/client/uthernet/patch_applewin.rb
deleted file mode 100644
index 75007c7..0000000
--- a/client/uthernet/patch_applewin.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-unpatched_applewin_filename='unpatched_applewin.exe'
-patched_applewin_filename='applewin.exe'
-
-c700_rom_filename='c700_rom.bin'
-bankswitch_eeprom_filename="bankswitch_eeprom.bin"
-
-[unpatched_applewin_filename,c700_rom_filename,bankswitch_eeprom_filename].each do |filename|
- if !(FileTest.file?(filename)) then
- puts "file '#{filename}' not found"
- exit
- end
-
-end
-
-filebytes=File.open(unpatched_applewin_filename,"rb").read
-
-c700_sig=(07).chr*256
-bankswitch_eeprom_sig=(0xF0).chr*256
-
-c700_rom_offset=filebytes.index(c700_sig)
-raise "C700 ROM signature not found in #{unpatched_applewin_filename}" if c700_rom_offset.nil?
-bankswitch_eeprom_offset=filebytes.index(bankswitch_eeprom_sig)
-raise "bankswitch EEPROM signature not found in #{unpatched_applewin_filename}" if bankswitch_eeprom_offset.nil?
-
-c700_rom=File.open(c700_rom_filename,"rb").read
-bankswitch_eeprom=File.open(bankswitch_eeprom_filename,"rb").read
-
-filebytes[c700_rom_offset,c700_rom.length]=c700_rom
-filebytes[bankswitch_eeprom_offset,bankswitch_eeprom.length]=bankswitch_eeprom
-filehandle=File.open(patched_applewin_filename,"wb")
-filehandle<load_handler
- bne @not_installed
- ldax #@already_installed_msg
- jsr __print
- rts
-
- @installed_msg: .byte "V1541 INSTALLED",0
- @already_installed_msg: .byte "V1541 ALREADY INSTALLED",0
-@not_installed:
-
-
- ldax #__DATA_LOAD__
- stax copy_src
- ldax #__DATA_RUN__
- stax copy_dest
- ldax #__DATA_SIZE__
- jsr __copymem
-
- ldax #__CODESTUB_LOAD__
- stax copy_src
- ldax #__CODESTUB_RUN__
- stax copy_dest
- ldax #__CODESTUB_SIZE__
- jsr __copymem
-
- ldax #__RODATA_LOAD__
- stax copy_src
- ldax #__RODATA_RUN__
- stax copy_dest
- ldax #__RODATA_SIZE__
- jsr __copymem
-
- ldax #__IP65_DEFAULTS_LOAD__
- stax copy_src
- ldax #__IP65_DEFAULTS_RUN__
- stax copy_dest
- ldax #__IP65_DEFAULTS_SIZE__
- jsr __copymem
-
-
-
-
- jsr swap_basic_out
-
- jsr ip65_init
- bcc @init_ok
- ldax #@no_nic
- jsr print
-@fail_and_exit:
- ldax #@not_installed_msg
- jsr print
- jmp @done
-@no_nic: .byte "NO RR-NET FOUND - ",0
-@not_installed_msg: .byte "V1541 NOT INSTALLED.",0
-@init_ok:
- ldax #@dhcp_init_msg
- jsr print
- jsr dhcp_init
- bcc @dhcp_worked
-@failed:
- ldax #@fail_msg
- jsr print
- jmp @fail_and_exit
-@dhcp_init_msg: .byte "DHCP INITIALISATION"
-@elipses: .byte "...",0
-@ok_msg: .byte "OK",13,0
-@fail_msg: .byte "FAILED",13,0
-@dhcp_worked:
- ldax #@ok_msg
- jsr print
-
- ldax #@resolve_servername_msg
- jsr print
- ldax #@elipses
- jsr print
- ldax #@servername
- jsr dns_set_hostname
- jsr dns_resolve
- bcc @dns_worked
- jmp @failed
-@resolve_servername_msg: .byte "RESOLVING "
-@servername: .byte SERVERNAME,0
-@dns_worked:
- ldax #@ok_msg
- jsr print
- ldx #3
-@copy_server_ip_loop:
- lda dns_ip,x
- sta tcp_connect_ip,x
- dex
- bpl @copy_server_ip_loop
-
- ldax #@connecting_msg
- jsr print
- ldax #@servername
- jsr print
- ldax #@elipses
- jsr print
- ldax #csip_callback
- stax tcp_callback
- ldax #SERVER_PORT
- jsr tcp_connect
- bcc @connect_worked
- jmp @failed
-@connecting_msg: .byte "CONNECTING TO ",0
-
-@connect_worked:
- ldax #@ok_msg
- jsr print
- ;IP stack OK, now set vectors
-
- ldax CINV
- stax old_irq_vector
-
- ldax ILOAD
- stax old_load_vector
- ldax #load_handler
- stax ILOAD
- ldax #@installed_msg
- jsr print
-
-ldax #irq_handler
- sei
- stax CINV
-
-@done:
- jsr swap_basic_in
- lda #0
- sta $dc08 ;make sure TOD clock is started
- cli
-
- rts
-
-__copymem:
- sta end
- ldy #0
-
- cpx #0
- beq @tail
-
-: lda (copy_src),y
- sta (copy_dest),y
- iny
- bne :-
- inc copy_src+1 ;next page
- inc copy_dest+1 ;next page
- dex
- bne :-
-
-@tail:
- lda end
- beq @done
-
-: lda (copy_src),y
- sta (copy_dest),y
- iny
- cpy end
- bne :-
-
-@done:
- rts
-
-end: .byte 0
-
-__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
-
-
-.code
-
-load_dev_2:
- ldy #$00
- sty receive_type ;0 = display to screen, 1 = load to memory
- sty buffer_length
- sty buffer_length+1
- lda (FNADDR),y
- cmp #'!'
- beq @do_disks
- cmp #'>'
- beq @do_command
- cmp #'#'
- beq @do_insert
- cmp #'='
- beq @do_find
- cmp #'/'
- bne @not_cf
- lda FNLEN
- cmp #1
- bne @do_cf
- ldax #cmd_cf_root
- jmp @send_string_receive_response
-@not_cf:
- cmp #'%'
- beq @do_name
- cmp #'$'
- beq @do_cat
- inc receive_type
- ldax #cmd_load
- jmp @copy_prefix
-
-@done:
-
- clc
- jmp swap_basic_in
-
-@do_command:
- ldy FNLEN
-@copy_cmd:
- lda (FNADDR),y
- sta cmd_buffer-1,y
- dey
- bne @copy_cmd
-
- ldy FNLEN
- lda #$0D
- sta cmd_buffer-1,y
- lda #0
- sta cmd_buffer,y
-@send_command_buffer:
- ldax #cmd_buffer
- jmp @send_string_receive_response
-
-@do_name:
- ldax #cmd_name
- jmp @send_string_receive_response
-
-@do_find:
- ldax #cmd_find
- jmp @copy_prefix
-
-@do_cat:
- ldax #cmd_cat
- jmp @send_string_receive_response
-
-
-@do_disks:
- ldax #cmd_dsks
-@send_string_receive_response:
- jsr tcp_send_string
- bcs @error
- lda receive_type
- bne @load_file
- jsr show_list
- jmp @done
-@load_file:
- jsr receive_file
- jmp @done
-
-@do_cf:
- ldax #cmd_cf
- jmp @copy_prefix
-
-
-@do_insert:
- ldax #cmd_insert
-@copy_prefix:
- stax copy_src
- ldy #0
-@copy_prefix_loop:
- lda (copy_src),y
- beq @end_copy_prefix
- sta cmd_buffer,y
- iny
- bne @copy_prefix_loop
-@end_copy_prefix:
- tya
- tax
- ldy #1
- lda receive_type
- beq :+
- dey ;if this is a LOAD command, don't skip the first byte
-:
- lda (FNADDR),y
- sta cmd_buffer,x
- iny
- inx
- cpy FNLEN
-
- bne :-
-
- lda #$0D
- sta cmd_buffer,x
- lda #0
- sta cmd_buffer+1,x
- jmp @send_command_buffer
-
-@error:
- ldax #SERVER_PORT
- jsr tcp_connect
-
- ldax #transmission_error
- jsr print
-
- jmp @done
-
-
-show_list:
-
-@loop:
- lda $91 ; look for STOP key
- cmp #$7F
- beq @done
- lda #2 ;wait for max 2 seconds
- jsr getc
- bcc @got_data
- rts
-@got_data:
-
- cmp #$03 ;ETX byte (indicating end of page)?
- beq @get_user_input
- cmp #$04 ;EOT byte (indicating end of list)?
- beq @done
- jsr print_a ;got a byte - output it
- jmp @loop ;continue getting characters
-
-;End of page, so ask for user input
- @get_user_input:
-
- jsr get_key
-
- cmp #'S'
- beq @user_exit
-
- cmp #$0D
- bne @get_user_input
- ldax #continue_cmd
-
- jsr tcp_send_string
- jmp @loop
-
-;User wishes to stop - send S to server and quit
-@user_exit:
- ldax #stop_cmd
- jsr tcp_send_string
-
-@done:
-
-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
-
-
-csip_callback:
- lda tcp_inbound_data_length+1
- cmp #$ff
- bne @not_eof
- rts
-@not_eof:
-
- ldax tcp_inbound_data_ptr
- stax copy_src
- ldax #csip_stream_buffer
- stax copy_dest
- stax next_char_ptr
-
- ldax tcp_inbound_data_length
- stax buffer_length
- jsr copymem
- rts
-
-getc:
- sta getc_timeout_seconds
-
- clc
- lda $dc09 ;time of day clock: seconds (in BCD)
- sed
- adc getc_timeout_seconds
- cmp #$60
- bcc @timeout_set
- sec
- sbc #$60
-@timeout_set:
- cld
- sta getc_timeout_end
-
-@poll_loop:
- jsr next_char
- bcs @no_char
- rts ;done!
-@no_char:
- jsr check_for_abort_key
- bcc @no_abort
- lda #KPR_ERROR_ABORTED_BY_USER
- sta ip65_error
- inc user_abort
- rts
-@no_abort:
- jsr ip65_process
- lda $dc09 ;time of day clock: seconds
- cmp getc_timeout_end
- bne @poll_loop
- lda #00
- sec
- rts
-
-next_char:
- lda buffer_length
- bne @not_eof
- lda buffer_length+1
- bne @not_eof
- sec
- rts
-@not_eof:
- next_char_ptr=*+1
- lda $ffff
- pha
- inc next_char_ptr
- bne :+
- inc next_char_ptr+1
-:
- sec
- lda buffer_length
- sbc #1
- sta buffer_length
- lda buffer_length+1
- sbc #0
- sta buffer_length+1
- pla
- clc
-
- rts
-
-tcp_irq_handler:
-
- inc keep_alive_counter
- lda keep_alive_counter
- bne @skip
- jsr tcp_send_keep_alive
-@skip:
- jsr ip65_process
-@done:
-
- rts
-
-receive_file:
- lda #0
- sta byte_count
-@loop:
- lda $91 ; look for STOP key
- cmp #$7F
- beq @done
- lda #2 ;wait for max 2 seconds
- jsr getc
- bcc @got_data
-@done:
- rts
-@got_data:
- ldy byte_count
- sta file_length,y
- inc byte_count
- lda byte_count
- cmp #4
- bne @loop
- ;is the first 4 bytes "500 "
-;
- lda file_length+1
- cmp #'0' ;if 2nd char was '0' this might be an ASCII error message
- bne @real_file_transmission
- lda file_location
- cmp #$01
- beq @real_file_transmission
- ;this was probably an ASCII error message
-
- lda #0
- sta byte_count
-:
- ldy byte_count
- lda file_length,y
- jsr print_a
- inc byte_count
- lda byte_count
- cmp #4
- bne :-
- jmp show_list
-@real_file_transmission:
- ldax file_location
- stax copy_dest
-
- lda file_length
- sec
- sbc #2
- sta file_length
-
- lda file_length+1
- sbc #0
- sta file_length+1
-
-@rx_loop:
- lda file_length+1
- bne @not_done
- lda file_length
- bne @not_done
- ;file now fully in RAM, time for housekeeping
- sta $297 ;RS-232 status = 0 (no error)
- sta $90 ;status = 0 (no error)
- ldy copy_dest+1 ;high byte of end of loaded program
- ldx copy_dest ;lo byte of end of loaded program
- inx
- bne :+
- iny ;if X rolled over, bump y
-:
- rts ;done!
-
-@not_done:
- lda #2 ;wait for max 2 seconds
- jsr getc
- bcs @rx_error
- ldy #0
- sta (copy_dest),y
- inc copy_dest
- bne :+
- inc copy_dest+1
-:
- lda file_length
- bne :+
- dec file_length+1
- lda #'.'
- jsr print_a
-:
- dec file_length
- jmp @rx_loop
-
-@rx_error:
- ldax #receive_error
- jmp print
-
-.segment "CODESTUB"
-
-swap_basic_out:
- lda $01
- sta underneath_basic
- and #$FE
- sta $01
- rts
-
-swap_basic_in:
- lda $01
- ora #$01
- sta $01
- lda #$0
- sta underneath_basic
- rts
-
-underneath_basic: .res 1
-
-load_handler:
- ldx $BA ; Current Device Number
- cpx #$02
- beq :+
- .byte $4c ;jmp
-old_load_vector:
- .word $ffff
- :
- jsr swap_basic_out
- jmp load_dev_2
-
-irq_handler:
-
- lda underneath_basic
- bne @done
- jsr swap_basic_out
- jsr tcp_irq_handler
- jsr swap_basic_in
-@done:
- .byte $4c ;jmp
-old_irq_vector:
- .word $ffff
-
-
-.data
-cmd_dsks: .byte "DISKS 22",$0d,$0
-cmd_insert: .byte "INSERT ",0
-cmd_cat: .byte "$",$0d,$00
-cmd_find: .byte "FIND ",$00
-cmd_name: .byte "NAME",$0d,$00
-cmd_cf: .byte "CF ",0
-cmd_load: .byte "LOAD ",0
-cmd_cf_root: .byte "CF /",$0d,0
-
-transmission_error: .byte "TRANSMIT ERROR",13,0
-receive_error: .byte "RECEIVE ERROR",13,0
-
-.segment "TCP_VARS"
-csip_stream_buffer: .res 1500
-cmd_buffer: .res 100
-.bss
-
-user_abort: .res 1
-getc_timeout_end: .res 1
-getc_timeout_seconds: .res 1
-buffer_length: .res 2
-keep_alive_counter: .res 1
-file_length: .res 2
-file_location: .res 2
-rx_length: .res 2
-receive_type: .res 1
-byte_count: .res 1
-.data
-continue_cmd: .byte $0D,0
-stop_cmd: .byte "S",0
-
-
-;-- LICENSE FOR v1541.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) 2010
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
diff --git a/client/wiznet/Makefile b/client/wiznet/Makefile
deleted file mode 100644
index a0bd917..0000000
--- a/client/wiznet/Makefile
+++ /dev/null
@@ -1,94 +0,0 @@
-AS=ca65
-LD=ld65
-CFLAGS=-Oirs -t $(TARGET)
-AFLAGS=
-
-INCFILES=\
- ../inc/common.i\
- ../inc/commonprint.i\
- ../inc/net.i\
- ../inc/menu.i\
- ../inc/kipper_constants.i\
- ../inc/version.i\
-
-IP65LIB=../ip65/ip65.lib
-IP65TCPLIB=../ip65/ip65_tcp.lib
-C64RRNETLIB=../drivers/c64rrnet.lib
-C64WIZNETLIB=../drivers/c64wiznet.lib
-IP65WIZNETLIB=../ip65/ip65_wiznet.lib
-
-
-all: ip65 drivers\
- wizboot.bin \
- wizboot2.prg \
- cartheader.prg \
- wiztest.prg \
- wizboot.prg \
- telnetd.bin \
- telnetd.prg \
- wizbobcart.prg \
- kt2wiz.d64 \
- wiztest.d64 \
- bootc64.prg \
-
-%.o: %.s $(INCFILES) timestamp.rb
- ruby timestamp.rb > timestamp.i
- $(AS) $(AFLAGS) $<
-
-
-%.prg: %.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64prg.cfg
- $(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65WIZNETLIB) $(C64WIZNETLIB)
-
-
-wizboot.bin: wizboot.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64_8kcart.cfg
- $(LD) -m wizboot.map -vm -C ../cfg/c64_8kcart.cfg -o $@ $< $(IP65WIZNETLIB) $(C64WIZNETLIB)
- ruby ../carts/fix_cart.rb $@ 8192
-
-wizboot.prg: wizboot.bin cartheader.prg
- cat cartheader.prg wizboot.bin > $@
-
-wizflash.prg: wizboot.bin wizflashheader.prg
- cat wizflashheader.prg wizboot.bin > $@
-
-telnetd.o: ../carts/telnetd.s $(INCFILES) timestamp.rb
- $(AS) $(AFLAGS) ../carts/telnetd.s -o telnetd.o
-
-telnetd.bin: telnetd.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) ../cfg/c64_8kcart.cfg
- $(LD) -m telnetd.map -vm -C ../cfg/c64_8kcart.cfg -o $@ $< $(IP65WIZNETLIB) $(C64WIZNETLIB)
- ruby ../carts/fix_cart.rb $@ 8192
-
-telnetd.prg: telnetd.bin cartheader.prg
- cat cartheader.prg telnetd.bin > $@
-
-wizbobcart.bin: wizbobcart.o $(IP65WIZNETLIB) $(C64WIZNETLIB) $(INCFILES) wizbobcart.cfg
- $(LD) -m wizbobcart.map -vm -C wizbobcart.cfg -o $@ $< $(IP65WIZNETLIB) $(C64WIZNETLIB)
- ruby ../carts/fix_cart.rb $@ 8192
-
-wizbobcart.prg: wizbobcart.bin cartheader.prg
- cat cartheader.prg wizbobcart.bin > $@
-
-wiztest.d64: wiztest.prg wizboot.prg wizflash.prg
- c1541 -format wiztest,wt d64 $@ -attach $@ -write wizboot.prg -write wiztest.prg -write wizflash.prg
-
-clean:
- rm -f *.o *.bin *.map *.prg *.pg2 *.dsk *.d64
-
-distclean: clean
- rm -f *~
-
-ip65:
- make -C ../ip65 all
-
-drivers:
- make -C ../drivers all
-
-kt2wiz.d64:
- make -C ../kipperterm2 kt2wiz.d64
-
-
-bootc64.prg:
-# cp wizbobcart.prg ../../server/boot/bootc64.prg
-# cp telnetd.prg ../../server/boot/bootc64.prg
-# cp wizboot2.prg ../../server/boot/bootc64.prg
- cp wiztest.prg ../../server/boot/bootc64.prg
-# cp wizflash.prg ../../server/boot/bootc64.prg
\ No newline at end of file
diff --git a/client/wiznet/cartheader.s b/client/wiznet/cartheader.s
deleted file mode 100644
index f49c65c..0000000
--- a/client/wiznet/cartheader.s
+++ /dev/null
@@ -1,54 +0,0 @@
-
-.include "../inc/common.i"
-
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
-;copy BASIC to RAM
- ldax #$A000
- stax copy_src
- stax copy_dest
- ldax #$2000
- jsr copymem
-
-;copy cart data from end of file to $8000 (RAM)
- ldax #cart_data
- stax copy_src
- ldax #$8000
- stax copy_dest
- ldax #$2000
- jsr copymem
-
-;swap out the cartridge (also swaps out BASIC)
-
- lda $01
- and #$fe ;reset bit 0
- sta $01
-
-;execute the cartridge from RAM
- jmp ($8002)
-
-
-.bss
-
-cart_data: ;this should point to where the cart data gets appended.
- .res $2000
\ No newline at end of file
diff --git a/client/wiznet/commonprint.i b/client/wiznet/commonprint.i
deleted file mode 100644
index 7e32057..0000000
--- a/client/wiznet/commonprint.i
+++ /dev/null
@@ -1,377 +0,0 @@
-
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- .export print_hex
- .export print_ip_config
- .export ok_msg
- .export failed_msg
- .export init_msg
- .export print
- .export print
- .export print_integer
- .export print_dotted_quad
- .export mac_address_msg
- .export ip_address_msg
- .export netmask_msg
- .export gateway_msg
- .export dns_server_msg
- .export tftp_server_msg
- .import ip65_error
- .export print_errorcode
- .export press_a_key_to_continue
-
-
-
-.import eth_driver_name
-.import eth_driver_io_base
-.importzp copy_src
-.import cfg_tftp_server
-;reuse the copy_src zero page var
-pptr = copy_src
-
-.bss
-temp_bin: .res 2
-temp_bcd: .res 3
-temp_ptr: .res 2
-.code
-.macro print_driver_init
- ldax #eth_driver_name
- jsr print
- lda #'('
- jsr print_a
- lda #'$'
- jsr print_a
- lda eth_driver_io_base+1
- jsr print_hex
- lda eth_driver_io_base
- jsr print_hex
- lda #')'
- jsr print_a
-
- ldax #init_msg
- jsr print
-.endmacro
-
-
-.macro print_dhcp_init
- ldax #dhcp_msg
- jsr print
- ldax #init_msg
- jsr print
-.endmacro
-
-.macro print_failed
- ldax #failed_msg
- jsr print
- jsr print_cr
-.endmacro
-
-.macro print_ok
- ldax #ok_msg
- jsr print
- jsr print_cr
-.endmacro
-
-
-.code
-
-.import print_a
-.import print_cr
-.import eth_driver_name
-print_ip_config:
-
- ldax #interface_type
- jsr print
-
- ldax #eth_driver_name
- jsr print
- jsr print_cr
-
- ldax #mac_address_msg
- jsr print
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- ;first 6 bytes of cfg_get_configuration_ptr is MAC address
- jsr print_mac
- jsr print_cr
-
- ldax #ip_address_msg
- jsr print
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_IP
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #netmask_msg
- jsr print
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_NETMASK
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #gateway_msg
- jsr print
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_GATEWAY
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #dns_server_msg
- jsr print
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_DNS_SERVER
- bcc :+
- inx
-: jsr print_dotted_quad
- jsr print_cr
-
- ldax #tftp_server_msg
- jsr print
- ldax #cfg_tftp_server
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #dhcp_server_msg
- jsr print
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_DHCP_SERVER
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- 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
-
-
-;print the 4 bytes pointed at by AX as dotted decimals
-print_dotted_quad:
- sta pptr
- stx pptr + 1
- lda #0
-@print_one_byte:
- pha
- tay
- lda (pptr),y
- ldx #0
- jsr print_integer
- pla
- cmp #3
- beq @done
- clc
- adc #1
- pha
- lda #'.'
- jsr print_a
- pla
- bne @print_one_byte
-@done:
-
- rts
-
-;print 6 bytes printed at by AX as a MAC address
-print_mac:
- stax pptr
- ldy #0
-@one_mac_digit:
- tya ;just to set the Z flag
- pha
- beq @dont_print_colon
- lda #':'
- jsr print_a
-@dont_print_colon:
- pla
- tay
- lda (pptr),y
- jsr print_hex
- iny
- cpy #06
- bne @one_mac_digit
- rts
-
-print_integer: ;print 16 bit number in AX as a decimal number
-
-;hex to bcd routine taken from Andrew Jacob's code at http://www.6502.org/source/integers/hex2dec-more.htm
- stax temp_bin
- sed ; Switch to decimal mode
- lda #0 ; Ensure the result is clear
- sta temp_bcd
- sta temp_bcd+1
- sta temp_bcd+2
- ldx #16 ; The number of source bits
- :
- asl temp_bin+0 ; Shift out one bit
- rol temp_bin+1
- 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
- lda temp_bcd+2 ; ... thru whole result
- adc temp_bcd+2
- sta temp_bcd+2
-
- dex ; And repeat for next bit
- bne :-
-
- stx temp_bin+1 ;x is now zero - reuse temp_bin as a count of non-zero digits
- cld ;back to binary
- ldx #2
- stx temp_bin+1 ;reuse temp_bin+1 as loop counter
-@print_one_byte:
- ldx temp_bin+1
- lda temp_bcd,x
- pha
- lsr
- lsr
- lsr
- lsr
- jsr @print_one_digit
- pla
- and #$0f
- jsr @print_one_digit
- dec temp_bin+1
- bpl @print_one_byte
- rts
-@print_one_digit:
- cmp #0
- beq @this_digit_is_zero
- inc temp_bin ;increment count of non-zero digits
-@ok_to_print:
- clc
- adc #'0'
- jsr print_a
- rts
-@this_digit_is_zero:
- ldx temp_bin ;how many non-zero digits have we printed?
- bne @ok_to_print
- ldx temp_bin+1 ;how many digits are left to print?
- bne @this_is_not_last_digit
- inc temp_bin ;to get to this point, this must be the high nibble of the last byte.
- ;by making 'count of non-zero digits' to be >0, we force printing of the last digit
-@this_is_not_last_digit:
- rts
-
-print_hex:
- pha
- pha
- lsr
- lsr
- lsr
- lsr
- tax
- lda hexdigits,x
- jsr print_a
- pla
- and #$0F
- tax
- lda hexdigits,x
- jsr print_a
- pla
- rts
-
-print_errorcode:
- ldax #error_code
- jsr print
- lda ip65_error
- jsr print_hex
- jmp print_cr
-
-.rodata
-hexdigits:
-.byte "0123456789ABCDEF"
-
-
-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
-
-dns_server_msg:
-.byte "DNS SERVER : ", 0
-
-dhcp_server_msg:
-.byte "DHCP SERVER : ", 0
-
-tftp_server_msg:
-.byte "TFTP SERVER : ", 0
-
-init_msg:
- .byte " INITIALIZING ",0
-
-
-dns_lookup_failed_msg:
- .byte "DNS LOOKUP "
-failed_msg:
- .byte "FAILED", 0
-
-ok_msg:
- .byte "OK", 0
-
-
-error_code:
- .asciiz "ERROR CODE: "
-
-press_a_key_to_continue:
- .byte "PRESS A KEY TO CONTINUE",13,0
-
-
-
-;-- LICENSE FOR commonprint.i --
-; 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/wiznet/kipperwizdisk.d64 b/client/wiznet/kipperwizdisk.d64
deleted file mode 100644
index c521e10..0000000
Binary files a/client/wiznet/kipperwizdisk.d64 and /dev/null differ
diff --git a/client/wiznet/telnetd.s b/client/wiznet/telnetd.s
deleted file mode 100644
index 8fd9538..0000000
--- a/client/wiznet/telnetd.s
+++ /dev/null
@@ -1,366 +0,0 @@
-; #############
-;
-; jonno@jamtronix.com - June 2011
-; Telnet server cartridge
-;
-
-TELNET_PORT=6400
- .include "../inc/common.i"
- .include "commonprint.i"
-
- .import ip65_init
- .import dhcp_init
- .import w5100_set_ip_config
- .import cls
- .import beep
- .import exit_to_basic
- .import timer_vbl_handler
- .import get_key_ip65
- .import cfg_mac
- .import cfg_size
- .import cfg_ip
- .import cfg_netmask
- .import cfg_gateway
- .import cfg_dns
- .import cfg_tftp_server
- .import cfg_get_configuration_ptr
- .import ip65_process
- .import copymem
- .import tcp_listen
- .import tcp_callback
- .import tcp_send
- .import tcp_send_data_len
- .import tcp_inbound_data_length
- .import tcp_inbound_data_ptr
- .import tcp_connected
- .importzp copy_src
- .importzp copy_dest
- buffer_ptr=copy_dest
- .import __DATA_LOAD__
- .import __DATA_RUN__
- .import __DATA_SIZE__
- .import __SELF_MODIFIED_CODE_LOAD__
- .import __SELF_MODIFIED_CODE_RUN__
- .import __SELF_MODIFIED_CODE_SIZE__
-
-
- CINV=$314 ;vector to IRQ interrupt routine
- ISTOP=$328;vector to kernal routine to check if STOP key pressed
- KEYD=$277 ;input keyboard buffer
- NDX=$C6 ;number of keypresses in buffer
- XMAX=$289 ;max keypresses in buffer
- STKEY=$91 ;last key pressed
-
- INIT_MAGIC_VALUE=$C7
-.segment "CARTRIDGE_HEADER"
-.word cold_init ;cold start vector
-.word warm_init ;warm start vector
-.byte $C3,$C2,$CD,$38,$30 ; "CBM80"
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-
-.code
-
-
-
-cold_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
-
-warm_init:
- lda #INIT_MAGIC_VALUE
- cmp init_flag
- bne @real_init
- jmp $fe5e ; contine on to real RESTORE routine
-@real_init:
- sta init_flag
-
-
- ;we need to set up BASIC as well
- jsr $e453 ;set BASIC vectors
- jsr $e3bf ;initialize zero page
-
-;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
-
-
-;set normal BASIC colour
- LDA #$0e ;light blue
- STA $D020 ;border
- LDA #$06 ;dark blue
- STA $D021 ;background
- lda #$9a
- jsr print_a
-
- ;copy KERNAL to RAM so we can patch it
-
-
- ldax #startup_msg
- jsr print
- jsr ip65_init
-
- bcs init_failed
- jsr dhcp_init
- bcc init_ok
-init_failed:
-
- jsr print_errorcode
- jsr print_ip_config
- jsr print_cr
-
-flash_forever:
- inc $d020
- jmp flash_forever
-init_ok:
-
-;install our new IRQ handler
- sei
- ldax CINV
- stax old_tick_handler
- ldax #tick_handler
- stax CINV
-
-;install our new STOP handler
-
- ldax ISTOP
- stax old_stop_handler
- ldax #stop_handler
- stax ISTOP
-
- cli
-
-start_listening:
-
- ldax #telnet_callback
- stax tcp_callback
- ldax #listening
- jsr print
- ldax #cfg_ip
- jsr print_dotted_quad
- ldax #port
- jsr print
-
- ;we need to copy BASIC as well since swapping KERNAL forces swap of BASIC
- ldax #$8000
- stax copy_src
- stax copy_dest
- ldax #$4000
- jsr copymem
-
- ldax #$E000
- stax copy_src
- stax copy_dest
- ldax #$2000
- jsr copymem
-
- ;now intercept calls to $E716
- ;we do this instead of using the $326 vector because the BASIC
- ;'READY' loop calls $E716 directly rather than calling $FFD2
-
- lda #$4C ;JMP
- sta $e716
- ldax #new_charout
- stax $e717
-
-
- ;swap out BASIC & KERNAL
- lda #$35
- sta $01
-
-
- ldax #TELNET_PORT
- jsr tcp_listen
- ldax #term_setup_string_length
- sta tcp_send_data_len
- ldax #term_setup_string
- jsr tcp_send
-
-
- jmp $E397
-
-wait_for_keypress:
- ldax #press_a_key_to_continue
- jsr print
-@loop:
- jsr $ffe4
- beq @loop
- rts
-
-get_key:
-@loop:
- jsr $ffe4
- beq @loop
- rts
-
-
-tick_handler: ;called at least 60hz via $314
- lda sending_flag
- bne @done
- inc jiffy_count
- lda jiffy_count
- cmp #$06 ;about 100ms
- bne @done
- lda #0
- sta jiffy_count
- lda tcp_connected
- beq @done
- jsr ip65_process
-@done:
- jmp (old_tick_handler)
-
-
-telnet_callback:
- lda tcp_inbound_data_length+1
- cmp #$ff
- bne @not_eof
- ldax #connection_closed
- jsr print
-
- jmp start_listening
-
-@not_eof:
- ldax tcp_inbound_data_ptr
- stax buffer_ptr
- ldy #0
-
-@next_byte:
- ldx NDX
- cpx XMAX
- beq @done
-
- lda (buffer_ptr),y
- cmp #$03 ;is ^C?
- bne @not_ctrl_c
- inc break_flag
- jmp @key_done
-@not_ctrl_c:
- inc NDX
- sta KEYD,x
-@key_done:
- iny
- cpy tcp_inbound_data_length
- bne @next_byte
- @done:
- rts
-
-new_charout:
- pha ;original $e716 code we patched over
- sta $d7 ;original $e716 code we patched over
- stx temp_x
- sty temp_y
- sta output_buffer
- pha
- ldax #1
- sta tcp_send_data_len
- sta sending_flag
- ldax #output_buffer
- jsr tcp_send
- dec sending_flag
- pla
- ldx temp_x
- ldy temp_y
- jmp $e719 ;after the code we patched
-
-stop_handler:
-
- lda break_flag
- beq @no_stop
-
- lda #$7F
- sta $91
- lda #0
- sta break_flag
-@no_stop:
- jmp (old_stop_handler)
-
-.bss
-init_flag: .res 1
-old_tick_handler: .res 2
-old_stop_handler: .res 2
-temp_x : .res 1
-temp_y : .res 1
-output_buffer: .res 64
-
-.data
-jiffy_count: .byte 0
-break_flag: .byte 0
-sending_flag: .byte 0
-.rodata
-
-startup_msg:
-.byte 147 ;cls
-;.byte 14 ;lower case
-.byte 142 ;upper case
-.byte 13,"TELNETD "
-.include "../inc/version.i"
-.include "timestamp.i"
-.byte 13
-.byte 0
-listening:
-.byte 13,"LISTENING ON "
-.byte 0
-port:
-.byte ":"
-.if (TELNET_PORT > 999 )
-.byte <(((TELNET_PORT / 1000) .mod 10) + $30)
-.endif
-.if TELNET_PORT>99
-.byte <(((TELNET_PORT / 100 ) .mod 10) + $30)
-.endif
-.byte <(((TELNET_PORT / 10 ) .mod 10) + $30)
-.byte <(((TELNET_PORT ) .mod 10) + $30)
-.byte 13
-.byte "HIT RUN/STOP TO ABORT"
-.byte 0
-
-connection_closed:
-.byte 13,"CONNECTION CLOSED",13,0
-
-term_setup_string:
-
- .byte 142 ;upper case
- .byte 147 ;cls
-term_setup_string_length=*-term_setup_string
-
-;we need a 'dummy' segment here - some drivers use this segment (e.g. wiznet), some don't (e.g. rr-net)
-;if we don't declare this, we get an 'undefined segment' error when linking to a driver that doesn't use it.
-.segment "SELF_MODIFIED_CODE"
-
-;-- LICENSE FOR wizboot.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 wizboot.
-;
-; The Initial Developer of the Original Code is Jonno Downes,
-; jonno@jamtronix.com.
-; Portions created by the Initial Developer are Copyright (C) 2011
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
diff --git a/client/wiznet/timestamp.rb b/client/wiznet/timestamp.rb
deleted file mode 100644
index a061cf9..0000000
--- a/client/wiznet/timestamp.rb
+++ /dev/null
@@ -1 +0,0 @@
-puts Time.now.strftime(".byte \" (%Y-%m-%d)\"")
\ No newline at end of file
diff --git a/client/wiznet/wizbobcart.cfg b/client/wiznet/wizbobcart.cfg
deleted file mode 100644
index 69b227b..0000000
--- a/client/wiznet/wizbobcart.cfg
+++ /dev/null
@@ -1,27 +0,0 @@
-# CA65 config for a Retro Replay cartridge
-# default is for GAME=1, EXROM=0,
-
-MEMORY {
- IP65ZP: start = $A3, size = $11, type = rw, define = yes;
- HEADER: start = $8000, size = $18, file = %O;
- DEFAULTS: start = $8018, size = $1F, file = %O;
- ROM: start = $8037, size = $1FC9, define = yes, file = %O;
- RAM: start = $C010, size = $0fE0, define = yes;
- RAM4: start = $7800, size = $07C9, define = yes; #scratch area for apps embedded in cart to use
-
-
-}
-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 = RAM4, type = rw, define = yes;
- APP_SCRATCH: load = RAM4, type = bss;
- TCP_VARS: load = RAM4, type = bss;
- HTTP_VARS: load=ROM, run = RAM4, type = rw,define = yes;
-
- }
diff --git a/client/wiznet/wizbobcart.s b/client/wiznet/wizbobcart.s
deleted file mode 100644
index d996604..0000000
--- a/client/wiznet/wizbobcart.s
+++ /dev/null
@@ -1,1755 +0,0 @@
-
-.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?
-INIT_MAGIC_VALUE=$C7
-;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
-FOUT = $BDDD ;convert floating point number to string
-STRLIT = $B487
-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 eth_driver_name
-.import get_key_if_available
-.import timer_read
-.import native_to_ascii
-.import ascii_to_native
-.import eth_init
-
-.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
-
-.segment "IP65ZP" : zeropage
-
-pptr: .res 2
-temp2: .res 2
-temp=pptr
-
-.segment "CARTRIDGE_HEADER"
-.word cold_init ;cold start vector
-.word warm_init ;warm start vector
-.byte $C3,$C2,$CD,$38,$30 ; "CBM80"
-.byte "KIPBOB"
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-
-.code
-
-
-cold_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
-
-warm_init:
- lda #INIT_MAGIC_VALUE
- cmp init_flag
- bne @real_init
- jmp $fe5e ; contine on to real RESTORE routine
-@real_init:
- sta init_flag
-
-;we need to set up BASIC as well
- jsr $e453 ;set BASIC vectors
- jsr $e3bf ;initialize zero page
-
-;set normal BASIC colour
- LDA #$0e ;light blue
- STA $D020 ;border
- LDA #$06 ;dark blue
- STA $D021 ;background
- lda #$9a
- jsr print_a
-
-;make some room for extra RAM
-
- ldax #$7000
- stax MEMSIZ
-
- stax http_variables_buffer
-
-; lda #$90 ;'rest of banner
-; ldy #$E4
-
-;print rest of startup banner
-; JSR $E42D
-
-;print normal startup banner
- JSR $E422
-
- ldax #welcome_banner
- jsr print
-
-;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
-@flash_forever:
- inc $d020
- jmp @flash_forever
-@no_nic:
- .byte 13,"RR-NET MK3 NOT FOUND",13,0
-
-@init_ok:
-
- jsr $A644 ;do a "NEW"
-
-
-; jmp $A474 ;"READY" prompt ;FIXME - delete this line to autoload 'INDEX.BAS'
-
- ldax #loading_index_bas
- jsr print
-
-
- ldx #index_bas
- lda #index_bas_length
- jsr SETNAM
- lda #$01 ; file number 1
- ldx #$08 ; default to device 8
- ldy #$01 ; secondary address = 1 means use load address in file
- jsr SETLFS
- lda #$00 ; $00 means: load to memory (not verify)
- jsr LOAD
- bcc @no_error
- pha
- ldax #error
- jsr print
- pla
- jsr print_hex
- jsr print_cr
- jmp $A474 ;"READY" prompt
-
-@no_error:
- ;we have a valid 'INDEX.BAS' loaded
-
- jsr $ffe7 ; make sure all files have been closed.
- jsr $a533 ; re-bind BASIC lines
-
- ldx $22 ;load end-of-BASIC pointer (lo byte)
- ldy $23 ;load end-of-BASIC pointer (hi byte)
- stx $2d ;save end-of-BASIC pointer (lo byte)
- sty $2e ;save end-of-BASIC pointer (hi byte)
- jsr $a659 ; CLR (reset variables)
-
-
- jmp $a7ae ; jump to BASIC interpreter loop
-
-
-welcome_banner:
-;.byte $93 ;CLS
-.byte $0d," ---> BASIC ON BAILS"
-.include "timestamp.i"
-.byte " <---"
-.byte $0d,$0d
-.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:
- jsr print_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+3,y
- dey
- bpl:-
- jsr eth_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
-
-; ldax #transfer_buffer
-; jsr print
-; lda hash
-; jsr print_hex
-; jsr print_cr
- rts
-
-
-yield_keyword:
- jsr flush_keyword
- jsr tcp_close
- jmp httpd_start
-
-gosub:
-
-
-bang_keyword:
-
- jsr FRMEVL
- bit VALTYP
- bmi @string_val
- jsr FOUT
- jsr STRLIT
-@string_val:
- jsr FRESTR ;if not string, will create type mismatch error
- sta param_length
-
- lda sent_header
- bne :+
- jsr send_header
-:
- ldy #0
- sty string_ptr
- cpy param_length
- beq @done
-@loop:
- lda ($22),y
- jsr xmit_a
- inc string_ptr
- ldy string_ptr
- cpy param_length
- bne @loop
-@done:
- 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
- tya
- 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:
- 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:
- 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
- cpy #error_buffer_length-1
- bne @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 $0d,"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
-
-loading_index_bas:
- .byte "LOADING "
-index_bas:
- .byte "INDEX.BAS"
-index_bas_length=*-index_bas
- .byte $0d
- .byte 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 "DHCP",$E2 ;DUMMY!
- .byte "PING",$E3
- .byte "MYIP",$E4
- .byte "NETMASK",$E5
- .byte "GATEWAY",$E6
- .byte "DNS",$E7 ;DUMMY!
- .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
-connection_timeout_seconds: .byte 0
-found_eol: .byte 0
-connection_closed: .byte 0
-
-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
-
-.bss
-init_flag: .res 1
-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
-output_buffer_length: .res 2
-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
-error_buffer_length=*-error_buffer
-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
-
-
-
-
-;-- LICENSE FOR wizbobcart.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,2011
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
diff --git a/client/wiznet/wizboot.s b/client/wiznet/wizboot.s
deleted file mode 100644
index 7a71a90..0000000
--- a/client/wiznet/wizboot.s
+++ /dev/null
@@ -1,353 +0,0 @@
-; #############
-;
-; jonno@jamtronix.com - May 2011
-;
-
-
- .include "../inc/common.i"
- .include "commonprint.i"
-
- .import ip65_init
- .import dhcp_init
- .import tftp_ip
- .importzp tftp_filename
- .import tftp_load_address
- .import tftp_download
- .import tftp_callback_vector
- .import w5100_set_ip_config
- .import cls
- .import beep
- .import exit_to_basic
- .import timer_vbl_handler
- .import get_key_ip65
- .import cfg_mac
- .import cfg_size
- .import cfg_ip
- .import cfg_netmask
- .import cfg_gateway
- .import cfg_dns
- .import cfg_tftp_server
- .import cfg_get_configuration_ptr
- .import dns_ip
- .import dns_set_hostname
- .import dns_resolve
- .import ip65_process
- .import copymem
- .importzp copy_src
- .importzp copy_dest
- .import get_filtered_input
- .import __DATA_LOAD__
- .import __DATA_RUN__
- .import __DATA_SIZE__
- .import __SELF_MODIFIED_CODE_LOAD__
- .import __SELF_MODIFIED_CODE_RUN__
- .import __SELF_MODIFIED_CODE_SIZE__
-
- SCNKEY=$FF9F ;Query keyboard - put matrix code into $00CB & status of shift keys $028D
-
- IP_CONFIG_SNAPSHOT=$200
-
- .bss
-tmp_load_address: .res 2
-shift_pressed_on_bootup : .res 1
-
- .data
-exit_cart:
-
-call_downloaded_prg:
- jsr $0000 ;overwritten when we load a file
- jmp warm_init
-
-
-.segment "CARTRIDGE_HEADER"
-.word cold_init ;cold start vector
-.word warm_init ;warm start vector
-.byte $C3,$C2,$CD,$38,$30 ; "CBM80"
-.byte "KIPWBT"
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-.byte $0,$0,$0 ;reserved for future use
-
-.code
-
-
-cold_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
-
-
- ;do the 'secret knock' to disable writes to the EEPROM
-
- lda #$55
- sta $9c55
- lda #$aa
- sta $83aa
- lda #$05
- sta $9c55
-
-@poll_loop:
- lda $8000
- cmp $8000
- bne @poll_loop
-
- ;copy ourselves to the C64 RAM
- ;so if we go into 'SHUTUP' mode, we keep executing from the same address, in C64 RAM
- ldax #$8000
- stax copy_src
- stax copy_dest
- ldax #$2000
- jsr copymem
-
-
-warm_init:
-
- jsr SCNKEY ;Query keyboard - put matrix code into $00CB & status of shift keys $028D
- lda $028D
- and #$02
- beq @commodore_key_not_pressed
- jmp $e394
-@commodore_key_not_pressed:
-
- lda $028D
- and #$01
- sta shift_pressed_on_bootup
-
- ;set some funky colours
- LDA #$05 ;green
- STA $D020 ;border
- LDA #$00 ;black
- STA $D021 ;background
-
- lda #$05 ;petscii for white text
-
-
- jsr print_a
-
-
-;relocate our r/w data
- ldax #__DATA_LOAD__
- stax copy_src
- ldax #__DATA_RUN__
- stax copy_dest
- ldax #__DATA_SIZE__
- jsr copymem
- ldax #__SELF_MODIFIED_CODE_LOAD__
- stax copy_src
- ldax #__SELF_MODIFIED_CODE_RUN__
- stax copy_dest
- ldax #__SELF_MODIFIED_CODE_SIZE__
- jsr copymem
-
-
- ldax #wizboot_msg
- jsr print
-
- ;monkey patch the TFTP callback handler
- ldax tftp_callback_vector+1
- stax new_tftp_callback_vector+1
- ldax #new_tftp_callback_vector
- stax tftp_callback_vector+1
-
- jsr ip65_init
-
- bcs init_failed
- jsr dhcp_init
- bcc init_ok
-init_failed:
-
- jsr print_errorcode
- jsr print_ip_config
-flash_forever:
- inc $d020
- jmp flash_forever
-init_ok:
- ;stash the IP config we just got somewhere that other WizNet apps can get it
- ldax #cfg_mac
- stax copy_src
- ldax #IP_CONFIG_SNAPSHOT
- stax copy_dest
- ldax #cfg_size
- jsr copymem
-
- lda shift_pressed_on_bootup
- bne @skip_resolving_tftp_hostname
-
- ldax #resolving_tftp_hostname
- jsr print
- jsr print_cr
- ldax #tftp_hostname
- jsr dns_set_hostname
- bcs init_failed
- jsr dns_resolve
- bcs init_failed
-
- ldx #$03
-@copy_tftp_ip_loop:
- lda dns_ip,x
- sta cfg_tftp_server,x
- dex
- bpl @copy_tftp_ip_loop
-
-@skip_resolving_tftp_hostname:
-
- ldx #$03
-:
- lda cfg_tftp_server,x
- sta tftp_ip,x
- dex
- bpl :-
-
- jsr print_cr
- jsr print_ip_config
-
-tftp_boot:
-
- ldax #tftp_file
- stax tftp_filename
-
-
- ldax #$0000 ;load address will be first 2 bytes of file we download (LO/HI order)
- stax tftp_load_address
-
- ldax #downloading_msg
- jsr print
- ldax tftp_filename
- jsr print
- jsr print_cr
- jsr tftp_download
-
- bcc file_downloaded_ok
-
-
-
- ldax #tftp_download_fail_msg
- jsr print
- jsr print_errorcode
- jsr wait_for_keypress
-return_to_main:
- jmp tftp_boot
-
-file_downloaded_ok:
-
- ldax #tftp_download_ok_msg
- jsr print
- ldax tftp_load_address
-
-boot_into_file:
- stax tmp_load_address ;use the param buffer as a temp holding place for the load address
- ;get ready to bank out
-
- jsr $ffe7 ; make sure all files have been closed.
- ;check whether the file we just downloaded was a BASIC prg
- lda tmp_load_address
- cmp #01
- bne @not_a_basic_file
-
- lda tmp_load_address+1
- cmp #$08
- bne @not_a_basic_file
-
-
- jsr $e453 ;set BASIC vectors
- jsr $e3bf ;initialize BASIC
- jsr $a86e
- jsr $a533 ; re-bind BASIC lines
- ldx $22 ;load end-of-BASIC pointer (lo byte)
- ldy $23 ;load end-of-BASIC pointer (hi byte)
- stx $2d ;save end-of-BASIC pointer (lo byte)
- sty $2e ;save end-of-BASIC pointer (hi byte)
- jsr $a659 ; CLR (reset variables)
- ldax #$a7ae ; jump to BASIC interpreter loop
- jmp exit_cart_via_ax
-
-@not_a_basic_file:
-
-
- ldax tmp_load_address
-exit_cart_via_ax:
- sta call_downloaded_prg+1
- stx call_downloaded_prg+2
- jmp exit_cart
-
-
-
-
-wait_for_keypress:
- ldax #press_a_key_to_continue
- jsr print
-@loop:
- jsr $ffe4
- beq @loop
- rts
-
-get_key:
-@loop:
- jsr $ffe4
- beq @loop
- rts
-
-
-.rodata
-
-wizboot_msg:
-.byte 147 ;cls
-;.byte 14 ;lower case
-.byte 142 ;upper case
-.byte 13," RR-NET MK3 - V"
-.include "../inc/version.i"
-.include "timestamp.i"
-.byte 13
-.byte 13," HOLD C= FOR BASIC / SHIFT FOR LAN BOOT",13,13
-.byte 0
-downloading_msg: .byte 13,"DOWNLOADING ",0
-
-tftp_download_fail_msg:
- .byte "DOWNLOAD FAILED", 13, 0
-
-tftp_download_ok_msg:
- .byte 13,"DOWNLOAD OK", 13, 0
-
-tftp_file:
- .asciiz "BOOTC64.PRG"
-
-resolving_tftp_hostname:
- .byte "RESOLVING "
-tftp_hostname:
- .asciiz "JAMTRONIX.COM"
-
- .data
- new_tftp_callback_vector:
- jsr $ffff
- lda #'.'
- jmp print_a
-
-
-
-;we need a 'dummy' segment here - some drivers use this segment (e.g. wiznet), some don't (e.g. rr-net)
-;if we don't declare this, we get an 'undefined segment' error when linking to a driver that doesn't use it.
-.segment "SELF_MODIFIED_CODE"
-
-;-- LICENSE FOR wizboot.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 wizboot.
-;
-; The Initial Developer of the Original Code is Jonno Downes,
-; jonno@jamtronix.com.
-; Portions created by the Initial Developer are Copyright (C) 2011
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
diff --git a/client/wiznet/wizboot2.s b/client/wiznet/wizboot2.s
deleted file mode 100644
index 505222e..0000000
--- a/client/wiznet/wizboot2.s
+++ /dev/null
@@ -1,121 +0,0 @@
-
-.include "../inc/common.i"
-.import cfg_get_configuration_ptr
-.include "../inc/commonprint.i"
-
-.include "../drivers/w5100.i"
-
-IP_CONFIG_SNAPSHOT=$200
-
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-.import ip_init
-.import arp_init
-.import timer_init
-.import cfg_mac
-.import cfg_size
-.import url_download
-.import url_download_buffer
-.import url_download_buffer_length
-
-
-.import __DATA_LOAD__
-.import __DATA_RUN__
-.import __DATA_SIZE__
-.import __SELF_MODIFIED_CODE_LOAD__
-.import __SELF_MODIFIED_CODE_RUN__
-.import __SELF_MODIFIED_CODE_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
-
-init:
-
- ;copy IP parameters & MAC address that we stashed in the 'stage 1' loader
-
- ldax #IP_CONFIG_SNAPSHOT
- stax copy_src
- ldax #cfg_mac
- stax copy_dest
- ldax #cfg_size
- jsr copymem
-
- jsr timer_init ; initialize timer
- jsr arp_init ; initialize arp
- jsr ip_init ; initialize ip, icmp, udp, and tcp
-
- ldax #download_buffer
- stax url_download_buffer
- ldax #download_buffer_length
- stax url_download_buffer_length
- ldax #banner
- jsr print
- ldax #initial_resource_file
- jsr get_resource_file
-
-
-@loop:
- jmp @loop
- rts
-
-get_resource_file:
- stax resource_file
- ldax #retrieving
- jsr print_ascii_as_native
- ldax resource_file
- jsr print_ascii_as_native
- ldax resource_file
- jsr url_download
- bcc @download_ok
- print_failed
- jsr print_errorcode
- rts
-@download_ok:
- ldax #download_buffer
- jsr print_ascii_as_native
- rts
-
-.rodata
-banner:
-.byte 147 ;cls
-.byte 14 ;lower case
-.byte "wIZnET lOADER - sTAGE 2",13,0
-retrieving: .asciiz "Fetch "
-initial_resource_file: .byte "http://jamtronix.com/c64files.txt",0
-.bss
-resource_file: .res 2
-download_buffer: .res 8192
-download_buffer_length=*-download_buffer
-
-;-- LICENSE FOR wizboot2.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 wizboot2.
-;
-; The Initial Developer of the Original Code is Jonno Downes,
-; jonno@jamtronix.com.
-; Portions created by the Initial Developer are Copyright (C) 2011
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
diff --git a/client/wiznet/wizflashheader.s b/client/wiznet/wizflashheader.s
deleted file mode 100644
index a5a7025..0000000
--- a/client/wiznet/wizflashheader.s
+++ /dev/null
@@ -1,423 +0,0 @@
-
-.include "../inc/common.i"
-print_a = $ffd2
-
-
-
-.zeropage
-cart_data_ptr: .res 2
-eeprom_ptr: .res 2
-pptr: .res 2
-checksum_ptr: .res 2
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ldax #banner
- jsr print
- cli
-
- ;check if our data is a KIPPER image (with MAC at offset 0x18)
- lda cart_data+9
- cmp #'K'
- bne @not_kipper
- lda cart_data+10
- cmp #'I'
- bne @not_kipper
- lda cart_data+11
- cmp #'P'
- bne @not_kipper
-@loop:
- ldax #found_kip
- jsr print
- lda cart_data+$18
- sta cart_data+$1FF8
- lda cart_data+$19
- sta cart_data+$1FF9
- lda cart_data+$1A
- sta cart_data+$1FFA
- lda cart_data+$1B
- sta cart_data+$1FFB
- lda cart_data+$1C
- sta cart_data+$1FFC
- lda cart_data+$1D
- sta cart_data+$1FFD
-
- lda #0 ;flag byte defaults to 0
- sta cart_data+$1FFE
-
- ldax #cart_data+$1FF8
- stax checksum_ptr
-
- clc
- ldy #0
- tya
-@checksum_loop:
- asl
- adc (checksum_ptr),y
- iny
- cpy #7 ;6 byte MAC address plus 1 byte flag
- bne @checksum_loop
-
- sta cart_data+$1FFF
- jsr print_hex
- jsr print_cr
-@not_kipper:
-
-
- ldax #$8000
- stax eeprom_ptr
-
- ;set up access to READ/WRITE external ROM
-
- lda #$37
- sta $01
- sta $de02 ;leave 'shut up' mode
- sta $de08 ;enable ROM
- sta $de0a ;set banking bit 0
- sta $de0c ;set banking bit 1
-
- lda $d011
- sta old_d011
- and #$ef ;turn off bit 4
- sta $d011
- jsr turn_off_write_protect
-
-
- ldax #$8000
- stax eeprom_ptr
-
-@reset_64_bytes:
- inc $d020
-
- ldy #0
-@reset_1_byte:
- lda #0
- sta (eeprom_ptr),y
- iny
- cpy #64
- bne @reset_1_byte
- jsr poll_till_stable
-
- clc
- tya
- adc eeprom_ptr
- sta eeprom_ptr
- bcc :+
- inc eeprom_ptr+1
-:
-
- lda eeprom_ptr+1
- cmp #$A0
- bne @reset_64_bytes
-
-;now validate the reset
- lda #$0
- sta validation_counter
- lda old_d011
- sta $d011
-
- ldax #validating_reset
- jsr print
-
-@reset_validation_loop:
- ldax #$8000
- stax eeprom_ptr
- ldy #0
-@reset_compare_loop:
- lda (eeprom_ptr),y
- bne @reset_validation_error
- iny
- bne @reset_compare_loop
- lda #'.'
- jsr print_a
-
- inc eeprom_ptr+1
- lda eeprom_ptr+1
- cmp #$A0
- bne @reset_compare_loop
- beq @reset_ok
- @reset_validation_error:
- jmp @validation_error
-
-@reset_ok:
- ldax #OK
- jsr print
-
-
- lda $d011
- and #$ef ;turn off bit 4
- sta $d011
-
-
- ldax #cart_data
- stax cart_data_ptr
- ldax #$8000
- stax eeprom_ptr
-
-@copy_64_bytes:
- inc $d020
-
- ldy #0
-@copy_1_byte:
- lda (cart_data_ptr),y
- sta (eeprom_ptr),y
- iny
- cpy #64
- bne @copy_1_byte
- jsr poll_till_stable
-
- clc
- tya
- adc eeprom_ptr
- sta eeprom_ptr
- bcc :+
- inc eeprom_ptr+1
-:
- clc
- tya
- adc cart_data_ptr
- sta cart_data_ptr
- bcc :+
- inc cart_data_ptr+1
-:
-
- lda eeprom_ptr+1
- cmp #$A0
- bne @copy_64_bytes
-
-;now validate the data
- lda #$0
- sta validation_counter
- lda old_d011
- sta $d011
-
- ldax #validating
- jsr print
-
-@validation_loop:
- ldax #cart_data
- stax cart_data_ptr
- ldax #$8000
- stax eeprom_ptr
- ldy #0
-@compare_loop:
- lda (cart_data_ptr),y
- cmp (eeprom_ptr),y
- bne @validation_error
- iny
- bne @compare_loop
- lda #'.'
- jsr print_a
-
- inc cart_data_ptr+1
- inc eeprom_ptr+1
- lda eeprom_ptr+1
- cmp #$A0
- bne @compare_loop
-
- inc validation_counter
- lda validation_counter
- cmp #$08
- bne @validation_loop
- ldax #ok
- jsr print
-
- ldax #$8000
- stax eeprom_ptr
-
- jsr turn_on_write_protect
-
- jmp @exit_to_basic
-
-@validation_error:
- sty error_offset
-
- ldax #validation_error
- jsr print
- lda eeprom_ptr+1
- jsr print_hex
- lda eeprom_ptr
- jsr print_hex
- ldax #offset
- jsr print
- lda error_offset
- jsr print_hex
- jsr print_cr
-
-
- ldax #wr
- jsr print
- lda #0
- sta byte_ptr
-@wr_loop:
- ldy byte_ptr
- lda (cart_data_ptr),y
- jsr print_hex
-
- lda byte_ptr
- cmp error_offset
- beq :+
- inc byte_ptr
- bne @wr_loop
-:
- jsr print_cr
-
- ldax #rd
- jsr print
- lda #0
- sta byte_ptr
-@rd_loop:
- ldy byte_ptr
- lda (eeprom_ptr),y
- jsr print_hex
- lda byte_ptr
- cmp error_offset
- beq :+
- inc byte_ptr
- bne @rd_loop
-:
- jsr print_cr
-
-;if there is an error somewhere in the eeprom, but we have a valid 'CBM80' header bad things can happen
-;so overwrite the signature bytes
- lda #$FF
- sta $8004
- sta $8005
- sta $8006
- sta $8007
- sta $8008
-
-@exit_to_basic:
- sei
- lda old_d011
- sta $d011
- rts
-
-turn_off_write_protect:
- ;do the 'secret knock' to enable writes
- lda #$55
- sta $9c55
- lda #$aa
- sta $83aa
- lda #$01
- sta $9c55
- lda #$55
- sta $9c55
- lda #$aa
- sta $83aa
- lda #$04
- sta $9c55
- jmp poll_till_stable
-
-turn_on_write_protect:
- ;do the 'secret knock' to disable writes
-
- lda #$55
- sta $9c55
- lda #$aa
- sta $83aa
- lda #$05
- sta $9c55
-
-poll_till_stable:
- ldax eeprom_ptr
- stax @offset_1+1
- stax @offset_2+1
- ldx #$03
-@poll_loop:
-@offset_1:
- lda $8000 ;address will get overwritten
-@offset_2:
- cmp $8000 ;address will get overwritten
- bne poll_till_stable
- dex
- bne @poll_loop
-@done:
- rts
-
-
-print_cr:
- lda #13
- jmp print_a
-
-print:
- sta pptr
- stx pptr + 1
-
-@print_loop:
- ldy #0
- lda (pptr),y
- beq @done_print
- jsr print_a
- inc pptr
- bne @print_loop
- inc pptr+1
- bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-)
-@done_print:
- rts
-
-print_hex:
- pha
- pha
- lsr
- lsr
- lsr
- lsr
- tax
- lda hexdigits,x
- jsr print_a
- pla
- and #$0F
- tax
- lda hexdigits,x
- jsr print_a
- pla
- rts
-
-.rodata
-hexdigits:
-.byte "0123456789ABCDEF"
-
-banner:
-.byte 147 ;cls
-.byte 142 ;upper case
-.byte 13," RR-NET MK3 FLASHER V0.02"
-.include "timestamp.i"
-.byte 13
-.byte 0
-ok: .byte 13,"OK",13,0
-validating: .byte 13,"CHECKING EEPROM DATA ",13,0
-validation_error:
-.byte 13,"VALIDATION ERROR : $",0
-offset: .byte " OFFSET : $",0
-OK: .byte 13,"OK",13,0
-validating_reset: .byte "VALIDATING EEPROM RESET",13,0
-rd: .byte "RD :",0
-wr: .byte "WR :",0
-found_kip:
-.byte 13," KIP HEADER FOUND - RELOCATING MAC",13
-.byte " CHECKSUM : $"
-.byte 0
-.bss
-cart_data: ;this should point to where the cart data gets appended.
- .res $2000
-
-error_offset: .res 1
-byte_ptr: .res 1
-old_d011: .res 1
-validation_counter: .res 1
diff --git a/client/wiznet/wiztest.s b/client/wiznet/wiztest.s
deleted file mode 100644
index 7a1d8ae..0000000
--- a/client/wiznet/wiztest.s
+++ /dev/null
@@ -1,1289 +0,0 @@
-
-;.include "../inc/common.i"
-;.import cfg_get_configuration_ptr
-;.include "../inc/commonprint.i"
-;
-;.include "../drivers/w5100.i"
-
-
-WIZNET_BASE=$DE04
-WIZNET_MODE_REG = WIZNET_BASE
-WIZNET_ADDR_HI = WIZNET_BASE+1
-WIZNET_ADDR_LO = WIZNET_BASE+2
-WIZNET_DATA_REG = WIZNET_BASE+3
-
-TEST_LOOPS=$FF
-
-TX_BUFFER_START_PAGE=$40
-
-TIMER_POSITION_ROW=6
-TIMER_POSITION_COL=15
-TIMER_POSITION=$400+TIMER_POSITION_ROW*40+TIMER_POSITION_COL
-LAST_PROMPT_POSITION=$400+16*40+9
-RESULTS_1_POS=$400+8*40+27
-
-; load A/X macro
- .macro ldax arg
- .if (.match (.left (1, arg), #)) ; immediate mode
- lda #<(.right (.tcount (arg)-1, arg))
- ldx #>(.right (.tcount (arg)-1, arg))
- .else ; assume absolute or zero page
- lda arg
- ldx 1+(arg)
- .endif
- .endmacro
-
-; store A/X macro
- .macro stax arg
- sta arg
- stx 1+(arg)
- .endmacro
-
-
-.zeropage
-pptr: .res 2
-test_ptr: .res 2
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ;set funky colours
- lda #$06 ;
- sta $D020 ;border
- lda #$00 ;dark blue
- sta $D021 ;background
-
- ldax #banner
- jsr print
-
- lda #0
- sta clockport_mode
- lda $de01
- ora #1 ;turn on clockport
- sta $de01
-
-
- lda #$80 ;reset
- sta WIZNET_MODE_REG
- lda WIZNET_MODE_REG
- beq @reset_ok
- ;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
-@error:
- ldax #not_found
- jsr print
- lda #>WIZNET_MODE_REG
- jsr print_hex
- lda #WIZNET_MODE_REG
- jsr print_hex
- lda #";",
- "s"=>";",
- "inc"=>";",
- "i"=>";",
- "rb"=>"#",
-}
-
-
-
-def add_license_to_file(filename,original_codebase,original_developer_name,original_developer_email)
-
-filename=~/\.([^.]+$)/
-short_filename=File.basename(filename)
-comment_char=COMMENT_CHAR[$1]
-comment_char="" if comment_char.nil?
-
-dash_dash="--"
-license_text="
-
-
-#{comment_char}#{dash_dash} LICENSE FOR #{short_filename} --
-#{comment_char} The contents of this file are subject to the Mozilla Public License
-#{comment_char} Version 1.1 (the \"License\"); you may not use this file except in
-#{comment_char} compliance with the License. You may obtain a copy of the License at
-#{comment_char} http://www.mozilla.org/MPL/
-#{comment_char}
-#{comment_char} Software distributed under the License is distributed on an \"AS IS\"
-#{comment_char} basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-#{comment_char} License for the specific language governing rights and limitations
-#{comment_char} under the License.
-#{comment_char}
-#{comment_char} The Original Code is #{original_codebase}.
-#{comment_char}
-#{comment_char} The Initial Developer of the Original Code is #{original_developer_name},
-#{comment_char} #{original_developer_email}.
-#{comment_char} Portions created by the Initial Developer are Copyright (C) #{Time.now.year}
-#{comment_char} #{original_developer_name}. All Rights Reserved.
-#{comment_char} #{dash_dash} LICENSE END --
-"
-
-lines=File.new(filename).read
- if (lines=~/-- LICENSE FOR #{short_filename} #{dash_dash}/) then
- puts "skipping #{filename}"
- return
- end
- puts "#{filename} - #{lines.length} lines"
- f=File.new(filename,"w")
- f<=3
- #~ usage && exit unless (number_of_options%2) ==1 #must be an odd number of options
- #~ filename=ARGV[0]
- #~ if !(FileTest.file?(filename)) then
- #~ puts "file '#{filename}' not found"
- #~ exit
-#~ end
-
-
-
-
-
-
-#~ files_to_parse=[]
-#~ Find.find(codebase_dir) do |path|
- #~ Find.prune if path[0]=='.'
- #~ files_to_parse <"stylesheet", :href=>"ca65-doc-style.css",:type=>"text/css")
- end
- body do
- h2 "#{symbol_type}s"
- table do
- tr do
- th "#{symbol_type}"
- th "defined in"
- end
- symbol_names.each do |symbol|
- if symbol_attributes[symbol][:type]==symbol_type then
- tr do
- td symbol
- count=0
- td do
- symbol_attributes[symbol][:defined_in].each do |filename|
- count+=1
- text ", " unless count==1
- a(:href=>"#{html_filenames[filename]}##{symbol_type}s", :target=>"docwin"){filename}
- source_files<"stylesheet", :href=>"ca65-doc-style.css",:type=>"text/css")
- end
-
- body do
- h1 "#{documentation_title}"
-
- h2 "files"
- table do
- tr do
- th "file"
- th "symbols"
- end
- source_files.sort.each do |filename|
- tr do
- td {a(:href=>"#{html_filenames[filename]}", :target=>"docwin"){filename}}
- symbols_in_file=(symbol_names.collect{|symbol| symbol_attributes[symbol][:defined_in].include?(filename) ? symbol:nil}).compact
- td symbols_in_file.join(", ")
- end
- end
- end
- end
-end
-File.open("#{output_dir}/ref_index.html","w") <"stylesheet", :href=>"ca65-doc-style.css",:type=>"text/css")
- end
- body do
- a(:href=>"ref_index.html") { h1 documentation_title}
- h1 "File : #{filename}"
- pre file_overviews[filename] if file_overviews[filename].length>1
-
- if functions_in_file.length>0 then
- h2(:id=>"functions") {"functions"}
- table do
- tr do
- th{"function"}
- th{"description"}
- end
- functions_in_file.each do |symbol|
- tr do
- td(:id=>symbol){symbol}
- td{pre symbol_attributes[symbol][:comment][filename] unless symbol_attributes[symbol][:comment].nil?}
- end
- end
- end
- end
-
- if variables_in_file.length>0 then
- h2(:id=>"variables"){"variables"}
- table do
- tr do
- th{"variable"}
- th{"description"}
- th{"size (bytes)"}
- end
- variables_in_file.each do |symbol|
- tr do
- td(:id=>symbol){symbol}
- td{symbol_attributes[symbol][:comment][filename] unless symbol_attributes[symbol][:comment].nil?}
- td{symbol_attributes[symbol][:size][filename] unless symbol_attributes[symbol][:size].nil?}
- end
- end
- end
-
- end
-
- if constants_in_file.length>0 then
- h2(:id=>"constants") {"constants"}
- table do
- tr do
- th{"constants"}
- th{"description"}
- th{"value"}
- end
- constants_in_file.each do |symbol|
- tr do
- td(:id=>symbol){symbol}
- td{symbol_attributes[symbol][:comment][filename] unless symbol_attributes[symbol][:comment].nil?}
- td{symbol_attributes[symbol][:value][filename] unless symbol_attributes[symbol][:value].nil?}
- end
- end
- end
-
- end
- h2{ "implementation"}
- pre(:id=>:code) {File.open("#{codebase_dir}/#{filename}").read.gsub("\t"," ")}
- end
- end
-
- File.open("#{output_dir}/#{html_filenames[filename]}","w") <
-
-
-
-
- #{documentation_title}
-
-
-
-
-
-
-
-
-
-
-EOF
-
-end
-
-
-
-if __FILE__ == $0 then
- #run from command line
- codebase_dir=Dir.pwd
- output_dir="doc"
- codebase_title=File.basename(codebase_dir)
- document_ca65_source_as_html(codebase_dir,codebase_title,output_dir)
-end
\ No newline at end of file
diff --git a/dist/make_dist.rb b/dist/make_dist.rb
deleted file mode 100644
index 4a51959..0000000
--- a/dist/make_dist.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-
-$:.unshift(File.dirname(__FILE__)) unless
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-require 'RubyGems'
-require 'archive/zip'
-require 'ftools'
-
-WORKING_DIR=File.expand_path(File.dirname(__FILE__)+"/netboot65")
-SRC_DIR=File.expand_path(File.dirname(__FILE__)+"/../")
-VERSION_FILE=File.expand_path(File.dirname(__FILE__)+"/version_number.txt")
-VERSION_INC_FILE=File.expand_path(File.dirname(__FILE__)+"/../client/inc/version.i")
-version_string=File.open(VERSION_FILE).read
-
-["","c64","lib","bin","boot","doc","inc"].each do |dir_suffix|
- dir_path="#{WORKING_DIR}/#{dir_suffix}"
- Dir.mkdir(dir_path) unless File.exist?(dir_path)
-end
-
-[
-#["client/nb65/utherboot.dsk","a2/"],
-["client/carts/set_ip_config.rb","bin/"],
-#["client/nb65/nb65_rrnet.bin","c64/"],
-["client/carts/kipperkart.prg","c64/"],
-["client/carts/kipperkart.bin","c64/"],
-["client/carts/kipperkart_rr.bin","c64/"],
-["client/carts/kipperterm.bin","c64/"],
-["client/carts/kipperterm_rr.bin","c64/"],
-["client/carts/kipperterm.prg","c64/"],
-["client/carts/kippergo.bin","c64/"],
-["client/carts/kippergo_rr.bin","c64/"],
-["client/carts/kippergo.prg","c64/"],
-["client/carts/netboot.bin","c64/"],
-#["client/nb65/d64_upload.prg","boot/"],
-["client/examples/upnatom.prg","boot/"],
-["server/lib/tftp_server.rb","lib"],
-["server/lib/file_list.rb","lib"],
-["server/bin/tftp_only_server.rb","bin/tftp_server.rb"],
-#["server/bin/import_ags_games.rb","bin"],
-#["server/boot/BOOTA2.PG2","boot"],
-#["doc/README.Apple2.html","a2"],
-["doc/README.C64.html","c64"],
-["doc/netboot65.html","doc/index.html"],
-#["doc/README.Apple2.html","doc"],
-["doc/README.C64.html","doc"],
-["doc/CONTRIBUTORS.txt","doc/"],
-["doc/LICENSE.txt","doc/"],
-["doc/CHANGES.txt","doc/"],
-["doc/kipper_api_technical_reference.doc","doc"],
-["client/inc/common.i","inc"],
-["client/inc/kipper_constants.i","inc"],
-["client/examples/upnatom.d64","c64/"],
-#["client/nb65/d64_upload.s","examples/"],
-#["client/nb65/nb65_skeleton.s","examples/"],
-].each do |args|
- dest="#{WORKING_DIR}/#{args[1]}"
- Dir["#{SRC_DIR}/#{args[0]}"].each do |src|
- File.copy(src,dest)
- puts "#{src}->#{dest}"
- end
-end
-
-
-zipfile_name=File.dirname(__FILE__)+"/netboot65-#{version_string}.zip"
-Archive::Zip.archive(zipfile_name, WORKING_DIR)
-
-(maj,min,rel)=version_string.split(".")
-version_string="#{maj}.#{min}.#{(rel.to_i)+1}"
-
-file=File.new(VERSION_INC_FILE,"w")
-file<<".byte \"#{version_string}\"\n"
-file.close
-
-file=File.new(VERSION_FILE,"w")
-file<#{dest}"
- end
-end
-
-
-require 'document_ca65_source_as_html.rb'
-codebase_dir=WORKING_DIR
-output_dir="#{WORKING_DIR}/doc"
-codebase_title='ip65'
-document_ca65_source_as_html(codebase_dir,codebase_title,output_dir)
-zipfile_name=File.dirname(__FILE__)+"/ip65-#{Time.now.strftime("%Y-%m-%d")}.zip"
-Archive::Zip.archive(zipfile_name, WORKING_DIR)
diff --git a/dist/make_error_codes.rb b/dist/make_error_codes.rb
deleted file mode 100644
index be43f9a..0000000
--- a/dist/make_error_codes.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-errors="ERROR CODE DESCRIPTION \n"
-IO.readlines("netboot65/inc/nb65_constants.i").each do |line|
- if line=~/NB65_ERROR_(\S*).*(\$\S\S)/ then
- code=$2
- description=$1.gsub("_"," ")
- errors<<"#{code} #{description} \n"
- end
-end
-errors<<"
\n"
-puts errors
-
diff --git a/dist/update_netboot65_web.bat b/dist/update_netboot65_web.bat
deleted file mode 100644
index 9916fdf..0000000
--- a/dist/update_netboot65_web.bat
+++ /dev/null
@@ -1 +0,0 @@
-pscp netboot65/doc/* jonnosan,netboot65@web.sourceforge.net:htdocs/
diff --git a/dist/version_number.txt b/dist/version_number.txt
deleted file mode 100644
index 36f23e1..0000000
--- a/dist/version_number.txt
+++ /dev/null
@@ -1 +0,0 @@
-1.0.45
\ No newline at end of file
diff --git a/doc/BOOTSTRAPPING.txt b/doc/BOOTSTRAPPING.txt
deleted file mode 100644
index da835da..0000000
--- a/doc/BOOTSTRAPPING.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-WE NEED:
-
- - about 4K of BSS space for ethernet buffers
- - about 6K of code
-
-BOOT FROM DISK (UTHERBOOT.BIN)
-
- - loads in at $0800
- - copies monitor rom to same spot in language card (F800-FFFF)
- - relocates to $D000-$C000 in the language card (bank 1 only)
- - makes language card active (bank 1)
- - downloads BOOTA2.BIN via tftp
- - turns off language card
- - jumps to start of of BOOTA2.BIN
diff --git a/doc/BUILD_REQUIREMENTS.txt b/doc/BUILD_REQUIREMENTS.txt
deleted file mode 100644
index 0e00e86..0000000
--- a/doc/BUILD_REQUIREMENTS.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-- ruby
- http://www.ruby-lang.org/en/downloads/
- You may also need: [sudo] gem install archive-zip
-- ca65
- http://www.cc65.org
-- ripxplore.rb >=0.7.0
- http://rubyforge.org/frs/?group_id=6922
- To install: [sudo] gem install ripxplore
-- GNU make or similar
diff --git a/doc/C64 gopher client.txt b/doc/C64 gopher client.txt
deleted file mode 100644
index bf16e2b..0000000
--- a/doc/C64 gopher client.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-C64 gopher browser v0.1
-
-
-REQUIREMENTS
- 1) RR-NET or compatible
- 2) DHCP server on LAN
-
-USAGE
-
-When run, the program will use DHCP to assign itself an IP address, default gateway and DNS server address.
-
-You will then be prompted for the address of a gopher server. you can enter a hostname or an ip address. If
-you just hit enter at this prompt, "gopher.floodgap.com" will load. NB - in the current version you can only
-enter a server name, not a specific resource on that server, or a port (the default gopher port 70 is used).
-
-Once a gopher resource is loaded, the following keys are active:
-
-SPACE, F7 or down arrow : scroll down to next page
-F1 or up arror : scroll up to previous page
-F2 : show recently visited resource
-F3 or left arrow : go back to last visited resource
-F5 : prompt to enter a new server (nb server name only - not resource or port)
-RUN/STOP : quit
-
-If the page currently being displayed has links to further resources in it, each link will be displayed
-starting with a highlighted letter (e.g. the first link on a page will have an inverse "A" next to it,
-the 2nd link on a page will have an inverse "B" next to it etc). Press the letter assigned to the link
-will load up that resource.
-
-Currently only Text and Directory resources are handled.
-
-jonno @ jamtronix.com
-2009-07-11
\ No newline at end of file
diff --git a/doc/CHANGES.txt b/doc/CHANGES.txt
deleted file mode 100644
index 810dfc4..0000000
--- a/doc/CHANGES.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-
-v1.0.33
- - FIX: gracefully close the TCP connection when a telnet connection is aborted by user keystroke
- - FIX: telnet client was reprocessing last received packet after an error (including user abort)
- - FIX: was not signalling an error when a RST or FIN was sent back to tcp_connect
-
-v1.0.32
- - CHANGE: when loading cart images from disk, set default drive for cart image to be whatever drive the cart
- was loaded from
- - FIX: autoexec.prg gets loaded from whatever is configured as current default drive, not drive 8
-
-v1.0.31
- - FIX: prg version of carts had garbled screen at start
- - FIX: remove background colour flicker when httpd request received (old debug code)
-
-v1.0.30
-- FIX: TCP - when using tcp_listen, an incorrect sequence number was being sent in the SYN/ACK packet
-
-v1.0.29
-- FIX: XMODEM didn't recover if remote end tried to use 1K blocks
-
-v1.0.28
-- CHANGE: after playing a SID, go back to last viewed dir listing, not main menu
-- FIX: PETSCII mode telnet was broken
-
-v1.0.27
-- FIX: more than 3 dots in a dotted quad would crash the hostname resolver
-- FIX: parse_integer was treating digit '9' as marking end of string :-(
-- ADD: can now send an arbitrary character (by entering ASCII value : option F5 from F1 telnet menu)
-- FIX: Can now send a ^C in telnet
-- CHANGE: added a 'wait for keypress' after succesful xmodem upload
-- FIX: default drive selection being overwritten with random values
-
-v1.0.26
-- FIX: telnet often failed to notice disconnect by remote server
-- ADD: change border colour to indicate telnet connect/disconnect
-
-v1.0.25
-- FIX: vt100 emulation was leaving a cursor after a "clear to end of line" command ( [J )
-- ADD: XMODEM upload support
-- CHANGE: removed 'line mode' from telnet
-
-v1.0.24
-- CHANGE: split KipperTerm (telnet + gopher) into KipperTerm (enhanced telnet) and KipperGo (basic telnet + gopher)
-- ADD: XMODEM download support for KipperTerm
-- FIX: tell remote server screen size (40x25)
-- FIX: vt100 no longer does line wrap & scroll when writing to bottom right hand corner
-- FIX: telnet sessions now send 'keep alive' (stops my broadband router from losing NAT state)
-- FIX: tcp was sending wrong seq number when ACKing inbound data just after sending data out
-- FIX: telnet packets > 256 bytes not completely processed
-- ADD: can change default disk drive
-
-v1.0.23
-- telnet now supports vt100 emulation (thanks to Lars Stollenwerk)
-- gopher: fixed bug preventing connection to jamtronix.com
-
diff --git a/doc/CONTRIBUTORS.txt b/doc/CONTRIBUTORS.txt
deleted file mode 100644
index e28a7ca..0000000
--- a/doc/CONTRIBUTORS.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-CONTRIBUTORS
-
-Jonno Downes - current maintainer of ip65, author of layers 4-7 (dhcp,dns,tcp,telnet, http, gopher)
-Glenn Holmer - icmp enhancements, bugfixes
-Per Olofsson - initial creator of ip65, layers 1-3 (eth,arp,ip,icmp,udp)
-Lars Stollenwerk - vt100 emulation
diff --git a/doc/LICENSE.txt b/doc/LICENSE.txt
deleted file mode 100644
index 0721004..0000000
--- a/doc/LICENSE.txt
+++ /dev/null
@@ -1,471 +0,0 @@
- MOZILLA PUBLIC LICENSE
- Version 1.1
-
- ---------------
-
-1. Definitions.
-
- 1.0.1. "Commercial Use" means distribution or otherwise making the
- Covered Code available to a third party.
-
- 1.1. "Contributor" means each entity that creates or contributes to
- the creation of Modifications.
-
- 1.2. "Contributor Version" means the combination of the Original
- Code, prior Modifications used by a Contributor, and the Modifications
- made by that particular Contributor.
-
- 1.3. "Covered Code" means the Original Code or Modifications or the
- combination of the Original Code and Modifications, in each case
- including portions thereof.
-
- 1.4. "Electronic Distribution Mechanism" means a mechanism generally
- accepted in the software development community for the electronic
- transfer of data.
-
- 1.5. "Executable" means Covered Code in any form other than Source
- Code.
-
- 1.6. "Initial Developer" means the individual or entity identified
- as the Initial Developer in the Source Code notice required by Exhibit
- A.
-
- 1.7. "Larger Work" means a work which combines Covered Code or
- portions thereof with code not governed by the terms of this License.
-
- 1.8. "License" means this document.
-
- 1.8.1. "Licensable" means having the right to grant, to the maximum
- extent possible, whether at the time of the initial grant or
- subsequently acquired, any and all of the rights conveyed herein.
-
- 1.9. "Modifications" means any addition to or deletion from the
- substance or structure of either the Original Code or any previous
- Modifications. When Covered Code is released as a series of files, a
- Modification is:
- A. Any addition to or deletion from the contents of a file
- containing Original Code or previous Modifications.
-
- B. Any new file that contains any part of the Original Code or
- previous Modifications.
-
- 1.10. "Original Code" means Source Code of computer software code
- which is described in the Source Code notice required by Exhibit A as
- Original Code, and which, at the time of its release under this
- License is not already Covered Code governed by this License.
-
- 1.10.1. "Patent Claims" means any patent claim(s), now owned or
- hereafter acquired, including without limitation, method, process,
- and apparatus claims, in any patent Licensable by grantor.
-
- 1.11. "Source Code" means the preferred form of the Covered Code for
- making modifications to it, including all modules it contains, plus
- any associated interface definition files, scripts used to control
- compilation and installation of an Executable, or source code
- differential comparisons against either the Original Code or another
- well known, available Covered Code of the Contributor's choice. The
- Source Code can be in a compressed or archival form, provided the
- appropriate decompression or de-archiving software is widely available
- for no charge.
-
- 1.12. "You" (or "Your") means an individual or a legal entity
- exercising rights under, and complying with all of the terms of, this
- License or a future version of this License issued under Section 6.1.
- For legal entities, "You" includes any entity which controls, is
- controlled by, or is under common control with You. For purposes of
- this definition, "control" means (a) the power, direct or indirect,
- to cause the direction or management of such entity, whether by
- contract or otherwise, or (b) ownership of more than fifty percent
- (50%) of the outstanding shares or beneficial ownership of such
- entity.
-
-2. Source Code License.
-
- 2.1. The Initial Developer Grant.
- The Initial Developer hereby grants You a world-wide, royalty-free,
- non-exclusive license, subject to third party intellectual property
- claims:
- (a) under intellectual property rights (other than patent or
- trademark) Licensable by Initial Developer to use, reproduce,
- modify, display, perform, sublicense and distribute the Original
- Code (or portions thereof) with or without Modifications, and/or
- as part of a Larger Work; and
-
- (b) under Patents Claims infringed by the making, using or
- selling of Original Code, to make, have made, use, practice,
- sell, and offer for sale, and/or otherwise dispose of the
- Original Code (or portions thereof).
-
- (c) the licenses granted in this Section 2.1(a) and (b) are
- effective on the date Initial Developer first distributes
- Original Code under the terms of this License.
-
- (d) Notwithstanding Section 2.1(b) above, no patent license is
- granted: 1) for code that You delete from the Original Code; 2)
- separate from the Original Code; or 3) for infringements caused
- by: i) the modification of the Original Code or ii) the
- combination of the Original Code with other software or devices.
-
- 2.2. Contributor Grant.
- Subject to third party intellectual property claims, each Contributor
- hereby grants You a world-wide, royalty-free, non-exclusive license
-
- (a) under intellectual property rights (other than patent or
- trademark) Licensable by Contributor, to use, reproduce, modify,
- display, perform, sublicense and distribute the Modifications
- created by such Contributor (or portions thereof) either on an
- unmodified basis, with other Modifications, as Covered Code
- and/or as part of a Larger Work; and
-
- (b) under Patent Claims infringed by the making, using, or
- selling of Modifications made by that Contributor either alone
- and/or in combination with its Contributor Version (or portions
- of such combination), to make, use, sell, offer for sale, have
- made, and/or otherwise dispose of: 1) Modifications made by that
- Contributor (or portions thereof); and 2) the combination of
- Modifications made by that Contributor with its Contributor
- Version (or portions of such combination).
-
- (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
- effective on the date Contributor first makes Commercial Use of
- the Covered Code.
-
- (d) Notwithstanding Section 2.2(b) above, no patent license is
- granted: 1) for any code that Contributor has deleted from the
- Contributor Version; 2) separate from the Contributor Version;
- 3) for infringements caused by: i) third party modifications of
- Contributor Version or ii) the combination of Modifications made
- by that Contributor with other software (except as part of the
- Contributor Version) or other devices; or 4) under Patent Claims
- infringed by Covered Code in the absence of Modifications made by
- that Contributor.
-
-3. Distribution Obligations.
-
- 3.1. Application of License.
- The Modifications which You create or to which You contribute are
- governed by the terms of this License, including without limitation
- Section 2.2. The Source Code version of Covered Code may be
- distributed only under the terms of this License or a future version
- of this License released under Section 6.1, and You must include a
- copy of this License with every copy of the Source Code You
- distribute. You may not offer or impose any terms on any Source Code
- version that alters or restricts the applicable version of this
- License or the recipients' rights hereunder. However, You may include
- an additional document offering the additional rights described in
- Section 3.5.
-
- 3.2. Availability of Source Code.
- Any Modification which You create or to which You contribute must be
- made available in Source Code form under the terms of this License
- either on the same media as an Executable version or via an accepted
- Electronic Distribution Mechanism to anyone to whom you made an
- Executable version available; and if made available via Electronic
- Distribution Mechanism, must remain available for at least twelve (12)
- months after the date it initially became available, or at least six
- (6) months after a subsequent version of that particular Modification
- has been made available to such recipients. You are responsible for
- ensuring that the Source Code version remains available even if the
- Electronic Distribution Mechanism is maintained by a third party.
-
- 3.3. Description of Modifications.
- You must cause all Covered Code to which You contribute to contain a
- file documenting the changes You made to create that Covered Code and
- the date of any change. You must include a prominent statement that
- the Modification is derived, directly or indirectly, from Original
- Code provided by the Initial Developer and including the name of the
- Initial Developer in (a) the Source Code, and (b) in any notice in an
- Executable version or related documentation in which You describe the
- origin or ownership of the Covered Code.
-
- 3.4. Intellectual Property Matters
- (a) Third Party Claims.
- If Contributor has knowledge that a license under a third party's
- intellectual property rights is required to exercise the rights
- granted by such Contributor under Sections 2.1 or 2.2,
- Contributor must include a text file with the Source Code
- distribution titled "LEGAL" which describes the claim and the
- party making the claim in sufficient detail that a recipient will
- know whom to contact. If Contributor obtains such knowledge after
- the Modification is made available as described in Section 3.2,
- Contributor shall promptly modify the LEGAL file in all copies
- Contributor makes available thereafter and shall take other steps
- (such as notifying appropriate mailing lists or newsgroups)
- reasonably calculated to inform those who received the Covered
- Code that new knowledge has been obtained.
-
- (b) Contributor APIs.
- If Contributor's Modifications include an application programming
- interface and Contributor has knowledge of patent licenses which
- are reasonably necessary to implement that API, Contributor must
- also include this information in the LEGAL file.
-
- (c) Representations.
- Contributor represents that, except as disclosed pursuant to
- Section 3.4(a) above, Contributor believes that Contributor's
- Modifications are Contributor's original creation(s) and/or
- Contributor has sufficient rights to grant the rights conveyed by
- this License.
-
- 3.5. Required Notices.
- You must duplicate the notice in Exhibit A in each file of the Source
- Code. If it is not possible to put such notice in a particular Source
- Code file due to its structure, then You must include such notice in a
- location (such as a relevant directory) where a user would be likely
- to look for such a notice. If You created one or more Modification(s)
- You may add your name as a Contributor to the notice described in
- Exhibit A. You must also duplicate this License in any documentation
- for the Source Code where You describe recipients' rights or ownership
- rights relating to Covered Code. You may choose to offer, and to
- charge a fee for, warranty, support, indemnity or liability
- obligations to one or more recipients of Covered Code. However, You
- may do so only on Your own behalf, and not on behalf of the Initial
- Developer or any Contributor. You must make it absolutely clear than
- any such warranty, support, indemnity or liability obligation is
- offered by You alone, and You hereby agree to indemnify the Initial
- Developer and every Contributor for any liability incurred by the
- Initial Developer or such Contributor as a result of warranty,
- support, indemnity or liability terms You offer.
-
- 3.6. Distribution of Executable Versions.
- You may distribute Covered Code in Executable form only if the
- requirements of Section 3.1-3.5 have been met for that Covered Code,
- and if You include a notice stating that the Source Code version of
- the Covered Code is available under the terms of this License,
- including a description of how and where You have fulfilled the
- obligations of Section 3.2. The notice must be conspicuously included
- in any notice in an Executable version, related documentation or
- collateral in which You describe recipients' rights relating to the
- Covered Code. You may distribute the Executable version of Covered
- Code or ownership rights under a license of Your choice, which may
- contain terms different from this License, provided that You are in
- compliance with the terms of this License and that the license for the
- Executable version does not attempt to limit or alter the recipient's
- rights in the Source Code version from the rights set forth in this
- License. If You distribute the Executable version under a different
- license You must make it absolutely clear that any terms which differ
- from this License are offered by You alone, not by the Initial
- Developer or any Contributor. You hereby agree to indemnify the
- Initial Developer and every Contributor for any liability incurred by
- the Initial Developer or such Contributor as a result of any such
- terms You offer.
-
- 3.7. Larger Works.
- You may create a Larger Work by combining Covered Code with other code
- not governed by the terms of this License and distribute the Larger
- Work as a single product. In such a case, You must make sure the
- requirements of this License are fulfilled for the Covered Code.
-
-4. Inability to Comply Due to Statute or Regulation.
-
- If it is impossible for You to comply with any of the terms of this
- License with respect to some or all of the Covered Code due to
- statute, judicial order, or regulation then You must: (a) comply with
- the terms of this License to the maximum extent possible; and (b)
- describe the limitations and the code they affect. Such description
- must be included in the LEGAL file described in Section 3.4 and must
- be included with all distributions of the Source Code. Except to the
- extent prohibited by statute or regulation, such description must be
- sufficiently detailed for a recipient of ordinary skill to be able to
- understand it.
-
-5. Application of this License.
-
- This License applies to code to which the Initial Developer has
- attached the notice in Exhibit A and to related Covered Code.
-
-6. Versions of the License.
-
- 6.1. New Versions.
- Netscape Communications Corporation ("Netscape") may publish revised
- and/or new versions of the License from time to time. Each version
- will be given a distinguishing version number.
-
- 6.2. Effect of New Versions.
- Once Covered Code has been published under a particular version of the
- License, You may always continue to use it under the terms of that
- version. You may also choose to use such Covered Code under the terms
- of any subsequent version of the License published by Netscape. No one
- other than Netscape has the right to modify the terms applicable to
- Covered Code created under this License.
-
- 6.3. Derivative Works.
- If You create or use a modified version of this License (which you may
- only do in order to apply it to code which is not already Covered Code
- governed by this License), You must (a) rename Your license so that
- the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
- "MPL", "NPL" or any confusingly similar phrase do not appear in your
- license (except to note that your license differs from this License)
- and (b) otherwise make it clear that Your version of the license
- contains terms which differ from the Mozilla Public License and
- Netscape Public License. (Filling in the name of the Initial
- Developer, Original Code or Contributor in the notice described in
- Exhibit A shall not of themselves be deemed to be modifications of
- this License.)
-
-7. DISCLAIMER OF WARRANTY.
-
- COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
- WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
- DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
- THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
- IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
- YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
- COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
- OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
- ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
-
-8. TERMINATION.
-
- 8.1. This License and the rights granted hereunder will terminate
- automatically if You fail to comply with terms herein and fail to cure
- such breach within 30 days of becoming aware of the breach. All
- sublicenses to the Covered Code which are properly granted shall
- survive any termination of this License. Provisions which, by their
- nature, must remain in effect beyond the termination of this License
- shall survive.
-
- 8.2. If You initiate litigation by asserting a patent infringement
- claim (excluding declatory judgment actions) against Initial Developer
- or a Contributor (the Initial Developer or Contributor against whom
- You file such action is referred to as "Participant") alleging that:
-
- (a) such Participant's Contributor Version directly or indirectly
- infringes any patent, then any and all rights granted by such
- Participant to You under Sections 2.1 and/or 2.2 of this License
- shall, upon 60 days notice from Participant terminate prospectively,
- unless if within 60 days after receipt of notice You either: (i)
- agree in writing to pay Participant a mutually agreeable reasonable
- royalty for Your past and future use of Modifications made by such
- Participant, or (ii) withdraw Your litigation claim with respect to
- the Contributor Version against such Participant. If within 60 days
- of notice, a reasonable royalty and payment arrangement are not
- mutually agreed upon in writing by the parties or the litigation claim
- is not withdrawn, the rights granted by Participant to You under
- Sections 2.1 and/or 2.2 automatically terminate at the expiration of
- the 60 day notice period specified above.
-
- (b) any software, hardware, or device, other than such Participant's
- Contributor Version, directly or indirectly infringes any patent, then
- any rights granted to You by such Participant under Sections 2.1(b)
- and 2.2(b) are revoked effective as of the date You first made, used,
- sold, distributed, or had made, Modifications made by that
- Participant.
-
- 8.3. If You assert a patent infringement claim against Participant
- alleging that such Participant's Contributor Version directly or
- indirectly infringes any patent where such claim is resolved (such as
- by license or settlement) prior to the initiation of patent
- infringement litigation, then the reasonable value of the licenses
- granted by such Participant under Sections 2.1 or 2.2 shall be taken
- into account in determining the amount or value of any payment or
- license.
-
- 8.4. In the event of termination under Sections 8.1 or 8.2 above,
- all end user license agreements (excluding distributors and resellers)
- which have been validly granted by You or any distributor hereunder
- prior to termination shall survive termination.
-
-9. LIMITATION OF LIABILITY.
-
- UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
- (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
- DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
- OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
- ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
- CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
- WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
- COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
- INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
- LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
- RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
- PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
- EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
- THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
-
-10. U.S. GOVERNMENT END USERS.
-
- The Covered Code is a "commercial item," as that term is defined in
- 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
- software" and "commercial computer software documentation," as such
- terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
- C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
- all U.S. Government End Users acquire Covered Code with only those
- rights set forth herein.
-
-11. MISCELLANEOUS.
-
- This License represents the complete agreement concerning subject
- matter hereof. If any provision of this License is held to be
- unenforceable, such provision shall be reformed only to the extent
- necessary to make it enforceable. This License shall be governed by
- California law provisions (except to the extent applicable law, if
- any, provides otherwise), excluding its conflict-of-law provisions.
- With respect to disputes in which at least one party is a citizen of,
- or an entity chartered or registered to do business in the United
- States of America, any litigation relating to this License shall be
- subject to the jurisdiction of the Federal Courts of the Northern
- District of California, with venue lying in Santa Clara County,
- California, with the losing party responsible for costs, including
- without limitation, court costs and reasonable attorneys' fees and
- expenses. The application of the United Nations Convention on
- Contracts for the International Sale of Goods is expressly excluded.
- Any law or regulation which provides that the language of a contract
- shall be construed against the drafter shall not apply to this
- License.
-
-12. RESPONSIBILITY FOR CLAIMS.
-
- As between Initial Developer and the Contributors, each party is
- responsible for claims and damages arising, directly or indirectly,
- out of its utilization of rights under this License and You agree to
- work with Initial Developer and Contributors to distribute such
- responsibility on an equitable basis. Nothing herein is intended or
- shall be deemed to constitute any admission of liability.
-
-13. MULTIPLE-LICENSED CODE.
-
- Initial Developer may designate portions of the Covered Code as
- "Multiple-Licensed". "Multiple-Licensed" means that the Initial
- Developer permits you to utilize portions of the Covered Code under
- Your choice of the NPL or the alternative licenses, if any, specified
- by the Initial Developer in the file described in Exhibit A.
-
-EXHIBIT A -Mozilla Public License.
-
- ``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 ______________________________________.
-
- The Initial Developer of the Original Code is ________________________.
- Portions created by ______________________ are Copyright (C) ______
- _______________________. All Rights Reserved.
-
- Contributor(s): ______________________________________.
-
- Alternatively, the contents of this file may be used under the terms
- of the _____ license (the "[___] License"), in which case the
- provisions of [______] License are applicable instead of those
- above. If you wish to allow use of your version of this file only
- under the terms of the [____] License and not to allow others to use
- your version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice and
- other provisions required by the [___] License. If you do not delete
- the provisions above, a recipient may use your version of this file
- under either the MPL or the [___] License."
-
- [NOTE: The text of this Exhibit A may differ slightly from the text of
- the notices in the Source Code files of the Original Code. You should
- use the text of this Exhibit A rather than the text found in the
- Original Code Source Code for Your Modifications.]
-
-
diff --git a/doc/README.Apple2.html b/doc/README.Apple2.html
deleted file mode 100644
index 690eb96..0000000
--- a/doc/README.Apple2.html
+++ /dev/null
@@ -1,70 +0,0 @@
-NETBOOT65 FOR THE APPLE ][
-
-TO USE
-
- unzip the archive somewhere on your local hard drive
- start the bin/tftp_server.rb script (e.g. by double-clicking on it)
- boot up the client/utherboot.dsk (either in AppleWin, or using ADTPro to transfer to a real Apple 2 disk)
-
-When Utherboot.dsk boots, it runs a program called "UTHERBOOT.PG2" that does the following
-
- checks for an uthernet in slot 3
- broadcasts a DHCP request to get an IP address allocated
- broadcasts a TFTP request for a directory listing for anything matching "*.PG2"
- displays a menu containing whatever files the TFTP server lists as available.
- Once a file is selected, it is downloaded via TFTP, and executed
-
-ADDING MORE FILES
-
-Only single-load files can be used (this may change in a future release). The files need to be in "PG2" format, which is essentially a DOS 3.3 Binary file.
-The first 2 bytes of the file must be the load address (little-endian, i.e. low/high), and then the next 2 bytes must be the file length (excluding the 4 byte
-header). The files also need to have a file extension of ".PG2" (in upper case, if your operating system of choice is case sensitive).
-
-If you use CiderPress (http://ciderpress.sourceforge.net/) to extract files from a DSK image, they will not be in the correct format, however there is
-a script that will convert such files (including, for example, the games supplied with the Apple 2 Game Server - http://a2gameserver.berlios.de/).
-If you run bin/import_ags_games.rb and specify the path to a folder containing files extracted with CiderPress, e.g. the Apple 2 Game Server "games"
-directory, a copy of all the games will be placed in the boot/ folder (converted to the appropriate format) - NB due to a limitation in the menu
-selection code, only the first 128 PG2 files in the boot/ folder can be selected.
-
-Alternatively, you can use dsktool.rb (http://dsktool.rubyforge.org/) to extract files - it will retain the appropriate file header during the extraction.
-For example, to extract the "DIG DUG" game from the online copy at http://mirrors.apple2.org.za/ftp.apple.asimov.net/images/games/action/digdug.dsk.gz, do
-the following:
-
-cd to the netboot65/boot folder
- execute 'dsktool http://mirrors.apple2.org.za/ftp.apple.asimov.net/images/games/action/digdug.dsk.gz -e "DIG DUG" -o DIGDUG.PG2'
-
-
-REQUIREMENTS
-
- Uthernet in slot 3 (to use under AppleWin, you will need winpcap installed)
- a DHCP server on your network
- a working ruby installation
-
-LIMITATIONS
-These may be fixed in a future release.
-
- Uthernet must be in slot 3
- Only single-load programs supported
- Only BRUNable files supported (i.e. not Applesoft or Integer BASIC)
- No more than 128 programs will be displayed in the menu
- no HGR font, starfield or plinkity plonkety "music"
-
-CREDITS
- IP65 - lightweight IP+UDP stack written in CA65 assembler, by Per Olofsson - http://www.paradroid.net/ip65
- TFTP extension to IP65 - Jonno Downes - jonno@jamtronix.com
-
-INSPIRATION
- Apple 2 Game Server
- AppleWin
- comp.sys.apple2 regulars
-
-LICENSE
- NETBOOT65 is licensed under the same terms as IP65, the Mozilla Public License Version 1.1.
-
-
-SOURCE CODE
- Browse online at http://netboot65.svn.sourceforge.net/viewvc/netboot65/ or else download the whole tree through SVN with the following instruction set:
- svn co https://netboot65.svn.sourceforge.net/svnroot/netboot65 netboot65
-
-AUTHOR
- Jonno Downes - jonno@jamtronix.com
diff --git a/doc/README.C64.html b/doc/README.C64.html
deleted file mode 100644
index d1d25d2..0000000
--- a/doc/README.C64.html
+++ /dev/null
@@ -1,172 +0,0 @@
-NETBOOT FOR THE C64
-
-There are 2 major 'flavours' of clients, the major difference being whether the cart supports UDP only (but allows access to BASIC), or UDP + TCP (but loses access to BASIC). The
-reason for this is the UDP only version of the client fits into an 8KB cartridge, whereas the TCP code pushes the cartridge size up to 16KB, and the upper half of a 16KB cartridge sits in the same
-memory location as BASIC.
-
-Within the major flavours, there are also variations in media - the majority of code is identical between the different media but there are different headers etc. The supported media are:
-
-
- A program that can be loaded from disk (filename will end with .prg)
- 'ordinary' cartridge images (that can be burned into an eeprom on e.g. a 64NIC+ card) (filename will end with .bin)
- 'Retro Replay' cartridge images - these are actually 'ordinary' cartridge images that have been converted into a form suitable for use in a Retro Replay using Doc Bacardi's
- CRT8040 tool (filename will end with _rr.bin)
-
-
-
-filename flavour cartidge size
-netboot.bin UDP only (+ BASIC) 8KB cart
-kipperkart.bin UDP/TCP (no BASIC) 16KB cart
-kippergo.bin basic telnet & gopher client 16KB cart
-kipperterm.bin enhanced telnet 16KB cart
-
-
-
-
-USING THE CARTRIDGES
-
-When one of the cartridge images start, it will attempt to configure the IP stack via DHCP. If the DHCP config fails (either by timing out, or the user press RUN/STOP)
-then the IP stack will fall back to using the IP configuration built into the cartridge. See the section "IP CONFIGURATION" for info on how to modify the
-cartridge defaults prior to burning an image.
-
-
-
NETBOOT - UDP only cart
-
-Once the IP stack is initialised, an attempt to boot from the network will take place. a TFTP server will be queried for a list of PRG files, and then a menu appears allowing the selection of a file to be downloaded and executed. Most 'single load' applications should work
-
-KIPPERKART - UDP/TCP cart
-
- F1 : TFTP BOOT. This will query a TFTP server for a list of PRG files, and allow the selection of a file to be downloaded and executed. This version of TFTP BOOT is restricted to running only
- pure machine language programs, since BASIC is not available when this cart is active. (NB - programs that are pure M/L except for a BASIC stub consisting of a single SYS call will be executed).
-
- F2 : DISK BOOT. This will display a catalogue of files in drive #8 and allow the selection of a file to be executed. This version of DISK BOOT is restricted to running only
- pure machine language programs, since BASIC is not available when this cart is active. (NB - programs that are pure M/L except for a BASIC stub consisting of a single SYS call will be executed).
-
-
- F3 : UPLOAD D64. You will prompted to specify a filename, then the disk in the default drive will be read and sent to the tftp server
- F4 : DOWNLOAD D64. A TFTP server is queried for a list of D64 files, which can be selected from a menu. Once a D64 file is selected, it will be downloaded and written to the default drive (usually #8).
- F5 : SID NETPLAY. A TFTP server is queried for a list of SID files, which can be selected from a menu. Once a SID file is selected, it will be played. Not all SIDs work yet.
- F6 : PING. You will be prompted for a hostname which will be pinged 3 times, and a response time (in milliseconds) is printed for each ping.
- F7 : CONFIG. This brings up a menu where the IP configuration can be modified. Changes made here will be persistent until the next reboot.
-
-
-AUTOEXEC
-Once the 16KB cartridge image has initialised the IP stack, it will look for a file called "autoexec.prg" on the default drive. If this file is found it will be loaded (using the load address specified by the first 2
-bytes of the file) and executed. NB - since BASIC is not available only 100% Machine Language programs can be executed, although if there is a BASIC stub consisting of a single line that does a SYS
-call, the target of the SYS call will be used as the address to start execution from.
-
-KIPPERGO cart
-
- F1 : TELNET. You will be prompted to enter a hostname, a port number, and a connection mode. Connection mode is either
-
- VT100 - keypresses are converted to ASCII before being sent out, and incoming data is converted to PETSCII before being displayed. Many common VT100 escape codes are interpreted, and keystrokes are sent a character at a time.
- PETSCII - no translation is done on data coming in or out. This mode is suitable for connecting to PETSCII BBSs
-
- Once a connection is made, it can be terminated by hitting RUN/STOP
- F3 : GOPHER. You will be prompted to enter the hostname (only - no port number can be specified) of a gopher server, and the gopher client will be launched connecting to the specified server.
- F5 : GOPHER.FLOODGAP.COM. This will launch the Gopher client, and connect to the gopher portal at gopher://gopher.floodgap.com/
- F7 : CONFIG. This brings up a menu where the IP configuration can be modified. Changes made here will be persistent until the next reboot.
-
-
-Gopher Client
-Once a gopher resource is loaded, the following keys are active:
-
-SPACE, F7 or down arrow : scroll down to next page
- F1 or up arror : scroll up to previous page
- F2 : show recently visited resource
- F3 or left arrow : go back to last visited resource
- F5 : prompt to enter a new server (nb server name only - not resource or port)
- RUN/STOP : quit
-
-If the page currently being displayed has links to further resources in it, each link will be displayed
-starting with a highlighted letter (e.g. the first link on a page will have an inverse "A" next to it,
-the 2nd link on a page will have an inverse "B" next to it etc). Press the letter assigned to the link
-to load up that resource.
-
-KIPPERTERM cart
-
- F1 : TELNET. You will be prompted to enter a hostname, a port number, and a connection mode. Connection mode is either
-
- VT100 - keypresses are converted to ASCII before being sent out, and incoming data is converted to PETSCII before being displayed. Many common VT100 escape codes are interpreted, and keystrokes are sent a character at a time.
- PETSCII - no translation is done on data coming in or out. This mode is suitable for connecting to PETSCII BBSs
-
-
-Once a connection is made, it can be terminated by hitting RUN/STOP
-File Transfer
-While connected, you can hit F1 to bring up a file transfer menu. This menu presents the following options:
-
- F1 : D/L File (XMODEM). Select this option after you have started the file download process on the remote server. You will be prompted for a filename for the file to be saved as after the download has completed.
- F3 : U/L File (XMODEM). Select this option after you have started the file upload process on the remote server. You will be given a menu of files on the local disk to transfer.
- F5 : Send ASCII char. You will be prompted to enter a number between 0 and 255, and the corresponding byte will be sent. This is useful for sending characters which can't be entered on a C64 keyboard.
- F7 : Return. Selecting this option will restore the screen return you to your connection
-
-
-
-
-
-
-IP CONFIGURATION
-There is a script in the "bin" folder called "set_ip_config.rb" that can be used to modify the MAC address and IP config details in the cart image before
-it is burned. For example, to set the MAC address and DNS servers, use this command:
-set_ip_config.rb nb65_std_cart.bin mac ab:cd:ef:12:34:56 dns 10.5.1.1
-run "set_ip_config.rb" with no parameters to see all the options for what can be configured.
-
-STARTING THE SERVER
-
- unzip the archive somewhere on your local hard drive
- start the bin/tftp_server.rb script (e.g. by double-clicking on it)
-
-
-ADDING MORE FILES
-
-Only single-load files can be used. The files need to be in "PRG" format, i.e.the first 2 bytes of the file must be
-the load address (little-endian, i.e. low/high). The files also need to have a file extension of ".PRG" (in upper case, if your operating system of choice
-is case sensitive).
-
-Files need to be placed in the 'boot/' folder.
-
-Due to a limitation in the menu selection code, only the first 128 PRG files in the boot/ folder can be selected.
-
-
ERROR CODES
-Most network functions will return an 8 bit error code if things go wrong.
-ERROR CODE DESCRIPTION
-$80 PORT IN USE
-$81 TIMEOUT ON RECEIVE
-$82 TRANSMIT FAILED
-$83 TRANSMISSION REJECTED BY PEER
-$84 INPUT TOO LARGE
-$85 DEVICE FAILURE
-$86 ABORTED BY USER
-$87 LISTENER NOT AVAILABLE
-$88 NO SUCH LISTENER
-$89 CONNECTION RESET BY PEER
-$8A CONNECTION CLOSED
-$8B TOO MANY ERRORS
-$90 FILE ACCESS FAILURE
-$A0 MALFORMED URL
-$A1 DNS LOOKUP FAILED
-$FE OPTION NOT SUPPORTED
-$FF FUNCTION NOT SUPPORTED
-
-REQUIREMENTS
-
- RR-NET or compatible adaptor (to use under VICE, you will need pcap or winpcap installed)
- (RECOMMENDED) a DHCP server on your network
- a working ruby installation
-
-LICENSE
-NETBOOT65 is licensed under the same terms as IP65, the Mozilla Public License Version 1.1.
-
-SOURCE CODE
- Browse online at http://netboot65.svn.sourceforge.net/viewvc/netboot65/ or else download the whole tree through SVN with the following instruction set:
- svn co https://netboot65.svn.sourceforge.net/svnroot/netboot65 netboot65
-
-CREDITS
-Package is maintained by Jonno Downes - jonno@jamtronix.com
-Contributors
-
-Jonno Downes - current maintainer of ip65, original developer of layers 4-7 (dhcp,dns,tcp,telnet, http, gopher)
-Glenn Holmer - icmp enhancements, bugfixes
-Per Olofsson - initial creator of ip65, original developer of layers 1-3 (eth,arp,ip,icmp,udp)
-Lars Stollenwerk - vt100 emulation
-
\ No newline at end of file
diff --git a/doc/apple_dos_33_memory_layout.txt b/doc/apple_dos_33_memory_layout.txt
deleted file mode 100644
index 3b87abf..0000000
--- a/doc/apple_dos_33_memory_layout.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-DOS 3.3 MEMORY LAYOUT
-
-$C000 --- TOP OF RAM
-
-$B600 --- RWTS
-
-$AAC9 --- FILE MANAGER
-
-$9D00 --- MAIN DOS ROUTINES
-
-$9600 -- DOS FILE BUFFERS (MAXFILES 3)
-
-
-BD00 - RWTS main entry
- - call with AY pointing at IOB
-
-Input/Output Control Block
-
-OFFSET DESCRIPTION
-$00 Table Type (must be 1)
-$01 Slot Number times 0x10
-$02 Drive Number ($01 or $02)
-$03 Volume Number ($00 matches any volume)
-$04 Track Number
-$05 Sector Number
-$06/$07 Address (lo/hi) of Device Characteristics Table
-$08/$09 Address (lo/hi) of 256 byte buffer for READ/WRITE
-$0A Not Used
-$0B byte count for partial sector
-$0c Command Code
- $00 = SEEK
- $01 = READ
- $02 = WRITE
- $04 = FORMAT
-$0d Return Code (if non zero, carry flag should be set)
- $00 = no error
- $08 = error during initialization
- $10 = write protect error
- $20 = volume mismatch error
- $40 = drive error
- $80 = read error (obsolete)
-$0e volume number of last access
-$0f slot number of last acces * 16
-$10 drive number of last access
-
-
\ No newline at end of file
diff --git a/doc/ca65-doc-style.css b/doc/ca65-doc-style.css
deleted file mode 100644
index 8442dfc..0000000
--- a/doc/ca65-doc-style.css
+++ /dev/null
@@ -1,55 +0,0 @@
-body { background-color: #cde; color: #333; }
-
-body, p, ol, ul, td, th {
- font-family: verdana, arial, helvetica, sans-serif;
- font-size: 9pt;
-/* line-height: 12pt;*/
-}
-
-pre {
- background-color: #eee;
- padding: 10px;
- font-size: 16px;
- white-space: pre-wrap; /* css-3 */
- white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
- word-wrap: break-word; /* Internet Explorer 5.5+ */
-}
-
-td,th {
- background-color: #eee;
- vertical-align: text-top;
-/* padding-left: 3px;
- padding-right: 3px;
-*/
-}
-
-tr.header {
- background-color: #aaf;
-}
-
-p.footer {
- font-size: 12px;
- line-height: 16px;
-}
-
-h2 {
- background-color: #bcd;
-}
-
-h3 {
- background-color: #bcd;
-}
-
-img {
- border: 0px;
-}
-
-
-a { color: #000; }
-a:visited { color: #666; }
-a:hover { color: #fff; background-color:#000; }
-
-
-
diff --git a/doc/ip65.html b/doc/ip65.html
deleted file mode 100644
index d86a279..0000000
--- a/doc/ip65.html
+++ /dev/null
@@ -1,232 +0,0 @@
-
-
-IP65 - a TCP/IP stack for 6502 computers
-
-
-
-
-
-
-
-IP65
-
-
-IP65 is a TCP/IP stack for 6502 based computers.
-
-
-
-Status
-
-
-
-
- Applications
- Telnet Client
- Gopher Client
- HTTP Client
- HTTP Server
- Ping
-
-
-
- Services
- TCP
- DHCP/DNS/TFTP
- Echo
-
-
-
- Transport
- UDP
- ICMP
-
-
-
- Network
- IP
-
-
-
- Addressing
- ARP
-
-
-
- Ethernet driver
- CS8900A (RR-NET/Uthernet)
- Wiznet W5100
-
-
-
-
-
- Host computer
- C64/C128
- Apple ][
- VIC-20
-
-
-
-
-
- Green : Working
- Yellow : Partial
- Red : Unimplemented
-
-
-
-
-
-Documentation
-
-
-
-Download
-
-Latest release (sourceforge.net)
-ip65-2009-01-22.zip (paradroid.net)
-
-
-
History
-
- 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
- 2009-07-12 Jonno Downes Initial TCP implementation (use -DTCP to include)
- 2009-03-21 Jonno Downes Added technical reference documentation
- 2009-03-15 Jonno Downes Added DHCP, DNS & TFTP
- 2009-01-22 Per Olofsson Added copymem fix from Jonno Downes. Added MPL license.
- 2008-09-27 Per Olofsson Added timeout fix for ineth_tx from David Schmidt.
- 2006-09-20 Per Olofsson Fixed checksum calculation for odd packet sizes.
- 2006-02-22 Per Olofsson Added fix for sending of packets larger than 256 bytes
- from Ewen Wannop and Glenn Jones.
-
-
-Sample UDP listener source
-
-
-gangedport = 60064
-
- jsr ip65_init
- lda #<gotpacket
- ldx #>gotpacket
- sta udp_callback
- stx udp_callback + 1
- lda #<gangedport
- ldx #>gangedport
- jsr udp_add_listener
-
-main:
- jsr ip65_process
- jmp main
-
-gotpacket:
- sei
- lda $01
- pha
- lda udp_inp
- sta $01
-
- lda udp_inp + 1
- ldx udp_inp + 2
- sta zp_data
- stx zp_data + 2
- ldy udp_inp + 3
-copy:
- lda udp_inp + 3,y
- sta (zp_data),y
- dey
- bne copy
-
- pla
- sta $01
- cli
- rts
-
-
-
-License
-
-This project is released under the Mozilla Public License Version 1.1.
-For details, please visit http://www.mozilla.org/MPL/ .
-
-
-
-Project Web Hosted by
-
-
-
-
diff --git a/doc/kipper_api_technical_reference.doc b/doc/kipper_api_technical_reference.doc
deleted file mode 100644
index e33c9f8..0000000
Binary files a/doc/kipper_api_technical_reference.doc and /dev/null differ
diff --git a/doc/netboot65.html b/doc/netboot65.html
deleted file mode 100644
index 7bfb067..0000000
--- a/doc/netboot65.html
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-NETBOOT65 - network booting for 6502 computers
-
-
-
-
-
-
-
-netboot65
-
-
-netboot65 is a project to support network booting Commodore 64 computers. It is based on the IP65 TCP/IP stack . Current components are:
-
-a server (written in ruby for maximum portability) that provides a TFTP server with some proprietary extensions to allow clients to request a directory listing.
- clients (currently a cartridge or a standalone prg file for C64) that initialises an IP stack, acquires an IP address via DHCP, queries the local LAN for a TFTP server,
-and then allows a program file to be downloaded via TFTP and executed. Currently only 'single load' programs are supported, but many old games and utility programs can be run in this way.
- the KIPPER API (currently for C64 only) that allows for IP aware applications to be developed without being tied to a specific MAC address, IP address or network device, as is the case with most existing
-IP libraries for 6502 computers.
-
-
-
-Status
-
-
-Documentation
-
-
-
-Download
-
-Latest release (sourceforge.net)
-
-
License
-
-This project is released under the Mozilla Public License Version 1.1.
-For details, please visit http://www.mozilla.org/MPL/ .
-
-Source Code
- Browse online at http://netboot65.svn.sourceforge.net/viewvc/netboot65/ or else download the whole tree through SVN with the following instruction set:
- svn co https://netboot65.svn.sourceforge.net/svnroot/netboot65 netboot65
-
-
-
-Project Web Hosted by
-
-
-
-
diff --git a/doc/protocol.txt b/doc/protocol.txt
deleted file mode 100644
index 2a803a1..0000000
--- a/doc/protocol.txt
+++ /dev/null
@@ -1,155 +0,0 @@
-TRIVIAL NETWORK DISK PROTOCOL
-
-* "CAPABILITIES REQUEST" is the only message type that should be broadcast. Everything else should be unicast
-
-All fields are in network byte order (hi/lo)
-
-FOR ALL MESSAGES
-Offset meaning
-
-
-$00..$03 signature 'TNDP' (ASCII, high byte clear)
-$04 1 byte version ID - current version = 1
-$05..$06 2 byte xid (echoed back in response)
-
-FOR ALL RQS
-
-$07 1 byte opcode
- $00 = CAPABILITIES REQUEST
- $01 = VOLUME CATALOG REQUEST
- $02 = READ T/S REQUEST
- $03 = WRITE T/S REQUEST
- $04 = INIT VOLUME REQUEST
-
-FOR CAPABILITIES REQUEST
-No further data
-
-FOR VOLUME CATALOG REQUEST
-$08.. requested client system architecture
- $00 = all architectures (regardless of architecture)
- $64 = C64
- $A2 = Apple 2
-
-$09.. requested file system
-
- $00 = Any
- $01 = RAW / other
- $02 = Apple DOS 3.3
- $03 = PRODOS 8
- $04 = Apple CPM
- $05 = CBM DOS
-
-$0A..$0B Catalogue Offset
-
-For READ/WRITE:
-
-$08..$09 2 byte track #
-$0A..$0B 2 byte sector #
-$0C..$0D 2 byte sector length (in bytes)
-$0E..$4B volume name (null padded 55 bytes)
-$4C null byte (i.e. filename can be 55 bytes long, MUST be at least 1 null at the 56th byte)
-FOR WRITE
-$4d.. sector data
-
-FOR INIT VOLUME
-$00..$3c volume name (up to 56 chars, null padded)
-$37 null byte
-$38 system architecture ID
-$39 file system ID
-$3A..$3B number of tracks
-$3C..$3D sector length (in bytes)
-$3E..$3F ??
-
-
-FOR ALL RESPONSES
-
-$07 1 byte opcode
- $80 = CAPABILITIES REQUEST RESPONSE
- $81 = VOLUME CATALOG REQUEST RESPONSE
- $82 = READ T/S REQUEST RESPONSE
- $83 = WRITE T/S REQUEST RESPONSE
- $FF = ERROR RESPONSE
-
-FOR CAPABILITIES RESPONSE
-$07 Maximum supported protocol version
-$08..$1b 19 byte application name
-$1c Null byte (so application name is null padded)
-$1d number of entries in supported architectures/file systems list (must be >=1, since list should
- always contain at least a "any architecture, any file system" entry, even if the count is 0).
-
-$1e.. list of supported architectures/file systems:
-supported architecture/file systems lists:
- $00 system architecture ID
- $01..$02 number of volumes available for this combination of architecture/file system
-
-list should be sorted by architecture ID (in descending order) and file system id (in descending order).
-Each architecture list should end with a file system Id of $00 (any) which is the count of all volumes available for
-this architecture.
-
-The list of supported architectures should end with an entry for architecture ID $00 (any) which should have a single
-file system ID $00 (any) which should have a count of all volumes available for all architectures on this server.
-
-FOR VOLUME CATALOG
-$08..$09 Total Catalogue Entries
-$0A..$0B Catalogue Offset (i.e. how many entries are there in the catalogue before the first entry in this response)
-$0C Number of Entries in this response (maximum of 10)
-
-$0D.. the volume catalog entries.
-for each entry
-
-$00..$3c volume name (up to 56 chars, null padded)
-$37 null byte
-$38 system architecture ID
-$39 file system ID
-$3A..$3B number of tracks
-$3C..$3D sector length (in bytes)
-$3E..$3F ??
-
-
-
-
-For READ/WRITE:
-
-$04..$05 2 byte track #
-$06..$07 2 byte sector #
-$06..$07 2 byte sector length (in bytes)
-$0A..$49 volume name (null padded 64 bytes)
-
-FOR READ
-$4A.. sector data
-
-FOR INIT VOLUME
-$00..$3c volume name (up to 56 chars, null padded)
-$37 null byte
-$38 system architecture ID
-$39 file system ID
-$3A..$3B number of tracks
-$3C..$3D sector length (in bytes)
-
-
-
-FOR ERROR
-
-$04..$05 Error Code
- $00 = OK
- $01 = BROADCAST NOT ALLOWED
- Capabilities Request (opcode=00) are the only message types that can be broadcast.
- $02 = UNKNOWN OPCODE
- The client sent a message with an opcode the server does not understand
- $03 = VERSION NOT SUPPORTED
- The client sent a message with an protocol version that the server does not support
- $04 = ARCHITECTURE NOT SUPPORTED
- $05 = FILE SYSTEM NOT SUPPORTED
- $06 = INVALID VOLUME NAME
- $07 = INVALID TRACK NUMBER
- $08 = INVALID SECTOR NUMBER
- $09 = INVALID SECTOR LENGTH
-
- $FF = INTERNAL SERVER ERROR
- The server suffered an internal error while processing the request
-
-$06..$0b bytes $04..$09 from original request
-$0c..$4c error message (null padded 63 bytes)
-$4d null byte
-
-
diff --git a/client/drivers/Makefile b/drivers/Makefile
similarity index 100%
rename from client/drivers/Makefile
rename to drivers/Makefile
diff --git a/client/drivers/a2_zero_page.s b/drivers/a2_zero_page.s
similarity index 97%
rename from client/drivers/a2_zero_page.s
rename to drivers/a2_zero_page.s
index 195f1e1..b7801a3 100644
--- a/client/drivers/a2_zero_page.s
+++ b/drivers/a2_zero_page.s
@@ -1,38 +1,38 @@
-;zero page definitions
-;On the Apple ][ with AppleSoft running there are not enough contiguous zero page locations
-;to allow LD65 to handle assignment
-;so we need to manually assign ZP pointers to known free locations
-
-.exportzp copy_src
-.exportzp copy_dest
-.exportzp dns_hostname
-.exportzp tftp_filename
-.exportzp buffer_ptr
-.exportzp eth_packet
-
-
-copy_src =$06 ;also $07
-copy_dest =$08 ;also $09
-dns_hostname =$18 ;also $19
-tftp_filename =$1D ;also $1E
-buffer_ptr =$EB ;also $EC
-eth_packet =$ED ;also $EE
-
-;-- LICENSE --
-; 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) 2013
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
+;zero page definitions
+;On the Apple ][ with AppleSoft running there are not enough contiguous zero page locations
+;to allow LD65 to handle assignment
+;so we need to manually assign ZP pointers to known free locations
+
+.exportzp copy_src
+.exportzp copy_dest
+.exportzp dns_hostname
+.exportzp tftp_filename
+.exportzp buffer_ptr
+.exportzp eth_packet
+
+
+copy_src =$06 ;also $07
+copy_dest =$08 ;also $09
+dns_hostname =$18 ;also $19
+tftp_filename =$1D ;also $1E
+buffer_ptr =$EB ;also $EC
+eth_packet =$ED ;also $EE
+
+;-- LICENSE --
+; 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) 2013
+; Jonno Downes. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/drivers/a2charconv.s b/drivers/a2charconv.s
similarity index 96%
rename from client/drivers/a2charconv.s
rename to drivers/a2charconv.s
index 6b20626..fc41c9c 100644
--- a/client/drivers/a2charconv.s
+++ b/drivers/a2charconv.s
@@ -1,38 +1,38 @@
-
-
-.export ascii_to_native
-.export native_to_ascii
-
-;given an A2 Screen Code char in A, return equivalent ASCII
-native_to_ascii:
-;just strip high bit
- and #$7f
- rts
-
-;given an ASCII char in A, return equivalent A2 Screen Code
-ascii_to_native:
-;set high bit
- ora #$80
- rts
-
-
-
-
-;-- LICENSE FOR a2charconv.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 --
+
+
+.export ascii_to_native
+.export native_to_ascii
+
+;given an A2 Screen Code char in A, return equivalent ASCII
+native_to_ascii:
+;just strip high bit
+ and #$7f
+ rts
+
+;given an ASCII char in A, return equivalent A2 Screen Code
+ascii_to_native:
+;set high bit
+ ora #$80
+ rts
+
+
+
+
+;-- LICENSE FOR a2charconv.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/drivers/a2input.s b/drivers/a2input.s
similarity index 95%
rename from client/drivers/a2input.s
rename to drivers/a2input.s
index f2ef11a..977e346 100644
--- a/client/drivers/a2input.s
+++ b/drivers/a2input.s
@@ -1,211 +1,211 @@
-.export get_key
-.export check_for_abort_key
-.export get_filtered_input
-.export filter_text
-.export filter_ip
-.export filter_dns
-.export filter_number
-.export get_key_ip65
-.export get_key_if_available
-
-.import ip65_process
-.import print_a
-.import print_hex
-
-.importzp copy_src
-
-.include "../inc/common.i"
-
-allowed_ptr=copy_src ;reuse zero page
-.code
-;use Apple 2 monitor ROM function to read from keyboard
-;inputs: none
-;outputs: A contains ASCII code of key pressed
-get_key:
- ;lda #$a0
- ;lda #$20
- ;ldy #$24 ;KEYIN assumes Y is loaded with column
- ;jmp $fd1b
- jmp $fd0c
-
-;inputs: none
-;outputs: A contains ASCII value of key just pressed (0 if no key pressed)
-get_key_if_available:
- bit $c000 ;Key down?
- bmi get_key
- lda #0
- rts
-
-
-
-
-;check whether the escape key is being pressed
-;inputs: none
-;outputs: sec if escape pressed, clear otherwise
-check_for_abort_key:
-lda $c000 ;current key pressed
-cmp #$9B
-bne :+
-bit $c010 ;clear the keyboard strobe
-sec
-rts
-:
-clc
-rts
-
-;process inbound ip packets while waiting for a keypress
-get_key_ip65:
- jsr ip65_process
- bit $c000 ;Key down?
- bpl get_key_ip65
- jmp get_key
-
-
-
-;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input
-;======================================================================
-;Input a string and store it in GOTINPUT, terminated with a null byte.
-;AX is a pointer to the allowed list of characters, null-terminated.
-;set AX to $0000 for no filter on input
-;max # of chars in y returns num of chars entered in y.
-;======================================================================
-
-
-; Main entry
-get_filtered_input:
- sty MAXCHARS
- stax temp_allowed
-
- ;Zero characters received.
- lda #$00
- sta INPUT_Y
-
-;Wait for a character.
-@input_get:
- jsr get_key_ip65
- ;convert to standard ASCII by turning off high bit
- and #$7f
- sta LASTCHAR
- cmp #$08 ;Delete
- beq @delete
-
- cmp #$0d ;Return
- beq @input_done
-
- ;End reached?
- lda INPUT_Y
- cmp MAXCHARS
- beq @input_get
-
- ;Check the allowed list of characters.
- ldax temp_allowed
- stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time!
- ldy #$00
- lda allowed_ptr+1 ;was the input filter point nul?
- beq @input_ok
-@check_allowed:
- lda (allowed_ptr),y ;Overwritten
- beq @input_get ;Reached end of list (0)
-
- cmp LASTCHAR
- beq @input_ok ;Match found
-
- ;Not end or match, keep checking
- iny
- jmp @check_allowed
-
-@input_ok:
- lda LASTCHAR ;Get the char back
- ldy INPUT_Y
- sta GOTINPUT,y ;Add it to string
-
- inc INPUT_Y ;Next character
- jsr print_a
- ;Not yet.
- jmp @input_get
-
-@input_done:
- ldy INPUT_Y
- beq @no_input
- lda #$00
- sta GOTINPUT,y ;Zero-terminate
- clc
- ldax #GOTINPUT
- rts
-@no_input:
- sec
- rts
-; Delete last character.
-@delete:
- ;First, check if we're at the beginning. If so, just exit.
- lda INPUT_Y
- bne @delete_ok
- jmp @input_get
-
- ;At least one character entered.
-@delete_ok:
- ;Move pointer back.
- dec INPUT_Y
-
- ;Store a zero over top of last character, just in case no other characters are entered.
- ldy INPUT_Y
- lda #$00
- sta GOTINPUT,y
-
- ;Print the backspace char
- lda #$88
- jsr print_a
-
- ;Print the a space
- lda #$a0
- jsr print_a
-
- ;Print the backspace char
- lda #$88
- jsr print_a
-
- ;Wait for next char
- jmp @input_get
-
-
-;=================================================
-;Some example filters
-;=================================================
-
-filter_text:
- .byte ",+!#$%&'()* "
-filter_dns:
-.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-filter_ip:
-.byte "."
-filter_number:
-.byte "1234567890",0
-
-;=================================================
-.bss
-temp_allowed: .res 2
-MAXCHARS: .res 1
-LASTCHAR: .res 1
-INPUT_Y: .res 1
-GOTINPUT: .res 40
-
-
-
-;-- LICENSE FOR a2input.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 --
+.export get_key
+.export check_for_abort_key
+.export get_filtered_input
+.export filter_text
+.export filter_ip
+.export filter_dns
+.export filter_number
+.export get_key_ip65
+.export get_key_if_available
+
+.import ip65_process
+.import print_a
+.import print_hex
+
+.importzp copy_src
+
+.include "../inc/common.i"
+
+allowed_ptr=copy_src ;reuse zero page
+.code
+;use Apple 2 monitor ROM function to read from keyboard
+;inputs: none
+;outputs: A contains ASCII code of key pressed
+get_key:
+ ;lda #$a0
+ ;lda #$20
+ ;ldy #$24 ;KEYIN assumes Y is loaded with column
+ ;jmp $fd1b
+ jmp $fd0c
+
+;inputs: none
+;outputs: A contains ASCII value of key just pressed (0 if no key pressed)
+get_key_if_available:
+ bit $c000 ;Key down?
+ bmi get_key
+ lda #0
+ rts
+
+
+
+
+;check whether the escape key is being pressed
+;inputs: none
+;outputs: sec if escape pressed, clear otherwise
+check_for_abort_key:
+lda $c000 ;current key pressed
+cmp #$9B
+bne :+
+bit $c010 ;clear the keyboard strobe
+sec
+rts
+:
+clc
+rts
+
+;process inbound ip packets while waiting for a keypress
+get_key_ip65:
+ jsr ip65_process
+ bit $c000 ;Key down?
+ bpl get_key_ip65
+ jmp get_key
+
+
+
+;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input
+;======================================================================
+;Input a string and store it in GOTINPUT, terminated with a null byte.
+;AX is a pointer to the allowed list of characters, null-terminated.
+;set AX to $0000 for no filter on input
+;max # of chars in y returns num of chars entered in y.
+;======================================================================
+
+
+; Main entry
+get_filtered_input:
+ sty MAXCHARS
+ stax temp_allowed
+
+ ;Zero characters received.
+ lda #$00
+ sta INPUT_Y
+
+;Wait for a character.
+@input_get:
+ jsr get_key_ip65
+ ;convert to standard ASCII by turning off high bit
+ and #$7f
+ sta LASTCHAR
+ cmp #$08 ;Delete
+ beq @delete
+
+ cmp #$0d ;Return
+ beq @input_done
+
+ ;End reached?
+ lda INPUT_Y
+ cmp MAXCHARS
+ beq @input_get
+
+ ;Check the allowed list of characters.
+ ldax temp_allowed
+ stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time!
+ ldy #$00
+ lda allowed_ptr+1 ;was the input filter point nul?
+ beq @input_ok
+@check_allowed:
+ lda (allowed_ptr),y ;Overwritten
+ beq @input_get ;Reached end of list (0)
+
+ cmp LASTCHAR
+ beq @input_ok ;Match found
+
+ ;Not end or match, keep checking
+ iny
+ jmp @check_allowed
+
+@input_ok:
+ lda LASTCHAR ;Get the char back
+ ldy INPUT_Y
+ sta GOTINPUT,y ;Add it to string
+
+ inc INPUT_Y ;Next character
+ jsr print_a
+ ;Not yet.
+ jmp @input_get
+
+@input_done:
+ ldy INPUT_Y
+ beq @no_input
+ lda #$00
+ sta GOTINPUT,y ;Zero-terminate
+ clc
+ ldax #GOTINPUT
+ rts
+@no_input:
+ sec
+ rts
+; Delete last character.
+@delete:
+ ;First, check if we're at the beginning. If so, just exit.
+ lda INPUT_Y
+ bne @delete_ok
+ jmp @input_get
+
+ ;At least one character entered.
+@delete_ok:
+ ;Move pointer back.
+ dec INPUT_Y
+
+ ;Store a zero over top of last character, just in case no other characters are entered.
+ ldy INPUT_Y
+ lda #$00
+ sta GOTINPUT,y
+
+ ;Print the backspace char
+ lda #$88
+ jsr print_a
+
+ ;Print the a space
+ lda #$a0
+ jsr print_a
+
+ ;Print the backspace char
+ lda #$88
+ jsr print_a
+
+ ;Wait for next char
+ jmp @input_get
+
+
+;=================================================
+;Some example filters
+;=================================================
+
+filter_text:
+ .byte ",+!#$%&'()* "
+filter_dns:
+.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+filter_ip:
+.byte "."
+filter_number:
+.byte "1234567890",0
+
+;=================================================
+.bss
+temp_allowed: .res 2
+MAXCHARS: .res 1
+LASTCHAR: .res 1
+INPUT_Y: .res 1
+GOTINPUT: .res 40
+
+
+
+;-- LICENSE FOR a2input.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/drivers/a2kernal.s b/drivers/a2kernal.s
similarity index 97%
rename from client/drivers/a2kernal.s
rename to drivers/a2kernal.s
index 0d39d77..a17c43c 100644
--- a/client/drivers/a2kernal.s
+++ b/drivers/a2kernal.s
@@ -1,25 +1,25 @@
-.export exit_to_basic
-
-.code
-exit_to_basic:
- jmp $3d0
-
-
-;-- LICENSE FOR a2kernal.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 --
+.export exit_to_basic
+
+.code
+exit_to_basic:
+ jmp $3d0
+
+
+;-- LICENSE FOR a2kernal.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/drivers/a2print.s b/drivers/a2print.s
similarity index 95%
rename from client/drivers/a2print.s
rename to drivers/a2print.s
index 1943891..a57e6ed 100644
--- a/client/drivers/a2print.s
+++ b/drivers/a2print.s
@@ -1,76 +1,76 @@
-
-.export print_a
-.export print_a_inverse
-.export print_cr
-.export cls
-.export beep
-.exportzp screen_current_row
-.exportzp screen_current_col
-
-.code
-
-screen_current_col=$24 ; CH - Horizontal cursor-position (0-39)
-screen_current_row=$25 ; CV - Vertical cursor-position (0-23)
-
-;
-;use Apple 2 monitor ROM function to display 1 char
-;inputs: A should be set to ASCII char to display
-;outputs: none
-print_a:
- ora #$80 ;turn ASCII into Apple 2 screen codes
- cmp #$8A ;is it a line feed?
- bne @not_line_feed
-; jmp print_cr
- pha
- lda #$0
- sta screen_current_col
- pla
-@not_line_feed:
-
- jmp $fded
-
-
-;use Apple 2 monitor ROM function to move to new line
-;inputs: none
-;outputs: none
-print_cr:
-
- jmp $fd8e
-
-
-;use Apple 2 monitor ROM function to move to clear the screen
-;inputs: none
-;outputs: none
-cls:
- jmp $fc58
-
-;use Apple 2 monitor ROM function to move to make a 'beep' noise
-;inputs: none
-;outputs: none
-beep:
- jmp $fbdd
-
-print_a_inverse:
- and #$7F ;turn off top bits
- jsr $fded
-
-
-
-;-- LICENSE FOR a2print.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 --
+
+.export print_a
+.export print_a_inverse
+.export print_cr
+.export cls
+.export beep
+.exportzp screen_current_row
+.exportzp screen_current_col
+
+.code
+
+screen_current_col=$24 ; CH - Horizontal cursor-position (0-39)
+screen_current_row=$25 ; CV - Vertical cursor-position (0-23)
+
+;
+;use Apple 2 monitor ROM function to display 1 char
+;inputs: A should be set to ASCII char to display
+;outputs: none
+print_a:
+ ora #$80 ;turn ASCII into Apple 2 screen codes
+ cmp #$8A ;is it a line feed?
+ bne @not_line_feed
+; jmp print_cr
+ pha
+ lda #$0
+ sta screen_current_col
+ pla
+@not_line_feed:
+
+ jmp $fded
+
+
+;use Apple 2 monitor ROM function to move to new line
+;inputs: none
+;outputs: none
+print_cr:
+
+ jmp $fd8e
+
+
+;use Apple 2 monitor ROM function to move to clear the screen
+;inputs: none
+;outputs: none
+cls:
+ jmp $fc58
+
+;use Apple 2 monitor ROM function to move to make a 'beep' noise
+;inputs: none
+;outputs: none
+beep:
+ jmp $fbdd
+
+print_a_inverse:
+ and #$7F ;turn off top bits
+ jsr $fded
+
+
+
+;-- LICENSE FOR a2print.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/drivers/a2timer.s b/drivers/a2timer.s
similarity index 96%
rename from client/drivers/a2timer.s
rename to drivers/a2timer.s
index 8c193d4..7a03511 100644
--- a/client/drivers/a2timer.s
+++ b/drivers/a2timer.s
@@ -1,66 +1,66 @@
-; timer routines
-;
-; unfortunately the standard Apple 2 has no CIA or VBI, so for the moment, we will
-; make each call to 'timer_read' delay for a little while
-; this kludge will make the polling loops work at least
-;
-; timer_read is meant to return a counter with millisecond resolution
-
- .include "../inc/common.i"
-
-
- .export timer_init
- .export timer_read
-
- .bss
- current_time_value: .res 2
-
- .code
-
-;reset timer to 0
-;inputs: none
-;outputs: none
-timer_init:
- ldax #0
- stax current_time_value
- rts
-
-;this SHOULD just read the current timer value
-;but since a standard apple 2 has no dedicated timing circuit,
-;each call to this function actually delays a while, then updates the current value
-; inputs: none
-; outputs: AX = current timer value (roughly equal to number of milliseconds since the last call to 'timer_init')
-timer_read:
- lda #111
- jsr $fca8 ;wait for about 33ms
- clc
- lda #33
- adc current_time_value
- sta current_time_value
- bcc :+
- inc current_time_value+1
-:
- ldax current_time_value
- rts
-
-
-
-
-;-- LICENSE FOR a2timer.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 --
+; timer routines
+;
+; unfortunately the standard Apple 2 has no CIA or VBI, so for the moment, we will
+; make each call to 'timer_read' delay for a little while
+; this kludge will make the polling loops work at least
+;
+; timer_read is meant to return a counter with millisecond resolution
+
+ .include "../inc/common.i"
+
+
+ .export timer_init
+ .export timer_read
+
+ .bss
+ current_time_value: .res 2
+
+ .code
+
+;reset timer to 0
+;inputs: none
+;outputs: none
+timer_init:
+ ldax #0
+ stax current_time_value
+ rts
+
+;this SHOULD just read the current timer value
+;but since a standard apple 2 has no dedicated timing circuit,
+;each call to this function actually delays a while, then updates the current value
+; inputs: none
+; outputs: AX = current timer value (roughly equal to number of milliseconds since the last call to 'timer_init')
+timer_read:
+ lda #111
+ jsr $fca8 ;wait for about 33ms
+ clc
+ lda #33
+ adc current_time_value
+ sta current_time_value
+ bcc :+
+ inc current_time_value+1
+:
+ ldax current_time_value
+ rts
+
+
+
+
+;-- LICENSE FOR a2timer.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/drivers/c64_vt100.s b/drivers/c64_vt100.s
similarity index 95%
rename from client/drivers/c64_vt100.s
rename to drivers/c64_vt100.s
index d8ee6c5..4c893b7 100644
--- a/client/drivers/c64_vt100.s
+++ b/drivers/c64_vt100.s
@@ -1,2124 +1,2124 @@
-; vt100 emulation for C64
-; vt100 emulation for C64
-; originally from CaTer - Copyright Lars Stollenwerk 2003
-; CaTer homepage is http://formica.nusseis.de/Cater/
-; converted for use with ip65 by Jonno Downes, 2009.
-; this version is for C64 only
-; CaTer originally licensed under GPL
-; Lars Stollenwerk has agreed to relicense the code in this file under MPL (Oct 2009)
-;
-; to use:
-; 1) call vt100_init_terminal
-; 2) for every 'inbound' data (received from remote host), call "vt100_process_inbound_char" - this will update the screen
-; 3) pass every keypress into vt100_transform_outbound_char. on return from this call,
-; Y = 0 means don't send anything as a result of this keypress
-; Y = 1 means A contains single character to send to remote host
-; Y = 2 means AX points at null terminated string to send to remote host (e.g. an ANSI escape sequence)
-
-
-
-.include "../inc/common.i"
-
-.export vt100_init_terminal
-.export vt100_process_inbound_char
-.export vt100_transform_outbound_char
-
-.import beep
-
-; --- colour values ---
-col_black = $00
-col_white = $01
-col_red = $02
-col_cyan = $03
-col_purple = $04
-col_green = $05
-col_blue = $06
-col_yellow = $07
-col_orange = $08
-col_brown = $09
-col_light_red = $0a
-col_gray_1 = $0b
-col_gray_2 = $0c
-col_light_green = $0d
-col_light_blue = $0e
-col_gray_3 = $0f
-
-; --- colours ---
-; vanilla f bold 1
-; underline e 3
-; blink 5 d
-; blink uline a 7
-charmode_vanilla = $0f
-charmode_bold = $01
-charmode_underline = $0e
-charmode_underline_bold = $03
-charmode_blink = $05
-charmode_blink_bold = $0d
-charmode_blink_underline = $0a
-charmode_blink_underline_bold = $07
-
-; text background
-text_background_colour = col_black
-
-
-.segment "APP_SCRATCH"
-escape_buffer: .res $100
-
-
-.zeropage
-
-; --- esc mode ---
-; $00 = normal
-; $0f = esc mode
-; $ff = esc [ mode
-; $f0 = ignore one char
-escape_mode: .res 1
-
-; --- Vector ---
-; four vectors in zeropage
-; for temporary use
-temp_ptr_z: .res 2
-temp_ptr_y: .res 2
-temp_ptr_x: .res 2
-temp_ptr_w: .res 2
-
-escape_buffer_length: .res 1 ; points to first free position
-escape_parameter: .res 1 ; numeric parameter in esc sequence
-scroll_region_start: .res 1
-scroll_region_end: .res 1
-
-
-; font_mode contains three bits
-; bit 0 = bold
-; bit 1 = underline
-; bit 2 = blink
-; bit 7 = direct ANSI ESC colour
-font_mode: .res 1
-
-direct_colour: .res 1
-
-; --- crsr save area ---
-; here is crsr info saved with
-; ESC 7 and restored from with
-; ESC 8
-
-saved_font_mode: .res 1
-saved_reverse_mode: .res 1
-saved_row: .res 1
-saved_column: .res 1
-
-print_ptr: .res 2 ;temp vector for printing to screen
-
-
-
-
-
-; -------------------------------------
-; memory map
-;
-; -------------------------------------
-
-; --- screen ---
-; $0400 - $07ff
-Screen = $0400
-
-; --- escape buffer ---
-; $0800 - $0bff
-
-; --- char ---
-; $2000 - $27ff
-font_table = $2000
-
-; -------------------------------------
-; constant declaration
-;
-; -------------------------------------
-
-esc = $1b
-brace = $5b
-
-.code
-
-;intialize VT100 emulation state
-;inputs: none
-;outputs: none
-vt100_init_terminal:
-
- jsr initialise_variables ; init memory variables
- jsr initialise_font; init font
- jsr initialise_screen ; init screen
- rts
-
-;process incoming character
-;inputs:
-; A is inbound character
-;outputs:
-; none, but screen and/or terminal state is updated.
-
-vt100_process_inbound_char:
- tay
- lda escape_mode ; handle esc mode
- beq :+ ; to far for branch to escape
- jmp handle_escape_char
-:
- lda ascii_to_petscii,y ; ASCII to PETSCII
- beq @done ; ignore non-printing chars
- cmp #$01 ; something special?
- beq handle_special_char
- jsr print_to_screen ; print to screen
-@done:
- rts
-
-
-
-do_cr:
- ldx $d6 ; get row
- ldy #$00 ; set col=0
- jsr cursor_plot ; set crsr
- rts
-
-do_line_feed:
- ldx $d6 ; crsr line
- cpx scroll_region_end ; end scroll region?
- bne down_one_line ; no -> go on
- jsr cursor_off
- jsr scroll_up_scrollregion ; yes -> scroll up
- jsr cursor_on
- rts
-
-handle_special_char:
- tya ; restore original char
- cmp #$0d ; CR?
- beq do_cr
-
- cmp #$08 ; BS?
- bne @not_bs
- ldy $d3 ; get col
- beq @bs_done ; stop at left margin
- dey ; dec column
- ldx $d6 ; get row
- jsr cursor_plot ; set crsr
-@bs_done:
- rts
-@not_bs:
- cmp #$1b ; esc?
- bne @not_escape
- lda #$0f ; set esc mode
- sta escape_mode
- rts
-@not_escape:
- cmp #$07 ; BEL?
- bne @not_bell
- jsr beep
- rts
-@not_bell:
- cmp #$0a ; LF?
- beq do_line_feed
-
-@not_lf:
- cmp #$09 ; TAB?
- bne @not_tab
- lda $d3 ; crsr col
- and #$f8 ; (col DIV 8) * 8
- clc ; col + 8
- adc #$08
- cmp #$28 ; col=40?
- bne @not_last_col ; no -> skip
- lda #$27 ; yes -> col=39
-@not_last_col:
- tay ; col to y
- ldx $d6 ; line to x
- jsr cursor_plot ; set crsr
- rts
-
-@not_tab:
- rts
-
-down_one_line:
- cpx #$18 ; end of screen?
- bne @not_end_of_screen ; no -> go on
- rts ; yes -> do nothing
-@not_end_of_screen:
- inx ; next line
- ldy $d3 ; get col
- jsr cursor_plot ; set crsr
- rts
-
-
-; esc mode
-; data in Y
-; escape_mode <> $00 in A
-handle_escape_char:
- tax ; save escape_mode
- and #$0f ; escape_mode = $0f?
- bne @not_discard_mode
-
-; --- discard mode --- escape_mode = $f0
-;discard char
- lda #$00 ; reset escape_mode
- sta escape_mode
- rts
-
-@not_discard_mode:
- txa ; restore escape_mode
- and #$f0 ; escape_mode = $ff?
- beq @short_escape_mode ; no -> short Emode
- jmp long_escape_mode ; yes -> long Emode
-
-; short esc mode
-; escape_mode = $0f
-; process first char
-@short_escape_mode:
- tya ; restore char
-; --- [ ---
- cmp #brace ; [ ?
- bne @not_brace
- lda #$ff ; set esc [ mode
- sta escape_mode
- rts
-; --- ( ---
-@not_brace:
- cmp #$28 ; ( ?
- bne :+
- jmp set_discard_mode
-; --- ) ---
-:
- cmp #$29 ; ) ?
- bne :+
- jmp set_discard_mode
-; --- # ---
-:
- cmp #$23 ; # ?
- bne :+
- jmp set_discard_mode
-; --- D --- index
-:
- cmp #$44 ; D ?
- bne :+
- jsr do_line_feed ; same as LF
- jmp done_escape
-; --- M --- reverse index
-:
- cmp #$4d ; M ?
- bne @not_M
- ldx $d6 ; get crsr row
- cpx scroll_region_start ; top of scroll reg?
- bne :+
- jsr cursor_off ; yes -> scroll down
- jsr scroll_down_scrollregion
- jsr cursor_on
- jmp done_escape
-:
- cpx #$00 ; top of screen?
- bne :+
- jmp done_escape ; yes -> do nothing
-:
- dex ; one line up
- ldy $d3 ; get crsr col
- jsr cursor_plot ; set crsr
- jmp done_escape
-
-@not_M:
-; --- E --- next line
- cmp #$45 ; E ?
- bne :+
- jsr do_cr
- jsr do_line_feed
- jmp done_escape
-:
-; --- 7 --- save crsr
- cmp #$37 ; 7?
- bne :+
- lda font_mode ; save font
- sta saved_font_mode
- lda $c7 ; save reverse mode
- sta saved_reverse_mode
- ldx $d6 ; save position
- ldy $d3
- stx saved_row
- sty saved_column
- jmp done_escape
-:
-; --- 8 --- restore crsr
- cmp #$38 ; 8?
- bne :+
- ldx saved_row ; restore pos
- ldy saved_column
- jsr cursor_plot
- lda saved_reverse_mode ; restore ..
- sta $c7 ; .. reverse mode
- ldx saved_font_mode ; restore font
- stx font_mode
- lda font_attribute_table,x
- sta $0286 ; set colour
- jmp done_escape
-
-; --- unknown ---
-:
-; --- reset ESC mode ---
-done_escape:
- lda #$00 ; reset escape_mode
- sta escape_mode
- rts
-
-; --- set Discard mode ---
-set_discard_mode:
- lda #$f0 ; set esc mode $f0
- sta escape_mode
- rts
-
-
-; -------------------------------------
-; [ esc mode
-;
-; escape_mode = $ff
-; -------------------------------------
-
-long_escape_mode:
- tya ; restore char
- ldy escape_buffer_length
- sta escape_buffer,y ; store char
- iny
- sty escape_buffer_length ; inc esc buffer
- jsr test_if_letter ; test letter
- bcs :+ ; process command
- rts
-
-; --- process esc command ---
-; A = last char
-; Y = escape_buffer_length
-; X counts processed command chars
-:
- ldx #$00 ; first char
-
-; --- A --- crsr up
- cmp #$41 ; A?
- bne @not_A
- jsr get_number_from_esc_seq ; get argument
- lda escape_parameter ; escape_parameter = 0...
- bne :+
- inc escape_parameter ; .. means 1
-:
- lda $d6 ; get crsr row
- sec
- sbc escape_parameter ; row = row - up
- cmp scroll_region_start ; stop at top of ..
- bpl :+ ; ..scroll region
- lda scroll_region_start
-:
- tax ; x is row
- ldy $d3 ; y is col
- jsr cursor_plot ; set crsr
- jmp @end_escape_seq
-
-; --- B --- crsr down
-@not_A:
- cmp #$42 ; B?
- bne @not_B
- jsr get_number_from_esc_seq ; get argument
- lda escape_parameter ; escape_parameter = 0...
- bne :+
- inc escape_parameter ; .. means 1
-:
- lda $d6 ; get crsr row
- clc
- adc escape_parameter ; row = row + down
- cmp scroll_region_end ; outside scrregion?
- bcs :+ ; yes -> branch
- tax ; x is row
- jmp @skip
-:
- ldx scroll_region_end ; x = row = scroll_region_end
-@skip:
- ldy $d3 ; y is col
- jsr cursor_plot ; set crsr
- jmp @end_escape_seq
-
-; --- C --- crsr right
-@not_B:
- cmp #$43 ; C?
- bne @not_C
- jsr get_number_from_esc_seq ; get argument
- lda escape_parameter ; escape_parameter = 0...
- bne :+
- inc escape_parameter ; .. means 1
-:
- lda $d3 ; get crsr col
- clc
- adc escape_parameter ; col = col + right
- cmp #$27 ; outside screen?
- bcs :+ ; yes -> branch
- tay
- jmp @skip2
-:
- ldy #$27 ; y=col=left margin
-@skip2:
- ldx $d6 ; x is row
- jsr cursor_plot ; set crsr
- jmp @end_escape_seq
-
-; --- D --- crsr left
-@not_C:
- cmp #$44 ; D?
- bne @not_D
- jsr get_number_from_esc_seq ; get argument
- lda escape_parameter ; escape_parameter = 0...
- bne :+
- inc escape_parameter ; .. means 1
-:
- lda $d3 ; get crsr col
- sec
- sbc escape_parameter ; col = col - left
- bpl :+ ; stop at left..
- lda #$00 ; ..margin
-:
- tay ; y is col
- ldx $d6 ; x is row
- jsr cursor_plot ; set crsr
- jmp @end_escape_seq
-
-; --- m --- font attributes
-@not_D:
- cmp #$6d ; m?
- bne @not_m
-@next_font_attribute:
- jsr get_number_from_esc_seq
- pha ; save nondigit char
- lda escape_parameter ; parameter to A
- ; -- 0 --
- bne :+ ; 0?
- sta font_mode ; set font = vanilla
- sta $c7 ; reverse off
- jmp @end_font_attribute ; jmp next par
- ; -- 1 -- bold
-:
- cmp #$01
- bne :+
- lda font_mode ; set bold
- ora #$01
- sta font_mode
- jmp @end_font_attribute ; next char
- ; -- 4 -- underline
-:
- cmp #$04
- bne :+
- lda font_mode ; set u_line
- ora #$02
- sta font_mode
- jmp @end_font_attribute ; next char
- ; -- 5 -- blink
-:
- cmp #$05
- bne :+
- lda font_mode ; set blink
- ora #$04
- sta font_mode
- jmp @end_font_attribute ; next char
- ; -- 7 -- reverse
-:
- cmp #$07
- bne :+
- lda #$01 ; set revers
- sta $c7
- jmp @end_font_attribute ; next char
-:
- ; -- 30 - 37 --
- cmp #38 ; >= 38?
- bcs @end_font_attribute
- cmp #30 ; < 30?
- bcc @end_font_attribute
- sbc #30 ; pointer for table
- sta direct_colour
- lda #$80 ; set direct colour
- sta font_mode
-
-@end_font_attribute: ; -- next char --
- pla ; get nondigit char
- cmp #$3b ; is semicolon?
- beq @next_font_attribute ; then next cahr
- ; -- set colour --
- lda font_mode ;
- bmi :+ ; bit 7->direct col
- tax ; font to colour
- lda font_attribute_table,x
- sta $0286 ; set colour
- jmp @end_escape_seq
-:
- ; -- set direct colour --
- ldx direct_colour ; colour maping
- lda direct_colour_table,x
- sta $0286 ; set colour
- jmp @end_escape_seq
-
-; --- K --- erase line
-@not_m:
- cmp #$4b ; K?
- bne @not_K
- jsr get_number_from_esc_seq ; get parameter
- lda escape_parameter ; in A
- ; -- 0 -- crsr to end of line
- bne :+
- jsr erase_to_end_of_line ; erase end line
- jmp @end_escape_seq
- ; -- 1 -- begin to crsr
-:
- cmp #$01
- bne :+
- jsr erase_line_to_cursor ; erase beg line
- jmp @end_escape_seq
- ; -- 2 -- whole line
-:
- cmp #$02
- bne :+ ; par undefined
- ldx $d6 ; line in X
- jsr erase_line_by_number ; erase line
- sta $ce ; del char ..
- ; ..under crsr
-:
- jmp @end_escape_seq
-
-; --- f --- same as H
-@not_K:
- cmp #$66
- bne @not_f
- jmp @set_cursor_position ; same as H
-
-; --- H --- cursor position
-@not_f:
- cmp #$48
- bne @not_H
-@set_cursor_position:
- cpy #$01 ; no par means home
- bne :+
- ; -- home --
- ldx #$00
- ldy #$00
- jsr cursor_plot ; set crsr
- jmp @end_escape_seq
- ; -- row, col --
-:
- jsr get_number_from_esc_seq
- cmp #$3b ; is ;?
- bne @end_set_cursor_position ; no -> error
- ; -- prepare row --
- ldy escape_parameter ; get row
- bne :+ ; 0 means 1
- iny
-:
- dey ; line 1 -> line 0
- cpy #$19 ; >= 25?..
- bcs @end_set_cursor_position ; ..error!
- sty temp_ptr_x ; save row
- ; -- prepare col
- jsr get_number_from_esc_seq
- ldy escape_parameter ; get col
- bne :+ ; 0 means 1
- iny
-:
- dey ; line 1 -> line 0
- cpy #$28 ; >= 40?..
- bcs @end_set_cursor_position ; ..error!
- ldx temp_ptr_x ; restore row to X
- jsr cursor_plot ; set crsr
-@end_set_cursor_position:
- jmp @end_escape_seq
-
-
-; --- J --- erase screen
-@not_H:
- cmp #$4a ;J?
- bne @not_J
- jsr get_number_from_esc_seq ; get parameter
- lda escape_parameter ; in A
- ; -- 0 -- crsr to end
- bne @not_cursor_to_end
- jsr erase_to_end_of_line ; del rest of line
- ldx $d6 ; get crsr line
-@erase_next_line:
- inx ; next line
- cpx #$19 ; line 25?
- bcs @end_escape_seq ; then end
- txa
- pha ; save X
- jsr erase_line_by_number ; erase line
- pla
- tax ; restore X
- jmp @erase_next_line ; next line
- ; -- 1 -- beg of screen to crsr
-@not_cursor_to_end:
- cmp #$01
- bne @not_start_to_cursor
- jsr erase_line_to_cursor ; del start of ln
- ldx $d6 ; get crsr line
-:
- dex ; previous line
- bmi @end_escape_seq ; neg line -> end
- txa
- pha ; save X
- jsr erase_line_by_number ; erase line
- pla
- tax ; restore X
- jmp :-
- ; -- 2 -- del screen
-@not_start_to_cursor:
- cmp #$02 ; unknown?
- bne @end_escape_seq ; then ingnore
- ldx #$18 ; start at ln 24
-:
- txa
- pha ; save X
- jsr erase_line_by_number ; erase line
- pla
- tax ; restore X
- dex ; previous line
- bpl :-
- jmp @end_escape_seq
-
-
-; --- r --- set scroll region
-@not_J:
- cmp #$72 ; r?
- bne @not_r
- ; -- prepare top --
- jsr get_number_from_esc_seq
- cmp #$3b ; is ;?
- bne @error_in_escape_seq ; no -> error
- ldy escape_parameter ; get top
- dey ; line 1 -> line 0
- cpy #$19 ; >=25?..
- bcs @error_in_escape_seq ; ..error!
- sty temp_ptr_x ; save top
- ; -- prepare bottom --
- jsr get_number_from_esc_seq
- ldy escape_parameter ; get bottom
- dey ; line 1 -> line 0
- cpy #$19 ; >=25?..
- bcs @error_in_escape_seq ; ..error!
- sty temp_ptr_y ; save bottom
- ; -- validate lines --
- lda temp_ptr_x ; restore top
- cmp temp_ptr_y ; >= bottom?..
- bcs @error_in_escape_seq ; ..error!
- sta scroll_region_start ; top -> SRStart
- sty scroll_region_end ; bottom -> SREnd
- ; -- home crsr
- ldx #$00
- ldy #$00
- jsr cursor_plot
-@error_in_escape_seq:
- jmp @end_escape_seq
-
-
-@not_r:
-; --- unknown ---
-@end_escape_seq:
- lda #$00
- sta escape_buffer_length ; reset esc buffer
- sta escape_mode ; reset esc mode
- rts
-
-
-
-; -------------------------------------
-; Test letter
-;
-; char in A
-; returns carry = 1 for A = letter
-; -------------------------------------
-test_if_letter:
- cmp #$41 ; smaller then A?
- bcs :+ ; no -> go on
- rts ; return no letter
-:
- cmp #$5b ; smaller then Z+1?
- bcs :+ ; no -> go on
- sec ; return letter
- rts
-:
- cmp #$61 ; smaller then a?
- bcs :+ ; no -> go on
- rts ; return no letter
-:
- cmp #$7b ; smaller then z+1?
- bcs :+ ; no -> go on
- sec ; return letter
- rts
-:
- clc ; return no letter
- rts
-
-
-
-; -------------------------------------
-; test digit
-;
-; char in A
-; returns carry = 1 for A = digit
-; -------------------------------------
-
-test_if_digit:
- cmp #$30 ; smaller then 0?
- bcs :+ ; no -> go on
- rts ; return no digit
-:
- cmp #$3a ; smaller then 9+1?
- bcs :+ ; no -> go on
- sec ; return digit
- rts
-:
- clc ; return no digit
- rts
-
-
-; -------------------------------------
-; get decimal number from esc sequence
-;
-; esc sequence in escape_buffer
-; first index to process in X
-; returns: number escape_parameter
-; first non digit char in A
-; -------------------------------------
-get_number_from_esc_seq:
- lda #$00 ; assume $00
- sta escape_parameter
-@next_digit:
- lda escape_buffer,x ; get next char
- inx
- jsr test_if_digit ; digit?
- bcc @done ; no -> return
- sbc #$30 ; ascii to #
- pha ; save digit
- ; old value * 10
- ; 10a = ( 4a + a ) * 2
- lda escape_parameter
- asl
- asl ; ( 4a
- clc
- adc escape_parameter ; + a )
- asl ; *2
- sta escape_parameter ; = 10a
- ; add new digit
- pla ; resore new digit
- clc
- adc escape_parameter
- sta escape_parameter
- jmp @next_digit ; next char
-@done:
- rts
-
-
-
-; *************************************
-; *
-; * outgoing data
-; *
-; *************************************
-; -------------------------------------
-; given a single char (read from keyboard)
-; work out what data should be sent to the remote host.
-; input:
-; A = keypress
-; output:
-; Y=0 - no data to be sent (i.e. ignore keypress)
-; Y=1 - A contains single byte to send
-; Y=2 - AX points to null terminated string to send
-; -------------------------------------
-
-;Y=0 nothing to send
-;Y=1 A = char to send
-;Y=2 AX=pointer to asciiz string to send
-
-vt100_transform_outbound_char:
- tay
- lda petscii_to_ascii,y ; PETSCII to ASCII
- bne :+
- ldy #0 ; ignore key
- rts
-:
- cmp #$ff
- beq output_string
- cmp #$fe
- beq command_key ; command key
- ;default - send (possibly transformed) single char
- ldy #1 ;means A contains single byte to send
-@done:
-rts
-
-
-
-; -------------------------------------
-; create an ansi control sequence
-; -------------------------------------
-
-
-output_string:
- tya ; restore original key
-
-; --- crsr U ---
- cmp #$91 ; test crsr U
- bne @not_U
- ldax #ansi_cursor_up
- ldy #2
- rts
-; --- crsr L ---
-@not_U:
- cmp #$9d ; test crsr L
- bne @not_L
- ldax #ansi_cursor_left
- ldy #2
- rts
-@not_L:
- cmp #$0d ;test CR
- bne @not_CR
- ldax #crlf
- ldy #2
- rts
-
-@not_CR:
- ldy #0 ;must be some kind of error
- rts
-
-
-; -------------------------------------
-; keypress was a command key
-; -------------------------------------
-
-command_key:
- tya ; restore character
-
-; --- crsr R ---
-; --- ^] ---
-; both events send $1d
- cmp #$1d
- bne @not_crsr_R
- lda #$04 ; test control Key
- bit $028d
- beq @cursor_right ; not pressed
- ; control ] is pressed
- tya ; send ^]
- ldy #1
- rts
-
-; crsr R
-@cursor_right:
- ldax #ansi_cursor_right
- ldy #2
- rts
-
-; --- crsr D ---
-; --- ^Q ---
-; both events send char $11
-@not_crsr_R:
- cmp #$11 ;^Q / crsr down
- bne @not_crsr_D
- lda #$04 ; test control Key
- bit $028d
- beq @cursor_down ; not pressed
- ; control Q is pressed
- tya ; send ^Q
- ldy #1
- rts
-
- ; crsr down is pressed
-@cursor_down:
- ldax #ansi_cursor_down
- ldy #2
- rts
-
-; --- HOME key ---
-; --- ^S ---
-; both events send char $13
-@not_crsr_D:
- cmp #$13 ;^S / HOME
- bne @not_home
- lda #$04 ; test control Key
- bit $028d
- beq @home ; not pressed
- ; control S is pressed
- tya ; send ^S
- ldy #1
- rts
-
-@home:
- lda #$09 ; send TAB
- ldy #1
- rts
-
-; --- DEL key ---
-; --- ^T ---
-; both events send char $14
-@not_home:
- cmp #$14 ;^T / DEL
- bne @not_del
- lda #$04 ; test control Key
- bit $028d
- beq @del ; not pressed
- ; control T is pressed
- tya ; send ^T
- ldy #1
- rts
-
- ; send DEL
-@del:
- lda #$08
- ldy #1
- rts
-
-
-; --- unknown C=-Key ---
-@not_del:
- ldy #0 ;means don't send anything
- rts
-
-; *************************************
-; *
-; * screen handling
-; *
-; *************************************
-
-; --- these variables become updated ---
-; on crsr movement.
-;
-; $d1 $d2 start of screen line
-; $d3 crsr column
-; $d6 crsr row
-; $f3 $f4 start of colour line
-; $0286 colour
-
-; --- these variables become updated ---
-; on crsr switching.
-;
-; $cc crsr flag, 0 = on
-; $cd crsr blink counter
-; $ce char under crsr
-; $cf crsr blink phase, 0 normal
-; $0287 colour under crsr
-
-
-
-; -------------------------------------
-; switch curser off and restore char.
-; this has to be done before every crsr
-; movement.
-; After movement there has to be a jump
-; to cursor_on.
-; -------------------------------------
-cursor_off:
- pha ; save registers
- tya
- pha
-
- ldy #$01 ; crsr of
- sty $cc
- lda $cf ; crsr revers?
- beq :+ ; no -> return
- dey ; set normal phase
- sty $cf
- ldy $d3 ; get column
- lda $ce ; restore char
- sta ($d1),y
- lda $0287 ; restore colour
- sta ($f3),y
-
-:
- pla ; restore registers
- tay
- pla
- rts
-
-; -------------------------------------
-; opposite of cursor_off
-; -------------------------------------
-
-cursor_on:
- pha
- tya
- pha
-
- ldy $d3 ; get column
- lda ($d1),y ; save chr
- sta $ce
- eor #$80 ; reverse char
- sta ($d1),y
- lda ($f3),y ; save colour
- sta $0287
- lda $0286 ; set crsr colour
- sta ($f3),y
- inc $cf ; set reverse phase
- lda #$14 ; set crsr counter..
- sta $cd ; ..to max
- lda #$00 ; cursor on
- sta $cc
-
- pla
- tay
- pla
- rts
-
-
-
-; -------------------------------------
-; moves the crsr to column Y
-; and line X
-; the crsr ist turned off during
-; operation
-; destroys all registers
-; -------------------------------------
-cursor_plot:
- jsr cursor_off
-
- stx $d6 ; set row
- sty $d3 ; set col
- jsr set_line_vectors
- ldx temp_ptr_x ; set screen line
- ldy temp_ptr_x+1
- stx $d1
- sty $d2
- ldx temp_ptr_y ; set color line
- ldy temp_ptr_y+1
- stx $f3
- sty $f4
-
- jsr cursor_on
- rts
-
-
-; -------------------------------------
-; Print char in A to screen
-; being aware of the crsr state
-; -------------------------------------
-
-print_to_screen:
- jsr cursor_off
- jsr plot_char
- jsr cursor_on
- rts
-
-; -------------------------------------
-; print char to screen
-; char = $ff means no output
-; chr in A
-; X and Y unaffected
-; -------------------------------------
-
-plot_char:
- sta temp_ptr_x ; save char
- txa ; save registers
- pha
- tya
- pha
- lda temp_ptr_x ; restore char
-
-; PETSCII to ScreenCode (SC)
-; --- $c0-$ff --- - illegal -
- cmp #$c0
- bcc :+
- jmp end_plot_char ; no output
-; --- $a0-$bf --- C=(latin-1) chars
-:
- cmp #$a0
- bcc :+
- sbc #$40 ; SC = PET - $40
- jmp @check_for_reverse
-; --- $80-$9f --- - illegal -
-:
- cmp #$80
- bcc :+
- jmp end_plot_char ; no output
-; --- $60-$7f --- kapital letters
-:
- cmp #$60
- bcc :+
- sbc #$20 ; SC = PET - $20
- jmp @check_for_reverse
-; --- $40-$5f --- small letters
-:
- cmp #$40
- bcc :+
- sbc #$40 ; SC = PET - $40
- jmp @check_for_reverse
-; --- $20-$3f --- interpunction
-:
- cmp #$20
- bcc :+
- jmp @check_for_reverse ; SC = PET
-; --- $00-$1f --- - illegal -
-:
- jmp end_plot_char ; no output
-
-; --- handle reverse mode---
-@check_for_reverse:
- ldx $c7 ; reverse mode?
- beq @put_char
- ora #$80 ; reverse char
-
-; --- put char to screen ---
-@put_char:
- ldy $d3 ; get crsr col
- cpy #$28 ;col = 40
- bcc @no_line_wrap
- ;the only way we end up trying to write to column 40 should
- ;be if we skipped the normal line wrap after writing to col 39
- ;because we are at the end of the scroll region
- ;that means we should do a scroll up and then write this char at col 0
- pha
- jsr scroll_up_scrollregion
- pla
- ldy #$00 ; begin of line
- sty $d3
-@no_line_wrap:
- sta ($d1),y ; char to screen
- lda $0286 ; get colour
- sta ($f3),y ; set colour
-
-; --- move on crsr ---
-
- ldx $d6 ; get crsr row
- cpx scroll_region_end ; end of scroll reg?
- beq @dont_scroll_yet ; we don't want to trigger a scroll of the whole screen unless
- ; we are actually writing a char. we shouldn't scroll just when
- ; writing to the bottom right hand screen (else e.g. the title bar
- ; in 'nano' gets pushed off the top of the screen.
- ;
- cpy #$27 ; col = 39?
- beq move_to_next_line ; yes -> new line
-@dont_scroll_yet:
- iny ; move on
- sty $d3
-
-end_plot_char:
- pla ; restore registers
- tay
- pla
- tax
- rts
-
-; -------------------------------------
-; subtask of plot_char
-; ends at end_plot_char
-; -------------------------------------
-move_to_next_line:
- ldx $d6 ; get crsr row
- cpx scroll_region_end ; end of scroll reg?
- beq @scroll_up ; yes -> branche
- cpx #$18 ; line 24?
- beq end_plot_char ; yes -> crsr stays
-; --- normal wrap ---
- inx ; increase line
- stx $d6
- ldy #$00 ; begin of line
- sty $d3
- jsr set_line_vectors
- ldx temp_ptr_x ; set screen line
- ldy temp_ptr_x+1
- stx $d1
- sty $d2
- ldx temp_ptr_y ; set colour line
- ldy temp_ptr_y+1
- stx $f3
- sty $f4
- jmp end_plot_char
-; --- scroll up ---
-@scroll_up:
- jsr scroll_up_scrollregion
- ldy #$00 ; begin of line
- sty $d3
- jmp end_plot_char
-
-
-
-scroll_up_scrollregion:
- ldx scroll_region_start ; get first line
-@scroll_one_line:
- ; -- new line: --
- ; -- temp_ptr_z and temp_ptr_w --
- jsr set_line_vectors
- lda temp_ptr_x ; screen line
- ldy temp_ptr_x+1
- sta temp_ptr_z
- sty temp_ptr_z+1
- lda temp_ptr_y ; colour line
- ldy temp_ptr_y+1
- sta temp_ptr_w
- sty temp_ptr_w+1
- ; -- old line: --
- ; -- temp_ptr_x and temp_ptr_y
- inx ; old line
- jsr set_line_vectors
- ; -- copy chars and colours --
- ldy #$27 ; col 39
-@scroll_one_char:
- lda (temp_ptr_x),y ; copy char
- sta (temp_ptr_z),y
- lda (temp_ptr_y),y ; copy colour
- sta (temp_ptr_w),y
- dey
- bpl @scroll_one_char
- cpx scroll_region_end ; last line?
- bne @scroll_one_line ; no -> go on
- jsr erase_line_by_vector ; del last line
-
- rts
-
-
-scroll_down_scrollregion:
- ldx scroll_region_end ; get last line
-@scroll_one_line:
- jsr set_line_vectors
- lda temp_ptr_x ; screen line
- ldy temp_ptr_x+1
- sta temp_ptr_z
- sty temp_ptr_z+1
- lda temp_ptr_y ; colour line
- ldy temp_ptr_y+1
- sta temp_ptr_w
- sty temp_ptr_w+1
- ; -- old line: --
- ; -- temp_ptr_x and temp_ptr_y
- dex ; old line
- jsr set_line_vectors
- ; -- copy chars ond colours --
- ldy #$27 ; col 39
-@scroll_one_char:
- lda (temp_ptr_x),y ; copy char
- sta (temp_ptr_z),y
- lda (temp_ptr_y),y ; copy colour
- sta (temp_ptr_w),y
- dey
- bpl @scroll_one_char
- cpx scroll_region_start ; first line?
- bne @scroll_one_line ; no -> go on
- jsr erase_line_by_vector ; del first line
-
- rts
-
-
-; -------------------------------------
-; print string to screen
-; string: chars, terminated by $00
-; start lo in x
-; start hi in y
-; affects A
-; takes care of crsr
-; the string must be smaller
-; than 255 chrs
-; -------------------------------------
-
-
-plot_string:
- stx print_ptr ; store start vector
- sty print_ptr+1
- jsr cursor_off
- ldy #$00
-@next_char:
- lda (print_ptr),y
- beq @end_string ; $00 terminates string
- jsr plot_char
- iny
- jmp @next_char
-
-@end_string:
- jsr cursor_on
- rts
-
-
-
-; -------------------------------------
-; delete screen line
-; (Erase Line)
-;
-; line number in X
-;
-; erase_line_by_vector needs line vectors in temp_ptr_x
-; and temp_ptr_y
-;
-; destroys all registers
-; returns $20 (space) in A
-; -------------------------------------
-
-erase_line_by_number:
- jsr set_line_vectors ; line start in temp_ptr_x
- ; col start in temp_ptr_y
-
-; erase chars
-erase_line_by_vector:
- ldy #$27 ; col 39
- lda #$20 ; load space
-:
- sta (temp_ptr_x),y ; clear char
- dey
- bpl :-
-
-; set colour
- ldy #$27 ; col 39
- lda #charmode_vanilla ; load vanilla
-:
- sta (temp_ptr_y),y ; clear char
- dey
- bpl :-
-
- rts
-
-
-
-; -------------------------------------
-; delete screen line from crsr to end
-; (Erase End of Line)
-; destroys all registers
-; -------------------------------------
-
-erase_to_end_of_line:
- jsr cursor_off
-; erase chars
- ldy $d3 ; get crsr col
- lda #$20 ; load space
-:
- sta ($d1),y ; clear char
- iny
- cpy #$28 ; pos 40?
- bne :- ; next char
- sta $ce ; del char ..
- ; ..under crsr
-; set colour
- ldy $d3 ; get crsr col
- lda #charmode_vanilla ; load vanilla
-:
- sta ($f3),y ; set colour
- iny
- cpy #$28 ; pos 40?
- bne :- ; next char
- jsr cursor_on
- rts
-
-; -------------------------------------
-; delete screen line up to crsr
-; (Erase Begin of Line)
-; destroys all registers
-; -------------------------------------
-erase_line_to_cursor:
-; erase chars
- ldy $d3 ; get crsr col
- lda #$20 ; load space
-:
- sta ($d1),y ; clear char
- dey
- bpl :- ; pos>=0 -> next
- sta $ce ; del char ..
- ; ..under crsr
-; set colour
- ldy $d3 ; get crsr col
- lda #charmode_vanilla ; load vanilla
-:
- sta ($f3),y ; clear char
- dey
- bpl :- ; pos>=0 -> next
- rts
-
-
-; -------------------------------------
-; set line vectors
-;
-; line no in X
-; destroys A and Y
-;
-; sets start of screen line in temp_ptr_x
-; sets start of colour line in temp_ptr_y
-; -------------------------------------
-
-set_line_vectors:
- lda $ecf0,x ; get lo byte
- sta temp_ptr_x
- sta temp_ptr_y
- ; determin hi byte
- ldy #$04 ; hi byte
- cpx #$07 ; line < 7?
- bcc @got_line_vector
- iny
- cpx #$0d ; line < 13?
- bcc @got_line_vector
- iny
- cpx #$14 ; line < 20?
- bcc @got_line_vector
- iny ; line 20-24
-@got_line_vector:
- sty temp_ptr_x+1
- tya
- clc ; colour RAM =
- adc #$d4 ; video RAM + d4
- sta temp_ptr_y+1
- rts
-
-
-
-; -------------------------------------
-; init routines
-;
-; -------------------------------------
-
-
-initialise_screen:
-
- ;--- set background ---
- lda #text_background_colour
- sta $d021
-; --- disable Shift C= ---
- lda #$80
- sta $0291
-; --- erase screen ---
- ldx #$18 ; start at ln 24
-@erase_one_line:
- txa
- pha ; save X
- jsr erase_line_by_number ; erase line
- pla
- tax ; restore X
- dex ; previous line
- bpl @erase_one_line
-
- lda #charmode_vanilla ; load vanilla
- sta $0286
-; --- crsr on ---
- jsr cursor_off
- jsr cursor_on
-; --- put crsr ---
- jsr do_cr
- jsr do_line_feed
- jsr do_line_feed
-
- rts
-
-
-
-initialise_variables:
- lda #$00
- sta escape_mode
- sta escape_buffer_length
- sta scroll_region_start
- sta font_mode
- sta saved_font_mode
- sta saved_reverse_mode
- sta saved_row
- sta saved_column
-
- lda #$18 ; last line
- sta scroll_region_end ; = 24
-
- rts
-
-
-reverse_font_table = font_table + $0400
-initialise_font:
- sei
- ldx #ROM_FONT
- stx temp_ptr_z
- sty temp_ptr_z+1
- ldx #font_table
- stx temp_ptr_y
- sty temp_ptr_y+1
- ldx #reverse_font_table
- stx temp_ptr_x
- sty temp_ptr_x+1
-
-; copy font
- ldx #$04 ; copy 4 pages = 1KB
- ldy #$00
-:
- lda (temp_ptr_z),y
- sta (temp_ptr_y),y
- eor #$ff ; reverse char
- sta (temp_ptr_x),y
- iny
- bne :-
- ; switch to next page
- inc temp_ptr_z+1
- inc temp_ptr_y+1
- inc temp_ptr_x+1
- dex
- bne :-
-
-; enable font
- lda $d018
- and #$f1
- ora #$09
- sta $d018
- cli
- rts
-
-
-.rodata
-font_attribute_table: ; bits mean blink, underline, bold
-.byte charmode_vanilla, charmode_bold ; 000 001
-.byte charmode_underline, charmode_underline_bold ; 010 011
-.byte charmode_blink, charmode_blink_bold ; 100 101
-.byte charmode_blink_underline, charmode_blink_underline_bold ; 110 111
-
-direct_colour_table:
-;ANSI 30 31 32 32 34 35 36 37
-; blk rd gr ye blu mg cy wh
-.byte 0, $0a, 5, 7, $0e, 4, 3, 1
-
-ansi_cursor_up: .byte esc, brace, $41, $00 ; esc [ A
-ansi_cursor_down: .byte esc, brace, $42, $00 ; esc [ B
-ansi_cursor_right: .byte esc, brace, $43, $00 ; esc [ C
-ansi_cursor_left: .byte esc, brace, $44, $00 ; esc [ D
-crlf: .byte $0d,$0a,0
-
-; -------------------------------------
-; table ASCII to PETSCII
-;
-; these characters cat be printed
-;
-; pet=$00 means ignore the char
-; pet=$01 means do something complicated
-; -------------------------------------
-ascii_to_petscii:
- .byte $00 ; $00
- .byte $00 ; $01
- .byte $00 ; $02
- .byte $00 ; $03
- .byte $00 ; $04
- .byte $00 ; $05
- .byte $00 ; $06
- .byte $01 ; $07 BEL
- .byte $01 ; $08 BS/DEL
- .byte $01 ; $09 TAB
- .byte $01 ; $0a LF
- .byte $00 ; $0b
- .byte $00 ; $0c
- .byte $01 ; $0d CR
- .byte $00 ; $0e
- .byte $00 ; $0f
- .byte $00 ; $10
- .byte $00 ; $11
- .byte $00 ; $12
- .byte $00 ; $13
- .byte $00 ; $14
- .byte $00 ; $15
- .byte $00 ; $16
- .byte $00 ; $17
- .byte $00 ; $18
- .byte $00 ; $19
- .byte $00 ; $1a
- .byte $01 ; $1b ESC
- .byte $00 ; $1c
- .byte $00 ; $1d
- .byte $00 ; $1e
- .byte $00 ; $1f
- .byte $20 ; $20 1:1
- .byte $21 ; $21 1:1
- .byte $22 ; $22 1:1
- .byte $23 ; $23 1:1
- .byte $24 ; $24 1:1
- .byte $25 ; $25 1:1
- .byte $26 ; $26 1:1
- .byte $27 ; $27 1:1
- .byte $28 ; $28 1:1
- .byte $29 ; $29 1:1
- .byte $2a ; $2a 1:1
- .byte $2b ; $2b 1:1
- .byte $2c ; $2c 1:1
- .byte $2d ; $2d 1:1
- .byte $2e ; $2e 1:1
- .byte $2f ; $2f 1:1
- .byte $30 ; $30 1:1
- .byte $31 ; $31 1:1
- .byte $32 ; $32 1:1
- .byte $33 ; $33 1:1
- .byte $34 ; $34 1:1
- .byte $35 ; $35 1:1
- .byte $36 ; $36 1:1
- .byte $37 ; $37 1:1
- .byte $38 ; $38 1:1
- .byte $39 ; $39 1:1
- .byte $3a ; $3a 1:1
- .byte $3b ; $3b 1:1
- .byte $3c ; $3c 1:1
- .byte $3d ; $3d 1:1
- .byte $3e ; $3e 1:1
- .byte $3f ; $3f 1:1
- .byte $40 ; $40 1:1
- .byte $61 ; $41 -----
- .byte $62 ; $42
- .byte $63 ; $43
- .byte $64 ; $44 capital
- .byte $65 ; $45
- .byte $66 ; $46
- .byte $67 ; $47
- .byte $68 ; $48
- .byte $69 ; $49
- .byte $6a ; $4a
- .byte $6b ; $4b
- .byte $6c ; $4c
- .byte $6d ; $4d letters
- .byte $6e ; $4e
- .byte $6f ; $4f
- .byte $70 ; $50
- .byte $71 ; $51
- .byte $72 ; $52
- .byte $73 ; $53
- .byte $74 ; $54
- .byte $75 ; $55
- .byte $76 ; $56
- .byte $77 ; $57
- .byte $78 ; $58
- .byte $79 ; $59
- .byte $7a ; $5a -----
- .byte $5b ; $5b 1:1
- .byte $5c ; $5c 1:1
- .byte $5d ; $5d 1:1
- .byte $5e ; $5e 1:1
- .byte $5f ; $5f 1:1
- .byte $60 ; $60 1:1
- .byte $41 ; $61 -----
- .byte $42 ; $62
- .byte $43 ; $63
- .byte $44 ; $64 small
- .byte $45 ; $65
- .byte $46 ; $66
- .byte $47 ; $67
- .byte $48 ; $68
- .byte $49 ; $69
- .byte $4a ; $6a
- .byte $4b ; $6b letters
- .byte $4c ; $6c
- .byte $4d ; $6d
- .byte $4e ; $6e
- .byte $4f ; $6f
- .byte $50 ; $70
- .byte $51 ; $71
- .byte $52 ; $72
- .byte $53 ; $73
- .byte $54 ; $74
- .byte $55 ; $75
- .byte $56 ; $76
- .byte $57 ; $77
- .byte $58 ; $78
- .byte $59 ; $79
- .byte $5a ; $7a -----
- .byte $7b ; $7b 1:1 {
- .byte $7c ; $7c 1:1 |
- .byte $7d ; $7d 1:1 }
- .byte $7e ; $7e 1:1 ~
- .byte $00 ; $7f
- .byte $00 ; $80
- .byte $00 ; $81
- .byte $00 ; $82
- .byte $00 ; $83
- .byte $00 ; $84
- .byte $00 ; $85
- .byte $00 ; $86
- .byte $00 ; $87
- .byte $00 ; $88
- .byte $00 ; $89
- .byte $00 ; $8a
- .byte $00 ; $8b
- .byte $00 ; $8c
- .byte $00 ; $8d
- .byte $00 ; $8e
- .byte $00 ; $8f
- .byte $00 ; $90
- .byte $00 ; $91
- .byte $00 ; $92
- .byte $00 ; $93
- .byte $00 ; $94
- .byte $00 ; $95
- .byte $00 ; $96
- .byte $00 ; $97
- .byte $00 ; $98
- .byte $00 ; $99
- .byte $00 ; $9a
- .byte $00 ; $9b
- .byte $00 ; $9c
- .byte $00 ; $9d
- .byte $00 ; $9e
- .byte $00 ; $9f
- .byte $20 ; $a0
- .byte $7f ; $a1
- .byte $7f ; $a2
- .byte $bf ; $a3
- .byte $be ; $a4
- .byte $7f ; $a5
- .byte $73 ; $a6
- .byte $b5 ; $a7
- .byte $53 ; $a8
- .byte $bb ; $a9
- .byte $7f ; $aa
- .byte $bc ; $ab
- .byte $7f ; $ac
- .byte $2d ; $ad
- .byte $7f ; $ae
- .byte $7f ; $af
- .byte $ba ; $b0
- .byte $b8 ; $b1
- .byte $b6 ; $b2
- .byte $b7 ; $b3
- .byte $7a ; $b4
- .byte $b9 ; $b5
- .byte $7f ; $b6
- .byte $7f ; $b7
- .byte $5a ; $b8
- .byte $7f ; $b9
- .byte $7f ; $ba
- .byte $bd ; $bb
- .byte $b0 ; $bc
- .byte $b0 ; $bd
- .byte $79 ; $be
- .byte $7f ; $bf
- .byte $a5 ; $c0
- .byte $61 ; $c1
- .byte $a4 ; $c2
- .byte $61 ; $c3
- .byte $a3 ; $c4
- .byte $a4 ; $c5
- .byte $7f ; $c6
- .byte $63 ; $c7
- .byte $ad ; $c8
- .byte $ab ; $c9
- .byte $ac ; $ca
- .byte $65 ; $cb
- .byte $69 ; $cc
- .byte $69 ; $cd
- .byte $69 ; $ce
- .byte $69 ; $cf
- .byte $64 ; $d0
- .byte $6e ; $d1
- .byte $6f ; $d2
- .byte $6f ; $d3
- .byte $b1 ; $d4
- .byte $6f ; $d5
- .byte $af ; $d6
- .byte $7f ; $d7
- .byte $6f ; $d8
- .byte $75 ; $d9
- .byte $75 ; $da
- .byte $75 ; $db
- .byte $b3 ; $dc
- .byte $79 ; $dd
- .byte $7f ; $de
- .byte $b4 ; $df
- .byte $a2 ; $e0
- .byte $41 ; $e1
- .byte $a1 ; $e2
- .byte $41 ; $e3
- .byte $a0 ; $e4
- .byte $a1 ; $e5
- .byte $7f ; $e6
- .byte $a6 ; $e7
- .byte $aa ; $e8
- .byte $a8 ; $e9
- .byte $a9 ; $ea
- .byte $a7 ; $eb
- .byte $49 ; $ec
- .byte $49 ; $ed
- .byte $49 ; $ee
- .byte $49 ; $ef
- .byte $7f ; $f0
- .byte $4e ; $f1
- .byte $4f ; $f2
- .byte $4f ; $f3
- .byte $b1 ; $f4
- .byte $4f ; $f5
- .byte $ae ; $f6
- .byte $7f ; $f7
- .byte $4f ; $f8
- .byte $55 ; $f9
- .byte $55 ; $fa
- .byte $55 ; $fb
- .byte $b2 ; $fc
- .byte $59 ; $fd
- .byte $7f ; $fe
- .byte $59 ; $ff
-
-; -------------------------------------
-; table PETSCII to ASCII
-;
-; these characters can be typed with
-; the keyboard
-;
-; ascii = $00 means ignore key
-; ascii = $ff menas send string
-; ascii = $fe means do something
-; complicated (command key)
-; -------------------------------------
-petscii_to_ascii:
- .byte $00 ; $00
- .byte $01 ; $01
- .byte $02 ; $02
- .byte $03 ; $03
- .byte $04 ; $04
- .byte $05 ; $05
- .byte $06 ; $06
- .byte $07 ; $07
- .byte $08 ; $08 DEL
- .byte $09 ; $09 TAB
- .byte $0a ; $0a
- .byte $0b ; $0b
- .byte $0c ; $0c
- .byte $ff ; $0d CR
- .byte $0e ; $0e
- .byte $0f ; $0f
- .byte $10 ; $10
- .byte $fe ; $11 ^Q (crsr down)
- .byte $12 ; $12
- .byte $fe ; $13 ^S TAB (HOME)
- .byte $fe ; $14 ^T BS (DEL)
- .byte $15 ; $15
- .byte $16 ; $16
- .byte $17 ; $17
- .byte $18 ; $18
- .byte $19 ; $19
- .byte $1a ; $1a
- .byte $1b ; $1b ESC
- .byte $1c ; $1c
- .byte $fe ; $1d ^](crsr right)
- .byte $1e ; $1e
- .byte $1f ; $1f
- .byte $20 ; $20 SPACE
- .byte $21 ; $21 !
- .byte $22 ; $22 "
- .byte $23 ; $23 #
- .byte $24 ; $24 $
- .byte $25 ; $25 %
- .byte $26 ; $26 &
- .byte $27 ; $27 '
- .byte $28 ; $28 (
- .byte $29 ; $29 )
- .byte $2a ; $2a *
- .byte $2b ; $2b +
- .byte $2c ; $2c ,
- .byte $2d ; $2d -
- .byte $2e ; $2e .
- .byte $2f ; $2f /
- .byte $30 ; $30 0
- .byte $31 ; $31 1
- .byte $32 ; $32 2
- .byte $33 ; $33 3
- .byte $34 ; $34 4
- .byte $35 ; $35 5
- .byte $36 ; $36 6
- .byte $37 ; $37 7
- .byte $38 ; $38 8
- .byte $39 ; $39 9
- .byte $3a ; $3a :
- .byte $3b ; $3b ;
- .byte $3c ; $3c <
- .byte $3d ; $3d =
- .byte $3e ; $3e >
- .byte $3f ; $3f ?
- .byte $40 ; $40 @
- .byte $61 ; $41 a
- .byte $62 ; $42 b
- .byte $63 ; $43 c
- .byte $64 ; $44 d
- .byte $65 ; $45 e
- .byte $66 ; $46 f
- .byte $67 ; $47 g
- .byte $68 ; $48 h
- .byte $69 ; $49 i
- .byte $6a ; $4a j
- .byte $6b ; $4b k
- .byte $6c ; $4c l
- .byte $6d ; $4d m
- .byte $6e ; $4e n
- .byte $6f ; $4f o
- .byte $70 ; $50 p
- .byte $71 ; $51 q
- .byte $72 ; $52 r
- .byte $73 ; $53 s
- .byte $74 ; $54 t
- .byte $75 ; $55 u
- .byte $76 ; $56 v
- .byte $77 ; $57 w
- .byte $78 ; $58 x
- .byte $79 ; $59 y
- .byte $7a ; $5a z
- .byte $5b ; $5b [
- .byte $5c ; $5c \ (Pound)
- .byte $5d ; $5d ]
- .byte $5e ; $5e ^
- .byte $1b ; $5f ESC ( <- )
- .byte $00 ; $60
- .byte $41 ; $61 A
- .byte $42 ; $62 B
- .byte $43 ; $63 C
- .byte $44 ; $64 D
- .byte $45 ; $65 E
- .byte $46 ; $66 F
- .byte $47 ; $67 G
- .byte $48 ; $68 H
- .byte $49 ; $69 I
- .byte $4a ; $6a J
- .byte $4b ; $6b K
- .byte $4c ; $6c L
- .byte $4d ; $6d M
- .byte $4e ; $6e N
- .byte $4f ; $6f O
- .byte $50 ; $70 P
- .byte $51 ; $71 Q
- .byte $52 ; $72 R
- .byte $53 ; $73 S
- .byte $54 ; $74 T
- .byte $55 ; $75 U
- .byte $56 ; $76 V
- .byte $57 ; $77 W
- .byte $58 ; $78 X
- .byte $59 ; $79 Y
- .byte $5a ; $7a Z
- .byte $00 ; $7b
- .byte $00 ; $7c
- .byte $00 ; $7d
- .byte $00 ; $7e
- .byte $00 ; $7f
- .byte $00 ; $80
- .byte $00 ; $81
- .byte $00 ; $82
- .byte $00 ; $83
- .byte $00 ; $84
- .byte $00 ; $85 (f1)
- .byte $00 ; $86 (f3)
- .byte $00 ; $87 (f5)
- .byte $00 ; $88 (f7)
- .byte $00 ; $89 (f2)
- .byte $00 ; $8a (f4)
- .byte $00 ; $8b (f6)
- .byte $00 ; $8c (f8)
- .byte $00 ; $8d (Shift RET)
- .byte $00 ; $8e
- .byte $00 ; $8f
- .byte $00 ; $90
- .byte $ff ; $91 (crsr up)
- .byte $00 ; $92
- .byte $00 ; $93 (Shift Clr/Home)
- .byte $7f ; $94 DEL (Shift Ins/Del)
- .byte $00 ; $95
- .byte $00 ; $96
- .byte $00 ; $97
- .byte $00 ; $98
- .byte $00 ; $99
- .byte $00 ; $9a
- .byte $00 ; $9b
- .byte $00 ; $9c
- .byte $ff ; $9d (crsr left)
- .byte $00 ; $9e
- .byte $00 ; $9f
- .byte $00 ; $a0 (Shift Space)
- .byte $00 ; $a1
- .byte $00 ; $a2
- .byte $00 ; $a3
- .byte $00 ; $a4
- .byte $00 ; $a5
- .byte $00 ; $a6
- .byte $00 ; $a7
- .byte $00 ; $a8
- .byte $7c ; $a9 | (Shift Pound)
- .byte $00 ; $aa
- .byte $00 ; $ab
- .byte $fe ; $ac C= D
- .byte $00 ; $ad
- .byte $fe ; $ae C= S
- .byte $00 ; $af
- .byte $fe ; $b0 C= A
- .byte $00 ; $b1
- .byte $fe ; $b2 C= R
- .byte $00 ; $b3
- .byte $00 ; $b4
- .byte $00 ; $b5
- .byte $fe ; $b6 C= L
- .byte $00 ; $b7
- .byte $00 ; $b8
- .byte $00 ; $b9
- .byte $60 ; $ba ` ( Shift @ )
- .byte $00 ; $bb
- .byte $fe ; $bc C= C
- .byte $00 ; $bd
- .byte $00 ; $be
- .byte $fe ; $bf C= B
- .byte $5f ; $c0 _ ( Shift * )
- .byte $41 ; $c1 -----
- .byte $42 ; $c2
- .byte $43 ; $c3 capital
- .byte $44 ; $c4
- .byte $45 ; $c5 letters
- .byte $46 ; $c6
- .byte $47 ; $c7 generate
- .byte $48 ; $c8
- .byte $49 ; $c9 these
- .byte $4a ; $ca
- .byte $4b ; $cb codes
- .byte $4c ; $cc
- .byte $4d ; $cd
- .byte $4e ; $ce
- .byte $4f ; $cf
- .byte $50 ; $d0
- .byte $51 ; $d1
- .byte $52 ; $d2
- .byte $53 ; $d3
- .byte $54 ; $d4
- .byte $55 ; $d5
- .byte $56 ; $d6
- .byte $57 ; $d7
- .byte $58 ; $d8
- .byte $59 ; $d9
- .byte $5a ; $da -----
- .byte $7b ; $db { ( Shift + )
- .byte $00 ; $dc ( C= - )
- .byte $7d ; $dd } ( Shift - )
- .byte $7e ; $de ~ ( Pi )
- .byte $00 ; $df
- .byte $00 ; $e0
- .byte $00 ; $e1
- .byte $00 ; $e2
- .byte $00 ; $e3
- .byte $00 ; $e4
- .byte $00 ; $e5
- .byte $00 ; $e6
- .byte $00 ; $e7
- .byte $00 ; $e8
- .byte $00 ; $e9
- .byte $00 ; $ea
- .byte $00 ; $eb
- .byte $00 ; $ec
- .byte $00 ; $ed
- .byte $00 ; $ee
- .byte $00 ; $ef
- .byte $00 ; $f0
- .byte $00 ; $f1
- .byte $00 ; $f2
- .byte $00 ; $f3
- .byte $00 ; $f4
- .byte $00 ; $f5
- .byte $00 ; $f6
- .byte $00 ; $f7
- .byte $00 ; $f8
- .byte $00 ; $f9
- .byte $00 ; $fa
- .byte $00 ; $fb
- .byte $00 ; $fc
- .byte $00 ; $fd
- .byte $00 ; $fe
- .byte $00 ; $ff
-
-ROM_FONT:
-.incbin "../inc/vt100_font.bin"
-
-;-- LICENSE FOR c64_vt100.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 Initial Developer of the Original Code is Lars Stollenwerk.
-;
-; Portions created by the Initial Developer are Copyright (C) 2003
-; Lars Stollenwerk. All Rights Reserved.
-;
-;Contributor(s): Jonno Downes
-; -- LICENSE END --
+; vt100 emulation for C64
+; vt100 emulation for C64
+; originally from CaTer - Copyright Lars Stollenwerk 2003
+; CaTer homepage is http://formica.nusseis.de/Cater/
+; converted for use with ip65 by Jonno Downes, 2009.
+; this version is for C64 only
+; CaTer originally licensed under GPL
+; Lars Stollenwerk has agreed to relicense the code in this file under MPL (Oct 2009)
+;
+; to use:
+; 1) call vt100_init_terminal
+; 2) for every 'inbound' data (received from remote host), call "vt100_process_inbound_char" - this will update the screen
+; 3) pass every keypress into vt100_transform_outbound_char. on return from this call,
+; Y = 0 means don't send anything as a result of this keypress
+; Y = 1 means A contains single character to send to remote host
+; Y = 2 means AX points at null terminated string to send to remote host (e.g. an ANSI escape sequence)
+
+
+
+.include "../inc/common.i"
+
+.export vt100_init_terminal
+.export vt100_process_inbound_char
+.export vt100_transform_outbound_char
+
+.import beep
+
+; --- colour values ---
+col_black = $00
+col_white = $01
+col_red = $02
+col_cyan = $03
+col_purple = $04
+col_green = $05
+col_blue = $06
+col_yellow = $07
+col_orange = $08
+col_brown = $09
+col_light_red = $0a
+col_gray_1 = $0b
+col_gray_2 = $0c
+col_light_green = $0d
+col_light_blue = $0e
+col_gray_3 = $0f
+
+; --- colours ---
+; vanilla f bold 1
+; underline e 3
+; blink 5 d
+; blink uline a 7
+charmode_vanilla = $0f
+charmode_bold = $01
+charmode_underline = $0e
+charmode_underline_bold = $03
+charmode_blink = $05
+charmode_blink_bold = $0d
+charmode_blink_underline = $0a
+charmode_blink_underline_bold = $07
+
+; text background
+text_background_colour = col_black
+
+
+.segment "APP_SCRATCH"
+escape_buffer: .res $100
+
+
+.zeropage
+
+; --- esc mode ---
+; $00 = normal
+; $0f = esc mode
+; $ff = esc [ mode
+; $f0 = ignore one char
+escape_mode: .res 1
+
+; --- Vector ---
+; four vectors in zeropage
+; for temporary use
+temp_ptr_z: .res 2
+temp_ptr_y: .res 2
+temp_ptr_x: .res 2
+temp_ptr_w: .res 2
+
+escape_buffer_length: .res 1 ; points to first free position
+escape_parameter: .res 1 ; numeric parameter in esc sequence
+scroll_region_start: .res 1
+scroll_region_end: .res 1
+
+
+; font_mode contains three bits
+; bit 0 = bold
+; bit 1 = underline
+; bit 2 = blink
+; bit 7 = direct ANSI ESC colour
+font_mode: .res 1
+
+direct_colour: .res 1
+
+; --- crsr save area ---
+; here is crsr info saved with
+; ESC 7 and restored from with
+; ESC 8
+
+saved_font_mode: .res 1
+saved_reverse_mode: .res 1
+saved_row: .res 1
+saved_column: .res 1
+
+print_ptr: .res 2 ;temp vector for printing to screen
+
+
+
+
+
+; -------------------------------------
+; memory map
+;
+; -------------------------------------
+
+; --- screen ---
+; $0400 - $07ff
+Screen = $0400
+
+; --- escape buffer ---
+; $0800 - $0bff
+
+; --- char ---
+; $2000 - $27ff
+font_table = $2000
+
+; -------------------------------------
+; constant declaration
+;
+; -------------------------------------
+
+esc = $1b
+brace = $5b
+
+.code
+
+;intialize VT100 emulation state
+;inputs: none
+;outputs: none
+vt100_init_terminal:
+
+ jsr initialise_variables ; init memory variables
+ jsr initialise_font; init font
+ jsr initialise_screen ; init screen
+ rts
+
+;process incoming character
+;inputs:
+; A is inbound character
+;outputs:
+; none, but screen and/or terminal state is updated.
+
+vt100_process_inbound_char:
+ tay
+ lda escape_mode ; handle esc mode
+ beq :+ ; to far for branch to escape
+ jmp handle_escape_char
+:
+ lda ascii_to_petscii,y ; ASCII to PETSCII
+ beq @done ; ignore non-printing chars
+ cmp #$01 ; something special?
+ beq handle_special_char
+ jsr print_to_screen ; print to screen
+@done:
+ rts
+
+
+
+do_cr:
+ ldx $d6 ; get row
+ ldy #$00 ; set col=0
+ jsr cursor_plot ; set crsr
+ rts
+
+do_line_feed:
+ ldx $d6 ; crsr line
+ cpx scroll_region_end ; end scroll region?
+ bne down_one_line ; no -> go on
+ jsr cursor_off
+ jsr scroll_up_scrollregion ; yes -> scroll up
+ jsr cursor_on
+ rts
+
+handle_special_char:
+ tya ; restore original char
+ cmp #$0d ; CR?
+ beq do_cr
+
+ cmp #$08 ; BS?
+ bne @not_bs
+ ldy $d3 ; get col
+ beq @bs_done ; stop at left margin
+ dey ; dec column
+ ldx $d6 ; get row
+ jsr cursor_plot ; set crsr
+@bs_done:
+ rts
+@not_bs:
+ cmp #$1b ; esc?
+ bne @not_escape
+ lda #$0f ; set esc mode
+ sta escape_mode
+ rts
+@not_escape:
+ cmp #$07 ; BEL?
+ bne @not_bell
+ jsr beep
+ rts
+@not_bell:
+ cmp #$0a ; LF?
+ beq do_line_feed
+
+@not_lf:
+ cmp #$09 ; TAB?
+ bne @not_tab
+ lda $d3 ; crsr col
+ and #$f8 ; (col DIV 8) * 8
+ clc ; col + 8
+ adc #$08
+ cmp #$28 ; col=40?
+ bne @not_last_col ; no -> skip
+ lda #$27 ; yes -> col=39
+@not_last_col:
+ tay ; col to y
+ ldx $d6 ; line to x
+ jsr cursor_plot ; set crsr
+ rts
+
+@not_tab:
+ rts
+
+down_one_line:
+ cpx #$18 ; end of screen?
+ bne @not_end_of_screen ; no -> go on
+ rts ; yes -> do nothing
+@not_end_of_screen:
+ inx ; next line
+ ldy $d3 ; get col
+ jsr cursor_plot ; set crsr
+ rts
+
+
+; esc mode
+; data in Y
+; escape_mode <> $00 in A
+handle_escape_char:
+ tax ; save escape_mode
+ and #$0f ; escape_mode = $0f?
+ bne @not_discard_mode
+
+; --- discard mode --- escape_mode = $f0
+;discard char
+ lda #$00 ; reset escape_mode
+ sta escape_mode
+ rts
+
+@not_discard_mode:
+ txa ; restore escape_mode
+ and #$f0 ; escape_mode = $ff?
+ beq @short_escape_mode ; no -> short Emode
+ jmp long_escape_mode ; yes -> long Emode
+
+; short esc mode
+; escape_mode = $0f
+; process first char
+@short_escape_mode:
+ tya ; restore char
+; --- [ ---
+ cmp #brace ; [ ?
+ bne @not_brace
+ lda #$ff ; set esc [ mode
+ sta escape_mode
+ rts
+; --- ( ---
+@not_brace:
+ cmp #$28 ; ( ?
+ bne :+
+ jmp set_discard_mode
+; --- ) ---
+:
+ cmp #$29 ; ) ?
+ bne :+
+ jmp set_discard_mode
+; --- # ---
+:
+ cmp #$23 ; # ?
+ bne :+
+ jmp set_discard_mode
+; --- D --- index
+:
+ cmp #$44 ; D ?
+ bne :+
+ jsr do_line_feed ; same as LF
+ jmp done_escape
+; --- M --- reverse index
+:
+ cmp #$4d ; M ?
+ bne @not_M
+ ldx $d6 ; get crsr row
+ cpx scroll_region_start ; top of scroll reg?
+ bne :+
+ jsr cursor_off ; yes -> scroll down
+ jsr scroll_down_scrollregion
+ jsr cursor_on
+ jmp done_escape
+:
+ cpx #$00 ; top of screen?
+ bne :+
+ jmp done_escape ; yes -> do nothing
+:
+ dex ; one line up
+ ldy $d3 ; get crsr col
+ jsr cursor_plot ; set crsr
+ jmp done_escape
+
+@not_M:
+; --- E --- next line
+ cmp #$45 ; E ?
+ bne :+
+ jsr do_cr
+ jsr do_line_feed
+ jmp done_escape
+:
+; --- 7 --- save crsr
+ cmp #$37 ; 7?
+ bne :+
+ lda font_mode ; save font
+ sta saved_font_mode
+ lda $c7 ; save reverse mode
+ sta saved_reverse_mode
+ ldx $d6 ; save position
+ ldy $d3
+ stx saved_row
+ sty saved_column
+ jmp done_escape
+:
+; --- 8 --- restore crsr
+ cmp #$38 ; 8?
+ bne :+
+ ldx saved_row ; restore pos
+ ldy saved_column
+ jsr cursor_plot
+ lda saved_reverse_mode ; restore ..
+ sta $c7 ; .. reverse mode
+ ldx saved_font_mode ; restore font
+ stx font_mode
+ lda font_attribute_table,x
+ sta $0286 ; set colour
+ jmp done_escape
+
+; --- unknown ---
+:
+; --- reset ESC mode ---
+done_escape:
+ lda #$00 ; reset escape_mode
+ sta escape_mode
+ rts
+
+; --- set Discard mode ---
+set_discard_mode:
+ lda #$f0 ; set esc mode $f0
+ sta escape_mode
+ rts
+
+
+; -------------------------------------
+; [ esc mode
+;
+; escape_mode = $ff
+; -------------------------------------
+
+long_escape_mode:
+ tya ; restore char
+ ldy escape_buffer_length
+ sta escape_buffer,y ; store char
+ iny
+ sty escape_buffer_length ; inc esc buffer
+ jsr test_if_letter ; test letter
+ bcs :+ ; process command
+ rts
+
+; --- process esc command ---
+; A = last char
+; Y = escape_buffer_length
+; X counts processed command chars
+:
+ ldx #$00 ; first char
+
+; --- A --- crsr up
+ cmp #$41 ; A?
+ bne @not_A
+ jsr get_number_from_esc_seq ; get argument
+ lda escape_parameter ; escape_parameter = 0...
+ bne :+
+ inc escape_parameter ; .. means 1
+:
+ lda $d6 ; get crsr row
+ sec
+ sbc escape_parameter ; row = row - up
+ cmp scroll_region_start ; stop at top of ..
+ bpl :+ ; ..scroll region
+ lda scroll_region_start
+:
+ tax ; x is row
+ ldy $d3 ; y is col
+ jsr cursor_plot ; set crsr
+ jmp @end_escape_seq
+
+; --- B --- crsr down
+@not_A:
+ cmp #$42 ; B?
+ bne @not_B
+ jsr get_number_from_esc_seq ; get argument
+ lda escape_parameter ; escape_parameter = 0...
+ bne :+
+ inc escape_parameter ; .. means 1
+:
+ lda $d6 ; get crsr row
+ clc
+ adc escape_parameter ; row = row + down
+ cmp scroll_region_end ; outside scrregion?
+ bcs :+ ; yes -> branch
+ tax ; x is row
+ jmp @skip
+:
+ ldx scroll_region_end ; x = row = scroll_region_end
+@skip:
+ ldy $d3 ; y is col
+ jsr cursor_plot ; set crsr
+ jmp @end_escape_seq
+
+; --- C --- crsr right
+@not_B:
+ cmp #$43 ; C?
+ bne @not_C
+ jsr get_number_from_esc_seq ; get argument
+ lda escape_parameter ; escape_parameter = 0...
+ bne :+
+ inc escape_parameter ; .. means 1
+:
+ lda $d3 ; get crsr col
+ clc
+ adc escape_parameter ; col = col + right
+ cmp #$27 ; outside screen?
+ bcs :+ ; yes -> branch
+ tay
+ jmp @skip2
+:
+ ldy #$27 ; y=col=left margin
+@skip2:
+ ldx $d6 ; x is row
+ jsr cursor_plot ; set crsr
+ jmp @end_escape_seq
+
+; --- D --- crsr left
+@not_C:
+ cmp #$44 ; D?
+ bne @not_D
+ jsr get_number_from_esc_seq ; get argument
+ lda escape_parameter ; escape_parameter = 0...
+ bne :+
+ inc escape_parameter ; .. means 1
+:
+ lda $d3 ; get crsr col
+ sec
+ sbc escape_parameter ; col = col - left
+ bpl :+ ; stop at left..
+ lda #$00 ; ..margin
+:
+ tay ; y is col
+ ldx $d6 ; x is row
+ jsr cursor_plot ; set crsr
+ jmp @end_escape_seq
+
+; --- m --- font attributes
+@not_D:
+ cmp #$6d ; m?
+ bne @not_m
+@next_font_attribute:
+ jsr get_number_from_esc_seq
+ pha ; save nondigit char
+ lda escape_parameter ; parameter to A
+ ; -- 0 --
+ bne :+ ; 0?
+ sta font_mode ; set font = vanilla
+ sta $c7 ; reverse off
+ jmp @end_font_attribute ; jmp next par
+ ; -- 1 -- bold
+:
+ cmp #$01
+ bne :+
+ lda font_mode ; set bold
+ ora #$01
+ sta font_mode
+ jmp @end_font_attribute ; next char
+ ; -- 4 -- underline
+:
+ cmp #$04
+ bne :+
+ lda font_mode ; set u_line
+ ora #$02
+ sta font_mode
+ jmp @end_font_attribute ; next char
+ ; -- 5 -- blink
+:
+ cmp #$05
+ bne :+
+ lda font_mode ; set blink
+ ora #$04
+ sta font_mode
+ jmp @end_font_attribute ; next char
+ ; -- 7 -- reverse
+:
+ cmp #$07
+ bne :+
+ lda #$01 ; set revers
+ sta $c7
+ jmp @end_font_attribute ; next char
+:
+ ; -- 30 - 37 --
+ cmp #38 ; >= 38?
+ bcs @end_font_attribute
+ cmp #30 ; < 30?
+ bcc @end_font_attribute
+ sbc #30 ; pointer for table
+ sta direct_colour
+ lda #$80 ; set direct colour
+ sta font_mode
+
+@end_font_attribute: ; -- next char --
+ pla ; get nondigit char
+ cmp #$3b ; is semicolon?
+ beq @next_font_attribute ; then next cahr
+ ; -- set colour --
+ lda font_mode ;
+ bmi :+ ; bit 7->direct col
+ tax ; font to colour
+ lda font_attribute_table,x
+ sta $0286 ; set colour
+ jmp @end_escape_seq
+:
+ ; -- set direct colour --
+ ldx direct_colour ; colour maping
+ lda direct_colour_table,x
+ sta $0286 ; set colour
+ jmp @end_escape_seq
+
+; --- K --- erase line
+@not_m:
+ cmp #$4b ; K?
+ bne @not_K
+ jsr get_number_from_esc_seq ; get parameter
+ lda escape_parameter ; in A
+ ; -- 0 -- crsr to end of line
+ bne :+
+ jsr erase_to_end_of_line ; erase end line
+ jmp @end_escape_seq
+ ; -- 1 -- begin to crsr
+:
+ cmp #$01
+ bne :+
+ jsr erase_line_to_cursor ; erase beg line
+ jmp @end_escape_seq
+ ; -- 2 -- whole line
+:
+ cmp #$02
+ bne :+ ; par undefined
+ ldx $d6 ; line in X
+ jsr erase_line_by_number ; erase line
+ sta $ce ; del char ..
+ ; ..under crsr
+:
+ jmp @end_escape_seq
+
+; --- f --- same as H
+@not_K:
+ cmp #$66
+ bne @not_f
+ jmp @set_cursor_position ; same as H
+
+; --- H --- cursor position
+@not_f:
+ cmp #$48
+ bne @not_H
+@set_cursor_position:
+ cpy #$01 ; no par means home
+ bne :+
+ ; -- home --
+ ldx #$00
+ ldy #$00
+ jsr cursor_plot ; set crsr
+ jmp @end_escape_seq
+ ; -- row, col --
+:
+ jsr get_number_from_esc_seq
+ cmp #$3b ; is ;?
+ bne @end_set_cursor_position ; no -> error
+ ; -- prepare row --
+ ldy escape_parameter ; get row
+ bne :+ ; 0 means 1
+ iny
+:
+ dey ; line 1 -> line 0
+ cpy #$19 ; >= 25?..
+ bcs @end_set_cursor_position ; ..error!
+ sty temp_ptr_x ; save row
+ ; -- prepare col
+ jsr get_number_from_esc_seq
+ ldy escape_parameter ; get col
+ bne :+ ; 0 means 1
+ iny
+:
+ dey ; line 1 -> line 0
+ cpy #$28 ; >= 40?..
+ bcs @end_set_cursor_position ; ..error!
+ ldx temp_ptr_x ; restore row to X
+ jsr cursor_plot ; set crsr
+@end_set_cursor_position:
+ jmp @end_escape_seq
+
+
+; --- J --- erase screen
+@not_H:
+ cmp #$4a ;J?
+ bne @not_J
+ jsr get_number_from_esc_seq ; get parameter
+ lda escape_parameter ; in A
+ ; -- 0 -- crsr to end
+ bne @not_cursor_to_end
+ jsr erase_to_end_of_line ; del rest of line
+ ldx $d6 ; get crsr line
+@erase_next_line:
+ inx ; next line
+ cpx #$19 ; line 25?
+ bcs @end_escape_seq ; then end
+ txa
+ pha ; save X
+ jsr erase_line_by_number ; erase line
+ pla
+ tax ; restore X
+ jmp @erase_next_line ; next line
+ ; -- 1 -- beg of screen to crsr
+@not_cursor_to_end:
+ cmp #$01
+ bne @not_start_to_cursor
+ jsr erase_line_to_cursor ; del start of ln
+ ldx $d6 ; get crsr line
+:
+ dex ; previous line
+ bmi @end_escape_seq ; neg line -> end
+ txa
+ pha ; save X
+ jsr erase_line_by_number ; erase line
+ pla
+ tax ; restore X
+ jmp :-
+ ; -- 2 -- del screen
+@not_start_to_cursor:
+ cmp #$02 ; unknown?
+ bne @end_escape_seq ; then ingnore
+ ldx #$18 ; start at ln 24
+:
+ txa
+ pha ; save X
+ jsr erase_line_by_number ; erase line
+ pla
+ tax ; restore X
+ dex ; previous line
+ bpl :-
+ jmp @end_escape_seq
+
+
+; --- r --- set scroll region
+@not_J:
+ cmp #$72 ; r?
+ bne @not_r
+ ; -- prepare top --
+ jsr get_number_from_esc_seq
+ cmp #$3b ; is ;?
+ bne @error_in_escape_seq ; no -> error
+ ldy escape_parameter ; get top
+ dey ; line 1 -> line 0
+ cpy #$19 ; >=25?..
+ bcs @error_in_escape_seq ; ..error!
+ sty temp_ptr_x ; save top
+ ; -- prepare bottom --
+ jsr get_number_from_esc_seq
+ ldy escape_parameter ; get bottom
+ dey ; line 1 -> line 0
+ cpy #$19 ; >=25?..
+ bcs @error_in_escape_seq ; ..error!
+ sty temp_ptr_y ; save bottom
+ ; -- validate lines --
+ lda temp_ptr_x ; restore top
+ cmp temp_ptr_y ; >= bottom?..
+ bcs @error_in_escape_seq ; ..error!
+ sta scroll_region_start ; top -> SRStart
+ sty scroll_region_end ; bottom -> SREnd
+ ; -- home crsr
+ ldx #$00
+ ldy #$00
+ jsr cursor_plot
+@error_in_escape_seq:
+ jmp @end_escape_seq
+
+
+@not_r:
+; --- unknown ---
+@end_escape_seq:
+ lda #$00
+ sta escape_buffer_length ; reset esc buffer
+ sta escape_mode ; reset esc mode
+ rts
+
+
+
+; -------------------------------------
+; Test letter
+;
+; char in A
+; returns carry = 1 for A = letter
+; -------------------------------------
+test_if_letter:
+ cmp #$41 ; smaller then A?
+ bcs :+ ; no -> go on
+ rts ; return no letter
+:
+ cmp #$5b ; smaller then Z+1?
+ bcs :+ ; no -> go on
+ sec ; return letter
+ rts
+:
+ cmp #$61 ; smaller then a?
+ bcs :+ ; no -> go on
+ rts ; return no letter
+:
+ cmp #$7b ; smaller then z+1?
+ bcs :+ ; no -> go on
+ sec ; return letter
+ rts
+:
+ clc ; return no letter
+ rts
+
+
+
+; -------------------------------------
+; test digit
+;
+; char in A
+; returns carry = 1 for A = digit
+; -------------------------------------
+
+test_if_digit:
+ cmp #$30 ; smaller then 0?
+ bcs :+ ; no -> go on
+ rts ; return no digit
+:
+ cmp #$3a ; smaller then 9+1?
+ bcs :+ ; no -> go on
+ sec ; return digit
+ rts
+:
+ clc ; return no digit
+ rts
+
+
+; -------------------------------------
+; get decimal number from esc sequence
+;
+; esc sequence in escape_buffer
+; first index to process in X
+; returns: number escape_parameter
+; first non digit char in A
+; -------------------------------------
+get_number_from_esc_seq:
+ lda #$00 ; assume $00
+ sta escape_parameter
+@next_digit:
+ lda escape_buffer,x ; get next char
+ inx
+ jsr test_if_digit ; digit?
+ bcc @done ; no -> return
+ sbc #$30 ; ascii to #
+ pha ; save digit
+ ; old value * 10
+ ; 10a = ( 4a + a ) * 2
+ lda escape_parameter
+ asl
+ asl ; ( 4a
+ clc
+ adc escape_parameter ; + a )
+ asl ; *2
+ sta escape_parameter ; = 10a
+ ; add new digit
+ pla ; resore new digit
+ clc
+ adc escape_parameter
+ sta escape_parameter
+ jmp @next_digit ; next char
+@done:
+ rts
+
+
+
+; *************************************
+; *
+; * outgoing data
+; *
+; *************************************
+; -------------------------------------
+; given a single char (read from keyboard)
+; work out what data should be sent to the remote host.
+; input:
+; A = keypress
+; output:
+; Y=0 - no data to be sent (i.e. ignore keypress)
+; Y=1 - A contains single byte to send
+; Y=2 - AX points to null terminated string to send
+; -------------------------------------
+
+;Y=0 nothing to send
+;Y=1 A = char to send
+;Y=2 AX=pointer to asciiz string to send
+
+vt100_transform_outbound_char:
+ tay
+ lda petscii_to_ascii,y ; PETSCII to ASCII
+ bne :+
+ ldy #0 ; ignore key
+ rts
+:
+ cmp #$ff
+ beq output_string
+ cmp #$fe
+ beq command_key ; command key
+ ;default - send (possibly transformed) single char
+ ldy #1 ;means A contains single byte to send
+@done:
+rts
+
+
+
+; -------------------------------------
+; create an ansi control sequence
+; -------------------------------------
+
+
+output_string:
+ tya ; restore original key
+
+; --- crsr U ---
+ cmp #$91 ; test crsr U
+ bne @not_U
+ ldax #ansi_cursor_up
+ ldy #2
+ rts
+; --- crsr L ---
+@not_U:
+ cmp #$9d ; test crsr L
+ bne @not_L
+ ldax #ansi_cursor_left
+ ldy #2
+ rts
+@not_L:
+ cmp #$0d ;test CR
+ bne @not_CR
+ ldax #crlf
+ ldy #2
+ rts
+
+@not_CR:
+ ldy #0 ;must be some kind of error
+ rts
+
+
+; -------------------------------------
+; keypress was a command key
+; -------------------------------------
+
+command_key:
+ tya ; restore character
+
+; --- crsr R ---
+; --- ^] ---
+; both events send $1d
+ cmp #$1d
+ bne @not_crsr_R
+ lda #$04 ; test control Key
+ bit $028d
+ beq @cursor_right ; not pressed
+ ; control ] is pressed
+ tya ; send ^]
+ ldy #1
+ rts
+
+; crsr R
+@cursor_right:
+ ldax #ansi_cursor_right
+ ldy #2
+ rts
+
+; --- crsr D ---
+; --- ^Q ---
+; both events send char $11
+@not_crsr_R:
+ cmp #$11 ;^Q / crsr down
+ bne @not_crsr_D
+ lda #$04 ; test control Key
+ bit $028d
+ beq @cursor_down ; not pressed
+ ; control Q is pressed
+ tya ; send ^Q
+ ldy #1
+ rts
+
+ ; crsr down is pressed
+@cursor_down:
+ ldax #ansi_cursor_down
+ ldy #2
+ rts
+
+; --- HOME key ---
+; --- ^S ---
+; both events send char $13
+@not_crsr_D:
+ cmp #$13 ;^S / HOME
+ bne @not_home
+ lda #$04 ; test control Key
+ bit $028d
+ beq @home ; not pressed
+ ; control S is pressed
+ tya ; send ^S
+ ldy #1
+ rts
+
+@home:
+ lda #$09 ; send TAB
+ ldy #1
+ rts
+
+; --- DEL key ---
+; --- ^T ---
+; both events send char $14
+@not_home:
+ cmp #$14 ;^T / DEL
+ bne @not_del
+ lda #$04 ; test control Key
+ bit $028d
+ beq @del ; not pressed
+ ; control T is pressed
+ tya ; send ^T
+ ldy #1
+ rts
+
+ ; send DEL
+@del:
+ lda #$08
+ ldy #1
+ rts
+
+
+; --- unknown C=-Key ---
+@not_del:
+ ldy #0 ;means don't send anything
+ rts
+
+; *************************************
+; *
+; * screen handling
+; *
+; *************************************
+
+; --- these variables become updated ---
+; on crsr movement.
+;
+; $d1 $d2 start of screen line
+; $d3 crsr column
+; $d6 crsr row
+; $f3 $f4 start of colour line
+; $0286 colour
+
+; --- these variables become updated ---
+; on crsr switching.
+;
+; $cc crsr flag, 0 = on
+; $cd crsr blink counter
+; $ce char under crsr
+; $cf crsr blink phase, 0 normal
+; $0287 colour under crsr
+
+
+
+; -------------------------------------
+; switch curser off and restore char.
+; this has to be done before every crsr
+; movement.
+; After movement there has to be a jump
+; to cursor_on.
+; -------------------------------------
+cursor_off:
+ pha ; save registers
+ tya
+ pha
+
+ ldy #$01 ; crsr of
+ sty $cc
+ lda $cf ; crsr revers?
+ beq :+ ; no -> return
+ dey ; set normal phase
+ sty $cf
+ ldy $d3 ; get column
+ lda $ce ; restore char
+ sta ($d1),y
+ lda $0287 ; restore colour
+ sta ($f3),y
+
+:
+ pla ; restore registers
+ tay
+ pla
+ rts
+
+; -------------------------------------
+; opposite of cursor_off
+; -------------------------------------
+
+cursor_on:
+ pha
+ tya
+ pha
+
+ ldy $d3 ; get column
+ lda ($d1),y ; save chr
+ sta $ce
+ eor #$80 ; reverse char
+ sta ($d1),y
+ lda ($f3),y ; save colour
+ sta $0287
+ lda $0286 ; set crsr colour
+ sta ($f3),y
+ inc $cf ; set reverse phase
+ lda #$14 ; set crsr counter..
+ sta $cd ; ..to max
+ lda #$00 ; cursor on
+ sta $cc
+
+ pla
+ tay
+ pla
+ rts
+
+
+
+; -------------------------------------
+; moves the crsr to column Y
+; and line X
+; the crsr ist turned off during
+; operation
+; destroys all registers
+; -------------------------------------
+cursor_plot:
+ jsr cursor_off
+
+ stx $d6 ; set row
+ sty $d3 ; set col
+ jsr set_line_vectors
+ ldx temp_ptr_x ; set screen line
+ ldy temp_ptr_x+1
+ stx $d1
+ sty $d2
+ ldx temp_ptr_y ; set color line
+ ldy temp_ptr_y+1
+ stx $f3
+ sty $f4
+
+ jsr cursor_on
+ rts
+
+
+; -------------------------------------
+; Print char in A to screen
+; being aware of the crsr state
+; -------------------------------------
+
+print_to_screen:
+ jsr cursor_off
+ jsr plot_char
+ jsr cursor_on
+ rts
+
+; -------------------------------------
+; print char to screen
+; char = $ff means no output
+; chr in A
+; X and Y unaffected
+; -------------------------------------
+
+plot_char:
+ sta temp_ptr_x ; save char
+ txa ; save registers
+ pha
+ tya
+ pha
+ lda temp_ptr_x ; restore char
+
+; PETSCII to ScreenCode (SC)
+; --- $c0-$ff --- - illegal -
+ cmp #$c0
+ bcc :+
+ jmp end_plot_char ; no output
+; --- $a0-$bf --- C=(latin-1) chars
+:
+ cmp #$a0
+ bcc :+
+ sbc #$40 ; SC = PET - $40
+ jmp @check_for_reverse
+; --- $80-$9f --- - illegal -
+:
+ cmp #$80
+ bcc :+
+ jmp end_plot_char ; no output
+; --- $60-$7f --- kapital letters
+:
+ cmp #$60
+ bcc :+
+ sbc #$20 ; SC = PET - $20
+ jmp @check_for_reverse
+; --- $40-$5f --- small letters
+:
+ cmp #$40
+ bcc :+
+ sbc #$40 ; SC = PET - $40
+ jmp @check_for_reverse
+; --- $20-$3f --- interpunction
+:
+ cmp #$20
+ bcc :+
+ jmp @check_for_reverse ; SC = PET
+; --- $00-$1f --- - illegal -
+:
+ jmp end_plot_char ; no output
+
+; --- handle reverse mode---
+@check_for_reverse:
+ ldx $c7 ; reverse mode?
+ beq @put_char
+ ora #$80 ; reverse char
+
+; --- put char to screen ---
+@put_char:
+ ldy $d3 ; get crsr col
+ cpy #$28 ;col = 40
+ bcc @no_line_wrap
+ ;the only way we end up trying to write to column 40 should
+ ;be if we skipped the normal line wrap after writing to col 39
+ ;because we are at the end of the scroll region
+ ;that means we should do a scroll up and then write this char at col 0
+ pha
+ jsr scroll_up_scrollregion
+ pla
+ ldy #$00 ; begin of line
+ sty $d3
+@no_line_wrap:
+ sta ($d1),y ; char to screen
+ lda $0286 ; get colour
+ sta ($f3),y ; set colour
+
+; --- move on crsr ---
+
+ ldx $d6 ; get crsr row
+ cpx scroll_region_end ; end of scroll reg?
+ beq @dont_scroll_yet ; we don't want to trigger a scroll of the whole screen unless
+ ; we are actually writing a char. we shouldn't scroll just when
+ ; writing to the bottom right hand screen (else e.g. the title bar
+ ; in 'nano' gets pushed off the top of the screen.
+ ;
+ cpy #$27 ; col = 39?
+ beq move_to_next_line ; yes -> new line
+@dont_scroll_yet:
+ iny ; move on
+ sty $d3
+
+end_plot_char:
+ pla ; restore registers
+ tay
+ pla
+ tax
+ rts
+
+; -------------------------------------
+; subtask of plot_char
+; ends at end_plot_char
+; -------------------------------------
+move_to_next_line:
+ ldx $d6 ; get crsr row
+ cpx scroll_region_end ; end of scroll reg?
+ beq @scroll_up ; yes -> branche
+ cpx #$18 ; line 24?
+ beq end_plot_char ; yes -> crsr stays
+; --- normal wrap ---
+ inx ; increase line
+ stx $d6
+ ldy #$00 ; begin of line
+ sty $d3
+ jsr set_line_vectors
+ ldx temp_ptr_x ; set screen line
+ ldy temp_ptr_x+1
+ stx $d1
+ sty $d2
+ ldx temp_ptr_y ; set colour line
+ ldy temp_ptr_y+1
+ stx $f3
+ sty $f4
+ jmp end_plot_char
+; --- scroll up ---
+@scroll_up:
+ jsr scroll_up_scrollregion
+ ldy #$00 ; begin of line
+ sty $d3
+ jmp end_plot_char
+
+
+
+scroll_up_scrollregion:
+ ldx scroll_region_start ; get first line
+@scroll_one_line:
+ ; -- new line: --
+ ; -- temp_ptr_z and temp_ptr_w --
+ jsr set_line_vectors
+ lda temp_ptr_x ; screen line
+ ldy temp_ptr_x+1
+ sta temp_ptr_z
+ sty temp_ptr_z+1
+ lda temp_ptr_y ; colour line
+ ldy temp_ptr_y+1
+ sta temp_ptr_w
+ sty temp_ptr_w+1
+ ; -- old line: --
+ ; -- temp_ptr_x and temp_ptr_y
+ inx ; old line
+ jsr set_line_vectors
+ ; -- copy chars and colours --
+ ldy #$27 ; col 39
+@scroll_one_char:
+ lda (temp_ptr_x),y ; copy char
+ sta (temp_ptr_z),y
+ lda (temp_ptr_y),y ; copy colour
+ sta (temp_ptr_w),y
+ dey
+ bpl @scroll_one_char
+ cpx scroll_region_end ; last line?
+ bne @scroll_one_line ; no -> go on
+ jsr erase_line_by_vector ; del last line
+
+ rts
+
+
+scroll_down_scrollregion:
+ ldx scroll_region_end ; get last line
+@scroll_one_line:
+ jsr set_line_vectors
+ lda temp_ptr_x ; screen line
+ ldy temp_ptr_x+1
+ sta temp_ptr_z
+ sty temp_ptr_z+1
+ lda temp_ptr_y ; colour line
+ ldy temp_ptr_y+1
+ sta temp_ptr_w
+ sty temp_ptr_w+1
+ ; -- old line: --
+ ; -- temp_ptr_x and temp_ptr_y
+ dex ; old line
+ jsr set_line_vectors
+ ; -- copy chars ond colours --
+ ldy #$27 ; col 39
+@scroll_one_char:
+ lda (temp_ptr_x),y ; copy char
+ sta (temp_ptr_z),y
+ lda (temp_ptr_y),y ; copy colour
+ sta (temp_ptr_w),y
+ dey
+ bpl @scroll_one_char
+ cpx scroll_region_start ; first line?
+ bne @scroll_one_line ; no -> go on
+ jsr erase_line_by_vector ; del first line
+
+ rts
+
+
+; -------------------------------------
+; print string to screen
+; string: chars, terminated by $00
+; start lo in x
+; start hi in y
+; affects A
+; takes care of crsr
+; the string must be smaller
+; than 255 chrs
+; -------------------------------------
+
+
+plot_string:
+ stx print_ptr ; store start vector
+ sty print_ptr+1
+ jsr cursor_off
+ ldy #$00
+@next_char:
+ lda (print_ptr),y
+ beq @end_string ; $00 terminates string
+ jsr plot_char
+ iny
+ jmp @next_char
+
+@end_string:
+ jsr cursor_on
+ rts
+
+
+
+; -------------------------------------
+; delete screen line
+; (Erase Line)
+;
+; line number in X
+;
+; erase_line_by_vector needs line vectors in temp_ptr_x
+; and temp_ptr_y
+;
+; destroys all registers
+; returns $20 (space) in A
+; -------------------------------------
+
+erase_line_by_number:
+ jsr set_line_vectors ; line start in temp_ptr_x
+ ; col start in temp_ptr_y
+
+; erase chars
+erase_line_by_vector:
+ ldy #$27 ; col 39
+ lda #$20 ; load space
+:
+ sta (temp_ptr_x),y ; clear char
+ dey
+ bpl :-
+
+; set colour
+ ldy #$27 ; col 39
+ lda #charmode_vanilla ; load vanilla
+:
+ sta (temp_ptr_y),y ; clear char
+ dey
+ bpl :-
+
+ rts
+
+
+
+; -------------------------------------
+; delete screen line from crsr to end
+; (Erase End of Line)
+; destroys all registers
+; -------------------------------------
+
+erase_to_end_of_line:
+ jsr cursor_off
+; erase chars
+ ldy $d3 ; get crsr col
+ lda #$20 ; load space
+:
+ sta ($d1),y ; clear char
+ iny
+ cpy #$28 ; pos 40?
+ bne :- ; next char
+ sta $ce ; del char ..
+ ; ..under crsr
+; set colour
+ ldy $d3 ; get crsr col
+ lda #charmode_vanilla ; load vanilla
+:
+ sta ($f3),y ; set colour
+ iny
+ cpy #$28 ; pos 40?
+ bne :- ; next char
+ jsr cursor_on
+ rts
+
+; -------------------------------------
+; delete screen line up to crsr
+; (Erase Begin of Line)
+; destroys all registers
+; -------------------------------------
+erase_line_to_cursor:
+; erase chars
+ ldy $d3 ; get crsr col
+ lda #$20 ; load space
+:
+ sta ($d1),y ; clear char
+ dey
+ bpl :- ; pos>=0 -> next
+ sta $ce ; del char ..
+ ; ..under crsr
+; set colour
+ ldy $d3 ; get crsr col
+ lda #charmode_vanilla ; load vanilla
+:
+ sta ($f3),y ; clear char
+ dey
+ bpl :- ; pos>=0 -> next
+ rts
+
+
+; -------------------------------------
+; set line vectors
+;
+; line no in X
+; destroys A and Y
+;
+; sets start of screen line in temp_ptr_x
+; sets start of colour line in temp_ptr_y
+; -------------------------------------
+
+set_line_vectors:
+ lda $ecf0,x ; get lo byte
+ sta temp_ptr_x
+ sta temp_ptr_y
+ ; determin hi byte
+ ldy #$04 ; hi byte
+ cpx #$07 ; line < 7?
+ bcc @got_line_vector
+ iny
+ cpx #$0d ; line < 13?
+ bcc @got_line_vector
+ iny
+ cpx #$14 ; line < 20?
+ bcc @got_line_vector
+ iny ; line 20-24
+@got_line_vector:
+ sty temp_ptr_x+1
+ tya
+ clc ; colour RAM =
+ adc #$d4 ; video RAM + d4
+ sta temp_ptr_y+1
+ rts
+
+
+
+; -------------------------------------
+; init routines
+;
+; -------------------------------------
+
+
+initialise_screen:
+
+ ;--- set background ---
+ lda #text_background_colour
+ sta $d021
+; --- disable Shift C= ---
+ lda #$80
+ sta $0291
+; --- erase screen ---
+ ldx #$18 ; start at ln 24
+@erase_one_line:
+ txa
+ pha ; save X
+ jsr erase_line_by_number ; erase line
+ pla
+ tax ; restore X
+ dex ; previous line
+ bpl @erase_one_line
+
+ lda #charmode_vanilla ; load vanilla
+ sta $0286
+; --- crsr on ---
+ jsr cursor_off
+ jsr cursor_on
+; --- put crsr ---
+ jsr do_cr
+ jsr do_line_feed
+ jsr do_line_feed
+
+ rts
+
+
+
+initialise_variables:
+ lda #$00
+ sta escape_mode
+ sta escape_buffer_length
+ sta scroll_region_start
+ sta font_mode
+ sta saved_font_mode
+ sta saved_reverse_mode
+ sta saved_row
+ sta saved_column
+
+ lda #$18 ; last line
+ sta scroll_region_end ; = 24
+
+ rts
+
+
+reverse_font_table = font_table + $0400
+initialise_font:
+ sei
+ ldx #ROM_FONT
+ stx temp_ptr_z
+ sty temp_ptr_z+1
+ ldx #font_table
+ stx temp_ptr_y
+ sty temp_ptr_y+1
+ ldx #reverse_font_table
+ stx temp_ptr_x
+ sty temp_ptr_x+1
+
+; copy font
+ ldx #$04 ; copy 4 pages = 1KB
+ ldy #$00
+:
+ lda (temp_ptr_z),y
+ sta (temp_ptr_y),y
+ eor #$ff ; reverse char
+ sta (temp_ptr_x),y
+ iny
+ bne :-
+ ; switch to next page
+ inc temp_ptr_z+1
+ inc temp_ptr_y+1
+ inc temp_ptr_x+1
+ dex
+ bne :-
+
+; enable font
+ lda $d018
+ and #$f1
+ ora #$09
+ sta $d018
+ cli
+ rts
+
+
+.rodata
+font_attribute_table: ; bits mean blink, underline, bold
+.byte charmode_vanilla, charmode_bold ; 000 001
+.byte charmode_underline, charmode_underline_bold ; 010 011
+.byte charmode_blink, charmode_blink_bold ; 100 101
+.byte charmode_blink_underline, charmode_blink_underline_bold ; 110 111
+
+direct_colour_table:
+;ANSI 30 31 32 32 34 35 36 37
+; blk rd gr ye blu mg cy wh
+.byte 0, $0a, 5, 7, $0e, 4, 3, 1
+
+ansi_cursor_up: .byte esc, brace, $41, $00 ; esc [ A
+ansi_cursor_down: .byte esc, brace, $42, $00 ; esc [ B
+ansi_cursor_right: .byte esc, brace, $43, $00 ; esc [ C
+ansi_cursor_left: .byte esc, brace, $44, $00 ; esc [ D
+crlf: .byte $0d,$0a,0
+
+; -------------------------------------
+; table ASCII to PETSCII
+;
+; these characters cat be printed
+;
+; pet=$00 means ignore the char
+; pet=$01 means do something complicated
+; -------------------------------------
+ascii_to_petscii:
+ .byte $00 ; $00
+ .byte $00 ; $01
+ .byte $00 ; $02
+ .byte $00 ; $03
+ .byte $00 ; $04
+ .byte $00 ; $05
+ .byte $00 ; $06
+ .byte $01 ; $07 BEL
+ .byte $01 ; $08 BS/DEL
+ .byte $01 ; $09 TAB
+ .byte $01 ; $0a LF
+ .byte $00 ; $0b
+ .byte $00 ; $0c
+ .byte $01 ; $0d CR
+ .byte $00 ; $0e
+ .byte $00 ; $0f
+ .byte $00 ; $10
+ .byte $00 ; $11
+ .byte $00 ; $12
+ .byte $00 ; $13
+ .byte $00 ; $14
+ .byte $00 ; $15
+ .byte $00 ; $16
+ .byte $00 ; $17
+ .byte $00 ; $18
+ .byte $00 ; $19
+ .byte $00 ; $1a
+ .byte $01 ; $1b ESC
+ .byte $00 ; $1c
+ .byte $00 ; $1d
+ .byte $00 ; $1e
+ .byte $00 ; $1f
+ .byte $20 ; $20 1:1
+ .byte $21 ; $21 1:1
+ .byte $22 ; $22 1:1
+ .byte $23 ; $23 1:1
+ .byte $24 ; $24 1:1
+ .byte $25 ; $25 1:1
+ .byte $26 ; $26 1:1
+ .byte $27 ; $27 1:1
+ .byte $28 ; $28 1:1
+ .byte $29 ; $29 1:1
+ .byte $2a ; $2a 1:1
+ .byte $2b ; $2b 1:1
+ .byte $2c ; $2c 1:1
+ .byte $2d ; $2d 1:1
+ .byte $2e ; $2e 1:1
+ .byte $2f ; $2f 1:1
+ .byte $30 ; $30 1:1
+ .byte $31 ; $31 1:1
+ .byte $32 ; $32 1:1
+ .byte $33 ; $33 1:1
+ .byte $34 ; $34 1:1
+ .byte $35 ; $35 1:1
+ .byte $36 ; $36 1:1
+ .byte $37 ; $37 1:1
+ .byte $38 ; $38 1:1
+ .byte $39 ; $39 1:1
+ .byte $3a ; $3a 1:1
+ .byte $3b ; $3b 1:1
+ .byte $3c ; $3c 1:1
+ .byte $3d ; $3d 1:1
+ .byte $3e ; $3e 1:1
+ .byte $3f ; $3f 1:1
+ .byte $40 ; $40 1:1
+ .byte $61 ; $41 -----
+ .byte $62 ; $42
+ .byte $63 ; $43
+ .byte $64 ; $44 capital
+ .byte $65 ; $45
+ .byte $66 ; $46
+ .byte $67 ; $47
+ .byte $68 ; $48
+ .byte $69 ; $49
+ .byte $6a ; $4a
+ .byte $6b ; $4b
+ .byte $6c ; $4c
+ .byte $6d ; $4d letters
+ .byte $6e ; $4e
+ .byte $6f ; $4f
+ .byte $70 ; $50
+ .byte $71 ; $51
+ .byte $72 ; $52
+ .byte $73 ; $53
+ .byte $74 ; $54
+ .byte $75 ; $55
+ .byte $76 ; $56
+ .byte $77 ; $57
+ .byte $78 ; $58
+ .byte $79 ; $59
+ .byte $7a ; $5a -----
+ .byte $5b ; $5b 1:1
+ .byte $5c ; $5c 1:1
+ .byte $5d ; $5d 1:1
+ .byte $5e ; $5e 1:1
+ .byte $5f ; $5f 1:1
+ .byte $60 ; $60 1:1
+ .byte $41 ; $61 -----
+ .byte $42 ; $62
+ .byte $43 ; $63
+ .byte $44 ; $64 small
+ .byte $45 ; $65
+ .byte $46 ; $66
+ .byte $47 ; $67
+ .byte $48 ; $68
+ .byte $49 ; $69
+ .byte $4a ; $6a
+ .byte $4b ; $6b letters
+ .byte $4c ; $6c
+ .byte $4d ; $6d
+ .byte $4e ; $6e
+ .byte $4f ; $6f
+ .byte $50 ; $70
+ .byte $51 ; $71
+ .byte $52 ; $72
+ .byte $53 ; $73
+ .byte $54 ; $74
+ .byte $55 ; $75
+ .byte $56 ; $76
+ .byte $57 ; $77
+ .byte $58 ; $78
+ .byte $59 ; $79
+ .byte $5a ; $7a -----
+ .byte $7b ; $7b 1:1 {
+ .byte $7c ; $7c 1:1 |
+ .byte $7d ; $7d 1:1 }
+ .byte $7e ; $7e 1:1 ~
+ .byte $00 ; $7f
+ .byte $00 ; $80
+ .byte $00 ; $81
+ .byte $00 ; $82
+ .byte $00 ; $83
+ .byte $00 ; $84
+ .byte $00 ; $85
+ .byte $00 ; $86
+ .byte $00 ; $87
+ .byte $00 ; $88
+ .byte $00 ; $89
+ .byte $00 ; $8a
+ .byte $00 ; $8b
+ .byte $00 ; $8c
+ .byte $00 ; $8d
+ .byte $00 ; $8e
+ .byte $00 ; $8f
+ .byte $00 ; $90
+ .byte $00 ; $91
+ .byte $00 ; $92
+ .byte $00 ; $93
+ .byte $00 ; $94
+ .byte $00 ; $95
+ .byte $00 ; $96
+ .byte $00 ; $97
+ .byte $00 ; $98
+ .byte $00 ; $99
+ .byte $00 ; $9a
+ .byte $00 ; $9b
+ .byte $00 ; $9c
+ .byte $00 ; $9d
+ .byte $00 ; $9e
+ .byte $00 ; $9f
+ .byte $20 ; $a0
+ .byte $7f ; $a1
+ .byte $7f ; $a2
+ .byte $bf ; $a3
+ .byte $be ; $a4
+ .byte $7f ; $a5
+ .byte $73 ; $a6
+ .byte $b5 ; $a7
+ .byte $53 ; $a8
+ .byte $bb ; $a9
+ .byte $7f ; $aa
+ .byte $bc ; $ab
+ .byte $7f ; $ac
+ .byte $2d ; $ad
+ .byte $7f ; $ae
+ .byte $7f ; $af
+ .byte $ba ; $b0
+ .byte $b8 ; $b1
+ .byte $b6 ; $b2
+ .byte $b7 ; $b3
+ .byte $7a ; $b4
+ .byte $b9 ; $b5
+ .byte $7f ; $b6
+ .byte $7f ; $b7
+ .byte $5a ; $b8
+ .byte $7f ; $b9
+ .byte $7f ; $ba
+ .byte $bd ; $bb
+ .byte $b0 ; $bc
+ .byte $b0 ; $bd
+ .byte $79 ; $be
+ .byte $7f ; $bf
+ .byte $a5 ; $c0
+ .byte $61 ; $c1
+ .byte $a4 ; $c2
+ .byte $61 ; $c3
+ .byte $a3 ; $c4
+ .byte $a4 ; $c5
+ .byte $7f ; $c6
+ .byte $63 ; $c7
+ .byte $ad ; $c8
+ .byte $ab ; $c9
+ .byte $ac ; $ca
+ .byte $65 ; $cb
+ .byte $69 ; $cc
+ .byte $69 ; $cd
+ .byte $69 ; $ce
+ .byte $69 ; $cf
+ .byte $64 ; $d0
+ .byte $6e ; $d1
+ .byte $6f ; $d2
+ .byte $6f ; $d3
+ .byte $b1 ; $d4
+ .byte $6f ; $d5
+ .byte $af ; $d6
+ .byte $7f ; $d7
+ .byte $6f ; $d8
+ .byte $75 ; $d9
+ .byte $75 ; $da
+ .byte $75 ; $db
+ .byte $b3 ; $dc
+ .byte $79 ; $dd
+ .byte $7f ; $de
+ .byte $b4 ; $df
+ .byte $a2 ; $e0
+ .byte $41 ; $e1
+ .byte $a1 ; $e2
+ .byte $41 ; $e3
+ .byte $a0 ; $e4
+ .byte $a1 ; $e5
+ .byte $7f ; $e6
+ .byte $a6 ; $e7
+ .byte $aa ; $e8
+ .byte $a8 ; $e9
+ .byte $a9 ; $ea
+ .byte $a7 ; $eb
+ .byte $49 ; $ec
+ .byte $49 ; $ed
+ .byte $49 ; $ee
+ .byte $49 ; $ef
+ .byte $7f ; $f0
+ .byte $4e ; $f1
+ .byte $4f ; $f2
+ .byte $4f ; $f3
+ .byte $b1 ; $f4
+ .byte $4f ; $f5
+ .byte $ae ; $f6
+ .byte $7f ; $f7
+ .byte $4f ; $f8
+ .byte $55 ; $f9
+ .byte $55 ; $fa
+ .byte $55 ; $fb
+ .byte $b2 ; $fc
+ .byte $59 ; $fd
+ .byte $7f ; $fe
+ .byte $59 ; $ff
+
+; -------------------------------------
+; table PETSCII to ASCII
+;
+; these characters can be typed with
+; the keyboard
+;
+; ascii = $00 means ignore key
+; ascii = $ff menas send string
+; ascii = $fe means do something
+; complicated (command key)
+; -------------------------------------
+petscii_to_ascii:
+ .byte $00 ; $00
+ .byte $01 ; $01
+ .byte $02 ; $02
+ .byte $03 ; $03
+ .byte $04 ; $04
+ .byte $05 ; $05
+ .byte $06 ; $06
+ .byte $07 ; $07
+ .byte $08 ; $08 DEL
+ .byte $09 ; $09 TAB
+ .byte $0a ; $0a
+ .byte $0b ; $0b
+ .byte $0c ; $0c
+ .byte $ff ; $0d CR
+ .byte $0e ; $0e
+ .byte $0f ; $0f
+ .byte $10 ; $10
+ .byte $fe ; $11 ^Q (crsr down)
+ .byte $12 ; $12
+ .byte $fe ; $13 ^S TAB (HOME)
+ .byte $fe ; $14 ^T BS (DEL)
+ .byte $15 ; $15
+ .byte $16 ; $16
+ .byte $17 ; $17
+ .byte $18 ; $18
+ .byte $19 ; $19
+ .byte $1a ; $1a
+ .byte $1b ; $1b ESC
+ .byte $1c ; $1c
+ .byte $fe ; $1d ^](crsr right)
+ .byte $1e ; $1e
+ .byte $1f ; $1f
+ .byte $20 ; $20 SPACE
+ .byte $21 ; $21 !
+ .byte $22 ; $22 "
+ .byte $23 ; $23 #
+ .byte $24 ; $24 $
+ .byte $25 ; $25 %
+ .byte $26 ; $26 &
+ .byte $27 ; $27 '
+ .byte $28 ; $28 (
+ .byte $29 ; $29 )
+ .byte $2a ; $2a *
+ .byte $2b ; $2b +
+ .byte $2c ; $2c ,
+ .byte $2d ; $2d -
+ .byte $2e ; $2e .
+ .byte $2f ; $2f /
+ .byte $30 ; $30 0
+ .byte $31 ; $31 1
+ .byte $32 ; $32 2
+ .byte $33 ; $33 3
+ .byte $34 ; $34 4
+ .byte $35 ; $35 5
+ .byte $36 ; $36 6
+ .byte $37 ; $37 7
+ .byte $38 ; $38 8
+ .byte $39 ; $39 9
+ .byte $3a ; $3a :
+ .byte $3b ; $3b ;
+ .byte $3c ; $3c <
+ .byte $3d ; $3d =
+ .byte $3e ; $3e >
+ .byte $3f ; $3f ?
+ .byte $40 ; $40 @
+ .byte $61 ; $41 a
+ .byte $62 ; $42 b
+ .byte $63 ; $43 c
+ .byte $64 ; $44 d
+ .byte $65 ; $45 e
+ .byte $66 ; $46 f
+ .byte $67 ; $47 g
+ .byte $68 ; $48 h
+ .byte $69 ; $49 i
+ .byte $6a ; $4a j
+ .byte $6b ; $4b k
+ .byte $6c ; $4c l
+ .byte $6d ; $4d m
+ .byte $6e ; $4e n
+ .byte $6f ; $4f o
+ .byte $70 ; $50 p
+ .byte $71 ; $51 q
+ .byte $72 ; $52 r
+ .byte $73 ; $53 s
+ .byte $74 ; $54 t
+ .byte $75 ; $55 u
+ .byte $76 ; $56 v
+ .byte $77 ; $57 w
+ .byte $78 ; $58 x
+ .byte $79 ; $59 y
+ .byte $7a ; $5a z
+ .byte $5b ; $5b [
+ .byte $5c ; $5c \ (Pound)
+ .byte $5d ; $5d ]
+ .byte $5e ; $5e ^
+ .byte $1b ; $5f ESC ( <- )
+ .byte $00 ; $60
+ .byte $41 ; $61 A
+ .byte $42 ; $62 B
+ .byte $43 ; $63 C
+ .byte $44 ; $64 D
+ .byte $45 ; $65 E
+ .byte $46 ; $66 F
+ .byte $47 ; $67 G
+ .byte $48 ; $68 H
+ .byte $49 ; $69 I
+ .byte $4a ; $6a J
+ .byte $4b ; $6b K
+ .byte $4c ; $6c L
+ .byte $4d ; $6d M
+ .byte $4e ; $6e N
+ .byte $4f ; $6f O
+ .byte $50 ; $70 P
+ .byte $51 ; $71 Q
+ .byte $52 ; $72 R
+ .byte $53 ; $73 S
+ .byte $54 ; $74 T
+ .byte $55 ; $75 U
+ .byte $56 ; $76 V
+ .byte $57 ; $77 W
+ .byte $58 ; $78 X
+ .byte $59 ; $79 Y
+ .byte $5a ; $7a Z
+ .byte $00 ; $7b
+ .byte $00 ; $7c
+ .byte $00 ; $7d
+ .byte $00 ; $7e
+ .byte $00 ; $7f
+ .byte $00 ; $80
+ .byte $00 ; $81
+ .byte $00 ; $82
+ .byte $00 ; $83
+ .byte $00 ; $84
+ .byte $00 ; $85 (f1)
+ .byte $00 ; $86 (f3)
+ .byte $00 ; $87 (f5)
+ .byte $00 ; $88 (f7)
+ .byte $00 ; $89 (f2)
+ .byte $00 ; $8a (f4)
+ .byte $00 ; $8b (f6)
+ .byte $00 ; $8c (f8)
+ .byte $00 ; $8d (Shift RET)
+ .byte $00 ; $8e
+ .byte $00 ; $8f
+ .byte $00 ; $90
+ .byte $ff ; $91 (crsr up)
+ .byte $00 ; $92
+ .byte $00 ; $93 (Shift Clr/Home)
+ .byte $7f ; $94 DEL (Shift Ins/Del)
+ .byte $00 ; $95
+ .byte $00 ; $96
+ .byte $00 ; $97
+ .byte $00 ; $98
+ .byte $00 ; $99
+ .byte $00 ; $9a
+ .byte $00 ; $9b
+ .byte $00 ; $9c
+ .byte $ff ; $9d (crsr left)
+ .byte $00 ; $9e
+ .byte $00 ; $9f
+ .byte $00 ; $a0 (Shift Space)
+ .byte $00 ; $a1
+ .byte $00 ; $a2
+ .byte $00 ; $a3
+ .byte $00 ; $a4
+ .byte $00 ; $a5
+ .byte $00 ; $a6
+ .byte $00 ; $a7
+ .byte $00 ; $a8
+ .byte $7c ; $a9 | (Shift Pound)
+ .byte $00 ; $aa
+ .byte $00 ; $ab
+ .byte $fe ; $ac C= D
+ .byte $00 ; $ad
+ .byte $fe ; $ae C= S
+ .byte $00 ; $af
+ .byte $fe ; $b0 C= A
+ .byte $00 ; $b1
+ .byte $fe ; $b2 C= R
+ .byte $00 ; $b3
+ .byte $00 ; $b4
+ .byte $00 ; $b5
+ .byte $fe ; $b6 C= L
+ .byte $00 ; $b7
+ .byte $00 ; $b8
+ .byte $00 ; $b9
+ .byte $60 ; $ba ` ( Shift @ )
+ .byte $00 ; $bb
+ .byte $fe ; $bc C= C
+ .byte $00 ; $bd
+ .byte $00 ; $be
+ .byte $fe ; $bf C= B
+ .byte $5f ; $c0 _ ( Shift * )
+ .byte $41 ; $c1 -----
+ .byte $42 ; $c2
+ .byte $43 ; $c3 capital
+ .byte $44 ; $c4
+ .byte $45 ; $c5 letters
+ .byte $46 ; $c6
+ .byte $47 ; $c7 generate
+ .byte $48 ; $c8
+ .byte $49 ; $c9 these
+ .byte $4a ; $ca
+ .byte $4b ; $cb codes
+ .byte $4c ; $cc
+ .byte $4d ; $cd
+ .byte $4e ; $ce
+ .byte $4f ; $cf
+ .byte $50 ; $d0
+ .byte $51 ; $d1
+ .byte $52 ; $d2
+ .byte $53 ; $d3
+ .byte $54 ; $d4
+ .byte $55 ; $d5
+ .byte $56 ; $d6
+ .byte $57 ; $d7
+ .byte $58 ; $d8
+ .byte $59 ; $d9
+ .byte $5a ; $da -----
+ .byte $7b ; $db { ( Shift + )
+ .byte $00 ; $dc ( C= - )
+ .byte $7d ; $dd } ( Shift - )
+ .byte $7e ; $de ~ ( Pi )
+ .byte $00 ; $df
+ .byte $00 ; $e0
+ .byte $00 ; $e1
+ .byte $00 ; $e2
+ .byte $00 ; $e3
+ .byte $00 ; $e4
+ .byte $00 ; $e5
+ .byte $00 ; $e6
+ .byte $00 ; $e7
+ .byte $00 ; $e8
+ .byte $00 ; $e9
+ .byte $00 ; $ea
+ .byte $00 ; $eb
+ .byte $00 ; $ec
+ .byte $00 ; $ed
+ .byte $00 ; $ee
+ .byte $00 ; $ef
+ .byte $00 ; $f0
+ .byte $00 ; $f1
+ .byte $00 ; $f2
+ .byte $00 ; $f3
+ .byte $00 ; $f4
+ .byte $00 ; $f5
+ .byte $00 ; $f6
+ .byte $00 ; $f7
+ .byte $00 ; $f8
+ .byte $00 ; $f9
+ .byte $00 ; $fa
+ .byte $00 ; $fb
+ .byte $00 ; $fc
+ .byte $00 ; $fd
+ .byte $00 ; $fe
+ .byte $00 ; $ff
+
+ROM_FONT:
+.incbin "../inc/vt100_font.bin"
+
+;-- LICENSE FOR c64_vt100.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 Initial Developer of the Original Code is Lars Stollenwerk.
+;
+; Portions created by the Initial Developer are Copyright (C) 2003
+; Lars Stollenwerk. All Rights Reserved.
+;
+;Contributor(s): Jonno Downes
+; -- LICENSE END --
diff --git a/client/drivers/c64inputs.s b/drivers/c64inputs.s
similarity index 95%
rename from client/drivers/c64inputs.s
rename to drivers/c64inputs.s
index 9c2ff06..d3da674 100644
--- a/client/drivers/c64inputs.s
+++ b/drivers/c64inputs.s
@@ -1,204 +1,204 @@
-.export get_key
-.export get_filtered_input
-.export filter_text
-.export filter_ip
-.export filter_dns
-.export filter_url
-.export filter_number
-.export check_for_abort_key
-.export get_key_if_available
-.export get_key_ip65
-.importzp copy_src
-
-.import ip65_process
-
-.include "../inc/common.i"
-.code
-
-allowed_ptr=copy_src ;reuse zero page
-
-;use C64 Kernel ROM function to read a key
-;inputs: none
-;outputs: A contains ASCII value of key just pressed
-get_key:
- jsr get_key_if_available
- beq get_key
- rts
-
-;use C64 Kernel ROM function to read a key
-;inputs: none
-;outputs: A contains ASCII value of key just pressed (0 if no key pressed)
-get_key_if_available=$f142 ;not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD)
-
-
-;process inbound ip packets while waiting for a keypress
-get_key_ip65:
- jsr ip65_process
- jsr get_key_if_available
- beq get_key_ip65
- rts
-
-
-
-
-;check whether the RUN/STOP key is being pressed
-;inputs: none
-;outputs: sec if RUN/STOP pressed, clear otherwise
-check_for_abort_key:
- lda $cb ;current key pressed
- cmp #$3F
- bne @not_abort
-@flush_loop:
- jsr get_key_if_available
- bne @flush_loop
- lda $cb ;current key pressed
- cmp #$3F
- beq @flush_loop
- sec
- rts
-@not_abort:
- clc
- rts
-
-;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input
-;======================================================================
-;Input a string and store it in GOTINPUT, terminated with a null byte.
-;AX is a pointer to the allowed list of characters, null-terminated.
-;set AX to $0000 for no filter on input
-;max # of chars in y returns num of chars entered in y.
-;======================================================================
-
-
-; Main entry
-get_filtered_input:
- sty MAXCHARS
- stax temp_allowed
-
- ;Zero characters received.
- lda #$00
- sta INPUT_Y
-
-;Wait for a character.
-@input_get:
- jsr get_key
- sta LASTCHAR
-
- cmp #$14 ;Delete
- beq @delete
-
- cmp #$0d ;Return
- beq @input_done
-
- ;End reached?
- lda INPUT_Y
- cmp MAXCHARS
- beq @input_get
-
- ;Check the allowed list of characters.
- ldax temp_allowed
- stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time!
-
- ldy #$00
- lda allowed_ptr+1 ;was the input filter point nul?
- beq @input_ok
-@check_allowed:
- lda (allowed_ptr),y ;Overwritten
- beq @input_get ;Reached end of list (0)
-
- cmp LASTCHAR
- beq @input_ok ;Match found
-
- ;Not end or match, keep checking
- iny
- jmp @check_allowed
-
-@input_ok:
- lda LASTCHAR ;Get the char back
- ldy INPUT_Y
- sta GOTINPUT,y ;Add it to string
- jsr $ffd2 ;Print it
-
- inc INPUT_Y ;Next character
-
- ;Not yet.
- jmp @input_get
-
-@input_done:
- ldy INPUT_Y
- beq @no_input
- lda #$00
- sta GOTINPUT,y ;Zero-terminate
- clc
- ldax #GOTINPUT
- rts
-@no_input:
- sec
- rts
-; Delete last character.
-@delete:
- ;First, check if we're at the beginning. If so, just exit.
- lda INPUT_Y
- bne @delete_ok
- jmp @input_get
-
- ;At least one character entered.
-@delete_ok:
- ;Move pointer back.
- dec INPUT_Y
-
- ;Store a zero over top of last character, just in case no other characters are entered.
- ldy INPUT_Y
- lda #$00
- sta GOTINPUT,y
-
- ;Print the delete char
- lda #$14
- jsr $ffd2
-
- ;Wait for next char
- jmp @input_get
-
-
-;=================================================
-;Some example filters
-;=================================================
-
-filter_text:
- .byte ",!#'()* "
-filter_url:
-.byte ":/%&?+$"
-filter_dns:
-.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-filter_ip:
-.byte "."
-filter_number:
-.byte "1234567890",0
-
-;=================================================
-.bss
-temp_allowed: .res 2
-MAXCHARS: .res 1
-LASTCHAR: .res 1
-INPUT_Y: .res 1
-GOTINPUT: .res 40
-
-
-
-;-- LICENSE FOR c64inputs.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 --
+.export get_key
+.export get_filtered_input
+.export filter_text
+.export filter_ip
+.export filter_dns
+.export filter_url
+.export filter_number
+.export check_for_abort_key
+.export get_key_if_available
+.export get_key_ip65
+.importzp copy_src
+
+.import ip65_process
+
+.include "../inc/common.i"
+.code
+
+allowed_ptr=copy_src ;reuse zero page
+
+;use C64 Kernel ROM function to read a key
+;inputs: none
+;outputs: A contains ASCII value of key just pressed
+get_key:
+ jsr get_key_if_available
+ beq get_key
+ rts
+
+;use C64 Kernel ROM function to read a key
+;inputs: none
+;outputs: A contains ASCII value of key just pressed (0 if no key pressed)
+get_key_if_available=$f142 ;not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD)
+
+
+;process inbound ip packets while waiting for a keypress
+get_key_ip65:
+ jsr ip65_process
+ jsr get_key_if_available
+ beq get_key_ip65
+ rts
+
+
+
+
+;check whether the RUN/STOP key is being pressed
+;inputs: none
+;outputs: sec if RUN/STOP pressed, clear otherwise
+check_for_abort_key:
+ lda $cb ;current key pressed
+ cmp #$3F
+ bne @not_abort
+@flush_loop:
+ jsr get_key_if_available
+ bne @flush_loop
+ lda $cb ;current key pressed
+ cmp #$3F
+ beq @flush_loop
+ sec
+ rts
+@not_abort:
+ clc
+ rts
+
+;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input
+;======================================================================
+;Input a string and store it in GOTINPUT, terminated with a null byte.
+;AX is a pointer to the allowed list of characters, null-terminated.
+;set AX to $0000 for no filter on input
+;max # of chars in y returns num of chars entered in y.
+;======================================================================
+
+
+; Main entry
+get_filtered_input:
+ sty MAXCHARS
+ stax temp_allowed
+
+ ;Zero characters received.
+ lda #$00
+ sta INPUT_Y
+
+;Wait for a character.
+@input_get:
+ jsr get_key
+ sta LASTCHAR
+
+ cmp #$14 ;Delete
+ beq @delete
+
+ cmp #$0d ;Return
+ beq @input_done
+
+ ;End reached?
+ lda INPUT_Y
+ cmp MAXCHARS
+ beq @input_get
+
+ ;Check the allowed list of characters.
+ ldax temp_allowed
+ stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time!
+
+ ldy #$00
+ lda allowed_ptr+1 ;was the input filter point nul?
+ beq @input_ok
+@check_allowed:
+ lda (allowed_ptr),y ;Overwritten
+ beq @input_get ;Reached end of list (0)
+
+ cmp LASTCHAR
+ beq @input_ok ;Match found
+
+ ;Not end or match, keep checking
+ iny
+ jmp @check_allowed
+
+@input_ok:
+ lda LASTCHAR ;Get the char back
+ ldy INPUT_Y
+ sta GOTINPUT,y ;Add it to string
+ jsr $ffd2 ;Print it
+
+ inc INPUT_Y ;Next character
+
+ ;Not yet.
+ jmp @input_get
+
+@input_done:
+ ldy INPUT_Y
+ beq @no_input
+ lda #$00
+ sta GOTINPUT,y ;Zero-terminate
+ clc
+ ldax #GOTINPUT
+ rts
+@no_input:
+ sec
+ rts
+; Delete last character.
+@delete:
+ ;First, check if we're at the beginning. If so, just exit.
+ lda INPUT_Y
+ bne @delete_ok
+ jmp @input_get
+
+ ;At least one character entered.
+@delete_ok:
+ ;Move pointer back.
+ dec INPUT_Y
+
+ ;Store a zero over top of last character, just in case no other characters are entered.
+ ldy INPUT_Y
+ lda #$00
+ sta GOTINPUT,y
+
+ ;Print the delete char
+ lda #$14
+ jsr $ffd2
+
+ ;Wait for next char
+ jmp @input_get
+
+
+;=================================================
+;Some example filters
+;=================================================
+
+filter_text:
+ .byte ",!#'()* "
+filter_url:
+.byte ":/%&?+$"
+filter_dns:
+.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+filter_ip:
+.byte "."
+filter_number:
+.byte "1234567890",0
+
+;=================================================
+.bss
+temp_allowed: .res 2
+MAXCHARS: .res 1
+LASTCHAR: .res 1
+INPUT_Y: .res 1
+GOTINPUT: .res 40
+
+
+
+;-- LICENSE FOR c64inputs.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/drivers/c64kernal.s b/drivers/c64kernal.s
similarity index 96%
rename from client/drivers/c64kernal.s
rename to drivers/c64kernal.s
index 7f4b256..52b862e 100644
--- a/client/drivers/c64kernal.s
+++ b/drivers/c64kernal.s
@@ -1,27 +1,27 @@
-.export exit_to_basic
-
-.code
-; jump to BASIC interpreter loop
-exit_to_basic:
- jmp $a7ae
-
-
-
-;-- LICENSE FOR c64kernal.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 --
+.export exit_to_basic
+
+.code
+; jump to BASIC interpreter loop
+exit_to_basic:
+ jmp $a7ae
+
+
+
+;-- LICENSE FOR c64kernal.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/drivers/c64print.s b/drivers/c64print.s
similarity index 94%
rename from client/drivers/c64print.s
rename to drivers/c64print.s
index e347e6d..fdb2282 100644
--- a/client/drivers/c64print.s
+++ b/drivers/c64print.s
@@ -1,112 +1,112 @@
-
-.export print_a
-.export print_cr
-.export cls
-.export beep
-.export print_a_inverse
-
-.exportzp screen_current_row
-.exportzp screen_current_col
-
-
-screen_current_row=$d6
-screen_current_col=$d3
-
-
-;use C64 Kernel ROM function to print a character to the screen
-;inputs: A contains petscii value of character to print
-;outputs: none
-print_a = $ffd2
-
-.bss
-beep_timer: .res 1
-
-.code
-
-;use C64 Kernel ROM function to move to a new line
-;inputs: none
-;outputs: none
-print_cr:
- lda #13
- jmp print_a
-
-;use C64 Kernel ROM function to clear the screen
-;inputs: none
-;outputs: none
-cls:
- lda #147 ; 'CLR/HOME'
- jmp print_a
-
-;currently does nothing (should make a 'beep noise')
-;inputs: none
-;outputs: none
-beep:
- lda #15
- sta $d418 ;set volume
-
- lda #0
- sta $d405
- lda #240
- sta $d406
- lda #8
- sta $d403
-
- ;tone values for voice 1
- lda #48
- sta $d400
- lda #28
- sta $d401
-
- ;enable tone register
- lda #65
- sta $d404
-
-
-; pause for qtr second
- lda $dd06 ;
- sta beep_timer
- inc beep_timer ;time counts backwards
-:
- lda $dd06 ;
- cmp beep_timer
- bne :-
-
- ;disable tone register
- lda #65
- sta $d404
- lda #0
- sta $d418 ;set volume
-
- rts
-
-
-;print a single char in inverse text:
-print_a_inverse:
- pha
- lda #18 ;inverse mode on
- jsr print_a
- pla
- jsr print_a
- lda #146 ;inverse mode off
- jmp print_a
-
-
-
-;-- LICENSE FOR c64print.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 --
+
+.export print_a
+.export print_cr
+.export cls
+.export beep
+.export print_a_inverse
+
+.exportzp screen_current_row
+.exportzp screen_current_col
+
+
+screen_current_row=$d6
+screen_current_col=$d3
+
+
+;use C64 Kernel ROM function to print a character to the screen
+;inputs: A contains petscii value of character to print
+;outputs: none
+print_a = $ffd2
+
+.bss
+beep_timer: .res 1
+
+.code
+
+;use C64 Kernel ROM function to move to a new line
+;inputs: none
+;outputs: none
+print_cr:
+ lda #13
+ jmp print_a
+
+;use C64 Kernel ROM function to clear the screen
+;inputs: none
+;outputs: none
+cls:
+ lda #147 ; 'CLR/HOME'
+ jmp print_a
+
+;currently does nothing (should make a 'beep noise')
+;inputs: none
+;outputs: none
+beep:
+ lda #15
+ sta $d418 ;set volume
+
+ lda #0
+ sta $d405
+ lda #240
+ sta $d406
+ lda #8
+ sta $d403
+
+ ;tone values for voice 1
+ lda #48
+ sta $d400
+ lda #28
+ sta $d401
+
+ ;enable tone register
+ lda #65
+ sta $d404
+
+
+; pause for qtr second
+ lda $dd06 ;
+ sta beep_timer
+ inc beep_timer ;time counts backwards
+:
+ lda $dd06 ;
+ cmp beep_timer
+ bne :-
+
+ ;disable tone register
+ lda #65
+ sta $d404
+ lda #0
+ sta $d418 ;set volume
+
+ rts
+
+
+;print a single char in inverse text:
+print_a_inverse:
+ pha
+ lda #18 ;inverse mode on
+ jsr print_a
+ pla
+ jsr print_a
+ lda #146 ;inverse mode off
+ jmp print_a
+
+
+
+;-- LICENSE FOR c64print.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/drivers/c64timer.s b/drivers/c64timer.s
similarity index 95%
rename from client/drivers/c64timer.s
rename to drivers/c64timer.s
index cf3e4a3..9b595f8 100644
--- a/client/drivers/c64timer.s
+++ b/drivers/c64timer.s
@@ -1,70 +1,70 @@
-; timer routines
-;
-; the timer should be a 16-bit counter that's incremented by about
-; 1000 units per second. it doesn't have to be particularly accurate.
-
- .include "../inc/common.i"
-
- .export timer_init
- .export timer_read
- .export timer_seconds ; this should return a single BCD byte (00..59) which is a count of seconds
- .code
-
-; initialize timers
-timer_init:
- lda #$80 ; stop timers
- sta $dd0e
- sta $dd0f
-
- ldax #999 ; timer A to 1000 cycles
- stax $dd04
-
- ldax #$ffff ; timer B to max cycles
- stax $dd06
-
- lda #$81 ; timer A in continuous mode
- sta $dd0e
-
- lda #$c1 ; timer B to count timer A underflows
- sta $dd0f
-
- lda #0
- sta $dc08
- sta $dc09
- rts
-
-timer_seconds:
- lda $dc09
- rts
-
-; return the current value
-timer_read:
- lda $dd07 ; cia counts backwards, return inverted value
- eor #$ff
- tax
- lda $dd06
- eor #$ff
- rts
-
-
-
-
-
-;-- LICENSE FOR c64timer.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 --
+; timer routines
+;
+; the timer should be a 16-bit counter that's incremented by about
+; 1000 units per second. it doesn't have to be particularly accurate.
+
+ .include "../inc/common.i"
+
+ .export timer_init
+ .export timer_read
+ .export timer_seconds ; this should return a single BCD byte (00..59) which is a count of seconds
+ .code
+
+; initialize timers
+timer_init:
+ lda #$80 ; stop timers
+ sta $dd0e
+ sta $dd0f
+
+ ldax #999 ; timer A to 1000 cycles
+ stax $dd04
+
+ ldax #$ffff ; timer B to max cycles
+ stax $dd06
+
+ lda #$81 ; timer A in continuous mode
+ sta $dd0e
+
+ lda #$c1 ; timer B to count timer A underflows
+ sta $dd0f
+
+ lda #0
+ sta $dc08
+ sta $dc09
+ rts
+
+timer_seconds:
+ lda $dc09
+ rts
+
+; return the current value
+timer_read:
+ lda $dd07 ; cia counts backwards, return inverted value
+ eor #$ff
+ tax
+ lda $dd06
+ eor #$ff
+ rts
+
+
+
+
+
+;-- LICENSE FOR c64timer.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/drivers/cbm_disk_access.s b/drivers/cbm_disk_access.s
similarity index 95%
rename from client/drivers/cbm_disk_access.s
rename to drivers/cbm_disk_access.s
index ffef124..726ea86 100644
--- a/client/drivers/cbm_disk_access.s
+++ b/drivers/cbm_disk_access.s
@@ -1,642 +1,642 @@
-;C64 disk access routines
-;
-
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../inc/common.i"
-.export io_device_no
-.export io_sector_no
-.export io_track_no
-.export io_read_sector
-.export io_write_sector
-.export io_read_catalogue
-.export io_read_catalogue_ex
-.export io_read_file
-.export io_read_file_with_callback
-.export io_filename
-.export io_filesize
-.export io_load_address
-.export io_callback
-.export io_error_buffer
-
-.importzp copy_src
-.import ip65_error
-.import output_buffer
-.importzp copy_dest
-
-
-io_error_buffer=error_buffer
-;reuse the copy_src zero page location
-buffer_ptr = copy_src
-
-;######### KERNEL functions
-CHKIN = $ffc6
-CHKOUT = $ffc9
-CHRIN = $ffcf
-CHROUT = $ffd2
-CLRCHN = $ffcc
-CLALL = $FFE7
-CLOSE = $ffc3
-OPEN = $ffc0
-READST = $ffb7
-SETNAM = $ffbd
-SETLFS = $ffba
-
-.segment "SELF_MODIFIED_CODE"
-
- io_track_no: .res 2
- io_sector_no: .res 1
- io_device_no: .byte 0
- io_filename: .res 2
- io_filesize: .res 2 ;although a file on disk can be >64K, io_filesize is only used when loading into RAM hence file must be <64K
- io_load_address: .res 2
- error_buffer = output_buffer + 256
- command_buffer = error_buffer+128
- sector_buffer_address: .res 2
- buffer_counter: .res 1
- extended_catalogue_flag: .res 1
-
-
- drive_id: .byte 08 ;default to drive 8
-
-jmp_to_callback:
- jmp $ffff
-io_callback=jmp_to_callback+1
-
-
-write_byte_to_buffer:
-tmp_buffer_ptr=write_byte_to_buffer+1
- sta $ffff
- inc tmp_buffer_ptr
- bne :+
- inc tmp_buffer_ptr+1
-:
- rts
-
-
-.code
-
-;routine to read a file
-; inputs:
-; io_device_number - specifies drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
-; io_filename - specifies filename to open
-; AX - address of buffer to read file into (set to $0000 to treat first 2 bytes as load address)
-; outputs:
-; on errror, carry flag is set
-; otherwise, io_filesize will be set to size of file and io_load_address will be set to actual load address used.
-;
-io_read_file:
- stax io_load_address
- sta sector_buffer_address
- stx sector_buffer_address+1 ;this also sets the Z flag
- bne @sector_buffer_address_set
- ;if we get here, X was $00 so we need to use first 2 bytes of file as load address
- ldax #output_buffer
- stax sector_buffer_address
-
-@sector_buffer_address_set:
- ldax #read_file_callback
- stax io_callback
- lda #0
- sta io_filesize
- sta io_filesize+1
- ldax sector_buffer_address
- jsr io_read_file_with_callback
- rts
-
-read_file_callback:
- sty io_filesize ;only 1 (the last) sector can ever be !=$100 bytes
- bne @not_full_sector
- inc io_filesize+1
- inc sector_buffer_address +1
-@not_full_sector:
- lda io_load_address+1 ;is the high byte of the address $00?
- bne @done
- ldax output_buffer ;if we get here we must have used downloaded into the static output buffer, so the
- ;first 2 bytes there are the real load address
- stax copy_dest ;now copy the rest of the sector
- stax sector_buffer_address
- stax io_load_address
- dey
- dey
-@copy_one_byte:
- dey
- lda output_buffer+2,y
- sta (copy_dest),y
- inc sector_buffer_address
- bne :+
- inc sector_buffer_address+1
-:
- tya
- bne @copy_one_byte
-
-@done:
- rts
-
-;routine to read a file with a callback after each 256 byte sector
-; inputs:
-; io_device_number - specifies drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
-; io_filename - specifies filename to open
-; io_callback - address of routine to be called after each sector is read
-; AX - address of buffer to read sector into
-; outputs:
-; on errror, carry flag is set
-
-io_read_file_with_callback:
-
- stax sector_buffer_address
- jsr CLALL
- jsr parse_filename
-
- jsr SETNAM
-
- jsr set_drive_id
- lda #$02 ; file number 2
- ldx drive_id
-
- ldy #02 ; secondary address 2
- jsr SETLFS
- jsr OPEN
-
- bcs @device_error ; if carry set, the device could not be addressed
-
- ;we should now check for file access errors
- jsr open_error_channel
-@no_error_opening_error_channel:
- jsr check_error_channel
- lda #$30
- cmp error_buffer
-
- beq @was_not_an_error
-@readerror:
- lda #KPR_ERROR_FILE_ACCESS_FAILURE
- sta ip65_error
- sec
- rts
- @was_not_an_error:
-
-@get_next_sector:
- ldx #$02 ;file number 2
- jsr CHKIN ;file 2 now used as input
-
- ldax sector_buffer_address
- stax buffer_ptr
- lda #$00
- sta buffer_counter
-@get_next_byte:
- jsr READST
- bne @eof
- jsr CHRIN
- ldy buffer_counter
- sta (buffer_ptr),y
- inc buffer_counter
- bne @get_next_byte
- ldy #$00;= 256 bytes
-
- jsr jmp_to_callback
- jmp @get_next_sector
-
-@eof:
- and #$40 ; end of file?
- beq @readerror
-
- ;we have part loaded a sector
- ldy buffer_counter
- beq @empty_sector
- jsr jmp_to_callback
-@empty_sector:
-
-@close:
- jmp close_filenumber_2
-@device_error:
- lda #KPR_ERROR_DEVICE_FAILURE
- sta ip65_error
- ldx #$00
- jsr CHKIN
- sec
- rts
-
-
-
-;io_filename is null-terminated.
-;this routines sets up up A,X,Y as needed by kernal routines i.e. XY=pointer to name, A = length of name
-parse_filename:
- ldax io_filename
- stax buffer_ptr
- ldy #$ff
-@next_byte:
- iny
- lda (buffer_ptr),y
- bne @next_byte
- tya
- ldx buffer_ptr
- ldy buffer_ptr+1
- rts
-
-;routine to catalogue disk (with filename, filetype, filesize)
-; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
-; AX - address of buffer to read catalogue into
-; outputs:
-; on errror, carry flag is set.
-; otherwise, buffer will be filled with asciiz filenames,followed by 1 byte filetype, followed by 2 byte file length (in 256 byte sectors)
-; there is an extra zero at the end of the last file.
-io_read_catalogue_ex:
- stax tmp_buffer_ptr
- lda #1
- bne extended_catalogue_flag_set
-
-;routine to catalogue disk (filenames only)
-; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
-; AX - address of buffer to read catalogue into
-; outputs:
-; on errror, carry flag is set.
-; otherwise, buffer will be filled with asciiz filenames (and an extra zero at the end of the last filename)
-io_read_catalogue:
- stax tmp_buffer_ptr
- lda #0
-extended_catalogue_flag_set:
- sta extended_catalogue_flag
- ;get the BAM
- lda #$12
- sta io_track_no
- lda #00
- sta io_sector_no
-
- ldax #output_buffer
- jsr io_read_sector
- bcs @end_catalogue
-
-@get_next_catalogue_sector:
-
- clc
- lda output_buffer
- beq @end_catalogue
- sta io_track_no
- lda output_buffer+1
- sta io_sector_no
- ldax #output_buffer
- jsr io_read_sector
- bcs @end_catalogue
- ldy #0
-
-
-@read_one_file:
- tya
- pha
-
- lda output_buffer+2,y ;file type
- and #$7f
- beq @skip_to_next_file
-
-@get_next_char:
- lda output_buffer+5,y ;file name
- beq @end_of_filename
- cmp #$a0
- beq @end_of_filename
- jsr write_byte_to_buffer
- iny
- jmp @get_next_char
-@end_of_filename:
- lda #0
- jsr write_byte_to_buffer
- pla
- pha
-
- tay ;get Y back to start of this file entry
-
- lda extended_catalogue_flag ;do we need to include the 'extended' data?
- beq @skip_to_next_file
- lda output_buffer+2,y ;file type
- jsr write_byte_to_buffer
- lda output_buffer+30,y ;lo byte of file length in sectors
- jsr write_byte_to_buffer
- lda output_buffer+31,y ;hi byte of file length in sectors
- jsr write_byte_to_buffer
-@skip_to_next_file:
- pla
- clc
- adc #$20
- tay
- bne @read_one_file
- jmp @get_next_catalogue_sector
-@end_catalogue:
- lda #0
- jsr write_byte_to_buffer
- jsr write_byte_to_buffer
- rts
-
-set_drive_id:
- lda io_device_no
- beq @drive_id_set
- clc
- adc #07 ;so 01->08, 02->09 etc
- sta drive_id
-@drive_id_set:
- rts
-
-;routine to write a sector
-;cribbed from http://codebase64.org/doku.php?id=base:writing_a_sector_to_disk (credited to "Graham")
-;inputs:
-; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
-; io_sector_no - set to sector number to be written
-; io_track_no - set to track number to be written (only lo byte is used)
-; AX - address of buffer to to write to sector
-; outputs:; on errror, carry flag is set.
-io_write_sector:
- stax sector_buffer_address
- jsr set_drive_id
- jsr CLALL
- lda #$32 ;"2"
- jsr make_user_command
- lda #1
- ldx #cname
- jsr SETNAM
- lda #02
- ldx drive_id
- ldy #02
- jsr SETLFS
- jsr OPEN
- bcs @error
-
- lda #7
- ldx #bpname
- jsr SETNAM
- lda #15
- ldx drive_id
- ldy #15
- jsr SETLFS
- jsr OPEN
- bcs @error
-
- jsr check_error_channel
- lda #$30
- cmp error_buffer
- bne @error
-
- ldx #$02 ; filenumber 2
- jsr CHKOUT ; file 2 now used as output
-
- ldax sector_buffer_address
- stax buffer_ptr
- ldy #0
-:
- lda (buffer_ptr),y ;get next byte in sector
- jsr CHROUT ;write it out
- iny
- bne :-
-
- ldx #$0F ; filenumber 15
- jsr CHKOUT ; file 15 now used as output
-
- ldy #$00
-:
- lda command_buffer,y
- beq :+
- jsr CHROUT ;write byte to command channel
- iny
- bne :-
-:
-
- lda #$0d ; carriage return, required to start command
- jsr CHROUT ;write it out
- jsr check_error_channel
- lda #$30
- cmp error_buffer
- bne @error
-
-@close:
- jsr close_filenumbers_2_and_15
- jsr CLRCHN
- clc
- rts
-
-@error:
- lda #KPR_ERROR_DEVICE_FAILURE
- sta ip65_error
- jsr @close
- sec
- rts
-
-
-close_filenumbers_2_and_15:
- lda #15 ; filenumber 15
- jsr CLOSE
-close_filenumber_2:
- lda #$02 ; filenumber 2
- jsr CLOSE
- ldx #$00 ; filenumber 0 = keyboard
- jsr CHKIN ;(keyboard now input device again)
- clc
- rts
-
-;routine to read a sector (credited to "Graham")
-;cribbed from http://codebase64.org/doku.php?id=base:reading_a_sector_from_disk
-;inputs:
-; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
-; io_sector_no - set to sector number to be read
-; io_track_no - set to track number to be read (only lo byte is used)
-; AX - address of buffer to read sector into
-; outputs:
-; on errror, carry flag is set. otherwise buffer will be filled with 256 bytes
-
-io_read_sector:
-
- stax sector_buffer_address
- jsr set_drive_id
- jsr CLALL
- lda #$31 ;"1"
- jsr make_user_command
- lda #1
- ldx #cname
- jsr SETNAM
- lda #02
- ldx drive_id
- ldy #02
- jsr SETLFS
- jsr OPEN
- bcs @error
- ldx #command_buffer
- lda #12
- jsr SETNAM
- lda #15
- ldx $BA ;use whatever was last device #
- ldy #15
- jsr SETLFS
- jsr OPEN
- bcs @error
-
- jsr check_error_channel
- lda #$30
- cmp error_buffer
- bne @error
-
- ldx #$02 ; filenumber 2
- jsr CHKIN ;(file 2 now used as input)
-
- lda sector_buffer_address
- sta buffer_ptr
- lda sector_buffer_address+1
- sta buffer_ptr+1
- ldy #$00
-@loop:
- jsr CHRIN ;(get a byte from file)
- sta (buffer_ptr),Y ; write byte to memory
- iny
- bne @loop ; next byte, end when 256 bytes are read
-@close:
- jmp close_filenumbers_2_and_15
-@error:
- lda #KPR_ERROR_DEVICE_FAILURE
- sta ip65_error
- jsr @close
- sec
- rts
-
-open_error_channel:
- lda #$00 ; no filename
- tax
- tay
- jsr SETNAM
- lda #$0f ;file number 15
- ldx drive_id
- ldy #$0f ; secondary address 15 (error channel)
- jsr SETLFS
- jsr OPEN
-
- rts
-
-
-check_error_channel:
- LDX #$0F ; filenumber 15
- JSR CHKIN ;(file 15 now used as input)
- LDY #$00
-@loop:
- JSR READST ;(read status byte)
- BNE @eof ; either EOF or read error
- JSR CHRIN ;(get a byte from file)
- sta error_buffer,y
- iny
-
- JMP @loop ; next byte
-
-@eof:
- lda #0
- sta error_buffer,y
- LDX #$00 ; filenumber 0 = keyboard
- JSR CHKIN ;(keyboard now input device again)
- rts
-
-make_user_command:
-;fill command buffer with "U " command, where "x" is passed in via A
-;i.e. A=1 makes command to read in track & sector
-;A=2 makes command to write track & sector
-;returns length of command in Y
-
- pha
- ldy #0
- lda #85 ;"U"
- sta command_buffer,y
- iny
- pla
- sta command_buffer,y
- iny
- lda #$20 ;" "
- sta command_buffer,y
- iny
- lda #$32 ;"2" - file number
- sta command_buffer,y
- iny
- lda #$20 ;" "
- sta command_buffer,y
- iny
- lda #$30 ;"0" - drive number
- sta command_buffer,y
- iny
- lda #$20 ;" "
- sta command_buffer,y
- iny
- lda io_track_no
- jsr byte_to_ascii
- pha
- txa
- sta command_buffer,y
- pla
- iny
- sta command_buffer,y
- iny
- lda #$20 ;" "
- sta command_buffer,y
- iny
- lda io_sector_no
- jsr byte_to_ascii
- pha
- txa
- sta command_buffer,y
- pla
- iny
- sta command_buffer,y
- iny
-
- lda #0
- sta command_buffer,y ;make it ASCIIZ so we can print it
-
- rts
-
-byte_to_ascii:
- cmp #30
- bmi @not_30
- ldx #$33
- clc
- adc #18
- rts
-@not_30:
- cmp #20
- bmi @not_20
- ldx #$32
- clc
- adc #28
- rts
-@not_20:
- cmp #10
- bmi @not_10
- ldx #$31
- clc
- adc #38
- rts
-@not_10:
- ldx #$30
- clc
- adc #48
- rts
-
-.rodata
-cname: .byte '#'
-bpname: .byte "B-P 2 0"
-
-
-;-- LICENSE FOR c64_disk_access.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 --
+;C64 disk access routines
+;
+
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../inc/common.i"
+.export io_device_no
+.export io_sector_no
+.export io_track_no
+.export io_read_sector
+.export io_write_sector
+.export io_read_catalogue
+.export io_read_catalogue_ex
+.export io_read_file
+.export io_read_file_with_callback
+.export io_filename
+.export io_filesize
+.export io_load_address
+.export io_callback
+.export io_error_buffer
+
+.importzp copy_src
+.import ip65_error
+.import output_buffer
+.importzp copy_dest
+
+
+io_error_buffer=error_buffer
+;reuse the copy_src zero page location
+buffer_ptr = copy_src
+
+;######### KERNEL functions
+CHKIN = $ffc6
+CHKOUT = $ffc9
+CHRIN = $ffcf
+CHROUT = $ffd2
+CLRCHN = $ffcc
+CLALL = $FFE7
+CLOSE = $ffc3
+OPEN = $ffc0
+READST = $ffb7
+SETNAM = $ffbd
+SETLFS = $ffba
+
+.segment "SELF_MODIFIED_CODE"
+
+ io_track_no: .res 2
+ io_sector_no: .res 1
+ io_device_no: .byte 0
+ io_filename: .res 2
+ io_filesize: .res 2 ;although a file on disk can be >64K, io_filesize is only used when loading into RAM hence file must be <64K
+ io_load_address: .res 2
+ error_buffer = output_buffer + 256
+ command_buffer = error_buffer+128
+ sector_buffer_address: .res 2
+ buffer_counter: .res 1
+ extended_catalogue_flag: .res 1
+
+
+ drive_id: .byte 08 ;default to drive 8
+
+jmp_to_callback:
+ jmp $ffff
+io_callback=jmp_to_callback+1
+
+
+write_byte_to_buffer:
+tmp_buffer_ptr=write_byte_to_buffer+1
+ sta $ffff
+ inc tmp_buffer_ptr
+ bne :+
+ inc tmp_buffer_ptr+1
+:
+ rts
+
+
+.code
+
+;routine to read a file
+; inputs:
+; io_device_number - specifies drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
+; io_filename - specifies filename to open
+; AX - address of buffer to read file into (set to $0000 to treat first 2 bytes as load address)
+; outputs:
+; on errror, carry flag is set
+; otherwise, io_filesize will be set to size of file and io_load_address will be set to actual load address used.
+;
+io_read_file:
+ stax io_load_address
+ sta sector_buffer_address
+ stx sector_buffer_address+1 ;this also sets the Z flag
+ bne @sector_buffer_address_set
+ ;if we get here, X was $00 so we need to use first 2 bytes of file as load address
+ ldax #output_buffer
+ stax sector_buffer_address
+
+@sector_buffer_address_set:
+ ldax #read_file_callback
+ stax io_callback
+ lda #0
+ sta io_filesize
+ sta io_filesize+1
+ ldax sector_buffer_address
+ jsr io_read_file_with_callback
+ rts
+
+read_file_callback:
+ sty io_filesize ;only 1 (the last) sector can ever be !=$100 bytes
+ bne @not_full_sector
+ inc io_filesize+1
+ inc sector_buffer_address +1
+@not_full_sector:
+ lda io_load_address+1 ;is the high byte of the address $00?
+ bne @done
+ ldax output_buffer ;if we get here we must have used downloaded into the static output buffer, so the
+ ;first 2 bytes there are the real load address
+ stax copy_dest ;now copy the rest of the sector
+ stax sector_buffer_address
+ stax io_load_address
+ dey
+ dey
+@copy_one_byte:
+ dey
+ lda output_buffer+2,y
+ sta (copy_dest),y
+ inc sector_buffer_address
+ bne :+
+ inc sector_buffer_address+1
+:
+ tya
+ bne @copy_one_byte
+
+@done:
+ rts
+
+;routine to read a file with a callback after each 256 byte sector
+; inputs:
+; io_device_number - specifies drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
+; io_filename - specifies filename to open
+; io_callback - address of routine to be called after each sector is read
+; AX - address of buffer to read sector into
+; outputs:
+; on errror, carry flag is set
+
+io_read_file_with_callback:
+
+ stax sector_buffer_address
+ jsr CLALL
+ jsr parse_filename
+
+ jsr SETNAM
+
+ jsr set_drive_id
+ lda #$02 ; file number 2
+ ldx drive_id
+
+ ldy #02 ; secondary address 2
+ jsr SETLFS
+ jsr OPEN
+
+ bcs @device_error ; if carry set, the device could not be addressed
+
+ ;we should now check for file access errors
+ jsr open_error_channel
+@no_error_opening_error_channel:
+ jsr check_error_channel
+ lda #$30
+ cmp error_buffer
+
+ beq @was_not_an_error
+@readerror:
+ lda #KPR_ERROR_FILE_ACCESS_FAILURE
+ sta ip65_error
+ sec
+ rts
+ @was_not_an_error:
+
+@get_next_sector:
+ ldx #$02 ;file number 2
+ jsr CHKIN ;file 2 now used as input
+
+ ldax sector_buffer_address
+ stax buffer_ptr
+ lda #$00
+ sta buffer_counter
+@get_next_byte:
+ jsr READST
+ bne @eof
+ jsr CHRIN
+ ldy buffer_counter
+ sta (buffer_ptr),y
+ inc buffer_counter
+ bne @get_next_byte
+ ldy #$00;= 256 bytes
+
+ jsr jmp_to_callback
+ jmp @get_next_sector
+
+@eof:
+ and #$40 ; end of file?
+ beq @readerror
+
+ ;we have part loaded a sector
+ ldy buffer_counter
+ beq @empty_sector
+ jsr jmp_to_callback
+@empty_sector:
+
+@close:
+ jmp close_filenumber_2
+@device_error:
+ lda #KPR_ERROR_DEVICE_FAILURE
+ sta ip65_error
+ ldx #$00
+ jsr CHKIN
+ sec
+ rts
+
+
+
+;io_filename is null-terminated.
+;this routines sets up up A,X,Y as needed by kernal routines i.e. XY=pointer to name, A = length of name
+parse_filename:
+ ldax io_filename
+ stax buffer_ptr
+ ldy #$ff
+@next_byte:
+ iny
+ lda (buffer_ptr),y
+ bne @next_byte
+ tya
+ ldx buffer_ptr
+ ldy buffer_ptr+1
+ rts
+
+;routine to catalogue disk (with filename, filetype, filesize)
+; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
+; AX - address of buffer to read catalogue into
+; outputs:
+; on errror, carry flag is set.
+; otherwise, buffer will be filled with asciiz filenames,followed by 1 byte filetype, followed by 2 byte file length (in 256 byte sectors)
+; there is an extra zero at the end of the last file.
+io_read_catalogue_ex:
+ stax tmp_buffer_ptr
+ lda #1
+ bne extended_catalogue_flag_set
+
+;routine to catalogue disk (filenames only)
+; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
+; AX - address of buffer to read catalogue into
+; outputs:
+; on errror, carry flag is set.
+; otherwise, buffer will be filled with asciiz filenames (and an extra zero at the end of the last filename)
+io_read_catalogue:
+ stax tmp_buffer_ptr
+ lda #0
+extended_catalogue_flag_set:
+ sta extended_catalogue_flag
+ ;get the BAM
+ lda #$12
+ sta io_track_no
+ lda #00
+ sta io_sector_no
+
+ ldax #output_buffer
+ jsr io_read_sector
+ bcs @end_catalogue
+
+@get_next_catalogue_sector:
+
+ clc
+ lda output_buffer
+ beq @end_catalogue
+ sta io_track_no
+ lda output_buffer+1
+ sta io_sector_no
+ ldax #output_buffer
+ jsr io_read_sector
+ bcs @end_catalogue
+ ldy #0
+
+
+@read_one_file:
+ tya
+ pha
+
+ lda output_buffer+2,y ;file type
+ and #$7f
+ beq @skip_to_next_file
+
+@get_next_char:
+ lda output_buffer+5,y ;file name
+ beq @end_of_filename
+ cmp #$a0
+ beq @end_of_filename
+ jsr write_byte_to_buffer
+ iny
+ jmp @get_next_char
+@end_of_filename:
+ lda #0
+ jsr write_byte_to_buffer
+ pla
+ pha
+
+ tay ;get Y back to start of this file entry
+
+ lda extended_catalogue_flag ;do we need to include the 'extended' data?
+ beq @skip_to_next_file
+ lda output_buffer+2,y ;file type
+ jsr write_byte_to_buffer
+ lda output_buffer+30,y ;lo byte of file length in sectors
+ jsr write_byte_to_buffer
+ lda output_buffer+31,y ;hi byte of file length in sectors
+ jsr write_byte_to_buffer
+@skip_to_next_file:
+ pla
+ clc
+ adc #$20
+ tay
+ bne @read_one_file
+ jmp @get_next_catalogue_sector
+@end_catalogue:
+ lda #0
+ jsr write_byte_to_buffer
+ jsr write_byte_to_buffer
+ rts
+
+set_drive_id:
+ lda io_device_no
+ beq @drive_id_set
+ clc
+ adc #07 ;so 01->08, 02->09 etc
+ sta drive_id
+@drive_id_set:
+ rts
+
+;routine to write a sector
+;cribbed from http://codebase64.org/doku.php?id=base:writing_a_sector_to_disk (credited to "Graham")
+;inputs:
+; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
+; io_sector_no - set to sector number to be written
+; io_track_no - set to track number to be written (only lo byte is used)
+; AX - address of buffer to to write to sector
+; outputs:; on errror, carry flag is set.
+io_write_sector:
+ stax sector_buffer_address
+ jsr set_drive_id
+ jsr CLALL
+ lda #$32 ;"2"
+ jsr make_user_command
+ lda #1
+ ldx #cname
+ jsr SETNAM
+ lda #02
+ ldx drive_id
+ ldy #02
+ jsr SETLFS
+ jsr OPEN
+ bcs @error
+
+ lda #7
+ ldx #bpname
+ jsr SETNAM
+ lda #15
+ ldx drive_id
+ ldy #15
+ jsr SETLFS
+ jsr OPEN
+ bcs @error
+
+ jsr check_error_channel
+ lda #$30
+ cmp error_buffer
+ bne @error
+
+ ldx #$02 ; filenumber 2
+ jsr CHKOUT ; file 2 now used as output
+
+ ldax sector_buffer_address
+ stax buffer_ptr
+ ldy #0
+:
+ lda (buffer_ptr),y ;get next byte in sector
+ jsr CHROUT ;write it out
+ iny
+ bne :-
+
+ ldx #$0F ; filenumber 15
+ jsr CHKOUT ; file 15 now used as output
+
+ ldy #$00
+:
+ lda command_buffer,y
+ beq :+
+ jsr CHROUT ;write byte to command channel
+ iny
+ bne :-
+:
+
+ lda #$0d ; carriage return, required to start command
+ jsr CHROUT ;write it out
+ jsr check_error_channel
+ lda #$30
+ cmp error_buffer
+ bne @error
+
+@close:
+ jsr close_filenumbers_2_and_15
+ jsr CLRCHN
+ clc
+ rts
+
+@error:
+ lda #KPR_ERROR_DEVICE_FAILURE
+ sta ip65_error
+ jsr @close
+ sec
+ rts
+
+
+close_filenumbers_2_and_15:
+ lda #15 ; filenumber 15
+ jsr CLOSE
+close_filenumber_2:
+ lda #$02 ; filenumber 2
+ jsr CLOSE
+ ldx #$00 ; filenumber 0 = keyboard
+ jsr CHKIN ;(keyboard now input device again)
+ clc
+ rts
+
+;routine to read a sector (credited to "Graham")
+;cribbed from http://codebase64.org/doku.php?id=base:reading_a_sector_from_disk
+;inputs:
+; io_device_number set to specify drive to use ($00 = same as last time, $01 = first disk (i.e. #8), $02 = 2nd disk (drive #9))
+; io_sector_no - set to sector number to be read
+; io_track_no - set to track number to be read (only lo byte is used)
+; AX - address of buffer to read sector into
+; outputs:
+; on errror, carry flag is set. otherwise buffer will be filled with 256 bytes
+
+io_read_sector:
+
+ stax sector_buffer_address
+ jsr set_drive_id
+ jsr CLALL
+ lda #$31 ;"1"
+ jsr make_user_command
+ lda #1
+ ldx #cname
+ jsr SETNAM
+ lda #02
+ ldx drive_id
+ ldy #02
+ jsr SETLFS
+ jsr OPEN
+ bcs @error
+ ldx #command_buffer
+ lda #12
+ jsr SETNAM
+ lda #15
+ ldx $BA ;use whatever was last device #
+ ldy #15
+ jsr SETLFS
+ jsr OPEN
+ bcs @error
+
+ jsr check_error_channel
+ lda #$30
+ cmp error_buffer
+ bne @error
+
+ ldx #$02 ; filenumber 2
+ jsr CHKIN ;(file 2 now used as input)
+
+ lda sector_buffer_address
+ sta buffer_ptr
+ lda sector_buffer_address+1
+ sta buffer_ptr+1
+ ldy #$00
+@loop:
+ jsr CHRIN ;(get a byte from file)
+ sta (buffer_ptr),Y ; write byte to memory
+ iny
+ bne @loop ; next byte, end when 256 bytes are read
+@close:
+ jmp close_filenumbers_2_and_15
+@error:
+ lda #KPR_ERROR_DEVICE_FAILURE
+ sta ip65_error
+ jsr @close
+ sec
+ rts
+
+open_error_channel:
+ lda #$00 ; no filename
+ tax
+ tay
+ jsr SETNAM
+ lda #$0f ;file number 15
+ ldx drive_id
+ ldy #$0f ; secondary address 15 (error channel)
+ jsr SETLFS
+ jsr OPEN
+
+ rts
+
+
+check_error_channel:
+ LDX #$0F ; filenumber 15
+ JSR CHKIN ;(file 15 now used as input)
+ LDY #$00
+@loop:
+ JSR READST ;(read status byte)
+ BNE @eof ; either EOF or read error
+ JSR CHRIN ;(get a byte from file)
+ sta error_buffer,y
+ iny
+
+ JMP @loop ; next byte
+
+@eof:
+ lda #0
+ sta error_buffer,y
+ LDX #$00 ; filenumber 0 = keyboard
+ JSR CHKIN ;(keyboard now input device again)
+ rts
+
+make_user_command:
+;fill command buffer with "U " command, where "x" is passed in via A
+;i.e. A=1 makes command to read in track & sector
+;A=2 makes command to write track & sector
+;returns length of command in Y
+
+ pha
+ ldy #0
+ lda #85 ;"U"
+ sta command_buffer,y
+ iny
+ pla
+ sta command_buffer,y
+ iny
+ lda #$20 ;" "
+ sta command_buffer,y
+ iny
+ lda #$32 ;"2" - file number
+ sta command_buffer,y
+ iny
+ lda #$20 ;" "
+ sta command_buffer,y
+ iny
+ lda #$30 ;"0" - drive number
+ sta command_buffer,y
+ iny
+ lda #$20 ;" "
+ sta command_buffer,y
+ iny
+ lda io_track_no
+ jsr byte_to_ascii
+ pha
+ txa
+ sta command_buffer,y
+ pla
+ iny
+ sta command_buffer,y
+ iny
+ lda #$20 ;" "
+ sta command_buffer,y
+ iny
+ lda io_sector_no
+ jsr byte_to_ascii
+ pha
+ txa
+ sta command_buffer,y
+ pla
+ iny
+ sta command_buffer,y
+ iny
+
+ lda #0
+ sta command_buffer,y ;make it ASCIIZ so we can print it
+
+ rts
+
+byte_to_ascii:
+ cmp #30
+ bmi @not_30
+ ldx #$33
+ clc
+ adc #18
+ rts
+@not_30:
+ cmp #20
+ bmi @not_20
+ ldx #$32
+ clc
+ adc #28
+ rts
+@not_20:
+ cmp #10
+ bmi @not_10
+ ldx #$31
+ clc
+ adc #38
+ rts
+@not_10:
+ ldx #$30
+ clc
+ adc #48
+ rts
+
+.rodata
+cname: .byte '#'
+bpname: .byte "B-P 2 0"
+
+
+;-- LICENSE FOR c64_disk_access.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/drivers/cs8900a.i b/drivers/cs8900a.i
similarity index 96%
rename from client/drivers/cs8900a.i
rename to drivers/cs8900a.i
index 4a0bbc0..277db1a 100644
--- a/client/drivers/cs8900a.i
+++ b/drivers/cs8900a.i
@@ -1,31 +1,31 @@
-;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
-
-pp_rx_ctl = $0104
-pp_line_ctl = $0112
-pp_self_ctl = $0114
-pp_bus_status = $0138
-pp_ia = $0158
-
-
-
-
-
-
-;-- LICENSE FOR cs8900a.i --
-; 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 --
+;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
+
+pp_rx_ctl = $0104
+pp_line_ctl = $0112
+pp_self_ctl = $0114
+pp_bus_status = $0138
+pp_ia = $0158
+
+
+
+
+
+
+;-- LICENSE FOR cs8900a.i --
+; 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/drivers/cs8900a.s b/drivers/cs8900a.s
similarity index 94%
rename from client/drivers/cs8900a.s
rename to drivers/cs8900a.s
index d967fd9..d844541 100644
--- a/client/drivers/cs8900a.s
+++ b/drivers/cs8900a.s
@@ -1,292 +1,292 @@
-; Ethernet driver for CS8900A chip (as used in RR-NET and Uthernet adapters)
-;
-; Based on Doc Bacardi's tftp source
-
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../inc/common.i"
-.include "cs8900a.i"
-
- .export eth_init
- .export eth_rx
- .export eth_tx
-
- .import eth_inp
- .import eth_inp_len
- .import eth_outp
- .import eth_outp_len
-
- .importzp eth_dest
- .importzp eth_src
- .importzp eth_type
- .importzp eth_data
-
- .import cs_init
- .import cs_packet_page
- .import cs_packet_data
- .import cs_rxtx_data
- .import cs_tx_cmd
- .import cs_tx_len
-
- .import cfg_mac
- .importzp eth_packet
-
- .import ip65_error
-
- .macro write_page page, value
- lda #page/2
- ldx #value
- jsr cs_write_page
- .endmacro
-
-
-
-
-
- .code
-
-;initialize the ethernet adaptor
-;inputs: none
-;outputs: carry flag is set if there was an error, clear otherwise
-eth_init:
- jsr cs_init
-
- lda #0 ; check magic signature
- jsr cs_read_page
- cpx #$0e
- bne @notfound
- cpy #$63
- bne @notfound
-
- lda #1
- jsr cs_read_page
- cpx #0
- bne @notfound
- ; y contains chip rev
-
- write_page pp_self_ctl, $0055 ; $0114, reset chip
-
- write_page pp_rx_ctl, $0d05 ; $0104, accept individual and broadcast packets
-
- lda #pp_ia/2 ; $0158, write mac address
- ldx cfg_mac
- ldy cfg_mac + 1
- jsr cs_write_page
-
- lda #pp_ia/2 + 1
- ldx cfg_mac + 2
- ldy cfg_mac + 3
- jsr cs_write_page
-
- lda #pp_ia/2 + 2
- ldx cfg_mac + 4
- ldy cfg_mac + 5
- jsr cs_write_page
-
- write_page pp_line_ctl, $00d3 ; $0112, enable rx and tx
-
- clc
- rts
-
-@notfound:
- sec
- 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:
- lda #$24 ; check rx status
- sta cs_packet_page
- lda #$01
- sta cs_packet_page + 1
-
- lda cs_packet_data + 1
- and #$0d
- bne :+
-
- sec ; no packet ready
- rts
-
-: lda cs_rxtx_data + 1 ; ignore status
- lda cs_rxtx_data
-
- lda cs_rxtx_data + 1 ; read packet length
- sta eth_inp_len + 1
- tax ; save
- lda cs_rxtx_data
- sta eth_inp_len
-
- lda #eth_inp
- sta eth_packet + 1
-
- ldy #0
- cpx #0 ; < 256 bytes left?
- beq @tail
-
-@get256:
- lda cs_rxtx_data
- sta (eth_packet),y
- iny
- lda cs_rxtx_data + 1
- sta (eth_packet),y
- iny
- bne @get256
- inc eth_packet + 1
- dex
- bne @get256
-
-@tail:
- lda eth_inp_len ; bytes left / 2, round up
- lsr
- adc #0
- beq @done
- tax
-
-@get:
- lda cs_rxtx_data
- sta (eth_packet),y
- iny
- lda cs_rxtx_data + 1
- sta (eth_packet),y
- iny
- dex
- bne @get
-
-@done:
- clc
- 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:
-
- lda #$c9 ; ask for buffer space
- sta cs_tx_cmd
- lda #0
- sta cs_tx_cmd + 1
-
- lda eth_outp_len ; set length
- sta cs_tx_len
- lda eth_outp_len + 1
- sta cs_tx_len + 1
- cmp #6
- bmi :+
- lda #KPR_ERROR_INPUT_TOO_LARGE
- sta ip65_error
- sec ; oversized packet
- rts
-
-: lda #pp_bus_status
- sta cs_packet_page + 1
-
-@waitspace:
- lda cs_packet_data + 1 ; wait for space
- ldx cs_packet_data
- lsr
- bcs @gotspace
- jsr @done ; polling too fast doesn't work, delay added by David Schmidt
- jmp @waitspace
-@gotspace:
- ldax #eth_outp ; send packet
- stax eth_packet
-
- ldy #0
- ldx eth_outp_len + 1
- beq @tail
-
-@send256:
- lda (eth_packet),y
- sta cs_rxtx_data
- iny
- lda (eth_packet),y
- sta cs_rxtx_data + 1
- iny
- bne @send256
- inc eth_packet + 1
- dex
- bne @send256
-
-@tail:
- ldx eth_outp_len
- beq @done
-
-@send:
- lda (eth_packet),y
- sta cs_rxtx_data
- dex
- beq @done
- iny
- lda (eth_packet),y
- sta cs_rxtx_data + 1
- iny
- dex
- bne @send
-
-@done: ; also used by timeout code above
- clc
- rts
-
-
-; read X/Y from page A * 2
-cs_read_page:
- asl
- sta cs_packet_page
- lda #0
- rol
- sta cs_packet_page + 1
- ldx cs_packet_data
- ldy cs_packet_data + 1
- rts
-
-; write X/Y to page A * 2
-cs_write_page:
- asl
- sta cs_packet_page
- lda #0
- rol
- sta cs_packet_page + 1
- stx cs_packet_data
- sty cs_packet_data + 1
- rts
-
-
-
-;-- LICENSE FOR cs8900a.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+; Ethernet driver for CS8900A chip (as used in RR-NET and Uthernet adapters)
+;
+; Based on Doc Bacardi's tftp source
+
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../inc/common.i"
+.include "cs8900a.i"
+
+ .export eth_init
+ .export eth_rx
+ .export eth_tx
+
+ .import eth_inp
+ .import eth_inp_len
+ .import eth_outp
+ .import eth_outp_len
+
+ .importzp eth_dest
+ .importzp eth_src
+ .importzp eth_type
+ .importzp eth_data
+
+ .import cs_init
+ .import cs_packet_page
+ .import cs_packet_data
+ .import cs_rxtx_data
+ .import cs_tx_cmd
+ .import cs_tx_len
+
+ .import cfg_mac
+ .importzp eth_packet
+
+ .import ip65_error
+
+ .macro write_page page, value
+ lda #page/2
+ ldx #value
+ jsr cs_write_page
+ .endmacro
+
+
+
+
+
+ .code
+
+;initialize the ethernet adaptor
+;inputs: none
+;outputs: carry flag is set if there was an error, clear otherwise
+eth_init:
+ jsr cs_init
+
+ lda #0 ; check magic signature
+ jsr cs_read_page
+ cpx #$0e
+ bne @notfound
+ cpy #$63
+ bne @notfound
+
+ lda #1
+ jsr cs_read_page
+ cpx #0
+ bne @notfound
+ ; y contains chip rev
+
+ write_page pp_self_ctl, $0055 ; $0114, reset chip
+
+ write_page pp_rx_ctl, $0d05 ; $0104, accept individual and broadcast packets
+
+ lda #pp_ia/2 ; $0158, write mac address
+ ldx cfg_mac
+ ldy cfg_mac + 1
+ jsr cs_write_page
+
+ lda #pp_ia/2 + 1
+ ldx cfg_mac + 2
+ ldy cfg_mac + 3
+ jsr cs_write_page
+
+ lda #pp_ia/2 + 2
+ ldx cfg_mac + 4
+ ldy cfg_mac + 5
+ jsr cs_write_page
+
+ write_page pp_line_ctl, $00d3 ; $0112, enable rx and tx
+
+ clc
+ rts
+
+@notfound:
+ sec
+ 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:
+ lda #$24 ; check rx status
+ sta cs_packet_page
+ lda #$01
+ sta cs_packet_page + 1
+
+ lda cs_packet_data + 1
+ and #$0d
+ bne :+
+
+ sec ; no packet ready
+ rts
+
+: lda cs_rxtx_data + 1 ; ignore status
+ lda cs_rxtx_data
+
+ lda cs_rxtx_data + 1 ; read packet length
+ sta eth_inp_len + 1
+ tax ; save
+ lda cs_rxtx_data
+ sta eth_inp_len
+
+ lda #eth_inp
+ sta eth_packet + 1
+
+ ldy #0
+ cpx #0 ; < 256 bytes left?
+ beq @tail
+
+@get256:
+ lda cs_rxtx_data
+ sta (eth_packet),y
+ iny
+ lda cs_rxtx_data + 1
+ sta (eth_packet),y
+ iny
+ bne @get256
+ inc eth_packet + 1
+ dex
+ bne @get256
+
+@tail:
+ lda eth_inp_len ; bytes left / 2, round up
+ lsr
+ adc #0
+ beq @done
+ tax
+
+@get:
+ lda cs_rxtx_data
+ sta (eth_packet),y
+ iny
+ lda cs_rxtx_data + 1
+ sta (eth_packet),y
+ iny
+ dex
+ bne @get
+
+@done:
+ clc
+ 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:
+
+ lda #$c9 ; ask for buffer space
+ sta cs_tx_cmd
+ lda #0
+ sta cs_tx_cmd + 1
+
+ lda eth_outp_len ; set length
+ sta cs_tx_len
+ lda eth_outp_len + 1
+ sta cs_tx_len + 1
+ cmp #6
+ bmi :+
+ lda #KPR_ERROR_INPUT_TOO_LARGE
+ sta ip65_error
+ sec ; oversized packet
+ rts
+
+: lda #pp_bus_status
+ sta cs_packet_page + 1
+
+@waitspace:
+ lda cs_packet_data + 1 ; wait for space
+ ldx cs_packet_data
+ lsr
+ bcs @gotspace
+ jsr @done ; polling too fast doesn't work, delay added by David Schmidt
+ jmp @waitspace
+@gotspace:
+ ldax #eth_outp ; send packet
+ stax eth_packet
+
+ ldy #0
+ ldx eth_outp_len + 1
+ beq @tail
+
+@send256:
+ lda (eth_packet),y
+ sta cs_rxtx_data
+ iny
+ lda (eth_packet),y
+ sta cs_rxtx_data + 1
+ iny
+ bne @send256
+ inc eth_packet + 1
+ dex
+ bne @send256
+
+@tail:
+ ldx eth_outp_len
+ beq @done
+
+@send:
+ lda (eth_packet),y
+ sta cs_rxtx_data
+ dex
+ beq @done
+ iny
+ lda (eth_packet),y
+ sta cs_rxtx_data + 1
+ iny
+ dex
+ bne @send
+
+@done: ; also used by timeout code above
+ clc
+ rts
+
+
+; read X/Y from page A * 2
+cs_read_page:
+ asl
+ sta cs_packet_page
+ lda #0
+ rol
+ sta cs_packet_page + 1
+ ldx cs_packet_data
+ ldy cs_packet_data + 1
+ rts
+
+; write X/Y to page A * 2
+cs_write_page:
+ asl
+ sta cs_packet_page
+ lda #0
+ rol
+ sta cs_packet_page + 1
+ stx cs_packet_data
+ sty cs_packet_data + 1
+ rts
+
+
+
+;-- LICENSE FOR cs8900a.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/drivers/generic_zero_page.s b/drivers/generic_zero_page.s
similarity index 97%
rename from client/drivers/generic_zero_page.s
rename to drivers/generic_zero_page.s
index 07f74af..fcf174a 100644
--- a/client/drivers/generic_zero_page.s
+++ b/drivers/generic_zero_page.s
@@ -1,43 +1,43 @@
-;zero page definitions
-;this 'generic' file just puts everything into a ZP segment
-;and lets LD65 in conjunction with cfg files assign zero page locations
-;however this can be overridden in the case that all necessary zp variables
-;cant be crammed into a contiguous segment, e.g. on the Apple ][
-
-
-.exportzp copy_src
-.exportzp copy_dest
-.exportzp dns_hostname
-.exportzp tftp_filename
-.exportzp buffer_ptr
-.exportzp eth_packet
-
-.segment "IP65ZP" : zeropage
-
-copy_src: .res 2 ; source pointer
-copy_dest: .res 2 ; destination pointer
-dns_hostname: .res 2
-tftp_filename: .res 2 ;name of file to d/l or filemask to get directory listing for
-buffer_ptr: .res 2 ; source pointer
-eth_packet: .res 2
-
-
-
-;-- LICENSE --
-; 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) 2013
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
+;zero page definitions
+;this 'generic' file just puts everything into a ZP segment
+;and lets LD65 in conjunction with cfg files assign zero page locations
+;however this can be overridden in the case that all necessary zp variables
+;cant be crammed into a contiguous segment, e.g. on the Apple ][
+
+
+.exportzp copy_src
+.exportzp copy_dest
+.exportzp dns_hostname
+.exportzp tftp_filename
+.exportzp buffer_ptr
+.exportzp eth_packet
+
+.segment "IP65ZP" : zeropage
+
+copy_src: .res 2 ; source pointer
+copy_dest: .res 2 ; destination pointer
+dns_hostname: .res 2
+tftp_filename: .res 2 ;name of file to d/l or filemask to get directory listing for
+buffer_ptr: .res 2 ; source pointer
+eth_packet: .res 2
+
+
+
+;-- LICENSE --
+; 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) 2013
+; Jonno Downes. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/drivers/lan91c96.s b/drivers/lan91c96.s
similarity index 95%
rename from client/drivers/lan91c96.s
rename to drivers/lan91c96.s
index 6a7d0f4..27499aa 100644
--- a/client/drivers/lan91c96.s
+++ b/drivers/lan91c96.s
@@ -1,461 +1,461 @@
-
-
-
-
-; Ethernet driver for SMC LAN91C96 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
- .export eth_driver_io_base
- .import eth_inp
- .import eth_inp_len
- .import eth_outp
- .import eth_outp_len
-
- .import cfg_mac
- .importzp eth_packet
-
-; LANceGS hardware addresses
-ethbsr := $c00E ; Bank select register R/W (2B)
-
-; Register bank 0
-ethtcr := $c000 ; Transmission control register R/W (2B)
-ethephsr := $c002 ; EPH status register R/O (2B)
-ethrcr := $c004 ; Receive control register R/W (2B)
-ethecr := $c006 ; Counter register R/O (2B)
-ethmir := $c008 ; Memory information register R/O (2B)
-ethmcr := $c00A ; Memory Config. reg. +0 R/W +1 R/O (2B)
-
-; Register bank 1
-ethcr := $c000 ; Configuration register R/W (2B)
-ethbar := $c002 ; Base address register R/W (2B)
-ethiar := $c004 ; Individual address register R/W (6B)
-ethgpr := $c00A ; General address register R/W (2B)
-ethctr := $c00C ; Control register R/W (2B)
-
-; Register bank 2
-ethmmucr := $c000 ; MMU command register W/O (1B)
-ethautotx := $c001 ; AUTO TX start register R/W (1B)
-ethpnr := $c002 ; Packet number register R/W (1B)
-etharr := $c003 ; Allocation result register R/O (1B)
-ethfifo := $c004 ; FIFO ports register R/O (2B)
-ethptr := $c006 ; Pointer register R/W (2B)
-ethdata := $c008 ; Data register R/W (4B)
-ethist := $c00C ; Interrupt status register R/O (1B)
-ethack := $c00C ; Interrupt acknowledge register W/O (1B)
-ethmsk := $c00D ; Interrupt mask register R/W (1B)
-
-; Register bank 3
-ethmt := $c000 ; Multicast table R/W (8B)
-ethmgmt := $c008 ; Management interface R/W (2B)
-ethrev := $c00A ; Revision register R/W (2B)
-ethercv := $c00C ; Early RCV register R/W (2B)
-
- .data
-
-;initialize the ethernet adaptor
-;inputs: none
-;outputs: carry flag is set if there was an error, clear otherwise
-eth_init:
- jsr lan_self_modify
- lda #$01
-fixlan00:
- sta ethbsr ; Select register bank 1
-fixlan01:
- lda ethcr ; Read first four bytes - $31, $20, $67, $18
- cmp #$31
- bne lanerror
-fixlan03:
- lda ethbar
- cmp #$67
- bne lanerror
-fixlan04:
- lda ethbar+1
- cmp #$18
- bne lanerror
- ; we have the magic signature
-
- ; Reset ETH card
- lda #$00 ; Bank 0
-fixlan05:
- sta ethbsr
- lda #%10000000 ; Software reset
-fixlan06:
- sta ethrcr+1
-
- ldy #$00
-fixlan07:
- sty ethrcr
-fixlan08:
- sty ethrcr+1
-
- ; Delay
-: cmp ($FF,x) ; 6 cycles
- cmp ($FF,x) ; 6 cycles
- iny ; 2 cycles
- bne :- ; 3 cycles
- ; 17 * 256 = 4352 -> 4,4 ms
-
- ; Enable transmit and receive
- lda #%10000001 ; Enable transmit TXENA, PAD_EN
- ldx #%00000011 ; Enable receive, strip CRC ???
-fixlan09:
- sta ethtcr
-fixlan10:
- stx ethrcr+1
-
- lda #$01 ; Bank 1
-fixlan11:
- sta ethbsr
-
-fixlan12:
- lda ethcr+1
- ora #%00010000 ; No wait (IOCHRDY)
-fixlan13:
- sta ethcr+1
-
- lda #%00001001 ; Auto release
-fixlan14:
- sta ethctr+1
-
- ; Set MAC address
- lda cfg_mac
- ldx cfg_mac + 1
-fixlan15:
- sta ethiar
-fixlan16:
- stx ethiar + 1
- lda cfg_mac + 2
- ldx cfg_mac + 3
-fixlan17:
- sta ethiar + 2
-fixlan18:
- stx ethiar + 3
- lda cfg_mac + 4
- ldx cfg_mac + 5
-fixlan19:
- sta ethiar + 4
-fixlan20:
- stx ethiar + 5
-
- ; Set interrupt mask
- lda #$02 ; Bank 2
-fixlan21:
- sta ethbsr
-
- lda #%00000000 ; No interrupts
-fixlan22:
- sta ethmsk
- clc
- rts
-
-lanerror:
- sec
- 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:
-fixlan38:
- lda ethist
- and #%00000001 ; Check receive interrupt
- bne :+
- sec ; No packet available
- rts
-
-: lda #$00
- ldx #%11100000 ; Receive, Auto Increment, Read
-fixlan39:
- sta ethptr
-fixlan40:
- stx ethptr + 1
-
- ; Last word contains 'last data byte' and $60 or 'fill byte' and $40
-fixlan41:
- lda ethdata ; Status word
-fixlan42:
- lda ethdata ; Only need high byte
-
- ; Move ODDFRM bit into carry:
- ; - Even packet length -> carry clear -> subtract 6 bytes
- ; - Odd packet length -> carry set -> subtract 5 bytes
- lsr
- lsr
- lsr
- lsr
- lsr
-
- ; The packet contains 3 extra words
-fixlan43:
- lda ethdata ; Total number of bytes
- sbc #$05 ; Actually 5 or 6 depending on carry
- sta eth_inp_len
-fixlan44:
- lda ethdata
- sbc #$00
- sta eth_inp_len+1
-
- ; Read bytes into buffer
- lda #eth_inp
- sta eth_packet
- stx eth_packet+1
- ldx eth_inp_len+1
- ldy #$00
-lanread:
-fixlan46:
- lda ethdata
- sta (eth_packet),y
- iny
- bne :+
- inc eth_packet+1
-: cpy eth_inp_len
- bne lanread
- dex
- bpl lanread
-
- ; Remove and release RX packet from the FIFO
- lda #%10000000
-fixlan47:
- sta ethmmucr
-
- clc
- 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:
- lda eth_outp_len + 1 ;
- ora #%00100000
-fixlan23:
- sta ethmmucr ; Allocate memory for transmission
-fixlan24:
- lda ethist
- and #%00001000 ; Allocation interrupt
- bne :+
- sec
- rts ; Not able to allocate; bail
-
-: lda #%00001000
-fixlan25:
- sta ethack ; Acknowledge interrupt
-
-fixlan26:
- lda etharr
-fixlan27:
- sta ethpnr ; Set packet number
-
- lda #$00
- ldx #%01000000 ; Auto increment
-fixlan28:
- sta ethptr
-fixlan29:
- stx ethptr + 1
-
- lda #$00 ; Status written by CSMA
-fixlan30:
- sta ethdata
-fixlan31:
- sta ethdata
-
- lda eth_outp_len
- eor #$01
- lsr
- lda eth_outp_len
- adc #$05 ; Actually will be 5 or 6 depending on carry
-fixlan32:
- sta ethdata
- lda eth_outp_len + 1
- adc #$00
-fixlan33:
- sta ethdata
-
- lda #eth_outp
- sta eth_packet
- stx eth_packet + 1
- ldx eth_outp_len + 1
- ldy #$00
-lanwrite:
- lda (eth_packet),y
-fixlan34:
- sta ethdata
- iny
- bne :+
- inc eth_packet + 1
-: cpy eth_outp_len
- bne lanwrite
- dex
- bpl lanwrite
-
- lda eth_outp_len ; Odd packet length?
- lsr
- bcc :+
-
- lda #%001000000 ; Yes, Odd
- bne fixlan36 ; Always
-
-: lda #$00 ; No
-fixlan35:
- sta ethdata ; Fill byte
-fixlan36:
- sta ethdata ; Control byte
- lda #%11000000 ; Enqueue packet - transmit
-fixlan37:
- sta ethmmucr
-
- clc
- rts
-
-
-;
-; lan_self_modify - make all entry points variable so we can move the
-; LANceGS card around in the Apple
-;
-lan_self_modify:
- lda #$C0 ; FIXME - hardcoded to slot 4
- clc ; We'll be adding later, so clear carry
- ; Make the accumulator contain slot number plus $80
- ; i.e. Slot 1 = $90
- ; i.e. Slot 2 = $A0
- ; i.e. Slot 3 = $B0
- ; i.e. Slot 4 = $C0
- ; i.e. Slot 5 = $D0
- ; i.e. Slot 6 = $E0
- ; i.e. Slot 7 = $F0
-; $C0s0: Save off all ethtcr, ethcr, ethmmucr, and ethmt mods
- sta fixlan01 + 1
- sta fixlan09 + 1
- sta fixlan23 + 1
- sta fixlan37 + 1
-; sta fixlan45 + 1 ; Removed
- sta fixlan47 + 1
-
-; $C0s1: Save off all ethtcr+1, ethcr+1, ethmmucr+1, and ethmt+1 mods
- adc #$01
-; sta fixlan02 + 1 ; Removed
- sta fixlan12 + 1
- sta fixlan13 + 1
-
-; $C0s2: Save off all ethephsr, ethbar, and ethpnr mods
- adc #$01
- sta fixlan03 + 1
- sta fixlan27 + 1
-
-; $C0s3: Save off all ethephsr+1, ethbar+1, ethpnr+1, and etharr mods
- adc #$01
- sta fixlan04 + 1
- sta fixlan26 + 1
-
-; $C0s4: Save off all ethrcr, ethiar, and ethfifo mods
- adc #$01
- sta fixlan07 + 1
- sta fixlan15 + 1
-
-; $C0s5: Save off all ethrcr+1, ethiar+1, and ethfifo+1 mods
- adc #$01
- sta fixlan06 + 1
- sta fixlan08 + 1
- sta fixlan10 + 1
- sta fixlan16 + 1
-
-; $C0s6: Save off all ethecr, ethptr, and ethiar+2 mods
- adc #$01
- sta fixlan17 + 1
- sta fixlan28 + 1
- sta fixlan39 + 1
-
-; $C0s7: Save off all ethecr+1, ethptr+1, and ethiar+3 mods
- adc #$01
- sta fixlan18 + 1
- sta fixlan29 + 1
- sta fixlan40 + 1
-
-; $C0s8: Save off all ethmir, ethdata, ethmgmt, and ethiar+4 mods
- adc #$01
- sta fixlan19 + 1
- sta fixlan30 + 1
- sta fixlan31 + 1
- sta fixlan32 + 1
- sta fixlan33 + 1
- sta fixlan34 + 1
- sta fixlan35 + 1
- sta fixlan36 + 1
- sta fixlan41 + 1
- sta fixlan42 + 1
- sta fixlan43 + 1
- sta fixlan44 + 1
- sta fixlan46 + 1
-
-; $C0s9: Save off all ethmir+1, ethdata+1, ethmgmt+1, and ethiar+5 mods
- adc #$01
- sta fixlan20 + 1
-
-; $C0sA: Save off all ethmcr, ethgpr, and ethrev mods
-; $C0sB: Save off all ethmcr+1, ethgpr+1, and ethrev+1 mods
- ; None
-
-; $C0sC: Save off all ethctr, ethist, ethack, and ethercv mods
- adc #$03 ; Because there were no a or b mods
- sta fixlan24 + 1
- sta fixlan25 + 1
- sta fixlan38 + 1
-
-; $C0sD: Save off all ethmsk, ethctr+1 mods
- adc #$01
- sta fixlan14 + 1
- sta fixlan22 + 1
-
-; $C0sE: Save off all ethbsr mods
- adc #$01
- sta fixlan00 + 1
- sta fixlan05 + 1
- sta fixlan11 + 1
- sta fixlan21 + 1
-
- rts
-
-.rodata
-eth_driver_name:
- .asciiz "LANceGS (91C96)"
-eth_driver_io_base=fixlan01+1
-
-
-; 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 David Schmidt
-; Portions created by the Initial Developer is Copyright (C) 2011
-; All Rights Reserved.
-; -- LICENSE END --
+
+
+
+
+; Ethernet driver for SMC LAN91C96 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
+ .export eth_driver_io_base
+ .import eth_inp
+ .import eth_inp_len
+ .import eth_outp
+ .import eth_outp_len
+
+ .import cfg_mac
+ .importzp eth_packet
+
+; LANceGS hardware addresses
+ethbsr := $c00E ; Bank select register R/W (2B)
+
+; Register bank 0
+ethtcr := $c000 ; Transmission control register R/W (2B)
+ethephsr := $c002 ; EPH status register R/O (2B)
+ethrcr := $c004 ; Receive control register R/W (2B)
+ethecr := $c006 ; Counter register R/O (2B)
+ethmir := $c008 ; Memory information register R/O (2B)
+ethmcr := $c00A ; Memory Config. reg. +0 R/W +1 R/O (2B)
+
+; Register bank 1
+ethcr := $c000 ; Configuration register R/W (2B)
+ethbar := $c002 ; Base address register R/W (2B)
+ethiar := $c004 ; Individual address register R/W (6B)
+ethgpr := $c00A ; General address register R/W (2B)
+ethctr := $c00C ; Control register R/W (2B)
+
+; Register bank 2
+ethmmucr := $c000 ; MMU command register W/O (1B)
+ethautotx := $c001 ; AUTO TX start register R/W (1B)
+ethpnr := $c002 ; Packet number register R/W (1B)
+etharr := $c003 ; Allocation result register R/O (1B)
+ethfifo := $c004 ; FIFO ports register R/O (2B)
+ethptr := $c006 ; Pointer register R/W (2B)
+ethdata := $c008 ; Data register R/W (4B)
+ethist := $c00C ; Interrupt status register R/O (1B)
+ethack := $c00C ; Interrupt acknowledge register W/O (1B)
+ethmsk := $c00D ; Interrupt mask register R/W (1B)
+
+; Register bank 3
+ethmt := $c000 ; Multicast table R/W (8B)
+ethmgmt := $c008 ; Management interface R/W (2B)
+ethrev := $c00A ; Revision register R/W (2B)
+ethercv := $c00C ; Early RCV register R/W (2B)
+
+ .data
+
+;initialize the ethernet adaptor
+;inputs: none
+;outputs: carry flag is set if there was an error, clear otherwise
+eth_init:
+ jsr lan_self_modify
+ lda #$01
+fixlan00:
+ sta ethbsr ; Select register bank 1
+fixlan01:
+ lda ethcr ; Read first four bytes - $31, $20, $67, $18
+ cmp #$31
+ bne lanerror
+fixlan03:
+ lda ethbar
+ cmp #$67
+ bne lanerror
+fixlan04:
+ lda ethbar+1
+ cmp #$18
+ bne lanerror
+ ; we have the magic signature
+
+ ; Reset ETH card
+ lda #$00 ; Bank 0
+fixlan05:
+ sta ethbsr
+ lda #%10000000 ; Software reset
+fixlan06:
+ sta ethrcr+1
+
+ ldy #$00
+fixlan07:
+ sty ethrcr
+fixlan08:
+ sty ethrcr+1
+
+ ; Delay
+: cmp ($FF,x) ; 6 cycles
+ cmp ($FF,x) ; 6 cycles
+ iny ; 2 cycles
+ bne :- ; 3 cycles
+ ; 17 * 256 = 4352 -> 4,4 ms
+
+ ; Enable transmit and receive
+ lda #%10000001 ; Enable transmit TXENA, PAD_EN
+ ldx #%00000011 ; Enable receive, strip CRC ???
+fixlan09:
+ sta ethtcr
+fixlan10:
+ stx ethrcr+1
+
+ lda #$01 ; Bank 1
+fixlan11:
+ sta ethbsr
+
+fixlan12:
+ lda ethcr+1
+ ora #%00010000 ; No wait (IOCHRDY)
+fixlan13:
+ sta ethcr+1
+
+ lda #%00001001 ; Auto release
+fixlan14:
+ sta ethctr+1
+
+ ; Set MAC address
+ lda cfg_mac
+ ldx cfg_mac + 1
+fixlan15:
+ sta ethiar
+fixlan16:
+ stx ethiar + 1
+ lda cfg_mac + 2
+ ldx cfg_mac + 3
+fixlan17:
+ sta ethiar + 2
+fixlan18:
+ stx ethiar + 3
+ lda cfg_mac + 4
+ ldx cfg_mac + 5
+fixlan19:
+ sta ethiar + 4
+fixlan20:
+ stx ethiar + 5
+
+ ; Set interrupt mask
+ lda #$02 ; Bank 2
+fixlan21:
+ sta ethbsr
+
+ lda #%00000000 ; No interrupts
+fixlan22:
+ sta ethmsk
+ clc
+ rts
+
+lanerror:
+ sec
+ 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:
+fixlan38:
+ lda ethist
+ and #%00000001 ; Check receive interrupt
+ bne :+
+ sec ; No packet available
+ rts
+
+: lda #$00
+ ldx #%11100000 ; Receive, Auto Increment, Read
+fixlan39:
+ sta ethptr
+fixlan40:
+ stx ethptr + 1
+
+ ; Last word contains 'last data byte' and $60 or 'fill byte' and $40
+fixlan41:
+ lda ethdata ; Status word
+fixlan42:
+ lda ethdata ; Only need high byte
+
+ ; Move ODDFRM bit into carry:
+ ; - Even packet length -> carry clear -> subtract 6 bytes
+ ; - Odd packet length -> carry set -> subtract 5 bytes
+ lsr
+ lsr
+ lsr
+ lsr
+ lsr
+
+ ; The packet contains 3 extra words
+fixlan43:
+ lda ethdata ; Total number of bytes
+ sbc #$05 ; Actually 5 or 6 depending on carry
+ sta eth_inp_len
+fixlan44:
+ lda ethdata
+ sbc #$00
+ sta eth_inp_len+1
+
+ ; Read bytes into buffer
+ lda #eth_inp
+ sta eth_packet
+ stx eth_packet+1
+ ldx eth_inp_len+1
+ ldy #$00
+lanread:
+fixlan46:
+ lda ethdata
+ sta (eth_packet),y
+ iny
+ bne :+
+ inc eth_packet+1
+: cpy eth_inp_len
+ bne lanread
+ dex
+ bpl lanread
+
+ ; Remove and release RX packet from the FIFO
+ lda #%10000000
+fixlan47:
+ sta ethmmucr
+
+ clc
+ 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:
+ lda eth_outp_len + 1 ;
+ ora #%00100000
+fixlan23:
+ sta ethmmucr ; Allocate memory for transmission
+fixlan24:
+ lda ethist
+ and #%00001000 ; Allocation interrupt
+ bne :+
+ sec
+ rts ; Not able to allocate; bail
+
+: lda #%00001000
+fixlan25:
+ sta ethack ; Acknowledge interrupt
+
+fixlan26:
+ lda etharr
+fixlan27:
+ sta ethpnr ; Set packet number
+
+ lda #$00
+ ldx #%01000000 ; Auto increment
+fixlan28:
+ sta ethptr
+fixlan29:
+ stx ethptr + 1
+
+ lda #$00 ; Status written by CSMA
+fixlan30:
+ sta ethdata
+fixlan31:
+ sta ethdata
+
+ lda eth_outp_len
+ eor #$01
+ lsr
+ lda eth_outp_len
+ adc #$05 ; Actually will be 5 or 6 depending on carry
+fixlan32:
+ sta ethdata
+ lda eth_outp_len + 1
+ adc #$00
+fixlan33:
+ sta ethdata
+
+ lda #eth_outp
+ sta eth_packet
+ stx eth_packet + 1
+ ldx eth_outp_len + 1
+ ldy #$00
+lanwrite:
+ lda (eth_packet),y
+fixlan34:
+ sta ethdata
+ iny
+ bne :+
+ inc eth_packet + 1
+: cpy eth_outp_len
+ bne lanwrite
+ dex
+ bpl lanwrite
+
+ lda eth_outp_len ; Odd packet length?
+ lsr
+ bcc :+
+
+ lda #%001000000 ; Yes, Odd
+ bne fixlan36 ; Always
+
+: lda #$00 ; No
+fixlan35:
+ sta ethdata ; Fill byte
+fixlan36:
+ sta ethdata ; Control byte
+ lda #%11000000 ; Enqueue packet - transmit
+fixlan37:
+ sta ethmmucr
+
+ clc
+ rts
+
+
+;
+; lan_self_modify - make all entry points variable so we can move the
+; LANceGS card around in the Apple
+;
+lan_self_modify:
+ lda #$C0 ; FIXME - hardcoded to slot 4
+ clc ; We'll be adding later, so clear carry
+ ; Make the accumulator contain slot number plus $80
+ ; i.e. Slot 1 = $90
+ ; i.e. Slot 2 = $A0
+ ; i.e. Slot 3 = $B0
+ ; i.e. Slot 4 = $C0
+ ; i.e. Slot 5 = $D0
+ ; i.e. Slot 6 = $E0
+ ; i.e. Slot 7 = $F0
+; $C0s0: Save off all ethtcr, ethcr, ethmmucr, and ethmt mods
+ sta fixlan01 + 1
+ sta fixlan09 + 1
+ sta fixlan23 + 1
+ sta fixlan37 + 1
+; sta fixlan45 + 1 ; Removed
+ sta fixlan47 + 1
+
+; $C0s1: Save off all ethtcr+1, ethcr+1, ethmmucr+1, and ethmt+1 mods
+ adc #$01
+; sta fixlan02 + 1 ; Removed
+ sta fixlan12 + 1
+ sta fixlan13 + 1
+
+; $C0s2: Save off all ethephsr, ethbar, and ethpnr mods
+ adc #$01
+ sta fixlan03 + 1
+ sta fixlan27 + 1
+
+; $C0s3: Save off all ethephsr+1, ethbar+1, ethpnr+1, and etharr mods
+ adc #$01
+ sta fixlan04 + 1
+ sta fixlan26 + 1
+
+; $C0s4: Save off all ethrcr, ethiar, and ethfifo mods
+ adc #$01
+ sta fixlan07 + 1
+ sta fixlan15 + 1
+
+; $C0s5: Save off all ethrcr+1, ethiar+1, and ethfifo+1 mods
+ adc #$01
+ sta fixlan06 + 1
+ sta fixlan08 + 1
+ sta fixlan10 + 1
+ sta fixlan16 + 1
+
+; $C0s6: Save off all ethecr, ethptr, and ethiar+2 mods
+ adc #$01
+ sta fixlan17 + 1
+ sta fixlan28 + 1
+ sta fixlan39 + 1
+
+; $C0s7: Save off all ethecr+1, ethptr+1, and ethiar+3 mods
+ adc #$01
+ sta fixlan18 + 1
+ sta fixlan29 + 1
+ sta fixlan40 + 1
+
+; $C0s8: Save off all ethmir, ethdata, ethmgmt, and ethiar+4 mods
+ adc #$01
+ sta fixlan19 + 1
+ sta fixlan30 + 1
+ sta fixlan31 + 1
+ sta fixlan32 + 1
+ sta fixlan33 + 1
+ sta fixlan34 + 1
+ sta fixlan35 + 1
+ sta fixlan36 + 1
+ sta fixlan41 + 1
+ sta fixlan42 + 1
+ sta fixlan43 + 1
+ sta fixlan44 + 1
+ sta fixlan46 + 1
+
+; $C0s9: Save off all ethmir+1, ethdata+1, ethmgmt+1, and ethiar+5 mods
+ adc #$01
+ sta fixlan20 + 1
+
+; $C0sA: Save off all ethmcr, ethgpr, and ethrev mods
+; $C0sB: Save off all ethmcr+1, ethgpr+1, and ethrev+1 mods
+ ; None
+
+; $C0sC: Save off all ethctr, ethist, ethack, and ethercv mods
+ adc #$03 ; Because there were no a or b mods
+ sta fixlan24 + 1
+ sta fixlan25 + 1
+ sta fixlan38 + 1
+
+; $C0sD: Save off all ethmsk, ethctr+1 mods
+ adc #$01
+ sta fixlan14 + 1
+ sta fixlan22 + 1
+
+; $C0sE: Save off all ethbsr mods
+ adc #$01
+ sta fixlan00 + 1
+ sta fixlan05 + 1
+ sta fixlan11 + 1
+ sta fixlan21 + 1
+
+ rts
+
+.rodata
+eth_driver_name:
+ .asciiz "LANceGS (91C96)"
+eth_driver_io_base=fixlan01+1
+
+
+; 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 David Schmidt
+; Portions created by the Initial Developer is Copyright (C) 2011
+; All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/drivers/petscii_charconv.s b/drivers/petscii_charconv.s
similarity index 97%
rename from client/drivers/petscii_charconv.s
rename to drivers/petscii_charconv.s
index 2f5bc24..7bee8f8 100644
--- a/client/drivers/petscii_charconv.s
+++ b/drivers/petscii_charconv.s
@@ -1,76 +1,76 @@
-;ASCII/PETSCII conversion tables
-;cribbed from http://www.ffd2.com/fridge/misc/petcom.c
-
-
-.export ascii_to_native
-.export native_to_ascii
-
-;given a PETSCII char in A, return equivalent ASCII
-native_to_ascii:
- tax
- lda petscii_to_ascii_table,x
- rts
-
-;given an ASCII char in A, return equivalent PETSCII
-ascii_to_native:
- tax
- lda ascii_to_petscii_table,x
- rts
-
-.rodata
-ascii_to_petscii_table:
-.byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$20,$0d,$11,$93,$0a,$0e,$0f
-.byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f
-.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f
-.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f
-.byte $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf
-.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$a4
-.byte $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f
-.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$df
-.byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f
-.byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f
-.byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
-.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
-.byte $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f
-.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f
-.byte $e0,$e1,$e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef
-.byte $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd,$fe,$ff
-
-petscii_to_ascii_table:
-.byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$09,$0d,$11,$93,$0a,$0e,$0f
-.byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f
-.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f
-.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f
-.byte $40,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f
-.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$5b,$5c,$5d,$5e,$5f
-.byte $c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf
-.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$db,$dc,$dd,$de,$df
-.byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f
-.byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f
-.byte $20,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
-.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
-.byte $60,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f
-.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$7b,$7c,$7d,$7e,$7f
-.byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
-.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
-
-
-
-;-- LICENSE FOR c64charconv.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 --
+;ASCII/PETSCII conversion tables
+;cribbed from http://www.ffd2.com/fridge/misc/petcom.c
+
+
+.export ascii_to_native
+.export native_to_ascii
+
+;given a PETSCII char in A, return equivalent ASCII
+native_to_ascii:
+ tax
+ lda petscii_to_ascii_table,x
+ rts
+
+;given an ASCII char in A, return equivalent PETSCII
+ascii_to_native:
+ tax
+ lda ascii_to_petscii_table,x
+ rts
+
+.rodata
+ascii_to_petscii_table:
+.byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$20,$0d,$11,$93,$0a,$0e,$0f
+.byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f
+.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f
+.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f
+.byte $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf
+.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$a4
+.byte $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f
+.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$df
+.byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f
+.byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f
+.byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
+.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
+.byte $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f
+.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f
+.byte $e0,$e1,$e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef
+.byte $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd,$fe,$ff
+
+petscii_to_ascii_table:
+.byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$09,$0d,$11,$93,$0a,$0e,$0f
+.byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f
+.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f
+.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f
+.byte $40,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f
+.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$5b,$5c,$5d,$5e,$5f
+.byte $c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf
+.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$db,$dc,$dd,$de,$df
+.byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f
+.byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f
+.byte $20,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
+.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
+.byte $60,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f
+.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$7b,$7c,$7d,$7e,$7f
+.byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
+.byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
+
+
+
+;-- LICENSE FOR c64charconv.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/drivers/rr-net.s b/drivers/rr-net.s
similarity index 96%
rename from client/drivers/rr-net.s
rename to drivers/rr-net.s
index 4059c81..4253829 100644
--- a/client/drivers/rr-net.s
+++ b/drivers/rr-net.s
@@ -1,63 +1,63 @@
-; RR-Net driver
-
-
- .export cs_init
-
- .export cs_packet_page
- .export cs_packet_data
- .export cs_rxtx_data
- .export cs_tx_cmd
- .export cs_tx_len
- .export eth_driver_name
- .export eth_driver_io_base
-
-IO_BASE=$de00
-;IO_BASE=$df00
-rr_ctl = IO_BASE+1 ;address of 'control' port on Retro-Replay
-cs_packet_page = IO_BASE+2 ;address of 'packet page' port on RR-Net
-cs_packet_data = IO_BASE+4;address of 'packet data' port on RR-Net
-cs_rxtx_data = IO_BASE+8 ;address of 'recieve/transmit data' port on RR-Net
-cs_tx_cmd = IO_BASE+$0c;address of 'transmit command' port on RR-Net
-cs_tx_len = IO_BASE+$0e;address of 'transmission length' port on RR-Net
-
-
-.code
-
-;initialise Retro Replay so we can access the network adapter
-;inputs: none
-;outputs: none
-cs_init:
- lda rr_ctl
- ora #1
- sta rr_ctl
- rts
-
-.rodata
-eth_driver_name:
-.if IO_BASE=$de00
-.byte "RR-NET",0
-.else
-.byte "64NIC+",0
-.endif
-eth_driver_io_base:
-.word IO_BASE
-
-
-;-- LICENSE FOR rr-net.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 --
+; RR-Net driver
+
+
+ .export cs_init
+
+ .export cs_packet_page
+ .export cs_packet_data
+ .export cs_rxtx_data
+ .export cs_tx_cmd
+ .export cs_tx_len
+ .export eth_driver_name
+ .export eth_driver_io_base
+
+IO_BASE=$de00
+;IO_BASE=$df00
+rr_ctl = IO_BASE+1 ;address of 'control' port on Retro-Replay
+cs_packet_page = IO_BASE+2 ;address of 'packet page' port on RR-Net
+cs_packet_data = IO_BASE+4;address of 'packet data' port on RR-Net
+cs_rxtx_data = IO_BASE+8 ;address of 'recieve/transmit data' port on RR-Net
+cs_tx_cmd = IO_BASE+$0c;address of 'transmit command' port on RR-Net
+cs_tx_len = IO_BASE+$0e;address of 'transmission length' port on RR-Net
+
+
+.code
+
+;initialise Retro Replay so we can access the network adapter
+;inputs: none
+;outputs: none
+cs_init:
+ lda rr_ctl
+ ora #1
+ sta rr_ctl
+ rts
+
+.rodata
+eth_driver_name:
+.if IO_BASE=$de00
+.byte "RR-NET",0
+.else
+.byte "64NIC+",0
+.endif
+eth_driver_io_base:
+.word IO_BASE
+
+
+;-- LICENSE FOR rr-net.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/drivers/uthernet.s b/drivers/uthernet.s
similarity index 96%
rename from client/drivers/uthernet.s
rename to drivers/uthernet.s
index 9e9cbd3..9d69c73 100644
--- a/client/drivers/uthernet.s
+++ b/drivers/uthernet.s
@@ -1,52 +1,52 @@
-;uthernet driver
-;currently hardcoded to use slot 3 addresses only
-
-
- .export cs_init
-
- .export cs_packet_page
- .export cs_packet_data
- .export cs_rxtx_data
- .export cs_tx_cmd
- .export cs_tx_len
- .export eth_driver_name
- .export eth_driver_io_base
-
-cs_rxtx_data = $c0b0 ;address of 'recieve/transmit data' port on Uthernet
-cs_tx_cmd = $c0b4;address of 'transmit command' port on Uthernet
-cs_tx_len = $c0b6;address of 'transmission length' port on Uthernet
-cs_packet_page = $c0ba;address of 'packet page' port on Uthernet
-cs_packet_data = $c0bc;address of 'packet data' port on Uthernet
-
-
- .code
-
-cs_init:
-
- rts
-
-.rodata
-eth_driver_name:
- .byte "UTHERNET",0
-eth_driver_io_base:
- .word cs_rxtx_data
-
-
-;-- LICENSE FOR uthernet.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 --
+;uthernet driver
+;currently hardcoded to use slot 3 addresses only
+
+
+ .export cs_init
+
+ .export cs_packet_page
+ .export cs_packet_data
+ .export cs_rxtx_data
+ .export cs_tx_cmd
+ .export cs_tx_len
+ .export eth_driver_name
+ .export eth_driver_io_base
+
+cs_rxtx_data = $c0b0 ;address of 'recieve/transmit data' port on Uthernet
+cs_tx_cmd = $c0b4;address of 'transmit command' port on Uthernet
+cs_tx_len = $c0b6;address of 'transmission length' port on Uthernet
+cs_packet_page = $c0ba;address of 'packet page' port on Uthernet
+cs_packet_data = $c0bc;address of 'packet data' port on Uthernet
+
+
+ .code
+
+cs_init:
+
+ rts
+
+.rodata
+eth_driver_name:
+ .byte "UTHERNET",0
+eth_driver_io_base:
+ .word cs_rxtx_data
+
+
+;-- LICENSE FOR uthernet.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/drivers/vic20-rr-net.s b/drivers/vic20-rr-net.s
similarity index 96%
rename from client/drivers/vic20-rr-net.s
rename to drivers/vic20-rr-net.s
index e851e49..ea6ef65 100644
--- a/client/drivers/vic20-rr-net.s
+++ b/drivers/vic20-rr-net.s
@@ -1,57 +1,57 @@
-; RR-Net driver, as seen on a VIC-20 (i.e. using a MasC=uerade adapter)
-
-
- .export cs_init
-
- .export cs_packet_page
- .export cs_packet_data
- .export cs_rxtx_data
- .export cs_tx_cmd
- .export cs_tx_len
- .export eth_driver_name
- .export eth_driver_io_base
-
-rr_ctl = $9801 ;address of 'control' port on Retro-Replay
-cs_packet_page = $9802 ;address of 'packet page' port on RR-Net
-cs_packet_data = $9804;address of 'packet data' port on RR-Net
-cs_rxtx_data = $9808 ;address of 'recieve/transmit data' port on RR-Net
-cs_tx_cmd = $980c;address of 'transmit command' port on RR-Net
-cs_tx_len = $980e;address of 'transmission length' port on RR-Net
-
-
-.code
-
-;initialise Retro Replay so we can access the network adapter
-;inputs: none
-;outputs: none
-cs_init:
- lda rr_ctl
- ora #1
- sta rr_ctl
- rts
-
-.rodata
-eth_driver_name:
- .asciiz "VIC20 RR-NET"
-eth_driver_io_base:
- .word rr_ctl-1
-
-
-;-- LICENSE FOR vic20-rr-net.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 --
+; RR-Net driver, as seen on a VIC-20 (i.e. using a MasC=uerade adapter)
+
+
+ .export cs_init
+
+ .export cs_packet_page
+ .export cs_packet_data
+ .export cs_rxtx_data
+ .export cs_tx_cmd
+ .export cs_tx_len
+ .export eth_driver_name
+ .export eth_driver_io_base
+
+rr_ctl = $9801 ;address of 'control' port on Retro-Replay
+cs_packet_page = $9802 ;address of 'packet page' port on RR-Net
+cs_packet_data = $9804;address of 'packet data' port on RR-Net
+cs_rxtx_data = $9808 ;address of 'recieve/transmit data' port on RR-Net
+cs_tx_cmd = $980c;address of 'transmit command' port on RR-Net
+cs_tx_len = $980e;address of 'transmission length' port on RR-Net
+
+
+.code
+
+;initialise Retro Replay so we can access the network adapter
+;inputs: none
+;outputs: none
+cs_init:
+ lda rr_ctl
+ ora #1
+ sta rr_ctl
+ rts
+
+.rodata
+eth_driver_name:
+ .asciiz "VIC20 RR-NET"
+eth_driver_io_base:
+ .word rr_ctl-1
+
+
+;-- LICENSE FOR vic20-rr-net.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/drivers/vic20input.s b/drivers/vic20input.s
similarity index 95%
rename from client/drivers/vic20input.s
rename to drivers/vic20input.s
index b337e51..f42931d 100644
--- a/client/drivers/vic20input.s
+++ b/drivers/vic20input.s
@@ -1,203 +1,203 @@
-.export get_key
-.export get_filtered_input
-.export filter_text
-.export filter_ip
-.export filter_dns
-.export filter_url
-.export filter_number
-.export check_for_abort_key
-.export get_key_if_available
-.export get_key_ip65
-.importzp copy_src
-
-.import ip65_process
-
-.include "../inc/common.i"
-.code
-
-allowed_ptr=copy_src ;reuse zero page
-
-;use Vic 20 Kernel ROM function to read a key
-;inputs: none
-;outputs: A contains ASCII value of key just pressed
-get_key:
- jsr get_key_if_available
- beq get_key
- rts
-
-;use VIC 20 Kernel ROM function to read a key
-;inputs: none
-;outputs: A contains ASCII value of key just pressed (0 if no key pressed)
-get_key_if_available=$f1f9 ;not officially documented - where F1f5 (GETIN) falls through to if device # is 0 (KEYBD)
-
-
-;process inbound ip packets while waiting for a keypress
-get_key_ip65:
- jsr ip65_process
- jsr get_key_if_available
- beq get_key_ip65
- rts
-
-
-
-
-;check whether the RUN/STOP key is being pressed
-;inputs: none
-;outputs: sec if RUN/STOP pressed, clear otherwise
-check_for_abort_key:
- lda $cb ;current key pressed
- cmp #$18
- bne @not_abort
-@flush_loop:
- jsr get_key_if_available
- bne @flush_loop
- lda $cb ;current key pressed
- cmp #$18
- beq @flush_loop
- sec
- rts
-@not_abort:
- clc
- rts
-
-;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input
-;======================================================================
-;Input a string and store it in GOTINPUT, terminated with a null byte.
-;AX is a pointer to the allowed list of characters, null-terminated.
-;set AX to $0000 for no filter on input
-;max # of chars in y returns num of chars entered in y.
-;======================================================================
-
-
-; Main entry
-get_filtered_input:
- sty MAXCHARS
- stax temp_allowed
-
- ;Zero characters received.
- lda #$00
- sta INPUT_Y
-
-;Wait for a character.
-@input_get:
- jsr get_key
- sta LASTCHAR
-
- cmp #$14 ;Delete
- beq @delete
-
- cmp #$0d ;Return
- beq @input_done
-
- ;End reached?
- lda INPUT_Y
- cmp MAXCHARS
- beq @input_get
-
- ;Check the allowed list of characters.
- ldax temp_allowed
- stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time!
-
- ldy #$00
- lda allowed_ptr+1 ;was the input filter point nul?
- beq @input_ok
-@check_allowed:
- lda (allowed_ptr),y ;Overwritten
- beq @input_get ;Reached end of list (0)
-
- cmp LASTCHAR
- beq @input_ok ;Match found
-
- ;Not end or match, keep checking
- iny
- jmp @check_allowed
-
-@input_ok:
- lda LASTCHAR ;Get the char back
- ldy INPUT_Y
- sta GOTINPUT,y ;Add it to string
- jsr $ffd2 ;Print it
-
- inc INPUT_Y ;Next character
-
- ;Not yet.
- jmp @input_get
-
-@input_done:
- ldy INPUT_Y
- beq @no_input
- lda #$00
- sta GOTINPUT,y ;Zero-terminate
- clc
- ldax #GOTINPUT
- rts
-@no_input:
- sec
- rts
-; Delete last character.
-@delete:
- ;First, check if we're at the beginning. If so, just exit.
- lda INPUT_Y
- bne @delete_ok
- jmp @input_get
-
- ;At least one character entered.
-@delete_ok:
- ;Move pointer back.
- dec INPUT_Y
-
- ;Store a zero over top of last character, just in case no other characters are entered.
- ldy INPUT_Y
- lda #$00
- sta GOTINPUT,y
-
- ;Print the delete char
- lda #$14
- jsr $ffd2
-
- ;Wait for next char
- jmp @input_get
-
-
-;=================================================
-;Some example filters
-;=================================================
-
-filter_text:
- .byte ",!#'()* "
-filter_url:
-.byte ":/%&?+$"
-filter_dns:
-.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-filter_ip:
-.byte "."
-filter_number:
-.byte "1234567890",0
-
-;=================================================
-.bss
-temp_allowed: .res 2
-MAXCHARS: .res 1
-LASTCHAR: .res 1
-INPUT_Y: .res 1
-GOTINPUT: .res 40
-
-
-
-; 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 --
+.export get_key
+.export get_filtered_input
+.export filter_text
+.export filter_ip
+.export filter_dns
+.export filter_url
+.export filter_number
+.export check_for_abort_key
+.export get_key_if_available
+.export get_key_ip65
+.importzp copy_src
+
+.import ip65_process
+
+.include "../inc/common.i"
+.code
+
+allowed_ptr=copy_src ;reuse zero page
+
+;use Vic 20 Kernel ROM function to read a key
+;inputs: none
+;outputs: A contains ASCII value of key just pressed
+get_key:
+ jsr get_key_if_available
+ beq get_key
+ rts
+
+;use VIC 20 Kernel ROM function to read a key
+;inputs: none
+;outputs: A contains ASCII value of key just pressed (0 if no key pressed)
+get_key_if_available=$f1f9 ;not officially documented - where F1f5 (GETIN) falls through to if device # is 0 (KEYBD)
+
+
+;process inbound ip packets while waiting for a keypress
+get_key_ip65:
+ jsr ip65_process
+ jsr get_key_if_available
+ beq get_key_ip65
+ rts
+
+
+
+
+;check whether the RUN/STOP key is being pressed
+;inputs: none
+;outputs: sec if RUN/STOP pressed, clear otherwise
+check_for_abort_key:
+ lda $cb ;current key pressed
+ cmp #$18
+ bne @not_abort
+@flush_loop:
+ jsr get_key_if_available
+ bne @flush_loop
+ lda $cb ;current key pressed
+ cmp #$18
+ beq @flush_loop
+ sec
+ rts
+@not_abort:
+ clc
+ rts
+
+;cribbed from http://codebase64.org/doku.php?id=base:robust_string_input
+;======================================================================
+;Input a string and store it in GOTINPUT, terminated with a null byte.
+;AX is a pointer to the allowed list of characters, null-terminated.
+;set AX to $0000 for no filter on input
+;max # of chars in y returns num of chars entered in y.
+;======================================================================
+
+
+; Main entry
+get_filtered_input:
+ sty MAXCHARS
+ stax temp_allowed
+
+ ;Zero characters received.
+ lda #$00
+ sta INPUT_Y
+
+;Wait for a character.
+@input_get:
+ jsr get_key
+ sta LASTCHAR
+
+ cmp #$14 ;Delete
+ beq @delete
+
+ cmp #$0d ;Return
+ beq @input_done
+
+ ;End reached?
+ lda INPUT_Y
+ cmp MAXCHARS
+ beq @input_get
+
+ ;Check the allowed list of characters.
+ ldax temp_allowed
+ stax allowed_ptr ;since we are reusing this zero page, it may not stil be the same value since last time!
+
+ ldy #$00
+ lda allowed_ptr+1 ;was the input filter point nul?
+ beq @input_ok
+@check_allowed:
+ lda (allowed_ptr),y ;Overwritten
+ beq @input_get ;Reached end of list (0)
+
+ cmp LASTCHAR
+ beq @input_ok ;Match found
+
+ ;Not end or match, keep checking
+ iny
+ jmp @check_allowed
+
+@input_ok:
+ lda LASTCHAR ;Get the char back
+ ldy INPUT_Y
+ sta GOTINPUT,y ;Add it to string
+ jsr $ffd2 ;Print it
+
+ inc INPUT_Y ;Next character
+
+ ;Not yet.
+ jmp @input_get
+
+@input_done:
+ ldy INPUT_Y
+ beq @no_input
+ lda #$00
+ sta GOTINPUT,y ;Zero-terminate
+ clc
+ ldax #GOTINPUT
+ rts
+@no_input:
+ sec
+ rts
+; Delete last character.
+@delete:
+ ;First, check if we're at the beginning. If so, just exit.
+ lda INPUT_Y
+ bne @delete_ok
+ jmp @input_get
+
+ ;At least one character entered.
+@delete_ok:
+ ;Move pointer back.
+ dec INPUT_Y
+
+ ;Store a zero over top of last character, just in case no other characters are entered.
+ ldy INPUT_Y
+ lda #$00
+ sta GOTINPUT,y
+
+ ;Print the delete char
+ lda #$14
+ jsr $ffd2
+
+ ;Wait for next char
+ jmp @input_get
+
+
+;=================================================
+;Some example filters
+;=================================================
+
+filter_text:
+ .byte ",!#'()* "
+filter_url:
+.byte ":/%&?+$"
+filter_dns:
+.byte "-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+filter_ip:
+.byte "."
+filter_number:
+.byte "1234567890",0
+
+;=================================================
+.bss
+temp_allowed: .res 2
+MAXCHARS: .res 1
+LASTCHAR: .res 1
+INPUT_Y: .res 1
+GOTINPUT: .res 40
+
+
+
+; 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/drivers/vic20print.s b/drivers/vic20print.s
similarity index 95%
rename from client/drivers/vic20print.s
rename to drivers/vic20print.s
index 5578b49..aa00fdf 100644
--- a/client/drivers/vic20print.s
+++ b/drivers/vic20print.s
@@ -1,95 +1,95 @@
-
-.export print_a
-.export print_cr
-.export cls
-.export beep
-.export print_a_inverse
-.import timer_read
-.exportzp screen_current_row
-.exportzp screen_current_col
-
-screen_current_row=$d6
-screen_current_col=$d3
-
-;use VIC 20 Kernel ROM function to print a character to the screen
-;inputs: A contains petscii value of character to print
-;outputs: none
-print_a = $ffd2
-
-.bss
-beep_timer: .res 1
-
-.code
-
-;use VIC 20 Kernel ROM function to move to a new line
-;inputs: none
-;outputs: none
-print_cr:
- lda #13
- jmp print_a
-
-;use VIC 20 Kernel ROM function to clear the screen
-;inputs: none
-;outputs: none
-cls:
- lda #147 ; 'CLR/HOME'
- jmp print_a
-
-;currently does nothing (should make a 'beep noise')
-;inputs: none
-;outputs: none
-beep:
- lda $900e
- ora #15
- sta $900e ;set volume
-
- ;turn on osc. 3
- lda #$FF
- sta $900c
-
-; pause for qtr second
- jsr timer_read
- stx beep_timer
- inc beep_timer
- inc beep_timer
-:
- jsr timer_read
- cpx beep_timer
- bne :-
-
- ;turn off osc. 3
- lda #$00
- sta $900c
-
- rts
-
-
-;print a single char in inverse text:
-print_a_inverse:
- pha
- lda #18 ;inverse mode on
- jsr print_a
- pla
- jsr print_a
- lda #146 ;inverse mode off
- jmp print_a
-
-
-
-; 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 --
+
+.export print_a
+.export print_cr
+.export cls
+.export beep
+.export print_a_inverse
+.import timer_read
+.exportzp screen_current_row
+.exportzp screen_current_col
+
+screen_current_row=$d6
+screen_current_col=$d3
+
+;use VIC 20 Kernel ROM function to print a character to the screen
+;inputs: A contains petscii value of character to print
+;outputs: none
+print_a = $ffd2
+
+.bss
+beep_timer: .res 1
+
+.code
+
+;use VIC 20 Kernel ROM function to move to a new line
+;inputs: none
+;outputs: none
+print_cr:
+ lda #13
+ jmp print_a
+
+;use VIC 20 Kernel ROM function to clear the screen
+;inputs: none
+;outputs: none
+cls:
+ lda #147 ; 'CLR/HOME'
+ jmp print_a
+
+;currently does nothing (should make a 'beep noise')
+;inputs: none
+;outputs: none
+beep:
+ lda $900e
+ ora #15
+ sta $900e ;set volume
+
+ ;turn on osc. 3
+ lda #$FF
+ sta $900c
+
+; pause for qtr second
+ jsr timer_read
+ stx beep_timer
+ inc beep_timer
+ inc beep_timer
+:
+ jsr timer_read
+ cpx beep_timer
+ bne :-
+
+ ;turn off osc. 3
+ lda #$00
+ sta $900c
+
+ rts
+
+
+;print a single char in inverse text:
+print_a_inverse:
+ pha
+ lda #18 ;inverse mode on
+ jsr print_a
+ pla
+ jsr print_a
+ lda #146 ;inverse mode off
+ jmp print_a
+
+
+
+; 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/drivers/vic20timer.s b/drivers/vic20timer.s
similarity index 95%
rename from client/drivers/vic20timer.s
rename to drivers/vic20timer.s
index 9e8dcbb..483d3d7 100644
--- a/client/drivers/vic20timer.s
+++ b/drivers/vic20timer.s
@@ -1,124 +1,124 @@
-; timer routines
-;
-; the timer should be a 16-bit counter that's incremented by about
-; 1000 units per second. it doesn't have to be particularly accurate.
-; this VIC20 implementation requires the routine timer_vbl_handler be called 60 times per second
-
- .include "../inc/common.i"
-
-
- .export timer_init
- .export timer_read
- .export timer_seconds
-
- IRQ_VECTOR=$314
-
- .bss
- current_time_value: .res 2
- current_seconds: .res 1
- current_jiffies: .res 1
- .data
- jmp_old_handler:
- .byte $4c ;JMP
-old_handler:
- .word $00
-
- .code
-
-;reset timer to 0
-;inputs: none
-;outputs: none
-timer_init:
- lda old_handler
- bne @handler_installed
- ldax IRQ_VECTOR
- stax old_handler
- ldax #timer_vbl_handler
- stax IRQ_VECTOR
-@handler_installed:
- lda #0
- sta current_time_value
- sta current_time_value+1
- sta current_seconds
- sta current_jiffies
- rts
-
-;read the current timer value
-; inputs: none
-; outputs: AX = current timer value (roughly equal to number of milliseconds since the last call to 'timer_init')
-timer_read:
- ldax current_time_value
- rts
-
-; tick over the current timer value - should be called 60 times per second
-; inputs: none
-; outputs: none (all registers preserved, by carry flag can be modified)
-timer_vbl_handler:
- pha
- lda #$11 ; 60 HZ =~ 17 ms per 'tick'
- adc current_time_value
- sta current_time_value
- bcc :+
- inc current_time_value+1
-:
-
- inc current_jiffies
- lda current_jiffies
- cmp #60
- bne @done
- lda #0
- sta current_jiffies
- inc current_seconds
- ;we don't want to mess around with decimal mode in an IRQ handler
- lda current_seconds
- cmp #$0a
- bne :+
- lda #$10
-:
- cmp #$1a
- bne :+
- lda #$20
-:
- cmp #$2a
- bne :+
- lda #$30
-:
- cmp #$3a
- bne :+
- lda #$40
-:
- cmp #$4a
- bne :+
- lda #$50
-:
- cmp #$5a
- bne :+
- lda #$00
-:
-sta current_seconds
-@done:
- pla
- jmp jmp_old_handler
-
-timer_seconds:
- lda current_seconds
- rts
-
-;-- LICENSE FOR c64timer_nb65.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 --
+; timer routines
+;
+; the timer should be a 16-bit counter that's incremented by about
+; 1000 units per second. it doesn't have to be particularly accurate.
+; this VIC20 implementation requires the routine timer_vbl_handler be called 60 times per second
+
+ .include "../inc/common.i"
+
+
+ .export timer_init
+ .export timer_read
+ .export timer_seconds
+
+ IRQ_VECTOR=$314
+
+ .bss
+ current_time_value: .res 2
+ current_seconds: .res 1
+ current_jiffies: .res 1
+ .data
+ jmp_old_handler:
+ .byte $4c ;JMP
+old_handler:
+ .word $00
+
+ .code
+
+;reset timer to 0
+;inputs: none
+;outputs: none
+timer_init:
+ lda old_handler
+ bne @handler_installed
+ ldax IRQ_VECTOR
+ stax old_handler
+ ldax #timer_vbl_handler
+ stax IRQ_VECTOR
+@handler_installed:
+ lda #0
+ sta current_time_value
+ sta current_time_value+1
+ sta current_seconds
+ sta current_jiffies
+ rts
+
+;read the current timer value
+; inputs: none
+; outputs: AX = current timer value (roughly equal to number of milliseconds since the last call to 'timer_init')
+timer_read:
+ ldax current_time_value
+ rts
+
+; tick over the current timer value - should be called 60 times per second
+; inputs: none
+; outputs: none (all registers preserved, by carry flag can be modified)
+timer_vbl_handler:
+ pha
+ lda #$11 ; 60 HZ =~ 17 ms per 'tick'
+ adc current_time_value
+ sta current_time_value
+ bcc :+
+ inc current_time_value+1
+:
+
+ inc current_jiffies
+ lda current_jiffies
+ cmp #60
+ bne @done
+ lda #0
+ sta current_jiffies
+ inc current_seconds
+ ;we don't want to mess around with decimal mode in an IRQ handler
+ lda current_seconds
+ cmp #$0a
+ bne :+
+ lda #$10
+:
+ cmp #$1a
+ bne :+
+ lda #$20
+:
+ cmp #$2a
+ bne :+
+ lda #$30
+:
+ cmp #$3a
+ bne :+
+ lda #$40
+:
+ cmp #$4a
+ bne :+
+ lda #$50
+:
+ cmp #$5a
+ bne :+
+ lda #$00
+:
+sta current_seconds
+@done:
+ pla
+ jmp jmp_old_handler
+
+timer_seconds:
+ lda current_seconds
+ rts
+
+;-- LICENSE FOR c64timer_nb65.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/drivers/w5100.i b/drivers/w5100.i
similarity index 100%
rename from client/drivers/w5100.i
rename to drivers/w5100.i
diff --git a/client/drivers/w5100.s b/drivers/w5100.s
similarity index 95%
rename from client/drivers/w5100.s
rename to drivers/w5100.s
index f04e10f..76bc071 100644
--- a/client/drivers/w5100.s
+++ b/drivers/w5100.s
@@ -1,1056 +1,1056 @@
-; Ethernet driver for W5100 W5100 chip
-;
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../inc/common.i"
-
-.include "w5100.i"
-
-WIZNET_BASE=$DE04
-
-WIZNET_MODE_REG = WIZNET_BASE
-WIZNET_ADDR_HI = WIZNET_BASE+1
-WIZNET_ADDR_LO = WIZNET_BASE+2
-WIZNET_DATA_REG = WIZNET_BASE+3
-
-
-;DEBUG = 1
- .export eth_init
- .export eth_rx
- .export eth_tx
- .export eth_driver_name
- .export eth_driver_io_base
- .import eth_inp
- .import eth_inp_len
- .import eth_outp
- .import eth_outp_len
-
- .import timer_init
- .import timer_read
-
- .import arp_init
- .import ip_init
- .import cfg_init
-
- .importzp eth_dest
- .importzp eth_src
- .importzp eth_type
- .importzp eth_data
- .importzp copy_src
- .importzp copy_dest
-
- .export w5100_ip65_init
- .export w5100_read_register
- .export w5100_select_register
-
- .export w5100_write_register
- .export w5100_set_ip_config
- .export tcp_connect
- .export tcp_connect_ip
- .export tcp_callback
- .export tcp_send_data_len
- .export tcp_send_string
- .export tcp_send
- .export tcp_send_keep_alive
- .export tcp_close
- .export tcp_state
-
- .export tcp_connect_remote_port
- .export tcp_remote_ip
- .export tcp_listen
-
- .export tcp_inbound_data_ptr
- .export tcp_inbound_data_length
-
- .import cfg_mac
- .import cfg_ip
- .import cfg_netmask
- .import cfg_gateway
-
- .import ip65_error
- .import ip65_process
- .import check_for_abort_key
-
-
- .code
-
-;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
-eth_init:
- lda $de01
- ora #1 ;turn on clockport
- sta $de01
-
-
- lda #$80 ;reset
- sta WIZNET_MODE_REG
- lda WIZNET_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 #$13 ;set indirect mode, with autoinc, no auto PING
- sta WIZNET_MODE_REG
- lda WIZNET_MODE_REG
- cmp #$13
- bne @error ;make sure if we write to mode register without bit 7 set,
- ;the value persists.
- lda #$00
- sta WIZNET_ADDR_HI
- lda #$16
- sta WIZNET_ADDR_LO
-
- ldx #$00 ;start writing to reg $0016 - Interrupt Mask Register
-@loop:
- lda w5100_config_data,x
- sta WIZNET_DATA_REG
- inx
- cpx #$06
- bne @loop
-
- lda #$09
- sta WIZNET_ADDR_LO
- ldx #$00 ;start writing to reg $0009 - MAC address
-
-@mac_loop:
- lda cfg_mac,x
- sta WIZNET_DATA_REG
- inx
- cpx #$06
- bne @mac_loop
-
- ;set up socket 0 for MAC RAW mode
-
- ldax #W5100_RMSR ;rx memory size (each socket)
- stx WIZNET_ADDR_HI
- sta WIZNET_ADDR_LO
-
- lda #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
- ;if this is changed, change the mask in eth_rx as well!
-
- sta WIZNET_DATA_REG
-
- ldax #W5100_TMSR ;rx memory size (each socket)
- stx WIZNET_ADDR_HI
- sta WIZNET_ADDR_LO
-
- lda #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
- ;if this is changed, change the mask in eth_tx as well!
- sta WIZNET_DATA_REG
-
- ldax #W5100_S0_MR
- stx WIZNET_ADDR_HI
- sta WIZNET_ADDR_LO
- lda #W5100_MODE_MAC_RAW
- sta WIZNET_DATA_REG
-
- ;open socket 0
-
-
- jsr w5100_write_register
- ldax #W5100_S0_CR
- stx WIZNET_ADDR_HI
- sta WIZNET_ADDR_LO
- lda #W5100_CMD_OPEN
- sta WIZNET_DATA_REG
-
- lda #tcp_cxn_state_closed
- sta tcp_state
-
- clc
- rts
-@error:
- sec
- rts ;
-
-;initialize the ip65 stack for the w5100 ethernet adaptor
-;inputs: none
-;outputs: carry flag is set if there was an error, clear otherwise
-
-w5100_ip65_init:
- jsr cfg_init ;copy default values (including MAC address) to RAM
- jsr eth_init
-
- bcc @ok
- lda #KPR_ERROR_DEVICE_FAILURE
- sta ip65_error
- rts
-@ok:
- jsr timer_init ; initialize timer
- jsr arp_init ; initialize arp
- jsr ip_init ; initialize ip, icmp, udp, and tcp
- clc
- 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:
-
- ;eth_rx will get called in the main polling loop
- ;we shoe horn a check for data on the TCP socket here
- ;if we do get TCP data, we will call the TCP callback routine
- ;but we hide all of this from the ip65 stack proper.
- lda tcp_state
- beq @no_tcp
-
- jsr tcp_rx
- bcc @no_tcp ;if we didn't get any TCP traffic, go check for a raw ethernet packet
- ;eth_inp and eth_inp_len are not valid, so leave carry flag set to indicate no ethernet frame data
- rts
-
-@no_tcp:
-
- ldax #W5100_S0_RX_RSR0
- jsr w5100_read_register
- sta eth_inp_len+1
- ldax #W5100_S0_RX_RSR1
- jsr w5100_read_register
- sta eth_inp_len
- bne @got_data
- lda eth_inp_len+1
- bne @got_data
- sec
- rts
-@got_data:
-
- lda #$8D ;opcode for STA
- sta next_eth_packet_byte
- ldax #eth_inp
- stax copy_dest
-
- lda #2
- sta byte_ctr_lo
- lda #0
- sta byte_ctr_hi
-
-;read the 2 byte frame length
- jsr @get_current_rx_rd
- jsr @mask_and_adjust_rx_read
-
-
- ldax rx_rd_ptr
- jsr w5100_read_register
- sta eth_inp_len+1 ;high byte of frame length
- jsr @inc_rx_rd_ptr
- ldax rx_rd_ptr
- jsr w5100_read_register
- sta eth_inp_len ;lo byte of frame length
-
- ;now copy the rest of the frame to the eth_inp buffer
- ;we keep our own copy of RX_RD_PTR in sync, rather than read WIZNET_ADDR registers
- ;because of issue where reads to WIZNET_ADDR can cause the autoinc ptr to advance erroneously
- ;when WizNet cart used in a cartridge expander
-
- ldy #0
-@get_next_byte:
- inc rx_rd_ptr
- bne :+
- inc rx_rd_ptr+1
- lda rx_rd_ptr+1
- and #$0F
- clc
- adc #$60
- sta rx_rd_ptr+1
- sta WIZNET_ADDR_HI
-:
- lda WIZNET_DATA_REG
- sta (copy_dest),y
- iny
- bne :+
- inc copy_dest+1
-:
- inc byte_ctr_lo
- bne :+
- inc byte_ctr_hi
-:
-
- lda byte_ctr_lo
- cmp eth_inp_len
- bne @get_next_byte
- lda byte_ctr_hi
- cmp eth_inp_len+1
- bne @get_next_byte
-
-
-;update the RX RD pointer past the frame we just read
- jsr @get_current_rx_rd
- clc
- lda rx_rd_ptr
- adc eth_inp_len
- sta rx_rd_ptr
- lda rx_rd_ptr+1
- adc eth_inp_len+1
- tay
- ldax #W5100_S0_RX_RD0
- jsr w5100_write_register
- ldy rx_rd_ptr
-
- ldax #W5100_S0_RX_RD1
- jsr w5100_write_register
- ldax #W5100_S0_CR
- ldy #W5100_CMD_RECV
- jsr w5100_write_register
-
-;now adjust the input length to remove the 2 byte header length
- sec
- lda eth_inp_len
- sbc #2
- sta eth_inp_len
- bcs :+
- dec eth_inp_len
-:
-
-
- clc
- rts
-
-@inc_rx_rd_ptr:
- inc rx_rd_ptr
- bne :+
- inc rx_rd_ptr+1
-@mask_and_adjust_rx_read:
- lda rx_rd_ptr+1
- and #$0F
- clc
- adc #$60
- sta rx_rd_ptr+1
-:
- rts
-
-@get_current_rx_rd:
- ldax #W5100_S0_RX_RD0
- jsr w5100_read_register
- sta rx_rd_ptr+1
- ldax #W5100_S0_RX_RD1
- jsr w5100_read_register
- sta rx_rd_ptr
- 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:
-
- lda #$AD ;opcode for LDA
- sta next_eth_packet_byte
- ldax #eth_outp
- sta eth_ptr_lo
- stx eth_ptr_hi
- lda #0
- sta byte_ctr_lo
- sta byte_ctr_hi
-
- jsr @get_current_tx_wr
- jmp @calculate_tx_wr_ptr
-@send_next_byte:
-
- jsr next_eth_packet_byte
- tay
- ldax tx_wr_ptr
- jsr w5100_write_register
-
- inc byte_ctr_lo
- bne :+
- inc byte_ctr_hi
-:
-
- inc tx_wr_ptr
- bne :+
- inc tx_wr_ptr+1
-@calculate_tx_wr_ptr:
- lda tx_wr_ptr+1
- and #$0F
- clc
- adc #$40
- sta tx_wr_ptr+1
-:
-
- lda byte_ctr_lo
- cmp eth_outp_len
- bne @send_next_byte
- lda byte_ctr_hi
- cmp eth_outp_len+1
- bne @send_next_byte
-
-;all bytes copied, now adjust the tx write ptr and SEND
- jsr @get_current_tx_wr
- clc
- lda tx_wr_ptr
- adc eth_outp_len
- sta tx_wr_ptr
- lda tx_wr_ptr+1
- adc eth_outp_len+1
- tay
- ldax #W5100_S0_TX_WR0
- jsr w5100_write_register
- ldy tx_wr_ptr
- ldax #W5100_S0_TX_WR1
- jsr w5100_write_register
- ldax #W5100_S0_CR
- ldy #W5100_CMD_SEND
- jsr w5100_write_register
-
- clc
- rts
-
-@get_current_tx_wr:
- ldax #W5100_S0_TX_WR0
- jsr w5100_read_register
- sta tx_wr_ptr+1
- ldax #W5100_S0_TX_WR1
- jsr w5100_read_register
- sta tx_wr_ptr
- rts
-
-advance_eth_ptr:
- inc eth_ptr_lo
- bne :+
- inc eth_ptr_hi
-:
- rts
-
-
-; read one of the W5100 registers
-; inputs: AX = register number to read
-; outputs: A = value of nominated register
-; y is overwritten
-w5100_read_register:
- jsr w5100_select_register
- lda WIZNET_DATA_REG
- rts
-
-; write to one of the W5100 registers
-; inputs: AX = register number to write
-; Y = value to write to register
-; outputs: none
-w5100_write_register:
- jsr w5100_select_register
- tya
- sta WIZNET_DATA_REG
- rts
-
-
-
-
-;listen for an inbound tcp connection
-;this is a 'blocking' call, i.e. it will not return until a connection has been made
-;inputs:
-; AX: destination port (2 bytes)
-; tcp_callback: vector to call when data arrives on this connection
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_listen:
-
- stax tcp_local_port
- jsr setup_tcp_socket
- ldax #W5100_S1_CR
- ldy #W5100_CMD_LISTEN
- jsr w5100_write_register
-
- ;now wait for the status to change to 'established'
-@listen_loop:
-; inc $d020
- jsr ip65_process
- jsr check_for_abort_key
- bcc @no_abort
- lda #KPR_ERROR_ABORTED_BY_USER
- sta ip65_error
- sec
- rts
-@no_abort:
- ldax #W5100_S1_SR
- jsr w5100_read_register
- cmp #W5100_STATUS_SOCK_ESTABLISHED
- bne @listen_loop
-
- lda #tcp_cxn_state_established
- sta tcp_state
-
- ;copy the remote IP address & port number
- ldax #W5100_S1_DIPR0
- jsr w5100_select_register
- ldx #0
-@ip_loop:
- lda WIZNET_DATA_REG
- sta tcp_remote_ip,x
- inx
- cpx #$04
- bne @ip_loop
-
- ldax #W5100_S1_DPORT0
- jsr w5100_select_register
- lda WIZNET_DATA_REG
- sta tcp_connect_remote_port+1
- lda WIZNET_DATA_REG
- sta tcp_connect_remote_port
-
- clc
- rts
-
-
-;make outbound tcp connection
-;inputs:
-; tcp_connect_ip: destination ip address (4 bytes)
-; AX: destination port (2 bytes)
-; tcp_callback: vector to call when data arrives on this connection
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_connect:
- stax tcp_remote_port
- jsr timer_read ;get a pseudo random value
- sta tcp_local_port+1
- inc tcp_local_port
-
-
- jsr setup_tcp_socket
-
-
- ;set the destination IP address
- ldax #W5100_S1_DIPR0
- jsr w5100_select_register
- ldx #0
-@remote_ip_loop:
- lda tcp_connect_ip,x
- sta WIZNET_DATA_REG
- inx
- cpx #$04
- bne @remote_ip_loop
- ldx #0
-
-;W5100 register address is now W5100_S1_DPORT0, so set the destination port
- lda tcp_remote_port+1
- sta WIZNET_DATA_REG
- lda tcp_remote_port
- sta WIZNET_DATA_REG
-
- ldax #W5100_S1_CR
- ldy #W5100_CMD_CONNECT
- jsr w5100_write_register
-
- ;now wait for the status to change to 'established'
-@connect_loop:
- ldax #W5100_S1_SR
- jsr w5100_read_register
- cmp #W5100_STATUS_SOCK_CLOSED
- beq @error
- cmp #W5100_STATUS_SOCK_ESTABLISHED
- beq @ok
-
- jsr check_for_abort_key
- bcc @connect_loop
- lda #KPR_ERROR_ABORTED_BY_USER
- jmp @set_error_and_exit
-
-@ok:
- lda #tcp_cxn_state_established
- sta tcp_state
-
- clc
- rts
-@error:
- lda #KPR_ERROR_CONNECTION_CLOSED
-@set_error_and_exit:
- sta ip65_error
- sec
- rts
-
-;send a string over the current tcp connection
-;inputs:
-; tcp connection should already be opened
-; AX: pointer to buffer - data up to (but not including)
-; the first nul byte will be sent. max of 255 bytes will be sent.
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_send_string:
- stax tcp_send_data_ptr
- stax copy_src
- lda #0
- tay
- sta tcp_send_data_len
- sta tcp_send_data_len+1
- lda (copy_src),y
- bne @find_end_of_string
- rts ; if the string is empty, don't send anything!
-@find_end_of_string:
- lda (copy_src),y
- beq @done
- inc tcp_send_data_len
- iny
- bne @find_end_of_string
-@done:
- ldax tcp_send_data_ptr
- ;now we can fall through into tcp_send
-
-;send tcp data
-;inputs:
-; tcp connection should already be opened
-; tcp_send_data_len: length of data to send (exclusive of any headers)
-; AX: pointer to buffer containing data to be sent
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_send:
- stax tcp_send_data_ptr
-
- ;are we connected?
- ldax #W5100_S1_SR
- jsr w5100_read_register
- cmp #W5100_STATUS_SOCK_ESTABLISHED
- beq @ok
-
- lda #KPR_ERROR_CONNECTION_CLOSED
- sta ip65_error
- sec
- rts
-@ok:
-
-
- lda #$AD ;opcode for LDA
- sta next_eth_packet_byte
-
- lda #0
- sta byte_ctr_lo
- sta byte_ctr_hi
-
- jsr @get_current_tx_wr
- jmp @calculate_tx_wr_ptr
-@send_next_byte:
- jsr next_eth_packet_byte
- tay
- ldax tx_wr_ptr
- jsr w5100_write_register
-
- inc byte_ctr_lo
- bne :+
- inc byte_ctr_hi
-:
-
- inc tx_wr_ptr
- bne :+
- inc tx_wr_ptr+1
-@calculate_tx_wr_ptr:
- lda tx_wr_ptr+1
- and #$0F
- clc
- adc #$50
- sta tx_wr_ptr+1
-:
-
- lda byte_ctr_lo
- cmp tcp_send_data_len
- bne @send_next_byte
- lda byte_ctr_hi
- cmp tcp_send_data_len+1
- bne @send_next_byte
-
-;all bytes copied, now adjust the tx write ptr and SEND
- jsr @get_current_tx_wr
- clc
- lda tx_wr_ptr
- adc tcp_send_data_len
- sta tx_wr_ptr
- lda tx_wr_ptr+1
- adc tcp_send_data_len+1
- tay
- ldax #W5100_S1_TX_WR0
- jsr w5100_write_register
- ldy tx_wr_ptr
- ldax #W5100_S1_TX_WR1
- jsr w5100_write_register
- ldax #W5100_S1_CR
- ldy #W5100_CMD_SEND
- jsr w5100_write_register
-
- clc
- rts
-
-@get_current_tx_wr:
- ldax #W5100_S1_TX_WR0
- jsr w5100_read_register
- sta tx_wr_ptr+1
- ldax #W5100_S1_TX_WR1
- jsr w5100_read_register
- sta tx_wr_ptr
- rts
-
-;send an empty ACK packet on the current connection
-;inputs:
-; none
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-
-tcp_send_keep_alive:
- ;are we connected?
- ldax #W5100_S1_SR
- jsr w5100_read_register
- cmp #W5100_STATUS_SOCK_ESTABLISHED
- beq @ok
-
- lda #KPR_ERROR_CONNECTION_CLOSED
- sta ip65_error
- sec
- rts
-@ok:
- ldax #W5100_S1_CR
- ldy #W5100_CMD_SEND_KEEP
- jsr w5100_write_register
- clc
- rts
-
-
-
-
-;close the current connection
-;inputs:
-; none
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_close:
-
- ldax #W5100_S1_CR
- ldy #W5100_CMD_DISCONNECT
- jsr w5100_write_register
- clc
- rts
-
-
-;poll the TCP socket
-;if there is data available, call the user supplied TCP callback
-;inputs:
-; none
-;outputs:
-; carry flag is set if there was data, clear otherwise
-tcp_rx:
-
- ;is there data?
- ldax #W5100_S1_RX_RSR0
- jsr w5100_read_register
- sta tcp_inbound_data_length+1
- ldax #W5100_S1_RX_RSR1
- jsr w5100_read_register
- sta tcp_inbound_data_length
- bne @got_data
- lda tcp_inbound_data_length+1
- bne @got_data
-
- ;are we connected?
- ldax #W5100_S1_SR
- jsr w5100_read_register
- cmp #W5100_STATUS_SOCK_ESTABLISHED
- beq @connected_but_no_data
- ;no longer connected
- lda #tcp_cxn_state_closed
- sta tcp_state
-
- lda #$ff
- sta tcp_inbound_data_length
- sta tcp_inbound_data_length+1
- jsr @make_fake_eth_header
- jsr jmp_to_callback ;let the caller see the connection has closed
- sec ;don't poll the MAC RAW socket, else it may clobber the output buffer
- rts
-@connected_but_no_data:
- clc ;no data - go check the MAC RAW socket
- rts
-@got_data:
- lda #$8D ;opcode for STA
- sta next_eth_packet_byte
-
- ldax #eth_inp+$36 ;we will write to the location that TCP data would appear if this was a raw eth frame,
- ;14 bytes of ethernet header
- ;20 bytes of IP header
- ;20 bytes of TCP header
-
- stax tcp_inbound_data_ptr
-
-
- sta eth_ptr_lo
- stx eth_ptr_hi
-
- lda #0
- sta byte_ctr_lo
- sta byte_ctr_hi
-
- lda tcp_inbound_data_length+1
- cmp #4 ;don't allow more than $4FF bytes at once ($1279) since we are writing to a 1500 byte
- bmi :+
- lda #4
- sta tcp_inbound_data_length+1
-:
-
- ;now copy the data just arrived to the eth_inp buffer
- jsr @get_current_rx_rd
- jsr @mask_and_adjust_rx_read
-@get_next_byte:
-
- ldax rx_rd_ptr
- jsr w5100_read_register
- jsr next_eth_packet_byte
-
- jsr @inc_rx_rd_ptr
-
- inc byte_ctr_lo
- bne :+
- inc byte_ctr_hi
-:
-
- lda byte_ctr_lo
- cmp tcp_inbound_data_length
- bne @get_next_byte
- lda byte_ctr_hi
- cmp tcp_inbound_data_length+1
- bne @get_next_byte
-
-
-;update the RX RD pointer past the frame we just read
- jsr @get_current_rx_rd
- clc
- lda rx_rd_ptr
- adc tcp_inbound_data_length
- sta rx_rd_ptr
- lda rx_rd_ptr+1
- adc tcp_inbound_data_length+1
- tay
- ldax #W5100_S1_RX_RD0
- jsr w5100_write_register
- ldy rx_rd_ptr
-
- ldax #W5100_S1_RX_RD1
- jsr w5100_write_register
- ldax #W5100_S1_CR
- ldy #W5100_CMD_RECV
- jsr w5100_write_register
-
- jsr @make_fake_eth_header
- jsr jmp_to_callback ;let the caller see the connection has closed
- sec ;don't poll the MAC RAW socket, else it may clobber the output buffer
- rts
-
-@inc_rx_rd_ptr:
- inc rx_rd_ptr
- bne :+
- inc rx_rd_ptr+1
-@mask_and_adjust_rx_read:
- lda rx_rd_ptr+1
- and #$0F
- clc
- adc #$70
- sta rx_rd_ptr+1
-:
- rts
-
-@get_current_rx_rd:
- ldax #W5100_S1_RX_RD0
- jsr w5100_read_register
- sta rx_rd_ptr+1
- ldax #W5100_S1_RX_RD1
- jsr w5100_read_register
- sta rx_rd_ptr
- rts
-
-;the function dispatcher (and possibly other parts of the ip65 stack) expect to find valid values in the eth_inp frame
-;when processing tcp data
-@make_fake_eth_header:
-
- .import ip_inp
- .import udp_inp
- ;first set the TCP protocol value
- lda #6 ;TCP protocol number
- sta ip_inp+9 ;proto number
-
- ;now copy the remote IP address
- ldx #0
-@ip_loop:
- lda tcp_remote_ip,x
- sta ip_inp+12,x ;src IP
- inx
- cpx #$04
- bne @ip_loop
-
- ;now the local & remote ports
- lda tcp_connect_remote_port
- sta udp_inp+1 ;remote port (lo byte)
- lda tcp_connect_remote_port+1
- sta udp_inp+0 ;remote port (high byte)
- lda tcp_local_port
- sta udp_inp+3 ;local port (lo byte)
- lda tcp_local_port+1
- sta udp_inp+2 ;local port (high byte)
-
- rts
-
-jmp_to_callback:
- jmp (tcp_callback)
-
-
-;copy the IP65 configuration to the the w5100 onchip configuration
-;we assume MAC has been configured already via eth_init, but IP
-;address etc may not be known when the w5100 was initialised (e.g.
-;if using DHCP).
-w5100_set_ip_config:
- ldax #W5100_GAR0
- jsr w5100_select_register
- ldx #0
-@gateway_loop:
- lda cfg_gateway,x
- sta WIZNET_DATA_REG
- inx
- cpx #$04
- bne @gateway_loop
- ldx #0
-@netmask_loop:
- lda cfg_netmask,x
- sta WIZNET_DATA_REG
- inx
- cpx #$04
- bne @netmask_loop
-
- ldax #W5100_SIPR0
- jsr w5100_select_register
- ldx #0
-@ip_loop:
- lda cfg_ip,x
- sta WIZNET_DATA_REG
- inx
- cpx #$04
- bne @ip_loop
- rts
-
-setup_tcp_socket:
- jsr w5100_set_ip_config
- ldax #W5100_S1_PORT0
- jsr w5100_select_register
- lda tcp_local_port+1
- sta WIZNET_DATA_REG
- lda tcp_local_port
- sta WIZNET_DATA_REG
-
- lda #0
- sta tcp_state
-
- ldax #W5100_S1_MR
- ldy #W5100_MODE_TCP
- jsr w5100_write_register
-
- ;open socket 1
- ldax #W5100_S1_CR
- ldy #W5100_CMD_OPEN
- jsr w5100_write_register
- rts
-
-
-.rodata
-eth_driver_name:
- .asciiz "RR-NET MK3 (WIZNET 5100)"
-
-eth_driver_io_base:
- .word WIZNET_BASE
-
-w5100_config_data:
- .byte $00 ;no interrupts
- .byte $0f ;400ms retry (default)
- .byte $a0
- .byte $08 ;# of timeouts
- .byte $55 ;4 sockets @2K each, tx/rx
- .byte $55
-
-
-;
-; select one of the W5100 registers for subsequent read or write
-; inputs: AX = register number to select
-; outputs: none
-w5100_select_register:
-set_hi:
- stx WIZNET_ADDR_HI
-set_lo:
- sta WIZNET_ADDR_LO
- rts
-
-; return which W5100 register the next read or write will access
-; inputs: none
-; outputs: AX = selected register number
-w5100_get_current_register:
-get_hi:
- ldx WIZNET_ADDR_HI
-get_lo:
- lda WIZNET_ADDR_LO
- rts
-
-
-.segment "SELF_MODIFIED_CODE"
-
-next_eth_packet_byte:
- lda $FFFF ;eth_packet
- jmp advance_eth_ptr
-
-eth_ptr_lo=next_eth_packet_byte+1
-eth_ptr_hi=next_eth_packet_byte+2
-
-; .bss
-; don't use BSS because we are out of room in the location that lives in the
-; config used for 16K carts ($C010..$CFFF)
-;there seems to be a little room still free in the seg used for SELF_MODIFIED_CODE
-
- w5100_addr: .res 2
- byte_ctr_lo: .res 1
- byte_ctr_hi: .res 1
-
- tx_wr_ptr: .res 2
- rx_rd_ptr: .res 2
-tcp_local_port: .res 2
-
-tcp_state: .res 1
-
-tcp_connect_ip: .res 4 ;ip address of remote server to connect to
-tcp_callback: .res 2 ;vector to routine to be called when data is received over tcp connection
-
-tcp_remote_port: .res 2 ;temp space for holding port to listen on or connect to
-tcp_send_data_len: .res 2
-tcp_send_data_ptr = eth_ptr_lo
-
-
-tcp_inbound_data_length: .res 2
-tcp_inbound_data_ptr: .res 2
-
-tcp_connect_remote_port: .res 2
-tcp_remote_ip = tcp_connect_ip
-
-tcp_cxn_state_closed = 0
-tcp_cxn_state_listening = 1 ;(waiting for an inbound SYN)
-tcp_cxn_state_syn_sent = 2 ;(waiting for an inbound SYN/ACK)
-tcp_cxn_state_established = 3 ;
-
-
-;-- 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
-; 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 is Copyright (C) 2010
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
+; Ethernet driver for W5100 W5100 chip
+;
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../inc/common.i"
+
+.include "w5100.i"
+
+WIZNET_BASE=$DE04
+
+WIZNET_MODE_REG = WIZNET_BASE
+WIZNET_ADDR_HI = WIZNET_BASE+1
+WIZNET_ADDR_LO = WIZNET_BASE+2
+WIZNET_DATA_REG = WIZNET_BASE+3
+
+
+;DEBUG = 1
+ .export eth_init
+ .export eth_rx
+ .export eth_tx
+ .export eth_driver_name
+ .export eth_driver_io_base
+ .import eth_inp
+ .import eth_inp_len
+ .import eth_outp
+ .import eth_outp_len
+
+ .import timer_init
+ .import timer_read
+
+ .import arp_init
+ .import ip_init
+ .import cfg_init
+
+ .importzp eth_dest
+ .importzp eth_src
+ .importzp eth_type
+ .importzp eth_data
+ .importzp copy_src
+ .importzp copy_dest
+
+ .export w5100_ip65_init
+ .export w5100_read_register
+ .export w5100_select_register
+
+ .export w5100_write_register
+ .export w5100_set_ip_config
+ .export tcp_connect
+ .export tcp_connect_ip
+ .export tcp_callback
+ .export tcp_send_data_len
+ .export tcp_send_string
+ .export tcp_send
+ .export tcp_send_keep_alive
+ .export tcp_close
+ .export tcp_state
+
+ .export tcp_connect_remote_port
+ .export tcp_remote_ip
+ .export tcp_listen
+
+ .export tcp_inbound_data_ptr
+ .export tcp_inbound_data_length
+
+ .import cfg_mac
+ .import cfg_ip
+ .import cfg_netmask
+ .import cfg_gateway
+
+ .import ip65_error
+ .import ip65_process
+ .import check_for_abort_key
+
+
+ .code
+
+;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
+eth_init:
+ lda $de01
+ ora #1 ;turn on clockport
+ sta $de01
+
+
+ lda #$80 ;reset
+ sta WIZNET_MODE_REG
+ lda WIZNET_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 #$13 ;set indirect mode, with autoinc, no auto PING
+ sta WIZNET_MODE_REG
+ lda WIZNET_MODE_REG
+ cmp #$13
+ bne @error ;make sure if we write to mode register without bit 7 set,
+ ;the value persists.
+ lda #$00
+ sta WIZNET_ADDR_HI
+ lda #$16
+ sta WIZNET_ADDR_LO
+
+ ldx #$00 ;start writing to reg $0016 - Interrupt Mask Register
+@loop:
+ lda w5100_config_data,x
+ sta WIZNET_DATA_REG
+ inx
+ cpx #$06
+ bne @loop
+
+ lda #$09
+ sta WIZNET_ADDR_LO
+ ldx #$00 ;start writing to reg $0009 - MAC address
+
+@mac_loop:
+ lda cfg_mac,x
+ sta WIZNET_DATA_REG
+ inx
+ cpx #$06
+ bne @mac_loop
+
+ ;set up socket 0 for MAC RAW mode
+
+ ldax #W5100_RMSR ;rx memory size (each socket)
+ stx WIZNET_ADDR_HI
+ sta WIZNET_ADDR_LO
+
+ lda #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
+ ;if this is changed, change the mask in eth_rx as well!
+
+ sta WIZNET_DATA_REG
+
+ ldax #W5100_TMSR ;rx memory size (each socket)
+ stx WIZNET_ADDR_HI
+ sta WIZNET_ADDR_LO
+
+ lda #$0A ;sockets 0 & 1 4KB each, other sockets 0KB
+ ;if this is changed, change the mask in eth_tx as well!
+ sta WIZNET_DATA_REG
+
+ ldax #W5100_S0_MR
+ stx WIZNET_ADDR_HI
+ sta WIZNET_ADDR_LO
+ lda #W5100_MODE_MAC_RAW
+ sta WIZNET_DATA_REG
+
+ ;open socket 0
+
+
+ jsr w5100_write_register
+ ldax #W5100_S0_CR
+ stx WIZNET_ADDR_HI
+ sta WIZNET_ADDR_LO
+ lda #W5100_CMD_OPEN
+ sta WIZNET_DATA_REG
+
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+
+ clc
+ rts
+@error:
+ sec
+ rts ;
+
+;initialize the ip65 stack for the w5100 ethernet adaptor
+;inputs: none
+;outputs: carry flag is set if there was an error, clear otherwise
+
+w5100_ip65_init:
+ jsr cfg_init ;copy default values (including MAC address) to RAM
+ jsr eth_init
+
+ bcc @ok
+ lda #KPR_ERROR_DEVICE_FAILURE
+ sta ip65_error
+ rts
+@ok:
+ jsr timer_init ; initialize timer
+ jsr arp_init ; initialize arp
+ jsr ip_init ; initialize ip, icmp, udp, and tcp
+ clc
+ 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:
+
+ ;eth_rx will get called in the main polling loop
+ ;we shoe horn a check for data on the TCP socket here
+ ;if we do get TCP data, we will call the TCP callback routine
+ ;but we hide all of this from the ip65 stack proper.
+ lda tcp_state
+ beq @no_tcp
+
+ jsr tcp_rx
+ bcc @no_tcp ;if we didn't get any TCP traffic, go check for a raw ethernet packet
+ ;eth_inp and eth_inp_len are not valid, so leave carry flag set to indicate no ethernet frame data
+ rts
+
+@no_tcp:
+
+ ldax #W5100_S0_RX_RSR0
+ jsr w5100_read_register
+ sta eth_inp_len+1
+ ldax #W5100_S0_RX_RSR1
+ jsr w5100_read_register
+ sta eth_inp_len
+ bne @got_data
+ lda eth_inp_len+1
+ bne @got_data
+ sec
+ rts
+@got_data:
+
+ lda #$8D ;opcode for STA
+ sta next_eth_packet_byte
+ ldax #eth_inp
+ stax copy_dest
+
+ lda #2
+ sta byte_ctr_lo
+ lda #0
+ sta byte_ctr_hi
+
+;read the 2 byte frame length
+ jsr @get_current_rx_rd
+ jsr @mask_and_adjust_rx_read
+
+
+ ldax rx_rd_ptr
+ jsr w5100_read_register
+ sta eth_inp_len+1 ;high byte of frame length
+ jsr @inc_rx_rd_ptr
+ ldax rx_rd_ptr
+ jsr w5100_read_register
+ sta eth_inp_len ;lo byte of frame length
+
+ ;now copy the rest of the frame to the eth_inp buffer
+ ;we keep our own copy of RX_RD_PTR in sync, rather than read WIZNET_ADDR registers
+ ;because of issue where reads to WIZNET_ADDR can cause the autoinc ptr to advance erroneously
+ ;when WizNet cart used in a cartridge expander
+
+ ldy #0
+@get_next_byte:
+ inc rx_rd_ptr
+ bne :+
+ inc rx_rd_ptr+1
+ lda rx_rd_ptr+1
+ and #$0F
+ clc
+ adc #$60
+ sta rx_rd_ptr+1
+ sta WIZNET_ADDR_HI
+:
+ lda WIZNET_DATA_REG
+ sta (copy_dest),y
+ iny
+ bne :+
+ inc copy_dest+1
+:
+ inc byte_ctr_lo
+ bne :+
+ inc byte_ctr_hi
+:
+
+ lda byte_ctr_lo
+ cmp eth_inp_len
+ bne @get_next_byte
+ lda byte_ctr_hi
+ cmp eth_inp_len+1
+ bne @get_next_byte
+
+
+;update the RX RD pointer past the frame we just read
+ jsr @get_current_rx_rd
+ clc
+ lda rx_rd_ptr
+ adc eth_inp_len
+ sta rx_rd_ptr
+ lda rx_rd_ptr+1
+ adc eth_inp_len+1
+ tay
+ ldax #W5100_S0_RX_RD0
+ jsr w5100_write_register
+ ldy rx_rd_ptr
+
+ ldax #W5100_S0_RX_RD1
+ jsr w5100_write_register
+ ldax #W5100_S0_CR
+ ldy #W5100_CMD_RECV
+ jsr w5100_write_register
+
+;now adjust the input length to remove the 2 byte header length
+ sec
+ lda eth_inp_len
+ sbc #2
+ sta eth_inp_len
+ bcs :+
+ dec eth_inp_len
+:
+
+
+ clc
+ rts
+
+@inc_rx_rd_ptr:
+ inc rx_rd_ptr
+ bne :+
+ inc rx_rd_ptr+1
+@mask_and_adjust_rx_read:
+ lda rx_rd_ptr+1
+ and #$0F
+ clc
+ adc #$60
+ sta rx_rd_ptr+1
+:
+ rts
+
+@get_current_rx_rd:
+ ldax #W5100_S0_RX_RD0
+ jsr w5100_read_register
+ sta rx_rd_ptr+1
+ ldax #W5100_S0_RX_RD1
+ jsr w5100_read_register
+ sta rx_rd_ptr
+ 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:
+
+ lda #$AD ;opcode for LDA
+ sta next_eth_packet_byte
+ ldax #eth_outp
+ sta eth_ptr_lo
+ stx eth_ptr_hi
+ lda #0
+ sta byte_ctr_lo
+ sta byte_ctr_hi
+
+ jsr @get_current_tx_wr
+ jmp @calculate_tx_wr_ptr
+@send_next_byte:
+
+ jsr next_eth_packet_byte
+ tay
+ ldax tx_wr_ptr
+ jsr w5100_write_register
+
+ inc byte_ctr_lo
+ bne :+
+ inc byte_ctr_hi
+:
+
+ inc tx_wr_ptr
+ bne :+
+ inc tx_wr_ptr+1
+@calculate_tx_wr_ptr:
+ lda tx_wr_ptr+1
+ and #$0F
+ clc
+ adc #$40
+ sta tx_wr_ptr+1
+:
+
+ lda byte_ctr_lo
+ cmp eth_outp_len
+ bne @send_next_byte
+ lda byte_ctr_hi
+ cmp eth_outp_len+1
+ bne @send_next_byte
+
+;all bytes copied, now adjust the tx write ptr and SEND
+ jsr @get_current_tx_wr
+ clc
+ lda tx_wr_ptr
+ adc eth_outp_len
+ sta tx_wr_ptr
+ lda tx_wr_ptr+1
+ adc eth_outp_len+1
+ tay
+ ldax #W5100_S0_TX_WR0
+ jsr w5100_write_register
+ ldy tx_wr_ptr
+ ldax #W5100_S0_TX_WR1
+ jsr w5100_write_register
+ ldax #W5100_S0_CR
+ ldy #W5100_CMD_SEND
+ jsr w5100_write_register
+
+ clc
+ rts
+
+@get_current_tx_wr:
+ ldax #W5100_S0_TX_WR0
+ jsr w5100_read_register
+ sta tx_wr_ptr+1
+ ldax #W5100_S0_TX_WR1
+ jsr w5100_read_register
+ sta tx_wr_ptr
+ rts
+
+advance_eth_ptr:
+ inc eth_ptr_lo
+ bne :+
+ inc eth_ptr_hi
+:
+ rts
+
+
+; read one of the W5100 registers
+; inputs: AX = register number to read
+; outputs: A = value of nominated register
+; y is overwritten
+w5100_read_register:
+ jsr w5100_select_register
+ lda WIZNET_DATA_REG
+ rts
+
+; write to one of the W5100 registers
+; inputs: AX = register number to write
+; Y = value to write to register
+; outputs: none
+w5100_write_register:
+ jsr w5100_select_register
+ tya
+ sta WIZNET_DATA_REG
+ rts
+
+
+
+
+;listen for an inbound tcp connection
+;this is a 'blocking' call, i.e. it will not return until a connection has been made
+;inputs:
+; AX: destination port (2 bytes)
+; tcp_callback: vector to call when data arrives on this connection
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_listen:
+
+ stax tcp_local_port
+ jsr setup_tcp_socket
+ ldax #W5100_S1_CR
+ ldy #W5100_CMD_LISTEN
+ jsr w5100_write_register
+
+ ;now wait for the status to change to 'established'
+@listen_loop:
+; inc $d020
+ jsr ip65_process
+ jsr check_for_abort_key
+ bcc @no_abort
+ lda #KPR_ERROR_ABORTED_BY_USER
+ sta ip65_error
+ sec
+ rts
+@no_abort:
+ ldax #W5100_S1_SR
+ jsr w5100_read_register
+ cmp #W5100_STATUS_SOCK_ESTABLISHED
+ bne @listen_loop
+
+ lda #tcp_cxn_state_established
+ sta tcp_state
+
+ ;copy the remote IP address & port number
+ ldax #W5100_S1_DIPR0
+ jsr w5100_select_register
+ ldx #0
+@ip_loop:
+ lda WIZNET_DATA_REG
+ sta tcp_remote_ip,x
+ inx
+ cpx #$04
+ bne @ip_loop
+
+ ldax #W5100_S1_DPORT0
+ jsr w5100_select_register
+ lda WIZNET_DATA_REG
+ sta tcp_connect_remote_port+1
+ lda WIZNET_DATA_REG
+ sta tcp_connect_remote_port
+
+ clc
+ rts
+
+
+;make outbound tcp connection
+;inputs:
+; tcp_connect_ip: destination ip address (4 bytes)
+; AX: destination port (2 bytes)
+; tcp_callback: vector to call when data arrives on this connection
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_connect:
+ stax tcp_remote_port
+ jsr timer_read ;get a pseudo random value
+ sta tcp_local_port+1
+ inc tcp_local_port
+
+
+ jsr setup_tcp_socket
+
+
+ ;set the destination IP address
+ ldax #W5100_S1_DIPR0
+ jsr w5100_select_register
+ ldx #0
+@remote_ip_loop:
+ lda tcp_connect_ip,x
+ sta WIZNET_DATA_REG
+ inx
+ cpx #$04
+ bne @remote_ip_loop
+ ldx #0
+
+;W5100 register address is now W5100_S1_DPORT0, so set the destination port
+ lda tcp_remote_port+1
+ sta WIZNET_DATA_REG
+ lda tcp_remote_port
+ sta WIZNET_DATA_REG
+
+ ldax #W5100_S1_CR
+ ldy #W5100_CMD_CONNECT
+ jsr w5100_write_register
+
+ ;now wait for the status to change to 'established'
+@connect_loop:
+ ldax #W5100_S1_SR
+ jsr w5100_read_register
+ cmp #W5100_STATUS_SOCK_CLOSED
+ beq @error
+ cmp #W5100_STATUS_SOCK_ESTABLISHED
+ beq @ok
+
+ jsr check_for_abort_key
+ bcc @connect_loop
+ lda #KPR_ERROR_ABORTED_BY_USER
+ jmp @set_error_and_exit
+
+@ok:
+ lda #tcp_cxn_state_established
+ sta tcp_state
+
+ clc
+ rts
+@error:
+ lda #KPR_ERROR_CONNECTION_CLOSED
+@set_error_and_exit:
+ sta ip65_error
+ sec
+ rts
+
+;send a string over the current tcp connection
+;inputs:
+; tcp connection should already be opened
+; AX: pointer to buffer - data up to (but not including)
+; the first nul byte will be sent. max of 255 bytes will be sent.
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_send_string:
+ stax tcp_send_data_ptr
+ stax copy_src
+ lda #0
+ tay
+ sta tcp_send_data_len
+ sta tcp_send_data_len+1
+ lda (copy_src),y
+ bne @find_end_of_string
+ rts ; if the string is empty, don't send anything!
+@find_end_of_string:
+ lda (copy_src),y
+ beq @done
+ inc tcp_send_data_len
+ iny
+ bne @find_end_of_string
+@done:
+ ldax tcp_send_data_ptr
+ ;now we can fall through into tcp_send
+
+;send tcp data
+;inputs:
+; tcp connection should already be opened
+; tcp_send_data_len: length of data to send (exclusive of any headers)
+; AX: pointer to buffer containing data to be sent
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_send:
+ stax tcp_send_data_ptr
+
+ ;are we connected?
+ ldax #W5100_S1_SR
+ jsr w5100_read_register
+ cmp #W5100_STATUS_SOCK_ESTABLISHED
+ beq @ok
+
+ lda #KPR_ERROR_CONNECTION_CLOSED
+ sta ip65_error
+ sec
+ rts
+@ok:
+
+
+ lda #$AD ;opcode for LDA
+ sta next_eth_packet_byte
+
+ lda #0
+ sta byte_ctr_lo
+ sta byte_ctr_hi
+
+ jsr @get_current_tx_wr
+ jmp @calculate_tx_wr_ptr
+@send_next_byte:
+ jsr next_eth_packet_byte
+ tay
+ ldax tx_wr_ptr
+ jsr w5100_write_register
+
+ inc byte_ctr_lo
+ bne :+
+ inc byte_ctr_hi
+:
+
+ inc tx_wr_ptr
+ bne :+
+ inc tx_wr_ptr+1
+@calculate_tx_wr_ptr:
+ lda tx_wr_ptr+1
+ and #$0F
+ clc
+ adc #$50
+ sta tx_wr_ptr+1
+:
+
+ lda byte_ctr_lo
+ cmp tcp_send_data_len
+ bne @send_next_byte
+ lda byte_ctr_hi
+ cmp tcp_send_data_len+1
+ bne @send_next_byte
+
+;all bytes copied, now adjust the tx write ptr and SEND
+ jsr @get_current_tx_wr
+ clc
+ lda tx_wr_ptr
+ adc tcp_send_data_len
+ sta tx_wr_ptr
+ lda tx_wr_ptr+1
+ adc tcp_send_data_len+1
+ tay
+ ldax #W5100_S1_TX_WR0
+ jsr w5100_write_register
+ ldy tx_wr_ptr
+ ldax #W5100_S1_TX_WR1
+ jsr w5100_write_register
+ ldax #W5100_S1_CR
+ ldy #W5100_CMD_SEND
+ jsr w5100_write_register
+
+ clc
+ rts
+
+@get_current_tx_wr:
+ ldax #W5100_S1_TX_WR0
+ jsr w5100_read_register
+ sta tx_wr_ptr+1
+ ldax #W5100_S1_TX_WR1
+ jsr w5100_read_register
+ sta tx_wr_ptr
+ rts
+
+;send an empty ACK packet on the current connection
+;inputs:
+; none
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+
+tcp_send_keep_alive:
+ ;are we connected?
+ ldax #W5100_S1_SR
+ jsr w5100_read_register
+ cmp #W5100_STATUS_SOCK_ESTABLISHED
+ beq @ok
+
+ lda #KPR_ERROR_CONNECTION_CLOSED
+ sta ip65_error
+ sec
+ rts
+@ok:
+ ldax #W5100_S1_CR
+ ldy #W5100_CMD_SEND_KEEP
+ jsr w5100_write_register
+ clc
+ rts
+
+
+
+
+;close the current connection
+;inputs:
+; none
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_close:
+
+ ldax #W5100_S1_CR
+ ldy #W5100_CMD_DISCONNECT
+ jsr w5100_write_register
+ clc
+ rts
+
+
+;poll the TCP socket
+;if there is data available, call the user supplied TCP callback
+;inputs:
+; none
+;outputs:
+; carry flag is set if there was data, clear otherwise
+tcp_rx:
+
+ ;is there data?
+ ldax #W5100_S1_RX_RSR0
+ jsr w5100_read_register
+ sta tcp_inbound_data_length+1
+ ldax #W5100_S1_RX_RSR1
+ jsr w5100_read_register
+ sta tcp_inbound_data_length
+ bne @got_data
+ lda tcp_inbound_data_length+1
+ bne @got_data
+
+ ;are we connected?
+ ldax #W5100_S1_SR
+ jsr w5100_read_register
+ cmp #W5100_STATUS_SOCK_ESTABLISHED
+ beq @connected_but_no_data
+ ;no longer connected
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+
+ lda #$ff
+ sta tcp_inbound_data_length
+ sta tcp_inbound_data_length+1
+ jsr @make_fake_eth_header
+ jsr jmp_to_callback ;let the caller see the connection has closed
+ sec ;don't poll the MAC RAW socket, else it may clobber the output buffer
+ rts
+@connected_but_no_data:
+ clc ;no data - go check the MAC RAW socket
+ rts
+@got_data:
+ lda #$8D ;opcode for STA
+ sta next_eth_packet_byte
+
+ ldax #eth_inp+$36 ;we will write to the location that TCP data would appear if this was a raw eth frame,
+ ;14 bytes of ethernet header
+ ;20 bytes of IP header
+ ;20 bytes of TCP header
+
+ stax tcp_inbound_data_ptr
+
+
+ sta eth_ptr_lo
+ stx eth_ptr_hi
+
+ lda #0
+ sta byte_ctr_lo
+ sta byte_ctr_hi
+
+ lda tcp_inbound_data_length+1
+ cmp #4 ;don't allow more than $4FF bytes at once ($1279) since we are writing to a 1500 byte
+ bmi :+
+ lda #4
+ sta tcp_inbound_data_length+1
+:
+
+ ;now copy the data just arrived to the eth_inp buffer
+ jsr @get_current_rx_rd
+ jsr @mask_and_adjust_rx_read
+@get_next_byte:
+
+ ldax rx_rd_ptr
+ jsr w5100_read_register
+ jsr next_eth_packet_byte
+
+ jsr @inc_rx_rd_ptr
+
+ inc byte_ctr_lo
+ bne :+
+ inc byte_ctr_hi
+:
+
+ lda byte_ctr_lo
+ cmp tcp_inbound_data_length
+ bne @get_next_byte
+ lda byte_ctr_hi
+ cmp tcp_inbound_data_length+1
+ bne @get_next_byte
+
+
+;update the RX RD pointer past the frame we just read
+ jsr @get_current_rx_rd
+ clc
+ lda rx_rd_ptr
+ adc tcp_inbound_data_length
+ sta rx_rd_ptr
+ lda rx_rd_ptr+1
+ adc tcp_inbound_data_length+1
+ tay
+ ldax #W5100_S1_RX_RD0
+ jsr w5100_write_register
+ ldy rx_rd_ptr
+
+ ldax #W5100_S1_RX_RD1
+ jsr w5100_write_register
+ ldax #W5100_S1_CR
+ ldy #W5100_CMD_RECV
+ jsr w5100_write_register
+
+ jsr @make_fake_eth_header
+ jsr jmp_to_callback ;let the caller see the connection has closed
+ sec ;don't poll the MAC RAW socket, else it may clobber the output buffer
+ rts
+
+@inc_rx_rd_ptr:
+ inc rx_rd_ptr
+ bne :+
+ inc rx_rd_ptr+1
+@mask_and_adjust_rx_read:
+ lda rx_rd_ptr+1
+ and #$0F
+ clc
+ adc #$70
+ sta rx_rd_ptr+1
+:
+ rts
+
+@get_current_rx_rd:
+ ldax #W5100_S1_RX_RD0
+ jsr w5100_read_register
+ sta rx_rd_ptr+1
+ ldax #W5100_S1_RX_RD1
+ jsr w5100_read_register
+ sta rx_rd_ptr
+ rts
+
+;the function dispatcher (and possibly other parts of the ip65 stack) expect to find valid values in the eth_inp frame
+;when processing tcp data
+@make_fake_eth_header:
+
+ .import ip_inp
+ .import udp_inp
+ ;first set the TCP protocol value
+ lda #6 ;TCP protocol number
+ sta ip_inp+9 ;proto number
+
+ ;now copy the remote IP address
+ ldx #0
+@ip_loop:
+ lda tcp_remote_ip,x
+ sta ip_inp+12,x ;src IP
+ inx
+ cpx #$04
+ bne @ip_loop
+
+ ;now the local & remote ports
+ lda tcp_connect_remote_port
+ sta udp_inp+1 ;remote port (lo byte)
+ lda tcp_connect_remote_port+1
+ sta udp_inp+0 ;remote port (high byte)
+ lda tcp_local_port
+ sta udp_inp+3 ;local port (lo byte)
+ lda tcp_local_port+1
+ sta udp_inp+2 ;local port (high byte)
+
+ rts
+
+jmp_to_callback:
+ jmp (tcp_callback)
+
+
+;copy the IP65 configuration to the the w5100 onchip configuration
+;we assume MAC has been configured already via eth_init, but IP
+;address etc may not be known when the w5100 was initialised (e.g.
+;if using DHCP).
+w5100_set_ip_config:
+ ldax #W5100_GAR0
+ jsr w5100_select_register
+ ldx #0
+@gateway_loop:
+ lda cfg_gateway,x
+ sta WIZNET_DATA_REG
+ inx
+ cpx #$04
+ bne @gateway_loop
+ ldx #0
+@netmask_loop:
+ lda cfg_netmask,x
+ sta WIZNET_DATA_REG
+ inx
+ cpx #$04
+ bne @netmask_loop
+
+ ldax #W5100_SIPR0
+ jsr w5100_select_register
+ ldx #0
+@ip_loop:
+ lda cfg_ip,x
+ sta WIZNET_DATA_REG
+ inx
+ cpx #$04
+ bne @ip_loop
+ rts
+
+setup_tcp_socket:
+ jsr w5100_set_ip_config
+ ldax #W5100_S1_PORT0
+ jsr w5100_select_register
+ lda tcp_local_port+1
+ sta WIZNET_DATA_REG
+ lda tcp_local_port
+ sta WIZNET_DATA_REG
+
+ lda #0
+ sta tcp_state
+
+ ldax #W5100_S1_MR
+ ldy #W5100_MODE_TCP
+ jsr w5100_write_register
+
+ ;open socket 1
+ ldax #W5100_S1_CR
+ ldy #W5100_CMD_OPEN
+ jsr w5100_write_register
+ rts
+
+
+.rodata
+eth_driver_name:
+ .asciiz "RR-NET MK3 (WIZNET 5100)"
+
+eth_driver_io_base:
+ .word WIZNET_BASE
+
+w5100_config_data:
+ .byte $00 ;no interrupts
+ .byte $0f ;400ms retry (default)
+ .byte $a0
+ .byte $08 ;# of timeouts
+ .byte $55 ;4 sockets @2K each, tx/rx
+ .byte $55
+
+
+;
+; select one of the W5100 registers for subsequent read or write
+; inputs: AX = register number to select
+; outputs: none
+w5100_select_register:
+set_hi:
+ stx WIZNET_ADDR_HI
+set_lo:
+ sta WIZNET_ADDR_LO
+ rts
+
+; return which W5100 register the next read or write will access
+; inputs: none
+; outputs: AX = selected register number
+w5100_get_current_register:
+get_hi:
+ ldx WIZNET_ADDR_HI
+get_lo:
+ lda WIZNET_ADDR_LO
+ rts
+
+
+.segment "SELF_MODIFIED_CODE"
+
+next_eth_packet_byte:
+ lda $FFFF ;eth_packet
+ jmp advance_eth_ptr
+
+eth_ptr_lo=next_eth_packet_byte+1
+eth_ptr_hi=next_eth_packet_byte+2
+
+; .bss
+; don't use BSS because we are out of room in the location that lives in the
+; config used for 16K carts ($C010..$CFFF)
+;there seems to be a little room still free in the seg used for SELF_MODIFIED_CODE
+
+ w5100_addr: .res 2
+ byte_ctr_lo: .res 1
+ byte_ctr_hi: .res 1
+
+ tx_wr_ptr: .res 2
+ rx_rd_ptr: .res 2
+tcp_local_port: .res 2
+
+tcp_state: .res 1
+
+tcp_connect_ip: .res 4 ;ip address of remote server to connect to
+tcp_callback: .res 2 ;vector to routine to be called when data is received over tcp connection
+
+tcp_remote_port: .res 2 ;temp space for holding port to listen on or connect to
+tcp_send_data_len: .res 2
+tcp_send_data_ptr = eth_ptr_lo
+
+
+tcp_inbound_data_length: .res 2
+tcp_inbound_data_ptr: .res 2
+
+tcp_connect_remote_port: .res 2
+tcp_remote_ip = tcp_connect_ip
+
+tcp_cxn_state_closed = 0
+tcp_cxn_state_listening = 1 ;(waiting for an inbound SYN)
+tcp_cxn_state_syn_sent = 2 ;(waiting for an inbound SYN/ACK)
+tcp_cxn_state_established = 3 ;
+
+
+;-- 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
+; 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 is Copyright (C) 2010
+; Jonno Downes. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/inc/common.i b/inc/common.i
similarity index 95%
rename from client/inc/common.i
rename to inc/common.i
index aaed06e..48df41f 100644
--- a/client/inc/common.i
+++ b/inc/common.i
@@ -1,65 +1,65 @@
-.ifndef COMMON__I__
-COMMON__I__ = 1
-; load A/X macro
- .macro ldax arg
- .if (.match (.left (1, arg), #)) ; immediate mode
- lda #<(.right (.tcount (arg)-1, arg))
- ldx #>(.right (.tcount (arg)-1, arg))
- .else ; assume absolute or zero page
- lda arg
- ldx 1+(arg)
- .endif
- .endmacro
-
-; store A/X macro
- .macro stax arg
- sta arg
- stx 1+(arg)
- .endmacro
-
-
-; load A/y macro
- .macro lday arg
- .if (.match (.left (1, arg), #)) ; immediate mode
- lda #<(.right (.tcount (arg)-1, arg))
- ldy #>(.right (.tcount (arg)-1, arg))
- .else ; assume absolute or zero page
- lda arg
- ldy 1+(arg)
- .endif
- .endmacro
-
-
-.macro phax
- pha
- txa
- pha
-.endmacro
-
-.macro plax
- pla
- tax
- pla
-.endmacro
-
-.endif
-
-
-;-- LICENSE FOR common.i --
-; 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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+.ifndef COMMON__I__
+COMMON__I__ = 1
+; load A/X macro
+ .macro ldax arg
+ .if (.match (.left (1, arg), #)) ; immediate mode
+ lda #<(.right (.tcount (arg)-1, arg))
+ ldx #>(.right (.tcount (arg)-1, arg))
+ .else ; assume absolute or zero page
+ lda arg
+ ldx 1+(arg)
+ .endif
+ .endmacro
+
+; store A/X macro
+ .macro stax arg
+ sta arg
+ stx 1+(arg)
+ .endmacro
+
+
+; load A/y macro
+ .macro lday arg
+ .if (.match (.left (1, arg), #)) ; immediate mode
+ lda #<(.right (.tcount (arg)-1, arg))
+ ldy #>(.right (.tcount (arg)-1, arg))
+ .else ; assume absolute or zero page
+ lda arg
+ ldy 1+(arg)
+ .endif
+ .endmacro
+
+
+.macro phax
+ pha
+ txa
+ pha
+.endmacro
+
+.macro plax
+ pla
+ tax
+ pla
+.endmacro
+
+.endif
+
+
+;-- LICENSE FOR common.i --
+; 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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/inc/commonprint.i b/inc/commonprint.i
similarity index 94%
rename from client/inc/commonprint.i
rename to inc/commonprint.i
index 67304db..19da6bb 100644
--- a/client/inc/commonprint.i
+++ b/inc/commonprint.i
@@ -1,430 +1,430 @@
-.ifndef SCREEN_WIDTH
- SCREEN_WIDTH = 40
-.endif
-
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- .export print_hex
- .export print_ip_config
- .export dhcp_msg
- .export ok_msg
- .export failed_msg
- .export init_msg
- .export print
- .export print_ascii_as_native
- .export print_integer
- .export print_dotted_quad
- .export mac_address_msg
- .export ip_address_msg
- .export netmask_msg
- .export gateway_msg
- .export dns_server_msg
- .export tftp_server_msg
- .import ip65_error
- .export print_errorcode
- .export press_a_key_to_continue
-
-.import ascii_to_native
-
-
-.import eth_driver_name
-.import eth_driver_io_base
-.importzp copy_src
-.import cfg_tftp_server
-;reuse the copy_src zero page var
-pptr = copy_src
-
-.bss
-temp_bin: .res 2
-temp_bcd: .res 3
-temp_ptr: .res 2
-.code
-
- .macro print_hex_double arg
- lda #>(.right (.tcount (arg)-1, arg))
- jsr print_hex
- lda #<(.right (.tcount (arg)-1, arg))
- jsr print_hex
-.endmacro
-
-.macro print_driver_init
- ldax #eth_driver_name
- jsr print_ascii_as_native
- lda #'('
- jsr print_a
- lda #'$'
- jsr print_a
- lda eth_driver_io_base+1
- jsr print_hex
- lda eth_driver_io_base
- jsr print_hex
- lda #')'
- jsr print_a
-
- ldax #init_msg
- jsr print_ascii_as_native
-.endmacro
-
-
-.macro print_dhcp_init
- ldax #dhcp_msg
- jsr print_ascii_as_native
- ldax #init_msg
- jsr print_ascii_as_native
-.endmacro
-
-.macro print_failed
- ldax #failed_msg
- jsr print_ascii_as_native
- jsr print_cr
-.endmacro
-
-.macro print_ok
- ldax #ok_msg
- jsr print_ascii_as_native
- jsr print_cr
-.endmacro
-
-
-.code
-
-.import print_a
-.import print_cr
-.import eth_driver_name
-print_ip_config:
-
- ldax #interface_type
- jsr print_ascii_as_native
-
- ldax #eth_driver_name
- jsr print_ascii_as_native
- jsr print_cr
-
- ldax #mac_address_msg
- jsr print_ascii_as_native
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- ;first 6 bytes of cfg_get_configuration_ptr is MAC address
- jsr print_mac
- jsr print_cr
-
- ldax #ip_address_msg
- jsr print_ascii_as_native
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_IP
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #netmask_msg
- jsr print_ascii_as_native
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_NETMASK
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #gateway_msg
- jsr print_ascii_as_native
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_GATEWAY
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #dns_server_msg
- jsr print_ascii_as_native
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_DNS_SERVER
- bcc :+
- inx
-: jsr print_dotted_quad
- jsr print_cr
-
- ldax #tftp_server_msg
- jsr print_ascii_as_native
- ldax #cfg_tftp_server
- jsr print_dotted_quad
- jsr print_cr
-
- ldax #dhcp_server_msg
- jsr print_ascii_as_native
- jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
- adc #KPR_CFG_DHCP_SERVER
- bcc :+
- inx
-:
- jsr print_dotted_quad
- jsr print_cr
-
- 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
-
-print_ascii_as_native:
- sta pptr
- stx pptr + 1
-
-@print_loop:
- ldy #0
- lda (pptr),y
- beq @done_print
- jsr ascii_to_native
- jsr print_a
- inc pptr
- bne @print_loop
- inc pptr+1
- bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-)
-@done_print:
- rts
-
-
-;print the 4 bytes pointed at by AX as dotted decimals
-print_dotted_quad:
- sta pptr
- stx pptr + 1
- lda #0
-@print_one_byte:
- pha
- tay
- lda (pptr),y
- ldx #0
- jsr print_integer
- pla
- cmp #3
- beq @done
- clc
- adc #1
- pha
- lda #'.'
- jsr print_a
- pla
- bne @print_one_byte
-@done:
-
- rts
-
-;print 6 bytes printed at by AX as a MAC address
-print_mac:
- stax pptr
- ldy #0
-@one_mac_digit:
- tya ;just to set the Z flag
- pha
- beq @dont_print_colon
- lda #':'
- jsr print_a
-@dont_print_colon:
- pla
- tay
- lda (pptr),y
- jsr print_hex
- iny
- cpy #06
- bne @one_mac_digit
- rts
-
-print_integer: ;print 16 bit number in AX as a decimal number
-
-;hex to bcd routine taken from Andrew Jacob's code at http://www.6502.org/source/integers/hex2dec-more.htm
- stax temp_bin
- sed ; Switch to decimal mode
- lda #0 ; Ensure the result is clear
- sta temp_bcd
- sta temp_bcd+1
- sta temp_bcd+2
- ldx #16 ; The number of source bits
- :
- asl temp_bin+0 ; Shift out one bit
- rol temp_bin+1
- 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
- lda temp_bcd+2 ; ... thru whole result
- adc temp_bcd+2
- sta temp_bcd+2
-
- dex ; And repeat for next bit
- bne :-
-
- stx temp_bin+1 ;x is now zero - reuse temp_bin as a count of non-zero digits
- cld ;back to binary
- ldx #2
- stx temp_bin+1 ;reuse temp_bin+1 as loop counter
-@print_one_byte:
- ldx temp_bin+1
- lda temp_bcd,x
- pha
- lsr
- lsr
- lsr
- lsr
- jsr @print_one_digit
- pla
- and #$0f
- jsr @print_one_digit
- dec temp_bin+1
- bpl @print_one_byte
- rts
-@print_one_digit:
- cmp #0
- beq @this_digit_is_zero
- inc temp_bin ;increment count of non-zero digits
-@ok_to_print:
- clc
- adc #'0'
- jsr print_a
- rts
-@this_digit_is_zero:
- ldx temp_bin ;how many non-zero digits have we printed?
- bne @ok_to_print
- ldx temp_bin+1 ;how many digits are left to print?
- bne @this_is_not_last_digit
- inc temp_bin ;to get to this point, this must be the high nibble of the last byte.
- ;by making 'count of non-zero digits' to be >0, we force printing of the last digit
-@this_is_not_last_digit:
- rts
-
-print_hex:
- pha
- pha
- lsr
- lsr
- lsr
- lsr
- tax
- lda hexdigits,x
- jsr print_a
- pla
- and #$0F
- tax
- lda hexdigits,x
- jsr print_a
- pla
- rts
-
-print_errorcode:
- ldax #error_code
- jsr print_ascii_as_native
- lda ip65_error
- jsr print_hex
- jmp print_cr
-
-.rodata
-hexdigits:
-.byte "0123456789ABCDEF"
-
-.if SCREEN_WIDTH >=30
-
-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
-
-dns_server_msg:
-.byte "DNS Server : ", 0
-
-dhcp_server_msg:
-.byte "DHCP Server : ", 0
-
-tftp_server_msg:
-.byte "TFTP Server : ", 0
-.else ;for small width screens e.g. VIC 20
-interface_type:
-.byte "Interface",10,0
-mac_address_msg:
-.byte "MAC Address",10,0
-ip_address_msg:
-.byte "IP Address",10,0
-netmask_msg:
-.byte "Netmask",10,0
-gateway_msg:
-.byte "Gateway",10,0
-dns_server_msg:
-.byte "DNS Server",10,0
-dhcp_server_msg:
-.byte "DHCP Server",10,0
-tftp_server_msg:
-.byte "TFTP Server",10,0
-
-.endif
-
-dhcp_msg:
- .byte "DHCP",0
-
-init_msg:
- .byte " Initializing ",0
-
-
-failed_msg:
- .byte "failed", 0
-
-ok_msg:
- .byte "OK", 0
-
-dns_lookup_failed_msg:
- .byte "DNS LOOKUP FAILED", 0
-
-error_code:
- .asciiz "error code: "
-
-press_a_key_to_continue:
- .byte "Press a key to continue",10,0
-
-
-
-;-- LICENSE FOR commonprint.i --
-; 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 --
+.ifndef SCREEN_WIDTH
+ SCREEN_WIDTH = 40
+.endif
+
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+ .export print_hex
+ .export print_ip_config
+ .export dhcp_msg
+ .export ok_msg
+ .export failed_msg
+ .export init_msg
+ .export print
+ .export print_ascii_as_native
+ .export print_integer
+ .export print_dotted_quad
+ .export mac_address_msg
+ .export ip_address_msg
+ .export netmask_msg
+ .export gateway_msg
+ .export dns_server_msg
+ .export tftp_server_msg
+ .import ip65_error
+ .export print_errorcode
+ .export press_a_key_to_continue
+
+.import ascii_to_native
+
+
+.import eth_driver_name
+.import eth_driver_io_base
+.importzp copy_src
+.import cfg_tftp_server
+;reuse the copy_src zero page var
+pptr = copy_src
+
+.bss
+temp_bin: .res 2
+temp_bcd: .res 3
+temp_ptr: .res 2
+.code
+
+ .macro print_hex_double arg
+ lda #>(.right (.tcount (arg)-1, arg))
+ jsr print_hex
+ lda #<(.right (.tcount (arg)-1, arg))
+ jsr print_hex
+.endmacro
+
+.macro print_driver_init
+ ldax #eth_driver_name
+ jsr print_ascii_as_native
+ lda #'('
+ jsr print_a
+ lda #'$'
+ jsr print_a
+ lda eth_driver_io_base+1
+ jsr print_hex
+ lda eth_driver_io_base
+ jsr print_hex
+ lda #')'
+ jsr print_a
+
+ ldax #init_msg
+ jsr print_ascii_as_native
+.endmacro
+
+
+.macro print_dhcp_init
+ ldax #dhcp_msg
+ jsr print_ascii_as_native
+ ldax #init_msg
+ jsr print_ascii_as_native
+.endmacro
+
+.macro print_failed
+ ldax #failed_msg
+ jsr print_ascii_as_native
+ jsr print_cr
+.endmacro
+
+.macro print_ok
+ ldax #ok_msg
+ jsr print_ascii_as_native
+ jsr print_cr
+.endmacro
+
+
+.code
+
+.import print_a
+.import print_cr
+.import eth_driver_name
+print_ip_config:
+
+ ldax #interface_type
+ jsr print_ascii_as_native
+
+ ldax #eth_driver_name
+ jsr print_ascii_as_native
+ jsr print_cr
+
+ ldax #mac_address_msg
+ jsr print_ascii_as_native
+ jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
+ ;first 6 bytes of cfg_get_configuration_ptr is MAC address
+ jsr print_mac
+ jsr print_cr
+
+ ldax #ip_address_msg
+ jsr print_ascii_as_native
+ jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
+ adc #KPR_CFG_IP
+ bcc :+
+ inx
+:
+ jsr print_dotted_quad
+ jsr print_cr
+
+ ldax #netmask_msg
+ jsr print_ascii_as_native
+ jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
+ adc #KPR_CFG_NETMASK
+ bcc :+
+ inx
+:
+ jsr print_dotted_quad
+ jsr print_cr
+
+ ldax #gateway_msg
+ jsr print_ascii_as_native
+ jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
+ adc #KPR_CFG_GATEWAY
+ bcc :+
+ inx
+:
+ jsr print_dotted_quad
+ jsr print_cr
+
+ ldax #dns_server_msg
+ jsr print_ascii_as_native
+ jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
+ adc #KPR_CFG_DNS_SERVER
+ bcc :+
+ inx
+: jsr print_dotted_quad
+ jsr print_cr
+
+ ldax #tftp_server_msg
+ jsr print_ascii_as_native
+ ldax #cfg_tftp_server
+ jsr print_dotted_quad
+ jsr print_cr
+
+ ldax #dhcp_server_msg
+ jsr print_ascii_as_native
+ jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear
+ adc #KPR_CFG_DHCP_SERVER
+ bcc :+
+ inx
+:
+ jsr print_dotted_quad
+ jsr print_cr
+
+ 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
+
+print_ascii_as_native:
+ sta pptr
+ stx pptr + 1
+
+@print_loop:
+ ldy #0
+ lda (pptr),y
+ beq @done_print
+ jsr ascii_to_native
+ jsr print_a
+ inc pptr
+ bne @print_loop
+ inc pptr+1
+ bne @print_loop ;if we ever get to $ffff, we've probably gone far enough ;-)
+@done_print:
+ rts
+
+
+;print the 4 bytes pointed at by AX as dotted decimals
+print_dotted_quad:
+ sta pptr
+ stx pptr + 1
+ lda #0
+@print_one_byte:
+ pha
+ tay
+ lda (pptr),y
+ ldx #0
+ jsr print_integer
+ pla
+ cmp #3
+ beq @done
+ clc
+ adc #1
+ pha
+ lda #'.'
+ jsr print_a
+ pla
+ bne @print_one_byte
+@done:
+
+ rts
+
+;print 6 bytes printed at by AX as a MAC address
+print_mac:
+ stax pptr
+ ldy #0
+@one_mac_digit:
+ tya ;just to set the Z flag
+ pha
+ beq @dont_print_colon
+ lda #':'
+ jsr print_a
+@dont_print_colon:
+ pla
+ tay
+ lda (pptr),y
+ jsr print_hex
+ iny
+ cpy #06
+ bne @one_mac_digit
+ rts
+
+print_integer: ;print 16 bit number in AX as a decimal number
+
+;hex to bcd routine taken from Andrew Jacob's code at http://www.6502.org/source/integers/hex2dec-more.htm
+ stax temp_bin
+ sed ; Switch to decimal mode
+ lda #0 ; Ensure the result is clear
+ sta temp_bcd
+ sta temp_bcd+1
+ sta temp_bcd+2
+ ldx #16 ; The number of source bits
+ :
+ asl temp_bin+0 ; Shift out one bit
+ rol temp_bin+1
+ 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
+ lda temp_bcd+2 ; ... thru whole result
+ adc temp_bcd+2
+ sta temp_bcd+2
+
+ dex ; And repeat for next bit
+ bne :-
+
+ stx temp_bin+1 ;x is now zero - reuse temp_bin as a count of non-zero digits
+ cld ;back to binary
+ ldx #2
+ stx temp_bin+1 ;reuse temp_bin+1 as loop counter
+@print_one_byte:
+ ldx temp_bin+1
+ lda temp_bcd,x
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ jsr @print_one_digit
+ pla
+ and #$0f
+ jsr @print_one_digit
+ dec temp_bin+1
+ bpl @print_one_byte
+ rts
+@print_one_digit:
+ cmp #0
+ beq @this_digit_is_zero
+ inc temp_bin ;increment count of non-zero digits
+@ok_to_print:
+ clc
+ adc #'0'
+ jsr print_a
+ rts
+@this_digit_is_zero:
+ ldx temp_bin ;how many non-zero digits have we printed?
+ bne @ok_to_print
+ ldx temp_bin+1 ;how many digits are left to print?
+ bne @this_is_not_last_digit
+ inc temp_bin ;to get to this point, this must be the high nibble of the last byte.
+ ;by making 'count of non-zero digits' to be >0, we force printing of the last digit
+@this_is_not_last_digit:
+ rts
+
+print_hex:
+ pha
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ tax
+ lda hexdigits,x
+ jsr print_a
+ pla
+ and #$0F
+ tax
+ lda hexdigits,x
+ jsr print_a
+ pla
+ rts
+
+print_errorcode:
+ ldax #error_code
+ jsr print_ascii_as_native
+ lda ip65_error
+ jsr print_hex
+ jmp print_cr
+
+.rodata
+hexdigits:
+.byte "0123456789ABCDEF"
+
+.if SCREEN_WIDTH >=30
+
+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
+
+dns_server_msg:
+.byte "DNS Server : ", 0
+
+dhcp_server_msg:
+.byte "DHCP Server : ", 0
+
+tftp_server_msg:
+.byte "TFTP Server : ", 0
+.else ;for small width screens e.g. VIC 20
+interface_type:
+.byte "Interface",10,0
+mac_address_msg:
+.byte "MAC Address",10,0
+ip_address_msg:
+.byte "IP Address",10,0
+netmask_msg:
+.byte "Netmask",10,0
+gateway_msg:
+.byte "Gateway",10,0
+dns_server_msg:
+.byte "DNS Server",10,0
+dhcp_server_msg:
+.byte "DHCP Server",10,0
+tftp_server_msg:
+.byte "TFTP Server",10,0
+
+.endif
+
+dhcp_msg:
+ .byte "DHCP",0
+
+init_msg:
+ .byte " Initializing ",0
+
+
+failed_msg:
+ .byte "failed", 0
+
+ok_msg:
+ .byte "OK", 0
+
+dns_lookup_failed_msg:
+ .byte "DNS LOOKUP FAILED", 0
+
+error_code:
+ .asciiz "error code: "
+
+press_a_key_to_continue:
+ .byte "Press a key to continue",10,0
+
+
+
+;-- LICENSE FOR commonprint.i --
+; 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/inc/kipper_constants.i b/inc/kipper_constants.i
similarity index 98%
rename from client/inc/kipper_constants.i
rename to inc/kipper_constants.i
index d8e1083..a4cc905 100644
--- a/client/inc/kipper_constants.i
+++ b/inc/kipper_constants.i
@@ -1,171 +1,171 @@
-;constants for accessing the KPR API file
-;to use this file under CA65, then add " .define EQU =" to your code before this file is included.
-
-
-KPR_API_VERSION_NUMBER EQU $01
-
-
-KPR_CART_SIGNATURE EQU $8009
-KPR_DISPATCH_VECTOR EQU $800f
-KPR_PERIODIC_PROCESSING_VECTOR EQU $8012
-
-;function numbers
-;to make a function call:
-; Y EQU function number
-; AX EQU pointer to parameter buffer (for functions that take parameters)
-; then JSR KPR_DISPATCH_VECTOR
-; on return, carry flag is set if there is an error, or clear otherwise
-; some functions return results in AX directly, others will update the parameter buffer they were called with.
-; any register not specified in outputs will have an undefined value on exit
-
-KPR_INITIALIZE EQU $01 ;no inputs or outputs - initializes IP stack, also sets IRQ chain to call KPR_VBL_VECTOR at @ 60hz
-KPR_GET_IP_CONFIG EQU $02 ;no inputs, outputs AX=pointer to IP configuration structure
-KPR_DEACTIVATE EQU $0F ;inputs: none, outputs: none (removes call to KPR_VBL_VECTOR on IRQ chain)
-
-KPR_UDP_ADD_LISTENER EQU $10 ;inputs: AX points to a UDP listener parameter structure, outputs: none
-KPR_GET_INPUT_PACKET_INFO EQU $11 ;inputs: AX points to a UDP/TCP packet parameter structure, outputs: UDP/TCP packet structure filled in
-KPR_SEND_UDP_PACKET EQU $12 ;inputs: AX points to a UDP packet parameter structure, outputs: none packet is sent
-KPR_UDP_REMOVE_LISTENER EQU $13 ;inputs: AX contains UDP port number that listener will be removed from
-
-KPR_TCP_CONNECT EQU $14 ;inputs: AX points to a TCP connect parameter structure, outputs: none
-KPR_SEND_TCP_PACKET EQU $15 ;inputs: AX points to a TCP send parameter structure, outputs: none packet is sent
-KPR_TCP_CLOSE_CONNECTION EQU $16 ;inputs: none outputs: none
-
-KPR_TFTP_SET_SERVER EQU $20 ;inputs: AX points to a TFTP server parameter structure, outputs: none
-KPR_TFTP_DOWNLOAD EQU $22 ;inputs: AX points to a TFTP transfer parameter structure, outputs: TFTP param structure updated with
- ;KPR_TFTP_POINTER updated to reflect actual load address (if load address $0000 originally passed in)
-KPR_TFTP_CALLBACK_DOWNLOAD EQU $23 ;inputs: AX points to a TFTP transfer parameter structure, outputs: none
-KPR_TFTP_UPLOAD EQU $24 ;upload: AX points to a TFTP transfer parameter structure, outputs: none
-KPR_TFTP_CALLBACK_UPLOAD EQU $25 ;upload: AX points to a TFTP transfer parameter structure, outputs: none
-
-KPR_DNS_RESOLVE EQU $30 ;inputs: AX points to a DNS parameter structure, outputs: DNS param structure updated with
- ;KPR_DNS_HOSTNAME_IP updated with IP address corresponding to hostname.
-KPR_DOWNLOAD_RESOURCE EQU $31 ;inputs: AX points to a URL download structure, outputs: none
-KPR_PING_HOST EQU $32 ;inputs: AX points to destination IP address for ping, outputs: AX=time (in milliseconds) to get response
-
-KPR_FILE_LOAD EQU $40 ;inputs: AX points to a file access parameter structure, outputs: none
-
-KPR_HTTPD_START EQU $50 ;inputs: AX points to a routine to call for each inbound request, outputs: none
-KPR_HTTPD_GET_VAR_VALUE EQU $52 ;inputs: A=variable to get value for ($01 to get method, $02 to get path)
-
-KPR_PRINT_ASCIIZ EQU $80 ;inputs: AX=pointer to null terminated string to be printed to screen, outputs: none
-KPR_PRINT_HEX EQU $81 ;inputs: A=byte digit to be displayed on screen as (zero padded) hex digit, outputs: none
-KPR_PRINT_DOTTED_QUAD EQU $82 ;inputs: AX=pointer to 4 bytes that will be displayed as a decimal dotted quad (e.g. 192.168.1.1)
-KPR_PRINT_IP_CONFIG EQU $83 ;no inputs, no outputs, prints to screen current IP configuration
-KPR_PRINT_INTEGER EQU $84 ;inputs: AX=16 byte number that will be printed as an unsigned decimal
-
-KPR_INPUT_STRING EQU $90 ;no inputs, outputs: AX = pointer to null terminated string
-KPR_INPUT_HOSTNAME EQU $91 ;no inputs, outputs: AX = pointer to hostname (which may be IP address).
-KPR_INPUT_PORT_NUMBER EQU $92 ;no inputs, outputs: AX = port number entered ($0000..$FFFF)
-
-KPR_BLOCK_COPY EQU $A0 ;inputs: AX points to a block copy structure, outputs: none
-KPR_PARSER_INIT EQU $A1 ;inputs: AX points to a null terminated string, outputs: none
-KPR_PARSER_SKIP_NEXT EQU $A2 ;inputs: AX points to a null terminated substring, outputs: AX points to
- ;previously loaded string that is just past the next occurance of substring
-
-KPR_GET_LAST_ERROR EQU $FF ;no inputs, outputs A EQU error code (from last function that set the global error value, not necessarily the
- ;last function that was called)
-
-;offsets in IP configuration structure (used by KPR_GET_IP_CONFIG)
-KPR_CFG_MAC EQU $00 ;6 byte MAC address
-KPR_CFG_IP EQU $06 ;4 byte local IP address (will be overwritten by DHCP)
-KPR_CFG_NETMASK EQU $0A ;4 byte local netmask (will be overwritten by DHCP)
-KPR_CFG_GATEWAY EQU $0E ;4 byte local gateway (will be overwritten by DHCP)
-KPR_CFG_DNS_SERVER EQU $12 ;4 byte IP address of DNS server (will be overwritten by DHCP)
-KPR_CFG_DHCP_SERVER EQU $16 ;4 byte IP address of DHCP server (will only be set by DHCP initialisation)
-KPR_DRIVER_NAME EQU $1A ;2 byte pointer to name of driver
-
-;offsets in TFTP transfer parameter structure (used by KPR_TFTP_DOWNLOAD, KPR_TFTP_CALLBACK_DOWNLOAD, KPR_TFTP_UPLOAD, KPR_TFTP_CALLBACK_UPLOAD)
-KPR_TFTP_FILENAME EQU $00 ;2 byte pointer to asciiz filename (or filemask)
-KPR_TFTP_POINTER EQU $02 ;2 byte pointer to memory location data to be stored in OR address of callback function
-KPR_TFTP_FILESIZE EQU $04 ;2 byte file length (filled in by KPR_TFTP_DOWNLOAD, must be passed in to KPR_TFTP_UPLOAD)
-
-;offsets in TFTP Server parameter structure (used by KPR_TFTP_SET_SERVER)
-KPR_TFTP_SERVER_IP EQU $00 ;4 byte IP address of TFTP server
-
-
-;offsets in DNS parameter structure (used by KPR_DNS_RESOLVE)
-KPR_DNS_HOSTNAME EQU $00 ;2 byte pointer to asciiz hostname to resolve (can also be a dotted quad string)
-KPR_DNS_HOSTNAME_IP EQU $00 ;4 byte IP address (filled in on succesful resolution of hostname)
-
-;offsets in UDP listener parameter structure
-KPR_UDP_LISTENER_PORT EQU $00 ;2 byte port number
-KPR_UDP_LISTENER_CALLBACK EQU $02 ;2 byte address of routine to call when UDP packet arrives for specified port
-
-;offsets in block copy parameter structure
-KPR_BLOCK_SRC EQU $00 ;2 byte address of start of source block
-KPR_BLOCK_DEST EQU $02 ;2 byte address of start of destination block
-KPR_BLOCK_SIZE EQU $04 ;2 byte length of block to be copied (in bytes
-
-
-;offsets in TCP connect parameter structure
-KPR_TCP_REMOTE_IP EQU $00 ;4 byte IP address of remote host (0.0.0.0 means wait for inbound i.e. server mode)
-KPR_TCP_PORT EQU $04 ;2 byte port number (to listen on, if ip address was 0.0.0.0, or connect to otherwise)
-KPR_TCP_CALLBACK EQU $06 ;2 byte address of routine to be called whenever a new packet arrives
-
-;offsets in TCP send parameter structure
-KPR_TCP_PAYLOAD_LENGTH EQU $00 ;2 byte length of payload of packet (after all ethernet,IP,UDP/TCP headers)
-KPR_TCP_PAYLOAD_POINTER EQU $02 ;2 byte pointer to payload of packet (after all headers)
-
-
-
-;offsets in TCP/UDP packet parameter structure
-KPR_REMOTE_IP EQU $00 ;4 byte IP address of remote machine (src of inbound packets, dest of outbound packets)
-KPR_REMOTE_PORT EQU $04 ;2 byte port number of remote machine (src of inbound packets, dest of outbound packets)
-KPR_LOCAL_PORT EQU $06 ;2 byte port number of local machine (src of outbound packets, dest of inbound packets)
-KPR_PAYLOAD_LENGTH EQU $08 ;2 byte length of payload of packet (after all ethernet,IP,UDP/TCP headers)
- ; in a TCP connection, if the length is $FFFF, this actually means "end of connection"
-KPR_PAYLOAD_POINTER EQU $0A ;2 byte pointer to payload of packet (after all headers)
-
-;offsets in URL download structure
-;inputs:
-KPR_URL EQU $00 ;2 byte pointer to null terminated URL (NB - must be ASCII not "native" string)
-KPR_URL_DOWNLOAD_BUFFER EQU $02 ;2 byte pointer to buffer that resource specified by URL will be downloaded into
-KPR_URL_DOWNLOAD_BUFFER_LENGTH EQU $04 ;2 byte length of buffer (download will truncate when buffer is full)
-
-
-;offsets in file access parameter structure (used by KPR_FILE_LOAD)
-KPR_FILE_ACCESS_FILENAME EQU $00 ;2 byte pointer to asciiz filename (or filemask)
-KPR_FILE_ACCESS_POINTER EQU $02 ;2 byte pointer to memory location data to be stored in OR address of callback function
-KPR_FILE_ACCESS_FILESIZE EQU $04 ;2 byte file length (filled in by KPR_FILE_ACCESS)
-KPR_FILE_ACCESS_DEVICE EQU $06 ;1 byte device number (set to $00 to use last accessed device)
-
-;error codes (as returned by KPR_GET_LAST_ERROR)
-KPR_ERROR_PORT_IN_USE EQU $80
-KPR_ERROR_TIMEOUT_ON_RECEIVE EQU $81
-KPR_ERROR_TRANSMIT_FAILED EQU $82
-KPR_ERROR_TRANSMISSION_REJECTED_BY_PEER EQU $83
-KPR_ERROR_INPUT_TOO_LARGE EQU $84
-KPR_ERROR_DEVICE_FAILURE EQU $85
-KPR_ERROR_ABORTED_BY_USER EQU $86
-KPR_ERROR_LISTENER_NOT_AVAILABLE EQU $87
-KPR_ERROR_NO_SUCH_LISTENER EQU $88
-KPR_ERROR_CONNECTION_RESET_BY_PEER EQU $89
-KPR_ERROR_CONNECTION_CLOSED EQU $8A
-KPR_ERROR_TOO_MANY_ERRORS EQU $8B
-KPR_ERROR_FILE_ACCESS_FAILURE EQU $90
-KPR_ERROR_MALFORMED_URL EQU $A0
-KPR_ERROR_DNS_LOOKUP_FAILED EQU $A1
-KPR_ERROR_OPTION_NOT_SUPPORTED EQU $FE
-KPR_ERROR_FUNCTION_NOT_SUPPORTED EQU $FF
-
-
-
-;-- LICENSE FOR kipper_constants.i --
-; 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 --
+;constants for accessing the KPR API file
+;to use this file under CA65, then add " .define EQU =" to your code before this file is included.
+
+
+KPR_API_VERSION_NUMBER EQU $01
+
+
+KPR_CART_SIGNATURE EQU $8009
+KPR_DISPATCH_VECTOR EQU $800f
+KPR_PERIODIC_PROCESSING_VECTOR EQU $8012
+
+;function numbers
+;to make a function call:
+; Y EQU function number
+; AX EQU pointer to parameter buffer (for functions that take parameters)
+; then JSR KPR_DISPATCH_VECTOR
+; on return, carry flag is set if there is an error, or clear otherwise
+; some functions return results in AX directly, others will update the parameter buffer they were called with.
+; any register not specified in outputs will have an undefined value on exit
+
+KPR_INITIALIZE EQU $01 ;no inputs or outputs - initializes IP stack, also sets IRQ chain to call KPR_VBL_VECTOR at @ 60hz
+KPR_GET_IP_CONFIG EQU $02 ;no inputs, outputs AX=pointer to IP configuration structure
+KPR_DEACTIVATE EQU $0F ;inputs: none, outputs: none (removes call to KPR_VBL_VECTOR on IRQ chain)
+
+KPR_UDP_ADD_LISTENER EQU $10 ;inputs: AX points to a UDP listener parameter structure, outputs: none
+KPR_GET_INPUT_PACKET_INFO EQU $11 ;inputs: AX points to a UDP/TCP packet parameter structure, outputs: UDP/TCP packet structure filled in
+KPR_SEND_UDP_PACKET EQU $12 ;inputs: AX points to a UDP packet parameter structure, outputs: none packet is sent
+KPR_UDP_REMOVE_LISTENER EQU $13 ;inputs: AX contains UDP port number that listener will be removed from
+
+KPR_TCP_CONNECT EQU $14 ;inputs: AX points to a TCP connect parameter structure, outputs: none
+KPR_SEND_TCP_PACKET EQU $15 ;inputs: AX points to a TCP send parameter structure, outputs: none packet is sent
+KPR_TCP_CLOSE_CONNECTION EQU $16 ;inputs: none outputs: none
+
+KPR_TFTP_SET_SERVER EQU $20 ;inputs: AX points to a TFTP server parameter structure, outputs: none
+KPR_TFTP_DOWNLOAD EQU $22 ;inputs: AX points to a TFTP transfer parameter structure, outputs: TFTP param structure updated with
+ ;KPR_TFTP_POINTER updated to reflect actual load address (if load address $0000 originally passed in)
+KPR_TFTP_CALLBACK_DOWNLOAD EQU $23 ;inputs: AX points to a TFTP transfer parameter structure, outputs: none
+KPR_TFTP_UPLOAD EQU $24 ;upload: AX points to a TFTP transfer parameter structure, outputs: none
+KPR_TFTP_CALLBACK_UPLOAD EQU $25 ;upload: AX points to a TFTP transfer parameter structure, outputs: none
+
+KPR_DNS_RESOLVE EQU $30 ;inputs: AX points to a DNS parameter structure, outputs: DNS param structure updated with
+ ;KPR_DNS_HOSTNAME_IP updated with IP address corresponding to hostname.
+KPR_DOWNLOAD_RESOURCE EQU $31 ;inputs: AX points to a URL download structure, outputs: none
+KPR_PING_HOST EQU $32 ;inputs: AX points to destination IP address for ping, outputs: AX=time (in milliseconds) to get response
+
+KPR_FILE_LOAD EQU $40 ;inputs: AX points to a file access parameter structure, outputs: none
+
+KPR_HTTPD_START EQU $50 ;inputs: AX points to a routine to call for each inbound request, outputs: none
+KPR_HTTPD_GET_VAR_VALUE EQU $52 ;inputs: A=variable to get value for ($01 to get method, $02 to get path)
+
+KPR_PRINT_ASCIIZ EQU $80 ;inputs: AX=pointer to null terminated string to be printed to screen, outputs: none
+KPR_PRINT_HEX EQU $81 ;inputs: A=byte digit to be displayed on screen as (zero padded) hex digit, outputs: none
+KPR_PRINT_DOTTED_QUAD EQU $82 ;inputs: AX=pointer to 4 bytes that will be displayed as a decimal dotted quad (e.g. 192.168.1.1)
+KPR_PRINT_IP_CONFIG EQU $83 ;no inputs, no outputs, prints to screen current IP configuration
+KPR_PRINT_INTEGER EQU $84 ;inputs: AX=16 byte number that will be printed as an unsigned decimal
+
+KPR_INPUT_STRING EQU $90 ;no inputs, outputs: AX = pointer to null terminated string
+KPR_INPUT_HOSTNAME EQU $91 ;no inputs, outputs: AX = pointer to hostname (which may be IP address).
+KPR_INPUT_PORT_NUMBER EQU $92 ;no inputs, outputs: AX = port number entered ($0000..$FFFF)
+
+KPR_BLOCK_COPY EQU $A0 ;inputs: AX points to a block copy structure, outputs: none
+KPR_PARSER_INIT EQU $A1 ;inputs: AX points to a null terminated string, outputs: none
+KPR_PARSER_SKIP_NEXT EQU $A2 ;inputs: AX points to a null terminated substring, outputs: AX points to
+ ;previously loaded string that is just past the next occurance of substring
+
+KPR_GET_LAST_ERROR EQU $FF ;no inputs, outputs A EQU error code (from last function that set the global error value, not necessarily the
+ ;last function that was called)
+
+;offsets in IP configuration structure (used by KPR_GET_IP_CONFIG)
+KPR_CFG_MAC EQU $00 ;6 byte MAC address
+KPR_CFG_IP EQU $06 ;4 byte local IP address (will be overwritten by DHCP)
+KPR_CFG_NETMASK EQU $0A ;4 byte local netmask (will be overwritten by DHCP)
+KPR_CFG_GATEWAY EQU $0E ;4 byte local gateway (will be overwritten by DHCP)
+KPR_CFG_DNS_SERVER EQU $12 ;4 byte IP address of DNS server (will be overwritten by DHCP)
+KPR_CFG_DHCP_SERVER EQU $16 ;4 byte IP address of DHCP server (will only be set by DHCP initialisation)
+KPR_DRIVER_NAME EQU $1A ;2 byte pointer to name of driver
+
+;offsets in TFTP transfer parameter structure (used by KPR_TFTP_DOWNLOAD, KPR_TFTP_CALLBACK_DOWNLOAD, KPR_TFTP_UPLOAD, KPR_TFTP_CALLBACK_UPLOAD)
+KPR_TFTP_FILENAME EQU $00 ;2 byte pointer to asciiz filename (or filemask)
+KPR_TFTP_POINTER EQU $02 ;2 byte pointer to memory location data to be stored in OR address of callback function
+KPR_TFTP_FILESIZE EQU $04 ;2 byte file length (filled in by KPR_TFTP_DOWNLOAD, must be passed in to KPR_TFTP_UPLOAD)
+
+;offsets in TFTP Server parameter structure (used by KPR_TFTP_SET_SERVER)
+KPR_TFTP_SERVER_IP EQU $00 ;4 byte IP address of TFTP server
+
+
+;offsets in DNS parameter structure (used by KPR_DNS_RESOLVE)
+KPR_DNS_HOSTNAME EQU $00 ;2 byte pointer to asciiz hostname to resolve (can also be a dotted quad string)
+KPR_DNS_HOSTNAME_IP EQU $00 ;4 byte IP address (filled in on succesful resolution of hostname)
+
+;offsets in UDP listener parameter structure
+KPR_UDP_LISTENER_PORT EQU $00 ;2 byte port number
+KPR_UDP_LISTENER_CALLBACK EQU $02 ;2 byte address of routine to call when UDP packet arrives for specified port
+
+;offsets in block copy parameter structure
+KPR_BLOCK_SRC EQU $00 ;2 byte address of start of source block
+KPR_BLOCK_DEST EQU $02 ;2 byte address of start of destination block
+KPR_BLOCK_SIZE EQU $04 ;2 byte length of block to be copied (in bytes
+
+
+;offsets in TCP connect parameter structure
+KPR_TCP_REMOTE_IP EQU $00 ;4 byte IP address of remote host (0.0.0.0 means wait for inbound i.e. server mode)
+KPR_TCP_PORT EQU $04 ;2 byte port number (to listen on, if ip address was 0.0.0.0, or connect to otherwise)
+KPR_TCP_CALLBACK EQU $06 ;2 byte address of routine to be called whenever a new packet arrives
+
+;offsets in TCP send parameter structure
+KPR_TCP_PAYLOAD_LENGTH EQU $00 ;2 byte length of payload of packet (after all ethernet,IP,UDP/TCP headers)
+KPR_TCP_PAYLOAD_POINTER EQU $02 ;2 byte pointer to payload of packet (after all headers)
+
+
+
+;offsets in TCP/UDP packet parameter structure
+KPR_REMOTE_IP EQU $00 ;4 byte IP address of remote machine (src of inbound packets, dest of outbound packets)
+KPR_REMOTE_PORT EQU $04 ;2 byte port number of remote machine (src of inbound packets, dest of outbound packets)
+KPR_LOCAL_PORT EQU $06 ;2 byte port number of local machine (src of outbound packets, dest of inbound packets)
+KPR_PAYLOAD_LENGTH EQU $08 ;2 byte length of payload of packet (after all ethernet,IP,UDP/TCP headers)
+ ; in a TCP connection, if the length is $FFFF, this actually means "end of connection"
+KPR_PAYLOAD_POINTER EQU $0A ;2 byte pointer to payload of packet (after all headers)
+
+;offsets in URL download structure
+;inputs:
+KPR_URL EQU $00 ;2 byte pointer to null terminated URL (NB - must be ASCII not "native" string)
+KPR_URL_DOWNLOAD_BUFFER EQU $02 ;2 byte pointer to buffer that resource specified by URL will be downloaded into
+KPR_URL_DOWNLOAD_BUFFER_LENGTH EQU $04 ;2 byte length of buffer (download will truncate when buffer is full)
+
+
+;offsets in file access parameter structure (used by KPR_FILE_LOAD)
+KPR_FILE_ACCESS_FILENAME EQU $00 ;2 byte pointer to asciiz filename (or filemask)
+KPR_FILE_ACCESS_POINTER EQU $02 ;2 byte pointer to memory location data to be stored in OR address of callback function
+KPR_FILE_ACCESS_FILESIZE EQU $04 ;2 byte file length (filled in by KPR_FILE_ACCESS)
+KPR_FILE_ACCESS_DEVICE EQU $06 ;1 byte device number (set to $00 to use last accessed device)
+
+;error codes (as returned by KPR_GET_LAST_ERROR)
+KPR_ERROR_PORT_IN_USE EQU $80
+KPR_ERROR_TIMEOUT_ON_RECEIVE EQU $81
+KPR_ERROR_TRANSMIT_FAILED EQU $82
+KPR_ERROR_TRANSMISSION_REJECTED_BY_PEER EQU $83
+KPR_ERROR_INPUT_TOO_LARGE EQU $84
+KPR_ERROR_DEVICE_FAILURE EQU $85
+KPR_ERROR_ABORTED_BY_USER EQU $86
+KPR_ERROR_LISTENER_NOT_AVAILABLE EQU $87
+KPR_ERROR_NO_SUCH_LISTENER EQU $88
+KPR_ERROR_CONNECTION_RESET_BY_PEER EQU $89
+KPR_ERROR_CONNECTION_CLOSED EQU $8A
+KPR_ERROR_TOO_MANY_ERRORS EQU $8B
+KPR_ERROR_FILE_ACCESS_FAILURE EQU $90
+KPR_ERROR_MALFORMED_URL EQU $A0
+KPR_ERROR_DNS_LOOKUP_FAILED EQU $A1
+KPR_ERROR_OPTION_NOT_SUPPORTED EQU $FE
+KPR_ERROR_FUNCTION_NOT_SUPPORTED EQU $FF
+
+
+
+;-- LICENSE FOR kipper_constants.i --
+; 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/inc/net.i b/inc/net.i
similarity index 95%
rename from client/inc/net.i
rename to inc/net.i
index bb9b456..06c21e9 100644
--- a/client/inc/net.i
+++ b/inc/net.i
@@ -1,62 +1,62 @@
- .import ip65_init
- .import ip65_process
-
- .import cfg_mac
- .import cfg_ip
- .import cfg_netmask
- .import cfg_gateway
- .import cfg_dns
- .import cfg_tftp_server
-
- .import dhcp_init
- .import dhcp_server
-
- .import cfg_get_configuration_ptr
-
-.macro init_ip_via_dhcp
-
- print_driver_init
- jsr ip65_init
- bcc :+
- print_failed
- sec
- jmp @end_macro
-
-:
-
- print_ok
-
- print_dhcp_init
-
-
- jsr dhcp_init
-
- bcc :+
- print_failed
- sec
- jmp @end_macro
-:
- print_ok
- clc
-@end_macro:
-.endmacro
-
-
-;-- LICENSE FOR net.i --
-; 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 --
+ .import ip65_init
+ .import ip65_process
+
+ .import cfg_mac
+ .import cfg_ip
+ .import cfg_netmask
+ .import cfg_gateway
+ .import cfg_dns
+ .import cfg_tftp_server
+
+ .import dhcp_init
+ .import dhcp_server
+
+ .import cfg_get_configuration_ptr
+
+.macro init_ip_via_dhcp
+
+ print_driver_init
+ jsr ip65_init
+ bcc :+
+ print_failed
+ sec
+ jmp @end_macro
+
+:
+
+ print_ok
+
+ print_dhcp_init
+
+
+ jsr dhcp_init
+
+ bcc :+
+ print_failed
+ sec
+ jmp @end_macro
+:
+ print_ok
+ clc
+@end_macro:
+.endmacro
+
+
+;-- LICENSE FOR net.i --
+; 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/inc/printf.i b/inc/printf.i
similarity index 95%
rename from client/inc/printf.i
rename to inc/printf.i
index 598a678..e682483 100644
--- a/client/inc/printf.i
+++ b/inc/printf.i
@@ -1,76 +1,76 @@
- .import console_printf
-
-
- .macro printfargs arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
- .ifnblank arg1
- .addr arg1
- printfargs arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
- .endif
- .endmacro
-
- .macro printf str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
-
- .local arglist
- .local string
-
- pha
- .ifpc02
- phx
- phy
- .else
- txa
- pha
- tya
- pha
- .endif
- ldax #arglist
- jsr console_printf
- .ifpc02
- ply
- plx
- .else
- pla
- tay
- pla
- tax
- .endif
- pla
-
- .pushseg
- .rodata
- .if (.match(str, ""))
-string:
- .asciiz str
-arglist:
- .addr string
- .else
-arglist:
- .addr str
- .endif
-
- printfargs arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
-
- .popseg
-
- .endmacro
-
-
-
-;-- LICENSE FOR printf.i --
-; 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 --
+ .import console_printf
+
+
+ .macro printfargs arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
+ .ifnblank arg1
+ .addr arg1
+ printfargs arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
+ .endif
+ .endmacro
+
+ .macro printf str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
+
+ .local arglist
+ .local string
+
+ pha
+ .ifpc02
+ phx
+ phy
+ .else
+ txa
+ pha
+ tya
+ pha
+ .endif
+ ldax #arglist
+ jsr console_printf
+ .ifpc02
+ ply
+ plx
+ .else
+ pla
+ tay
+ pla
+ tax
+ .endif
+ pla
+
+ .pushseg
+ .rodata
+ .if (.match(str, ""))
+string:
+ .asciiz str
+arglist:
+ .addr string
+ .else
+arglist:
+ .addr str
+ .endif
+
+ printfargs arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
+
+ .popseg
+
+ .endmacro
+
+
+
+;-- LICENSE FOR printf.i --
+; 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/inc/version.i b/inc/version.i
similarity index 100%
rename from client/inc/version.i
rename to inc/version.i
diff --git a/client/inc/vt100_font.bin b/inc/vt100_font.bin
similarity index 100%
rename from client/inc/vt100_font.bin
rename to inc/vt100_font.bin
diff --git a/client/ip65/Makefile b/ip65/Makefile
similarity index 100%
rename from client/ip65/Makefile
rename to ip65/Makefile
diff --git a/client/ip65/arithmetic.s b/ip65/arithmetic.s
similarity index 94%
rename from client/ip65/arithmetic.s
rename to ip65/arithmetic.s
index 9de1bf5..9ebfd04 100644
--- a/client/ip65/arithmetic.s
+++ b/ip65/arithmetic.s
@@ -1,170 +1,170 @@
-.include "../inc/common.i"
-
-;helper routines for arithmetic on 32 bit numbers
-
-;reuse the copy_* zero page locations as pointers for 32bit addition
-.importzp copy_src
-.importzp copy_dest
-
-acc32 =copy_src ;32bit accumulater (pointer)
-op32 =copy_dest ;32 bit operand (pointer)
-
-acc16 =acc32 ;16bit accumulater (value, NOT pointer)
-
-.bss
-temp_ax: .res 2
-.code
-;no 16bit operand as can just use AX
-.exportzp acc32
-.exportzp op32
-.exportzp acc16
-
-.export add_32_32
-.export add_16_32
-
-.export sub_16_16
-
-.export cmp_32_32
-.export cmp_16_16
-
-.export mul_8_16
-
-;compare 2 32bit numbers
-;on exit, zero flag clear iff acc32==op32
-cmp_32_32:
- ldy #0
- lda (op32),y
- cmp (acc32),y
- bne @exit
- iny
- lda (op32),y
- cmp (acc32),y
- bne @exit
- iny
- lda (op32),y
- cmp (acc32),y
- bne @exit
- iny
- lda (op32),y
- cmp (acc32),y
-@exit:
- rts
-
-;compare 2 16bit numbers
-;on exit, zero flag clear iff acc16==AX
-cmp_16_16:
- cmp acc16
- bne @exit
- txa
- cmp acc16+1
-@exit:
- rts
-
-;subtract 2 16 bit numbers
-;acc16=acc16-AX
-sub_16_16:
- stax temp_ax
- sec
- lda acc16
- sbc temp_ax
- sta acc16
- lda acc16+1
- sbc temp_ax+1
- sta acc16+1
- rts
-
-;add a 32bit operand to the 32 bit accumulater
-;acc32=acc32+op32
-add_32_32:
- clc
- ldy #0
- lda (op32),y
- adc (acc32),y
- sta (acc32),y
- iny
- lda (op32),y
- adc (acc32),y
- sta (acc32),y
- iny
- lda (op32),y
- adc (acc32),y
- sta (acc32),y
- iny
- lda (op32),y
- adc (acc32),y
- sta (acc32),y
-
- rts
-
-
-;add a 16bit operand to the 32 bit accumulater
-;acc32=acc32+AX
-add_16_32:
- clc
- ldy #0
- adc (acc32),y
- sta (acc32),y
- iny
- txa
- adc (acc32),y
- sta (acc32),y
- iny
- lda #0
- adc (acc32),y
- sta (acc32),y
- iny
- lda #0
- adc (acc32),y
- sta (acc32),y
- rts
-
-;multiply a 16 bit number by an 8 bit number
-;acc16=acc16*a
-mul_8_16:
- tax
- beq @operand_is_zero
- lda acc16
- sta temp_ax
- lda acc16+1
- sta temp_ax+1
-
-@addition_loop:
- dex
- beq @done
- clc
- lda acc16
- adc temp_ax
- sta acc16
- lda acc16+1
- adc temp_ax+1
- sta acc16+1
- jmp @addition_loop
-
-@done:
-
- rts
-@operand_is_zero:
- sta acc16
- sta acc16+1
- rts
-
-
-
-;-- LICENSE FOR arithmetic.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 --
+.include "../inc/common.i"
+
+;helper routines for arithmetic on 32 bit numbers
+
+;reuse the copy_* zero page locations as pointers for 32bit addition
+.importzp copy_src
+.importzp copy_dest
+
+acc32 =copy_src ;32bit accumulater (pointer)
+op32 =copy_dest ;32 bit operand (pointer)
+
+acc16 =acc32 ;16bit accumulater (value, NOT pointer)
+
+.bss
+temp_ax: .res 2
+.code
+;no 16bit operand as can just use AX
+.exportzp acc32
+.exportzp op32
+.exportzp acc16
+
+.export add_32_32
+.export add_16_32
+
+.export sub_16_16
+
+.export cmp_32_32
+.export cmp_16_16
+
+.export mul_8_16
+
+;compare 2 32bit numbers
+;on exit, zero flag clear iff acc32==op32
+cmp_32_32:
+ ldy #0
+ lda (op32),y
+ cmp (acc32),y
+ bne @exit
+ iny
+ lda (op32),y
+ cmp (acc32),y
+ bne @exit
+ iny
+ lda (op32),y
+ cmp (acc32),y
+ bne @exit
+ iny
+ lda (op32),y
+ cmp (acc32),y
+@exit:
+ rts
+
+;compare 2 16bit numbers
+;on exit, zero flag clear iff acc16==AX
+cmp_16_16:
+ cmp acc16
+ bne @exit
+ txa
+ cmp acc16+1
+@exit:
+ rts
+
+;subtract 2 16 bit numbers
+;acc16=acc16-AX
+sub_16_16:
+ stax temp_ax
+ sec
+ lda acc16
+ sbc temp_ax
+ sta acc16
+ lda acc16+1
+ sbc temp_ax+1
+ sta acc16+1
+ rts
+
+;add a 32bit operand to the 32 bit accumulater
+;acc32=acc32+op32
+add_32_32:
+ clc
+ ldy #0
+ lda (op32),y
+ adc (acc32),y
+ sta (acc32),y
+ iny
+ lda (op32),y
+ adc (acc32),y
+ sta (acc32),y
+ iny
+ lda (op32),y
+ adc (acc32),y
+ sta (acc32),y
+ iny
+ lda (op32),y
+ adc (acc32),y
+ sta (acc32),y
+
+ rts
+
+
+;add a 16bit operand to the 32 bit accumulater
+;acc32=acc32+AX
+add_16_32:
+ clc
+ ldy #0
+ adc (acc32),y
+ sta (acc32),y
+ iny
+ txa
+ adc (acc32),y
+ sta (acc32),y
+ iny
+ lda #0
+ adc (acc32),y
+ sta (acc32),y
+ iny
+ lda #0
+ adc (acc32),y
+ sta (acc32),y
+ rts
+
+;multiply a 16 bit number by an 8 bit number
+;acc16=acc16*a
+mul_8_16:
+ tax
+ beq @operand_is_zero
+ lda acc16
+ sta temp_ax
+ lda acc16+1
+ sta temp_ax+1
+
+@addition_loop:
+ dex
+ beq @done
+ clc
+ lda acc16
+ adc temp_ax
+ sta acc16
+ lda acc16+1
+ adc temp_ax+1
+ sta acc16+1
+ jmp @addition_loop
+
+@done:
+
+ rts
+@operand_is_zero:
+ sta acc16
+ sta acc16+1
+ rts
+
+
+
+;-- LICENSE FOR arithmetic.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/ip65/arp.s b/ip65/arp.s
similarity index 95%
rename from client/ip65/arp.s
rename to ip65/arp.s
index 6d724e1..21b6cd5 100644
--- a/client/ip65/arp.s
+++ b/ip65/arp.s
@@ -1,442 +1,442 @@
-; ARP address resolution
-
-.include "../inc/common.i"
-
- .export arp_init
- .export arp_lookup
- .export arp_process
- .export arp_add
- .export arp_calculate_gateway_mask
- .export arp_ip
- .export arp_mac
- .export arp_cache
- .exportzp ac_size
-
- .import eth_inp
- .import eth_inp_len
- .import eth_outp
- .import eth_outp_len
- .import eth_tx
- .import eth_set_broadcast_dest
- .import eth_set_my_mac_src
- .import eth_set_proto
- .importzp eth_proto_arp
-
- .import cfg_mac
- .import cfg_ip
- .import cfg_netmask
- .import cfg_gateway
-
- .import timer_read
- .import timer_timeout
-
- .importzp copy_src
- ap=copy_src
-
-ARP_TIMEOUT_MS=100
-
- .bss
-
-; arp state machine
-arp_idle = 1 ; idling
-arp_wait = 2 ; waiting for reply
-arp_state: .res 1 ; current activity
-
-; arguments for lookup and add
-arp: ; ptr to mac/ip pair
-arp_mac: .res 6 ; result is delivered here when arp_lookup returns with carry flag clear
-arp_ip: .res 4 ; set arp_ip before calling arp_lookup
-
-; arp cache
-ac_size = 8 ; lookup cache
-ac_ip = 6 ; offset for ip
-ac_mac = 0 ; offset for mac
-arp_cache: .res (6+4)*ac_size ;cache of IP addresses and corresponding MAC addresses
-
-; offsets for arp packet generation
-ap_hw = 14 ; hw type (eth = 0001)
-ap_proto = 16 ; protocol (ip = 0800)
-ap_hwlen = 18 ; hw addr len (eth = 06)
-ap_protolen = 19 ; proto addr len (ip = 04)
-ap_op = 20 ; request = 0001, reply = 0002
-ap_shw = 22 ; sender hw addr
-ap_sp = 28 ; sender proto addr
-ap_thw = 32 ; target hw addr
-ap_tp = 38 ; target protoaddr
-ap_packlen = 42 ; total length of packet
-
-; gateway handling
-gw_mask: .res 4 ; inverted netmask
-gw_test: .res 4 ; gateway ip or:d with inverted netmask
-gw_last: .res 1 ; netmask length - 1
-
-; timeout
-arptimeout: .res 2 ; time when we will have timed out
-
-
- .code
-;initialize arp (including clearing the arp cache)
-;inputs: none
-;outputs: none
-arp_init:
- lda #0
-
- ldx #(6+4)*ac_size - 1 ; clear cache
-:
- sta arp_cache,x
- dex
- bpl :-
-
-arp_calculate_gateway_mask:
-
- lda #$ff ; counter for netmask length - 1
- sta gw_last
-
- ldx #3
-@gw:
- lda cfg_netmask,x
- eor #$ff
- cmp #$ff
- bne :+
- inc gw_last
-: sta gw_mask,x
- ora cfg_gateway,x
- sta gw_test,x
- dex
- bpl @gw
-
- lda #arp_idle ; start out idle
- sta arp_state
-
- rts
-
-
-;lookup the mac address for an ip
-;inputs: arp_ip should be set to ip address to be resolved
-;outputs:
-; if carry flag is clear, then arp_mac will be set to correct mac address
-; if carry flag is set, then the correct mac address could not be found in
-; the arp cache, so an arp request was sent. so the caller should wait a while
-; (to allow time for an arp response message to arrive) and then call arp_lookup again.
-arp_lookup:
-
- lda arp_ip ; check for broadcast IP (255.255.255.255)
- and arp_ip + 1
- and arp_ip + 2
- and arp_ip + 3
- cmp #$ff
- bne @notbroadcast
- ldx #6 ;copy ff:ff:ff:ff:ff:ff to ap_mac
-: sta arp_mac,x
- dex
- bpl :-
- clc
- rts
-
-@notbroadcast:
-
- ldx gw_last ; check if address is on our subnet
-: lda arp_ip,x
- ora gw_mask,x
- cmp gw_test,x
- bne @notlocal
- dex
- bpl :-
- bmi @local
-
-@notlocal:
-
- ldx #3 ; copy gateway's ip address
-: lda cfg_gateway,x
- sta arp_ip,x
- dex
- bpl :-
-
-@local:
- jsr findip
- bcs @cachemiss
-
- ldy #ac_ip - 1 ; copy mac
-: lda (ap),y
- sta arp,y
- dey
- bpl :-
- rts
-
-@cachemiss:
- lda arp_state ; are we already waiting for a reply?
- cmp #arp_idle
- beq @sendrequest ; yes, send request
-
- ldax arptimeout ; check if we've timed out
- jsr timer_timeout
- bcs @notimeout ; no, don't send
-
-@sendrequest: ; send out arp request
- jsr eth_set_broadcast_dest
- jsr eth_set_my_mac_src
-
- jsr makearppacket ; add arp, eth, ip, hwlen, protolen
-
- lda #0 ; set opcode (request = 0001)
- sta eth_outp + ap_op
- lda #1
- sta eth_outp + ap_op + 1
-
- ldx #5
-: lda cfg_mac,x ; set source mac addr
- sta eth_outp + ap_shw,x
- lda #0 ; set target mac addr
- sta eth_outp + ap_thw,x
- dex
- bpl :-
-
- ldx #3
-: lda cfg_ip,x ; set source ip addr
- sta eth_outp + ap_sp,x
- lda arp_ip,x ; set target ip addr
- sta eth_outp + ap_tp,x
- dex
- bpl :-
-
- lda #ap_packlen
- sta eth_outp_len + 1
-
- jsr eth_tx ; send packet
-
- lda #arp_wait ; waiting for reply
- sta arp_state
-
- jsr timer_read ; read current timer value
- clc
- adc #ARP_TIMEOUT_MS
- sta arptimeout + 1
-
-@notimeout:
- sec ; set carry to indicate that
- rts ; no result is availble
-
-
-; find arp_ip in the cache
-; clc returns pointer to entry in (ap)
-findip:
-
- ldax #arp_cache
- stax ap
- ldx #ac_size
-@compare: ; compare cache entry
- ldy #ac_ip
- lda (ap),y
- beq @notfound
-: lda (ap),y
- cmp arp,y
- bne @next
- iny
- cpy #ac_ip + 4
- bne :-
-
- clc ; return
- rts
-
-@next: ; next entry
- lda ap
- clc
- adc #10
- sta ap
- bcc :+
- inc ap + 1
-: dex
- bne @compare
-
-@notfound:
- sec
- rts
-
-
-;handle incoming arp packets
-;inputs: eth_inp should contain an arp packet
-;outputs:
-; carry flag is set if there was an error processing the arp packet, clear otherwise
-; the arp_cache will be updated with the mac & ip address (whether the inbound
-; message was a request or a response). if the incoming packet was an arp
-; request for this machine, then an arp response will be created (overwriting
-; eth_outp) and sent out
-arp_process:
-
- lda eth_inp + ap_op ; should be 0
- bne @badpacket
- lda eth_inp + ap_op + 1 ; check opcode
- cmp #1 ; request?
- beq @request
- cmp #2 ; reply?
- beq @reply
-
-@badpacket:
- sec
- rts
-
-@request:
- ldx #3
-: lda eth_inp + ap_tp,x ; check if they're asking for
- cmp cfg_ip,x ; my address
- bne @done
- dex
- bpl :-
-
- ldax #eth_inp + ap_shw
- jsr ac_add_source ; add them to arp cache
-
- ldx #5 ; send reply
-: lda eth_inp + ap_shw,x
- sta eth_outp,x ; set sender packet dest
- sta eth_outp + ap_thw,x ; and as target
- lda cfg_mac,x ; me as source
- sta eth_outp + ap_shw,x
- dex
- bpl :-
-
- jsr eth_set_my_mac_src ; me as packet source
-
- jsr makearppacket ; add arp, eth, ip, hwlen, protolen
-
- lda #0 ; set opcode (reply = 0002)
- sta eth_outp + ap_op
- lda #2
- sta eth_outp + ap_op + 1
-
- ldx #3
-: lda eth_inp + ap_sp,x ; sender as target addr
- sta eth_outp + ap_tp,x
- lda cfg_ip,x ; my ip as source addr
- sta eth_outp + ap_sp,x
- dex
- bpl :-
-
- lda #ap_packlen
- sta eth_outp_len + 1
-
- jsr eth_tx ; send packet
-
-@done:
- clc
- rts
-
-@reply:
- lda arp_state
- cmp #arp_wait ; are we waiting for a reply?
- bne @badpacket
-
- ldax #eth_inp + ap_shw
- jsr ac_add_source ; add to cache
-
- lda #arp_idle
- sta arp_state
-
- rts
-
-
-; add arp_mac and arp_ip to the cache
-;inputs:
-; arp_ip is ip address to add to cache
-; arp_mac is corresponding mac address of specified ip
-;outputs:
-; arp_cache is updated
-arp_add:
- jsr findip ; check if ip is already in cache
- bcs @add
-
- ldy #9 ; update old entry
-: lda arp,y ; move to top as well?
- sta (ap),y
- dey
- bpl :-
-
- rts
-
-@add:
- ldax #arp ; add
-
-
-;add source to cache
-ac_add_source:
- stax ap
-
- ldx #9 ; make space in the arp cache
-:
-
- lda arp_cache + 60,x
- sta arp_cache + 70,x
- lda arp_cache + 50,x
- sta arp_cache + 60,x
- lda arp_cache + 40,x
- sta arp_cache + 50,x
- lda arp_cache + 30,x
- sta arp_cache + 40,x
- lda arp_cache + 20,x
- sta arp_cache + 30,x
- lda arp_cache + 10,x
- sta arp_cache + 20,x
- lda arp_cache,x
- sta arp_cache + 10,x
-
- dex
- bpl :-
-
- ldy #9
-: lda (ap),y ; copy source
- sta arp_cache,y
- dey
- bpl :-
-
- rts
-
-
-; adds proto = arp, hw = eth, and proto = ip to outgoing packet
-makearppacket:
- lda #eth_proto_arp
- jsr eth_set_proto
-
- lda #0 ; set hw type (eth = 0001)
- sta eth_outp + ap_hw
- lda #1
- sta eth_outp + ap_hw + 1
-
- lda #8 ; set protcol (ip = 0800)
- sta eth_outp + ap_proto
- lda #0
- sta eth_outp + ap_proto + 1
-
- lda #6 ; set hw addr len (eth = 06)
- sta eth_outp + ap_hwlen
- lda #4 ; set proto addr len (eth = 04)
- sta eth_outp + ap_protolen
-
- rts
-
-
-
-;-- LICENSE FOR arp.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+; ARP address resolution
+
+.include "../inc/common.i"
+
+ .export arp_init
+ .export arp_lookup
+ .export arp_process
+ .export arp_add
+ .export arp_calculate_gateway_mask
+ .export arp_ip
+ .export arp_mac
+ .export arp_cache
+ .exportzp ac_size
+
+ .import eth_inp
+ .import eth_inp_len
+ .import eth_outp
+ .import eth_outp_len
+ .import eth_tx
+ .import eth_set_broadcast_dest
+ .import eth_set_my_mac_src
+ .import eth_set_proto
+ .importzp eth_proto_arp
+
+ .import cfg_mac
+ .import cfg_ip
+ .import cfg_netmask
+ .import cfg_gateway
+
+ .import timer_read
+ .import timer_timeout
+
+ .importzp copy_src
+ ap=copy_src
+
+ARP_TIMEOUT_MS=100
+
+ .bss
+
+; arp state machine
+arp_idle = 1 ; idling
+arp_wait = 2 ; waiting for reply
+arp_state: .res 1 ; current activity
+
+; arguments for lookup and add
+arp: ; ptr to mac/ip pair
+arp_mac: .res 6 ; result is delivered here when arp_lookup returns with carry flag clear
+arp_ip: .res 4 ; set arp_ip before calling arp_lookup
+
+; arp cache
+ac_size = 8 ; lookup cache
+ac_ip = 6 ; offset for ip
+ac_mac = 0 ; offset for mac
+arp_cache: .res (6+4)*ac_size ;cache of IP addresses and corresponding MAC addresses
+
+; offsets for arp packet generation
+ap_hw = 14 ; hw type (eth = 0001)
+ap_proto = 16 ; protocol (ip = 0800)
+ap_hwlen = 18 ; hw addr len (eth = 06)
+ap_protolen = 19 ; proto addr len (ip = 04)
+ap_op = 20 ; request = 0001, reply = 0002
+ap_shw = 22 ; sender hw addr
+ap_sp = 28 ; sender proto addr
+ap_thw = 32 ; target hw addr
+ap_tp = 38 ; target protoaddr
+ap_packlen = 42 ; total length of packet
+
+; gateway handling
+gw_mask: .res 4 ; inverted netmask
+gw_test: .res 4 ; gateway ip or:d with inverted netmask
+gw_last: .res 1 ; netmask length - 1
+
+; timeout
+arptimeout: .res 2 ; time when we will have timed out
+
+
+ .code
+;initialize arp (including clearing the arp cache)
+;inputs: none
+;outputs: none
+arp_init:
+ lda #0
+
+ ldx #(6+4)*ac_size - 1 ; clear cache
+:
+ sta arp_cache,x
+ dex
+ bpl :-
+
+arp_calculate_gateway_mask:
+
+ lda #$ff ; counter for netmask length - 1
+ sta gw_last
+
+ ldx #3
+@gw:
+ lda cfg_netmask,x
+ eor #$ff
+ cmp #$ff
+ bne :+
+ inc gw_last
+: sta gw_mask,x
+ ora cfg_gateway,x
+ sta gw_test,x
+ dex
+ bpl @gw
+
+ lda #arp_idle ; start out idle
+ sta arp_state
+
+ rts
+
+
+;lookup the mac address for an ip
+;inputs: arp_ip should be set to ip address to be resolved
+;outputs:
+; if carry flag is clear, then arp_mac will be set to correct mac address
+; if carry flag is set, then the correct mac address could not be found in
+; the arp cache, so an arp request was sent. so the caller should wait a while
+; (to allow time for an arp response message to arrive) and then call arp_lookup again.
+arp_lookup:
+
+ lda arp_ip ; check for broadcast IP (255.255.255.255)
+ and arp_ip + 1
+ and arp_ip + 2
+ and arp_ip + 3
+ cmp #$ff
+ bne @notbroadcast
+ ldx #6 ;copy ff:ff:ff:ff:ff:ff to ap_mac
+: sta arp_mac,x
+ dex
+ bpl :-
+ clc
+ rts
+
+@notbroadcast:
+
+ ldx gw_last ; check if address is on our subnet
+: lda arp_ip,x
+ ora gw_mask,x
+ cmp gw_test,x
+ bne @notlocal
+ dex
+ bpl :-
+ bmi @local
+
+@notlocal:
+
+ ldx #3 ; copy gateway's ip address
+: lda cfg_gateway,x
+ sta arp_ip,x
+ dex
+ bpl :-
+
+@local:
+ jsr findip
+ bcs @cachemiss
+
+ ldy #ac_ip - 1 ; copy mac
+: lda (ap),y
+ sta arp,y
+ dey
+ bpl :-
+ rts
+
+@cachemiss:
+ lda arp_state ; are we already waiting for a reply?
+ cmp #arp_idle
+ beq @sendrequest ; yes, send request
+
+ ldax arptimeout ; check if we've timed out
+ jsr timer_timeout
+ bcs @notimeout ; no, don't send
+
+@sendrequest: ; send out arp request
+ jsr eth_set_broadcast_dest
+ jsr eth_set_my_mac_src
+
+ jsr makearppacket ; add arp, eth, ip, hwlen, protolen
+
+ lda #0 ; set opcode (request = 0001)
+ sta eth_outp + ap_op
+ lda #1
+ sta eth_outp + ap_op + 1
+
+ ldx #5
+: lda cfg_mac,x ; set source mac addr
+ sta eth_outp + ap_shw,x
+ lda #0 ; set target mac addr
+ sta eth_outp + ap_thw,x
+ dex
+ bpl :-
+
+ ldx #3
+: lda cfg_ip,x ; set source ip addr
+ sta eth_outp + ap_sp,x
+ lda arp_ip,x ; set target ip addr
+ sta eth_outp + ap_tp,x
+ dex
+ bpl :-
+
+ lda #ap_packlen
+ sta eth_outp_len + 1
+
+ jsr eth_tx ; send packet
+
+ lda #arp_wait ; waiting for reply
+ sta arp_state
+
+ jsr timer_read ; read current timer value
+ clc
+ adc #ARP_TIMEOUT_MS
+ sta arptimeout + 1
+
+@notimeout:
+ sec ; set carry to indicate that
+ rts ; no result is availble
+
+
+; find arp_ip in the cache
+; clc returns pointer to entry in (ap)
+findip:
+
+ ldax #arp_cache
+ stax ap
+ ldx #ac_size
+@compare: ; compare cache entry
+ ldy #ac_ip
+ lda (ap),y
+ beq @notfound
+: lda (ap),y
+ cmp arp,y
+ bne @next
+ iny
+ cpy #ac_ip + 4
+ bne :-
+
+ clc ; return
+ rts
+
+@next: ; next entry
+ lda ap
+ clc
+ adc #10
+ sta ap
+ bcc :+
+ inc ap + 1
+: dex
+ bne @compare
+
+@notfound:
+ sec
+ rts
+
+
+;handle incoming arp packets
+;inputs: eth_inp should contain an arp packet
+;outputs:
+; carry flag is set if there was an error processing the arp packet, clear otherwise
+; the arp_cache will be updated with the mac & ip address (whether the inbound
+; message was a request or a response). if the incoming packet was an arp
+; request for this machine, then an arp response will be created (overwriting
+; eth_outp) and sent out
+arp_process:
+
+ lda eth_inp + ap_op ; should be 0
+ bne @badpacket
+ lda eth_inp + ap_op + 1 ; check opcode
+ cmp #1 ; request?
+ beq @request
+ cmp #2 ; reply?
+ beq @reply
+
+@badpacket:
+ sec
+ rts
+
+@request:
+ ldx #3
+: lda eth_inp + ap_tp,x ; check if they're asking for
+ cmp cfg_ip,x ; my address
+ bne @done
+ dex
+ bpl :-
+
+ ldax #eth_inp + ap_shw
+ jsr ac_add_source ; add them to arp cache
+
+ ldx #5 ; send reply
+: lda eth_inp + ap_shw,x
+ sta eth_outp,x ; set sender packet dest
+ sta eth_outp + ap_thw,x ; and as target
+ lda cfg_mac,x ; me as source
+ sta eth_outp + ap_shw,x
+ dex
+ bpl :-
+
+ jsr eth_set_my_mac_src ; me as packet source
+
+ jsr makearppacket ; add arp, eth, ip, hwlen, protolen
+
+ lda #0 ; set opcode (reply = 0002)
+ sta eth_outp + ap_op
+ lda #2
+ sta eth_outp + ap_op + 1
+
+ ldx #3
+: lda eth_inp + ap_sp,x ; sender as target addr
+ sta eth_outp + ap_tp,x
+ lda cfg_ip,x ; my ip as source addr
+ sta eth_outp + ap_sp,x
+ dex
+ bpl :-
+
+ lda #ap_packlen
+ sta eth_outp_len + 1
+
+ jsr eth_tx ; send packet
+
+@done:
+ clc
+ rts
+
+@reply:
+ lda arp_state
+ cmp #arp_wait ; are we waiting for a reply?
+ bne @badpacket
+
+ ldax #eth_inp + ap_shw
+ jsr ac_add_source ; add to cache
+
+ lda #arp_idle
+ sta arp_state
+
+ rts
+
+
+; add arp_mac and arp_ip to the cache
+;inputs:
+; arp_ip is ip address to add to cache
+; arp_mac is corresponding mac address of specified ip
+;outputs:
+; arp_cache is updated
+arp_add:
+ jsr findip ; check if ip is already in cache
+ bcs @add
+
+ ldy #9 ; update old entry
+: lda arp,y ; move to top as well?
+ sta (ap),y
+ dey
+ bpl :-
+
+ rts
+
+@add:
+ ldax #arp ; add
+
+
+;add source to cache
+ac_add_source:
+ stax ap
+
+ ldx #9 ; make space in the arp cache
+:
+
+ lda arp_cache + 60,x
+ sta arp_cache + 70,x
+ lda arp_cache + 50,x
+ sta arp_cache + 60,x
+ lda arp_cache + 40,x
+ sta arp_cache + 50,x
+ lda arp_cache + 30,x
+ sta arp_cache + 40,x
+ lda arp_cache + 20,x
+ sta arp_cache + 30,x
+ lda arp_cache + 10,x
+ sta arp_cache + 20,x
+ lda arp_cache,x
+ sta arp_cache + 10,x
+
+ dex
+ bpl :-
+
+ ldy #9
+: lda (ap),y ; copy source
+ sta arp_cache,y
+ dey
+ bpl :-
+
+ rts
+
+
+; adds proto = arp, hw = eth, and proto = ip to outgoing packet
+makearppacket:
+ lda #eth_proto_arp
+ jsr eth_set_proto
+
+ lda #0 ; set hw type (eth = 0001)
+ sta eth_outp + ap_hw
+ lda #1
+ sta eth_outp + ap_hw + 1
+
+ lda #8 ; set protcol (ip = 0800)
+ sta eth_outp + ap_proto
+ lda #0
+ sta eth_outp + ap_proto + 1
+
+ lda #6 ; set hw addr len (eth = 06)
+ sta eth_outp + ap_hwlen
+ lda #4 ; set proto addr len (eth = 04)
+ sta eth_outp + ap_protolen
+
+ rts
+
+
+
+;-- LICENSE FOR arp.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/cifs.s b/ip65/cifs.s
similarity index 95%
rename from client/ip65/cifs.s
rename to ip65/cifs.s
index 567fe2d..3c7199d 100644
--- a/client/ip65/cifs.s
+++ b/ip65/cifs.s
@@ -1,918 +1,918 @@
-;a simple NETBIOS over TCP server
-;aka "Common Internet File System"
-;
-; refs: RFC1001, RFC1002, "Implementing CIFS" - http://ubiqx.org/cifs/
-
-.include "../inc/common.i"
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-DEFAULT_CIFS_CMD_BUFFER = $6800
-DEFAULT_SMB_RESPONSE_BUFFER=$6000
-.export cifs_l1_encode
-.export cifs_l1_decode
-.export cifs_start
-
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-
-.import cfg_ip
-.import output_buffer
-.importzp udp_data
-.import udp_send
-.import udp_inp
-.importzp udp_data
-.import udp_send_dest
-.import udp_send_src_port
-.import udp_send_dest_port
-.import udp_send_len
-.importzp ip_src
-.importzp ip_dest
-.import ip_data
-.import ip_inp
-.import tcp_close
-.import tcp_listen
-.import tcp_callback
-.import tcp_inbound_data_length
-.import tcp_inbound_data_ptr
-.import tcp_send
-.import tcp_send_data_len
-
-.import ip65_process
-.import udp_add_listener
-.import udp_callback
-
-nbns_txn_id = 0
-nbns_opcode=2
-nbns_flags_rcode=3
-nbns_qdcount=4
-nbns_ancount=6
-nbns_nscount=8
-nbns_arcount=10
-nbns_question_name=12
-nbns_service_type=43
-
-
-nbns_my_ip=64
-nbns_registration_message_length=68
-
-
-;given an ASCII (or PETSCII) hostname, convert to
-;canonical 'level 1 encoded' form.
-;
-;only supports the default scope (' ' : 0x20)
-;inputs:
-; AX: pointer to null terminated hostname to be encoded
-;outputs:
-; AX: pointer to decoded hostname
-cifs_l1_encode:
- stax copy_src
- lda #0
- tax
- sta hostname_buffer+32
-@empty_buffer_loop:
- lda #$43
- sta hostname_buffer,x
- inx
- lda #$41
- sta hostname_buffer,x
- inx
- cpx #$20
- bmi @empty_buffer_loop
- ldy #0
- ldx #0
-@copy_loop:
-
- lda (copy_src),y
- beq @done
- lsr
- lsr
- lsr
- lsr
- clc
- adc #$41
- sta hostname_buffer,x
-
- inx
- lda (copy_src),y
- and #$0F
- clc
- adc #$41
- sta hostname_buffer,x
- inx
- iny
- cpx #$1D
- bmi @copy_loop
-@done:
- ldax #hostname_buffer
- rts
-
-;given a 'level 1 encoded' hostname, decode to ASCII .
-;
-;inputs:
-; AX: pointer to encoded hostname to be decoded
-;outputs:
-; AX: pointer to decoded hostname (will be 16 byte hostname, right padded with spaces, nul terminated)
-cifs_l1_decode:
- stax copy_src
- ldy #0
- ldx #0
-@decode_loop:
- lda (copy_src),y
- sec
- sbc #$41
- asl
- asl
- asl
- asl
- sta hi_nibble
- iny
- lda (copy_src),y
- sec
- sbc #$41
- clc
- adc hi_nibble
- sta hostname_buffer,x
- iny
- inx
- cpx #$10
- bmi @decode_loop
- lda #0
- sta hostname_buffer,x
- ldax #hostname_buffer
- rts
-
-
-;start a CIFS (SMB) server process, and advertise the specified hostname on the local LAN
-;
-;inputs:
-;AX = ptr to hostname to be used
-;outputs:
-; none
-cifs_start:
-
- ;save the hostname in 'raw' form
- stax copy_src
- ldax #raw_local_hostname
- stax copy_dest
- ldax #$0f
- stx raw_local_hostname+15
- jsr copymem
-
- ;set up callbacks
- ldax #nbns_callback
- stax udp_callback
- ldax #137
- jsr udp_add_listener
-
- ldax #nbns_callback
- stax udp_callback
- ldax #137
- jsr udp_add_listener
-
- ldax #raw_local_hostname
- jsr cifs_l1_encode
- ldx #0
-@copy_hostname_loop:
- lda hostname_buffer,x
- sta local_hostname,x
- inx
- cpx #$21
- bmi @copy_hostname_loop
-
- jsr cifs_advertise_hostname
- jsr cifs_advertise_hostname
-
-
- ldax #nb_session_callback
- stax tcp_callback
-@listen:
-
- ldax #-4 ;start at -4, to skip the NBT header length
- stax cifs_cmd_length
-
-
- ldax cifs_cmd_buffer
- stax cifs_cmd_buffer_ptr
- ldax #139
- stx connection_closed
-
- jsr tcp_listen
-
-@loop:
- inc $d020 ;FIXME
- jsr ip65_process
- lda connection_closed
- beq @loop
-
- jmp @listen
- rts
-
-
-;broadcast a Name Registration Request message to the local LAN
-cifs_advertise_hostname:
-
- ; advertise the 'server' service for own hostname
- ;overwrite the hostname in 'DNS compressed form'
- ;we assume this hostname ends with <20>
- lda #$20 ;indicates what follows is a netbios name
- sta output_buffer+nbns_question_name
-
- ldx #0
-@copy_hostname_loop:
- lda local_hostname,x
- sta registration_request_servername+1,x
- inx
- cpx #$21
- bmi @copy_hostname_loop
-
- jsr @send_nbns_message
-
-
- ;copy our encode hostname to the host announcment
- ldax #local_hostname
- stax copy_src
- ldax #host_announce_hostname
- stax copy_dest
- ldax #$20
- jsr copymem
-
- ;copy our raw hostname to the host announcment
- ldax #raw_local_hostname
- stax copy_src
- ldax #host_announce_servername
- stax copy_dest
- ldax #$10
- jsr copymem
-
-
-;copy the local IP address to the 'sender' field of the host announcment
- ldx #03
-@copy_sending_address_loop:
- lda cfg_ip,x
- sta host_announce_my_ip,x
- dex
- bpl @copy_sending_address_loop
-
-
- ldax #138
- stax udp_send_dest_port
- stax udp_send_src_port
-
- ldax #host_announce_message_length
- stax udp_send_len
-
- ldax #host_announce_message
- jsr udp_send
- rts
-
-
-@send_nbns_message:
-;copy the local IP address
- ldx #03
-@copy_my_address_loop:
- lda cfg_ip,x
- sta nbns_my_ip,x
- dex
- bpl @copy_my_address_loop
-
- ;send to the broadcast address
- lda #$ff
- ldx #03
-@copy_broadcast_address_loop:
- sta udp_send_dest,x
- dex
- bpl @copy_broadcast_address_loop
-
- ldax #137
- stax udp_send_dest_port
- stax udp_send_src_port
-
- ldax #nbns_registration_message_length
- stax udp_send_len
-
- ldax #registration_request
- jsr udp_send
-
-
- rts
-
-
-
-nbns_callback:
-
- lda udp_inp+udp_data+nbns_opcode
- and #$f8 ;mask the lower three bits
- beq @name_request
- rts
-@name_request:
-
- ;this is a NB NAME REQUEST.
- ;is it a unicast message?
- ldx #3
-@check_unicast_loop:
- lda ip_inp+ip_dest,x
- cmp cfg_ip,x
- bne @not_unicast
- dex
- bpl @check_unicast_loop
-
- jmp @looking_for_us
-
-@not_unicast:
- ;is it looking for our local hostname?
- ldax #udp_inp+udp_data+nbns_question_name+1
- stax copy_src
- ldy #0
-@cmp_loop:
- lda (copy_src),y
- cmp local_hostname,y
- bne @not_us
- iny
- cpy #30
- bne @cmp_loop
-
-@looking_for_us:
- ;this is a request for our name!
- ;copy the txn id
- ldax udp_inp+udp_data ;first 2 bytes of data are txn id
- stax netbios_name_query_response
-
- ;set the sender & recipients IP address
- ldx #03
-@copy_address_loop:
- lda ip_inp+ip_src,x
- sta udp_send_dest,x
- lda cfg_ip,x
- sta netbios_name_query_response_ip,x
- dex
- bpl @copy_address_loop
-
- ;copy our encoded hostname
- ldax #local_hostname
- stax copy_src
- ldax #netbios_name_query_response_hostname
- stax copy_dest
- ldax #30
- jsr copymem
-
- ;copy the service identifier - last 2 bytes in the query hostname
- .import eth_inp
- ldax eth_inp+$55
- stax netbios_name_query_response_hostname+30
-
- ldax #137
- stax udp_send_dest_port
- stax udp_send_src_port
-
- ldax #netbios_name_query_response_length
- stax udp_send_len
-
- ldax #netbios_name_query_response
- jmp udp_send
-
-
-@not_us:
- rts
-
-
-nb_session_callback:
-
- lda tcp_inbound_data_length+1
- cmp #$ff
- bne @not_eof
-@eof:
- inc connection_closed
-@done:
- rts
-@not_eof:
-
-;copy this chunk to our input buffer
- ldax cifs_cmd_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 cifs_cmd_buffer_ptr
- adc tcp_inbound_data_length
- sta cifs_cmd_buffer_ptr
- lda cifs_cmd_buffer_ptr+1
- adc tcp_inbound_data_length+1
- sta cifs_cmd_buffer_ptr+1
-
-;increment the cmd buffer length
- clc
- lda cifs_cmd_length
- adc tcp_inbound_data_length
- sta cifs_cmd_length
- lda cifs_cmd_length+1
- adc tcp_inbound_data_length+1
- sta cifs_cmd_length+1
-
-;have we got a complete message?
- ldax cifs_cmd_buffer
- stax copy_src
- ldy #3
- lda (copy_src),y
- cmp cifs_cmd_length
- bne @not_got_full_message
- dey
- lda (copy_src),y
- cmp cifs_cmd_length+1
- bne @not_got_full_message
-
- ;we have a complete message!
- ldy #0
- lda (copy_src),y ;get the message type
- cmp #$81 ;is it a session request?
- bne @not_session_request
- ldax #positive_session_response_packet_length
- stax tcp_send_data_len
- ldax #positive_session_response_packet
- jsr tcp_send
-
- jmp @message_handled
- @not_session_request:
- cmp #$00 ;is it a session message?
- bne @not_session_message
-
- ;this SHOULD be a SMB - best check the header
-
- ldy #4
- lda (copy_src),y ;get the message data
- cmp #$FF ;start of SMB header
- bne @not_smb
- iny
- lda (copy_src),y ;get the message data
- cmp #'S' ;start of SMB header
- bne @not_smb
-
- jsr smb_handler
-
- jmp @message_handled
-
- ;this doesn't look like a NBT session message or SMB, so give up
- @not_session_message:
-
- @not_smb:
-
- jsr tcp_close
- jmp @eof
-
-@message_handled:
- ;reset ready for next message on this connection
- ldax #-4 ;start at -4, to skip the NBT header length
- stax cifs_cmd_length
-
-
- ldax cifs_cmd_buffer
- stax cifs_cmd_buffer_ptr
-
-
-
- @not_got_full_message:
- rts
-
-
-smb_handler:
-; at this point, copy_src points to an SMB block encapsulated in an NBT session header
-
- clc
- lda copy_src
- adc #4
- sta smb_ptr ;skip past the NBT header
- lda copy_src+1
- adc #00
- sta smb_ptr+1
-
- ldy #8
- lda (copy_src),y ;get the SMB type
- cmp #$72
- bne @not_negotiate_protocol
- jmp @negotiate_protocol
-@not_negotiate_protocol:
- ;we assume it is an "AndX" command
-
-
-
- sta andx_opcode
- lda smb_ptr
- clc
- adc #$20 ;skip over SMB header
- sta andx_ptr
-
- lda smb_ptr+1
- adc #00
- sta andx_ptr+1
-
- jsr start_smb_response
-
-@parse_andx_block:
- ldax andx_ptr
- stax copy_src
- lda andx_opcode
-
- cmp #$ff
- beq @done_all_andx_blocks
-
- ldy #0
-@andx_opcode_scan:
- lda andx_opcodes,y
- beq @opcode_not_found
- cmp andx_opcode
- beq @opcode_found
- iny
- iny
- iny
- jmp @andx_opcode_scan
-@opcode_found:
- lda andx_opcodes+1,y
- sta andx_handler+1
- lda andx_opcodes+2,y
- sta andx_handler+2
- jsr andx_handler
- jmp @go_to_next_andx_block
-
-@opcode_not_found:
- jsr unknown_andx
-
-@go_to_next_andx_block:
- ldy #3
- lda (copy_src),y ;get the AndX offset low byte
- clc
- adc smb_ptr
- sta andx_ptr
- iny
- lda (copy_src),y ;get the AndX offset high byte
- adc smb_ptr+1
- sta andx_ptr+1
- ldy #1
- lda (copy_src),y ;get the subsequent AndX opcode
- sta andx_opcode
-
- jmp @parse_andx_block
-
-@done_all_andx_blocks:
- ldax smb_response_length
- inx ;FIXME! this is to force wireshark to dump as SMB even tho packet is incorrect
- stax tcp_send_data_len
- ldax smb_response_buffer
- jsr tcp_send
-
- rts
-@negotiate_protocol:
-;copy the request TID,PID,UID,MID into the response
- ldy #28 ;offset of TID from start of message
- ldx #0
-:
- lda (copy_src),y
- sta negotiate_protocol_response_tid,x
- inx
- iny
- cpx #8
- bne :-
-
-
- lda #$ff
- sta dialect_index
- sta dialect_index+1
- clc
- lda cifs_cmd_buffer
- adc #$26
- sta copy_src
- lda cifs_cmd_buffer+1
- adc #$00
- sta copy_src+1
-
- ldy #$0
-@dialect_scan_loop:
- iny
- bmi @end_of_dialects ;if we go to offset $80, we have gone too far
- lda dialect_index
- cmp #$10 ;if we've scanned more than $10 dialects, something is wrong
- beq @end_of_dialects
- lda (copy_src),y
- cmp #$02
- bne @test_dialect
- inc dialect_index
- jmp @dialect_scan_loop
-@test_dialect:
-
- tya
- clc
- adc copy_src
- sta copy_src
- bcc :+
- inc copy_src+1
-:
- ldy #0
-
-@test_dialect_loop:
- lda (copy_src),y
- cmp preferred_dialect_id,y
- bne @dialect_scan_loop
- iny
- cpy #preferred_dialect_id_length
- bne @test_dialect_loop
- inc dialect_index+1
- jmp @found_preferred_dialect
-
-@end_of_dialects:
- lda #$ff
- sta dialect_index
-
- @found_preferred_dialect:
-
- ldax #negotiate_protocol_response_message_length
- stax tcp_send_data_len
- ldax #negotiate_protocol_response_message
- jsr tcp_send
-
- rts
-
-start_smb_response:
- ldax smb_response_buffer
- stax copy_dest
- ldy #0
-@copy_header_loop:
- lda (copy_src),y ; copy_src should be the SMB request - cloning this will set PID / MID etc
- sta (copy_dest),y
- iny
- cpy #smb_response_header_length
- bne @copy_header_loop
- lda #0
- sta smb_response_length+1
- lda #smb_response_header_length
- sta smb_response_length
- ldy #3
- sta (copy_dest),y
-
- ;set the flags correctly
- ldy #smb_response_flags_offset
- lda #$82 ;FLAGS byte
- sta (copy_dest),y
- iny
- lda #$01 ;FLAGS2 low byte
- sta (copy_dest),y
- iny
- lda #$00 ;FLAGS2 hi byte
- sta (copy_dest),y
-
- rts
-
-add_andx_response:
- rts
-
-
-.import print_a
-.import print_hex
-session_setup_andx:
- lda #'S'
- jsr print_a
- rts
-
-tree_connect_andx:
- lda #'T'
- jsr print_a
- rts
-
-unknown_andx:
- lda andx_opcode
- jsr print_hex
- lda #'?'
- jsr print_a
- rts
-
-.rodata
-
-andx_opcodes:
- .byte $73
- .word session_setup_andx
- .byte $75
- .word tree_connect_andx
- .byte $00
-
-
-
-.data
-
-andx_handler:
- jmp $FFFF ;filled in later
-
-smb_response_header:
-negotiate_protocol_response_message:
- .byte $00 ;message type = session message
- .byte $00,$00,negotiate_protocol_response_message_length-4 ;NBT header
- .byte $FF,"SMB" ;SMB header
- .byte $72 ;command = negotiate protocol
- .byte $00,$00,$00,$00 ;status = OK
-smb_response_flags_offset =*-smb_response_header
- .byte $82 ;flags : oplocks not supported, paths are case sensitive
- .byte $01,$00 ;flags 2 - long file names allowed
- .byte $00, $00 ;PID HIGH
- .byte $00,$00,$00,$00,$00,$00,$00,$00 ; signature
- .byte $00, $00 ;reserved
-negotiate_protocol_response_tid:
- .byte $00,$00 ;tree ID
- .byte $98,$76 ;PID - to be overwritten
- .byte $65,$64 ;USER ID - to be overwritten
- .byte $ab,$cd ;multiplex ID - to be overwritten
-smb_response_header_length=*-smb_response_header
- .byte $11 ;word count
-dialect_index: .res 2 ;index of selected dialect
- .byte $00 ;security mode: share, no encryption
- .byte $01,$00 ;Max MPX count
- .byte $01,$00 ;Max VCs count
- .byte $00,$08,$00,$00 ;max buffer size
- .byte $00,$08,$00,$00 ;max raw size
- .byte $12,$34,$56,$78 ;session key
- .byte $00,$00,$00,$00 ;capabilities
- .byte $00,$00,$00,$00 ;server time low
- .byte $00,$00,$00,$00 ;server time high
- .byte $00,$00 ;server GMT offset
- .byte $00 ;encryption key length
- .word negotiate_protocol_response_message_data_length ;data length
-negotiate_protocol_response_message_data:
- .byte "WORKGROUP",0
- .byte "SERVERNAME",0
-
-negotiate_protocol_response_message_length=*-negotiate_protocol_response_message
-negotiate_protocol_response_message_data_length=*-negotiate_protocol_response_message_data
-
-host_announce_message:
- .byte $11 ;message type = direct group datagram
- .byte $02 ;no more fragments, this is first fragment, node type = B
- .byte $ab,$cd ;txn id
-host_announce_my_ip:
- .byte $0,0,0,0 ;source IP
- .byte $0,138 ;source port
- .byte $00,<(host_announce_message_length-4) ;datagram length
- .byte $00,$00 ;packet offset
- .byte $20 ;hostname length
-host_announce_hostname:
- .res 32 ;hostname
- .byte $0 ;nul at end of hostname
- ;now WORKGROUP<1D> encoded
-
- .byte $20, $46, $48, $45, $50, $46, $43, $45, $4c, $45, $48, $46, $43, $45, $50, $46
- .byte $46, $46, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $42, $4E, $00
-
- .byte $ff,"SMB" ;Server Message Block header
- .byte $25 ;SMB command = Transaction
- .byte $00 ;error class = success
- .byte $00 ;reserved
- .byte $00,$00 ;no error
- .byte $00 ;flags
- .byte $00,$00 ;flags2
- .byte $00,$00 ;PID high
- .byte $00,$00,$00,$00,$00,$00,$00,$00 ;Signature
- .byte $00,$00 ;reserved
- .byte $00,$00 ;tree ID
- .byte $00,$00 ;process ID
- .byte $00,$00 ;user ID
- .byte $00,$00 ;multiplex ID
- .byte $11 ;txn word count
- .byte $00,$00 ;txn paramater count
- .byte $21,$00 ;txn total data count
- .byte $00,$00 ;txn max paramater count
- .byte $00,$00 ;txn max data count
- .byte $00 ;txn max setup count
- .byte $00 ;reserved
- .byte $00,$00 ;flags
- .byte $ed,$03,$00,$00 ;timeout = 1 second
- .byte $00,$00 ;reserved
- .byte $00,$00 ;paramater count
- .byte $00,$00 ;paramater offset
- .byte $21,$00 ;data count
- .byte $56,$00 ;data offset
- .byte $03 ;setup count
- .byte $00 ;reserved
-
- .byte $01,$00 ;opcode = WRITE MAIL SLOT
- .byte $00,$00 ;priority 0
- .byte $02,$00 ;class = unreliable & broadcast
- .byte $32,$00 ;byte count
- .byte "\MAILSLOT\BROWSE", 0
- .byte $01 ;command - HOST ANNOUNCEMENT
- .byte $0 ;update count 0
- .byte $80,$fc,03,00 ;update period
- host_announce_servername:
- .res 16
- .byte $01 ;OS major version
- .byte $64 ;OS minor version
- .byte $03,$02,$0,$0 ;advertise as a workstation, server & print host
- .byte $0F ;browser major version
- .byte $01 ;browser minor version
- .byte $55,$aa ;signature
- .byte $0 ;host comment
- host_announce_message_length=*-host_announce_message
-
-
-netbios_name_query_response:
- .byte $12,$34 ;transaction id
- .byte $85,$00 ;flags: name query response, no error
- .byte $00,$00 ;questions = 0
- .byte $00,$01 ;answers = 1
- .byte $00,$00 ;authority records = 0
- .byte $00,$00 ;additional records = 0
- .byte $20 ;
-netbios_name_query_response_hostname:
- .res 30 ;will be replaced with encoded hostname
- .byte $43,$41 ;
- .byte $00 ;
- .byte $00,$20 ; type = NB
- .byte $00,$01 ;class = IN
- .byte $00,$00,$01,$40 ; TTL = 64 seconds
- .byte $00,$06 ;data length
- .byte $00,$00 ;FLAGS = B-NODE, UNIQUE NAME
-netbios_name_query_response_ip:
- .res 4 ;filled in with our IP
- netbios_name_query_response_length=*-netbios_name_query_response
-
-registration_request:
-
- .byte $0c, $64 ;txn ID
- .byte $29,$10 ;Registration Request opcode & flags
- .byte $00,$01 ;questions = 1
- .byte $00,$00 ;answers = 0
- .byte $00,$00 ;authority records = 0
- .byte $00,$01 ;additional records = 1
-registration_request_servername:
- ;now WORKGROUP<00> encoded
- .byte $20, $46, $48, $45, $50, $46, $43, $45, $4c, $45, $48, $46, $43, $45, $50, $46
- .byte $46, $46, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $41, $41, $00
-
- .byte $00,$20 ;question_type = NB
- .byte $00,$01 ;question_class = IN
- .byte $c0,$0c ;additional record name : ptr to string in QUESTION NAME
- .byte $00,$20 ;question_type = NB
- .byte $00,$01 ;question_class = IN
- .byte $00,$00,$01,$40 ; TTL = 64 seconds
- .byte $00,$06 ;data length
- .byte $00,$00 ;FLAGS = B-NODE, UNIQUE NAME
-
-.rodata
-preferred_dialect_id: .byte "NT LM 0.12"
-preferred_dialect_id_length=*-preferred_dialect_id
-
-positive_session_response_packet:
- .byte $82 ;packet type = Positive session response
- .byte $00 ;flags
- .byte $00, $00 ;message length
-positive_session_response_packet_length=*-positive_session_response_packet
-
-.data
-
-cifs_cmd_buffer: .word DEFAULT_CIFS_CMD_BUFFER
-
-smb_response_buffer: .word DEFAULT_SMB_RESPONSE_BUFFER
-
-.bss
-hostname_buffer: .res 33
-
-
-local_hostname: .res 33
-
-raw_local_hostname:
- .res 16
-
-hi_nibble: .res 1
-
-connection_closed: .res 1
-
-cifs_cmd_buffer_ptr: .res 2
-cifs_cmd_length: .res 2
-
-andx_opcode: .res 1
-andx_ptr: .res 2 ;pointer to next 'AndX' command
-andx_length: .res 2
-smb_ptr: .res 2
-smb_response_length: .res 2
-
-
-; 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 --
-
+;a simple NETBIOS over TCP server
+;aka "Common Internet File System"
+;
+; refs: RFC1001, RFC1002, "Implementing CIFS" - http://ubiqx.org/cifs/
+
+.include "../inc/common.i"
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+DEFAULT_CIFS_CMD_BUFFER = $6800
+DEFAULT_SMB_RESPONSE_BUFFER=$6000
+.export cifs_l1_encode
+.export cifs_l1_decode
+.export cifs_start
+
+.import copymem
+.importzp copy_src
+.importzp copy_dest
+
+.import cfg_ip
+.import output_buffer
+.importzp udp_data
+.import udp_send
+.import udp_inp
+.importzp udp_data
+.import udp_send_dest
+.import udp_send_src_port
+.import udp_send_dest_port
+.import udp_send_len
+.importzp ip_src
+.importzp ip_dest
+.import ip_data
+.import ip_inp
+.import tcp_close
+.import tcp_listen
+.import tcp_callback
+.import tcp_inbound_data_length
+.import tcp_inbound_data_ptr
+.import tcp_send
+.import tcp_send_data_len
+
+.import ip65_process
+.import udp_add_listener
+.import udp_callback
+
+nbns_txn_id = 0
+nbns_opcode=2
+nbns_flags_rcode=3
+nbns_qdcount=4
+nbns_ancount=6
+nbns_nscount=8
+nbns_arcount=10
+nbns_question_name=12
+nbns_service_type=43
+
+
+nbns_my_ip=64
+nbns_registration_message_length=68
+
+
+;given an ASCII (or PETSCII) hostname, convert to
+;canonical 'level 1 encoded' form.
+;
+;only supports the default scope (' ' : 0x20)
+;inputs:
+; AX: pointer to null terminated hostname to be encoded
+;outputs:
+; AX: pointer to decoded hostname
+cifs_l1_encode:
+ stax copy_src
+ lda #0
+ tax
+ sta hostname_buffer+32
+@empty_buffer_loop:
+ lda #$43
+ sta hostname_buffer,x
+ inx
+ lda #$41
+ sta hostname_buffer,x
+ inx
+ cpx #$20
+ bmi @empty_buffer_loop
+ ldy #0
+ ldx #0
+@copy_loop:
+
+ lda (copy_src),y
+ beq @done
+ lsr
+ lsr
+ lsr
+ lsr
+ clc
+ adc #$41
+ sta hostname_buffer,x
+
+ inx
+ lda (copy_src),y
+ and #$0F
+ clc
+ adc #$41
+ sta hostname_buffer,x
+ inx
+ iny
+ cpx #$1D
+ bmi @copy_loop
+@done:
+ ldax #hostname_buffer
+ rts
+
+;given a 'level 1 encoded' hostname, decode to ASCII .
+;
+;inputs:
+; AX: pointer to encoded hostname to be decoded
+;outputs:
+; AX: pointer to decoded hostname (will be 16 byte hostname, right padded with spaces, nul terminated)
+cifs_l1_decode:
+ stax copy_src
+ ldy #0
+ ldx #0
+@decode_loop:
+ lda (copy_src),y
+ sec
+ sbc #$41
+ asl
+ asl
+ asl
+ asl
+ sta hi_nibble
+ iny
+ lda (copy_src),y
+ sec
+ sbc #$41
+ clc
+ adc hi_nibble
+ sta hostname_buffer,x
+ iny
+ inx
+ cpx #$10
+ bmi @decode_loop
+ lda #0
+ sta hostname_buffer,x
+ ldax #hostname_buffer
+ rts
+
+
+;start a CIFS (SMB) server process, and advertise the specified hostname on the local LAN
+;
+;inputs:
+;AX = ptr to hostname to be used
+;outputs:
+; none
+cifs_start:
+
+ ;save the hostname in 'raw' form
+ stax copy_src
+ ldax #raw_local_hostname
+ stax copy_dest
+ ldax #$0f
+ stx raw_local_hostname+15
+ jsr copymem
+
+ ;set up callbacks
+ ldax #nbns_callback
+ stax udp_callback
+ ldax #137
+ jsr udp_add_listener
+
+ ldax #nbns_callback
+ stax udp_callback
+ ldax #137
+ jsr udp_add_listener
+
+ ldax #raw_local_hostname
+ jsr cifs_l1_encode
+ ldx #0
+@copy_hostname_loop:
+ lda hostname_buffer,x
+ sta local_hostname,x
+ inx
+ cpx #$21
+ bmi @copy_hostname_loop
+
+ jsr cifs_advertise_hostname
+ jsr cifs_advertise_hostname
+
+
+ ldax #nb_session_callback
+ stax tcp_callback
+@listen:
+
+ ldax #-4 ;start at -4, to skip the NBT header length
+ stax cifs_cmd_length
+
+
+ ldax cifs_cmd_buffer
+ stax cifs_cmd_buffer_ptr
+ ldax #139
+ stx connection_closed
+
+ jsr tcp_listen
+
+@loop:
+ inc $d020 ;FIXME
+ jsr ip65_process
+ lda connection_closed
+ beq @loop
+
+ jmp @listen
+ rts
+
+
+;broadcast a Name Registration Request message to the local LAN
+cifs_advertise_hostname:
+
+ ; advertise the 'server' service for own hostname
+ ;overwrite the hostname in 'DNS compressed form'
+ ;we assume this hostname ends with <20>
+ lda #$20 ;indicates what follows is a netbios name
+ sta output_buffer+nbns_question_name
+
+ ldx #0
+@copy_hostname_loop:
+ lda local_hostname,x
+ sta registration_request_servername+1,x
+ inx
+ cpx #$21
+ bmi @copy_hostname_loop
+
+ jsr @send_nbns_message
+
+
+ ;copy our encode hostname to the host announcment
+ ldax #local_hostname
+ stax copy_src
+ ldax #host_announce_hostname
+ stax copy_dest
+ ldax #$20
+ jsr copymem
+
+ ;copy our raw hostname to the host announcment
+ ldax #raw_local_hostname
+ stax copy_src
+ ldax #host_announce_servername
+ stax copy_dest
+ ldax #$10
+ jsr copymem
+
+
+;copy the local IP address to the 'sender' field of the host announcment
+ ldx #03
+@copy_sending_address_loop:
+ lda cfg_ip,x
+ sta host_announce_my_ip,x
+ dex
+ bpl @copy_sending_address_loop
+
+
+ ldax #138
+ stax udp_send_dest_port
+ stax udp_send_src_port
+
+ ldax #host_announce_message_length
+ stax udp_send_len
+
+ ldax #host_announce_message
+ jsr udp_send
+ rts
+
+
+@send_nbns_message:
+;copy the local IP address
+ ldx #03
+@copy_my_address_loop:
+ lda cfg_ip,x
+ sta nbns_my_ip,x
+ dex
+ bpl @copy_my_address_loop
+
+ ;send to the broadcast address
+ lda #$ff
+ ldx #03
+@copy_broadcast_address_loop:
+ sta udp_send_dest,x
+ dex
+ bpl @copy_broadcast_address_loop
+
+ ldax #137
+ stax udp_send_dest_port
+ stax udp_send_src_port
+
+ ldax #nbns_registration_message_length
+ stax udp_send_len
+
+ ldax #registration_request
+ jsr udp_send
+
+
+ rts
+
+
+
+nbns_callback:
+
+ lda udp_inp+udp_data+nbns_opcode
+ and #$f8 ;mask the lower three bits
+ beq @name_request
+ rts
+@name_request:
+
+ ;this is a NB NAME REQUEST.
+ ;is it a unicast message?
+ ldx #3
+@check_unicast_loop:
+ lda ip_inp+ip_dest,x
+ cmp cfg_ip,x
+ bne @not_unicast
+ dex
+ bpl @check_unicast_loop
+
+ jmp @looking_for_us
+
+@not_unicast:
+ ;is it looking for our local hostname?
+ ldax #udp_inp+udp_data+nbns_question_name+1
+ stax copy_src
+ ldy #0
+@cmp_loop:
+ lda (copy_src),y
+ cmp local_hostname,y
+ bne @not_us
+ iny
+ cpy #30
+ bne @cmp_loop
+
+@looking_for_us:
+ ;this is a request for our name!
+ ;copy the txn id
+ ldax udp_inp+udp_data ;first 2 bytes of data are txn id
+ stax netbios_name_query_response
+
+ ;set the sender & recipients IP address
+ ldx #03
+@copy_address_loop:
+ lda ip_inp+ip_src,x
+ sta udp_send_dest,x
+ lda cfg_ip,x
+ sta netbios_name_query_response_ip,x
+ dex
+ bpl @copy_address_loop
+
+ ;copy our encoded hostname
+ ldax #local_hostname
+ stax copy_src
+ ldax #netbios_name_query_response_hostname
+ stax copy_dest
+ ldax #30
+ jsr copymem
+
+ ;copy the service identifier - last 2 bytes in the query hostname
+ .import eth_inp
+ ldax eth_inp+$55
+ stax netbios_name_query_response_hostname+30
+
+ ldax #137
+ stax udp_send_dest_port
+ stax udp_send_src_port
+
+ ldax #netbios_name_query_response_length
+ stax udp_send_len
+
+ ldax #netbios_name_query_response
+ jmp udp_send
+
+
+@not_us:
+ rts
+
+
+nb_session_callback:
+
+ lda tcp_inbound_data_length+1
+ cmp #$ff
+ bne @not_eof
+@eof:
+ inc connection_closed
+@done:
+ rts
+@not_eof:
+
+;copy this chunk to our input buffer
+ ldax cifs_cmd_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 cifs_cmd_buffer_ptr
+ adc tcp_inbound_data_length
+ sta cifs_cmd_buffer_ptr
+ lda cifs_cmd_buffer_ptr+1
+ adc tcp_inbound_data_length+1
+ sta cifs_cmd_buffer_ptr+1
+
+;increment the cmd buffer length
+ clc
+ lda cifs_cmd_length
+ adc tcp_inbound_data_length
+ sta cifs_cmd_length
+ lda cifs_cmd_length+1
+ adc tcp_inbound_data_length+1
+ sta cifs_cmd_length+1
+
+;have we got a complete message?
+ ldax cifs_cmd_buffer
+ stax copy_src
+ ldy #3
+ lda (copy_src),y
+ cmp cifs_cmd_length
+ bne @not_got_full_message
+ dey
+ lda (copy_src),y
+ cmp cifs_cmd_length+1
+ bne @not_got_full_message
+
+ ;we have a complete message!
+ ldy #0
+ lda (copy_src),y ;get the message type
+ cmp #$81 ;is it a session request?
+ bne @not_session_request
+ ldax #positive_session_response_packet_length
+ stax tcp_send_data_len
+ ldax #positive_session_response_packet
+ jsr tcp_send
+
+ jmp @message_handled
+ @not_session_request:
+ cmp #$00 ;is it a session message?
+ bne @not_session_message
+
+ ;this SHOULD be a SMB - best check the header
+
+ ldy #4
+ lda (copy_src),y ;get the message data
+ cmp #$FF ;start of SMB header
+ bne @not_smb
+ iny
+ lda (copy_src),y ;get the message data
+ cmp #'S' ;start of SMB header
+ bne @not_smb
+
+ jsr smb_handler
+
+ jmp @message_handled
+
+ ;this doesn't look like a NBT session message or SMB, so give up
+ @not_session_message:
+
+ @not_smb:
+
+ jsr tcp_close
+ jmp @eof
+
+@message_handled:
+ ;reset ready for next message on this connection
+ ldax #-4 ;start at -4, to skip the NBT header length
+ stax cifs_cmd_length
+
+
+ ldax cifs_cmd_buffer
+ stax cifs_cmd_buffer_ptr
+
+
+
+ @not_got_full_message:
+ rts
+
+
+smb_handler:
+; at this point, copy_src points to an SMB block encapsulated in an NBT session header
+
+ clc
+ lda copy_src
+ adc #4
+ sta smb_ptr ;skip past the NBT header
+ lda copy_src+1
+ adc #00
+ sta smb_ptr+1
+
+ ldy #8
+ lda (copy_src),y ;get the SMB type
+ cmp #$72
+ bne @not_negotiate_protocol
+ jmp @negotiate_protocol
+@not_negotiate_protocol:
+ ;we assume it is an "AndX" command
+
+
+
+ sta andx_opcode
+ lda smb_ptr
+ clc
+ adc #$20 ;skip over SMB header
+ sta andx_ptr
+
+ lda smb_ptr+1
+ adc #00
+ sta andx_ptr+1
+
+ jsr start_smb_response
+
+@parse_andx_block:
+ ldax andx_ptr
+ stax copy_src
+ lda andx_opcode
+
+ cmp #$ff
+ beq @done_all_andx_blocks
+
+ ldy #0
+@andx_opcode_scan:
+ lda andx_opcodes,y
+ beq @opcode_not_found
+ cmp andx_opcode
+ beq @opcode_found
+ iny
+ iny
+ iny
+ jmp @andx_opcode_scan
+@opcode_found:
+ lda andx_opcodes+1,y
+ sta andx_handler+1
+ lda andx_opcodes+2,y
+ sta andx_handler+2
+ jsr andx_handler
+ jmp @go_to_next_andx_block
+
+@opcode_not_found:
+ jsr unknown_andx
+
+@go_to_next_andx_block:
+ ldy #3
+ lda (copy_src),y ;get the AndX offset low byte
+ clc
+ adc smb_ptr
+ sta andx_ptr
+ iny
+ lda (copy_src),y ;get the AndX offset high byte
+ adc smb_ptr+1
+ sta andx_ptr+1
+ ldy #1
+ lda (copy_src),y ;get the subsequent AndX opcode
+ sta andx_opcode
+
+ jmp @parse_andx_block
+
+@done_all_andx_blocks:
+ ldax smb_response_length
+ inx ;FIXME! this is to force wireshark to dump as SMB even tho packet is incorrect
+ stax tcp_send_data_len
+ ldax smb_response_buffer
+ jsr tcp_send
+
+ rts
+@negotiate_protocol:
+;copy the request TID,PID,UID,MID into the response
+ ldy #28 ;offset of TID from start of message
+ ldx #0
+:
+ lda (copy_src),y
+ sta negotiate_protocol_response_tid,x
+ inx
+ iny
+ cpx #8
+ bne :-
+
+
+ lda #$ff
+ sta dialect_index
+ sta dialect_index+1
+ clc
+ lda cifs_cmd_buffer
+ adc #$26
+ sta copy_src
+ lda cifs_cmd_buffer+1
+ adc #$00
+ sta copy_src+1
+
+ ldy #$0
+@dialect_scan_loop:
+ iny
+ bmi @end_of_dialects ;if we go to offset $80, we have gone too far
+ lda dialect_index
+ cmp #$10 ;if we've scanned more than $10 dialects, something is wrong
+ beq @end_of_dialects
+ lda (copy_src),y
+ cmp #$02
+ bne @test_dialect
+ inc dialect_index
+ jmp @dialect_scan_loop
+@test_dialect:
+
+ tya
+ clc
+ adc copy_src
+ sta copy_src
+ bcc :+
+ inc copy_src+1
+:
+ ldy #0
+
+@test_dialect_loop:
+ lda (copy_src),y
+ cmp preferred_dialect_id,y
+ bne @dialect_scan_loop
+ iny
+ cpy #preferred_dialect_id_length
+ bne @test_dialect_loop
+ inc dialect_index+1
+ jmp @found_preferred_dialect
+
+@end_of_dialects:
+ lda #$ff
+ sta dialect_index
+
+ @found_preferred_dialect:
+
+ ldax #negotiate_protocol_response_message_length
+ stax tcp_send_data_len
+ ldax #negotiate_protocol_response_message
+ jsr tcp_send
+
+ rts
+
+start_smb_response:
+ ldax smb_response_buffer
+ stax copy_dest
+ ldy #0
+@copy_header_loop:
+ lda (copy_src),y ; copy_src should be the SMB request - cloning this will set PID / MID etc
+ sta (copy_dest),y
+ iny
+ cpy #smb_response_header_length
+ bne @copy_header_loop
+ lda #0
+ sta smb_response_length+1
+ lda #smb_response_header_length
+ sta smb_response_length
+ ldy #3
+ sta (copy_dest),y
+
+ ;set the flags correctly
+ ldy #smb_response_flags_offset
+ lda #$82 ;FLAGS byte
+ sta (copy_dest),y
+ iny
+ lda #$01 ;FLAGS2 low byte
+ sta (copy_dest),y
+ iny
+ lda #$00 ;FLAGS2 hi byte
+ sta (copy_dest),y
+
+ rts
+
+add_andx_response:
+ rts
+
+
+.import print_a
+.import print_hex
+session_setup_andx:
+ lda #'S'
+ jsr print_a
+ rts
+
+tree_connect_andx:
+ lda #'T'
+ jsr print_a
+ rts
+
+unknown_andx:
+ lda andx_opcode
+ jsr print_hex
+ lda #'?'
+ jsr print_a
+ rts
+
+.rodata
+
+andx_opcodes:
+ .byte $73
+ .word session_setup_andx
+ .byte $75
+ .word tree_connect_andx
+ .byte $00
+
+
+
+.data
+
+andx_handler:
+ jmp $FFFF ;filled in later
+
+smb_response_header:
+negotiate_protocol_response_message:
+ .byte $00 ;message type = session message
+ .byte $00,$00,negotiate_protocol_response_message_length-4 ;NBT header
+ .byte $FF,"SMB" ;SMB header
+ .byte $72 ;command = negotiate protocol
+ .byte $00,$00,$00,$00 ;status = OK
+smb_response_flags_offset =*-smb_response_header
+ .byte $82 ;flags : oplocks not supported, paths are case sensitive
+ .byte $01,$00 ;flags 2 - long file names allowed
+ .byte $00, $00 ;PID HIGH
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; signature
+ .byte $00, $00 ;reserved
+negotiate_protocol_response_tid:
+ .byte $00,$00 ;tree ID
+ .byte $98,$76 ;PID - to be overwritten
+ .byte $65,$64 ;USER ID - to be overwritten
+ .byte $ab,$cd ;multiplex ID - to be overwritten
+smb_response_header_length=*-smb_response_header
+ .byte $11 ;word count
+dialect_index: .res 2 ;index of selected dialect
+ .byte $00 ;security mode: share, no encryption
+ .byte $01,$00 ;Max MPX count
+ .byte $01,$00 ;Max VCs count
+ .byte $00,$08,$00,$00 ;max buffer size
+ .byte $00,$08,$00,$00 ;max raw size
+ .byte $12,$34,$56,$78 ;session key
+ .byte $00,$00,$00,$00 ;capabilities
+ .byte $00,$00,$00,$00 ;server time low
+ .byte $00,$00,$00,$00 ;server time high
+ .byte $00,$00 ;server GMT offset
+ .byte $00 ;encryption key length
+ .word negotiate_protocol_response_message_data_length ;data length
+negotiate_protocol_response_message_data:
+ .byte "WORKGROUP",0
+ .byte "SERVERNAME",0
+
+negotiate_protocol_response_message_length=*-negotiate_protocol_response_message
+negotiate_protocol_response_message_data_length=*-negotiate_protocol_response_message_data
+
+host_announce_message:
+ .byte $11 ;message type = direct group datagram
+ .byte $02 ;no more fragments, this is first fragment, node type = B
+ .byte $ab,$cd ;txn id
+host_announce_my_ip:
+ .byte $0,0,0,0 ;source IP
+ .byte $0,138 ;source port
+ .byte $00,<(host_announce_message_length-4) ;datagram length
+ .byte $00,$00 ;packet offset
+ .byte $20 ;hostname length
+host_announce_hostname:
+ .res 32 ;hostname
+ .byte $0 ;nul at end of hostname
+ ;now WORKGROUP<1D> encoded
+
+ .byte $20, $46, $48, $45, $50, $46, $43, $45, $4c, $45, $48, $46, $43, $45, $50, $46
+ .byte $46, $46, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $42, $4E, $00
+
+ .byte $ff,"SMB" ;Server Message Block header
+ .byte $25 ;SMB command = Transaction
+ .byte $00 ;error class = success
+ .byte $00 ;reserved
+ .byte $00,$00 ;no error
+ .byte $00 ;flags
+ .byte $00,$00 ;flags2
+ .byte $00,$00 ;PID high
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ;Signature
+ .byte $00,$00 ;reserved
+ .byte $00,$00 ;tree ID
+ .byte $00,$00 ;process ID
+ .byte $00,$00 ;user ID
+ .byte $00,$00 ;multiplex ID
+ .byte $11 ;txn word count
+ .byte $00,$00 ;txn paramater count
+ .byte $21,$00 ;txn total data count
+ .byte $00,$00 ;txn max paramater count
+ .byte $00,$00 ;txn max data count
+ .byte $00 ;txn max setup count
+ .byte $00 ;reserved
+ .byte $00,$00 ;flags
+ .byte $ed,$03,$00,$00 ;timeout = 1 second
+ .byte $00,$00 ;reserved
+ .byte $00,$00 ;paramater count
+ .byte $00,$00 ;paramater offset
+ .byte $21,$00 ;data count
+ .byte $56,$00 ;data offset
+ .byte $03 ;setup count
+ .byte $00 ;reserved
+
+ .byte $01,$00 ;opcode = WRITE MAIL SLOT
+ .byte $00,$00 ;priority 0
+ .byte $02,$00 ;class = unreliable & broadcast
+ .byte $32,$00 ;byte count
+ .byte "\MAILSLOT\BROWSE", 0
+ .byte $01 ;command - HOST ANNOUNCEMENT
+ .byte $0 ;update count 0
+ .byte $80,$fc,03,00 ;update period
+ host_announce_servername:
+ .res 16
+ .byte $01 ;OS major version
+ .byte $64 ;OS minor version
+ .byte $03,$02,$0,$0 ;advertise as a workstation, server & print host
+ .byte $0F ;browser major version
+ .byte $01 ;browser minor version
+ .byte $55,$aa ;signature
+ .byte $0 ;host comment
+ host_announce_message_length=*-host_announce_message
+
+
+netbios_name_query_response:
+ .byte $12,$34 ;transaction id
+ .byte $85,$00 ;flags: name query response, no error
+ .byte $00,$00 ;questions = 0
+ .byte $00,$01 ;answers = 1
+ .byte $00,$00 ;authority records = 0
+ .byte $00,$00 ;additional records = 0
+ .byte $20 ;
+netbios_name_query_response_hostname:
+ .res 30 ;will be replaced with encoded hostname
+ .byte $43,$41 ;
+ .byte $00 ;
+ .byte $00,$20 ; type = NB
+ .byte $00,$01 ;class = IN
+ .byte $00,$00,$01,$40 ; TTL = 64 seconds
+ .byte $00,$06 ;data length
+ .byte $00,$00 ;FLAGS = B-NODE, UNIQUE NAME
+netbios_name_query_response_ip:
+ .res 4 ;filled in with our IP
+ netbios_name_query_response_length=*-netbios_name_query_response
+
+registration_request:
+
+ .byte $0c, $64 ;txn ID
+ .byte $29,$10 ;Registration Request opcode & flags
+ .byte $00,$01 ;questions = 1
+ .byte $00,$00 ;answers = 0
+ .byte $00,$00 ;authority records = 0
+ .byte $00,$01 ;additional records = 1
+registration_request_servername:
+ ;now WORKGROUP<00> encoded
+ .byte $20, $46, $48, $45, $50, $46, $43, $45, $4c, $45, $48, $46, $43, $45, $50, $46
+ .byte $46, $46, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $41, $41, $00
+
+ .byte $00,$20 ;question_type = NB
+ .byte $00,$01 ;question_class = IN
+ .byte $c0,$0c ;additional record name : ptr to string in QUESTION NAME
+ .byte $00,$20 ;question_type = NB
+ .byte $00,$01 ;question_class = IN
+ .byte $00,$00,$01,$40 ; TTL = 64 seconds
+ .byte $00,$06 ;data length
+ .byte $00,$00 ;FLAGS = B-NODE, UNIQUE NAME
+
+.rodata
+preferred_dialect_id: .byte "NT LM 0.12"
+preferred_dialect_id_length=*-preferred_dialect_id
+
+positive_session_response_packet:
+ .byte $82 ;packet type = Positive session response
+ .byte $00 ;flags
+ .byte $00, $00 ;message length
+positive_session_response_packet_length=*-positive_session_response_packet
+
+.data
+
+cifs_cmd_buffer: .word DEFAULT_CIFS_CMD_BUFFER
+
+smb_response_buffer: .word DEFAULT_SMB_RESPONSE_BUFFER
+
+.bss
+hostname_buffer: .res 33
+
+
+local_hostname: .res 33
+
+raw_local_hostname:
+ .res 16
+
+hi_nibble: .res 1
+
+connection_closed: .res 1
+
+cifs_cmd_buffer_ptr: .res 2
+cifs_cmd_length: .res 2
+
+andx_opcode: .res 1
+andx_ptr: .res 2 ;pointer to next 'AndX' command
+andx_length: .res 2
+smb_ptr: .res 2
+smb_response_length: .res 2
+
+
+; 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/ip65/config.s b/ip65/config.s
similarity index 97%
rename from client/ip65/config.s
rename to ip65/config.s
index eadc5bb..de88ec9 100644
--- a/client/ip65/config.s
+++ b/ip65/config.s
@@ -1,93 +1,93 @@
-;IP configuration defaults
-;most of these will be overwritten if dhcp is used for configuration
-
-.include "../inc/common.i"
-
-.export cfg_mac
-.export cfg_mac_default
-.export cfg_ip
-.export cfg_netmask
-.export cfg_gateway
-.export cfg_dns
-.export cfg_tftp_server
-.export cfg_get_configuration_ptr
-.export cfg_init
-.export cfg_default_drive
-.export cfg_size
-
-.export dhcp_server
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-.code
-
-;return a pointer to where the IP configuration is kept
-;this is really only useful for the NB65 API - for anything
-;linking directly against ip65, you would just import the
-;address of the individual configuration elements, rather
-;than use a base pointer+offsets to find each item.
-;inputs: none
-;outputs: AX = pointer to IP configuration.
-cfg_get_configuration_ptr:
- ldax #cfg_mac
- clc
- rts
-
-;copy the IP stack defaults (probably stored in ROM) to the running values in RAM
-;inputs: none
-;outputs: AX = pointer to IP configuration.
-cfg_init:
- ldax #cfg_mac_default
- stax copy_src
- ldax #cfg_mac
- stax copy_dest
- ldax #cfg_size
- jmp copymem
-
-.segment "IP65_DEFAULTS"
-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)
-;cfg_gateway_default: .byte 0, 0, 0, 0 ;ip address of router on local network (will be overwritten if dhcp_init is called)
-cfg_gateway_default: .byte 192, 168, 1, 1 ;ip address of router on local network (will be overwritten if dhcp_init is called)
-cfg_dns_default: .byte 0, 0, 0, 0; ip address of dns server to use (will be overwritten if dhcp_init is called)
-dhcp_server_default: .res 4 ;will be set address of dhcp server that configuration was obtained from
-cfg_tftp_server_default: .byte $ff,$ff,$ff,$ff ; ip address of server to send tftp requests to (can be a broadcast address)
-cfg_default_drive_default: .byte 8
-cfg_end_defaults:
-cfg_size=cfg_end_defaults-cfg_mac_default+1
-
-
-.bss
-
-cfg_mac: .res 6 ;mac address to be assigned to local machine
-cfg_ip: .res 4 ;ip address of local machine (will be overwritten if dhcp_init is called)
-cfg_netmask: .res 4; netmask of local network (will be overwritten if dhcp_init is called)
-cfg_gateway: .res 4 ;ip address of router on local network (will be overwritten if dhcp_init is called)
-cfg_dns: .res 4; ip address of dns server to use (will be overwritten if dhcp_init is called)
-dhcp_server: .res 4 ;will be set address of dhcp server that configuration was obtained from
-cfg_tftp_server: .res 4 ; ip address of server to send tftp requests to (can be a broadcast address)
-cfg_default_drive: .res 1
-
-
-
-
-;-- LICENSE FOR config.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+;IP configuration defaults
+;most of these will be overwritten if dhcp is used for configuration
+
+.include "../inc/common.i"
+
+.export cfg_mac
+.export cfg_mac_default
+.export cfg_ip
+.export cfg_netmask
+.export cfg_gateway
+.export cfg_dns
+.export cfg_tftp_server
+.export cfg_get_configuration_ptr
+.export cfg_init
+.export cfg_default_drive
+.export cfg_size
+
+.export dhcp_server
+.import copymem
+.importzp copy_src
+.importzp copy_dest
+.code
+
+;return a pointer to where the IP configuration is kept
+;this is really only useful for the NB65 API - for anything
+;linking directly against ip65, you would just import the
+;address of the individual configuration elements, rather
+;than use a base pointer+offsets to find each item.
+;inputs: none
+;outputs: AX = pointer to IP configuration.
+cfg_get_configuration_ptr:
+ ldax #cfg_mac
+ clc
+ rts
+
+;copy the IP stack defaults (probably stored in ROM) to the running values in RAM
+;inputs: none
+;outputs: AX = pointer to IP configuration.
+cfg_init:
+ ldax #cfg_mac_default
+ stax copy_src
+ ldax #cfg_mac
+ stax copy_dest
+ ldax #cfg_size
+ jmp copymem
+
+.segment "IP65_DEFAULTS"
+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)
+;cfg_gateway_default: .byte 0, 0, 0, 0 ;ip address of router on local network (will be overwritten if dhcp_init is called)
+cfg_gateway_default: .byte 192, 168, 1, 1 ;ip address of router on local network (will be overwritten if dhcp_init is called)
+cfg_dns_default: .byte 0, 0, 0, 0; ip address of dns server to use (will be overwritten if dhcp_init is called)
+dhcp_server_default: .res 4 ;will be set address of dhcp server that configuration was obtained from
+cfg_tftp_server_default: .byte $ff,$ff,$ff,$ff ; ip address of server to send tftp requests to (can be a broadcast address)
+cfg_default_drive_default: .byte 8
+cfg_end_defaults:
+cfg_size=cfg_end_defaults-cfg_mac_default+1
+
+
+.bss
+
+cfg_mac: .res 6 ;mac address to be assigned to local machine
+cfg_ip: .res 4 ;ip address of local machine (will be overwritten if dhcp_init is called)
+cfg_netmask: .res 4; netmask of local network (will be overwritten if dhcp_init is called)
+cfg_gateway: .res 4 ;ip address of router on local network (will be overwritten if dhcp_init is called)
+cfg_dns: .res 4; ip address of dns server to use (will be overwritten if dhcp_init is called)
+dhcp_server: .res 4 ;will be set address of dhcp server that configuration was obtained from
+cfg_tftp_server: .res 4 ; ip address of server to send tftp requests to (can be a broadcast address)
+cfg_default_drive: .res 1
+
+
+
+
+;-- LICENSE FOR config.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/copymem.s b/ip65/copymem.s
similarity index 94%
rename from client/ip65/copymem.s
rename to ip65/copymem.s
index 8ef78da..067bee9 100644
--- a/client/ip65/copymem.s
+++ b/ip65/copymem.s
@@ -1,70 +1,70 @@
-; utility routine to copy memory
-
-
- .export copymem
- .importzp copy_src
- .importzp copy_dest
-
-
- .bss
-
-end: .res 1
-
-
- .code
-
-;copy memory
-;inputs:
-; copy_src is address of buffer to copy from
-; copy_dest is address of buffer to copy to
-; AX = number of bytes to copy
-;outputs: none
-copymem:
- sta end
- ldy #0
-
- cpx #0
- beq @tail
-
-: lda (copy_src),y
- sta (copy_dest),y
- iny
- bne :-
- inc copy_src+1 ;next page
- inc copy_dest+1 ;next page
- dex
- bne :-
-
-@tail:
- lda end
- beq @done
-
-: lda (copy_src),y
- sta (copy_dest),y
- iny
- cpy end
- bne :-
-
-@done:
- rts
-
-
-
-;-- LICENSE FOR copymem.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+; utility routine to copy memory
+
+
+ .export copymem
+ .importzp copy_src
+ .importzp copy_dest
+
+
+ .bss
+
+end: .res 1
+
+
+ .code
+
+;copy memory
+;inputs:
+; copy_src is address of buffer to copy from
+; copy_dest is address of buffer to copy to
+; AX = number of bytes to copy
+;outputs: none
+copymem:
+ sta end
+ ldy #0
+
+ cpx #0
+ beq @tail
+
+: lda (copy_src),y
+ sta (copy_dest),y
+ iny
+ bne :-
+ inc copy_src+1 ;next page
+ inc copy_dest+1 ;next page
+ dex
+ bne :-
+
+@tail:
+ lda end
+ beq @done
+
+: lda (copy_src),y
+ sta (copy_dest),y
+ iny
+ cpy end
+ bne :-
+
+@done:
+ rts
+
+
+
+;-- LICENSE FOR copymem.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/debug.s b/ip65/debug.s
similarity index 95%
rename from client/ip65/debug.s
rename to ip65/debug.s
index e77063f..a127934 100644
--- a/client/ip65/debug.s
+++ b/ip65/debug.s
@@ -1,164 +1,164 @@
-;routines for dumping debug information
-
-.include "../inc/common.i"
-.include "../inc/printf.i"
-
-
- .export dbgout16
- .export dbg_dump_eth_header
- .export dbg_dump_ip_header
- .export dbg_dump_udp_header
-
- .export console_out
- .export console_strout
-
-
- .import eth_outp, eth_outp_len
- .import ip_outp
- .import udp_outp
- .importzp copy_src
-
- .code
-
-
-;prints out the header of ethernet packet that is ready to be sent;
-; inputs:
-; eth_outp: pointer to ethernet packet
-; eth_outp_len: length of ethernet packet
-; outputs: none
-dbg_dump_eth_header:
- pha
- txa
- pha
- tya
- pha
-
- printf "\rethernet header:\r"
- printf "len: %04x\r", eth_outp_len
- printf "dest: %04x:%04x:%04x\r", eth_outp, eth_outp + 2, eth_outp + 4
- printf "src: %04x:%04x:%04x\r", eth_outp + 6, eth_outp + 8, eth_outp + 10
- printf "type: %04x\r", eth_outp + 12
-
- pla
- tay
- pla
- tax
- pla
- rts
-
-;prints out the header of ip packet that is ready to be sent;
-; inputs:
-; eth_outp: pointer to ethernet packet containing an ip packet
-; eth_outp_len: length of ethernet packet
-; outputs: none
-dbg_dump_ip_header:
- pha
- txa
- pha
- tya
- pha
-
- printf "\rip header:\r"
- printf "ver,ihl,tos: %04x\r", ip_outp
- printf "len: %04x\r", ip_outp + 2
- printf "id: %04x\r", ip_outp + 4
- printf "frag: %04x\r", ip_outp + 6
- printf "ttl: %02x\r", ip_outp + 8
- printf "proto: %02x\r", ip_outp + 9
- printf "cksum: %04x\r", ip_outp + 10
- printf "src: %04x%04x\r", ip_outp + 12, ip_outp + 14
- printf "dest: %04x%04x\r", ip_outp + 16, ip_outp + 18
-
- pla
- tay
- pla
- tax
- pla
- rts
-
-;prints out the header of udp packet that is ready to be sent;
-; inputs:
-; eth_outp: pointer to ethernet packet containing a udp packet
-; eth_outp_len: length of ethernet packet
-; outputs: none
-dbg_dump_udp_header:
- pha
- txa
- pha
- tya
- pha
-
- printf "\rudp header:\r"
- printf "srcport: %04x\r", ip_outp
- printf "destport: %04x\r", ip_outp + 2
- printf "len: %04x\r", ip_outp + 4
- printf "cksum: %04x\r", ip_outp + 6
-
- pla
- tay
- pla
- tax
- pla
- rts
-
-
-console_out = $ffd2
-
-;print a string to the console
-;inputs: AX = address of (null terminated) string to print
-;outputs: none
-console_strout:
- stax copy_src
-
- pha
- txa
- pha
- tya
- pha
- ldy #0
-: lda (copy_src),y
- beq @done
- jsr console_out
- iny
- bne :-
-@done:
- pla
- tay
- pla
- tax
- pla
- rts
-
-;print a 32 bit number as 4 hex digits
-;inputs: AX = 32 bit number to print
-;outputs: none
-dbgout16:
- stax val16
- printf "%04x", val16
- rts
-
-
- .bss
-
-val16: .res 2
-
-
-
-;-- LICENSE FOR debug.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+;routines for dumping debug information
+
+.include "../inc/common.i"
+.include "../inc/printf.i"
+
+
+ .export dbgout16
+ .export dbg_dump_eth_header
+ .export dbg_dump_ip_header
+ .export dbg_dump_udp_header
+
+ .export console_out
+ .export console_strout
+
+
+ .import eth_outp, eth_outp_len
+ .import ip_outp
+ .import udp_outp
+ .importzp copy_src
+
+ .code
+
+
+;prints out the header of ethernet packet that is ready to be sent;
+; inputs:
+; eth_outp: pointer to ethernet packet
+; eth_outp_len: length of ethernet packet
+; outputs: none
+dbg_dump_eth_header:
+ pha
+ txa
+ pha
+ tya
+ pha
+
+ printf "\rethernet header:\r"
+ printf "len: %04x\r", eth_outp_len
+ printf "dest: %04x:%04x:%04x\r", eth_outp, eth_outp + 2, eth_outp + 4
+ printf "src: %04x:%04x:%04x\r", eth_outp + 6, eth_outp + 8, eth_outp + 10
+ printf "type: %04x\r", eth_outp + 12
+
+ pla
+ tay
+ pla
+ tax
+ pla
+ rts
+
+;prints out the header of ip packet that is ready to be sent;
+; inputs:
+; eth_outp: pointer to ethernet packet containing an ip packet
+; eth_outp_len: length of ethernet packet
+; outputs: none
+dbg_dump_ip_header:
+ pha
+ txa
+ pha
+ tya
+ pha
+
+ printf "\rip header:\r"
+ printf "ver,ihl,tos: %04x\r", ip_outp
+ printf "len: %04x\r", ip_outp + 2
+ printf "id: %04x\r", ip_outp + 4
+ printf "frag: %04x\r", ip_outp + 6
+ printf "ttl: %02x\r", ip_outp + 8
+ printf "proto: %02x\r", ip_outp + 9
+ printf "cksum: %04x\r", ip_outp + 10
+ printf "src: %04x%04x\r", ip_outp + 12, ip_outp + 14
+ printf "dest: %04x%04x\r", ip_outp + 16, ip_outp + 18
+
+ pla
+ tay
+ pla
+ tax
+ pla
+ rts
+
+;prints out the header of udp packet that is ready to be sent;
+; inputs:
+; eth_outp: pointer to ethernet packet containing a udp packet
+; eth_outp_len: length of ethernet packet
+; outputs: none
+dbg_dump_udp_header:
+ pha
+ txa
+ pha
+ tya
+ pha
+
+ printf "\rudp header:\r"
+ printf "srcport: %04x\r", ip_outp
+ printf "destport: %04x\r", ip_outp + 2
+ printf "len: %04x\r", ip_outp + 4
+ printf "cksum: %04x\r", ip_outp + 6
+
+ pla
+ tay
+ pla
+ tax
+ pla
+ rts
+
+
+console_out = $ffd2
+
+;print a string to the console
+;inputs: AX = address of (null terminated) string to print
+;outputs: none
+console_strout:
+ stax copy_src
+
+ pha
+ txa
+ pha
+ tya
+ pha
+ ldy #0
+: lda (copy_src),y
+ beq @done
+ jsr console_out
+ iny
+ bne :-
+@done:
+ pla
+ tay
+ pla
+ tax
+ pla
+ rts
+
+;print a 32 bit number as 4 hex digits
+;inputs: AX = 32 bit number to print
+;outputs: none
+dbgout16:
+ stax val16
+ printf "%04x", val16
+ rts
+
+
+ .bss
+
+val16: .res 2
+
+
+
+;-- LICENSE FOR debug.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/dhcp.s b/ip65/dhcp.s
similarity index 95%
rename from client/ip65/dhcp.s
rename to ip65/dhcp.s
index 3894425..a87d27e 100644
--- a/client/ip65/dhcp.s
+++ b/ip65/dhcp.s
@@ -1,508 +1,508 @@
-; minimal dhcp implementation - ip addresses are requested from a dhcp server
-; (aka 'leased') but are not renewed or released. although this is not correct
-; behaviour according to the DHCP RFC, this works fine in practice in a typical
-; home network environment.
-;
-; cfg_ip,cfg_netmask,cfg_gateway and cfg_dns variables are all overwritten,
-; therefore, these values must be stored in RAM not ROM
-;
-
-MAX_DHCP_MESSAGES_SENT=12 ;timeout after sending 12 messages will be about 15 seconds (1+2+3...)/4
-
- .include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- .export dhcp_init
- .import dhcp_server
- .export dhcp_state
-
- .import ip65_error
- .import cfg_mac
- .import cfg_ip
- .import cfg_netmask
- .import cfg_gateway
- .import cfg_dns
-
- .import arp_calculate_gateway_mask
-
- .import ip65_process
-
- .import udp_add_listener
- .import udp_remove_listener
-
- .import udp_callback
- .import udp_send
-
- .import udp_inp
-
- .importzp udp_data
-
- .import output_buffer
-
- .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
-
- .bss
-
-; dhcp packet offsets
-dhcp_inp = udp_inp + udp_data
-
-dhcp_op = 0
-dhcp_htype = 1
-dhcp_hlen = 2
-dhcp_hops = 3
-dhcp_xid = 4
-dhcp_secs = 8
-dhcp_flags = 10
-dhcp_ciaddr = 12
-dhcp_yiaddr = 16
-dhcp_siaddr = 20
-dhcp_giaddr = 24
-dhcp_chaddr =28
-dhcp_sname = 44
-dhcp_file=108
-dhcp_cookie=236
-dhcp_options=240
-
-dhcp_server_port=67
-dhcp_client_port=68
-
-
-; dhcp state machine
-dhcp_initializing = 1 ; initial state
-dhcp_selecting = 2 ; sent a DHCPDISCOVER, waiting for a DHCPOFFER
-dhcp_ready_to_request = 3 ; got a DHCPOFFER, ready to send a DHCPREQUEST
-dhcp_requesting = 4 ; sent a DHCPREQUEST, waiting for a DHCPACK
-dhcp_bound = 5 ; we have been allocated an IP address
-
-;flag indicating current state of dhcp initialization.
-dhcp_state: .res 1
-
-dhcp_message_sent_count: .res 1
-dhcp_timer: .res 1
-dhcp_loop_count: .res 1
-dhcp_break_polling_loop: .res 1
-
-
-
-;DHCP constants
-BOOTREQUEST =1
-BOOTREPLY =2
-
-DHCPDISCOVER =1
-DHCPOFFER =2
-DHCPREQUEST =3
-DHCPDECLINE =4
-DHCPACK =5
-DHCPNAK =6
-DHCPRELEASE =7
-DHCPINFORM =8
-
-
- .code
-;
-;inputs: none (although ip65_init should be called first)
-;outputs:
-; carry flag clear means IP config has been sucesfully obtained and
-; cfg_ip, cfg_netmask, cfg_gateway and cfg_dns will be set per response from dhcp server.
-; dhcp_server will be set to address of server that provided configuration
-; if carry flag is set there was an error.
-; in either case, dhcp_state will indicate where dhcp initialization ended (to help debug)
-; possible values for dhcp_state are:
-; 1 - initial state
-; 2 - sent a DHCPDISCOVER, waiting for a DHCPOFFER
-; 3 - got a DHCPOFFER, ready to send a DHCPREQUEST
-; 4 - sent a DHCPREQUEST, waiting for a DHCPACK
-; 5 - we have been allocated an IP address
-dhcp_init:
-
- ldx #3 ; rewrite ip address
- lda #0
-: sta cfg_ip,x
- dex
- bpl :-
-
- lda #dhcp_initializing
- sta dhcp_state
-
- ldax #dhcp_in
- stax udp_callback
- ldax #dhcp_client_port
- jsr udp_add_listener
- bcc :+
- rts
-:
- lda #0 ;reset the "message sent" counter
- sta dhcp_message_sent_count
- jsr send_dhcpdiscover
-
-@dhcp_polling_loop:
-
- lda dhcp_message_sent_count
- adc #1
- sta dhcp_loop_count ;we wait a bit longer between each resend
-
-@outer_delay_loop:
- lda #0
- sta dhcp_break_polling_loop
- jsr timer_read
- stx dhcp_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 #0
- cmp dhcp_break_polling_loop
- bne @break_polling_loop
- jsr timer_read
- cpx dhcp_timer ;this will tick over after about 1/4 of a second
- beq @inner_delay_loop
-
- dec dhcp_loop_count
- bne @outer_delay_loop
-
-@break_polling_loop:
-
- inc dhcp_message_sent_count
- lda dhcp_message_sent_count
- cmp #MAX_DHCP_MESSAGES_SENT-1
- bpl @too_many_messages_sent
- lda dhcp_state
- cmp #dhcp_initializing
- beq @initializing
- cmp #dhcp_selecting
- beq @selecting
- cmp #dhcp_ready_to_request
- beq @ready_to_request
- cmp #dhcp_bound
- beq @bound
- jmp @dhcp_polling_loop
-@initializing:
-@selecting:
- jsr send_dhcpdiscover
- jmp @dhcp_polling_loop
-
-@ready_to_request:
- jsr send_dhcprequest
- jmp @dhcp_polling_loop
-
-@bound:
- ldax #dhcp_client_port
- jsr udp_remove_listener
- rts
-
-@too_many_messages_sent:
- lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
- sta ip65_error
- jsr @bound ;to remove the listener ( thanks to ShadowM for bug report)
- sec ;signal an error
- rts
-
-dhcp_create_request_msg:
- lda #BOOTREQUEST
- sta output_buffer+dhcp_op
- lda #1 ;htype 1 = "10 MB ethernet"
- sta output_buffer+dhcp_htype
- lda #6 ;ethernet MACs are 6 bytes
- sta output_buffer+dhcp_hlen
- lda #0 ;hops = 0
- sta output_buffer+dhcp_hops
- ldx #3 ;set xid to be "1234"
- clc
-: txa
- adc #01
- sta output_buffer+dhcp_xid,x
- dex
- bpl :-
-
- lda #0 ;secs =00
- sta output_buffer+dhcp_secs
- sta output_buffer+dhcp_secs+1
- ;initially turn off all flags
- sta output_buffer+dhcp_flags
- sta output_buffer+dhcp_flags+1
-
- ldx #$0F ;set ciaddr to 0.0.0.0
- ;set yiaddr to 0.0.0.0
- ;set siaddr to 0.0.0.0
- ;set giaddr to 0.0.0.0
-: sta output_buffer+dhcp_ciaddr,x
- dex
- bpl :-
-
- ldx #5 ;set chaddr to mac
-: lda cfg_mac,x
- sta output_buffer+dhcp_chaddr,x
- dex
- bpl :-
-
- ldx #192 ;set sname & file both to null
- lda #0
-: sta output_buffer+dhcp_sname-1,x
- dex
- bne :-
-
-
- lda #$63 ;copy the magic cookie
- sta output_buffer+dhcp_cookie+0
- lda #$82
- sta output_buffer+dhcp_cookie+1
- lda #$53
- sta output_buffer+dhcp_cookie+2
- lda #$63
- sta output_buffer+dhcp_cookie+3
-
- ldax #dhcp_client_port ; set source port
- stax udp_send_src_port
-
- ldax #dhcp_server_port ; set destination port
- stax udp_send_dest_port
-
- rts
-
-send_dhcpdiscover:
- lda #dhcp_initializing
- sta dhcp_state
-
- jsr dhcp_create_request_msg
-
- lda #$80 ;broadcast flag =1, all other bits 0
- sta output_buffer+dhcp_flags
-
-
- ldx #dhcp_discover_options_length ; set destination address
-:
- lda dhcp_discover_options,x
- sta output_buffer+dhcp_options,x
- dex
- bpl :-
-
- ldx #3 ; set destination address
- lda #$FF ; des = 255.255.255.255 (broadcast)
-: sta udp_send_dest,x
- dex
- bpl :-
-
- ldax #dhcp_options+dhcp_discover_options_length
- stax udp_send_len
- ldax #output_buffer
- jsr udp_send
- bcc :+
- rts
-
-: lda #dhcp_selecting
- sta dhcp_state
- rts
-
-dhcp_discover_options:
-.byte 53 ;option 53 - DHCP message type
-.byte 1 ;option length =1
-.byte DHCPDISCOVER ; message type
-.byte 55 ; option 55 - Parameter Request List
-.byte 3 ;option length
-.byte 1 ; subnet mask
-.byte 3 ; router (gateway)
-.byte 6 ; DNS server
-.byte $FF ; end of options
-
-dhcp_discover_options_length=*-dhcp_discover_options
-
-;got a message on port 68
-dhcp_in:
-
- lda dhcp_inp+dhcp_op
- cmp #BOOTREPLY
- beq :+
- rts ;it's not what we were expecting
-:
-
- lda #0
- cmp dhcp_inp+dhcp_yiaddr ;is the first byte in the assigned address 0?
- bne :+
- rts ;if so, it's a bogus response - ignore
-:
- ldx #4 ;copy the our new IP address
-:
- lda dhcp_inp+dhcp_yiaddr,x
- sta cfg_ip,x
- dex
- bpl :-
-
- ldx #0
-@unpack_dhcp_options:
- lda dhcp_inp+dhcp_options,x
- cmp #$ff
- bne :+
- jmp @finished_unpacking_dhcp_options
-:
- cmp #53 ;is this field DHCP message type?
- bne @not_dhcp_message_type
- jmp @get_next_option
- lda dhcp_inp+dhcp_options+2,x
- cmp #DHCPOFFER ;if it's not a DHCP OFFER message, then stop processing
- beq :+
- rts
-: jmp @get_next_option
-
-@not_dhcp_message_type:
-
- cmp #1 ;option 1 is netmask
- bne @not_netmask
- lda dhcp_inp+dhcp_options+2,x
- sta cfg_netmask
- lda dhcp_inp+dhcp_options+3,x
- sta cfg_netmask+1
- lda dhcp_inp+dhcp_options+4,x
- sta cfg_netmask+2
- lda dhcp_inp+dhcp_options+5,x
- sta cfg_netmask+3
- jmp @get_next_option
-
-@not_netmask:
-
- cmp #3 ;option 3 is gateway
- bne @not_gateway
- lda dhcp_inp+dhcp_options+2,x
- sta cfg_gateway
- lda dhcp_inp+dhcp_options+3,x
- sta cfg_gateway+1
- lda dhcp_inp+dhcp_options+4,x
- sta cfg_gateway+2
- lda dhcp_inp+dhcp_options+5,x
- sta cfg_gateway+3
- jmp @get_next_option
-
-@not_gateway:
-
- cmp #6 ;option 6 is dns server
- bne @not_dns_server
- lda dhcp_inp+dhcp_options+2,x
- sta cfg_dns
- lda dhcp_inp+dhcp_options+3,x
- sta cfg_dns+1
- lda dhcp_inp+dhcp_options+4,x
- sta cfg_dns+2
- lda dhcp_inp+dhcp_options+5,x
- sta cfg_dns+3
- jmp @get_next_option
-
-@not_dns_server:
-
- cmp #54 ;option 54 is DHCP server
- bne @not_server
- lda dhcp_inp+dhcp_options+2,x
- sta dhcp_server
- lda dhcp_inp+dhcp_options+3,x
- sta dhcp_server+1
- lda dhcp_inp+dhcp_options+4,x
- sta dhcp_server+2
- lda dhcp_inp+dhcp_options+5,x
- sta dhcp_server+3
- jmp @get_next_option
-
-@not_server:
-
-
-@get_next_option:
- txa
- clc
- adc #02
- adc dhcp_inp+dhcp_options+1,x
- bcs @finished_unpacking_dhcp_options ; if we overflow, then we're done
- tax
- jmp @unpack_dhcp_options
-
-
-@finished_unpacking_dhcp_options:
- jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test
- lda dhcp_state
- cmp #dhcp_bound
- beq :+
- lda #dhcp_ready_to_request
- sta dhcp_state
-:
- lda #1
- sta dhcp_break_polling_loop
-
- rts
-
-send_dhcprequest:
- jsr dhcp_create_request_msg
- lda #53 ;option 53 - DHCP message type
- sta output_buffer+dhcp_options+0
- lda #1 ;option length is 1
- sta output_buffer+dhcp_options+1
- lda #DHCPREQUEST
- sta output_buffer+dhcp_options+2
-
- lda #50 ;option 50 - requested IP address
- sta output_buffer+dhcp_options+3
- ldx #4 ;option length is 4
- stx output_buffer+dhcp_options+4
- dex
-: lda cfg_ip,x
- sta output_buffer+dhcp_options+5,x
- dex
- bpl :-
-
- lda #54 ;option 54 - DHCP server
- sta output_buffer+dhcp_options+9
- ldx #4 ;option length is 4
- stx output_buffer+dhcp_options+10
- dex
-
-: lda dhcp_server,x
- sta output_buffer+dhcp_options+11,x
- lda #$ff ;bugfix by ShadowM - DHCP request should be broadcast
- sta udp_send_dest,x
- dex
- bpl :-
-
- ;A still = option FF = end of options
-
- sta output_buffer+dhcp_options+15
-
- ldax #dhcp_options+16
- stax udp_send_len
-
- ldax #output_buffer
- jsr udp_send
- bcs :+ ;if we didn't send the message we probably need to wait for an ARP reply to come back.
- lda #dhcp_bound ;technically, we should wait till we get a DHCPACK message. but we'll assume success
- sta dhcp_state
- rts
-:
- rts
-
-
-
-;-- LICENSE FOR dhcp.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 --
+; minimal dhcp implementation - ip addresses are requested from a dhcp server
+; (aka 'leased') but are not renewed or released. although this is not correct
+; behaviour according to the DHCP RFC, this works fine in practice in a typical
+; home network environment.
+;
+; cfg_ip,cfg_netmask,cfg_gateway and cfg_dns variables are all overwritten,
+; therefore, these values must be stored in RAM not ROM
+;
+
+MAX_DHCP_MESSAGES_SENT=12 ;timeout after sending 12 messages will be about 15 seconds (1+2+3...)/4
+
+ .include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+ .export dhcp_init
+ .import dhcp_server
+ .export dhcp_state
+
+ .import ip65_error
+ .import cfg_mac
+ .import cfg_ip
+ .import cfg_netmask
+ .import cfg_gateway
+ .import cfg_dns
+
+ .import arp_calculate_gateway_mask
+
+ .import ip65_process
+
+ .import udp_add_listener
+ .import udp_remove_listener
+
+ .import udp_callback
+ .import udp_send
+
+ .import udp_inp
+
+ .importzp udp_data
+
+ .import output_buffer
+
+ .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
+
+ .bss
+
+; dhcp packet offsets
+dhcp_inp = udp_inp + udp_data
+
+dhcp_op = 0
+dhcp_htype = 1
+dhcp_hlen = 2
+dhcp_hops = 3
+dhcp_xid = 4
+dhcp_secs = 8
+dhcp_flags = 10
+dhcp_ciaddr = 12
+dhcp_yiaddr = 16
+dhcp_siaddr = 20
+dhcp_giaddr = 24
+dhcp_chaddr =28
+dhcp_sname = 44
+dhcp_file=108
+dhcp_cookie=236
+dhcp_options=240
+
+dhcp_server_port=67
+dhcp_client_port=68
+
+
+; dhcp state machine
+dhcp_initializing = 1 ; initial state
+dhcp_selecting = 2 ; sent a DHCPDISCOVER, waiting for a DHCPOFFER
+dhcp_ready_to_request = 3 ; got a DHCPOFFER, ready to send a DHCPREQUEST
+dhcp_requesting = 4 ; sent a DHCPREQUEST, waiting for a DHCPACK
+dhcp_bound = 5 ; we have been allocated an IP address
+
+;flag indicating current state of dhcp initialization.
+dhcp_state: .res 1
+
+dhcp_message_sent_count: .res 1
+dhcp_timer: .res 1
+dhcp_loop_count: .res 1
+dhcp_break_polling_loop: .res 1
+
+
+
+;DHCP constants
+BOOTREQUEST =1
+BOOTREPLY =2
+
+DHCPDISCOVER =1
+DHCPOFFER =2
+DHCPREQUEST =3
+DHCPDECLINE =4
+DHCPACK =5
+DHCPNAK =6
+DHCPRELEASE =7
+DHCPINFORM =8
+
+
+ .code
+;
+;inputs: none (although ip65_init should be called first)
+;outputs:
+; carry flag clear means IP config has been sucesfully obtained and
+; cfg_ip, cfg_netmask, cfg_gateway and cfg_dns will be set per response from dhcp server.
+; dhcp_server will be set to address of server that provided configuration
+; if carry flag is set there was an error.
+; in either case, dhcp_state will indicate where dhcp initialization ended (to help debug)
+; possible values for dhcp_state are:
+; 1 - initial state
+; 2 - sent a DHCPDISCOVER, waiting for a DHCPOFFER
+; 3 - got a DHCPOFFER, ready to send a DHCPREQUEST
+; 4 - sent a DHCPREQUEST, waiting for a DHCPACK
+; 5 - we have been allocated an IP address
+dhcp_init:
+
+ ldx #3 ; rewrite ip address
+ lda #0
+: sta cfg_ip,x
+ dex
+ bpl :-
+
+ lda #dhcp_initializing
+ sta dhcp_state
+
+ ldax #dhcp_in
+ stax udp_callback
+ ldax #dhcp_client_port
+ jsr udp_add_listener
+ bcc :+
+ rts
+:
+ lda #0 ;reset the "message sent" counter
+ sta dhcp_message_sent_count
+ jsr send_dhcpdiscover
+
+@dhcp_polling_loop:
+
+ lda dhcp_message_sent_count
+ adc #1
+ sta dhcp_loop_count ;we wait a bit longer between each resend
+
+@outer_delay_loop:
+ lda #0
+ sta dhcp_break_polling_loop
+ jsr timer_read
+ stx dhcp_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 #0
+ cmp dhcp_break_polling_loop
+ bne @break_polling_loop
+ jsr timer_read
+ cpx dhcp_timer ;this will tick over after about 1/4 of a second
+ beq @inner_delay_loop
+
+ dec dhcp_loop_count
+ bne @outer_delay_loop
+
+@break_polling_loop:
+
+ inc dhcp_message_sent_count
+ lda dhcp_message_sent_count
+ cmp #MAX_DHCP_MESSAGES_SENT-1
+ bpl @too_many_messages_sent
+ lda dhcp_state
+ cmp #dhcp_initializing
+ beq @initializing
+ cmp #dhcp_selecting
+ beq @selecting
+ cmp #dhcp_ready_to_request
+ beq @ready_to_request
+ cmp #dhcp_bound
+ beq @bound
+ jmp @dhcp_polling_loop
+@initializing:
+@selecting:
+ jsr send_dhcpdiscover
+ jmp @dhcp_polling_loop
+
+@ready_to_request:
+ jsr send_dhcprequest
+ jmp @dhcp_polling_loop
+
+@bound:
+ ldax #dhcp_client_port
+ jsr udp_remove_listener
+ rts
+
+@too_many_messages_sent:
+ lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
+ sta ip65_error
+ jsr @bound ;to remove the listener ( thanks to ShadowM for bug report)
+ sec ;signal an error
+ rts
+
+dhcp_create_request_msg:
+ lda #BOOTREQUEST
+ sta output_buffer+dhcp_op
+ lda #1 ;htype 1 = "10 MB ethernet"
+ sta output_buffer+dhcp_htype
+ lda #6 ;ethernet MACs are 6 bytes
+ sta output_buffer+dhcp_hlen
+ lda #0 ;hops = 0
+ sta output_buffer+dhcp_hops
+ ldx #3 ;set xid to be "1234"
+ clc
+: txa
+ adc #01
+ sta output_buffer+dhcp_xid,x
+ dex
+ bpl :-
+
+ lda #0 ;secs =00
+ sta output_buffer+dhcp_secs
+ sta output_buffer+dhcp_secs+1
+ ;initially turn off all flags
+ sta output_buffer+dhcp_flags
+ sta output_buffer+dhcp_flags+1
+
+ ldx #$0F ;set ciaddr to 0.0.0.0
+ ;set yiaddr to 0.0.0.0
+ ;set siaddr to 0.0.0.0
+ ;set giaddr to 0.0.0.0
+: sta output_buffer+dhcp_ciaddr,x
+ dex
+ bpl :-
+
+ ldx #5 ;set chaddr to mac
+: lda cfg_mac,x
+ sta output_buffer+dhcp_chaddr,x
+ dex
+ bpl :-
+
+ ldx #192 ;set sname & file both to null
+ lda #0
+: sta output_buffer+dhcp_sname-1,x
+ dex
+ bne :-
+
+
+ lda #$63 ;copy the magic cookie
+ sta output_buffer+dhcp_cookie+0
+ lda #$82
+ sta output_buffer+dhcp_cookie+1
+ lda #$53
+ sta output_buffer+dhcp_cookie+2
+ lda #$63
+ sta output_buffer+dhcp_cookie+3
+
+ ldax #dhcp_client_port ; set source port
+ stax udp_send_src_port
+
+ ldax #dhcp_server_port ; set destination port
+ stax udp_send_dest_port
+
+ rts
+
+send_dhcpdiscover:
+ lda #dhcp_initializing
+ sta dhcp_state
+
+ jsr dhcp_create_request_msg
+
+ lda #$80 ;broadcast flag =1, all other bits 0
+ sta output_buffer+dhcp_flags
+
+
+ ldx #dhcp_discover_options_length ; set destination address
+:
+ lda dhcp_discover_options,x
+ sta output_buffer+dhcp_options,x
+ dex
+ bpl :-
+
+ ldx #3 ; set destination address
+ lda #$FF ; des = 255.255.255.255 (broadcast)
+: sta udp_send_dest,x
+ dex
+ bpl :-
+
+ ldax #dhcp_options+dhcp_discover_options_length
+ stax udp_send_len
+ ldax #output_buffer
+ jsr udp_send
+ bcc :+
+ rts
+
+: lda #dhcp_selecting
+ sta dhcp_state
+ rts
+
+dhcp_discover_options:
+.byte 53 ;option 53 - DHCP message type
+.byte 1 ;option length =1
+.byte DHCPDISCOVER ; message type
+.byte 55 ; option 55 - Parameter Request List
+.byte 3 ;option length
+.byte 1 ; subnet mask
+.byte 3 ; router (gateway)
+.byte 6 ; DNS server
+.byte $FF ; end of options
+
+dhcp_discover_options_length=*-dhcp_discover_options
+
+;got a message on port 68
+dhcp_in:
+
+ lda dhcp_inp+dhcp_op
+ cmp #BOOTREPLY
+ beq :+
+ rts ;it's not what we were expecting
+:
+
+ lda #0
+ cmp dhcp_inp+dhcp_yiaddr ;is the first byte in the assigned address 0?
+ bne :+
+ rts ;if so, it's a bogus response - ignore
+:
+ ldx #4 ;copy the our new IP address
+:
+ lda dhcp_inp+dhcp_yiaddr,x
+ sta cfg_ip,x
+ dex
+ bpl :-
+
+ ldx #0
+@unpack_dhcp_options:
+ lda dhcp_inp+dhcp_options,x
+ cmp #$ff
+ bne :+
+ jmp @finished_unpacking_dhcp_options
+:
+ cmp #53 ;is this field DHCP message type?
+ bne @not_dhcp_message_type
+ jmp @get_next_option
+ lda dhcp_inp+dhcp_options+2,x
+ cmp #DHCPOFFER ;if it's not a DHCP OFFER message, then stop processing
+ beq :+
+ rts
+: jmp @get_next_option
+
+@not_dhcp_message_type:
+
+ cmp #1 ;option 1 is netmask
+ bne @not_netmask
+ lda dhcp_inp+dhcp_options+2,x
+ sta cfg_netmask
+ lda dhcp_inp+dhcp_options+3,x
+ sta cfg_netmask+1
+ lda dhcp_inp+dhcp_options+4,x
+ sta cfg_netmask+2
+ lda dhcp_inp+dhcp_options+5,x
+ sta cfg_netmask+3
+ jmp @get_next_option
+
+@not_netmask:
+
+ cmp #3 ;option 3 is gateway
+ bne @not_gateway
+ lda dhcp_inp+dhcp_options+2,x
+ sta cfg_gateway
+ lda dhcp_inp+dhcp_options+3,x
+ sta cfg_gateway+1
+ lda dhcp_inp+dhcp_options+4,x
+ sta cfg_gateway+2
+ lda dhcp_inp+dhcp_options+5,x
+ sta cfg_gateway+3
+ jmp @get_next_option
+
+@not_gateway:
+
+ cmp #6 ;option 6 is dns server
+ bne @not_dns_server
+ lda dhcp_inp+dhcp_options+2,x
+ sta cfg_dns
+ lda dhcp_inp+dhcp_options+3,x
+ sta cfg_dns+1
+ lda dhcp_inp+dhcp_options+4,x
+ sta cfg_dns+2
+ lda dhcp_inp+dhcp_options+5,x
+ sta cfg_dns+3
+ jmp @get_next_option
+
+@not_dns_server:
+
+ cmp #54 ;option 54 is DHCP server
+ bne @not_server
+ lda dhcp_inp+dhcp_options+2,x
+ sta dhcp_server
+ lda dhcp_inp+dhcp_options+3,x
+ sta dhcp_server+1
+ lda dhcp_inp+dhcp_options+4,x
+ sta dhcp_server+2
+ lda dhcp_inp+dhcp_options+5,x
+ sta dhcp_server+3
+ jmp @get_next_option
+
+@not_server:
+
+
+@get_next_option:
+ txa
+ clc
+ adc #02
+ adc dhcp_inp+dhcp_options+1,x
+ bcs @finished_unpacking_dhcp_options ; if we overflow, then we're done
+ tax
+ jmp @unpack_dhcp_options
+
+
+@finished_unpacking_dhcp_options:
+ jsr arp_calculate_gateway_mask ;we have modified our netmask, so we need to recalculate gw_test
+ lda dhcp_state
+ cmp #dhcp_bound
+ beq :+
+ lda #dhcp_ready_to_request
+ sta dhcp_state
+:
+ lda #1
+ sta dhcp_break_polling_loop
+
+ rts
+
+send_dhcprequest:
+ jsr dhcp_create_request_msg
+ lda #53 ;option 53 - DHCP message type
+ sta output_buffer+dhcp_options+0
+ lda #1 ;option length is 1
+ sta output_buffer+dhcp_options+1
+ lda #DHCPREQUEST
+ sta output_buffer+dhcp_options+2
+
+ lda #50 ;option 50 - requested IP address
+ sta output_buffer+dhcp_options+3
+ ldx #4 ;option length is 4
+ stx output_buffer+dhcp_options+4
+ dex
+: lda cfg_ip,x
+ sta output_buffer+dhcp_options+5,x
+ dex
+ bpl :-
+
+ lda #54 ;option 54 - DHCP server
+ sta output_buffer+dhcp_options+9
+ ldx #4 ;option length is 4
+ stx output_buffer+dhcp_options+10
+ dex
+
+: lda dhcp_server,x
+ sta output_buffer+dhcp_options+11,x
+ lda #$ff ;bugfix by ShadowM - DHCP request should be broadcast
+ sta udp_send_dest,x
+ dex
+ bpl :-
+
+ ;A still = option FF = end of options
+
+ sta output_buffer+dhcp_options+15
+
+ ldax #dhcp_options+16
+ stax udp_send_len
+
+ ldax #output_buffer
+ jsr udp_send
+ bcs :+ ;if we didn't send the message we probably need to wait for an ARP reply to come back.
+ lda #dhcp_bound ;technically, we should wait till we get a DHCPACK message. but we'll assume success
+ sta dhcp_state
+ rts
+:
+ rts
+
+
+
+;-- LICENSE FOR dhcp.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/ip65/dns.s b/ip65/dns.s
similarity index 96%
rename from client/ip65/dns.s
rename to ip65/dns.s
index 396b02b..5eb92f4 100644
--- a/client/ip65/dns.s
+++ b/ip65/dns.s
@@ -1,484 +1,484 @@
-; minimal dns implementation - requires a DNS server that supports recursion
-
- MAX_DNS_MESSAGES_SENT=8 ;timeout after sending 8 messages will be about 7 seconds (1+2+3+4+5+6+7+8)/4
-
-.include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- .export dns_set_hostname
- .export dns_resolve
- .export dns_ip
- .export dns_status
- .import ip65_error
- .import cfg_dns
-
- .import parse_dotted_quad
- .import dotted_quad_value
-
- .import ip65_process
-
- .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
-
- .importzp dns_hostname
-
-
- .bss
-
-; dns packet offsets
-dns_inp = udp_inp + udp_data
-dns_id = 0
-dns_flags=2
-dns_qdcount=4
-dns_ancount=6
-dns_nscount=8
-dns_arcount=10
-dns_qname=12
-
-dns_server_port=53
-dns_client_port_low_byte: .res 1
-
-dns_ip: .res 4 ;will be contain ip address of hostname after succesful exection of dns_resolve
-
-dns_msg_id: .res 2
-
-dns_current_label_length: .res 1
-dns_current_label_offset: .res 1
-
-dns_message_sent_count: .res 1
-
-dns_packed_hostname: .res 128
-
-; dns state machine
-dns_initializing = 1 ; initial state
-dns_query_sent = 2 ; sent a query, waiting for a response
-dns_complete = 3 ; got a good response
-dns_failed = 4 ; got either a 'no such name' or 'recursion declined' response
-
-dns_state: .res 1 ; flag indicating the current stage in the dns resolution process
-dns_timer: .res 1
-dns_loop_count: .res 1
-dns_break_polling_loop: .res 1
-
-dns_status: .res 2 ; for debugging purposes only (behaviour not garuanteed)
-
-hostname_copied: .res 1
-
-questions_in_response: .res 1
-
-hostname_was_dotted_quad: .res 1
-
- .code
-
-; sets up for resolution of a hostname to an ip address
-; inputs:
-; AX = pointer to null terminated string that contains either a dns hostname
-; (e.g. "host.example.com",0) or an address in "dotted quad" format,
-; (e.g. "192.168.1.0",0)
-; outputs:
-; carry flag is set on error (i.e. hostname too long), clear otherwise
-dns_set_hostname:
- stax dns_hostname
- ;copy the hostname into a buffer suitable to copy directly into the qname field
- ;we need to split on dots
-
- jsr parse_dotted_quad ; if we are passed an IP address instead of a hostname, don't bother looking it up in dns
- bcs @wasnt_dotted_quad
- ;if the string was a dotted quad, then copy the parsed 4 bytes in to dns_ip
- lda #1
- sta hostname_was_dotted_quad
- ldx #3 ; set destination address
-: lda dotted_quad_value,x
- sta dns_ip,x
- dex
- bpl :-
-
- rts ;done!
-
-@wasnt_dotted_quad:
-
-
- ldy #0 ;input pointer
- ldx #1 ;output pointer (start at 1, to skip first length offset, which will be filled in later)
-
- sty hostname_was_dotted_quad
- sty dns_current_label_length
- sty dns_current_label_offset
- sty hostname_copied
-
-@next_hostname_byte:
- lda (dns_hostname),y ;get next char in hostname
- beq @end_of_hostname
- cmp #'/' ; allow hostnames to be terminated by "/" or ":" to help with URL parsing
- beq @end_of_hostname
- cmp #':'
- bne :+
-@end_of_hostname:
- inc hostname_copied
- bne @set_length_of_last_label
-:
-
- cmp #'.' ;do we need to split the labels?
- bne @not_a_dot
-@set_length_of_last_label:
- txa
- pha
- lda dns_current_label_length
- ldx dns_current_label_offset
- sta dns_packed_hostname,x
- lda #0
- sta dns_current_label_length
- pla
- tax
- stx dns_current_label_offset
- lda hostname_copied
- beq @update_counters
- jmp @hostname_done
-@not_a_dot:
- sta dns_packed_hostname,x
- inc dns_current_label_length
-
-@update_counters:
- iny
- inx
- bmi @hostname_too_long ;don't allow a hostname of more than 128 bytes
- jmp @next_hostname_byte
-
-@hostname_done:
-
- lda dns_packed_hostname-1,x ;get the last byte we wrote out
- beq :+ ;was it a zero?
- lda #0
- sta dns_packed_hostname,x ;write a trailing zero (i.e. a zero length label)
- inx
-:
- clc ;no error
-
- rts
-
-@hostname_too_long:
- lda #KPR_ERROR_INPUT_TOO_LARGE
- sta ip65_error
- sec
- rts
-
-; resolve a string containing a hostname (or a dotted quad) to an ip address
-; inputs:
-; cfg_dns must point to a DNS server that supports recursion
-; dns_set_hostname must have been called to load the string to be resolved
-; outputs:
-; carry flag is set if there was an error, clear otherwise
-; dns_ip: set to the ip address of the hostname (if no error)
-dns_resolve:
- lda hostname_was_dotted_quad
- beq @hostname_not_dotted_quad
- clc
- rts ;we already set dns_ip when copying the hostname
-@hostname_not_dotted_quad:
- ldax #dns_in
- stax udp_callback
- lda #53
- inc dns_client_port_low_byte ;each call to resolve uses a different client address
- ldx dns_client_port_low_byte ;so we don't get confused by late replies to a previous call
- jsr udp_add_listener
-
- bcc :+
- rts
-:
-
- lda #dns_initializing
- sta dns_state
- lda #0 ;reset the "message sent" counter
- sta dns_message_sent_count
-
- jsr send_dns_query
-
-@dns_polling_loop:
- lda dns_message_sent_count
- adc #1
- sta dns_loop_count ;we wait a bit longer between each resend
-@outer_delay_loop:
- lda #0
- sta dns_break_polling_loop
- jsr timer_read
- stx dns_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 dns_state
- cmp #dns_complete
- beq @complete
- cmp #dns_failed
- beq @failed
-
- lda #0
- cmp dns_break_polling_loop
- bne @break_polling_loop
- jsr timer_read
- cpx dns_timer ;this will tick over after about 1/4 of a second
- beq @inner_delay_loop
-
- dec dns_loop_count
- bne @outer_delay_loop
-
-@break_polling_loop:
- jsr send_dns_query
- inc dns_message_sent_count
- lda dns_message_sent_count
- cmp #MAX_DNS_MESSAGES_SENT-1
- bpl @too_many_messages_sent
- jmp @dns_polling_loop
-
-@complete:
-
- lda #53
- ldx dns_client_port_low_byte
- jsr udp_remove_listener
- rts
-
-@too_many_messages_sent:
-@failed:
- lda #53
- ldx dns_client_port_low_byte
- jsr udp_remove_listener
- lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
- sta ip65_error
- sec ;signal an error
- rts
-
-send_dns_query:
- ldax dns_msg_id
- inx
- adc #0
- stax dns_msg_id
- stax output_buffer+dns_id
-
- ldax #$0001 ;QR =0 (query), opcode=0 (query), AA=0, TC=0,RD=1,RA=0,Z=0,RCODE=0
- stax output_buffer+dns_flags
- ldax #$0100 ;we ask 1 question
- stax output_buffer+dns_qdcount
- ldax #$0000
- stax output_buffer+dns_ancount ;we send no answers
- stax output_buffer+dns_nscount ;we send no name servers
- stax output_buffer+dns_arcount ;we send no authorative records
-
- ldx #0
-:
- lda dns_packed_hostname,x
- sta output_buffer+dns_qname,x
- inx
- bpl @hostname_still_ok
- lda #KPR_ERROR_INPUT_TOO_LARGE
- sta ip65_error
- jmp @error_on_send ;if we got past 128 bytes, there's a problem
-@hostname_still_ok:
- cmp #0
- bne :- ;keep looping until we have a zero byte.
-
- lda #0
- sta output_buffer+dns_qname,x ;high byte of QTYPE=1 (A)
- sta output_buffer+dns_qname+2,x ;high byte of QLASS=1 (IN)
- lda #1
- sta output_buffer+dns_qname+1,x ;low byte of QTYPE=1 (A)
- sta output_buffer+dns_qname+3,x ;low byte of QLASS=1 (IN)
-
- txa
- clc
- adc #(dns_qname+4)
- ldx #0
- stax udp_send_len
-
- lda #53
- ldx dns_client_port_low_byte
- stax udp_send_src_port
-
- ldx #3 ; set destination address
-: lda cfg_dns,x
- sta udp_send_dest,x
- dex
- bpl :-
-
- ldax #dns_server_port ; set destination port
- stax udp_send_dest_port
- ldax #output_buffer
- jsr udp_send
- bcs @error_on_send
- lda #dns_query_sent
- sta dns_state
-
- rts
-@error_on_send:
- sec
- rts
-
-dns_in:
- lda dns_inp+dns_flags+1 ;
- and #$0f ;get the RCODE
- cmp #0
- beq @not_an_error_response
-
- sta dns_status ;anything non-zero is a permanent error (invalid domain, server doesn't support recursion etc)
- sta dns_status+1
- lda #dns_failed
- sta dns_state
- rts
-@not_an_error_response:
- lda dns_inp+dns_qdcount+1
- sta questions_in_response
- cmp #1 ;should be exactly 1 Q in the response (i.e. the one we sent)
- beq :+
- jmp @error_in_response
-:
- lda dns_inp+dns_ancount+1
- bne :+
- jmp @error_in_response ;should be at least 1 answer in response
-: ;we need to skip over the question (we will assume it's the question we just asked)
- ldx #dns_qname
-:
- lda dns_inp,x ;get next length byte in question
- beq :+ ; we're done if length==0
- clc
- txa
-
- adc dns_inp,x ;add length of next label to ptr
- adc #1 ;+1 for the length byte itself
- tax
- bcs @error_in_response ;if we overflowed x, then message is too big
- bcc :-
-:
- inx ;skip past the nul byte
- lda dns_inp+1,x
- cmp #1 ;QTYPE should 1
- lda dns_inp+3,x
- cmp #1 ;QCLASS should 1
- bne @error_in_response
-
- inx ;skip past the QTYPE/QCLASS
- inx
- inx
- inx
-
- ;x now points to the start of the answers
-
- lda dns_inp,x
- bpl @error_in_response ;we are expecting the high bit to be set (we assume the server will send us back the answer to the question we just asked)
- inx ;skip past the compression
- inx
- ;we are now pointing at the TYPE field
- lda dns_inp+1,x ;
-
- cmp #5 ; is this a CNAME?
- bne @not_a_cname
-
-
- txa
- clc
- adc #10 ;skip 2 bytes TYPE, 2 bytes CLASS, 4 bytes TTL, 2 bytes RDLENGTH
- tax
- ;we're now pointing at the CNAME record
- ldy #0 ;start of CNAME hostname
-:
- lda dns_inp,x
- beq @last_byte_of_cname
- bmi @found_compression_marker
- sta dns_packed_hostname,y
- inx
- iny
- bmi @error_in_response ;if we go past 128 bytes, something is wrong
- bpl :- ;go get next byte
- @last_byte_of_cname:
- sta dns_packed_hostname,y
-
- lda #$ff ;set a status marker so we know whats going on
- sta dns_status
- stx dns_status+1
-
- lda #1
- sta dns_break_polling_loop
-
- rts ; finished processing - the main dns polling loop should now resend a query, this time for the hostname from the CNAME record
-
-@found_compression_marker:
- lda dns_inp+1,x
- tax
- jmp :-
-
-@not_a_cname:
- cmp #1 ; should be 1 (A record)
- bne @error_in_response
- txa
- clc
- adc #10 ;skip 2 bytes TYPE, 2 bytes CLASS, 4 bytes TTL, 2 bytes RDLENGTH
- tax
- ;we're now pointing at the answer!
- lda dns_inp,x
- sta dns_ip
-
- lda dns_inp+1,x
- sta dns_ip+1
-
- lda dns_inp+2,x
- sta dns_ip+2
-
- lda dns_inp+3,x
- sta dns_ip+3
-
-
- lda #dns_complete
- sta dns_state
-
- lda #1
- sta dns_break_polling_loop
-
-@error_in_response:
-
- sta dns_status
- stx dns_status+1
- rts
-
-
-
-
-
-;-- LICENSE FOR dns.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 --
+; minimal dns implementation - requires a DNS server that supports recursion
+
+ MAX_DNS_MESSAGES_SENT=8 ;timeout after sending 8 messages will be about 7 seconds (1+2+3+4+5+6+7+8)/4
+
+.include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+ .export dns_set_hostname
+ .export dns_resolve
+ .export dns_ip
+ .export dns_status
+ .import ip65_error
+ .import cfg_dns
+
+ .import parse_dotted_quad
+ .import dotted_quad_value
+
+ .import ip65_process
+
+ .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
+
+ .importzp dns_hostname
+
+
+ .bss
+
+; dns packet offsets
+dns_inp = udp_inp + udp_data
+dns_id = 0
+dns_flags=2
+dns_qdcount=4
+dns_ancount=6
+dns_nscount=8
+dns_arcount=10
+dns_qname=12
+
+dns_server_port=53
+dns_client_port_low_byte: .res 1
+
+dns_ip: .res 4 ;will be contain ip address of hostname after succesful exection of dns_resolve
+
+dns_msg_id: .res 2
+
+dns_current_label_length: .res 1
+dns_current_label_offset: .res 1
+
+dns_message_sent_count: .res 1
+
+dns_packed_hostname: .res 128
+
+; dns state machine
+dns_initializing = 1 ; initial state
+dns_query_sent = 2 ; sent a query, waiting for a response
+dns_complete = 3 ; got a good response
+dns_failed = 4 ; got either a 'no such name' or 'recursion declined' response
+
+dns_state: .res 1 ; flag indicating the current stage in the dns resolution process
+dns_timer: .res 1
+dns_loop_count: .res 1
+dns_break_polling_loop: .res 1
+
+dns_status: .res 2 ; for debugging purposes only (behaviour not garuanteed)
+
+hostname_copied: .res 1
+
+questions_in_response: .res 1
+
+hostname_was_dotted_quad: .res 1
+
+ .code
+
+; sets up for resolution of a hostname to an ip address
+; inputs:
+; AX = pointer to null terminated string that contains either a dns hostname
+; (e.g. "host.example.com",0) or an address in "dotted quad" format,
+; (e.g. "192.168.1.0",0)
+; outputs:
+; carry flag is set on error (i.e. hostname too long), clear otherwise
+dns_set_hostname:
+ stax dns_hostname
+ ;copy the hostname into a buffer suitable to copy directly into the qname field
+ ;we need to split on dots
+
+ jsr parse_dotted_quad ; if we are passed an IP address instead of a hostname, don't bother looking it up in dns
+ bcs @wasnt_dotted_quad
+ ;if the string was a dotted quad, then copy the parsed 4 bytes in to dns_ip
+ lda #1
+ sta hostname_was_dotted_quad
+ ldx #3 ; set destination address
+: lda dotted_quad_value,x
+ sta dns_ip,x
+ dex
+ bpl :-
+
+ rts ;done!
+
+@wasnt_dotted_quad:
+
+
+ ldy #0 ;input pointer
+ ldx #1 ;output pointer (start at 1, to skip first length offset, which will be filled in later)
+
+ sty hostname_was_dotted_quad
+ sty dns_current_label_length
+ sty dns_current_label_offset
+ sty hostname_copied
+
+@next_hostname_byte:
+ lda (dns_hostname),y ;get next char in hostname
+ beq @end_of_hostname
+ cmp #'/' ; allow hostnames to be terminated by "/" or ":" to help with URL parsing
+ beq @end_of_hostname
+ cmp #':'
+ bne :+
+@end_of_hostname:
+ inc hostname_copied
+ bne @set_length_of_last_label
+:
+
+ cmp #'.' ;do we need to split the labels?
+ bne @not_a_dot
+@set_length_of_last_label:
+ txa
+ pha
+ lda dns_current_label_length
+ ldx dns_current_label_offset
+ sta dns_packed_hostname,x
+ lda #0
+ sta dns_current_label_length
+ pla
+ tax
+ stx dns_current_label_offset
+ lda hostname_copied
+ beq @update_counters
+ jmp @hostname_done
+@not_a_dot:
+ sta dns_packed_hostname,x
+ inc dns_current_label_length
+
+@update_counters:
+ iny
+ inx
+ bmi @hostname_too_long ;don't allow a hostname of more than 128 bytes
+ jmp @next_hostname_byte
+
+@hostname_done:
+
+ lda dns_packed_hostname-1,x ;get the last byte we wrote out
+ beq :+ ;was it a zero?
+ lda #0
+ sta dns_packed_hostname,x ;write a trailing zero (i.e. a zero length label)
+ inx
+:
+ clc ;no error
+
+ rts
+
+@hostname_too_long:
+ lda #KPR_ERROR_INPUT_TOO_LARGE
+ sta ip65_error
+ sec
+ rts
+
+; resolve a string containing a hostname (or a dotted quad) to an ip address
+; inputs:
+; cfg_dns must point to a DNS server that supports recursion
+; dns_set_hostname must have been called to load the string to be resolved
+; outputs:
+; carry flag is set if there was an error, clear otherwise
+; dns_ip: set to the ip address of the hostname (if no error)
+dns_resolve:
+ lda hostname_was_dotted_quad
+ beq @hostname_not_dotted_quad
+ clc
+ rts ;we already set dns_ip when copying the hostname
+@hostname_not_dotted_quad:
+ ldax #dns_in
+ stax udp_callback
+ lda #53
+ inc dns_client_port_low_byte ;each call to resolve uses a different client address
+ ldx dns_client_port_low_byte ;so we don't get confused by late replies to a previous call
+ jsr udp_add_listener
+
+ bcc :+
+ rts
+:
+
+ lda #dns_initializing
+ sta dns_state
+ lda #0 ;reset the "message sent" counter
+ sta dns_message_sent_count
+
+ jsr send_dns_query
+
+@dns_polling_loop:
+ lda dns_message_sent_count
+ adc #1
+ sta dns_loop_count ;we wait a bit longer between each resend
+@outer_delay_loop:
+ lda #0
+ sta dns_break_polling_loop
+ jsr timer_read
+ stx dns_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 dns_state
+ cmp #dns_complete
+ beq @complete
+ cmp #dns_failed
+ beq @failed
+
+ lda #0
+ cmp dns_break_polling_loop
+ bne @break_polling_loop
+ jsr timer_read
+ cpx dns_timer ;this will tick over after about 1/4 of a second
+ beq @inner_delay_loop
+
+ dec dns_loop_count
+ bne @outer_delay_loop
+
+@break_polling_loop:
+ jsr send_dns_query
+ inc dns_message_sent_count
+ lda dns_message_sent_count
+ cmp #MAX_DNS_MESSAGES_SENT-1
+ bpl @too_many_messages_sent
+ jmp @dns_polling_loop
+
+@complete:
+
+ lda #53
+ ldx dns_client_port_low_byte
+ jsr udp_remove_listener
+ rts
+
+@too_many_messages_sent:
+@failed:
+ lda #53
+ ldx dns_client_port_low_byte
+ jsr udp_remove_listener
+ lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
+ sta ip65_error
+ sec ;signal an error
+ rts
+
+send_dns_query:
+ ldax dns_msg_id
+ inx
+ adc #0
+ stax dns_msg_id
+ stax output_buffer+dns_id
+
+ ldax #$0001 ;QR =0 (query), opcode=0 (query), AA=0, TC=0,RD=1,RA=0,Z=0,RCODE=0
+ stax output_buffer+dns_flags
+ ldax #$0100 ;we ask 1 question
+ stax output_buffer+dns_qdcount
+ ldax #$0000
+ stax output_buffer+dns_ancount ;we send no answers
+ stax output_buffer+dns_nscount ;we send no name servers
+ stax output_buffer+dns_arcount ;we send no authorative records
+
+ ldx #0
+:
+ lda dns_packed_hostname,x
+ sta output_buffer+dns_qname,x
+ inx
+ bpl @hostname_still_ok
+ lda #KPR_ERROR_INPUT_TOO_LARGE
+ sta ip65_error
+ jmp @error_on_send ;if we got past 128 bytes, there's a problem
+@hostname_still_ok:
+ cmp #0
+ bne :- ;keep looping until we have a zero byte.
+
+ lda #0
+ sta output_buffer+dns_qname,x ;high byte of QTYPE=1 (A)
+ sta output_buffer+dns_qname+2,x ;high byte of QLASS=1 (IN)
+ lda #1
+ sta output_buffer+dns_qname+1,x ;low byte of QTYPE=1 (A)
+ sta output_buffer+dns_qname+3,x ;low byte of QLASS=1 (IN)
+
+ txa
+ clc
+ adc #(dns_qname+4)
+ ldx #0
+ stax udp_send_len
+
+ lda #53
+ ldx dns_client_port_low_byte
+ stax udp_send_src_port
+
+ ldx #3 ; set destination address
+: lda cfg_dns,x
+ sta udp_send_dest,x
+ dex
+ bpl :-
+
+ ldax #dns_server_port ; set destination port
+ stax udp_send_dest_port
+ ldax #output_buffer
+ jsr udp_send
+ bcs @error_on_send
+ lda #dns_query_sent
+ sta dns_state
+
+ rts
+@error_on_send:
+ sec
+ rts
+
+dns_in:
+ lda dns_inp+dns_flags+1 ;
+ and #$0f ;get the RCODE
+ cmp #0
+ beq @not_an_error_response
+
+ sta dns_status ;anything non-zero is a permanent error (invalid domain, server doesn't support recursion etc)
+ sta dns_status+1
+ lda #dns_failed
+ sta dns_state
+ rts
+@not_an_error_response:
+ lda dns_inp+dns_qdcount+1
+ sta questions_in_response
+ cmp #1 ;should be exactly 1 Q in the response (i.e. the one we sent)
+ beq :+
+ jmp @error_in_response
+:
+ lda dns_inp+dns_ancount+1
+ bne :+
+ jmp @error_in_response ;should be at least 1 answer in response
+: ;we need to skip over the question (we will assume it's the question we just asked)
+ ldx #dns_qname
+:
+ lda dns_inp,x ;get next length byte in question
+ beq :+ ; we're done if length==0
+ clc
+ txa
+
+ adc dns_inp,x ;add length of next label to ptr
+ adc #1 ;+1 for the length byte itself
+ tax
+ bcs @error_in_response ;if we overflowed x, then message is too big
+ bcc :-
+:
+ inx ;skip past the nul byte
+ lda dns_inp+1,x
+ cmp #1 ;QTYPE should 1
+ lda dns_inp+3,x
+ cmp #1 ;QCLASS should 1
+ bne @error_in_response
+
+ inx ;skip past the QTYPE/QCLASS
+ inx
+ inx
+ inx
+
+ ;x now points to the start of the answers
+
+ lda dns_inp,x
+ bpl @error_in_response ;we are expecting the high bit to be set (we assume the server will send us back the answer to the question we just asked)
+ inx ;skip past the compression
+ inx
+ ;we are now pointing at the TYPE field
+ lda dns_inp+1,x ;
+
+ cmp #5 ; is this a CNAME?
+ bne @not_a_cname
+
+
+ txa
+ clc
+ adc #10 ;skip 2 bytes TYPE, 2 bytes CLASS, 4 bytes TTL, 2 bytes RDLENGTH
+ tax
+ ;we're now pointing at the CNAME record
+ ldy #0 ;start of CNAME hostname
+:
+ lda dns_inp,x
+ beq @last_byte_of_cname
+ bmi @found_compression_marker
+ sta dns_packed_hostname,y
+ inx
+ iny
+ bmi @error_in_response ;if we go past 128 bytes, something is wrong
+ bpl :- ;go get next byte
+ @last_byte_of_cname:
+ sta dns_packed_hostname,y
+
+ lda #$ff ;set a status marker so we know whats going on
+ sta dns_status
+ stx dns_status+1
+
+ lda #1
+ sta dns_break_polling_loop
+
+ rts ; finished processing - the main dns polling loop should now resend a query, this time for the hostname from the CNAME record
+
+@found_compression_marker:
+ lda dns_inp+1,x
+ tax
+ jmp :-
+
+@not_a_cname:
+ cmp #1 ; should be 1 (A record)
+ bne @error_in_response
+ txa
+ clc
+ adc #10 ;skip 2 bytes TYPE, 2 bytes CLASS, 4 bytes TTL, 2 bytes RDLENGTH
+ tax
+ ;we're now pointing at the answer!
+ lda dns_inp,x
+ sta dns_ip
+
+ lda dns_inp+1,x
+ sta dns_ip+1
+
+ lda dns_inp+2,x
+ sta dns_ip+2
+
+ lda dns_inp+3,x
+ sta dns_ip+3
+
+
+ lda #dns_complete
+ sta dns_state
+
+ lda #1
+ sta dns_break_polling_loop
+
+@error_in_response:
+
+ sta dns_status
+ stx dns_status+1
+ rts
+
+
+
+
+
+;-- LICENSE FOR dns.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/ip65/dottedquad.s b/ip65/dottedquad.s
similarity index 95%
rename from client/ip65/dottedquad.s
rename to ip65/dottedquad.s
index bfdc345..cd0b310 100644
--- a/client/ip65/dottedquad.s
+++ b/ip65/dottedquad.s
@@ -1,105 +1,105 @@
-
- .include "../inc/common.i"
-
-
- .export parse_dotted_quad
- .export dotted_quad_value
-
- .bss
- dotted_quad_value: .res 4 ;set to 32 bit ip address on a succesful call to parse_dotted_quad
-
- .data
-
- ;self modifying code
- dotted_quad_ptr:
- lda $FFFF
- rts
-
-
- .code
-
-
-; convert a string representing a dotted quad (IP address, netmask) into 4 octets
-; inputs:
-; AX= pointer to null-terminated (*) string containing dotted quad
-; e.g. "192.168.1.0",0
-; outputs:
-; carry flag is set if there was an error, clear otherwise
-; dotted_quad_value: will be set to (32 bit) ip address (if no error)
-; (*) NB to assist with url parsing, a ':' or '/' can also terminate the string
-parse_dotted_quad:
- stax dotted_quad_ptr+1
- ldx #0
- txa
- sta dotted_quad_value
-@each_byte:
- jsr get_next_byte
- cmp #0
- beq @done
- and #$7F ;turn off bit 7
- cmp #'.'
- beq @got_dot
- cmp #':'
- beq @done
- cmp #'/'
- beq @done
- sec
- sbc #'0'
- bcc @error
- cmp #10
- bcs @error
-
- clc
- ldy #10
-@mul_by_y:
- adc dotted_quad_value,x
- bcs @error
- dey
- bne @mul_by_y
- sta dotted_quad_value,x
- jmp @each_byte
-
-@got_dot:
- inx
- cpx #4
- beq @error
- lda #0
- sta dotted_quad_value,x
- jmp @each_byte
-@done:
- cpx #3
- bne @error
- clc
- rts
-@error:
- sec
- rts
-
-
-get_next_byte:
- jsr dotted_quad_ptr
- inc dotted_quad_ptr+1
- bne :+
- inc dotted_quad_ptr+2
-:
- rts
-
-
-;-- LICENSE FOR dottedquad.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 --
+
+ .include "../inc/common.i"
+
+
+ .export parse_dotted_quad
+ .export dotted_quad_value
+
+ .bss
+ dotted_quad_value: .res 4 ;set to 32 bit ip address on a succesful call to parse_dotted_quad
+
+ .data
+
+ ;self modifying code
+ dotted_quad_ptr:
+ lda $FFFF
+ rts
+
+
+ .code
+
+
+; convert a string representing a dotted quad (IP address, netmask) into 4 octets
+; inputs:
+; AX= pointer to null-terminated (*) string containing dotted quad
+; e.g. "192.168.1.0",0
+; outputs:
+; carry flag is set if there was an error, clear otherwise
+; dotted_quad_value: will be set to (32 bit) ip address (if no error)
+; (*) NB to assist with url parsing, a ':' or '/' can also terminate the string
+parse_dotted_quad:
+ stax dotted_quad_ptr+1
+ ldx #0
+ txa
+ sta dotted_quad_value
+@each_byte:
+ jsr get_next_byte
+ cmp #0
+ beq @done
+ and #$7F ;turn off bit 7
+ cmp #'.'
+ beq @got_dot
+ cmp #':'
+ beq @done
+ cmp #'/'
+ beq @done
+ sec
+ sbc #'0'
+ bcc @error
+ cmp #10
+ bcs @error
+
+ clc
+ ldy #10
+@mul_by_y:
+ adc dotted_quad_value,x
+ bcs @error
+ dey
+ bne @mul_by_y
+ sta dotted_quad_value,x
+ jmp @each_byte
+
+@got_dot:
+ inx
+ cpx #4
+ beq @error
+ lda #0
+ sta dotted_quad_value,x
+ jmp @each_byte
+@done:
+ cpx #3
+ bne @error
+ clc
+ rts
+@error:
+ sec
+ rts
+
+
+get_next_byte:
+ jsr dotted_quad_ptr
+ inc dotted_quad_ptr+1
+ bne :+
+ inc dotted_quad_ptr+2
+:
+ rts
+
+
+;-- LICENSE FOR dottedquad.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/ip65/eth.s b/ip65/eth.s
similarity index 96%
rename from client/ip65/eth.s
rename to ip65/eth.s
index aab21bb..d5c16cb 100644
--- a/client/ip65/eth.s
+++ b/ip65/eth.s
@@ -1,100 +1,100 @@
-; Common ethernet driver code (independant of host computer or ethernet chipset)
-
-.include "../inc/common.i"
-
- .export eth_set_broadcast_dest
- .export eth_set_my_mac_src
- .export eth_set_proto
-
- .exportzp eth_proto_ip
- .exportzp eth_proto_arp
- .exportzp eth_dest
- .exportzp eth_src
- .exportzp eth_type
- .exportzp eth_data
-
- .export eth_outp
- .export eth_outp_len
- .export eth_inp
- .export eth_inp_len
-
- .import cfg_mac
-
- .bss
-
-; input and output buffers
-eth_inp_len: .res 2 ; input packet length
-eth_inp: .res 1518 ; space for input packet
-eth_outp_len: .res 2 ; output packet length
-eth_outp: .res 1518 ; space for output packet
-
-
-
-; ethernet packet offsets
-eth_dest = 0 ; offset of destination address in ethernet packet
-eth_src = 6 ; offset of source address in ethernet packet
-eth_type = 12 ; offset of packet type in ethernet packet
-eth_data = 14 ; offset of packet data in ethernet packet
-
-; protocols
-
-eth_proto_ip = 0
-eth_proto_arp = 6
-
-
- .code
-;set the destination address in the packet under construction to be the ethernet
-;broadcast address (FF:FF:FF:FF:FF:FF)
-;inputs:
-; eth_outp: buffer in which outbound ethernet packet is being constructed
-;outputs: none
-eth_set_broadcast_dest:
- ldx #5
- lda #$ff
-: sta eth_outp,x
- dex
- bpl :-
- rts
-
-;set the source address in the packet under construction to be local mac address
-;inputs:
-; eth_outp: buffer in which outbound ethernet packet is being constructed
-;outputs: none
-eth_set_my_mac_src:
- ldx #5
-: lda cfg_mac,x
- sta eth_outp + 6,x
- dex
- bpl :-
- rts
-
-;set the 'protocol' field in the packet under construction
-;inputs:
-; A = protocol number (per 'eth_proto_*' constants)
-;outputs: none
-eth_set_proto:
- sta eth_outp + eth_type + 1
- lda #8
- sta eth_outp + eth_type
- rts
-
-
-
-;-- LICENSE FOR eth.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+; Common ethernet driver code (independant of host computer or ethernet chipset)
+
+.include "../inc/common.i"
+
+ .export eth_set_broadcast_dest
+ .export eth_set_my_mac_src
+ .export eth_set_proto
+
+ .exportzp eth_proto_ip
+ .exportzp eth_proto_arp
+ .exportzp eth_dest
+ .exportzp eth_src
+ .exportzp eth_type
+ .exportzp eth_data
+
+ .export eth_outp
+ .export eth_outp_len
+ .export eth_inp
+ .export eth_inp_len
+
+ .import cfg_mac
+
+ .bss
+
+; input and output buffers
+eth_inp_len: .res 2 ; input packet length
+eth_inp: .res 1518 ; space for input packet
+eth_outp_len: .res 2 ; output packet length
+eth_outp: .res 1518 ; space for output packet
+
+
+
+; ethernet packet offsets
+eth_dest = 0 ; offset of destination address in ethernet packet
+eth_src = 6 ; offset of source address in ethernet packet
+eth_type = 12 ; offset of packet type in ethernet packet
+eth_data = 14 ; offset of packet data in ethernet packet
+
+; protocols
+
+eth_proto_ip = 0
+eth_proto_arp = 6
+
+
+ .code
+;set the destination address in the packet under construction to be the ethernet
+;broadcast address (FF:FF:FF:FF:FF:FF)
+;inputs:
+; eth_outp: buffer in which outbound ethernet packet is being constructed
+;outputs: none
+eth_set_broadcast_dest:
+ ldx #5
+ lda #$ff
+: sta eth_outp,x
+ dex
+ bpl :-
+ rts
+
+;set the source address in the packet under construction to be local mac address
+;inputs:
+; eth_outp: buffer in which outbound ethernet packet is being constructed
+;outputs: none
+eth_set_my_mac_src:
+ ldx #5
+: lda cfg_mac,x
+ sta eth_outp + 6,x
+ dex
+ bpl :-
+ rts
+
+;set the 'protocol' field in the packet under construction
+;inputs:
+; A = protocol number (per 'eth_proto_*' constants)
+;outputs: none
+eth_set_proto:
+ sta eth_outp + eth_type + 1
+ lda #8
+ sta eth_outp + eth_type
+ rts
+
+
+
+;-- LICENSE FOR eth.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/function_dispatcher.s b/ip65/function_dispatcher.s
similarity index 94%
rename from client/ip65/function_dispatcher.s
rename to ip65/function_dispatcher.s
index 8cffa36..cdff777 100644
--- a/client/ip65/function_dispatcher.s
+++ b/ip65/function_dispatcher.s
@@ -1,699 +1,699 @@
-;this is some very quick and dirty glue to make the most useful IP65 functions available via a single entry point.
-;this allows user applications to be developed that don't link ip65 in directly, rather they use an instance of ip65 that is preloaded (or in a cartridge/ROM)
-;this whole file could (and should) be greatly optimised by making it all table driven, but since this file is probably only going to be used in a bankswitched ROM where
-;space is not at such a premium, I'll go with the gross hack for now.
-
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-.export kipper_dispatcher
-
-.import ip65_init
-.import dhcp_init
-.import cfg_get_configuration_ptr
-.import tftp_load_address
-.importzp tftp_filename
-.import tftp_ip
-.import ip65_error
-.import tftp_clear_callbacks
-.import tftp_download
-.import tftp_upload
-.import tftp_set_callback_vector
-.import tftp_filesize
-.import dns_ip
-.import dns_resolve
-.import dns_set_hostname
-.import udp_callback
-.import udp_add_listener
-.import udp_remove_listener
-.import ip_inp
-.import udp_inp
-.import udp_send
-.import udp_send_src
-.import udp_send_src_port
-.import udp_send_dest
-.import udp_send_dest_port
-.import udp_send_len
-
-.import copymem
-.import cfg_mac
-.import cfg_tftp_server
-.importzp copy_src
-.importzp copy_dest
-
-;reuse the copy_src zero page location
-kipper_params = copy_src
-buffer_ptr= copy_dest
-.data
-
-
-
-ip_configured_flag:
- .byte 0
-
-.code
-
-
-set_tftp_params:
- ldx #$03
-:
- lda cfg_tftp_server,x
- sta tftp_ip,x
- dex
- bpl :-
-
- ldy #KPR_TFTP_FILENAME
- lda (kipper_params),y
- sta tftp_filename
- iny
- lda (kipper_params),y
- sta tftp_filename+1
-
- ldy #KPR_TFTP_POINTER
- lda (kipper_params),y
- sta tftp_load_address
- iny
- lda (kipper_params),y
- sta tftp_load_address+1
-
- jsr tftp_clear_callbacks
-
- rts
-
-set_tftp_callback_vector:
- ldy #KPR_TFTP_POINTER+1
- lda (kipper_params),y
- tax
- dey
- lda (kipper_params),y
- jmp tftp_set_callback_vector
-
-kipper_dispatcher:
- stax kipper_params
-
-
- cpy #KPR_INITIALIZE
- bne :+
- lda ip_configured_flag
- bne ip_configured
- jsr ip65_init
- bcs init_failed
- jsr dhcp_init
- bcc dhcp_ok
- jsr ip65_init ;if DHCP failed, then reinit the IP stack (which will reset IP address etc that DHCP messed with to cartridge default values)
-dhcp_ok:
- lda #1
- sta ip_configured_flag
- clc
-init_failed:
- rts
-
-ip_configured:
- clc
- rts
-:
-
- cpy #KPR_GET_IP_CONFIG
- bne :+
- ldax #cfg_mac
- clc
- rts
-:
-
- cpy #KPR_DNS_RESOLVE
- bne :+
- phax
- ldy #KPR_DNS_HOSTNAME+1
- lda (kipper_params),y
- tax
- dey
- lda (kipper_params),y
- jsr dns_set_hostname
- bcs @dns_error
- jsr dns_resolve
- bcs @dns_error
-
- ldy #KPR_DNS_HOSTNAME_IP
- plax
- stax kipper_params
- ldx #4
-@copy_dns_ip:
- lda dns_ip,y
- sta (kipper_params),y
- iny
- dex
- bne @copy_dns_ip
- rts
-@dns_error:
- plax
- rts
-
-:
-
- cpy #KPR_UDP_ADD_LISTENER
- bne :+
- ldy #KPR_UDP_LISTENER_CALLBACK
- lda (kipper_params),y
- sta udp_callback
- iny
- lda (kipper_params),y
- sta udp_callback+1
- ldy #KPR_UDP_LISTENER_PORT+1
- lda (kipper_params),y
- tax
- dey
- lda (kipper_params),y
-
- jmp udp_add_listener
-:
-
- cpy #KPR_GET_INPUT_PACKET_INFO
- bne :+
- ldy #3
-@copy_src_ip:
- lda ip_inp+12,y ;src IP
- sta (kipper_params),y
- dey
- bpl @copy_src_ip
-
- ldy #KPR_REMOTE_PORT
- lda udp_inp+1 ;src port (lo byte)
- sta (kipper_params),y
- iny
- lda udp_inp+0 ;src port (high byte)
- sta (kipper_params),y
- iny
- lda udp_inp+3 ;dest port (lo byte)
- sta (kipper_params),y
- iny
- lda udp_inp+2 ;dest port (high byte)
- sta (kipper_params),y
-
- iny
- sec
- lda udp_inp+5 ;payload length (lo byte)
- sbc #8 ;to remove length of header
- sta (kipper_params),y
-
- iny
- lda udp_inp+4 ;payload length (hi byte)
- sbc #0 ;in case there was a carry from the lo byte
- sta (kipper_params),y
-
- iny
- lda #<(udp_inp+8) ;payload ptr (lo byte)
- sta (kipper_params),y
-
- iny
- lda #>(udp_inp+8) ;payload ptr (hi byte)
- sta (kipper_params),y
-
-.import tcp_inbound_data_ptr
-.import tcp_inbound_data_length
-
- lda ip_inp+9 ;proto number
- cmp #6 ;TCP
- bne @not_tcp
- ldy #KPR_PAYLOAD_LENGTH
- lda tcp_inbound_data_length
- sta (kipper_params),y
- iny
- lda tcp_inbound_data_length+1
- sta (kipper_params),y
-
- ldy #KPR_PAYLOAD_POINTER
- lda tcp_inbound_data_ptr
- sta (kipper_params),y
- iny
- lda tcp_inbound_data_ptr+1
- sta (kipper_params),y
-@not_tcp:
-
- clc
- rts
-:
-
- cpy #KPR_SEND_UDP_PACKET
- bne :+
- ldy #3
-@copy_dest_ip:
- lda (kipper_params),y
- sta udp_send_dest,y
- dey
- bpl @copy_dest_ip
-
- ldy #KPR_REMOTE_PORT
- lda (kipper_params),y
- sta udp_send_dest_port
- iny
- lda (kipper_params),y
- sta udp_send_dest_port+1
- iny
-
- lda (kipper_params),y
- sta udp_send_src_port
- iny
- lda (kipper_params),y
- sta udp_send_src_port+1
- iny
-
-
- lda (kipper_params),y
- sta udp_send_len
- iny
- lda (kipper_params),y
- sta udp_send_len+1
- iny
-
- ;AX should point at data to send
- lda (kipper_params),y
- pha
- iny
- lda (kipper_params),y
- tax
- pla
- jmp udp_send
-:
-
- cpy #KPR_UDP_REMOVE_LISTENER
- bne :+
- jmp udp_remove_listener
-:
-
-
- cpy #KPR_DEACTIVATE
- ;nothing to do now we don't use IRQ
- bne :+
- clc
- rts
-:
-
- cpy #KPR_TFTP_SET_SERVER
- bne :+
- ldy #3
-@copy_tftp_server_ip:
- lda (kipper_params),y
- sta cfg_tftp_server,y
- dey
- bpl @copy_tftp_server_ip
- clc
- rts
-
-:
- cpy #KPR_TFTP_DOWNLOAD
- bne :+
- phax
- jsr set_tftp_params
- jsr tftp_download
-
-@after_tftp_call: ;write the current load address back to the param buffer (so if $0000 was passed in, the caller can find out the actual value used)
- plax
- bcs @tftp_error
- stax kipper_params
-
- ldy #KPR_TFTP_POINTER
- lda tftp_load_address
- sta (kipper_params),y
- iny
- lda tftp_load_address+1
- sta (kipper_params),y
-
- ldy #KPR_TFTP_FILESIZE
- lda tftp_filesize
- sta (kipper_params),y
- iny
- lda tftp_filesize+1
- sta (kipper_params),y
- clc
-@tftp_error:
- rts
-:
-
-
-
- cpy #KPR_TFTP_CALLBACK_DOWNLOAD
- bne :+
- phax
- jsr set_tftp_params
- jsr set_tftp_callback_vector
- jsr tftp_download
- jmp @after_tftp_call
-:
-
- cpy #KPR_TFTP_UPLOAD
- bne :+
- phax
- jsr set_tftp_params
- ldy #KPR_TFTP_POINTER
- lda (kipper_params),y
- sta tftp_filesize
- iny
- lda (kipper_params),y
- sta tftp_filesize+1
-
- jsr tftp_download
- jmp @after_tftp_call
-:
-
- cpy #KPR_TFTP_CALLBACK_UPLOAD
- bne :+
- jsr set_tftp_params
- jsr set_tftp_callback_vector
- jmp tftp_upload
-:
-
- cpy #KPR_PRINT_ASCIIZ
- bne :+
- jsr print
- clc
- rts
-:
-
- cpy #KPR_PRINT_HEX
- bne :+
- jsr print_hex
- clc
- rts
-:
-
- cpy #KPR_PRINT_DOTTED_QUAD
- bne :+
- jsr print_dotted_quad
- clc
- rts
-:
-
- cpy #KPR_PRINT_IP_CONFIG
- bne :+
- jsr print_ip_config
- clc
- rts
-:
-
- cpy #KPR_PRINT_INTEGER
- bne :+
- jsr print_integer
- clc
- rts
-:
-
-
- .segment "TCP_VARS"
- port_number: .res 2
- nonzero_octets: .res 1
- .code
-
- cpy #KPR_DOWNLOAD_RESOURCE
- bne :+
-.import url_download
-.import url_download_buffer
-.import url_download_buffer_length
-
-
- ldy #KPR_URL_DOWNLOAD_BUFFER
- lda (kipper_params),y
- sta url_download_buffer
- iny
- lda (kipper_params),y
- sta url_download_buffer+1
-
- ldy #KPR_URL_DOWNLOAD_BUFFER_LENGTH
- lda (kipper_params),y
- sta url_download_buffer_length
- iny
- lda (kipper_params),y
- sta url_download_buffer_length+1
-
- ldy #KPR_URL+1
- lda (kipper_params),y
- tax
- dey
- lda (kipper_params),y
- jmp url_download
-:
-
- cpy #KPR_FILE_LOAD
-bne :+
-.import io_device_no
-.import io_read_file
-.import io_filename
-.import io_filesize
-.import io_load_address
- phax
- ldy #KPR_FILE_ACCESS_FILENAME
- lda (kipper_params),y
- sta io_filename
- iny
- lda (kipper_params),y
- sta io_filename+1
-
- ldy #KPR_FILE_ACCESS_DEVICE
- lda (kipper_params),y
- sta io_device_no
-
- ldy #KPR_FILE_ACCESS_POINTER+1
- lda (kipper_params),y
- tax
- dey
- lda (kipper_params),y
- jsr io_read_file
- plax
- bcc @read_file_ok
- rts
-
-@read_file_ok:
- stax kipper_params
-
- ldy #KPR_FILE_ACCESS_POINTER
- lda io_load_address
- sta (kipper_params),y
- iny
- lda io_load_address+1
- sta (kipper_params),y
-
- ldy #KPR_FILE_ACCESS_FILESIZE
- lda io_filesize
- sta (kipper_params),y
- iny
- lda io_filesize+1
- sta (kipper_params),y
- rts
-:
-
-
- cpy #KPR_HTTPD_START
- bne :+
- .import httpd_start
- jmp httpd_start
-:
-
-cpy #KPR_HTTPD_GET_VAR_VALUE
- bne :+
- .import http_get_value
- jmp http_get_value
-:
-
-
-
- cpy #KPR_PING_HOST
- .import icmp_echo_ip
- .import icmp_ping
- bne :+
- ldy #3
-@copy_ping_ip_loop:
- lda (kipper_params),y
- sta icmp_echo_ip,y
- dey
- bpl @copy_ping_ip_loop
- jmp icmp_ping
-
-:
- cpy #KPR_TCP_CONNECT
- bne :+
- .import tcp_connect
- .import tcp_callback
- .import tcp_connect_ip
- .import tcp_listen
- ldy #3
- lda #0
- sta nonzero_octets
-@copy_dest_ip:
- lda (kipper_params),y
- beq @octet_was_zero
- inc nonzero_octets
-@octet_was_zero:
- sta tcp_connect_ip,y
- dey
- bpl @copy_dest_ip
-
- ldy #KPR_TCP_CALLBACK
- lda (kipper_params),y
- sta tcp_callback
- iny
- lda (kipper_params),y
- sta tcp_callback+1
-
- ldy #KPR_TCP_PORT+1
- lda (kipper_params),y
- tax
- dey
- lda (kipper_params),y
- ldy nonzero_octets
- bne @outbound_tcp_connection
- jmp tcp_listen
-
-@outbound_tcp_connection:
- jmp tcp_connect
-
-:
-
- .import tcp_send
- .import tcp_send_data_len
- cpy #KPR_SEND_TCP_PACKET
- bne :+
- ldy #KPR_TCP_PAYLOAD_LENGTH
- lda (kipper_params),y
- sta tcp_send_data_len
- iny
- lda (kipper_params),y
- sta tcp_send_data_len+1
- ldy #KPR_TCP_PAYLOAD_POINTER+1
- lda (kipper_params),y
- tax
- dey
- lda (kipper_params),y
- jmp tcp_send
-
-:
-
-
-.import tcp_close
- cpy #KPR_TCP_CLOSE_CONNECTION
- bne :+
- jmp tcp_close
-:
-
-
-.import filter_dns
-.import get_filtered_input
-.import filter_number
-
- cpy #KPR_INPUT_STRING
- bne :+
- ldy #40 ;max chars
- ldax #$0000
- jmp get_filtered_input
-:
-
- cpy #KPR_INPUT_HOSTNAME
- bne :+
- ldy #40 ;max chars
- ldax #filter_dns
- jmp get_filtered_input
-:
-
-cpy #KPR_INPUT_PORT_NUMBER
- bne :+
- ldy #5 ;max chars
- ldax #filter_number
- jsr get_filtered_input
- bcs @no_port_entered
-
- ;AX now points a string containing port number
- .import parse_integer
- jmp parse_integer
-
-@no_port_entered:
- rts
-:
-
-cpy #KPR_BLOCK_COPY
- bne :+
- ;this is where we pay the price for trying to save a few 'zero page' pointers
- ;by reusing the 'copy_src' and 'copy_dest' addresses!
-.segment "TCP_VARS"
- tmp_copy_src: .res 2
- tmp_copy_dest: .res 2
- tmp_copy_length: .res 2
-.code
-
- ldy #KPR_BLOCK_SRC
- lda (kipper_params),y
- sta tmp_copy_src
- iny
- lda (kipper_params),y
- sta tmp_copy_src+1
-
- ldy #KPR_BLOCK_DEST
- lda (kipper_params),y
- sta tmp_copy_dest
- iny
- lda (kipper_params),y
- sta tmp_copy_dest+1
-
- ldy #KPR_BLOCK_SIZE
- lda (kipper_params),y
- sta tmp_copy_length
- iny
- lda (kipper_params),y
- sta tmp_copy_length+1
-
- ldax tmp_copy_src
- stax copy_src
- ldax tmp_copy_dest
- stax copy_dest
- ldax tmp_copy_length
- jmp copymem
-:
-
- cpy #KPR_PARSER_INIT
- bne :+
- .import parser_init
- jmp parser_init
-:
-
- cpy #KPR_PARSER_SKIP_NEXT
- bne :+
- .import parser_skip_next
- jmp parser_skip_next
-:
-
-
-
- cpy #KPR_GET_LAST_ERROR
- bne :+
- lda ip65_error
- clc
- rts
-:
-
-
-;default function handler
- lda #KPR_ERROR_FUNCTION_NOT_SUPPORTED
- sta ip65_error
- sec ;carry flag set = error
- rts
-
-
-;-- LICENSE FOR function_dispatcher.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 --
+;this is some very quick and dirty glue to make the most useful IP65 functions available via a single entry point.
+;this allows user applications to be developed that don't link ip65 in directly, rather they use an instance of ip65 that is preloaded (or in a cartridge/ROM)
+;this whole file could (and should) be greatly optimised by making it all table driven, but since this file is probably only going to be used in a bankswitched ROM where
+;space is not at such a premium, I'll go with the gross hack for now.
+
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+.include "../inc/common.i"
+.include "../inc/commonprint.i"
+.export kipper_dispatcher
+
+.import ip65_init
+.import dhcp_init
+.import cfg_get_configuration_ptr
+.import tftp_load_address
+.importzp tftp_filename
+.import tftp_ip
+.import ip65_error
+.import tftp_clear_callbacks
+.import tftp_download
+.import tftp_upload
+.import tftp_set_callback_vector
+.import tftp_filesize
+.import dns_ip
+.import dns_resolve
+.import dns_set_hostname
+.import udp_callback
+.import udp_add_listener
+.import udp_remove_listener
+.import ip_inp
+.import udp_inp
+.import udp_send
+.import udp_send_src
+.import udp_send_src_port
+.import udp_send_dest
+.import udp_send_dest_port
+.import udp_send_len
+
+.import copymem
+.import cfg_mac
+.import cfg_tftp_server
+.importzp copy_src
+.importzp copy_dest
+
+;reuse the copy_src zero page location
+kipper_params = copy_src
+buffer_ptr= copy_dest
+.data
+
+
+
+ip_configured_flag:
+ .byte 0
+
+.code
+
+
+set_tftp_params:
+ ldx #$03
+:
+ lda cfg_tftp_server,x
+ sta tftp_ip,x
+ dex
+ bpl :-
+
+ ldy #KPR_TFTP_FILENAME
+ lda (kipper_params),y
+ sta tftp_filename
+ iny
+ lda (kipper_params),y
+ sta tftp_filename+1
+
+ ldy #KPR_TFTP_POINTER
+ lda (kipper_params),y
+ sta tftp_load_address
+ iny
+ lda (kipper_params),y
+ sta tftp_load_address+1
+
+ jsr tftp_clear_callbacks
+
+ rts
+
+set_tftp_callback_vector:
+ ldy #KPR_TFTP_POINTER+1
+ lda (kipper_params),y
+ tax
+ dey
+ lda (kipper_params),y
+ jmp tftp_set_callback_vector
+
+kipper_dispatcher:
+ stax kipper_params
+
+
+ cpy #KPR_INITIALIZE
+ bne :+
+ lda ip_configured_flag
+ bne ip_configured
+ jsr ip65_init
+ bcs init_failed
+ jsr dhcp_init
+ bcc dhcp_ok
+ jsr ip65_init ;if DHCP failed, then reinit the IP stack (which will reset IP address etc that DHCP messed with to cartridge default values)
+dhcp_ok:
+ lda #1
+ sta ip_configured_flag
+ clc
+init_failed:
+ rts
+
+ip_configured:
+ clc
+ rts
+:
+
+ cpy #KPR_GET_IP_CONFIG
+ bne :+
+ ldax #cfg_mac
+ clc
+ rts
+:
+
+ cpy #KPR_DNS_RESOLVE
+ bne :+
+ phax
+ ldy #KPR_DNS_HOSTNAME+1
+ lda (kipper_params),y
+ tax
+ dey
+ lda (kipper_params),y
+ jsr dns_set_hostname
+ bcs @dns_error
+ jsr dns_resolve
+ bcs @dns_error
+
+ ldy #KPR_DNS_HOSTNAME_IP
+ plax
+ stax kipper_params
+ ldx #4
+@copy_dns_ip:
+ lda dns_ip,y
+ sta (kipper_params),y
+ iny
+ dex
+ bne @copy_dns_ip
+ rts
+@dns_error:
+ plax
+ rts
+
+:
+
+ cpy #KPR_UDP_ADD_LISTENER
+ bne :+
+ ldy #KPR_UDP_LISTENER_CALLBACK
+ lda (kipper_params),y
+ sta udp_callback
+ iny
+ lda (kipper_params),y
+ sta udp_callback+1
+ ldy #KPR_UDP_LISTENER_PORT+1
+ lda (kipper_params),y
+ tax
+ dey
+ lda (kipper_params),y
+
+ jmp udp_add_listener
+:
+
+ cpy #KPR_GET_INPUT_PACKET_INFO
+ bne :+
+ ldy #3
+@copy_src_ip:
+ lda ip_inp+12,y ;src IP
+ sta (kipper_params),y
+ dey
+ bpl @copy_src_ip
+
+ ldy #KPR_REMOTE_PORT
+ lda udp_inp+1 ;src port (lo byte)
+ sta (kipper_params),y
+ iny
+ lda udp_inp+0 ;src port (high byte)
+ sta (kipper_params),y
+ iny
+ lda udp_inp+3 ;dest port (lo byte)
+ sta (kipper_params),y
+ iny
+ lda udp_inp+2 ;dest port (high byte)
+ sta (kipper_params),y
+
+ iny
+ sec
+ lda udp_inp+5 ;payload length (lo byte)
+ sbc #8 ;to remove length of header
+ sta (kipper_params),y
+
+ iny
+ lda udp_inp+4 ;payload length (hi byte)
+ sbc #0 ;in case there was a carry from the lo byte
+ sta (kipper_params),y
+
+ iny
+ lda #<(udp_inp+8) ;payload ptr (lo byte)
+ sta (kipper_params),y
+
+ iny
+ lda #>(udp_inp+8) ;payload ptr (hi byte)
+ sta (kipper_params),y
+
+.import tcp_inbound_data_ptr
+.import tcp_inbound_data_length
+
+ lda ip_inp+9 ;proto number
+ cmp #6 ;TCP
+ bne @not_tcp
+ ldy #KPR_PAYLOAD_LENGTH
+ lda tcp_inbound_data_length
+ sta (kipper_params),y
+ iny
+ lda tcp_inbound_data_length+1
+ sta (kipper_params),y
+
+ ldy #KPR_PAYLOAD_POINTER
+ lda tcp_inbound_data_ptr
+ sta (kipper_params),y
+ iny
+ lda tcp_inbound_data_ptr+1
+ sta (kipper_params),y
+@not_tcp:
+
+ clc
+ rts
+:
+
+ cpy #KPR_SEND_UDP_PACKET
+ bne :+
+ ldy #3
+@copy_dest_ip:
+ lda (kipper_params),y
+ sta udp_send_dest,y
+ dey
+ bpl @copy_dest_ip
+
+ ldy #KPR_REMOTE_PORT
+ lda (kipper_params),y
+ sta udp_send_dest_port
+ iny
+ lda (kipper_params),y
+ sta udp_send_dest_port+1
+ iny
+
+ lda (kipper_params),y
+ sta udp_send_src_port
+ iny
+ lda (kipper_params),y
+ sta udp_send_src_port+1
+ iny
+
+
+ lda (kipper_params),y
+ sta udp_send_len
+ iny
+ lda (kipper_params),y
+ sta udp_send_len+1
+ iny
+
+ ;AX should point at data to send
+ lda (kipper_params),y
+ pha
+ iny
+ lda (kipper_params),y
+ tax
+ pla
+ jmp udp_send
+:
+
+ cpy #KPR_UDP_REMOVE_LISTENER
+ bne :+
+ jmp udp_remove_listener
+:
+
+
+ cpy #KPR_DEACTIVATE
+ ;nothing to do now we don't use IRQ
+ bne :+
+ clc
+ rts
+:
+
+ cpy #KPR_TFTP_SET_SERVER
+ bne :+
+ ldy #3
+@copy_tftp_server_ip:
+ lda (kipper_params),y
+ sta cfg_tftp_server,y
+ dey
+ bpl @copy_tftp_server_ip
+ clc
+ rts
+
+:
+ cpy #KPR_TFTP_DOWNLOAD
+ bne :+
+ phax
+ jsr set_tftp_params
+ jsr tftp_download
+
+@after_tftp_call: ;write the current load address back to the param buffer (so if $0000 was passed in, the caller can find out the actual value used)
+ plax
+ bcs @tftp_error
+ stax kipper_params
+
+ ldy #KPR_TFTP_POINTER
+ lda tftp_load_address
+ sta (kipper_params),y
+ iny
+ lda tftp_load_address+1
+ sta (kipper_params),y
+
+ ldy #KPR_TFTP_FILESIZE
+ lda tftp_filesize
+ sta (kipper_params),y
+ iny
+ lda tftp_filesize+1
+ sta (kipper_params),y
+ clc
+@tftp_error:
+ rts
+:
+
+
+
+ cpy #KPR_TFTP_CALLBACK_DOWNLOAD
+ bne :+
+ phax
+ jsr set_tftp_params
+ jsr set_tftp_callback_vector
+ jsr tftp_download
+ jmp @after_tftp_call
+:
+
+ cpy #KPR_TFTP_UPLOAD
+ bne :+
+ phax
+ jsr set_tftp_params
+ ldy #KPR_TFTP_POINTER
+ lda (kipper_params),y
+ sta tftp_filesize
+ iny
+ lda (kipper_params),y
+ sta tftp_filesize+1
+
+ jsr tftp_download
+ jmp @after_tftp_call
+:
+
+ cpy #KPR_TFTP_CALLBACK_UPLOAD
+ bne :+
+ jsr set_tftp_params
+ jsr set_tftp_callback_vector
+ jmp tftp_upload
+:
+
+ cpy #KPR_PRINT_ASCIIZ
+ bne :+
+ jsr print
+ clc
+ rts
+:
+
+ cpy #KPR_PRINT_HEX
+ bne :+
+ jsr print_hex
+ clc
+ rts
+:
+
+ cpy #KPR_PRINT_DOTTED_QUAD
+ bne :+
+ jsr print_dotted_quad
+ clc
+ rts
+:
+
+ cpy #KPR_PRINT_IP_CONFIG
+ bne :+
+ jsr print_ip_config
+ clc
+ rts
+:
+
+ cpy #KPR_PRINT_INTEGER
+ bne :+
+ jsr print_integer
+ clc
+ rts
+:
+
+
+ .segment "TCP_VARS"
+ port_number: .res 2
+ nonzero_octets: .res 1
+ .code
+
+ cpy #KPR_DOWNLOAD_RESOURCE
+ bne :+
+.import url_download
+.import url_download_buffer
+.import url_download_buffer_length
+
+
+ ldy #KPR_URL_DOWNLOAD_BUFFER
+ lda (kipper_params),y
+ sta url_download_buffer
+ iny
+ lda (kipper_params),y
+ sta url_download_buffer+1
+
+ ldy #KPR_URL_DOWNLOAD_BUFFER_LENGTH
+ lda (kipper_params),y
+ sta url_download_buffer_length
+ iny
+ lda (kipper_params),y
+ sta url_download_buffer_length+1
+
+ ldy #KPR_URL+1
+ lda (kipper_params),y
+ tax
+ dey
+ lda (kipper_params),y
+ jmp url_download
+:
+
+ cpy #KPR_FILE_LOAD
+bne :+
+.import io_device_no
+.import io_read_file
+.import io_filename
+.import io_filesize
+.import io_load_address
+ phax
+ ldy #KPR_FILE_ACCESS_FILENAME
+ lda (kipper_params),y
+ sta io_filename
+ iny
+ lda (kipper_params),y
+ sta io_filename+1
+
+ ldy #KPR_FILE_ACCESS_DEVICE
+ lda (kipper_params),y
+ sta io_device_no
+
+ ldy #KPR_FILE_ACCESS_POINTER+1
+ lda (kipper_params),y
+ tax
+ dey
+ lda (kipper_params),y
+ jsr io_read_file
+ plax
+ bcc @read_file_ok
+ rts
+
+@read_file_ok:
+ stax kipper_params
+
+ ldy #KPR_FILE_ACCESS_POINTER
+ lda io_load_address
+ sta (kipper_params),y
+ iny
+ lda io_load_address+1
+ sta (kipper_params),y
+
+ ldy #KPR_FILE_ACCESS_FILESIZE
+ lda io_filesize
+ sta (kipper_params),y
+ iny
+ lda io_filesize+1
+ sta (kipper_params),y
+ rts
+:
+
+
+ cpy #KPR_HTTPD_START
+ bne :+
+ .import httpd_start
+ jmp httpd_start
+:
+
+cpy #KPR_HTTPD_GET_VAR_VALUE
+ bne :+
+ .import http_get_value
+ jmp http_get_value
+:
+
+
+
+ cpy #KPR_PING_HOST
+ .import icmp_echo_ip
+ .import icmp_ping
+ bne :+
+ ldy #3
+@copy_ping_ip_loop:
+ lda (kipper_params),y
+ sta icmp_echo_ip,y
+ dey
+ bpl @copy_ping_ip_loop
+ jmp icmp_ping
+
+:
+ cpy #KPR_TCP_CONNECT
+ bne :+
+ .import tcp_connect
+ .import tcp_callback
+ .import tcp_connect_ip
+ .import tcp_listen
+ ldy #3
+ lda #0
+ sta nonzero_octets
+@copy_dest_ip:
+ lda (kipper_params),y
+ beq @octet_was_zero
+ inc nonzero_octets
+@octet_was_zero:
+ sta tcp_connect_ip,y
+ dey
+ bpl @copy_dest_ip
+
+ ldy #KPR_TCP_CALLBACK
+ lda (kipper_params),y
+ sta tcp_callback
+ iny
+ lda (kipper_params),y
+ sta tcp_callback+1
+
+ ldy #KPR_TCP_PORT+1
+ lda (kipper_params),y
+ tax
+ dey
+ lda (kipper_params),y
+ ldy nonzero_octets
+ bne @outbound_tcp_connection
+ jmp tcp_listen
+
+@outbound_tcp_connection:
+ jmp tcp_connect
+
+:
+
+ .import tcp_send
+ .import tcp_send_data_len
+ cpy #KPR_SEND_TCP_PACKET
+ bne :+
+ ldy #KPR_TCP_PAYLOAD_LENGTH
+ lda (kipper_params),y
+ sta tcp_send_data_len
+ iny
+ lda (kipper_params),y
+ sta tcp_send_data_len+1
+ ldy #KPR_TCP_PAYLOAD_POINTER+1
+ lda (kipper_params),y
+ tax
+ dey
+ lda (kipper_params),y
+ jmp tcp_send
+
+:
+
+
+.import tcp_close
+ cpy #KPR_TCP_CLOSE_CONNECTION
+ bne :+
+ jmp tcp_close
+:
+
+
+.import filter_dns
+.import get_filtered_input
+.import filter_number
+
+ cpy #KPR_INPUT_STRING
+ bne :+
+ ldy #40 ;max chars
+ ldax #$0000
+ jmp get_filtered_input
+:
+
+ cpy #KPR_INPUT_HOSTNAME
+ bne :+
+ ldy #40 ;max chars
+ ldax #filter_dns
+ jmp get_filtered_input
+:
+
+cpy #KPR_INPUT_PORT_NUMBER
+ bne :+
+ ldy #5 ;max chars
+ ldax #filter_number
+ jsr get_filtered_input
+ bcs @no_port_entered
+
+ ;AX now points a string containing port number
+ .import parse_integer
+ jmp parse_integer
+
+@no_port_entered:
+ rts
+:
+
+cpy #KPR_BLOCK_COPY
+ bne :+
+ ;this is where we pay the price for trying to save a few 'zero page' pointers
+ ;by reusing the 'copy_src' and 'copy_dest' addresses!
+.segment "TCP_VARS"
+ tmp_copy_src: .res 2
+ tmp_copy_dest: .res 2
+ tmp_copy_length: .res 2
+.code
+
+ ldy #KPR_BLOCK_SRC
+ lda (kipper_params),y
+ sta tmp_copy_src
+ iny
+ lda (kipper_params),y
+ sta tmp_copy_src+1
+
+ ldy #KPR_BLOCK_DEST
+ lda (kipper_params),y
+ sta tmp_copy_dest
+ iny
+ lda (kipper_params),y
+ sta tmp_copy_dest+1
+
+ ldy #KPR_BLOCK_SIZE
+ lda (kipper_params),y
+ sta tmp_copy_length
+ iny
+ lda (kipper_params),y
+ sta tmp_copy_length+1
+
+ ldax tmp_copy_src
+ stax copy_src
+ ldax tmp_copy_dest
+ stax copy_dest
+ ldax tmp_copy_length
+ jmp copymem
+:
+
+ cpy #KPR_PARSER_INIT
+ bne :+
+ .import parser_init
+ jmp parser_init
+:
+
+ cpy #KPR_PARSER_SKIP_NEXT
+ bne :+
+ .import parser_skip_next
+ jmp parser_skip_next
+:
+
+
+
+ cpy #KPR_GET_LAST_ERROR
+ bne :+
+ lda ip65_error
+ clc
+ rts
+:
+
+
+;default function handler
+ lda #KPR_ERROR_FUNCTION_NOT_SUPPORTED
+ sta ip65_error
+ sec ;carry flag set = error
+ rts
+
+
+;-- LICENSE FOR function_dispatcher.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/ip65/http.s b/ip65/http.s
similarity index 95%
rename from client/ip65/http.s
rename to ip65/http.s
index 60207dc..4ed5f8f 100644
--- a/client/ip65/http.s
+++ b/ip65/http.s
@@ -1,255 +1,255 @@
-;routines for parsing a HTTP request
-;to use - first call http_parse_request, then call http_get_value to get method name, path, and variable values
-;NB - this routine uses the same buffer space and zero page locations as many other ip65 routines. so do not call
-;other ip65 routines between the http_parse_request & http_get_value else odd things will happen.
-
-.include "../inc/common.i"
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-
-.export http_parse_request
-.export http_get_value
-.export http_variables_buffer
-
-.importzp copy_src
-.importzp copy_dest
-.import output_buffer
-.import parse_hex_digits
-;reuse the copy_src zero page var
-string_ptr = copy_src
-table_ptr=copy_dest
-
-
-.bss
-var_name: .res 1
-hex_digit: .res 1
-
-.data
-http_variables_buffer: .word $2800 ;work area for storing variables extracted from query string
-
-
-.code
-
-
-;split a HTTP request into method (e.g. GET or POST), the path, and any querystring variables
-;NB only the first letter in a variable name is significant. i.e. if a querystring contains variables 'a','alpha' & 'alabama', only the first one in will be retreivable.
-;the method is stored in var $01
-;the path is stored in var $02
-;for example, parsing "GET /goober?a=foo&alpha=beta" would result in:
-;value of A when calling http_get_value value returned by http_get_value
-; #$01 "GET"
-; #$02 "/goober"
-; #'a' "foo"
-; #'A' (error)
-;inputs:
-;AX = pointer to HTTP request
-;outputs:
-; none - but values can be retrieved through subsequent calls to http_get_value
-http_parse_request:
- stax string_ptr
-
- ldax http_variables_buffer
-
- stax table_ptr
-
- lda #1 ;start of method
- ldy #0
- jsr put_byte
- lda (string_ptr),y
- cmp #'/'
- beq @gopher
- jsr @check_end_of_string
- bcs @gopher
- lda (string_ptr),y
-@extract_method:
-
- cmp #' '
- beq @end_of_method
- jsr @check_end_of_string
- bcc :+
- jmp @done
-:
- jsr put_byte
- jsr get_next_byte_in_source
- jmp @extract_method
-
-@gopher:
- jsr @output_end_of_method
- lda #'/'
- jmp @got_path_char
-@output_end_of_method:
- lda #0 ;end of method
- jsr put_byte
- lda #2 ;start of path
- jmp put_byte
-
-@end_of_method:
- jsr @output_end_of_method
-
-@extract_path:
- jsr get_next_byte_in_source
- jsr @check_end_of_string
- bcs @done
- cmp #'?'
- beq @end_of_path
- cmp #'&'
- beq @end_of_path
-@got_path_char:
- jsr put_byte
- jmp @extract_path
-@end_of_path:
- lda #0 ;end of path
- jsr put_byte
-
-@next_var:
-
- jsr get_next_byte_in_source
- jsr @check_end_of_string
- bcs @done
- jsr put_byte
-
-
- @skip_to_equals:
- jsr get_next_byte_in_source
- jsr @check_end_of_string
- bcs @done
- cmp #'?'
- beq @next_var
- cmp #'&'
- beq @next_var
- cmp #'='
- beq @got_var
- jmp @skip_to_equals
-
-@got_var:
-
- jsr get_next_byte_in_source
- jsr @check_end_of_string
- bcs @done
- cmp #'?'
- beq @end_of_var
- cmp #'&'
- beq @end_of_var
-
- cmp #'%'
- beq @get_percent_encoded_byte
- cmp #'+'
- bne :+
- lda #' '
-:
-@got_byte:
- jsr put_byte
- jmp @got_var
-
-@end_of_var:
- lda #0
- jsr put_byte
- jmp @next_var
-
-
-@done:
- lda #0
- jsr put_byte
- jsr put_byte
- rts
-
-@check_end_of_string:
- cmp #0
- beq @end_of_string
- cmp #' '
- beq @end_of_string
- cmp #$0a
- beq @end_of_string
- cmp #$0d
- beq @end_of_string
- clc
- rts
-@end_of_string:
- sec
- rts
-
-@get_percent_encoded_byte:
- jsr get_next_byte_in_source
- tax
- jsr get_next_byte_in_source
- jsr parse_hex_digits
- jmp @got_byte
-
-put_byte:
- sta (table_ptr),y
- inc table_ptr
- bne :+
- inc table_ptr+1
-:
- rts
-
-;retrieve the value of a variable defined in the previously parsed HTTP request.
-;inputs:
-;A = variable to retrieve.
-; to get the method (GET/POST/HEAD), pass A=$01.
-; to get the path (everything between the method and the first '?'), pass A=$02.
-;outputs:
-; if variable exists in HTTP request, carry flag will be clear and AX points to value (null terminated string)
-; if variable did not exist, carry flag will be set.
-http_get_value:
- sta var_name
- ldax http_variables_buffer
- stax string_ptr
- ldy #0
-
-lda (string_ptr),y
-@check_next_var:
- beq @end_of_vars
- cmp var_name
- beq @got_var
- ;not the var we want, so skip over till next byte
-@skip_till_null_byte:
- jsr get_next_byte_in_source
- bne @skip_till_null_byte
- jsr get_next_byte_in_source
- bne @check_next_var
-
-@end_of_vars:
- sec
- rts
-
-@got_var:
- jsr get_next_byte_in_source
- ldax string_ptr
- clc
- rts
-
-
-get_next_byte_in_source:
- inc string_ptr
- bne :+
- inc string_ptr+1
-:
- lda (string_ptr),y
- rts
-
-
-
-
-;-- LICENSE FOR http.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 --
+;routines for parsing a HTTP request
+;to use - first call http_parse_request, then call http_get_value to get method name, path, and variable values
+;NB - this routine uses the same buffer space and zero page locations as many other ip65 routines. so do not call
+;other ip65 routines between the http_parse_request & http_get_value else odd things will happen.
+
+.include "../inc/common.i"
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+
+.export http_parse_request
+.export http_get_value
+.export http_variables_buffer
+
+.importzp copy_src
+.importzp copy_dest
+.import output_buffer
+.import parse_hex_digits
+;reuse the copy_src zero page var
+string_ptr = copy_src
+table_ptr=copy_dest
+
+
+.bss
+var_name: .res 1
+hex_digit: .res 1
+
+.data
+http_variables_buffer: .word $2800 ;work area for storing variables extracted from query string
+
+
+.code
+
+
+;split a HTTP request into method (e.g. GET or POST), the path, and any querystring variables
+;NB only the first letter in a variable name is significant. i.e. if a querystring contains variables 'a','alpha' & 'alabama', only the first one in will be retreivable.
+;the method is stored in var $01
+;the path is stored in var $02
+;for example, parsing "GET /goober?a=foo&alpha=beta" would result in:
+;value of A when calling http_get_value value returned by http_get_value
+; #$01 "GET"
+; #$02 "/goober"
+; #'a' "foo"
+; #'A' (error)
+;inputs:
+;AX = pointer to HTTP request
+;outputs:
+; none - but values can be retrieved through subsequent calls to http_get_value
+http_parse_request:
+ stax string_ptr
+
+ ldax http_variables_buffer
+
+ stax table_ptr
+
+ lda #1 ;start of method
+ ldy #0
+ jsr put_byte
+ lda (string_ptr),y
+ cmp #'/'
+ beq @gopher
+ jsr @check_end_of_string
+ bcs @gopher
+ lda (string_ptr),y
+@extract_method:
+
+ cmp #' '
+ beq @end_of_method
+ jsr @check_end_of_string
+ bcc :+
+ jmp @done
+:
+ jsr put_byte
+ jsr get_next_byte_in_source
+ jmp @extract_method
+
+@gopher:
+ jsr @output_end_of_method
+ lda #'/'
+ jmp @got_path_char
+@output_end_of_method:
+ lda #0 ;end of method
+ jsr put_byte
+ lda #2 ;start of path
+ jmp put_byte
+
+@end_of_method:
+ jsr @output_end_of_method
+
+@extract_path:
+ jsr get_next_byte_in_source
+ jsr @check_end_of_string
+ bcs @done
+ cmp #'?'
+ beq @end_of_path
+ cmp #'&'
+ beq @end_of_path
+@got_path_char:
+ jsr put_byte
+ jmp @extract_path
+@end_of_path:
+ lda #0 ;end of path
+ jsr put_byte
+
+@next_var:
+
+ jsr get_next_byte_in_source
+ jsr @check_end_of_string
+ bcs @done
+ jsr put_byte
+
+
+ @skip_to_equals:
+ jsr get_next_byte_in_source
+ jsr @check_end_of_string
+ bcs @done
+ cmp #'?'
+ beq @next_var
+ cmp #'&'
+ beq @next_var
+ cmp #'='
+ beq @got_var
+ jmp @skip_to_equals
+
+@got_var:
+
+ jsr get_next_byte_in_source
+ jsr @check_end_of_string
+ bcs @done
+ cmp #'?'
+ beq @end_of_var
+ cmp #'&'
+ beq @end_of_var
+
+ cmp #'%'
+ beq @get_percent_encoded_byte
+ cmp #'+'
+ bne :+
+ lda #' '
+:
+@got_byte:
+ jsr put_byte
+ jmp @got_var
+
+@end_of_var:
+ lda #0
+ jsr put_byte
+ jmp @next_var
+
+
+@done:
+ lda #0
+ jsr put_byte
+ jsr put_byte
+ rts
+
+@check_end_of_string:
+ cmp #0
+ beq @end_of_string
+ cmp #' '
+ beq @end_of_string
+ cmp #$0a
+ beq @end_of_string
+ cmp #$0d
+ beq @end_of_string
+ clc
+ rts
+@end_of_string:
+ sec
+ rts
+
+@get_percent_encoded_byte:
+ jsr get_next_byte_in_source
+ tax
+ jsr get_next_byte_in_source
+ jsr parse_hex_digits
+ jmp @got_byte
+
+put_byte:
+ sta (table_ptr),y
+ inc table_ptr
+ bne :+
+ inc table_ptr+1
+:
+ rts
+
+;retrieve the value of a variable defined in the previously parsed HTTP request.
+;inputs:
+;A = variable to retrieve.
+; to get the method (GET/POST/HEAD), pass A=$01.
+; to get the path (everything between the method and the first '?'), pass A=$02.
+;outputs:
+; if variable exists in HTTP request, carry flag will be clear and AX points to value (null terminated string)
+; if variable did not exist, carry flag will be set.
+http_get_value:
+ sta var_name
+ ldax http_variables_buffer
+ stax string_ptr
+ ldy #0
+
+lda (string_ptr),y
+@check_next_var:
+ beq @end_of_vars
+ cmp var_name
+ beq @got_var
+ ;not the var we want, so skip over till next byte
+@skip_till_null_byte:
+ jsr get_next_byte_in_source
+ bne @skip_till_null_byte
+ jsr get_next_byte_in_source
+ bne @check_next_var
+
+@end_of_vars:
+ sec
+ rts
+
+@got_var:
+ jsr get_next_byte_in_source
+ ldax string_ptr
+ clc
+ rts
+
+
+get_next_byte_in_source:
+ inc string_ptr
+ bne :+
+ inc string_ptr+1
+:
+ lda (string_ptr),y
+ rts
+
+
+
+
+;-- LICENSE FOR http.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/ip65/httpd.s b/ip65/httpd.s
similarity index 94%
rename from client/ip65/httpd.s
rename to ip65/httpd.s
index dd4d626..e4e1009 100644
--- a/client/ip65/httpd.s
+++ b/ip65/httpd.s
@@ -1,626 +1,626 @@
-;a simple HTTP server
-;to use - call httpd_start with AX pointing at routine to call for each inbound page
-.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?
-
-
-.export httpd_start
-
-.import http_parse_request
-.import http_get_value
-.import tcp_listen
-.import tcp_callback
-.import ip65_process
-.import check_for_abort_key
-.import ip65_error
-.import parse_hex_digits
-.import print
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-.import tcp_inbound_data_ptr
-.import tcp_inbound_data_length
-.import tcp_send_data_len
-.import tcp_send
-.import tcp_close
-.import io_read_catalogue
-.import native_to_ascii
-.import io_read_file_with_callback
-.import io_filename
-.import io_callback
-.import timer_seconds
-.import __HTTP_VARS_LOAD__
-.import __HTTP_VARS_RUN__
-.import __HTTP_VARS_SIZE__
-
-temp_ptr =copy_src
-
-.bss
-found_eol: .byte 0
-connection_closed: .byte 0
-output_buffer_length: .res 2
-sent_header: .res 1
-connection_timeout_seconds: .byte 0
-tcp_buffer_ptr: .res 2
-buffer_size: .res 1
-skip_mode: .res 1
-temp_x: .res 1
-
-.segment "HTTP_VARS"
-
-httpd_io_buffer: .word $2000 ;by default, use a 3k buffer at $2000 for storing inbound requests.
-httpd_scratch_buffer: .word $2B00 ;by default, use a 1k buffer at $2b00 as a scratchpad
-httpd_port_number: .word 80
-
-
-jump_to_callback:
- jmp $ffff
-
-jump_to_embedded_routine:
- jmp $ffff
-
-get_next_byte:
- lda $ffff
- inc get_next_byte+1
- bne @skip
- inc get_next_byte+2
-@skip:
- rts
-
-
-emit_a:
- stx temp_x
- ldx skip_mode
- bne skip_emit_a
-emit_a_ptr:
- sta $ffff
- inc emit_a_ptr+1
- bne :+
- inc emit_a_ptr+2
-:
- inc output_buffer_length
- bne :+
- inc output_buffer_length+1
- lda output_buffer_length+1
- cmp #2
- bne :+
- jsr send_buffer
-:
-skip_emit_a:
- ldx temp_x
- rts
-
-.code
-
-;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:
-;httpd_port_number=port number to listen on
-;AX = pointer to routine to callback for each inbound HTTP request=
-;set this to $0000 to use the default handler (which will look for requested files on the local disk).
-;outputs:
-; none
-httpd_start:
- pha ;save AX while we relocate self modifying code
- txa
- pha
-
- ;relocate the self-modifying code
- ldax #__HTTP_VARS_LOAD__
- stax copy_src
- ldax #__HTTP_VARS_RUN__
- stax copy_dest
- ldax #__HTTP_VARS_SIZE__
- jsr copymem
- pla
- tax
- pla
-
- stx jump_to_callback+2
- bne @not_default_handler
- ldax #default_httpd_handler
- jmp httpd_start
-@not_default_handler:
- sta jump_to_callback+1
-
-
-
-@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
- bcc @connect_ok
- rts
-@connect_ok:
-
- lda #0
- sta connection_closed
- sta found_eol
- clc
- jsr timer_seconds ;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
- lda #KPR_ERROR_ABORTED_BY_USER
- sta ip65_error
- rts
-@no_abort:
- lda found_eol
- bne @got_eol
-
- jsr timer_seconds ;time of day clock: seconds
-
- cmp connection_timeout_seconds
- beq @connection_timed_out
- lda connection_closed
- beq @main_polling_loop
-@connection_timed_out:
- jmp @listen
-
-@got_eol:
- ldax httpd_io_buffer
- jsr http_parse_request
- jsr jump_to_callback ;call the handler to generate the response for this request.
- ;AX should now point at data to be sent
- ;Y should contain the content type/status code
- bcs :+ ;carry is set if the callback routine already sent the response
- jsr send_response
- :
-
-
- jmp @listen ;go listen for the next 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
-
-
-default_httpd_handler:
- lda #$02
- jsr http_get_value
- bcc @not_error
- ldy #5
- clc
- rts
-@not_error:
- stax temp_ptr
- ldy #1
- lda (temp_ptr),y
- bne @not_index
- ldax #default_html
- ldy #2
- clc
- rts
-@not_index:
- ;assume that 'path' is a filename
- inc temp_ptr
- bne :+
- inc temp_ptr
-:
- lda #0
- sta sent_header
- ldax temp_ptr
- stax io_filename
- ldax #send_file_callback
- stax io_callback
- ldax httpd_scratch_buffer
- jsr io_read_file_with_callback
- bcc @sent_ok
- ldy #4
- clc
- rts
-@sent_ok:
- sec
- rts
-
-send_file_callback:
- sty buffer_size ;only 1 (the last) sector can ever be !=$100 bytes
- lda sent_header
- bne @sent_header
- ldy #3 ;"application/octet-stream"
- jsr send_header
- inc sent_header
-@sent_header:
- ldax httpd_scratch_buffer
- stax temp_ptr
- ldy #0
-@loop:
- tya
- pha
- lda (temp_ptr),y
- jsr emit_a
- pla
- tay
- iny
- cpy buffer_size
- bne @loop
- rts
-
-reset_output_buffer:
- ldax httpd_io_buffer
- sta emit_a_ptr+1
- stx emit_a_ptr+2
- lda #0
- sta output_buffer_length
- sta output_buffer_length+1
- sta skip_mode
- rts
-
-
-emit_disk_catalogue:
-
- ldax httpd_scratch_buffer
- jsr io_read_catalogue
- lda get_next_byte+1
- pha
- lda get_next_byte+2
- pha
- ldax httpd_scratch_buffer
- stax get_next_byte+1
-
-@next_filename:
-
- jsr get_next_byte
- cmp #0
- beq @done
- pha
-
-
- ldax #file_li_preamble
- jsr emit_string
- pla
- pha
- jsr emit_a
- ldax get_next_byte+1
- jsr emit_string
-
- ldax #file_li_middle
- jsr emit_string
- pla
- bne @convert_byte
-@next_byte:
- jsr get_next_byte
- cmp #0
- beq @done_this_filename
-@convert_byte:
- jsr native_to_ascii
- jsr emit_a
- jmp @next_byte
-@done_this_filename:
-
-
-
-
- ldax #file_li_postamble
- jsr emit_string
-
-
- jmp @next_filename
-@done:
-
- pla
- sta get_next_byte+2
- pla
- sta get_next_byte+1
- rts
-
-send_response:
- stax get_next_byte+1
- jsr reset_output_buffer
- jsr send_header
-
-@response_loop:
- jsr get_next_byte
- cmp #0
- bne @not_last_byte
-@send_buffer:
- jmp send_buffer
-@not_last_byte:
- cmp #'%'
- beq @escape
-@back_from_escape:
- jsr emit_a
- jmp @response_loop
-
-@escape:
- jsr get_next_byte
- cmp #0
- beq @send_buffer
- cmp #'%'
- beq @back_from_escape
- cmp #'$'
- bne :+
- jsr get_next_byte
- jsr http_get_value
- bcs @response_loop
- jsr emit_string
- jmp @response_loop
-:
- cmp #'.'
- bne :+
- lda #0
- sta skip_mode
- jmp @response_loop
-:
- cmp #'?'
- bne :+
- lda #0
- sta skip_mode
- jsr get_next_byte
- jsr http_get_value
- bcc @response_loop
- inc skip_mode
- jmp @response_loop
-:
- cmp #'!'
- bne :+
- lda #0
- sta skip_mode
- jsr get_next_byte
- jsr http_get_value
- bcs @response_loop
- inc skip_mode
- jmp @response_loop
-:
-
- cmp #';'
- bne :+
- jsr get_next_byte
- sta jump_to_embedded_routine+1
- jsr get_next_byte
- sta jump_to_embedded_routine+2
- jmp @call_embedded_routine
- :
- cmp #':'
- bne :+
- jsr @get_next_hex_value
- sta jump_to_embedded_routine+2
- jsr @get_next_hex_value
- sta jump_to_embedded_routine+1
-@call_embedded_routine:
- lda skip_mode
- bne @dont_call_embedded_routine
- ldax #emit_a
- jsr jump_to_embedded_routine
-@dont_call_embedded_routine:
- jmp @response_loop
- :
-;if we got here, it's an invalid escape code
- jmp @response_loop
-
-@get_next_hex_value:
- jsr get_next_byte
- tax
- jsr get_next_byte
- jmp parse_hex_digits
-
-send_buffer:
- ldax output_buffer_length
- stax tcp_send_data_len
- ldax httpd_io_buffer
- jsr tcp_send
- jmp reset_output_buffer
-
- send_header:
-;inputs: Y = header type
-;$00 = no header (assume header sent already)
-;$01 = 200 OK, 'text/text'
-;$02 = 200 OK, 'text/html'
-;$03 = 200 OK, 'application/octet-stream'
-;$04 = 404 Not Found
-;$05..$FF = 500 System Error
-
- cpy #00
- bne :+
- rts
-:
- cpy #1
- bne @not_text
- jsr emit_ok_status_line_and_content_type
- ldax #text_text
- jsr emit_string
- jmp @done
-
-@not_text:
- cpy #2
-
- bne @not_html
- jsr emit_ok_status_line_and_content_type
- ldax #text_html
- jsr emit_string
- jmp @done
-
-@not_html:
- cpy #3
- bne @not_binary
- jsr emit_ok_status_line_and_content_type
- ldax #application_octet_stream
- jsr emit_string
- jmp @done
-
-@not_binary:
- cpy #4
- bne @not_404
- ldax #http_version
- jsr emit_string
- ldax #status_not_found
- jsr emit_string
-
- jsr @done
- ldax #status_not_found
- jmp emit_string
-
-@not_404:
- ldax #http_version
- jsr emit_string
- ldax #status_system_error
- jsr emit_string
- jsr @done
- ldax #status_system_error
- jmp emit_string
-@done:
- ldax #end_of_header
- jmp emit_string
-
-
-emit_ok_status_line_and_content_type:
- ldax #http_version
- jsr emit_string
- ldax #status_ok
- jsr emit_string
- ldax #content_type
- jmp emit_string
-
-emit_string:
- stax temp_ptr
- ldy #0
-@next_byte:
- lda (temp_ptr),y
- beq @done
- jsr emit_a
- iny
- bne @next_byte
-@done:
- rts
-
-
-.rodata
-default_html:
-.byte "Index of / %;"
-.word emit_disk_catalogue
-.byte " kipper - the 100%% 6502 m/l web server "
-.byte 0
-
-
-CR=$0D
-LF=$0A
-
-http_version:
- .byte "HTTP/1.0 ",0
-
-status_ok:
- .byte "200 OK",CR,LF,0
-
-status_not_found:
- .byte "404 Not Found",CR,LF,0
-
-status_system_error:
- .byte "500 System Error",CR,LF,0
-content_type:
- .byte "Content-Type: ",0
-
-text_text:
- .byte "text/text",CR,LF,0
-
-text_html:
- .byte "text/html",CR,LF,0
-
-application_octet_stream:
- .byte "application/octet-stream",CR,LF,0
-
-end_of_header:
- .byte "Connection: Close",CR,LF
- .byte "Server: Kipper_httpd/0.c64",CR,LF
- .byte CR,LF,0
-
-file_li_preamble:
- .byte "",0
-file_li_postamble:
- .byte " ",0
-
-
-
-;-- LICENSE FOR httpd.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 --
+;a simple HTTP server
+;to use - call httpd_start with AX pointing at routine to call for each inbound page
+.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?
+
+
+.export httpd_start
+
+.import http_parse_request
+.import http_get_value
+.import tcp_listen
+.import tcp_callback
+.import ip65_process
+.import check_for_abort_key
+.import ip65_error
+.import parse_hex_digits
+.import print
+.import copymem
+.importzp copy_src
+.importzp copy_dest
+.import tcp_inbound_data_ptr
+.import tcp_inbound_data_length
+.import tcp_send_data_len
+.import tcp_send
+.import tcp_close
+.import io_read_catalogue
+.import native_to_ascii
+.import io_read_file_with_callback
+.import io_filename
+.import io_callback
+.import timer_seconds
+.import __HTTP_VARS_LOAD__
+.import __HTTP_VARS_RUN__
+.import __HTTP_VARS_SIZE__
+
+temp_ptr =copy_src
+
+.bss
+found_eol: .byte 0
+connection_closed: .byte 0
+output_buffer_length: .res 2
+sent_header: .res 1
+connection_timeout_seconds: .byte 0
+tcp_buffer_ptr: .res 2
+buffer_size: .res 1
+skip_mode: .res 1
+temp_x: .res 1
+
+.segment "HTTP_VARS"
+
+httpd_io_buffer: .word $2000 ;by default, use a 3k buffer at $2000 for storing inbound requests.
+httpd_scratch_buffer: .word $2B00 ;by default, use a 1k buffer at $2b00 as a scratchpad
+httpd_port_number: .word 80
+
+
+jump_to_callback:
+ jmp $ffff
+
+jump_to_embedded_routine:
+ jmp $ffff
+
+get_next_byte:
+ lda $ffff
+ inc get_next_byte+1
+ bne @skip
+ inc get_next_byte+2
+@skip:
+ rts
+
+
+emit_a:
+ stx temp_x
+ ldx skip_mode
+ bne skip_emit_a
+emit_a_ptr:
+ sta $ffff
+ inc emit_a_ptr+1
+ bne :+
+ inc emit_a_ptr+2
+:
+ inc output_buffer_length
+ bne :+
+ inc output_buffer_length+1
+ lda output_buffer_length+1
+ cmp #2
+ bne :+
+ jsr send_buffer
+:
+skip_emit_a:
+ ldx temp_x
+ rts
+
+.code
+
+;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:
+;httpd_port_number=port number to listen on
+;AX = pointer to routine to callback for each inbound HTTP request=
+;set this to $0000 to use the default handler (which will look for requested files on the local disk).
+;outputs:
+; none
+httpd_start:
+ pha ;save AX while we relocate self modifying code
+ txa
+ pha
+
+ ;relocate the self-modifying code
+ ldax #__HTTP_VARS_LOAD__
+ stax copy_src
+ ldax #__HTTP_VARS_RUN__
+ stax copy_dest
+ ldax #__HTTP_VARS_SIZE__
+ jsr copymem
+ pla
+ tax
+ pla
+
+ stx jump_to_callback+2
+ bne @not_default_handler
+ ldax #default_httpd_handler
+ jmp httpd_start
+@not_default_handler:
+ sta jump_to_callback+1
+
+
+
+@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
+ bcc @connect_ok
+ rts
+@connect_ok:
+
+ lda #0
+ sta connection_closed
+ sta found_eol
+ clc
+ jsr timer_seconds ;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
+ lda #KPR_ERROR_ABORTED_BY_USER
+ sta ip65_error
+ rts
+@no_abort:
+ lda found_eol
+ bne @got_eol
+
+ jsr timer_seconds ;time of day clock: seconds
+
+ cmp connection_timeout_seconds
+ beq @connection_timed_out
+ lda connection_closed
+ beq @main_polling_loop
+@connection_timed_out:
+ jmp @listen
+
+@got_eol:
+ ldax httpd_io_buffer
+ jsr http_parse_request
+ jsr jump_to_callback ;call the handler to generate the response for this request.
+ ;AX should now point at data to be sent
+ ;Y should contain the content type/status code
+ bcs :+ ;carry is set if the callback routine already sent the response
+ jsr send_response
+ :
+
+
+ jmp @listen ;go listen for the next 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
+
+
+default_httpd_handler:
+ lda #$02
+ jsr http_get_value
+ bcc @not_error
+ ldy #5
+ clc
+ rts
+@not_error:
+ stax temp_ptr
+ ldy #1
+ lda (temp_ptr),y
+ bne @not_index
+ ldax #default_html
+ ldy #2
+ clc
+ rts
+@not_index:
+ ;assume that 'path' is a filename
+ inc temp_ptr
+ bne :+
+ inc temp_ptr
+:
+ lda #0
+ sta sent_header
+ ldax temp_ptr
+ stax io_filename
+ ldax #send_file_callback
+ stax io_callback
+ ldax httpd_scratch_buffer
+ jsr io_read_file_with_callback
+ bcc @sent_ok
+ ldy #4
+ clc
+ rts
+@sent_ok:
+ sec
+ rts
+
+send_file_callback:
+ sty buffer_size ;only 1 (the last) sector can ever be !=$100 bytes
+ lda sent_header
+ bne @sent_header
+ ldy #3 ;"application/octet-stream"
+ jsr send_header
+ inc sent_header
+@sent_header:
+ ldax httpd_scratch_buffer
+ stax temp_ptr
+ ldy #0
+@loop:
+ tya
+ pha
+ lda (temp_ptr),y
+ jsr emit_a
+ pla
+ tay
+ iny
+ cpy buffer_size
+ bne @loop
+ rts
+
+reset_output_buffer:
+ ldax httpd_io_buffer
+ sta emit_a_ptr+1
+ stx emit_a_ptr+2
+ lda #0
+ sta output_buffer_length
+ sta output_buffer_length+1
+ sta skip_mode
+ rts
+
+
+emit_disk_catalogue:
+
+ ldax httpd_scratch_buffer
+ jsr io_read_catalogue
+ lda get_next_byte+1
+ pha
+ lda get_next_byte+2
+ pha
+ ldax httpd_scratch_buffer
+ stax get_next_byte+1
+
+@next_filename:
+
+ jsr get_next_byte
+ cmp #0
+ beq @done
+ pha
+
+
+ ldax #file_li_preamble
+ jsr emit_string
+ pla
+ pha
+ jsr emit_a
+ ldax get_next_byte+1
+ jsr emit_string
+
+ ldax #file_li_middle
+ jsr emit_string
+ pla
+ bne @convert_byte
+@next_byte:
+ jsr get_next_byte
+ cmp #0
+ beq @done_this_filename
+@convert_byte:
+ jsr native_to_ascii
+ jsr emit_a
+ jmp @next_byte
+@done_this_filename:
+
+
+
+
+ ldax #file_li_postamble
+ jsr emit_string
+
+
+ jmp @next_filename
+@done:
+
+ pla
+ sta get_next_byte+2
+ pla
+ sta get_next_byte+1
+ rts
+
+send_response:
+ stax get_next_byte+1
+ jsr reset_output_buffer
+ jsr send_header
+
+@response_loop:
+ jsr get_next_byte
+ cmp #0
+ bne @not_last_byte
+@send_buffer:
+ jmp send_buffer
+@not_last_byte:
+ cmp #'%'
+ beq @escape
+@back_from_escape:
+ jsr emit_a
+ jmp @response_loop
+
+@escape:
+ jsr get_next_byte
+ cmp #0
+ beq @send_buffer
+ cmp #'%'
+ beq @back_from_escape
+ cmp #'$'
+ bne :+
+ jsr get_next_byte
+ jsr http_get_value
+ bcs @response_loop
+ jsr emit_string
+ jmp @response_loop
+:
+ cmp #'.'
+ bne :+
+ lda #0
+ sta skip_mode
+ jmp @response_loop
+:
+ cmp #'?'
+ bne :+
+ lda #0
+ sta skip_mode
+ jsr get_next_byte
+ jsr http_get_value
+ bcc @response_loop
+ inc skip_mode
+ jmp @response_loop
+:
+ cmp #'!'
+ bne :+
+ lda #0
+ sta skip_mode
+ jsr get_next_byte
+ jsr http_get_value
+ bcs @response_loop
+ inc skip_mode
+ jmp @response_loop
+:
+
+ cmp #';'
+ bne :+
+ jsr get_next_byte
+ sta jump_to_embedded_routine+1
+ jsr get_next_byte
+ sta jump_to_embedded_routine+2
+ jmp @call_embedded_routine
+ :
+ cmp #':'
+ bne :+
+ jsr @get_next_hex_value
+ sta jump_to_embedded_routine+2
+ jsr @get_next_hex_value
+ sta jump_to_embedded_routine+1
+@call_embedded_routine:
+ lda skip_mode
+ bne @dont_call_embedded_routine
+ ldax #emit_a
+ jsr jump_to_embedded_routine
+@dont_call_embedded_routine:
+ jmp @response_loop
+ :
+;if we got here, it's an invalid escape code
+ jmp @response_loop
+
+@get_next_hex_value:
+ jsr get_next_byte
+ tax
+ jsr get_next_byte
+ jmp parse_hex_digits
+
+send_buffer:
+ ldax output_buffer_length
+ stax tcp_send_data_len
+ ldax httpd_io_buffer
+ jsr tcp_send
+ jmp reset_output_buffer
+
+ send_header:
+;inputs: Y = header type
+;$00 = no header (assume header sent already)
+;$01 = 200 OK, 'text/text'
+;$02 = 200 OK, 'text/html'
+;$03 = 200 OK, 'application/octet-stream'
+;$04 = 404 Not Found
+;$05..$FF = 500 System Error
+
+ cpy #00
+ bne :+
+ rts
+:
+ cpy #1
+ bne @not_text
+ jsr emit_ok_status_line_and_content_type
+ ldax #text_text
+ jsr emit_string
+ jmp @done
+
+@not_text:
+ cpy #2
+
+ bne @not_html
+ jsr emit_ok_status_line_and_content_type
+ ldax #text_html
+ jsr emit_string
+ jmp @done
+
+@not_html:
+ cpy #3
+ bne @not_binary
+ jsr emit_ok_status_line_and_content_type
+ ldax #application_octet_stream
+ jsr emit_string
+ jmp @done
+
+@not_binary:
+ cpy #4
+ bne @not_404
+ ldax #http_version
+ jsr emit_string
+ ldax #status_not_found
+ jsr emit_string
+
+ jsr @done
+ ldax #status_not_found
+ jmp emit_string
+
+@not_404:
+ ldax #http_version
+ jsr emit_string
+ ldax #status_system_error
+ jsr emit_string
+ jsr @done
+ ldax #status_system_error
+ jmp emit_string
+@done:
+ ldax #end_of_header
+ jmp emit_string
+
+
+emit_ok_status_line_and_content_type:
+ ldax #http_version
+ jsr emit_string
+ ldax #status_ok
+ jsr emit_string
+ ldax #content_type
+ jmp emit_string
+
+emit_string:
+ stax temp_ptr
+ ldy #0
+@next_byte:
+ lda (temp_ptr),y
+ beq @done
+ jsr emit_a
+ iny
+ bne @next_byte
+@done:
+ rts
+
+
+.rodata
+default_html:
+.byte "Index of / %;"
+.word emit_disk_catalogue
+.byte " kipper - the 100%% 6502 m/l web server "
+.byte 0
+
+
+CR=$0D
+LF=$0A
+
+http_version:
+ .byte "HTTP/1.0 ",0
+
+status_ok:
+ .byte "200 OK",CR,LF,0
+
+status_not_found:
+ .byte "404 Not Found",CR,LF,0
+
+status_system_error:
+ .byte "500 System Error",CR,LF,0
+content_type:
+ .byte "Content-Type: ",0
+
+text_text:
+ .byte "text/text",CR,LF,0
+
+text_html:
+ .byte "text/html",CR,LF,0
+
+application_octet_stream:
+ .byte "application/octet-stream",CR,LF,0
+
+end_of_header:
+ .byte "Connection: Close",CR,LF
+ .byte "Server: Kipper_httpd/0.c64",CR,LF
+ .byte CR,LF,0
+
+file_li_preamble:
+ .byte "",0
+file_li_postamble:
+ .byte " ",0
+
+
+
+;-- LICENSE FOR httpd.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/ip65/icmp.s b/ip65/icmp.s
similarity index 95%
rename from client/ip65/icmp.s
rename to ip65/icmp.s
index 71db15e..7fb64f0 100644
--- a/client/ip65/icmp.s
+++ b/ip65/icmp.s
@@ -1,469 +1,469 @@
-;ICMP implementation
-;
-
-.include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- .export icmp_init
- .export icmp_process
- .export icmp_add_listener
- .export icmp_remove_listener
-
- .export icmp_callback
-
- .export icmp_inp
- .export icmp_outp
- .exportzp icmp_type
- .exportzp icmp_code
- .exportzp icmp_cksum
- .exportzp icmp_data
-
-.ifdef TCP
- .export icmp_echo_ip
- .export icmp_send_echo
- .export icmp_ping
-.endif
-
-
-
- .import ip65_process
- .import ip65_error
-
- .import ip_calc_cksum
- .import ip_inp
- .import ip_outp
- .import ip_broadcast
- .import ip_send
- .import ip_create_packet
- .importzp ip_proto
- .importzp ip_proto_icmp
-
- .importzp ip_cksum_ptr
- .importzp ip_header_cksum
- .importzp ip_src
- .importzp ip_dest
- .importzp ip_data
- .importzp ip_len
-
- .import eth_tx
- .import eth_inp
- .import eth_inp_len
- .import eth_outp
- .import eth_outp_len
- .import timer_read
- .import timer_timeout
-
-.data
- icmp_cbtmp: jmp $0000 ; temporary vector - address filled in later
-
-
- .bss
-
-; argument for icmp_add_listener
-icmp_callback: .res 2
-
-
-; icmp callbacks
-icmp_cbmax = 2
-icmp_cbveclo: .res icmp_cbmax ; table of listener vectors (lsb)
-icmp_cbvechi: .res icmp_cbmax ; table of listener vectors (msb)
-icmp_cbtype: .res icmp_cbmax ; table of listener types
-icmp_cbcount: .res 1 ; number of active listeners
-
-; icmp packet offsets
-icmp_inp = ip_inp + ip_data ;pointer to inbound icmp packet
-icmp_outp = ip_outp + ip_data ;pointer to outbound icmp packet
-icmp_type = 0 ;offset of 'type' field in icmp packet
-icmp_code = 1 ;offset of 'code' field in icmp packet
-icmp_cksum = 2 ;offset of 'checksum' field in icmp packet
-icmp_data = 4;offset of 'data' field in icmp packet
-
-; icmp echo packet offsets
-icmp_echo_id = 4 ;offset of 'id' field in icmp echo request/echo response
-icmp_echo_seq = 6 ;offset of 'sequence' field in icmp echo request/echo response
-icmp_echo_data = 8 ;offset of 'data' field in icmp echo request/echo response
-
-;icmp type codes
-icmp_msg_type_echo_reply=0
-icmp_msg_type_destination_unreachable=3
-icmp_msg_type_source_quench=4
-icmp_msg_type_redirect=5
-icmp_msg_type_echo_request=8
-icmp_msg_type_time_exceeded=11
-icmp_msg_type_paramater_problem=12
-icmp_msg_type_timestamp=13
-icmp_msg_type_timestamp_reply=14
-icmp_msg_type_information_request=15
-icmp_msg_type_information_reply=16
-
-;ping states
-ping_state_request_sent=0
-ping_state_response_received=1
-
-
-.ifdef TCP
-.segment "TCP_VARS"
-icmp_echo_ip: .res 4 ; destination IP address for echo request ("ping")
-icmp_echo_cnt: .res 1 ;ping sequence counter
-ping_state: .res 1
- ping_timer: .res 2 ;
-.endif
-
- .code
-
-; initialize icmp
-; inputs: none
-; outputs: none
-icmp_init:
- lda #0
- sta icmp_cbcount
- rts
-
-;process incoming icmp packet
-;inputs:
-; eth_inp points to an ethernet frame containing an icmp packet
-;outputs:
-; carry flag - set on any error, clear if OK
-; if inbound packet is a request (e.g. 'echo request') and an icmp listener
-; has been installed, then an appropriate response message will be
-; generated and sent out (overwriting the eth_outp buffer)
-icmp_process:
- lda icmp_inp + icmp_type
- cmp #icmp_msg_type_echo_request ; ping
- beq @echo
-
- lda icmp_cbcount ; any installed icmp listeners?
- beq @drop
-
- ldx icmp_cbcount ; check listened types
- dex
-: lda icmp_cbtype,x
- cmp icmp_inp + icmp_type
- beq @handle ; found a match
- dex
- bpl :-
-
-@drop:
- sec
- rts
-
-@handle:
- lda icmp_cbveclo,x ; copy vector
- sta icmp_cbtmp + 1
- lda icmp_cbvechi,x
- sta icmp_cbtmp + 2
- jsr icmp_cbtmp ; call listener
- clc
- rts
-
-@echo:
- lda ip_broadcast ; check if packet is broadcast
- beq @notbc
- sec ; don't reply to broadcast pings
- rts
-@notbc:
- ldx #5
-: lda eth_inp,x ; swap dest and src mac
- sta eth_outp + 6,x
- lda eth_inp + 6,x
- sta eth_outp,x
- dex
- bpl :-
-
- ldx #12 ; copy the packet
-: lda eth_inp,x
- sta eth_outp,x
- inx
- cpx eth_inp_len
- bne :-
-
- ldx #3
-: lda ip_inp + ip_src,x ; swap dest and src ip
- sta ip_outp + ip_dest,x
- lda ip_inp + ip_dest,x
- sta ip_outp + ip_src,x
- dex
- bpl :-
-
- lda #0 ; change type to reply
- sta icmp_outp + icmp_type
-
- lda icmp_inp + icmp_cksum ; recalc checksum
- clc
- adc #8
- sta icmp_outp + icmp_cksum
- bcc :+
- inc icmp_outp + icmp_cksum + 1
-:
- lda eth_inp_len ; copy length
- sta eth_outp_len
- lda eth_inp_len + 1
- sta eth_outp_len + 1
-
- lda #0 ; clear checksum
- sta ip_outp + ip_header_cksum
- sta ip_outp + ip_header_cksum + 1
- ldax #ip_outp ; calculate ip header checksum
- stax ip_cksum_ptr
- ldax #20
- jsr ip_calc_cksum
- stax ip_outp + ip_header_cksum
-
- jsr eth_tx ; send packet
-
- clc
- rts
-
-
-;add an icmp listener
-;inputs:
-; A = icmp type
-; icmp_callback: vector to call when an icmp packet of specified type arrives
-;outputs:
-; carry flag - set if error, clear if no error
-icmp_add_listener:
- ldx icmp_cbcount ; any listeners at all?
- beq @add
- cpx #icmp_cbmax ; max?
- beq @full
- ldx #0
-: cmp icmp_cbtype,x ; check if type is already listened
- beq @busy
- inx
- cpx icmp_cbcount
- bne :-
-@add:
- inc icmp_cbcount ; increase counter
- sta icmp_cbtype,x ; add type
- lda icmp_callback ; and vector
- sta icmp_cbveclo,x
- lda icmp_callback + 1
- sta icmp_cbvechi,x
-
- clc
- rts
-@full:
-@busy:
- sec
- rts
-
-
-;remove an icmp listener
-;inputs:
-; A = icmp type
-;outputs:
-; carry flag - set if error (i.e. no listner for this type exists),
-; clear if no error
-icmp_remove_listener:
- ldx icmp_cbcount ; any listeners installed?
- beq @notfound
- dex
-: cmp icmp_cbtype,x ; check if type is listened
- beq @remove
- dex
- bpl :-
-@notfound:
- sec
- rts
-@remove:
- txa ; number of listeners below
- eor #$ff
- clc
- adc icmp_cbcount
- beq @done
-@move:
- tay ; number of items to move
-: lda icmp_cbtype + 1,x ; move type
- sta icmp_cbtype,x
- lda icmp_cbveclo + 1,x ; move vector lsb
- sta icmp_cbveclo,x
- lda icmp_cbvechi + 1,x ; move vector msb
- sta icmp_cbvechi,x
- inx
- dey
- bne :-
-@done:
- dec icmp_cbcount ; decrement counter
- clc
- rts
-
-.ifdef TCP
-
-; icmp_send_echo was contributed by Glenn Holmer (ShadowM)
-
-;send an ICMP echo ("ping") request
-;inputs:
-; icmp_echo_ip: destination IP address
-;outputs:
-; carry flag - set if error, clear if no error
-icmp_send_echo:
- ldy #3
-:
- lda icmp_echo_ip,y
- sta ip_outp + ip_dest,y
- dey
- bpl :-
-
-
- lda #icmp_msg_type_echo_request
- sta icmp_outp + icmp_type
- lda #0 ;not used for echo packets
- sta icmp_outp + icmp_code
- sta icmp_outp + icmp_cksum ;clear checksum
- sta icmp_outp + icmp_cksum + 1
- sta icmp_outp + icmp_echo_id ;set id to 0
- sta icmp_outp + icmp_echo_id + 1
- inc icmp_echo_cnt + 1 ;big-endian
- bne :+
- inc icmp_echo_cnt
-:
- ldax icmp_echo_cnt
- stax icmp_outp + icmp_echo_seq
-
- ldy #0
-:
- lda ip65_msg,y
- beq @set_ip_len
- sta icmp_outp + icmp_echo_data,y
- iny
- bne :-
-@set_ip_len:
- tya
- clc
- adc #28 ;IP header + ICMP type, code, cksum, id, seq
- sta ip_outp + ip_len + 1 ;high byte first
- lda #0 ;will never be >256
- sta ip_outp + ip_len
-
- ldax #icmp_outp ;start of ICMP packet
- stax ip_cksum_ptr
- tya
- clc
- adc #8 ;ICMP type, code, cksum, id, seq
- ldx #0 ;AX = length of ICMP data
- jsr ip_calc_cksum
- stax icmp_outp + icmp_cksum
- lda #ip_proto_icmp
- sta ip_outp + ip_proto
- jsr ip_create_packet
- jmp ip_send
-
-;send a ping (ICMP echo request) to a remote host, and wait for a response
-;inputs:
-; icmp_echo_ip: destination IP address
-;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:
- jsr icmp_send_echo
- bcc @message_sent_ok
- ;we couldn't send the message - most likely we needed to do an ARP lookup.
- ;so wait a bit, and retry
-
- jsr timer_read ; read current timer value
- stax ping_timer
-@loop_during_arp_lookup:
-
- jsr ip65_process
- ldax ping_timer
- adc #50 ; set timeout to now + 50 ms
- bcc :+
- inx
-:
-
- jsr timer_timeout
- bcs @loop_during_arp_lookup
- jsr icmp_send_echo
- bcc @message_sent_ok
- ;still can't send? then give up
- lda #KPR_ERROR_TRANSMIT_FAILED
- sta ip65_error
- rts
-@message_sent_ok:
- jsr timer_read ; read current timer value
- stax ping_timer
- ldax #icmp_ping_callback
- stax icmp_callback
- lda #icmp_msg_type_echo_reply
- jsr icmp_add_listener
- lda #ping_state_request_sent
- sta ping_state
-@loop_till_get_ping_response:
- jsr ip65_process
-
- lda ping_state
- cmp #ping_state_response_received
- beq @got_reply
- ldax ping_timer
- inx ;x rolls over about 4 times per second
- inx ;so we will timeout after about 2 seconds
- inx
- inx
- inx
- inx
- inx
- inx
-
-
- jsr timer_timeout
- bcs @loop_till_get_ping_response
- lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
- sta ip65_error
- lda #icmp_msg_type_echo_reply
- jsr icmp_remove_listener
- sec
- rts
-@got_reply:
- lda #icmp_msg_type_echo_reply
- jsr icmp_remove_listener
- jsr timer_read
- sec
- sbc ping_timer
- pha
- txa
- sbc ping_timer+1
- tax
- pla
- clc
- rts
-
-icmp_ping_callback:
- lda icmp_inp + icmp_echo_seq
- cmp icmp_echo_cnt
- bne @not_what_we_were_waiting_for
- lda #ping_state_response_received
- sta ping_state
-@not_what_we_were_waiting_for:
- rts
-
-ip65_msg:
- .byte "ip65 - the 6502 IP stack",0
-.endif
-
-
-;-- LICENSE FOR icmp.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-;
-;Contributor(s): Jonno Downes, Glenn Holmer
-; -- LICENSE END --
+;ICMP implementation
+;
+
+.include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+ .export icmp_init
+ .export icmp_process
+ .export icmp_add_listener
+ .export icmp_remove_listener
+
+ .export icmp_callback
+
+ .export icmp_inp
+ .export icmp_outp
+ .exportzp icmp_type
+ .exportzp icmp_code
+ .exportzp icmp_cksum
+ .exportzp icmp_data
+
+.ifdef TCP
+ .export icmp_echo_ip
+ .export icmp_send_echo
+ .export icmp_ping
+.endif
+
+
+
+ .import ip65_process
+ .import ip65_error
+
+ .import ip_calc_cksum
+ .import ip_inp
+ .import ip_outp
+ .import ip_broadcast
+ .import ip_send
+ .import ip_create_packet
+ .importzp ip_proto
+ .importzp ip_proto_icmp
+
+ .importzp ip_cksum_ptr
+ .importzp ip_header_cksum
+ .importzp ip_src
+ .importzp ip_dest
+ .importzp ip_data
+ .importzp ip_len
+
+ .import eth_tx
+ .import eth_inp
+ .import eth_inp_len
+ .import eth_outp
+ .import eth_outp_len
+ .import timer_read
+ .import timer_timeout
+
+.data
+ icmp_cbtmp: jmp $0000 ; temporary vector - address filled in later
+
+
+ .bss
+
+; argument for icmp_add_listener
+icmp_callback: .res 2
+
+
+; icmp callbacks
+icmp_cbmax = 2
+icmp_cbveclo: .res icmp_cbmax ; table of listener vectors (lsb)
+icmp_cbvechi: .res icmp_cbmax ; table of listener vectors (msb)
+icmp_cbtype: .res icmp_cbmax ; table of listener types
+icmp_cbcount: .res 1 ; number of active listeners
+
+; icmp packet offsets
+icmp_inp = ip_inp + ip_data ;pointer to inbound icmp packet
+icmp_outp = ip_outp + ip_data ;pointer to outbound icmp packet
+icmp_type = 0 ;offset of 'type' field in icmp packet
+icmp_code = 1 ;offset of 'code' field in icmp packet
+icmp_cksum = 2 ;offset of 'checksum' field in icmp packet
+icmp_data = 4;offset of 'data' field in icmp packet
+
+; icmp echo packet offsets
+icmp_echo_id = 4 ;offset of 'id' field in icmp echo request/echo response
+icmp_echo_seq = 6 ;offset of 'sequence' field in icmp echo request/echo response
+icmp_echo_data = 8 ;offset of 'data' field in icmp echo request/echo response
+
+;icmp type codes
+icmp_msg_type_echo_reply=0
+icmp_msg_type_destination_unreachable=3
+icmp_msg_type_source_quench=4
+icmp_msg_type_redirect=5
+icmp_msg_type_echo_request=8
+icmp_msg_type_time_exceeded=11
+icmp_msg_type_paramater_problem=12
+icmp_msg_type_timestamp=13
+icmp_msg_type_timestamp_reply=14
+icmp_msg_type_information_request=15
+icmp_msg_type_information_reply=16
+
+;ping states
+ping_state_request_sent=0
+ping_state_response_received=1
+
+
+.ifdef TCP
+.segment "TCP_VARS"
+icmp_echo_ip: .res 4 ; destination IP address for echo request ("ping")
+icmp_echo_cnt: .res 1 ;ping sequence counter
+ping_state: .res 1
+ ping_timer: .res 2 ;
+.endif
+
+ .code
+
+; initialize icmp
+; inputs: none
+; outputs: none
+icmp_init:
+ lda #0
+ sta icmp_cbcount
+ rts
+
+;process incoming icmp packet
+;inputs:
+; eth_inp points to an ethernet frame containing an icmp packet
+;outputs:
+; carry flag - set on any error, clear if OK
+; if inbound packet is a request (e.g. 'echo request') and an icmp listener
+; has been installed, then an appropriate response message will be
+; generated and sent out (overwriting the eth_outp buffer)
+icmp_process:
+ lda icmp_inp + icmp_type
+ cmp #icmp_msg_type_echo_request ; ping
+ beq @echo
+
+ lda icmp_cbcount ; any installed icmp listeners?
+ beq @drop
+
+ ldx icmp_cbcount ; check listened types
+ dex
+: lda icmp_cbtype,x
+ cmp icmp_inp + icmp_type
+ beq @handle ; found a match
+ dex
+ bpl :-
+
+@drop:
+ sec
+ rts
+
+@handle:
+ lda icmp_cbveclo,x ; copy vector
+ sta icmp_cbtmp + 1
+ lda icmp_cbvechi,x
+ sta icmp_cbtmp + 2
+ jsr icmp_cbtmp ; call listener
+ clc
+ rts
+
+@echo:
+ lda ip_broadcast ; check if packet is broadcast
+ beq @notbc
+ sec ; don't reply to broadcast pings
+ rts
+@notbc:
+ ldx #5
+: lda eth_inp,x ; swap dest and src mac
+ sta eth_outp + 6,x
+ lda eth_inp + 6,x
+ sta eth_outp,x
+ dex
+ bpl :-
+
+ ldx #12 ; copy the packet
+: lda eth_inp,x
+ sta eth_outp,x
+ inx
+ cpx eth_inp_len
+ bne :-
+
+ ldx #3
+: lda ip_inp + ip_src,x ; swap dest and src ip
+ sta ip_outp + ip_dest,x
+ lda ip_inp + ip_dest,x
+ sta ip_outp + ip_src,x
+ dex
+ bpl :-
+
+ lda #0 ; change type to reply
+ sta icmp_outp + icmp_type
+
+ lda icmp_inp + icmp_cksum ; recalc checksum
+ clc
+ adc #8
+ sta icmp_outp + icmp_cksum
+ bcc :+
+ inc icmp_outp + icmp_cksum + 1
+:
+ lda eth_inp_len ; copy length
+ sta eth_outp_len
+ lda eth_inp_len + 1
+ sta eth_outp_len + 1
+
+ lda #0 ; clear checksum
+ sta ip_outp + ip_header_cksum
+ sta ip_outp + ip_header_cksum + 1
+ ldax #ip_outp ; calculate ip header checksum
+ stax ip_cksum_ptr
+ ldax #20
+ jsr ip_calc_cksum
+ stax ip_outp + ip_header_cksum
+
+ jsr eth_tx ; send packet
+
+ clc
+ rts
+
+
+;add an icmp listener
+;inputs:
+; A = icmp type
+; icmp_callback: vector to call when an icmp packet of specified type arrives
+;outputs:
+; carry flag - set if error, clear if no error
+icmp_add_listener:
+ ldx icmp_cbcount ; any listeners at all?
+ beq @add
+ cpx #icmp_cbmax ; max?
+ beq @full
+ ldx #0
+: cmp icmp_cbtype,x ; check if type is already listened
+ beq @busy
+ inx
+ cpx icmp_cbcount
+ bne :-
+@add:
+ inc icmp_cbcount ; increase counter
+ sta icmp_cbtype,x ; add type
+ lda icmp_callback ; and vector
+ sta icmp_cbveclo,x
+ lda icmp_callback + 1
+ sta icmp_cbvechi,x
+
+ clc
+ rts
+@full:
+@busy:
+ sec
+ rts
+
+
+;remove an icmp listener
+;inputs:
+; A = icmp type
+;outputs:
+; carry flag - set if error (i.e. no listner for this type exists),
+; clear if no error
+icmp_remove_listener:
+ ldx icmp_cbcount ; any listeners installed?
+ beq @notfound
+ dex
+: cmp icmp_cbtype,x ; check if type is listened
+ beq @remove
+ dex
+ bpl :-
+@notfound:
+ sec
+ rts
+@remove:
+ txa ; number of listeners below
+ eor #$ff
+ clc
+ adc icmp_cbcount
+ beq @done
+@move:
+ tay ; number of items to move
+: lda icmp_cbtype + 1,x ; move type
+ sta icmp_cbtype,x
+ lda icmp_cbveclo + 1,x ; move vector lsb
+ sta icmp_cbveclo,x
+ lda icmp_cbvechi + 1,x ; move vector msb
+ sta icmp_cbvechi,x
+ inx
+ dey
+ bne :-
+@done:
+ dec icmp_cbcount ; decrement counter
+ clc
+ rts
+
+.ifdef TCP
+
+; icmp_send_echo was contributed by Glenn Holmer (ShadowM)
+
+;send an ICMP echo ("ping") request
+;inputs:
+; icmp_echo_ip: destination IP address
+;outputs:
+; carry flag - set if error, clear if no error
+icmp_send_echo:
+ ldy #3
+:
+ lda icmp_echo_ip,y
+ sta ip_outp + ip_dest,y
+ dey
+ bpl :-
+
+
+ lda #icmp_msg_type_echo_request
+ sta icmp_outp + icmp_type
+ lda #0 ;not used for echo packets
+ sta icmp_outp + icmp_code
+ sta icmp_outp + icmp_cksum ;clear checksum
+ sta icmp_outp + icmp_cksum + 1
+ sta icmp_outp + icmp_echo_id ;set id to 0
+ sta icmp_outp + icmp_echo_id + 1
+ inc icmp_echo_cnt + 1 ;big-endian
+ bne :+
+ inc icmp_echo_cnt
+:
+ ldax icmp_echo_cnt
+ stax icmp_outp + icmp_echo_seq
+
+ ldy #0
+:
+ lda ip65_msg,y
+ beq @set_ip_len
+ sta icmp_outp + icmp_echo_data,y
+ iny
+ bne :-
+@set_ip_len:
+ tya
+ clc
+ adc #28 ;IP header + ICMP type, code, cksum, id, seq
+ sta ip_outp + ip_len + 1 ;high byte first
+ lda #0 ;will never be >256
+ sta ip_outp + ip_len
+
+ ldax #icmp_outp ;start of ICMP packet
+ stax ip_cksum_ptr
+ tya
+ clc
+ adc #8 ;ICMP type, code, cksum, id, seq
+ ldx #0 ;AX = length of ICMP data
+ jsr ip_calc_cksum
+ stax icmp_outp + icmp_cksum
+ lda #ip_proto_icmp
+ sta ip_outp + ip_proto
+ jsr ip_create_packet
+ jmp ip_send
+
+;send a ping (ICMP echo request) to a remote host, and wait for a response
+;inputs:
+; icmp_echo_ip: destination IP address
+;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:
+ jsr icmp_send_echo
+ bcc @message_sent_ok
+ ;we couldn't send the message - most likely we needed to do an ARP lookup.
+ ;so wait a bit, and retry
+
+ jsr timer_read ; read current timer value
+ stax ping_timer
+@loop_during_arp_lookup:
+
+ jsr ip65_process
+ ldax ping_timer
+ adc #50 ; set timeout to now + 50 ms
+ bcc :+
+ inx
+:
+
+ jsr timer_timeout
+ bcs @loop_during_arp_lookup
+ jsr icmp_send_echo
+ bcc @message_sent_ok
+ ;still can't send? then give up
+ lda #KPR_ERROR_TRANSMIT_FAILED
+ sta ip65_error
+ rts
+@message_sent_ok:
+ jsr timer_read ; read current timer value
+ stax ping_timer
+ ldax #icmp_ping_callback
+ stax icmp_callback
+ lda #icmp_msg_type_echo_reply
+ jsr icmp_add_listener
+ lda #ping_state_request_sent
+ sta ping_state
+@loop_till_get_ping_response:
+ jsr ip65_process
+
+ lda ping_state
+ cmp #ping_state_response_received
+ beq @got_reply
+ ldax ping_timer
+ inx ;x rolls over about 4 times per second
+ inx ;so we will timeout after about 2 seconds
+ inx
+ inx
+ inx
+ inx
+ inx
+ inx
+
+
+ jsr timer_timeout
+ bcs @loop_till_get_ping_response
+ lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
+ sta ip65_error
+ lda #icmp_msg_type_echo_reply
+ jsr icmp_remove_listener
+ sec
+ rts
+@got_reply:
+ lda #icmp_msg_type_echo_reply
+ jsr icmp_remove_listener
+ jsr timer_read
+ sec
+ sbc ping_timer
+ pha
+ txa
+ sbc ping_timer+1
+ tax
+ pla
+ clc
+ rts
+
+icmp_ping_callback:
+ lda icmp_inp + icmp_echo_seq
+ cmp icmp_echo_cnt
+ bne @not_what_we_were_waiting_for
+ lda #ping_state_response_received
+ sta ping_state
+@not_what_we_were_waiting_for:
+ rts
+
+ip65_msg:
+ .byte "ip65 - the 6502 IP stack",0
+.endif
+
+
+;-- LICENSE FOR icmp.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+;
+;Contributor(s): Jonno Downes, Glenn Holmer
+; -- LICENSE END --
diff --git a/client/ip65/ip.s b/ip65/ip.s
similarity index 95%
rename from client/ip65/ip.s
rename to ip65/ip.s
index c454716..f45b3ea 100644
--- a/client/ip65/ip.s
+++ b/ip65/ip.s
@@ -1,510 +1,510 @@
-.include "../inc/common.i"
-
- .export ip_init
- .export ip_process
- .export ip_calc_cksum
- .export ip_create_packet
- .export ip_send
- .export ip_inp
- .export ip_outp
- .export ip_broadcast
- .exportzp ip_ver_ihl
- .exportzp ip_tos
- .exportzp ip_len
- .exportzp ip_id
- .exportzp ip_frag
- .exportzp ip_ttl
- .exportzp ip_proto
- .exportzp ip_header_cksum
- .exportzp ip_src
- .exportzp ip_dest
- .exportzp ip_data
-
- .exportzp ip_proto_icmp
- .exportzp ip_proto_tcp
- .exportzp ip_proto_udp
-
-
- .import cfg_mac
- .import cfg_ip
-
- .import eth_tx
- .import eth_set_proto
- .import eth_inp
- .import eth_inp_len
- .import eth_outp
- .import eth_outp_len
-
- .importzp eth_dest
- .importzp eth_src
- .importzp eth_type
- .importzp eth_data
- .importzp eth_proto_ip
- .importzp eth_proto_arp
-
- .import arp_lookup
- .import arp_mac
- .import arp_ip
-
- .import icmp_init
- .import icmp_process
-
- .import udp_init
- .import udp_process
-
-.ifdef TCP
- .import tcp_init
- .import tcp_process
-.endif
- .importzp copy_src
- .importzp copy_dest
- .exportzp ip_cksum_ptr
- ip_cksum_ptr=copy_dest
-
-
-
-
-.bss
-
-ip_cksum_len: .res 2 ; length of data to be checksummed
-
-; ip packets start at ethernet packet + 14
-ip_inp = eth_inp + eth_data ;pointer to start of IP packet in input ethernet frame
-ip_outp = eth_outp + eth_data ;pointer to start of IP packet in output ethernet frame
-
-; temp storage for size calculation
-len: .res 2
-
-; flag for incoming broadcast packets
-ip_broadcast: .res 1 ;flag set when an incoming IP packet was sent to a broadcast address
-
-; ip packet offsets
-ip_ver_ihl = 0 ;offset of 4 bit "version" field and 4 bit "header length" field in an IP packet header
-ip_tos = 1 ;offset of "type of service" field in an IP packet header
-ip_len = 2 ;offset of "length" field in an IP packet header
-ip_id = 4 ;offset of "identification" field in an IP packet header
-ip_frag = 6 ;offset of "fragmentation offset" field in an IP packet header
-ip_ttl = 8 ;offset of "time to live" field in an IP packet header
-ip_proto = 9 ;offset of "protocol number" field in an IP packet header
-ip_header_cksum = 10 ;offset of "ip header checksum" field in an IP packet header
-ip_src = 12 ;offset of "source address" field in an IP packet header
-ip_dest = 16 ;offset of "destination address" field in an IP packet header
-ip_data = 20 ;offset of data payload in an IP packet
-
-; ip protocols
-
-ip_proto_icmp = 1
-ip_proto_tcp = 6
-ip_proto_udp = 17
-
-
-; temp for calculating checksum
-cksum: .res 3
-
-; bad packet counters
-bad_header: .res 2
-bad_addr: .res 2
-
-
- .code
-
-; initialize ip routines
-; inputs: none
-; outputs: none
-ip_init:
- lda #0
- sta bad_header
- sta bad_header + 1
- sta bad_addr
- sta bad_addr + 1
-
- jsr icmp_init
-.ifdef TCP
- jsr tcp_init
-.endif
- jsr udp_init
-
- rts
-
-
-;process an incoming packet & call the appropriate protocol handler
-;inputs:
-; eth_inp: should point to the received ethernet packet
-;outputs:
-; carry flag - set on any error, clear if OK
-; depending on the packet contents and the protocol handler, a response
-; message may be generated and sent out (overwriting eth_outp buffer)
-ip_process:
- jsr verifyheader ; ver, ihl, len, frag, checksum
- bcc @ok
-@badpacket:
-
- sec
- rts
-@ok:
- jsr checkaddr ; make sure it's meant for us
- bcs @badpacket
-
- lda ip_inp + ip_proto
- cmp #ip_proto_icmp
- bne :+
- jmp icmp_process ; jump to icmp handler
-.ifdef TCP
-: cmp #ip_proto_tcp
- bne :+
- jmp tcp_process ; jump to tcp handler
-.endif
-: cmp #ip_proto_udp
- bne :+
- jmp udp_process ; jump to udp handler
-:
-unknown_protocol:
- sec ; unknown protocol
- rts
-
-
-; verify that header contains what we expect
-verifyheader:
- lda ip_inp + ip_ver_ihl ; IPv4 and no IP options
- cmp #$45
- bne @badpacket
-
-; lda ip_inp + ip_tos ; ignore ToS
-
- lda ip_inp + ip_len + 1 ; ip + 14 bytes ethernet header
- clc
- adc #14
- sta len
- lda ip_inp + ip_len
- adc #0
- sta len + 1
-
- lda eth_inp_len ; check if advertised length is shorter
- sec ; than actual length
- sbc len
- lda eth_inp_len + 1
- sbc len + 1
- bmi @badpacket
-
- lda ip_inp + ip_frag ; check for fragmentation
- beq :+
- cmp #$40
- bne @badpacket
-: lda ip_inp + ip_frag + 1
- bne @badpacket
-
-
- ;it is possible that the checksum has not been set in inbound packets
- ;this is especially likely to happen if we are running in an emulator on a host machine that
- ;does checksum offloading (i.e. where the NIC calculates the checksum) and then
- ;try to send traffic from the host to the emulated computer (e.g. ip65 running on AppleWin or VICE)
- ;in this case the traffic will be seen by the emulated computer BEFORE the host NIC
- ;has calculated the checksum
- ;so if the checksum field in the inbound packet is 0000, ignore it
- lda ip_inp+10
- bne @has_cksum
- lda ip_inp+11
- bne @has_cksum
- clc
- rts
-
-@has_cksum:
- ldax #ip_inp ; verify checksum
- stax ip_cksum_ptr
- ldax #20
- jsr ip_calc_cksum
- cmp #0
- bne @badpacket
- cpx #0
- bne @badpacket
-
- clc
- rts
-@badpacket:
- brk
- inc bad_header
- bne :+
- inc bad_header + 1
-: sec
- rts
-
-
-; check that this packet was addressed to us
-checkaddr:
- lda #0
- sta ip_broadcast
- lda ip_inp + ip_dest ; compare ip address
- cmp cfg_ip
- bne @broadcast
- lda ip_inp + ip_dest + 1
- cmp cfg_ip + 1
- bne @broadcast
- lda ip_inp + ip_dest + 2
- cmp cfg_ip + 2
- bne @broadcast
- lda ip_inp + ip_dest + 3
- cmp cfg_ip + 3
- bne @broadcast
-@ok: clc
- rts
-@broadcast:
-;jonno 2011-01-2
-;previously this was just checking for 255.255.255.255
-;however it is also possible to do a broadcast to a specific subnet, e.g. 10.5.1.255
-;this is particularly common with NETBIOS over TCP
-;we really should use the netmask, but as a kludge, just see if last octet is 255.
-;this will work on a /24 network
-;
- inc ip_broadcast
-; lda ip_inp + ip_dest ; check for broadcast
-; and ip_inp + ip_dest + 1
-; and ip_inp + ip_dest + 2
-; and ip_inp + ip_dest + 3
- lda ip_inp + ip_dest +3 ; check for broadcast
- cmp #$ff
- beq @ok
- inc bad_addr
-
- bne :+
- inc bad_addr + 1
-: sec
- rts
-
-
-; create an IP header (with all the appropriate flags and common fields set) inside an
-; ethernet frame
-;inputs:
-; eth_outp: should point to a buffer in which the ethernet frame is being built
-;outputs:
-; eth_outp: contains an IP header with version, TTL, flags, src address & IP header
-; checksum fields set.
-ip_create_packet:
- lda #$45 ; set IP version and header length
- sta ip_outp + ip_ver_ihl
-
- lda #0 ; set type of service
- sta ip_outp + ip_tos
-
- ; skip length
-
- ; skip ID
-
- lda #$40 ; don't fragment - or should we not care?
- sta ip_outp + ip_frag
- lda #0
- sta ip_outp + ip_frag + 1
-
- lda #$40 ; set time to live
- sta ip_outp + ip_ttl
-
- ; skip protocol
-
- lda #0 ; clear checksum
- sta ip_outp + ip_header_cksum
- sta ip_outp + ip_header_cksum + 1
-
- ldx #3 ; copy source address
-: lda cfg_ip,x
- sta ip_outp + ip_src,x
- dex
- bpl :-
-
- ; skip destination address
-
- rts
-
-
-; send an IP packet
-;inputs
-; eth_outp: should point to an ethernet frame that has an IP header created (by
-; calling ip_create_packet)
-; ip_len: should contain length of IP packet (header + data)
-; ip_id: should contain an ID that is unique for each packet
-; ip_protocol: should contain protocol ID
-; ip_dest: should contain the destination IP address
-;outputs:
-; eth_outp: ethernet frame updated with correct IP header, then sent out over
-; the wire
-; carry flag - set on any error, clear if OK
-ip_send:
- ldx #3 ; get mac addr from ip
-: lda ip_outp + ip_dest,x
- sta arp_ip,x
- dex
- bpl :-
-
- jsr arp_lookup
- bcc :+
- rts ; packet buffer nuked, fail
-:
- ldax #ip_outp ; calculate ip header checksum
- stax ip_cksum_ptr
- ldax #20
- jsr ip_calc_cksum
- stax ip_outp + ip_header_cksum
-
- ldx #5
-: lda arp_mac,x ; copy destination mac address
- sta eth_outp + eth_dest,x
- lda cfg_mac,x ; copy my mac address
- sta eth_outp + eth_src,x
- dex
- bpl :-
-
- lda #eth_proto_ip ; set type to IP
- jsr eth_set_proto
-
- lda ip_outp + ip_len + 1 ; set packet length
- lsr
- bcc @dontpad
-
- rol ; pad with 0
- ;clc
- adc #ip_outp
- sta copy_src + 1
- ldy #0
- tya
- sta (copy_src),y
-
- sec ; round up to even number
-@dontpad:
- lda ip_outp + ip_len + 1
- adc #eth_data
- sta eth_outp_len
- lda ip_outp + ip_len
- adc #0
- sta eth_outp_len + 1
-
- ;jsr dbg_dump_ip_header
-
- jmp eth_tx ; send packet and return status
-
-
-; calculate checksum for a buffer according to the standard IP checksum algorithm
-; David Schmidt discovered errors in the original ip65 implementation, and he replaced
-; this with an implementation from the contiki project (http://www.sics.se/contiki/)
-; when incorporating ip65 into ADTPro (http://adtpro.sourceforge.net/)
-; So I have cribbed that version from
-; http://adtpro.cvs.sourceforge.net/viewvc/adtpro/adtpro/client/src/ip65/ip.s
-;inputs:
-; ip_cksum_ptr: points at buffer to be checksummed
-; AX: length of buffer to be checksumed
-;outputs:
-; AX: checkum of buffer
-ip_calc_cksum:
- sta ip_cksum_len ; save length
- stx ip_cksum_len + 1
-
- lda #0
- sta cksum
- sta cksum+1
-
- lda ip_cksum_len+1
- beq chksumlast
-
-; If checksum is > 256, do the first runs.
- ldy #0
- clc
-chksumloop_256:
- lda (ip_cksum_ptr),y
- adc cksum
- sta cksum
- iny
- lda (ip_cksum_ptr),y
- adc cksum+1
- sta cksum+1
- iny
- bne chksumloop_256
- inc ip_cksum_ptr+1
- dec ip_cksum_len+1
- bne chksumloop_256
-
-chksum_endloop_256:
- lda cksum
- adc #0
- sta cksum
- lda cksum+1
- adc #0
- sta cksum+1
- bcs chksum_endloop_256
-
-chksumlast:
- lda ip_cksum_len
- lsr
- bcc chksum_noodd
- ldy ip_cksum_len
- dey
- lda (ip_cksum_ptr),y
- clc
- adc cksum
- sta cksum
- bcc noinc1
- inc cksum+1
- bne noinc1
- inc cksum
-noinc1:
- dec ip_cksum_len
-
-chksum_noodd:
- clc
- php
- ldy ip_cksum_len
-chksum_loop1:
- cpy #0
- beq chksum_loop1_end
- plp
- dey
- dey
- lda (ip_cksum_ptr),y
- adc cksum
- sta cksum
- iny
- lda (ip_cksum_ptr),y
- adc cksum+1
- sta cksum+1
- dey
- php
- jmp chksum_loop1
-chksum_loop1_end:
- plp
-
-chksum_endloop:
- lda cksum
- adc #0
- sta cksum
- lda cksum+1
- adc #0
- sta cksum+1
- bcs chksum_endloop
-
- lda cksum+1
- eor #$ff
- tax
- lda cksum
- eor #$ff
-
- rts
-
-
-
-;-- LICENSE FOR ip.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+.include "../inc/common.i"
+
+ .export ip_init
+ .export ip_process
+ .export ip_calc_cksum
+ .export ip_create_packet
+ .export ip_send
+ .export ip_inp
+ .export ip_outp
+ .export ip_broadcast
+ .exportzp ip_ver_ihl
+ .exportzp ip_tos
+ .exportzp ip_len
+ .exportzp ip_id
+ .exportzp ip_frag
+ .exportzp ip_ttl
+ .exportzp ip_proto
+ .exportzp ip_header_cksum
+ .exportzp ip_src
+ .exportzp ip_dest
+ .exportzp ip_data
+
+ .exportzp ip_proto_icmp
+ .exportzp ip_proto_tcp
+ .exportzp ip_proto_udp
+
+
+ .import cfg_mac
+ .import cfg_ip
+
+ .import eth_tx
+ .import eth_set_proto
+ .import eth_inp
+ .import eth_inp_len
+ .import eth_outp
+ .import eth_outp_len
+
+ .importzp eth_dest
+ .importzp eth_src
+ .importzp eth_type
+ .importzp eth_data
+ .importzp eth_proto_ip
+ .importzp eth_proto_arp
+
+ .import arp_lookup
+ .import arp_mac
+ .import arp_ip
+
+ .import icmp_init
+ .import icmp_process
+
+ .import udp_init
+ .import udp_process
+
+.ifdef TCP
+ .import tcp_init
+ .import tcp_process
+.endif
+ .importzp copy_src
+ .importzp copy_dest
+ .exportzp ip_cksum_ptr
+ ip_cksum_ptr=copy_dest
+
+
+
+
+.bss
+
+ip_cksum_len: .res 2 ; length of data to be checksummed
+
+; ip packets start at ethernet packet + 14
+ip_inp = eth_inp + eth_data ;pointer to start of IP packet in input ethernet frame
+ip_outp = eth_outp + eth_data ;pointer to start of IP packet in output ethernet frame
+
+; temp storage for size calculation
+len: .res 2
+
+; flag for incoming broadcast packets
+ip_broadcast: .res 1 ;flag set when an incoming IP packet was sent to a broadcast address
+
+; ip packet offsets
+ip_ver_ihl = 0 ;offset of 4 bit "version" field and 4 bit "header length" field in an IP packet header
+ip_tos = 1 ;offset of "type of service" field in an IP packet header
+ip_len = 2 ;offset of "length" field in an IP packet header
+ip_id = 4 ;offset of "identification" field in an IP packet header
+ip_frag = 6 ;offset of "fragmentation offset" field in an IP packet header
+ip_ttl = 8 ;offset of "time to live" field in an IP packet header
+ip_proto = 9 ;offset of "protocol number" field in an IP packet header
+ip_header_cksum = 10 ;offset of "ip header checksum" field in an IP packet header
+ip_src = 12 ;offset of "source address" field in an IP packet header
+ip_dest = 16 ;offset of "destination address" field in an IP packet header
+ip_data = 20 ;offset of data payload in an IP packet
+
+; ip protocols
+
+ip_proto_icmp = 1
+ip_proto_tcp = 6
+ip_proto_udp = 17
+
+
+; temp for calculating checksum
+cksum: .res 3
+
+; bad packet counters
+bad_header: .res 2
+bad_addr: .res 2
+
+
+ .code
+
+; initialize ip routines
+; inputs: none
+; outputs: none
+ip_init:
+ lda #0
+ sta bad_header
+ sta bad_header + 1
+ sta bad_addr
+ sta bad_addr + 1
+
+ jsr icmp_init
+.ifdef TCP
+ jsr tcp_init
+.endif
+ jsr udp_init
+
+ rts
+
+
+;process an incoming packet & call the appropriate protocol handler
+;inputs:
+; eth_inp: should point to the received ethernet packet
+;outputs:
+; carry flag - set on any error, clear if OK
+; depending on the packet contents and the protocol handler, a response
+; message may be generated and sent out (overwriting eth_outp buffer)
+ip_process:
+ jsr verifyheader ; ver, ihl, len, frag, checksum
+ bcc @ok
+@badpacket:
+
+ sec
+ rts
+@ok:
+ jsr checkaddr ; make sure it's meant for us
+ bcs @badpacket
+
+ lda ip_inp + ip_proto
+ cmp #ip_proto_icmp
+ bne :+
+ jmp icmp_process ; jump to icmp handler
+.ifdef TCP
+: cmp #ip_proto_tcp
+ bne :+
+ jmp tcp_process ; jump to tcp handler
+.endif
+: cmp #ip_proto_udp
+ bne :+
+ jmp udp_process ; jump to udp handler
+:
+unknown_protocol:
+ sec ; unknown protocol
+ rts
+
+
+; verify that header contains what we expect
+verifyheader:
+ lda ip_inp + ip_ver_ihl ; IPv4 and no IP options
+ cmp #$45
+ bne @badpacket
+
+; lda ip_inp + ip_tos ; ignore ToS
+
+ lda ip_inp + ip_len + 1 ; ip + 14 bytes ethernet header
+ clc
+ adc #14
+ sta len
+ lda ip_inp + ip_len
+ adc #0
+ sta len + 1
+
+ lda eth_inp_len ; check if advertised length is shorter
+ sec ; than actual length
+ sbc len
+ lda eth_inp_len + 1
+ sbc len + 1
+ bmi @badpacket
+
+ lda ip_inp + ip_frag ; check for fragmentation
+ beq :+
+ cmp #$40
+ bne @badpacket
+: lda ip_inp + ip_frag + 1
+ bne @badpacket
+
+
+ ;it is possible that the checksum has not been set in inbound packets
+ ;this is especially likely to happen if we are running in an emulator on a host machine that
+ ;does checksum offloading (i.e. where the NIC calculates the checksum) and then
+ ;try to send traffic from the host to the emulated computer (e.g. ip65 running on AppleWin or VICE)
+ ;in this case the traffic will be seen by the emulated computer BEFORE the host NIC
+ ;has calculated the checksum
+ ;so if the checksum field in the inbound packet is 0000, ignore it
+ lda ip_inp+10
+ bne @has_cksum
+ lda ip_inp+11
+ bne @has_cksum
+ clc
+ rts
+
+@has_cksum:
+ ldax #ip_inp ; verify checksum
+ stax ip_cksum_ptr
+ ldax #20
+ jsr ip_calc_cksum
+ cmp #0
+ bne @badpacket
+ cpx #0
+ bne @badpacket
+
+ clc
+ rts
+@badpacket:
+ brk
+ inc bad_header
+ bne :+
+ inc bad_header + 1
+: sec
+ rts
+
+
+; check that this packet was addressed to us
+checkaddr:
+ lda #0
+ sta ip_broadcast
+ lda ip_inp + ip_dest ; compare ip address
+ cmp cfg_ip
+ bne @broadcast
+ lda ip_inp + ip_dest + 1
+ cmp cfg_ip + 1
+ bne @broadcast
+ lda ip_inp + ip_dest + 2
+ cmp cfg_ip + 2
+ bne @broadcast
+ lda ip_inp + ip_dest + 3
+ cmp cfg_ip + 3
+ bne @broadcast
+@ok: clc
+ rts
+@broadcast:
+;jonno 2011-01-2
+;previously this was just checking for 255.255.255.255
+;however it is also possible to do a broadcast to a specific subnet, e.g. 10.5.1.255
+;this is particularly common with NETBIOS over TCP
+;we really should use the netmask, but as a kludge, just see if last octet is 255.
+;this will work on a /24 network
+;
+ inc ip_broadcast
+; lda ip_inp + ip_dest ; check for broadcast
+; and ip_inp + ip_dest + 1
+; and ip_inp + ip_dest + 2
+; and ip_inp + ip_dest + 3
+ lda ip_inp + ip_dest +3 ; check for broadcast
+ cmp #$ff
+ beq @ok
+ inc bad_addr
+
+ bne :+
+ inc bad_addr + 1
+: sec
+ rts
+
+
+; create an IP header (with all the appropriate flags and common fields set) inside an
+; ethernet frame
+;inputs:
+; eth_outp: should point to a buffer in which the ethernet frame is being built
+;outputs:
+; eth_outp: contains an IP header with version, TTL, flags, src address & IP header
+; checksum fields set.
+ip_create_packet:
+ lda #$45 ; set IP version and header length
+ sta ip_outp + ip_ver_ihl
+
+ lda #0 ; set type of service
+ sta ip_outp + ip_tos
+
+ ; skip length
+
+ ; skip ID
+
+ lda #$40 ; don't fragment - or should we not care?
+ sta ip_outp + ip_frag
+ lda #0
+ sta ip_outp + ip_frag + 1
+
+ lda #$40 ; set time to live
+ sta ip_outp + ip_ttl
+
+ ; skip protocol
+
+ lda #0 ; clear checksum
+ sta ip_outp + ip_header_cksum
+ sta ip_outp + ip_header_cksum + 1
+
+ ldx #3 ; copy source address
+: lda cfg_ip,x
+ sta ip_outp + ip_src,x
+ dex
+ bpl :-
+
+ ; skip destination address
+
+ rts
+
+
+; send an IP packet
+;inputs
+; eth_outp: should point to an ethernet frame that has an IP header created (by
+; calling ip_create_packet)
+; ip_len: should contain length of IP packet (header + data)
+; ip_id: should contain an ID that is unique for each packet
+; ip_protocol: should contain protocol ID
+; ip_dest: should contain the destination IP address
+;outputs:
+; eth_outp: ethernet frame updated with correct IP header, then sent out over
+; the wire
+; carry flag - set on any error, clear if OK
+ip_send:
+ ldx #3 ; get mac addr from ip
+: lda ip_outp + ip_dest,x
+ sta arp_ip,x
+ dex
+ bpl :-
+
+ jsr arp_lookup
+ bcc :+
+ rts ; packet buffer nuked, fail
+:
+ ldax #ip_outp ; calculate ip header checksum
+ stax ip_cksum_ptr
+ ldax #20
+ jsr ip_calc_cksum
+ stax ip_outp + ip_header_cksum
+
+ ldx #5
+: lda arp_mac,x ; copy destination mac address
+ sta eth_outp + eth_dest,x
+ lda cfg_mac,x ; copy my mac address
+ sta eth_outp + eth_src,x
+ dex
+ bpl :-
+
+ lda #eth_proto_ip ; set type to IP
+ jsr eth_set_proto
+
+ lda ip_outp + ip_len + 1 ; set packet length
+ lsr
+ bcc @dontpad
+
+ rol ; pad with 0
+ ;clc
+ adc #ip_outp
+ sta copy_src + 1
+ ldy #0
+ tya
+ sta (copy_src),y
+
+ sec ; round up to even number
+@dontpad:
+ lda ip_outp + ip_len + 1
+ adc #eth_data
+ sta eth_outp_len
+ lda ip_outp + ip_len
+ adc #0
+ sta eth_outp_len + 1
+
+ ;jsr dbg_dump_ip_header
+
+ jmp eth_tx ; send packet and return status
+
+
+; calculate checksum for a buffer according to the standard IP checksum algorithm
+; David Schmidt discovered errors in the original ip65 implementation, and he replaced
+; this with an implementation from the contiki project (http://www.sics.se/contiki/)
+; when incorporating ip65 into ADTPro (http://adtpro.sourceforge.net/)
+; So I have cribbed that version from
+; http://adtpro.cvs.sourceforge.net/viewvc/adtpro/adtpro/client/src/ip65/ip.s
+;inputs:
+; ip_cksum_ptr: points at buffer to be checksummed
+; AX: length of buffer to be checksumed
+;outputs:
+; AX: checkum of buffer
+ip_calc_cksum:
+ sta ip_cksum_len ; save length
+ stx ip_cksum_len + 1
+
+ lda #0
+ sta cksum
+ sta cksum+1
+
+ lda ip_cksum_len+1
+ beq chksumlast
+
+; If checksum is > 256, do the first runs.
+ ldy #0
+ clc
+chksumloop_256:
+ lda (ip_cksum_ptr),y
+ adc cksum
+ sta cksum
+ iny
+ lda (ip_cksum_ptr),y
+ adc cksum+1
+ sta cksum+1
+ iny
+ bne chksumloop_256
+ inc ip_cksum_ptr+1
+ dec ip_cksum_len+1
+ bne chksumloop_256
+
+chksum_endloop_256:
+ lda cksum
+ adc #0
+ sta cksum
+ lda cksum+1
+ adc #0
+ sta cksum+1
+ bcs chksum_endloop_256
+
+chksumlast:
+ lda ip_cksum_len
+ lsr
+ bcc chksum_noodd
+ ldy ip_cksum_len
+ dey
+ lda (ip_cksum_ptr),y
+ clc
+ adc cksum
+ sta cksum
+ bcc noinc1
+ inc cksum+1
+ bne noinc1
+ inc cksum
+noinc1:
+ dec ip_cksum_len
+
+chksum_noodd:
+ clc
+ php
+ ldy ip_cksum_len
+chksum_loop1:
+ cpy #0
+ beq chksum_loop1_end
+ plp
+ dey
+ dey
+ lda (ip_cksum_ptr),y
+ adc cksum
+ sta cksum
+ iny
+ lda (ip_cksum_ptr),y
+ adc cksum+1
+ sta cksum+1
+ dey
+ php
+ jmp chksum_loop1
+chksum_loop1_end:
+ plp
+
+chksum_endloop:
+ lda cksum
+ adc #0
+ sta cksum
+ lda cksum+1
+ adc #0
+ sta cksum+1
+ bcs chksum_endloop
+
+ lda cksum+1
+ eor #$ff
+ tax
+ lda cksum
+ eor #$ff
+
+ rts
+
+
+
+;-- LICENSE FOR ip.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/ip65.s b/ip65/ip65.s
similarity index 96%
rename from client/ip65/ip65.s
rename to ip65/ip65.s
index 3f47618..82b6182 100644
--- a/client/ip65/ip65.s
+++ b/ip65/ip65.s
@@ -1,147 +1,147 @@
-; ip65 main routines
-
-.include "../inc/common.i"
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- .export ip65_init
- .export ip65_process
- .export ip65_random_word
- .export ip65_ctr
- .export ip65_ctr_arp
- .export ip65_ctr_ip
-
- .export ip65_error
-
- .import cfg_init
-
- .import eth_init
- .import timer_init
- .import arp_init
- .import ip_init
- .import timer_read
-
- .import eth_inp
- .import eth_outp
- .import eth_rx
-
- .import ip_process
- .import arp_process
-
- .importzp eth_proto_arp
-
- .export ip65_random_word
-
- .bss
-
-
-ip65_ctr: .res 1 ; incremented for every incoming packet
-ip65_ctr_arp: .res 1 ; incremented for every incoming arp packet
-ip65_ctr_ip: .res 1 ; incremented for every incoming ip packet
-
-ip65_error: .res 1 ;last error code
-
- .code
-
-;generate a 'random' 16 bit word
-;entropy comes from the last ethernet frame, counters, and timer
-;inputs: none
-;outputs: AX set to a pseudo-random 16 bit number
-ip65_random_word:
- jsr timer_read ;sets AX
- 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
- ora #$08 ;make sure we grab at least 8 bytes from eth_inp
- tax
-:
- adc eth_inp,x
- adc eth_outp,x
- dex
- bne :-
- tax
- pla
- adc ip65_ctr
- eor ip65_ctr_ip
- rts
-
-; initialise the IP stack
-; this calls the individual protocol & driver initialisations, so this is
-; the only *_init routine that must be called by a user application,
-; except for dhcp_init which must also be called if the application
-; is using dhcp rather than hardcoded ip configuration
-; inputs: none
-; outputs: none
-ip65_init:
- jsr cfg_init ;copy default values (including MAC address) to RAM
- jsr eth_init ; initialize ethernet driver
-
- bcc @ok
- lda #KPR_ERROR_DEVICE_FAILURE
- sta ip65_error
- rts
-@ok:
- jsr timer_init ; initialize timer
- jsr arp_init ; initialize arp
- jsr ip_init ; initialize ip, icmp, udp, and tcp
- clc
- rts
-
-
-;main ip polling loop
-;this routine should be periodically called by an application at any time
-;that an inbound packet needs to be handled.
-;it is 'non-blocking', i.e. it will return if there is no packet waiting to be
-;handled. any inbound packet will be handed off to the appropriate handler.
-;inputs: none
-;outputs: carry flag set if no packet was waiting, or packet handling caused error.
-; since the inbound packet may trigger generation of an outbound, eth_outp
-; and eth_outp_len may be overwriiten.
-ip65_process:
- jsr eth_rx ; check for incoming packets
- bcs @done
-
- lda eth_inp + 12 ; type should be 08xx
- cmp #8
- bne @done
-
- lda eth_inp + 13
-; cmp #eth_proto_ip ; ip = 00
- beq @ip
- cmp #eth_proto_arp ; arp = 06
- beq @arp
-@done:
- rts
-
-@arp:
- inc ip65_ctr_arp
- jmp arp_process
-
-@ip:
- inc ip65_ctr_ip
- jmp ip_process
-
-
-
-;-- LICENSE FOR ip65.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+; ip65 main routines
+
+.include "../inc/common.i"
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+ .export ip65_init
+ .export ip65_process
+ .export ip65_random_word
+ .export ip65_ctr
+ .export ip65_ctr_arp
+ .export ip65_ctr_ip
+
+ .export ip65_error
+
+ .import cfg_init
+
+ .import eth_init
+ .import timer_init
+ .import arp_init
+ .import ip_init
+ .import timer_read
+
+ .import eth_inp
+ .import eth_outp
+ .import eth_rx
+
+ .import ip_process
+ .import arp_process
+
+ .importzp eth_proto_arp
+
+ .export ip65_random_word
+
+ .bss
+
+
+ip65_ctr: .res 1 ; incremented for every incoming packet
+ip65_ctr_arp: .res 1 ; incremented for every incoming arp packet
+ip65_ctr_ip: .res 1 ; incremented for every incoming ip packet
+
+ip65_error: .res 1 ;last error code
+
+ .code
+
+;generate a 'random' 16 bit word
+;entropy comes from the last ethernet frame, counters, and timer
+;inputs: none
+;outputs: AX set to a pseudo-random 16 bit number
+ip65_random_word:
+ jsr timer_read ;sets AX
+ 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
+ ora #$08 ;make sure we grab at least 8 bytes from eth_inp
+ tax
+:
+ adc eth_inp,x
+ adc eth_outp,x
+ dex
+ bne :-
+ tax
+ pla
+ adc ip65_ctr
+ eor ip65_ctr_ip
+ rts
+
+; initialise the IP stack
+; this calls the individual protocol & driver initialisations, so this is
+; the only *_init routine that must be called by a user application,
+; except for dhcp_init which must also be called if the application
+; is using dhcp rather than hardcoded ip configuration
+; inputs: none
+; outputs: none
+ip65_init:
+ jsr cfg_init ;copy default values (including MAC address) to RAM
+ jsr eth_init ; initialize ethernet driver
+
+ bcc @ok
+ lda #KPR_ERROR_DEVICE_FAILURE
+ sta ip65_error
+ rts
+@ok:
+ jsr timer_init ; initialize timer
+ jsr arp_init ; initialize arp
+ jsr ip_init ; initialize ip, icmp, udp, and tcp
+ clc
+ rts
+
+
+;main ip polling loop
+;this routine should be periodically called by an application at any time
+;that an inbound packet needs to be handled.
+;it is 'non-blocking', i.e. it will return if there is no packet waiting to be
+;handled. any inbound packet will be handed off to the appropriate handler.
+;inputs: none
+;outputs: carry flag set if no packet was waiting, or packet handling caused error.
+; since the inbound packet may trigger generation of an outbound, eth_outp
+; and eth_outp_len may be overwriiten.
+ip65_process:
+ jsr eth_rx ; check for incoming packets
+ bcs @done
+
+ lda eth_inp + 12 ; type should be 08xx
+ cmp #8
+ bne @done
+
+ lda eth_inp + 13
+; cmp #eth_proto_ip ; ip = 00
+ beq @ip
+ cmp #eth_proto_arp ; arp = 06
+ beq @arp
+@done:
+ rts
+
+@arp:
+ inc ip65_ctr_arp
+ jmp arp_process
+
+@ip:
+ inc ip65_ctr_ip
+ jmp ip_process
+
+
+
+;-- LICENSE FOR ip65.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/output_buffer.s b/ip65/output_buffer.s
similarity index 97%
rename from client/ip65/output_buffer.s
rename to ip65/output_buffer.s
index 17e100b..130fee1 100644
--- a/client/ip65/output_buffer.s
+++ b/ip65/output_buffer.s
@@ -1,27 +1,27 @@
-.bss
-
-;global scratch buffer that DHCP/DNS/TFTP and others can use while building outbound packets.
-;you need to be careful if using this that you don't call a function that also uses it.
-;if this is reserved for higher level protocols, the likelyhood of collision is low.
-.export output_buffer
-output_buffer: .res 520
-
-
-;-- LICENSE FOR output_buffer.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 --
+.bss
+
+;global scratch buffer that DHCP/DNS/TFTP and others can use while building outbound packets.
+;you need to be careful if using this that you don't call a function that also uses it.
+;if this is reserved for higher level protocols, the likelyhood of collision is low.
+.export output_buffer
+output_buffer: .res 520
+
+
+;-- LICENSE FOR output_buffer.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/ip65/parser.s b/ip65/parser.s
similarity index 95%
rename from client/ip65/parser.s
rename to ip65/parser.s
index 355926f..a7c5825 100644
--- a/client/ip65/parser.s
+++ b/ip65/parser.s
@@ -1,104 +1,104 @@
-;text file parsing routines
-; first call parser_init
-; then call parser_skip_next
-
-.export parser_init
-.export parser_skip_next
-.importzp copy_src
-.importzp copy_dest
-
-
-target_string=copy_src
-search_string=copy_dest
-
-.include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.bss
-temp_ptr: .res 2
-
-.segment "SELF_MODIFIED_CODE"
-get_next_byte:
-current_string_ptr=get_next_byte+1
- lda $ffff
- inc current_string_ptr
- bne :+
- inc current_string_ptr+1
-:
- pha
- pla ;reload A so flags are set correctly
- rts
-
-.code
-
-;set up a string for parsing
-;inputs: AX = pointer to (null terminated) string to be parsed
-;outputs: none
-parser_init:
- stax current_string_ptr
- clc
- rts
-
-
-;advance pointer along till just past the next occurance of specified string
-;inputs: AX= pointer to (null terminated) string to search for
-;outputs: sec if search string not found
-; if clc, AX = pointer to first byte after string specified
-; if sec (i.e. no match found), pointer stays in same place
-parser_skip_next:
- stax search_string
- ldax current_string_ptr
- stax temp_ptr
-@check_string:
- ldy #0
- ldax current_string_ptr
- stax target_string
-@check_next_char:
- lda (search_string),y
- beq @matched
- cmp (target_string),y
- bne @not_matched
- iny
- bne @check_next_char
-@matched:
- ;now skip 'y' bytes
-
-@skip_byte:
- jsr get_next_byte
- dey
- bne @skip_byte
-
- ldax current_string_ptr
- clc
- rts
- @not_matched:
- jsr get_next_byte
- bne @check_string
- ldax temp_ptr
- stax current_string_ptr
- sec
- rts
-
-
-
-;-- LICENSE FOR parser.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 --
+;text file parsing routines
+; first call parser_init
+; then call parser_skip_next
+
+.export parser_init
+.export parser_skip_next
+.importzp copy_src
+.importzp copy_dest
+
+
+target_string=copy_src
+search_string=copy_dest
+
+.include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.bss
+temp_ptr: .res 2
+
+.segment "SELF_MODIFIED_CODE"
+get_next_byte:
+current_string_ptr=get_next_byte+1
+ lda $ffff
+ inc current_string_ptr
+ bne :+
+ inc current_string_ptr+1
+:
+ pha
+ pla ;reload A so flags are set correctly
+ rts
+
+.code
+
+;set up a string for parsing
+;inputs: AX = pointer to (null terminated) string to be parsed
+;outputs: none
+parser_init:
+ stax current_string_ptr
+ clc
+ rts
+
+
+;advance pointer along till just past the next occurance of specified string
+;inputs: AX= pointer to (null terminated) string to search for
+;outputs: sec if search string not found
+; if clc, AX = pointer to first byte after string specified
+; if sec (i.e. no match found), pointer stays in same place
+parser_skip_next:
+ stax search_string
+ ldax current_string_ptr
+ stax temp_ptr
+@check_string:
+ ldy #0
+ ldax current_string_ptr
+ stax target_string
+@check_next_char:
+ lda (search_string),y
+ beq @matched
+ cmp (target_string),y
+ bne @not_matched
+ iny
+ bne @check_next_char
+@matched:
+ ;now skip 'y' bytes
+
+@skip_byte:
+ jsr get_next_byte
+ dey
+ bne @skip_byte
+
+ ldax current_string_ptr
+ clc
+ rts
+ @not_matched:
+ jsr get_next_byte
+ bne @check_string
+ ldax temp_ptr
+ stax current_string_ptr
+ sec
+ rts
+
+
+
+;-- LICENSE FOR parser.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/ip65/printf.s b/ip65/printf.s
similarity index 92%
rename from client/ip65/printf.s
rename to ip65/printf.s
index 63e4a60..e4781c8 100644
--- a/client/ip65/printf.s
+++ b/ip65/printf.s
@@ -1,428 +1,428 @@
-.include "../inc/common.i"
-
- .export console_printf
-
-
- .import console_out
- .import console_strout
-
-
- .segment "IP65ZP" : zeropage
-
-strptr: .res 2
-argptr: .res 2
-valptr: .res 2
-
-
- .bss
-
-ysave: .res 1
-arg: .res 1
-fieldwidth: .res 1
-fieldwcnt: .res 1
-leadzero: .res 1
-argtemp: .res 1
-int: .res 2
-num: .res 5
-ext: .res 2
-
-
- .code
-
-;print a string to console, with (some) standard printf % codes converted
-;inputs: AX = pointer to 'argument list'
-; first word in argument list is the string to be printed
-; subsequent words in argument list are interpolated in to the string as
-; it is displayed. (argument list is automagically created by the 'printf' macro
-; defined in inc/printf.i)
-;outputs: none
-;supported % codes:
-; %s: string (argument interpreted as pointer to null terminated string)
-; %d: decimal number (arguement interpreted as 16 bit number)
-; %x: hex number (arguement interpreted as 16 bit number)
-; %c: char (arguement interpreted as pointer to single ASCII char)
-;"field width" modifiers are also supported, e.g "%02x" to print 2 hex digits
-console_printf:
- stax argptr
- ldy #0
- lda (argptr),y
- sta strptr
- iny
- lda (argptr),y
- sta strptr + 1
- iny
- sty arg
-
- ldy #0
-@nextchar:
- lda (strptr),y
- bne :+
- rts
-:
- cmp #'%'
- beq @printarg
-
- cmp #'\'
- beq @printescape
-
- jsr console_out
-
-@next:
- iny
- bne @nextchar
-
- inc strptr + 1
- jmp @nextchar
-
-@printescape:
- iny
- bne :+
- inc strptr + 1
-: lda (strptr),y
- ldx #esc_count - 1
-: cmp esc_code,x
- beq @escmatch
- dex
- bpl :-
- bmi @next
-@escmatch:
- lda esc_char,x
- jsr console_out
- jmp @next
-
-@printarg:
- lda #0
- sta fieldwidth
- sta leadzero
- lda #$ff
- sta fieldwcnt
-@argnext:
- iny
- bne :+
- inc strptr + 1
-:
- tya
- pha
-
- lda (strptr),y
-
- cmp #'0' ; check for field width
- bcc @notdigit
- cmp #'9'+1
- bcs @notdigit
- and #$0f
- bne :+ ; check for leading 0
- inc fieldwcnt
- bne :+
- lda #$80
- sta leadzero
- pla
- tay
- jmp @argnext
-:
- pha ; multiply old value by 10
- asl fieldwidth
- lda fieldwidth
- asl
- asl
- clc
- adc fieldwidth
- sta fieldwidth
- pla
- clc ; add new value
- adc fieldwidth
- sta fieldwidth
- pla
- tay
- jmp @argnext
-
-@notdigit:
- cmp #'s'
- beq @argstr
-
- cmp #'d'
- beq @argint
-
- cmp #'x'
- beq @arghex
-
- cmp #'c'
- beq @argchar
-
-@argdone:
- pla
- tay
- jmp @next
-
-@argstr:
- jsr @argax
- jsr console_strout
-
- jmp @argdone
-
-@argint:
- jsr @argax
- stax valptr
- jsr @valax
- jsr printint
-
- jmp @argdone
-
-@arghex:
- jsr @argax
- stax valptr
- jsr @valax
- jsr printhex
-
- jmp @argdone
-
-@argchar:
- jsr @argax
- stax valptr
- ldy #0
- lda (valptr),y
- jsr console_out
-
- jmp @argdone
-
-@argax:
- ldy arg
- lda (argptr),y
- pha
- iny
- lda (argptr),y
- tax
- iny
- sty arg
- pla
- rts
-
-@valax:
- ldy #0
- lda (valptr),y
- pha
- iny
- lda (valptr),y
- tax
- pla
- rts
-
-@printx:
- txa
- lsr
- lsr
- lsr
- lsr
- tay
- lda hex2asc,y
- jsr console_out
- txa
- and #$0f
- tay
- lda hex2asc,y
- jmp console_out
-
-
-; print 16-bit hexadecimal number
-printhex:
- tay
- and #$0f
- sta num + 3
- tya
- lsr
- lsr
- lsr
- lsr
- sta num + 2
-
- txa
- and #$0f
- sta num + 1
- txa
- lsr
- lsr
- lsr
- lsr
- sta num
-
- lda #4
- sec
- sbc fieldwidth
- tax
- bpl :+
- jsr printlong
-:
- cpx #4
- beq @nowidth
-
-@printlead:
- lda num,x
- bne @printrest
- lda #' '
- bit leadzero
- bpl :+
- lda #'0'
-: jsr console_out
- inx
- cpx #3
- bne @printlead
-
-@nowidth:
- ldx #0
-: lda num,x
- bne @printrest
- inx
- cpx #4
- bne :-
- lda #'0'
- jsr console_out
- rts
-
-@printrest:
- lda num,x
- tay
- lda hex2asc,y
- jsr console_out
- inx
- cpx #4
- bne @printrest
- rts
-
-
-printlong:
- lda #' '
- bit leadzero
- bpl :+
- lda #'0'
-: jsr console_out
- inx
- bne :-
- rts
-
-
-; print a 16-bit integer
-printint:
- stax int
-
- ldx #4
-@next:
- lda #0
- sta num,x
- jsr div10
- lda ext
- sta num,x
- dex
- bpl @next
-
- lda fieldwidth
- beq @nowidth
- lda #5
- sec
- sbc fieldwidth
- tax
- bpl :+
- jsr printlong
-:
-@printlead:
- lda num,x
- bne @print
-
- lda #' '
- bit leadzero
- bpl :+
- lda #'0'
-: jsr console_out
- inx
- cpx #5
- bne @printlead
- beq @printzero
-
-@nowidth:
- inx
- cpx #5
- beq @printzero
- lda num,x
- beq @nowidth
-
-@print:
- clc
- adc #'0'
- jsr console_out
- inx
- cpx #5
- beq @done
-@printall:
- lda num,x
- jmp @print
-
-@done:
- rts
-
-@printzero:
- lda #'0'
- jmp console_out
-
-
-; 16/16-bit division, from the fridge
-; int/aux -> int, remainder in ext
-div10:
- lda #0
- sta ext+1
- ldy #$10
-@dloop:
- asl int
- rol int+1
- rol
- rol ext+1
- pha
- cmp #10
- lda ext+1
- sbc #0 ; is this a nop?
- bcc @div2
- sta ext+1
- pla
- sbc #10
- pha
- inc int
-@div2:
- pla
- dey
- bne @dloop
- sta ext
- rts
-
-
- .rodata
-
-msg_unimplemented:
- .byte "",0
-
-hex2asc:
- .byte "0123456789abcdef"
-
-esc_code:
- .byte "eabfnrt", '\'
-esc_count = * - esc_code
-esc_char:
- .byte 27, 7, 8, 12, 10, 13, 9, '\'
-
-
-
-;-- LICENSE FOR printf.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+.include "../inc/common.i"
+
+ .export console_printf
+
+
+ .import console_out
+ .import console_strout
+
+
+ .segment "IP65ZP" : zeropage
+
+strptr: .res 2
+argptr: .res 2
+valptr: .res 2
+
+
+ .bss
+
+ysave: .res 1
+arg: .res 1
+fieldwidth: .res 1
+fieldwcnt: .res 1
+leadzero: .res 1
+argtemp: .res 1
+int: .res 2
+num: .res 5
+ext: .res 2
+
+
+ .code
+
+;print a string to console, with (some) standard printf % codes converted
+;inputs: AX = pointer to 'argument list'
+; first word in argument list is the string to be printed
+; subsequent words in argument list are interpolated in to the string as
+; it is displayed. (argument list is automagically created by the 'printf' macro
+; defined in inc/printf.i)
+;outputs: none
+;supported % codes:
+; %s: string (argument interpreted as pointer to null terminated string)
+; %d: decimal number (arguement interpreted as 16 bit number)
+; %x: hex number (arguement interpreted as 16 bit number)
+; %c: char (arguement interpreted as pointer to single ASCII char)
+;"field width" modifiers are also supported, e.g "%02x" to print 2 hex digits
+console_printf:
+ stax argptr
+ ldy #0
+ lda (argptr),y
+ sta strptr
+ iny
+ lda (argptr),y
+ sta strptr + 1
+ iny
+ sty arg
+
+ ldy #0
+@nextchar:
+ lda (strptr),y
+ bne :+
+ rts
+:
+ cmp #'%'
+ beq @printarg
+
+ cmp #'\'
+ beq @printescape
+
+ jsr console_out
+
+@next:
+ iny
+ bne @nextchar
+
+ inc strptr + 1
+ jmp @nextchar
+
+@printescape:
+ iny
+ bne :+
+ inc strptr + 1
+: lda (strptr),y
+ ldx #esc_count - 1
+: cmp esc_code,x
+ beq @escmatch
+ dex
+ bpl :-
+ bmi @next
+@escmatch:
+ lda esc_char,x
+ jsr console_out
+ jmp @next
+
+@printarg:
+ lda #0
+ sta fieldwidth
+ sta leadzero
+ lda #$ff
+ sta fieldwcnt
+@argnext:
+ iny
+ bne :+
+ inc strptr + 1
+:
+ tya
+ pha
+
+ lda (strptr),y
+
+ cmp #'0' ; check for field width
+ bcc @notdigit
+ cmp #'9'+1
+ bcs @notdigit
+ and #$0f
+ bne :+ ; check for leading 0
+ inc fieldwcnt
+ bne :+
+ lda #$80
+ sta leadzero
+ pla
+ tay
+ jmp @argnext
+:
+ pha ; multiply old value by 10
+ asl fieldwidth
+ lda fieldwidth
+ asl
+ asl
+ clc
+ adc fieldwidth
+ sta fieldwidth
+ pla
+ clc ; add new value
+ adc fieldwidth
+ sta fieldwidth
+ pla
+ tay
+ jmp @argnext
+
+@notdigit:
+ cmp #'s'
+ beq @argstr
+
+ cmp #'d'
+ beq @argint
+
+ cmp #'x'
+ beq @arghex
+
+ cmp #'c'
+ beq @argchar
+
+@argdone:
+ pla
+ tay
+ jmp @next
+
+@argstr:
+ jsr @argax
+ jsr console_strout
+
+ jmp @argdone
+
+@argint:
+ jsr @argax
+ stax valptr
+ jsr @valax
+ jsr printint
+
+ jmp @argdone
+
+@arghex:
+ jsr @argax
+ stax valptr
+ jsr @valax
+ jsr printhex
+
+ jmp @argdone
+
+@argchar:
+ jsr @argax
+ stax valptr
+ ldy #0
+ lda (valptr),y
+ jsr console_out
+
+ jmp @argdone
+
+@argax:
+ ldy arg
+ lda (argptr),y
+ pha
+ iny
+ lda (argptr),y
+ tax
+ iny
+ sty arg
+ pla
+ rts
+
+@valax:
+ ldy #0
+ lda (valptr),y
+ pha
+ iny
+ lda (valptr),y
+ tax
+ pla
+ rts
+
+@printx:
+ txa
+ lsr
+ lsr
+ lsr
+ lsr
+ tay
+ lda hex2asc,y
+ jsr console_out
+ txa
+ and #$0f
+ tay
+ lda hex2asc,y
+ jmp console_out
+
+
+; print 16-bit hexadecimal number
+printhex:
+ tay
+ and #$0f
+ sta num + 3
+ tya
+ lsr
+ lsr
+ lsr
+ lsr
+ sta num + 2
+
+ txa
+ and #$0f
+ sta num + 1
+ txa
+ lsr
+ lsr
+ lsr
+ lsr
+ sta num
+
+ lda #4
+ sec
+ sbc fieldwidth
+ tax
+ bpl :+
+ jsr printlong
+:
+ cpx #4
+ beq @nowidth
+
+@printlead:
+ lda num,x
+ bne @printrest
+ lda #' '
+ bit leadzero
+ bpl :+
+ lda #'0'
+: jsr console_out
+ inx
+ cpx #3
+ bne @printlead
+
+@nowidth:
+ ldx #0
+: lda num,x
+ bne @printrest
+ inx
+ cpx #4
+ bne :-
+ lda #'0'
+ jsr console_out
+ rts
+
+@printrest:
+ lda num,x
+ tay
+ lda hex2asc,y
+ jsr console_out
+ inx
+ cpx #4
+ bne @printrest
+ rts
+
+
+printlong:
+ lda #' '
+ bit leadzero
+ bpl :+
+ lda #'0'
+: jsr console_out
+ inx
+ bne :-
+ rts
+
+
+; print a 16-bit integer
+printint:
+ stax int
+
+ ldx #4
+@next:
+ lda #0
+ sta num,x
+ jsr div10
+ lda ext
+ sta num,x
+ dex
+ bpl @next
+
+ lda fieldwidth
+ beq @nowidth
+ lda #5
+ sec
+ sbc fieldwidth
+ tax
+ bpl :+
+ jsr printlong
+:
+@printlead:
+ lda num,x
+ bne @print
+
+ lda #' '
+ bit leadzero
+ bpl :+
+ lda #'0'
+: jsr console_out
+ inx
+ cpx #5
+ bne @printlead
+ beq @printzero
+
+@nowidth:
+ inx
+ cpx #5
+ beq @printzero
+ lda num,x
+ beq @nowidth
+
+@print:
+ clc
+ adc #'0'
+ jsr console_out
+ inx
+ cpx #5
+ beq @done
+@printall:
+ lda num,x
+ jmp @print
+
+@done:
+ rts
+
+@printzero:
+ lda #'0'
+ jmp console_out
+
+
+; 16/16-bit division, from the fridge
+; int/aux -> int, remainder in ext
+div10:
+ lda #0
+ sta ext+1
+ ldy #$10
+@dloop:
+ asl int
+ rol int+1
+ rol
+ rol ext+1
+ pha
+ cmp #10
+ lda ext+1
+ sbc #0 ; is this a nop?
+ bcc @div2
+ sta ext+1
+ pla
+ sbc #10
+ pha
+ inc int
+@div2:
+ pla
+ dey
+ bne @dloop
+ sta ext
+ rts
+
+
+ .rodata
+
+msg_unimplemented:
+ .byte "",0
+
+hex2asc:
+ .byte "0123456789abcdef"
+
+esc_code:
+ .byte "eabfnrt", '\'
+esc_count = * - esc_code
+esc_char:
+ .byte 27, 7, 8, 12, 10, 13, 9, '\'
+
+
+
+;-- LICENSE FOR printf.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/sntp.s b/ip65/sntp.s
similarity index 95%
rename from client/ip65/sntp.s
rename to ip65/sntp.s
index 0b6ef7f..deab4f7 100644
--- a/client/ip65/sntp.s
+++ b/ip65/sntp.s
@@ -1,211 +1,211 @@
-; 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
-
-
-
-.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=123
-
-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 #10
- sta sntp_loop_count
-@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:
-
- ;make a zero filled buffer
- lda #$0
- ldx #$30
- stx udp_send_len
- sta udp_send_len+1
-:
- sta output_buffer,x
- dex
- bpl :-
-
- ;set the flags field
- lda #$E3 ; flags - LI=11 (unknown), VN=100 (4), MODE=011 (client)
- sta output_buffer
-
- 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,2011
-; Jonno Downes. All Rights Reserved.
-; -- LICENSE END --
+; 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
+
+
+
+.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=123
+
+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 #10
+ sta sntp_loop_count
+@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:
+
+ ;make a zero filled buffer
+ lda #$0
+ ldx #$30
+ stx udp_send_len
+ sta udp_send_len+1
+:
+ sta output_buffer,x
+ dex
+ bpl :-
+
+ ;set the flags field
+ lda #$E3 ; flags - LI=11 (unknown), VN=100 (4), MODE=011 (client)
+ sta output_buffer
+
+ 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,2011
+; Jonno Downes. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/string_utils.s b/ip65/string_utils.s
similarity index 94%
rename from client/ip65/string_utils.s
rename to ip65/string_utils.s
index 64ffe52..9c057c9 100644
--- a/client/ip65/string_utils.s
+++ b/ip65/string_utils.s
@@ -1,114 +1,114 @@
-;text file parsing routines
-
-.export parse_integer
-.export parse_hex_digits
-
-.importzp copy_dest
-
-.import mul_8_16
-.importzp acc16
-
-
-target_string=copy_dest
-
-.include "../inc/common.i"
-
-.bss
-temp_value: .res 2
-
-
-.code
-;parses a string, returns integer (up to 16 bits)
-;inputs: AX points to a string containing an integer
-;outputs: AX contains integer
-parse_integer:
-
- stax target_string
- lda #0
- sta temp_value
- sta temp_value+1
- tay
-@parse_int:
- lda (target_string),y
- cmp #$30
- bcc @end_of_int ;any non-decimal char should be treated as end of integer
- cmp #$3A
- bcs @end_of_int ;any non-decimal char should be treated as end of integer
-
- ldax temp_value
- stax acc16
- lda #10
- jsr mul_8_16
- ldax acc16
- stax temp_value
- lda (target_string),y
- sec
- sbc #'0'
- clc
- adc temp_value
- sta temp_value
- bcc @no_rollover
- inc temp_value+1
-@no_rollover:
- iny
- bne @parse_int
-@end_of_int:
- ldax temp_value
- clc
- rts
-
-
-parse_hex_digits:
-;parses 2 hex digits, returns a byte
-;inputs: X contains high nibble char, A contains low nibble char
-;outputs: A contains byte
- pha
- txa
- jsr parse_1_digit
- asl
- asl
- asl
- asl
- sta temp_value
-
- pla
- jsr parse_1_digit
- clc
- adc temp_value
- rts
-
-parse_1_digit:
- cmp #$3A
-
- bcs @not_digit
- sec
- sbc #$30
- rts
-@not_digit:
- ora #$20 ;make lower case
- sec
- sbc #'a'-10
- rts
-
-
-
-
-
-;-- LICENSE FOR string_utils.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 --
+;text file parsing routines
+
+.export parse_integer
+.export parse_hex_digits
+
+.importzp copy_dest
+
+.import mul_8_16
+.importzp acc16
+
+
+target_string=copy_dest
+
+.include "../inc/common.i"
+
+.bss
+temp_value: .res 2
+
+
+.code
+;parses a string, returns integer (up to 16 bits)
+;inputs: AX points to a string containing an integer
+;outputs: AX contains integer
+parse_integer:
+
+ stax target_string
+ lda #0
+ sta temp_value
+ sta temp_value+1
+ tay
+@parse_int:
+ lda (target_string),y
+ cmp #$30
+ bcc @end_of_int ;any non-decimal char should be treated as end of integer
+ cmp #$3A
+ bcs @end_of_int ;any non-decimal char should be treated as end of integer
+
+ ldax temp_value
+ stax acc16
+ lda #10
+ jsr mul_8_16
+ ldax acc16
+ stax temp_value
+ lda (target_string),y
+ sec
+ sbc #'0'
+ clc
+ adc temp_value
+ sta temp_value
+ bcc @no_rollover
+ inc temp_value+1
+@no_rollover:
+ iny
+ bne @parse_int
+@end_of_int:
+ ldax temp_value
+ clc
+ rts
+
+
+parse_hex_digits:
+;parses 2 hex digits, returns a byte
+;inputs: X contains high nibble char, A contains low nibble char
+;outputs: A contains byte
+ pha
+ txa
+ jsr parse_1_digit
+ asl
+ asl
+ asl
+ asl
+ sta temp_value
+
+ pla
+ jsr parse_1_digit
+ clc
+ adc temp_value
+ rts
+
+parse_1_digit:
+ cmp #$3A
+
+ bcs @not_digit
+ sec
+ sbc #$30
+ rts
+@not_digit:
+ ora #$20 ;make lower case
+ sec
+ sbc #'a'-10
+ rts
+
+
+
+
+
+;-- LICENSE FOR string_utils.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/ip65/tcp.s b/ip65/tcp.s
similarity index 96%
rename from client/ip65/tcp.s
rename to ip65/tcp.s
index 5523521..3785e9a 100644
--- a/client/ip65/tcp.s
+++ b/ip65/tcp.s
@@ -1,1096 +1,1096 @@
-;TCP (transmission control protocol) functions
-;NB to use these functions, you must pass "-DTCP" to ca65 when assembling "ip.s"
-;otherwise inbound tcp packets won't get passed in to tcp_process
-;currently only a single outbound (client) connection is supported
-;to use, first call "tcp_connect" to create a connection. to send data on that connection, call "tcp_send".
-;whenever data arrives, a call will be made to the routine pointed at by tcp_callback.
-
-
-MAX_TCP_PACKETS_SENT=8 ;timeout after sending 8 messages will be about 7 seconds (1+2+3+4+5+6+7+8)/4
-
-.include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.import ip65_error
-
-.export tcp_init
-.export tcp_process
-.export tcp_connect
-.export tcp_callback
-.export tcp_connect_ip
-.export tcp_send_data_len
-.export tcp_send
-.export tcp_send_string
-.export tcp_close
-.export tcp_listen
-.export tcp_send_keep_alive
-.export tcp_connect_remote_port
-.export tcp_remote_ip
-.export tcp_state
-.export tcp_inbound_data_ptr
-.export tcp_inbound_data_length
-
-
-.import ip_calc_cksum
-.import ip_send
-.import ip_create_packet
-.import ip_inp
-.import ip_outp
-.import ip65_process
-
-.import check_for_abort_key
-.import timer_read
-.import ip65_random_word
-
-.importzp acc32
-.importzp op32
-.importzp acc16
-
-.import add_32_32
-.import add_16_32
-.import cmp_32_32
-.import cmp_16_16
-.import sub_16_16
-
-
-
-.importzp ip_cksum_ptr
-.importzp ip_header_cksum
-.importzp ip_src
-.importzp ip_dest
-.importzp ip_data
-.importzp ip_proto
-.importzp ip_proto_tcp
-.importzp ip_id
-.importzp ip_len
-
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-
-.import cfg_ip
-
-tcp_cxn_state_closed = 0
-tcp_cxn_state_listening = 1 ;(waiting for an inbound SYN)
-tcp_cxn_state_syn_sent = 2 ;(waiting for an inbound SYN/ACK)
-tcp_cxn_state_established = 3 ;
-
-; tcp packet offsets
-tcp_inp = ip_inp + ip_data ;pointer to tcp packet inside inbound ethernet frame
-tcp_outp = ip_outp + ip_data ;pointer to tcp packet inside outbound ethernet frame
-tcp_src_port = 0 ;offset of source port field in tcp packet
-tcp_dest_port = 2 ;offset of destination port field in tcp packet
-tcp_seq = 4 ;offset of sequence number field in tcp packet
-tcp_ack = 8 ;offset of acknowledgement field in tcp packet
-tcp_header_length = 12 ;offset of header length field in tcp packet
-tcp_flags_field = 13 ;offset of flags field in tcp packet
-tcp_window_size = 14 ; offset of window size field in tcp packet
-tcp_checksum = 16 ; offset of checksum field in tcp packet
-tcp_urgent_pointer = 18 ; offset of urgent pointer field in tcp packet
-tcp_data=20 ;offset of data in tcp packet
-
-; virtual header
-tcp_vh = tcp_outp - 12
-tcp_vh_src = 0
-tcp_vh_dest = 4
-tcp_vh_zero = 8
-tcp_vh_proto = 9
-tcp_vh_len = 10
-
-;
-tcp_flag_FIN =1
-tcp_flag_SYN =2
-tcp_flag_RST =4
-tcp_flag_PSH =8
-tcp_flag_ACK =16
-tcp_flag_URG =32
-
-
-
-
-.segment "TCP_VARS"
-tcp_state: .res 1
-tcp_local_port: .res 2
-tcp_remote_port: .res 2
-tcp_remote_ip: .res 4
-tcp_sequence_number: .res 4
-tcp_ack_number: .res 4
-tcp_data_ptr: .res 2
-tcp_data_len: .res 2
-tcp_send_data_ptr: .res 2
-tcp_send_data_len: .res 2 ;length (in bytes) of data to be sent over tcp connection
-tcp_callback: .res 2 ;vector to routine to be called when data is received over tcp connection
-tcp_flags: .res 1
-tcp_fin_sent: .res 1
-
-tcp_listen_port: .res 2
-
-tcp_inbound_data_ptr: .res 2 ;pointer to data just recieved over tcp connection
-tcp_inbound_data_length: .res 2 ;length of data just received over tcp connection
-;(if this is $ffff, that means "end of file", i.e. remote end has closed connection)
-tcp_connect_sequence_number: .res 4 ;the seq number we will next send out
-tcp_connect_expected_ack_number: .res 4 ;what we expect to see in the next inbound ack
-tcp_connect_ack_number: .res 4 ;what we will next ack
-tcp_connect_last_received_seq_number: .res 4 ;the seq field in the last inbound packet for this connection
-tcp_connect_last_ack: .res 4 ;ack field in the last inbound packet for this connection
-tcp_connect_local_port: .res 2 ;
-tcp_connect_remote_port: .res 2
-tcp_connect_ip: .res 4 ;ip address of remote server to connect to
-
-
-tcp_timer: .res 1
-tcp_loop_count: .res 1
-tcp_packet_sent_count: .res 1
-
-
-.code
-
-; initialize tcp
-;called automatically by ip_init if "ip.s" was compiled with -DTCP
-; inputs: none
-; outputs: none
-tcp_init:
-
- rts
-
-
-jmp_to_callback:
- jmp (tcp_callback)
-
-;listen for an inbound tcp connection
-;this is a 'blocking' call, i.e. it will not return until a connection has been made
-;inputs:
-; AX: destination port (2 bytes)
-; tcp_callback: vector to call when data arrives on this connection
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_listen:
- stax tcp_listen_port
- lda #tcp_cxn_state_listening
- sta tcp_state
- lda #0 ;reset the "packet sent" counter
- sta tcp_packet_sent_count
- sta tcp_fin_sent
-
- ;set the low word of seq number to $0000, high word to something random
- sta tcp_connect_sequence_number
- sta tcp_connect_sequence_number+1
- jsr ip65_random_word
- stax tcp_connect_sequence_number+2
- jsr set_expected_ack; ;due to various ugly hacks, the 'expected ack' value is now what is put into the 'SEQ' field in outbound packets
-@listen_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 #tcp_cxn_state_listening
- cmp tcp_state
- beq @listen_loop
-
- jmp tcp_connection_established
- rts
-
-;make outbound tcp connection
-;inputs:
-; tcp_connect_ip: destination ip address (4 bytes)
-; AX: destination port (2 bytes)
-; tcp_callback: vector to call when data arrives on this connection
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_connect:
- stax tcp_connect_remote_port
- jsr ip65_random_word
- stax tcp_connect_local_port
- lda #tcp_cxn_state_syn_sent
- sta tcp_state
- lda #0 ;reset the "packet sent" counter
- sta tcp_packet_sent_count
- sta tcp_fin_sent
-
- ;set the low word of seq number to $0000, high word to something random
- sta tcp_connect_sequence_number
- sta tcp_connect_sequence_number+1
- jsr ip65_random_word
- stax tcp_connect_sequence_number+2
-
-
-@tcp_polling_loop:
-
- ;create a SYN packet
- lda #tcp_flag_SYN
- sta tcp_flags
- lda #0
- sta tcp_data_len
- sta tcp_data_len+1
-
- ldx #3 ;
-: lda tcp_connect_ip,x
- sta tcp_remote_ip,x
- lda tcp_connect_sequence_number,x
- sta tcp_sequence_number,x
- dex
- bpl :-
- ldax tcp_connect_local_port
- stax tcp_local_port
- ldax tcp_connect_remote_port
- stax tcp_remote_port
-
- jsr tcp_send_packet
- lda tcp_packet_sent_count
- adc #1
- sta tcp_loop_count ;we wait a bit longer between each resend
-@outer_delay_loop:
- jsr timer_read
- stx tcp_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 tcp_state
- cmp #tcp_cxn_state_syn_sent
- bne @got_a_response
-
- jsr timer_read
- cpx tcp_timer ;this will tick over after about 1/4 of a second
- beq @inner_delay_loop
-
- dec tcp_loop_count
- bne @outer_delay_loop
-
-
- inc tcp_packet_sent_count
- lda tcp_packet_sent_count
- cmp #MAX_TCP_PACKETS_SENT-1
- bpl @too_many_messages_sent
- jmp @tcp_polling_loop
-
-@too_many_messages_sent:
-@failed:
- lda #tcp_cxn_state_closed
- sta tcp_state
- lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
- sta ip65_error
- sec ;signal an error
- rts
-@got_a_response:
- lda tcp_state
- cmp #tcp_cxn_state_closed
- bne @was_accepted
- sec ;if we got here, then the other side sent a RST or FIN, so signal an error to the caller
- rts
-@was_accepted:
-tcp_connection_established:
-;inc the sequence number to cover the SYN we have sent
- ldax #tcp_connect_sequence_number
- stax acc32
- ldax #$01
- jsr add_16_32
-
-set_expected_ack:
-;set the expected ack number with current seq number
- ldx #3 ;
-: lda tcp_connect_sequence_number,x
- sta tcp_connect_expected_ack_number,x
- dex
- bpl :-
-
- clc
- rts
-
-tcp_close:
-;close the current connection
-;inputs:
-; none
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-
-
- lda tcp_state
- cmp #tcp_cxn_state_established
- beq :+
-@connection_closed:
- lda #tcp_cxn_state_closed
- sta tcp_state
- clc
- rts
-:
- ;increment the expected sequence number for the SYN we are about to send
- ldax #tcp_connect_expected_ack_number
- stax acc32
- ldax #1
- sta tcp_fin_sent
- jsr add_16_32
-
-
-@send_fin_loop:
- lda #tcp_flag_FIN+tcp_flag_ACK
- sta tcp_flags
- ldax #0
- stax tcp_data_len
- ldx #3 ;
-: lda tcp_connect_ip,x
- sta tcp_remote_ip,x
- lda tcp_connect_ack_number,x
- sta tcp_ack_number,x
- lda tcp_connect_sequence_number,x
- sta tcp_sequence_number,x
- dex
- bpl :-
- ldax tcp_connect_local_port
- stax tcp_local_port
- ldax tcp_connect_remote_port
- stax tcp_remote_port
-
- jsr tcp_send_packet
-
- lda tcp_packet_sent_count
- adc #1
- sta tcp_loop_count ;we wait a bit longer between each resend
-@outer_delay_loop:
- jsr timer_read
- stx tcp_timer ;we only care about the high byte
-@inner_delay_loop:
- jsr ip65_process
- lda tcp_state
- cmp #tcp_cxn_state_established
- bne @connection_closed
-
- jsr timer_read
- cpx tcp_timer ;this will tick over after about 1/4 of a second
- beq @inner_delay_loop
-
- dec tcp_loop_count
- bne @outer_delay_loop
-
- inc tcp_packet_sent_count
- lda tcp_packet_sent_count
- cmp #MAX_TCP_PACKETS_SENT-1
- bpl @too_many_messages_sent
- jmp @send_fin_loop
-@too_many_messages_sent:
-@failed:
- lda #tcp_cxn_state_closed
- sta tcp_state
- lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
- sta ip65_error
- sec ;signal an error
- rts
-
-
-
-;send a string over the current tcp connection
-;inputs:
-; tcp connection should already be opened
-; AX: pointer to buffer - data up to (but not including)
-; the first nul byte will be sent. max of 255 bytes will be sent.
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_send_string:
- stax tcp_send_data_ptr
- stax copy_src
- lda #0
- tay
- sta tcp_send_data_len
- sta tcp_send_data_len+1
- lda (copy_src),y
- bne @find_end_of_string
- rts ; if the string is empty, don't send anything!
-@find_end_of_string:
- lda (copy_src),y
- beq @done
- inc tcp_send_data_len
- iny
- bne @find_end_of_string
-@done:
- ldax tcp_send_data_ptr
- ;now we can fall through into tcp_send
-
-
-;send tcp data
-;inputs:
-; tcp connection should already be opened
-; tcp_send_data_len: length of data to send (exclusive of any headers)
-; AX: pointer to buffer containing data to be sent
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_send:
-
- stax tcp_send_data_ptr
-
- lda tcp_state
- cmp #tcp_cxn_state_established
- beq @connection_established
- lda #KPR_ERROR_CONNECTION_CLOSED
- sta ip65_error
- sec
- rts
- lda #0 ;reset the "packet sent" counter
- sta tcp_packet_sent_count
-
-@connection_established:
- ;increment the expected sequence number
- ldax #tcp_connect_expected_ack_number
- stax acc32
- ldax tcp_send_data_len
- jsr add_16_32
-
-
-@tcp_polling_loop:
-
- ;create a data packet
- lda #tcp_flag_ACK+tcp_flag_PSH
- sta tcp_flags
- ldax tcp_send_data_len
- stax tcp_data_len
-
- ldax tcp_send_data_ptr
- stax tcp_data_ptr
-
- ldx #3 ;
-: lda tcp_connect_ip,x
- sta tcp_remote_ip,x
- lda tcp_connect_sequence_number,x
- sta tcp_sequence_number,x
-
- dex
- bpl :-
- ldax tcp_connect_local_port
- stax tcp_local_port
- ldax tcp_connect_remote_port
- stax tcp_remote_port
-
-
- jsr tcp_send_packet
- lda tcp_packet_sent_count
- adc #1
- sta tcp_loop_count ;we wait a bit longer between each resend
-@outer_delay_loop:
- jsr timer_read
- stx tcp_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
- lda #tcp_cxn_state_closed
- sta tcp_state
-
- rts
-@no_abort:
- ldax #tcp_connect_last_ack
- stax acc32
- ldax #tcp_connect_expected_ack_number
- stax op32
- jsr cmp_32_32
- beq @got_ack
-
- jsr timer_read
- cpx tcp_timer ;this will tick over after about 1/4 of a second
- beq @inner_delay_loop
-
- dec tcp_loop_count
- bne @outer_delay_loop
-
-
- inc tcp_packet_sent_count
- lda tcp_packet_sent_count
- cmp #MAX_TCP_PACKETS_SENT-1
- bpl @too_many_messages_sent
- jmp @tcp_polling_loop
-
-@too_many_messages_sent:
-@failed:
-
- lda #tcp_cxn_state_closed
- sta tcp_state
- lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
- sta ip65_error
- sec ;signal an error
- rts
-@got_ack:
- ;finished - now we need to advance the sequence number for the data we just sent
- ldax #tcp_connect_sequence_number
- stax acc32
- ldax tcp_send_data_len
- jsr add_16_32
-
- clc
- rts
-
-
-;send a single tcp packet
-;inputs:
-; tcp_remote_ip: IP address of destination server
-; tcp_remote_port: destination tcp port
-; tcp_local_port: source tcp port
-; tcp_flags: 6 bit flags
-; tcp_data_ptr: pointer to data to include in this packet
-; tcp_data_len: length of data pointed at by tcp_data_ptr
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_send_packet:
- ldax tcp_data_ptr
- stax copy_src ; copy data to output buffer
- ldax #tcp_outp + tcp_data
- stax copy_dest
- ldax tcp_data_len
- jsr copymem
-
- ldx #3 ; copy virtual header addresses
-: lda tcp_remote_ip,x
- sta tcp_vh + tcp_vh_dest,x ; set virtual header destination
- lda cfg_ip,x
- sta tcp_vh + tcp_vh_src,x ; set virtual header source
- dex
- bpl :-
-
- lda tcp_local_port ; copy source port
- sta tcp_outp + tcp_src_port + 1
- lda tcp_local_port + 1
- sta tcp_outp + tcp_src_port
-
- lda tcp_remote_port ; copy destination port
- sta tcp_outp + tcp_dest_port + 1
- lda tcp_remote_port + 1
- sta tcp_outp + tcp_dest_port
-
- ldx #3 ; copy sequence and ack (if ACK flag set) numbers (in reverse order)
- ldy #0
-: lda tcp_sequence_number,x
- sta tcp_outp + tcp_seq,y
- lda #tcp_flag_ACK
- bit tcp_flags
- bne @ack_set
- lda #0
- beq @sta_ack
- @ack_set:
- lda tcp_ack_number,x
- @sta_ack:
- sta tcp_outp + tcp_ack,y
- iny
- dex
- bpl :-
-
- lda #$50 ;4 bit header length in 32bit words + 4 bits of zero
- sta tcp_outp+tcp_header_length
- lda tcp_flags
- sta tcp_outp+tcp_flags_field
-
- lda #ip_proto_tcp
- sta tcp_vh + tcp_vh_proto
-
- ldax #$0010 ;$1000 in network byte order
- stax tcp_outp+tcp_window_size
-
- lda #0 ; clear checksum
- sta tcp_outp + tcp_checksum
- sta tcp_outp + tcp_checksum + 1
- sta tcp_vh + tcp_vh_zero ; clear virtual header zero byte
-
- ldax #tcp_vh ; checksum pointer to virtual header
- stax ip_cksum_ptr
-
- lda tcp_data_len ; copy length + 20
- clc
- adc #20
- sta tcp_vh + tcp_vh_len + 1 ; lsb for virtual header
- tay
- lda tcp_data_len + 1
- adc #0
- sta tcp_vh + tcp_vh_len ; msb for virtual header
-
- tax ; length to A/X
- tya
-
- clc ; add 12 bytes for virtual header
- adc #12
- bcc :+
- inx
-:
- jsr ip_calc_cksum ; calculate checksum
- stax tcp_outp + tcp_checksum
-
- ldx #3 ; copy addresses
-: lda tcp_remote_ip,x
- sta ip_outp + ip_dest,x ; set ip destination address
- dex
- bpl :-
-
- jsr ip_create_packet ; create ip packet template
-
- lda tcp_data_len ; ip len = tcp data length +20 byte ip header + 20 byte tcp header
- ldx tcp_data_len +1
- clc
- adc #40
- bcc :+
- inx
-: sta ip_outp + ip_len + 1 ; set length
- stx ip_outp + ip_len
-
- ldax #$1234 ; set ID
- stax ip_outp + ip_id
-
- lda #ip_proto_tcp ; set protocol
- sta ip_outp + ip_proto
-
- jmp ip_send ; send packet, sec on error
-
-
-
-check_current_connection:
-;see if the ip packet we just got is for a valid (non-closed) tcp connection
-;inputs:
-; eth_inp: should contain an ethernet frame encapsulating an inbound tcp packet
-;outputs:
-; carry flag clear if inbound tcp packet part of existing connection
-
-
- lda tcp_state
- cmp #tcp_cxn_state_closed
- bne @connection_not_closed
- sec
- rts
-@connection_not_closed:
- ldax #ip_inp+ip_src
- stax acc32
- ldax #tcp_connect_ip
- stax op32
- jsr cmp_32_32
- beq @remote_ip_matches
-
- sec
- rts
-@remote_ip_matches:
- ldax tcp_inp+tcp_src_port
- stax acc16
- lda tcp_connect_remote_port+1 ;this value in reverse byte order to how it is presented in the TCP header
- ldx tcp_connect_remote_port
- jsr cmp_16_16
- beq @remote_port_matches
- sec
- rts
-@remote_port_matches:
- ldax tcp_inp+tcp_dest_port
- stax acc16
- lda tcp_connect_local_port+1 ;this value in reverse byte order to how it is presented in the TCP header
- ldx tcp_connect_local_port
- jsr cmp_16_16
- beq @local_port_matches
- sec
- rts
-@local_port_matches:
- clc
- rts
-
-;process incoming tcp packet
-;called automatically by ip_process if "ip.s" was compiled with -DTCP
-;inputs:
-; eth_inp: should contain an ethernet frame encapsulating an inbound tcp packet
-;outputs:
-; none but if connection was found, an outbound message may be created, overwriting eth_outp
-; also tcp_state and other tcp variables may be modified
-tcp_process:
-
- lda #tcp_flag_RST
- bit tcp_inp+tcp_flags_field
- beq @not_reset
- jsr check_current_connection
- bcs @not_current_connection_on_rst
- ;for some reason, search.twitter.com is sending RSTs with ID=$1234 (i.e. echoing the inbound ID)
- ;but then keeps the connection open and ends up sending the file.
- ;so lets ignore a reset with ID=$1234
- lda ip_inp+ip_id
- cmp #$34
- bne @not_invalid_reset
- lda ip_inp+ip_id+1
- cmp #$12
- bne @not_invalid_reset
- jmp @send_ack
-@not_invalid_reset:
- ;connection has been reset so mark it as closed
- lda #tcp_cxn_state_closed
- sta tcp_state
- lda #KPR_ERROR_CONNECTION_RESET_BY_PEER
- sta ip65_error
-
- lda #$ff
- sta tcp_inbound_data_length
- sta tcp_inbound_data_length+1
- jsr jmp_to_callback ;let the caller see the connection has closed
-
-@not_current_connection_on_rst:
- ;if we get a reset for a closed or nonexistent connection, then ignore it
- rts
-@not_reset:
- lda tcp_inp+tcp_flags_field
- cmp #tcp_flag_SYN+tcp_flag_ACK
- bne @not_syn_ack
-
- ;it's a SYN/ACK
- jsr check_current_connection
- bcc @current_connection_on_syn_ack
- ;if we get a SYN/ACK for something that aint the connection we're expecting,
- ;terminate with extreme prejudice
- jmp @send_rst
-@current_connection_on_syn_ack:
- lda tcp_state
- cmp #tcp_cxn_state_syn_sent
- bne @not_expecting_syn_ack
- ;this IS the syn/ack we are waiting for :-)
- ldx #3 ; copy sequence number to ack (in reverse order)
- ldy #0
-: lda tcp_inp + tcp_seq,y
- sta tcp_connect_ack_number,x
- iny
- dex
- bpl :-
-
- ldax #tcp_connect_ack_number
- stax acc32
- ldax #$0001 ;
- jsr add_16_32 ;increment the ACK counter by 1, for the SYN we just received
-
-
- lda #tcp_cxn_state_established
- sta tcp_state
-
-@not_expecting_syn_ack:
-;we get a SYN/ACK for the current connection,
-;but we're not expecting it, it's probably
-;a retransmist - just ACK it
- jmp @send_ack
-
-
-@not_syn_ack:
-
-;is it an ACK - alone or with PSH/URGENT but not a SYN/ACK?
- lda #tcp_flag_ACK
- bit tcp_inp+tcp_flags_field
- bne @ack
- jmp @not_ack
-@ack:
- ;is this the current connection?
- jsr check_current_connection
- bcc @current_connection_on_ack
- ;if we get an ACK for something that is not the current connection
- ;we should send a RST
- jmp @send_rst
-@current_connection_on_ack:
- ;if it's an ACK, then record the last ACK (reorder the bytes in the process)
- ldx #3 ; copy seq & ack fields (in reverse order)
- ldy #0
-: lda tcp_inp + tcp_ack,y
- sta tcp_connect_last_ack,x
- lda tcp_inp + tcp_seq,y
- sta tcp_connect_last_received_seq_number,x
- iny
- dex
- bpl :-
-
- ;was this the next sequence number we're waiting for?
- ldax #tcp_connect_ack_number
- stax acc32
- ldax #tcp_connect_last_received_seq_number
- stax op32
- jsr cmp_32_32
-
- bne @not_expected_seq_number
-
-
-
- ;what is the size of data in this packet?
- lda ip_inp+ip_len+1 ;payload length (lo byte)
- sta acc16
- lda ip_inp+ip_len ;payload length (hi byte)
- sta acc16+1
- lda tcp_inp+tcp_header_length ;high 4 bits is header length in 32 bit words
- lsr ; A=A/2
- lsr ; A=A/2
- clc ; A now equal to tcp header length in bytes
- adc #20 ;add 20 bytes for IP header. this gives length of IP +TCP headers
- ldx #0
- sta tcp_header_length
- jsr sub_16_16
-
- ;acc16 now contains the length of data in this TCP packet
-
- lda acc16
- sta tcp_inbound_data_length
- lda acc16+1
- sta tcp_inbound_data_length+1
- bne @not_empty_packet
- lda acc16
- bne @not_empty_packet
- jmp @empty_packet
-@not_empty_packet:
-
-
- ;calculate ptr to tcp data
- clc
- lda tcp_header_length
- adc #ip_inp
- adc #0
- sta tcp_inbound_data_ptr+1
-
- ; do a callback
- jsr jmp_to_callback
-
-
- ; move ack ptr along
- ldax #tcp_connect_ack_number
- stax acc32
- ldax tcp_inbound_data_length
- jsr add_16_32
-
-
-@not_expected_seq_number: ;send an ACK with the sequence number we expect
-
- ;send the ACK for any data in this packet, then return to check for FIN flag
- jsr @send_ack
-
-@not_ack:
-@empty_packet:
-
-;is it a FIN?
- lda #tcp_flag_FIN
- bit tcp_inp+tcp_flags_field
- bne @fin
- jmp @not_fin
-@fin:
- ;is this the current connection?
- jsr check_current_connection
- bcc :+
- jmp @send_rst ;reset if not current connection
-:
- ldx #3 ; copy seq field (in reverse order)
- ldy #0
-: lda tcp_inp + tcp_seq,y
- sta tcp_connect_last_received_seq_number,x
- iny
- dex
- bpl :-
-
- ;was this the next sequence number we're waiting for?
- ldax #tcp_connect_ack_number
- stax acc32
- ldax #tcp_connect_last_received_seq_number
- stax op32
- jsr cmp_32_32
-
- beq :+
- rts ;bail if not expected sequence number
-:
-
- ;set the length to $ffff
- lda #$ff
- sta tcp_inbound_data_length
- sta tcp_inbound_data_length+1
- jsr jmp_to_callback ;let the caller see the connection has closed
-
-
- lda #tcp_cxn_state_closed
- sta tcp_state
-
- ;send a FIN/ACK
- ; move ack ptr along for the inbound FIN
- ldax #tcp_connect_ack_number
- stax acc32
- ldax #$01
- sta tcp_fin_sent
- jsr add_16_32
-
- ;if we've already sent a FIN then just send back an ACK
- lda tcp_fin_sent
- beq @send_fin_ack
-;if we get here, we've sent a FIN, and just received an inbound FIN.
-;when we sent the fin, we didn't update the sequence number, since
-;we want to use the old sequence on every resend of that FIN
-;now that our fin has been ACKed, we need to inc the sequence number
-;and then send another ACK.
-
- ldax #tcp_connect_sequence_number
- stax acc32
- ldax #$0001 ;
- jsr add_16_32 ;increment the SEQ counter by 1, for the FIN we have been sending
-
- lda #tcp_flag_ACK
- jmp @send_packet
-
-@send_fin_ack:
-
- lda #tcp_flag_FIN+tcp_flag_ACK
-
- jmp @send_packet
-
-
-@not_fin:
-
- lda tcp_inp+tcp_flags_field
- cmp #tcp_flag_SYN
- beq @syn
- jmp @not_syn
-@syn:
-
- ;is this the port we are listening on?
- lda tcp_inp+tcp_dest_port+1
- cmp tcp_listen_port
- bne @decline_syn_with_reset
- lda tcp_inp+tcp_dest_port
- cmp tcp_listen_port+1
- bne @decline_syn_with_reset
-
- ;it's the right port - are we actually waiting for a connecting?
- lda #tcp_cxn_state_listening
- cmp tcp_state
- beq @this_is_connection_we_are_waiting_for
- ;is this the current connection? that would mean our ACK got lost, so resend
- jsr check_current_connection
- bcc @this_is_connection_we_are_waiting_for
-
- rts ;if we've currently got a connection open, then ignore any new requests
- ;the sender will timeout and resend the SYN, by which time we may be
- ;ready to accept it again.
-
-@this_is_connection_we_are_waiting_for:
-
- ; copy sequence number to ack (in reverse order) and remote IP
- ldx #3
- ldy #0
-: lda tcp_inp + tcp_seq,y
- sta tcp_connect_ack_number,x
- lda ip_inp+ip_src,x
- sta tcp_connect_ip,x
- iny
- dex
- bpl :-
-
- ;copy ports
- ldax tcp_listen_port
- stax tcp_connect_local_port
-
- lda tcp_inp+tcp_src_port+1
- sta tcp_connect_remote_port
- lda tcp_inp+tcp_src_port
- sta tcp_connect_remote_port+1
-
- lda #tcp_cxn_state_established
- sta tcp_state
-
- ldax #tcp_connect_ack_number
- stax acc32
- ldax #$0001 ;
- jsr add_16_32 ;increment the ACK counter by 1, for the SYN we just received
- lda #tcp_flag_SYN+tcp_flag_ACK
- jmp @send_packet
-
-@decline_syn_with_reset:
-;create a RST packet
- ldx #3 ; copy sequence number to ack (in reverse order)
- ldy #0
-: lda tcp_inp + tcp_seq,y
- sta tcp_ack_number,x
- iny
- dex
- bpl :-
-
- ldax #tcp_ack_number
- stax acc32
- ldax #$0001 ;
- jsr add_16_32 ;increment the ACK counter by 1, for the SYN we just received
-
-@send_rst:
-
- lda #tcp_flag_RST+tcp_flag_ACK
- sta tcp_flags
- ldax #0
- stax tcp_data_len
- ldx #3 ;
-: lda ip_inp+ip_src,x
- sta tcp_remote_ip,x
- dex
- bpl :-
-
- ;copy src/dest ports in inverted byte order
- lda tcp_inp+tcp_src_port
- sta tcp_remote_port+1
- lda tcp_inp+tcp_src_port+1
- sta tcp_remote_port
-
- lda tcp_inp+tcp_dest_port
- sta tcp_local_port+1
- lda tcp_inp+tcp_dest_port+1
- sta tcp_local_port
-
- jsr tcp_send_packet
- rts
-
-@not_syn:
- rts
-
-@send_ack:
-
-;create an ACK packet
- lda #tcp_flag_ACK
-
-@send_packet:
- sta tcp_flags
- ldax #0
- stax tcp_data_len
- ldx #3 ;
-: lda tcp_connect_ip,x
- sta tcp_remote_ip,x
- lda tcp_connect_ack_number,x
- sta tcp_ack_number,x
-;if we have just sent a packet out, we may not yet have updated tcp_connect_sequence_number yet
-;so use current value of tcp_connect_expected_ack_number as outbound sequence number instead
- lda tcp_connect_expected_ack_number,x
- sta tcp_sequence_number,x
- dex
- bpl :-
- ldax tcp_connect_local_port
- stax tcp_local_port
- ldax tcp_connect_remote_port
- stax tcp_remote_port
-
-
- jmp tcp_send_packet
-
-
-;send an empty ACK packet on the current connection
-;inputs:
-; none
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-tcp_send_keep_alive=@send_ack
-
-;-- LICENSE FOR tcp.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 --
+;TCP (transmission control protocol) functions
+;NB to use these functions, you must pass "-DTCP" to ca65 when assembling "ip.s"
+;otherwise inbound tcp packets won't get passed in to tcp_process
+;currently only a single outbound (client) connection is supported
+;to use, first call "tcp_connect" to create a connection. to send data on that connection, call "tcp_send".
+;whenever data arrives, a call will be made to the routine pointed at by tcp_callback.
+
+
+MAX_TCP_PACKETS_SENT=8 ;timeout after sending 8 messages will be about 7 seconds (1+2+3+4+5+6+7+8)/4
+
+.include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.import ip65_error
+
+.export tcp_init
+.export tcp_process
+.export tcp_connect
+.export tcp_callback
+.export tcp_connect_ip
+.export tcp_send_data_len
+.export tcp_send
+.export tcp_send_string
+.export tcp_close
+.export tcp_listen
+.export tcp_send_keep_alive
+.export tcp_connect_remote_port
+.export tcp_remote_ip
+.export tcp_state
+.export tcp_inbound_data_ptr
+.export tcp_inbound_data_length
+
+
+.import ip_calc_cksum
+.import ip_send
+.import ip_create_packet
+.import ip_inp
+.import ip_outp
+.import ip65_process
+
+.import check_for_abort_key
+.import timer_read
+.import ip65_random_word
+
+.importzp acc32
+.importzp op32
+.importzp acc16
+
+.import add_32_32
+.import add_16_32
+.import cmp_32_32
+.import cmp_16_16
+.import sub_16_16
+
+
+
+.importzp ip_cksum_ptr
+.importzp ip_header_cksum
+.importzp ip_src
+.importzp ip_dest
+.importzp ip_data
+.importzp ip_proto
+.importzp ip_proto_tcp
+.importzp ip_id
+.importzp ip_len
+
+.import copymem
+.importzp copy_src
+.importzp copy_dest
+
+.import cfg_ip
+
+tcp_cxn_state_closed = 0
+tcp_cxn_state_listening = 1 ;(waiting for an inbound SYN)
+tcp_cxn_state_syn_sent = 2 ;(waiting for an inbound SYN/ACK)
+tcp_cxn_state_established = 3 ;
+
+; tcp packet offsets
+tcp_inp = ip_inp + ip_data ;pointer to tcp packet inside inbound ethernet frame
+tcp_outp = ip_outp + ip_data ;pointer to tcp packet inside outbound ethernet frame
+tcp_src_port = 0 ;offset of source port field in tcp packet
+tcp_dest_port = 2 ;offset of destination port field in tcp packet
+tcp_seq = 4 ;offset of sequence number field in tcp packet
+tcp_ack = 8 ;offset of acknowledgement field in tcp packet
+tcp_header_length = 12 ;offset of header length field in tcp packet
+tcp_flags_field = 13 ;offset of flags field in tcp packet
+tcp_window_size = 14 ; offset of window size field in tcp packet
+tcp_checksum = 16 ; offset of checksum field in tcp packet
+tcp_urgent_pointer = 18 ; offset of urgent pointer field in tcp packet
+tcp_data=20 ;offset of data in tcp packet
+
+; virtual header
+tcp_vh = tcp_outp - 12
+tcp_vh_src = 0
+tcp_vh_dest = 4
+tcp_vh_zero = 8
+tcp_vh_proto = 9
+tcp_vh_len = 10
+
+;
+tcp_flag_FIN =1
+tcp_flag_SYN =2
+tcp_flag_RST =4
+tcp_flag_PSH =8
+tcp_flag_ACK =16
+tcp_flag_URG =32
+
+
+
+
+.segment "TCP_VARS"
+tcp_state: .res 1
+tcp_local_port: .res 2
+tcp_remote_port: .res 2
+tcp_remote_ip: .res 4
+tcp_sequence_number: .res 4
+tcp_ack_number: .res 4
+tcp_data_ptr: .res 2
+tcp_data_len: .res 2
+tcp_send_data_ptr: .res 2
+tcp_send_data_len: .res 2 ;length (in bytes) of data to be sent over tcp connection
+tcp_callback: .res 2 ;vector to routine to be called when data is received over tcp connection
+tcp_flags: .res 1
+tcp_fin_sent: .res 1
+
+tcp_listen_port: .res 2
+
+tcp_inbound_data_ptr: .res 2 ;pointer to data just recieved over tcp connection
+tcp_inbound_data_length: .res 2 ;length of data just received over tcp connection
+;(if this is $ffff, that means "end of file", i.e. remote end has closed connection)
+tcp_connect_sequence_number: .res 4 ;the seq number we will next send out
+tcp_connect_expected_ack_number: .res 4 ;what we expect to see in the next inbound ack
+tcp_connect_ack_number: .res 4 ;what we will next ack
+tcp_connect_last_received_seq_number: .res 4 ;the seq field in the last inbound packet for this connection
+tcp_connect_last_ack: .res 4 ;ack field in the last inbound packet for this connection
+tcp_connect_local_port: .res 2 ;
+tcp_connect_remote_port: .res 2
+tcp_connect_ip: .res 4 ;ip address of remote server to connect to
+
+
+tcp_timer: .res 1
+tcp_loop_count: .res 1
+tcp_packet_sent_count: .res 1
+
+
+.code
+
+; initialize tcp
+;called automatically by ip_init if "ip.s" was compiled with -DTCP
+; inputs: none
+; outputs: none
+tcp_init:
+
+ rts
+
+
+jmp_to_callback:
+ jmp (tcp_callback)
+
+;listen for an inbound tcp connection
+;this is a 'blocking' call, i.e. it will not return until a connection has been made
+;inputs:
+; AX: destination port (2 bytes)
+; tcp_callback: vector to call when data arrives on this connection
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_listen:
+ stax tcp_listen_port
+ lda #tcp_cxn_state_listening
+ sta tcp_state
+ lda #0 ;reset the "packet sent" counter
+ sta tcp_packet_sent_count
+ sta tcp_fin_sent
+
+ ;set the low word of seq number to $0000, high word to something random
+ sta tcp_connect_sequence_number
+ sta tcp_connect_sequence_number+1
+ jsr ip65_random_word
+ stax tcp_connect_sequence_number+2
+ jsr set_expected_ack; ;due to various ugly hacks, the 'expected ack' value is now what is put into the 'SEQ' field in outbound packets
+@listen_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 #tcp_cxn_state_listening
+ cmp tcp_state
+ beq @listen_loop
+
+ jmp tcp_connection_established
+ rts
+
+;make outbound tcp connection
+;inputs:
+; tcp_connect_ip: destination ip address (4 bytes)
+; AX: destination port (2 bytes)
+; tcp_callback: vector to call when data arrives on this connection
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_connect:
+ stax tcp_connect_remote_port
+ jsr ip65_random_word
+ stax tcp_connect_local_port
+ lda #tcp_cxn_state_syn_sent
+ sta tcp_state
+ lda #0 ;reset the "packet sent" counter
+ sta tcp_packet_sent_count
+ sta tcp_fin_sent
+
+ ;set the low word of seq number to $0000, high word to something random
+ sta tcp_connect_sequence_number
+ sta tcp_connect_sequence_number+1
+ jsr ip65_random_word
+ stax tcp_connect_sequence_number+2
+
+
+@tcp_polling_loop:
+
+ ;create a SYN packet
+ lda #tcp_flag_SYN
+ sta tcp_flags
+ lda #0
+ sta tcp_data_len
+ sta tcp_data_len+1
+
+ ldx #3 ;
+: lda tcp_connect_ip,x
+ sta tcp_remote_ip,x
+ lda tcp_connect_sequence_number,x
+ sta tcp_sequence_number,x
+ dex
+ bpl :-
+ ldax tcp_connect_local_port
+ stax tcp_local_port
+ ldax tcp_connect_remote_port
+ stax tcp_remote_port
+
+ jsr tcp_send_packet
+ lda tcp_packet_sent_count
+ adc #1
+ sta tcp_loop_count ;we wait a bit longer between each resend
+@outer_delay_loop:
+ jsr timer_read
+ stx tcp_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 tcp_state
+ cmp #tcp_cxn_state_syn_sent
+ bne @got_a_response
+
+ jsr timer_read
+ cpx tcp_timer ;this will tick over after about 1/4 of a second
+ beq @inner_delay_loop
+
+ dec tcp_loop_count
+ bne @outer_delay_loop
+
+
+ inc tcp_packet_sent_count
+ lda tcp_packet_sent_count
+ cmp #MAX_TCP_PACKETS_SENT-1
+ bpl @too_many_messages_sent
+ jmp @tcp_polling_loop
+
+@too_many_messages_sent:
+@failed:
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+ lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
+ sta ip65_error
+ sec ;signal an error
+ rts
+@got_a_response:
+ lda tcp_state
+ cmp #tcp_cxn_state_closed
+ bne @was_accepted
+ sec ;if we got here, then the other side sent a RST or FIN, so signal an error to the caller
+ rts
+@was_accepted:
+tcp_connection_established:
+;inc the sequence number to cover the SYN we have sent
+ ldax #tcp_connect_sequence_number
+ stax acc32
+ ldax #$01
+ jsr add_16_32
+
+set_expected_ack:
+;set the expected ack number with current seq number
+ ldx #3 ;
+: lda tcp_connect_sequence_number,x
+ sta tcp_connect_expected_ack_number,x
+ dex
+ bpl :-
+
+ clc
+ rts
+
+tcp_close:
+;close the current connection
+;inputs:
+; none
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+
+
+ lda tcp_state
+ cmp #tcp_cxn_state_established
+ beq :+
+@connection_closed:
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+ clc
+ rts
+:
+ ;increment the expected sequence number for the SYN we are about to send
+ ldax #tcp_connect_expected_ack_number
+ stax acc32
+ ldax #1
+ sta tcp_fin_sent
+ jsr add_16_32
+
+
+@send_fin_loop:
+ lda #tcp_flag_FIN+tcp_flag_ACK
+ sta tcp_flags
+ ldax #0
+ stax tcp_data_len
+ ldx #3 ;
+: lda tcp_connect_ip,x
+ sta tcp_remote_ip,x
+ lda tcp_connect_ack_number,x
+ sta tcp_ack_number,x
+ lda tcp_connect_sequence_number,x
+ sta tcp_sequence_number,x
+ dex
+ bpl :-
+ ldax tcp_connect_local_port
+ stax tcp_local_port
+ ldax tcp_connect_remote_port
+ stax tcp_remote_port
+
+ jsr tcp_send_packet
+
+ lda tcp_packet_sent_count
+ adc #1
+ sta tcp_loop_count ;we wait a bit longer between each resend
+@outer_delay_loop:
+ jsr timer_read
+ stx tcp_timer ;we only care about the high byte
+@inner_delay_loop:
+ jsr ip65_process
+ lda tcp_state
+ cmp #tcp_cxn_state_established
+ bne @connection_closed
+
+ jsr timer_read
+ cpx tcp_timer ;this will tick over after about 1/4 of a second
+ beq @inner_delay_loop
+
+ dec tcp_loop_count
+ bne @outer_delay_loop
+
+ inc tcp_packet_sent_count
+ lda tcp_packet_sent_count
+ cmp #MAX_TCP_PACKETS_SENT-1
+ bpl @too_many_messages_sent
+ jmp @send_fin_loop
+@too_many_messages_sent:
+@failed:
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+ lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
+ sta ip65_error
+ sec ;signal an error
+ rts
+
+
+
+;send a string over the current tcp connection
+;inputs:
+; tcp connection should already be opened
+; AX: pointer to buffer - data up to (but not including)
+; the first nul byte will be sent. max of 255 bytes will be sent.
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_send_string:
+ stax tcp_send_data_ptr
+ stax copy_src
+ lda #0
+ tay
+ sta tcp_send_data_len
+ sta tcp_send_data_len+1
+ lda (copy_src),y
+ bne @find_end_of_string
+ rts ; if the string is empty, don't send anything!
+@find_end_of_string:
+ lda (copy_src),y
+ beq @done
+ inc tcp_send_data_len
+ iny
+ bne @find_end_of_string
+@done:
+ ldax tcp_send_data_ptr
+ ;now we can fall through into tcp_send
+
+
+;send tcp data
+;inputs:
+; tcp connection should already be opened
+; tcp_send_data_len: length of data to send (exclusive of any headers)
+; AX: pointer to buffer containing data to be sent
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_send:
+
+ stax tcp_send_data_ptr
+
+ lda tcp_state
+ cmp #tcp_cxn_state_established
+ beq @connection_established
+ lda #KPR_ERROR_CONNECTION_CLOSED
+ sta ip65_error
+ sec
+ rts
+ lda #0 ;reset the "packet sent" counter
+ sta tcp_packet_sent_count
+
+@connection_established:
+ ;increment the expected sequence number
+ ldax #tcp_connect_expected_ack_number
+ stax acc32
+ ldax tcp_send_data_len
+ jsr add_16_32
+
+
+@tcp_polling_loop:
+
+ ;create a data packet
+ lda #tcp_flag_ACK+tcp_flag_PSH
+ sta tcp_flags
+ ldax tcp_send_data_len
+ stax tcp_data_len
+
+ ldax tcp_send_data_ptr
+ stax tcp_data_ptr
+
+ ldx #3 ;
+: lda tcp_connect_ip,x
+ sta tcp_remote_ip,x
+ lda tcp_connect_sequence_number,x
+ sta tcp_sequence_number,x
+
+ dex
+ bpl :-
+ ldax tcp_connect_local_port
+ stax tcp_local_port
+ ldax tcp_connect_remote_port
+ stax tcp_remote_port
+
+
+ jsr tcp_send_packet
+ lda tcp_packet_sent_count
+ adc #1
+ sta tcp_loop_count ;we wait a bit longer between each resend
+@outer_delay_loop:
+ jsr timer_read
+ stx tcp_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
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+
+ rts
+@no_abort:
+ ldax #tcp_connect_last_ack
+ stax acc32
+ ldax #tcp_connect_expected_ack_number
+ stax op32
+ jsr cmp_32_32
+ beq @got_ack
+
+ jsr timer_read
+ cpx tcp_timer ;this will tick over after about 1/4 of a second
+ beq @inner_delay_loop
+
+ dec tcp_loop_count
+ bne @outer_delay_loop
+
+
+ inc tcp_packet_sent_count
+ lda tcp_packet_sent_count
+ cmp #MAX_TCP_PACKETS_SENT-1
+ bpl @too_many_messages_sent
+ jmp @tcp_polling_loop
+
+@too_many_messages_sent:
+@failed:
+
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+ lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
+ sta ip65_error
+ sec ;signal an error
+ rts
+@got_ack:
+ ;finished - now we need to advance the sequence number for the data we just sent
+ ldax #tcp_connect_sequence_number
+ stax acc32
+ ldax tcp_send_data_len
+ jsr add_16_32
+
+ clc
+ rts
+
+
+;send a single tcp packet
+;inputs:
+; tcp_remote_ip: IP address of destination server
+; tcp_remote_port: destination tcp port
+; tcp_local_port: source tcp port
+; tcp_flags: 6 bit flags
+; tcp_data_ptr: pointer to data to include in this packet
+; tcp_data_len: length of data pointed at by tcp_data_ptr
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_send_packet:
+ ldax tcp_data_ptr
+ stax copy_src ; copy data to output buffer
+ ldax #tcp_outp + tcp_data
+ stax copy_dest
+ ldax tcp_data_len
+ jsr copymem
+
+ ldx #3 ; copy virtual header addresses
+: lda tcp_remote_ip,x
+ sta tcp_vh + tcp_vh_dest,x ; set virtual header destination
+ lda cfg_ip,x
+ sta tcp_vh + tcp_vh_src,x ; set virtual header source
+ dex
+ bpl :-
+
+ lda tcp_local_port ; copy source port
+ sta tcp_outp + tcp_src_port + 1
+ lda tcp_local_port + 1
+ sta tcp_outp + tcp_src_port
+
+ lda tcp_remote_port ; copy destination port
+ sta tcp_outp + tcp_dest_port + 1
+ lda tcp_remote_port + 1
+ sta tcp_outp + tcp_dest_port
+
+ ldx #3 ; copy sequence and ack (if ACK flag set) numbers (in reverse order)
+ ldy #0
+: lda tcp_sequence_number,x
+ sta tcp_outp + tcp_seq,y
+ lda #tcp_flag_ACK
+ bit tcp_flags
+ bne @ack_set
+ lda #0
+ beq @sta_ack
+ @ack_set:
+ lda tcp_ack_number,x
+ @sta_ack:
+ sta tcp_outp + tcp_ack,y
+ iny
+ dex
+ bpl :-
+
+ lda #$50 ;4 bit header length in 32bit words + 4 bits of zero
+ sta tcp_outp+tcp_header_length
+ lda tcp_flags
+ sta tcp_outp+tcp_flags_field
+
+ lda #ip_proto_tcp
+ sta tcp_vh + tcp_vh_proto
+
+ ldax #$0010 ;$1000 in network byte order
+ stax tcp_outp+tcp_window_size
+
+ lda #0 ; clear checksum
+ sta tcp_outp + tcp_checksum
+ sta tcp_outp + tcp_checksum + 1
+ sta tcp_vh + tcp_vh_zero ; clear virtual header zero byte
+
+ ldax #tcp_vh ; checksum pointer to virtual header
+ stax ip_cksum_ptr
+
+ lda tcp_data_len ; copy length + 20
+ clc
+ adc #20
+ sta tcp_vh + tcp_vh_len + 1 ; lsb for virtual header
+ tay
+ lda tcp_data_len + 1
+ adc #0
+ sta tcp_vh + tcp_vh_len ; msb for virtual header
+
+ tax ; length to A/X
+ tya
+
+ clc ; add 12 bytes for virtual header
+ adc #12
+ bcc :+
+ inx
+:
+ jsr ip_calc_cksum ; calculate checksum
+ stax tcp_outp + tcp_checksum
+
+ ldx #3 ; copy addresses
+: lda tcp_remote_ip,x
+ sta ip_outp + ip_dest,x ; set ip destination address
+ dex
+ bpl :-
+
+ jsr ip_create_packet ; create ip packet template
+
+ lda tcp_data_len ; ip len = tcp data length +20 byte ip header + 20 byte tcp header
+ ldx tcp_data_len +1
+ clc
+ adc #40
+ bcc :+
+ inx
+: sta ip_outp + ip_len + 1 ; set length
+ stx ip_outp + ip_len
+
+ ldax #$1234 ; set ID
+ stax ip_outp + ip_id
+
+ lda #ip_proto_tcp ; set protocol
+ sta ip_outp + ip_proto
+
+ jmp ip_send ; send packet, sec on error
+
+
+
+check_current_connection:
+;see if the ip packet we just got is for a valid (non-closed) tcp connection
+;inputs:
+; eth_inp: should contain an ethernet frame encapsulating an inbound tcp packet
+;outputs:
+; carry flag clear if inbound tcp packet part of existing connection
+
+
+ lda tcp_state
+ cmp #tcp_cxn_state_closed
+ bne @connection_not_closed
+ sec
+ rts
+@connection_not_closed:
+ ldax #ip_inp+ip_src
+ stax acc32
+ ldax #tcp_connect_ip
+ stax op32
+ jsr cmp_32_32
+ beq @remote_ip_matches
+
+ sec
+ rts
+@remote_ip_matches:
+ ldax tcp_inp+tcp_src_port
+ stax acc16
+ lda tcp_connect_remote_port+1 ;this value in reverse byte order to how it is presented in the TCP header
+ ldx tcp_connect_remote_port
+ jsr cmp_16_16
+ beq @remote_port_matches
+ sec
+ rts
+@remote_port_matches:
+ ldax tcp_inp+tcp_dest_port
+ stax acc16
+ lda tcp_connect_local_port+1 ;this value in reverse byte order to how it is presented in the TCP header
+ ldx tcp_connect_local_port
+ jsr cmp_16_16
+ beq @local_port_matches
+ sec
+ rts
+@local_port_matches:
+ clc
+ rts
+
+;process incoming tcp packet
+;called automatically by ip_process if "ip.s" was compiled with -DTCP
+;inputs:
+; eth_inp: should contain an ethernet frame encapsulating an inbound tcp packet
+;outputs:
+; none but if connection was found, an outbound message may be created, overwriting eth_outp
+; also tcp_state and other tcp variables may be modified
+tcp_process:
+
+ lda #tcp_flag_RST
+ bit tcp_inp+tcp_flags_field
+ beq @not_reset
+ jsr check_current_connection
+ bcs @not_current_connection_on_rst
+ ;for some reason, search.twitter.com is sending RSTs with ID=$1234 (i.e. echoing the inbound ID)
+ ;but then keeps the connection open and ends up sending the file.
+ ;so lets ignore a reset with ID=$1234
+ lda ip_inp+ip_id
+ cmp #$34
+ bne @not_invalid_reset
+ lda ip_inp+ip_id+1
+ cmp #$12
+ bne @not_invalid_reset
+ jmp @send_ack
+@not_invalid_reset:
+ ;connection has been reset so mark it as closed
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+ lda #KPR_ERROR_CONNECTION_RESET_BY_PEER
+ sta ip65_error
+
+ lda #$ff
+ sta tcp_inbound_data_length
+ sta tcp_inbound_data_length+1
+ jsr jmp_to_callback ;let the caller see the connection has closed
+
+@not_current_connection_on_rst:
+ ;if we get a reset for a closed or nonexistent connection, then ignore it
+ rts
+@not_reset:
+ lda tcp_inp+tcp_flags_field
+ cmp #tcp_flag_SYN+tcp_flag_ACK
+ bne @not_syn_ack
+
+ ;it's a SYN/ACK
+ jsr check_current_connection
+ bcc @current_connection_on_syn_ack
+ ;if we get a SYN/ACK for something that aint the connection we're expecting,
+ ;terminate with extreme prejudice
+ jmp @send_rst
+@current_connection_on_syn_ack:
+ lda tcp_state
+ cmp #tcp_cxn_state_syn_sent
+ bne @not_expecting_syn_ack
+ ;this IS the syn/ack we are waiting for :-)
+ ldx #3 ; copy sequence number to ack (in reverse order)
+ ldy #0
+: lda tcp_inp + tcp_seq,y
+ sta tcp_connect_ack_number,x
+ iny
+ dex
+ bpl :-
+
+ ldax #tcp_connect_ack_number
+ stax acc32
+ ldax #$0001 ;
+ jsr add_16_32 ;increment the ACK counter by 1, for the SYN we just received
+
+
+ lda #tcp_cxn_state_established
+ sta tcp_state
+
+@not_expecting_syn_ack:
+;we get a SYN/ACK for the current connection,
+;but we're not expecting it, it's probably
+;a retransmist - just ACK it
+ jmp @send_ack
+
+
+@not_syn_ack:
+
+;is it an ACK - alone or with PSH/URGENT but not a SYN/ACK?
+ lda #tcp_flag_ACK
+ bit tcp_inp+tcp_flags_field
+ bne @ack
+ jmp @not_ack
+@ack:
+ ;is this the current connection?
+ jsr check_current_connection
+ bcc @current_connection_on_ack
+ ;if we get an ACK for something that is not the current connection
+ ;we should send a RST
+ jmp @send_rst
+@current_connection_on_ack:
+ ;if it's an ACK, then record the last ACK (reorder the bytes in the process)
+ ldx #3 ; copy seq & ack fields (in reverse order)
+ ldy #0
+: lda tcp_inp + tcp_ack,y
+ sta tcp_connect_last_ack,x
+ lda tcp_inp + tcp_seq,y
+ sta tcp_connect_last_received_seq_number,x
+ iny
+ dex
+ bpl :-
+
+ ;was this the next sequence number we're waiting for?
+ ldax #tcp_connect_ack_number
+ stax acc32
+ ldax #tcp_connect_last_received_seq_number
+ stax op32
+ jsr cmp_32_32
+
+ bne @not_expected_seq_number
+
+
+
+ ;what is the size of data in this packet?
+ lda ip_inp+ip_len+1 ;payload length (lo byte)
+ sta acc16
+ lda ip_inp+ip_len ;payload length (hi byte)
+ sta acc16+1
+ lda tcp_inp+tcp_header_length ;high 4 bits is header length in 32 bit words
+ lsr ; A=A/2
+ lsr ; A=A/2
+ clc ; A now equal to tcp header length in bytes
+ adc #20 ;add 20 bytes for IP header. this gives length of IP +TCP headers
+ ldx #0
+ sta tcp_header_length
+ jsr sub_16_16
+
+ ;acc16 now contains the length of data in this TCP packet
+
+ lda acc16
+ sta tcp_inbound_data_length
+ lda acc16+1
+ sta tcp_inbound_data_length+1
+ bne @not_empty_packet
+ lda acc16
+ bne @not_empty_packet
+ jmp @empty_packet
+@not_empty_packet:
+
+
+ ;calculate ptr to tcp data
+ clc
+ lda tcp_header_length
+ adc #ip_inp
+ adc #0
+ sta tcp_inbound_data_ptr+1
+
+ ; do a callback
+ jsr jmp_to_callback
+
+
+ ; move ack ptr along
+ ldax #tcp_connect_ack_number
+ stax acc32
+ ldax tcp_inbound_data_length
+ jsr add_16_32
+
+
+@not_expected_seq_number: ;send an ACK with the sequence number we expect
+
+ ;send the ACK for any data in this packet, then return to check for FIN flag
+ jsr @send_ack
+
+@not_ack:
+@empty_packet:
+
+;is it a FIN?
+ lda #tcp_flag_FIN
+ bit tcp_inp+tcp_flags_field
+ bne @fin
+ jmp @not_fin
+@fin:
+ ;is this the current connection?
+ jsr check_current_connection
+ bcc :+
+ jmp @send_rst ;reset if not current connection
+:
+ ldx #3 ; copy seq field (in reverse order)
+ ldy #0
+: lda tcp_inp + tcp_seq,y
+ sta tcp_connect_last_received_seq_number,x
+ iny
+ dex
+ bpl :-
+
+ ;was this the next sequence number we're waiting for?
+ ldax #tcp_connect_ack_number
+ stax acc32
+ ldax #tcp_connect_last_received_seq_number
+ stax op32
+ jsr cmp_32_32
+
+ beq :+
+ rts ;bail if not expected sequence number
+:
+
+ ;set the length to $ffff
+ lda #$ff
+ sta tcp_inbound_data_length
+ sta tcp_inbound_data_length+1
+ jsr jmp_to_callback ;let the caller see the connection has closed
+
+
+ lda #tcp_cxn_state_closed
+ sta tcp_state
+
+ ;send a FIN/ACK
+ ; move ack ptr along for the inbound FIN
+ ldax #tcp_connect_ack_number
+ stax acc32
+ ldax #$01
+ sta tcp_fin_sent
+ jsr add_16_32
+
+ ;if we've already sent a FIN then just send back an ACK
+ lda tcp_fin_sent
+ beq @send_fin_ack
+;if we get here, we've sent a FIN, and just received an inbound FIN.
+;when we sent the fin, we didn't update the sequence number, since
+;we want to use the old sequence on every resend of that FIN
+;now that our fin has been ACKed, we need to inc the sequence number
+;and then send another ACK.
+
+ ldax #tcp_connect_sequence_number
+ stax acc32
+ ldax #$0001 ;
+ jsr add_16_32 ;increment the SEQ counter by 1, for the FIN we have been sending
+
+ lda #tcp_flag_ACK
+ jmp @send_packet
+
+@send_fin_ack:
+
+ lda #tcp_flag_FIN+tcp_flag_ACK
+
+ jmp @send_packet
+
+
+@not_fin:
+
+ lda tcp_inp+tcp_flags_field
+ cmp #tcp_flag_SYN
+ beq @syn
+ jmp @not_syn
+@syn:
+
+ ;is this the port we are listening on?
+ lda tcp_inp+tcp_dest_port+1
+ cmp tcp_listen_port
+ bne @decline_syn_with_reset
+ lda tcp_inp+tcp_dest_port
+ cmp tcp_listen_port+1
+ bne @decline_syn_with_reset
+
+ ;it's the right port - are we actually waiting for a connecting?
+ lda #tcp_cxn_state_listening
+ cmp tcp_state
+ beq @this_is_connection_we_are_waiting_for
+ ;is this the current connection? that would mean our ACK got lost, so resend
+ jsr check_current_connection
+ bcc @this_is_connection_we_are_waiting_for
+
+ rts ;if we've currently got a connection open, then ignore any new requests
+ ;the sender will timeout and resend the SYN, by which time we may be
+ ;ready to accept it again.
+
+@this_is_connection_we_are_waiting_for:
+
+ ; copy sequence number to ack (in reverse order) and remote IP
+ ldx #3
+ ldy #0
+: lda tcp_inp + tcp_seq,y
+ sta tcp_connect_ack_number,x
+ lda ip_inp+ip_src,x
+ sta tcp_connect_ip,x
+ iny
+ dex
+ bpl :-
+
+ ;copy ports
+ ldax tcp_listen_port
+ stax tcp_connect_local_port
+
+ lda tcp_inp+tcp_src_port+1
+ sta tcp_connect_remote_port
+ lda tcp_inp+tcp_src_port
+ sta tcp_connect_remote_port+1
+
+ lda #tcp_cxn_state_established
+ sta tcp_state
+
+ ldax #tcp_connect_ack_number
+ stax acc32
+ ldax #$0001 ;
+ jsr add_16_32 ;increment the ACK counter by 1, for the SYN we just received
+ lda #tcp_flag_SYN+tcp_flag_ACK
+ jmp @send_packet
+
+@decline_syn_with_reset:
+;create a RST packet
+ ldx #3 ; copy sequence number to ack (in reverse order)
+ ldy #0
+: lda tcp_inp + tcp_seq,y
+ sta tcp_ack_number,x
+ iny
+ dex
+ bpl :-
+
+ ldax #tcp_ack_number
+ stax acc32
+ ldax #$0001 ;
+ jsr add_16_32 ;increment the ACK counter by 1, for the SYN we just received
+
+@send_rst:
+
+ lda #tcp_flag_RST+tcp_flag_ACK
+ sta tcp_flags
+ ldax #0
+ stax tcp_data_len
+ ldx #3 ;
+: lda ip_inp+ip_src,x
+ sta tcp_remote_ip,x
+ dex
+ bpl :-
+
+ ;copy src/dest ports in inverted byte order
+ lda tcp_inp+tcp_src_port
+ sta tcp_remote_port+1
+ lda tcp_inp+tcp_src_port+1
+ sta tcp_remote_port
+
+ lda tcp_inp+tcp_dest_port
+ sta tcp_local_port+1
+ lda tcp_inp+tcp_dest_port+1
+ sta tcp_local_port
+
+ jsr tcp_send_packet
+ rts
+
+@not_syn:
+ rts
+
+@send_ack:
+
+;create an ACK packet
+ lda #tcp_flag_ACK
+
+@send_packet:
+ sta tcp_flags
+ ldax #0
+ stax tcp_data_len
+ ldx #3 ;
+: lda tcp_connect_ip,x
+ sta tcp_remote_ip,x
+ lda tcp_connect_ack_number,x
+ sta tcp_ack_number,x
+;if we have just sent a packet out, we may not yet have updated tcp_connect_sequence_number yet
+;so use current value of tcp_connect_expected_ack_number as outbound sequence number instead
+ lda tcp_connect_expected_ack_number,x
+ sta tcp_sequence_number,x
+ dex
+ bpl :-
+ ldax tcp_connect_local_port
+ stax tcp_local_port
+ ldax tcp_connect_remote_port
+ stax tcp_remote_port
+
+
+ jmp tcp_send_packet
+
+
+;send an empty ACK packet on the current connection
+;inputs:
+; none
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+tcp_send_keep_alive=@send_ack
+
+;-- LICENSE FOR tcp.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/ip65/telnet.s b/ip65/telnet.s
similarity index 95%
rename from client/ip65/telnet.s
rename to ip65/telnet.s
index bfc3384..1e88a84 100644
--- a/client/ip65/telnet.s
+++ b/ip65/telnet.s
@@ -1,496 +1,496 @@
-;minimal telnet implementation (dumb terminal emulation only)
-;to use:
-;set the following variables - telnet_use_native_charset,telnet_port,telnet_ip
-;then call telnet_connect
-;you must also define (and export) these function
-; telnet_menu - called whenever the F1 key is pressed.
-; telnet_on_connection - called after succesful connection
-
-.include "../inc/common.i"
-
- .import tcp_connect
- .import tcp_callback
- .import tcp_connect_ip
- .import tcp_listen
- .importzp KEYCODE_F1
- .import tcp_inbound_data_ptr
- .import tcp_inbound_data_length
- .import tcp_send
- .import tcp_send_data_len
- .import tcp_close
- .import print_a
- .import print_cr
- .import vt100_init_terminal
- .import vt100_process_inbound_char
- .import vt100_transform_outbound_char
- .import tcp_send_keep_alive
- .import timer_read
-
- .import ip65_process
- .import get_key_if_available
- .import get_filtered_input
- .import check_for_abort_key
- .import ok_msg
- .import failed_msg
- .import print
- .import print_errorcode
- .import native_to_ascii
- .import ascii_to_native
-
-.export telnet_connect
-.export telnet_use_native_charset
-.export telnet_port
-.export telnet_ip
-
-.import telnet_menu
-.import telnet_on_connection
-
-.importzp buffer_ptr
-
-.code
-
-;connect to a remote telnet server
-;inputs:
-;telnet_use_native_charset: set to 0 if remote server uses standard ASCII, 1 if remote server uses the 'native' charset (i.e. PETSCII)
-;telnet_port: port number to connect to
-;telnet_ip: ip address of remote server
-telnet_connect:
- lda telnet_use_native_charset
- bne :+
- jsr vt100_init_terminal
-:
- ldax #telnet_callback
- stax tcp_callback
- ldx #3
-@copy_dest_ip:
- lda telnet_ip,x
- sta tcp_connect_ip,x
- dex
- bpl @copy_dest_ip
-
- ldax telnet_port
- jsr tcp_connect
-
- bcc @connect_ok
- jsr print_cr
- ldax #failed_msg
- jsr print
- jsr print_cr
- jsr print_errorcode
- rts
-@connect_ok:
-
- jsr telnet_on_connection
-
- ldax #ok_msg
- jsr print
- jsr print_cr
- lda #0
- sta connection_closed
- sta iac_response_buffer_length
-
-@main_polling_loop:
-
- jsr check_for_abort_key
- bcc @no_abort
- jsr tcp_close
- jmp @disconnected
-
-@no_abort:
- jsr timer_read
- txa
- adc #$20 ;32 x 1/4 = ~ 8seconds
- sta telnet_timeout
-@wait_for_keypress:
- jsr timer_read
- cpx telnet_timeout
- bne @no_timeout
- jsr tcp_send_keep_alive
- jmp @main_polling_loop
-@no_timeout:
- jsr ip65_process
- lda connection_closed
- beq @not_disconnected
-@disconnected:
- ldax #disconnected
- jsr print
- rts
-@not_disconnected:
- lda iac_response_buffer_length
- beq @no_iac_response
- ldx #0
- stax tcp_send_data_len
- stx iac_response_buffer_length
- ldax #iac_response_buffer
- jsr tcp_send
-@no_iac_response:
-
-
-
- jsr get_key_if_available
- beq @wait_for_keypress
-
- cmp #KEYCODE_F1
- bne @not_telnet_menu
- jsr telnet_menu
- jmp @main_polling_loop
-@not_telnet_menu:
-
- ldx #0
- stx tcp_send_data_len
- stx tcp_send_data_len+1
-
- ldx telnet_use_native_charset
- bne @no_conversion_required
-
-
- jsr vt100_transform_outbound_char
-
- sta temp_a
- tya
- bne :+
- jmp @main_polling_loop ;Y=0 means nothing to send
-:
-
- cmp #2
- beq :+
- lda temp_a
- jmp @no_conversion_required
-:
-
-
- lda temp_a
- stax buffer_ptr
- ldy #0
-:
- lda (buffer_ptr),y
- beq @send_char
- sta scratch_buffer,y
- inc tcp_send_data_len
- iny
- bne :-
- jmp @send_char
-
-@no_conversion_required:
- ldy tcp_send_data_len
- sta scratch_buffer,y
- inc tcp_send_data_len
-
-@send_char:
-
- ldax #scratch_buffer
- jsr tcp_send
- bcs @error_on_send
- jmp @main_polling_loop
-
-@error_on_send:
- ldax #transmission_error
- jsr print
- jmp print_errorcode
-
-
-;tcp callback - will be executed whenever data arrives on the TCP connection
-telnet_callback:
-
- lda tcp_inbound_data_length+1
- cmp #$ff
- bne @not_eof
- lda #1
- sta connection_closed
- rts
-@not_eof:
-
- ldax tcp_inbound_data_ptr
- stax buffer_ptr
- lda tcp_inbound_data_length
- sta buffer_length
- lda tcp_inbound_data_length+1
- sta buffer_length+1
-
-@next_byte:
- ldy #0
- lda (buffer_ptr),y
- tax
- lda telnet_use_native_charset
- beq :+
- jmp @no_conversion_req
-:
-
-;if we get here, we are in ASCII 'char at a time' mode, so look for (and process) Telnet style IAC bytes
- lda telnet_state
- cmp #telnet_state_got_command
- bne :+
- jmp @waiting_for_option
-:
- cmp #telnet_state_got_iac
- beq @waiting_for_command
- cmp #telnet_state_got_suboption
- beq @waiting_for_suboption_end
-; we must be in 'normal' mode
- txa
- cmp #255
- beq :+
- jmp @not_iac
-:
- lda #telnet_state_got_iac
- sta telnet_state
- jmp @byte_processed
-
-@waiting_for_suboption_end:
- txa
-
- ldx iac_suboption_buffer_length
- sta iac_suboption_buffer,x
- inc iac_suboption_buffer_length
- cmp #$f0 ;SE - suboption end
- bne @exit_suboption
-
- lda #telnet_state_normal
- sta telnet_state
- lda iac_suboption_buffer
- cmp #$18
- bne @not_terminal_type
-
- ldx #0
-:
- lda terminal_type_response,x
- ldy iac_response_buffer_length
- inc iac_response_buffer_length
- sta iac_response_buffer,y
- inx
- txa
- cmp #terminal_type_response_length
- bne :-
-
-@not_terminal_type:
-
-@exit_suboption:
- jmp @byte_processed
-@waiting_for_command:
- txa
- sta telnet_command
- cmp #$fa ; SB - suboption begin
- beq @suboption
- cmp #$fb ;WILL
- beq @option
- cmp #$fc ;WONT
- beq @option
- cmp #$fd ; DO
- beq @option
- cmp #$fe ;DONT
- beq @option
-;we got a command we don't understand - just ignore it
- lda #telnet_state_normal
- sta telnet_state
- jmp @byte_processed
-@suboption:
-
- lda #telnet_state_got_suboption
- sta telnet_state
- lda #0
- sta iac_suboption_buffer_length
- jmp @byte_processed
-
-@option:
- lda #telnet_state_got_command
- sta telnet_state
- jmp @byte_processed
-
-@waiting_for_option:
-;we have now got IAC, ,
- txa
- sta telnet_option
- lda telnet_command
-
- cmp #$fb
- beq @iac_will
-
- cmp #$fc
- beq @iac_wont
-
- cmp #$fe
- beq @iac_dont
-
- ;if we get here, then it's a "do"
-
-
- lda telnet_option
-
- cmp #$18 ;terminal type
- beq @do_terminaltype
-
- cmp #$1f
- beq @do_naws
-
-
- ;if we get here, then it's a "do" command we don't honour
-
-@iac_dont:
- lda #$fc ;wont
-@add_iac_response:
- ldx iac_response_buffer_length
- sta iac_response_buffer+1,x
- lda #255
- sta iac_response_buffer,x
- lda telnet_option
- sta iac_response_buffer+2,x
-
- inc iac_response_buffer_length
- inc iac_response_buffer_length
- inc iac_response_buffer_length
-@after_set_iac_response:
- lda #telnet_state_normal
- sta telnet_state
- jmp @byte_processed
-@iac_will:
- lda telnet_option
- cmp #$01 ;ECHO
- beq @will_echo
- cmp #$03 ;DO SUPPRESS GA
- beq @will_suppress_ga
-
-@iac_wont:
- lda #$fe ;dont
- jmp @add_iac_response
-
-@will_echo:
- lda #$fd ;DO
- jmp @add_iac_response
-
-@will_suppress_ga:
- lda #$fd ;DO
- jmp @add_iac_response
-
-@do_naws:
- ldx #0
-:
- lda naws_response,x
- ldy iac_response_buffer_length
- inc iac_response_buffer_length
- sta iac_response_buffer,y
- inx
- txa
- cmp #naws_response_length
- bne :-
-
- jmp @after_set_iac_response
-
-@do_terminaltype:
- lda #$fb ;WILL
- jmp @add_iac_response
-
-
-@not_iac:
-@convert_to_native:
- txa
- jsr vt100_process_inbound_char
- jmp @byte_processed
-@no_conversion_req:
- txa
- jsr print_a
-@byte_processed:
- inc buffer_ptr
- bne :+
- inc buffer_ptr+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
-
-;constants
-closing_connection: .byte "CLOSING CONNECTION",13,0
-disconnected: .byte 13,"CONNECTION CLOSED",13,0
-transmission_error: .byte "ERROR WHILE SENDING ",0
-
-;initial_telnet_options:
-; .byte $ff,$fb,$1F ;IAC WILL NAWS
-; .byte $ff,$fb,$18 ;IAC WILL TERMINAL TYPE
-
-;initial_telnet_options_length=*-initial_telnet_options
-
-terminal_type_response:
- .byte $ff ; IAC
- .byte $fa; SB
- .byte $18 ; TERMINAL TYPE
- .byte $0 ; IS
- .byte "vt100" ;what we pretend to be
- .byte $ff ; IAC
- .byte $f0 ; SE
-terminal_type_response_length=*-terminal_type_response
-
-
-naws_response:
- .byte $ff,$fb,$1F ;IAC WILL NAWS
- .byte $ff ; IAC
- .byte $fa; SB
- .byte $1F ; NAWS
- .byte $00 ; width (high byte)
- .byte 40 ; width (low byte)
- .byte $00 ; height (high byte)
- .byte 25 ; height (low byte)
-
- .byte $ff ; IAC
- .byte $f0 ; SE
-
-naws_response_length=*-naws_response
-
-
-;variables
-.segment "APP_SCRATCH"
-telnet_ip: .res 4 ;ip address of remote server
-telnet_port: .res 2 ;port number to connect to
-telnet_timeout: .res 1
-connection_closed: .res 1
-telnet_use_native_charset: .res 1 ; 0 means all data is translated to/from NVT ASCII
-buffer_offset: .res 1
-telnet_command: .res 1
-telnet_option: .res 1
-
-telnet_state_normal = 0
-telnet_state_got_iac = 1
-telnet_state_got_command = 2
-telnet_state_got_suboption=3
-
-buffer_length: .res 2
-
-telnet_state: .res 1
-temp_a: .res 1
-iac_response_buffer: .res 64
-iac_response_buffer_length: .res 1
-scratch_buffer : .res 40
-iac_suboption_buffer: .res 64
-iac_suboption_buffer_length: .res 1
-
-
-;-- LICENSE FOR telnet.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 --
+;minimal telnet implementation (dumb terminal emulation only)
+;to use:
+;set the following variables - telnet_use_native_charset,telnet_port,telnet_ip
+;then call telnet_connect
+;you must also define (and export) these function
+; telnet_menu - called whenever the F1 key is pressed.
+; telnet_on_connection - called after succesful connection
+
+.include "../inc/common.i"
+
+ .import tcp_connect
+ .import tcp_callback
+ .import tcp_connect_ip
+ .import tcp_listen
+ .importzp KEYCODE_F1
+ .import tcp_inbound_data_ptr
+ .import tcp_inbound_data_length
+ .import tcp_send
+ .import tcp_send_data_len
+ .import tcp_close
+ .import print_a
+ .import print_cr
+ .import vt100_init_terminal
+ .import vt100_process_inbound_char
+ .import vt100_transform_outbound_char
+ .import tcp_send_keep_alive
+ .import timer_read
+
+ .import ip65_process
+ .import get_key_if_available
+ .import get_filtered_input
+ .import check_for_abort_key
+ .import ok_msg
+ .import failed_msg
+ .import print
+ .import print_errorcode
+ .import native_to_ascii
+ .import ascii_to_native
+
+.export telnet_connect
+.export telnet_use_native_charset
+.export telnet_port
+.export telnet_ip
+
+.import telnet_menu
+.import telnet_on_connection
+
+.importzp buffer_ptr
+
+.code
+
+;connect to a remote telnet server
+;inputs:
+;telnet_use_native_charset: set to 0 if remote server uses standard ASCII, 1 if remote server uses the 'native' charset (i.e. PETSCII)
+;telnet_port: port number to connect to
+;telnet_ip: ip address of remote server
+telnet_connect:
+ lda telnet_use_native_charset
+ bne :+
+ jsr vt100_init_terminal
+:
+ ldax #telnet_callback
+ stax tcp_callback
+ ldx #3
+@copy_dest_ip:
+ lda telnet_ip,x
+ sta tcp_connect_ip,x
+ dex
+ bpl @copy_dest_ip
+
+ ldax telnet_port
+ jsr tcp_connect
+
+ bcc @connect_ok
+ jsr print_cr
+ ldax #failed_msg
+ jsr print
+ jsr print_cr
+ jsr print_errorcode
+ rts
+@connect_ok:
+
+ jsr telnet_on_connection
+
+ ldax #ok_msg
+ jsr print
+ jsr print_cr
+ lda #0
+ sta connection_closed
+ sta iac_response_buffer_length
+
+@main_polling_loop:
+
+ jsr check_for_abort_key
+ bcc @no_abort
+ jsr tcp_close
+ jmp @disconnected
+
+@no_abort:
+ jsr timer_read
+ txa
+ adc #$20 ;32 x 1/4 = ~ 8seconds
+ sta telnet_timeout
+@wait_for_keypress:
+ jsr timer_read
+ cpx telnet_timeout
+ bne @no_timeout
+ jsr tcp_send_keep_alive
+ jmp @main_polling_loop
+@no_timeout:
+ jsr ip65_process
+ lda connection_closed
+ beq @not_disconnected
+@disconnected:
+ ldax #disconnected
+ jsr print
+ rts
+@not_disconnected:
+ lda iac_response_buffer_length
+ beq @no_iac_response
+ ldx #0
+ stax tcp_send_data_len
+ stx iac_response_buffer_length
+ ldax #iac_response_buffer
+ jsr tcp_send
+@no_iac_response:
+
+
+
+ jsr get_key_if_available
+ beq @wait_for_keypress
+
+ cmp #KEYCODE_F1
+ bne @not_telnet_menu
+ jsr telnet_menu
+ jmp @main_polling_loop
+@not_telnet_menu:
+
+ ldx #0
+ stx tcp_send_data_len
+ stx tcp_send_data_len+1
+
+ ldx telnet_use_native_charset
+ bne @no_conversion_required
+
+
+ jsr vt100_transform_outbound_char
+
+ sta temp_a
+ tya
+ bne :+
+ jmp @main_polling_loop ;Y=0 means nothing to send
+:
+
+ cmp #2
+ beq :+
+ lda temp_a
+ jmp @no_conversion_required
+:
+
+
+ lda temp_a
+ stax buffer_ptr
+ ldy #0
+:
+ lda (buffer_ptr),y
+ beq @send_char
+ sta scratch_buffer,y
+ inc tcp_send_data_len
+ iny
+ bne :-
+ jmp @send_char
+
+@no_conversion_required:
+ ldy tcp_send_data_len
+ sta scratch_buffer,y
+ inc tcp_send_data_len
+
+@send_char:
+
+ ldax #scratch_buffer
+ jsr tcp_send
+ bcs @error_on_send
+ jmp @main_polling_loop
+
+@error_on_send:
+ ldax #transmission_error
+ jsr print
+ jmp print_errorcode
+
+
+;tcp callback - will be executed whenever data arrives on the TCP connection
+telnet_callback:
+
+ lda tcp_inbound_data_length+1
+ cmp #$ff
+ bne @not_eof
+ lda #1
+ sta connection_closed
+ rts
+@not_eof:
+
+ ldax tcp_inbound_data_ptr
+ stax buffer_ptr
+ lda tcp_inbound_data_length
+ sta buffer_length
+ lda tcp_inbound_data_length+1
+ sta buffer_length+1
+
+@next_byte:
+ ldy #0
+ lda (buffer_ptr),y
+ tax
+ lda telnet_use_native_charset
+ beq :+
+ jmp @no_conversion_req
+:
+
+;if we get here, we are in ASCII 'char at a time' mode, so look for (and process) Telnet style IAC bytes
+ lda telnet_state
+ cmp #telnet_state_got_command
+ bne :+
+ jmp @waiting_for_option
+:
+ cmp #telnet_state_got_iac
+ beq @waiting_for_command
+ cmp #telnet_state_got_suboption
+ beq @waiting_for_suboption_end
+; we must be in 'normal' mode
+ txa
+ cmp #255
+ beq :+
+ jmp @not_iac
+:
+ lda #telnet_state_got_iac
+ sta telnet_state
+ jmp @byte_processed
+
+@waiting_for_suboption_end:
+ txa
+
+ ldx iac_suboption_buffer_length
+ sta iac_suboption_buffer,x
+ inc iac_suboption_buffer_length
+ cmp #$f0 ;SE - suboption end
+ bne @exit_suboption
+
+ lda #telnet_state_normal
+ sta telnet_state
+ lda iac_suboption_buffer
+ cmp #$18
+ bne @not_terminal_type
+
+ ldx #0
+:
+ lda terminal_type_response,x
+ ldy iac_response_buffer_length
+ inc iac_response_buffer_length
+ sta iac_response_buffer,y
+ inx
+ txa
+ cmp #terminal_type_response_length
+ bne :-
+
+@not_terminal_type:
+
+@exit_suboption:
+ jmp @byte_processed
+@waiting_for_command:
+ txa
+ sta telnet_command
+ cmp #$fa ; SB - suboption begin
+ beq @suboption
+ cmp #$fb ;WILL
+ beq @option
+ cmp #$fc ;WONT
+ beq @option
+ cmp #$fd ; DO
+ beq @option
+ cmp #$fe ;DONT
+ beq @option
+;we got a command we don't understand - just ignore it
+ lda #telnet_state_normal
+ sta telnet_state
+ jmp @byte_processed
+@suboption:
+
+ lda #telnet_state_got_suboption
+ sta telnet_state
+ lda #0
+ sta iac_suboption_buffer_length
+ jmp @byte_processed
+
+@option:
+ lda #telnet_state_got_command
+ sta telnet_state
+ jmp @byte_processed
+
+@waiting_for_option:
+;we have now got IAC, ,
+ txa
+ sta telnet_option
+ lda telnet_command
+
+ cmp #$fb
+ beq @iac_will
+
+ cmp #$fc
+ beq @iac_wont
+
+ cmp #$fe
+ beq @iac_dont
+
+ ;if we get here, then it's a "do"
+
+
+ lda telnet_option
+
+ cmp #$18 ;terminal type
+ beq @do_terminaltype
+
+ cmp #$1f
+ beq @do_naws
+
+
+ ;if we get here, then it's a "do" command we don't honour
+
+@iac_dont:
+ lda #$fc ;wont
+@add_iac_response:
+ ldx iac_response_buffer_length
+ sta iac_response_buffer+1,x
+ lda #255
+ sta iac_response_buffer,x
+ lda telnet_option
+ sta iac_response_buffer+2,x
+
+ inc iac_response_buffer_length
+ inc iac_response_buffer_length
+ inc iac_response_buffer_length
+@after_set_iac_response:
+ lda #telnet_state_normal
+ sta telnet_state
+ jmp @byte_processed
+@iac_will:
+ lda telnet_option
+ cmp #$01 ;ECHO
+ beq @will_echo
+ cmp #$03 ;DO SUPPRESS GA
+ beq @will_suppress_ga
+
+@iac_wont:
+ lda #$fe ;dont
+ jmp @add_iac_response
+
+@will_echo:
+ lda #$fd ;DO
+ jmp @add_iac_response
+
+@will_suppress_ga:
+ lda #$fd ;DO
+ jmp @add_iac_response
+
+@do_naws:
+ ldx #0
+:
+ lda naws_response,x
+ ldy iac_response_buffer_length
+ inc iac_response_buffer_length
+ sta iac_response_buffer,y
+ inx
+ txa
+ cmp #naws_response_length
+ bne :-
+
+ jmp @after_set_iac_response
+
+@do_terminaltype:
+ lda #$fb ;WILL
+ jmp @add_iac_response
+
+
+@not_iac:
+@convert_to_native:
+ txa
+ jsr vt100_process_inbound_char
+ jmp @byte_processed
+@no_conversion_req:
+ txa
+ jsr print_a
+@byte_processed:
+ inc buffer_ptr
+ bne :+
+ inc buffer_ptr+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
+
+;constants
+closing_connection: .byte "CLOSING CONNECTION",13,0
+disconnected: .byte 13,"CONNECTION CLOSED",13,0
+transmission_error: .byte "ERROR WHILE SENDING ",0
+
+;initial_telnet_options:
+; .byte $ff,$fb,$1F ;IAC WILL NAWS
+; .byte $ff,$fb,$18 ;IAC WILL TERMINAL TYPE
+
+;initial_telnet_options_length=*-initial_telnet_options
+
+terminal_type_response:
+ .byte $ff ; IAC
+ .byte $fa; SB
+ .byte $18 ; TERMINAL TYPE
+ .byte $0 ; IS
+ .byte "vt100" ;what we pretend to be
+ .byte $ff ; IAC
+ .byte $f0 ; SE
+terminal_type_response_length=*-terminal_type_response
+
+
+naws_response:
+ .byte $ff,$fb,$1F ;IAC WILL NAWS
+ .byte $ff ; IAC
+ .byte $fa; SB
+ .byte $1F ; NAWS
+ .byte $00 ; width (high byte)
+ .byte 40 ; width (low byte)
+ .byte $00 ; height (high byte)
+ .byte 25 ; height (low byte)
+
+ .byte $ff ; IAC
+ .byte $f0 ; SE
+
+naws_response_length=*-naws_response
+
+
+;variables
+.segment "APP_SCRATCH"
+telnet_ip: .res 4 ;ip address of remote server
+telnet_port: .res 2 ;port number to connect to
+telnet_timeout: .res 1
+connection_closed: .res 1
+telnet_use_native_charset: .res 1 ; 0 means all data is translated to/from NVT ASCII
+buffer_offset: .res 1
+telnet_command: .res 1
+telnet_option: .res 1
+
+telnet_state_normal = 0
+telnet_state_got_iac = 1
+telnet_state_got_command = 2
+telnet_state_got_suboption=3
+
+buffer_length: .res 2
+
+telnet_state: .res 1
+temp_a: .res 1
+iac_response_buffer: .res 64
+iac_response_buffer_length: .res 1
+scratch_buffer : .res 40
+iac_suboption_buffer: .res 64
+iac_suboption_buffer_length: .res 1
+
+
+;-- LICENSE FOR telnet.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/ip65/tftp.s b/ip65/tftp.s
similarity index 96%
rename from client/ip65/tftp.s
rename to ip65/tftp.s
index 28d8e92..96a3f3d 100644
--- a/client/ip65/tftp.s
+++ b/ip65/tftp.s
@@ -1,595 +1,595 @@
-;minimal tftp implementation (client only)
-;supports file upload and download
-
-
- TFTP_MAX_RESENDS=10
- TFTP_TIMER_MASK=$F8 ;mask lower two bits, means we wait for 8 x1/4 seconds
-
- .include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- .export tftp_load_address
- .export tftp_ip
- .export tftp_download
- .export tftp_upload
- .export tftp_data_block_length
- .export tftp_set_callback_vector
- .export tftp_callback_vector
- .export tftp_clear_callbacks
- .export tftp_filesize
- .export tftp_upload_from_memory
- .import ip65_process
- .import ip65_error
-
-
- .import udp_add_listener
- .import udp_remove_listener
- .import output_buffer
- .import udp_callback
- .import udp_send
- .import check_for_abort_key
- .import udp_inp
- .import ip_inp
- .importzp ip_src
- .importzp udp_src_port
-
-
- .importzp udp_data
-
- .import udp_send_dest
- .import udp_send_src_port
- .import udp_send_dest_port
- .import udp_send_len
-
- .import copymem
- .importzp copy_src
- .importzp copy_dest
-
- .import timer_read
-
- .importzp tftp_filename
- .bss
-
-;packet offsets
-tftp_inp = udp_inp + udp_data
-tftp_outp = output_buffer
-
-;everything after filename in a request at a relative address, not fixed, so don't bother defining offset constants
-
-tftp_server_port=69
-tftp_client_port_low_byte: .res 1
-
-tftp_load_address: .res 2 ;address file will be (or was) downloaded to
-tftp_ip: .res 4 ;ip address of tftp server - set to 255.255.255.255 (broadcast) to send request to all tftp servers on local lan
-
-tftp_data_block_length: .res 2
-tftp_send_len: .res 2
-tftp_current_memloc: .res 2
-
-; tftp state machine
-tftp_initializing = 1 ; initial state
-tftp_initial_request_sent=2 ; sent the RRQ or WRQ, waiting for some data
-tftp_transmission_in_progress=3 ; we have sent/received the first packet of file data
-tftp_complete=4 ; we have sent/received the final packet of file data
-tftp_error=5 ; we got an error
-
-tftp_state: .res 1 ; current activity
-tftp_timer: .res 1
-tftp_resend_counter: .res 1
-tftp_break_inner_loop: .res 1
-tftp_current_block_number: .res 2
-tftp_actual_server_port: .res 2 ;this is read from the reply - it is not (usually) the port # we send the RRQ or WRQ to
-tftp_actual_server_ip: .res 4 ;this is read from the reply - it may not be the IP we sent to (e.g. if we send to broadcast)
-
-tftp_just_set_new_load_address: .res 1
-
-tftp_opcode: .res 2 ; will be set to 4 if we are doing a RRQ, or 7 if we are doing a DIR
-tftp_filesize: .res 2 ;will be set by tftp_download, needs to be set before calling tftp_upload_from_memory
-tftp_bytes_remaining: .res 2
-
-.code
-
-;uploads a file to a tftp server with data retrieved from specified memory location
-; inputs:
-; tftp_ip: ip address of host to send file to (set to 255.255.255.255 for broadcast)
-; tftp_filename: pointer to null terminated name of file to upload
-; tftp_load_address: starting address of data to be sent
-; tftp_filesize: length of data to send
-; outputs: carry flag is set if there was an error
-; if a callback vector has been set with tftp_set_callback_vector
-; then the specified routine will be called once for each 512 byte packet
-; to be sent to the tftp server
-tftp_upload_from_memory:
- ldax #copy_ram_to_tftp_block
- jsr tftp_set_callback_vector
- ldax tftp_filesize
- stax tftp_bytes_remaining
- lda #00
- sta tftp_filesize
- sta tftp_filesize+1
-
-;uploads a file to a tftp server with data retrieved from user supplied routine
-; inputs:
-; tftp_ip: ip address of host to send file to (set to 255.255.255.255 for broadcast)
-; tftp_filename: pointer to null terminated name of file to upload
-; a callback vector should have been set with tftp_set_callback_vector
-; outputs: carry flag is set if there was an error
-; the specified routine will be called once for each 512 byte packet
-; to be sent from the tftp server.
-tftp_upload:
- ldax #$0200 ;opcode 02 = WRQ
- jmp set_tftp_opcode
-
-;download a file from a tftp server
-; inputs:
-; tftp_ip: ip address of host to download from (set to 255.255.255.255 for broadcast)
-; tftp_filename: pointer to null terminated name of file to download
-; tftp_load_address: memory location that dir will be stored in, or $0000 to
-; treat first 2 bytes received from tftp server as memory address that rest
-; of file should be loaded into (e.g. if downloading a C64 'prg' file)
-; outputs: carry flag is set if there was an error
-; if a callback vector has been set with tftp_set_callback_vector
-; then the specified routine will be called once for each 512 byte packet
-; sent from the tftp server (each time AX will point at data block just arrived,
-; and tftp_data_block_length will contain number of bytes in that data block)
-; otherwise, the buffer at tftp_load_address will be filled
-; with file downloaded.
-; tftp_load_address: will be set to the actual address loaded into (NB - this field is
-; ignored if a callback vector has been set with tftp_set_callback_vector)
-tftp_download:
- lda #00
- sta tftp_filesize
- sta tftp_filesize+1
- ldx #$01 ;opcode 01 = RRQ (A should already be zero from having just reset file length)
-set_tftp_opcode:
- stax tftp_opcode
- lda #tftp_initializing
- sta tftp_state
- ldax #0000
- stax tftp_current_block_number
- ldax tftp_load_address
- stax tftp_current_memloc
- ldax #tftp_in
- stax udp_callback
- ldx #$69
- inc tftp_client_port_low_byte ;each transfer uses a different client port
- lda tftp_client_port_low_byte ;so we don't get confused by late replies to a previous call
-
- jsr udp_add_listener
-
- bcc :+ ;bail if we couldn't listen on the port we want
- lda #KPR_ERROR_PORT_IN_USE
- sta ip65_error
- rts
-:
-
- lda #TFTP_MAX_RESENDS
- sta tftp_resend_counter
-@outer_delay_loop:
- jsr timer_read
- txa
- and #TFTP_TIMER_MASK
- sta tftp_timer ;we only care about the high byte
- lda #0
- sta tftp_break_inner_loop
- lda tftp_state
- cmp #tftp_initializing
- bne @not_initializing
- jsr send_request_packet
-
- jmp @inner_delay_loop
-
-@not_initializing:
-
- cmp #tftp_error
- bne @not_error
-
-@exit_with_error:
- ldx #$69
- lda tftp_client_port_low_byte
- jsr udp_remove_listener
- sec
- rts
-
-@not_error:
-
- cmp #tftp_complete
- bne @not_complete
- jsr send_ack ;send the ack for the last block
- bcs @not_complete ;if we couldn't send the ACK (e.g. coz we need to do an ARP request) then keep looping
- ldx #$69
- lda tftp_client_port_low_byte
- jsr udp_remove_listener
- rts
-
-@not_complete:
- cmp #tftp_transmission_in_progress
- bne @not_transmitting
- jsr send_tftp_packet
- jmp @inner_delay_loop
-@not_transmitting:
- jsr send_request_packet
-
-@inner_delay_loop:
- jsr ip65_process
- jsr check_for_abort_key
- bcc @no_abort
- lda #KPR_ERROR_ABORTED_BY_USER
- sta ip65_error
- jmp @exit_with_error
-@no_abort:
- lda tftp_break_inner_loop
- bne @outer_delay_loop
- jsr timer_read
- txa
- and #TFTP_TIMER_MASK
- cmp tftp_timer
- beq @inner_delay_loop
-
- dec tftp_resend_counter
- bne @outer_delay_loop
- lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
- sta ip65_error
- jmp @exit_with_error
-
-send_request_packet:
- lda #tftp_initializing
- sta tftp_state
- ldax tftp_opcode
- stax tftp_outp
-
- ldx #$01 ;we inc x/y at start of loop, so
- ldy #$ff ;set them to be 1 below where we want the copy to begin
-@copy_filename_loop:
- inx
- iny
- bmi @error_in_send ;if we get to 0x80 bytes, we've gone too far
- lda (tftp_filename),y
- sta tftp_outp,x
- bne @copy_filename_loop
-
- ldy #$ff
-@copy_mode_loop:
- inx
- iny
- lda tftp_octet_mode,y
- sta tftp_outp,x
- bne @copy_mode_loop
-
- inx
- txa
- ldx #0
- stax udp_send_len
-
- ldx #$69
- lda tftp_client_port_low_byte
- stax udp_send_src_port
-
- ldx #3 ; set destination address
-: lda tftp_ip,x
- sta udp_send_dest,x
- dex
- bpl :-
-
- ldax #tftp_server_port ; set destination port
- stax udp_send_dest_port
- ldax #tftp_outp
- jsr udp_send
- bcs @error_in_send
- lda #tftp_initial_request_sent
- sta tftp_state
- rts
-@error_in_send:
- lda #KPR_ERROR_TRANSMIT_FAILED
- sta ip65_error
- sec
- rts
-
-send_ack:
- ldax #$0400 ;opcode 04 = ACK
- stax tftp_outp
- ldax #04
- stax tftp_send_len
-send_tftp_packet: ;TFTP block should be created in tftp_outp, we just add the UDP&IP stuff and send
-
- ldx tftp_current_block_number
- lda tftp_current_block_number+1
- stax tftp_outp+2
-
- ldx #$69
- lda tftp_client_port_low_byte
- stax udp_send_src_port
-
- lda tftp_actual_server_ip
- sta udp_send_dest
- lda tftp_actual_server_ip+1
- sta udp_send_dest+1
- lda tftp_actual_server_ip+2
- sta udp_send_dest+2
- lda tftp_actual_server_ip+3
- sta udp_send_dest+3
- ldx tftp_actual_server_port
- lda tftp_actual_server_port+1
- stax udp_send_dest_port
- ldax tftp_send_len
- stax udp_send_len
-
- ldax #tftp_outp
- jsr udp_send
- rts
-
-got_expected_block:
- lda tftp_current_block_number
- inc tftp_current_block_number
- bne :+
- inc tftp_current_block_number+1
-:
- lda #tftp_transmission_in_progress
- sta tftp_state
- lda #TFTP_MAX_RESENDS
- sta tftp_resend_counter
- lda #1
- sta tftp_break_inner_loop
-
- ldax udp_inp+udp_src_port
- stax tftp_actual_server_port
- ldax ip_inp+ip_src
- stax tftp_actual_server_ip
- ldax ip_inp+ip_src+2
- stax tftp_actual_server_ip+2
- rts
-
-tftp_in:
-
- lda tftp_inp+1 ;get the opcode
- cmp #5
- bne @not_an_error
-@recv_error:
- lda #tftp_error
- sta tftp_state
- lda #KPR_ERROR_TRANSMISSION_REJECTED_BY_PEER
- sta ip65_error
- rts
-@not_an_error:
-
- cmp #3
- beq :+
- jmp @not_data_block
-:
-
-
- lda #0
- sta tftp_just_set_new_load_address ;clear the flag
- clc
- lda tftp_load_address
- adc tftp_load_address+1 ;is load address currently $0000?
- bne @dont_set_load_address
-
- lda tftp_callback_address_set ;have we overridden the default handler?
- bne @dont_set_load_address ;if so, don't skip the first two bytes in the file
-
- ldax udp_inp+$0c ;get first two bytes of data
- stax tftp_load_address ;make them the new load adress
- stax tftp_current_memloc ;also the current memory destination
- lda #1 ;set the flag
- sta tftp_just_set_new_load_address
-
-@dont_set_load_address:
- ldx tftp_inp+3 ;get the (low byte) of the data block
- dex
- cpx tftp_current_block_number
- beq :+
- jmp @not_expected_block_number
-:
- ;this is the block we wanted
- jsr got_expected_block
-
- lda tftp_just_set_new_load_address
- bne @skip_first_2_bytes_in_calculating_header_length
- lda udp_inp+5 ;get the low byte of udp packet length
- sec
- sbc #$0c ;take off the length of the UDP header+OPCODE + BLOCK
-
- jmp @adjusted_header_length
-@skip_first_2_bytes_in_calculating_header_length:
- lda udp_inp+5 ;get the low byte of udp packet length
- sec
- sbc #$0e ;take off the length of the UDP header+OPCODE + BLOCK + first 2 bytes (memory location)
-@adjusted_header_length:
-
- sta tftp_data_block_length
- lda udp_inp+4 ;get high byte of the length of the UDP packet
- sbc #0
- sta tftp_data_block_length+1
-
- lda tftp_just_set_new_load_address
- bne @skip_first_2_bytes_in_calculating_copy_src
- ldax #udp_inp+$0c
- jmp @got_pointer_to_tftp_data
-@skip_first_2_bytes_in_calculating_copy_src:
- ldax #udp_inp+$0e
-@got_pointer_to_tftp_data:
-
- stax copy_src
- ldax #output_buffer+2
- stax copy_dest
- ldax tftp_data_block_length
- stax output_buffer
- jsr copymem
- ldax #output_buffer
-
- jsr tftp_callback_vector
- jsr send_ack
-
- lda udp_inp+4 ;check the length of the UDP packet
- cmp #02
- bne @last_block
-
- lda udp_inp+5
- cmp #$0c
- bne @last_block
- beq @not_last_block
-@not_data_block:
- cmp #4 ;ACK is opcode 4
- beq :+
- jmp @not_ack
-:
-;it's an ACK, so we must be sending a file
-
- ldx tftp_inp+3 ;get the (low byte) of the data block
- cpx tftp_current_block_number
- beq :+
- jmp @not_expected_block_number
-:
-;the last block we sent was acked so now we need to send the next one
-;
- ldax #output_buffer+4
- jsr tftp_callback_vector ;this (caller supplied) routine should fill the buffer with up to 512 bytes
- stax tftp_data_block_length
- clc
- adc #4
- bcc :+
- inx
-:
- stax tftp_send_len
- ldax #$0300 ;opcode 03 = DATA
- stax tftp_outp
- jsr got_expected_block
- jsr send_tftp_packet
-
-
- lda tftp_data_block_length+1 ;get length of data we just sent (high byte)
- cmp #2
- bne @last_block
-@not_last_block:
- inc tftp_filesize+1 ;add $200 to file size
- inc tftp_filesize+1 ;add $200 to file size
-
-@not_ack:
-@not_expected_block_number:
- rts
-
-@last_block:
- lda tftp_data_block_length
- sta tftp_filesize; this must be the first block that is not a multiple of 512, hence till now the low byte in tftp_filesize is still $00
- lda tftp_data_block_length+1 ;this can only be 0 or 1
- beq :+
- inc tftp_filesize+1
-:
- lda #tftp_complete
- sta tftp_state
- rts
-
-
-;default handler when block arrives:
-;copy to RAM
-;assumes tftp_data_block_length has been set, and AX should point to start of data
-copy_tftp_block_to_ram:
- clc
- adc #02 ;skip the 2 byte length at start of buffer
- bcc :+
- inx
-:
- stax copy_src
- ldax tftp_current_memloc
- stax copy_dest
- ldax tftp_data_block_length
- jsr copymem
- clc
- lda tftp_data_block_length ;update the location where the next data will go
- adc tftp_current_memloc
- sta tftp_current_memloc
- lda tftp_data_block_length+1
- adc tftp_current_memloc+1
- sta tftp_current_memloc+1
- rts
-
-;default handler for uploading a file
-copy_ram_to_tftp_block:
-
- stax copy_dest
- ldax tftp_current_memloc
- stax copy_src
- clc
- lda tftp_bytes_remaining+1
- beq @last_block
- cmp #01
- beq @last_block
- dec tftp_bytes_remaining+1
- dec tftp_bytes_remaining+1
- ldax #$0200
-@length_is_set:
- stax tftp_data_block_length
- jsr copymem
- inc tftp_current_memloc+1
- inc tftp_current_memloc+1
- ldax tftp_data_block_length
- clc
- rts
-@last_block:
- ldax tftp_bytes_remaining
- jmp @length_is_set
-
-;set up vector of routine to be called when each 512 packet arrives from tftp server
-;when downloading OR for routine to be called when ready to send new block
-;when uploading.
-;when vector is called when downloading, AX will point to data that was downloaded,
-;tftp_data_block_length will be set to length of downloaded data block. This will be
-;equal to $200 (512) for each block EXCEPT the final block. THe final block will
-;always be less than $200 bytes - if the file is an exact multiple if $200 bytes
-;long, then a final block will be received with length $00.
-;when vector is called when uploading, AX will point to a 512 byte buffer that
-;should be filled with the next block. the user supplied routine should set AX
-;to be equal to the actual number of bytes inserted into the buffer, which should
-;equal to $200 (512) for each block EXCEPT the final block. The final block must
-;always be less than $200 bytes - if the file is an exact multiple if $200 bytes
-;long, then a final block must be created with length $00.
-
-; inputs:
-; AX - address of routine to call for each packet.
-; outputs: none
-tftp_set_callback_vector:
- stax tftp_callback_vector+1
- inc tftp_callback_address_set
- rts
-
-;clear callback vectors, i.e. all future transfers read from/write to RAM
-;inputs: none
-;outputs: none
-tftp_clear_callbacks:
- lda #0
- sta tftp_callback_address_set
- ldax #copy_tftp_block_to_ram
- jmp tftp_set_callback_vector
-
-.rodata
- tftp_octet_mode: .asciiz "OCTET"
-
-.data
-tftp_callback_vector:
- jmp copy_tftp_block_to_ram ;vector for action to take when a data block received (default is to store block in RAM)
-
-tftp_callback_address_set: .byte 0
-
-
-;-- LICENSE FOR tftp.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 --
+;minimal tftp implementation (client only)
+;supports file upload and download
+
+
+ TFTP_MAX_RESENDS=10
+ TFTP_TIMER_MASK=$F8 ;mask lower two bits, means we wait for 8 x1/4 seconds
+
+ .include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+ .export tftp_load_address
+ .export tftp_ip
+ .export tftp_download
+ .export tftp_upload
+ .export tftp_data_block_length
+ .export tftp_set_callback_vector
+ .export tftp_callback_vector
+ .export tftp_clear_callbacks
+ .export tftp_filesize
+ .export tftp_upload_from_memory
+ .import ip65_process
+ .import ip65_error
+
+
+ .import udp_add_listener
+ .import udp_remove_listener
+ .import output_buffer
+ .import udp_callback
+ .import udp_send
+ .import check_for_abort_key
+ .import udp_inp
+ .import ip_inp
+ .importzp ip_src
+ .importzp udp_src_port
+
+
+ .importzp udp_data
+
+ .import udp_send_dest
+ .import udp_send_src_port
+ .import udp_send_dest_port
+ .import udp_send_len
+
+ .import copymem
+ .importzp copy_src
+ .importzp copy_dest
+
+ .import timer_read
+
+ .importzp tftp_filename
+ .bss
+
+;packet offsets
+tftp_inp = udp_inp + udp_data
+tftp_outp = output_buffer
+
+;everything after filename in a request at a relative address, not fixed, so don't bother defining offset constants
+
+tftp_server_port=69
+tftp_client_port_low_byte: .res 1
+
+tftp_load_address: .res 2 ;address file will be (or was) downloaded to
+tftp_ip: .res 4 ;ip address of tftp server - set to 255.255.255.255 (broadcast) to send request to all tftp servers on local lan
+
+tftp_data_block_length: .res 2
+tftp_send_len: .res 2
+tftp_current_memloc: .res 2
+
+; tftp state machine
+tftp_initializing = 1 ; initial state
+tftp_initial_request_sent=2 ; sent the RRQ or WRQ, waiting for some data
+tftp_transmission_in_progress=3 ; we have sent/received the first packet of file data
+tftp_complete=4 ; we have sent/received the final packet of file data
+tftp_error=5 ; we got an error
+
+tftp_state: .res 1 ; current activity
+tftp_timer: .res 1
+tftp_resend_counter: .res 1
+tftp_break_inner_loop: .res 1
+tftp_current_block_number: .res 2
+tftp_actual_server_port: .res 2 ;this is read from the reply - it is not (usually) the port # we send the RRQ or WRQ to
+tftp_actual_server_ip: .res 4 ;this is read from the reply - it may not be the IP we sent to (e.g. if we send to broadcast)
+
+tftp_just_set_new_load_address: .res 1
+
+tftp_opcode: .res 2 ; will be set to 4 if we are doing a RRQ, or 7 if we are doing a DIR
+tftp_filesize: .res 2 ;will be set by tftp_download, needs to be set before calling tftp_upload_from_memory
+tftp_bytes_remaining: .res 2
+
+.code
+
+;uploads a file to a tftp server with data retrieved from specified memory location
+; inputs:
+; tftp_ip: ip address of host to send file to (set to 255.255.255.255 for broadcast)
+; tftp_filename: pointer to null terminated name of file to upload
+; tftp_load_address: starting address of data to be sent
+; tftp_filesize: length of data to send
+; outputs: carry flag is set if there was an error
+; if a callback vector has been set with tftp_set_callback_vector
+; then the specified routine will be called once for each 512 byte packet
+; to be sent to the tftp server
+tftp_upload_from_memory:
+ ldax #copy_ram_to_tftp_block
+ jsr tftp_set_callback_vector
+ ldax tftp_filesize
+ stax tftp_bytes_remaining
+ lda #00
+ sta tftp_filesize
+ sta tftp_filesize+1
+
+;uploads a file to a tftp server with data retrieved from user supplied routine
+; inputs:
+; tftp_ip: ip address of host to send file to (set to 255.255.255.255 for broadcast)
+; tftp_filename: pointer to null terminated name of file to upload
+; a callback vector should have been set with tftp_set_callback_vector
+; outputs: carry flag is set if there was an error
+; the specified routine will be called once for each 512 byte packet
+; to be sent from the tftp server.
+tftp_upload:
+ ldax #$0200 ;opcode 02 = WRQ
+ jmp set_tftp_opcode
+
+;download a file from a tftp server
+; inputs:
+; tftp_ip: ip address of host to download from (set to 255.255.255.255 for broadcast)
+; tftp_filename: pointer to null terminated name of file to download
+; tftp_load_address: memory location that dir will be stored in, or $0000 to
+; treat first 2 bytes received from tftp server as memory address that rest
+; of file should be loaded into (e.g. if downloading a C64 'prg' file)
+; outputs: carry flag is set if there was an error
+; if a callback vector has been set with tftp_set_callback_vector
+; then the specified routine will be called once for each 512 byte packet
+; sent from the tftp server (each time AX will point at data block just arrived,
+; and tftp_data_block_length will contain number of bytes in that data block)
+; otherwise, the buffer at tftp_load_address will be filled
+; with file downloaded.
+; tftp_load_address: will be set to the actual address loaded into (NB - this field is
+; ignored if a callback vector has been set with tftp_set_callback_vector)
+tftp_download:
+ lda #00
+ sta tftp_filesize
+ sta tftp_filesize+1
+ ldx #$01 ;opcode 01 = RRQ (A should already be zero from having just reset file length)
+set_tftp_opcode:
+ stax tftp_opcode
+ lda #tftp_initializing
+ sta tftp_state
+ ldax #0000
+ stax tftp_current_block_number
+ ldax tftp_load_address
+ stax tftp_current_memloc
+ ldax #tftp_in
+ stax udp_callback
+ ldx #$69
+ inc tftp_client_port_low_byte ;each transfer uses a different client port
+ lda tftp_client_port_low_byte ;so we don't get confused by late replies to a previous call
+
+ jsr udp_add_listener
+
+ bcc :+ ;bail if we couldn't listen on the port we want
+ lda #KPR_ERROR_PORT_IN_USE
+ sta ip65_error
+ rts
+:
+
+ lda #TFTP_MAX_RESENDS
+ sta tftp_resend_counter
+@outer_delay_loop:
+ jsr timer_read
+ txa
+ and #TFTP_TIMER_MASK
+ sta tftp_timer ;we only care about the high byte
+ lda #0
+ sta tftp_break_inner_loop
+ lda tftp_state
+ cmp #tftp_initializing
+ bne @not_initializing
+ jsr send_request_packet
+
+ jmp @inner_delay_loop
+
+@not_initializing:
+
+ cmp #tftp_error
+ bne @not_error
+
+@exit_with_error:
+ ldx #$69
+ lda tftp_client_port_low_byte
+ jsr udp_remove_listener
+ sec
+ rts
+
+@not_error:
+
+ cmp #tftp_complete
+ bne @not_complete
+ jsr send_ack ;send the ack for the last block
+ bcs @not_complete ;if we couldn't send the ACK (e.g. coz we need to do an ARP request) then keep looping
+ ldx #$69
+ lda tftp_client_port_low_byte
+ jsr udp_remove_listener
+ rts
+
+@not_complete:
+ cmp #tftp_transmission_in_progress
+ bne @not_transmitting
+ jsr send_tftp_packet
+ jmp @inner_delay_loop
+@not_transmitting:
+ jsr send_request_packet
+
+@inner_delay_loop:
+ jsr ip65_process
+ jsr check_for_abort_key
+ bcc @no_abort
+ lda #KPR_ERROR_ABORTED_BY_USER
+ sta ip65_error
+ jmp @exit_with_error
+@no_abort:
+ lda tftp_break_inner_loop
+ bne @outer_delay_loop
+ jsr timer_read
+ txa
+ and #TFTP_TIMER_MASK
+ cmp tftp_timer
+ beq @inner_delay_loop
+
+ dec tftp_resend_counter
+ bne @outer_delay_loop
+ lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
+ sta ip65_error
+ jmp @exit_with_error
+
+send_request_packet:
+ lda #tftp_initializing
+ sta tftp_state
+ ldax tftp_opcode
+ stax tftp_outp
+
+ ldx #$01 ;we inc x/y at start of loop, so
+ ldy #$ff ;set them to be 1 below where we want the copy to begin
+@copy_filename_loop:
+ inx
+ iny
+ bmi @error_in_send ;if we get to 0x80 bytes, we've gone too far
+ lda (tftp_filename),y
+ sta tftp_outp,x
+ bne @copy_filename_loop
+
+ ldy #$ff
+@copy_mode_loop:
+ inx
+ iny
+ lda tftp_octet_mode,y
+ sta tftp_outp,x
+ bne @copy_mode_loop
+
+ inx
+ txa
+ ldx #0
+ stax udp_send_len
+
+ ldx #$69
+ lda tftp_client_port_low_byte
+ stax udp_send_src_port
+
+ ldx #3 ; set destination address
+: lda tftp_ip,x
+ sta udp_send_dest,x
+ dex
+ bpl :-
+
+ ldax #tftp_server_port ; set destination port
+ stax udp_send_dest_port
+ ldax #tftp_outp
+ jsr udp_send
+ bcs @error_in_send
+ lda #tftp_initial_request_sent
+ sta tftp_state
+ rts
+@error_in_send:
+ lda #KPR_ERROR_TRANSMIT_FAILED
+ sta ip65_error
+ sec
+ rts
+
+send_ack:
+ ldax #$0400 ;opcode 04 = ACK
+ stax tftp_outp
+ ldax #04
+ stax tftp_send_len
+send_tftp_packet: ;TFTP block should be created in tftp_outp, we just add the UDP&IP stuff and send
+
+ ldx tftp_current_block_number
+ lda tftp_current_block_number+1
+ stax tftp_outp+2
+
+ ldx #$69
+ lda tftp_client_port_low_byte
+ stax udp_send_src_port
+
+ lda tftp_actual_server_ip
+ sta udp_send_dest
+ lda tftp_actual_server_ip+1
+ sta udp_send_dest+1
+ lda tftp_actual_server_ip+2
+ sta udp_send_dest+2
+ lda tftp_actual_server_ip+3
+ sta udp_send_dest+3
+ ldx tftp_actual_server_port
+ lda tftp_actual_server_port+1
+ stax udp_send_dest_port
+ ldax tftp_send_len
+ stax udp_send_len
+
+ ldax #tftp_outp
+ jsr udp_send
+ rts
+
+got_expected_block:
+ lda tftp_current_block_number
+ inc tftp_current_block_number
+ bne :+
+ inc tftp_current_block_number+1
+:
+ lda #tftp_transmission_in_progress
+ sta tftp_state
+ lda #TFTP_MAX_RESENDS
+ sta tftp_resend_counter
+ lda #1
+ sta tftp_break_inner_loop
+
+ ldax udp_inp+udp_src_port
+ stax tftp_actual_server_port
+ ldax ip_inp+ip_src
+ stax tftp_actual_server_ip
+ ldax ip_inp+ip_src+2
+ stax tftp_actual_server_ip+2
+ rts
+
+tftp_in:
+
+ lda tftp_inp+1 ;get the opcode
+ cmp #5
+ bne @not_an_error
+@recv_error:
+ lda #tftp_error
+ sta tftp_state
+ lda #KPR_ERROR_TRANSMISSION_REJECTED_BY_PEER
+ sta ip65_error
+ rts
+@not_an_error:
+
+ cmp #3
+ beq :+
+ jmp @not_data_block
+:
+
+
+ lda #0
+ sta tftp_just_set_new_load_address ;clear the flag
+ clc
+ lda tftp_load_address
+ adc tftp_load_address+1 ;is load address currently $0000?
+ bne @dont_set_load_address
+
+ lda tftp_callback_address_set ;have we overridden the default handler?
+ bne @dont_set_load_address ;if so, don't skip the first two bytes in the file
+
+ ldax udp_inp+$0c ;get first two bytes of data
+ stax tftp_load_address ;make them the new load adress
+ stax tftp_current_memloc ;also the current memory destination
+ lda #1 ;set the flag
+ sta tftp_just_set_new_load_address
+
+@dont_set_load_address:
+ ldx tftp_inp+3 ;get the (low byte) of the data block
+ dex
+ cpx tftp_current_block_number
+ beq :+
+ jmp @not_expected_block_number
+:
+ ;this is the block we wanted
+ jsr got_expected_block
+
+ lda tftp_just_set_new_load_address
+ bne @skip_first_2_bytes_in_calculating_header_length
+ lda udp_inp+5 ;get the low byte of udp packet length
+ sec
+ sbc #$0c ;take off the length of the UDP header+OPCODE + BLOCK
+
+ jmp @adjusted_header_length
+@skip_first_2_bytes_in_calculating_header_length:
+ lda udp_inp+5 ;get the low byte of udp packet length
+ sec
+ sbc #$0e ;take off the length of the UDP header+OPCODE + BLOCK + first 2 bytes (memory location)
+@adjusted_header_length:
+
+ sta tftp_data_block_length
+ lda udp_inp+4 ;get high byte of the length of the UDP packet
+ sbc #0
+ sta tftp_data_block_length+1
+
+ lda tftp_just_set_new_load_address
+ bne @skip_first_2_bytes_in_calculating_copy_src
+ ldax #udp_inp+$0c
+ jmp @got_pointer_to_tftp_data
+@skip_first_2_bytes_in_calculating_copy_src:
+ ldax #udp_inp+$0e
+@got_pointer_to_tftp_data:
+
+ stax copy_src
+ ldax #output_buffer+2
+ stax copy_dest
+ ldax tftp_data_block_length
+ stax output_buffer
+ jsr copymem
+ ldax #output_buffer
+
+ jsr tftp_callback_vector
+ jsr send_ack
+
+ lda udp_inp+4 ;check the length of the UDP packet
+ cmp #02
+ bne @last_block
+
+ lda udp_inp+5
+ cmp #$0c
+ bne @last_block
+ beq @not_last_block
+@not_data_block:
+ cmp #4 ;ACK is opcode 4
+ beq :+
+ jmp @not_ack
+:
+;it's an ACK, so we must be sending a file
+
+ ldx tftp_inp+3 ;get the (low byte) of the data block
+ cpx tftp_current_block_number
+ beq :+
+ jmp @not_expected_block_number
+:
+;the last block we sent was acked so now we need to send the next one
+;
+ ldax #output_buffer+4
+ jsr tftp_callback_vector ;this (caller supplied) routine should fill the buffer with up to 512 bytes
+ stax tftp_data_block_length
+ clc
+ adc #4
+ bcc :+
+ inx
+:
+ stax tftp_send_len
+ ldax #$0300 ;opcode 03 = DATA
+ stax tftp_outp
+ jsr got_expected_block
+ jsr send_tftp_packet
+
+
+ lda tftp_data_block_length+1 ;get length of data we just sent (high byte)
+ cmp #2
+ bne @last_block
+@not_last_block:
+ inc tftp_filesize+1 ;add $200 to file size
+ inc tftp_filesize+1 ;add $200 to file size
+
+@not_ack:
+@not_expected_block_number:
+ rts
+
+@last_block:
+ lda tftp_data_block_length
+ sta tftp_filesize; this must be the first block that is not a multiple of 512, hence till now the low byte in tftp_filesize is still $00
+ lda tftp_data_block_length+1 ;this can only be 0 or 1
+ beq :+
+ inc tftp_filesize+1
+:
+ lda #tftp_complete
+ sta tftp_state
+ rts
+
+
+;default handler when block arrives:
+;copy to RAM
+;assumes tftp_data_block_length has been set, and AX should point to start of data
+copy_tftp_block_to_ram:
+ clc
+ adc #02 ;skip the 2 byte length at start of buffer
+ bcc :+
+ inx
+:
+ stax copy_src
+ ldax tftp_current_memloc
+ stax copy_dest
+ ldax tftp_data_block_length
+ jsr copymem
+ clc
+ lda tftp_data_block_length ;update the location where the next data will go
+ adc tftp_current_memloc
+ sta tftp_current_memloc
+ lda tftp_data_block_length+1
+ adc tftp_current_memloc+1
+ sta tftp_current_memloc+1
+ rts
+
+;default handler for uploading a file
+copy_ram_to_tftp_block:
+
+ stax copy_dest
+ ldax tftp_current_memloc
+ stax copy_src
+ clc
+ lda tftp_bytes_remaining+1
+ beq @last_block
+ cmp #01
+ beq @last_block
+ dec tftp_bytes_remaining+1
+ dec tftp_bytes_remaining+1
+ ldax #$0200
+@length_is_set:
+ stax tftp_data_block_length
+ jsr copymem
+ inc tftp_current_memloc+1
+ inc tftp_current_memloc+1
+ ldax tftp_data_block_length
+ clc
+ rts
+@last_block:
+ ldax tftp_bytes_remaining
+ jmp @length_is_set
+
+;set up vector of routine to be called when each 512 packet arrives from tftp server
+;when downloading OR for routine to be called when ready to send new block
+;when uploading.
+;when vector is called when downloading, AX will point to data that was downloaded,
+;tftp_data_block_length will be set to length of downloaded data block. This will be
+;equal to $200 (512) for each block EXCEPT the final block. THe final block will
+;always be less than $200 bytes - if the file is an exact multiple if $200 bytes
+;long, then a final block will be received with length $00.
+;when vector is called when uploading, AX will point to a 512 byte buffer that
+;should be filled with the next block. the user supplied routine should set AX
+;to be equal to the actual number of bytes inserted into the buffer, which should
+;equal to $200 (512) for each block EXCEPT the final block. The final block must
+;always be less than $200 bytes - if the file is an exact multiple if $200 bytes
+;long, then a final block must be created with length $00.
+
+; inputs:
+; AX - address of routine to call for each packet.
+; outputs: none
+tftp_set_callback_vector:
+ stax tftp_callback_vector+1
+ inc tftp_callback_address_set
+ rts
+
+;clear callback vectors, i.e. all future transfers read from/write to RAM
+;inputs: none
+;outputs: none
+tftp_clear_callbacks:
+ lda #0
+ sta tftp_callback_address_set
+ ldax #copy_tftp_block_to_ram
+ jmp tftp_set_callback_vector
+
+.rodata
+ tftp_octet_mode: .asciiz "OCTET"
+
+.data
+tftp_callback_vector:
+ jmp copy_tftp_block_to_ram ;vector for action to take when a data block received (default is to store block in RAM)
+
+tftp_callback_address_set: .byte 0
+
+
+;-- LICENSE FOR tftp.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/ip65/timer.s b/ip65/timer.s
similarity index 96%
rename from client/ip65/timer.s
rename to ip65/timer.s
index d767b9f..bea154e 100644
--- a/client/ip65/timer.s
+++ b/ip65/timer.s
@@ -1,59 +1,59 @@
-; timer routines
-;
-; the timer should be a 16-bit counter that's incremented by about
-; 1000 units per second. it doesn't have to be particularly accurate,
-; if you're working with e.g. a 60 Hz VBLANK IRQ, adding 17 to the
-; counter every frame would be just fine.
-;
-; this is generic timer routines, machine specific code goes in drivers/timer.s
- .include "../inc/common.i"
-
-
- .export timer_timeout
- .import timer_read
-
- .bss
-
-time: .res 2
-
-
- .code
-
-;check if specified period of time has passed yet
-;inputs: AX - maximum number of milliseconds we are willing to wait for
-;outputs: carry flag set if timeout occured, clear otherwise
-timer_timeout:
- pha
- txa
- pha
- jsr timer_read
- stax time
- pla
- tax
- pla
- sec ; subtract current value
- sbc time
- txa
- sbc time + 1
- rts ; clc = timeout, sec = no timeout
-
-
-
-;-- LICENSE FOR timer.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 --
+; timer routines
+;
+; the timer should be a 16-bit counter that's incremented by about
+; 1000 units per second. it doesn't have to be particularly accurate,
+; if you're working with e.g. a 60 Hz VBLANK IRQ, adding 17 to the
+; counter every frame would be just fine.
+;
+; this is generic timer routines, machine specific code goes in drivers/timer.s
+ .include "../inc/common.i"
+
+
+ .export timer_timeout
+ .import timer_read
+
+ .bss
+
+time: .res 2
+
+
+ .code
+
+;check if specified period of time has passed yet
+;inputs: AX - maximum number of milliseconds we are willing to wait for
+;outputs: carry flag set if timeout occured, clear otherwise
+timer_timeout:
+ pha
+ txa
+ pha
+ jsr timer_read
+ stax time
+ pla
+ tax
+ pla
+ sec ; subtract current value
+ sbc time
+ txa
+ sbc time + 1
+ rts ; clc = timeout, sec = no timeout
+
+
+
+;-- LICENSE FOR timer.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/ip65/udp.s b/ip65/udp.s
similarity index 95%
rename from client/ip65/udp.s
rename to ip65/udp.s
index 7a4ebe9..683cdff 100644
--- a/client/ip65/udp.s
+++ b/ip65/udp.s
@@ -1,360 +1,360 @@
-;UDP (user datagram protocol) functions
-
-.include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
- ;.import dbg_dump_udp_header
-
- .import ip65_error
-
- .export udp_init
- .export udp_process
- .export udp_add_listener
- .export udp_remove_listener
- .export udp_send
-
- .export udp_callback
-
- .export udp_inp
- .export udp_outp
-
- .exportzp udp_src_port
- .exportzp udp_dest_port
- .exportzp udp_len
- .exportzp udp_cksum
- .exportzp udp_data
-
- .export udp_send_dest
- .export udp_send_src_port
- .export udp_send_dest_port
- .export udp_send_len
-
- .import ip_calc_cksum
- .import ip_send
- .import ip_create_packet
- .import ip_inp
- .import ip_outp
- .importzp ip_cksum_ptr
- .importzp ip_header_cksum
- .importzp ip_src
- .importzp ip_dest
- .importzp ip_data
- .importzp ip_proto
- .importzp ip_proto_udp
- .importzp ip_id
- .importzp ip_len
-
- .import copymem
- .importzp copy_src
- .importzp copy_dest
-
- .import cfg_ip
-
- .data
- udp_cbtmp: jmp $ffff ; temporary vector - gets filled in later
-
-
- .bss
-
-; argument for udp_add_listener
-udp_callback: .res 2 ;vector to routine to be called when a udp packet arrives
-
-; arguments for udp_send
-udp_send_dest: .res 4 ;set to ip address that udp packet will be sent to
-udp_send_src_port: .res 2 ;set to port that udp packet will be sent from
-udp_send_dest_port: .res 2 ;set to port that udp packet will be sent to
-udp_send_len: .res 2 ;set to length of data to be sent in udp packet (excluding ethernet,ip & udp headers)
-
-; udp listener callbacks
-udp_cbmax = 4
-udp_cbveclo: .res udp_cbmax ; table of listener vectors (lsb)
-udp_cbvechi: .res udp_cbmax ; table of listener vectors (msb)
-udp_cbportlo: .res udp_cbmax ; table of ports (lsb)
-udp_cbporthi: .res udp_cbmax ; table of ports (msb)
-udp_cbcount: .res 1 ; number of active listeners
-
-; udp packet offsets
-udp_inp = ip_inp + ip_data ;pointer to udp packet inside inbound ethernet frame
-udp_outp = ip_outp + ip_data ;pointer to udp packet inside outbound ethernet frame
-udp_src_port = 0 ;offset of source port field in udp packet
-udp_dest_port = 2 ;offset of destination port field in udp packet
-udp_len = 4 ;offset of length field in udp packet
-udp_cksum = 6 ;offset of checksum field in udp packet
-udp_data = 8 ;offset of data in udp packet
-
-; virtual header
-udp_vh = udp_outp - 12
-udp_vh_src = 0
-udp_vh_dest = 4
-udp_vh_zero = 8
-udp_vh_proto = 9
-udp_vh_len = 10
-
-
-; temp for port comparison
-port: .res 2
-
-
- .code
-
-; initialize udp
-; inputs: none
-; outputs: none
-udp_init:
- lda #0
- sta udp_cbcount
- rts
-
-
-;process incoming udp packet
-;inputs:
-; eth_inp: should contain an ethernet frame encapsulating an inbound udp packet
-;outputs:
-; carry flag set if any error occured (including if no handler for specified port
-; was found)
-; carry flag clear if no error
-; if handler was found, an outbound message may be created, overwriting eth_outp
-
-udp_process:
- lda udp_cbcount ; any installed udp listeners?
- beq @drop
-
- tax ; check ports
- dex
-@checkport:
- lda udp_cbportlo,x
- cmp udp_inp + udp_dest_port + 1
- bne :+
- lda udp_cbporthi,x
- cmp udp_inp + udp_dest_port
- beq @handle
-: dex
- bpl @checkport
-
-@drop:
- sec
- rts
-
-@handle:
- lda udp_cbveclo,x ; copy vector
- sta udp_cbtmp + 1
- lda udp_cbvechi,x
- sta udp_cbtmp + 2
- jsr udp_cbtmp ; call listener
- clc
- rts
-
-
-;add a udp listener
-;inputs:
-; udp_callback: vector to call when udp packet arrives on specified port
-; AX: set to udp port to listen on
-;outputs:
-; carry flag set if too may listeners already installed, clear otherwise
-udp_add_listener:
- sta port
- stx port + 1
-
- ldy udp_cbcount ; any listeners at all?
- beq @add
- cpy #udp_cbmax ; max?
- beq @full
- ldy #0
-@check:
- lda udp_cbportlo,y ; check if port is already handled
- cmp port
- bne :+
- lda udp_cbporthi,y
- cmp port + 1
- beq @busy
-: iny
- cpy udp_cbcount
- bne @check
-@add:
- inc udp_cbcount ; increase counter
- sta udp_cbportlo,y ; add port
- txa
- sta udp_cbporthi,y ; add port
- lda udp_callback ; and vector
- sta udp_cbveclo,y
- lda udp_callback + 1
- sta udp_cbvechi,y
-
- clc
- rts
-@full:
-@busy:
- lda #KPR_ERROR_LISTENER_NOT_AVAILABLE
- sta ip65_error
- sec
- sec
- rts
-
-
-; remove an udp listener
-; inputs:
-; AX = port to stop listening on
-; outputs:
-; carry flag clear of handler found and removed
-; carry flag set if handler for specified port not found
-udp_remove_listener:
- sta port
- stx port + 1
-
- ldy udp_cbcount ; any listeners installed?
- beq @notfound
- dey
-@check:
- lda udp_cbportlo,y ; check if port is handled
- cmp port
- bne :+
- lda udp_cbporthi,y
- cmp port + 1
- beq @remove
-: dey
- bpl @check
-@notfound:
- sec
- rts
-@remove:
- tya ; number of listeners below
- eor #$ff
- clc
- adc udp_cbcount
- beq @done
-@move:
- tax ; number of items to move
-: lda udp_cbportlo + 1,y ; move ports
- sta udp_cbportlo,y
- lda udp_cbporthi + 1,y
- sta udp_cbporthi,y
- lda udp_cbveclo + 1,y ; move vectors
- sta udp_cbveclo,y
- lda udp_cbvechi + 1,y
- sta udp_cbvechi,y
- iny
- dex
- bne :-
-@done:
- dec udp_cbcount ; decrement counter
- clc
- rts
-
-
-;send udp packet
-;inputs:
-; udp_send_dest: destination ip address (4 bytes)
-; udp_send_dest_port: destination port (2 bytes)
-; udp_send_src_port: source port (2 bytes)
-; udp_send_len: length of data to send (exclusive of any headers)
-; AX: pointer to buffer containing data to be sent
-;outputs:
-; carry flag is set if an error occured, clear otherwise
-udp_send:
- stax copy_src ; copy data to output buffer
- ldax #udp_outp + udp_data
- stax copy_dest
- ldax udp_send_len
- jsr copymem
-
- ldx #3 ; copy virtual header addresses
-: lda udp_send_dest,x
- sta udp_vh + udp_vh_dest,x ; set virtual header destination
- lda cfg_ip,x
- sta udp_vh + udp_vh_src,x ; set virtual header source
- dex
- bpl :-
-
- lda udp_send_src_port ; copy source port
- sta udp_outp + udp_src_port + 1
- lda udp_send_src_port + 1
- sta udp_outp + udp_src_port
-
- lda udp_send_dest_port ; copy destination port
- sta udp_outp + udp_dest_port + 1
- lda udp_send_dest_port + 1
- sta udp_outp + udp_dest_port
-
- lda #ip_proto_udp
- sta udp_vh + udp_vh_proto
-
- lda #0 ; clear checksum
- sta udp_outp + udp_cksum
- sta udp_outp + udp_cksum + 1
- sta udp_vh + udp_vh_zero ; clear virtual header zero byte
-
- ldax #udp_vh ; checksum pointer to virtual header
- stax ip_cksum_ptr
-
- lda udp_send_len ; copy length + 8
- clc
- adc #8
- sta udp_outp + udp_len + 1 ; lsb for udp header
- sta udp_vh + udp_vh_len + 1 ; lsb for virtual header
- tay
- lda udp_send_len + 1
- adc #0
- sta udp_outp + udp_len ; msb for udp header
- sta udp_vh + udp_vh_len ; msb for virtual header
-
- tax ; length to A/X
- tya
-
- clc ; add 12 bytes for virtual header
- adc #12
- bcc :+
- inx
-:
- jsr ip_calc_cksum ; calculate checksum
- stax udp_outp + udp_cksum
-
- ldx #3 ; copy addresses
-: lda udp_send_dest,x
- sta ip_outp + ip_dest,x ; set ip destination address
- dex
- bpl :-
-
- jsr ip_create_packet ; create ip packet template
-
- lda udp_outp + udp_len + 1 ; ip len = udp len + 20
- ldx udp_outp + udp_len
- clc
- adc #20
- bcc :+
- inx
-: sta ip_outp + ip_len + 1 ; set length
- stx ip_outp + ip_len
-
- ldax #$1234 ; set ID
- stax ip_outp + ip_id
-
- lda #ip_proto_udp ; set protocol
- sta ip_outp + ip_proto
-
- ;jsr dbg_dump_udp_header
-
- jmp ip_send ; send packet, sec on error
-
-
-
-;-- LICENSE FOR udp.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 Per Olofsson,
-; MagerValp@gmail.com.
-; Portions created by the Initial Developer are Copyright (C) 2009
-; Per Olofsson. All Rights Reserved.
-; -- LICENSE END --
+;UDP (user datagram protocol) functions
+
+.include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+ ;.import dbg_dump_udp_header
+
+ .import ip65_error
+
+ .export udp_init
+ .export udp_process
+ .export udp_add_listener
+ .export udp_remove_listener
+ .export udp_send
+
+ .export udp_callback
+
+ .export udp_inp
+ .export udp_outp
+
+ .exportzp udp_src_port
+ .exportzp udp_dest_port
+ .exportzp udp_len
+ .exportzp udp_cksum
+ .exportzp udp_data
+
+ .export udp_send_dest
+ .export udp_send_src_port
+ .export udp_send_dest_port
+ .export udp_send_len
+
+ .import ip_calc_cksum
+ .import ip_send
+ .import ip_create_packet
+ .import ip_inp
+ .import ip_outp
+ .importzp ip_cksum_ptr
+ .importzp ip_header_cksum
+ .importzp ip_src
+ .importzp ip_dest
+ .importzp ip_data
+ .importzp ip_proto
+ .importzp ip_proto_udp
+ .importzp ip_id
+ .importzp ip_len
+
+ .import copymem
+ .importzp copy_src
+ .importzp copy_dest
+
+ .import cfg_ip
+
+ .data
+ udp_cbtmp: jmp $ffff ; temporary vector - gets filled in later
+
+
+ .bss
+
+; argument for udp_add_listener
+udp_callback: .res 2 ;vector to routine to be called when a udp packet arrives
+
+; arguments for udp_send
+udp_send_dest: .res 4 ;set to ip address that udp packet will be sent to
+udp_send_src_port: .res 2 ;set to port that udp packet will be sent from
+udp_send_dest_port: .res 2 ;set to port that udp packet will be sent to
+udp_send_len: .res 2 ;set to length of data to be sent in udp packet (excluding ethernet,ip & udp headers)
+
+; udp listener callbacks
+udp_cbmax = 4
+udp_cbveclo: .res udp_cbmax ; table of listener vectors (lsb)
+udp_cbvechi: .res udp_cbmax ; table of listener vectors (msb)
+udp_cbportlo: .res udp_cbmax ; table of ports (lsb)
+udp_cbporthi: .res udp_cbmax ; table of ports (msb)
+udp_cbcount: .res 1 ; number of active listeners
+
+; udp packet offsets
+udp_inp = ip_inp + ip_data ;pointer to udp packet inside inbound ethernet frame
+udp_outp = ip_outp + ip_data ;pointer to udp packet inside outbound ethernet frame
+udp_src_port = 0 ;offset of source port field in udp packet
+udp_dest_port = 2 ;offset of destination port field in udp packet
+udp_len = 4 ;offset of length field in udp packet
+udp_cksum = 6 ;offset of checksum field in udp packet
+udp_data = 8 ;offset of data in udp packet
+
+; virtual header
+udp_vh = udp_outp - 12
+udp_vh_src = 0
+udp_vh_dest = 4
+udp_vh_zero = 8
+udp_vh_proto = 9
+udp_vh_len = 10
+
+
+; temp for port comparison
+port: .res 2
+
+
+ .code
+
+; initialize udp
+; inputs: none
+; outputs: none
+udp_init:
+ lda #0
+ sta udp_cbcount
+ rts
+
+
+;process incoming udp packet
+;inputs:
+; eth_inp: should contain an ethernet frame encapsulating an inbound udp packet
+;outputs:
+; carry flag set if any error occured (including if no handler for specified port
+; was found)
+; carry flag clear if no error
+; if handler was found, an outbound message may be created, overwriting eth_outp
+
+udp_process:
+ lda udp_cbcount ; any installed udp listeners?
+ beq @drop
+
+ tax ; check ports
+ dex
+@checkport:
+ lda udp_cbportlo,x
+ cmp udp_inp + udp_dest_port + 1
+ bne :+
+ lda udp_cbporthi,x
+ cmp udp_inp + udp_dest_port
+ beq @handle
+: dex
+ bpl @checkport
+
+@drop:
+ sec
+ rts
+
+@handle:
+ lda udp_cbveclo,x ; copy vector
+ sta udp_cbtmp + 1
+ lda udp_cbvechi,x
+ sta udp_cbtmp + 2
+ jsr udp_cbtmp ; call listener
+ clc
+ rts
+
+
+;add a udp listener
+;inputs:
+; udp_callback: vector to call when udp packet arrives on specified port
+; AX: set to udp port to listen on
+;outputs:
+; carry flag set if too may listeners already installed, clear otherwise
+udp_add_listener:
+ sta port
+ stx port + 1
+
+ ldy udp_cbcount ; any listeners at all?
+ beq @add
+ cpy #udp_cbmax ; max?
+ beq @full
+ ldy #0
+@check:
+ lda udp_cbportlo,y ; check if port is already handled
+ cmp port
+ bne :+
+ lda udp_cbporthi,y
+ cmp port + 1
+ beq @busy
+: iny
+ cpy udp_cbcount
+ bne @check
+@add:
+ inc udp_cbcount ; increase counter
+ sta udp_cbportlo,y ; add port
+ txa
+ sta udp_cbporthi,y ; add port
+ lda udp_callback ; and vector
+ sta udp_cbveclo,y
+ lda udp_callback + 1
+ sta udp_cbvechi,y
+
+ clc
+ rts
+@full:
+@busy:
+ lda #KPR_ERROR_LISTENER_NOT_AVAILABLE
+ sta ip65_error
+ sec
+ sec
+ rts
+
+
+; remove an udp listener
+; inputs:
+; AX = port to stop listening on
+; outputs:
+; carry flag clear of handler found and removed
+; carry flag set if handler for specified port not found
+udp_remove_listener:
+ sta port
+ stx port + 1
+
+ ldy udp_cbcount ; any listeners installed?
+ beq @notfound
+ dey
+@check:
+ lda udp_cbportlo,y ; check if port is handled
+ cmp port
+ bne :+
+ lda udp_cbporthi,y
+ cmp port + 1
+ beq @remove
+: dey
+ bpl @check
+@notfound:
+ sec
+ rts
+@remove:
+ tya ; number of listeners below
+ eor #$ff
+ clc
+ adc udp_cbcount
+ beq @done
+@move:
+ tax ; number of items to move
+: lda udp_cbportlo + 1,y ; move ports
+ sta udp_cbportlo,y
+ lda udp_cbporthi + 1,y
+ sta udp_cbporthi,y
+ lda udp_cbveclo + 1,y ; move vectors
+ sta udp_cbveclo,y
+ lda udp_cbvechi + 1,y
+ sta udp_cbvechi,y
+ iny
+ dex
+ bne :-
+@done:
+ dec udp_cbcount ; decrement counter
+ clc
+ rts
+
+
+;send udp packet
+;inputs:
+; udp_send_dest: destination ip address (4 bytes)
+; udp_send_dest_port: destination port (2 bytes)
+; udp_send_src_port: source port (2 bytes)
+; udp_send_len: length of data to send (exclusive of any headers)
+; AX: pointer to buffer containing data to be sent
+;outputs:
+; carry flag is set if an error occured, clear otherwise
+udp_send:
+ stax copy_src ; copy data to output buffer
+ ldax #udp_outp + udp_data
+ stax copy_dest
+ ldax udp_send_len
+ jsr copymem
+
+ ldx #3 ; copy virtual header addresses
+: lda udp_send_dest,x
+ sta udp_vh + udp_vh_dest,x ; set virtual header destination
+ lda cfg_ip,x
+ sta udp_vh + udp_vh_src,x ; set virtual header source
+ dex
+ bpl :-
+
+ lda udp_send_src_port ; copy source port
+ sta udp_outp + udp_src_port + 1
+ lda udp_send_src_port + 1
+ sta udp_outp + udp_src_port
+
+ lda udp_send_dest_port ; copy destination port
+ sta udp_outp + udp_dest_port + 1
+ lda udp_send_dest_port + 1
+ sta udp_outp + udp_dest_port
+
+ lda #ip_proto_udp
+ sta udp_vh + udp_vh_proto
+
+ lda #0 ; clear checksum
+ sta udp_outp + udp_cksum
+ sta udp_outp + udp_cksum + 1
+ sta udp_vh + udp_vh_zero ; clear virtual header zero byte
+
+ ldax #udp_vh ; checksum pointer to virtual header
+ stax ip_cksum_ptr
+
+ lda udp_send_len ; copy length + 8
+ clc
+ adc #8
+ sta udp_outp + udp_len + 1 ; lsb for udp header
+ sta udp_vh + udp_vh_len + 1 ; lsb for virtual header
+ tay
+ lda udp_send_len + 1
+ adc #0
+ sta udp_outp + udp_len ; msb for udp header
+ sta udp_vh + udp_vh_len ; msb for virtual header
+
+ tax ; length to A/X
+ tya
+
+ clc ; add 12 bytes for virtual header
+ adc #12
+ bcc :+
+ inx
+:
+ jsr ip_calc_cksum ; calculate checksum
+ stax udp_outp + udp_cksum
+
+ ldx #3 ; copy addresses
+: lda udp_send_dest,x
+ sta ip_outp + ip_dest,x ; set ip destination address
+ dex
+ bpl :-
+
+ jsr ip_create_packet ; create ip packet template
+
+ lda udp_outp + udp_len + 1 ; ip len = udp len + 20
+ ldx udp_outp + udp_len
+ clc
+ adc #20
+ bcc :+
+ inx
+: sta ip_outp + ip_len + 1 ; set length
+ stx ip_outp + ip_len
+
+ ldax #$1234 ; set ID
+ stax ip_outp + ip_id
+
+ lda #ip_proto_udp ; set protocol
+ sta ip_outp + ip_proto
+
+ ;jsr dbg_dump_udp_header
+
+ jmp ip_send ; send packet, sec on error
+
+
+
+;-- LICENSE FOR udp.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 Per Olofsson,
+; MagerValp@gmail.com.
+; Portions created by the Initial Developer are Copyright (C) 2009
+; Per Olofsson. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/ip65/url.s b/ip65/url.s
similarity index 95%
rename from client/ip65/url.s
rename to ip65/url.s
index 66d5b51..329cda1 100644
--- a/client/ip65/url.s
+++ b/ip65/url.s
@@ -1,458 +1,458 @@
-;routines for parsing a URL, and downloading an URL
-
-
-.include "../inc/common.i"
-
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-TIMEOUT_SECONDS=15
-
-.import output_buffer
-.importzp copy_src
-.importzp copy_dest
-.import copymem
-.import timer_read
-.import ip65_error
-.import ip65_process
-.import parser_init
-.import parser_skip_next
-.import dns_set_hostname
-.import dns_resolve
-.import parse_integer
-.import dns_ip
-.import tcp_connect
-.import tcp_send_string
-.import tcp_send_data_len
-.import tcp_callback
-.import tcp_close
-.import tcp_connect_ip
-.import tcp_inbound_data_length
-.import tcp_inbound_data_ptr
-
-
-.export url_ip
-.export url_port
-.export url_selector
-.export url_resource_type
-.export url_parse
-.export url_download
-.export url_download_buffer
-.export url_download_buffer_length
-.export resource_download
-
-target_string=copy_src
-search_string=copy_dest
-selector_buffer=output_buffer
-
-.segment "TCP_VARS"
-
- url_string: .res 2
- url_ip: .res 4 ;will be set with ip address of host in url
- url_port: .res 2 ;will be set with port number of url
- url_selector: .res 2 ;will be set with address of selector part of URL
- url_type: .res 1
- url_resource_type: .res 1
- url_type_unknown=0
- url_type_gopher=1
- url_type_http=2
-
- src_ptr: .res 1
- dest_ptr: .res 1
- timeout_counter: .res 1
- url_download_buffer: .res 2 ; points to a buffer that url will be downloaded into
- url_download_buffer_length: .res 2 ;length of buffer that url will be downloaded into
-
- temp_buffer: .res 2
- temp_buffer_length: .res 2
-
- download_flag: .res 1
-
-
-.code
-
-
-;parses a URL into a form that makes it easy to retrieve the specified resource
-;inputs:
-;AX = address of URL string
-;any control character (i.e. <$20) is treated as 'end of string', e.g. a CR or LF, as well as $00
-;outputs:
-; sec if a malformed url, otherwise:
-; url_ip = ip address of host in url
-; url_port = port number of url
-; url_selector= address of selector part of URL
-url_parse:
- stax url_string
- ldy #0
- sty url_type
- sty url_port
- sty url_port+1
- sty url_resource_type
-
- jsr skip_to_hostname
- bcc :+
- ldax url_string
- jmp @no_protocol_specifier
-:
- ldax url_string
- stax search_string
-
- lda (search_string),y
- cmp #'g'
- beq @gopher
- cmp #'G'
- beq @gopher
- cmp #'h'
- beq @http
- cmp #'H'
- beq @http
-@exit_with_error:
- lda #KPR_ERROR_MALFORMED_URL
- sta ip65_error
-@exit_with_sec:
- sec
- rts
-@http:
- lda #url_type_http
- sta url_type
- lda #80
- sta url_port
- jmp @protocol_set
-@gopher:
-lda #url_type_gopher
- sta url_type
- lda #70
- sta url_port
-@protocol_set:
- jsr skip_to_hostname
- ;now pointing at hostname
- bcs @exit_with_error
-@no_protocol_specifier:
- jsr dns_set_hostname
- bcs @exit_with_sec
- jsr dns_resolve
- bcc :+
- lda #KPR_ERROR_DNS_LOOKUP_FAILED
- sta ip65_error
- jmp @exit_with_sec
- :
- ;copy IP address
- ldx #3
-:
- lda dns_ip,x
- sta url_ip,x
- dex
- bpl :-
-
- jsr skip_to_hostname
-
- ;skip over next colon
- ldax #colon
- jsr parser_skip_next
- bcs @no_port_in_url
- ;AX now point at first thing past a colon - should be a number:
- jsr parse_integer
- stax url_port
-@no_port_in_url:
- ;skip over next slash
- ldax #slash
- jsr parser_skip_next
- ;AX now pointing at selector
- stax copy_src
- ldax #selector_buffer
- stax copy_dest
- lda #0
- sta src_ptr
- sta dest_ptr
- lda url_type
-
- cmp #url_type_gopher
- bne @not_gopher
- ;first byte after / in a gopher url is the resource type
- ldy src_ptr
- lda (copy_src),y
- beq @start_of_selector
- sta url_resource_type
- inc src_ptr
- jmp @start_of_selector
-@not_gopher:
- cmp #url_type_http
- beq @build_http_request
- jmp @done ; if it's not gopher or http, we don't know how to build a selector
-@build_http_request:
- ldy #get_length-1
- sty dest_ptr
-:
- lda get,y
- sta (copy_dest),y
- dey
- bpl :-
-
-@start_of_selector:
- lda #'/'
- inc dest_ptr
- jmp @save_first_byte_of_selector
-@copy_one_byte:
- ldy src_ptr
- lda (copy_src),y
- cmp #$20
- bcc @end_of_selector ;any control char (including CR,LF, and $00) should be treated as end of URL
- inc src_ptr
-@save_first_byte_of_selector:
- ldy dest_ptr
- sta (copy_dest),y
- inc dest_ptr
- bne @copy_one_byte
-@end_of_selector:
-
-
- ldx #1 ;number of CRLF at end of gopher request
- lda url_type
-
- cmp #url_type_http
- bne @final_crlf
-
- ;now the HTTP version number & Host: field
- ldx #0
-:
- lda http_preamble,x
- beq :+
- ldy dest_ptr
- inc dest_ptr
- sta (copy_dest),y
- inx
- bne :-
-:
-
-
- ;now copy the host field
- jsr skip_to_hostname
- ;AX now pointing at hostname
- stax copy_src
- ldax #selector_buffer
- stax copy_dest
-
- lda #0
- sta src_ptr
-
-@copy_one_byte_of_hostname:
- ldy src_ptr
- lda (copy_src),y
- beq @end_of_hostname
- cmp #':'
- beq @end_of_hostname
- cmp #'/'
- beq @end_of_hostname
- inc src_ptr
- ldy dest_ptr
- sta (copy_dest),y
- inc dest_ptr
- bne @copy_one_byte_of_hostname
-@end_of_hostname:
-
- ldx #2 ;number of CRLF at end of HTTP request
-
-@final_crlf:
- ldy dest_ptr
- lda #$0d
- sta (copy_dest),y
- iny
- lda #$0a
- sta (copy_dest),y
- iny
- sty dest_ptr
- dex
- bne @final_crlf
-
-@done:
- lda #$00
- sta (copy_dest),y
- ldax #selector_buffer
- stax url_selector
- clc
-
- rts
-
-skip_to_hostname:
- ldax url_string
- jsr parser_init
- ldax #colon_slash_slash
- jmp parser_skip_next
-
-
-
-;download a resource specified by an URL
-;inputs:
-;AX = address of URL string
-; url_download_buffer - points to a buffer that url will be downloaded into
-; url_download_buffer_length - length of buffer
-;outputs:
-; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents
-; of specified resource (with an extra 2 null bytes at the end),
-; AX = length of resource downloaded.
-url_download:
- jsr url_parse
- bcc resource_download
- rts
-
-;download a resource specified by ip,port & selector
-;inputs:
-; url_ip = ip address of host to connect to
-; url_port = port number of to connect to
-; url_selector= address of selector to send to host after connecting
-; url_download_buffer - points to a buffer that url will be downloaded into
-; url_download_buffer_length - length of buffer
-;outputs:
-; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents
-; of specified resource (with an extra 2 null bytes at the end),
-; AX = length of resource downloaded.
-resource_download:
-
- ldax url_download_buffer
- stax temp_buffer
- ldax url_download_buffer_length
- stax temp_buffer_length
- jsr put_zero_at_end_of_dl_buffer
-
- ldx #3 ; save IP address just retrieved
-: lda url_ip,x
- sta tcp_connect_ip,x
- dex
- bpl :-
- ldax #url_download_callback
- stax tcp_callback
-
- ldax url_port
- jsr tcp_connect
- bcs @error
-
- ;connected, now send the selector
- ldx #0
- stx download_flag
- ldax url_selector
-
- jsr tcp_send_string
- jsr timer_read
- txa
- adc #TIMEOUT_SECONDS*4 ;what value should trigger the timeout?
- sta timeout_counter
- ;now loop until we're done
-@download_loop:
- jsr ip65_process
- jsr timer_read
- cpx timeout_counter
- beq @timeout
- lda download_flag
- beq @download_loop
-@timeout:
- jsr tcp_close
- clc
-@error:
- rts
-
-
- lda #KPR_ERROR_FILE_ACCESS_FAILURE
- sta ip65_error
- sec
- rts
-
-
- url_download_callback:
-
- lda tcp_inbound_data_length+1
- cmp #$ff
- bne not_end_of_file
-@end_of_file:
- lda #1
- sta download_flag
-
-put_zero_at_end_of_dl_buffer:
- ;put a zero byte at the end of the file
- ldax temp_buffer
- stax copy_dest
- lda #0
- tay
- sta (copy_dest),y
- rts
-
-not_end_of_file:
-;copy this chunk to our input buffer
- ldax temp_buffer
- stax copy_dest
- ldax tcp_inbound_data_ptr
- stax copy_src
- sec
- lda temp_buffer_length
- sbc tcp_inbound_data_length
- pha
- lda temp_buffer_length+1
- sbc tcp_inbound_data_length+1
- bcc @would_overflow_buffer
- sta temp_buffer_length+1
- pla
- sta temp_buffer_length
- ldax tcp_inbound_data_length
- jsr copymem
-;increment the pointer into the input buffer
- clc
- lda temp_buffer
- adc tcp_inbound_data_length
- sta temp_buffer
- lda temp_buffer+1
- adc tcp_inbound_data_length+1
- sta temp_buffer+1
- jmp put_zero_at_end_of_dl_buffer
-
-@would_overflow_buffer:
- pla ;clean up the stack
- ldax temp_buffer_length
- jsr copymem
- lda temp_buffer
- adc temp_buffer_length
- sta temp_buffer
- lda temp_buffer+1
- adc temp_buffer_length+1
- sta temp_buffer+1
- lda #0
- sta temp_buffer_length
- sta temp_buffer_length+1
- jmp put_zero_at_end_of_dl_buffer
-
- .rodata
- get: .byte "GET "
- get_length=4
- http_preamble:
- .byte " HTTP/1.0",$0d,$0a
- .byte "User-Agent: IP65/"
- .include "../inc/version.i"
- .byte $0d,$0a
- .byte "Connection: close",$0d,$0a
- .byte "Host: ",0
-
- colon_slash_slash: .byte ":/"
- slash: .byte "/",0
- colon: .byte ":",0
-
-
-
-
-;-- LICENSE FOR url.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 --
+;routines for parsing a URL, and downloading an URL
+
+
+.include "../inc/common.i"
+
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+TIMEOUT_SECONDS=15
+
+.import output_buffer
+.importzp copy_src
+.importzp copy_dest
+.import copymem
+.import timer_read
+.import ip65_error
+.import ip65_process
+.import parser_init
+.import parser_skip_next
+.import dns_set_hostname
+.import dns_resolve
+.import parse_integer
+.import dns_ip
+.import tcp_connect
+.import tcp_send_string
+.import tcp_send_data_len
+.import tcp_callback
+.import tcp_close
+.import tcp_connect_ip
+.import tcp_inbound_data_length
+.import tcp_inbound_data_ptr
+
+
+.export url_ip
+.export url_port
+.export url_selector
+.export url_resource_type
+.export url_parse
+.export url_download
+.export url_download_buffer
+.export url_download_buffer_length
+.export resource_download
+
+target_string=copy_src
+search_string=copy_dest
+selector_buffer=output_buffer
+
+.segment "TCP_VARS"
+
+ url_string: .res 2
+ url_ip: .res 4 ;will be set with ip address of host in url
+ url_port: .res 2 ;will be set with port number of url
+ url_selector: .res 2 ;will be set with address of selector part of URL
+ url_type: .res 1
+ url_resource_type: .res 1
+ url_type_unknown=0
+ url_type_gopher=1
+ url_type_http=2
+
+ src_ptr: .res 1
+ dest_ptr: .res 1
+ timeout_counter: .res 1
+ url_download_buffer: .res 2 ; points to a buffer that url will be downloaded into
+ url_download_buffer_length: .res 2 ;length of buffer that url will be downloaded into
+
+ temp_buffer: .res 2
+ temp_buffer_length: .res 2
+
+ download_flag: .res 1
+
+
+.code
+
+
+;parses a URL into a form that makes it easy to retrieve the specified resource
+;inputs:
+;AX = address of URL string
+;any control character (i.e. <$20) is treated as 'end of string', e.g. a CR or LF, as well as $00
+;outputs:
+; sec if a malformed url, otherwise:
+; url_ip = ip address of host in url
+; url_port = port number of url
+; url_selector= address of selector part of URL
+url_parse:
+ stax url_string
+ ldy #0
+ sty url_type
+ sty url_port
+ sty url_port+1
+ sty url_resource_type
+
+ jsr skip_to_hostname
+ bcc :+
+ ldax url_string
+ jmp @no_protocol_specifier
+:
+ ldax url_string
+ stax search_string
+
+ lda (search_string),y
+ cmp #'g'
+ beq @gopher
+ cmp #'G'
+ beq @gopher
+ cmp #'h'
+ beq @http
+ cmp #'H'
+ beq @http
+@exit_with_error:
+ lda #KPR_ERROR_MALFORMED_URL
+ sta ip65_error
+@exit_with_sec:
+ sec
+ rts
+@http:
+ lda #url_type_http
+ sta url_type
+ lda #80
+ sta url_port
+ jmp @protocol_set
+@gopher:
+lda #url_type_gopher
+ sta url_type
+ lda #70
+ sta url_port
+@protocol_set:
+ jsr skip_to_hostname
+ ;now pointing at hostname
+ bcs @exit_with_error
+@no_protocol_specifier:
+ jsr dns_set_hostname
+ bcs @exit_with_sec
+ jsr dns_resolve
+ bcc :+
+ lda #KPR_ERROR_DNS_LOOKUP_FAILED
+ sta ip65_error
+ jmp @exit_with_sec
+ :
+ ;copy IP address
+ ldx #3
+:
+ lda dns_ip,x
+ sta url_ip,x
+ dex
+ bpl :-
+
+ jsr skip_to_hostname
+
+ ;skip over next colon
+ ldax #colon
+ jsr parser_skip_next
+ bcs @no_port_in_url
+ ;AX now point at first thing past a colon - should be a number:
+ jsr parse_integer
+ stax url_port
+@no_port_in_url:
+ ;skip over next slash
+ ldax #slash
+ jsr parser_skip_next
+ ;AX now pointing at selector
+ stax copy_src
+ ldax #selector_buffer
+ stax copy_dest
+ lda #0
+ sta src_ptr
+ sta dest_ptr
+ lda url_type
+
+ cmp #url_type_gopher
+ bne @not_gopher
+ ;first byte after / in a gopher url is the resource type
+ ldy src_ptr
+ lda (copy_src),y
+ beq @start_of_selector
+ sta url_resource_type
+ inc src_ptr
+ jmp @start_of_selector
+@not_gopher:
+ cmp #url_type_http
+ beq @build_http_request
+ jmp @done ; if it's not gopher or http, we don't know how to build a selector
+@build_http_request:
+ ldy #get_length-1
+ sty dest_ptr
+:
+ lda get,y
+ sta (copy_dest),y
+ dey
+ bpl :-
+
+@start_of_selector:
+ lda #'/'
+ inc dest_ptr
+ jmp @save_first_byte_of_selector
+@copy_one_byte:
+ ldy src_ptr
+ lda (copy_src),y
+ cmp #$20
+ bcc @end_of_selector ;any control char (including CR,LF, and $00) should be treated as end of URL
+ inc src_ptr
+@save_first_byte_of_selector:
+ ldy dest_ptr
+ sta (copy_dest),y
+ inc dest_ptr
+ bne @copy_one_byte
+@end_of_selector:
+
+
+ ldx #1 ;number of CRLF at end of gopher request
+ lda url_type
+
+ cmp #url_type_http
+ bne @final_crlf
+
+ ;now the HTTP version number & Host: field
+ ldx #0
+:
+ lda http_preamble,x
+ beq :+
+ ldy dest_ptr
+ inc dest_ptr
+ sta (copy_dest),y
+ inx
+ bne :-
+:
+
+
+ ;now copy the host field
+ jsr skip_to_hostname
+ ;AX now pointing at hostname
+ stax copy_src
+ ldax #selector_buffer
+ stax copy_dest
+
+ lda #0
+ sta src_ptr
+
+@copy_one_byte_of_hostname:
+ ldy src_ptr
+ lda (copy_src),y
+ beq @end_of_hostname
+ cmp #':'
+ beq @end_of_hostname
+ cmp #'/'
+ beq @end_of_hostname
+ inc src_ptr
+ ldy dest_ptr
+ sta (copy_dest),y
+ inc dest_ptr
+ bne @copy_one_byte_of_hostname
+@end_of_hostname:
+
+ ldx #2 ;number of CRLF at end of HTTP request
+
+@final_crlf:
+ ldy dest_ptr
+ lda #$0d
+ sta (copy_dest),y
+ iny
+ lda #$0a
+ sta (copy_dest),y
+ iny
+ sty dest_ptr
+ dex
+ bne @final_crlf
+
+@done:
+ lda #$00
+ sta (copy_dest),y
+ ldax #selector_buffer
+ stax url_selector
+ clc
+
+ rts
+
+skip_to_hostname:
+ ldax url_string
+ jsr parser_init
+ ldax #colon_slash_slash
+ jmp parser_skip_next
+
+
+
+;download a resource specified by an URL
+;inputs:
+;AX = address of URL string
+; url_download_buffer - points to a buffer that url will be downloaded into
+; url_download_buffer_length - length of buffer
+;outputs:
+; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents
+; of specified resource (with an extra 2 null bytes at the end),
+; AX = length of resource downloaded.
+url_download:
+ jsr url_parse
+ bcc resource_download
+ rts
+
+;download a resource specified by ip,port & selector
+;inputs:
+; url_ip = ip address of host to connect to
+; url_port = port number of to connect to
+; url_selector= address of selector to send to host after connecting
+; url_download_buffer - points to a buffer that url will be downloaded into
+; url_download_buffer_length - length of buffer
+;outputs:
+; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents
+; of specified resource (with an extra 2 null bytes at the end),
+; AX = length of resource downloaded.
+resource_download:
+
+ ldax url_download_buffer
+ stax temp_buffer
+ ldax url_download_buffer_length
+ stax temp_buffer_length
+ jsr put_zero_at_end_of_dl_buffer
+
+ ldx #3 ; save IP address just retrieved
+: lda url_ip,x
+ sta tcp_connect_ip,x
+ dex
+ bpl :-
+ ldax #url_download_callback
+ stax tcp_callback
+
+ ldax url_port
+ jsr tcp_connect
+ bcs @error
+
+ ;connected, now send the selector
+ ldx #0
+ stx download_flag
+ ldax url_selector
+
+ jsr tcp_send_string
+ jsr timer_read
+ txa
+ adc #TIMEOUT_SECONDS*4 ;what value should trigger the timeout?
+ sta timeout_counter
+ ;now loop until we're done
+@download_loop:
+ jsr ip65_process
+ jsr timer_read
+ cpx timeout_counter
+ beq @timeout
+ lda download_flag
+ beq @download_loop
+@timeout:
+ jsr tcp_close
+ clc
+@error:
+ rts
+
+
+ lda #KPR_ERROR_FILE_ACCESS_FAILURE
+ sta ip65_error
+ sec
+ rts
+
+
+ url_download_callback:
+
+ lda tcp_inbound_data_length+1
+ cmp #$ff
+ bne not_end_of_file
+@end_of_file:
+ lda #1
+ sta download_flag
+
+put_zero_at_end_of_dl_buffer:
+ ;put a zero byte at the end of the file
+ ldax temp_buffer
+ stax copy_dest
+ lda #0
+ tay
+ sta (copy_dest),y
+ rts
+
+not_end_of_file:
+;copy this chunk to our input buffer
+ ldax temp_buffer
+ stax copy_dest
+ ldax tcp_inbound_data_ptr
+ stax copy_src
+ sec
+ lda temp_buffer_length
+ sbc tcp_inbound_data_length
+ pha
+ lda temp_buffer_length+1
+ sbc tcp_inbound_data_length+1
+ bcc @would_overflow_buffer
+ sta temp_buffer_length+1
+ pla
+ sta temp_buffer_length
+ ldax tcp_inbound_data_length
+ jsr copymem
+;increment the pointer into the input buffer
+ clc
+ lda temp_buffer
+ adc tcp_inbound_data_length
+ sta temp_buffer
+ lda temp_buffer+1
+ adc tcp_inbound_data_length+1
+ sta temp_buffer+1
+ jmp put_zero_at_end_of_dl_buffer
+
+@would_overflow_buffer:
+ pla ;clean up the stack
+ ldax temp_buffer_length
+ jsr copymem
+ lda temp_buffer
+ adc temp_buffer_length
+ sta temp_buffer
+ lda temp_buffer+1
+ adc temp_buffer_length+1
+ sta temp_buffer+1
+ lda #0
+ sta temp_buffer_length
+ sta temp_buffer_length+1
+ jmp put_zero_at_end_of_dl_buffer
+
+ .rodata
+ get: .byte "GET "
+ get_length=4
+ http_preamble:
+ .byte " HTTP/1.0",$0d,$0a
+ .byte "User-Agent: IP65/"
+ .include "../inc/version.i"
+ .byte $0d,$0a
+ .byte "Connection: close",$0d,$0a
+ .byte "Host: ",0
+
+ colon_slash_slash: .byte ":/"
+ slash: .byte "/",0
+ colon: .byte ":",0
+
+
+
+
+;-- LICENSE FOR url.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/ip65/xmodem.s b/ip65/xmodem.s
similarity index 94%
rename from client/ip65/xmodem.s
rename to ip65/xmodem.s
index 38452f1..c78bb3d 100644
--- a/client/ip65/xmodem.s
+++ b/ip65/xmodem.s
@@ -1,599 +1,599 @@
-; XMODEM file transfer
-
-.include "../inc/common.i"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-
-XMODEM_BLOCK_SIZE=$80 ;how many bytes (excluding header & checksum) in each block?
-XMODEM_TIMEOUT_SECONDS=5
-XMODEM_MAX_ERRORS=10
-SOH = $01
-EOT = $04
-ACK = $06
-NAK = $15
-CAN = $18
-PAD = $1A ;padding added to end of file
-
-.export xmodem_receive
-.export xmodem_send
-
-.export xmodem_iac_escape ;are IAC bytes ($FF) escaped?
-
-.import ip65_process
-.import ip65_error
-.import tcp_callback
-.import copymem
-.importzp copy_src
-.importzp copy_dest
-.import tcp_send
-.import tcp_send_data_len
-.import tcp_inbound_data_ptr
-.import tcp_inbound_data_length
-.import check_for_abort_key
-.import print_a
-.import print_cr
-.import print_ascii_as_native
-.import print_hex
-.import timer_seconds
-
-.segment "SELF_MODIFIED_CODE"
-got_byte:
- jmp $ffff
-
-get_byte:
- jmp $ffff
-
-next_char:
- lda buffer_length
- bne @not_eof
- lda buffer_length+1
- bne @not_eof
- sec
- rts
-@not_eof:
- next_char_ptr=*+1
- lda $ffff
- pha
- inc next_char_ptr
- bne :+
- inc next_char_ptr+1
-:
- sec
- lda buffer_length
- sbc #1
- sta buffer_length
- lda buffer_length+1
- sbc #0
- sta buffer_length+1
- pla
- clc
- rts
-
-
-emit_a:
-;put a byte to the output buffer
-;if the byte is $FF, and xmodem_iac_escape is not zero, it is doubled
- jsr @real_emit_a
- cmp #$ff
- bne exit_emit_a
- ldx xmodem_iac_escape
- beq exit_emit_a
-@real_emit_a:
-emit_a_ptr=*+1
- sta $ffff
- inc emit_a_ptr
- bne :+
- inc emit_a_ptr+1
-:
- inc xmodem_block_buffer_length
- bne :+
- inc xmodem_block_buffer_length+1
-:
-exit_emit_a:
- rts
-
- .bss
-
-original_tcp_callback: .res 2
-getc_timeout_end: .res 1
-getc_timeout_seconds: .res 1
-buffer_length: .res 2
-
- .code
-
-;send a file via XMODEM (checksum mode only, not CRC)
-;assumes that a tcp connection has already been set up, and that the other end is waiting to start receiving
-;inputs: AX points to routine to call once for each byte in file to send (e.g. save to disk, print to screen, whatever) - byte will be in A, carry flag set means EOF
-; xmodem_iac_escape should be set to non-zero if the remote end escapes $FF bytes (i.e. if it is a real telnet server)
-;outputs: none
-xmodem_send:
- stax get_byte+1
- jsr xmodem_transfer_setup
- lda #0
- sta at_eof
-
-@send_block:
- ldax #sending
- jsr print_ascii_as_native
-
- ldax #block_number_msg
- jsr print_ascii_as_native
- lda expected_block_number
- jsr print_hex
- jsr print_cr
-
-
-@wait_for_ack_or_nak:
- lda #XMODEM_TIMEOUT_SECONDS
- jsr getc
- bcs @synch_error
- cmp #ACK
- beq @got_ack
- cmp #NAK
- beq @got_nak
-
-@synch_error:
- pha
- lda user_abort
- beq @no_user_abort
- pla
- jmp xmodem_transfer_exit
-@no_user_abort:
-
-
-;flush the input buffer
- lda #0
- sta buffer_length
- lda buffer_length+1
-
- lda #'('
- jsr print_a
- pla
- jsr print_hex
- lda #')'
- jsr print_a
-
- inc error_number
- ldax #sync_error_msg
- jsr print_ascii_as_native
- ldax #error_count_msg
- jsr print_ascii_as_native
- lda error_number
- jsr print_hex
- jsr print_cr
- lda error_number
- cmp #XMODEM_MAX_ERRORS
- bcc @wait_for_ack_or_nak
- lda #KPR_ERROR_TOO_MANY_ERRORS
- sta ip65_error
-
-
- jmp xmodem_transfer_exit
-
-@got_ack:
- inc expected_block_number
- lda at_eof
- bne @send_eot
-@got_nak:
- lda #0
- sta checksum
- sta xmodem_block_buffer_length
- sta xmodem_block_buffer_length+1
- ldax #xmodem_block_buffer
- stax emit_a_ptr
-
- lda #SOH
- jsr emit_a
- lda expected_block_number
- jsr emit_a
- eor #$ff
- jsr emit_a
- lda #$80
- sta block_ptr
-@copy_one_byte:
- lda at_eof
- bne @add_pad_byte
-
- jsr get_byte
- bcc @got_byte
- ;sec indicates EOF
- lda block_ptr
- cmp #$80 ;have we sent any data at all?
- bne @add_pad_byte
-
-@send_eot:
- ;if we get here, we should send an EOT, then read an ACK
- ldax #1
- stax tcp_send_data_len
- ldax #eot_packet
- jsr tcp_send
-
- lda #XMODEM_TIMEOUT_SECONDS
- jsr getc ;should be an ACK coming back, doesn't really matter if we don't see it though
-
- jmp xmodem_transfer_exit
-
-@add_pad_byte:
- lda #PAD
-@got_byte:
- pha
- clc
- adc checksum
- sta checksum
- pla
- jsr emit_a
- dec block_ptr
- bne @copy_one_byte
- lda checksum
- jsr emit_a
-
- ldax xmodem_block_buffer_length
- stax tcp_send_data_len
- ldax #xmodem_block_buffer
- jsr tcp_send
- bcc @send_ok
- ldax #send_error
- jsr print_ascii_as_native
- lda ip65_error
- jsr print_hex
- jsr print_cr
-@send_ok:
- jmp @send_block
-
- rts
-
-
-
-xmodem_transfer_setup:
- lda #0
- sta buffer_length
- sta buffer_length+1
- sta error_number
- sta user_abort
- lda #1
- sta expected_block_number
-
-
- ldax tcp_callback
- stax original_tcp_callback
- ldax #xmodem_tcp_callback
- stax tcp_callback
- rts
-
-
-;recieve a file via XMODEM (checksum mode only, not CRC)
-;assumes that a tcp connection has already been set up, and that the other end is waiting to start sending
-;inputs: AX points to routine to call once for each byte in downloaded file (e.g. save to disk, print to screen, whatever) - byte will be in A
-; xmodem_iac_escape should be set to non-zero if the remote end escapes $FF bytes (i.e. if it is a real telnet server)
-;outputs: none
-xmodem_receive:
-
- stax got_byte+1
- jsr xmodem_transfer_setup
- jsr send_nak
-
-
-@next_block:
- lda #0
- sta block_ptr
- sta checksum
- ldax #expecting
- jsr print_ascii_as_native
-
- ldax #block_number_msg
- jsr print_ascii_as_native
- lda expected_block_number
- jsr print_hex
- jsr print_cr
-
-@wait_for_block_start:
- lda #XMODEM_TIMEOUT_SECONDS
- jsr getc
- bcc @got_block_start
- lda user_abort
- beq @no_user_abort
- sec
- jmp xmodem_transfer_exit
-@no_user_abort:
- jsr send_nak
- inc error_number
- ldax #timeout_msg
- jsr print_ascii_as_native
- ldax #error_count_msg
- jsr print_ascii_as_native
- lda error_number
- jsr print_hex
- jsr print_cr
- lda error_number
- cmp #XMODEM_MAX_ERRORS
- bcc @wait_for_block_start
- lda #KPR_ERROR_TOO_MANY_ERRORS
- sta ip65_error
- jmp xmodem_transfer_exit
-@got_block_start:
- cmp #EOT
- bne :+
- ldax #got_eot
- jsr print_ascii_as_native
-
- jsr send_ack
- clc
- jmp xmodem_transfer_exit
-:
-
- cmp #$81 ;jamming signal BBS seems to use $81 not $01 as SOH
- beq @got_soh
- cmp #SOH
- beq @got_soh
- lda #'!' ;we got an unexpected character
- jsr print_a
- jsr print_hex
- ;we need to clear the input buffer
-@clear_input_buffer:
- lda #'!' ;we got an unexpected character
- jsr print_a
- lda #1
- jsr getc
- bcc @clear_input_buffer
-
-
- jmp @wait_for_block_start
-@got_soh:
- ;now get block number
- lda #XMODEM_TIMEOUT_SECONDS
- jsr getc
- bcc :+
- jsr send_nak
- lda #'.'
- jmp print_a
- jmp @wait_for_block_start
-:
- sta actual_block_number
-
- ;now get block number check
- lda #XMODEM_TIMEOUT_SECONDS
- jsr getc
- bcc :+
- lda #'.'
- jmp print_a
- jsr send_nak
- jmp @wait_for_block_start
-:
- adc actual_block_number
- cmp #$ff
- beq :+
- lda #'?'
- jsr print_a
- jmp @wait_for_block_start
-:
- ldax #receiving
- jsr print_ascii_as_native
-
- ldax #block_number_msg
- jsr print_ascii_as_native
- lda actual_block_number
- jsr print_hex
- jsr print_cr
-
-@next_byte:
- lda #XMODEM_TIMEOUT_SECONDS
- jsr getc
- bcc :+
- jmp xmodem_transfer_exit
-:
- ldx block_ptr
- sta xmodem_block_buffer,x
- adc checksum
- sta checksum
-
- inc block_ptr
- lda block_ptr
- bpl @next_byte
-
- ldax #checksum_msg
- jsr print_ascii_as_native
-
- lda checksum
- jsr print_hex
-
- lda #'/'
- jsr print_a
-
- lda #XMODEM_TIMEOUT_SECONDS
- jsr getc
- bcs xmodem_transfer_exit
- sta received_checksum
- jsr print_hex
- jsr print_cr
-
- lda received_checksum
- cmp checksum
- beq @checksum_ok
- ;checksum error :-(
- inc error_number
- ldax #checksum_error_msg
- jsr print_ascii_as_native
- ldax #error_count_msg
- jsr print_ascii_as_native
- lda error_number
- jsr print_hex
- jsr print_cr
- lda error_number
- cmp #XMODEM_MAX_ERRORS
- bcs :+
- jmp @wait_for_block_start
-:
- lda #KPR_ERROR_TOO_MANY_ERRORS
- sta ip65_error
- jmp xmodem_transfer_exit
-
- jsr send_nak
- jmp @next_block
-
-@checksum_ok:
- lda expected_block_number
- cmp actual_block_number
- bne @skip_block_output
-
- lda #0
- sta block_ptr
-
-@output_byte:
- ldx block_ptr
- lda xmodem_block_buffer,x
- jsr got_byte
- inc block_ptr
- lda block_ptr
- bpl @output_byte
-
- inc expected_block_number
-
-@skip_block_output:
- jsr send_ack
- jmp @next_block
-
- clc
-
-xmodem_transfer_exit:
- ldax original_tcp_callback
- stax tcp_callback
-
- rts
-
-xmodem_tcp_callback:
- lda tcp_inbound_data_length+1
- cmp #$ff
- bne @not_eof
- rts
-@not_eof:
-
- ldax tcp_inbound_data_ptr
- stax copy_src
- ldax #xmodem_stream_buffer
- stax copy_dest
- stax next_char_ptr
-
- ldax tcp_inbound_data_length
- stax buffer_length
- jsr copymem
- rts
-
-send_nak:
- ldax #1
- stax tcp_send_data_len
- ldax #nak_packet
- jmp tcp_send
-
-send_ack:
- ldax #1
- stax tcp_send_data_len
- ldax #ack_packet
- jmp tcp_send
-
-
-getc:
- jsr @real_getc
- bcc :+ ;of we got an error, then bail
- rts
-:
- cmp #$ff
- beq @got_ff
- clc
- rts
-@got_ff:
- lda xmodem_iac_escape
- bne @real_getc ;need to skip over the $FF and go read another byte
- lda #$ff
- clc
- rts
-
-@real_getc:
- sta getc_timeout_seconds
-
- clc
- jsr timer_seconds ;time of day clock: seconds (in BCD)
- sed
- adc getc_timeout_seconds
- cmp #$60
- bcc @timeout_set
- sec
- sbc #$60
-@timeout_set:
- cld
- sta getc_timeout_end
-
-@poll_loop:
- jsr next_char
- bcs @no_char
- rts ;done!
-@no_char:
- jsr check_for_abort_key
- bcc @no_abort
- lda #KPR_ERROR_ABORTED_BY_USER
- sta ip65_error
- inc user_abort
- rts
-@no_abort:
- jsr ip65_process
- jsr timer_seconds ;time of day clock: seconds
- cmp getc_timeout_end
- bne @poll_loop
- lda #00
- sec
- rts
-
-
-
-.rodata
- ack_packet: .byte ACK
- nak_packet: .byte NAK
- eot_packet: .byte EOT
-
-block_number_msg: .byte " block $",0
-expecting: .byte "expecting",0
-receiving: .byte "receiving",0
-sending: .byte "sending",0
-got_eot: .byte "end of transmission",10,0
-
-bad_block_number: .byte "bad block number",0
-checksum_msg: .byte "checksum $",0
-checksum_error_msg : .byte "checksum",0
-timeout_msg: .byte "timeout error",0
-sync_error_msg: .byte "sync",0
-error_count_msg: .byte " error - error count $",0
-send_error: .byte " send error - $",0
-
-.segment "APP_SCRATCH"
-xmodem_stream_buffer: .res 1600
-xmodem_block_buffer: .res 300
-xmodem_block_buffer_length: .res 2
-expected_block_number: .res 1
-actual_block_number: .res 1
-checksum: .res 1
-received_checksum: .res 1
-block_ptr: .res 1
-error_number: .res 1
-user_abort: .res 1
-xmodem_iac_escape: .res 1
-at_eof: .res 1
-;-- LICENSE FOR xmodem.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 --
+; XMODEM file transfer
+
+.include "../inc/common.i"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+
+XMODEM_BLOCK_SIZE=$80 ;how many bytes (excluding header & checksum) in each block?
+XMODEM_TIMEOUT_SECONDS=5
+XMODEM_MAX_ERRORS=10
+SOH = $01
+EOT = $04
+ACK = $06
+NAK = $15
+CAN = $18
+PAD = $1A ;padding added to end of file
+
+.export xmodem_receive
+.export xmodem_send
+
+.export xmodem_iac_escape ;are IAC bytes ($FF) escaped?
+
+.import ip65_process
+.import ip65_error
+.import tcp_callback
+.import copymem
+.importzp copy_src
+.importzp copy_dest
+.import tcp_send
+.import tcp_send_data_len
+.import tcp_inbound_data_ptr
+.import tcp_inbound_data_length
+.import check_for_abort_key
+.import print_a
+.import print_cr
+.import print_ascii_as_native
+.import print_hex
+.import timer_seconds
+
+.segment "SELF_MODIFIED_CODE"
+got_byte:
+ jmp $ffff
+
+get_byte:
+ jmp $ffff
+
+next_char:
+ lda buffer_length
+ bne @not_eof
+ lda buffer_length+1
+ bne @not_eof
+ sec
+ rts
+@not_eof:
+ next_char_ptr=*+1
+ lda $ffff
+ pha
+ inc next_char_ptr
+ bne :+
+ inc next_char_ptr+1
+:
+ sec
+ lda buffer_length
+ sbc #1
+ sta buffer_length
+ lda buffer_length+1
+ sbc #0
+ sta buffer_length+1
+ pla
+ clc
+ rts
+
+
+emit_a:
+;put a byte to the output buffer
+;if the byte is $FF, and xmodem_iac_escape is not zero, it is doubled
+ jsr @real_emit_a
+ cmp #$ff
+ bne exit_emit_a
+ ldx xmodem_iac_escape
+ beq exit_emit_a
+@real_emit_a:
+emit_a_ptr=*+1
+ sta $ffff
+ inc emit_a_ptr
+ bne :+
+ inc emit_a_ptr+1
+:
+ inc xmodem_block_buffer_length
+ bne :+
+ inc xmodem_block_buffer_length+1
+:
+exit_emit_a:
+ rts
+
+ .bss
+
+original_tcp_callback: .res 2
+getc_timeout_end: .res 1
+getc_timeout_seconds: .res 1
+buffer_length: .res 2
+
+ .code
+
+;send a file via XMODEM (checksum mode only, not CRC)
+;assumes that a tcp connection has already been set up, and that the other end is waiting to start receiving
+;inputs: AX points to routine to call once for each byte in file to send (e.g. save to disk, print to screen, whatever) - byte will be in A, carry flag set means EOF
+; xmodem_iac_escape should be set to non-zero if the remote end escapes $FF bytes (i.e. if it is a real telnet server)
+;outputs: none
+xmodem_send:
+ stax get_byte+1
+ jsr xmodem_transfer_setup
+ lda #0
+ sta at_eof
+
+@send_block:
+ ldax #sending
+ jsr print_ascii_as_native
+
+ ldax #block_number_msg
+ jsr print_ascii_as_native
+ lda expected_block_number
+ jsr print_hex
+ jsr print_cr
+
+
+@wait_for_ack_or_nak:
+ lda #XMODEM_TIMEOUT_SECONDS
+ jsr getc
+ bcs @synch_error
+ cmp #ACK
+ beq @got_ack
+ cmp #NAK
+ beq @got_nak
+
+@synch_error:
+ pha
+ lda user_abort
+ beq @no_user_abort
+ pla
+ jmp xmodem_transfer_exit
+@no_user_abort:
+
+
+;flush the input buffer
+ lda #0
+ sta buffer_length
+ lda buffer_length+1
+
+ lda #'('
+ jsr print_a
+ pla
+ jsr print_hex
+ lda #')'
+ jsr print_a
+
+ inc error_number
+ ldax #sync_error_msg
+ jsr print_ascii_as_native
+ ldax #error_count_msg
+ jsr print_ascii_as_native
+ lda error_number
+ jsr print_hex
+ jsr print_cr
+ lda error_number
+ cmp #XMODEM_MAX_ERRORS
+ bcc @wait_for_ack_or_nak
+ lda #KPR_ERROR_TOO_MANY_ERRORS
+ sta ip65_error
+
+
+ jmp xmodem_transfer_exit
+
+@got_ack:
+ inc expected_block_number
+ lda at_eof
+ bne @send_eot
+@got_nak:
+ lda #0
+ sta checksum
+ sta xmodem_block_buffer_length
+ sta xmodem_block_buffer_length+1
+ ldax #xmodem_block_buffer
+ stax emit_a_ptr
+
+ lda #SOH
+ jsr emit_a
+ lda expected_block_number
+ jsr emit_a
+ eor #$ff
+ jsr emit_a
+ lda #$80
+ sta block_ptr
+@copy_one_byte:
+ lda at_eof
+ bne @add_pad_byte
+
+ jsr get_byte
+ bcc @got_byte
+ ;sec indicates EOF
+ lda block_ptr
+ cmp #$80 ;have we sent any data at all?
+ bne @add_pad_byte
+
+@send_eot:
+ ;if we get here, we should send an EOT, then read an ACK
+ ldax #1
+ stax tcp_send_data_len
+ ldax #eot_packet
+ jsr tcp_send
+
+ lda #XMODEM_TIMEOUT_SECONDS
+ jsr getc ;should be an ACK coming back, doesn't really matter if we don't see it though
+
+ jmp xmodem_transfer_exit
+
+@add_pad_byte:
+ lda #PAD
+@got_byte:
+ pha
+ clc
+ adc checksum
+ sta checksum
+ pla
+ jsr emit_a
+ dec block_ptr
+ bne @copy_one_byte
+ lda checksum
+ jsr emit_a
+
+ ldax xmodem_block_buffer_length
+ stax tcp_send_data_len
+ ldax #xmodem_block_buffer
+ jsr tcp_send
+ bcc @send_ok
+ ldax #send_error
+ jsr print_ascii_as_native
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+@send_ok:
+ jmp @send_block
+
+ rts
+
+
+
+xmodem_transfer_setup:
+ lda #0
+ sta buffer_length
+ sta buffer_length+1
+ sta error_number
+ sta user_abort
+ lda #1
+ sta expected_block_number
+
+
+ ldax tcp_callback
+ stax original_tcp_callback
+ ldax #xmodem_tcp_callback
+ stax tcp_callback
+ rts
+
+
+;recieve a file via XMODEM (checksum mode only, not CRC)
+;assumes that a tcp connection has already been set up, and that the other end is waiting to start sending
+;inputs: AX points to routine to call once for each byte in downloaded file (e.g. save to disk, print to screen, whatever) - byte will be in A
+; xmodem_iac_escape should be set to non-zero if the remote end escapes $FF bytes (i.e. if it is a real telnet server)
+;outputs: none
+xmodem_receive:
+
+ stax got_byte+1
+ jsr xmodem_transfer_setup
+ jsr send_nak
+
+
+@next_block:
+ lda #0
+ sta block_ptr
+ sta checksum
+ ldax #expecting
+ jsr print_ascii_as_native
+
+ ldax #block_number_msg
+ jsr print_ascii_as_native
+ lda expected_block_number
+ jsr print_hex
+ jsr print_cr
+
+@wait_for_block_start:
+ lda #XMODEM_TIMEOUT_SECONDS
+ jsr getc
+ bcc @got_block_start
+ lda user_abort
+ beq @no_user_abort
+ sec
+ jmp xmodem_transfer_exit
+@no_user_abort:
+ jsr send_nak
+ inc error_number
+ ldax #timeout_msg
+ jsr print_ascii_as_native
+ ldax #error_count_msg
+ jsr print_ascii_as_native
+ lda error_number
+ jsr print_hex
+ jsr print_cr
+ lda error_number
+ cmp #XMODEM_MAX_ERRORS
+ bcc @wait_for_block_start
+ lda #KPR_ERROR_TOO_MANY_ERRORS
+ sta ip65_error
+ jmp xmodem_transfer_exit
+@got_block_start:
+ cmp #EOT
+ bne :+
+ ldax #got_eot
+ jsr print_ascii_as_native
+
+ jsr send_ack
+ clc
+ jmp xmodem_transfer_exit
+:
+
+ cmp #$81 ;jamming signal BBS seems to use $81 not $01 as SOH
+ beq @got_soh
+ cmp #SOH
+ beq @got_soh
+ lda #'!' ;we got an unexpected character
+ jsr print_a
+ jsr print_hex
+ ;we need to clear the input buffer
+@clear_input_buffer:
+ lda #'!' ;we got an unexpected character
+ jsr print_a
+ lda #1
+ jsr getc
+ bcc @clear_input_buffer
+
+
+ jmp @wait_for_block_start
+@got_soh:
+ ;now get block number
+ lda #XMODEM_TIMEOUT_SECONDS
+ jsr getc
+ bcc :+
+ jsr send_nak
+ lda #'.'
+ jmp print_a
+ jmp @wait_for_block_start
+:
+ sta actual_block_number
+
+ ;now get block number check
+ lda #XMODEM_TIMEOUT_SECONDS
+ jsr getc
+ bcc :+
+ lda #'.'
+ jmp print_a
+ jsr send_nak
+ jmp @wait_for_block_start
+:
+ adc actual_block_number
+ cmp #$ff
+ beq :+
+ lda #'?'
+ jsr print_a
+ jmp @wait_for_block_start
+:
+ ldax #receiving
+ jsr print_ascii_as_native
+
+ ldax #block_number_msg
+ jsr print_ascii_as_native
+ lda actual_block_number
+ jsr print_hex
+ jsr print_cr
+
+@next_byte:
+ lda #XMODEM_TIMEOUT_SECONDS
+ jsr getc
+ bcc :+
+ jmp xmodem_transfer_exit
+:
+ ldx block_ptr
+ sta xmodem_block_buffer,x
+ adc checksum
+ sta checksum
+
+ inc block_ptr
+ lda block_ptr
+ bpl @next_byte
+
+ ldax #checksum_msg
+ jsr print_ascii_as_native
+
+ lda checksum
+ jsr print_hex
+
+ lda #'/'
+ jsr print_a
+
+ lda #XMODEM_TIMEOUT_SECONDS
+ jsr getc
+ bcs xmodem_transfer_exit
+ sta received_checksum
+ jsr print_hex
+ jsr print_cr
+
+ lda received_checksum
+ cmp checksum
+ beq @checksum_ok
+ ;checksum error :-(
+ inc error_number
+ ldax #checksum_error_msg
+ jsr print_ascii_as_native
+ ldax #error_count_msg
+ jsr print_ascii_as_native
+ lda error_number
+ jsr print_hex
+ jsr print_cr
+ lda error_number
+ cmp #XMODEM_MAX_ERRORS
+ bcs :+
+ jmp @wait_for_block_start
+:
+ lda #KPR_ERROR_TOO_MANY_ERRORS
+ sta ip65_error
+ jmp xmodem_transfer_exit
+
+ jsr send_nak
+ jmp @next_block
+
+@checksum_ok:
+ lda expected_block_number
+ cmp actual_block_number
+ bne @skip_block_output
+
+ lda #0
+ sta block_ptr
+
+@output_byte:
+ ldx block_ptr
+ lda xmodem_block_buffer,x
+ jsr got_byte
+ inc block_ptr
+ lda block_ptr
+ bpl @output_byte
+
+ inc expected_block_number
+
+@skip_block_output:
+ jsr send_ack
+ jmp @next_block
+
+ clc
+
+xmodem_transfer_exit:
+ ldax original_tcp_callback
+ stax tcp_callback
+
+ rts
+
+xmodem_tcp_callback:
+ lda tcp_inbound_data_length+1
+ cmp #$ff
+ bne @not_eof
+ rts
+@not_eof:
+
+ ldax tcp_inbound_data_ptr
+ stax copy_src
+ ldax #xmodem_stream_buffer
+ stax copy_dest
+ stax next_char_ptr
+
+ ldax tcp_inbound_data_length
+ stax buffer_length
+ jsr copymem
+ rts
+
+send_nak:
+ ldax #1
+ stax tcp_send_data_len
+ ldax #nak_packet
+ jmp tcp_send
+
+send_ack:
+ ldax #1
+ stax tcp_send_data_len
+ ldax #ack_packet
+ jmp tcp_send
+
+
+getc:
+ jsr @real_getc
+ bcc :+ ;of we got an error, then bail
+ rts
+:
+ cmp #$ff
+ beq @got_ff
+ clc
+ rts
+@got_ff:
+ lda xmodem_iac_escape
+ bne @real_getc ;need to skip over the $FF and go read another byte
+ lda #$ff
+ clc
+ rts
+
+@real_getc:
+ sta getc_timeout_seconds
+
+ clc
+ jsr timer_seconds ;time of day clock: seconds (in BCD)
+ sed
+ adc getc_timeout_seconds
+ cmp #$60
+ bcc @timeout_set
+ sec
+ sbc #$60
+@timeout_set:
+ cld
+ sta getc_timeout_end
+
+@poll_loop:
+ jsr next_char
+ bcs @no_char
+ rts ;done!
+@no_char:
+ jsr check_for_abort_key
+ bcc @no_abort
+ lda #KPR_ERROR_ABORTED_BY_USER
+ sta ip65_error
+ inc user_abort
+ rts
+@no_abort:
+ jsr ip65_process
+ jsr timer_seconds ;time of day clock: seconds
+ cmp getc_timeout_end
+ bne @poll_loop
+ lda #00
+ sec
+ rts
+
+
+
+.rodata
+ ack_packet: .byte ACK
+ nak_packet: .byte NAK
+ eot_packet: .byte EOT
+
+block_number_msg: .byte " block $",0
+expecting: .byte "expecting",0
+receiving: .byte "receiving",0
+sending: .byte "sending",0
+got_eot: .byte "end of transmission",10,0
+
+bad_block_number: .byte "bad block number",0
+checksum_msg: .byte "checksum $",0
+checksum_error_msg : .byte "checksum",0
+timeout_msg: .byte "timeout error",0
+sync_error_msg: .byte "sync",0
+error_count_msg: .byte " error - error count $",0
+send_error: .byte " send error - $",0
+
+.segment "APP_SCRATCH"
+xmodem_stream_buffer: .res 1600
+xmodem_block_buffer: .res 300
+xmodem_block_buffer_length: .res 2
+expected_block_number: .res 1
+actual_block_number: .res 1
+checksum: .res 1
+received_checksum: .res 1
+block_ptr: .res 1
+error_number: .res 1
+user_abort: .res 1
+xmodem_iac_escape: .res 1
+at_eof: .res 1
+;-- LICENSE FOR xmodem.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/libnet/Makefile b/libnet/Makefile
similarity index 100%
rename from client/libnet/Makefile
rename to libnet/Makefile
diff --git a/client/libnet/c64libnet.cfg b/libnet/c64libnet.cfg
similarity index 100%
rename from client/libnet/c64libnet.cfg
rename to libnet/c64libnet.cfg
diff --git a/client/libnet/libnet.h b/libnet/libnet.h
similarity index 100%
rename from client/libnet/libnet.h
rename to libnet/libnet.h
diff --git a/client/libnet/libnet.s b/libnet/libnet.s
similarity index 95%
rename from client/libnet/libnet.s
rename to libnet/libnet.s
index c88c230..4b3cd63 100644
--- a/client/libnet/libnet.s
+++ b/libnet/libnet.s
@@ -1,95 +1,95 @@
-.export _libnet_init
-.export _libnet_get_config
-.export _libnet_MAC
-
-.import cfg_init
-.import cfg_ip
-.import copymem
-.import ip65_init
-.import dhcp_init
-.import ip65_error
-.import cfg_mac_default
-.import cfg_mac
-.import cfg_size
-
-_libnet_MAC=cfg_mac_default
-
-; load A/X macro
-.macro ldax arg
-.if (.match (.left (1, arg), #)) ; immediate mode
- lda #<(.right (.tcount (arg)-1, arg))
- ldx #>(.right (.tcount (arg)-1, arg))
-.else ; assume absolute or zero page
- lda arg
- ldx 1+(arg)
-.endif
-.endmacro
-
-; store A/X macro
-.macro stax arg
- sta arg
- stx 1+(arg)
-.endmacro
-
-
-NO_ERROR=$00
-
-
-.importzp copy_src
-.importzp copy_dest
-.zeropage
-
-.code
-_libnet_init:
- sta copy_src
- stx copy_src+1
- beq @dhcp_request
- ldax #cfg_ip
- stax copy_dest
- ldax #$10 ;4 items of config data
- jsr copymem
- jsr ip65_init
-@check_error:
- bcc @ok
- lda ip65_error
- rts
-@ok:
- lda #NO_ERROR
- rts
-
-
-@dhcp_request:
- jsr ip65_init
- jsr dhcp_init
- jmp @check_error
-
-_libnet_get_config:
-
- stax copy_dest
- ldax #cfg_ip
- stax copy_src
- ldax #$10 ;4 items of config data
-
- jmp copymem
-
-.bss
-tmp_ax: .res 2
-
-;-- LICENSE FOR libnet.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 libnet.
-;
-; The Initial Developer of the Original Code is Jonno Downes,
-; jonno@jamtronix.com.
-; Portions created by the Initial Developer are Copyright (C) 2012
-; Jonno DOwnes. All Rights Reserved.
-; -- LICENSE END --
+.export _libnet_init
+.export _libnet_get_config
+.export _libnet_MAC
+
+.import cfg_init
+.import cfg_ip
+.import copymem
+.import ip65_init
+.import dhcp_init
+.import ip65_error
+.import cfg_mac_default
+.import cfg_mac
+.import cfg_size
+
+_libnet_MAC=cfg_mac_default
+
+; load A/X macro
+.macro ldax arg
+.if (.match (.left (1, arg), #)) ; immediate mode
+ lda #<(.right (.tcount (arg)-1, arg))
+ ldx #>(.right (.tcount (arg)-1, arg))
+.else ; assume absolute or zero page
+ lda arg
+ ldx 1+(arg)
+.endif
+.endmacro
+
+; store A/X macro
+.macro stax arg
+ sta arg
+ stx 1+(arg)
+.endmacro
+
+
+NO_ERROR=$00
+
+
+.importzp copy_src
+.importzp copy_dest
+.zeropage
+
+.code
+_libnet_init:
+ sta copy_src
+ stx copy_src+1
+ beq @dhcp_request
+ ldax #cfg_ip
+ stax copy_dest
+ ldax #$10 ;4 items of config data
+ jsr copymem
+ jsr ip65_init
+@check_error:
+ bcc @ok
+ lda ip65_error
+ rts
+@ok:
+ lda #NO_ERROR
+ rts
+
+
+@dhcp_request:
+ jsr ip65_init
+ jsr dhcp_init
+ jmp @check_error
+
+_libnet_get_config:
+
+ stax copy_dest
+ ldax #cfg_ip
+ stax copy_src
+ ldax #$10 ;4 items of config data
+
+ jmp copymem
+
+.bss
+tmp_ax: .res 2
+
+;-- LICENSE FOR libnet.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 libnet.
+;
+; The Initial Developer of the Original Code is Jonno Downes,
+; jonno@jamtronix.com.
+; Portions created by the Initial Developer are Copyright (C) 2012
+; Jonno DOwnes. All Rights Reserved.
+; -- LICENSE END --
diff --git a/client/libnet/test_sntp.c b/libnet/test_sntp.c
similarity index 100%
rename from client/libnet/test_sntp.c
rename to libnet/test_sntp.c
diff --git a/server/bin/import_ags_games.rb b/server/bin/import_ags_games.rb
deleted file mode 100644
index 65c09ef..0000000
--- a/server/bin/import_ags_games.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Jonno Downes (jonno@jamtronix.com) - January, 2009
-#
-#
-
-require 'scanf'
-ags_games_dir=ARGV[0]
-
-if ags_games_dir.nil? or !(File.directory?(ags_games_dir)) then
- scriptname=File.basename(__FILE__)
- puts "usage: #{scriptname} "
- exit
-end
-
-output_dir=File.expand_path(File.dirname(__FILE__)+"/../boot")
-puts "importing games from #{ags_games_dir} to #{output_dir}"
-Dir.chdir(ags_games_dir) do
- Dir.glob("*#06*").each do |input_filename|
- if (input_filename=~/(.+)#06(\w\w\w\w)/) then
- base_filename=$1
- load_address=$2.scanf("%4x")[0]
- file_data=File.new(input_filename,"rb").read
- file_length=file_data.length
-# puts "#{input_filename} : #{base_filename},A$#{"%04X" % load_address},L$#{"%04X" % file_length}"
- header=[load_address,file_length].pack("vv")
- out_file=File.new("#{output_dir}/#{base_filename}.PG2","wb")
- out_file< "
- puts "specified filename will be downloaded from specified tftp server and dumpt to stdout"
- true
-end
-
-number_of_options=ARGV.length
-usage && exit unless number_of_options==2
-servername=ARGV[0]
-filename=ARGV[1]
-
-t = Net::TFTP.new(servername)
-t.getbinary(filename,$stdout)
-
diff --git a/server/bin/tftp_only_server.rb b/server/bin/tftp_only_server.rb
deleted file mode 100644
index d72a705..0000000
--- a/server/bin/tftp_only_server.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# tftp only server
-#
-# Jonno Downes (jonno@jamtronix.com) - January, 2009
-#
-#
-
-Thread.abort_on_exception=true
-
-def log_msg(msg)
- puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} #{msg}"
-end
-
-lib_path=File.expand_path(File.dirname(__FILE__)+'/../lib')
-$:.unshift(lib_path) unless $:.include?(lib_path)
-require 'tftp_server'
-
-bootfile_dir=File.expand_path(File.dirname(__FILE__)+'/../boot')
-tftp_server=Netboot65TFTPServer.new(bootfile_dir,69)
-tftp_server.start
-
-begin
- loop do
- sleep(1) #wake up every second to get keyboard input, so we break on ^C
- end
-rescue Interrupt
- log_msg "got interrupt signal - shutting down"
-end
-tftp_server.shutdown
-log_msg "shut down complete."
diff --git a/server/lib/SubclassTracking.rb b/server/lib/SubclassTracking.rb
deleted file mode 100644
index a3f9653..0000000
--- a/server/lib/SubclassTracking.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-#derived from http://ola-bini.blogspot.com/2007/07/objectspace-to-have-or-not-to-have.html
-module SubclassTracking
-def self.extended(klazz)
- (class <[],:directories=>[]}
- Dir.glob("#{dir}/**").each do |filename|
- relative_filename=filename.sub(/#{base_dir}/,'')
- if File.ftype(filename)=="directory"
- dir_contents[:directories]<<[relative_filename,read_dir(filename,base_dir)]
- elsif (relative_filename=~/(\..{1,3})$/)
- ext=$1.downcase
- dir_contents[:files]<'RRQ', #read request
- 2=>'WRQ', #write request
- 3=>'DATA',
- 4=>'ACK',
- 5=>'ERROR',
- }
-
- TFTP_ERRORCODES={
- 1 =>'File not found.',
- 2 =>'Access violation.',
- 3 =>'Disk full or allocation exceeded.',
- 4 =>'Illegal TFTP operation.',
- 5 =>'Unknown transfer ID.',
- 6 =>'File already exists.',
- 7 =>'No such user.',
- }
- TFTP_MAX_RESENDS=10
-
- attr_reader :bootfile_dir,:port,:server_thread
- def initialize(bootfile_dir,port=69)
- @bootfile_dir=bootfile_dir
- @file_list=FileList.new(bootfile_dir)
- @port=port
- @server_thread=nil
- @current_connection={}
- end
-
- def send_error(client_ip,client_port,error_code,error_msg)
- packet=[5,error_code,error_msg,0].pack("nnA#{error_msg.length}c")
- socket=UDPSocket.open.send(packet,0,client_ip,client_port)
- log_msg("sent error #{error_code}:'#{error_msg}' to #{client_ip}:#{client_port}")
- end
-
- def send_data(client_ip,client_port,filename,data_to_send)
-
- client_sock=UDPSocket.open
- client_sock.connect(client_ip,client_port)
-
- blocks_to_send=1+(data_to_send.length.to_f/512.0).floor
- log_msg("sending #{filename} to #{client_ip}:#{client_port} (#{blocks_to_send} blocks)")
- start_time=Time.now
- blocks_to_send.times do |block_number|
- block_data=data_to_send[block_number*512,512]
- packet=[3,block_number+1,block_data].pack("nnA*")
- got_ack=false
- TFTP_MAX_RESENDS.times do |attempt_number|
- log_msg("sending block #{block_number+1}/#{blocks_to_send} of #{filename} to #{client_ip}:#{client_port} - #{block_data.length} bytes - attempt #{attempt_number+1}")
- client_sock.send(packet,0)
- if (IO.select([client_sock], nil, nil, 1)) then
- data,addr_info=client_sock.recvfrom(4096)
- client_ip=addr_info[3]
- client_port=addr_info[1]
- opcode=data[0,2].unpack("n")[0]
- opcode_description=TFTP_OPCODES[opcode]
- if opcode==4 then
- acked_block_number=data[2,2].unpack("n")[0]
- log_msg "TFTP: ACK from #{client_ip}:#{client_port} - block #{acked_block_number}"
- got_ack=true if acked_block_number==block_number+1
- else
- opcode_description="[UNK]" if opcode_description.nil?
- log_msg "TFTP: response from #{client_ip}:#{client_port} - opcode #{opcode} : #{opcode_description}"
- end
- end
- break if got_ack
- end
- if !got_ack then
- log_msg "TFTP: timed out waiting for ACK of block #{block_number} from #{client_ip}"
- break
- end
- end
- end_time=Time.now
- duration=end_time-start_time
- log_msg "TFTP: transmission time to #{client_ip} = #{duration} seconds"
- end
-
-
- def recv_data(client_ip,client_port,filename,file_handle)
-
- client_sock=UDPSocket.open
- client_sock.connect(client_ip,client_port)
- client_id="#{client_ip}:#{client_port}"
- if @current_connection[client_id]==true then
- log_msg("already sending to #{client_id}" )
- end
- @current_connection[client_id]=true
- log_msg("receiving #{filename} from #{client_ip}:#{client_port}")
- got_last_block=false
- finished=false
- block_number=0
- finished
- until finished do
- packet=[4,block_number].pack("nn")
- got_block=false
- TFTP_MAX_RESENDS.times do |attempt_number|
- log_msg("ACKing block #{block_number} of #{filename} from #{client_ip}:#{client_port} - attempt #{attempt_number+1}")
- client_sock.send(packet,0)
- if got_last_block then
- puts "last block received"
- finished=true
- break
- else
- if (IO.select([client_sock], nil, nil, 1)) then
- data,addr_info=client_sock.recvfrom(4096)
- client_ip=addr_info[3]
- client_port=addr_info[1]
- opcode=data[0,2].unpack("n")[0]
- opcode_description=TFTP_OPCODES[opcode]
- if opcode==3 then
- recved_block_number=data[2,2].unpack("n")[0]
- block_data=data[4,512]
- got_last_block=(block_data.length!=512)
- log_msg "TFTP: DATA from #{client_ip}:#{client_port} - block #{recved_block_number} - #{block_data.length} bytes"
- if recved_block_number==block_number+1
- got_block=true
- file_handle<e
- send_error(client_ip,client_port,1,"error retrieving '#{filename}':#{e.to_s}")
- log_msg(e.backtrace.join("\n"))
- end
- end
- when 2 : #WRITE REQUEST
- opcode,filename_and_mode=data.unpack("nA*")
- filename,mode=filename_and_mode.split(0.chr)
- log_msg "WRQ for #{filename} (#{mode})"
- if filename=~/^\./ || filename=~/\.\./ then #looks like something dodgy - either a dotfile or a directory traversal attempt
- send_error(client_ip,client_port,1,"'#{filename}' invalid filename")
- else
- full_filename="#{bootfile_dir}/#{filename}"
- begin
- file_handle=File.open(full_filename,"wb")
- Thread.new {recv_data(client_ip,client_port,full_filename,file_handle)}
- rescue Exception=>e
- send_error(client_ip,client_port,2,"error writing to '#{full_filename}': #{e.to_s}")
- end
- end
- when 0x65 : #DIR REQUEST
- opcode,filemask_and_mode=data.unpack("nA*")
- filemask,mode=filemask_and_mode.split(0.chr)
- log_msg "DIR for #{filemask} (#{mode})"
- if filename=~/^\./ || filename=~/\.\./ then #looks like something dodgy - either a dotfile or a directory traversal attempt
- send_error(client_ip,client_port,1,"'#{filemask}' invalid filename")
- else
- data_to_send=""
- Dir.chdir(bootfile_dir) do
- Dir.glob(filemask).each {|filename| data_to_send<<"#{filename}\000"}
- end
- data_to_send<<0.chr
- Thread.new {send_data(client_ip,client_port,"DIR of #{filemask}",data_to_send)}
- end
- else
- send_error(client_ip,client_port,4,"opcode #{opcode} not supported")
- end
- socket.close
- end
- end
-# @server_thread.join
- end
-
- def shutdown()
- log_msg "TFTP: stopping"
- server_thread.kill
- end
-
-end
\ No newline at end of file
diff --git a/server/lib/tndp.rb b/server/lib/tndp.rb
deleted file mode 100644
index 0d4809c..0000000
--- a/server/lib/tndp.rb
+++ /dev/null
@@ -1,459 +0,0 @@
-#
-# message formats for Trivial Network Disk Protocol
-#
-$:.unshift(File.dirname(__FILE__)) unless
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-require 'SubclassTracking'
-
-
-#useful extension to Hash class
-
-class Hash
- def key_by_value(value)
- self.keys.each do |key|
- return key if self[key]==value
- end
- nil
- end
-end
-
-
-module TNDP
-
- OPCODES={
- 0x00 =>"CAPABILITIES REQUEST",
- 0x01 =>"VOLUME CATALOG REQUEST",
- 0x02 =>"READ SECTOR REQUEST",
- 0x03 =>"WRITE SECTOR REQUEST",
- 0x04=>"INIT VOLUME REQUEST",
- 0x80 =>"CAPABILITIES RESPONSE",
- 0x81 =>"VOLUME CATALOG RESPONSE",
- 0x82 =>"READ SECTOR RESPONSE",
- 0x83 =>"WRITE SECTOR RESPONSE",
- 0x84=>"INIT VOLUME RESPONSE",
- 0xFF =>"ERROR RESPONSE",
- }
-
- MAX_CATALOG_ENTRIES_PER_MESSAGE=8
- MAX_VOLUME_NAME_LENGTH=127
- SYSTEM_ARCHITECTURES={
- :any=>0x00,
- :c64=>0x64,
- :apple2=>0xA2,
- :unknown=>0xFF,
- }
-
-FILESYSTEMS={
- :any=>0x00,
- :raw=>0x01,
- :apple_dos_33=>0x02,
- :prodos=>0x03,
- :cpm=>0x04,
- :cbm_dos=>0x05,
- :unknown=>0xFF,
-}
-
- class ErrorCodes
- OK=0x00
- UNKNOWN_OPCODE=0x02
- VERSION_NOT_SUPPORTED=0x03
- ARCHITECTURE_NOT_SUPPORTED=0x04
- FILESYSTEM_NOT_SUPPORTED=0x05
- INVALID_VOLUME_NAME=0x06
- INVALID_TRACK_NUMBER=0x07
- INVALID_SECTOR_NUMBER=0x08
- INVALID_SECTOR_LENGTH=0x09
- INTERNAL_SERVER_ERROR=0xFF
- end
-
- class FormatError 0 then
- line.each_byte {|byte|
- lhs+= sprintf("%02X ", byte)
- rhs+=byte.chr.sub(/[\x00-\x1f]/,'.')
- }
- lhs+=" "*(16-line.length)*3
- s+=sprintf("%02X\t%s %s\n",start_byte,lhs,rhs)
- end
- }
- s
- end
-
- def TNDP.coalesce(a,b)
- if a.nil? then
- b
- else
- a
- end
- end
-
- @@next_transaction_id=0
- def TNDP.next_transaction_id
- @@next_transaction_id+=1
- @@next_transaction_id
- end
-
- MESSAGE_SIGNATURE='TNDP'
- VERSION_ID=1
- def TNDP.message_from_buffer(buffer)
- raise BufferTooShort unless buffer.length>=0x07
- signature,version_id,transaction_id,opcode=buffer.unpack("Z4CnC")
- raise InvalidSignature unless signature==MESSAGE_SIGNATURE
- raise InvalidVersion unless version_id==1
-
- BaseMessage.subclasses.each do |msg_type|
- next unless defined?(msg_type::OPCODE)
- return msg_type.from_buffer(buffer) if opcode==msg_type::OPCODE
- end
- raise InvalidOpcode
- end
-
- class BaseMessage
- attr_accessor :signature,:version_id,:transaction_id,:opcode,:raw_bytes
-
- def raw_bytes
- @raw_bytes=to_buffer if @raw_bytes.nil?
- @raw_bytes
- end
-
- def to_buffer
- packed_buffer=[signature,version_id,transaction_id,opcode].pack("Z4cnC")
- packed_buffer
- end
-
- def to_s
- hex_dump+
-"
-TNDP MESSAGE
-SIGNATURE: #{signature}
-VERSION: #{version_id}
-TRANSACTION ID: $#{"%04x"%transaction_id}
-OPCODE: $#{"%02X"%opcode} [#{OPCODES[opcode].nil? ? "UNKNOWN" : OPCODES[opcode]}]"
- end
-
- def hex_dump
- TNDP.hex_dump(raw_bytes)
- end
- def initialize(args={})
- @signature=TNDP.coalesce(args[:signature],MESSAGE_SIGNATURE)
- @version_id=TNDP.coalesce(args[:version_id],0x01)
- @transaction_id=TNDP.coalesce(args[:transaction_id],TNDP.next_transaction_id)
- @opcode=TNDP.coalesce(args[:opcode],0xFF)
- end
-
-private
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode=buffer.unpack("Z4CnC")
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,:opcode=>opcode})
- end
-
- self.extend SubclassTracking
-
- end
-
- class CapabilitiesRequestMessage < BaseMessage
- OPCODE=0x00
- def initialize(args={})
- args[:opcode]=OPCODE
- super(args)
- end
- end
-
- class CapabilitiesResponseMessage < BaseMessage
- OPCODE=0x80
- attr_reader :application_name,:highest_supported_version_id,:supported_architectures
- def initialize(args={})
- args[:opcode]=OPCODE
- @application_name=TNDP.coalesce(args[:application_name],"netboot 65")
- @highest_supported_version_id=TNDP.coalesce(args[:highest_supported_version_id],VERSION_ID)
- @supported_architectures=TNDP.coalesce(args[:supported_architectures],[[:any,0]])
- super(args)
- end
-
- def to_s
- s=""
- supported_architectures.each do |entry|
- system_architecture_id=TNDP::SYSTEM_ARCHITECTURES[entry[0]]
- count=entry[1]
- s<<"\n%s [0x%02X] - 0x%04X" % [entry[0],system_architecture_id,count]
- end
- super+s
- end
-
- def to_buffer
- supported_architectures_buffer=[supported_architectures.length].pack("C")
- supported_architectures.each{|a| supported_architectures_buffer+=[TNDP::SYSTEM_ARCHITECTURES[a[0]],a[1]].pack("CC")}
- super+[highest_supported_version_id,application_name].pack("CZ20")+supported_architectures_buffer
- end
-
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode,highest_supported_version_id,application_name,supported_architectures_length=buffer.unpack("Z4CnCCZ20C")
- supported_architectures={}
- supported_architectures_length.times do |i|
- system_architecture_id=buffer[(i*2)+0x1E]
- system_architecture=TNDP.coalesce(TNDP::SYSTEM_ARCHITECTURES.key_by_value(system_architecture_id),:unknown)
- count=buffer[(i*2)+0x1F]
- supported_architectures[system_architecture]=count
- end
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,
- :opcode=>opcode,:application_name=>application_name,:highest_supported_version_id=>highest_supported_version_id,:supported_architectures=>supported_architectures})
- end
-
- end
-
- class VolumeCatalogRequestMessage < BaseMessage
- attr_reader :system_architecture, :file_system, :catalog_offset
- OPCODE=0x01
- def initialize(args={})
- args[:opcode]=OPCODE
- @system_architecture=TNDP.coalesce(TNDP::SYSTEM_ARCHITECTURES.key_by_value(TNDP::SYSTEM_ARCHITECTURES[args[:system_architecture]]),:any)
- @file_system=TNDP.coalesce(TNDP::FILESYSTEMS.key_by_value(TNDP::FILESYSTEMS[args[:file_system]]),:any)
- @catalog_offset=TNDP.coalesce(args[:catalog_offset],0)
- super(args)
- end
-
- def to_s
- system_architecture_id=TNDP::SYSTEM_ARCHITECTURES[system_architecture]
- file_system_id=TNDP::FILESYSTEMS[file_system]
- super+"
-ARCHITECTURE: #{system_architecture} [$#{"%02X"%system_architecture_id}]
-FILE SYSTEM: #{file_system} [$#{"%02X"%file_system_id}]
-CATALOG OFFSET: $#{"%04x" % catalog_offset}"
-
- end
-
- def to_buffer
- super+[TNDP::SYSTEM_ARCHITECTURES[system_architecture],TNDP::FILESYSTEMS[file_system],catalog_offset].pack("CCn")
- end
-
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode,system_architecture_id,file_system_id,catalog_offset=buffer.unpack("Z4CnCCCn")
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,
- :opcode=>opcode,:system_architecture=>TNDP::SYSTEM_ARCHITECTURES.key_by_value(system_architecture_id),:file_system=>TNDP::FILESYSTEMS.key_by_value(file_system_id),:catalog_offset=>catalog_offset})
- end
-
- end
-
- class VolumeCatalogResponseMessage < BaseMessage
- attr_reader :catalog_offset,:total_catalog_size,:catalog_entries
- OPCODE=0x81
- def initialize(args={})
- args[:opcode]=OPCODE
- @catalog_entries=TNDP.coalesce(args[:catalog_entries],[])
- @catalog_offset=TNDP.coalesce(args[:catalog_offset],0)
- @total_catalog_size=TNDP.coalesce(args[:total_catalog_size],0)
- super(args)
- end
- def to_s
- s="\nCATALOG ENTRIES:\n___________________"
- catalog_entries.each do |entry|
- s<<"\nVOLUME NAME: %s\n\tSYSTEM ARCHITECTURE: %s\n\tFILE SYSTEM: %s\n\tTRACKS : 0x%04X\n\tSECTOR SIZE: 0x%04X" % entry
- end
- super+"
- CATALOG SIZE: $#{"%04x" % total_catalog_size}
- CATALOG OFFSET: $#{"%04x" % catalog_offset}"+s
- end
-
- def to_buffer
- catalog_buffer=[total_catalog_size,catalog_offset,catalog_entries.length].pack("nnC")
- catalog_entries.each do |entry|
- catalog_buffer+=[entry[0][0,TNDP::MAX_VOLUME_NAME_LENGTH],TNDP::SYSTEM_ARCHITECTURES[entry[1]],TNDP::FILESYSTEMS[entry[2]],entry[3],entry[4]].pack("Z#{TNDP::MAX_VOLUME_NAME_LENGTH+1}CCnn")
- end
- super+catalog_buffer
- end
-
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode,total_catalog_size,catalog_offset,catalog_entries_length=buffer.unpack("Z4CnCnnC")
- catalog_entries=[]
- catalog_entries_length.times do |i|
- entry_buffer=buffer[0x0D+(i*(TNDP::MAX_VOLUME_NAME_LENGTH+7)),TNDP::MAX_VOLUME_NAME_LENGTH+7]
- volume_name,system_architecture_id,file_system_id,track_count,sector_size=entry_buffer.unpack("Z#{TNDP::MAX_VOLUME_NAME_LENGTH+1}CCnn")
- system_architecture=TNDP.coalesce(TNDP::SYSTEM_ARCHITECTURES.key_by_value(system_architecture_id),:unknown)
- file_system=TNDP.coalesce(TNDP::FILESYSTEMS.key_by_value(file_system_id),:unknown)
- catalog_entries<<[volume_name,system_architecture,file_system,track_count,sector_size]
- end
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,
- :opcode=>opcode,:total_catalog_size=>total_catalog_size,:catalog_offset=>catalog_offset,:catalog_entries=>catalog_entries})
- end
- end
-
- class SectorReadRequestMessage < BaseMessage
- attr_reader :track_no,:sector_no,:sector_length,:volume_name
- OPCODE=0x02
- def initialize(args={})
- args[:opcode]=OPCODE
- [:track_no,:sector_no,:sector_length,:volume_name].each do |arg|
- raise "#{arg} must be specified in a #{self.class}" if args[arg].nil?
- end
-
- @track_no=args[:track_no]
- @sector_no=args[:sector_no]
- @sector_length=args[:sector_length]
- @volume_name=args[:volume_name]
-
- super(args)
- end
-
- def to_s
- super+"
-VOLUME NAME: #{volume_name}
-TRACK NO: $#{"%04X"%track_no}
-SECTOR NO: $#{"%04X"%sector_no}
-SECTOR LENGTH: $#{"%04x" % sector_length}"
- end
-
- def to_buffer
- super+[track_no,sector_no,sector_length,volume_name[0,MAX_VOLUME_NAME_LENGTH]].pack("nnnZ#{TNDP::MAX_VOLUME_NAME_LENGTH+1}")
- end
-
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode,track_no,sector_no,sector_length,volume_name=buffer.unpack("Z4CnCnnnZ#{TNDP::MAX_VOLUME_NAME_LENGTH+1}")
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,
- :opcode=>opcode,:track_no=>track_no,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>volume_name})
- end
- end
-
- class SectorReadResponseMessage < SectorReadRequestMessage
- OPCODE=0x82
- attr_reader :sector_data
- def initialize(args={})
- raise "sector_data must be specified in a #{self.class}" if args[:sector_data].nil?
- @sector_data=args[:sector_data]
- super(args)
- @opcode=OPCODE
- raise "length of sector_data #{@sector_data.length} must match specified sector_length #{@sector_length}" unless @sector_data.length==@sector_length
- end
- def to_s
- super+"\nSECTOR DATA:\n"+TNDP.hex_dump(sector_data)
- end
-
- def to_buffer
- super+[sector_data].pack("A#{sector_length}")
- end
-
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode,track_no,sector_no,sector_length,volume_name,sector_data=buffer.unpack("Z4CnCnnnZ#{TNDP::MAX_VOLUME_NAME_LENGTH+1}a*")
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,
- :opcode=>opcode,:track_no=>track_no,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>volume_name,:sector_data=>sector_data})
- end
- end
-
- class SectorWriteRequestMessage < SectorReadResponseMessage
- OPCODE=0x03
- def initialize(args={})
- super(args)
- @opcode=OPCODE
- end
- end
-
-
- class SectorWriteResponseMessage < SectorReadRequestMessage
- OPCODE=0x83
- def initialize(args={})
- super(args)
- @opcode=OPCODE
- end
- end
-
-
- class CreateVolumeRequestMessage < BaseMessage
- attr_reader :system_architecture,:volume_name,:track_count,:sector_length
- OPCODE=0x04
- def initialize(args={})
- args[:opcode]=OPCODE if args[:opcode].nil?
- [:system_architecture,:volume_name,:track_count,:sector_length].each do |arg|
- raise "#{arg} must be specified in a #{self.class}" if args[arg].nil?
- end
- @system_architecture=args[:system_architecture]
- @track_count=args[:track_count]
- @sector_length=args[:sector_length]
- @volume_name=args[:volume_name]
-
- super(args)
- end
-
- def to_s
- system_architecture_id=TNDP::SYSTEM_ARCHITECTURES[system_architecture]
-
- super+"
-VOLUME NAME: #{volume_name}
-ARCHITECTURE: #{system_architecture} [$#{"%02X"%system_architecture_id}]
-TRACK COUNT: $#{"%04X"%track_count}
-SECTOR LENGTH: $#{"%04x" % sector_length}"
- end
-
- def to_buffer
- super+[volume_name[0,MAX_VOLUME_NAME_LENGTH],TNDP::SYSTEM_ARCHITECTURES[system_architecture],track_count,sector_length].pack("Z#{TNDP::MAX_VOLUME_NAME_LENGTH+1}Cnn")
- end
-
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode,volume_name,system_architecture_id,track_count,sector_length=buffer.unpack("Z4CnCZ#{TNDP::MAX_VOLUME_NAME_LENGTH+1}Cnn")
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,:opcode=>opcode,:volume_name=>volume_name,
- :system_architecture=>TNDP::SYSTEM_ARCHITECTURES.key_by_value(system_architecture_id), :track_count=>track_count,:sector_length=>sector_length})
- end
- end
-
- class CreateVolumeResponseMessage < CreateVolumeRequestMessage
- OPCODE=0x84
- def initialize(args={})
- args[:opcode]=OPCODE
- super(args)
- end
- end
-
-
- class ErrorResponseMessage < BaseMessage
- OPCODE=0xFF
- attr_reader :errorcode,:error_description,:original_data_elements
- def initialize(args={})
- args[:opcode]=OPCODE
- @errorcode=TNDP.coalesce(args[:errorcode],0xFF)
- @error_description=TNDP.coalesce(args[:error_description],"an error occured")
- @original_data_elements=TNDP.coalesce(args[:original_data_elements],"")
- super(args)
- end
- def self.from_buffer(buffer)
- signature,version_id,transaction_id,opcode,errorcode,error_description,original_data_elements=buffer.unpack("Z4CnCnZ128Z16")
- self.new({:signature=>signature,:version=>version_id,:transaction_id=>transaction_id,
- :opcode=>opcode,:errorcode=>errorcode,:error_description=>error_description,:original_data_elements=>original_data_elements})
- end
-
- def to_s
- super+"
-ERROR CODE: $#{"%02X"%errorcode}
-DESCRIPTION: #{error_description}
-ORIGINAL DATA: #{original_data_elements}
-"
- end
- def to_buffer
- super+[errorcode,error_description,0,original_data_elements].pack("nZ127CZ16")
- end
-
- def self.create_error_response(original_request_buffer,errorcode,error_description)
- transaction_id=original_request_buffer[5,2].unpack("n")[0] #pull direct from data in case "message_from_buffer" was what raised the error
- self.new({:signature=>MESSAGE_SIGNATURE,:version=>VERSION_ID,:transaction_id=>transaction_id,
- :opcode=>OPCODE,:errorcode=>errorcode,:error_description=>error_description,:original_data_elements=>original_request_buffer[0,16]})
- end
- end
-end
diff --git a/server/lib/tndp_server.rb b/server/lib/tndp_server.rb
deleted file mode 100644
index 72ee628..0000000
--- a/server/lib/tndp_server.rb
+++ /dev/null
@@ -1,178 +0,0 @@
-#
-# message formats for Trivial Network Disk Protocol
-#
-$:.unshift(File.dirname(__FILE__)) unless
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-require 'tndp'
-require 'socket'
-require 'LibRipXplore'
-
- SYSTEM_ARCHITECTURE_TRANSLATIONS={
- "Apple2"=>:apple2,
- "C64"=>:c64,
- }
- FILE_SYSTEM_TRANSLATIONS={
- "AppleDos"=>:apple_dos_33,
- "CbmDos"=>:cbm_dos,
- "RawDisk"=>:raw,
- "ProDos"=>:prodos,
- "AppleCPM"=>:cpm,
- }
-
-VOLUME_CREATION_PARAMATERS={
- :apple2=>["0.chr*request.track_count*request.sector_length*16",RawDisk,A2DskPhysicalOrder,256],
- :c64=>["0.chr*((17*21)+(7*19)+(6*18)+((request.track_count-30)*17))*256",RawDisk,D64,256],
-}
-
-class TNDPServer
- LISTENING_PORT=6502
- attr_reader :root_directory,:port ,:server_thread,:socket,:volume_catalog
- def initialize(root_directory,port=LISTENING_PORT)
- @root_directory=root_directory
- @port=port
- end
-
-
- def start
- create_volume_catalog
- @server_thread=Thread.start do
- @socket=UDPSocket.open
- @socket.bind("",port)
- log_msg("serving #{root_directory} on UDP port #{port}")
- loop do
- data,addr_info=@socket.recvfrom(4096)
- client_port=addr_info[1]
- client_ip=addr_info[3]
- log_msg "#{data.length} bytes received from #{client_ip}:#{client_port}"
- begin
- request=TNDP.message_from_buffer(data)
- log_msg(request.to_s)
- case request.opcode
- when TNDP::CapabilitiesRequestMessage::OPCODE
- supported_architectures={}
- volume_catalog.each do |entry|
- supported_architectures[entry[1]]=1+TNDP.coalesce(supported_architectures[entry[1]],0)
- end
- response=TNDP::CapabilitiesResponseMessage.new({:supported_architectures=>supported_architectures})
- when TNDP::VolumeCatalogRequestMessage::OPCODE
- catalog_subset=subset_volume_catalog(request.system_architecture,request.file_system)
- catalog_offset=request.catalog_offset
- catalog_entries=catalog_subset[catalog_offset,TNDP::MAX_CATALOG_ENTRIES_PER_MESSAGE]
- response=TNDP::VolumeCatalogResponseMessage.new({:catalog_entries=>catalog_entries,:catalog_offset=>catalog_offset,:total_catalog_size=>catalog_subset.length})
- when TNDP::SectorReadRequestMessage::OPCODE
- file_system_image=nil
- begin
- file_system_image=RipXplore.best_fit_from_filename("#{@root_directory}/#{request.volume_name}")
- rescue Exception=>e
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_VOLUME_NAME,e.to_s)
- end
- if !(file_system_image.nil?) then
- track_no=request.track_no
- sector_no=request.sector_no
- sector_length=request.sector_length
- if (track_nofile_system_image.end_track) then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_TRACK_NUMBER,"requested track $#{"%X"% track_no} outside allowable range of $#{"%X"% file_system_image.start_track}..$#{"%X"% file_system_image.end_track}")
- else
- sector_data=file_system_image.get_sector(track_no,sector_no)
- if sector_data.nil? then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_SECTOR_NUMBER,"requested sector $#{"%X"% sector_no} not found in track $#{"%X"% track_no}")
- elsif (sector_data.length)!=sector_length then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_SECTOR_LENGTH,"requested track $#{"%X"% track_no}/sector $#{"%X"% sector_no} is of length $#{"%X"% sector_data.length}, not $#{"%X"% sector_length}")
- else
- response=TNDP::SectorReadResponseMessage.new({:track_no=>track_no,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>request.volume_name,:sector_data=>sector_data})
- end
- end
- end
- when TNDP::SectorWriteRequestMessage::OPCODE
- file_system_image=nil
- begin
- file_system_image_path="#{@root_directory}/#{request.volume_name}"
- file_system_image=RipXplore.best_fit_from_filename(file_system_image_path)
- rescue Exception=>e
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_VOLUME_NAME,e.to_s)
- end
- if !(file_system_image.nil?) then
- track_no=request.track_no
- sector_no=request.sector_no
- sector_length=request.sector_length
- sector_data=request.sector_data
- if (track_nofile_system_image.end_track) then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_TRACK_NUMBER,"requested track $#{"%X"% track_no} outside allowable range of $#{"%X"% file_system_image.start_track}..$#{"%X"% file_system_image.end_track}")
- else
- existing_sector_data=file_system_image.get_sector(track_no,sector_no)
- if existing_sector_data.nil? then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_SECTOR_NUMBER,"requested sector $#{"%X"% sector_no} not found in track $#{"%X"% track_no}")
- elsif (existing_sector_data.length)!=sector_length then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_SECTOR_LENGTH,"requested track $#{"%X"% track_no}/sector $#{"%X"% sector_no} is of length $#{"%X"% sector_data.length}, not $#{"%X"% sector_length}")
- else
- file_system_image.set_sector(track_no,sector_no,sector_data)
- file_system_image.save_as(file_system_image_path)
- response=TNDP::SectorWriteResponseMessage.new({:track_no=>track_no,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>request.volume_name})
- end
- end
- end
- when TNDP::CreateVolumeRequestMessage::OPCODE
- volume_file="#{@root_directory}/#{request.volume_name}"
- volume_creation_paramaters=VOLUME_CREATION_PARAMATERS[request.system_architecture]
- if volume_creation_paramaters.nil? then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::ARCHITECTURE_NOT_SUPPORTED,"create volume requests for #{request.system_architecture} not supported")
- elsif request.sector_length!=volume_creation_paramaters[3] then
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INVALID_SECTOR_LENGTH,"create volume requests for #{request.system_architecture} should have sector length #{volume_creation_paramaters[3]}")
-
- else
- file_bytes=eval(volume_creation_paramaters[0],binding)
- volume=FileSystemImage.new(file_bytes,volume_creation_paramaters[1],volume_creation_paramaters[2],volume_file)
- volume.save_as(volume_file)
- response=TNDP::CreateVolumeResponseMessage.new({:volume_name=>request.volume_name,:system_architecture=>request.system_architecture,:track_count=>request.track_count,:sector_length=>request.sector_length} )
- end
- else
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::UNKNOWN_OPCODE,"unknown opcode $#{"%02X" % request.opcode}")
- end
- response.transaction_id=request.transaction_id
- rescue Exception=>e
- response=TNDP::ErrorResponseMessage.create_error_response(data,TNDP::ErrorCodes::INTERNAL_SERVER_ERROR,e.to_s+e.backtrace[0])
- end
- log_msg("Response:")
- log_msg(response.to_s)
- @socket.send(response.to_buffer,0,client_ip,client_port)
- end
- end
- end
-
- def shutdown
- log_msg("TNDP server on UDP port #{port} shutting down")
- @server_thread.kill
- end
-
- #return a subset of the total volume catalog that includes just the entries that match the passed in system architecture & file system
- def subset_volume_catalog(system_architecture,file_system)
-# return volume_catalog
- vc=[]
- volume_catalog.each do |entry|
- vc<e
- #don't stop if anything throws an exception
- log_msg("ERROR: parsing of #{filename} failed:\n"+e.to_s)
- end
- end
- end
- end
-
-end
\ No newline at end of file
diff --git a/server/test/tc_file_list.rb b/server/test/tc_file_list.rb
deleted file mode 100644
index f586fe5..0000000
--- a/server/test/tc_file_list.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib")
-$:.unshift(lib_path) unless $:.include?(lib_path)
-
-require 'test/unit'
-require 'file_list'
-
-
-BOOT_DIR=File.expand_path(File.dirname(__FILE__)+'/../boot')
-
-def log_msg(msg)
- puts msg
-end
-
-class TestFileList 0,"file list for $*.prg should not be empty")
- assert(prg_file_list=~/\000\000$/,"$*.prg file list should end in two zeros")
- assert(prg_file_list=~/\.prg/i,"$*.prg file list should contain at least one .prg file")
- assert(!(prg_file_list=~/.pg2/i),"$*.prg file list should contain no .pg2 files")
- assert(prg_file_list=~/\$\/subdir/i,"$*.prg file list should contain subdirectory")
-
- pg2_file_list=file_list["$/*.pg2"]
- assert(pg2_file_list.length>0,"file list for $*.pg2 should not be empty")
- assert(pg2_file_list=~/\000\000$/,"$*.pg2 file list should end in two zeros")
- assert(pg2_file_list=~/\.pg2/i,"$*.pg2 file list should contain at least one .pg2 file")
- assert(!(pg2_file_list=~/.prg/i),"$*.pg2 file list should contain at no .prg files")
-
-
- puts "PG2 list"
- puts pg2_file_list.split(0.chr).join("\n")
-
- subdir_file_list=file_list["$/subdir/*.prg"]
- puts "SUBDIR list"
- puts subdir_file_list.split(0.chr).join("\n")
-
- assert(subdir_file_list.length>0,"file list for $/subdir/*.prg should not be empty")
- assert(subdir_file_list=~/\000\000$/,"$/subdir/*.prg file list should end in two zeros")
- assert(subdir_file_list=~/\.prg/i,"$/subdir/*.prg file list should contain at least one .prg file")
- assert(!(subdir_file_list=~/.pg2/i),"$/subdir/*.prg file list should contain no .pg2 files")
-
-
- empty_subdir_file_list=file_list["$/subdir/empty/*.prg"]
- puts "EMPTY SUBDIR list"
- puts empty_subdir_file_list.split(0.chr).join("\n")
-# assert_equal(2,empty_subdir_file_list.length,"file list for $/subdir/empty/*.prg should be empty")
-
- filemask="$/subdir/another_subdir/*.pg2"
- multiple_subdir_file_list=file_list[filemask]
- puts "MULTIPLE SUBDIR list"
- puts multiple_subdir_file_list.split(0.chr).join("\n")
-
- assert(multiple_subdir_file_list.length>2,"file list for #{filemask} should not be empty")
- assert(multiple_subdir_file_list=~/\.pg2/i,"#{filemask} file list should contain at least one .prg file")
- assert_equal("/",multiple_subdir_file_list.split(0.chr)[0],"first entry file list for #{filemask} should be /")
- assert_equal("/subdir",multiple_subdir_file_list.split(0.chr)[1],"first entry file list for #{filemask} should be /subdir")
-
-# puts file_list["$*.prg"]
-# puts file_list["$/subdir/*.prg"]
- end
-end
\ No newline at end of file
diff --git a/server/test/tc_test_message_formats.rb b/server/test/tc_test_message_formats.rb
deleted file mode 100644
index c0930dc..0000000
--- a/server/test/tc_test_message_formats.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib")
-$:.unshift(lib_path) unless $:.include?(lib_path)
-
-require 'test/unit'
-require 'tndp'
-
-class TestMessageFormats 0,"should be at least 1 apple2 image")
- assert(capabilities_response_msg.supported_architectures[:c64]>0,"should be at least 1 C64 image")
- [
- [:apple2,'SCRATCH_TEST.DSK',35,256],
- [:apple2,'SCRATCH_TEST2.DO',40,256],
- [:c64,'SCRATCH_TEST.D64',35,256],
- [:c64,'SCRATCH_TEST2.D64',40,256],
- ].each do |a|
- #try to make a new blank disk
- system_architecture=a[0]
- volume_name=a[1]
- track_count=a[2]
- sector_length=a[3]
- image_full_path="#{TEST_IMAGES_DIR}\\#{volume_name}"
- File.delete(image_full_path) if File.exist?(image_full_path)
- create_volume_request_msg=TNDP::CreateVolumeRequestMessage.new({:volume_name=>volume_name,:system_architecture=>system_architecture,:track_count=>track_count,:sector_length=>sector_length})
- create_volume_response_msg=send_request_and_get_response(create_volume_request_msg)
- assert_equal(TNDP::CreateVolumeResponseMessage::OPCODE,create_volume_response_msg.opcode,"init volume response message should have correct opcode")
- assert_equal(system_architecture,create_volume_response_msg.system_architecture)
- assert(File.exist?(image_full_path),"file just created should exist at #{image_full_path}")
- sector_data=([system_architecture.to_s,volume_name,track_count,sector_length].pack("Z12Z30CC")*200)[0,sector_length]
- track_no=track_count-1
- sector_no=1
- sector_write_request_msg=TNDP::SectorWriteRequestMessage.new({:track_no=>track_no,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>volume_name,:sector_data=>sector_data})
- sector_write_response_msg=send_request_and_get_response(sector_write_request_msg)
- assert_equal(TNDP::SectorWriteResponseMessage::OPCODE,sector_write_response_msg.opcode,"sector write response message should have correct opcode")
-
- file_system_image=RipXplore.best_fit_from_filename(image_full_path)
- assert_equal(track_count,file_system_image.track_count,"file just created should have correct number of tracks")
- assert_equal(sector_data,file_system_image.get_sector(track_no,sector_no),"file just created should have sector data set correctly")
-
- end
- raise "done"
- #test every combination of host and file system
- [[:apple2,:apple_dos_33],[:apple2,:prodos],[:apple2,:any],[:c64,:cbm_dos],[:any,:any],[:any,:prodos]].each do |a|
- desired_system_architecture=a[0]
- desired_file_system=a[1]
- log_msg ("TESTING CATALOG FOR ARCHITECTURE #{desired_system_architecture} / FILE SYSTEM #{desired_file_system}")
-
- done=false
- catalog_offset=0
- while !done do
- volume_catalog_request_msg=TNDP::VolumeCatalogRequestMessage.new({:system_architecture=>desired_system_architecture,:file_system=>desired_file_system,:catalog_offset=>catalog_offset})
- assert_equal(desired_system_architecture,volume_catalog_request_msg.system_architecture)
- assert_equal(desired_file_system,volume_catalog_request_msg.file_system)
- volume_catalog_response_msg=send_request_and_get_response(volume_catalog_request_msg)
- assert(volume_catalog_response_msg.respond_to?(:catalog_entries),"volume catalogue response message should include list of volumes on server")
- assert(volume_catalog_response_msg.catalog_entries.length>0,"volume catalogue response message should have at least 1 entry")
- entry_count=0
- volume_catalog_response_msg.catalog_entries.each do |entry|
- assert_equal(desired_system_architecture,entry[1],"each entry should be for specified architecture") unless desired_system_architecture==:any
- assert_equal(desired_file_system,entry[2],"each entry should be for specified file system") unless desired_file_system==:any
- volume_name=entry[0]
- track_no=entry[3]-1 #last track
- sector_no=1
- sector_length=entry[4]
- if entry_count==0 then #do these tests only once for each combination of architecture/file system
- assert_equal(TNDP::ErrorCodes::INVALID_VOLUME_NAME,send_request_and_get_response(TNDP::SectorReadRequestMessage.new({:track_no=>track_no,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>"invalid file name"})).errorcode,"invalid volume name should return error")
- assert_equal(TNDP::ErrorCodes::INVALID_TRACK_NUMBER,send_request_and_get_response(TNDP::SectorReadRequestMessage.new({:track_no=>0xDEAD,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>volume_name})).errorcode,"invalid track number should return error")
- assert_equal(TNDP::ErrorCodes::INVALID_SECTOR_NUMBER,send_request_and_get_response(TNDP::SectorReadRequestMessage.new({:track_no=>track_no,:sector_no=>0xBEEF,:sector_length=>sector_length,:volume_name=>volume_name})).errorcode,"invalid sector number should return error")
- assert_equal(TNDP::ErrorCodes::INVALID_SECTOR_LENGTH,send_request_and_get_response(TNDP::SectorReadRequestMessage.new({:track_no=>track_no,:sector_no=>sector_no,:sector_length=>0xD00D,:volume_name=>volume_name})).errorcode,"invalid sector length should return error")
- end
- file_system_image=RipXplore.best_fit_from_filename("#{TEST_IMAGES_DIR}/#{volume_name}")
- assert_equal(sector_length,file_system_image.get_sector(track_no,sector_no).length,"sector as read from disk should be of correct length")
- sector_read_request_msg=TNDP::SectorReadRequestMessage.new({:track_no=>track_no,:sector_no=>sector_no,:sector_length=>sector_length,:volume_name=>volume_name})
- sector_read_response_msg=send_request_and_get_response(sector_read_request_msg)
-
- assert(sector_read_response_msg.respond_to?(:sector_data),"sector read response message should include sector data")
- assert_equal(sector_length,sector_read_response_msg.sector_data.length,"sector read response message should include full length sector")
- assert_equal(TNDP.hex_dump(file_system_image.get_sector(track_no,sector_no)),TNDP.hex_dump(sector_read_response_msg.sector_data),"data returned from server should match data read directly from disk")
- entry_count+=1
- end
- catalog_offset+=volume_catalog_response_msg.catalog_entries.length
- done=(catalog_offset>volume_catalog_response_msg.total_catalog_size-1)
- end
- end
- server.shutdown
- end
-
-end
\ No newline at end of file
diff --git a/server/test/ts_test_all.rb b/server/test/ts_test_all.rb
deleted file mode 100644
index 3e57a4b..0000000
--- a/server/test/ts_test_all.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-$:.unshift(File.dirname(__FILE__)) unless
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-
-def log_msg(msg)
- puts msg
-end
-
-Dir.glob("tc_*.rb").each do |tc|
- require tc
-end
\ No newline at end of file
diff --git a/client/test/Makefile b/test/Makefile
similarity index 100%
rename from client/test/Makefile
rename to test/Makefile
diff --git a/client/test/test_cart_api.s b/test/test_cart_api.s
similarity index 94%
rename from client/test/test_cart_api.s
rename to test/test_cart_api.s
index 9c3d618..598f605 100644
--- a/client/test/test_cart_api.s
+++ b/test/test_cart_api.s
@@ -1,441 +1,441 @@
-;test the "Kipper Kartridge API"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../ip65/copymem.s"
-
-; load A/X macro
- .macro ldax arg
- .if (.match (.left (1, arg), #)) ; immediate mode
- lda #<(.right (.tcount (arg)-1, arg))
- ldx #>(.right (.tcount (arg)-1, arg))
- .else ; assume absolute or zero page
- lda arg
- ldx 1+(arg)
- .endif
- .endmacro
-
-; store A/X macro
-.macro stax arg
- sta arg
- stx 1+(arg)
-.endmacro
-
-print_a = $ffd2
-
-.macro cout arg
- lda arg
- jsr print_a
-.endmacro
-
- .zeropage
- temp_ptr: .res 2
-
- .bss
- kipper_param_buffer: .res $20
- block_number: .res $0
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-.macro print arg
- ldax arg
- ldy #KPR_PRINT_ASCIIZ
- jsr KPR_DISPATCH_VECTOR
-.endmacro
-
-.macro print_cr
- lda #13
- jsr print_a
-.endmacro
-
-.macro call arg
- ldy arg
- jsr KPR_DISPATCH_VECTOR
-.endmacro
-
-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
-
-
-;look for KIPPER signature at location pointed at by AX
-look_for_signature:
- stax temp_ptr
- ldy #5
-@check_one_byte:
- lda (temp_ptr),y
- cmp kipper_signature,y
- bne @bad_match
- dey
- bpl@check_one_byte
- clc
- rts
-@bad_match:
- sec
- rts
-
-init:
-
-
- ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge
- jsr look_for_signature
- bcc @found_kipper_signature
- jmp kipper_signature_not_found
-
-@found_kipper_signature:
-
- print #initializing
-
- ldy #KPR_INITIALIZE
- jsr KPR_DISPATCH_VECTOR
- bcc :+
- print #failed
- jsr print_errorcode
- jmp bad_boot
-:
-
- print #ok
- print_cr
-
- call #KPR_PRINT_IP_CONFIG
-
-;DNS resolution test
-
- ldax #test_hostname
- stax kipper_param_buffer+KPR_DNS_HOSTNAME
-
- call #KPR_PRINT_ASCIIZ
-
- cout #' '
- cout #':'
- cout #' '
-
- ldax #kipper_param_buffer
- call #KPR_DNS_RESOLVE
- bcc :+
- print #dns_lookup_failed_msg
- print_cr
- jmp print_errorcode
-:
- ldax #kipper_param_buffer+KPR_DNS_HOSTNAME_IP
- call #KPR_PRINT_DOTTED_QUAD
- print_cr
-
- ldax #64
- call #KPR_UDP_REMOVE_LISTENER ;should generate an error since there is no listener on port 64
- jsr print_errorcode
-
-
-;tftp send test
- lda #0
- sta block_number
- ldax #test_file
- stax kipper_param_buffer+KPR_TFTP_FILENAME
- ldax #tftp_upload_callback
- stax kipper_param_buffer+KPR_TFTP_POINTER
- ldax #kipper_param_buffer
- call #KPR_TFTP_CALLBACK_UPLOAD
- bcc :+
- jmp print_errorcode
-:
-
-
-@download_test:
-;tftp download callback test
- lda #0
- sta block_number
- ldax #test_file
- stax kipper_param_buffer+KPR_TFTP_FILENAME
- ldax #tftp_download_callback
- stax kipper_param_buffer+KPR_TFTP_POINTER
- ldax #kipper_param_buffer
- call #KPR_TFTP_CALLBACK_DOWNLOAD
- bcc :+
- jmp print_errorcode
-:
- lda #'$'
- jsr print_a
- lda kipper_param_buffer+KPR_TFTP_FILESIZE+1
- jsr print_hex
- lda kipper_param_buffer+KPR_TFTP_FILESIZE
- jsr print_hex
- print #bytes_download
- print_cr
-
-;udp callback test
-
- ldax #64 ;listen on port 64
- stax kipper_param_buffer+KPR_UDP_LISTENER_PORT
- ldax #udp_callback
- stax kipper_param_buffer+KPR_UDP_LISTENER_CALLBACK
- ldax #kipper_param_buffer
- call #KPR_UDP_ADD_LISTENER
- bcc :+
- print #failed
- jsr print_errorcode
- jmp bad_boot
-:
-
- print #listening
-
-
-@loop_forever:
- jsr KPR_PERIODIC_PROCESSING_VECTOR
- jmp @loop_forever
-
-
-tftp_upload_callback:
- stax copy_dest
- inc block_number
- print #sending
- print #block_no
- lda block_number
- jsr print_hex
- print_cr
-
- lda block_number
- asl
- cmp #$10
- beq @last_block
- clc
- adc #$a0
- tax
- lda #0
- stax copy_src
- ldax #$200
- jsr copymem
- ldax #$200
- rts
-@last_block:
- ldax #0
- rts
-
-tftp_download_callback:
- inc block_number
- print #received
- print #block_no
- lda block_number
- jsr print_hex
- print_cr
- rts
-
-udp_callback:
-
- ldax #kipper_param_buffer
- call #KPR_GET_INPUT_PACKET_INFO
-
- print #port
-
- lda kipper_param_buffer+KPR_LOCAL_PORT+1
- call #KPR_PRINT_HEX
-
- lda kipper_param_buffer+KPR_LOCAL_PORT
- call #KPR_PRINT_HEX
-
- print_cr
-
- print #received
- print #from
-
- ldax #kipper_param_buffer+KPR_REMOTE_IP
- call #KPR_PRINT_DOTTED_QUAD
-
- cout #' '
-
- print #port
-
- lda kipper_param_buffer+KPR_REMOTE_PORT+1
- call #KPR_PRINT_HEX
- lda kipper_param_buffer+KPR_REMOTE_PORT
- call #KPR_PRINT_HEX
-
- print_cr
-
- print #length
-
- lda kipper_param_buffer+KPR_PAYLOAD_LENGTH+1
- call #KPR_PRINT_HEX
- lda kipper_param_buffer+KPR_PAYLOAD_LENGTH
- call #KPR_PRINT_HEX
- print_cr
- print #data
-
- ldax kipper_param_buffer+KPR_PAYLOAD_POINTER
-
- stax temp_ptr
- ldx kipper_param_buffer+KPR_PAYLOAD_LENGTH ;assumes length is < 255
- ldy #0
-:
- lda (temp_ptr),y
- jsr print_a
- iny
- dex
- bpl :-
-
- print_cr
-
-;make and send reply
- ldax #reply_message
- stax kipper_param_buffer+KPR_PAYLOAD_POINTER
-
- ldax #reply_message_length
- stax kipper_param_buffer+KPR_PAYLOAD_LENGTH
-
- ldax #kipper_param_buffer
- call #KPR_SEND_UDP_PACKET
- bcc :+
- jmp print_errorcode
-:
- print #reply_sent
- rts
-
-bad_boot:
- print #press_a_key_to_continue
-restart:
- jsr get_key
- jmp $fce2 ;do a cold start
-
-
-print_errorcode:
- print #error_code
- call #KPR_GET_LAST_ERROR
- call #KPR_PRINT_HEX
- print_cr
- rts
-
-kipper_signature_not_found:
-
- ldy #0
-:
- lda kipper_signature_not_found_message,y
- beq restart
- jsr print_a
- iny
- jmp :-
-
-
-;use C64 Kernel ROM function to read a key
-;inputs: none
-;outputs: A contains ASCII value of key just pressed
-get_key:
- jsr $ffe4
- cmp #0
- beq get_key
- rts
-
- print_hex:
- pha
- pha
- lsr
- lsr
- lsr
- lsr
- tax
- lda hexdigits,x
- jsr print_a
- pla
- and #$0F
- tax
- lda hexdigits,x
- jsr print_a
- pla
- rts
-
-.rodata
-hexdigits:
-.byte "0123456789ABCDEF"
-
-test_hostname:
- .byte "RETROHACKERS.COM",0 ;this should be an A record
-
- received:
- .asciiz "RECEIVED "
- sending:
- .asciiz "SENDING "
- from:
- .asciiz " FROM: "
-
-listening:
- .byte "LISTENING ON UDP PORT 64",13,0
-
-
-reply_sent:
- .byte "REPLY SENT.",13,0
-
-
-initializing:
- .byte "INITIALIZING ",0
-
-port:
- .byte "PORT: $",0
-
-length:
- .byte "LENGTH: $",0
-
-data:
- .byte "DATA: ",0
-
-block_no:
- .byte "BLOCK: $",0
-
-error_code:
- .asciiz "ERROR CODE: $"
-press_a_key_to_continue:
- .byte "PRESS A KEY TO CONTINUE",13,0
-
-failed:
- .byte "FAILED ", 0
-
-ok:
- .byte "OK ", 0
-
- kipper_signature_not_found_message:
- .byte "NO KIPPER API FOUND",13,"PRESS ANY KEY TO RESET", 0
-
-dns_lookup_failed_msg:
- .byte "DNS LOOKUP FAILED", 0
-
-bytes_download: .byte "BYTES DOWNLOADED",13,0
-
-reply_message:
- .byte "PONG!"
-reply_message_end:
-reply_message_length=reply_message_end-reply_message
-
-test_file:
-.byte "TESTFILE.BIN",0
-
-kipper_signature:
- .byte "KIPPER" ; API signature
-
-
-;-- LICENSE FOR test_cart_api.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 --
+;test the "Kipper Kartridge API"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../ip65/copymem.s"
+
+; load A/X macro
+ .macro ldax arg
+ .if (.match (.left (1, arg), #)) ; immediate mode
+ lda #<(.right (.tcount (arg)-1, arg))
+ ldx #>(.right (.tcount (arg)-1, arg))
+ .else ; assume absolute or zero page
+ lda arg
+ ldx 1+(arg)
+ .endif
+ .endmacro
+
+; store A/X macro
+.macro stax arg
+ sta arg
+ stx 1+(arg)
+.endmacro
+
+print_a = $ffd2
+
+.macro cout arg
+ lda arg
+ jsr print_a
+.endmacro
+
+ .zeropage
+ temp_ptr: .res 2
+
+ .bss
+ kipper_param_buffer: .res $20
+ block_number: .res $0
+
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+.macro print arg
+ ldax arg
+ ldy #KPR_PRINT_ASCIIZ
+ jsr KPR_DISPATCH_VECTOR
+.endmacro
+
+.macro print_cr
+ lda #13
+ jsr print_a
+.endmacro
+
+.macro call arg
+ ldy arg
+ jsr KPR_DISPATCH_VECTOR
+.endmacro
+
+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
+
+
+;look for KIPPER signature at location pointed at by AX
+look_for_signature:
+ stax temp_ptr
+ ldy #5
+@check_one_byte:
+ lda (temp_ptr),y
+ cmp kipper_signature,y
+ bne @bad_match
+ dey
+ bpl@check_one_byte
+ clc
+ rts
+@bad_match:
+ sec
+ rts
+
+init:
+
+
+ ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge
+ jsr look_for_signature
+ bcc @found_kipper_signature
+ jmp kipper_signature_not_found
+
+@found_kipper_signature:
+
+ print #initializing
+
+ ldy #KPR_INITIALIZE
+ jsr KPR_DISPATCH_VECTOR
+ bcc :+
+ print #failed
+ jsr print_errorcode
+ jmp bad_boot
+:
+
+ print #ok
+ print_cr
+
+ call #KPR_PRINT_IP_CONFIG
+
+;DNS resolution test
+
+ ldax #test_hostname
+ stax kipper_param_buffer+KPR_DNS_HOSTNAME
+
+ call #KPR_PRINT_ASCIIZ
+
+ cout #' '
+ cout #':'
+ cout #' '
+
+ ldax #kipper_param_buffer
+ call #KPR_DNS_RESOLVE
+ bcc :+
+ print #dns_lookup_failed_msg
+ print_cr
+ jmp print_errorcode
+:
+ ldax #kipper_param_buffer+KPR_DNS_HOSTNAME_IP
+ call #KPR_PRINT_DOTTED_QUAD
+ print_cr
+
+ ldax #64
+ call #KPR_UDP_REMOVE_LISTENER ;should generate an error since there is no listener on port 64
+ jsr print_errorcode
+
+
+;tftp send test
+ lda #0
+ sta block_number
+ ldax #test_file
+ stax kipper_param_buffer+KPR_TFTP_FILENAME
+ ldax #tftp_upload_callback
+ stax kipper_param_buffer+KPR_TFTP_POINTER
+ ldax #kipper_param_buffer
+ call #KPR_TFTP_CALLBACK_UPLOAD
+ bcc :+
+ jmp print_errorcode
+:
+
+
+@download_test:
+;tftp download callback test
+ lda #0
+ sta block_number
+ ldax #test_file
+ stax kipper_param_buffer+KPR_TFTP_FILENAME
+ ldax #tftp_download_callback
+ stax kipper_param_buffer+KPR_TFTP_POINTER
+ ldax #kipper_param_buffer
+ call #KPR_TFTP_CALLBACK_DOWNLOAD
+ bcc :+
+ jmp print_errorcode
+:
+ lda #'$'
+ jsr print_a
+ lda kipper_param_buffer+KPR_TFTP_FILESIZE+1
+ jsr print_hex
+ lda kipper_param_buffer+KPR_TFTP_FILESIZE
+ jsr print_hex
+ print #bytes_download
+ print_cr
+
+;udp callback test
+
+ ldax #64 ;listen on port 64
+ stax kipper_param_buffer+KPR_UDP_LISTENER_PORT
+ ldax #udp_callback
+ stax kipper_param_buffer+KPR_UDP_LISTENER_CALLBACK
+ ldax #kipper_param_buffer
+ call #KPR_UDP_ADD_LISTENER
+ bcc :+
+ print #failed
+ jsr print_errorcode
+ jmp bad_boot
+:
+
+ print #listening
+
+
+@loop_forever:
+ jsr KPR_PERIODIC_PROCESSING_VECTOR
+ jmp @loop_forever
+
+
+tftp_upload_callback:
+ stax copy_dest
+ inc block_number
+ print #sending
+ print #block_no
+ lda block_number
+ jsr print_hex
+ print_cr
+
+ lda block_number
+ asl
+ cmp #$10
+ beq @last_block
+ clc
+ adc #$a0
+ tax
+ lda #0
+ stax copy_src
+ ldax #$200
+ jsr copymem
+ ldax #$200
+ rts
+@last_block:
+ ldax #0
+ rts
+
+tftp_download_callback:
+ inc block_number
+ print #received
+ print #block_no
+ lda block_number
+ jsr print_hex
+ print_cr
+ rts
+
+udp_callback:
+
+ ldax #kipper_param_buffer
+ call #KPR_GET_INPUT_PACKET_INFO
+
+ print #port
+
+ lda kipper_param_buffer+KPR_LOCAL_PORT+1
+ call #KPR_PRINT_HEX
+
+ lda kipper_param_buffer+KPR_LOCAL_PORT
+ call #KPR_PRINT_HEX
+
+ print_cr
+
+ print #received
+ print #from
+
+ ldax #kipper_param_buffer+KPR_REMOTE_IP
+ call #KPR_PRINT_DOTTED_QUAD
+
+ cout #' '
+
+ print #port
+
+ lda kipper_param_buffer+KPR_REMOTE_PORT+1
+ call #KPR_PRINT_HEX
+ lda kipper_param_buffer+KPR_REMOTE_PORT
+ call #KPR_PRINT_HEX
+
+ print_cr
+
+ print #length
+
+ lda kipper_param_buffer+KPR_PAYLOAD_LENGTH+1
+ call #KPR_PRINT_HEX
+ lda kipper_param_buffer+KPR_PAYLOAD_LENGTH
+ call #KPR_PRINT_HEX
+ print_cr
+ print #data
+
+ ldax kipper_param_buffer+KPR_PAYLOAD_POINTER
+
+ stax temp_ptr
+ ldx kipper_param_buffer+KPR_PAYLOAD_LENGTH ;assumes length is < 255
+ ldy #0
+:
+ lda (temp_ptr),y
+ jsr print_a
+ iny
+ dex
+ bpl :-
+
+ print_cr
+
+;make and send reply
+ ldax #reply_message
+ stax kipper_param_buffer+KPR_PAYLOAD_POINTER
+
+ ldax #reply_message_length
+ stax kipper_param_buffer+KPR_PAYLOAD_LENGTH
+
+ ldax #kipper_param_buffer
+ call #KPR_SEND_UDP_PACKET
+ bcc :+
+ jmp print_errorcode
+:
+ print #reply_sent
+ rts
+
+bad_boot:
+ print #press_a_key_to_continue
+restart:
+ jsr get_key
+ jmp $fce2 ;do a cold start
+
+
+print_errorcode:
+ print #error_code
+ call #KPR_GET_LAST_ERROR
+ call #KPR_PRINT_HEX
+ print_cr
+ rts
+
+kipper_signature_not_found:
+
+ ldy #0
+:
+ lda kipper_signature_not_found_message,y
+ beq restart
+ jsr print_a
+ iny
+ jmp :-
+
+
+;use C64 Kernel ROM function to read a key
+;inputs: none
+;outputs: A contains ASCII value of key just pressed
+get_key:
+ jsr $ffe4
+ cmp #0
+ beq get_key
+ rts
+
+ print_hex:
+ pha
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ tax
+ lda hexdigits,x
+ jsr print_a
+ pla
+ and #$0F
+ tax
+ lda hexdigits,x
+ jsr print_a
+ pla
+ rts
+
+.rodata
+hexdigits:
+.byte "0123456789ABCDEF"
+
+test_hostname:
+ .byte "RETROHACKERS.COM",0 ;this should be an A record
+
+ received:
+ .asciiz "RECEIVED "
+ sending:
+ .asciiz "SENDING "
+ from:
+ .asciiz " FROM: "
+
+listening:
+ .byte "LISTENING ON UDP PORT 64",13,0
+
+
+reply_sent:
+ .byte "REPLY SENT.",13,0
+
+
+initializing:
+ .byte "INITIALIZING ",0
+
+port:
+ .byte "PORT: $",0
+
+length:
+ .byte "LENGTH: $",0
+
+data:
+ .byte "DATA: ",0
+
+block_no:
+ .byte "BLOCK: $",0
+
+error_code:
+ .asciiz "ERROR CODE: $"
+press_a_key_to_continue:
+ .byte "PRESS A KEY TO CONTINUE",13,0
+
+failed:
+ .byte "FAILED ", 0
+
+ok:
+ .byte "OK ", 0
+
+ kipper_signature_not_found_message:
+ .byte "NO KIPPER API FOUND",13,"PRESS ANY KEY TO RESET", 0
+
+dns_lookup_failed_msg:
+ .byte "DNS LOOKUP FAILED", 0
+
+bytes_download: .byte "BYTES DOWNLOADED",13,0
+
+reply_message:
+ .byte "PONG!"
+reply_message_end:
+reply_message_length=reply_message_end-reply_message
+
+test_file:
+.byte "TESTFILE.BIN",0
+
+kipper_signature:
+ .byte "KIPPER" ; API signature
+
+
+;-- LICENSE FOR test_cart_api.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_cifs.s b/test/test_cifs.s
similarity index 95%
rename from client/test/test_cifs.s
rename to test/test_cifs.s
index a42d136..350a703 100644
--- a/client/test/test_cifs.s
+++ b/test/test_cifs.s
@@ -1,140 +1,140 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
- .import exit_to_basic
-
- .import cfg_get_configuration_ptr
- .import cifs_l1_encode
- .import cifs_l1_decode
- .import cifs_start
-
- .import __CODE_LOAD__
- .import __CODE_SIZE__
- .import __RODATA_SIZE__
- .import __DATA_SIZE__
- .import __IP65_DEFAULTS_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__+__IP65_DEFAULTS_SIZE__+4 ; Size
- jmp init
-
-.code
-
-init:
- lda #$0E ;change to lower case
- jsr print_a
- jsr print_cr
- init_ip_via_dhcp
-
-; jsr ip65_init
-
- ldx #3
-:
- lda static_ip,x
- sta cfg_ip,x
- dex
- bpl :-
-
- jsr print_ip_config
-
- ldax #hostname_1
- jsr do_encoding_test
-
- ldax #hostname_2
- jsr do_encoding_test
-
- ldax #hostname_3
- jsr do_encoding_test
-
- ldax #cifs_hostname
- jsr cifs_start
- jmp exit_to_basic
-
-
-do_encoding_test:
- stax hostname_ptr
- jsr print
- lda #' '
- jsr print_a
- lda #':'
- jsr print_a
- lda #' '
- jsr print_a
- ldax hostname_ptr
- jsr cifs_l1_encode
- stax hostname_ptr
- jsr print
- jsr print_cr
- ldax hostname_ptr
- jsr cifs_l1_decode
- jsr print
- jsr print_cr
- rts
-
-
-
- .rodata
-
-
-hostname_ptr: .res 2
-hostname_1:
- .byte "Neko",0 ;this should be an A record
-
-hostname_2:
- .byte "NEKO",0 ;this should be a CNAME
-
-hostname_3:
- .byte "HOSTNAMEWITHLOTSOFCHARSINNAME",0 ;this should be another CNAME
-
-cifs_hostname:
- .byte "KIPPERCIFS",0
-
-static_ip:
- .byte 10,5,1,64
-sample_msg:
-.byte $ff, $ff, $ff, $ff, $ff, $ff, $f8, $1e, $df, $dc, $47, $a1, $08, $00, $45, $00
-.byte $00, $4e, $9e, $cf, $00, $00, $40, $11, $c4, $c5, $0a, $05, $01, $02, $0a, $05
-.byte $01, $ff, $fe, $66, $00, $89, $00, $3a, $86, $0a, $00, $02, $01, $10, $00, $01
-.byte $00, $00, $00, $00, $00, $00, $20, $45, $48, $45, $50, $45, $50, $45, $43, $45
-.byte $46, $46, $43, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43
-.byte $41, $43, $41, $43, $41, $43, $41, $00, $00, $20, $00, $01
-
-
-
-;-- LICENSE FOR testdns.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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+ .import exit_to_basic
+
+ .import cfg_get_configuration_ptr
+ .import cifs_l1_encode
+ .import cifs_l1_decode
+ .import cifs_start
+
+ .import __CODE_LOAD__
+ .import __CODE_SIZE__
+ .import __RODATA_SIZE__
+ .import __DATA_SIZE__
+ .import __IP65_DEFAULTS_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__+__IP65_DEFAULTS_SIZE__+4 ; Size
+ jmp init
+
+.code
+
+init:
+ lda #$0E ;change to lower case
+ jsr print_a
+ jsr print_cr
+ init_ip_via_dhcp
+
+; jsr ip65_init
+
+ ldx #3
+:
+ lda static_ip,x
+ sta cfg_ip,x
+ dex
+ bpl :-
+
+ jsr print_ip_config
+
+ ldax #hostname_1
+ jsr do_encoding_test
+
+ ldax #hostname_2
+ jsr do_encoding_test
+
+ ldax #hostname_3
+ jsr do_encoding_test
+
+ ldax #cifs_hostname
+ jsr cifs_start
+ jmp exit_to_basic
+
+
+do_encoding_test:
+ stax hostname_ptr
+ jsr print
+ lda #' '
+ jsr print_a
+ lda #':'
+ jsr print_a
+ lda #' '
+ jsr print_a
+ ldax hostname_ptr
+ jsr cifs_l1_encode
+ stax hostname_ptr
+ jsr print
+ jsr print_cr
+ ldax hostname_ptr
+ jsr cifs_l1_decode
+ jsr print
+ jsr print_cr
+ rts
+
+
+
+ .rodata
+
+
+hostname_ptr: .res 2
+hostname_1:
+ .byte "Neko",0 ;this should be an A record
+
+hostname_2:
+ .byte "NEKO",0 ;this should be a CNAME
+
+hostname_3:
+ .byte "HOSTNAMEWITHLOTSOFCHARSINNAME",0 ;this should be another CNAME
+
+cifs_hostname:
+ .byte "KIPPERCIFS",0
+
+static_ip:
+ .byte 10,5,1,64
+sample_msg:
+.byte $ff, $ff, $ff, $ff, $ff, $ff, $f8, $1e, $df, $dc, $47, $a1, $08, $00, $45, $00
+.byte $00, $4e, $9e, $cf, $00, $00, $40, $11, $c4, $c5, $0a, $05, $01, $02, $0a, $05
+.byte $01, $ff, $fe, $66, $00, $89, $00, $3a, $86, $0a, $00, $02, $01, $10, $00, $01
+.byte $00, $00, $00, $00, $00, $00, $20, $45, $48, $45, $50, $45, $50, $45, $43, $45
+.byte $46, $46, $43, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43
+.byte $41, $43, $41, $43, $41, $43, $41, $00, $00, $20, $00, $01
+
+
+
+;-- LICENSE FOR testdns.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_disk_io.s b/test/test_disk_io.s
similarity index 94%
rename from client/test/test_disk_io.s
rename to test/test_disk_io.s
index 87361ff..9df499a 100644
--- a/client/test/test_disk_io.s
+++ b/test/test_disk_io.s
@@ -1,471 +1,471 @@
-
-.ifndef KIPPER_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-.import print_a
-.import cfg_get_configuration_ptr
-.import io_device_no
-.import io_sector_no
-.import io_track_no
-.import io_read_sector
-.import io_write_sector
-.import io_read_file_with_callback
-.import io_read_file
-.import io_filename
-.import io_filesize
-.import io_load_address
-.import io_callback
-.import get_key
-.import ip65_error
-.import io_read_catalogue_ex
-
-.macro cout arg
- lda arg
- jsr print_a
-.endmacro
-
-
-
-.bss
- sector_buffer: .res 256
- output_buffer: .res 520
- .export output_buffer
-current_byte_in_row: .res 1
-current_byte_in_sector: .res 1
-start_of_current_row: .res 1
-
-directory_buffer: .res 4096
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ;switch to lower case charset
- lda #23
- sta $d018
-
- ;test we can read catalogue the hard way
- ldax #loading
- jsr print
- ldax #dir_fname
- stax io_filename
- jsr print
-
-
- jsr print_cr
- lda #01
- sta io_device_no
-
- ldax #readfile_callback
- stax io_callback
- ldax #$3000
- jsr io_read_file
- bcc :+
- jsr print_error_code
- rts
-:
-
-
-
- ;test we can write sector to default desk
-
- ldx #$00
-@fill_sector_loop:
- txa
- sta sector_buffer,x
- inx
- bne @fill_sector_loop
-
- lda #$01
- sta io_track_no
- lda #$01
- sta io_sector_no
- ldax #write_sector
- jsr print
- lda io_sector_no
- jsr print_hex
- jsr print_cr
- ldax #sector_buffer
- jsr io_write_sector
-
- bcc :+
- jsr print_error_code
- rts
-:
-
-
-
- inc io_sector_no
- ldax #write_sector
- jsr print
- lda io_sector_no
- jsr print_hex
- jsr print_cr
- ldax #sector_buffer
- jsr io_write_sector
-
- bcc :+
- jsr print_error_code
- rts
-:
-
- inc io_sector_no
- ldax #write_sector
- jsr print
- lda io_sector_no
- jsr print_hex
- jsr print_cr
- ldax #sector_buffer
- jsr io_write_sector
-
- bcc :+
- jsr print_error_code
- rts
-:
-
-
-
- ;test we can read a sector from default desk
- ldax #read_sector
- jsr print
-
- lda #$01
- sta io_track_no
- lda #$03
- sta io_sector_no
- ldax #sector_buffer
- jsr io_read_sector
- bcc :+
- jsr print_error_code
- rts
-:
-
- jsr dump_sector
-
- ;test we can read the catalogue
- ldax #read_catalogue
- jsr print
-
- lda #01
- sta io_device_no
-
- ldax #directory_buffer
- jsr io_read_catalogue_ex
-
- bcc @no_error_on_catalogue
- jsr print_error_code
- rts
-@no_error_on_catalogue:
- ldax #directory_buffer
- jsr print_catalogue
-
- ;test we can read without callbacks to fixed buffer
- ldax #loading
- jsr print
- ldax #fname
- stax io_filename
- jsr print
-
-
- jsr print_cr
- lda #01
- sta io_device_no
-
- ldax #readfile_callback
- stax io_callback
- ldax #$3000
- jsr io_read_file
- bcc :+
- jsr print_error_code
- rts
-:
-
- ldax io_filesize
- jsr print_integer
- ldax #bytes_to
- jsr print
- lda io_load_address+1
- jsr print_hex
- lda io_load_address
- jsr print_hex
- jsr print_cr
-
-
-;test we can read without callbacks to address in file
- ldax #loading
- jsr print
- ldax #fname2
- stax io_filename
- jsr print
-
-
- jsr print_cr
- lda #01
- sta io_device_no
-
- ldax #readfile_callback
- stax io_callback
- ldax #$0000
- jsr io_read_file
- bcc :+
- jsr print_error_code
- rts
-:
-
- ldax io_filesize
- jsr print_integer
- ldax #bytes_to
- jsr print
- lda io_load_address+1
- jsr print_hex
- lda io_load_address
- jsr print_hex
- jsr print_cr
-
- jsr wait_for_keypress
-
- ;test we can read via callbacks
-
- ldax #loading
- jsr print
- ldax #fname
- stax io_filename
- jsr print
-
- jsr print_cr
- lda #01
- sta io_device_no
-
- ldax #readfile_callback
- stax io_callback
- ldax #sector_buffer
-
- jsr io_read_file_with_callback
- bcc :+
- jsr print_error_code
-:
-
-
-
- rts
-
-
-@error:
- jsr print_cr
- lda ip65_error
- jsr print_hex
- rts
-
-
-;print catalogue pointed at by AX
-print_catalogue:
- stax tmp_buffer_ptr
-
- @print_one_filename:
- jsr read_byte_from_buffer
- beq @catalogue_done
-@print_one_char:
- jsr print_a
- jsr read_byte_from_buffer
- beq @end_of_filename
- jmp @print_one_char
-@end_of_filename:
- jsr print_cr
- ldax #filetype
- jsr print
- jsr read_byte_from_buffer
- jsr print_hex
- ldax #sectors
- jsr print
- jsr read_byte_from_buffer
- pha
- jsr read_byte_from_buffer
- jsr print_hex
- pla
- jsr print_hex
- jsr print_cr
- jmp @print_one_filename
-@catalogue_done:
- rts
-
-read_byte_from_buffer:
-tmp_buffer_ptr=read_byte_from_buffer+1
- lda $ffff
- inc tmp_buffer_ptr
- bne :+
- inc tmp_buffer_ptr+1
-:
- pha
- pla ;reload A so flags are set correctly
- rts
-
-
-
-readfile_callback:
- tya
- jsr print_hex
- ldax #bytes
- jsr print
- jsr dump_sector
- rts
-
-print_error_code:
- jsr print_cr
- ldax #error
- jsr print
- lda ip65_error
- jsr print_hex
- jsr print_cr
- rts
-
-wait_for_keypress:
- lda #0
- sta $c6 ;set the keyboard buffer to be empty
- ldax #press_a_key_to_continue
- jsr print
- jsr get_key
- rts
-
-dump_sector:
-;hex dump sector
- lda #0
- sta current_byte_in_sector
- sta start_of_current_row
-
-@one_row:
- lda #$80
- cmp current_byte_in_sector
- bne @dont_wait_for_key
- jsr wait_for_keypress
-@dont_wait_for_key:
- lda current_byte_in_sector
-
- sta start_of_current_row
- jsr print_hex
- lda #':'
- jsr print_a
- lda #' '
- jsr print_a
-
- lda #0
- sta current_byte_in_row
-
-;first the hex values
-@dump_byte:
- ldy current_byte_in_sector
- lda sector_buffer,y
- jsr print_hex
- lda #' '
- jsr print_a
- inc current_byte_in_sector
- inc current_byte_in_row
- lda current_byte_in_row
- cmp #08
- bne @dump_byte
-
-;now the ascii values
- lda start_of_current_row
- sta current_byte_in_sector
-@print_byte:
- ldy current_byte_in_sector
- lda sector_buffer,y
- cmp #32
- bmi @not_printable
- cmp #94
- bmi @printable
-@not_printable:
- lda #'.'
-@printable:
- jsr print_a
- inc current_byte_in_sector
- beq @last_byte
- dec current_byte_in_row
- bne @print_byte
- jsr print_cr
- jmp @one_row
-@last_byte:
- jsr print_cr
- jsr wait_for_keypress
- rts
-
-
-
-write_sector:
- .byte "WRITING SECTOR",0
-
-read_sector:
- .byte "READING SECTOR",13,0
-
-
-dir_fname: .byte "$",0
-
-read_catalogue:
- .byte "READING CATALOGUE",13,0
-fname:
- .byte "TEST_DISK_IO.PRG",0
-
-fname2:
- .byte "SCREEN.PRG",0
-
-loading: .byte "LOADING ",0
-.rodata
-
-filetype:
- .byte "TYPE: $",0
-
-sectors:
- .byte " SECTORS: $",0
-error:
- .byte "ERROR - $", 0
-
-failed:
- .byte "FAILED ", 0
-
-ok:
- .byte "OK ", 0
-
-bytes:
- .byte " BYTES.", 0
-
-bytes_to:
- .byte " BYTES TO $", 0
-
-
-
-
-;-- LICENSE FOR test_disk_io.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 --
+
+.ifndef KIPPER_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../inc/common.i"
+.include "../inc/commonprint.i"
+.import print_a
+.import cfg_get_configuration_ptr
+.import io_device_no
+.import io_sector_no
+.import io_track_no
+.import io_read_sector
+.import io_write_sector
+.import io_read_file_with_callback
+.import io_read_file
+.import io_filename
+.import io_filesize
+.import io_load_address
+.import io_callback
+.import get_key
+.import ip65_error
+.import io_read_catalogue_ex
+
+.macro cout arg
+ lda arg
+ jsr print_a
+.endmacro
+
+
+
+.bss
+ sector_buffer: .res 256
+ output_buffer: .res 520
+ .export output_buffer
+current_byte_in_row: .res 1
+current_byte_in_sector: .res 1
+start_of_current_row: .res 1
+
+directory_buffer: .res 4096
+
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+basicstub:
+ .word @nextline
+ .word 2003
+ .byte $9e
+ .byte <(((init / 1000) .mod 10) + $30)
+ .byte <(((init / 100 ) .mod 10) + $30)
+ .byte <(((init / 10 ) .mod 10) + $30)
+ .byte <(((init ) .mod 10) + $30)
+ .byte 0
+@nextline:
+ .word 0
+
+init:
+
+ ;switch to lower case charset
+ lda #23
+ sta $d018
+
+ ;test we can read catalogue the hard way
+ ldax #loading
+ jsr print
+ ldax #dir_fname
+ stax io_filename
+ jsr print
+
+
+ jsr print_cr
+ lda #01
+ sta io_device_no
+
+ ldax #readfile_callback
+ stax io_callback
+ ldax #$3000
+ jsr io_read_file
+ bcc :+
+ jsr print_error_code
+ rts
+:
+
+
+
+ ;test we can write sector to default desk
+
+ ldx #$00
+@fill_sector_loop:
+ txa
+ sta sector_buffer,x
+ inx
+ bne @fill_sector_loop
+
+ lda #$01
+ sta io_track_no
+ lda #$01
+ sta io_sector_no
+ ldax #write_sector
+ jsr print
+ lda io_sector_no
+ jsr print_hex
+ jsr print_cr
+ ldax #sector_buffer
+ jsr io_write_sector
+
+ bcc :+
+ jsr print_error_code
+ rts
+:
+
+
+
+ inc io_sector_no
+ ldax #write_sector
+ jsr print
+ lda io_sector_no
+ jsr print_hex
+ jsr print_cr
+ ldax #sector_buffer
+ jsr io_write_sector
+
+ bcc :+
+ jsr print_error_code
+ rts
+:
+
+ inc io_sector_no
+ ldax #write_sector
+ jsr print
+ lda io_sector_no
+ jsr print_hex
+ jsr print_cr
+ ldax #sector_buffer
+ jsr io_write_sector
+
+ bcc :+
+ jsr print_error_code
+ rts
+:
+
+
+
+ ;test we can read a sector from default desk
+ ldax #read_sector
+ jsr print
+
+ lda #$01
+ sta io_track_no
+ lda #$03
+ sta io_sector_no
+ ldax #sector_buffer
+ jsr io_read_sector
+ bcc :+
+ jsr print_error_code
+ rts
+:
+
+ jsr dump_sector
+
+ ;test we can read the catalogue
+ ldax #read_catalogue
+ jsr print
+
+ lda #01
+ sta io_device_no
+
+ ldax #directory_buffer
+ jsr io_read_catalogue_ex
+
+ bcc @no_error_on_catalogue
+ jsr print_error_code
+ rts
+@no_error_on_catalogue:
+ ldax #directory_buffer
+ jsr print_catalogue
+
+ ;test we can read without callbacks to fixed buffer
+ ldax #loading
+ jsr print
+ ldax #fname
+ stax io_filename
+ jsr print
+
+
+ jsr print_cr
+ lda #01
+ sta io_device_no
+
+ ldax #readfile_callback
+ stax io_callback
+ ldax #$3000
+ jsr io_read_file
+ bcc :+
+ jsr print_error_code
+ rts
+:
+
+ ldax io_filesize
+ jsr print_integer
+ ldax #bytes_to
+ jsr print
+ lda io_load_address+1
+ jsr print_hex
+ lda io_load_address
+ jsr print_hex
+ jsr print_cr
+
+
+;test we can read without callbacks to address in file
+ ldax #loading
+ jsr print
+ ldax #fname2
+ stax io_filename
+ jsr print
+
+
+ jsr print_cr
+ lda #01
+ sta io_device_no
+
+ ldax #readfile_callback
+ stax io_callback
+ ldax #$0000
+ jsr io_read_file
+ bcc :+
+ jsr print_error_code
+ rts
+:
+
+ ldax io_filesize
+ jsr print_integer
+ ldax #bytes_to
+ jsr print
+ lda io_load_address+1
+ jsr print_hex
+ lda io_load_address
+ jsr print_hex
+ jsr print_cr
+
+ jsr wait_for_keypress
+
+ ;test we can read via callbacks
+
+ ldax #loading
+ jsr print
+ ldax #fname
+ stax io_filename
+ jsr print
+
+ jsr print_cr
+ lda #01
+ sta io_device_no
+
+ ldax #readfile_callback
+ stax io_callback
+ ldax #sector_buffer
+
+ jsr io_read_file_with_callback
+ bcc :+
+ jsr print_error_code
+:
+
+
+
+ rts
+
+
+@error:
+ jsr print_cr
+ lda ip65_error
+ jsr print_hex
+ rts
+
+
+;print catalogue pointed at by AX
+print_catalogue:
+ stax tmp_buffer_ptr
+
+ @print_one_filename:
+ jsr read_byte_from_buffer
+ beq @catalogue_done
+@print_one_char:
+ jsr print_a
+ jsr read_byte_from_buffer
+ beq @end_of_filename
+ jmp @print_one_char
+@end_of_filename:
+ jsr print_cr
+ ldax #filetype
+ jsr print
+ jsr read_byte_from_buffer
+ jsr print_hex
+ ldax #sectors
+ jsr print
+ jsr read_byte_from_buffer
+ pha
+ jsr read_byte_from_buffer
+ jsr print_hex
+ pla
+ jsr print_hex
+ jsr print_cr
+ jmp @print_one_filename
+@catalogue_done:
+ rts
+
+read_byte_from_buffer:
+tmp_buffer_ptr=read_byte_from_buffer+1
+ lda $ffff
+ inc tmp_buffer_ptr
+ bne :+
+ inc tmp_buffer_ptr+1
+:
+ pha
+ pla ;reload A so flags are set correctly
+ rts
+
+
+
+readfile_callback:
+ tya
+ jsr print_hex
+ ldax #bytes
+ jsr print
+ jsr dump_sector
+ rts
+
+print_error_code:
+ jsr print_cr
+ ldax #error
+ jsr print
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+ rts
+
+wait_for_keypress:
+ lda #0
+ sta $c6 ;set the keyboard buffer to be empty
+ ldax #press_a_key_to_continue
+ jsr print
+ jsr get_key
+ rts
+
+dump_sector:
+;hex dump sector
+ lda #0
+ sta current_byte_in_sector
+ sta start_of_current_row
+
+@one_row:
+ lda #$80
+ cmp current_byte_in_sector
+ bne @dont_wait_for_key
+ jsr wait_for_keypress
+@dont_wait_for_key:
+ lda current_byte_in_sector
+
+ sta start_of_current_row
+ jsr print_hex
+ lda #':'
+ jsr print_a
+ lda #' '
+ jsr print_a
+
+ lda #0
+ sta current_byte_in_row
+
+;first the hex values
+@dump_byte:
+ ldy current_byte_in_sector
+ lda sector_buffer,y
+ jsr print_hex
+ lda #' '
+ jsr print_a
+ inc current_byte_in_sector
+ inc current_byte_in_row
+ lda current_byte_in_row
+ cmp #08
+ bne @dump_byte
+
+;now the ascii values
+ lda start_of_current_row
+ sta current_byte_in_sector
+@print_byte:
+ ldy current_byte_in_sector
+ lda sector_buffer,y
+ cmp #32
+ bmi @not_printable
+ cmp #94
+ bmi @printable
+@not_printable:
+ lda #'.'
+@printable:
+ jsr print_a
+ inc current_byte_in_sector
+ beq @last_byte
+ dec current_byte_in_row
+ bne @print_byte
+ jsr print_cr
+ jmp @one_row
+@last_byte:
+ jsr print_cr
+ jsr wait_for_keypress
+ rts
+
+
+
+write_sector:
+ .byte "WRITING SECTOR",0
+
+read_sector:
+ .byte "READING SECTOR",13,0
+
+
+dir_fname: .byte "$",0
+
+read_catalogue:
+ .byte "READING CATALOGUE",13,0
+fname:
+ .byte "TEST_DISK_IO.PRG",0
+
+fname2:
+ .byte "SCREEN.PRG",0
+
+loading: .byte "LOADING ",0
+.rodata
+
+filetype:
+ .byte "TYPE: $",0
+
+sectors:
+ .byte " SECTORS: $",0
+error:
+ .byte "ERROR - $", 0
+
+failed:
+ .byte "FAILED ", 0
+
+ok:
+ .byte "OK ", 0
+
+bytes:
+ .byte " BYTES.", 0
+
+bytes_to:
+ .byte " BYTES TO $", 0
+
+
+
+
+;-- LICENSE FOR test_disk_io.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_get_url.s b/test/test_get_url.s
similarity index 95%
rename from client/test/test_get_url.s
rename to test/test_get_url.s
index dd6d455..8751639 100644
--- a/client/test/test_get_url.s
+++ b/test/test_get_url.s
@@ -1,152 +1,152 @@
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-.include "../inc/net.i"
-
-.import print_a
-.import get_key
-.import cfg_get_configuration_ptr
-.import ascii_to_native
-.import parser_init
-.import parser_skip_next
-.importzp copy_src
-.importzp copy_dest
-.import url_ip
-.import url_port
-.import url_selector
-.import url_resource_type
-.import url_parse
-.import url_download
-.import url_download_buffer
-.import url_download_buffer_length
-temp_buff=copy_dest
-
-.bss
-
-string_offset: .res 1
-selector_ptr: .res 2
-temp_url_ptr: .res 2
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ;switch to lower case charset
- lda #23
- sta $d018
-
- init_ip_via_dhcp
- jsr print_ip_config
-
- ldax #url_1
- jsr test_url_download
-
- ldax #url_2
- jsr test_url_download
-
- rts
-
-test_url_download:
- stax temp_url_ptr
- ldax #downloading
- jsr print
- ldax temp_url_ptr
- jsr print
- jsr print_cr
- ldax #dl_buffer
- stax url_download_buffer
- ldax #dl_buffer_length
- stax url_download_buffer_length
-
- ldax temp_url_ptr
- jsr url_download
- bcc :+
- jmp print_errorcode
- :
- ldax #dl_buffer
- jsr parser_init
-@next_title:
- ldax #title
- jsr parser_skip_next
- bcs @done
-
- jsr print_tag_contents
- jsr print_cr
-
- jmp @next_title
-@done:
-
- rts
-
-wait_key:
- ldax #press_a_key
- jsr print
- jmp get_key
-
-
-print_tag_contents:
- stax temp_buff
- lda #0
- sta string_offset
-@next_byte:
- ldy string_offset
- lda (temp_buff),y
- beq @done
- cmp #'<'
- beq @done
- jsr ascii_to_native
- jsr print_a
- inc string_offset
- beq @done
- jmp @next_byte
-@done:
- rts
-
-.data
-title:
-.byte "",0
-
-url_1:
-.byte "http://static.cricinfo.com/rss/livescores.xml",0
-url_2:
-.byte "http://search.twitter.com/search.atom?q=kipper",0
-
-downloading: .asciiz "DOWNLOADING "
-press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0
-
-.bss
-dl_buffer_length=8092
-dl_buffer: .res dl_buffer_length
-
-
-
-;-- LICENSE FOR test_get_url.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 --
+.include "../inc/common.i"
+.include "../inc/commonprint.i"
+.include "../inc/net.i"
+
+.import print_a
+.import get_key
+.import cfg_get_configuration_ptr
+.import ascii_to_native
+.import parser_init
+.import parser_skip_next
+.importzp copy_src
+.importzp copy_dest
+.import url_ip
+.import url_port
+.import url_selector
+.import url_resource_type
+.import url_parse
+.import url_download
+.import url_download_buffer
+.import url_download_buffer_length
+temp_buff=copy_dest
+
+.bss
+
+string_offset: .res 1
+selector_ptr: .res 2
+temp_url_ptr: .res 2
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+basicstub:
+ .word @nextline
+ .word 2003
+ .byte $9e
+ .byte <(((init / 1000) .mod 10) + $30)
+ .byte <(((init / 100 ) .mod 10) + $30)
+ .byte <(((init / 10 ) .mod 10) + $30)
+ .byte <(((init ) .mod 10) + $30)
+ .byte 0
+@nextline:
+ .word 0
+
+init:
+
+ ;switch to lower case charset
+ lda #23
+ sta $d018
+
+ init_ip_via_dhcp
+ jsr print_ip_config
+
+ ldax #url_1
+ jsr test_url_download
+
+ ldax #url_2
+ jsr test_url_download
+
+ rts
+
+test_url_download:
+ stax temp_url_ptr
+ ldax #downloading
+ jsr print
+ ldax temp_url_ptr
+ jsr print
+ jsr print_cr
+ ldax #dl_buffer
+ stax url_download_buffer
+ ldax #dl_buffer_length
+ stax url_download_buffer_length
+
+ ldax temp_url_ptr
+ jsr url_download
+ bcc :+
+ jmp print_errorcode
+ :
+ ldax #dl_buffer
+ jsr parser_init
+@next_title:
+ ldax #title
+ jsr parser_skip_next
+ bcs @done
+
+ jsr print_tag_contents
+ jsr print_cr
+
+ jmp @next_title
+@done:
+
+ rts
+
+wait_key:
+ ldax #press_a_key
+ jsr print
+ jmp get_key
+
+
+print_tag_contents:
+ stax temp_buff
+ lda #0
+ sta string_offset
+@next_byte:
+ ldy string_offset
+ lda (temp_buff),y
+ beq @done
+ cmp #'<'
+ beq @done
+ jsr ascii_to_native
+ jsr print_a
+ inc string_offset
+ beq @done
+ jmp @next_byte
+@done:
+ rts
+
+.data
+title:
+.byte "",0
+
+url_1:
+.byte "http://static.cricinfo.com/rss/livescores.xml",0
+url_2:
+.byte "http://search.twitter.com/search.atom?q=kipper",0
+
+downloading: .asciiz "DOWNLOADING "
+press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0
+
+.bss
+dl_buffer_length=8092
+dl_buffer: .res dl_buffer_length
+
+
+
+;-- LICENSE FOR test_get_url.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_getc.s b/test/test_getc.s
similarity index 95%
rename from client/test/test_getc.s
rename to test/test_getc.s
index d157cbb..6a853fe 100644
--- a/client/test/test_getc.s
+++ b/test/test_getc.s
@@ -1,196 +1,196 @@
-
-.ifndef KIPPER_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-.import print_a
-.import cfg_get_configuration_ptr
-.import io_device_no
-.import io_sector_no
-.import io_track_no
-.import io_read_sector
-.import io_write_sector
-
-.import io_read_file_with_callback
-.import io_read_file
-.import io_filename
-.import io_filesize
-.import io_load_address
-.import io_callback
-.import get_key
-.import ip65_error
-.import ip65_process
-.import io_read_catalogue_ex
-
-.macro cout arg
- lda arg
- jsr print_a
-.endmacro
-
-
-
-.bss
- sector_buffer: .res 256
- output_buffer: .res 520
- .export output_buffer
-current_byte_in_row: .res 1
-current_byte_in_sector: .res 1
-start_of_current_row: .res 1
-
-directory_buffer: .res 4096
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
- lda #14
- jsr print_a ;switch to lower case
- lda $dc08 ;read deci-seconds - start clock ticking
- sta $dc08
- jsr load_buffer
-@loop:
- lda #5 ;timeout period
- jsr getc
- bcs @done
- jsr print_a
- jmp @loop
-@done:
- rts
-
-load_buffer:
- ldax #buffer
- stax next_char_ptr
- ldax #buffer_length
- stax buff_length
- rts
-
-
-getc:
- sta getc_timeout_seconds
-
- clc
- lda $dc09 ;time of day clock: seconds (in BCD)
- sed
- adc getc_timeout_seconds
- cmp #$60
- bcc @timeout_set
- sec
- sbc #$60
-@timeout_set:
- cld
- sta getc_timeout_end
-
-@poll_loop:
- jsr ip65_process
- jsr next_char
- bcs @no_char
- rts ;done!
-@no_char:
- lda $dc09 ;time of day clock: seconds
- cmp getc_timeout_end
- bne @poll_loop
- sec
- rts
-
-next_char:
- lda buff_length
- bne @not_eof
- lda buff_length+1
- bne @not_eof
- sec
- rts
-@not_eof:
- next_char_ptr=*+1
- lda $ffff
- pha
- inc next_char_ptr
- bne :+
- inc next_char_ptr+1
-:
- sec
- lda buff_length
- sbc #1
- sta buff_length
- lda buff_length+1
- sbc #0
- sta buff_length+1
- pla
- clc
-
- rts
-
-.rodata
-buffer:
- .byte "this is a test1!",13
- .byte "this is a test2!",13
- .byte "this is a test3!",13
- .byte "this is a test4!",13
- .byte "this is a test5!",13
- .byte "this is a test6!",13
- .byte "this is a test7!",13
- .byte "this is a test8!",13
- .byte "this is a test9!",13
- .byte "this is a test10!",13
- .byte "this is a test1@",13
- .byte "this is a test2@",13
- .byte "this is a test3@",13
- .byte "this is a test4@",13
- .byte "this is a test5@",13
- .byte "this is a test6@",13
- .byte "this is a test7@",13
- .byte "this is a test8@",13
- .byte "this is a test9@",13
- .byte "this is a test10@",13
- .byte "this is a test1*",13
- .byte "this is a test2*",13
- .byte "this is a test3*",13
- .byte "this is a test4*",13
- .byte "this is a test5*",13
- .byte "this is a test6*",13
- .byte "this is a test7*",13
- .byte "this is a test8*",13
- .byte "this is a test9*",13
- .byte "this is a test10*",13
-
-buffer_length=*-buffer
-
-.bss
-getc_timeout_end: .res 1
-getc_timeout_seconds: .res 1
-buff_length: .res 2
-
-
-;-- LICENSE FOR test_getc.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 --
+
+.ifndef KIPPER_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../inc/common.i"
+.include "../inc/commonprint.i"
+.import print_a
+.import cfg_get_configuration_ptr
+.import io_device_no
+.import io_sector_no
+.import io_track_no
+.import io_read_sector
+.import io_write_sector
+
+.import io_read_file_with_callback
+.import io_read_file
+.import io_filename
+.import io_filesize
+.import io_load_address
+.import io_callback
+.import get_key
+.import ip65_error
+.import ip65_process
+.import io_read_catalogue_ex
+
+.macro cout arg
+ lda arg
+ jsr print_a
+.endmacro
+
+
+
+.bss
+ sector_buffer: .res 256
+ output_buffer: .res 520
+ .export output_buffer
+current_byte_in_row: .res 1
+current_byte_in_sector: .res 1
+start_of_current_row: .res 1
+
+directory_buffer: .res 4096
+
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+basicstub:
+ .word @nextline
+ .word 2003
+ .byte $9e
+ .byte <(((init / 1000) .mod 10) + $30)
+ .byte <(((init / 100 ) .mod 10) + $30)
+ .byte <(((init / 10 ) .mod 10) + $30)
+ .byte <(((init ) .mod 10) + $30)
+ .byte 0
+@nextline:
+ .word 0
+
+init:
+ lda #14
+ jsr print_a ;switch to lower case
+ lda $dc08 ;read deci-seconds - start clock ticking
+ sta $dc08
+ jsr load_buffer
+@loop:
+ lda #5 ;timeout period
+ jsr getc
+ bcs @done
+ jsr print_a
+ jmp @loop
+@done:
+ rts
+
+load_buffer:
+ ldax #buffer
+ stax next_char_ptr
+ ldax #buffer_length
+ stax buff_length
+ rts
+
+
+getc:
+ sta getc_timeout_seconds
+
+ clc
+ lda $dc09 ;time of day clock: seconds (in BCD)
+ sed
+ adc getc_timeout_seconds
+ cmp #$60
+ bcc @timeout_set
+ sec
+ sbc #$60
+@timeout_set:
+ cld
+ sta getc_timeout_end
+
+@poll_loop:
+ jsr ip65_process
+ jsr next_char
+ bcs @no_char
+ rts ;done!
+@no_char:
+ lda $dc09 ;time of day clock: seconds
+ cmp getc_timeout_end
+ bne @poll_loop
+ sec
+ rts
+
+next_char:
+ lda buff_length
+ bne @not_eof
+ lda buff_length+1
+ bne @not_eof
+ sec
+ rts
+@not_eof:
+ next_char_ptr=*+1
+ lda $ffff
+ pha
+ inc next_char_ptr
+ bne :+
+ inc next_char_ptr+1
+:
+ sec
+ lda buff_length
+ sbc #1
+ sta buff_length
+ lda buff_length+1
+ sbc #0
+ sta buff_length+1
+ pla
+ clc
+
+ rts
+
+.rodata
+buffer:
+ .byte "this is a test1!",13
+ .byte "this is a test2!",13
+ .byte "this is a test3!",13
+ .byte "this is a test4!",13
+ .byte "this is a test5!",13
+ .byte "this is a test6!",13
+ .byte "this is a test7!",13
+ .byte "this is a test8!",13
+ .byte "this is a test9!",13
+ .byte "this is a test10!",13
+ .byte "this is a test1@",13
+ .byte "this is a test2@",13
+ .byte "this is a test3@",13
+ .byte "this is a test4@",13
+ .byte "this is a test5@",13
+ .byte "this is a test6@",13
+ .byte "this is a test7@",13
+ .byte "this is a test8@",13
+ .byte "this is a test9@",13
+ .byte "this is a test10@",13
+ .byte "this is a test1*",13
+ .byte "this is a test2*",13
+ .byte "this is a test3*",13
+ .byte "this is a test4*",13
+ .byte "this is a test5*",13
+ .byte "this is a test6*",13
+ .byte "this is a test7*",13
+ .byte "this is a test8*",13
+ .byte "this is a test9*",13
+ .byte "this is a test10*",13
+
+buffer_length=*-buffer
+
+.bss
+getc_timeout_end: .res 1
+getc_timeout_seconds: .res 1
+buff_length: .res 2
+
+
+;-- LICENSE FOR test_getc.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_httpd.s b/test/test_httpd.s
similarity index 94%
rename from client/test/test_httpd.s
rename to test/test_httpd.s
index 50b60fa..0b30249 100644
--- a/client/test/test_httpd.s
+++ b/test/test_httpd.s
@@ -1,227 +1,227 @@
-;test the "Kipper Kartridge API"
-.ifndef KPR_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../ip65/copymem.s"
-
-; load A/X macro
- .macro ldax arg
- .if (.match (.left (1, arg), #)) ; immediate mode
- lda #<(.right (.tcount (arg)-1, arg))
- ldx #>(.right (.tcount (arg)-1, arg))
- .else ; assume absolute or zero page
- lda arg
- ldx 1+(arg)
- .endif
- .endmacro
-
-; store A/X macro
-.macro stax arg
- sta arg
- stx 1+(arg)
-.endmacro
-
-print_a = $ffd2
-
-.macro cout arg
- lda arg
- jsr print_a
-.endmacro
-
- .zeropage
- temp_ptr: .res 2
-
- .bss
- kipper_param_buffer: .res $20
- block_number: .res $0
-
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-.macro print arg
- ldax arg
- ldy #KPR_PRINT_ASCIIZ
- jsr KPR_DISPATCH_VECTOR
-.endmacro
-
-.macro print_cr
- lda #13
- jsr print_a
-.endmacro
-
-.macro call arg
- ldy arg
- jsr KPR_DISPATCH_VECTOR
-.endmacro
-
-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
-
-
-;look for KIPPER signature at location pointed at by AX
-look_for_signature:
- stax temp_ptr
- ldy #5
-@check_one_byte:
- lda (temp_ptr),y
- cmp kipper_signature,y
- bne @bad_match
- dey
- bpl@check_one_byte
- clc
- rts
-@bad_match:
- sec
- rts
-
-init:
-
-
- ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge
- jsr look_for_signature
- bcc @found_kipper_signature
- jmp kipper_signature_not_found
-
-@found_kipper_signature:
-
- lda #14
- jsr print_a ;switch to lower case
-
- print #initializing
-
- lda #$4c
- sta $4000
- ldax #print_vars
- stax $4001
-
-
- ldy #KPR_INITIALIZE
- jsr KPR_DISPATCH_VECTOR
- bcc :+
- print #failed
- jsr print_errorcode
- jmp bad_boot
-:
-
- print #ok
- print_cr
-
- call #KPR_PRINT_IP_CONFIG
- print #listening
- ldax #httpd_callback
-; ldax #$0000
- call #KPR_HTTPD_START
- jsr print_errorcode
- rts
-
-
-print_vars:
-
- lda #'h'
- call #KPR_HTTPD_GET_VAR_VALUE
- bcs :+
- call #KPR_PRINT_ASCIIZ
- print #said
- lda #'m'
- call #KPR_HTTPD_GET_VAR_VALUE
- bcs :+
- call #KPR_PRINT_ASCIIZ
- print_cr
-:
- rts
-bad_boot:
- print #press_a_key_to_continue
-restart:
- jsr get_key
- jmp $fce2 ;do a cold start
-
-
-print_errorcode:
- print #error_code
- call #KPR_GET_LAST_ERROR
- call #KPR_PRINT_HEX
- print_cr
- rts
-
-;use C64 Kernel ROM function to read a key
-;inputs: none
-;outputs: A contains ASCII value of key just pressed
-get_key:
- jsr $ffe4
- cmp #0
- beq get_key
- rts
-
-kipper_signature_not_found:
-
- ldy #0
-:
- lda kipper_signature_not_found_message,y
- beq restart
- jsr print_a
- iny
- jmp :-
-
-httpd_callback:
- jsr print_vars
- ldax #html
- ldy #2 ;text/html
- clc
- rts
-
-
-.rodata
-
-kipper_signature:
- .byte "KIPPER" ; API signature
- error_code:
- .asciiz "ERROR CODE: $"
-press_a_key_to_continue:
- .byte "PRESS A KEY TO CONTINUE",13,0
-failed:
- .byte "FAILED ", 0
-
-ok:
- .byte "OK ", 0
-
- kipper_signature_not_found_message:
- .byte "NO KIPPER API FOUND",13,"PRESS ANY KEY TO RESET", 0
-initializing:
- .byte "INITIALIZING ",0
-listening:
- .byte "LISTENING",0
-said:
- .byte ":",0
-html:
- .byte "hello world %?mMessage recorded as '%$h:%$m'%. ",0
-
-;-- LICENSE FOR test_httpd.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 --
+;test the "Kipper Kartridge API"
+.ifndef KPR_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../ip65/copymem.s"
+
+; load A/X macro
+ .macro ldax arg
+ .if (.match (.left (1, arg), #)) ; immediate mode
+ lda #<(.right (.tcount (arg)-1, arg))
+ ldx #>(.right (.tcount (arg)-1, arg))
+ .else ; assume absolute or zero page
+ lda arg
+ ldx 1+(arg)
+ .endif
+ .endmacro
+
+; store A/X macro
+.macro stax arg
+ sta arg
+ stx 1+(arg)
+.endmacro
+
+print_a = $ffd2
+
+.macro cout arg
+ lda arg
+ jsr print_a
+.endmacro
+
+ .zeropage
+ temp_ptr: .res 2
+
+ .bss
+ kipper_param_buffer: .res $20
+ block_number: .res $0
+
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+.macro print arg
+ ldax arg
+ ldy #KPR_PRINT_ASCIIZ
+ jsr KPR_DISPATCH_VECTOR
+.endmacro
+
+.macro print_cr
+ lda #13
+ jsr print_a
+.endmacro
+
+.macro call arg
+ ldy arg
+ jsr KPR_DISPATCH_VECTOR
+.endmacro
+
+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
+
+
+;look for KIPPER signature at location pointed at by AX
+look_for_signature:
+ stax temp_ptr
+ ldy #5
+@check_one_byte:
+ lda (temp_ptr),y
+ cmp kipper_signature,y
+ bne @bad_match
+ dey
+ bpl@check_one_byte
+ clc
+ rts
+@bad_match:
+ sec
+ rts
+
+init:
+
+
+ ldax #KPR_CART_SIGNATURE ;where signature should be in cartridge
+ jsr look_for_signature
+ bcc @found_kipper_signature
+ jmp kipper_signature_not_found
+
+@found_kipper_signature:
+
+ lda #14
+ jsr print_a ;switch to lower case
+
+ print #initializing
+
+ lda #$4c
+ sta $4000
+ ldax #print_vars
+ stax $4001
+
+
+ ldy #KPR_INITIALIZE
+ jsr KPR_DISPATCH_VECTOR
+ bcc :+
+ print #failed
+ jsr print_errorcode
+ jmp bad_boot
+:
+
+ print #ok
+ print_cr
+
+ call #KPR_PRINT_IP_CONFIG
+ print #listening
+ ldax #httpd_callback
+; ldax #$0000
+ call #KPR_HTTPD_START
+ jsr print_errorcode
+ rts
+
+
+print_vars:
+
+ lda #'h'
+ call #KPR_HTTPD_GET_VAR_VALUE
+ bcs :+
+ call #KPR_PRINT_ASCIIZ
+ print #said
+ lda #'m'
+ call #KPR_HTTPD_GET_VAR_VALUE
+ bcs :+
+ call #KPR_PRINT_ASCIIZ
+ print_cr
+:
+ rts
+bad_boot:
+ print #press_a_key_to_continue
+restart:
+ jsr get_key
+ jmp $fce2 ;do a cold start
+
+
+print_errorcode:
+ print #error_code
+ call #KPR_GET_LAST_ERROR
+ call #KPR_PRINT_HEX
+ print_cr
+ rts
+
+;use C64 Kernel ROM function to read a key
+;inputs: none
+;outputs: A contains ASCII value of key just pressed
+get_key:
+ jsr $ffe4
+ cmp #0
+ beq get_key
+ rts
+
+kipper_signature_not_found:
+
+ ldy #0
+:
+ lda kipper_signature_not_found_message,y
+ beq restart
+ jsr print_a
+ iny
+ jmp :-
+
+httpd_callback:
+ jsr print_vars
+ ldax #html
+ ldy #2 ;text/html
+ clc
+ rts
+
+
+.rodata
+
+kipper_signature:
+ .byte "KIPPER" ; API signature
+ error_code:
+ .asciiz "ERROR CODE: $"
+press_a_key_to_continue:
+ .byte "PRESS A KEY TO CONTINUE",13,0
+failed:
+ .byte "FAILED ", 0
+
+ok:
+ .byte "OK ", 0
+
+ kipper_signature_not_found_message:
+ .byte "NO KIPPER API FOUND",13,"PRESS ANY KEY TO RESET", 0
+initializing:
+ .byte "INITIALIZING ",0
+listening:
+ .byte "LISTENING",0
+said:
+ .byte ":",0
+html:
+ .byte "hello world %?mMessage recorded as '%$h:%$m'%. ",0
+
+;-- LICENSE FOR test_httpd.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_lancegs.s b/test/test_lancegs.s
similarity index 96%
rename from client/test/test_lancegs.s
rename to test/test_lancegs.s
index 76323e7..1a4a5f1 100644
--- a/client/test/test_lancegs.s
+++ b/test/test_lancegs.s
@@ -1,31 +1,31 @@
- .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 exit_to_basic
-
-
- .import __CODE_LOAD__
- .import __CODE_SIZE__
- .import __RODATA_SIZE__
- .import __DATA_SIZE__
- .import __IP65_DEFAULTS_SIZE__
-.segment "EXEHDR" ;this is what gets put an the start of the file on the Apple 2
- .addr __CODE_LOAD__-$03 ; Start address
- .word __CODE_SIZE__+__RODATA_SIZE__+__DATA_SIZE__+__IP65_DEFAULTS_SIZE__+4 ; file size
- jmp init
-
-.code
-
-init:
-cld
- jsr print_cr
- init_ip_via_dhcp
- jsr print_ip_config
- jsr print_cr
- jmp exit_to_basic
+ .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 exit_to_basic
+
+
+ .import __CODE_LOAD__
+ .import __CODE_SIZE__
+ .import __RODATA_SIZE__
+ .import __DATA_SIZE__
+ .import __IP65_DEFAULTS_SIZE__
+.segment "EXEHDR" ;this is what gets put an the start of the file on the Apple 2
+ .addr __CODE_LOAD__-$03 ; Start address
+ .word __CODE_SIZE__+__RODATA_SIZE__+__DATA_SIZE__+__IP65_DEFAULTS_SIZE__+4 ; file size
+ jmp init
+
+.code
+
+init:
+cld
+ jsr print_cr
+ init_ip_via_dhcp
+ jsr print_ip_config
+ jsr print_cr
+ jmp exit_to_basic
\ No newline at end of file
diff --git a/client/test/test_parse_querystring.s b/test/test_parse_querystring.s
similarity index 95%
rename from client/test/test_parse_querystring.s
rename to test/test_parse_querystring.s
index 47f97c7..0bb0ac5 100644
--- a/client/test/test_parse_querystring.s
+++ b/test/test_parse_querystring.s
@@ -1,142 +1,142 @@
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-.include "../inc/net.i"
-
-.import print_a
-.import get_key
-.import cfg_get_configuration_ptr
-.import ascii_to_native
-
-.import http_parse_request
-.import http_get_value
-
-
-.bss
-temp_ax: .res 2
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ;switch to lower case charset
- lda #23
- sta $d018
-
-
- ldax #query_1
- jsr test_querystring
- ldax #query_2
- jsr test_querystring
- ldax #query_3
- jsr test_querystring
- jsr get_key
- ldax #query_4
- jsr test_querystring
- ldax #query_5
- jsr test_querystring
- ldax #query_6
- jsr test_querystring
-
- rts
-
-test_querystring:
- stax temp_ax
- jsr print_ascii_as_native
- jsr print_cr
- ldax temp_ax
- jsr http_parse_request
-
- lda #1
- jsr print_var
- lda #2
- jsr print_var
- lda #'h'
- jsr print_var
- lda #'m'
- jsr print_var
- lda #'q'
- jsr print_var
- rts
-
-print_var:
- pha
- cmp #1
- beq @print_method
- cmp #2
- beq @print_path
- jsr ascii_to_native
-
- jsr print_a
-@print_equals:
- lda #'='
- jsr print_a
- pla
- jsr http_get_value
- bcc @found_var_value
- lda #'?'
- jsr print_a
- jmp print_cr
-@found_var_value:
- jsr print_ascii_as_native
- jmp print_cr
-
-@print_path:
- ldax #path
- jmp @print_caption
-@print_method:
- ldax #method
-@print_caption:
- jsr print_ascii_as_native
- jmp @print_equals
-
-.rodata
-path: .byte "path",0
-method: .byte "method",0
-
-query_1:
-.byte "GET /?h=slack&m=goober+woober+woo%21+%3B+i+am+text HTTP/1.1",0
-query_2:
-.byte "POST /?h=slack&m=goober+woober+woo!+%3b+i+am+text",0
-query_3:
-.byte "GET /?handle=slack&message=goober+woober+woo%21+%3B+i+am+text+%0d%0a%21%40%23%24%25%5E%26%25%5D%5B%7B%7D& HTTP/1.1",0
-query_4:
-.byte "GET /this/is/a/long/q/path.html?q=foo",0
-query_5:
-.byte "/this/is/a/gopher_selector",0
-query_6:
-.byte $0d,$0a,0 ;this should also be a gopher path
-
-
-
-
-;-- LICENSE FOR test_parse_querystring.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 --
+.include "../inc/common.i"
+.include "../inc/commonprint.i"
+.include "../inc/net.i"
+
+.import print_a
+.import get_key
+.import cfg_get_configuration_ptr
+.import ascii_to_native
+
+.import http_parse_request
+.import http_get_value
+
+
+.bss
+temp_ax: .res 2
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+basicstub:
+ .word @nextline
+ .word 2003
+ .byte $9e
+ .byte <(((init / 1000) .mod 10) + $30)
+ .byte <(((init / 100 ) .mod 10) + $30)
+ .byte <(((init / 10 ) .mod 10) + $30)
+ .byte <(((init ) .mod 10) + $30)
+ .byte 0
+@nextline:
+ .word 0
+
+init:
+
+ ;switch to lower case charset
+ lda #23
+ sta $d018
+
+
+ ldax #query_1
+ jsr test_querystring
+ ldax #query_2
+ jsr test_querystring
+ ldax #query_3
+ jsr test_querystring
+ jsr get_key
+ ldax #query_4
+ jsr test_querystring
+ ldax #query_5
+ jsr test_querystring
+ ldax #query_6
+ jsr test_querystring
+
+ rts
+
+test_querystring:
+ stax temp_ax
+ jsr print_ascii_as_native
+ jsr print_cr
+ ldax temp_ax
+ jsr http_parse_request
+
+ lda #1
+ jsr print_var
+ lda #2
+ jsr print_var
+ lda #'h'
+ jsr print_var
+ lda #'m'
+ jsr print_var
+ lda #'q'
+ jsr print_var
+ rts
+
+print_var:
+ pha
+ cmp #1
+ beq @print_method
+ cmp #2
+ beq @print_path
+ jsr ascii_to_native
+
+ jsr print_a
+@print_equals:
+ lda #'='
+ jsr print_a
+ pla
+ jsr http_get_value
+ bcc @found_var_value
+ lda #'?'
+ jsr print_a
+ jmp print_cr
+@found_var_value:
+ jsr print_ascii_as_native
+ jmp print_cr
+
+@print_path:
+ ldax #path
+ jmp @print_caption
+@print_method:
+ ldax #method
+@print_caption:
+ jsr print_ascii_as_native
+ jmp @print_equals
+
+.rodata
+path: .byte "path",0
+method: .byte "method",0
+
+query_1:
+.byte "GET /?h=slack&m=goober+woober+woo%21+%3B+i+am+text HTTP/1.1",0
+query_2:
+.byte "POST /?h=slack&m=goober+woober+woo!+%3b+i+am+text",0
+query_3:
+.byte "GET /?handle=slack&message=goober+woober+woo%21+%3B+i+am+text+%0d%0a%21%40%23%24%25%5E%26%25%5D%5B%7B%7D& HTTP/1.1",0
+query_4:
+.byte "GET /this/is/a/long/q/path.html?q=foo",0
+query_5:
+.byte "/this/is/a/gopher_selector",0
+query_6:
+.byte $0d,$0a,0 ;this should also be a gopher path
+
+
+
+
+;-- LICENSE FOR test_parse_querystring.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_parser.s b/test/test_parser.s
similarity index 94%
rename from client/test/test_parser.s
rename to test/test_parser.s
index 60d756b..0641a5b 100644
--- a/client/test/test_parser.s
+++ b/test/test_parser.s
@@ -1,236 +1,236 @@
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-.include "../inc/net.i"
-
-.import print_a
-.import get_key
-.import cfg_get_configuration_ptr
-.import ascii_to_native
-.import parser_init
-.import parser_skip_next
-.importzp copy_src
-.importzp copy_dest
-.import url_ip
-.import url_port
-.import url_selector
-.import url_resource_type
-.import url_parse
-temp_buff=copy_dest
-
-.bss
-
-string_offset: .res 1
-selector_ptr: .res 2
-temp_url_ptr: .res 2
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 2003
- .byte $9e
- .byte <(((init / 1000) .mod 10) + $30)
- .byte <(((init / 100 ) .mod 10) + $30)
- .byte <(((init / 10 ) .mod 10) + $30)
- .byte <(((init ) .mod 10) + $30)
- .byte 0
-@nextline:
- .word 0
-
-init:
-
- ;switch to lower case charset
- lda #23
- sta $d018
-
- init_ip_via_dhcp
- jsr print_ip_config
-
- ldax #url_1
- jsr test_url_parse
- jsr wait_key
-
-
- ldax #url_2
- jsr test_url_parse
- ldax #url_3
- jsr test_url_parse
- ldax #url_4
- jsr test_url_parse
- jsr wait_key
-
- ldax #url_5
- jsr test_url_parse
- ldax #url_6
- jsr test_url_parse
- ldax #url_7
- jsr test_url_parse
- ldax #url_8
- jsr test_url_parse
- jsr wait_key
-
- ldax #url_9
- jsr test_url_parse
- ldax #url_a
- jsr test_url_parse
- ldax #url_b
- jsr test_url_parse
- ldax #url_c
- jsr test_url_parse
-
- jsr wait_key
-
-
- ldax #atom_file
- jsr parser_init
-
-; ldax #entry
-; jsr parser_skip_next
-; bcs @done
-
-@next_title:
- ldax #title
- jsr parser_skip_next
- bcs @done
-
- jsr print_tag_contents
- jsr print_cr
-
- jmp @next_title
-@done:
- rts
-test_url_parse:
- stax temp_url_ptr
- ldax #parsing
- jsr print
- ldax temp_url_ptr
- jsr print
- jsr print_cr
- ldax temp_url_ptr
- jsr url_parse
- bcc :+
- jmp print_errorcode
- :
- stax selector_ptr
- jmp print_parsed_url
-
-print_tag_contents:
- stax temp_buff
- lda #0
- sta string_offset
-@next_byte:
- ldy string_offset
- lda (temp_buff),y
- beq @done
- cmp #'<'
- beq @done
- jsr ascii_to_native
- jsr print_a
- inc string_offset
- beq @done
- jmp @next_byte
-@done:
- rts
-
-print_parsed_url:
- ldax #ip
- jsr print
- ldax #url_ip
- jsr print_dotted_quad
- ldax #port
- jsr print
- ldax url_port
- jsr print_integer
- ldax #type
- jsr print
- lda url_resource_type
- jsr print_a
- jsr print_cr
- ldax #selector
- jsr print
- ldax selector_ptr
- jsr print
- jmp print_cr
-
-wait_key:
- ldax #press_a_key
- jsr print
- jmp get_key
-
-.data
-
-entry:
-.byte "",0
-title:
-.byte "",0
-
-url_1:
-.byte "http://www.jamtronix.com/",13,"not part of URL!",0
-
-url_2:
-.byte "http://www.jamtronix.com/goober",0
-
-url_3:
-.byte "http://www.jamtronix.com:8080/foo",0
-
-url_4:
-.byte "gopher://gopher.floodgap.com/",0
-
-url_5:
-.byte "gopher://10.5.1.164/0goober",0
-
-url_6:
-.byte "gopher://gopher.floodgap.com:7070/7/goober",0
-
-url_7:
-.byte "www.jamtronix.com",0
-
-url_8:
-.byte "jamtronix.com:70",0
-
-url_9:
-.byte "gopher.floodgap.com",0
-
-url_a:
-.byte "10.5.1.123:70",0
-
-url_b:
-.byte "gopher.floodgap.com:80",0
-
-url_c:
-.byte "gopher.floodgap.com:70",0
-
-
-parsing: .asciiz "PARSING "
-ip: .asciiz "IP: "
-port: .asciiz " PORT: "
-type: .asciiz " TYPE:"
-selector: .asciiz "SELECTOR: "
-press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0
-
-atom_file:
-;.incbin "atom_test.xml"
-
-
-.byte 0
-
-
-;-- LICENSE FOR test_parser.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 --
+.include "../inc/common.i"
+.include "../inc/commonprint.i"
+.include "../inc/net.i"
+
+.import print_a
+.import get_key
+.import cfg_get_configuration_ptr
+.import ascii_to_native
+.import parser_init
+.import parser_skip_next
+.importzp copy_src
+.importzp copy_dest
+.import url_ip
+.import url_port
+.import url_selector
+.import url_resource_type
+.import url_parse
+temp_buff=copy_dest
+
+.bss
+
+string_offset: .res 1
+selector_ptr: .res 2
+temp_url_ptr: .res 2
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+basicstub:
+ .word @nextline
+ .word 2003
+ .byte $9e
+ .byte <(((init / 1000) .mod 10) + $30)
+ .byte <(((init / 100 ) .mod 10) + $30)
+ .byte <(((init / 10 ) .mod 10) + $30)
+ .byte <(((init ) .mod 10) + $30)
+ .byte 0
+@nextline:
+ .word 0
+
+init:
+
+ ;switch to lower case charset
+ lda #23
+ sta $d018
+
+ init_ip_via_dhcp
+ jsr print_ip_config
+
+ ldax #url_1
+ jsr test_url_parse
+ jsr wait_key
+
+
+ ldax #url_2
+ jsr test_url_parse
+ ldax #url_3
+ jsr test_url_parse
+ ldax #url_4
+ jsr test_url_parse
+ jsr wait_key
+
+ ldax #url_5
+ jsr test_url_parse
+ ldax #url_6
+ jsr test_url_parse
+ ldax #url_7
+ jsr test_url_parse
+ ldax #url_8
+ jsr test_url_parse
+ jsr wait_key
+
+ ldax #url_9
+ jsr test_url_parse
+ ldax #url_a
+ jsr test_url_parse
+ ldax #url_b
+ jsr test_url_parse
+ ldax #url_c
+ jsr test_url_parse
+
+ jsr wait_key
+
+
+ ldax #atom_file
+ jsr parser_init
+
+; ldax #entry
+; jsr parser_skip_next
+; bcs @done
+
+@next_title:
+ ldax #title
+ jsr parser_skip_next
+ bcs @done
+
+ jsr print_tag_contents
+ jsr print_cr
+
+ jmp @next_title
+@done:
+ rts
+test_url_parse:
+ stax temp_url_ptr
+ ldax #parsing
+ jsr print
+ ldax temp_url_ptr
+ jsr print
+ jsr print_cr
+ ldax temp_url_ptr
+ jsr url_parse
+ bcc :+
+ jmp print_errorcode
+ :
+ stax selector_ptr
+ jmp print_parsed_url
+
+print_tag_contents:
+ stax temp_buff
+ lda #0
+ sta string_offset
+@next_byte:
+ ldy string_offset
+ lda (temp_buff),y
+ beq @done
+ cmp #'<'
+ beq @done
+ jsr ascii_to_native
+ jsr print_a
+ inc string_offset
+ beq @done
+ jmp @next_byte
+@done:
+ rts
+
+print_parsed_url:
+ ldax #ip
+ jsr print
+ ldax #url_ip
+ jsr print_dotted_quad
+ ldax #port
+ jsr print
+ ldax url_port
+ jsr print_integer
+ ldax #type
+ jsr print
+ lda url_resource_type
+ jsr print_a
+ jsr print_cr
+ ldax #selector
+ jsr print
+ ldax selector_ptr
+ jsr print
+ jmp print_cr
+
+wait_key:
+ ldax #press_a_key
+ jsr print
+ jmp get_key
+
+.data
+
+entry:
+.byte "",0
+title:
+.byte "",0
+
+url_1:
+.byte "http://www.jamtronix.com/",13,"not part of URL!",0
+
+url_2:
+.byte "http://www.jamtronix.com/goober",0
+
+url_3:
+.byte "http://www.jamtronix.com:8080/foo",0
+
+url_4:
+.byte "gopher://gopher.floodgap.com/",0
+
+url_5:
+.byte "gopher://10.5.1.164/0goober",0
+
+url_6:
+.byte "gopher://gopher.floodgap.com:7070/7/goober",0
+
+url_7:
+.byte "www.jamtronix.com",0
+
+url_8:
+.byte "jamtronix.com:70",0
+
+url_9:
+.byte "gopher.floodgap.com",0
+
+url_a:
+.byte "10.5.1.123:70",0
+
+url_b:
+.byte "gopher.floodgap.com:80",0
+
+url_c:
+.byte "gopher.floodgap.com:70",0
+
+
+parsing: .asciiz "PARSING "
+ip: .asciiz "IP: "
+port: .asciiz " PORT: "
+type: .asciiz " TYPE:"
+selector: .asciiz "SELECTOR: "
+press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0
+
+atom_file:
+;.incbin "atom_test.xml"
+
+
+.byte 0
+
+
+;-- LICENSE FOR test_parser.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_ping.s b/test/test_ping.s
similarity index 95%
rename from client/test/test_ping.s
rename to test/test_ping.s
index 3da4806..9b8275e 100644
--- a/client/test/test_ping.s
+++ b/test/test_ping.s
@@ -1,94 +1,94 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
- .import exit_to_basic
-
- .import cfg_get_configuration_ptr
- .import copymem
- .importzp copy_src
- .importzp copy_dest
-
- .import icmp_echo_ip
- .import icmp_ping
-
-
- .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
-
-.code
-
-init:
- jsr print_cr
- init_ip_via_dhcp
- jsr print_ip_config
- jsr print_cr
-
- ;our default gateway is probably a safe thing to ping
- ldx #$3
-:
- lda cfg_gateway,x
- sta icmp_echo_ip,x
- dex
- bpl :-
- ldax #pinging
- jsr print
-
- ldax #icmp_echo_ip
- jsr print_dotted_quad
- jsr print_cr
- jsr icmp_ping
- bcs @error
- jsr print_integer
- ldax #ms
- jsr print
- rts
-@error:
- jmp print_errorcode
-
-.rodata
-ms: .byte " MS",13,0
-pinging: .byte "PINGING ",0
-.bss
-block_number: .res 1
-block_length: .res 2
-buffer1: .res 256
-buffer2: .res 256
-
-
-;-- 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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+ .import exit_to_basic
+
+ .import cfg_get_configuration_ptr
+ .import copymem
+ .importzp copy_src
+ .importzp copy_dest
+
+ .import icmp_echo_ip
+ .import icmp_ping
+
+
+ .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
+
+.code
+
+init:
+ jsr print_cr
+ init_ip_via_dhcp
+ jsr print_ip_config
+ jsr print_cr
+
+ ;our default gateway is probably a safe thing to ping
+ ldx #$3
+:
+ lda cfg_gateway,x
+ sta icmp_echo_ip,x
+ dex
+ bpl :-
+ ldax #pinging
+ jsr print
+
+ ldax #icmp_echo_ip
+ jsr print_dotted_quad
+ jsr print_cr
+ jsr icmp_ping
+ bcs @error
+ jsr print_integer
+ ldax #ms
+ jsr print
+ rts
+@error:
+ jmp print_errorcode
+
+.rodata
+ms: .byte " MS",13,0
+pinging: .byte "PINGING ",0
+.bss
+block_number: .res 1
+block_length: .res 2
+buffer1: .res 256
+buffer2: .res 256
+
+
+;-- 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/test/test_sntp.s
similarity index 95%
rename from client/test/test_sntp.s
rename to test/test_sntp.s
index 4ea3aaa..8d62ddf 100644
--- a/client/test/test_sntp.s
+++ b/test/test_sntp.s
@@ -1,131 +1,131 @@
- .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
-
-init:
- lda #14
- jsr print_a ;switch to lower case
- 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
-
-
-.data
-
-
-
-time_server_msg:
- .byte "TIME SERVER : ",0
-
-time_server_host:
- .byte "jamtronix.com",0
-; .byte "150.101.112.134",0
- .byte "0.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 --
+ .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
+
+init:
+ lda #14
+ jsr print_a ;switch to lower case
+ 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
+
+
+.data
+
+
+
+time_server_msg:
+ .byte "TIME SERVER : ",0
+
+time_server_host:
+ .byte "jamtronix.com",0
+; .byte "150.101.112.134",0
+ .byte "0.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_tcp.s b/test/test_tcp.s
similarity index 93%
rename from client/test/test_tcp.s
rename to test/test_tcp.s
index 5c2eabd..c579812 100644
--- a/client/test/test_tcp.s
+++ b/test/test_tcp.s
@@ -1,645 +1,645 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
- .import exit_to_basic
- .import ascii_to_native
- .import parse_dotted_quad
- .import dotted_quad_value
-
- .import tcp_listen
- .import tcp_callback
- .import ip65_random_word
- .import ip65_error
-
- .import tcp_connect
- .import tcp_connect_ip
-
- .import tcp_inbound_data_ptr
- .import tcp_inbound_data_length
-
- .import tcp_send
- .import tcp_send_data_len
-
- .import __CODE_LOAD__
- .import __CODE_SIZE__
- .import __RODATA_SIZE__
- .import __DATA_SIZE__
-
-
- .importzp acc32
- .importzp op32
- .importzp acc16
-
- .import add_32_32
- .import add_16_32
- .import cmp_32_32
- .import cmp_16_16
- .import mul_8_16
-
- .import sub_16_16
-
- .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
-
-.bss
-cxn_closed: .res 1
-byte_counter: .res 1
-
-.data
-get_next_byte:
- lda $ffff
- rts
-
-.code
-
-init:
-
-
- ldax #$1234
- stax acc16
- ldax #$1235
- jsr test_sub_16_16
-
- ldax #$180
- stax acc16
- ldax #$28
- jsr test_sub_16_16
-
- rts
- ldax #$ff34
- stax acc16
- ldax #$1235
- jsr test_sub_16_16
-
- ldax #$100
- stax acc16
- ldax #$ffff
- jsr test_sub_16_16
-
- ldax #$ffff
- stax acc16
- ldax #$100
- jsr test_sub_16_16
-
-
- ldax #number1
- stax acc32
- stax op32
- jsr test_cmp_32_32
-
- ldax #number1
- stax acc32
- ldax #number13
- stax op32
- jsr test_cmp_32_32
-
- ldax #number1
- stax acc32
- ldax #number2
- stax op32
- jsr test_cmp_32_32
-
- ldax #$12
- stax acc16
- jsr test_cmp_16_16
-
- ldax #$1234
- stax acc16
- jsr test_cmp_16_16
-
- ldax #$1234
- stax acc16
- ldax #$1235
- jsr test_cmp_16_16
-
-
- ldax #$1234
- stax acc16
- ldax #$2234
- jsr test_cmp_16_16
-
-
- ldax #$0000
- stax acc16
- jsr test_cmp_16_16
-
- ldax #$FFFF
- stax acc16
- jsr test_cmp_16_16
-
-
-
- ldax #number1
- stax acc32
- ldax #number2
- stax op32
- jsr test_add_32_32
-
-
-
- ldax #number3
- stax acc32
- ldax #number4
- stax op32
- jsr test_add_32_32
-
- ldax #number5
- stax acc32
- ldax #number6
- stax op32
- jsr test_add_32_32
-
- ldax #number7
- stax acc32
- ldax #number8
- stax op32
- jsr test_add_32_32
-
- ldax #number9
- stax acc32
- ldax #number10
- stax op32
- jsr test_add_32_32
-
- ldax #number11
- stax acc32
- ldax #number12
- stax op32
- jsr test_add_32_32
-
-
- ldax #number13
- stax acc32
- ldax #$1234
- jsr test_add_16_32
-
- ldax #number14
- stax acc32
- ldax #$1234
- jsr test_add_16_32
-
- ldax #number15
- stax acc32
- ldax #$1234
- jsr test_add_16_32
-
- ldax #number16
- stax acc32
- ldax #$1234
- jsr test_add_16_32
-
- ldax #number17
- stax acc32
- ldax #$158
- jsr test_add_16_32
-
-
- jsr print_cr
- init_ip_via_dhcp
- jsr print_ip_config
-
- jsr print_cr
-
-
- jsr print_random_number
-
- ;connect to port 81 - should be rejected
-
- ldax #tcp_callback_routine
- stax tcp_callback
- ldax tcp_dest_ip
- stax tcp_connect_ip
- ldax tcp_dest_ip+2
- stax tcp_connect_ip+2
-
- ldax #81
- jsr tcp_connect
- jsr check_for_error
-
- ldax #http_get_length
- stax tcp_send_data_len
- ldax #http_get_msg
- jsr tcp_send
- jsr check_for_error
-
- ;now try to connect to port 80 - should be accepted
-
- ldax #tcp_callback_routine
- stax tcp_callback
- ldax tcp_dest_ip
- stax tcp_connect_ip
- ldax tcp_dest_ip+2
- stax tcp_connect_ip+2
-
-
- ldax #80
- jsr tcp_connect
- jsr check_for_error
-
- lda #0
- sta cxn_closed
-
- ldax #http_get_length
- stax tcp_send_data_len
- ldax #http_get_msg
- jsr tcp_send
- jsr check_for_error
-
-@loop_till_end:
- jsr ip65_process
- lda #1
- cmp cxn_closed
-
- beq @loop_till_end
-
- rts
-
-
- ldax #tcp_callback_routine
- stax tcp_callback
- ldax tcp_dest_ip
- stax tcp_connect_ip
- ldax tcp_dest_ip+2
- stax tcp_connect_ip+2
-
-
-
- ldax #80
- jsr tcp_connect
- jsr check_for_error
-
- ldax #4
- stax tcp_send_data_len
- ldax #http_get_msg
- jsr tcp_send
- jsr check_for_error
- ldax #http_get_length-4
- stax tcp_send_data_len
- ldax #http_get_msg+4
- jsr tcp_send
- jsr check_for_error
-
-
- ldax #looping
- jsr print
-@loop_forever:
- jsr ip65_process
- jmp @loop_forever
- rts
-
-tcp_callback_routine:
-
-
-
- lda tcp_inbound_data_length
- cmp #$ff
- bne @not_end_of_file
- lda #1
- sta cxn_closed
- rts
-
-@not_end_of_file:
- lda #14
- jsr print_a ;switch to lower case
-
-
- ldax tcp_inbound_data_ptr
- stax get_next_byte+1
-
- lda #0
- sta byte_counter
- sta byte_counter+1
-
-@print_one_byte:
- jsr get_next_byte
- jsr ascii_to_native
-
- jsr print_a
- inc get_next_byte+1
- bne :+
- inc get_next_byte+2
-:
-
- inc byte_counter
- bne :+
- inc byte_counter+1
-:
- ldax byte_counter
- stax acc16
- ldax tcp_inbound_data_length
- jsr cmp_16_16
- bne @print_one_byte
-
- rts
-
-
-
-check_for_error:
- lda ip65_error
- beq @exit
- ldax #error_code
- jsr print
- lda ip65_error
- jsr print_hex
- jsr print_cr
- lda #0
- sta ip65_error
-@exit:
- rts
-
-print_random_number:
- jsr ip65_random_word
- stx temp_ax
- jsr print_hex
- lda temp_ax
- jsr print_hex
- jsr print_cr
- rts
-
-;assumes acc32 & op32 already set
-test_add_32_32:
- ldy #3
-:
- lda (acc32),y
- jsr print_hex
- dey
- bpl :-
-
- lda #'+'
- jsr print_a
- ldy #3
-:
- lda (op32),y
- jsr print_hex
- dey
- bpl :-
-
- lda #'='
- jsr print_a
- jsr add_32_32
-
- ldy #3
-:
- lda (acc32),y
- jsr print_hex
- dey
- bpl :-
- jsr print_cr
- rts
-
-
-
-;assumes acc32 & op32 already set
-test_cmp_32_32:
- ldy #3
-:
- lda (acc32),y
- jsr print_hex
- dey
- bpl :-
-
- lda #'='
- jsr print_a
- ldy #3
-:
- lda (op32),y
- jsr print_hex
- dey
- bpl :-
-
- lda #':'
- jsr print_a
- jsr cmp_32_32
- bne @not_equal
- lda #'T'
- jmp @char_set
-@not_equal:
- lda #'F'
-@char_set:
- jsr print_a
- jsr print_cr
- rts
-
-;assumes acc16& AX already set
-test_cmp_16_16:
- stax temp_ax
- lda acc16+1
- jsr print_hex
- lda acc16
- jsr print_hex
-
- lda #'='
- jsr print_a
- lda temp_ax+1
- jsr print_hex
- lda temp_ax
- jsr print_hex
-
- lda #':'
- jsr print_a
- ldax temp_ax
- jsr cmp_16_16
- bne @not_equal
- lda #'T'
- jmp @char_set
-@not_equal:
- lda #'F'
-@char_set:
- jsr print_a
- jsr print_cr
- rts
-
-
-;assumes acc32 & AX already set
-test_add_16_32:
- stax temp_ax
- ldy #3
-:
- lda (acc32),y
- jsr print_hex
- dey
- bpl :-
-
- lda #'+'
- jsr print_a
-
- lda temp_ax+1
- jsr print_hex
- lda temp_ax
- jsr print_hex
-
- lda #'='
- jsr print_a
- ldax temp_ax
- jsr add_16_32
-
- ldy #3
-:
- lda (acc32),y
- jsr print_hex
- dey
- bpl :-
- jsr print_cr
- rts
-
-;assumes acc16& A already set
-test_mul_8_16:
- sta temp_ax
- lda acc16+1
- jsr print_hex
- lda acc16
- jsr print_hex
-
- lda #'*'
- jsr print_a
- lda temp_ax
- jsr print_hex
-
- lda #'='
- jsr print_a
- lda temp_ax
- jsr mul_8_16
- lda acc16+1
- jsr print_hex
- lda acc16
- jsr print_hex
- jsr print_cr
- rts
-
-
-;assumes acc16 & AX already set
-test_sub_16_16:
- stax temp_ax
-
- lda acc16+1
- jsr print_hex
- lda acc16
- jsr print_hex
-
- lda #'-'
- jsr print_a
-
- lda temp_ax+1
- jsr print_hex
- lda temp_ax
- jsr print_hex
-
- lda #'='
- jsr print_a
- ldax temp_ax
- jsr sub_16_16
-
- lda acc16+1
- jsr print_hex
- lda acc16
- jsr print_hex
-
- jsr print_cr
- rts
-
-
-@error:
- ldax #failed_msg
- jsr print
- jsr print_cr
- rts
-
- .bss
- temp_ax: .res 2
-
- .rodata
-
-
-.data
-number1:
- .byte $1,$2,$3,$f
-number2:
-.byte $10,$20,$30,$f0
-number3:
- .byte $ff,$ff,$ff,$ff
-number4:
- .byte $1,$0,$0,$0
-
-number5:
- .byte $ff,$ff,$ff,$ff
-number6:
- .byte $0,$0,$0,$0
-number7:
- .byte $ff,$ff,$ff,$fe
-number8:
- .byte $1,$0,$0,$0
-number9:
- .byte $ff,$ff,$ff,$fe
-number10:
- .byte $5,$0,$0,$0
-number11:
- .byte $ff,$0,$0,$e
-number12:
- .byte $5,$0,$0,$0
-
-number13:
- .byte $1,$2,$3,$4
-
-number14:
- .byte $ff,$ff,$ff,$ff
-
-number15:
- .byte $ff,$ff,$00,$00
-
-number16:
- .byte $00,$00,$00,$00
-
-number17:
- .byte $5b,$bc,$08,$a9
-
-tcp_dest_ip:
- ; .byte 10,5,1,1
- .byte 74,207,242,229
-looping:
- .asciiz "LOOPING..."
-
-http_get_msg:
- .byte "GET /blogx/ HTTP/1.0",13,10,13,10
-http_get_msg_end:
- http_get_length=http_get_msg_end-http_get_msg
-
-
-
-
-;-- LICENSE FOR test_tcp.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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+ .import exit_to_basic
+ .import ascii_to_native
+ .import parse_dotted_quad
+ .import dotted_quad_value
+
+ .import tcp_listen
+ .import tcp_callback
+ .import ip65_random_word
+ .import ip65_error
+
+ .import tcp_connect
+ .import tcp_connect_ip
+
+ .import tcp_inbound_data_ptr
+ .import tcp_inbound_data_length
+
+ .import tcp_send
+ .import tcp_send_data_len
+
+ .import __CODE_LOAD__
+ .import __CODE_SIZE__
+ .import __RODATA_SIZE__
+ .import __DATA_SIZE__
+
+
+ .importzp acc32
+ .importzp op32
+ .importzp acc16
+
+ .import add_32_32
+ .import add_16_32
+ .import cmp_32_32
+ .import cmp_16_16
+ .import mul_8_16
+
+ .import sub_16_16
+
+ .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
+
+.bss
+cxn_closed: .res 1
+byte_counter: .res 1
+
+.data
+get_next_byte:
+ lda $ffff
+ rts
+
+.code
+
+init:
+
+
+ ldax #$1234
+ stax acc16
+ ldax #$1235
+ jsr test_sub_16_16
+
+ ldax #$180
+ stax acc16
+ ldax #$28
+ jsr test_sub_16_16
+
+ rts
+ ldax #$ff34
+ stax acc16
+ ldax #$1235
+ jsr test_sub_16_16
+
+ ldax #$100
+ stax acc16
+ ldax #$ffff
+ jsr test_sub_16_16
+
+ ldax #$ffff
+ stax acc16
+ ldax #$100
+ jsr test_sub_16_16
+
+
+ ldax #number1
+ stax acc32
+ stax op32
+ jsr test_cmp_32_32
+
+ ldax #number1
+ stax acc32
+ ldax #number13
+ stax op32
+ jsr test_cmp_32_32
+
+ ldax #number1
+ stax acc32
+ ldax #number2
+ stax op32
+ jsr test_cmp_32_32
+
+ ldax #$12
+ stax acc16
+ jsr test_cmp_16_16
+
+ ldax #$1234
+ stax acc16
+ jsr test_cmp_16_16
+
+ ldax #$1234
+ stax acc16
+ ldax #$1235
+ jsr test_cmp_16_16
+
+
+ ldax #$1234
+ stax acc16
+ ldax #$2234
+ jsr test_cmp_16_16
+
+
+ ldax #$0000
+ stax acc16
+ jsr test_cmp_16_16
+
+ ldax #$FFFF
+ stax acc16
+ jsr test_cmp_16_16
+
+
+
+ ldax #number1
+ stax acc32
+ ldax #number2
+ stax op32
+ jsr test_add_32_32
+
+
+
+ ldax #number3
+ stax acc32
+ ldax #number4
+ stax op32
+ jsr test_add_32_32
+
+ ldax #number5
+ stax acc32
+ ldax #number6
+ stax op32
+ jsr test_add_32_32
+
+ ldax #number7
+ stax acc32
+ ldax #number8
+ stax op32
+ jsr test_add_32_32
+
+ ldax #number9
+ stax acc32
+ ldax #number10
+ stax op32
+ jsr test_add_32_32
+
+ ldax #number11
+ stax acc32
+ ldax #number12
+ stax op32
+ jsr test_add_32_32
+
+
+ ldax #number13
+ stax acc32
+ ldax #$1234
+ jsr test_add_16_32
+
+ ldax #number14
+ stax acc32
+ ldax #$1234
+ jsr test_add_16_32
+
+ ldax #number15
+ stax acc32
+ ldax #$1234
+ jsr test_add_16_32
+
+ ldax #number16
+ stax acc32
+ ldax #$1234
+ jsr test_add_16_32
+
+ ldax #number17
+ stax acc32
+ ldax #$158
+ jsr test_add_16_32
+
+
+ jsr print_cr
+ init_ip_via_dhcp
+ jsr print_ip_config
+
+ jsr print_cr
+
+
+ jsr print_random_number
+
+ ;connect to port 81 - should be rejected
+
+ ldax #tcp_callback_routine
+ stax tcp_callback
+ ldax tcp_dest_ip
+ stax tcp_connect_ip
+ ldax tcp_dest_ip+2
+ stax tcp_connect_ip+2
+
+ ldax #81
+ jsr tcp_connect
+ jsr check_for_error
+
+ ldax #http_get_length
+ stax tcp_send_data_len
+ ldax #http_get_msg
+ jsr tcp_send
+ jsr check_for_error
+
+ ;now try to connect to port 80 - should be accepted
+
+ ldax #tcp_callback_routine
+ stax tcp_callback
+ ldax tcp_dest_ip
+ stax tcp_connect_ip
+ ldax tcp_dest_ip+2
+ stax tcp_connect_ip+2
+
+
+ ldax #80
+ jsr tcp_connect
+ jsr check_for_error
+
+ lda #0
+ sta cxn_closed
+
+ ldax #http_get_length
+ stax tcp_send_data_len
+ ldax #http_get_msg
+ jsr tcp_send
+ jsr check_for_error
+
+@loop_till_end:
+ jsr ip65_process
+ lda #1
+ cmp cxn_closed
+
+ beq @loop_till_end
+
+ rts
+
+
+ ldax #tcp_callback_routine
+ stax tcp_callback
+ ldax tcp_dest_ip
+ stax tcp_connect_ip
+ ldax tcp_dest_ip+2
+ stax tcp_connect_ip+2
+
+
+
+ ldax #80
+ jsr tcp_connect
+ jsr check_for_error
+
+ ldax #4
+ stax tcp_send_data_len
+ ldax #http_get_msg
+ jsr tcp_send
+ jsr check_for_error
+ ldax #http_get_length-4
+ stax tcp_send_data_len
+ ldax #http_get_msg+4
+ jsr tcp_send
+ jsr check_for_error
+
+
+ ldax #looping
+ jsr print
+@loop_forever:
+ jsr ip65_process
+ jmp @loop_forever
+ rts
+
+tcp_callback_routine:
+
+
+
+ lda tcp_inbound_data_length
+ cmp #$ff
+ bne @not_end_of_file
+ lda #1
+ sta cxn_closed
+ rts
+
+@not_end_of_file:
+ lda #14
+ jsr print_a ;switch to lower case
+
+
+ ldax tcp_inbound_data_ptr
+ stax get_next_byte+1
+
+ lda #0
+ sta byte_counter
+ sta byte_counter+1
+
+@print_one_byte:
+ jsr get_next_byte
+ jsr ascii_to_native
+
+ jsr print_a
+ inc get_next_byte+1
+ bne :+
+ inc get_next_byte+2
+:
+
+ inc byte_counter
+ bne :+
+ inc byte_counter+1
+:
+ ldax byte_counter
+ stax acc16
+ ldax tcp_inbound_data_length
+ jsr cmp_16_16
+ bne @print_one_byte
+
+ rts
+
+
+
+check_for_error:
+ lda ip65_error
+ beq @exit
+ ldax #error_code
+ jsr print
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+ lda #0
+ sta ip65_error
+@exit:
+ rts
+
+print_random_number:
+ jsr ip65_random_word
+ stx temp_ax
+ jsr print_hex
+ lda temp_ax
+ jsr print_hex
+ jsr print_cr
+ rts
+
+;assumes acc32 & op32 already set
+test_add_32_32:
+ ldy #3
+:
+ lda (acc32),y
+ jsr print_hex
+ dey
+ bpl :-
+
+ lda #'+'
+ jsr print_a
+ ldy #3
+:
+ lda (op32),y
+ jsr print_hex
+ dey
+ bpl :-
+
+ lda #'='
+ jsr print_a
+ jsr add_32_32
+
+ ldy #3
+:
+ lda (acc32),y
+ jsr print_hex
+ dey
+ bpl :-
+ jsr print_cr
+ rts
+
+
+
+;assumes acc32 & op32 already set
+test_cmp_32_32:
+ ldy #3
+:
+ lda (acc32),y
+ jsr print_hex
+ dey
+ bpl :-
+
+ lda #'='
+ jsr print_a
+ ldy #3
+:
+ lda (op32),y
+ jsr print_hex
+ dey
+ bpl :-
+
+ lda #':'
+ jsr print_a
+ jsr cmp_32_32
+ bne @not_equal
+ lda #'T'
+ jmp @char_set
+@not_equal:
+ lda #'F'
+@char_set:
+ jsr print_a
+ jsr print_cr
+ rts
+
+;assumes acc16& AX already set
+test_cmp_16_16:
+ stax temp_ax
+ lda acc16+1
+ jsr print_hex
+ lda acc16
+ jsr print_hex
+
+ lda #'='
+ jsr print_a
+ lda temp_ax+1
+ jsr print_hex
+ lda temp_ax
+ jsr print_hex
+
+ lda #':'
+ jsr print_a
+ ldax temp_ax
+ jsr cmp_16_16
+ bne @not_equal
+ lda #'T'
+ jmp @char_set
+@not_equal:
+ lda #'F'
+@char_set:
+ jsr print_a
+ jsr print_cr
+ rts
+
+
+;assumes acc32 & AX already set
+test_add_16_32:
+ stax temp_ax
+ ldy #3
+:
+ lda (acc32),y
+ jsr print_hex
+ dey
+ bpl :-
+
+ lda #'+'
+ jsr print_a
+
+ lda temp_ax+1
+ jsr print_hex
+ lda temp_ax
+ jsr print_hex
+
+ lda #'='
+ jsr print_a
+ ldax temp_ax
+ jsr add_16_32
+
+ ldy #3
+:
+ lda (acc32),y
+ jsr print_hex
+ dey
+ bpl :-
+ jsr print_cr
+ rts
+
+;assumes acc16& A already set
+test_mul_8_16:
+ sta temp_ax
+ lda acc16+1
+ jsr print_hex
+ lda acc16
+ jsr print_hex
+
+ lda #'*'
+ jsr print_a
+ lda temp_ax
+ jsr print_hex
+
+ lda #'='
+ jsr print_a
+ lda temp_ax
+ jsr mul_8_16
+ lda acc16+1
+ jsr print_hex
+ lda acc16
+ jsr print_hex
+ jsr print_cr
+ rts
+
+
+;assumes acc16 & AX already set
+test_sub_16_16:
+ stax temp_ax
+
+ lda acc16+1
+ jsr print_hex
+ lda acc16
+ jsr print_hex
+
+ lda #'-'
+ jsr print_a
+
+ lda temp_ax+1
+ jsr print_hex
+ lda temp_ax
+ jsr print_hex
+
+ lda #'='
+ jsr print_a
+ ldax temp_ax
+ jsr sub_16_16
+
+ lda acc16+1
+ jsr print_hex
+ lda acc16
+ jsr print_hex
+
+ jsr print_cr
+ rts
+
+
+@error:
+ ldax #failed_msg
+ jsr print
+ jsr print_cr
+ rts
+
+ .bss
+ temp_ax: .res 2
+
+ .rodata
+
+
+.data
+number1:
+ .byte $1,$2,$3,$f
+number2:
+.byte $10,$20,$30,$f0
+number3:
+ .byte $ff,$ff,$ff,$ff
+number4:
+ .byte $1,$0,$0,$0
+
+number5:
+ .byte $ff,$ff,$ff,$ff
+number6:
+ .byte $0,$0,$0,$0
+number7:
+ .byte $ff,$ff,$ff,$fe
+number8:
+ .byte $1,$0,$0,$0
+number9:
+ .byte $ff,$ff,$ff,$fe
+number10:
+ .byte $5,$0,$0,$0
+number11:
+ .byte $ff,$0,$0,$e
+number12:
+ .byte $5,$0,$0,$0
+
+number13:
+ .byte $1,$2,$3,$4
+
+number14:
+ .byte $ff,$ff,$ff,$ff
+
+number15:
+ .byte $ff,$ff,$00,$00
+
+number16:
+ .byte $00,$00,$00,$00
+
+number17:
+ .byte $5b,$bc,$08,$a9
+
+tcp_dest_ip:
+ ; .byte 10,5,1,1
+ .byte 74,207,242,229
+looping:
+ .asciiz "LOOPING..."
+
+http_get_msg:
+ .byte "GET /blogx/ HTTP/1.0",13,10,13,10
+http_get_msg_end:
+ http_get_length=http_get_msg_end-http_get_msg
+
+
+
+
+;-- LICENSE FOR test_tcp.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/test/test_vic20.s
similarity index 95%
rename from client/test/test_vic20.s
rename to test/test_vic20.s
index 524b667..3c28835 100644
--- a/client/test/test_vic20.s
+++ b/test/test_vic20.s
@@ -1,90 +1,90 @@
-.ifndef SCREEN_WIDTH
- SCREEN_WIDTH = 22
-.endif
-
-
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
-.import timer_init
-.import timer_read
-.import timer_seconds
-.import beep
-.import check_for_abort_key
-.import get_key_if_available
- .segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
- .word basicstub ; load address
-
-basicstub:
- .word @nextline
- .word 20
- .byte $9e ;SYS
- .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
- .word 0
-
-.code
-
-init:
- lda #14
- jsr print_a ;switch to lower case
-
- jsr timer_init
- init_ip_via_dhcp
- 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
-@loop2:
-
- jsr get_key_if_available
- beq @loop2
- jsr print_hex
- jsr check_for_abort_key
- bcc @loop2
- rts
-
-
-print_ax:
- pha
- txa
- jsr print_hex
- pla
- jmp print_hex
-
-.data
-last_seconds: .byte 0
-
-;-- LICENSE FOR test_tcp.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 --
+.ifndef SCREEN_WIDTH
+ SCREEN_WIDTH = 22
+.endif
+
+
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+.import timer_init
+.import timer_read
+.import timer_seconds
+.import beep
+.import check_for_abort_key
+.import get_key_if_available
+ .segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+ .word basicstub ; load address
+
+basicstub:
+ .word @nextline
+ .word 20
+ .byte $9e ;SYS
+ .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
+ .word 0
+
+.code
+
+init:
+ lda #14
+ jsr print_a ;switch to lower case
+
+ jsr timer_init
+ init_ip_via_dhcp
+ 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
+@loop2:
+
+ jsr get_key_if_available
+ beq @loop2
+ jsr print_hex
+ jsr check_for_abort_key
+ bcc @loop2
+ rts
+
+
+print_ax:
+ pha
+ txa
+ jsr print_hex
+ pla
+ jmp print_hex
+
+.data
+last_seconds: .byte 0
+
+;-- LICENSE FOR test_tcp.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_vt100.s b/test/test_vt100.s
similarity index 95%
rename from client/test/test_vt100.s
rename to test/test_vt100.s
index b1de18c..24a2ec9 100644
--- a/client/test/test_vt100.s
+++ b/test/test_vt100.s
@@ -1,105 +1,105 @@
-
-.ifndef KIPPER_API_VERSION_NUMBER
- .define EQU =
- .include "../inc/kipper_constants.i"
-.endif
-
-.include "../inc/common.i"
-.include "../inc/commonprint.i"
-.import print_a
-.import cfg_get_configuration_ptr
-
-.import get_key
-.import timer_init
-.import beep
-.segment "STARTUP" ;this is what gets put at the start of the file on the C64
-
-.word basicstub ; load address
-
-.import vt100_init_terminal
-.import vt100_process_inbound_char
-
-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
-
-.code
-init:
-
- jsr timer_init
- jsr vt100_init_terminal
- ldax #string1
- jsr emit_string
-
- rts
-
-
-emit_string:
- stax next_byte+1
-:
- jsr next_byte
-
- beq @done
- jsr vt100_process_inbound_char
- jmp :-
-@done:
- rts
-
-next_byte:
- lda $ffff
- inc next_byte+1
- bne :+
- inc next_byte+2
-:
- cmp #0
- rts
-
-
-.rodata
-
-string1:
-.byte $1b,"[H" ;HOME
-.byte "hello world",13,10
-.byte $1b,"[1m" ;BOLD
-.byte "hello bold",13,10
-.byte $1b,"[7m" ;reverse
-.byte "hello reverse bold",13,10
-.byte $1b,"7" ;save cursor position & attributes
-.byte $1b,"[m" ;normal
-.byte "hello normal",13,10
-.byte 07
-.byte "that was a beep!",13,10
-.byte $1b,"8" ;restor cursor position & attributes
-.byte $1b,"[20;1H"; ;move to row 20, pos 1
-.byte "ABCDEFGhijklmnopqRsTuVwXyZ01234567890"
-.byte $1b,"[20;10f"; ;move to row 20, pos 1
-.byte $1b,"[1K"
-
-.byte 0
-
-;-- LICENSE FOR test_vt00.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 --
+
+.ifndef KIPPER_API_VERSION_NUMBER
+ .define EQU =
+ .include "../inc/kipper_constants.i"
+.endif
+
+.include "../inc/common.i"
+.include "../inc/commonprint.i"
+.import print_a
+.import cfg_get_configuration_ptr
+
+.import get_key
+.import timer_init
+.import beep
+.segment "STARTUP" ;this is what gets put at the start of the file on the C64
+
+.word basicstub ; load address
+
+.import vt100_init_terminal
+.import vt100_process_inbound_char
+
+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
+
+.code
+init:
+
+ jsr timer_init
+ jsr vt100_init_terminal
+ ldax #string1
+ jsr emit_string
+
+ rts
+
+
+emit_string:
+ stax next_byte+1
+:
+ jsr next_byte
+
+ beq @done
+ jsr vt100_process_inbound_char
+ jmp :-
+@done:
+ rts
+
+next_byte:
+ lda $ffff
+ inc next_byte+1
+ bne :+
+ inc next_byte+2
+:
+ cmp #0
+ rts
+
+
+.rodata
+
+string1:
+.byte $1b,"[H" ;HOME
+.byte "hello world",13,10
+.byte $1b,"[1m" ;BOLD
+.byte "hello bold",13,10
+.byte $1b,"[7m" ;reverse
+.byte "hello reverse bold",13,10
+.byte $1b,"7" ;save cursor position & attributes
+.byte $1b,"[m" ;normal
+.byte "hello normal",13,10
+.byte 07
+.byte "that was a beep!",13,10
+.byte $1b,"8" ;restor cursor position & attributes
+.byte $1b,"[20;1H"; ;move to row 20, pos 1
+.byte "ABCDEFGhijklmnopqRsTuVwXyZ01234567890"
+.byte $1b,"[20;10f"; ;move to row 20, pos 1
+.byte $1b,"[1K"
+
+.byte 0
+
+;-- LICENSE FOR test_vt00.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_wiznet.s b/test/test_wiznet.s
similarity index 93%
rename from client/test/test_wiznet.s
rename to test/test_wiznet.s
index 3960a84..a56ca87 100644
--- a/client/test/test_wiznet.s
+++ b/test/test_wiznet.s
@@ -1,455 +1,455 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
- .include "../drivers/w5100.i"
-
- .import exit_to_basic
-
- .import cfg_get_configuration_ptr
- .import copymem
- .importzp copy_src
- .importzp copy_dest
- .import icmp_echo_ip
- .import icmp_ping
- .import get_key_ip65
- .import w5100_ip65_init
- .import w5100_read_register
- .import dns_set_hostname
- .import dns_resolve
- .import dns_ip
- .import dns_status
-
- .import tcp_connect
- .import tcp_connect_ip
- .import tcp_callback
- .import tcp_send_string
- .import tcp_close
- .import tcp_inbound_data_ptr
- .import tcp_inbound_data_length
- .import tcp_connect_remote_port
- .import tcp_remote_ip
- .import tcp_listen
- .importzp acc16
- .import cmp_16_16
-
-
- .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
-
-.code
-
-init:
-
- ldax #starting
- jsr print
-@loop:
- inc $d020
- jmp @loop
-
-
- ldax #$DE00
- jsr probe_for_w5100
- bcc @found
- ldax #$DF00
- jsr probe_for_w5100
- bcc @found
- ldax #$DF20
- jsr probe_for_w5100
- bcc @found
- ldax #no_wiznet
- jmp print
- rts
-
-@found:
- jsr dhcp_init
- lda #0
- jsr dump_wiznet_register_page
- lda #4
- jsr dump_wiznet_register_page
-
-@skip:
-
-
- jsr print_ip_config
-
- jsr ping_test
- jsr ping_test_2
-
- jsr tcp_listen_test
-
- ldax #hostname_1
- jsr do_dns_query
- bcs :+
- jsr ping_test_3
- jsr tcp_test
-:
- rts
-
-
-tcp_listen_test:
-
- ldax #tcp_callback_routine
- stax tcp_callback
- ldax #listening
- jsr print
- ldax #80
-
- jsr tcp_listen
- bcc :+
- ldax #error
- jsr print
- lda ip65_error
- jsr print_hex
- jsr print_cr
- rts
-:
-
- 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
- jmp send_tcp_data
-
-tcp_test:
-
- ldax #tcp_callback_routine
- stax tcp_callback
-
- ;send without connecting - should get an error
- ldax #http_string1
- jsr tcp_send_string
- bcc :+
- ldax #error
- jsr print
- lda ip65_error
- jsr print_hex
- jsr print_cr
-:
- ldx #$3
-:
- lda dns_ip,x
- sta tcp_connect_ip,x
- dex
- bpl :-
- ldax #connecting
- jsr print
-
- ldax #tcp_connect_ip
- jsr print_dotted_quad
- jsr print_cr
-
-
- ldax #80 ;port number
-
- jsr tcp_connect
- bcc @no_error
- ldax #error
- jsr print
- lda ip65_error
- jsr print_hex
- jsr print_cr
- lda #0
- jsr dump_wiznet_register_page
- lda #5
- jsr dump_wiznet_register_page
-
- rts
-@no_error:
-
-send_tcp_data:
- lda #0
- sta cxn_closed
-
- ldax #sending
- jsr print
- ldax #http_string1
- jsr print
- ldax #http_string1
- jsr tcp_send_string
- bcc @ok1
-
-@error:
- ldax #error
- jsr print
- lda ip65_error
- jsr print_hex
- jsr print_cr
-@done:
- lda #0
- jsr dump_wiznet_register_page
- lda #5
- jsr dump_wiznet_register_page
-
- rts
-
- @ok1:
- ldax #sending
- jsr print
- ldax #http_string2
- jsr print
- ldax #http_string2
- jsr tcp_send_string
- bcs @error
-@poll_loop:
- jsr ip65_process
- lda cxn_closed
- beq @poll_loop
- jsr tcp_close
- ldax #EOF
- jsr print
-
- jmp @done
-
-ping_test:
- ldx #$3
-:
- lda dhcp_server,x
- sta icmp_echo_ip,x
- dex
- bpl :-
- jmp do_ping
-
-ping_test_2:
- ldx #$3
-:
- lda cfg_gateway,x
- sta icmp_echo_ip,x
- dex
- bpl :-
- jmp do_ping
-
-ping_test_3:
- ldx #$3
-:
- lda dns_ip,x
- sta icmp_echo_ip,x
- dex
- bpl :-
- jmp do_ping
-
-
-do_ping:
- ldax #pinging
- jsr print
-
- ldax #icmp_echo_ip
- jsr print_dotted_quad
- jsr print_cr
- jsr icmp_ping
- bcs @error
- jsr print_integer
- ldax #ms
- jsr print
- rts
-@error:
- jmp print_errorcode
-
- rts
-
-
-probe_for_w5100:
- stax w5100_addr
- ldax #probing
- jsr print
- lda w5100_addr+1
- jsr print_hex
- lda w5100_addr
- jsr print_hex
- jsr print_cr
- ldax w5100_addr
- jmp w5100_ip65_init
-
-wait_for_keypress:
- lda #0
- sta $c6 ;set the keyboard buffer to be empty
- ldax #press_a_key_to_continue
- jsr print
- jsr get_key_ip65
- rts
-
-
-
-do_dns_query:
- pha
- jsr print
- lda #' '
- jsr print_a
- lda #':'
- jsr print_a
- lda #' '
- jsr print_a
- pla
- jsr dns_set_hostname
- jsr dns_resolve
- bcc :+
- ldax #dns_lookup_failed_msg
- jsr print
- lda #0
- jsr dump_wiznet_register_page
- lda #5
- jsr dump_wiznet_register_page
-
- sec
- rts
-:
- ldax #dns_ip
- jsr print_dotted_quad
- jsr print_cr
- clc
- rts
-
-
-dump_wiznet_register_page:
- sta register_page
- lda #0
- sta current_register
- jsr print_cr
-
-@one_row:
- lda current_register
- cmp #$20
- beq @done
- lda register_page
- jsr print_hex
- lda current_register
- jsr print_hex
- lda #':'
- jsr print_a
- lda #' '
- jsr print_a
-
- lda #0
- sta current_byte_in_row
-
-@dump_byte:
- lda current_register
- ldx register_page
- jsr w5100_read_register
- jsr print_hex
- lda #' '
- jsr print_a
- inc current_register
- inc current_byte_in_row
- lda current_byte_in_row
- cmp #08
- bne @dump_byte
-
- jsr print_cr
- jmp @one_row
-@done:
- jsr print_cr
- rts
-
-
-tcp_callback_routine:
-
- lda tcp_inbound_data_length
- cmp #$ff
- bne @not_end_of_file
- lda #1
- sta cxn_closed
- rts
-
-@not_end_of_file:
- lda #14
- jsr print_a ;switch to lower case
-
-
- ldax tcp_inbound_data_ptr
- stax get_next_byte+1
-
- lda #0
- sta byte_counter
- sta byte_counter+1
-
-@print_one_byte:
- jsr get_next_byte
- jsr ascii_to_native
-
- jsr print_a
- inc get_next_byte+1
- bne :+
- inc get_next_byte+2
-:
-
- inc byte_counter
- bne :+
- inc byte_counter+1
-:
- ldax byte_counter
- stax acc16
- ldax tcp_inbound_data_length
- jsr cmp_16_16
- bne @print_one_byte
-
- rts
-
-get_next_byte:
- lda $ffff
- rts
-
-
-.rodata
-starting: .byte "STARTING",13,0
-ms: .byte " MS",13,0
-pinging: .byte "PINGING ",0
-connecting: .byte "CONNECTING ",0
-sending: .byte "SENDING ",0
-hello: .byte "HELLO WORLD!",13,10,0
-no_wiznet: .byte "NO W5100 FOUND",13,10,0
-probing: .byte "LOOKING FOR W5100 AT $",0
-ping_ip: .byte 10,5,1,84
-hostname_1: .byte "JAMTRONIX.COM",0
-error: .byte "ERROR $",0
-ok: .byte "OK",13,0
-EOF: .byte "CONNECTION CLOSED",13,0
-listening: .byte "LISTENING ON PORT 80",13,0
-http_string1: .byte "GET ",0
-connection_from: .byte "CONNECTION FROM ",0
-http_string2: .byte "/ HTTP/1.0",13,10,13,10,0
-.bss
-w5100_addr: .res 2
-current_register:.res 1
-current_byte_in_row: .res 1
-register_page: .res 1
-cxn_closed: .res 1
-byte_counter: .res 2
-
-
-
-;-- 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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+ .include "../drivers/w5100.i"
+
+ .import exit_to_basic
+
+ .import cfg_get_configuration_ptr
+ .import copymem
+ .importzp copy_src
+ .importzp copy_dest
+ .import icmp_echo_ip
+ .import icmp_ping
+ .import get_key_ip65
+ .import w5100_ip65_init
+ .import w5100_read_register
+ .import dns_set_hostname
+ .import dns_resolve
+ .import dns_ip
+ .import dns_status
+
+ .import tcp_connect
+ .import tcp_connect_ip
+ .import tcp_callback
+ .import tcp_send_string
+ .import tcp_close
+ .import tcp_inbound_data_ptr
+ .import tcp_inbound_data_length
+ .import tcp_connect_remote_port
+ .import tcp_remote_ip
+ .import tcp_listen
+ .importzp acc16
+ .import cmp_16_16
+
+
+ .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
+
+.code
+
+init:
+
+ ldax #starting
+ jsr print
+@loop:
+ inc $d020
+ jmp @loop
+
+
+ ldax #$DE00
+ jsr probe_for_w5100
+ bcc @found
+ ldax #$DF00
+ jsr probe_for_w5100
+ bcc @found
+ ldax #$DF20
+ jsr probe_for_w5100
+ bcc @found
+ ldax #no_wiznet
+ jmp print
+ rts
+
+@found:
+ jsr dhcp_init
+ lda #0
+ jsr dump_wiznet_register_page
+ lda #4
+ jsr dump_wiznet_register_page
+
+@skip:
+
+
+ jsr print_ip_config
+
+ jsr ping_test
+ jsr ping_test_2
+
+ jsr tcp_listen_test
+
+ ldax #hostname_1
+ jsr do_dns_query
+ bcs :+
+ jsr ping_test_3
+ jsr tcp_test
+:
+ rts
+
+
+tcp_listen_test:
+
+ ldax #tcp_callback_routine
+ stax tcp_callback
+ ldax #listening
+ jsr print
+ ldax #80
+
+ jsr tcp_listen
+ bcc :+
+ ldax #error
+ jsr print
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+ rts
+:
+
+ 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
+ jmp send_tcp_data
+
+tcp_test:
+
+ ldax #tcp_callback_routine
+ stax tcp_callback
+
+ ;send without connecting - should get an error
+ ldax #http_string1
+ jsr tcp_send_string
+ bcc :+
+ ldax #error
+ jsr print
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+:
+ ldx #$3
+:
+ lda dns_ip,x
+ sta tcp_connect_ip,x
+ dex
+ bpl :-
+ ldax #connecting
+ jsr print
+
+ ldax #tcp_connect_ip
+ jsr print_dotted_quad
+ jsr print_cr
+
+
+ ldax #80 ;port number
+
+ jsr tcp_connect
+ bcc @no_error
+ ldax #error
+ jsr print
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+ lda #0
+ jsr dump_wiznet_register_page
+ lda #5
+ jsr dump_wiznet_register_page
+
+ rts
+@no_error:
+
+send_tcp_data:
+ lda #0
+ sta cxn_closed
+
+ ldax #sending
+ jsr print
+ ldax #http_string1
+ jsr print
+ ldax #http_string1
+ jsr tcp_send_string
+ bcc @ok1
+
+@error:
+ ldax #error
+ jsr print
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+@done:
+ lda #0
+ jsr dump_wiznet_register_page
+ lda #5
+ jsr dump_wiznet_register_page
+
+ rts
+
+ @ok1:
+ ldax #sending
+ jsr print
+ ldax #http_string2
+ jsr print
+ ldax #http_string2
+ jsr tcp_send_string
+ bcs @error
+@poll_loop:
+ jsr ip65_process
+ lda cxn_closed
+ beq @poll_loop
+ jsr tcp_close
+ ldax #EOF
+ jsr print
+
+ jmp @done
+
+ping_test:
+ ldx #$3
+:
+ lda dhcp_server,x
+ sta icmp_echo_ip,x
+ dex
+ bpl :-
+ jmp do_ping
+
+ping_test_2:
+ ldx #$3
+:
+ lda cfg_gateway,x
+ sta icmp_echo_ip,x
+ dex
+ bpl :-
+ jmp do_ping
+
+ping_test_3:
+ ldx #$3
+:
+ lda dns_ip,x
+ sta icmp_echo_ip,x
+ dex
+ bpl :-
+ jmp do_ping
+
+
+do_ping:
+ ldax #pinging
+ jsr print
+
+ ldax #icmp_echo_ip
+ jsr print_dotted_quad
+ jsr print_cr
+ jsr icmp_ping
+ bcs @error
+ jsr print_integer
+ ldax #ms
+ jsr print
+ rts
+@error:
+ jmp print_errorcode
+
+ rts
+
+
+probe_for_w5100:
+ stax w5100_addr
+ ldax #probing
+ jsr print
+ lda w5100_addr+1
+ jsr print_hex
+ lda w5100_addr
+ jsr print_hex
+ jsr print_cr
+ ldax w5100_addr
+ jmp w5100_ip65_init
+
+wait_for_keypress:
+ lda #0
+ sta $c6 ;set the keyboard buffer to be empty
+ ldax #press_a_key_to_continue
+ jsr print
+ jsr get_key_ip65
+ rts
+
+
+
+do_dns_query:
+ pha
+ jsr print
+ lda #' '
+ jsr print_a
+ lda #':'
+ jsr print_a
+ lda #' '
+ jsr print_a
+ pla
+ jsr dns_set_hostname
+ jsr dns_resolve
+ bcc :+
+ ldax #dns_lookup_failed_msg
+ jsr print
+ lda #0
+ jsr dump_wiznet_register_page
+ lda #5
+ jsr dump_wiznet_register_page
+
+ sec
+ rts
+:
+ ldax #dns_ip
+ jsr print_dotted_quad
+ jsr print_cr
+ clc
+ rts
+
+
+dump_wiznet_register_page:
+ sta register_page
+ lda #0
+ sta current_register
+ jsr print_cr
+
+@one_row:
+ lda current_register
+ cmp #$20
+ beq @done
+ lda register_page
+ jsr print_hex
+ lda current_register
+ jsr print_hex
+ lda #':'
+ jsr print_a
+ lda #' '
+ jsr print_a
+
+ lda #0
+ sta current_byte_in_row
+
+@dump_byte:
+ lda current_register
+ ldx register_page
+ jsr w5100_read_register
+ jsr print_hex
+ lda #' '
+ jsr print_a
+ inc current_register
+ inc current_byte_in_row
+ lda current_byte_in_row
+ cmp #08
+ bne @dump_byte
+
+ jsr print_cr
+ jmp @one_row
+@done:
+ jsr print_cr
+ rts
+
+
+tcp_callback_routine:
+
+ lda tcp_inbound_data_length
+ cmp #$ff
+ bne @not_end_of_file
+ lda #1
+ sta cxn_closed
+ rts
+
+@not_end_of_file:
+ lda #14
+ jsr print_a ;switch to lower case
+
+
+ ldax tcp_inbound_data_ptr
+ stax get_next_byte+1
+
+ lda #0
+ sta byte_counter
+ sta byte_counter+1
+
+@print_one_byte:
+ jsr get_next_byte
+ jsr ascii_to_native
+
+ jsr print_a
+ inc get_next_byte+1
+ bne :+
+ inc get_next_byte+2
+:
+
+ inc byte_counter
+ bne :+
+ inc byte_counter+1
+:
+ ldax byte_counter
+ stax acc16
+ ldax tcp_inbound_data_length
+ jsr cmp_16_16
+ bne @print_one_byte
+
+ rts
+
+get_next_byte:
+ lda $ffff
+ rts
+
+
+.rodata
+starting: .byte "STARTING",13,0
+ms: .byte " MS",13,0
+pinging: .byte "PINGING ",0
+connecting: .byte "CONNECTING ",0
+sending: .byte "SENDING ",0
+hello: .byte "HELLO WORLD!",13,10,0
+no_wiznet: .byte "NO W5100 FOUND",13,10,0
+probing: .byte "LOOKING FOR W5100 AT $",0
+ping_ip: .byte 10,5,1,84
+hostname_1: .byte "JAMTRONIX.COM",0
+error: .byte "ERROR $",0
+ok: .byte "OK",13,0
+EOF: .byte "CONNECTION CLOSED",13,0
+listening: .byte "LISTENING ON PORT 80",13,0
+http_string1: .byte "GET ",0
+connection_from: .byte "CONNECTION FROM ",0
+http_string2: .byte "/ HTTP/1.0",13,10,13,10,0
+.bss
+w5100_addr: .res 2
+current_register:.res 1
+current_byte_in_row: .res 1
+register_page: .res 1
+cxn_closed: .res 1
+byte_counter: .res 2
+
+
+
+;-- 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_xmodem.s b/test/test_xmodem.s
similarity index 94%
rename from client/test/test_xmodem.s
rename to test/test_xmodem.s
index 81206f1..163b1f6 100644
--- a/client/test/test_xmodem.s
+++ b/test/test_xmodem.s
@@ -1,326 +1,326 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
- .import parse_dotted_quad
- .import dotted_quad_value
-
- .import tcp_listen
- .import tcp_callback
- .import ip65_error
- .import get_key_ip65
-
- .import tcp_connect
- .import tcp_connect_ip
-
- .import tcp_inbound_data_ptr
- .import tcp_inbound_data_length
-
- .import xmodem_send
- .import xmodem_receive
- .import xmodem_iac_escape
-
- .import tcp_send
- .import tcp_send_data_len
- .import tcp_send_string
- .import tcp_close
- .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
-
-.bss
-packet_count: .res 1
-.code
-
-init:
-
-
- lda #14
- jsr print_a ;switch to lower case
-
-
- lda #1
-; lda #0
- sta xmodem_iac_escape
- lda #0
- sta $dc08 ;set deciseconds - starts TOD going
- jsr print_cr
- init_ip_via_dhcp
- jsr print_ip_config
-
- ldax #starting
- jsr print_ascii_as_native
- jsr print_cr
-
-
- ;connect to port 1000 - xmodem server
-
- ldax #tcp_callback_routine
- stax tcp_callback
- ldax tcp_dest_ip
- stax tcp_connect_ip
- ldax tcp_dest_ip+2
- stax tcp_connect_ip+2
-
- lda #0
- sta packet_count
- ldax #1000
- jsr tcp_connect
-
- bcc :+
- jmp check_for_error
-:
-
- ldax #first_message
- jsr tcp_send_string
-:
- jsr ip65_process
- lda packet_count
- beq :-
-
- ldax #connected
- jsr print_ascii_as_native
- jsr download_file
- jsr check_for_error
- jsr upload_file
- jsr check_for_error
- jsr tcp_close
- rts
-
-upload_file:
- ldax #uploading
- jsr print_ascii_as_native
-
- ldax #start_upload
- jsr tcp_send_string
- bcc :+
-@error:
- jsr check_for_error
-:
-
- jsr open_upload_file
- bcc :+
- jmp check_for_error
-:
- ldax #read_byte
- jsr xmodem_send
- jsr close_file
-
- rts
-
-read_byte:
- lda eof
- beq @not_eof
- sec
- rts
-@not_eof:
- ldx #$02 ; filenumber 2 = output file
- jsr $FFC6 ; call CHKIN (file 2 now used as input)
-
- jsr $FFCF ; call CHRIN (get a byte from file)
- pha
-
- jsr $FFB7 ; call READST (read status byte)
-
- beq :+ ; either EOF or read error
- inc eof
-:
- ldx #$00 ; filenumber 0 = console
- jsr $FFC6 ; call CHKIN (console now used as input)
-
- pla
- clc
- rts
-
-eof: .byte $0
-
-
-download_file:
- ldax #downloading
- jsr print_ascii_as_native
-
- ldax #start_download
- jsr tcp_send_string
- bcc :+
-@error:
- jsr check_for_error
-:
-
- jsr open_download_file
- bcc :+
- jmp check_for_error
-:
- ldax #write_byte
- jsr xmodem_receive
- jsr close_file
-
-
- rts
-
-
-tcp_callback_routine:
-
- inc packet_count
- rts
-
-
-
-
-check_for_error:
- lda ip65_error
- beq @exit
- ldax #error_code
- jsr print
- lda ip65_error
- jsr print_hex
- jsr print_cr
- lda #0
- sta ip65_error
-@exit:
- rts
-
-
-
-@error:
- ldax #failed_msg
- jsr print
- jsr print_cr
- rts
-
-
-open_upload_file:
- lda #upload_filename_end-upload_filename
- ldx #upload_filename
- jmp open_file
-
-open_download_file:
- lda #download_filename_end-download_filename
- ldx #download_filename
-
-open_file:
- jsr $FFBD ; call SETNAM
- lda #$02 ; file number 2
- ldx $BA ; last used device number
- bne @skip
-.import cfg_default_drive
- ldx cfg_default_drive
-@skip:
-
-
- ldy #$02 ; secondary address 2
- jsr $FFBA ; call SETLFS
-
- jsr $FFC0 ; call OPEN
- bcs @error ; if carry set, the file could not be opened
-
- rts
-@error:
- sta ip65_error
- jsr close_file
- sec
- rts
-
-write_byte:
- pha
- ldx #$02 ; filenumber 2 = output file
- jsr $FFC9 ; call CHKOUT
- pla
- jsr $ffd2 ;write byte
- JSR $FFB7 ; call READST (read status byte)
- bne @error
- ldx #$00 ; filenumber 0 = console
- jsr $FFC9 ; call CHKOUT
- rts
-@error:
- lda #KPR_ERROR_FILE_ACCESS_FAILURE
- sta ip65_error
- jsr close_file
- sec
- rts
-
-
-close_file:
-
- lda #$02 ; filenumber 2
- jsr $FFC3 ; call CLOSE
- rts
-
-
- .bss
- temp_ax: .res 2
-
- .rodata
-
-starting:
-.byte "saving to "
-download_filename: .byte "@0:XMODEM.TMP,P,W" ; @0: means 'overwrite if existing', ',P,W' is required to make this an output file
-download_filename_end:
-.byte 0
-first_message:
- .byte "yo!",0
-
-upload_filename: .byte "XMODEM.TMP"
-upload_filename_end:
-.byte 0
-
-start_download:
- .byte "B",0 ;B=Binary, i.e. trigger IAC escape, R=receive text, i.e. no IAC escape
-.data
-
-start_upload:
- .byte "S",0 ;S send via normal checksum mode (not CRC)
-.data
-
-uploading: .byte "uploading",10,0
-downloading: .byte "downloading",10,0
-connected: .byte "connected",10,0
-tcp_dest_ip:
- .byte 10,5,1,102
-; .byte 192,168,160,1
-
-
-
-
-;-- LICENSE FOR test_xmodem.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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+ .import parse_dotted_quad
+ .import dotted_quad_value
+
+ .import tcp_listen
+ .import tcp_callback
+ .import ip65_error
+ .import get_key_ip65
+
+ .import tcp_connect
+ .import tcp_connect_ip
+
+ .import tcp_inbound_data_ptr
+ .import tcp_inbound_data_length
+
+ .import xmodem_send
+ .import xmodem_receive
+ .import xmodem_iac_escape
+
+ .import tcp_send
+ .import tcp_send_data_len
+ .import tcp_send_string
+ .import tcp_close
+ .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
+
+.bss
+packet_count: .res 1
+.code
+
+init:
+
+
+ lda #14
+ jsr print_a ;switch to lower case
+
+
+ lda #1
+; lda #0
+ sta xmodem_iac_escape
+ lda #0
+ sta $dc08 ;set deciseconds - starts TOD going
+ jsr print_cr
+ init_ip_via_dhcp
+ jsr print_ip_config
+
+ ldax #starting
+ jsr print_ascii_as_native
+ jsr print_cr
+
+
+ ;connect to port 1000 - xmodem server
+
+ ldax #tcp_callback_routine
+ stax tcp_callback
+ ldax tcp_dest_ip
+ stax tcp_connect_ip
+ ldax tcp_dest_ip+2
+ stax tcp_connect_ip+2
+
+ lda #0
+ sta packet_count
+ ldax #1000
+ jsr tcp_connect
+
+ bcc :+
+ jmp check_for_error
+:
+
+ ldax #first_message
+ jsr tcp_send_string
+:
+ jsr ip65_process
+ lda packet_count
+ beq :-
+
+ ldax #connected
+ jsr print_ascii_as_native
+ jsr download_file
+ jsr check_for_error
+ jsr upload_file
+ jsr check_for_error
+ jsr tcp_close
+ rts
+
+upload_file:
+ ldax #uploading
+ jsr print_ascii_as_native
+
+ ldax #start_upload
+ jsr tcp_send_string
+ bcc :+
+@error:
+ jsr check_for_error
+:
+
+ jsr open_upload_file
+ bcc :+
+ jmp check_for_error
+:
+ ldax #read_byte
+ jsr xmodem_send
+ jsr close_file
+
+ rts
+
+read_byte:
+ lda eof
+ beq @not_eof
+ sec
+ rts
+@not_eof:
+ ldx #$02 ; filenumber 2 = output file
+ jsr $FFC6 ; call CHKIN (file 2 now used as input)
+
+ jsr $FFCF ; call CHRIN (get a byte from file)
+ pha
+
+ jsr $FFB7 ; call READST (read status byte)
+
+ beq :+ ; either EOF or read error
+ inc eof
+:
+ ldx #$00 ; filenumber 0 = console
+ jsr $FFC6 ; call CHKIN (console now used as input)
+
+ pla
+ clc
+ rts
+
+eof: .byte $0
+
+
+download_file:
+ ldax #downloading
+ jsr print_ascii_as_native
+
+ ldax #start_download
+ jsr tcp_send_string
+ bcc :+
+@error:
+ jsr check_for_error
+:
+
+ jsr open_download_file
+ bcc :+
+ jmp check_for_error
+:
+ ldax #write_byte
+ jsr xmodem_receive
+ jsr close_file
+
+
+ rts
+
+
+tcp_callback_routine:
+
+ inc packet_count
+ rts
+
+
+
+
+check_for_error:
+ lda ip65_error
+ beq @exit
+ ldax #error_code
+ jsr print
+ lda ip65_error
+ jsr print_hex
+ jsr print_cr
+ lda #0
+ sta ip65_error
+@exit:
+ rts
+
+
+
+@error:
+ ldax #failed_msg
+ jsr print
+ jsr print_cr
+ rts
+
+
+open_upload_file:
+ lda #upload_filename_end-upload_filename
+ ldx #upload_filename
+ jmp open_file
+
+open_download_file:
+ lda #download_filename_end-download_filename
+ ldx #download_filename
+
+open_file:
+ jsr $FFBD ; call SETNAM
+ lda #$02 ; file number 2
+ ldx $BA ; last used device number
+ bne @skip
+.import cfg_default_drive
+ ldx cfg_default_drive
+@skip:
+
+
+ ldy #$02 ; secondary address 2
+ jsr $FFBA ; call SETLFS
+
+ jsr $FFC0 ; call OPEN
+ bcs @error ; if carry set, the file could not be opened
+
+ rts
+@error:
+ sta ip65_error
+ jsr close_file
+ sec
+ rts
+
+write_byte:
+ pha
+ ldx #$02 ; filenumber 2 = output file
+ jsr $FFC9 ; call CHKOUT
+ pla
+ jsr $ffd2 ;write byte
+ JSR $FFB7 ; call READST (read status byte)
+ bne @error
+ ldx #$00 ; filenumber 0 = console
+ jsr $FFC9 ; call CHKOUT
+ rts
+@error:
+ lda #KPR_ERROR_FILE_ACCESS_FAILURE
+ sta ip65_error
+ jsr close_file
+ sec
+ rts
+
+
+close_file:
+
+ lda #$02 ; filenumber 2
+ jsr $FFC3 ; call CLOSE
+ rts
+
+
+ .bss
+ temp_ax: .res 2
+
+ .rodata
+
+starting:
+.byte "saving to "
+download_filename: .byte "@0:XMODEM.TMP,P,W" ; @0: means 'overwrite if existing', ',P,W' is required to make this an output file
+download_filename_end:
+.byte 0
+first_message:
+ .byte "yo!",0
+
+upload_filename: .byte "XMODEM.TMP"
+upload_filename_end:
+.byte 0
+
+start_download:
+ .byte "B",0 ;B=Binary, i.e. trigger IAC escape, R=receive text, i.e. no IAC escape
+.data
+
+start_upload:
+ .byte "S",0 ;S send via normal checksum mode (not CRC)
+.data
+
+uploading: .byte "uploading",10,0
+downloading: .byte "downloading",10,0
+connected: .byte "connected",10,0
+tcp_dest_ip:
+ .byte 10,5,1,102
+; .byte 192,168,160,1
+
+
+
+
+;-- LICENSE FOR test_xmodem.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/testdns.s b/test/testdns.s
similarity index 95%
rename from client/test/testdns.s
rename to test/testdns.s
index 5d9e0d6..af7cc17 100644
--- a/client/test/testdns.s
+++ b/test/testdns.s
@@ -1,157 +1,157 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
- .import exit_to_basic
-
- .import dns_set_hostname
- .import dns_resolve
- .import dns_ip
- .import dns_status
- .import cfg_get_configuration_ptr
-
-
- .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 print_cr
- jsr print_ip_config
- init_ip_via_dhcp
-; jsr overwrite_with_hardcoded_dns_server
- jsr print_ip_config
-
- ldax #hostname_1
- jsr do_dns_query
-
- ldax #hostname_2
- jsr do_dns_query
-
- ldax #hostname_3
- jsr do_dns_query
-
- ldax #hostname_4
- jsr do_dns_query
-
- ldax #hostname_5
- jsr do_dns_query
-
- ldax #hostname_6
- jsr do_dns_query
-
- jmp exit_to_basic
-
-
-do_dns_query:
- pha
- jsr print
- lda #' '
- jsr print_a
- lda #':'
- jsr print_a
- lda #' '
- jsr print_a
- pla
- jsr dns_set_hostname
- jsr dns_resolve
- bcc :+
- ldax #dns_lookup_failed_msg
- jsr print
- jmp @print_dns_status
-:
- ldax #dns_ip
- jsr print_dotted_quad
-@print_dns_status:
- jsr print_cr
- lda dns_status
- jsr print_hex
- lda dns_status+1
- jsr print_hex
- jsr print_cr
- rts
-
-overwrite_with_hardcoded_dns_server:
- ldx #3
-:
- lda hardcoded_dns_server,x
- sta cfg_dns,x
- dex
- bpl :-
- rts
-
-
-
- .rodata
-
-
-hostname_1:
- .byte "SLASHDOT.ORG",0 ;this should be an A record
-
-hostname_2:
- .byte "VICTA.JAMTRONIX.COM",0 ;this should be a CNAME
-
-hostname_3:
- .byte "WWW.JAMTRONIX.COM",0 ;this should be another CNAME
-
-hostname_4:
- .byte "FOO.BAR.BOGUS",0 ;this should fail
-
-hostname_5: ;this should work (without hitting dns)
- .byte "111.22.3.4",0
-
-hostname_6: ;make sure doesn't get treated as a number
- .byte "3COM.COM",0
-
-hardcoded_dns_server:
-;.byte 61,9,195,193
-;.byte 64,127,100,12
-.byte 205,171,3,65
-.byte 69,111,95,106
-
-
-
-;-- LICENSE FOR testdns.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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+ .import exit_to_basic
+
+ .import dns_set_hostname
+ .import dns_resolve
+ .import dns_ip
+ .import dns_status
+ .import cfg_get_configuration_ptr
+
+
+ .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 print_cr
+ jsr print_ip_config
+ init_ip_via_dhcp
+; jsr overwrite_with_hardcoded_dns_server
+ jsr print_ip_config
+
+ ldax #hostname_1
+ jsr do_dns_query
+
+ ldax #hostname_2
+ jsr do_dns_query
+
+ ldax #hostname_3
+ jsr do_dns_query
+
+ ldax #hostname_4
+ jsr do_dns_query
+
+ ldax #hostname_5
+ jsr do_dns_query
+
+ ldax #hostname_6
+ jsr do_dns_query
+
+ jmp exit_to_basic
+
+
+do_dns_query:
+ pha
+ jsr print
+ lda #' '
+ jsr print_a
+ lda #':'
+ jsr print_a
+ lda #' '
+ jsr print_a
+ pla
+ jsr dns_set_hostname
+ jsr dns_resolve
+ bcc :+
+ ldax #dns_lookup_failed_msg
+ jsr print
+ jmp @print_dns_status
+:
+ ldax #dns_ip
+ jsr print_dotted_quad
+@print_dns_status:
+ jsr print_cr
+ lda dns_status
+ jsr print_hex
+ lda dns_status+1
+ jsr print_hex
+ jsr print_cr
+ rts
+
+overwrite_with_hardcoded_dns_server:
+ ldx #3
+:
+ lda hardcoded_dns_server,x
+ sta cfg_dns,x
+ dex
+ bpl :-
+ rts
+
+
+
+ .rodata
+
+
+hostname_1:
+ .byte "SLASHDOT.ORG",0 ;this should be an A record
+
+hostname_2:
+ .byte "VICTA.JAMTRONIX.COM",0 ;this should be a CNAME
+
+hostname_3:
+ .byte "WWW.JAMTRONIX.COM",0 ;this should be another CNAME
+
+hostname_4:
+ .byte "FOO.BAR.BOGUS",0 ;this should fail
+
+hostname_5: ;this should work (without hitting dns)
+ .byte "111.22.3.4",0
+
+hostname_6: ;make sure doesn't get treated as a number
+ .byte "3COM.COM",0
+
+hardcoded_dns_server:
+;.byte 61,9,195,193
+;.byte 64,127,100,12
+.byte 205,171,3,65
+.byte 69,111,95,106
+
+
+
+;-- LICENSE FOR testdns.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/testdottedquad.s b/test/testdottedquad.s
similarity index 95%
rename from client/test/testdottedquad.s
rename to test/testdottedquad.s
index 862edef..d4ed4d1 100644
--- a/client/test/testdottedquad.s
+++ b/test/testdottedquad.s
@@ -1,134 +1,134 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
- .import exit_to_basic
-
- .import parse_dotted_quad
- .import dotted_quad_value
-
- .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 print_cr
-
- ldax #dotted_quad_1
- jsr test_dotted_quad_string
-
- ldax #dotted_quad_2
- jsr test_dotted_quad_string
-
- ldax #dotted_quad_3
- jsr test_dotted_quad_string
-
- ldax #dotted_quad_4
- jsr test_dotted_quad_string
-
- ldax #dotted_quad_5
- jsr test_dotted_quad_string
-
- ldax #dotted_quad_6
- jsr test_dotted_quad_string
-
- ldax #dotted_quad_7
- jsr test_dotted_quad_string
-
- jmp exit_to_basic
-
-test_dotted_quad_string:
- stax temp_ax
- jsr print
- lda #':'
- jsr print_a
- lda #' '
- jsr print_a
- ldax temp_ax
- jsr parse_dotted_quad
- bcs @error
- ldax #dotted_quad_value
- jsr print_dotted_quad
- jsr print_cr
- rts
-
-@error:
- ldax #failed_msg
- jsr print
- jsr print_cr
- rts
-
- .bss
- temp_ax: .res 2
-
- .rodata
-
-
-dotted_quad_1:
- .byte "1.1.1.1",0 ;should work
-
-dotted_quad_2:
- .byte "GOOBER",0 ;should fail
-
-dotted_quad_3:
- .byte "255.255.255.0",0 ;should work
-
-dotted_quad_4:
- .byte "111.222.333.444",0 ;should fail
-
-dotted_quad_5:
- .byte "111.22.3",0 ; should fail
-
-dotted_quad_6:
- .byte "111.22.3.4",0 ; should work
-
-dotted_quad_7:
- .byte "3.4.5.6X",0 ; should fail
-
-
-
-
-;-- LICENSE FOR testdottedquad.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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+ .import exit_to_basic
+
+ .import parse_dotted_quad
+ .import dotted_quad_value
+
+ .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 print_cr
+
+ ldax #dotted_quad_1
+ jsr test_dotted_quad_string
+
+ ldax #dotted_quad_2
+ jsr test_dotted_quad_string
+
+ ldax #dotted_quad_3
+ jsr test_dotted_quad_string
+
+ ldax #dotted_quad_4
+ jsr test_dotted_quad_string
+
+ ldax #dotted_quad_5
+ jsr test_dotted_quad_string
+
+ ldax #dotted_quad_6
+ jsr test_dotted_quad_string
+
+ ldax #dotted_quad_7
+ jsr test_dotted_quad_string
+
+ jmp exit_to_basic
+
+test_dotted_quad_string:
+ stax temp_ax
+ jsr print
+ lda #':'
+ jsr print_a
+ lda #' '
+ jsr print_a
+ ldax temp_ax
+ jsr parse_dotted_quad
+ bcs @error
+ ldax #dotted_quad_value
+ jsr print_dotted_quad
+ jsr print_cr
+ rts
+
+@error:
+ ldax #failed_msg
+ jsr print
+ jsr print_cr
+ rts
+
+ .bss
+ temp_ax: .res 2
+
+ .rodata
+
+
+dotted_quad_1:
+ .byte "1.1.1.1",0 ;should work
+
+dotted_quad_2:
+ .byte "GOOBER",0 ;should fail
+
+dotted_quad_3:
+ .byte "255.255.255.0",0 ;should work
+
+dotted_quad_4:
+ .byte "111.222.333.444",0 ;should fail
+
+dotted_quad_5:
+ .byte "111.22.3",0 ; should fail
+
+dotted_quad_6:
+ .byte "111.22.3.4",0 ; should work
+
+dotted_quad_7:
+ .byte "3.4.5.6X",0 ; should fail
+
+
+
+
+;-- LICENSE FOR testdottedquad.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/testtftp.s b/test/testtftp.s
similarity index 95%
rename from client/test/testtftp.s
rename to test/testtftp.s
index 2f39252..c889803 100644
--- a/client/test/testtftp.s
+++ b/test/testtftp.s
@@ -1,140 +1,140 @@
- .include "../inc/common.i"
- .include "../inc/commonprint.i"
- .include "../inc/net.i"
-
- .import exit_to_basic
-
- .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__
- .import tftp_upload
- .import tftp_upload_from_memory
- .import tftp_set_callback_vector
- .import tftp_ip
- .import tftp_filesize
- .importzp tftp_filename
-
- .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 print_cr
- init_ip_via_dhcp
- jsr print_ip_config
-
- ldax #upload_callback
- jsr tftp_set_callback_vector
- lda #0
- sta block_number
- ldax #test_file
- stax tftp_filename
- lda #$ff
- ldx #$3
-:
- sta tftp_ip,x
- dex
- bpl :-
-
- ldax #sending_via_callback
- jsr print
- jsr tftp_upload
- bcs @error
- print_ok
-
- ldax #basic_file
- stax tftp_filename
-
- ldax #$2000
- stax tftp_filesize
- ldax #sending_ram
- jsr print
- jsr tftp_upload_from_memory
- bcs @error
- print_ok
-
-rts
-
-@error:
- print_failed
- rts
-upload_callback:
- stax copy_dest
- ldax #buffer1
- stax copy_src
- inc block_number
- lda block_number
- ldx #00
-@next_byte:
- sta buffer1,x
- sta buffer2,x
- inx
- bne @next_byte
- cmp #7
- beq @last_block
- ldax #512
- jmp :+
-@last_block:
- ldax #129
-:
- stax block_length
- jsr copymem
- ldax block_length
- rts
-.rodata
-
-test_file: .byte "TESTFILE.BIN",0
-basic_file: .byte "CBMBASIC.BIN",0
-sending_via_callback: .byte "SENDING VIA CALLBACK...",0
-sending_ram: .byte "SENDING RAM...",0
-.bss
-block_number: .res 1
-block_length: .res 2
-buffer1: .res 256
-buffer2: .res 256
-
-
-;-- LICENSE FOR testtftp.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 --
+ .include "../inc/common.i"
+ .include "../inc/commonprint.i"
+ .include "../inc/net.i"
+
+ .import exit_to_basic
+
+ .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__
+ .import tftp_upload
+ .import tftp_upload_from_memory
+ .import tftp_set_callback_vector
+ .import tftp_ip
+ .import tftp_filesize
+ .importzp tftp_filename
+
+ .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 print_cr
+ init_ip_via_dhcp
+ jsr print_ip_config
+
+ ldax #upload_callback
+ jsr tftp_set_callback_vector
+ lda #0
+ sta block_number
+ ldax #test_file
+ stax tftp_filename
+ lda #$ff
+ ldx #$3
+:
+ sta tftp_ip,x
+ dex
+ bpl :-
+
+ ldax #sending_via_callback
+ jsr print
+ jsr tftp_upload
+ bcs @error
+ print_ok
+
+ ldax #basic_file
+ stax tftp_filename
+
+ ldax #$2000
+ stax tftp_filesize
+ ldax #sending_ram
+ jsr print
+ jsr tftp_upload_from_memory
+ bcs @error
+ print_ok
+
+rts
+
+@error:
+ print_failed
+ rts
+upload_callback:
+ stax copy_dest
+ ldax #buffer1
+ stax copy_src
+ inc block_number
+ lda block_number
+ ldx #00
+@next_byte:
+ sta buffer1,x
+ sta buffer2,x
+ inx
+ bne @next_byte
+ cmp #7
+ beq @last_block
+ ldax #512
+ jmp :+
+@last_block:
+ ldax #129
+:
+ stax block_length
+ jsr copymem
+ ldax block_length
+ rts
+.rodata
+
+test_file: .byte "TESTFILE.BIN",0
+basic_file: .byte "CBMBASIC.BIN",0
+sending_via_callback: .byte "SENDING VIA CALLBACK...",0
+sending_ram: .byte "SENDING RAM...",0
+.bss
+block_number: .res 1
+block_length: .res 2
+buffer1: .res 256
+buffer2: .res 256
+
+
+;-- LICENSE FOR testtftp.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 --