mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-12-25 13:29:59 +00:00
Made API for garbage collector (now called heap system)
This commit is contained in:
parent
a6c2b46a92
commit
39c37c2517
@ -50,10 +50,6 @@ gcHash_link = $5300
|
||||
gcHash_dstLo = $5400
|
||||
gcHash_dstHi = $5500
|
||||
|
||||
; Heap area
|
||||
heapStart = $F000 ; must be page aligned
|
||||
heapEnd = $F800 ; must be page aligned
|
||||
|
||||
; Other equates
|
||||
prodosMemMap = $BF58
|
||||
|
||||
@ -651,6 +647,8 @@ typeTblL !fill MAX_TYPES
|
||||
typeTblH !fill MAX_TYPES
|
||||
typeLen !fill MAX_TYPES ; length does not include type byte
|
||||
|
||||
heapStartPg !byte 0
|
||||
heapEndPg !byte 0
|
||||
heapTop !word 0
|
||||
gcHash_top !byte 0
|
||||
nHeapBlks !byte 0
|
||||
@ -682,12 +680,11 @@ setTypeTbl: !zone
|
||||
|
||||
; Clear the heap
|
||||
heapReset: !zone
|
||||
lda #<heapStart
|
||||
sta heapTop
|
||||
lda #>heapStart
|
||||
sta heapTop
|
||||
lda #0
|
||||
sta heapTop
|
||||
sta nHeapBlks
|
||||
lda heapStartPg
|
||||
sta heapTop
|
||||
; fall through to:
|
||||
; Zero memory heapTop.heapEnd
|
||||
heapClr: !zone
|
||||
@ -699,7 +696,7 @@ heapClr: !zone
|
||||
inx
|
||||
bne .st
|
||||
iny
|
||||
cpy #>heapEnd
|
||||
cpy heapEndPg
|
||||
bne .pg
|
||||
rts
|
||||
|
||||
@ -722,7 +719,7 @@ heapAlloc: !zone
|
||||
adc pTmp
|
||||
bcc +
|
||||
iny
|
||||
cpy #>heapEnd
|
||||
cpy heapEndPg
|
||||
bcs .needgc
|
||||
+ sta heapTop
|
||||
sty heapTop+1
|
||||
@ -790,7 +787,7 @@ heapCheck: !zone
|
||||
bcc .blklup
|
||||
inc pTmp+1
|
||||
lda pTmp+1
|
||||
cmp #>heapEnd
|
||||
cmp heapEndPg
|
||||
bcc .blklup
|
||||
bcs heapCorrupt
|
||||
.isobj and #$7F
|
||||
@ -814,9 +811,9 @@ heapCheck: !zone
|
||||
bcs heapCorrupt ; but beyond end is not ok
|
||||
+ lda (pTmp),y ; get hi byte of ptr
|
||||
beq .tscan ; null is ok
|
||||
cmp #>heapStart ; else check if < start of heap
|
||||
cmp heapStartPg ; else check if < start of heap
|
||||
bcc heapCorrupt
|
||||
cmp #>heapEnd ; or >= than end of heap
|
||||
cmp heapEndPg ; or >= than end of heap
|
||||
bcc .tscan
|
||||
heapCorrupt:
|
||||
ldx pTmp
|
||||
@ -832,9 +829,8 @@ gc1_mark: !zone
|
||||
- sta gcHash_first,x
|
||||
inx
|
||||
bne -
|
||||
lda #<heapStart ; global block is at very start of heap
|
||||
sta pSrc
|
||||
lda #>heapEnd
|
||||
stx pSrc ; X is zero'd from loop above
|
||||
lda heapStartPg
|
||||
sta pSrc+1
|
||||
sec ; sec means add if not found
|
||||
jsr gcHash_chk ; seed the hash, and thus our queue, with the global block
|
||||
@ -897,10 +893,10 @@ gc3_fix:
|
||||
|
||||
; Phase 2 of Garbage Collection: sweep all accessible blocks together
|
||||
gc2_sweep: !zone
|
||||
lda #<heapStart
|
||||
lda #0
|
||||
sta pSrc
|
||||
sta pDst
|
||||
lda #>heapStart
|
||||
lda heapStartPg
|
||||
sta pSrc+1
|
||||
sta pDst+1
|
||||
.outer clc ; clc = do not add to hash
|
||||
|
@ -248,19 +248,13 @@ DEBUG_MEM = $1A
|
||||
; Print out the currently allocated memory blocks and their states.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
CHAIN_LOADER = $1E
|
||||
; Input: X-reg / Y-reg - pointer to loader (X=lo, Y=hi) to add to chain
|
||||
CHECK_MEM = $1E
|
||||
; Input: None
|
||||
;
|
||||
; Output: None
|
||||
;
|
||||
; Add a loader to the chain just after this loader. The current next
|
||||
; loader (if there is one) will be passed to the new loader with another
|
||||
; CHAIN_LOADER command.
|
||||
;
|
||||
; The purpose of a loader chain is to insert faster devices between the
|
||||
; main/aux loader (fastest) and the disk loader (slowest). Note that the
|
||||
; main mem and aux mem loaders are conceptually one; a chained loader will
|
||||
; always be inserted after them, not between them.
|
||||
; Check that memory manager structures (and heap structures, if a heap
|
||||
; has been set) are all intact.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
FATAL_ERROR = $1F
|
||||
@ -274,6 +268,84 @@ FATAL_ERROR = $1F
|
||||
;
|
||||
; This command halts and thus never returns.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
HEAP_SET = $20
|
||||
; Input: X-reg(lo) / Y-reg(hi): pointer to allocated block for heap
|
||||
;
|
||||
; Output: None
|
||||
;
|
||||
; Establishes a block of memory to use as a garbage collected small-object
|
||||
; heap. The block must be page-aligned and sized in whole pages, and
|
||||
; generally should be locked first.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
HEAP_TYPE = $21
|
||||
; Input: X-reg(lo) / Y-reg(hi): pointer to type table
|
||||
;
|
||||
; Output: None
|
||||
;
|
||||
; Adds a type to the list of known heap types. Each type will be assigned
|
||||
; a number starting at $80 and going up to $81, $82, etc. By convention
|
||||
; type $80 should be the single "Global" object from which all others live
|
||||
; objects can be traced.
|
||||
;
|
||||
; The type table for the type should be laid out as follows:
|
||||
; byte 0: length byte (1 to 127)
|
||||
; byte 1: offset of first pointer (1 to 127)
|
||||
; byte 2: offset of second pointer
|
||||
; ...
|
||||
; byte n: zero (0) value marks end of table
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
HEAP_ALLOC = $22
|
||||
; Input: X-reg: string length $01-7F, or type code $80-FF
|
||||
;
|
||||
; Output: X-reg(lo) / Y-reg(hi): pointer to allocated object space
|
||||
;
|
||||
; Allocates an object on the heap. If X <= $7F, it's a string object
|
||||
; (no internal pointers). If X >= $80, it's a typed object corresponding
|
||||
; to the types added with HEAP_TYPE.
|
||||
;
|
||||
; The first byte of the returned block will be the length or type code,
|
||||
; (which you must never change), and subsequent bytes are initialized to
|
||||
; all zero.
|
||||
;
|
||||
; By convention, the very first block allocated should be of the "Global"
|
||||
; type ($80) and all other live objects must be traceable from there.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
HEAP_COLLECT = $23
|
||||
; Input: None.
|
||||
;
|
||||
; Output: X-reg(lo) / Y-reg(hi): free space in heap after collection
|
||||
;
|
||||
; Traces objects in the heap to determine which ones are "live", that is,
|
||||
; reachable from the very first object allocated. By convention, that first
|
||||
; object should be of the "Global" type, i.e. $80, and everything reachable
|
||||
; from pointers there is considered live.
|
||||
;
|
||||
; Live objects are then coalesced together in contiguous memory, squeezing
|
||||
; out any objects that can no longer be reached.
|
||||
;
|
||||
; NOTE: The main memory area from $4000.5FFF is used during the collection
|
||||
; process. Therefore, HEAP_COLLECT should not be run during a
|
||||
; START_LOAD..FINISH_LOAD sequence, nor when hi-res page 2 is being shown.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
CHAIN_LOADER = $30
|
||||
; Input: X-reg / Y-reg - pointer to loader (X=lo, Y=hi) to add to chain
|
||||
;
|
||||
; Output: None
|
||||
;
|
||||
; Add a loader to the chain just after this loader. The current next
|
||||
; loader (if there is one) will be passed to the new loader with another
|
||||
; CHAIN_LOADER command.
|
||||
;
|
||||
; The purpose of a loader chain is to insert faster devices between the
|
||||
; main/aux loader (fastest) and the disk loader (slowest). Note that the
|
||||
; main mem and aux mem loaders are conceptually one; a chained loader will
|
||||
; always be inserted after them, not between them.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Convenience for writing assembly routines in PLASMA source
|
||||
; Macro param: number of parameters passed from PLASMA to the asm routine
|
||||
|
Loading…
Reference in New Issue
Block a user