diff --git a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy index 4bd261aa..0f7e375c 100644 --- a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy +++ b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy @@ -2266,6 +2266,7 @@ class A2PackPartitions assembleCode("expand", "src/raycast/") assembleCode("fontEngine", "src/font/") assembleCode("tileEngine", "src/tile/") + assembleCode("marks", "src/marks/") code.each { k,v -> addResourceDep("map", "", "code", k) } diff --git a/Platform/Apple/virtual/src/core/mem.s b/Platform/Apple/virtual/src/core/mem.s index f06caf7a..a43a5f91 100644 --- a/Platform/Apple/virtual/src/core/mem.s +++ b/Platform/Apple/virtual/src/core/mem.s @@ -398,6 +398,11 @@ brkHandler: pha and #$10 ; check for BRK bit beq + ; if not brk, handle without bank switch + lda $45 + sta clrAuxZP + sta $45 + sta clrAuxRd + sta clrAuxWr bit setROM ; for BRK, do bank switch bit $c051 ; also switch to text screen 1 bit $c054 diff --git a/Platform/Apple/virtual/src/plasma/diskops.pla b/Platform/Apple/virtual/src/plasma/diskops.pla index 35e1ffed..67a48986 100644 --- a/Platform/Apple/virtual/src/plasma/diskops.pla +++ b/Platform/Apple/virtual/src/plasma/diskops.pla @@ -30,12 +30,20 @@ const RWTS_OPENDIR = (1<<8) const LOAD_SAVE_BUF = $4E00 +const fontEngine = $EC00 // main mem LC +const fontEngineLen = $F00 // really a bit less, but this leaves space for debug code +const fontData = $FB00 // main mem LC +const fontDataLen = $4FA // really only $474, but we need to fill all gaps + +const expandVec = $800 // aux mem (only for raycaster) + // Exported functions go here. First a predef for each one, then a table with function pointers // in the same order as the constants are defined in the the header. +predef _startup()#1 predef _saveGame()#1 predef _loadGame()#1 predef _newOrLoadGame(ask)#1 -word[] funcTbl = @_saveGame, @_loadGame, @_newOrLoadGame +word[] funcTbl = @_startup, @_saveGame, @_loadGame, @_newOrLoadGame byte[] game1_filename = "GAME.1.SAVE" byte[] legendos_filename = "LEGENDOS.SYSTEM" @@ -51,6 +59,7 @@ asm __defs !source "../../include/global.i" !source "../../include/plasma.i" !source "../../include/mem.i" +!source "../../include/fontEngine.i" ; Optional debug printing support DEBUG = 0 @@ -79,6 +88,50 @@ cmdseek = 0 ;requires enable_seek=1 cmdread = 1 ;requires enable_write=1 cmdwrite = 2 ;requires enable_write=1 +; Yes, needs to be adjusted 3 places. +expandVec = $800 + +end + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Set up the font engine +asm setFont(pFont)#0 + +asmPlasmNoRet 1 + jmp SetFont +end + +/////////////////////////////////////////////////////////////////////////////////////////////////// +asm splitExpander()#1 // param: expandVec; returns: remaining lo-aux size +!zone { + +asmPlasmRet 0 +.jsr + jsr fixedRTS + tsx + dex + lda $100,x + clc + adc #.splitexp-.jsr-2 + sta pTmp + lda $101,x + adc #0 + sta pTmp+1 + ldy #14 +- lda (pTmp),y + sta $10,y + dey + bpl - + jmp $10 +.splitexp +!pseudopc $10 { + sei ; prevent interrupts while in aux mem + sta setAuxRd + jsr + + sta clrAuxRd + cli + rts ++ jmp (expandVec) +} ; end of pseudopc +} ; end of zone end /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -128,6 +181,80 @@ asm callProRWTS(cmdPlusOpenFlg, filename, addr, size)#1 rts end +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Load and display the title screen, set up everything in memory +def _startup()#1 + word pEngine, pFont, expanderSize + + puts("Loading game.\n") + + auxMmgr(FREE_MEMORY, $800) // was temporarily reserved by gameloop to keep diskops bytecode out + + // Allocate and permanently lock mem for the font engine and its font (up in LC ram) + mmgr(START_LOAD, 1) // partition 1 is where code lives + mmgr(SET_MEM_TARGET, fontEngine) + mmgr(REQUEST_MEMORY, fontEngineLen) + mmgr(LOCK_MEMORY, fontEngine) + + mmgr(SET_MEM_TARGET, fontData) + mmgr(REQUEST_MEMORY, fontDataLen) + mmgr(LOCK_MEMORY, fontData) + + // Load them into lo mem + pEngine = mmgr(QUEUE_LOAD, CODE_FONT_ENGINE<<8 | RES_TYPE_CODE) + pFont = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_FONT) + mmgr(FINISH_LOAD, 0) + + // Relocate font engine and font data to their final spots up in the language card + memcpy(pEngine, fontEngine, fontEngineLen) + memcpy(pFont, fontData, fontDataLen) + + // Load the title screen and show it. + loadFrameImg(1) // title screen is fixed at #1 + ^$C050 // graphics + ^$C057 // hi-res + ^$C054 // page 1 + ^$C052 // full screen + // Hack for real (not emulated) IIc: sometimes displays only lo-bit graphics + // unless we do this. *HUGE* thanks to Brendan Robert for the fix! + ^$C07E=0 // disable double-hi-res + ^$C05F // disable double-hi-res + ^EMUSIG_FULL_COLOR + + // While we're loading, let's get the expander into aux RAM. + auxMmgr(SET_MEM_TARGET, expandVec) + auxMmgr(QUEUE_LOAD, CODE_EXPAND<<8 | RES_TYPE_CODE) + + mmgr(FINISH_LOAD, 0) + + // Tell the font engine where to find its font + setFont(fontData) + + // And free up the font low mem + mmgr(FREE_MEMORY, pEngine) + mmgr(FREE_MEMORY, pFont) + + // Split the expander (relocating most of it to aux LC ram) + expanderSize = splitExpander() + + // Lock in the part of the expander that remains in low aux mem. + auxMmgr(FREE_MEMORY, expandVec) + auxMmgr(SET_MEM_TARGET, expandVec) + auxMmgr(REQUEST_MEMORY, expanderSize) + auxMmgr(LOCK_MEMORY, expandVec) + + // To reduce fragmentation, load the resource index directly after the + // remaining part of the expander + pResourceIndex = expandVec + expanderSize + auxMmgr(SET_MEM_TARGET, pResourceIndex) + auxMmgr(QUEUE_LOAD, CODE_RESOURCE_INDEX<<8 | RES_TYPE_CODE) + auxMmgr(LOCK_MEMORY, pResourceIndex) + mmgr(FINISH_LOAD, 0) + + // All done. + return 0 +end + /////////////////////////////////////////////////////////////////////////////////////////////////// def _rwGame(cmd)#0 while TRUE diff --git a/Platform/Apple/virtual/src/plasma/diskops.plh b/Platform/Apple/virtual/src/plasma/diskops.plh index 194dee88..d2613ab9 100644 --- a/Platform/Apple/virtual/src/plasma/diskops.plh +++ b/Platform/Apple/virtual/src/plasma/diskops.plh @@ -9,6 +9,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// // Each module-exported function needs its own constant, 0..n -const diskops_saveGame = 0 -const diskops_loadGame = 2 -const diskops_newOrLoadGame = 4 +const diskops_startup = 0 +const diskops_saveGame = 2 +const diskops_loadGame = 4 +const diskops_newOrLoadGame = 6 diff --git a/Platform/Apple/virtual/src/plasma/gamelib.plh b/Platform/Apple/virtual/src/plasma/gamelib.plh index 15ba5456..59d9d98c 100644 --- a/Platform/Apple/virtual/src/plasma/gamelib.plh +++ b/Platform/Apple/virtual/src/plasma/gamelib.plh @@ -157,6 +157,7 @@ import gamelib word totalMapHeight word pCurMap byte curMapPartition + word pResourceIndex /////////// Shared string constants ////////////// diff --git a/Platform/Apple/virtual/src/plasma/gameloop.pla b/Platform/Apple/virtual/src/plasma/gameloop.pla index e7b1f5c5..b789ee05 100644 --- a/Platform/Apple/virtual/src/plasma/gameloop.pla +++ b/Platform/Apple/virtual/src/plasma/gameloop.pla @@ -12,11 +12,6 @@ // Fixed memory locations const seed = $4E // Incremented continuously by keyboard read routine const displayEngine = $6000 // main mem (raycaster and tile engine at same location) -const expandVec = $800 // aux mem (only for raycaster) -const fontEngine = $EC00 // main mem LC -const fontEngineLen = $F00 // really a bit less, but this leaves space for debug code -const fontData = $FB00 // main mem LC -const fontDataLen = $4FA // really only $474, but we need to fill all gaps /////////////////////////////////////////////////////////////////////////////////////////////////// // Other constants @@ -76,7 +71,7 @@ predef doRender()#0 predef pause(count)#1 predef printf2(str, arg1, arg2)#0 predef playerDeath()#0 -predef startGame(ask)#0 +predef startGame(firstTime, ask)#0 predef showAnimFrame()#0 predef showParty()#0 @@ -112,7 +107,7 @@ byte heapLocked = FALSE byte allowZoneInit = FALSE word curEngine = NULL word pIntimate = NULL -word pResourceIndex = NULL +export word pResourceIndex = NULL word pGlobalTileset = NULL export byte curMapPartition = 0 export word pGodModule = NULL @@ -214,9 +209,6 @@ ysav1 = $35 seed = $4E magic = $2227 ; there are 2048 magic values that work; this one caught my eye. - MH -; Yes, needs to be adjusted 3 places. -expandVec = $800 - ; NOTE ABOUT ABSOLUTE CODE ADDRESSING (e.g. STA .var, JMP .label, etc.) ; We cannot use it: this code will be preceded by stubs for the PLASMA routines, hence ; absolute addressing must be done carefully, adding ABS_OFFSET below. @@ -504,27 +496,6 @@ asm readAuxByte(ptr)#1 rts end -/////////////////////////////////////////////////////////////////////////////////////////////////// -asm splitExpander()#1 // param: expandVec; returns: remaining lo-aux size - +asmPlasmRet 0 - ldy #14 -- lda .splitexp+ABS_OFFSET,y - sta $10,y - dey - bpl - - jmp $10 -.splitexp -!pseudopc $10 { - sei ; prevent interrupts while in aux mem - sta setAuxRd - jsr + - sta clrAuxRd - cli - rts -+ jmp (expandVec) -} -end - /////////////////////////////////////////////////////////////////////////////////////////////////// // String building for display with the font engine. Includes plurality processing to handily // handle things like "Dirt bag(s)" and "his/their" @@ -916,13 +887,6 @@ export asm brk()#0 brk end -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Set up the font engine -asm setFont(pFont)#0 - +asmPlasmNoRet 1 - jmp SetFont -end - /////////////////////////////////////////////////////////////////////////////////////////////////// // Use the font engine to clear the current text window. // Parameters: top, bottom, left, right @@ -3066,7 +3030,7 @@ end /////////////////////////////////////////////////////////////////////////////////////////////////// def playerDeath()#0 callGlobalFunc(GS_DEATH, 0, 0, 0) - startGame(FALSE) // don't ask, just load + startGame(FALSE, FALSE) // don't ask, just load end /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3250,75 +3214,6 @@ def initCmds()#0 fin end -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Load and display the title screen. -def loadTitle()#0 - word pEngine, pFont, expanderSize - - puts("Loading game.\n") - - // Allocate and permanently lock mem for the font engine and its font (up in LC ram) - mmgr(START_LOAD, 1) // partition 1 is where code lives - mmgr(SET_MEM_TARGET, fontEngine) - mmgr(REQUEST_MEMORY, fontEngineLen) - mmgr(LOCK_MEMORY, fontEngine) - - mmgr(SET_MEM_TARGET, fontData) - mmgr(REQUEST_MEMORY, fontDataLen) - mmgr(LOCK_MEMORY, fontData) - - // Load them into lo mem - pEngine = mmgr(QUEUE_LOAD, CODE_FONT_ENGINE<<8 | RES_TYPE_CODE) - pFont = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_FONT) - mmgr(FINISH_LOAD, 0) - - // Relocate font engine and font data to their final spots up in the language card - memcpy(pEngine, fontEngine, fontEngineLen) - memcpy(pFont, fontData, fontDataLen) - - // Load the title screen and show it. - loadFrameImg(1) // title screen is fixed at #1 - ^$C050 // graphics - ^$C057 // hi-res - ^$C054 // page 1 - ^$C052 // full screen - // Hack for real (not emulated) IIc: sometimes displays only lo-bit graphics - // unless we do this. *HUGE* thanks to Brendan Robert for the fix! - ^$C07E=0 // disable double-hi-res - ^$C05F // disable double-hi-res - ^EMUSIG_FULL_COLOR - - // While we're loading, let's get the expander into aux RAM. - auxMmgr(SET_MEM_TARGET, expandVec) - auxMmgr(QUEUE_LOAD, CODE_EXPAND<<8 | RES_TYPE_CODE) - - mmgr(FINISH_LOAD, 0) - - // Tell the font engine where to find its font - setFont(fontData) - - // And free up the font low mem - mmgr(FREE_MEMORY, pEngine) - mmgr(FREE_MEMORY, pFont) - - // Split the expander (relocating most of it to aux LC ram) - expanderSize = splitExpander() - - // Lock in the part of the expander that remains in low aux mem. - auxMmgr(FREE_MEMORY, expandVec) - auxMmgr(SET_MEM_TARGET, expandVec) - auxMmgr(REQUEST_MEMORY, expanderSize) - auxMmgr(LOCK_MEMORY, expandVec) - - // To reduce fragmentation, load the resource index directly after the - // remaining part of the expander - pResourceIndex = expandVec + expanderSize - auxMmgr(SET_MEM_TARGET, pResourceIndex) - auxMmgr(QUEUE_LOAD, CODE_RESOURCE_INDEX<<8 | RES_TYPE_CODE) - auxMmgr(LOCK_MEMORY, pResourceIndex) - mmgr(FINISH_LOAD, 0) -end - /////////////////////////////////////////////////////////////////////////////////////////////////// // Set up the small-object heap. Set loadedSize to zero on initial, or non-zero for loaded game. export def initHeap(loadedSize)#0 @@ -3710,15 +3605,20 @@ export def buySell(storeCode, profitRatio)#0 end /////////////////////////////////////////////////////////////////////////////////////////////////// -def startGame(ask)#0 +def startGame(firstTime, ask)#0 word p_module typeHash = hashBuffer(@typeTbl_TGlobal, @typeTbls - @typeTbl_TGlobal) ^ HEAP_BOTTOM // Create a new game or load an existing one mmgr(START_LOAD, 1) // code is in partition 1 + if firstTime + auxMmgr(SET_MEM_TARGET, $800) // well above where expander loads at startup + auxMmgr(REQUEST_MEMORY, $6000) // plenty of room for expander + fin p_module = mmgr(QUEUE_LOAD, MOD_DISKOPS<<8 | RES_TYPE_MODULE) mmgr(FINISH_LOAD, 0) + if firstTime; p_module()=>diskops_startup(); fin if p_module()=>diskops_newOrLoadGame(ask) mapIs3D = q_mapIs3D mapNum = q_mapNum @@ -3738,8 +3638,7 @@ end // Main code. // scriptDisplayStr(@_scriptDisplayStr) // 1-time init -loadTitle() -startGame(TRUE) // ask whether new or load +startGame(TRUE, TRUE) // first time init; ask whether new or load kbdLoop() done diff --git a/Platform/Apple/virtual/src/raycast/render.s b/Platform/Apple/virtual/src/raycast/render.s index 8e35a4e7..e7398bfe 100644 --- a/Platform/Apple/virtual/src/raycast/render.s +++ b/Platform/Apple/virtual/src/raycast/render.s @@ -2285,48 +2285,29 @@ pl_initMap: !zone ; Save automap bits saveAutomap: !zone + lda mapBase + sec ; skip sentinel at start of row + adc mapWidth ; plus skip row of sentinels + pha + lda mapBase+1 + adc #0 + pha + lda mapNum - ora #$80 + ora #$80 ; map number: hi bit to mark 3D maps + pha + ldx mapWidth ldy mapHeight + dey ; height: adjust for two sentinel rows + dey + txa + dex ; width: adjust for two sentinel columns + dex + sta setAuxZP -; jsr getAutomapBuf ; TODO + ;jsr saveMarks sta clrAuxZP - sta pDst - sty pDst+1 - lda mapBase - sta pMap - lda mapBase+1 - sta pMap+1 - lda #$80 - sta tmp - lda mapHeight - sta lineCt - ldy #0 ; Y stays zero for the entire process below -.row ldx mapWidth -.col lda (pMap),y - asl - asl ; shift $40 bit (automap) into carry - ror tmp ; save the bit - bcc + - lda tmp - sta (pDst),y - lda #$80 ; restore sentinel - sta tmp - inc pDst - bne + - inc pDst+1 -+ inc pMap - bne + - inc pMap+1 -+ dex - bne .col - dec lineCt - bne .row - lda tmp -- lsr ; low-align last set of bits - bcc - - sta (pDst),y rts ; Following are log/pow lookup tables. For speed, align them on a page boundary.