clear contents of geometry engine ram when it's powered down. fixes #31 (imagine teacher black garbage on screen)

This commit is contained in:
zeromus 2017-03-04 03:34:20 -06:00
parent 51163c33a1
commit 66b5da1cdc
5 changed files with 40 additions and 19 deletions

View File

@ -1802,6 +1802,8 @@ static void writereg_POWCNT1(const int size, const u32 adr, const u32 val) {
writereg_POWCNT1(8,adr+1,(val>>8)&0xFF);
break;
}
//do we need to test this?
//gbatek: "When disabled, corresponding Ports become Read-only, corresponding (palette-) memory becomes read-only-zero-filled."
}
static INLINE void MMU_IPCSync(u8 proc, u32 val)
@ -3224,9 +3226,9 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
if ((adr >= 0x04000008) && (adr <= 0x0400005F)) return;
if (nds.power1.gpuSub == 0)
if ((adr >= 0x04001008) && (adr <= 0x0400105F)) return;
if (nds.power1.gfx3d_geometry == 0)
if (nds.power_geometry == 0)
if ((adr >= 0x04000400) && (adr <= 0x040006FF)) return;
if (nds.power1.gfx3d_render == 0)
if (nds.power_render == 0)
if ((adr >= 0x04000320) && (adr <= 0x040003FF)) return;
if(MMU_new.is_dma(adr)) {
@ -3708,9 +3710,9 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
if ((adr >= 0x04000008) && (adr <= 0x0400005F)) return;
if (nds.power1.gpuSub == 0)
if ((adr >= 0x04001008) && (adr <= 0x0400105F)) return;
if (nds.power1.gfx3d_geometry == 0)
if (nds.power_geometry == 0)
if ((adr >= 0x04000400) && (adr <= 0x040006FF)) return;
if (nds.power1.gfx3d_render == 0)
if (nds.power_render == 0)
if ((adr >= 0x04000320) && (adr <= 0x040003FF)) return;
if(MMU_new.is_dma(adr)) {
@ -4288,16 +4290,18 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
{
if (!validateIORegsWrite<ARMCPU_ARM9>(adr, 32, val)) return;
//this blocks writes to memories when the engines that control them are powered down
//but is there any other way to write to the geometry engine? (via FIFO?)
// TODO: add pal reg
if (nds.power1.gpuMain == 0)
if ((adr >= 0x04000008) && (adr <= 0x0400005F)) return;
if (nds.power1.gpuSub == 0)
if ((adr >= 0x04001008) && (adr <= 0x0400105F)) return;
if (nds.power1.gfx3d_geometry == 0)
if (nds.power_geometry == 0)
if ((adr >= 0x04000400) && (adr <= 0x040006FF)) return;
if (nds.power1.gfx3d_render == 0)
if (nds.power_render == 0)
if ((adr >= 0x04000320) && (adr <= 0x040003FF)) return;
// MightyMax: no need to do several ifs, when only one can happen
// switch/case instead
// both comparison >=,< per if can be replaced by one bit comparison since

View File

@ -2533,7 +2533,8 @@ void NDS_Reset()
nds.sleeping = FALSE;
nds.cardEjected = FALSE;
nds.freezeBus = 0;
nds.power1.lcd = nds.power1.gpuMain = nds.power1.gfx3d_render = nds.power1.gfx3d_geometry = nds.power1.gpuSub = nds.power1.dispswap = 1;
nds.power1.lcd = nds.power1.gpuMain = nds.power1.gfx3d_render = nds.power1.gfx3d_geometry = nds.power1.gpuSub = nds.power1.dispswap = 1; //is this proper?
nds.power_geometry = nds.power_render = TRUE; //whether this is proper follows from prior
nds.power2.speakers = 1;
nds.power2.wifi = 0;
nds.wifiCycle = 0;

View File

@ -238,6 +238,8 @@ struct NDSSystem
u8 speakers, wifi /*(initial value=0)*/;
} power2; //POWCNT2
BOOL power_render, power_geometry;
bool isInVblank() const { return VCount >= 192; }
bool isIn3dVblank() const { return VCount >= 192 && VCount<215; }
};

View File

@ -401,7 +401,6 @@ static void twiddleLists()
vertlist->count = 0;
}
static BOOL flushPending = FALSE;
static BOOL drawPending = FALSE;
//------------------------------------------------------------
@ -549,7 +548,6 @@ void gfx3d_reset()
gxf_hardware.reset();
drawPending = FALSE;
flushPending = FALSE;
memset(polylists, 0, sizeof(POLYLIST)*2);
memset(vertlists, 0, sizeof(VERTLIST)*2);
gfx3d.state.invalidateToon = true;
@ -1781,11 +1779,6 @@ void gfx3d_glClearDepth(u32 v)
gfx3d.state.clearDepth = DS_DEPTH15TO24(v);
}
// Ignored for now
void gfx3d_glSwapScreen(unsigned int screen)
{
}
int gfx3d_GetNumPolys()
{
//so is this in the currently-displayed or currently-built list?
@ -2335,16 +2328,36 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
CurrentRenderer->SetRenderNeedsFinish(false);
GPU->GetEventHandler()->DidRender3DEnd();
}
//try powering on geometry
if(!nds.power_geometry && nds.power1.gfx3d_geometry)
{
nds.power_geometry = TRUE;
}
else if(nds.power_geometry && !nds.power1.gfx3d_geometry)
{
//kill the geometry data when the power goes off
reconstruct(&gfx3d.state);
nds.power_geometry = FALSE;
}
//try powering on rendering. unclear whether there's anything very special about this
if(!nds.power_render && nds.power1.gfx3d_render)
nds.power_render = TRUE;
else if(nds.power_render && !nds.power1.gfx3d_render)
nds.power_render = FALSE;
if (!drawPending) return;
if (skipFrame) return;
drawPending = FALSE;
GPU->GetEventHandler()->DidRender3DBegin();
CurrentRenderer->SetRenderNeedsFinish(true);
if (CommonSettings.showGpu.main)
//the timing of powering on rendering may not be exactly right here.
if (CommonSettings.showGpu.main && nds.power_render)
{
CurrentRenderer->SetTextureProcessingProperties(CommonSettings.GFX3D_Renderer_TextureScalingFactor,
CommonSettings.GFX3D_Renderer_TextureDeposterize,
@ -2514,7 +2527,6 @@ SFORMAT SF_GFX3D[]={
{ "GMAM", 2, 1, &dsAmbient},
{ "GMSP", 2, 1, &dsSpecular},
{ "GMEM", 2, 1, &dsEmission},
{ "GFLP", 4, 1, &flushPending},
{ "GDRP", 4, 1, &drawPending},
{ "GSET", 4, 1, &gfx3d.state.enableTexturing},
{ "GSEA", 4, 1, &gfx3d.state.enableAlphaTest},

View File

@ -213,6 +213,8 @@ SFORMAT SF_NDS[]={
{ "_P05", 1, 1, &nds.power1.dispswap},
{ "_P06", 1, 1, &nds.power2.speakers},
{ "_P07", 1, 1, &nds.power2.wifi},
{ "_P0G", 1, 1, &nds.power_geometry},
{ "_P0R", 1, 1, &nds.power_render},
{ 0 }
};