separate GPU2D registers and renderer

This commit is contained in:
RSDuck 2021-02-27 22:25:27 +01:00
parent f8692f85a4
commit a046eb5038
7 changed files with 421 additions and 387 deletions

View File

@ -82,8 +82,10 @@ int FrontBuffer;
u32* Framebuffer[2][2];
int Renderer = 0;
std::unique_ptr<GPU2D> GPU2D_A = {};
std::unique_ptr<GPU2D> GPU2D_B = {};
GPU2D::Unit GPU2D_A(0);
GPU2D::Unit GPU2D_B(1);
std::unique_ptr<GPU2D::Renderer2D> GPU2D_Renderer = {};
/*
VRAM invalidation tracking
@ -143,8 +145,7 @@ std::unique_ptr<GLCompositor> CurGLCompositor = {};
bool Init()
{
GPU2D_A = std::make_unique<GPU2D_Soft>(0);
GPU2D_B = std::make_unique<GPU2D_Soft>(1);
GPU2D_Renderer = std::make_unique<GPU2D::SoftRenderer>();
if (!GPU3D::Init()) return false;
FrontBuffer = 0;
@ -157,8 +158,7 @@ bool Init()
void DeInit()
{
GPU2D_A.reset();
GPU2D_B.reset();
GPU2D_Renderer.reset();
GPU3D::DeInit();
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
@ -262,13 +262,12 @@ void Reset()
Framebuffer[1][1][i] = 0xFFFFFFFF;
}
GPU2D_A->Reset();
GPU2D_B->Reset();
GPU2D_A.Reset();
GPU2D_B.Reset();
GPU3D::Reset();
int backbuf = FrontBuffer ? 0 : 1;
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
GPU2D_Renderer->SetFramebuffer(Framebuffer[backbuf][1], Framebuffer[backbuf][0]);
ResetRenderer();
@ -358,8 +357,8 @@ void DoSavestate(Savestate* file)
VRAMPtr_BOBJ[i] = GetUniqueBankPtr(VRAMMap_BOBJ[i], i << 14);
}
GPU2D_A->DoSavestate(file);
GPU2D_B->DoSavestate(file);
GPU2D_A.DoSavestate(file);
GPU2D_B.DoSavestate(file);
GPU3D::DoSavestate(file);
ResetVRAMCache();
@ -370,13 +369,11 @@ void AssignFramebuffers()
int backbuf = FrontBuffer ? 0 : 1;
if (NDS::PowerControl9 & (1<<15))
{
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]);
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]);
GPU2D_Renderer->SetFramebuffer(Framebuffer[backbuf][0], Framebuffer[backbuf][1]);
}
else
{
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
GPU2D_Renderer->SetFramebuffer(Framebuffer[backbuf][1], Framebuffer[backbuf][0]);
}
}
@ -973,8 +970,8 @@ void SetPowerCnt(u32 val)
if (!(val & (1<<0))) printf("!!! CLEARING POWCNT BIT0. DANGER\n");
GPU2D_A->SetEnabled(val & (1<<1));
GPU2D_B->SetEnabled(val & (1<<9));
GPU2D_A.SetEnabled(val & (1<<1));
GPU2D_B.SetEnabled(val & (1<<9));
GPU3D::SetEnabled(val & (1<<3), val & (1<<2));
AssignFramebuffers();
@ -989,9 +986,9 @@ void DisplayFIFO(u32 x)
if (x > 0)
{
if (x == 8)
GPU2D_A->SampleFIFO(0, 5);
GPU2D_A.SampleFIFO(0, 5);
else
GPU2D_A->SampleFIFO(x-11, 8);
GPU2D_A.SampleFIFO(x-11, 8);
}
if (x < 256)
@ -1001,7 +998,7 @@ void DisplayFIFO(u32 x)
NDS::ScheduleEvent(NDS::Event_DisplayFIFO, true, 6*8, DisplayFIFO, x+8);
}
else
GPU2D_A->SampleFIFO(253, 3); // sample the remaining pixels
GPU2D_A.SampleFIFO(253, 3); // sample the remaining pixels
}
void StartFrame()
@ -1009,7 +1006,7 @@ void StartFrame()
// only run the display FIFO if needed:
// * if it is used for display or capture
// * if we have display FIFO DMA
RunFIFO = GPU2D_A->UsesFIFO() || NDS::DMAsInMode(0, 0x04);
RunFIFO = GPU2D_A.UsesFIFO() || NDS::DMAsInMode(0, 0x04);
TotalScanlines = 0;
StartScanline(0);
@ -1026,15 +1023,15 @@ void StartHBlank(u32 line)
// note: this should start 48 cycles after the scanline start
if (line < 192)
{
GPU2D_A->DrawScanline(line);
GPU2D_B->DrawScanline(line);
GPU2D_Renderer->DrawScanline(line, &GPU2D_A);
GPU2D_Renderer->DrawScanline(line, &GPU2D_B);
}
// sprites are pre-rendered one scanline in advance
if (line < 191)
{
GPU2D_A->DrawSprites(line+1);
GPU2D_B->DrawSprites(line+1);
GPU2D_Renderer->DrawSprites(line+1, &GPU2D_A);
GPU2D_Renderer->DrawSprites(line+1, &GPU2D_B);
}
NDS::CheckDMAs(0, 0x02);
@ -1045,8 +1042,8 @@ void StartHBlank(u32 line)
}
else if (VCount == 262)
{
GPU2D_A->DrawSprites(0);
GPU2D_B->DrawSprites(0);
GPU2D_Renderer->DrawSprites(0, &GPU2D_A);
GPU2D_Renderer->DrawSprites(0, &GPU2D_B);
}
if (DispStat[0] & (1<<4)) NDS::SetIRQ(0, NDS::IRQ_HBlank);
@ -1098,8 +1095,8 @@ void StartScanline(u32 line)
else
DispStat[1] &= ~(1<<2);
GPU2D_A->CheckWindows(VCount);
GPU2D_B->CheckWindows(VCount);
GPU2D_A.CheckWindows(VCount);
GPU2D_B.CheckWindows(VCount);
if (VCount >= 2 && VCount < 194)
NDS::CheckDMAs(0, 0x03);
@ -1110,8 +1107,8 @@ void StartScanline(u32 line)
{
if (line == 0)
{
GPU2D_A->VBlankEnd();
GPU2D_B->VBlankEnd();
GPU2D_A.VBlankEnd();
GPU2D_B.VBlankEnd();
}
if (RunFIFO)
@ -1149,8 +1146,9 @@ void StartScanline(u32 line)
if (DispStat[0] & (1<<3)) NDS::SetIRQ(0, NDS::IRQ_VBlank);
if (DispStat[1] & (1<<3)) NDS::SetIRQ(1, NDS::IRQ_VBlank);
GPU2D_A->VBlank();
GPU2D_B->VBlank();
GPU2D_Renderer->VBlankEnd(&GPU2D_A, &GPU2D_B);
GPU2D_A.VBlank();
GPU2D_B.VBlank();
GPU3D::VBlank();
#ifdef OGLRENDERER_ENABLED

View File

@ -75,8 +75,8 @@ extern u8* VRAMPtr_BOBJ[0x8];
extern int FrontBuffer;
extern u32* Framebuffer[2][2];
extern std::unique_ptr<GPU2D> GPU2D_A;
extern std::unique_ptr<GPU2D> GPU2D_B;
extern GPU2D::Unit GPU2D_A;
extern GPU2D::Unit GPU2D_B;
extern int Renderer;

View File

@ -80,13 +80,15 @@
// for example these aren't affected by POWCNT GPU-disable bits.
// to model the hardware more accurately, the relevant logic should be moved to GPU.cpp.
namespace GPU2D
{
GPU2D::GPU2D(u32 num)
Unit::Unit(u32 num)
{
Num = num;
}
void GPU2D::Reset()
void Unit::Reset()
{
Enabled = false;
DispCnt = 0;
@ -134,11 +136,9 @@ void GPU2D::Reset()
CaptureLatch = false;
MasterBrightness = 0;
MosaicXSizeChanged();
}
void GPU2D::DoSavestate(Savestate* file)
void Unit::DoSavestate(Savestate* file)
{
file->Section((char*)(Num ? "GP2B" : "GP2A"));
@ -187,16 +187,9 @@ void GPU2D::DoSavestate(Savestate* file)
file->Var32(&Win0Active);
file->Var32(&Win1Active);
MosaicXSizeChanged();
}
void GPU2D::SetFramebuffer(u32* buf)
{
Framebuffer = buf;
}
u8 GPU2D::Read8(u32 addr)
u8 Unit::Read8(u32 addr)
{
switch (addr & 0x00000FFF)
{
@ -229,7 +222,7 @@ u8 GPU2D::Read8(u32 addr)
return 0;
}
u16 GPU2D::Read16(u32 addr)
u16 Unit::Read16(u32 addr)
{
switch (addr & 0x00000FFF)
{
@ -258,7 +251,7 @@ u16 GPU2D::Read16(u32 addr)
return 0;
}
u32 GPU2D::Read32(u32 addr)
u32 Unit::Read32(u32 addr)
{
switch (addr & 0x00000FFF)
{
@ -270,7 +263,7 @@ u32 GPU2D::Read32(u32 addr)
return Read16(addr) | (Read16(addr+2) << 16);
}
void GPU2D::Write8(u32 addr, u8 val)
void Unit::Write8(u32 addr, u8 val)
{
switch (addr & 0x00000FFF)
{
@ -347,12 +340,10 @@ void GPU2D::Write8(u32 addr, u8 val)
case 0x04C:
BGMosaicSize[0] = val & 0xF;
BGMosaicSize[1] = val >> 4;
MosaicXSizeChanged();
return;
case 0x04D:
OBJMosaicSize[0] = val & 0xF;
OBJMosaicSize[1] = val >> 4;
MosaicXSizeChanged();
return;
case 0x050: BlendCnt = (BlendCnt & 0x3F00) | val; return;
@ -376,7 +367,7 @@ void GPU2D::Write8(u32 addr, u8 val)
printf("unknown GPU write8 %08X %02X\n", addr, val);
}
void GPU2D::Write16(u32 addr, u16 val)
void Unit::Write16(u32 addr, u16 val)
{
switch (addr & 0x00000FFF)
{
@ -501,7 +492,6 @@ void GPU2D::Write16(u32 addr, u16 val)
BGMosaicSize[1] = (val >> 4) & 0xF;
OBJMosaicSize[0] = (val >> 8) & 0xF;
OBJMosaicSize[1] = val >> 12;
MosaicXSizeChanged();
return;
case 0x050: BlendCnt = val & 0x3FFF; return;
@ -521,7 +511,7 @@ void GPU2D::Write16(u32 addr, u16 val)
//printf("unknown GPU write16 %08X %04X\n", addr, val);
}
void GPU2D::Write32(u32 addr, u32 val)
void Unit::Write32(u32 addr, u32 val)
{
switch (addr & 0x00000FFF)
{
@ -575,7 +565,7 @@ void GPU2D::Write32(u32 addr, u32 val)
Write16(addr+2, val>>16);
}
void GPU2D::UpdateMosaicCounters(u32 line)
void Unit::UpdateMosaicCounters(u32 line)
{
// Y mosaic uses incrementing 4-bit counters
// the transformed Y position is updated every time the counter matches the MOSAIC register
@ -592,7 +582,7 @@ void GPU2D::UpdateMosaicCounters(u32 line)
}
}
void GPU2D::VBlank()
void Unit::VBlank()
{
if (CaptureLatch)
{
@ -604,7 +594,7 @@ void GPU2D::VBlank()
DispFIFOWritePtr = 0;
}
void GPU2D::VBlankEnd()
void Unit::VBlankEnd()
{
// TODO: find out the exact time this happens
BGXRefInternal[0] = BGXRef[0];
@ -620,7 +610,7 @@ void GPU2D::VBlankEnd()
//OBJMosaicYCount = 0;
}
void GPU2D::SampleFIFO(u32 offset, u32 num)
void Unit::SampleFIFO(u32 offset, u32 num)
{
for (u32 i = 0; i < num; i++)
{
@ -632,7 +622,7 @@ void GPU2D::SampleFIFO(u32 offset, u32 num)
}
}
u16* GPU2D::GetBGExtPal(u32 slot, u32 pal)
u16* Unit::GetBGExtPal(u32 slot, u32 pal)
{
const u32 PaletteSize = 256 * 2;
const u32 SlotSize = PaletteSize * 16;
@ -641,14 +631,14 @@ u16* GPU2D::GetBGExtPal(u32 slot, u32 pal)
: GPU::VRAMFlat_BBGExtPal)[slot * SlotSize + pal * PaletteSize];
}
u16* GPU2D::GetOBJExtPal()
u16* Unit::GetOBJExtPal()
{
return Num == 0
? (u16*)GPU::VRAMFlat_AOBJExtPal
: (u16*)GPU::VRAMFlat_BOBJExtPal;
}
void GPU2D::CheckWindows(u32 line)
void Unit::CheckWindows(u32 line)
{
line &= 0xFF;
if (line == Win0Coords[3]) Win0Active &= ~0x1;
@ -657,18 +647,18 @@ void GPU2D::CheckWindows(u32 line)
else if (line == Win1Coords[2]) Win1Active |= 0x1;
}
void GPU2D::CalculateWindowMask(u32 line)
void Unit::CalculateWindowMask(u32 line, u8* windowMask, u8* objWindow)
{
for (u32 i = 0; i < 256; i++)
WindowMask[i] = WinCnt[2]; // window outside
windowMask[i] = WinCnt[2]; // window outside
if (DispCnt & (1<<15))
{
// OBJ window
for (int i = 0; i < 256; i++)
{
if (OBJWindow[i])
WindowMask[i] = WinCnt[3];
if (objWindow[i])
windowMask[i] = WinCnt[3];
}
}
@ -683,7 +673,7 @@ void GPU2D::CalculateWindowMask(u32 line)
if (i == x2) Win1Active &= ~0x2;
else if (i == x1) Win1Active |= 0x2;
if (Win1Active == 0x3) WindowMask[i] = WinCnt[1];
if (Win1Active == 0x3) windowMask[i] = WinCnt[1];
}
}
@ -698,12 +688,12 @@ void GPU2D::CalculateWindowMask(u32 line)
if (i == x2) Win0Active &= ~0x2;
else if (i == x1) Win0Active |= 0x2;
if (Win0Active == 0x3) WindowMask[i] = WinCnt[0];
if (Win0Active == 0x3) windowMask[i] = WinCnt[0];
}
}
}
void GPU2D::GetBGVRAM(u8*& data, u32& mask)
void Unit::GetBGVRAM(u8*& data, u32& mask)
{
if (Num == 0)
{
@ -717,7 +707,7 @@ void GPU2D::GetBGVRAM(u8*& data, u32& mask)
}
}
void GPU2D::GetOBJVRAM(u8*& data, u32& mask)
void Unit::GetOBJVRAM(u8*& data, u32& mask)
{
if (Num == 0)
{
@ -730,3 +720,5 @@ void GPU2D::GetOBJVRAM(u8*& data, u32& mask)
mask = 0x1FFFF;
}
}
}

View File

@ -22,21 +22,22 @@
#include "types.h"
#include "Savestate.h"
class GPU2D
namespace GPU2D
{
class Unit
{
public:
GPU2D(u32 num);
virtual ~GPU2D() {}
Unit(u32 num);
GPU2D(const GPU2D&) = delete;
GPU2D& operator=(const GPU2D&) = delete;
Unit(const Unit&) = delete;
Unit& operator=(const Unit&) = delete;
void Reset();
void DoSavestate(Savestate* file);
void SetEnabled(bool enable) { Enabled = enable; }
void SetFramebuffer(u32* buf);
u8 Read8(u32 addr);
u16 Read16(u32 addr);
@ -57,8 +58,6 @@ public:
void SampleFIFO(u32 offset, u32 num);
virtual void DrawScanline(u32 line) = 0;
virtual void DrawSprites(u32 line) = 0;
void VBlank();
virtual void VBlankEnd();
@ -70,10 +69,11 @@ public:
void GetBGVRAM(u8*& data, u32& mask);
void GetOBJVRAM(u8*& data, u32& mask);
protected:
void UpdateMosaicCounters(u32 line);
void CalculateWindowMask(u32 line, u8* windowMask, u8* objWindow);
u32 Num;
bool Enabled;
u32* Framebuffer;
u16 DispFIFO[16];
u32 DispFIFOReadPtr;
@ -116,14 +116,29 @@ protected:
u32 CaptureCnt;
u16 MasterBrightness;
alignas(8) u8 WindowMask[256];
alignas(8) u8 OBJWindow[256];
void UpdateMosaicCounters(u32 line);
void CalculateWindowMask(u32 line);
virtual void MosaicXSizeChanged() = 0;
};
class Renderer2D
{
public:
virtual ~Renderer2D() {}
virtual void DrawScanline(u32 line, Unit* unit) = 0;
virtual void DrawSprites(u32 line, Unit* unit) = 0;
virtual void VBlankEnd(Unit* unitA, Unit* unitB) = 0;
void SetFramebuffer(u32* unitA, u32* unitB)
{
Framebuffer[0] = unitA;
Framebuffer[1] = unitB;
}
protected:
u32* Framebuffer[2];
Unit* CurUnit;
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -20,32 +20,32 @@
#include "GPU2D.h"
class GPU2D_Soft : public GPU2D
namespace GPU2D
{
class SoftRenderer : public Renderer2D
{
public:
GPU2D_Soft(u32 num);
~GPU2D_Soft() override {}
void DrawScanline(u32 line) override;
void DrawSprites(u32 line) override;
void VBlankEnd() override;
protected:
void MosaicXSizeChanged() override;
SoftRenderer();
~SoftRenderer() override {}
void DrawScanline(u32 line, Unit* unit) override;
void DrawSprites(u32 line, Unit* unit) override;
void VBlankEnd(Unit* unitA, Unit* unitB) override;
private:
alignas(8) u32 BGOBJLine[256*3];
u32* _3DLine;
alignas(8) u32 OBJLine[256];
alignas(8) u8 OBJIndex[256];
alignas(8) u8 WindowMask[256];
u32 NumSprites;
alignas(8) u32 OBJLine[2][256];
alignas(8) u8 OBJIndex[2][256];
alignas(8) u8 OBJWindow[2][256];
u32 NumSprites[2];
u8 MosaicTable[16][256];
u8* CurBGXMosaicTable;
u8* CurOBJXMosaicTable;
u8 MosaicTable[16][256];
u32 ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb);
u32 ColorBlend5(u32 val1, u32 val2);
@ -76,4 +76,6 @@ private:
template<bool window> void DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos);
void DoCapture(u32 line, u32 width);
};
};
}

View File

@ -2882,11 +2882,11 @@ u8 ARM9IORead8(u32 addr)
if (addr >= 0x04000000 && addr < 0x04000060)
{
return GPU::GPU2D_A->Read8(addr);
return GPU::GPU2D_A.Read8(addr);
}
if (addr >= 0x04001000 && addr < 0x04001060)
{
return GPU::GPU2D_B->Read8(addr);
return GPU::GPU2D_B.Read8(addr);
}
if (addr >= 0x04000320 && addr < 0x040006A4)
{
@ -2906,7 +2906,7 @@ u16 ARM9IORead16(u32 addr)
case 0x04000060: return GPU3D::Read16(addr);
case 0x04000064:
case 0x04000066: return GPU::GPU2D_A->Read16(addr);
case 0x04000066: return GPU::GPU2D_A.Read16(addr);
case 0x040000B8: return DMAs[0]->Cnt & 0xFFFF;
case 0x040000BA: return DMAs[0]->Cnt >> 16;
@ -3004,11 +3004,11 @@ u16 ARM9IORead16(u32 addr)
if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
{
return GPU::GPU2D_A->Read16(addr);
return GPU::GPU2D_A.Read16(addr);
}
if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
{
return GPU::GPU2D_B->Read16(addr);
return GPU::GPU2D_B.Read16(addr);
}
if (addr >= 0x04000320 && addr < 0x040006A4)
{
@ -3026,7 +3026,7 @@ u32 ARM9IORead32(u32 addr)
case 0x04000004: return GPU::DispStat[0] | (GPU::VCount << 16);
case 0x04000060: return GPU3D::Read32(addr);
case 0x04000064: return GPU::GPU2D_A->Read32(addr);
case 0x04000064: return GPU::GPU2D_A.Read32(addr);
case 0x040000B0: return DMAs[0]->SrcAddr;
case 0x040000B4: return DMAs[0]->DstAddr;
@ -3124,11 +3124,11 @@ u32 ARM9IORead32(u32 addr)
if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
{
return GPU::GPU2D_A->Read32(addr);
return GPU::GPU2D_A.Read32(addr);
}
if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
{
return GPU::GPU2D_B->Read32(addr);
return GPU::GPU2D_B.Read32(addr);
}
if (addr >= 0x04000320 && addr < 0x040006A4)
{
@ -3144,9 +3144,9 @@ void ARM9IOWrite8(u32 addr, u8 val)
switch (addr)
{
case 0x0400006C:
case 0x0400006D: GPU::GPU2D_A->Write8(addr, val); return;
case 0x0400006D: GPU::GPU2D_A.Write8(addr, val); return;
case 0x0400106C:
case 0x0400106D: GPU::GPU2D_B->Write8(addr, val); return;
case 0x0400106D: GPU::GPU2D_B.Write8(addr, val); return;
case 0x04000132:
KeyCnt = (KeyCnt & 0xFF00) | val;
@ -3205,12 +3205,12 @@ void ARM9IOWrite8(u32 addr, u8 val)
if (addr >= 0x04000000 && addr < 0x04000060)
{
GPU::GPU2D_A->Write8(addr, val);
GPU::GPU2D_A.Write8(addr, val);
return;
}
if (addr >= 0x04001000 && addr < 0x04001060)
{
GPU::GPU2D_B->Write8(addr, val);
GPU::GPU2D_B.Write8(addr, val);
return;
}
if (addr >= 0x04000320 && addr < 0x040006A4)
@ -3232,10 +3232,10 @@ void ARM9IOWrite16(u32 addr, u16 val)
case 0x04000060: GPU3D::Write16(addr, val); return;
case 0x04000068:
case 0x0400006A: GPU::GPU2D_A->Write16(addr, val); return;
case 0x0400006A: GPU::GPU2D_A.Write16(addr, val); return;
case 0x0400006C: GPU::GPU2D_A->Write16(addr, val); return;
case 0x0400106C: GPU::GPU2D_B->Write16(addr, val); return;
case 0x0400006C: GPU::GPU2D_A.Write16(addr, val); return;
case 0x0400106C: GPU::GPU2D_B.Write16(addr, val); return;
case 0x040000B8: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0xFFFF0000) | val); return;
case 0x040000BA: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0x0000FFFF) | (val << 16)); return;
@ -3371,12 +3371,12 @@ void ARM9IOWrite16(u32 addr, u16 val)
if (addr >= 0x04000000 && addr < 0x04000060)
{
GPU::GPU2D_A->Write16(addr, val);
GPU::GPU2D_A.Write16(addr, val);
return;
}
if (addr >= 0x04001000 && addr < 0x04001060)
{
GPU::GPU2D_B->Write16(addr, val);
GPU::GPU2D_B.Write16(addr, val);
return;
}
if (addr >= 0x04000320 && addr < 0x040006A4)
@ -3399,10 +3399,10 @@ void ARM9IOWrite32(u32 addr, u32 val)
case 0x04000060: GPU3D::Write32(addr, val); return;
case 0x04000064:
case 0x04000068: GPU::GPU2D_A->Write32(addr, val); return;
case 0x04000068: GPU::GPU2D_A.Write32(addr, val); return;
case 0x0400006C: GPU::GPU2D_A->Write16(addr, val&0xFFFF); return;
case 0x0400106C: GPU::GPU2D_B->Write16(addr, val&0xFFFF); return;
case 0x0400006C: GPU::GPU2D_A.Write16(addr, val&0xFFFF); return;
case 0x0400106C: GPU::GPU2D_B.Write16(addr, val&0xFFFF); return;
case 0x040000B0: DMAs[0]->SrcAddr = val; return;
case 0x040000B4: DMAs[0]->DstAddr = val; return;
@ -3534,12 +3534,12 @@ void ARM9IOWrite32(u32 addr, u32 val)
if (addr >= 0x04000000 && addr < 0x04000060)
{
GPU::GPU2D_A->Write32(addr, val);
GPU::GPU2D_A.Write32(addr, val);
return;
}
if (addr >= 0x04001000 && addr < 0x04001060)
{
GPU::GPU2D_B->Write32(addr, val);
GPU::GPU2D_B.Write32(addr, val);
return;
}
if (addr >= 0x04000320 && addr < 0x040006A4)