From d6dd17eca22b66beb1abbf0483da324d75cc50ad Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 12 Apr 2026 09:23:19 +0200 Subject: [PATCH] make simplebuffer's display register set order the same as in scrollbuffer, fix display glitches on AGA configs --- src/ace/managers/copper.c | 29 +++++++------ src/ace/managers/viewport/simplebuffer.c | 55 ++++++++++++------------ 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/ace/managers/copper.c b/src/ace/managers/copper.c index df1a938a..7d846f9a 100644 --- a/src/ace/managers/copper.c +++ b/src/ace/managers/copper.c @@ -197,7 +197,7 @@ tCopList *copListCreate(void *pTagList, ...) { pCopList->pBackBfr = memAllocFastClear(sizeof(tCopBfr)); // Handle raw copperlist creation - pCopList->ubMode = tagGet(pTagList, vaTags, TAG_COPPER_LIST_MODE, COPPER_MODE_BLOCK); + pCopList->ubMode = tagGet(pTagList, vaTags, TAG_COPPER_LIST_MODE, COPPER_MODE_BLOCK); if(pCopList->ubMode == COPPER_MODE_RAW) { const ULONG ulInvalidSize = ULONG_MAX; ULONG ulListSize = tagGet( @@ -214,17 +214,21 @@ tCopList *copListCreate(void *pTagList, ...) { ); goto fail; } - logWrite("RAW mode, size: %lu + WAIT(0xFFFF)\n", ulListSize); + logWrite("RAW mode, size: %lu + 2x WAIT(0xFFFF)\n", ulListSize); + // Front bfr - pCopList->pFrontBfr->uwCmdCount = ulListSize+1; - pCopList->pFrontBfr->uwAllocSize = (ulListSize+1)*sizeof(tCopCmd); + pCopList->pFrontBfr->uwCmdCount = ulListSize + 2; + pCopList->pFrontBfr->uwAllocSize = (ulListSize + 2) * sizeof(tCopCmd); pCopList->pFrontBfr->pList = memAllocChipClear(pCopList->pFrontBfr->uwAllocSize); copSetWait(&pCopList->pFrontBfr->pList[ulListSize].sWait, 0xFF, 0xFF); + copSetWait(&pCopList->pFrontBfr->pList[ulListSize + 1].sWait, 0xFF, 0xFF); + // Back bfr - pCopList->pBackBfr->uwCmdCount = ulListSize+1; - pCopList->pBackBfr->uwAllocSize = (ulListSize+1)*sizeof(tCopCmd); + pCopList->pBackBfr->uwCmdCount = ulListSize + 2; + pCopList->pBackBfr->uwAllocSize = (ulListSize + 2) * sizeof(tCopCmd); pCopList->pBackBfr->pList = memAllocChipClear(pCopList->pBackBfr->uwAllocSize); copSetWait(&pCopList->pBackBfr->pList[ulListSize].sWait, 0xFF, 0xFF); + copSetWait(&pCopList->pBackBfr->pList[ulListSize + 1].sWait, 0xFF, 0xFF); } else { logWrite("BLOCK mode\n"); @@ -364,12 +368,11 @@ UBYTE copBfrRealloc(void) { // Calculate new list size if(pCopList->ubStatus & STATUS_REALLOC_CURR) { - pBackBfr->uwAllocSize = 0; for(pBlock = pCopList->pFirstBlock; pBlock; pBlock = pBlock->pNext) { pBackBfr->uwAllocSize += 1 + pBlock->uwMaxCmds; // WAIT + MOVEs } - pBackBfr->uwAllocSize += 2; // final WAIT + room for double WAIT + pBackBfr->uwAllocSize += 2; // room for trailing double WAIT pBackBfr->uwAllocSize *= sizeof(tCopCmd); // Pass realloc to next buffer ubNewStatus = STATUS_REALLOC_PREV; @@ -491,7 +494,7 @@ UBYTE copUpdateFromBlocks(void) { // Update WAIT if(pBlock->uWaitPos.uwY >= 0xFF) { - // FIXME: double WAIT only when previous line ended before some pos + // TODO: do the double WAIT only when previous line ended before some pos? if(!ubWasLimitY) { copSetWait((tCopWaitCmd*)&pBackBfr->pList[uwListPos], 0xDF, 0xFF); ++uwListPos; @@ -520,9 +523,11 @@ UBYTE copUpdateFromBlocks(void) { uwListPos += pBlock->uwCurrCount; } - // Add 0xFFFF terminator - copSetWait((tCopWaitCmd*)&pBackBfr->pList[uwListPos], 0xFF, 0xFF); - ++uwListPos; + // Add 0xFFFF terminators + copSetWait((tCopWaitCmd*)&pBackBfr->pList[uwListPos++], 0xFF, 0xFF); + if(!ubWasLimitY) { + copSetWait((tCopWaitCmd*)&pBackBfr->pList[uwListPos++], 0xFF, 0xFF); + } pCopList->pBackBfr->uwCmdCount = uwListPos; diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index d5d0ed73..dd17ea4e 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -88,41 +88,43 @@ static void simpleBufferInitializeCopperList( "Setting copperlist %p at offs %u\n", pCopList->pBackBfr, pManager->uwCopperOffset ); - copSetWait(&pCmdList[0].sWait, s_pCopperWaitXByBitplanes[pManager->sCommon.pVPort->ubBpp], ( + + UBYTE ubCmdCount = 0; + copSetWait(&pCmdList[ubCmdCount++].sWait, s_pCopperWaitXByBitplanes[pManager->sCommon.pVPort->ubBpp], ( pManager->sCommon.pVPort->uwOffsY + pManager->sCommon.pVPort->pView->ubPosY -1 )); - copSetMove(&pCmdList[1].sMove, &g_pCustom->ddfstop, uwDDfStop); // Data fetch - copSetMove(&pCmdList[2].sMove, &g_pCustom->ddfstrt, uwDDfStrt); - copSetMove(&pCmdList[3].sMove, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo - copSetMove(&pCmdList[4].sMove, &g_pCustom->bpl2mod, uwModulo); - copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, 0); // Shift: 0 - - // Copy to front buffer since it needs initialization there too - for(UWORD i = pManager->uwCopperOffset; i < pManager->uwCopperOffset + 6; ++i) { - pCopList->pFrontBfr->pList[i].ulCode = pCopList->pBackBfr->pList[i].ulCode; - } + copSetMove(&pCmdList[ubCmdCount++].sMove, &g_pCustom->bplcon1, 0); // Shift: 0 // Proper back buffer pointers - setBitplanePtrs(&pCmdList[6], pManager->pFront, ulBplOffs); + setBitplanePtrs(&pCmdList[ubCmdCount], pManager->pFront, ulBplOffs); + ubCmdCount += pManager->pFront->Depth * 2; + + copSetMove(&pCmdList[ubCmdCount++].sMove, &g_pCustom->ddfstrt, uwDDfStrt); + copSetMove(&pCmdList[ubCmdCount++].sMove, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo + copSetMove(&pCmdList[ubCmdCount++].sMove, &g_pCustom->bpl2mod, uwModulo); + copSetMove(&pCmdList[ubCmdCount++].sMove, &g_pCustom->ddfstop, uwDDfStop); // Data fetch - // Proper front buffer pointers - pCmdList = &pCopList->pFrontBfr->pList[pManager->uwCopperOffset]; - setBitplanePtrs(&pCmdList[6], pManager->pBack, ulBplOffs); + // Copy to front buffer since it needs initialization there too + while(ubCmdCount--) { + pCopList->pFrontBfr->pList[pManager->uwCopperOffset + ubCmdCount].ulCode = pCopList->pBackBfr->pList[pManager->uwCopperOffset + ubCmdCount].ulCode; + } } else { tCopBlock *pBlock = pManager->pCopBlock; pBlock->uwCurrCount = 0; // Rewind to beginning - copMove(pCopList, pBlock, &g_pCustom->ddfstop, uwDDfStop); // Data fetch - copMove(pCopList, pBlock, &g_pCustom->ddfstrt, uwDDfStrt); - copMove(pCopList, pBlock, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo - copMove(pCopList, pBlock, &g_pCustom->bpl2mod, uwModulo); copMove(pCopList, pBlock, &g_pCustom->bplcon1, 0); // Shift: 0 + for (UBYTE i = 0; i < pManager->sCommon.pVPort->ubBpp; ++i) { ULONG ulPlaneAddr = (ULONG)pManager->pBack->Planes[i] + ulBplOffs; copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } + + copMove(pCopList, pBlock, &g_pCustom->ddfstrt, uwDDfStrt); + copMove(pCopList, pBlock, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo + copMove(pCopList, pBlock, &g_pCustom->bpl2mod, uwModulo); + copMove(pCopList, pBlock, &g_pCustom->ddfstop, uwDDfStop); // Data fetch } } @@ -326,8 +328,8 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { ULONG ulBplOffs; UWORD uwShift = simpleBufferCalcBplOffsAndShift(pManager, &ulBplOffs); tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; - copSetMoveVal(&pCmdList[5].sMove, uwShift); - updateBitplanePtrs(&pCmdList[6], pManager->pBack, ulBplOffs); + copSetMoveVal(&pCmdList[1].sMove, uwShift); // 0th cmd is WAIT + updateBitplanePtrs(&pCmdList[2], pManager->pBack, ulBplOffs); --pManager->ubDirtyCounter; } } @@ -337,13 +339,10 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { // copperlist needs refreshing. ULONG ulBplOffs; UWORD uwShift = simpleBufferCalcBplOffsAndShift(pManager, &ulBplOffs); - pManager->pCopBlock->uwCurrCount = 4; // Rewind to shift cmd pos - copMove(pCopList, pManager->pCopBlock, &g_pCustom->bplcon1, uwShift); - for(UBYTE i = 0; i < pManager->pBack->Depth; ++i) { - ULONG ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; - copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); - copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); - } + copSetMoveVal(&pManager->pCopBlock->pCmds[0].sMove, uwShift); // WAIT isn't part of pCmds + updateBitplanePtrs(&pManager->pCopBlock->pCmds[1], pManager->pBack, ulBplOffs); + pManager->pCopBlock->ubUpdated = 2; + pCopList->ubStatus |= STATUS_UPDATE; } // Swap buffers if needed