Good progress on reworking START_LOAD/FINISH_LOAD to figure out on their own what to do.

This commit is contained in:
Martin Haye 2016-09-08 08:30:08 -07:00
parent 65b414a954
commit fe704379ce
3 changed files with 116 additions and 92 deletions

View File

@ -29,8 +29,8 @@ MAX_SEGS = 96
DO_COMP_CHECKSUMS = 0 ; during compression debugging
DEBUG_DECOMP = 0
DEBUG = 0
SANITY_CHECK = 0 ; also prints out request data
DEBUG = 1
SANITY_CHECK = 1 ; also prints out request data
; Zero page temporary variables
tmp = $2 ; len 2
@ -1099,9 +1099,20 @@ gc2_sweep: !zone
sta heapTop+1
rts
closePartFile: !zone
lda partFileRef ; close the partition file
beq .done
!if DEBUG { +prStr : !text "Closing part file.",0 }
jsr closeFile
lda #0 ; zero out...
sta partFileRef ; ... the file reference so we know it's no longer open
.done rts
heapCollect: !zone
lda partFileRef ; check if the buffer space is already in use
bne .partOpen
; can't collect why anything queued for load
lda nSegsQueued
bne .unfin
jsr closePartFile
jsr gc1_mark ; mark reachable blocks
jsr gc2_sweep ; sweep them into one place
jsr gc3_fix ; adjust all pointers
@ -1109,8 +1120,7 @@ heapCollect: !zone
ldx heapTop ; return new top-of-heap in x=lo/y=hi
ldy heapTop+1
rts
.partOpen:
jsr inlineFatal : !text "NdClose",0
.unfin: jsr inlineFatal : !text "NdFinish",0
lastLoMem = *
} ; end of !pseodupc $800
@ -1129,6 +1139,7 @@ segNum: !byte 0
nextLdVec: jmp diskLoader
curPartition: !byte 0
partFileRef: !byte 0
nSegsQueued: !byte 0
fixupHint: !word 0
bufferDigest: !fill 4
multiDiskMode: !byte 0 ; hardcoded to YES for now
@ -1932,7 +1943,7 @@ calcBufferDigest: !zone
sty tmp+1
sty tmp+2
sty tmp+3
ldx #4 ; sum 4 pages in each buffer
ldx #6 ; sum 6 pages in each buffer - covers first part of heap collect zone also
clc
.sum lda tmp
rol
@ -1955,7 +1966,8 @@ calcBufferDigest: !zone
sta tmp+3
iny
bpl .sum ; bpl = 128 times through the loop
iny
bpl .sum ; every even offset 0..126
inc .ld1+2 ; go to next page
inc .ld2+2
@ -2092,17 +2104,17 @@ prodosError: !zone
;------------------------------------------------------------------------------
disk_startLoad: !zone
; Make sure we don't get start without finish
txa
beq sequenceError ; partition zero is illegal
cpx curPartition ; ok to open same partition twice without close
beq .nop
lda curPartition
bne sequenceError ; error to open new partition without closing old
; Just record the partition number; it's possible we won't actually be asked
; to queue anything, so we should put off opening the file.
stx curPartition
.nop rts
cpx curPartition ; switching partition?
stx curPartition ; (and store the new part num in any case)
bne .new ; if different, close the old one
lda partFileRef
beq .done ; if nothing already open, we're okay with that.
jsr calcBufferDigest ; same partition - check that buffers are still intact
beq .done ; if correct partition file already open, we're done.
.new jsr closePartFile
.done rts
;------------------------------------------------------------------------------
startHeaderScan: !zone
@ -2117,6 +2129,7 @@ startHeaderScan: !zone
disk_queueLoad: !zone
stx resType ; save resource type
sty resNum ; and resource num
inc nSegsQueued ; record the fact that we're queuing a seg
lda partFileRef ; check if we've opened the file yet
bne + ; yes, don't re-open
jsr openPartition ; open the partition file
@ -2181,14 +2194,10 @@ disk_queueLoad: !zone
.resLen: !byte 0
;------------------------------------------------------------------------------
disk_finishLoad: !zone
stx .keepOpenChk+1 ; store flag telling us whether to keep open (1) or close (0)
lda partFileRef ; see if we actually queued anything (and opened the file)
bne .work ; non-zero means we have work to do
txa
bne +
sta curPartition ; if "closing", clear the partition number
+ rts ; nothing to do - return immediately
.work sta setMarkFileRef ; copy the file ref number to our MLI param blocks
lda nSegsQueued ; see if we actually queued anything
beq .done ; if nothing queued, we're done
lda partFileRef
sta setMarkFileRef ; copy the file ref number to our MLI param blocks
sta readFileRef
lda headerBuf ; grab # header bytes
sta setMarkPos ; set to start reading at first non-header byte in file
@ -2199,22 +2208,17 @@ disk_finishLoad: !zone
sta .nFixups
jsr startHeaderScan ; start scanning the partition header
.scan: lda (pTmp),y ; get resource type byte
bne .notEnd ; non-zero = not end of header
; end of header. Check if we need to close the file.
.keepOpenChk:
lda #11 ; self-modified to 0 or 1 at start of routine
bne + ; 1 means leave open, 0 means close
!if DEBUG { +prStr : !text "Closing partition file.",0 }
lda partFileRef ; close the partition file
jsr closeFile
lda #0 ; zero out...
sta partFileRef ; ... the file reference so we know it's no longer open
sta curPartition ; ... and the partition number
+ lda .nFixups ; any fixups encountered?
beq +
bne .notdone ; zero = end of header
; At the end, record new buffer digest, and perform all fixups
jsr calcBufferDigest
lda .nFixups ; any fixups encountered?
beq .done
jsr doAllFixups ; found fixups - execute and free them
+ rts
.notEnd bmi .load ; hi bit set -> queued for load
.done lda #0
sta nSegsQueued ; we loaded everything, so record that fact
rts
.notdone:
bmi .load ; hi bit set -> queued for load
iny ; not set, not queued, so skip over it
iny
bne .next

View File

@ -103,43 +103,43 @@ pTmp = $4
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Copy entire heap (Aux LC $D000.DFFF) to or from main $4000.4FFF
asm copyHeap // params: dir (0=AuxtoMain, 1=MainToAux)
+asmPlasm_bank2 1
lsr ; direction bit to carry flag
lda #$40
bcs +
lda #$EF ; $EF00 is start of heap (right after font engine)
+ sta tmp+1
eor #$AF ; $EF -> $40, $F0 -> $41, etc.
sta pTmp+1
ldy #0
sty tmp
sty pTmp
ldx #$C
- lda (tmp),y
sta (pTmp),y
iny
bne -
inc tmp+1
inc pTmp+1
dex
bne -
rts
// Copy entire heap (main LC $EF00.FAFF) to or from main low mem $5000.5BFF
asm copyHeap // params: dir (0=LCtoMain, 1=MainToLC)
+asmPlasm 1
lsr ; direction bit to carry flag
lda #$50
bcs +
lda #$EF ; $EF00 is start of heap (right after font engine)
+ sta tmp+1
eor #$BF ; $EF -> $50, $F0 -> $51, etc.
sta pTmp+1
ldy #0
sty tmp
sty pTmp
ldx #12 ; Heap is 12 pages
- lda (tmp),y
sta (pTmp),y
iny
bne -
inc tmp+1
inc pTmp+1
dex
bne -
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
asm mliStub
; call MLI directly. Caller is expected to modify the command and param vectors
; before calling.
+asmPlasm 0 ; bytes 0-4
jsr mli ; bytes 5-7
!byte 0 ; byte 8
!word 0 ; bytes 9-10
bcs +
lda #0
+ bit setLcRW+lcBank2 ; Our crazy aux ProDOS stub doesn't preserve the LC bank; put PLASMA back.
rts
; call MLI directly. Caller is expected to modify the command and param vectors
; before calling.
+asmPlasm 0 ; bytes 0-4
jsr mli ; bytes 5-7
!byte 0 ; byte 8
!word 0 ; bytes 9-10
bcs +
lda #0
+ bit setLcRW+lcBank2 ; Our crazy aux ProDOS stub doesn't preserve the LC bank; put PLASMA back.
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -181,11 +181,11 @@ def _saveGame()
// Copy data to main memory
showMapName("Saving game...")
diskActivity($FF)
copyHeap(0) // aux to main
copyHeap(0) // LC to low mem
// Open the file if it already exists...
open_filename = @game1_filename
open_buffer = $5000
open_buffer = $5C00
if callMLI(MLI_OPEN, @open_params) > 0
create_filename = open_filename
create_accessbits = $C3 // full access
@ -200,7 +200,7 @@ def _saveGame()
// Write the game data to it
write_fileref = open_fileref
write_addr = $4000
write_addr = $5000
write_length = HEAP_SIZE
guaranteeMLI(MLI_WRITE, @write_params)
@ -212,17 +212,16 @@ end
def loadInternal()
word p_loaded
mmgr(FINISH_LOAD, WITH_CLOSE)
// Open the file. If that fails, return FALSE (instead of halting)
open_filename = @game1_filename
open_buffer = $5000
open_buffer = $5C00
if callMLI(MLI_OPEN, @open_params) > 0; return FALSE; fin
// Read the game data from it
read_fileref = open_fileref
read_addr = $4000
read_length = $800 // FIXME
read_addr = $5000
read_length = HEAP_SIZE
guaranteeMLI(MLI_READ, @read_params)
// All done with the file
@ -230,8 +229,11 @@ def loadInternal()
guaranteeMLI(MLI_CLOSE, @close_params)
// Copy the heap up, and init it with the correct size.
p_loaded = $4000
copyHeap(1) // main to aux
p_loaded = $5000
if p_loaded=>w_heapSize < 100 or p_loaded=>w_heapSize > HEAP_SIZE
fatal("Corrupt game file.")
fin
copyHeap(1) // low mem to LC
initHeap(p_loaded=>w_heapSize)
global = getGlobals()
return TRUE
@ -239,6 +241,8 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _loadGame()
setMapWindow()
clearWindow()
diskActivity($FF)
showMapName("Loading game...")

View File

@ -65,6 +65,7 @@ word totalMapHeight
byte needRender = FALSE
byte needShowParty = FALSE
byte renderLoaded = FALSE
byte texturesLoaded = FALSE
byte textDrawn = FALSE
byte isPlural = FALSE
@ -1189,8 +1190,9 @@ export def showParty()
displayStr(convertDec(p=>w_health))
displayChar('/')
displayStr(convertDec(p=>w_maxHealth))
displayChar('\n')
p = p=>p_nextObj
// Newline after data, except last character
if p; displayChar('\n'); fin
loop
// Finish up
@ -1259,6 +1261,7 @@ def initMap(x, y, dir)
triggerTbl = NULL
setWindow2()
initDisplay(mapNum, pMap, x, y, dir)
texturesLoaded = TRUE
needRender = FALSE
textDrawn = FALSE
curPortrait = 0
@ -1336,15 +1339,20 @@ def checkScripts(x, y)
return anyTriggered
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def unloadTextures()
if renderLoaded and texturesLoaded
texControl(0)
texturesLoaded = FALSE
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Display a portrait drawing (typically called from scripts)
export def clearPortrait()
if curPortrait
auxMmgr(FREE_MEMORY, curPortrait)
curPortrait = 0
if renderLoaded
texControl(1) // 1=load
fin
needRender = TRUE
fin
end
@ -1353,6 +1361,15 @@ end
// Perform rendering, copy if necessary, clear appropriate flags
def doRender()
if curPortrait; clearPortrait(); fin
if !texturesLoaded
if mapIs3D
flipToPage1()
diskActivity($FF)
texControl(1)
diskActivity(0)
fin
texturesLoaded = TRUE
fin
render()
if textDrawn and mapIs3D; copyWindow(); fin
needRender = FALSE
@ -1732,9 +1749,7 @@ export def setPortrait(portraitNum)
saveCursor()
// Make room by unloading the textures (only if renderer is loaded)
if renderLoaded
texControl(0)
fin
unloadTextures()
// Now clear out the map area
setMapWindow()
@ -2357,13 +2372,16 @@ export def createAndAddUnique(moduleID, creationFuncNum, pList)
word p_module, funcTbl, func, p_thing
// Unload textures to make room for the module
if renderLoaded; texControl(0); fin
unloadTextures()
// Load the module that is capable of creating the thing
flipToPage1()
diskActivity($FF)
mmgr(FINISH_LOAD, WITH_CLOSE)
mmgr(START_LOAD, 1) // code is in partition 1
p_module = mmgr(QUEUE_LOAD, moduleID<<8 | RES_TYPE_MODULE)
mmgr(FINISH_LOAD, LEAVE_OPEN)
diskActivity(0)
// Figure out which creation function to call there, and create the thing
funcTbl = p_module()
@ -2378,8 +2396,6 @@ export def createAndAddUnique(moduleID, creationFuncNum, pList)
// Finished with the module now.
mmgr(FINISH_LOAD, WITH_CLOSE)
mmgr(FREE_MEMORY, p_module)
if renderLoaded; texControl(1); fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////