git-svn-id: http://svn.code.sf.net/p/netboot65/code@45 93682198-c243-4bdb-bd91-e943c89aac3b

This commit is contained in:
jonnosan 2009-03-21 06:40:53 +00:00
parent dcc21f16b8
commit e3e22ba41c
29 changed files with 460 additions and 306 deletions

View File

@ -16,7 +16,7 @@ dist:
dist-ip65:
rm -rf dist/ip65
ruby dist/make_dist_ip65.rb
ruby dist/make_dist_ip65.rb
distclean:
make -C client distclean

View File

@ -1,5 +1,8 @@
.export get_key
.code
;use Apple 2 monitor ROM function to read from keyboard
;inputs: none
;outputs: A contains ASCII code of key pressed
get_key:
jmp $fd1b

View File

@ -5,19 +5,31 @@
.export beep
.code
;
;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
jmp $fdf0
;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

View File

@ -17,14 +17,19 @@
.code
;reset timer to 0
;inputs: none
;outputs: none
timer_init:
ldax #0
stax current_time_value
rts
; return the current value (actually, delay a while, then update current value, then return it in ax)
;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

View File

@ -1,6 +1,10 @@
.export get_key
.code
;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

View File

@ -1,5 +1,6 @@
.export exit_to_basic
.code
; jump to BASIC interpreter loop
exit_to_basic:
jmp $a7ae ; jump to BASIC interpreter loop
jmp $a7ae

View File

@ -5,17 +5,29 @@
.export beep
.data
;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
.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:
rts

View File

@ -14,7 +14,9 @@
.code
; initialize timers
;initialize timers
;inputs: none
;outputs: none
timer_init:
lda #$80 ; stop timers
sta $dd0e
@ -35,7 +37,9 @@ timer_init:
rts
; return the current value
;initialize timers
;inputs: none
;outputs: AX = count in milliseconds sent last call to timer_init
timer_read:
lda $dd07 ; cia counts backwards, return inverted value
eor #$ff

View File

@ -10,20 +10,19 @@
.export cs_tx_len
.export cs_driver_name
rr_ctl = $de01
;cs_irq = $de00
cs_packet_page = $de02
cs_packet_data = $de04
;cs_packet_data2 = $de06
cs_rxtx_data = $de08
;cs_rxtx_data2 = $de0a
cs_tx_cmd = $de0c
cs_tx_len = $de0e
rr_ctl = $de01 ;address of 'control' port on Retro-Replay
cs_packet_page = $de02 ;address of 'packet page' port on RR-Net
cs_packet_data = $de04;address of 'packet data' port on RR-Net
cs_rxtx_data = $de08 ;address of 'recieve/transmit data' port on RR-Net
cs_tx_cmd = $de0c;address of 'transmit command' port on RR-Net
cs_tx_len = $de0e;address of 'transmission length' port on RR-Net
.code
.code
;initialise Retro Replay so we can access the network adapter
;inputs: none
;outputs: none
cs_init:
lda rr_ctl
ora #1

View File

@ -1,5 +1,5 @@
; uthernet driver
; for the moment, always assume slot 3
;uthernet driver
;currently hardcoded to use slot 3 addresses only
.export cs_init
@ -11,11 +11,11 @@
.export cs_tx_len
.export cs_driver_name
cs_rxtx_data = $c0b0
cs_tx_cmd = $c0b4
cs_tx_len = $c0b6
cs_packet_page = $c0ba
cs_packet_data = $c0bc
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

View File

@ -1,13 +1,11 @@
; ARP address resolution
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
.include "../inc/common.i"
.export arp_init
.export arp_lookup
.export arp_process
.export arp_add
.export arp_add
.export arp_ip
.export arp_mac
@ -46,14 +44,14 @@ 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
arp_ip: .res 4 ; set ip before calling lookup
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
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)
@ -77,8 +75,9 @@ arptimeout: .res 2 ; time when we will have timed out
.code
; initialize arp
;initialize arp (including clearing the arp cache)
;inputs: none
;outputs: none
arp_init:
lda #0
@ -109,9 +108,13 @@ arp_init:
rts
; lookup an ip
; clc = mac returned in arp_mac
; sec = request sent, call again for result
;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)
@ -252,14 +255,15 @@ findip:
rts
; handle incoming arp packets
;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_len ; check packet size
; cmp #<ap_packlen
; bne @badpacket
; lda eth_inp_len + 1
; cmp #>ap_packlen
; bne @badpacket
lda eth_inp + ap_op ; should be 0
bne @badpacket
@ -326,14 +330,6 @@ arp_process:
cmp #arp_wait ; are we waiting for a reply?
bne @badpacket
; ldx #0
;: lda gotmsg,x
; beq :+
; jsr $ffd2
; inx
; bne :-
;:
ldax #eth_inp + ap_shw
jsr ac_add_source ; add to cache
@ -342,14 +338,13 @@ arp_process:
rts
;gotmsg:
; .byte "gOT arp REPLY",13,0
;
;addmsg:
; .byte "aDDING ARP ENTRY",13,0
; add arp_mac and arp_ip to the cache
; 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
@ -365,38 +360,15 @@ arp_add:
ldax #arp ; add
; add source to cache
;add source to cache
ac_add_source:
stax ap
; ldx #0
;: lda addmsg,x
; beq :+
; jsr $ffd2
; inx
; bne :-
;:
ldx #9 ; make space in the arp cache
:
; lda arp_cache + 140,x
; sta arp_cache + 150,x
; lda arp_cache + 130,x
; sta arp_cache + 140,x
; lda arp_cache + 120,x
; sta arp_cache + 130,x
; lda arp_cache + 110,x
; sta arp_cache + 120,x
; lda arp_cache + 100,x
; sta arp_cache + 110,x
; lda arp_cache + 90,x
; sta arp_cache + 100,x
; lda arp_cache + 80,x
; sta arp_cache + 90,x
; lda arp_cache + 70,x
; sta arp_cache + 80,x
lda arp_cache + 60,x
sta arp_cache + 70,x
lda arp_cache + 50,x

View File

@ -1,7 +1,5 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
; Configuration
;IP configuration defaults
;most of these will be overwritten if dhcp is used for configuration
.export cfg_mac
.export cfg_ip
@ -10,12 +8,14 @@
.export cfg_dns
.export cfg_tftp_server
.data ; these are defaults
.data
cfg_mac: .byte $00, $80, $10, $6d, $76, $30
cfg_mac: .byte $00, $80, $10, $6d, $76, $30 ;mac address to be assigned to local machine
;cfg_ip: .byte 192, 168, 0, 64
cfg_ip: .byte 0,0,0,0
cfg_netmask: .byte 255, 255, 255, 0
cfg_gateway: .byte 0, 0, 0, 0
cfg_dns: .byte 0, 0, 0, 0
cfg_tftp_server: .byte $ff,$ff,$ff,$ff
cfg_ip: .byte 0,0,0,0 ;ip address of local machine (will be overwritten if dhcp_init is called)
cfg_netmask: .byte 255, 255, 255, 0; netmask of local network (will be overwritten if dhcp_init is called)
cfg_gateway: .byte 0, 0, 0, 0 ;ip address of router on local network (will be overwritten if dhcp_init is called)
cfg_dns: .byte 0, 0, 0, 0; ip address of dns server to use (will be overwritten if dhcp_init is called)
cfg_tftp_server: .byte $ff,$ff,$ff,$ff ; ip address of server to send tftp requests to (can be a broadcast address)

View File

@ -1,6 +1,4 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
; copy memory
; utility routine to copy memory
.export copymem
@ -22,8 +20,12 @@ end: .res 1
.code
; copy memory
; set copy_src and copy_dest, length in A/X
;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

View File

@ -1,6 +1,4 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
; Ethernet driver for CS8900A
; Ethernet driver for CS8900A chip (as used in RR-NET and Uthernet adapters)
;
; Based on Doc Bacardi's tftp source
@ -8,10 +6,6 @@
.include "../inc/common.i"
.include "cs8900a.i"
;.import dbg_dump_eth_header
.export eth_init
.export eth_rx
.export eth_tx
@ -58,15 +52,17 @@ eth_outp_len: .res 2 ; output packet length
eth_outp: .res 1518 ; space for output packet
; ethernet packet offsets
eth_dest = 0 ; destination address
eth_src = 6 ; source address
eth_type = 12 ; packet type
eth_data = 14 ; packet data
eth_dest = 0 ; offset of destination mac address in an ethernet packet
eth_src = 6 ; offset of source address in an ethernet packet
eth_type = 12 ; offset of packet type in an ethernet packet
eth_data = 14 ; offset of packet data in an ethernet packet
.code
; initialize, return clc on success
;initialize the ethernet adaptor
;inputs: none
;outputs: carry flag is set if there was an error, clear otherwise
eth_init:
jsr cs_init
@ -86,7 +82,6 @@ eth_init:
write_page pp_self_ctl, $0055 ; $0114, reset chip
write_page pp_rx_ctl, $0d05 ; $0104, accept individual and broadcast packets
;write_page pp_rx_ctl, $0d85 ; $0104, promiscuous mode
lda #pp_ia/2 ; $0158, write mac address
ldx cfg_mac
@ -113,7 +108,13 @@ eth_init:
rts
; receive a packet
;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
@ -179,10 +180,15 @@ eth_rx:
rts
; send a packet
; 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:
;jsr dbg_dump_eth_header
lda #$c9 ; ask for buffer space
sta cs_tx_cmd
lda #0

View File

@ -1,4 +1,4 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
;routines for dumping debug information
.include "../inc/common.i"
.include "../inc/printf.i"
@ -26,6 +26,11 @@ cptr: .res 2
.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
@ -46,7 +51,11 @@ dbg_dump_eth_header:
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
@ -72,7 +81,11 @@ dbg_dump_ip_header:
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
@ -96,6 +109,9 @@ dbg_dump_udp_header:
console_out = $ffd2
;print a string to the console
;inputs: AX = address of (null terminated) string to print
;outputs: none
console_strout:
stax cptr
@ -118,7 +134,9 @@ console_strout:
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

View File

@ -1,23 +1,18 @@
;########################
; minimal dhcp implementation
; written by jonno@jamtronix.com 2009
;
;########################
; to use - first call ip65_init, then call dhcp_init
; no inputs required.
; on return, carry flag clear means IP config has been
; sucesfully obtained (cfg_ip, cfg_netmask, cfg_gateway and cfg_dns set as appropriate).
; if carry flag is set, IP config could not be set. that could be because of a network
; error or because there was no response from a DHCP server within about 5 seconds.
;########################
; 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"
.export dhcp_init
.export dhcp_server
.export dhcp_state
.export dhcp_server ;will be set address of dhcp server that configuration was obtained from
.export dhcp_state
.import cfg_mac
.import cfg_ip
@ -79,7 +74,8 @@ 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
dhcp_state: .res 1 ; current activity
;flag indicating current state of dhcp initialization.
dhcp_state: .res 1
dhcp_message_sent_count: .res 1
dhcp_timer: .res 1
@ -103,10 +99,22 @@ 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

View File

@ -1,17 +1,4 @@
;########################
; minimal dns implementation
; requires a DNS server that supports recursion
; written by jonno@jamtronix.com 2009
;
;########################
; to use -
; ensure cfg_dns points to a DNS server that supports recursion
; call dns_set_hostname with AX pointing to null terminated hostname
; then call dns_resolve
; on exit: carry flag is set if there was an error. if carry flag is clear, then dns_ip will point to the
; IP address of the hostname
;########################
; 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
@ -67,7 +54,7 @@ dns_qname=12
dns_server_port=53
dns_client_port_low_byte: .res 1
dns_ip: .res 4
dns_ip: .res 4 ;will be contain ip address of hostname after succesful exection of dns_resolve
dns_msg_id: .res 2
@ -84,12 +71,12 @@ 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 ; current activity
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
dns_status: .res 2 ; for debugging purposes only (behaviour not garuanteed)
hostname_copied: .res 1
@ -98,7 +85,14 @@ 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
@ -178,6 +172,13 @@ dns_set_hostname:
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

View File

@ -1,14 +1,3 @@
;########################
; helper routine to convert a string representing a dotted quad (IP address, netmask) into 4 octets
; written by jonno@jamtronix.com 2009
;
;########################
; to use -
; ldax with ptr of dotted quad string
; then call parse_dotted_quad
; on exit: carry flag is set if there was an error. if carry flag is clear, then dotted_quad_value will be set
;########################
.include "../inc/common.i"
@ -17,15 +6,21 @@
.export dotted_quad_value
.bss
dotted_quad_value: .res 4
dotted_quad_value: .res 4 ;set to 32 bit ip address on a succesful call to parse_dotted_quad
dotted_quad_ptr: .res 4
.code
parse_dotted_quad:
; 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)
parse_dotted_quad:
stax dotted_quad_ptr+1
lda #$AD ; $AD='LDA immediate'

View File

@ -1,7 +1,4 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
; Common ethernet driver code
; Common ethernet driver code (independant of host computer or ethernet chipset)
.include "../inc/common.i"
@ -18,18 +15,23 @@
; ethernet packet offsets
eth_dest = 0 ; destination address
eth_src = 6 ; source address
eth_type = 12 ; packet type
eth_data = 14 ; packet data
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
; 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
@ -38,7 +40,10 @@ eth_set_broadcast_dest:
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
@ -47,7 +52,10 @@ eth_set_my_mac_src:
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

View File

@ -1,4 +1,5 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
;ICMP implementation
;
.include "../inc/common.i"
@ -48,22 +49,24 @@ 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
icmp_outp = ip_outp + ip_data
icmp_type = 0
icmp_code = 1
icmp_cksum = 2
icmp_data = 4
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
icmp_echo_seq = 6
icmp_echo_data = 8
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
.code
; initialize icmp
; initialize icmp
; inputs: none
; outputs: none
icmp_init:
lda #0
sta icmp_cbcount
@ -71,8 +74,14 @@ icmp_init:
sta icmp_cbtmp
rts
; process incoming icmp packet
;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 #8 ; ping
@ -161,8 +170,12 @@ icmp_process:
rts
; add an icmp listener
; icmp type in A, vector in icmp_callback
;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
@ -190,8 +203,12 @@ icmp_add_listener:
rts
; remove an icmp listener
; icmp type in A
;add 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

View File

@ -1,10 +1,5 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
.include "../inc/common.i"
;.import dbg_dump_ip_header
.export ip_init
.export ip_process
.export ip_calc_cksum
@ -65,37 +60,38 @@
.segment "IP65ZP" : zeropage
; checksum
ip_cksum_ptr: .res 2 ; data pointer
ip_cksum_ptr: .res 2 ; pointer to data to be checksummed
.bss
ip_cksum_len: .res 2 ; length of data
ip_cksum_len: .res 2 ; length of data to be checksummed
; ip packets start at ethernet packet + 14
ip_inp = eth_inp + eth_data
ip_outp = eth_outp + eth_data
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
ip_broadcast: .res 1 ;flag set when an incoming IP packet was sent to a broadcast address
; ip packet offsets
ip_ver_ihl = 0
ip_tos = 1
ip_len = 2
ip_id = 4
ip_frag = 6
ip_ttl = 8
ip_proto = 9
ip_header_cksum = 10
ip_src = 12
ip_dest = 16
ip_data = 20
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 protocols
ip_proto_icmp = 1
ip_proto_tcp = 6
ip_proto_udp = 17
@ -111,7 +107,9 @@ bad_addr: .res 2
.code
; initialize ip routines
; initialize ip routines
; inputs: none
; outputs: none
ip_init:
lda #0
sta bad_header
@ -126,7 +124,13 @@ ip_init:
rts
; process an incoming packet
;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
@ -235,7 +239,13 @@ checkaddr:
rts
; create a packet template
; 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
@ -272,15 +282,18 @@ ip_create_packet:
rts
; send an IP packet
;
; but first:
;
; call ip_create_packet
; set length
; set ID
; set protocol
; set destination address
; 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
@ -338,7 +351,12 @@ ip_send:
jmp eth_tx ; send packet and return status
; calculate checksum for ip header
; calculate checksum for a buffer according to the standard IP checksum algorithm
;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

View File

@ -1,5 +1,3 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
; ip65 main routines
.include "../inc/common.i"
@ -34,9 +32,14 @@ ip65_ctr_ip: .res 1 ; incremented for every incoming ip packet
.code
; initialize stack
; 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 eth_init ; initialize ethernet driver
@ -49,8 +52,15 @@ ip65_init:
rts
; maintenance routine
; polls for packets, and dispatches to listeners
;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

View File

@ -1,5 +1,3 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
.include "../inc/common.i"
.export console_printf
@ -30,7 +28,20 @@ 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

View File

@ -1,26 +1,5 @@
;########################
; minimal tftp implementation (client only)
; supports file download (not upload) and custom directory listing (using opcode of 0x65)
; written by jonno@jamtronix.com 2009
;
;########################
; to get a directory listing
; set tftp_ip to host to download from (which can be broadcast address 255.255.255.255)
; set tftp_load_address to point to memory location that dir will be stored in
; set tftp_filename to null terminated filemask (e.g. "*.prg")
; then call tftp_directory_listing
; on exit: carry flag is set if there was an error.
;
; to d/l a file:
; set tftp_ip to host to download from (which can be broadcast address 255.255.255.255)
; set tftp_load_address to point to memory location that file will be downloaded to
; OR set tftp_load_address to $0000, and first 2 bytes of downloaded file will be treated as the load address
; set tftp_filename to null terminated filename to download
; then call tftp_download
; on exit: carry flag is set if there was an error. tftp_load_address will be set to address file loaded to (i.e. gets overwritten if originally set to $0000)
;
;########################
;minimal tftp implementation (client only)
;supports file download (not upload) and custom directory listing (using non-standard tftp opcode of 0x65)
TFTP_MAX_RESENDS=10
TFTP_TIMER_MASK=$F8 ;mask lower two bits, means we wait for 8 x1/4 seconds
@ -62,20 +41,20 @@
.segment "IP65ZP" : zeropage
tftp_filename: .res 2
tftp_filename: .res 2 ;name of file to d/l or filemask to get directory listing for
.bss
;packet offsets
tftp_inp = udp_inp + udp_data
tftp_inp = udp_inp + udp_data
tftp_outp: .res 128
;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
tftp_ip: .res 4
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_bytes_to_copy: .res 2
tftp_current_memloc: .res 2
@ -102,10 +81,35 @@ tftp_opcode: .res 2 ; will be set to 4 if we are doing a RRQ, or 7 if we are doi
.code
; query a tftp server for a directory listing (uses a non-standard tftp opcode,
; currently only supported by tftp server built in to 'netboot65' server)
; inputs:
; tftp_ip: ip address of host to download from (set to 255.255.255.255 for broadcast)
; tftp_load_address: memory location that dir will be stored in
; tftp_filename: pointer to null terminated filemask (e.g. "*.prg",0)
; outputs: carry flag is set if there was an error
; if there was no error, the buffer at tftp_load_address will be filled
; with null-terminated strings containing the names of all files on the
; server that matched the specified file mask, and an additional null
; byte will follow the null byte terminating the last file name.
; NB - there is no limit to the amount of memory this function will consume,
; so depending on where tftp_load_address is set, there is potential to
; overwrite other data or code
tftp_directory_listing:
ldax #$6500 ;opcode 65 = netboot65 DIR (non-standard opcode)
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_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)
; tftp_filename: pointer to null terminated name of file to download
; outputs: carry flag is set if there was an error
; if there was no error, the buffer at tftp_load_address will be filled
; with file downloaded.
; tftp_load_address: will be set to the actual address loaded into
tftp_download:
ldax #$0100 ;opcode 01 = RRQ
set_tftp_opcode:

View File

@ -1,13 +1,11 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
; 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/<machinename>timer.s
.include "../inc/common.i"
@ -21,7 +19,9 @@ time: .res 2
.code
; check if value in A/X is smaller than current timer value
;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

View File

@ -1,4 +1,4 @@
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
;UDP (user datagram protocol) functions
.include "../inc/common.i"
@ -53,13 +53,13 @@
.bss
; argument for udp_add_listener
udp_callback: .res 2
udp_callback: .res 2 ;vector to routine to be called when a udp packet arrives
; arguments for udp_send
udp_send_dest: .res 4
udp_send_src_port: .res 2
udp_send_dest_port: .res 2
udp_send_len: .res 2
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
@ -71,13 +71,13 @@ 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
udp_outp = ip_outp + ip_data
udp_src_port = 0
udp_dest_port = 2
udp_len = 4
udp_cksum = 6
udp_data = 8
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
@ -94,7 +94,9 @@ port: .res 2
.code
; initialize udp
; initialize udp
; inputs: none
; outputs: none
udp_init:
lda #0
sta udp_cbcount
@ -103,7 +105,15 @@ udp_init:
rts
; process incoming udp packet
;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
@ -134,8 +144,12 @@ udp_process:
rts
; add an udp listener
; udp port in A/X, vector in udp_callback
;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
@ -173,8 +187,12 @@ udp_add_listener:
rts
; remove an udp listener
; udp port in A/X
; 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
@ -219,14 +237,15 @@ udp_remove_listener:
rts
; send udp packet
;
; but first:
;
; set destination address
; set source port
; set destination port
; set length
;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

5
dist/make_dist.rb vendored
View File

@ -1,3 +1,7 @@
$:.unshift(File.dirname(__FILE__)) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
gem 'archive-zip'
require 'archive/zip'
require 'ftools'
@ -22,5 +26,6 @@ end
File.copy(src,dest)
end
zipfile_name=File.dirname(__FILE__)+"/netboot65-#{Time.now.strftime("%Y-%m-%d")}.zip"
Archive::Zip.archive(zipfile_name, WORKING_DIR)

View File

@ -1,3 +1,7 @@
$:.unshift(File.dirname(__FILE__)) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
gem 'archive-zip'
require 'archive/zip'
require 'ftools'
@ -18,7 +22,8 @@ end
["client/drivers/*.[s|i]","drivers/"],
["client/drivers/Makefile","drivers/"],
["client/cfg/*","cfg/"],
["doc/ip65.html","doc/"],
["doc/ip65.html","doc/index.html"],
["doc/ca65-doc*.*","doc/"],
["client/Makefile","/"],
].each do |args|
dest="#{WORKING_DIR}/#{args[1]}"
@ -32,6 +37,10 @@ dummy_makefile=File.new("#{WORKING_DIR}/clients/Makefile","w")
dummy_makefile<<"#dummy makefile, so we can reuse the top level Makefile from the netboot65/clients directory\nall:\n"
dummy_makefile.close
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)

View File

@ -137,6 +137,11 @@ IP65 is a TCP/IP stack for 6502 based computers.
</table>
<h2>Documentation</h2>
<ul>
<li><a href=ref_frames.html>ip65 technical reference</a>
</ul>
<h2>Download</h2>
@ -148,7 +153,8 @@ IP65 is a TCP/IP stack for 6502 based computers.
<pre>
Release Maintainer Changes
------- ---------- -------
2009-03-08 Jonno Downes Added DHCP, DNS & TFTP
2009-03-15 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.
@ -208,5 +214,10 @@ copy:
This project is released under the Mozilla Public License Version 1.1.
For details, please visit <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>.
<p>
<a href="http://sourceforge.net/">
Project Web Hosted by <img src="http://sflogo.sourceforge.net/sflogo.php?group_id=255596&amp;type=3" alt="SourceForge.net" />
</a>
</body>
</html>