mirror of
https://github.com/bobbimanners/emailler.git
synced 2025-01-22 18:32:06 +00:00
git-svn-id: http://svn.code.sf.net/p/netboot65/code@45 93682198-c243-4bdb-bd91-e943c89aac3b
This commit is contained in:
parent
dcc21f16b8
commit
e3e22ba41c
2
Makefile
2
Makefile
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
5
dist/make_dist.rb
vendored
@ -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)
|
||||
|
13
dist/make_dist_ip65.rb
vendored
13
dist/make_dist_ip65.rb
vendored
@ -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)
|
||||
|
||||
|
@ -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&type=3" alt="SourceForge.net" />
|
||||
</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user