mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-06-01 00:41:30 +00:00
Introduced C interface to IP65.
The IP5 usage of ld65 segments and zeropage variables was made compatible with cc65 C programs already a while ago. This commit is the next logical step which is to introduce the actual C interface to IP65. IP65 for C programs shares the the ip65.lib / ip65_tcp.lib with IP65 for assembler programs. However the various libraries from the 'drivers' are not reused. Instead there's exactly one library for every target named ip65_<target>.lib. Those libraries contain only functions used by ip65.lib / ip65_tcp.lib. TODOs: - Introduce c64_timer.s and atr_timer.s. - Add a C interface to the rest of the IP65 functionality (especially TCP).
This commit is contained in:
parent
32a66c5d7c
commit
6680772b04
|
@ -1,3 +1,5 @@
|
||||||
|
# For assembler programs
|
||||||
|
# ----------------------
|
||||||
# c64rrnet.lib : C64 with RR-Net (or clone) (default base addr: $de0x)
|
# c64rrnet.lib : C64 with RR-Net (or clone) (default base addr: $de0x)
|
||||||
# c64eth64.lib : C64 with ETH64 (default base addr: $de0x)
|
# c64eth64.lib : C64 with ETH64 (default base addr: $de0x)
|
||||||
# c64wiz811.lib : C64 with WIZ811MJ (default base addr: $de0x)
|
# c64wiz811.lib : C64 with WIZ811MJ (default base addr: $de0x)
|
||||||
|
@ -9,20 +11,32 @@
|
||||||
# atrdragon.lib : ATARI 8-bit with Dragon Cart (default base addr: $d500)
|
# atrdragon.lib : ATARI 8-bit with Dragon Cart (default base addr: $d500)
|
||||||
# vic20rrnet.lib : VIC20 with RR-Net or clone (default base addr: $980x)
|
# vic20rrnet.lib : VIC20 with RR-Net or clone (default base addr: $980x)
|
||||||
|
|
||||||
|
# For C programs
|
||||||
|
# --------------
|
||||||
|
# ip65_c64.lib : C64 with RR-Net or ETH64 or WIZ811MJ (default base addr: $de0x)
|
||||||
|
# ip65_apple2.lib : Apple ][ with Uthernet or LANceGS or Uthernet II (default slot: #3)
|
||||||
|
# ip65_atari.lib : ATARI 8-bit with Dragon Cart (default base addr: $d500)
|
||||||
|
|
||||||
DRIVERS=\
|
DRIVERS=\
|
||||||
c64rrnet.lib \
|
c64rrnet.lib \
|
||||||
c64eth64.lib \
|
c64eth64.lib \
|
||||||
c64wiz811.lib \
|
c64wiz811.lib \
|
||||||
c64combo.lib \
|
c64combo.lib \
|
||||||
|
ip65_c64.lib \
|
||||||
a2uther.lib \
|
a2uther.lib \
|
||||||
a2lancegs.lib \
|
a2lancegs.lib \
|
||||||
a2uther2.lib \
|
a2uther2.lib \
|
||||||
a2combo.lib \
|
a2combo.lib \
|
||||||
|
ip65_apple2.lib \
|
||||||
atrdragon.lib \
|
atrdragon.lib \
|
||||||
|
ip65_atari.lib \
|
||||||
vic20rrnet.lib
|
vic20rrnet.lib
|
||||||
|
|
||||||
all: $(DRIVERS)
|
all: $(DRIVERS)
|
||||||
|
|
||||||
|
$(DRIVERS):
|
||||||
|
ar65 a $@ $^
|
||||||
|
|
||||||
%.o: %.s
|
%.o: %.s
|
||||||
ca65 -D DYN_DRV=0 $<
|
ca65 -D DYN_DRV=0 $<
|
||||||
|
|
||||||
|
@ -35,6 +49,10 @@ C64OBJS=\
|
||||||
c64vt100.o \
|
c64vt100.o \
|
||||||
cbmcharconv.o
|
cbmcharconv.o
|
||||||
|
|
||||||
|
C64_OBJS=\
|
||||||
|
c64timer.o \
|
||||||
|
c64_input.o
|
||||||
|
|
||||||
A2OBJS=\
|
A2OBJS=\
|
||||||
a2print.o \
|
a2print.o \
|
||||||
a2timer.o \
|
a2timer.o \
|
||||||
|
@ -44,6 +62,10 @@ A2OBJS=\
|
||||||
a2vt100.o \
|
a2vt100.o \
|
||||||
a2charconv.o
|
a2charconv.o
|
||||||
|
|
||||||
|
A2_OBJS=\
|
||||||
|
a2_timer.o \
|
||||||
|
a2_input.o
|
||||||
|
|
||||||
ATROBJS=\
|
ATROBJS=\
|
||||||
atrprint.o \
|
atrprint.o \
|
||||||
atrtimer.o \
|
atrtimer.o \
|
||||||
|
@ -54,6 +76,10 @@ ATROBJS=\
|
||||||
atrvt100font.o \
|
atrvt100font.o \
|
||||||
atrcharconv.o
|
atrcharconv.o
|
||||||
|
|
||||||
|
ATR_OBJS=\
|
||||||
|
atrtimer.o \
|
||||||
|
atr_input.o
|
||||||
|
|
||||||
VIC20OBJS=\
|
VIC20OBJS=\
|
||||||
vic20print.o \
|
vic20print.o \
|
||||||
vic20timer.o \
|
vic20timer.o \
|
||||||
|
@ -63,35 +89,52 @@ VIC20OBJS=\
|
||||||
vic20vt100.o \
|
vic20vt100.o \
|
||||||
cbmcharconv.o
|
cbmcharconv.o
|
||||||
|
|
||||||
c64rrnet.lib: rr-net.o cs8900a.o cs8900adriver.o ethernet.o c64init.o $(C64OBJS)
|
CS8900AOBJS=\
|
||||||
ar65 a $@ $^
|
cs8900a.o \
|
||||||
|
cs8900adriver.o \
|
||||||
|
ethernet.o
|
||||||
|
|
||||||
c64eth64.lib: eth64.o lan91c96.o lan91c96driver.o ethernet.o c64init.o $(C64OBJS)
|
LAN91C96OBJS=\
|
||||||
ar65 a $@ $^
|
lan91c96.o \
|
||||||
|
lan91c96driver.o \
|
||||||
|
ethernet.o
|
||||||
|
|
||||||
c64wiz811.lib: wiz811mj.o w5100.o w5100driver.o ethernet.o c64init.o $(C64OBJS)
|
W5100OBJS=\
|
||||||
ar65 a $@ $^
|
w5100.o \
|
||||||
|
w5100driver.o \
|
||||||
|
ethernet.o
|
||||||
|
|
||||||
c64combo.lib: rr-net.o cs8900a.o eth64.o lan91c96.o wiz811mj.o w5100.o ethernetcombo.o c64init.o $(C64OBJS)
|
COMBOOBJS=\
|
||||||
ar65 a $@ $^
|
cs8900a.o \
|
||||||
|
lan91c96.o \
|
||||||
|
w5100.o \
|
||||||
|
ethernetcombo.o
|
||||||
|
|
||||||
a2uther.lib: uthernet.o cs8900a.o cs8900adriver.o ethernet.o a2init.o $(A2OBJS)
|
c64rrnet.lib: c64init.o rr-net.o $(CS8900AOBJS) $(C64OBJS)
|
||||||
ar65 a $@ $^
|
|
||||||
|
|
||||||
a2lancegs.lib: lancegs.o lan91c96.o lan91c96driver.o ethernet.o a2init.o $(A2OBJS)
|
c64eth64.lib: c64init.o eth64.o $(LAN91C96OBJS) $(C64OBJS)
|
||||||
ar65 a $@ $^
|
|
||||||
|
|
||||||
a2uther2.lib: uthernet2.o w5100.o w5100driver.o ethernet.o a2init.o $(A2OBJS)
|
c64wiz811.lib: c64init.o wiz811mj.o $(W5100OBJS) $(C64OBJS)
|
||||||
ar65 a $@ $^
|
|
||||||
|
|
||||||
a2combo.lib: uthernet.o cs8900a.o lancegs.o lan91c96.o uthernet2.o w5100.o ethernetcombo.o a2initcombo.o $(A2OBJS)
|
c64combo.lib: c64init.o rr-net.o eth64.o wiz811mj.o $(COMBOOBJS) $(C64OBJS)
|
||||||
ar65 a $@ $^
|
|
||||||
|
|
||||||
atrdragon.lib: dragoncart.o cs8900a.o cs8900adriver.o ethernet.o atrinit.o $(ATROBJS)
|
ip65_c64.lib: c64init.o rr-net.o eth64.o wiz811mj.o $(COMBOOBJS) $(C64_OBJS)
|
||||||
ar65 a $@ $^
|
|
||||||
|
|
||||||
vic20rrnet.lib: vic20-rr-net.o cs8900a.o cs8900adriver.o ethernet.o vic20init.o $(VIC20OBJS)
|
a2uther.lib: a2init.o uthernet.o $(CS8900AOBJS) $(A2OBJS)
|
||||||
ar65 a $@ $^
|
|
||||||
|
a2lancegs.lib: a2init.o lancegs.o $(LAN91C96OBJS) $(A2OBJS)
|
||||||
|
|
||||||
|
a2uther2.lib: a2init.o uthernet2.o $(W5100OBJS) $(A2OBJS)
|
||||||
|
|
||||||
|
a2combo.lib: a2initcombo.o uthernet.o lancegs.o uthernet2.o $(COMBOOBJS) $(A2OBJS)
|
||||||
|
|
||||||
|
ip65_apple2.lib: a2initcombo.o uthernet.o lancegs.o uthernet2.o $(COMBOOBJS) $(A2_OBJS)
|
||||||
|
|
||||||
|
atrdragon.lib: atrinit.o dragoncart.o $(CS8900AOBJS) $(ATROBJS)
|
||||||
|
|
||||||
|
ip65_atari.lib: atrinit.o dragoncart.o $(CS8900AOBJS) $(ATR_OBJS)
|
||||||
|
|
||||||
|
vic20rrnet.lib: vic20init.o vic20-rr-net.o $(CS8900AOBJS) $(VIC20OBJS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f *.o
|
-rm -f *.o
|
||||||
|
|
46
drivers/a2_input.s
Normal file
46
drivers/a2_input.s
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
.export check_for_abort_key
|
||||||
|
.export abort_key
|
||||||
|
.exportzp abort_key_default = $9b
|
||||||
|
.exportzp abort_key_disable = $80
|
||||||
|
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
abort_key: .byte $9b ; ESC
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
; check whether the abort key is being pressed
|
||||||
|
; inputs: none
|
||||||
|
; outputs: sec if abort key pressed, clear otherwise
|
||||||
|
check_for_abort_key:
|
||||||
|
lda $c000 ; current key pressed
|
||||||
|
cmp abort_key
|
||||||
|
bne :+
|
||||||
|
bit $c010 ; clear the keyboard strobe
|
||||||
|
sec
|
||||||
|
rts
|
||||||
|
: clc
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; -- LICENSE FOR a2_inputc.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 --
|
73
drivers/a2_timer.s
Normal file
73
drivers/a2_timer.s
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
; 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
|
||||||
|
.export timer_seconds
|
||||||
|
|
||||||
|
|
||||||
|
.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:
|
||||||
|
bit $c082 ; switch in ROM
|
||||||
|
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
|
||||||
|
bit $c080 ; switch in LC bank 2 for R/O
|
||||||
|
rts
|
||||||
|
|
||||||
|
timer_seconds:
|
||||||
|
lda #0
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; -- LICENSE FOR a2_timerc.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 --
|
49
drivers/atr_input.s
Normal file
49
drivers/atr_input.s
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
.include "atari.inc"
|
||||||
|
|
||||||
|
.export check_for_abort_key
|
||||||
|
.export abort_key
|
||||||
|
.exportzp abort_key_default = 1
|
||||||
|
.exportzp abort_key_disable = 0
|
||||||
|
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
abort_key: .byte 1
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
; check whether the abort key is being pressed
|
||||||
|
; inputs: none
|
||||||
|
; outputs: sec if abort key pressed, clear otherwise
|
||||||
|
check_for_abort_key:
|
||||||
|
lda abort_key ; is "abort" enabled?
|
||||||
|
beq nokey ; no
|
||||||
|
lda BRKKEY
|
||||||
|
bne nokey
|
||||||
|
dec BRKKEY
|
||||||
|
sec
|
||||||
|
rts
|
||||||
|
nokey:
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;-- LICENSE FOR atr_inputs.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 --
|
54
drivers/c64_input.s
Normal file
54
drivers/c64_input.s
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
.export check_for_abort_key
|
||||||
|
.export abort_key
|
||||||
|
.exportzp abort_key_default = $3f
|
||||||
|
.exportzp abort_key_disable = $ff
|
||||||
|
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
abort_key: .byte $3f ; RUN/STOP
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
; check whether the abort key is being pressed
|
||||||
|
; inputs: none
|
||||||
|
; outputs: sec if abort key pressed, clear otherwise
|
||||||
|
check_for_abort_key:
|
||||||
|
lda $cb ; current key pressed
|
||||||
|
cmp abort_key
|
||||||
|
bne no_key
|
||||||
|
@flush_loop:
|
||||||
|
ldy #$ff
|
||||||
|
jsr $f142 ; not officially documented - where F13E (GETIN) falls through to if device # is 0 (KEYBD)
|
||||||
|
cpy #$ff ; Y gets modified iff there's a character available - this approach allows to read ^@ as 0
|
||||||
|
bne @flush_loop
|
||||||
|
lda $cb ; current key pressed
|
||||||
|
cmp abort_key
|
||||||
|
beq @flush_loop
|
||||||
|
sec
|
||||||
|
rts
|
||||||
|
no_key:
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; -- LICENSE FOR c64_input.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 --
|
181
inc/ip65.h
Normal file
181
inc/ip65.h
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
#ifndef _IP65_H
|
||||||
|
#define _IP65_H
|
||||||
|
|
||||||
|
// Error codes
|
||||||
|
//
|
||||||
|
#define IP65_ERROR_PORT_IN_USE $80
|
||||||
|
#define IP65_ERROR_TIMEOUT_ON_RECEIVE $81
|
||||||
|
#define IP65_ERROR_TRANSMIT_FAILED $82
|
||||||
|
#define IP65_ERROR_TRANSMISSION_REJECTED_BY_PEER $83
|
||||||
|
#define IP65_ERROR_INPUT_TOO_LARGE $84
|
||||||
|
#define IP65_ERROR_DEVICE_FAILURE $85
|
||||||
|
#define IP65_ERROR_ABORTED_BY_USER $86
|
||||||
|
#define IP65_ERROR_LISTENER_NOT_AVAILABLE $87
|
||||||
|
#define IP65_ERROR_CONNECTION_RESET_BY_PEER $89
|
||||||
|
#define IP65_ERROR_CONNECTION_CLOSED $8A
|
||||||
|
#define IP65_ERROR_FILE_ACCESS_FAILURE $90
|
||||||
|
#define IP65_ERROR_MALFORMED_URL $A0
|
||||||
|
#define IP65_ERROR_DNS_LOOKUP_FAILED $A1
|
||||||
|
|
||||||
|
// Last error code
|
||||||
|
//
|
||||||
|
extern unsigned char ip65_error;
|
||||||
|
|
||||||
|
// MAC address of local machine (will be overwritten if ip65_init is called)
|
||||||
|
//
|
||||||
|
extern unsigned char cfg_mac[6];
|
||||||
|
|
||||||
|
// IP address of local machine (will be overwritten if dhcp_init is called)
|
||||||
|
//
|
||||||
|
extern unsigned long cfg_ip;
|
||||||
|
|
||||||
|
// Netmask of local network (will be overwritten if dhcp_init is called)
|
||||||
|
//
|
||||||
|
extern unsigned long cfg_netmask;
|
||||||
|
|
||||||
|
// IP address of router on local network (will be overwritten if dhcp_init is called)
|
||||||
|
//
|
||||||
|
extern unsigned long cfg_gateway;
|
||||||
|
|
||||||
|
// IP address of dns server to use (will be overwritten if dhcp_init is called)
|
||||||
|
//
|
||||||
|
extern unsigned long cfg_dns;
|
||||||
|
|
||||||
|
// Will be set to address of DHCP server that configuration was obtained from
|
||||||
|
//
|
||||||
|
extern unsigned long dhcp_server;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
extern unsigned char* tcp_packet;
|
||||||
|
extern unsigned int tcp_packet_len;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// Output: 1 if there was an error, 0 otherwise
|
||||||
|
//
|
||||||
|
unsigned char ip65_init(void);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// Output: 1 if no packet was waiting or packet handling caused error, 0 otherwise
|
||||||
|
//
|
||||||
|
unsigned char ip65_process(void);
|
||||||
|
|
||||||
|
// Generate a 'random' 16 bit word
|
||||||
|
//
|
||||||
|
// Entropy comes from the last ethernet frame, counters, and timer.
|
||||||
|
//
|
||||||
|
// Inputs: None
|
||||||
|
// Output: Pseudo-random 16 bit number
|
||||||
|
//
|
||||||
|
unsigned int ip65_random_word(void);
|
||||||
|
|
||||||
|
// Convert 4 octets (IP address, netmask) into a string representing a dotted quad
|
||||||
|
//
|
||||||
|
// The string is returned in a statically allocated buffer, which subsequent calls
|
||||||
|
// will overwrite.
|
||||||
|
//
|
||||||
|
// Inputs: quad: IP address
|
||||||
|
// Output: Null terminated string containing dotted quad (e.g. "192.168.1.0")
|
||||||
|
//
|
||||||
|
char* __fastcall__ dotted_quad(unsigned long quad);
|
||||||
|
|
||||||
|
// Convert a string representing a dotted quad (IP address, netmask) into 4 octets
|
||||||
|
//
|
||||||
|
// Inputs: quad: Null terminated string containing dotted quad (e.g. "192.168.1.0"),
|
||||||
|
// to simplify URL parsing, a ':' or '/' can also terminate the string.
|
||||||
|
// Output: IP address, 0 on error
|
||||||
|
//
|
||||||
|
unsigned long __fastcall__ parse_dotted_quad(char* quad);
|
||||||
|
|
||||||
|
// Minimal DHCP client 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.
|
||||||
|
//
|
||||||
|
// Inputs: None (although ip65_init should be called first)
|
||||||
|
// Output: 0 if 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.
|
||||||
|
// 1 if there was an error
|
||||||
|
//
|
||||||
|
unsigned char dhcp_init(void);
|
||||||
|
|
||||||
|
// Resolve a string containing a hostname (or a dotted quad) to an IP address
|
||||||
|
//
|
||||||
|
// Inputs: hostname: pointer to null terminated string that contains either
|
||||||
|
// a DNS hostname (e.g. "host.example.com") or an address
|
||||||
|
// in "dotted quad" format (e.g. "192.168.1.0").
|
||||||
|
// Output: IP address of the hostname, 0 on error
|
||||||
|
//
|
||||||
|
unsigned long __fastcall__ dns_resolve(const char* hostname);
|
||||||
|
|
||||||
|
// Send a ping (ICMP echo request) to a remote host, and wait for a response
|
||||||
|
//
|
||||||
|
// Inputs: dest: Destination IP address
|
||||||
|
// Output: 0 if no response, otherwise time (in miliseconds) for host to respond
|
||||||
|
//
|
||||||
|
unsigned int __fastcall__ icmp_ping(unsigned long dest);
|
||||||
|
|
||||||
|
// Add a UDP listener
|
||||||
|
//
|
||||||
|
// Inputs: port: UDP port to listen on
|
||||||
|
// callback: Vector to call when UDP packet arrives on specified port
|
||||||
|
// Output: 1 if too may listeners already installed, 0 otherwise
|
||||||
|
//
|
||||||
|
unsigned char __fastcall__ udp_add_listener(unsigned int port, void (*callback)(void));
|
||||||
|
|
||||||
|
// Remove a UDP listener
|
||||||
|
//
|
||||||
|
// Inputs: port: UDP port to stop listening on
|
||||||
|
// Output: 0 if handler found and removed,
|
||||||
|
// 1 if handler for specified port not found
|
||||||
|
//
|
||||||
|
unsigned char __fastcall__ udp_remove_listener(unsigned int port);
|
||||||
|
|
||||||
|
// Access to received UDP packet
|
||||||
|
//
|
||||||
|
// Access to the four items below is only valid in the context of a callback
|
||||||
|
// added with udp_add_listener.
|
||||||
|
//
|
||||||
|
extern unsigned char udp_recv_buf[1476]; // Buffer with data received
|
||||||
|
unsigned int udp_recv_len(void); // Length of data received
|
||||||
|
unsigned long udp_recv_src(void); // Source IP address
|
||||||
|
unsigned int udp_recv_src_port(void); // Source port
|
||||||
|
|
||||||
|
// Send a UDP packet
|
||||||
|
//
|
||||||
|
// If the correct MAC address can't be found in the ARP cache then
|
||||||
|
// an ARP request is sent - and the UDP packet is NOT sent. The caller
|
||||||
|
// should wait a while calling ip65_process (to allow time for an ARP
|
||||||
|
// response to arrive) and then call upd_send again. This behavior
|
||||||
|
// makes sense as a UDP packet may get lost in transit at any time
|
||||||
|
// so the caller should to be prepared to resend it after a while
|
||||||
|
// anyway.
|
||||||
|
//
|
||||||
|
// Inputs: buf: Pointer to buffer containing data to be sent
|
||||||
|
// len: Length of data to send (exclusive of any headers)
|
||||||
|
// dest: Destination IP address
|
||||||
|
// dest_port: Destination port
|
||||||
|
// src_port: Source port
|
||||||
|
// Output: 1 if an error occured, 0 otherwise
|
||||||
|
//
|
||||||
|
unsigned char __fastcall__ udp_send(const unsigned char* buf, unsigned int len,
|
||||||
|
unsigned long dest, unsigned int dest_port,
|
||||||
|
unsigned int src_port);
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,14 +13,20 @@ IP65OBJS=\
|
||||||
arithmetic.o \
|
arithmetic.o \
|
||||||
arp.o \
|
arp.o \
|
||||||
config.o \
|
config.o \
|
||||||
|
config_c.o \
|
||||||
copymem.o \
|
copymem.o \
|
||||||
dhcp.o \
|
dhcp.o \
|
||||||
|
dhcp_c.o \
|
||||||
dns.o \
|
dns.o \
|
||||||
|
dns_c.o \
|
||||||
dottedquad.o \
|
dottedquad.o \
|
||||||
|
dottedquad_c.o \
|
||||||
eth.o \
|
eth.o \
|
||||||
http.o \
|
http.o \
|
||||||
httpd.o \
|
httpd.o \
|
||||||
|
icmp_c.o \
|
||||||
ip65.o \
|
ip65.o \
|
||||||
|
ip65_c.o \
|
||||||
tftp.o \
|
tftp.o \
|
||||||
timer.o \
|
timer.o \
|
||||||
output_buffer.o \
|
output_buffer.o \
|
||||||
|
@ -28,6 +34,7 @@ IP65OBJS=\
|
||||||
sntp.o \
|
sntp.o \
|
||||||
string_utils.o \
|
string_utils.o \
|
||||||
udp.o \
|
udp.o \
|
||||||
|
udp_c.o \
|
||||||
url.o
|
url.o
|
||||||
|
|
||||||
ip65.lib: $(IP65OBJS) ip.o icmp.o
|
ip65.lib: $(IP65OBJS) ip.o icmp.o
|
||||||
|
|
27
ip65/config_c.s
Normal file
27
ip65/config_c.s
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export _cfg_mac
|
||||||
|
.export _cfg_ip
|
||||||
|
.export _cfg_netmask
|
||||||
|
.export _cfg_gateway
|
||||||
|
.export _cfg_dns
|
||||||
|
.export _dhcp_server
|
||||||
|
|
||||||
|
.import cfg_mac
|
||||||
|
.import cfg_ip
|
||||||
|
.import cfg_netmask
|
||||||
|
.import cfg_gateway
|
||||||
|
.import cfg_dns
|
||||||
|
.import dhcp_server
|
||||||
|
|
||||||
|
_cfg_mac := cfg_mac
|
||||||
|
|
||||||
|
_cfg_ip := cfg_ip
|
||||||
|
|
||||||
|
_cfg_netmask := cfg_netmask
|
||||||
|
|
||||||
|
_cfg_gateway := cfg_gateway
|
||||||
|
|
||||||
|
_cfg_dns := cfg_dns
|
||||||
|
|
||||||
|
_dhcp_server := dhcp_server
|
12
ip65/dhcp_c.s
Normal file
12
ip65/dhcp_c.s
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export _dhcp_init
|
||||||
|
|
||||||
|
.import dhcp_init
|
||||||
|
|
||||||
|
_dhcp_init:
|
||||||
|
jsr dhcp_init
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
rol
|
||||||
|
rts
|
25
ip65/dns_c.s
Normal file
25
ip65/dns_c.s
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export _dns_resolve
|
||||||
|
|
||||||
|
.import dns_set_hostname
|
||||||
|
.import dns_resolve
|
||||||
|
.import dns_ip
|
||||||
|
|
||||||
|
.importzp sreg
|
||||||
|
|
||||||
|
_dns_resolve:
|
||||||
|
jsr dns_set_hostname
|
||||||
|
bcs error
|
||||||
|
jsr dns_resolve
|
||||||
|
bcs error
|
||||||
|
ldax dns_ip+2
|
||||||
|
stax sreg
|
||||||
|
ldax dns_ip
|
||||||
|
rts
|
||||||
|
|
||||||
|
error:
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
stax sreg
|
||||||
|
rts
|
92
ip65/dottedquad_c.s
Normal file
92
ip65/dottedquad_c.s
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export _dotted_quad
|
||||||
|
.export _parse_dotted_quad
|
||||||
|
|
||||||
|
.import parse_dotted_quad
|
||||||
|
.import dotted_quad_value
|
||||||
|
|
||||||
|
.importzp sreg, tmp1, tmp2, tmp3
|
||||||
|
|
||||||
|
|
||||||
|
.bss
|
||||||
|
|
||||||
|
dotted_quad: .res 4*4 ; "xxx.xxx.xxx.xxx\0"
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
_dotted_quad:
|
||||||
|
stax dotted_quad_value
|
||||||
|
ldax sreg
|
||||||
|
stax dotted_quad_value+2
|
||||||
|
|
||||||
|
ldx #$00
|
||||||
|
ldy #$00
|
||||||
|
: jsr convert_byte
|
||||||
|
inx
|
||||||
|
cpx #4
|
||||||
|
bcc :-
|
||||||
|
|
||||||
|
dey
|
||||||
|
lda #$00
|
||||||
|
sta dotted_quad,y ; replace last dot with '\0'
|
||||||
|
ldax #dotted_quad
|
||||||
|
rts
|
||||||
|
|
||||||
|
convert_byte:
|
||||||
|
; hex to bcd routine taken from Andrew Jacob's code at http://www.6502.org/source/integers/hex2dec-more.htm
|
||||||
|
sed ; switch to decimal mode
|
||||||
|
lda #$00 ; ensure the result is clear
|
||||||
|
sta tmp1 ; BCD low
|
||||||
|
sta tmp2 ; BCD high
|
||||||
|
lda #8 ; the number of source bits
|
||||||
|
sta tmp3
|
||||||
|
: asl dotted_quad_value,x ; shift out one bit
|
||||||
|
lda tmp1 ; and add into result
|
||||||
|
adc tmp1
|
||||||
|
sta tmp1
|
||||||
|
lda tmp2 ; propagating any carry
|
||||||
|
adc tmp2
|
||||||
|
sta tmp2
|
||||||
|
dec tmp3 ; and repeat for next bit
|
||||||
|
bne :-
|
||||||
|
cld ; back to binary
|
||||||
|
|
||||||
|
lda tmp2
|
||||||
|
beq :+
|
||||||
|
ora #'0'
|
||||||
|
sta dotted_quad,y ; write x00 if not 0
|
||||||
|
iny
|
||||||
|
: lda tmp1
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
beq :+
|
||||||
|
ora #'0'
|
||||||
|
sta dotted_quad,y ; write 0x0 if not 0
|
||||||
|
iny
|
||||||
|
: lda tmp1
|
||||||
|
and #$0F
|
||||||
|
ora #'0'
|
||||||
|
sta dotted_quad,y ; write 00x
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda #'.'
|
||||||
|
sta dotted_quad,y ; write dot
|
||||||
|
iny
|
||||||
|
rts
|
||||||
|
|
||||||
|
_parse_dotted_quad:
|
||||||
|
jsr parse_dotted_quad
|
||||||
|
bcs error
|
||||||
|
ldax dotted_quad_value+2
|
||||||
|
stax sreg
|
||||||
|
ldax dotted_quad_value
|
||||||
|
rts
|
||||||
|
|
||||||
|
error:
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
stax sreg
|
||||||
|
rts
|
18
ip65/icmp_c.s
Normal file
18
ip65/icmp_c.s
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export _icmp_ping
|
||||||
|
|
||||||
|
.import icmp_echo_ip
|
||||||
|
.import icmp_ping
|
||||||
|
|
||||||
|
.importzp sreg
|
||||||
|
|
||||||
|
_icmp_ping:
|
||||||
|
stax icmp_echo_ip
|
||||||
|
ldax sreg
|
||||||
|
stax icmp_echo_ip+2
|
||||||
|
jsr icmp_ping
|
||||||
|
bcc :+
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
: rts
|
29
ip65/ip65_c.s
Normal file
29
ip65/ip65_c.s
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export _ip65_init
|
||||||
|
.export _ip65_process
|
||||||
|
.export _ip65_random_word
|
||||||
|
.export _ip65_error
|
||||||
|
|
||||||
|
.import ip65_init
|
||||||
|
.import ip65_process
|
||||||
|
.import ip65_random_word
|
||||||
|
.import ip65_error
|
||||||
|
|
||||||
|
_ip65_init:
|
||||||
|
jsr ip65_init
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
rol
|
||||||
|
rts
|
||||||
|
|
||||||
|
_ip65_process:
|
||||||
|
jsr ip65_process
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
rol
|
||||||
|
rts
|
||||||
|
|
||||||
|
_ip65_random_word := ip65_random_word
|
||||||
|
|
||||||
|
_ip65_error := ip65_error
|
83
ip65/udp_c.s
Normal file
83
ip65/udp_c.s
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export _udp_add_listener
|
||||||
|
.export _udp_remove_listener
|
||||||
|
.export _udp_recv_buf
|
||||||
|
.export _udp_recv_len
|
||||||
|
.export _udp_recv_src
|
||||||
|
.export _udp_recv_src_port
|
||||||
|
.export _udp_send
|
||||||
|
|
||||||
|
.import udp_add_listener
|
||||||
|
.import udp_remove_listener
|
||||||
|
.import ip_inp
|
||||||
|
.import udp_inp
|
||||||
|
.import udp_send
|
||||||
|
|
||||||
|
.import udp_callback
|
||||||
|
.importzp ip_src
|
||||||
|
.importzp udp_src_port
|
||||||
|
.importzp udp_len
|
||||||
|
.importzp udp_data
|
||||||
|
.import udp_send_len
|
||||||
|
.import udp_send_dest
|
||||||
|
.import udp_send_dest_port
|
||||||
|
.import udp_send_src_port
|
||||||
|
|
||||||
|
.import popax, popeax
|
||||||
|
.importzp sreg
|
||||||
|
|
||||||
|
_udp_add_listener:
|
||||||
|
stax udp_callback
|
||||||
|
jsr popax
|
||||||
|
jsr udp_add_listener
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
rol
|
||||||
|
rts
|
||||||
|
|
||||||
|
_udp_remove_listener:
|
||||||
|
jsr udp_remove_listener
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
rol
|
||||||
|
rts
|
||||||
|
|
||||||
|
_udp_recv_buf := udp_inp+udp_data
|
||||||
|
|
||||||
|
_udp_recv_len:
|
||||||
|
lda udp_inp+udp_len+1
|
||||||
|
ldx udp_inp+udp_len
|
||||||
|
sec
|
||||||
|
sbc #udp_data
|
||||||
|
bcs :+
|
||||||
|
dex
|
||||||
|
: rts
|
||||||
|
|
||||||
|
_udp_recv_src:
|
||||||
|
ldax ip_inp+ip_src+2
|
||||||
|
stax sreg
|
||||||
|
ldax ip_inp+ip_src
|
||||||
|
rts
|
||||||
|
|
||||||
|
_udp_recv_src_port:
|
||||||
|
lda udp_inp+udp_src_port+1
|
||||||
|
ldx udp_inp+udp_src_port
|
||||||
|
rts
|
||||||
|
|
||||||
|
_udp_send:
|
||||||
|
stax udp_send_src_port
|
||||||
|
jsr popax
|
||||||
|
stax udp_send_dest_port
|
||||||
|
jsr popeax
|
||||||
|
stax udp_send_dest
|
||||||
|
ldax sreg
|
||||||
|
stax udp_send_dest+2
|
||||||
|
jsr popax
|
||||||
|
stax udp_send_len
|
||||||
|
jsr popax
|
||||||
|
jsr udp_send
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
rol
|
||||||
|
rts
|
|
@ -29,6 +29,7 @@ UDP =\
|
||||||
parsequerystring \
|
parsequerystring \
|
||||||
sntp \
|
sntp \
|
||||||
tftp \
|
tftp \
|
||||||
|
udp \
|
||||||
vt100
|
vt100
|
||||||
|
|
||||||
TCP =\
|
TCP =\
|
||||||
|
@ -91,6 +92,8 @@ vt100.com: ATARI_CFG = ../apps/atrtelnet.cfg
|
||||||
%-slotscan.o: %.s
|
%-slotscan.o: %.s
|
||||||
ca65 -D A2_SLOT_SCAN -o $@ $<
|
ca65 -D A2_SLOT_SCAN -o $@ $<
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
|
||||||
%.prg: %.o ip65 drivers $(INCFILES)
|
%.prg: %.o ip65 drivers $(INCFILES)
|
||||||
ld65 -o $*.prg -C c64.cfg -m $*.c64.map -vm $< $(IP65LIB) $(C64DRIVERLIB) c64.lib
|
ld65 -o $*.prg -C c64.cfg -m $*.c64.map -vm $< $(IP65LIB) $(C64DRIVERLIB) c64.lib
|
||||||
|
|
||||||
|
@ -103,6 +106,18 @@ vt100.com: ATARI_CFG = ../apps/atrtelnet.cfg
|
||||||
%.vicprg: %.o ip65 drivers $(INCFILES)
|
%.vicprg: %.o ip65 drivers $(INCFILES)
|
||||||
ld65 -o $*.vicprg -C vic20-32k.cfg -m $*.vic.map -vm $< $(IP65LIB) $(VICDRIVERLIB) vic20.lib
|
ld65 -o $*.vicprg -C vic20-32k.cfg -m $*.vic.map -vm $< $(IP65LIB) $(VICDRIVERLIB) vic20.lib
|
||||||
|
|
||||||
|
%.prg: %.c ip65 drivers $(INCFILES)
|
||||||
|
cl65 -o $*.prg -O -t c64 -m $*.c64.map -vm $< $(IP65LIB) ../drivers/ip65_c64.lib
|
||||||
|
rm $*.o
|
||||||
|
|
||||||
|
%.bin: %.c ip65 drivers $(INCFILES)
|
||||||
|
cl65 -o $*.bin -O -t apple2 -m $*.a2.map -vm $< $(IP65LIB) ../drivers/ip65_apple2.lib
|
||||||
|
rm $*.o
|
||||||
|
|
||||||
|
%.com: %.c ip65 drivers $(INCFILES)
|
||||||
|
cl65 -o $*.com -O -t atari -m $*.atr.map -vm $< $(IP65LIB) ../drivers/ip65_atari.lib
|
||||||
|
rm $*.o
|
||||||
|
|
||||||
ip65test.d64: prg
|
ip65test.d64: prg
|
||||||
$(C1541) -format ip65,00 d64 $@
|
$(C1541) -format ip65,00 d64 $@
|
||||||
$(C1541) -attach $@ -write dns.prg dns,p
|
$(C1541) -attach $@ -write dns.prg dns,p
|
||||||
|
@ -114,6 +129,7 @@ ip65test.d64: prg
|
||||||
$(C1541) -attach $@ -write ping.prg ping,p
|
$(C1541) -attach $@ -write ping.prg ping,p
|
||||||
$(C1541) -attach $@ -write sntp.prg sntp,p
|
$(C1541) -attach $@ -write sntp.prg sntp,p
|
||||||
$(C1541) -attach $@ -write tftp.prg tftp,p
|
$(C1541) -attach $@ -write tftp.prg tftp,p
|
||||||
|
$(C1541) -attach $@ -write udp.prg udp,p
|
||||||
$(C1541) -attach $@ -write vt100.prg vt100,p
|
$(C1541) -attach $@ -write vt100.prg vt100,p
|
||||||
|
|
||||||
ip65test.dsk: bin
|
ip65test.dsk: bin
|
||||||
|
@ -128,6 +144,7 @@ ip65test.dsk: bin
|
||||||
java -jar $(AC) -cc65 $@ ping bin < ping.bin
|
java -jar $(AC) -cc65 $@ ping bin < ping.bin
|
||||||
java -jar $(AC) -cc65 $@ sntp bin < sntp.bin
|
java -jar $(AC) -cc65 $@ sntp bin < sntp.bin
|
||||||
java -jar $(AC) -cc65 $@ tftp bin < tftp.bin
|
java -jar $(AC) -cc65 $@ tftp bin < tftp.bin
|
||||||
|
java -jar $(AC) -cc65 $@ udp bin < udp.bin
|
||||||
java -jar $(AC) -cc65 $@ vt100 bin < vt100.bin
|
java -jar $(AC) -cc65 $@ vt100 bin < vt100.bin
|
||||||
|
|
||||||
ip65test.atr: com
|
ip65test.atr: com
|
||||||
|
@ -143,12 +160,16 @@ ip65test.atr: com
|
||||||
cp ping.com atr/ping.com
|
cp ping.com atr/ping.com
|
||||||
cp sntp.com atr/sntp.com
|
cp sntp.com atr/sntp.com
|
||||||
cp tftp.com atr/tftp.com
|
cp tftp.com atr/tftp.com
|
||||||
|
cp udp.com atr/udp.com
|
||||||
cp vt100.com atr/vt100.com
|
cp vt100.com atr/vt100.com
|
||||||
$(DIR2ATR) -b Dos25 1040 $@ atr
|
$(DIR2ATR) -b Dos25 1040 $@ atr
|
||||||
rm -r atr
|
rm -r atr
|
||||||
|
|
||||||
|
%.exe: %.c
|
||||||
|
cl /Fe:$@ $^
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C ../ip65 clean
|
make -C ../ip65 clean
|
||||||
make -C ../drivers clean
|
make -C ../drivers clean
|
||||||
-rm -f *.o *.prg *.bin *.com *.vicprg *.map
|
-rm -f *.o *.prg *.bin *.com *.vicprg *.map *.obj *.exe
|
||||||
-rm -f ip65test.d64 ip65test.dsk ip65test.atr
|
-rm -f ip65test.d64 ip65test.dsk ip65test.atr
|
||||||
|
|
212
test/peer.c
Normal file
212
test/peer.c
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <winsock2.h>
|
||||||
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
|
||||||
|
#define LEN 200
|
||||||
|
|
||||||
|
static void dump(unsigned char *buf, unsigned len)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
if ((i % 24) == 0)
|
||||||
|
{
|
||||||
|
printf("\n$%04X:", i);
|
||||||
|
}
|
||||||
|
printf(" %02X", buf[i]);
|
||||||
|
}
|
||||||
|
printf(".\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
printf("Init\n");
|
||||||
|
WSADATA wsa;
|
||||||
|
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET udp = socket(AF_INET, SOCK_DGRAM , IPPROTO_UDP);
|
||||||
|
if (udp == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SOCKET srv = socket(AF_INET, SOCK_STREAM , IPPROTO_TCP);
|
||||||
|
if (srv == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_long arg = 1;
|
||||||
|
if (ioctlsocket(udp, FIONBIO, &arg) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ioctlsocket(srv, FIONBIO, &arg) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKADDR_IN local;
|
||||||
|
local.sin_family = AF_INET;
|
||||||
|
local.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
local.sin_port = htons(6502);
|
||||||
|
if (bind(udp, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bind(srv, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(srv, 1) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKADDR_IN remote;
|
||||||
|
remote.sin_addr.s_addr = INADDR_NONE;
|
||||||
|
|
||||||
|
SOCKET tcp = INVALID_SOCKET;
|
||||||
|
|
||||||
|
printf("(U)DP, (T)CP or e(X)it\n");
|
||||||
|
char key;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
unsigned char buf[1500];
|
||||||
|
|
||||||
|
if (kbhit())
|
||||||
|
{
|
||||||
|
key = getch();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == 'u')
|
||||||
|
{
|
||||||
|
if (remote.sin_addr.s_addr == INADDR_NONE)
|
||||||
|
{
|
||||||
|
printf("Peer Unknown As Yet\n", len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
len = LEN;
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
buf[i] = i;
|
||||||
|
}
|
||||||
|
printf("Send Len %d To %s", len, inet_ntoa(remote.sin_addr));
|
||||||
|
if (sendto(udp, buf, len, 0, (SOCKADDR *)&remote, sizeof(remote)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf(".\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == 't')
|
||||||
|
{
|
||||||
|
if (tcp == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
printf("No Connection\n", len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
len = LEN;
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
buf[i] = i;
|
||||||
|
}
|
||||||
|
printf("Send Len %d", len);
|
||||||
|
if (send(tcp, buf, len, 0) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf(".\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned remote_size = sizeof(remote);
|
||||||
|
len = recvfrom(udp, buf, sizeof(buf), 0, (SOCKADDR *)&remote, &remote_size);
|
||||||
|
if (len == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len)
|
||||||
|
{
|
||||||
|
printf("Recv Len %d From %s", len, inet_ntoa(remote.sin_addr));
|
||||||
|
dump(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcp == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
SOCKADDR_IN conn;
|
||||||
|
unsigned conn_size = sizeof(conn);
|
||||||
|
tcp = accept(srv, (SOCKADDR *)&conn, &conn_size);
|
||||||
|
if (tcp == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Connect From %s\n", inet_ntoa(conn.sin_addr));
|
||||||
|
|
||||||
|
u_long arg = 1;
|
||||||
|
if (ioctlsocket(tcp, FIONBIO, &arg) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = recv(tcp, buf, sizeof(buf), 0);
|
||||||
|
if (len == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len)
|
||||||
|
{
|
||||||
|
printf("Recv Len %d", len);
|
||||||
|
dump(buf, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Disconnect\n");
|
||||||
|
closesocket(tcp);
|
||||||
|
tcp = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sleep(10);
|
||||||
|
}
|
||||||
|
while (key != 'x');
|
||||||
|
|
||||||
|
closesocket(udp);
|
||||||
|
closesocket(tcp);
|
||||||
|
closesocket(srv);
|
||||||
|
WSACleanup();
|
||||||
|
printf("Done\n");
|
||||||
|
}
|
114
test/udp.c
Normal file
114
test/udp.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include <cc65.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "../inc/ip65.h"
|
||||||
|
|
||||||
|
#define LEN 500
|
||||||
|
#define SRV "192.168.0.10"
|
||||||
|
|
||||||
|
char buf[LEN];
|
||||||
|
|
||||||
|
void error_exit(void)
|
||||||
|
{
|
||||||
|
printf("Error $%X\n", ip65_error);
|
||||||
|
if (doesclrscrafterexit())
|
||||||
|
{
|
||||||
|
printf("Press any key\n");
|
||||||
|
cgetc();
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void udp_recv(void)
|
||||||
|
{
|
||||||
|
unsigned len = udp_recv_len();
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
printf("Recv Len %u From %s", len, dotted_quad(udp_recv_src()));
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
if ((i % 11) == 0)
|
||||||
|
{
|
||||||
|
printf("\n$%04X:", i);
|
||||||
|
}
|
||||||
|
printf(" %02X", udp_recv_buf[i]);
|
||||||
|
}
|
||||||
|
printf(".\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
unsigned long srv;
|
||||||
|
char key;
|
||||||
|
|
||||||
|
for (i = 0; i < LEN; ++i)
|
||||||
|
buf[i] = i;
|
||||||
|
|
||||||
|
if(!(srv = parse_dotted_quad(SRV)))
|
||||||
|
{
|
||||||
|
error_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Init\n");
|
||||||
|
if (ip65_init())
|
||||||
|
{
|
||||||
|
error_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("DHCP\n");
|
||||||
|
if (dhcp_init())
|
||||||
|
{
|
||||||
|
error_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("IP Addr: %s\n", dotted_quad(cfg_ip));
|
||||||
|
printf("Netmask: %s\n", dotted_quad(cfg_netmask));
|
||||||
|
printf("Gateway: %s\n", dotted_quad(cfg_gateway));
|
||||||
|
printf("DNS Srv: %s\n", dotted_quad(cfg_dns));
|
||||||
|
|
||||||
|
printf("Listen\n");
|
||||||
|
if (udp_add_listener(6502, udp_recv))
|
||||||
|
{
|
||||||
|
error_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("(U)DP or e(X)it\n");
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ip65_process();
|
||||||
|
|
||||||
|
if (kbhit())
|
||||||
|
{
|
||||||
|
key = cgetc();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == 'u')
|
||||||
|
{
|
||||||
|
printf("Send Len %d To %s", LEN, SRV);
|
||||||
|
if (udp_send(buf, LEN, srv, 6502, 6502))
|
||||||
|
{
|
||||||
|
printf("!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(".\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (key != 'x');
|
||||||
|
|
||||||
|
printf("Unlisten\n");
|
||||||
|
if (udp_remove_listener(6502))
|
||||||
|
{
|
||||||
|
error_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Done\n");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user