mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-04 09:29:28 +00:00
Working on module loading in mem manager.
This commit is contained in:
parent
68c70a3ec6
commit
d4b90e32f8
@ -632,7 +632,7 @@ class PackPartitions
|
|||||||
assert fixup[sp++] == 2 // code table fixup
|
assert fixup[sp++] == 2 // code table fixup
|
||||||
def addr = fixup[sp++] & 0xFF
|
def addr = fixup[sp++] & 0xFF
|
||||||
addr |= (fixup[sp++] & 0xFF) << 8
|
addr |= (fixup[sp++] & 0xFF) << 8
|
||||||
invDefs[addr] = it*5 + 2 // account for initial placeholder
|
invDefs[addr] = it*5
|
||||||
addr -= 0x1000
|
addr -= 0x1000
|
||||||
addr -= byteCodeStart
|
addr -= byteCodeStart
|
||||||
assert addr >= 0 && addr < byteCode.size
|
assert addr >= 0 && addr < byteCode.size
|
||||||
@ -644,8 +644,6 @@ class PackPartitions
|
|||||||
def dp = 0
|
def dp = 0
|
||||||
def stubsSize = defCount * 5
|
def stubsSize = defCount * 5
|
||||||
def newAsmCode = new byte[stubsSize + asmCode.size + 2]
|
def newAsmCode = new byte[stubsSize + asmCode.size + 2]
|
||||||
newAsmCode[dp++] = 0 // placeholders for aux addr...
|
|
||||||
newAsmCode[dp++] = 0 // ...that fixups were applied to
|
|
||||||
(0..<defCount).each {
|
(0..<defCount).each {
|
||||||
newAsmCode[dp++] = 0x20 // JSR
|
newAsmCode[dp++] = 0x20 // JSR
|
||||||
newAsmCode[dp++] = 0xDC // Aux mem interp ($3DC)
|
newAsmCode[dp++] = 0xDC // Aux mem interp ($3DC)
|
||||||
@ -692,7 +690,7 @@ class PackPartitions
|
|||||||
target += stubsSize // account for the stubs we prepended to the asm code
|
target += stubsSize // account for the stubs we prepended to the asm code
|
||||||
println String.format("...adjusted to target offset 0x%04x", target)
|
println String.format("...adjusted to target offset 0x%04x", target)
|
||||||
}
|
}
|
||||||
assert target >= 7 && target < newAsmCode.length
|
assert target >= 5 && target < newAsmCode.length
|
||||||
|
|
||||||
// Put the adjusted target back in the code
|
// Put the adjusted target back in the code
|
||||||
codeBuf[addr] = (byte)(target & 0xFF)
|
codeBuf[addr] = (byte)(target & 0xFF)
|
||||||
|
@ -83,6 +83,7 @@ segNum: !byte 0
|
|||||||
nextLdVec: jmp diskLoader
|
nextLdVec: jmp diskLoader
|
||||||
curPartition: !byte 0
|
curPartition: !byte 0
|
||||||
partFileRef: !byte 0
|
partFileRef: !byte 0
|
||||||
|
fixupHint: !word 0
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
!source "../include/debug.i"
|
!source "../include/debug.i"
|
||||||
@ -118,9 +119,11 @@ releaseSegment: !zone
|
|||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
scanForAddr: !zone
|
scanForAddr: !zone
|
||||||
; Input: pTmp - address to scan for
|
; Input: X(lo)/Y(hi) - address to scan for
|
||||||
; Output: X-reg - segment found (zero if not found), N and Z set for X-reg
|
; Output: X-reg - segment found (zero if not found), N and Z set for X-reg
|
||||||
; carry clear if addr == seg start, set if addr != seg start
|
; carry clear if addr == seg start, set if addr != seg start
|
||||||
|
stx pTmp ; save target addr
|
||||||
|
sty pTmp+1
|
||||||
ldx isAuxCmd ; grab correct starting segment (0=main mem, 1=aux)
|
ldx isAuxCmd ; grab correct starting segment (0=main mem, 1=aux)
|
||||||
.loop: ldy tSegLink,x ; grab link to next segment, which we'll need regardless
|
.loop: ldy tSegLink,x ; grab link to next segment, which we'll need regardless
|
||||||
lda pTmp ; compare pTmp
|
lda pTmp ; compare pTmp
|
||||||
@ -582,7 +585,11 @@ reset: !zone
|
|||||||
.next: lda tSegLink,x ; get link to next seg
|
.next: lda tSegLink,x ; get link to next seg
|
||||||
tax ; to X reg, and test if end of chain (x=0)
|
tax ; to X reg, and test if end of chain (x=0)
|
||||||
bne .inactivate ; no, not end of chain, so loop again
|
bne .inactivate ; no, not end of chain, so loop again
|
||||||
rts ; yes, end of chain: done
|
lda #0 ; default to putting fixups at $8000, to avoid fragmentation
|
||||||
|
sta fixupHint
|
||||||
|
lda #$80
|
||||||
|
sta fixupHint+1
|
||||||
|
rts
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
outOfMemErr: !zone
|
outOfMemErr: !zone
|
||||||
@ -608,9 +615,10 @@ shared_request:
|
|||||||
sta isAuxCmd ; save whether we're working on main or aux mem
|
sta isAuxCmd ; save whether we're working on main or aux mem
|
||||||
stx reqLen ; save requested length
|
stx reqLen ; save requested length
|
||||||
sty reqLen+1 ; all 16 bits
|
sty reqLen+1 ; all 16 bits
|
||||||
shared_alloc: lda #1
|
shared_alloc:
|
||||||
|
lda #1
|
||||||
sta .reclaimFlg ; we will try to reclaim once
|
sta .reclaimFlg ; we will try to reclaim once
|
||||||
.try: lda targetAddr+1 ; see if SET_MEM_TARGET was called
|
.try: ldy targetAddr+1 ; see if SET_MEM_TARGET was called
|
||||||
bne .gotTarget ; no, we need to choose location
|
bne .gotTarget ; no, we need to choose location
|
||||||
; no target address has been specified, we need to choose one
|
; no target address has been specified, we need to choose one
|
||||||
.chooseAddr:
|
.chooseAddr:
|
||||||
@ -625,9 +633,7 @@ shared_alloc: lda #1
|
|||||||
jmp invalAddr
|
jmp invalAddr
|
||||||
; target addr was specified. See if we can fulfill the request.
|
; target addr was specified. See if we can fulfill the request.
|
||||||
.gotTarget:
|
.gotTarget:
|
||||||
sta pTmp+1 ; save target addr
|
ldx targetAddr ; all 16 bits
|
||||||
lda targetAddr ; all 16 bits
|
|
||||||
sta pTmp
|
|
||||||
jsr scanForAddr ; locate block containing target addr
|
jsr scanForAddr ; locate block containing target addr
|
||||||
beq .notFound ; fail if we couldn't find it
|
beq .notFound ; fail if we couldn't find it
|
||||||
lda tSegType,x ; check flags
|
lda tSegType,x ; check flags
|
||||||
@ -692,17 +698,46 @@ shared_alloc: lda #1
|
|||||||
.reclaimFlg: !byte 0
|
.reclaimFlg: !byte 0
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
; Free everything that's inactive
|
||||||
reclaim: !zone
|
reclaim: !zone
|
||||||
ldx #<+
|
ldx isAuxCmd ; grab correct starting segment (0=main mem, 1=aux)
|
||||||
ldy #>+
|
.loop: ldy tSegLink,x ; grab link to next segment, which we'll need regardless
|
||||||
jmp fatalError
|
lda tSegType,x ; check flag and type of this seg
|
||||||
+ !text "Reclaim not impl yet", 0
|
bmi .next
|
||||||
|
lda #0
|
||||||
|
sta tSegType,x
|
||||||
|
.next: tya ; next in chain
|
||||||
|
tax ; to X reg index
|
||||||
|
bne .loop ; non-zero = not end of chain - loop again
|
||||||
|
; fall through to coalesce...
|
||||||
|
; Join adjacent free blocks of memory, where "free" is defined as having
|
||||||
|
; resource type zero and no flags. Note that it will not join inactive blocks
|
||||||
|
; that still have a resource type.
|
||||||
|
coalesce: !zone
|
||||||
|
ldx isAuxCmd ; grab correct starting segment (0=main mem, 1=aux)
|
||||||
|
.loop: ldy tSegLink,x ; grab link to next segment, which we'll need regardless
|
||||||
|
beq .done ; no next segment, nothing to join to ==> done
|
||||||
|
lda tSegType,x ; check flag and type of this seg
|
||||||
|
ora tSegType,y ; and next seg
|
||||||
|
bmi .next ; if either is active or has a type, can't combine
|
||||||
|
; we can combine the next segment into this one.
|
||||||
|
stx tmp
|
||||||
|
tya
|
||||||
|
tax
|
||||||
|
jsr releaseSegment
|
||||||
|
lda tSegLink,x ; link to what the combined segment was linked to
|
||||||
|
ldx tmp
|
||||||
|
sta tSegLink,x
|
||||||
|
jmp .loop ; we may be able to combine even more
|
||||||
|
.next: tya ; next in chain
|
||||||
|
tax ; to X reg index
|
||||||
|
bne .loop ; non-zero = not end of chain - loop again
|
||||||
|
.done rts ; all done
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
shared_scan: !zone
|
shared_scan: !zone
|
||||||
sta isAuxCmd ; save whether main or aux mem
|
sta isAuxCmd ; save whether main or aux mem
|
||||||
stx pTmp ; save addr lo...
|
|
||||||
sty pTmp+1 ; ... and hi
|
|
||||||
jsr scanForAddr ; scan for block that matches
|
jsr scanForAddr ; scan for block that matches
|
||||||
beq invalAddr ; if not found, invalid
|
beq invalAddr ; if not found, invalid
|
||||||
bcs invalAddr ; if addr not exactly equal, invalid
|
bcs invalAddr ; if addr not exactly equal, invalid
|
||||||
@ -799,7 +834,9 @@ shared_queueLoad:
|
|||||||
sta isAuxCmd ; save whether main or aux
|
sta isAuxCmd ; save whether main or aux
|
||||||
stx resType ; save resource type
|
stx resType ; save resource type
|
||||||
sty resNum ; save resource number
|
sty resNum ; save resource number
|
||||||
jsr scanForResource ; scan to see if we already have this resource in mem
|
cpx #RES_TYPE_MODULE ; loading a module?
|
||||||
|
beq .module ; extra work for modules
|
||||||
|
.notMod jsr scanForResource ; scan to see if we already have this resource in mem
|
||||||
beq .notFound ; nope, pass to next loader
|
beq .notFound ; nope, pass to next loader
|
||||||
stx segNum ; save seg num for later
|
stx segNum ; save seg num for later
|
||||||
lda tSegType,x ; get flags
|
lda tSegType,x ; get flags
|
||||||
@ -830,6 +867,54 @@ shared_queueLoad:
|
|||||||
ldy resNum ; and number
|
ldy resNum ; and number
|
||||||
lda #QUEUE_LOAD ; set to re-try same operation
|
lda #QUEUE_LOAD ; set to re-try same operation
|
||||||
jmp nextLdVec ; pass to next loader
|
jmp nextLdVec ; pass to next loader
|
||||||
|
; extra work for modules
|
||||||
|
.module lda #RES_TYPE_BYTECODE
|
||||||
|
sta resType
|
||||||
|
lda #1
|
||||||
|
sta isAuxCmd
|
||||||
|
jsr scanForResource ; do we have the aux mem part?
|
||||||
|
beq .reload
|
||||||
|
lda #RES_TYPE_MODULE
|
||||||
|
sta resType
|
||||||
|
lda #0
|
||||||
|
sta isAuxCmd
|
||||||
|
jsr scanForResource ; do we have the main mem part?
|
||||||
|
beq .reload
|
||||||
|
rts ; we have both parts already -- no need for fixups
|
||||||
|
.reload lda #RES_TYPE_MODULE
|
||||||
|
sta resType
|
||||||
|
lda #0
|
||||||
|
sta isAuxCmd
|
||||||
|
jsr .notMod ; queue the main memory part of the module
|
||||||
|
stx .modRet+1 ; save address of main load for eventual return
|
||||||
|
sty .modRet+3 ; yes, self-modifying
|
||||||
|
ldx #RES_TYPE_BYTECODE
|
||||||
|
ldy resNum
|
||||||
|
jsr aux_queueLoad ; load the aux mem part (the bytecode)
|
||||||
|
; try to pick a location for the fixups that we can free without fragmenting everything.
|
||||||
|
ldx fixupHint
|
||||||
|
ldy fixupHint+1
|
||||||
|
jsr scanForAddr ; locate block containing target addr
|
||||||
|
beq .frag
|
||||||
|
lda tSegType,x ; check flags
|
||||||
|
bmi .frag ; if already active, can't re-allocate it
|
||||||
|
lda fixupHint ; Okay, found a good place to put it
|
||||||
|
sta targetAddr
|
||||||
|
lda fixupHint+1
|
||||||
|
sta targetAddr+1
|
||||||
|
.frag ldx #RES_TYPE_FIXUP ; queue loading of the fixup resource
|
||||||
|
ldy resNum
|
||||||
|
jsr aux_queueLoad
|
||||||
|
lda fixupHint ; advance hint for next fixup by the size of this fixup
|
||||||
|
clc
|
||||||
|
adc reqLen
|
||||||
|
sta fixupHint
|
||||||
|
lda fixupHint+1
|
||||||
|
adc reqLen+1
|
||||||
|
sta fixupHint+1
|
||||||
|
.modRet ldx #11 ; all done; return address of the main memory block.
|
||||||
|
ldy #22
|
||||||
|
rts
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
diskLoader: !zone
|
diskLoader: !zone
|
||||||
|
@ -83,13 +83,16 @@ auxLoader = $806
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; Resource types
|
; Resource types
|
||||||
|
|
||||||
RES_TYPE_CODE = 1
|
RES_TYPE_CODE = 1
|
||||||
RES_TYPE_2D_MAP = 2
|
RES_TYPE_2D_MAP = 2
|
||||||
RES_TYPE_3D_MAP = 3
|
RES_TYPE_3D_MAP = 3
|
||||||
RES_TYPE_TILE = 4
|
RES_TYPE_TILE = 4
|
||||||
RES_TYPE_TEXTURE= 5
|
RES_TYPE_TEXTURE = 5
|
||||||
RES_TYPE_SCREEN = 6
|
RES_TYPE_SCREEN = 6
|
||||||
RES_TYPE_FONT = 7
|
RES_TYPE_FONT = 7
|
||||||
|
RES_TYPE_MODULE = 8
|
||||||
|
RES_TYPE_BYTECODE = 9
|
||||||
|
RES_TYPE_FIXUP = 10
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; Command codes
|
; Command codes
|
||||||
|
Loading…
Reference in New Issue
Block a user