1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-07-05 04:28:57 +00:00

Fix pointer dereferences once and for all (I hope). Simplify memory

manager. Homing in on ethernet interface
This commit is contained in:
David Schmenk 2015-01-24 10:00:45 -08:00
parent ee04be4c5a
commit c2dccbdc18
5 changed files with 185 additions and 194 deletions

View File

@ -48,26 +48,24 @@ end
struc t_freblk
word fresiz
word frenxt
word freprv
end
//
// Block size
//
const MAX_BLK_SIZE = $2010
const MAX_BLK_MASK = $1FFF
const MIN_BLK_SIZE = $08
const MIN_BLK_MASK = $07
const MIN_BLK_SIZE = $04
const MIN_BLK_MASK = $03
//
// Block states
//
const HMEM_ADDR = $FFF8
const HMEM_SIZE = $FFF8
const HMEM_ADDR = $FFFC
const HMEM_SIZE = $FFFC
const HMEM_STATE = $07
const HMEM_MOVEABLE = $00 // Many dependencies on this being $00
const HMEM_AVAIL = $01
const HMEM_LOCKED = $02
const HMEM_SWAPPED = $03
const HMEM_UNINIT = $04
//
// Block flags
//
@ -214,44 +212,37 @@ end
//
// Find exact/best free memory match
//
def unlink(freblk)
def unlink(freblk, freprv)
//
// Unlink free block
//
if freblk=>freprv
freblk=>freprv=>frenxt = freblk=>frenxt
if freprv
freprv=>frenxt = freblk=>frenxt
else
frelst = freblk=>frenxt
fin
if freblk=>frenxt
freblk=>frenxt=>freprv = freblk=>freprv
fin
return freblk
end
def unfre(freblk, size)
def unfre(freblk, freprv, size)
word shrink
if freblk=>fresiz == size
//
// Unlink free block
//
unlink(freblk)
unlink(freblk, freprv)
elsif freblk=>fresiz > size
//
// Shrink free block
//
shrink = freblk + size
if freblk=>freprv
freblk=>freprv=>frenxt = shrink
if freprv
freprv=>frenxt = shrink
else
frelst = shrink
fin
if freblk=>frenxt
freblk=>frenxt=>freprv = shrink
fin
shrink=>fresiz = freblk=>fresiz - size
shrink=>frenxt = freblk=>frenxt
shrink=>freprv = freblk=>freprv
else
freblk = 0
fin
@ -268,30 +259,23 @@ def addfre(freblk)
//
// Insert into list
//
freblk=>freprv = srch
freblk=>frenxt = srch=>frenxt
srch=>frenxt=>freprv = freblk
srch=>frenxt = freblk
freblk=>frenxt = srch=>frenxt
srch=>frenxt = freblk
return
fin
srch = srch=>frenxt
srch = srch=>frenxt
loop
//
// Add to end of list
//
freblk=>freprv = srch
freblk=>frenxt = 0
srch=>frenxt = freblk
else
//
// Add to beginning of list
//
freblk=>freprv = 0
freblk=>frenxt = frelst
if frelst
frelst=>freprv = freblk
fin
frelst = freblk
frelst = freblk
fin
end
//
@ -309,9 +293,6 @@ def coallesce
//
srch=>fresiz = srch=>fresiz + srch=>frenxt=>fresiz
srch=>frenxt = srch=>frenxt=>frenxt
if srch=>frenxt
srch=>frenxt=>freprv = srch
fin
combined = 1
//putc('C')
else
@ -321,7 +302,7 @@ def coallesce
return combined
end
def compact
word page, entry, memblk, moveblk, size, srch
word page, entry, memblk, moveblk, size, srch, prev
byte moved
moved = 0
@ -332,13 +313,15 @@ def compact
memblk = hpgtbl:[page, entry]
size = memblk=>blksiz
moveblk = 0
prev = 0
srch = frelst
while srch and srch < memblk
if srch=>fresiz >= size
moveblk = unfre(srch, size)
moveblk = unfre(srch, prev, size)
//putc('M');putc(' ');puth(moveblk);putc('=');puth(memblk);putln
break
fin
prev = srch
srch = srch=>frenxt
loop
if moveblk
@ -389,6 +372,9 @@ def swapout(accessed)
// Write it out
//
if write(ref, memblk, size) == size
//
// Zero size in page table flags swapin to read from disk
//
hpgtbl:[page, entry] = HMEM_SWAPPED
addfre(memblk)
swapped = 1
@ -412,26 +398,30 @@ end
// Find a memory block
//
def findexact(size)
word srch
word srch, prev
srch = frelst
prev = 0
while srch
if srch=>fresiz == size
//putc('E')
return unlink(srch)
return unlink(srch, prev)
fin
prev = srch
srch = srch=>frenxt
loop
end
def findbest(size)
word srch, shrink
word srch, prev
srch = frelst
prev = 0
srch = frelst
while srch
if srch=>fresiz >= size
//putc('B')
return unfre(srch, size)
return unfre(srch, prev, size)
fin
prev = srch
srch = srch=>frenxt
loop
end
@ -476,41 +466,36 @@ def swapin(hmem)
byte ref
word memblk, size
memblk = 0
when hpgtbl:[hmem.lsb, hmem.msb].lsb & HMEM_STATE
is HMEM_SWAPPED
//
// Swap this block back in
size = hpgtbl:[hmem.lsb, hmem.msb] & HMEM_SIZE
if size
//
// This was just uninitialized memory, don't bother reading from file
//
memblk = findblk(size)
else
//
// Swap this block back in
//
swapfile(@filename, hmem)
get_info(@filename, @info)
size = info:2 // Size encoded in aux type
memblk = findblk(size)
if memblk
//
swapfile(@filename, hmem)
get_info(@filename, @info)
size = info:2 // size encoded in aux type
memblk = findblk(size)
if memblk
//
// Read it in
//
ref = open(@filename)
if ref
read(ref, memblk, size)
hpgtbl:[hmem.lsb, hmem.msb] = memblk
close(ref)
destroy(@filename)
else
memblk = 0
fin
// Read it in
//
ref = open(@filename)
if ref
read(ref, memblk, size)
close(ref)
destroy(@filename)
fin
//puts(@swapinstr);puts(@filename);putc('@');puth(memblk);putc(':');puth(size);putln
break
is HMEM_UNINIT
//
// Initialize this block
//
memblk = findblk(hpgtbl:[hmem.lsb, hmem.msb] & HMEM_SIZE)
if memblk
hpgtbl:[hmem.lsb, hmem.msb] = memblk
fin
wend
//puts(@swapinstr);puts(@filename);putc('@');puth(memblk);putc(':');puth(size);putln
fin
fin
if memblk
hpgtbl:[hmem.lsb, hmem.msb] = memblk
fin
return memblk
end
//
@ -567,7 +552,6 @@ export def brk(addr)
frelst = heapalign
frelst=>fresiz = brksiz
frelst=>frenxt = 0
frelst=>freprv = 0
else
poolsize = 0
fin
@ -579,20 +563,18 @@ export def brk(addr)
brksiz = addr - heapmark
brkblk = heapalloc(brksiz)
if brkblk
poolsize = poolsize + brksiz
//
// Add block to end of free list
//
poolsize = poolsize + brksiz
brkblk=>fresiz = brksiz
brkblk=>frenxt = 0
if frelst
srch = frelst
while srch=>frenxt; srch = srch=>frenxt; loop
srch=>frenxt = brkblk
brkblk=>freprv = srch
srch=>frenxt = brkblk
else
frelst = brkblk
brkblk=>freprv = 0
frelst = brkblk
fin
coallesce // combine adjacent free space
fin
@ -670,11 +652,12 @@ export def hmemNew(size)
for entry = 255 downto 0
if hpgtbl:[page, entry].lsb == HMEM_AVAIL
//
// Reserve handle as uninitialized memory
// Reserve handle as swapped out block
// Nonzero size will flag swapin to not read from disk
//
//putc('N');putc(' ');putb(entry);putb(page);putc('@')
size = ((size + t_memblk) | MIN_BLK_MASK) + 1
hpgtbl:[page, entry] = size | HMEM_UNINIT
hpgtbl:[page, entry] = size | HMEM_SWAPPED
hnew.lsb = page
hnew.msb = entry
return hnew
@ -690,7 +673,6 @@ export def hmemLock(hmem)
memblk = hpgtbl:[hmem.lsb, hmem.msb]
when memblk.lsb & HMEM_STATE
is HMEM_UNINIT
is HMEM_SWAPPED
memblk = swapin(hmem)
if not memblk; return 0; fin
@ -732,7 +714,6 @@ export def hmemRef(hmem)
memblk = hpgtbl:[hmem.lsb, hmem.msb]
when memblk.lsb & HMEM_STATE
is HMEM_UNINIT
is HMEM_SWAPPED
memblk = swapin(hmem)
is HMEM_LOCKED
@ -768,8 +749,6 @@ export def hmemDel(hmem)
memblk->blkref = ref
fin
break
is HMEM_UNINIT
hpgtbl:[hmem.lsb, hmem.msb] = HMEM_AVAIL
wend
end
//

View File

@ -1,27 +1,11 @@
import STDLIB
import stdlib
predef syscall, call, memset, getc, gets, putc, puts, putln
predef memset, memcpy, modaddr, modexec
predef heapmark, heapallocalign, heapalloc, heaprelease
byte MACHID
end
//
// Ethernet adapter driver
//
byte etherlib = "UTHERNET", 0
struc t_edrvr
word fillMAC
word writeFrame
word readFrame
word recvFrame
end
word edrvr
//
// Ethernet packet header
//
struc t_ether
byte[6] hwdst
byte[6] hwsrc
word payload
import uthernet
predef MAC, writeEther, readEther, recvEther
end
//
// IP datagram header
@ -75,10 +59,13 @@ byte[4] localip = 192,168,123,10
byte[6] remoteha
byte[4] remoteip = 192,168,123,1
//
// ARP segment list
//
word segARP = @ARP, t_arp
//
// Max Ethernet frame size
//
const maxesize = 1518
word pkt, len
const MAX_FRAME_SIZE = 1518
//
// Defines for ASM routines
//
@ -202,21 +189,37 @@ def dumpfrm(packet, len)
next
putln
end
if modexec(@etherlib) == 0
edrvr = modaddr(@etherlib)
edrvr=>fillMAC(@localha)
edrvr=>writeFrame(@BCAST, PAYLOAD_ARP, @ARP, t_arp)
repeat; len = edrvr=>recvFrame(); until len or ^$C000 > 127
if len
pkt = heapalloc(len)
if edrvr=>readFrame(pkt) == PAYLOAD_ARP
//
// Service incoming packets
//
def serviceIP
word pkt, len
when recvEther()
is 0
break
is PAYLOAD_ARP
pkt = heapalloc(MAX_FRAME_SIZE)
len = readEther(pkt, t_arp)
dumparp(pkt)
else
readEther(pkt, len) // read remaining packet data
heaprelease(pkt)
break
otherwise
len = readEther(pkt, 0)
pkt = heapalloc(len)
readEther(pkt, len)
dumpfrm(pkt, len)
fin
heaprelease(pkt)
fin
^$C010
fin
heaprelease(pkt)
wend
end
localha:0 = MAC:0
localha:2 = MAC:2
localha:4 = MAC:4
writeEther(@BCAST, PAYLOAD_ARP, @segARP, t_arp)
repeat
serviceIP
until ^$C000 > 127
^$C010
done

View File

@ -1,4 +1,4 @@
import STDLIB
import stdlib
predef syscall, call, memset, getc, gets, putc, puts, putln
predef memset, memcpy, modaddr, modexec
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
@ -10,15 +10,6 @@ end
const modkeep = $2000
const modinitkeep = $4000
//
// Module interface defined by first 4 fields:
// word fillMAC
// word writeFrame
// word readFrame
// word nextEvent
//
predef fillmac, writefrm, readfrm, recvfrm
word = @fillmac, @writefrm, @readfrm, @recvfrm, 0
//
// Uthernet register offsets
//
const TXDATA = $00
@ -41,7 +32,7 @@ byte pregdata
//
// MAC address
//
byte MAC = $00,$0A,$99,$1E,$02,$00
export byte MAC = $00,$0A,$99,$1E,$02,$00
//
// Ethernet header
//
@ -51,8 +42,14 @@ struc t_ehdr
word ehdr_type
end
//
// Current status an packet len
word status, len // MUST be in this order!
// Max Ethernet frame size
//
const MAX_FRAME_SIZE = 1518
//
// Current receive status and packet size
//
word rxstatus, rxsize // MUST be in this order!
word rxpacket, rxptr
//
// Defines for ASM routines
//
@ -94,8 +91,8 @@ asm _peekiowh
RTS
end
//
// POKE PACKET FRAME INTO I/O SPACE
// _pokefrm(BUF, LEN)
// WRITE PACKET FRAME INTO I/O SPACE
// pokefrm(BUF, LEN)
//
asm pokefrm
LDY #$00
@ -132,8 +129,8 @@ asm _pokefrmh
RTS
end
//
// PEEK PACKET FRAME FROM I/O SPACE
// _peekfrm(BUF, LEN)
// READ PACKET FRAME FROM I/O SPACE
// peekfrm(BUF, LEN)
//
asm peekfrm
LDA ESTKL+1,X
@ -192,13 +189,14 @@ end
//
// Uthernet interface
//
def fillmac(pmac)
pmac=>0 = MAC:0
pmac=>2 = MAC:2
pmac=>4 = MAC:4
return pmac + 6
export def writeEther(packet, size)
pokeiow(txcmd, $C0)
pokeiow(txlen, size)
repeat; until peekpreg($0138) & $0100
return pokefrm(packet, size)
end
def writefrm(destha, payload, packet, size)
export def writevEther(destha, payload, seglist, size)
word segsize
pokeiow(txcmd, $C0)
pokeiow(txlen, size + t_ehdr)
@ -206,35 +204,63 @@ def writefrm(destha, payload, packet, size)
pokefrm(destha, 6)
pokefrm(@MAC, 6)
pokefrm(@payload, 2)
return pokefrm(packet, size)
while size > 0
segsize = seglist=>2
if segsize > size
segsize = size
fin
pokefrm(seglist=>0, segsize)
size = size - segsize
seglist = seglist + 4
loop
end
def readfrm(packet)
byte[t_ehdr] header
word readlen
export def readEther(size)
word segptr
readlen = len
if status & $0100
peekfrm(@header, t_ehdr)
peekfrm(packet, len)
if rxsize > 0
if size > rxsize
size = rxsize
fin
segptr = rxptr
rxptr = rxptr + size
rxsize = rxsize - size
else
segptr = 0
fin
status = 0
len = 0
return header:ehdr_type
return segptr
end
def recvfrm
if len == 0
export def readvEther(seglist, size)
word segsize
while size > 0
segsize = seglist=>2
size = size - segsize
if segsize > rxsize
segsize = rxsize
fin
memcpy(seglist=>0, rxptr, segsize)
rxptr = rxptr + segsize
rxsize = rxsize - segsize
seglist = seglist + 4
loop
return rxsize
end
export def recvEther
if rxsize == 0
if peekiow(isq) & $3F == 4
peekfrm(@status, 4)
if !(status & $0100)
pokepreg($0102, $0140) // Skip pkt
status = 0
len = 0
peekfrm(@rxstatus, 4)
if rxstatus & $0100
if !rxpacket; rxpacket = heapalloc(MAX_FRAME_SIZE); fin
peekfrm(rxpacket, rxsize)
rxptr = rxpacket
else
len = len - t_ehdr
pokepreg($0102, $0140) // Skip pkt
rxstatus = 0
rxsize = 0
fin
fin
fin
return len
return rxsize
end
//
// Identify Uthernet card and initialize

View File

@ -397,13 +397,19 @@ int parse_value(int rvalue)
if (deref)
push_op(scantoken, 0);
else
{
deref++;
type |= BPTR_TYPE;
}
break;
case WPTR_TOKEN:
if (deref)
push_op(scantoken, 0);
else
{
deref++;
type |= WPTR_TYPE;
}
break;
case AT_TOKEN:
deref--;
@ -690,16 +696,7 @@ int parse_value(int rvalue)
emit_const(value);
else if (type & ADDR_TYPE)
{
if (type & PTR_TYPE)
{
if (type & FUNC_TYPE)
emit_call(value, ref_type);
else if (type & LOCAL_TYPE)
(type & BYTE_TYPE) ? emit_llb(value + ref_offset) : emit_llw(value + ref_offset);
else
(type & BYTE_TYPE) ? emit_lab(value, ref_offset, ref_type) : emit_law(value, ref_offset, ref_type);
}
else if (type & LOCAL_TYPE)
if (type & LOCAL_TYPE)
emit_localaddr(value + ref_offset);
else
emit_globaladdr(value, ref_offset, ref_type);

View File

@ -3107,14 +3107,16 @@ def parse_value(rvalue)
if deref
push_op(token, 0)
else
type = type | BPTR_TYPE
deref = deref + 1
type = type | BPTR_TYPE
fin
break
is WPTR_TKN
if deref
push_op(token, 0)
else
type = type | WPTR_TYPE
deref = deref + 1
type = type | WPTR_TYPE
fin
break
is AT_TKN
@ -3405,23 +3407,7 @@ def parse_value(rvalue)
if type & CONST_TYPE
emit_const(value)
elsif type & ADDR_TYPE
if type & PTR_TYPE
if type & FUNC_TYPE
emit_call(value)
elsif type & LOCAL_TYPE
if type & BYTE_TYPE
emit_llb(value + ref_offset)
else
emit_llw(value + ref_offset)
fin
else
if type & BYTE_TYPE
emit_lab(value, ref_offset)
else
emit_law(value, ref_offset)
fin
fin
elsif type & LOCAL_TYPE
if type & LOCAL_TYPE
emit_localaddr(value + ref_offset)
else
emit_globaladdr(value, ref_offset)