mirror of
https://github.com/dschmenk/PLASMA.git
synced 2024-08-21 21:29:08 +00:00
update to latest library and formatting
This commit is contained in:
parent
0d484e75d2
commit
b25b5cd233
@ -37,6 +37,7 @@ import fileio
|
||||
word getpfx
|
||||
word setpfx
|
||||
word getfileinfo
|
||||
word geteof
|
||||
word open
|
||||
word close
|
||||
word read
|
||||
|
1002
src/libsrc/dgr.pla
1002
src/libsrc/dgr.pla
File diff suppressed because it is too large
Load Diff
@ -2,29 +2,7 @@
|
||||
// DHCP
|
||||
//
|
||||
include "inc/cmdsys.plh"
|
||||
//
|
||||
// Net object
|
||||
//
|
||||
import inet
|
||||
word iNet
|
||||
end
|
||||
struc t_inet
|
||||
word initIP
|
||||
word serviceIP
|
||||
word openUDP
|
||||
word sendUDP
|
||||
word closeUDP
|
||||
word listenTCP
|
||||
word connectTCP
|
||||
word sendTCP
|
||||
word closeTCP
|
||||
word setInterfaceIP
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
include "inc/inet.plh"
|
||||
//
|
||||
// Needed to init subnet
|
||||
//
|
||||
@ -109,58 +87,58 @@ byte[] endDHCP
|
||||
//
|
||||
// DEBUG
|
||||
//
|
||||
byte boundstr = "Apple II bound to:\n"
|
||||
byte dnsstr = "DNS: "
|
||||
def putb(hexb)
|
||||
return call($FDDA, hexb, 0, 0, 0)
|
||||
end
|
||||
def puth(hex)
|
||||
return call($F941, hex >> 8, hex, 0, 0)
|
||||
end
|
||||
def putip(ipptr)
|
||||
byte i
|
||||
|
||||
for i = 0 to 2
|
||||
puti(ipptr->[i]); putc('.')
|
||||
next
|
||||
return puti(ipptr->[i])
|
||||
end
|
||||
def dumpbytes(buf, len)
|
||||
word i
|
||||
|
||||
for i = 0 to len - 1
|
||||
putb(buf->[i])
|
||||
if i & 15 == 15
|
||||
putln
|
||||
else
|
||||
putc(' ')
|
||||
fin
|
||||
next
|
||||
end
|
||||
def dumpdhcp(pkt)
|
||||
putb(pkt->dhcp_op);putln
|
||||
putb(pkt->dhcp_htype);putln
|
||||
putb(pkt->dhcp_hlen);putln
|
||||
putb(pkt->dhcp_hops);putln
|
||||
dumpbytes(@pkt->dhcp_xid, 4);putln
|
||||
putip(@pkt->dhcp_clientip);putln
|
||||
putip(@pkt->dhcp_yourip);putln
|
||||
putip(@pkt->dhcp_serverip);putln
|
||||
putip(@pkt->dhcp_gatewayip);putln
|
||||
dumpbytes(@pkt->dhcp_opts, 48);putln
|
||||
end
|
||||
//byte boundstr = "Apple II bound to:\n"
|
||||
//byte dnsstr = "DNS: "
|
||||
//def putb(hexb)
|
||||
// return call($FDDA, hexb, 0, 0, 0)
|
||||
//end
|
||||
//def puth(hex)
|
||||
// return call($F941, hex >> 8, hex, 0, 0)
|
||||
//end
|
||||
//def putip(ipptr)
|
||||
// byte i
|
||||
//
|
||||
// for i = 0 to 2
|
||||
// puti(ipptr->[i]); putc('.')
|
||||
// next
|
||||
// return puti(ipptr->[i])
|
||||
//end
|
||||
//def dumpbytes(buf, len)
|
||||
// word i
|
||||
//
|
||||
// for i = 0 to len - 1
|
||||
// putb(buf->[i])
|
||||
// if i & 15 == 15
|
||||
// putln
|
||||
// else
|
||||
// putc(' ')
|
||||
// fin
|
||||
// next
|
||||
//end
|
||||
//def dumpdhcp(pkt)
|
||||
// putb(pkt->dhcp_op);putln
|
||||
// putb(pkt->dhcp_htype);putln
|
||||
// putb(pkt->dhcp_hlen);putln
|
||||
// putb(pkt->dhcp_hops);putln
|
||||
// dumpbytes(@pkt->dhcp_xid, 4);putln
|
||||
// putip(@pkt->dhcp_clientip);putln
|
||||
// putip(@pkt->dhcp_yourip);putln
|
||||
// putip(@pkt->dhcp_serverip);putln
|
||||
// putip(@pkt->dhcp_gatewayip);putln
|
||||
// dumpbytes(@pkt->dhcp_opts, 48);putln
|
||||
//end
|
||||
def parseopts(opts, match)
|
||||
byte i
|
||||
|
||||
i = 0
|
||||
while opts->[i] <> $FF and i < 64
|
||||
while !opts->[i] and i < 64
|
||||
i = i + 1
|
||||
loop
|
||||
while !opts->[i] and i < 64
|
||||
i = i + 1
|
||||
loop
|
||||
if opts->[i] == match
|
||||
return i
|
||||
fin
|
||||
i = i + opts->[i + 1] + 2
|
||||
return i
|
||||
fin
|
||||
i = i + opts->[i + 1] + 2
|
||||
loop
|
||||
return -1
|
||||
end
|
||||
@ -171,41 +149,41 @@ def recvDHCP(remip, remport, pkt, len, param)
|
||||
//dumpdhcp(pkt)
|
||||
if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 == $0403
|
||||
when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2]
|
||||
is DHCP_OFFER
|
||||
//
|
||||
// Copy offer parameters to request
|
||||
//
|
||||
optsOP.2 = DHCP_REQUEST
|
||||
memcpy(@optsIP.2, @pkt->dhcp_yourip, IP4ADR_SIZE)
|
||||
servopts = parseopts(@pkt->dhcp_opts, 54) + 2
|
||||
if servopts >= 0
|
||||
optsSRV = 54
|
||||
memcpy(@optsSRV.2, @pkt->dhcp_opts.[servopts], IP4ADR_SIZE)
|
||||
fin
|
||||
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @endDHCP - @DHCP)
|
||||
break
|
||||
is DHCP_ACK
|
||||
optsOP.2 = DHCP_ACK
|
||||
//
|
||||
// Copy parameters to working copy
|
||||
//
|
||||
memcpy(@localip, @pkt->dhcp_yourip, IP4ADR_SIZE)
|
||||
maskopts = parseopts(@pkt->dhcp_opts, 1) + 2
|
||||
if maskopts >= 0
|
||||
memcpy(@localnet, @pkt->dhcp_opts.[maskopts], IP4ADR_SIZE)
|
||||
fin
|
||||
gwopts = parseopts(@pkt->dhcp_opts, 3) + 2
|
||||
if gwopts >= 0
|
||||
memcpy(@localgw, @pkt->dhcp_opts.[gwopts], IP4ADR_SIZE)
|
||||
fin
|
||||
dnsopts = parseopts(@pkt->dhcp_opts, 6) + 2
|
||||
if dnsopts >= 0
|
||||
memcpy(@localdns, @pkt->dhcp_opts.[dnsopts], IP4ADR_SIZE)
|
||||
fin
|
||||
break
|
||||
otherwise
|
||||
dumpdhcp(pkt)
|
||||
wend
|
||||
is DHCP_OFFER
|
||||
//
|
||||
// Copy offer parameters to request
|
||||
//
|
||||
optsOP.2 = DHCP_REQUEST
|
||||
memcpy(@optsIP.2, @pkt->dhcp_yourip, IP4ADR_SIZE)
|
||||
servopts = parseopts(@pkt->dhcp_opts, 54) + 2
|
||||
if servopts >= 0
|
||||
optsSRV = 54
|
||||
memcpy(@optsSRV.2, @pkt->dhcp_opts.[servopts], IP4ADR_SIZE)
|
||||
fin
|
||||
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @endDHCP - @DHCP)
|
||||
break
|
||||
is DHCP_ACK
|
||||
optsOP.2 = DHCP_ACK
|
||||
//
|
||||
// Copy parameters to working copy
|
||||
//
|
||||
memcpy(@localip, @pkt->dhcp_yourip, IP4ADR_SIZE)
|
||||
maskopts = parseopts(@pkt->dhcp_opts, 1) + 2
|
||||
if maskopts >= 0
|
||||
memcpy(@localnet, @pkt->dhcp_opts.[maskopts], IP4ADR_SIZE)
|
||||
fin
|
||||
gwopts = parseopts(@pkt->dhcp_opts, 3) + 2
|
||||
if gwopts >= 0
|
||||
memcpy(@localgw, @pkt->dhcp_opts.[gwopts], IP4ADR_SIZE)
|
||||
fin
|
||||
dnsopts = parseopts(@pkt->dhcp_opts, 6) + 2
|
||||
if dnsopts >= 0
|
||||
memcpy(@localdns, @pkt->dhcp_opts.[dnsopts], IP4ADR_SIZE)
|
||||
fin
|
||||
break
|
||||
otherwise
|
||||
//dumpdhcp(pkt)
|
||||
wend
|
||||
fin
|
||||
end
|
||||
//
|
||||
@ -229,23 +207,23 @@ repeat
|
||||
//
|
||||
// Broadcast DHCP DISCOVER message
|
||||
//
|
||||
optsOP.2 = DHCP_DISCOVER
|
||||
optsIP:2 = 0
|
||||
optsIP:4 = 0
|
||||
optsSRV = 255
|
||||
optsOP.2 = DHCP_DISCOVER
|
||||
optsIP:2 = 0
|
||||
optsIP:4 = 0
|
||||
optsSRV = 255
|
||||
DHCP.dhcp_secs.1 = retry
|
||||
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @optsSRV - @DHCP + 1)
|
||||
for timeout = 0 to 1000
|
||||
iNet:serviceIP()
|
||||
if optsOP.2 == DHCP_ACK
|
||||
break
|
||||
if optsOP.2 == DHCP_ACK
|
||||
break
|
||||
fin
|
||||
next
|
||||
retry = retry + 1
|
||||
until retry > 4 or optsOP.2 == DHCP_ACK
|
||||
iNet:closeUDP(portDHCP)
|
||||
iNet:setInterfaceIP(@localip, @localnet, @localgw)
|
||||
puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln
|
||||
//puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln
|
||||
iNet:setDNS(@localdns)
|
||||
puts(@dnsstr);putip(@localdns);putln
|
||||
//puts(@dnsstr);putip(@localdns);putln
|
||||
done
|
||||
|
@ -1,27 +1,5 @@
|
||||
include "inc/cmdsys.plh"
|
||||
//
|
||||
// Net object
|
||||
//
|
||||
import inet
|
||||
word iNet
|
||||
end
|
||||
struc t_inet
|
||||
word initIP
|
||||
word serviceIP
|
||||
word openUDP
|
||||
word sendUDP
|
||||
word closeUDP
|
||||
word listenTCP
|
||||
word connectTCP
|
||||
word sendTCP
|
||||
word closeTCP
|
||||
word setInterfaceIP
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
include "inc/inet.plh"
|
||||
//
|
||||
// Predefine service routine
|
||||
//
|
||||
@ -87,14 +65,14 @@ struc t_icmp
|
||||
word[2] icmp_header
|
||||
end
|
||||
//
|
||||
// UDP IPv4 psuedo header
|
||||
// UDP IPv4 pseudo header
|
||||
//
|
||||
struc t_piphdr
|
||||
byte[IP4ADR_SIZE] pip_src
|
||||
byte[IP4ADR_SIZE] pip_dst
|
||||
byte pip_zero
|
||||
byte pip_proto
|
||||
word pip_len
|
||||
byte pip_zero
|
||||
byte pip_proto
|
||||
word pip_len
|
||||
end
|
||||
//
|
||||
// UDP header
|
||||
@ -117,19 +95,19 @@ end
|
||||
//
|
||||
// ARP packet
|
||||
//
|
||||
const HW_ETHER = $0100 // BE format
|
||||
const ARP_PROTO = $0008 // BE format
|
||||
const ARP_REQST = $0100 // BE format
|
||||
const ARP_REPLY = $0200 // BE format
|
||||
const HW_ETHER = $0100 // BE format
|
||||
const ARP_PROTO = $0008 // BE format
|
||||
const ARP_REQST = $0100 // BE format
|
||||
const ARP_REPLY = $0200 // BE format
|
||||
struc t_arp
|
||||
word arp_hw
|
||||
word arp_proto
|
||||
byte arp_hlen
|
||||
byte arp_plen
|
||||
word arp_op
|
||||
byte[MAC_SIZE] arp_senderha
|
||||
byte[MAC_SIZE] arp_senderha
|
||||
byte[IP4ADR_SIZE] arp_senderip
|
||||
byte[MAC_SIZE] arp_targha
|
||||
byte[MAC_SIZE] arp_targha
|
||||
byte[IP4ADR_SIZE] arp_targip
|
||||
end
|
||||
const t_earp = t_ethrhdr+t_arp
|
||||
@ -152,14 +130,14 @@ word ePayload = PAYLOAD_ARP
|
||||
//
|
||||
// Pre-configured ARP packet - MUST follow ethernet header!
|
||||
//
|
||||
word ARP = HW_ETHER // HW TYPE
|
||||
word = ARP_PROTO // PROTO TYPE
|
||||
byte = MAC_SIZE // HLEN
|
||||
word ARP = HW_ETHER // HW TYPE
|
||||
word = ARP_PROTO // PROTO TYPE
|
||||
byte = MAC_SIZE // HLEN
|
||||
byte = IP4ADR_SIZE // PLEN
|
||||
word opARP // OP
|
||||
export byte[MAC_SIZE] localha
|
||||
word opARP // OP
|
||||
export byte[MAC_SIZE] localha
|
||||
export byte[IP4ADR_SIZE] localip
|
||||
byte[MAC_SIZE] remoteha
|
||||
byte[MAC_SIZE] remoteha
|
||||
byte[IP4ADR_SIZE] remoteip
|
||||
//
|
||||
// Local network parameters
|
||||
@ -167,8 +145,8 @@ byte[IP4ADR_SIZE] remoteip
|
||||
byte[IP4ADR_SIZE] netmask
|
||||
byte[IP4ADR_SIZE] subnet
|
||||
byte[IP4ADR_SIZE] gateway
|
||||
const MAX_UDP_NOTIFIES = 4
|
||||
const MAX_TCP_NOTIFIES = 4
|
||||
const MAX_UDP_NOTIFIES = 4
|
||||
const MAX_TCP_NOTIFIES = 4
|
||||
//
|
||||
// Notify callbacks
|
||||
//
|
||||
@ -191,64 +169,64 @@ word setFrameLen, writeFrame, getFrameLen, readFrame
|
||||
// Defines for ASM routines
|
||||
//
|
||||
asm equates
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
end
|
||||
//
|
||||
// Swap bytes in word
|
||||
//
|
||||
asm swab
|
||||
LDA ESTKL,X
|
||||
LDY ESTKH,X
|
||||
STA ESTKH,X
|
||||
STY ESTKL,X
|
||||
RTS
|
||||
LDA ESTKL,X
|
||||
LDY ESTKH,X
|
||||
STA ESTKH,X
|
||||
STY ESTKL,X
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// 1'S COMPLIMENT SUM BE format
|
||||
// sum1(PREVSUM, BUF, LEN)
|
||||
//
|
||||
asm sum1
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
STA SRCL
|
||||
LDA ESTKH+1,X
|
||||
STA SRCH
|
||||
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
|
||||
LDA ESTKL,X
|
||||
ROR
|
||||
ADC #$00
|
||||
STA ESTKL,X
|
||||
BEQ +
|
||||
!BYTE $A9
|
||||
- CLC
|
||||
INC ESTKH,X
|
||||
+ BCS -
|
||||
CHKLP LDA (SRC),Y
|
||||
PHA
|
||||
INY
|
||||
BNE +
|
||||
INC SRCH
|
||||
+ LDA (SRC),Y
|
||||
ADC ESTKH+2,X
|
||||
STA ESTKH+2,X
|
||||
PLA
|
||||
ADC ESTKL+2,X
|
||||
STA ESTKL+2,X
|
||||
INY
|
||||
BNE +
|
||||
INC SRCH
|
||||
+ DEC ESTKL,X
|
||||
BNE CHKLP
|
||||
DEC ESTKH,X
|
||||
BNE CHKLP
|
||||
BCC +
|
||||
- INC ESTKH+2,X
|
||||
BNE +
|
||||
INC ESTKL+2,X
|
||||
BEQ -
|
||||
+ INX
|
||||
INX
|
||||
RTS
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
STA SRCL
|
||||
LDA ESTKH+1,X
|
||||
STA SRCH
|
||||
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
|
||||
LDA ESTKL,X
|
||||
ROR
|
||||
ADC #$00
|
||||
STA ESTKL,X
|
||||
BEQ +
|
||||
!BYTE $A9
|
||||
- CLC
|
||||
INC ESTKH,X
|
||||
+ BCS -
|
||||
CHKLP LDA (SRC),Y
|
||||
PHA
|
||||
INY
|
||||
BNE +
|
||||
INC SRCH
|
||||
+ LDA (SRC),Y
|
||||
ADC ESTKH+2,X
|
||||
STA ESTKH+2,X
|
||||
PLA
|
||||
ADC ESTKL+2,X
|
||||
STA ESTKL+2,X
|
||||
INY
|
||||
BNE +
|
||||
INC SRCH
|
||||
+ DEC ESTKL,X
|
||||
BNE CHKLP
|
||||
DEC ESTKH,X
|
||||
BNE CHKLP
|
||||
BCC +
|
||||
- INC ESTKH+2,X
|
||||
BNE +
|
||||
INC ESTKL+2,X
|
||||
BEQ -
|
||||
+ INX
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// Send IP datagram
|
||||
@ -268,34 +246,34 @@ def etherSendIP(ipdst, proto, seglist, size)
|
||||
hdr:ip_chksm = 0
|
||||
memcpy(@hdr.ip_src, @localip, IP4ADR_SIZE)
|
||||
if !ipdst // IP_BROADCAST
|
||||
memset(@hdr.ip_dst, IP_BROADCAST, IP4ADR_SIZE)
|
||||
memset(@hdr.ip_dst, IP_BROADCAST, IP4ADR_SIZE)
|
||||
memset(@dstMAC, MAC_BROADCAST, MAC_SIZE)
|
||||
else
|
||||
if ipdst=>0 & netmask:0 <> subnet:0 or ipdst=>2 & netmask:2 <> subnet:2
|
||||
ipdst = @gateway // External net destination
|
||||
fin
|
||||
memcpy(@hdr.ip_dst, ipdst, IP4ADR_SIZE)
|
||||
fin
|
||||
memcpy(@hdr.ip_dst, ipdst, IP4ADR_SIZE)
|
||||
retry = 0
|
||||
while hdr:ip_dst:0 <> remoteip:0 and hdr:ip_dst:2 <> remoteip:2
|
||||
if retry >= 3
|
||||
if retry >= 3
|
||||
return -1 // ARP failed
|
||||
fin
|
||||
retry = retry + 1
|
||||
fin
|
||||
retry = retry + 1
|
||||
memset(@dstMAC, MAC_BROADCAST, MAC_SIZE)
|
||||
memset(@remoteha, 0, MAC_SIZE)
|
||||
memcpy(@remoteip, @hdr.ip_dst, IP4ADR_SIZE)
|
||||
ePayload = PAYLOAD_ARP
|
||||
opARP = ARP_REQST
|
||||
setFrameLen(t_earp)
|
||||
writeFrame(@eFrame, t_earp)
|
||||
for timeout = 1000 downto 0
|
||||
etherServiceIP
|
||||
if remoteha:0 | remoteha:2 | remoteha:4
|
||||
break
|
||||
fin
|
||||
next
|
||||
loop
|
||||
memcpy(@dstMAC, @remoteha, MAC_SIZE)
|
||||
memset(@remoteha, 0, MAC_SIZE)
|
||||
memcpy(@remoteip, @hdr.ip_dst, IP4ADR_SIZE)
|
||||
ePayload = PAYLOAD_ARP
|
||||
opARP = ARP_REQST
|
||||
setFrameLen(t_earp)
|
||||
writeFrame(@eFrame, t_earp)
|
||||
for timeout = 1000 downto 0
|
||||
etherServiceIP
|
||||
if remoteha:0 | remoteha:2 | remoteha:4
|
||||
break
|
||||
fin
|
||||
next
|
||||
loop
|
||||
memcpy(@dstMAC, @remoteha, MAC_SIZE)
|
||||
fin
|
||||
//
|
||||
// Calculate checksum
|
||||
@ -318,9 +296,9 @@ def etherSendIP(ipdst, proto, seglist, size)
|
||||
// Write the remaining segments
|
||||
//
|
||||
while size > 0
|
||||
writeFrame(seglist=>seg_buf, seglist=>seg_len)
|
||||
size = size - seglist=>seg_len
|
||||
seglist = seglist + t_segment
|
||||
writeFrame(seglist=>seg_buf, seglist=>seg_len)
|
||||
size = size - seglist=>seg_len
|
||||
seglist = seglist + t_segment
|
||||
loop
|
||||
end
|
||||
//
|
||||
@ -330,10 +308,10 @@ def etherSendUDP(port, ipdst, portdst, data, len)
|
||||
word[8] seglist // list of data and header segments
|
||||
byte[t_udphdr] hdr
|
||||
|
||||
hdr:udp_src = swab(port=>notify_port)
|
||||
hdr:udp_dst = swab(portdst)
|
||||
hdr:udp_len = swab(t_udphdr + len)
|
||||
hdr:udp_chksm = 0
|
||||
hdr:udp_src = swab(port=>notify_port)
|
||||
hdr:udp_dst = swab(portdst)
|
||||
hdr:udp_len = swab(t_udphdr + len)
|
||||
hdr:udp_chksm = 0
|
||||
seglist:0:seg_buf = @hdr
|
||||
seglist:0:seg_len = t_udphdr
|
||||
seglist:4:seg_buf = data
|
||||
@ -354,11 +332,11 @@ def etherOpenUDP(localport, callback, param)
|
||||
port = @portsUDP
|
||||
for i = 1 to MAX_UDP_NOTIFIES
|
||||
if port=>notify_port == localport
|
||||
port=>notify_func = callback
|
||||
port=>notify_parm = param
|
||||
return port
|
||||
fin
|
||||
port = port + t_notify
|
||||
port=>notify_func = callback
|
||||
port=>notify_parm = param
|
||||
return port
|
||||
fin
|
||||
port = port + t_notify
|
||||
next
|
||||
//
|
||||
// Add notification on localport if room
|
||||
@ -366,12 +344,12 @@ def etherOpenUDP(localport, callback, param)
|
||||
port = @portsUDP
|
||||
for i = 1 to MAX_UDP_NOTIFIES
|
||||
if !port=>notify_port
|
||||
port=>notify_port = localport
|
||||
port=>notify_func = callback
|
||||
port=>notify_parm = param
|
||||
return port
|
||||
fin
|
||||
port = port + t_notify
|
||||
port=>notify_port = localport
|
||||
port=>notify_func = callback
|
||||
port=>notify_parm = param
|
||||
return port
|
||||
fin
|
||||
port = port + t_notify
|
||||
next
|
||||
end
|
||||
//
|
||||
@ -382,13 +360,13 @@ def etherCloseUDP(port)
|
||||
byte i
|
||||
|
||||
if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify)
|
||||
//
|
||||
// Clear notiications on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
//
|
||||
// Clear notiications on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
port=>notify_port = 0
|
||||
return 0
|
||||
fin
|
||||
return 0
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
@ -420,13 +398,13 @@ end
|
||||
//
|
||||
def etherSetCallback(port, callback)
|
||||
if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify)
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
port=>notify_func = callback
|
||||
return 0
|
||||
fin
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
port=>notify_func = callback
|
||||
return 0
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
@ -438,13 +416,13 @@ end
|
||||
//
|
||||
def etherSetParam(port, param)
|
||||
if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify)
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
port=>notify_parm = param
|
||||
return 0
|
||||
fin
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
port=>notify_parm = param
|
||||
return 0
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
@ -467,109 +445,109 @@ def etherServiceIP
|
||||
rxsize = getFrameLen()
|
||||
if rxsize
|
||||
//
|
||||
// Read the entire packet into memory
|
||||
//
|
||||
rxpacket = heapalloc(rxsize)
|
||||
// Read the entire packet into memory
|
||||
//
|
||||
rxpacket = heapalloc(rxsize)
|
||||
readFrame(rxpacket, rxsize)
|
||||
rxptr = rxpacket + t_ethrhdr
|
||||
rxsize = rxsize - t_ethrhdr
|
||||
//
|
||||
// What kind of packet is it?
|
||||
//
|
||||
when rxpacket=>ethr_payload
|
||||
rxsize = rxsize - t_ethrhdr
|
||||
//
|
||||
// What kind of packet is it?
|
||||
//
|
||||
when rxpacket=>ethr_payload
|
||||
is PAYLOAD_IP
|
||||
iphdr = rxptr
|
||||
rxptr = rxptr + t_iphdr
|
||||
rxsize = rxsize - t_iphdr
|
||||
if iphdr->ip_vers_hlen <> $45
|
||||
optlen = iphdr=>ip_vers_hlen
|
||||
if optlen & $F0 <> $40
|
||||
//
|
||||
// Not IPv4, ignore
|
||||
//
|
||||
break
|
||||
fin
|
||||
optlen = (optlen & $0F) << 2
|
||||
if optlen > t_iphdr
|
||||
//
|
||||
// Read the options and throw them on the ground!
|
||||
//
|
||||
rxptr = rxptr + (optlen - t_iphdr)
|
||||
rxsize = rxsize - (optlen - t_iphdr)
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Filter valid destination address
|
||||
//
|
||||
if iphdr=>ip_dst:2 <> localip:2 // Yes, this is a little lazy
|
||||
if (iphdr=>ip_dst:0|netmask:0) & (iphdr=>ip_dst:2|netmask:2) <> IP_BROADCAST
|
||||
break
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// What kind of IP protocol is it?
|
||||
//
|
||||
when iphdr->ip_proto
|
||||
is IP_PROTO_UDP
|
||||
port = @portsUDP
|
||||
if port
|
||||
lclport = swab(rxptr=>udp_dst)
|
||||
for i = 1 to MAX_UDP_NOTIFIES
|
||||
if port=>notify_port == lclport
|
||||
port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm)
|
||||
break
|
||||
fin
|
||||
port = port + t_notify
|
||||
next
|
||||
fin
|
||||
break
|
||||
is IP_PROTO_TCP
|
||||
break
|
||||
is IP_PROTO_ICMP
|
||||
//
|
||||
// Service ICMP packets
|
||||
//
|
||||
if rxptr->icmp_type == ICMP_ECHO_REQST
|
||||
if rxsize > 128
|
||||
echolen = 128
|
||||
else
|
||||
echolen = rxsize
|
||||
fin
|
||||
memcpy(@echo_reply, rxptr, echolen)
|
||||
echo_reply.icmp_type = ICMP_ECHO_REPLY
|
||||
echo_reply:icmp_chksm = 0
|
||||
seglist:seg_buf = @echo_reply
|
||||
seglist:seg_len = echolen
|
||||
etherSendIP(@iphdr=>ip_src, IP_PROTO_ICMP, @seglist, echolen)
|
||||
fin
|
||||
if hookICMP
|
||||
hookICMP(@iphdr=>ip_src, rxptr, rxsize)
|
||||
fin
|
||||
wend
|
||||
break
|
||||
is PAYLOAD_ARP
|
||||
when rxptr=>arp_op
|
||||
is ARP_REPLY
|
||||
//
|
||||
// Fill in ARP cache
|
||||
//
|
||||
memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip
|
||||
break
|
||||
is ARP_REQST
|
||||
//
|
||||
// Is this a request for me?
|
||||
//
|
||||
if rxptr=>arp_targip:0 == localip:0 and rxptr=>arp_targip:2 == localip:2
|
||||
memcpy(@dstMAC, @rxptr=>arp_senderha, MAC_SIZE)
|
||||
memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip
|
||||
ePayload = PAYLOAD_ARP
|
||||
opARP = ARP_REPLY
|
||||
setFrameLen(t_earp)
|
||||
writeFrame(@eFrame, t_earp)
|
||||
fin
|
||||
wend
|
||||
iphdr = rxptr
|
||||
rxptr = rxptr + t_iphdr
|
||||
rxsize = rxsize - t_iphdr
|
||||
if iphdr->ip_vers_hlen <> $45
|
||||
optlen = iphdr=>ip_vers_hlen
|
||||
if optlen & $F0 <> $40
|
||||
//
|
||||
// Not IPv4, ignore
|
||||
//
|
||||
break
|
||||
fin
|
||||
optlen = (optlen & $0F) << 2
|
||||
if optlen > t_iphdr
|
||||
//
|
||||
// Read the options and throw them on the ground!
|
||||
//
|
||||
rxptr = rxptr + (optlen - t_iphdr)
|
||||
rxsize = rxsize - (optlen - t_iphdr)
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Filter valid destination address
|
||||
//
|
||||
if iphdr=>ip_dst:2 <> localip:2 // Yes, this is a little lazy
|
||||
if (iphdr=>ip_dst:0|netmask:0) & (iphdr=>ip_dst:2|netmask:2) <> IP_BROADCAST
|
||||
break
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// What kind of IP protocol is it?
|
||||
//
|
||||
when iphdr->ip_proto
|
||||
is IP_PROTO_UDP
|
||||
port = @portsUDP
|
||||
if port
|
||||
lclport = swab(rxptr=>udp_dst)
|
||||
for i = 1 to MAX_UDP_NOTIFIES
|
||||
if port=>notify_port == lclport
|
||||
port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm)
|
||||
break
|
||||
fin
|
||||
port = port + t_notify
|
||||
next
|
||||
fin
|
||||
break
|
||||
is IP_PROTO_TCP
|
||||
break
|
||||
is IP_PROTO_ICMP
|
||||
//
|
||||
// Service ICMP packets
|
||||
//
|
||||
if rxptr->icmp_type == ICMP_ECHO_REQST
|
||||
if rxsize > 128
|
||||
echolen = 128
|
||||
else
|
||||
echolen = rxsize
|
||||
fin
|
||||
memcpy(@echo_reply, rxptr, echolen)
|
||||
echo_reply.icmp_type = ICMP_ECHO_REPLY
|
||||
echo_reply:icmp_chksm = 0
|
||||
seglist:seg_buf = @echo_reply
|
||||
seglist:seg_len = echolen
|
||||
etherSendIP(@iphdr=>ip_src, IP_PROTO_ICMP, @seglist, echolen)
|
||||
fin
|
||||
if hookICMP
|
||||
hookICMP(@iphdr=>ip_src, rxptr, rxsize)
|
||||
fin
|
||||
wend
|
||||
break
|
||||
is PAYLOAD_ARP
|
||||
when rxptr=>arp_op
|
||||
is ARP_REPLY
|
||||
//
|
||||
// Fill in ARP cache
|
||||
//
|
||||
memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip
|
||||
break
|
||||
is ARP_REQST
|
||||
//
|
||||
// Is this a request for me?
|
||||
//
|
||||
if rxptr=>arp_targip:0 == localip:0 and rxptr=>arp_targip:2 == localip:2
|
||||
memcpy(@dstMAC, @rxptr=>arp_senderha, MAC_SIZE)
|
||||
memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip
|
||||
ePayload = PAYLOAD_ARP
|
||||
opARP = ARP_REPLY
|
||||
setFrameLen(t_earp)
|
||||
writeFrame(@eFrame, t_earp)
|
||||
fin
|
||||
wend
|
||||
wend
|
||||
heaprelease(rxpacket)
|
||||
heaprelease(rxpacket)
|
||||
fin
|
||||
end
|
||||
//
|
||||
|
@ -26,6 +26,7 @@ struc t_fileio
|
||||
word getpfx
|
||||
word setpfx
|
||||
word getfileinfo
|
||||
word geteof
|
||||
word open
|
||||
word close
|
||||
word read
|
||||
@ -36,13 +37,13 @@ struc t_fileio
|
||||
word readblock
|
||||
word writeblock
|
||||
end
|
||||
predef a2getpfx, a23setpfx, a2getfileinfo, a2open, a23close
|
||||
predef a2getpfx, a23setpfx, a2getfileinfo, a23geteof, a2open, a23close
|
||||
predef a23read, a2write, a2create, a23destroy
|
||||
predef a23newline, a2readblock, a2writeblock
|
||||
//
|
||||
// Exported function table.
|
||||
//
|
||||
export word fileio[] = @a2getpfx, @a23setpfx, @a2getfileinfo, @a2open, @a23close
|
||||
export word fileio[] = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2open, @a23close
|
||||
word = @a23read, @a2write, @a2create, @a23destroy
|
||||
word = @a23newline, @a2readblock, @a2writeblock
|
||||
//
|
||||
@ -108,6 +109,19 @@ def a3getfileinfo(path, fileinfo)
|
||||
perr = syscall($C4, @params)
|
||||
return perr
|
||||
end
|
||||
def a1geteof(refnum)
|
||||
return 0
|
||||
end
|
||||
def a23geteof(refnum)
|
||||
byte params[6]
|
||||
|
||||
params.0 = 2
|
||||
params.1 = refnum
|
||||
params:2 = 0
|
||||
params:4 = 0
|
||||
syscall($D1, @params)
|
||||
return params:2
|
||||
end
|
||||
def a1open(path)
|
||||
*CFFA1FileName = path
|
||||
return 0
|
||||
@ -273,6 +287,7 @@ when MACHID & $C8
|
||||
fileio:getpfx = @a1getpfx
|
||||
fileio:setpfx = @a1setpfx
|
||||
fileio:getfileinfo = @a1getfileinfo
|
||||
fileio:geteof = @a1geteof
|
||||
fileio:open = @a1open
|
||||
fileio:close = @a1close
|
||||
fileio:read = @a1read
|
||||
|
@ -1,6 +1,6 @@
|
||||
include "inc/cmdsys.plh"
|
||||
//
|
||||
// Net object
|
||||
// iNet API - must match inet.plh
|
||||
//
|
||||
struc t_inet
|
||||
word initIP
|
||||
@ -53,32 +53,32 @@ def iNetSetDNS(ipptr)
|
||||
return memcpy(@dns, ipptr, 4)
|
||||
end
|
||||
|
||||
def putb(hexb)
|
||||
return call($FDDA, hexb, 0, 0, 0)
|
||||
end
|
||||
def puth(hex)
|
||||
return call($F941, hex >> 8, hex, 0, 0)
|
||||
end
|
||||
def putip(ipptr)
|
||||
byte i
|
||||
|
||||
for i = 0 to 2
|
||||
puti(ipptr->[i]); putc('.')
|
||||
next
|
||||
return puti(ipptr->[i])
|
||||
end
|
||||
def dumpbytes(buf, len)
|
||||
word i
|
||||
|
||||
for i = 0 to len - 1
|
||||
putb(buf->[i])
|
||||
if i & 7 == 7
|
||||
putln
|
||||
else
|
||||
putc(' ')
|
||||
fin
|
||||
next
|
||||
end
|
||||
//def putb(hexb)
|
||||
// return call($FDDA, hexb, 0, 0, 0)
|
||||
//end
|
||||
//def puth(hex)
|
||||
// return call($F941, hex >> 8, hex, 0, 0)
|
||||
//end
|
||||
//def dumpbytes(buf, len)
|
||||
// word i
|
||||
//
|
||||
// for i = 0 to len - 1
|
||||
// putb(buf->[i])
|
||||
// if i & 7 == 7
|
||||
// putln
|
||||
// else
|
||||
// putc(' ')
|
||||
// fin
|
||||
// next
|
||||
//end
|
||||
//def putip(ipptr)
|
||||
// byte i
|
||||
//
|
||||
// for i = 0 to 2
|
||||
// puti(ipptr->[i]); putc('.')
|
||||
// next
|
||||
// return puti(ipptr->[i])
|
||||
//end
|
||||
|
||||
def parseIP(ipstr, ipaddr)
|
||||
byte i
|
||||
@ -123,38 +123,38 @@ def recvDNS(remip, remport, pkt, len, ipaddr)
|
||||
if pkt=>dnsID == $BEEF
|
||||
q = pkt->dnsQdCount.1
|
||||
r = pkt->dnsAnCount.1 + pkt->dnsNsCount.1 + pkt->dnsArCount.1
|
||||
resptr = pkt + t_dnshdr
|
||||
while q
|
||||
while ^resptr
|
||||
//puts(resptr); putc('.')
|
||||
resptr = resptr + ^resptr + 1
|
||||
loop
|
||||
resptr = resptr + 1
|
||||
//putln; dumpbytes(resptr, 4); putln
|
||||
resptr = resptr + 4
|
||||
q = q - 1
|
||||
loop
|
||||
while r
|
||||
//dumpbytes(resptr, 40); putln
|
||||
if ^resptr & $C0 == $C0
|
||||
resptr = resptr + 2
|
||||
else
|
||||
while ^resptr
|
||||
//puts(resptr); putc('.')
|
||||
resptr = resptr + ^resptr + 1
|
||||
loop
|
||||
resptr = resptr + 1
|
||||
fin
|
||||
if resptr->1 == 1 and resptr->3 == 1 and resptr->9 == 4
|
||||
ipaddr=>0 = resptr=>10
|
||||
ipaddr=>2 = resptr=>12
|
||||
fin
|
||||
//putln; dumpbytes(resptr, 10); putc(':'); putln
|
||||
resptr = resptr + 8
|
||||
//dumpbytes(resptr + 2, ^(resptr + 1))
|
||||
resptr = resptr + 2 + ^(resptr + 1); putln
|
||||
r = r - 1
|
||||
loop
|
||||
resptr = pkt + t_dnshdr
|
||||
while q
|
||||
while ^resptr
|
||||
//puts(resptr); putc('.')
|
||||
resptr = resptr + ^resptr + 1
|
||||
loop
|
||||
resptr = resptr + 1
|
||||
//putln; dumpbytes(resptr, 4); putln
|
||||
resptr = resptr + 4
|
||||
q--
|
||||
loop
|
||||
while r
|
||||
//dumpbytes(resptr, 40); putln
|
||||
if ^resptr & $C0 == $C0
|
||||
resptr = resptr + 2
|
||||
else
|
||||
while ^resptr
|
||||
//puts(resptr); putc('.')
|
||||
resptr = resptr + ^resptr + 1
|
||||
loop
|
||||
resptr = resptr + 1
|
||||
fin
|
||||
if resptr->1 == 1 and resptr->3 == 1 and resptr->9 == 4
|
||||
ipaddr=>0 = resptr=>10
|
||||
ipaddr=>2 = resptr=>12
|
||||
fin
|
||||
//putln; dumpbytes(resptr, 10); putc(':'); putln
|
||||
resptr = resptr + 8
|
||||
//dumpbytes(resptr + 2, ^(resptr + 1))
|
||||
resptr = resptr + 2 + ^(resptr + 1); putln
|
||||
r = r - 1
|
||||
loop
|
||||
fin
|
||||
stateDNS = DNS_ANSWER
|
||||
end
|
||||
@ -167,38 +167,38 @@ def iNetResolve(namestr, ipaddr)
|
||||
ipaddr=>2 = 0
|
||||
if not parseIP(namestr, ipaddr)
|
||||
//
|
||||
// Query Domain Name Server for address
|
||||
//
|
||||
dnspkt = heapmark // Use heap as working DNS query packet
|
||||
msgptr = dnspkt
|
||||
msgptr=>dnsID = $BEEF
|
||||
msgptr=>dnsCode = $0001 // RD (Recursion Desired)
|
||||
msgptr=>dnsQdCount = $0100 // BE count = 1
|
||||
msgptr=>dnsAnCount = 0
|
||||
msgptr=>dnsNsCount = 0
|
||||
msgptr=>dnsArCount = 0
|
||||
msgptr = parseDomain(namestr, msgptr + t_dnshdr)
|
||||
msgptr=>0 = $0100 // BE TYPE = Address
|
||||
msgptr=>2 = $0100 // BE CLASS = INternet
|
||||
msglen = msgptr - dnspkt + 4
|
||||
heapalloc(msglen)
|
||||
//
|
||||
// Prepare to receive DNS answer from server
|
||||
//
|
||||
portDNS = iNet:openUDP(3999, @recvDNS, ipaddr)
|
||||
//
|
||||
// Service IP
|
||||
//
|
||||
stateDNS = DNS_QUERY
|
||||
iNet:sendUDP(portDNS, @dns, 53, dnspkt, msglen)
|
||||
for timeout = 1 to 1000
|
||||
iNet:serviceIP()
|
||||
if stateDNS == DNS_ANSWER
|
||||
break
|
||||
fin
|
||||
next
|
||||
iNet:closeUDP(portDNS)
|
||||
heaprelease(dnspkt)
|
||||
// Query Domain Name Server for address
|
||||
//
|
||||
dnspkt = heapmark // Use heap as working DNS query packet
|
||||
msgptr = dnspkt
|
||||
msgptr=>dnsID = $BEEF
|
||||
msgptr=>dnsCode = $0001 // RD (Recursion Desired)
|
||||
msgptr=>dnsQdCount = $0100 // BE count = 1
|
||||
msgptr=>dnsAnCount = 0
|
||||
msgptr=>dnsNsCount = 0
|
||||
msgptr=>dnsArCount = 0
|
||||
msgptr = parseDomain(namestr, msgptr + t_dnshdr)
|
||||
msgptr=>0 = $0100 // BE TYPE = Address
|
||||
msgptr=>2 = $0100 // BE CLASS = INternet
|
||||
msglen = msgptr - dnspkt + 4
|
||||
heapalloc(msglen)
|
||||
//
|
||||
// Prepare to receive DNS answer from server
|
||||
//
|
||||
portDNS = iNet:openUDP(3999, @recvDNS, ipaddr)
|
||||
//
|
||||
// Service IP
|
||||
//
|
||||
stateDNS = DNS_QUERY
|
||||
iNet:sendUDP(portDNS, @dns, 53, dnspkt, msglen)
|
||||
for timeout = 1 to 1000
|
||||
iNet:serviceIP()
|
||||
if stateDNS == DNS_ANSWER
|
||||
break
|
||||
fin
|
||||
next
|
||||
iNet:closeUDP(portDNS)
|
||||
heaprelease(dnspkt)
|
||||
fin
|
||||
return ipaddr=>0 <> 0 or ipaddr=>2 <> 0
|
||||
end
|
||||
@ -209,10 +209,10 @@ export def iNetInit
|
||||
//
|
||||
while ^driver
|
||||
//puts(driver);putln
|
||||
if modexec(driver) >= 0
|
||||
break
|
||||
fin
|
||||
driver = driver + ^driver + 1
|
||||
if modexec(driver) >= 0
|
||||
break
|
||||
fin
|
||||
driver = driver + ^driver + 1
|
||||
loop
|
||||
if !^driver
|
||||
return 0
|
||||
@ -228,7 +228,6 @@ end
|
||||
//
|
||||
// Fill iNet class
|
||||
//
|
||||
iNet:initIP = @iNetInit
|
||||
iNet:setDNS = @iNetSetDNS
|
||||
|
||||
iNet:initIP = @iNetInit
|
||||
iNet:setDNS = @iNetSetDNS
|
||||
done
|
||||
|
@ -9,11 +9,6 @@ import etherip
|
||||
predef setEtherDriver
|
||||
end
|
||||
//
|
||||
// Module don't free memory
|
||||
//
|
||||
const modkeep = $2000
|
||||
const modinitkeep = $4000
|
||||
//
|
||||
// Uthernet register offsets
|
||||
//
|
||||
const TXDATA = $00
|
||||
@ -42,129 +37,129 @@ byte[6] utherMAC = $00,$0A,$99,$1E,$02,$A0
|
||||
// Defines for ASM routines
|
||||
//
|
||||
asm equates
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
end
|
||||
//
|
||||
// Uthernet I/O functions
|
||||
//
|
||||
asm _pokeiow
|
||||
LDA ESTKL,X
|
||||
LDA ESTKL,X
|
||||
end
|
||||
asm _pokeiowl
|
||||
STA $C000
|
||||
LDA ESTKH,X
|
||||
STA $C000
|
||||
LDA ESTKH,X
|
||||
end
|
||||
asm _pokeiowh
|
||||
STA $C000
|
||||
RTS
|
||||
STA $C000
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// PEEK BYTE FROM I/O SPACE
|
||||
// _peekio()
|
||||
//
|
||||
asm _peekio
|
||||
DEX
|
||||
DEX
|
||||
end
|
||||
asm _peekiol
|
||||
LDA $C000
|
||||
STA ESTKL,X
|
||||
LDA #$00
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
LDA $C000
|
||||
STA ESTKL,X
|
||||
LDA #$00
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// PEEK WORD FROM I/O SPACE
|
||||
// _peekiow()
|
||||
//
|
||||
asm _peekiow
|
||||
DEX
|
||||
DEX
|
||||
end
|
||||
asm _peekiowl
|
||||
LDA $C000
|
||||
STA ESTKL,X
|
||||
LDA $C000
|
||||
STA ESTKL,X
|
||||
end
|
||||
asm _peekiowh
|
||||
LDA $C000
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
LDA $C000
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// WRITE FRAME DATA INTO I/O SPACE
|
||||
// pokefrm(BUF, LEN)
|
||||
//
|
||||
asm pokefrm
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
STA SRCL
|
||||
LDA ESTKH+1,X
|
||||
STA SRCH
|
||||
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
|
||||
LDA ESTKL,X
|
||||
ROR
|
||||
ADC #$00
|
||||
STA ESTKL,X
|
||||
BEQ +
|
||||
!BYTE $A9
|
||||
- CLC
|
||||
INC ESTKH,X
|
||||
+ BCS -
|
||||
POKELP LDA (SRC),Y
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
STA SRCL
|
||||
LDA ESTKH+1,X
|
||||
STA SRCH
|
||||
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
|
||||
LDA ESTKL,X
|
||||
ROR
|
||||
ADC #$00
|
||||
STA ESTKL,X
|
||||
BEQ +
|
||||
!BYTE $A9
|
||||
- CLC
|
||||
INC ESTKH,X
|
||||
+ BCS -
|
||||
POKELP LDA (SRC),Y
|
||||
end
|
||||
asm _pokefrml
|
||||
STA $C000
|
||||
INY
|
||||
LDA (SRC),Y
|
||||
STA $C000
|
||||
INY
|
||||
LDA (SRC),Y
|
||||
end
|
||||
asm _pokefrmh
|
||||
STA $C000
|
||||
INY
|
||||
BNE +
|
||||
INC SRCH
|
||||
+ DEC ESTKL,X
|
||||
BNE POKELP
|
||||
DEC ESTKH,X
|
||||
BNE POKELP
|
||||
INX
|
||||
RTS
|
||||
STA $C000
|
||||
INY
|
||||
BNE +
|
||||
INC SRCH
|
||||
+ DEC ESTKL,X
|
||||
BNE POKELP
|
||||
DEC ESTKH,X
|
||||
BNE POKELP
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
//
|
||||
// READ FRAME DATA FROM I/O SPACE
|
||||
// peekfrm(BUF, LEN)
|
||||
//
|
||||
asm peekfrm
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
STA DSTL
|
||||
LDA ESTKH+1,X
|
||||
STA DSTH
|
||||
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
|
||||
LDA ESTKL,X
|
||||
ROR
|
||||
ADC #$00
|
||||
STA ESTKL,X
|
||||
BEQ +
|
||||
!BYTE $A9
|
||||
- CLC
|
||||
INC ESTKH,X
|
||||
+ BCS -
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
STA DSTL
|
||||
LDA ESTKH+1,X
|
||||
STA DSTH
|
||||
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
|
||||
LDA ESTKL,X
|
||||
ROR
|
||||
ADC #$00
|
||||
STA ESTKL,X
|
||||
BEQ +
|
||||
!BYTE $A9
|
||||
- CLC
|
||||
INC ESTKH,X
|
||||
+ BCS -
|
||||
end
|
||||
asm _peekfrml
|
||||
PEEKLP LDA $C000
|
||||
STA (DST),Y
|
||||
INY
|
||||
PEEKLP LDA $C000
|
||||
STA (DST),Y
|
||||
INY
|
||||
end
|
||||
asm _peekfrmh
|
||||
+ LDA $C000
|
||||
STA (DST),Y
|
||||
INY
|
||||
BNE +
|
||||
INC DSTH
|
||||
+ DEC ESTKL,X
|
||||
BNE PEEKLP
|
||||
DEC ESTKH,X
|
||||
BNE PEEKLP
|
||||
EXPSW INX
|
||||
RTS
|
||||
+ LDA $C000
|
||||
STA (DST),Y
|
||||
INY
|
||||
BNE +
|
||||
INC DSTH
|
||||
+ DEC ESTKL,X
|
||||
BNE PEEKLP
|
||||
DEC ESTKH,X
|
||||
BNE PEEKLP
|
||||
EXPSW INX
|
||||
RTS
|
||||
end
|
||||
def pokeiow(io, data)
|
||||
_pokeiowl.1 = io
|
||||
@ -205,12 +200,12 @@ def peekfrmlen
|
||||
if peekiow(isq) & $3F == $04
|
||||
if peekio(rxdata_hi) & $01
|
||||
peekio(rxdata_lo)
|
||||
len.1 = peekio(rxdata_hi)
|
||||
len.0 = peekio(rxdata_lo)
|
||||
else
|
||||
peekio(rxdata_lo)
|
||||
pokepreg($0102, $0140) // Skip pkt
|
||||
fin
|
||||
len.1 = peekio(rxdata_hi)
|
||||
len.0 = peekio(rxdata_lo)
|
||||
else
|
||||
peekio(rxdata_lo)
|
||||
pokepreg($0102, $0140) // Skip pkt
|
||||
fin
|
||||
fin
|
||||
return len
|
||||
end
|
||||
@ -220,10 +215,10 @@ end
|
||||
for slot = $90 to $F0 step $10
|
||||
if (peekiow(slot+TXCMD) & $CC3F) == $09
|
||||
pokeiow(slot+PREG_INDEX, 0)
|
||||
if peekiow(slot+PREG_DATA) == $630E
|
||||
if peekiow(slot+PREG_DATA) == $630E
|
||||
pokepreg($0114, $40) // RESET
|
||||
rxdata_hi = slot + 1
|
||||
txcmd = slot + TXCMD
|
||||
rxdata_hi = slot + 1
|
||||
txcmd = slot + TXCMD
|
||||
txlen = slot + TXLEN
|
||||
isq = slot + INT_STATUS
|
||||
pregidx = slot + PREG_INDEX
|
||||
@ -239,13 +234,13 @@ for slot = $90 to $F0 step $10
|
||||
pokepreg($0104, $0D00) // Recv ctrl
|
||||
pokepreg($0106, $8200) // Xmit cfg
|
||||
pokepreg($0112, $00C0) // Line ctrl
|
||||
//
|
||||
// Install etherip driver
|
||||
//
|
||||
puts("Found Uthernet I in slot #")
|
||||
putc('0' + ((slot - $80) >> 4))
|
||||
putln
|
||||
setEtherDriver(@utherMAC, @peekfrmlen, @peekfrm, @pokefrmlen, @pokefrm)
|
||||
//
|
||||
// Install etherip driver
|
||||
//
|
||||
puts("Found Uthernet I in slot #")
|
||||
putc('0' + ((slot - $80) >> 4))
|
||||
putln
|
||||
setEtherDriver(@utherMAC, @peekfrmlen, @peekfrm, @pokefrmlen, @pokefrm)
|
||||
return modkeep
|
||||
fin
|
||||
fin
|
||||
|
@ -5,34 +5,7 @@
|
||||
// layers, like the Uthernet
|
||||
//
|
||||
include "inc/cmdsys.plh"
|
||||
//
|
||||
// Net object
|
||||
//
|
||||
import inet
|
||||
word iNet
|
||||
end
|
||||
struc t_inet
|
||||
word initIP
|
||||
word serviceIP
|
||||
word openUDP
|
||||
word sendUDP
|
||||
word closeUDP
|
||||
word listenTCP
|
||||
word connectTCP
|
||||
word sendTCP
|
||||
word closeTCP
|
||||
word setInterfaceIP
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
//
|
||||
// Module don't free memory
|
||||
//
|
||||
const modkeep = $2000
|
||||
const modinitkeep = $4000
|
||||
include "inc/inet.plh"
|
||||
//
|
||||
// Wiznet registers
|
||||
//
|
||||
|
@ -9,33 +9,11 @@
|
||||
// still todo: output base filename for Content-Disposition header
|
||||
//
|
||||
include "inc/cmdsys.plh"
|
||||
//
|
||||
// Net object
|
||||
//
|
||||
import inet
|
||||
word iNet
|
||||
end
|
||||
struc t_inet
|
||||
word initIP
|
||||
word serviceIP
|
||||
word openUDP
|
||||
word sendUDP
|
||||
word closeUDP
|
||||
word listenTCP
|
||||
word connectTCP
|
||||
word sendTCP
|
||||
word closeTCP
|
||||
word setInterfaceIP
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
include "inc/inet.plh"
|
||||
include "inc/fileio.plh"
|
||||
|
||||
word socketHTTP
|
||||
byte[65] prefix
|
||||
byte perr
|
||||
word filebuff, iobuff
|
||||
byte fileInfo[12] = 0 // used for get_file_info()
|
||||
byte hello = "Apple II Web Server - 12 Nov 15\n"
|
||||
@ -60,73 +38,6 @@ byte httpEnd = "\n\r\n\r"
|
||||
byte mimeTextHtml = "text/html"
|
||||
byte mimeOctetStream = "application/octet-stream"
|
||||
//
|
||||
// ProDOS routines
|
||||
//
|
||||
def getpfx(path)
|
||||
byte params[3]
|
||||
|
||||
^path = 0
|
||||
params.0 = 1
|
||||
params:1 = path
|
||||
perr = syscall($C7, @params)
|
||||
return path
|
||||
end
|
||||
def setpfx(path)
|
||||
byte params[3]
|
||||
|
||||
params.0 = 1
|
||||
params:1 = path
|
||||
perr = syscall($C6, @params)
|
||||
return path
|
||||
end
|
||||
def open(path, buff)
|
||||
byte params[6]
|
||||
|
||||
params.0 = 3
|
||||
params:1 = path
|
||||
params:3 = buff
|
||||
params.5 = 0
|
||||
perr = syscall($C8, @params)
|
||||
return params.5
|
||||
end
|
||||
def close(refnum)
|
||||
byte params[2]
|
||||
|
||||
params.0 = 1
|
||||
params.1 = refnum
|
||||
perr = syscall($CC, @params)
|
||||
return perr
|
||||
end
|
||||
def read(refnum, buff, len)
|
||||
byte params[8]
|
||||
|
||||
params.0 = 4
|
||||
params.1 = refnum
|
||||
params:2 = buff
|
||||
params:4 = len
|
||||
params:6 = 0
|
||||
perr = syscall($CA, @params)
|
||||
return params:6
|
||||
end
|
||||
def get_eof(refnum)
|
||||
byte params[5]
|
||||
|
||||
params.0 = 2
|
||||
params.1 = refnum
|
||||
params:2 = 0
|
||||
params.4 = 0
|
||||
syscall($D1, @params)
|
||||
return params:2
|
||||
end
|
||||
def get_file_info(path)
|
||||
|
||||
fileInfo.0 = 10 // param count
|
||||
fileInfo:1 = path // path name
|
||||
|
||||
perr = syscall($C4, @fileInfo)
|
||||
return perr
|
||||
end
|
||||
//
|
||||
// DEBUG
|
||||
//
|
||||
def putb(hexb)
|
||||
@ -148,11 +59,11 @@ def dumpbytes(buf, len)
|
||||
|
||||
for i = 0 to len - 1
|
||||
putb(buf->[i])
|
||||
if i & 15 == 15
|
||||
putln
|
||||
else
|
||||
putc(' ')
|
||||
fin
|
||||
if i & 15 == 15
|
||||
putln
|
||||
else
|
||||
putc(' ')
|
||||
fin
|
||||
next
|
||||
end
|
||||
def dumpchars(buf, len)
|
||||
@ -187,13 +98,13 @@ end
|
||||
//
|
||||
def sendFile(fd, socket, len)
|
||||
while isuge(len, 1024)
|
||||
read(fd, filebuff, 1024)
|
||||
len = len - 1024
|
||||
iNet:sendTCP(socket, filebuff, 1024)
|
||||
fileio:read(fd, filebuff, 1024)
|
||||
len = len - 1024
|
||||
iNet:sendTCP(socket, filebuff, 1024)
|
||||
loop
|
||||
if len
|
||||
read(fd, filebuff, len)
|
||||
iNet:sendTCP(socket, filebuff, len)
|
||||
fileio:read(fd, filebuff, len)
|
||||
iNet:sendTCP(socket, filebuff, len)
|
||||
fin
|
||||
end
|
||||
//
|
||||
@ -211,78 +122,78 @@ def servHTTP(remip, remport, lclport, data, len, param)
|
||||
if len > 0
|
||||
//dumpchars(data, len)
|
||||
//
|
||||
// Better be 'GET'
|
||||
//
|
||||
// Better be 'GET'
|
||||
//
|
||||
if data->0 == 'G' and data->1 == 'E' and data->2 == 'T' and data->3 == ' '
|
||||
len = len - 1
|
||||
if len > 64
|
||||
len = 64 // maximum ProDOS path
|
||||
fin
|
||||
len = len - 1
|
||||
if len > 64
|
||||
len = 64 // maximum ProDOS path
|
||||
fin
|
||||
for i = 4 to len // get ProDOS path from URL
|
||||
if data->[i] <= ' '
|
||||
data->3= i - 4
|
||||
url = data + 3
|
||||
if url->1 == '/'
|
||||
if url->0 == 1
|
||||
url = @defhtml // Is this a directory with no file given? Use index.html
|
||||
else
|
||||
url->1 = url->0 - 1
|
||||
url = url + 1
|
||||
fin
|
||||
fin
|
||||
strcat(@filename, @prefix, url)
|
||||
puts("GET:"); puts(@filename);putln
|
||||
//
|
||||
// Get file info
|
||||
//
|
||||
//puts("getting file info "); // debug
|
||||
get_file_info(@filename)
|
||||
refnum = open(@filename, iobuff) // try to open this file with ProDOS
|
||||
if refnum // file was opened OK
|
||||
filelen = get_eof(refnum) // get length of file for Content-Length
|
||||
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
|
||||
strcat(@okhdr, @httpOK, @httpContentLen)
|
||||
strcat(@okhdr, @okhdr, @lenstr)
|
||||
strcat(@okhdr, @okhdr, "\n\r")
|
||||
//
|
||||
// Content type header
|
||||
//
|
||||
if fileInfo.4 == $03 OR fileInfo.4 == $04
|
||||
//
|
||||
// this a text file
|
||||
//
|
||||
//puts(@mimeTextHtml) // debug
|
||||
strcat(@okhdr, @okhdr, @httpContentType)
|
||||
strcat(@okhdr, @okhdr, @mimeTextHtml)
|
||||
else
|
||||
//
|
||||
// send as binary attachment
|
||||
//
|
||||
//puts(@mimeOctetStream) // debug
|
||||
strcat(@okhdr, @okhdr, @httpContentType)
|
||||
strcat(@okhdr, @okhdr, @mimeOctetStream)
|
||||
strcat(@okhdr, @okhdr, "\n\r")
|
||||
//
|
||||
// and send filename too
|
||||
//
|
||||
strcat(@okhdr, @okhdr, @httpContentAttach)
|
||||
// todo: get the base filename...
|
||||
fin
|
||||
strcat(@okhdr, @okhdr, @httpEnd)
|
||||
//dumpchars(@okhdr + 1, okhdr) // debug
|
||||
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client
|
||||
sendFile(refnum, socketHTTP, filelen) // send file data to client
|
||||
close(refnum)
|
||||
else // file couldn't be opened, so return 404 on this
|
||||
puts("404 Not Found");putln // debug
|
||||
iNet:sendTCP(socketHTTP, @httpNOTFOUND + 1, httpNOTFOUND)
|
||||
fin // if refnum
|
||||
break // return
|
||||
fin
|
||||
data->3 = i - 4
|
||||
url = data + 3
|
||||
if url->1 == '/'
|
||||
if url->0 == 1
|
||||
url = @defhtml // Is this a directory with no file given? Use index.html
|
||||
else
|
||||
url->1 = url->0 - 1
|
||||
url = url + 1
|
||||
fin
|
||||
fin
|
||||
strcat(@filename, @prefix, url)
|
||||
puts("GET:"); puts(@filename);putln
|
||||
//
|
||||
// Get file info
|
||||
//
|
||||
//puts("getting file info "); // debug
|
||||
fileio:getfileinfo(@filename)
|
||||
refnum = fileio:open(@filename) // try to open this file with ProDOS
|
||||
if refnum // file was opened OK
|
||||
filelen = fileio:geteof(refnum) // get length of file for Content-Length
|
||||
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
|
||||
strcat(@okhdr, @httpOK, @httpContentLen)
|
||||
strcat(@okhdr, @okhdr, @lenstr)
|
||||
strcat(@okhdr, @okhdr, "\n\r")
|
||||
//
|
||||
// Content type header
|
||||
//
|
||||
if fileInfo.4 == $03 OR fileInfo.4 == $04
|
||||
//
|
||||
// this a text file
|
||||
//
|
||||
//puts(@mimeTextHtml) // debug
|
||||
strcat(@okhdr, @okhdr, @httpContentType)
|
||||
strcat(@okhdr, @okhdr, @mimeTextHtml)
|
||||
else
|
||||
//
|
||||
// send as binary attachment
|
||||
//
|
||||
//puts(@mimeOctetStream) // debug
|
||||
strcat(@okhdr, @okhdr, @httpContentType)
|
||||
strcat(@okhdr, @okhdr, @mimeOctetStream)
|
||||
strcat(@okhdr, @okhdr, "\n\r")
|
||||
//
|
||||
// and send filename too
|
||||
//
|
||||
strcat(@okhdr, @okhdr, @httpContentAttach)
|
||||
// todo: get the base filename...
|
||||
fin
|
||||
strcat(@okhdr, @okhdr, @httpEnd)
|
||||
//dumpchars(@okhdr + 1, okhdr) // debug
|
||||
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client
|
||||
sendFile(refnum, socketHTTP, filelen) // send file data to client
|
||||
fileio:close(refnum)
|
||||
else // file couldn't be opened, so return 404 on this
|
||||
puts("404 Not Found");putln // debug
|
||||
iNet:sendTCP(socketHTTP, @httpNOTFOUND + 1, httpNOTFOUND)
|
||||
fin // if refnum
|
||||
break // return
|
||||
fin
|
||||
next
|
||||
else
|
||||
iNet:sendTCP(socketHTTP, @httpBAD + 1, httpBAD)
|
||||
fin
|
||||
else
|
||||
iNet:sendTCP(socketHTTP, @httpBAD + 1, httpBAD)
|
||||
fin
|
||||
fin
|
||||
socketHTTP = iNet:closeTCP(socketHTTP)
|
||||
end
|
||||
@ -296,7 +207,7 @@ getpfx(@prefix)
|
||||
// Alloc aligned file/io buffers
|
||||
//
|
||||
filebuff = heapallocalign(1024, 8, 0)
|
||||
iobuff = heapallocalign(1024, 8, 0)
|
||||
//iobuff = heapallocalign(1024, 8, 0)
|
||||
//
|
||||
// Service IP
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user