aboutsummaryrefslogtreecommitdiff
path: root/src/NDS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/NDS.cpp')
-rw-r--r--src/NDS.cpp142
1 files changed, 91 insertions, 51 deletions
diff --git a/src/NDS.cpp b/src/NDS.cpp
index d8f346e..18a6f46 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -25,6 +25,7 @@
#include "DMA.h"
#include "FIFO.h"
#include "GPU.h"
+#include "SPU.h"
#include "SPI.h"
#include "RTC.h"
#include "Wifi.h"
@@ -37,11 +38,6 @@ namespace NDS
// * stick all the variables in a big structure?
// would make it easier to deal with savestates
-/*SchedEvent SchedBuffer[SCHED_BUF_LEN];
-SchedEvent* SchedQueue;
-
-bool NeedReschedule;*/
-
ARM* ARM9;
ARM* ARM7;
@@ -87,6 +83,7 @@ u16 PowerControl7;
u16 ARM7BIOSProt;
Timer Timers[8];
+u8 TimerCheckMask[2];
DMA* DMAs[8];
u32 DMA9Fill[4];
@@ -108,8 +105,6 @@ u32 SqrtRes;
u32 KeyInput;
-u16 _soundbias; // temp
-
bool Running;
@@ -132,6 +127,7 @@ bool Init()
if (!NDSCart::Init()) return false;
if (!GPU::Init()) return false;
+ if (!SPU::Init()) return false;
if (!SPI::Init()) return false;
if (!RTC::Init()) return false;
@@ -151,6 +147,7 @@ void DeInit()
NDSCart::DeInit();
GPU::DeInit();
+ SPU::DeInit();
SPI::DeInit();
RTC::DeInit();
}
@@ -221,9 +218,14 @@ void SetupDirectBoot()
ARM9->JumpTo(bootparams[1]);
ARM7->JumpTo(bootparams[5]);
+ PostFlag9 = 0x01;
+ PostFlag7 = 0x01;
+
PowerControl9 = 0x820F;
GPU::DisplaySwap(PowerControl9);
+ SPU::SetBias(0x200);
+
ARM7BIOSProt = 0x1204;
SPI_Firmware::SetupDirectBoot();
@@ -296,18 +298,12 @@ void Reset()
CPUStop = 0;
memset(Timers, 0, 8*sizeof(Timer));
+ TimerCheckMask[0] = 0;
+ TimerCheckMask[1] = 0;
for (i = 0; i < 8; i++) DMAs[i]->Reset();
memset(DMA9Fill, 0, 4*4);
- NDSCart::Reset();
- GPU::Reset();
- SPI::Reset();
- RTC::Reset();
- Wifi::Reset();
-
- // memset(SchedBuffer, 0, sizeof(SchedEvent)*SCHED_BUF_LEN);
- // SchedQueue = NULL;
memset(SchedList, 0, sizeof(SchedList));
SchedListMask = 0;
@@ -319,7 +315,12 @@ void Reset()
KeyInput = 0x007F03FF;
- _soundbias = 0;
+ NDSCart::Reset();
+ GPU::Reset();
+ SPU::Reset();
+ SPI::Reset();
+ RTC::Reset();
+ Wifi::Reset();
}
void LoadROM(const char* path, bool direct)
@@ -563,8 +564,16 @@ bool HaltInterrupted(u32 cpu)
void StopCPU(u32 cpu, u32 mask)
{
- if (cpu) mask <<= 16;
- CPUStop |= mask;
+ if (cpu)
+ {
+ CPUStop |= (mask << 16);
+ ARM7->Halt(2);
+ }
+ else
+ {
+ CPUStop |= mask;
+ ARM9->Halt(2);
+ }
}
void ResumeCPU(u32 cpu, u32 mask)
@@ -611,8 +620,8 @@ void HandleTimerOverflow(u32 tid)
void RunTimer(u32 tid, s32 cycles)
{
Timer* timer = &Timers[tid];
- if ((timer->Cnt & 0x84) != 0x80)
- return;
+ //if ((timer->Cnt & 0x84) != 0x80)
+ // return;
u32 oldcount = timer->Counter;
timer->Counter += (cycles << timer->CycleShift);
@@ -622,10 +631,12 @@ void RunTimer(u32 tid, s32 cycles)
void RunTimingCriticalDevices(u32 cpu, s32 cycles)
{
- RunTimer((cpu<<2)+0, cycles);
- RunTimer((cpu<<2)+1, cycles);
- RunTimer((cpu<<2)+2, cycles);
- RunTimer((cpu<<2)+3, cycles);
+ register u32 timermask = TimerCheckMask[cpu];
+
+ if (timermask & 0x1) RunTimer((cpu<<2)+0, cycles);
+ if (timermask & 0x2) RunTimer((cpu<<2)+1, cycles);
+ if (timermask & 0x4) RunTimer((cpu<<2)+2, cycles);
+ if (timermask & 0x8) RunTimer((cpu<<2)+3, cycles);
if (cpu == 0)
{
@@ -678,6 +689,11 @@ void TimerStart(u32 id, u16 cnt)
{
timer->Counter = timer->Reload << 16;
}
+
+ if ((cnt & 0x84) == 0x80)
+ TimerCheckMask[id>>2] |= (1<<(id&0x3));
+ else
+ TimerCheckMask[id>>2] &= ~(1<<(id&0x3));
}
@@ -808,8 +824,19 @@ void debug(u32 param)
printf("ARM9 PC=%08X LR=%08X %08X\n", ARM9->R[15], ARM9->R[14], ARM9->R_IRQ[1]);
printf("ARM7 PC=%08X LR=%08X %08X\n", ARM7->R[15], ARM7->R[14], ARM7->R_IRQ[1]);
- for (int i = 0; i < 9; i++)
- printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]);
+ printf("ARM9 IME=%08X IE=%08X IF=%08X\n", IME[0], IE[0], IF[0]);
+ printf("ARM7 IME=%08X IE=%08X IF=%08X\n", IME[1], IE[1], IF[1]);
+
+ //for (int i = 0; i < 9; i++)
+ // printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]);
+
+ /*FILE* shit = fopen("debug/poke7.bin", "wb");
+ for (u32 i = 0x02000000; i < 0x03810000; i+=4)
+ {
+ u32 val = ARM7Read32(i);
+ fwrite(&val, 4, 1, shit);
+ }
+ fclose(shit);*/
}
@@ -904,7 +931,7 @@ u16 ARM9Read16(u32 addr)
return 0xFFFF;
}
- //printf("unknown arm9 read16 %08X %08X %08X %08X\n", addr, ARM9->R[15], ARM9->R[1], ARM9->R[2]);
+ //printf("unknown arm9 read16 %08X %08X\n", addr, ARM9->R[15]);
return 0;
}
@@ -1202,7 +1229,7 @@ void ARM7Write8(u32 addr, u8 val)
return;
}
- printf("unknown arm7 write8 %08X %02X | %08X | %08X %08X %08X %08X\n", addr, val, ARM7->R[15], IME[1], IE[1], ARM7->R[0], ARM7->R[1]);
+ printf("unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7->R[15]);
}
void ARM7Write16(u32 addr, u16 val)
@@ -1237,7 +1264,7 @@ void ARM7Write16(u32 addr, u16 val)
return;
}
- printf("unknown arm7 write16 %08X %04X | %08X\n", addr, val, ARM7->R[15]);
+ printf("unknown arm7 write16 %08X %04X @ %08X\n", addr, val, ARM7->R[15]);
}
void ARM7Write32(u32 addr, u32 val)
@@ -1268,7 +1295,7 @@ void ARM7Write32(u32 addr, u32 val)
return;
}
- printf("unknown arm7 write32 %08X %08X | %08X %08X\n", addr, val, ARM7->R[15], ARM7->CurInstr);
+ printf("unknown arm7 write32 %08X %08X @ %08X\n", addr, val, ARM7->R[15]);
}
@@ -1278,6 +1305,9 @@ u8 ARM9IORead8(u32 addr)
{
switch (addr)
{
+ case 0x04000130: return KeyInput & 0xFF;
+ case 0x04000131: return (KeyInput >> 8) & 0xFF;
+
case 0x040001A2: return NDSCart::ReadSPIData();
case 0x040001A8: return NDSCart::ROMCommand[0];
@@ -1402,11 +1432,11 @@ u16 ARM9IORead16(u32 addr)
case 0x04000304: return PowerControl9;
}
- if (addr >= 0x04000000 && addr < 0x04000060)
+ if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
{
return GPU::GPU2D_A->Read16(addr);
}
- if (addr >= 0x04001000 && addr < 0x04001060)
+ if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
{
return GPU::GPU2D_B->Read16(addr);
}
@@ -1471,6 +1501,7 @@ u32 ARM9IORead32(u32 addr)
case 0x04000244: return GPU::VRAMCNT[4] | (GPU::VRAMCNT[5] << 8) | (GPU::VRAMCNT[6] << 16) | (WRAMCnt << 24);
case 0x04000248: return GPU::VRAMCNT[7] | (GPU::VRAMCNT[8] << 8);
+ case 0x04000280: return DivCnt;
case 0x04000290: return DivNumerator[0];
case 0x04000294: return DivNumerator[1];
case 0x04000298: return DivDenominator[0];
@@ -1480,6 +1511,7 @@ u32 ARM9IORead32(u32 addr)
case 0x040002A8: return DivRemainder[0];
case 0x040002AC: return DivRemainder[1];
+ case 0x040002B0: return SqrtCnt;
case 0x040002B4: return SqrtRes;
case 0x040002B8: return SqrtVal[0];
case 0x040002BC: return SqrtVal[1];
@@ -1510,11 +1542,11 @@ u32 ARM9IORead32(u32 addr)
return 0;
}
- if (addr >= 0x04000000 && addr < 0x04000060)
+ if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
{
return GPU::GPU2D_A->Read32(addr);
}
- if (addr >= 0x04001000 && addr < 0x04001060)
+ if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
{
return GPU::GPU2D_B->Read32(addr);
}
@@ -1611,6 +1643,15 @@ void ARM9IOWrite16(u32 addr, u16 val)
case 0x040000DC: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0xFFFF0000) | val); return;
case 0x040000DE: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0x0000FFFF) | (val << 16)); return;
+ case 0x040000E0: DMA9Fill[0] = (DMA9Fill[0] & 0xFFFF0000) | val; return;
+ case 0x040000E2: DMA9Fill[0] = (DMA9Fill[0] & 0x0000FFFF) | (val << 16); return;
+ case 0x040000E4: DMA9Fill[1] = (DMA9Fill[1] & 0xFFFF0000) | val; return;
+ case 0x040000E6: DMA9Fill[1] = (DMA9Fill[1] & 0x0000FFFF) | (val << 16); return;
+ case 0x040000E8: DMA9Fill[2] = (DMA9Fill[2] & 0xFFFF0000) | val; return;
+ case 0x040000EA: DMA9Fill[2] = (DMA9Fill[2] & 0x0000FFFF) | (val << 16); return;
+ case 0x040000EC: DMA9Fill[3] = (DMA9Fill[3] & 0xFFFF0000) | val; return;
+ case 0x040000EE: DMA9Fill[3] = (DMA9Fill[3] & 0x0000FFFF) | (val << 16); return;
+
case 0x04000100: Timers[0].Reload = val; return;
case 0x04000102: TimerStart(0, val); return;
case 0x04000104: Timers[1].Reload = val; return;
@@ -1629,7 +1670,6 @@ void ARM9IOWrite16(u32 addr, u16 val)
{
SetIRQ(1, IRQ_IPCSync);
}
- //CompensateARM7();
return;
case 0x04000184:
@@ -1838,6 +1878,10 @@ void ARM9IOWrite32(u32 addr, u32 val)
GPU::MapVRAM_I(8, (val >> 8) & 0xFF);
return;
+ case 0x04000280: DivCnt = val; StartDiv(); return;
+
+ case 0x040002B0: SqrtCnt = val; StartSqrt(); return;
+
case 0x04000290: DivNumerator[0] = val; StartDiv(); return;
case 0x04000294: DivNumerator[1] = val; StartDiv(); return;
case 0x04000298: DivDenominator[0] = val; StartDiv(); return;
@@ -1876,6 +1920,11 @@ u8 ARM7IORead8(u32 addr)
{
switch (addr)
{
+ case 0x04000130: return KeyInput & 0xFF;
+ case 0x04000131: return (KeyInput >> 8) & 0xFF;
+ case 0x04000136: return (KeyInput >> 16) & 0xFF;
+ case 0x04000137: return KeyInput >> 24;
+
case 0x04000138: return RTC::Read() & 0xFF;
case 0x040001A2: return NDSCart::ReadSPIData();
@@ -1901,8 +1950,7 @@ u8 ARM7IORead8(u32 addr)
if (addr >= 0x04000400 && addr < 0x04000520)
{
- // sound I/O
- return 0;
+ return SPU::Read8(addr);
}
printf("unknown ARM7 IO read8 %08X\n", addr);
@@ -1972,14 +2020,11 @@ u16 ARM7IORead16(u32 addr)
case 0x04000300: return PostFlag7;
case 0x04000304: return PowerControl7;
case 0x04000308: return ARM7BIOSProt;
-
- case 0x04000504: return _soundbias;
}
if (addr >= 0x04000400 && addr < 0x04000520)
{
- // sound I/O
- return 0;
+ return SPU::Read16(addr);
}
printf("unknown ARM7 IO read16 %08X %08X\n", addr, ARM9->R[15]);
@@ -2057,8 +2102,7 @@ u32 ARM7IORead32(u32 addr)
if (addr >= 0x04000400 && addr < 0x04000520)
{
- // sound I/O
- return 0;
+ return SPU::Read32(addr);
}
printf("unknown ARM7 IO read32 %08X\n", addr);
@@ -2116,7 +2160,7 @@ void ARM7IOWrite8(u32 addr, u8 val)
if (addr >= 0x04000400 && addr < 0x04000520)
{
- // sound I/O
+ SPU::Write8(addr, val);
return;
}
@@ -2147,7 +2191,7 @@ void ARM7IOWrite16(u32 addr, u16 val)
case 0x0400010C: Timers[7].Reload = val; return;
case 0x0400010E: TimerStart(7, val); return;
- case 0x04000134: return;printf("set debug port %04X %08X\n", val, ARM7Read32(ARM7->R[13]+4)); return;
+ case 0x04000134: /* TODO? */ return;
case 0x04000138: RTC::Write(val, false); return;
@@ -2228,15 +2272,11 @@ void ARM7IOWrite16(u32 addr, u16 val)
if (ARM7BIOSProt == 0)
ARM7BIOSProt = val;
return;
-
- case 0x04000504: // removeme
- _soundbias = val & 0x3FF;
- return;
}
if (addr >= 0x04000400 && addr < 0x04000520)
{
- // sound I/O
+ SPU::Write16(addr, val);
return;
}
@@ -2326,7 +2366,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
if (addr >= 0x04000400 && addr < 0x04000520)
{
- // sound I/O
+ SPU::Write32(addr, val);
return;
}