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

View File

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

View File

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

View File

@ -397,13 +397,19 @@ int parse_value(int rvalue)
if (deref) if (deref)
push_op(scantoken, 0); push_op(scantoken, 0);
else else
{
deref++;
type |= BPTR_TYPE; type |= BPTR_TYPE;
}
break; break;
case WPTR_TOKEN: case WPTR_TOKEN:
if (deref) if (deref)
push_op(scantoken, 0); push_op(scantoken, 0);
else else
{
deref++;
type |= WPTR_TYPE; type |= WPTR_TYPE;
}
break; break;
case AT_TOKEN: case AT_TOKEN:
deref--; deref--;
@ -690,16 +696,7 @@ int parse_value(int rvalue)
emit_const(value); emit_const(value);
else if (type & ADDR_TYPE) else if (type & ADDR_TYPE)
{ {
if (type & PTR_TYPE) if (type & LOCAL_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)
emit_localaddr(value + ref_offset); emit_localaddr(value + ref_offset);
else else
emit_globaladdr(value, ref_offset, ref_type); emit_globaladdr(value, ref_offset, ref_type);

View File

@ -3107,14 +3107,16 @@ def parse_value(rvalue)
if deref if deref
push_op(token, 0) push_op(token, 0)
else else
type = type | BPTR_TYPE deref = deref + 1
type = type | BPTR_TYPE
fin fin
break break
is WPTR_TKN is WPTR_TKN
if deref if deref
push_op(token, 0) push_op(token, 0)
else else
type = type | WPTR_TYPE deref = deref + 1
type = type | WPTR_TYPE
fin fin
break break
is AT_TKN is AT_TKN
@ -3405,23 +3407,7 @@ def parse_value(rvalue)
if type & CONST_TYPE if type & CONST_TYPE
emit_const(value) emit_const(value)
elsif type & ADDR_TYPE elsif type & ADDR_TYPE
if type & PTR_TYPE if type & LOCAL_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
emit_localaddr(value + ref_offset) emit_localaddr(value + ref_offset)
else else
emit_globaladdr(value, ref_offset) emit_globaladdr(value, ref_offset)