diff options
| author | Jesse Talavera-Greenberg <jesse@jesse.tg> | 2023-11-28 17:16:41 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-28 23:16:41 +0100 | 
| commit | e973236203292637eb7bd009a4cfbd6fd785181f (patch) | |
| tree | 4c348a9927bfa6f8f37cc943291174a1096434b3 | |
| parent | c84cb174628c5a2e8e6cc0179e16de3eab47864a (diff) | |
Refactor `NDS` and `DSi` to be objects (#1893)
* First crack at refactoring NDS and DSi into objects
- Remove all global/`static` variables in `NDS` and related classes
- Rely more on virtual dispatch when we need to pick methods at runtime
- Pass `NDS&` or `DSi&` to its constituent components where necessary
- Introduce some headers or move some definitions to break `#include` cycles
* Refactor the frontend to accommodate the core's changes
* Move up `SchedList`'s declaration
- Move it to before the components are initialized so the `map`s inside are initialized
- Fields in C++ are initialized in the order they're declared
* Fix a crash when allocating memory
* Fix JIT-free builds
* Fix GDB-free builds
* Fix Linux builds
- Explicitly qualify some member types in NDS, since they share the same name as their classes
* Remove an unnecessary template argument
- This was causing the build to fail on macOS
* Fix ARM and Android builds
* Rename `Constants.h` to `MemConstants.h`
* Add `NDS::IsRunning()`
* Use an `#include` guard instead of `#pragma once`
73 files changed, 3587 insertions, 3226 deletions
diff --git a/src/AREngine.cpp b/src/AREngine.cpp index 1d992b8..4e13a39 100644 --- a/src/AREngine.cpp +++ b/src/AREngine.cpp @@ -29,40 +29,11 @@ namespace melonDS  using Platform::Log;  using Platform::LogLevel; - -AREngine::AREngine() +AREngine::AREngine(melonDS::NDS& nds) : NDS(nds)  {      CodeFile = nullptr;  } -AREngine::~AREngine() -{ -} - -void AREngine::Reset() -{ -    if (NDS::ConsoleType == 1) -    { -        BusRead8 = DSi::ARM7Read8; -        BusRead16 = DSi::ARM7Read16; -        BusRead32 = DSi::ARM7Read32; -        BusWrite8 = DSi::ARM7Write8; -        BusWrite16 = DSi::ARM7Write16; -        BusWrite32 = DSi::ARM7Write32; -    } -    else -    { -        BusRead8 = NDS::ARM7Read8; -        BusRead16 = NDS::ARM7Read16; -        BusRead32 = NDS::ARM7Read32; -        BusWrite8 = NDS::ARM7Write8; -        BusWrite16 = NDS::ARM7Write16; -        BusWrite32 = NDS::ARM7Write32; -    } -} - - -  #define case16(x) \      case ((x)+0x00): case ((x)+0x01): case ((x)+0x02): case ((x)+0x03): \      case ((x)+0x04): case ((x)+0x05): case ((x)+0x06): case ((x)+0x07): \ @@ -113,15 +84,15 @@ void AREngine::RunCheat(ARCode& arcode)          switch (op)          {          case16(0x00): // 32-bit write -            BusWrite32((a & 0x0FFFFFFF) + offset, b); +            NDS.ARM7Write32((a & 0x0FFFFFFF) + offset, b);              break;          case16(0x10): // 16-bit write -            BusWrite16((a & 0x0FFFFFFF) + offset, b & 0xFFFF); +            NDS.ARM7Write16((a & 0x0FFFFFFF) + offset, b & 0xFFFF);              break;          case16(0x20): // 8-bit write -            BusWrite8((a & 0x0FFFFFFF) + offset, b & 0xFF); +            NDS.ARM7Write8((a & 0x0FFFFFFF) + offset, b & 0xFF);              break;          case16(0x30): // IF b > u32[a] @@ -131,7 +102,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u32 chk = BusRead32(addr); +                u32 chk = NDS.ARM7Read32(addr);                  cond = (b > chk) ? 1:0;              } @@ -144,7 +115,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u32 chk = BusRead32(addr); +                u32 chk = NDS.ARM7Read32(addr);                  cond = (b < chk) ? 1:0;              } @@ -157,7 +128,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u32 chk = BusRead32(addr); +                u32 chk = NDS.ARM7Read32(addr);                  cond = (b == chk) ? 1:0;              } @@ -170,7 +141,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u32 chk = BusRead32(addr); +                u32 chk = NDS.ARM7Read32(addr);                  cond = (b != chk) ? 1:0;              } @@ -183,7 +154,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u16 val = BusRead16(addr); +                u16 val = NDS.ARM7Read16(addr);                  u16 chk = ~(b >> 16);                  chk &= val; @@ -198,7 +169,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u16 val = BusRead16(addr); +                u16 val = NDS.ARM7Read16(addr);                  u16 chk = ~(b >> 16);                  chk &= val; @@ -213,7 +184,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u16 val = BusRead16(addr); +                u16 val = NDS.ARM7Read16(addr);                  u16 chk = ~(b >> 16);                  chk &= val; @@ -228,7 +199,7 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 addr = a & 0x0FFFFFFF;                  if (!addr) addr = offset; -                u16 val = BusRead16(addr); +                u16 val = NDS.ARM7Read16(addr);                  u16 chk = ~(b >> 16);                  chk &= val; @@ -237,7 +208,7 @@ void AREngine::RunCheat(ARCode& arcode)              break;          case16(0xB0): // offset = u32[a + offset] -            offset = BusRead32((a & 0x0FFFFFFF) + offset); +            offset = NDS.ARM7Read32((a & 0x0FFFFFFF) + offset);              break;          case 0xC0: // FOR 0..b @@ -274,7 +245,7 @@ void AREngine::RunCheat(ARCode& arcode)              break;          case 0xC6: // u32[b] = offset -            BusWrite32(b, offset); +            NDS.ARM7Write32(b, offset);              break;          case 0xD0: // ENDIF @@ -323,30 +294,30 @@ void AREngine::RunCheat(ARCode& arcode)              break;          case 0xD6: // u32[b+offset] = datareg / offset += 4 -            BusWrite32(b + offset, datareg); +            NDS.ARM7Write32(b + offset, datareg);              offset += 4;              break;          case 0xD7: // u16[b+offset] = datareg / offset += 2 -            BusWrite16(b + offset, datareg & 0xFFFF); +            NDS.ARM7Write16(b + offset, datareg & 0xFFFF);              offset += 2;              break;          case 0xD8: // u8[b+offset] = datareg / offset += 1 -            BusWrite8(b + offset, datareg & 0xFF); +            NDS.ARM7Write8(b + offset, datareg & 0xFF);              offset += 1;              break;          case 0xD9: // datareg = u32[b+offset] -            datareg = BusRead32(b + offset); +            datareg = NDS.ARM7Read32(b + offset);              break;          case 0xDA: // datareg = u16[b+offset] -            datareg = BusRead16(b + offset); +            datareg = NDS.ARM7Read16(b + offset);              break;          case 0xDB: // datareg = u8[b+offset] -            datareg = BusRead8(b + offset); +            datareg = NDS.ARM7Read8(b + offset);              break;          case 0xDC: // offset += b @@ -361,8 +332,8 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 bytesleft = b;                  while (bytesleft >= 8)                  { -                    BusWrite32(dstaddr, *code++); dstaddr += 4; -                    BusWrite32(dstaddr, *code++); dstaddr += 4; +                    NDS.ARM7Write32(dstaddr, *code++); dstaddr += 4; +                    NDS.ARM7Write32(dstaddr, *code++); dstaddr += 4;                      bytesleft -= 8;                  }                  if (bytesleft > 0) @@ -371,13 +342,13 @@ void AREngine::RunCheat(ARCode& arcode)                      code += 2;                      if (bytesleft >= 4)                      { -                        BusWrite32(dstaddr, *(u32*)leftover); dstaddr += 4; +                        NDS.ARM7Write32(dstaddr, *(u32*)leftover); dstaddr += 4;                          leftover += 4;                          bytesleft -= 4;                      }                      while (bytesleft > 0)                      { -                        BusWrite8(dstaddr, *leftover++); dstaddr++; +                        NDS.ARM7Write8(dstaddr, *leftover++); dstaddr++;                          bytesleft--;                      }                  } @@ -393,14 +364,14 @@ void AREngine::RunCheat(ARCode& arcode)                  u32 bytesleft = b;                  while (bytesleft >= 4)                  { -                    BusWrite32(dstaddr, BusRead32(srcaddr)); +                    NDS.ARM7Write32(dstaddr, NDS.ARM7Read32(srcaddr));                      srcaddr += 4;                      dstaddr += 4;                      bytesleft -= 4;                  }                  while (bytesleft > 0)                  { -                    BusWrite8(dstaddr, BusRead8(srcaddr)); +                    NDS.ARM7Write8(dstaddr, NDS.ARM7Read8(srcaddr));                      srcaddr++;                      dstaddr++;                      bytesleft--; diff --git a/src/AREngine.h b/src/AREngine.h index a6926ab..1f2ee18 100644 --- a/src/AREngine.h +++ b/src/AREngine.h @@ -23,12 +23,11 @@  namespace melonDS  { +class NDS;  class AREngine  {  public: -    AREngine(); -    ~AREngine(); -    void Reset(); +    AREngine(melonDS::NDS& nds);      ARCodeFile* GetCodeFile() { return CodeFile; }      void SetCodeFile(ARCodeFile* file) { CodeFile = file; } @@ -36,15 +35,8 @@ public:      void RunCheats();      void RunCheat(ARCode& arcode);  private: +    melonDS::NDS& NDS;      ARCodeFile* CodeFile; // AR code file - frontend is responsible for managing this - -    // TEMPORARY -    u8 (*BusRead8)(u32 addr); -    u16 (*BusRead16)(u32 addr); -    u32 (*BusRead32)(u32 addr); -    void (*BusWrite8)(u32 addr, u8 val); -    void (*BusWrite16)(u32 addr, u16 val); -    void (*BusWrite32)(u32 addr, u32 val);  };  } diff --git a/src/ARM.cpp b/src/ARM.cpp index a1485e9..659d303 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -106,13 +106,12 @@ const u32 ARM::ConditionTable[16] =      0x0000  // NE  }; -ARM::ARM(u32 num, ARMJIT& jit, melonDS::GPU& gpu) : +ARM::ARM(u32 num, melonDS::NDS& nds) :  #ifdef GDBSTUB_ENABLED      GdbStub(this, Platform::GetConfigInt(num ? Platform::GdbPortARM7 : Platform::GdbPortARM9)),  #endif -    JIT(jit),      Num(num), // well uh -    GPU(gpu) +    NDS(nds)  {  #ifdef GDBSTUB_ENABLED      if (Platform::GetConfigBool(Platform::GdbEnabled) @@ -130,14 +129,14 @@ ARM::~ARM()      // dorp  } -ARMv5::ARMv5(ARMJIT& jit, melonDS::GPU& gpu) : ARM(0, jit, gpu) +ARMv5::ARMv5(melonDS::NDS& nds) : ARM(0, nds)  { -    DTCM = JIT.Memory.GetARM9DTCM(); +    DTCM = NDS.JIT.Memory.GetARM9DTCM();      PU_Map = PU_PrivMap;  } -ARMv4::ARMv4(ARMJIT& jit, melonDS::GPU& gpu) : ARM(1, jit, gpu) +ARMv4::ARMv4(melonDS::NDS& nds) : ARM(1, nds)  {      //  } @@ -198,56 +197,11 @@ void ARM::Reset()  void ARMv5::Reset()  { -    if (NDS::ConsoleType == 1) -    { -        BusRead8 = DSi::ARM9Read8; -        BusRead16 = DSi::ARM9Read16; -        BusRead32 = DSi::ARM9Read32; -        BusWrite8 = DSi::ARM9Write8; -        BusWrite16 = DSi::ARM9Write16; -        BusWrite32 = DSi::ARM9Write32; -        GetMemRegion = DSi::ARM9GetMemRegion; -    } -    else -    { -        BusRead8 = NDS::ARM9Read8; -        BusRead16 = NDS::ARM9Read16; -        BusRead32 = NDS::ARM9Read32; -        BusWrite8 = NDS::ARM9Write8; -        BusWrite16 = NDS::ARM9Write16; -        BusWrite32 = NDS::ARM9Write32; -        GetMemRegion = NDS::ARM9GetMemRegion; -    } -      PU_Map = PU_PrivMap;      ARM::Reset();  } -void ARMv4::Reset() -{ -    if (NDS::ConsoleType) -    { -        BusRead8 = DSi::ARM7Read8; -        BusRead16 = DSi::ARM7Read16; -        BusRead32 = DSi::ARM7Read32; -        BusWrite8 = DSi::ARM7Write8; -        BusWrite16 = DSi::ARM7Write16; -        BusWrite32 = DSi::ARM7Write32; -    } -    else -    { -        BusRead8 = NDS::ARM7Read8; -        BusRead16 = NDS::ARM7Read16; -        BusRead32 = NDS::ARM7Read32; -        BusWrite8 = NDS::ARM7Write8; -        BusWrite16 = NDS::ARM7Write16; -        BusWrite32 = NDS::ARM7Write32; -    } - -    ARM::Reset(); -} -  void ARM::DoSavestate(Savestate* file)  { @@ -270,7 +224,7 @@ void ARM::DoSavestate(Savestate* file)      file->VarArray(R_UND, 3*sizeof(u32));      file->Var32(&CurInstr);  #ifdef JIT_ENABLED -    if (file->Saving && NDS::EnableJIT) +    if (file->Saving && NDS.EnableJIT)      {          // hack, the JIT doesn't really pipeline          // but we still want JIT save states to be @@ -396,7 +350,7 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)          return;      } -    NDS::MonitorARM9Jump(addr); +    NDS.MonitorARM9Jump(addr);  }  void ARMv4::JumpTo(u32 addr, bool restorecpsr) @@ -424,7 +378,7 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)          NextInstr[0] = CodeRead16(addr);          NextInstr[1] = CodeRead16(addr+2); -        Cycles += NDS::ARM7MemTimings[CodeCycles][0] + NDS::ARM7MemTimings[CodeCycles][1]; +        Cycles += NDS.ARM7MemTimings[CodeCycles][0] + NDS.ARM7MemTimings[CodeCycles][1];          CPSR |= 0x20;      } @@ -437,7 +391,7 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)          NextInstr[0] = CodeRead32(addr);          NextInstr[1] = CodeRead32(addr+4); -        Cycles += NDS::ARM7MemTimings[CodeCycles][2] + NDS::ARM7MemTimings[CodeCycles][3]; +        Cycles += NDS.ARM7MemTimings[CodeCycles][2] + NDS.ARM7MemTimings[CodeCycles][3];          CPSR &= ~0x20;      } @@ -582,8 +536,8 @@ void ARM::TriggerIRQ()      // normally, those work by hijacking the ARM7 VBlank handler      if (Num == 1)      { -        if ((NDS::IF[1] & NDS::IE[1]) & (1<<NDS::IRQ_VBlank)) -            NDS::AREngine->RunCheats(); +        if ((NDS.IF[1] & NDS.IE[1]) & (1<<IRQ_VBlank)) +            NDS.AREngine.RunCheats();      }  } @@ -601,7 +555,7 @@ void ARMv5::PrefetchAbort()      if (!(PU_Map[ExceptionBase>>12] & 0x04))      {          Log(LogLevel::Error, "!!!!! EXCEPTION REGION NOT EXECUTABLE. THIS IS VERY BAD!!\n"); -        NDS::Stop(Platform::StopReason::BadExceptionRegion); +        NDS.Stop(Platform::StopReason::BadExceptionRegion);          return;      } @@ -639,20 +593,20 @@ void ARMv5::Execute()          {              Halted = 0;          } -        else if (NDS::HaltInterrupted(0)) +        else if (NDS.HaltInterrupted(0))          {              Halted = 0; -            if (NDS::IME[0] & 0x1) +            if (NDS.IME[0] & 0x1)                  TriggerIRQ();          }          else          { -            NDS::ARM9Timestamp = NDS::ARM9Target; +            NDS.ARM9Timestamp = NDS.ARM9Target;              return;          }      } -    while (NDS::ARM9Timestamp < NDS::ARM9Target) +    while (NDS.ARM9Timestamp < NDS.ARM9Target)      {          if (CPSR & 0x20) // THUMB          { @@ -696,9 +650,9 @@ void ARMv5::Execute()          // TODO optimize this shit!!!          if (Halted)          { -            if (Halted == 1 && NDS::ARM9Timestamp < NDS::ARM9Target) +            if (Halted == 1 && NDS.ARM9Timestamp < NDS.ARM9Target)              { -                NDS::ARM9Timestamp = NDS::ARM9Target; +                NDS.ARM9Timestamp = NDS.ARM9Target;              }              break;          } @@ -709,7 +663,7 @@ void ARMv5::Execute()          }*/          if (IRQ) TriggerIRQ(); -        NDS::ARM9Timestamp += Cycles; +        NDS.ARM9Timestamp += Cycles;          Cycles = 0;      } @@ -726,37 +680,37 @@ void ARMv5::ExecuteJIT()          {              Halted = 0;          } -        else if (NDS::HaltInterrupted(0)) +        else if (NDS.HaltInterrupted(0))          {              Halted = 0; -            if (NDS::IME[0] & 0x1) +            if (NDS.IME[0] & 0x1)                  TriggerIRQ();          }          else          { -            NDS::ARM9Timestamp = NDS::ARM9Target; +            NDS.ARM9Timestamp = NDS.ARM9Target;              return;          }      } -    while (NDS::ARM9Timestamp < NDS::ARM9Target) +    while (NDS.ARM9Timestamp < NDS.ARM9Target)      {          u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);          if ((instrAddr < FastBlockLookupStart || instrAddr >= (FastBlockLookupStart + FastBlockLookupSize)) -            && !JIT.SetupExecutableRegion(0, instrAddr, FastBlockLookup, FastBlockLookupStart, FastBlockLookupSize)) +            && !NDS.JIT.SetupExecutableRegion(0, instrAddr, FastBlockLookup, FastBlockLookupStart, FastBlockLookupSize))          { -            NDS::ARM9Timestamp = NDS::ARM9Target; +            NDS.ARM9Timestamp = NDS.ARM9Target;              Log(LogLevel::Error, "ARMv5 PC in non executable region %08X\n", R[15]);              return;          } -        JitBlockEntry block = JIT.LookUpBlock(0, FastBlockLookup, +        JitBlockEntry block = NDS.JIT.LookUpBlock(0, FastBlockLookup,              instrAddr - FastBlockLookupStart, instrAddr);          if (block)              ARM_Dispatch(this, block);          else -            JIT.CompileBlock(this); +            NDS.JIT.CompileBlock(this);          if (StopExecution)          { @@ -766,17 +720,17 @@ void ARMv5::ExecuteJIT()              if (Halted || IdleLoop)              { -                if ((Halted == 1 || IdleLoop) && NDS::ARM9Timestamp < NDS::ARM9Target) +                if ((Halted == 1 || IdleLoop) && NDS.ARM9Timestamp < NDS.ARM9Target)                  {                      Cycles = 0; -                    NDS::ARM9Timestamp = NDS::ARM9Target; +                    NDS.ARM9Timestamp = NDS.ARM9Target;                  }                  IdleLoop = 0;                  break;              }          } -        NDS::ARM9Timestamp += Cycles; +        NDS.ARM9Timestamp += Cycles;          Cycles = 0;      } @@ -795,20 +749,20 @@ void ARMv4::Execute()          {              Halted = 0;          } -        else if (NDS::HaltInterrupted(1)) +        else if (NDS.HaltInterrupted(1))          {              Halted = 0; -            if (NDS::IME[1] & 0x1) +            if (NDS.IME[1] & 0x1)                  TriggerIRQ();          }          else          { -            NDS::ARM7Timestamp = NDS::ARM7Target; +            NDS.ARM7Timestamp = NDS.ARM7Target;              return;          }      } -    while (NDS::ARM7Timestamp < NDS::ARM7Target) +    while (NDS.ARM7Timestamp < NDS.ARM7Target)      {          if (CPSR & 0x20) // THUMB          { @@ -847,9 +801,9 @@ void ARMv4::Execute()          // TODO optimize this shit!!!          if (Halted)          { -            if (Halted == 1 && NDS::ARM7Timestamp < NDS::ARM7Target) +            if (Halted == 1 && NDS.ARM7Timestamp < NDS.ARM7Target)              { -                NDS::ARM7Timestamp = NDS::ARM7Target; +                NDS.ARM7Timestamp = NDS.ARM7Target;              }              break;          } @@ -860,7 +814,7 @@ void ARMv4::Execute()          }*/          if (IRQ) TriggerIRQ(); -        NDS::ARM7Timestamp += Cycles; +        NDS.ARM7Timestamp += Cycles;          Cycles = 0;      } @@ -869,7 +823,9 @@ void ARMv4::Execute()      if (Halted == 4)      { -        DSi::SoftReset(); +        assert(NDS.ConsoleType == 1); +        auto& dsi = dynamic_cast<melonDS::DSi&>(NDS); +        dsi.SoftReset();          Halted = 2;      }  } @@ -883,37 +839,37 @@ void ARMv4::ExecuteJIT()          {              Halted = 0;          } -        else if (NDS::HaltInterrupted(1)) +        else if (NDS.HaltInterrupted(1))          {              Halted = 0; -            if (NDS::IME[1] & 0x1) +            if (NDS.IME[1] & 0x1)                  TriggerIRQ();          }          else          { -            NDS::ARM7Timestamp = NDS::ARM7Target; +            NDS.ARM7Timestamp = NDS.ARM7Target;              return;          }      } -    while (NDS::ARM7Timestamp < NDS::ARM7Target) +    while (NDS.ARM7Timestamp < NDS.ARM7Target)      {          u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);          if ((instrAddr < FastBlockLookupStart || instrAddr >= (FastBlockLookupStart + FastBlockLookupSize)) -            && !JIT.SetupExecutableRegion(1, instrAddr, FastBlockLookup, FastBlockLookupStart, FastBlockLookupSize)) +            && !NDS.JIT.SetupExecutableRegion(1, instrAddr, FastBlockLookup, FastBlockLookupStart, FastBlockLookupSize))          { -            NDS::ARM7Timestamp = NDS::ARM7Target; +            NDS.ARM7Timestamp = NDS.ARM7Target;              Log(LogLevel::Error, "ARMv4 PC in non executable region %08X\n", R[15]);              return;          } -        JitBlockEntry block = JIT.LookUpBlock(1, FastBlockLookup, +        JitBlockEntry block = NDS.JIT.LookUpBlock(1, FastBlockLookup,              instrAddr - FastBlockLookupStart, instrAddr);          if (block)              ARM_Dispatch(this, block);          else -            JIT.CompileBlock(this); +            NDS.JIT.CompileBlock(this);          if (StopExecution)          { @@ -922,17 +878,17 @@ void ARMv4::ExecuteJIT()              if (Halted || IdleLoop)              { -                if ((Halted == 1 || IdleLoop) && NDS::ARM7Timestamp < NDS::ARM7Target) +                if ((Halted == 1 || IdleLoop) && NDS.ARM7Timestamp < NDS.ARM7Target)                  {                      Cycles = 0; -                    NDS::ARM7Timestamp = NDS::ARM7Target; +                    NDS.ARM7Timestamp = NDS.ARM7Target;                  }                  IdleLoop = 0;                  break;              }          } -        NDS::ARM7Timestamp += Cycles; +        NDS.ARM7Timestamp += Cycles;          Cycles = 0;      } @@ -941,7 +897,9 @@ void ARMv4::ExecuteJIT()      if (Halted == 4)      { -        DSi::SoftReset(); +        assert(NDS.ConsoleType == 1); +        auto& dsi = dynamic_cast<melonDS::DSi&>(NDS); +        dsi.SoftReset();          Halted = 2;      }  } @@ -1136,8 +1094,8 @@ void ARM::WriteMem(u32 addr, int size, u32 v)  void ARM::ResetGdb()  { -    NDS::Reset(); -    GPU.StartFrame(); // need this to properly kick off the scheduler & frame output +    NDS.Reset(); +    NDS.GPU.StartFrame(); // need this to properly kick off the scheduler & frame output  }  int ARM::RemoteCmd(const u8* cmd, size_t len)  { @@ -1193,6 +1151,195 @@ u32 ARMv5::ReadMem(u32 addr, int size)      return ARM::ReadMem(addr, size);  } -}  #endif +void ARMv4::DataRead8(u32 addr, u32* val) +{ +    *val = BusRead8(addr); +    DataRegion = addr; +    DataCycles = NDS.ARM7MemTimings[addr >> 15][0]; +} + +void ARMv4::DataRead16(u32 addr, u32* val) +{ +    addr &= ~1; + +    *val = BusRead16(addr); +    DataRegion = addr; +    DataCycles = NDS.ARM7MemTimings[addr >> 15][0]; +} + +void ARMv4::DataRead32(u32 addr, u32* val) +{ +    addr &= ~3; + +    *val = BusRead32(addr); +    DataRegion = addr; +    DataCycles = NDS.ARM7MemTimings[addr >> 15][2]; +} + +void ARMv4::DataRead32S(u32 addr, u32* val) +{ +    addr &= ~3; + +    *val = BusRead32(addr); +    DataCycles += NDS.ARM7MemTimings[addr >> 15][3]; +} + +void ARMv4::DataWrite8(u32 addr, u8 val) +{ +    BusWrite8(addr, val); +    DataRegion = addr; +    DataCycles = NDS.ARM7MemTimings[addr >> 15][0]; +} + +void ARMv4::DataWrite16(u32 addr, u16 val) +{ +    addr &= ~1; + +    BusWrite16(addr, val); +    DataRegion = addr; +    DataCycles = NDS.ARM7MemTimings[addr >> 15][0]; +} + +void ARMv4::DataWrite32(u32 addr, u32 val) +{ +    addr &= ~3; + +    BusWrite32(addr, val); +    DataRegion = addr; +    DataCycles = NDS.ARM7MemTimings[addr >> 15][2]; +} + +void ARMv4::DataWrite32S(u32 addr, u32 val) +{ +    addr &= ~3; + +    BusWrite32(addr, val); +    DataCycles += NDS.ARM7MemTimings[addr >> 15][3]; +} + + +void ARMv4::AddCycles_C() +{ +    // code only. this code fetch is sequential. +    Cycles += NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?1:3]; +} + +void ARMv4::AddCycles_CI(s32 num) +{ +    // code+internal. results in a nonseq code fetch. +    Cycles += NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2] + num; +} + +void ARMv4::AddCycles_CDI() +{ +    // LDR/LDM cycles. +    s32 numC = NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; +    s32 numD = DataCycles; + +    if ((DataRegion >> 24) == 0x02) // mainRAM +    { +        if (CodeRegion == 0x02) +            Cycles += numC + numD; +        else +        { +            numC++; +            Cycles += std::max(numC + numD - 3, std::max(numC, numD)); +        } +    } +    else if (CodeRegion == 0x02) +    { +        numD++; +        Cycles += std::max(numC + numD - 3, std::max(numC, numD)); +    } +    else +    { +        Cycles += numC + numD + 1; +    } +} + +void ARMv4::AddCycles_CD() +{ +    // TODO: max gain should be 5c when writing to mainRAM +    s32 numC = NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; +    s32 numD = DataCycles; + +    if ((DataRegion >> 24) == 0x02) +    { +        if (CodeRegion == 0x02) +            Cycles += numC + numD; +        else +            Cycles += std::max(numC + numD - 3, std::max(numC, numD)); +    } +    else if (CodeRegion == 0x02) +    { +        Cycles += std::max(numC + numD - 3, std::max(numC, numD)); +    } +    else +    { +        Cycles += numC + numD; +    } +} + +u8 ARMv5::BusRead8(u32 addr) +{ +    return NDS.ARM9Read8(addr); +} + +u16 ARMv5::BusRead16(u32 addr) +{ +    return NDS.ARM9Read16(addr); +} + +u32 ARMv5::BusRead32(u32 addr) +{ +    return NDS.ARM9Read32(addr); +} + +void ARMv5::BusWrite8(u32 addr, u8 val) +{ +    NDS.ARM9Write8(addr, val); +} + +void ARMv5::BusWrite16(u32 addr, u16 val) +{ +    NDS.ARM9Write16(addr, val); +} + +void ARMv5::BusWrite32(u32 addr, u32 val) +{ +    NDS.ARM9Write32(addr, val); +} + +u8 ARMv4::BusRead8(u32 addr) +{ +    return NDS.ARM7Read8(addr); +} + +u16 ARMv4::BusRead16(u32 addr) +{ +    return NDS.ARM7Read16(addr); +} + +u32 ARMv4::BusRead32(u32 addr) +{ +    return NDS.ARM7Read32(addr); +} + +void ARMv4::BusWrite8(u32 addr, u8 val) +{ +    NDS.ARM7Write8(addr, val); +} + +void ARMv4::BusWrite16(u32 addr, u16 val) +{ +    NDS.ARM7Write16(addr, val); +} + +void ARMv4::BusWrite32(u32 addr, u32 val) +{ +    NDS.ARM7Write32(addr, val); +} +} + @@ -22,7 +22,7 @@  #include <algorithm>  #include "types.h" -#include "NDS.h" +#include "MemRegion.h"  #ifdef GDBSTUB_ENABLED  #include "debug/GdbStub.h" @@ -48,6 +48,8 @@ const u32 DTCMPhysicalSize = 0x4000;  class ARMJIT;  class GPU;  class ARMJIT_Memory; +class NDS; +class Savestate;  class ARM  #ifdef GDBSTUB_ENABLED @@ -55,7 +57,7 @@ class ARM  #endif  {  public: -    ARM(u32 num, ARMJIT& jit, GPU& gpu); +    ARM(u32 num, NDS& nds);      virtual ~ARM(); // destroy shit      virtual void Reset(); @@ -73,6 +75,7 @@ public:          Halted = halt;      } +    void NocashPrint(u32 addr) noexcept;      virtual void Execute() = 0;  #ifdef JIT_ENABLED      virtual void ExecuteJIT() = 0; @@ -174,7 +177,7 @@ public:      u32 ExceptionBase; -    NDS::MemRegion CodeMem; +    MemRegion CodeMem;  #ifdef JIT_ENABLED      u32 FastBlockLookupStart, FastBlockLookupSize; @@ -186,14 +189,14 @@ public:      Gdb::GdbStub GdbStub;  #endif -    ARMJIT& JIT; +    melonDS::NDS& NDS;  protected: -    u8 (*BusRead8)(u32 addr); -    u16 (*BusRead16)(u32 addr); -    u32 (*BusRead32)(u32 addr); -    void (*BusWrite8)(u32 addr, u8 val); -    void (*BusWrite16)(u32 addr, u16 val); -    void (*BusWrite32)(u32 addr, u32 val); +    virtual u8 BusRead8(u32 addr) = 0; +    virtual u16 BusRead16(u32 addr) = 0; +    virtual u32 BusRead32(u32 addr) = 0; +    virtual void BusWrite8(u32 addr, u8 val) = 0; +    virtual void BusWrite16(u32 addr, u16 val) = 0; +    virtual void BusWrite32(u32 addr, u32 val) = 0;  #ifdef GDBSTUB_ENABLED      bool IsSingleStep; @@ -217,14 +220,12 @@ protected:      void GdbCheckA();      void GdbCheckB();      void GdbCheckC(); -private: -    melonDS::GPU& GPU;  };  class ARMv5 : public ARM  {  public: -    ARMv5(ARMJIT& jit, melonDS::GPU& gpu); +    ARMv5(melonDS::NDS& nds);      ~ARMv5();      void Reset() override; @@ -296,7 +297,7 @@ public:          //    Cycles += numC + numD;      } -    void GetCodeMemRegion(u32 addr, NDS::MemRegion* region); +    void GetCodeMemRegion(u32 addr, MemRegion* region);      void CP15Reset();      void CP15DoSavestate(Savestate* file); @@ -357,20 +358,26 @@ public:      u8* CurICacheLine; -    bool (*GetMemRegion)(u32 addr, bool write, NDS::MemRegion* region); +    bool (*GetMemRegion)(u32 addr, bool write, MemRegion* region);  #ifdef GDBSTUB_ENABLED      u32 ReadMem(u32 addr, int size) override;      void WriteMem(u32 addr, int size, u32 v) override;  #endif + +protected: +    u8 BusRead8(u32 addr) override; +    u16 BusRead16(u32 addr) override; +    u32 BusRead32(u32 addr) override; +    void BusWrite8(u32 addr, u8 val) override; +    void BusWrite16(u32 addr, u16 val) override; +    void BusWrite32(u32 addr, u32 val) override;  };  class ARMv4 : public ARM  {  public: -    ARMv4(ARMJIT& jit, melonDS::GPU& gpu); - -    void Reset() override; +    ARMv4(melonDS::NDS& nds);      void FillPipeline() override; @@ -391,134 +398,25 @@ public:          return BusRead32(addr);      } -    void DataRead8(u32 addr, u32* val) override -    { -        *val = BusRead8(addr); -        DataRegion = addr; -        DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; -    } - -    void DataRead16(u32 addr, u32* val) override -    { -        addr &= ~1; - -        *val = BusRead16(addr); -        DataRegion = addr; -        DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; -    } - -    void DataRead32(u32 addr, u32* val) override -    { -        addr &= ~3; - -        *val = BusRead32(addr); -        DataRegion = addr; -        DataCycles = NDS::ARM7MemTimings[addr >> 15][2]; -    } - -    void DataRead32S(u32 addr, u32* val) override -    { -        addr &= ~3; - -        *val = BusRead32(addr); -        DataCycles += NDS::ARM7MemTimings[addr >> 15][3]; -    } - -    void DataWrite8(u32 addr, u8 val) override -    { -        BusWrite8(addr, val); -        DataRegion = addr; -        DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; -    } - -    void DataWrite16(u32 addr, u16 val) override -    { -        addr &= ~1; - -        BusWrite16(addr, val); -        DataRegion = addr; -        DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; -    } - -    void DataWrite32(u32 addr, u32 val) override -    { -        addr &= ~3; - -        BusWrite32(addr, val); -        DataRegion = addr; -        DataCycles = NDS::ARM7MemTimings[addr >> 15][2]; -    } - -    void DataWrite32S(u32 addr, u32 val) override -    { -        addr &= ~3; - -        BusWrite32(addr, val); -        DataCycles += NDS::ARM7MemTimings[addr >> 15][3]; -    } - - -    void AddCycles_C() override -    { -        // code only. this code fetch is sequential. -        Cycles += NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?1:3]; -    } - -    void AddCycles_CI(s32 num) override -    { -        // code+internal. results in a nonseq code fetch. -        Cycles += NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2] + num; -    } - -    void AddCycles_CDI() override -    { -        // LDR/LDM cycles. -        s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; -        s32 numD = DataCycles; - -        if ((DataRegion >> 24) == 0x02) // mainRAM -        { -            if (CodeRegion == 0x02) -                Cycles += numC + numD; -            else -            { -                numC++; -                Cycles += std::max(numC + numD - 3, std::max(numC, numD)); -            } -        } -        else if (CodeRegion == 0x02) -        { -            numD++; -            Cycles += std::max(numC + numD - 3, std::max(numC, numD)); -        } -        else -        { -            Cycles += numC + numD + 1; -        } -    } - -    void AddCycles_CD() override -    { -        // TODO: max gain should be 5c when writing to mainRAM -        s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; -        s32 numD = DataCycles; - -        if ((DataRegion >> 24) == 0x02) -        { -            if (CodeRegion == 0x02) -                Cycles += numC + numD; -            else -                Cycles += std::max(numC + numD - 3, std::max(numC, numD)); -        } -        else if (CodeRegion == 0x02) -        { -            Cycles += std::max(numC + numD - 3, std::max(numC, numD)); -        } -        else -        { -            Cycles += numC + numD; -        } -    } +    void DataRead8(u32 addr, u32* val) override; +    void DataRead16(u32 addr, u32* val) override; +    void DataRead32(u32 addr, u32* val) override; +    void DataRead32S(u32 addr, u32* val) override; +    void DataWrite8(u32 addr, u8 val) override; +    void DataWrite16(u32 addr, u16 val) override; +    void DataWrite32(u32 addr, u32 val) override; +    void DataWrite32S(u32 addr, u32 val) override; +    void AddCycles_C() override; +    void AddCycles_CI(s32 num) override; +    void AddCycles_CDI() override; +    void AddCycles_CD() override; +protected: +    u8 BusRead8(u32 addr) override; +    u16 BusRead16(u32 addr) override; +    u32 BusRead32(u32 addr) override; +    void BusWrite8(u32 addr, u8 val) override; +    void BusWrite16(u32 addr, u16 val) override; +    void BusWrite32(u32 addr, u32 val) override;  };  namespace ARMInterpreter @@ -528,14 +426,5 @@ void A_UNK(ARM* cpu);  void T_UNK(ARM* cpu);  } - -namespace NDS -{ - -extern ARMv5* ARM9; -extern ARMv4* ARM7; - -} -  }  #endif // ARM_H diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index 313f764..315d59d 100644 --- a/src/ARMInterpreter_ALU.cpp +++ b/src/ARMInterpreter_ALU.cpp @@ -18,6 +18,7 @@  #include <stdio.h>  #include "ARM.h" +#include "NDS.h"  namespace melonDS::ARMInterpreter  { @@ -692,7 +693,7 @@ void A_MOV_REG_LSL_IMM_DBG(ARM* cpu)          // but since they serve no purpose ATTOW, we can skip them          u32 addr = cpu->R[15] + 4; // Skip 2nd ID and flags          // TODO: Pass flags to NocashPrint -        NDS::NocashPrint(cpu->Num, addr); +        cpu->NDS.NocashPrint(cpu->Num, addr);      }  } @@ -1561,7 +1562,7 @@ void T_MOV_HIREG(ARM* cpu)          // but since they serve no purpose ATTOW, we can skip them          u32 addr = cpu->R[15] + 4; // Skip 2nd ID and flags          // TODO: Pass flags to NocashPrint -        NDS::NocashPrint(cpu->Num, addr); +        cpu->NDS.NocashPrint(cpu->Num, addr);      }  } diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index 4544582..b938dfb 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -64,20 +64,20 @@ const u32 CodeRegionSizes[ARMJIT_Memory::memregions_Count] =      ITCMPhysicalSize,      0,      sizeof(NDS::ARM9BIOS), -    NDS::MainRAMMaxSize, -    NDS::SharedWRAMSize, +    MainRAMMaxSize, +    SharedWRAMSize,      0,      0x100000,      sizeof(NDS::ARM7BIOS), -    NDS::ARM7WRAMSize, +    ARM7WRAMSize,      0,      0,      0x40000,      0x10000,      0x10000, -    DSi::NWRAMSize, -    DSi::NWRAMSize, -    DSi::NWRAMSize, +    NWRAMSize, +    NWRAMSize, +    NWRAMSize,  };  u32 ARMJIT::LocaliseCodeAddress(u32 num, u32 addr) const noexcept @@ -103,11 +103,11 @@ T SlowRead9(u32 addr, ARMv5* cpu)      else if ((addr & cpu->DTCMMask) == cpu->DTCMBase)          val = *(T*)&cpu->DTCM[addr & 0x3FFF];      else if (std::is_same<T, u32>::value) -        val = (ConsoleType == 0 ? NDS::ARM9Read32 : DSi::ARM9Read32)(addr); +        val = NDS::Current->ARM9Read32(addr);      else if (std::is_same<T, u16>::value) -        val = (ConsoleType == 0 ? NDS::ARM9Read16 : DSi::ARM9Read16)(addr); +        val = NDS::Current->ARM9Read16(addr);      else -        val = (ConsoleType == 0 ? NDS::ARM9Read8 : DSi::ARM9Read8)(addr); +        val = NDS::Current->ARM9Read8(addr);      if (std::is_same<T, u32>::value)          return ROR(val, offset << 3); @@ -123,11 +123,11 @@ T SlowRead7(u32 addr)      T val;      if (std::is_same<T, u32>::value) -        val = (ConsoleType == 0 ? NDS::ARM7Read32 : DSi::ARM7Read32)(addr); +        val = NDS::Current->ARM7Read32(addr);      else if (std::is_same<T, u16>::value) -        val = (ConsoleType == 0 ? NDS::ARM7Read16 : DSi::ARM7Read16)(addr); +        val = NDS::Current->ARM7Read16(addr);      else -        val = (ConsoleType == 0 ? NDS::ARM7Read8 : DSi::ARM7Read8)(addr); +        val = NDS::Current->ARM7Read8(addr);      if (std::is_same<T, u32>::value)          return ROR(val, offset << 3); @@ -142,7 +142,7 @@ void SlowWrite9(u32 addr, ARMv5* cpu, u32 val)      if (addr < cpu->ITCMSize)      { -        cpu->JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +        cpu->NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);          *(T*)&cpu->ITCM[addr & 0x7FFF] = val;      }      else if ((addr & cpu->DTCMMask) == cpu->DTCMBase) @@ -151,15 +151,15 @@ void SlowWrite9(u32 addr, ARMv5* cpu, u32 val)      }      else if (std::is_same<T, u32>::value)      { -        (ConsoleType == 0 ? NDS::ARM9Write32 : DSi::ARM9Write32)(addr, val); +        NDS::Current->ARM9Write32(addr, val);      }      else if (std::is_same<T, u16>::value)      { -        (ConsoleType == 0 ? NDS::ARM9Write16 : DSi::ARM9Write16)(addr, val); +        NDS::Current->ARM9Write16(addr, val);      }      else      { -        (ConsoleType == 0 ? NDS::ARM9Write8 : DSi::ARM9Write8)(addr, val); +        NDS::Current->ARM9Write8(addr, val);      }  } @@ -169,11 +169,11 @@ void SlowWrite7(u32 addr, u32 val)      addr &= ~(sizeof(T) - 1);      if (std::is_same<T, u32>::value) -        (ConsoleType == 0 ? NDS::ARM7Write32 : DSi::ARM7Write32)(addr, val); +        NDS::Current->ARM7Write32(addr, val);      else if (std::is_same<T, u16>::value) -        (ConsoleType == 0 ? NDS::ARM7Write16 : DSi::ARM7Write16)(addr, val); +        NDS::Current->ARM7Write16(addr, val);      else -        (ConsoleType == 0 ? NDS::ARM7Write8 : DSi::ARM7Write8)(addr, val); +        NDS::Current->ARM7Write8(addr, val);  }  template <bool Write, int ConsoleType> diff --git a/src/ARMJIT.h b/src/ARMJIT.h index 4191824..9e1ca07 100644 --- a/src/ARMJIT.h +++ b/src/ARMJIT.h @@ -30,6 +30,7 @@  #endif  #include "ARMJIT_Compiler.h" +#include "MemConstants.h"  namespace melonDS  { @@ -39,7 +40,7 @@ class JitBlock;  class ARMJIT  {  public: -    ARMJIT() noexcept : JITCompiler(*this), Memory(*this) {} +    ARMJIT(melonDS::NDS& nds) noexcept : NDS(nds), Memory(nds), JITCompiler(nds) {};      ~ARMJIT() noexcept NOOP_IF_NO_JIT;      void InvalidateByAddr(u32) noexcept NOOP_IF_NO_JIT;      void CheckAndInvalidateWVRAM(int) noexcept NOOP_IF_NO_JIT; @@ -72,8 +73,8 @@ public:      bool BranchOptimizations = false;      bool FastMemory = false; +    melonDS::NDS& NDS;      TinyVector<u32> InvalidLiterals {}; -private:      friend class ARMJIT_Memory;      void blockSanityCheck(u32 num, u32 blockAddr, JitBlockEntry entry) noexcept;      void RetireJitBlock(JitBlock* block) noexcept; @@ -86,32 +87,32 @@ private:      AddressRange CodeIndexITCM[ITCMPhysicalSize / 512] {}; -    AddressRange CodeIndexMainRAM[NDS::MainRAMMaxSize / 512] {}; -    AddressRange CodeIndexSWRAM[NDS::SharedWRAMSize / 512] {}; +    AddressRange CodeIndexMainRAM[MainRAMMaxSize / 512] {}; +    AddressRange CodeIndexSWRAM[SharedWRAMSize / 512] {};      AddressRange CodeIndexVRAM[0x100000 / 512] {}; -    AddressRange CodeIndexARM9BIOS[sizeof(NDS::ARM9BIOS) / 512] {}; -    AddressRange CodeIndexARM7BIOS[sizeof(NDS::ARM7BIOS) / 512] {}; -    AddressRange CodeIndexARM7WRAM[NDS::ARM7WRAMSize / 512] {}; +    AddressRange CodeIndexARM9BIOS[ARM9BIOSSize / 512] {}; +    AddressRange CodeIndexARM7BIOS[ARM7BIOSSize / 512] {}; +    AddressRange CodeIndexARM7WRAM[ARM7WRAMSize / 512] {};      AddressRange CodeIndexARM7WVRAM[0x40000 / 512] {};      AddressRange CodeIndexBIOS9DSi[0x10000 / 512] {};      AddressRange CodeIndexBIOS7DSi[0x10000 / 512] {}; -    AddressRange CodeIndexNWRAM_A[DSi::NWRAMSize / 512] {}; -    AddressRange CodeIndexNWRAM_B[DSi::NWRAMSize / 512] {}; -    AddressRange CodeIndexNWRAM_C[DSi::NWRAMSize / 512] {}; +    AddressRange CodeIndexNWRAM_A[NWRAMSize / 512] {}; +    AddressRange CodeIndexNWRAM_B[NWRAMSize / 512] {}; +    AddressRange CodeIndexNWRAM_C[NWRAMSize / 512] {};      u64 FastBlockLookupITCM[ITCMPhysicalSize / 2] {}; -    u64 FastBlockLookupMainRAM[NDS::MainRAMMaxSize / 2] {}; -    u64 FastBlockLookupSWRAM[NDS::SharedWRAMSize / 2] {}; +    u64 FastBlockLookupMainRAM[MainRAMMaxSize / 2] {}; +    u64 FastBlockLookupSWRAM[SharedWRAMSize / 2] {};      u64 FastBlockLookupVRAM[0x100000 / 2] {}; -    u64 FastBlockLookupARM9BIOS[sizeof(NDS::ARM9BIOS) / 2] {}; -    u64 FastBlockLookupARM7BIOS[sizeof(NDS::ARM7BIOS) / 2] {}; -    u64 FastBlockLookupARM7WRAM[NDS::ARM7WRAMSize / 2] {}; +    u64 FastBlockLookupARM9BIOS[ARM9BIOSSize / 2] {}; +    u64 FastBlockLookupARM7BIOS[ARM7BIOSSize / 2] {}; +    u64 FastBlockLookupARM7WRAM[ARM7WRAMSize / 2] {};      u64 FastBlockLookupARM7WVRAM[0x40000 / 2] {};      u64 FastBlockLookupBIOS9DSi[0x10000 / 2] {};      u64 FastBlockLookupBIOS7DSi[0x10000 / 2] {}; -    u64 FastBlockLookupNWRAM_A[DSi::NWRAMSize / 2] {}; -    u64 FastBlockLookupNWRAM_B[DSi::NWRAMSize / 2] {}; -    u64 FastBlockLookupNWRAM_C[DSi::NWRAMSize / 2] {}; +    u64 FastBlockLookupNWRAM_A[NWRAMSize / 2] {}; +    u64 FastBlockLookupNWRAM_B[NWRAMSize / 2] {}; +    u64 FastBlockLookupNWRAM_C[NWRAMSize / 2] {};      AddressRange* const CodeMemRegions[ARMJIT_Memory::memregions_Count] =      { diff --git a/src/ARMJIT_A64/ARMJIT_Branch.cpp b/src/ARMJIT_A64/ARMJIT_Branch.cpp index d18a0e0..92717e9 100644 --- a/src/ARMJIT_A64/ARMJIT_Branch.cpp +++ b/src/ARMJIT_A64/ARMJIT_Branch.cpp @@ -17,6 +17,7 @@  */  #include "ARMJIT_Compiler.h" +#include "../NDS.h"  using namespace Arm64Gen; @@ -132,7 +133,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles)              u32 compileTimePC = CurCPU->R[15];              CurCPU->R[15] = newPC; -            cycles += NDS::ARM7MemTimings[codeCycles][0] + NDS::ARM7MemTimings[codeCycles][1]; +            cycles += NDS.ARM7MemTimings[codeCycles][0] + NDS.ARM7MemTimings[codeCycles][1];              CurCPU->R[15] = compileTimePC;          } @@ -144,7 +145,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles)              u32 compileTimePC = CurCPU->R[15];              CurCPU->R[15] = newPC; -            cycles += NDS::ARM7MemTimings[codeCycles][2] + NDS::ARM7MemTimings[codeCycles][3]; +            cycles += NDS.ARM7MemTimings[codeCycles][2] + NDS.ARM7MemTimings[codeCycles][3];              CurCPU->R[15] = compileTimePC;          } @@ -235,7 +236,7 @@ void* Compiler::Gen_JumpTo7(int kind)      LSR(W1, W0, 15);      STR(INDEX_UNSIGNED, W1, RCPU, offsetof(ARM, CodeCycles)); -    MOVP2R(X2, NDS::ARM7MemTimings); +    MOVP2R(X2, NDS.ARM7MemTimings);      LDR(W3, X2, ArithOption(W1, true));      FixupBranch switchToThumb; diff --git a/src/ARMJIT_A64/ARMJIT_Compiler.cpp b/src/ARMJIT_A64/ARMJIT_Compiler.cpp index 1b03758..c306dd8 100644 --- a/src/ARMJIT_A64/ARMJIT_Compiler.cpp +++ b/src/ARMJIT_A64/ARMJIT_Compiler.cpp @@ -21,6 +21,7 @@  #include "../ARMJIT_Internal.h"  #include "../ARMInterpreter.h"  #include "../ARMJIT.h" +#include "../NDS.h"  #if defined(__SWITCH__)  #include <switch.h> @@ -220,7 +221,7 @@ void Compiler::PopRegs(bool saveHiRegs, bool saveRegsToBeChanged)      }  } -Compiler::Compiler(ARMJIT& jit) : Arm64Gen::ARM64XEmitter(), JIT(jit) +Compiler::Compiler(melonDS::NDS& nds) : Arm64Gen::ARM64XEmitter(), NDS(nds)  {  #ifdef __SWITCH__      JitRWBase = aligned_alloc(0x1000, JitMemSize); @@ -705,12 +706,12 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]      if (JitMemMainSize - GetCodeOffset() < 1024 * 16)      {          Log(LogLevel::Debug, "JIT near memory full, resetting...\n"); -        JIT.ResetBlockCache(); +        NDS.JIT.ResetBlockCache();      }      if ((JitMemMainSize +  JitMemSecondarySize) - OtherCodeRegion < 1024 * 8)      {          Log(LogLevel::Debug, "JIT far memory full, resetting...\n"); -        JIT.ResetBlockCache(); +        NDS.JIT.ResetBlockCache();      }      JitBlockEntry res = (JitBlockEntry)GetRXPtr(); @@ -723,7 +724,7 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]      CPSRDirty = false;      if (hasMemInstr) -        MOVP2R(RMemBase, Num == 0 ? JIT.Memory.FastMem9Start : JIT.Memory.FastMem7Start); +        MOVP2R(RMemBase, Num == 0 ? NDS.JIT.Memory.FastMem9Start : NDS.JIT.Memory.FastMem7Start);      for (int i = 0; i < instrsCount; i++)      { @@ -871,7 +872,7 @@ void Compiler::Reset()  void Compiler::Comp_AddCycles_C(bool forceNonConstant)  {      s32 cycles = Num ? -        NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 1 : 3] +        NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 1 : 3]          : ((R15 & 0x2) ? 0 : CurInstr.CodeCycles);      if (forceNonConstant) @@ -885,7 +886,7 @@ void Compiler::Comp_AddCycles_CI(u32 numI)      IrregularCycles = true;      s32 cycles = (Num ? -        NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2] +        NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]          : ((R15 & 0x2) ? 0 : CurInstr.CodeCycles)) + numI;      if (Thumb || CurInstr.Cond() == 0xE) @@ -899,7 +900,7 @@ void Compiler::Comp_AddCycles_CI(u32 c, ARM64Reg numI, ArithOption shift)      IrregularCycles = true;      s32 cycles = (Num ? -        NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2] +        NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]          : ((R15 & 0x2) ? 0 : CurInstr.CodeCycles)) + c;      ADD(RCycles, RCycles, cycles); @@ -919,7 +920,7 @@ void Compiler::Comp_AddCycles_CDI()          s32 cycles; -        s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]; +        s32 numC = NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2];          s32 numD = CurInstr.DataCycles;          if ((CurInstr.DataRegion >> 24) == 0x02) // mainRAM @@ -964,7 +965,7 @@ void Compiler::Comp_AddCycles_CD()      }      else      { -        s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]; +        s32 numC = NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2];          s32 numD = CurInstr.DataCycles;          if ((CurInstr.DataRegion >> 24) == 0x02) diff --git a/src/ARMJIT_A64/ARMJIT_Compiler.h b/src/ARMJIT_A64/ARMJIT_Compiler.h index d1e5c44..72dd7bc 100644 --- a/src/ARMJIT_A64/ARMJIT_Compiler.h +++ b/src/ARMJIT_A64/ARMJIT_Compiler.h @@ -96,7 +96,11 @@ class Compiler : public Arm64Gen::ARM64XEmitter  public:      typedef void (Compiler::*CompileFunc)(); -    Compiler(ARMJIT& jit); +#ifdef JIT_ENABLED +    explicit Compiler(melonDS::NDS& nds); +#else +    explicit Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds) {} +#endif      ~Compiler();      void PushRegs(bool saveHiRegs, bool saveRegsToBeChanged, bool allowUnload = true); @@ -242,7 +246,7 @@ public:          OtherCodeRegion = offset;      } -    ARMJIT& JIT; +    melonDS::NDS& NDS;      ptrdiff_t OtherCodeRegion;      bool Exit; diff --git a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp index 93cd75e..22a410a 100644 --- a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp @@ -21,6 +21,7 @@  #include "../ARMJIT.h"  #include "../ARMJIT_Memory.h" +#include "../NDS.h"  using namespace Arm64Gen; @@ -62,9 +63,9 @@ u8* Compiler::RewriteMemAccess(u8* pc)  bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr)  { -    u32 localAddr = JIT.LocaliseCodeAddress(Num, addr); +    u32 localAddr = NDS.JIT.LocaliseCodeAddress(Num, addr); -    int invalidLiteralIdx = JIT.InvalidLiterals.Find(localAddr); +    int invalidLiteralIdx = NDS.JIT.InvalidLiterals.Find(localAddr);      if (invalidLiteralIdx != -1)      {          return false; @@ -111,7 +112,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)      if (size == 16)          addressMask = ~1; -    if (JIT.LiteralOptimizations && rn == 15 && rd != 15 && offset.IsImm && !(flags & (memop_Post|memop_Store|memop_Writeback))) +    if (NDS.JIT.LiteralOptimizations && rn == 15 && rd != 15 && offset.IsImm && !(flags & (memop_Post|memop_Store|memop_Writeback)))      {          u32 addr = R15 + offset.Imm * ((flags & memop_SubtractOffset) ? -1 : 1); @@ -146,7 +147,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)          MOV(W0, rnMapped);      } -    bool addrIsStatic = JIT.LiteralOptimizations +    bool addrIsStatic = NDS.JIT.LiteralOptimizations          && RegCache.IsLiteral(rn) && offset.IsImm && !(flags & (memop_Writeback|memop_Post));      u32 staticAddress;      if (addrIsStatic) @@ -185,18 +186,18 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)          MOV(rnMapped, W0);      u32 expectedTarget = Num == 0 -        ? JIT.Memory.ClassifyAddress9(addrIsStatic ? staticAddress : CurInstr.DataRegion) -        : JIT.Memory.ClassifyAddress7(addrIsStatic ? staticAddress : CurInstr.DataRegion); +        ? NDS.JIT.Memory.ClassifyAddress9(addrIsStatic ? staticAddress : CurInstr.DataRegion) +        : NDS.JIT.Memory.ClassifyAddress7(addrIsStatic ? staticAddress : CurInstr.DataRegion); -    if (JIT.FastMemory && ((!Thumb && CurInstr.Cond() != 0xE) || JIT.Memory.IsFastmemCompatible(expectedTarget))) +    if (NDS.JIT.FastMemory && ((!Thumb && CurInstr.Cond() != 0xE) || NDS.JIT.Memory.IsFastmemCompatible(expectedTarget)))      {          ptrdiff_t memopStart = GetCodeOffset();          LoadStorePatch patch;          assert((rdMapped >= W8 && rdMapped <= W15) || (rdMapped >= W19 && rdMapped <= W25) || rdMapped == W4);          patch.PatchFunc = flags & memop_Store -            ? PatchedStoreFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped] -            : PatchedLoadFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped]; +            ? PatchedStoreFuncs[NDS.ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped] +            : PatchedLoadFuncs[NDS.ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped];          // take a chance at fastmem          if (size > 8) @@ -225,7 +226,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)      {          void* func = NULL;          if (addrIsStatic) -            func = JIT.Memory.GetFuncForAddr(CurCPU, staticAddress, flags & memop_Store, size); +            func = NDS.JIT.Memory.GetFuncForAddr(CurCPU, staticAddress, flags & memop_Store, size);          PushRegs(false, false); @@ -263,7 +264,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)                  if (flags & memop_Store)                  {                      MOV(W2, rdMapped); -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: QuickCallFunction(X3, SlowWrite9<u32, 0>); break;                      case 33: QuickCallFunction(X3, SlowWrite9<u32, 1>); break; @@ -275,7 +276,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)                  }                  else                  { -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: QuickCallFunction(X3, SlowRead9<u32, 0>); break;                      case 33: QuickCallFunction(X3, SlowRead9<u32, 1>); break; @@ -291,7 +292,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)                  if (flags & memop_Store)                  {                      MOV(W1, rdMapped); -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: QuickCallFunction(X3, SlowWrite7<u32, 0>); break;                      case 33: QuickCallFunction(X3, SlowWrite7<u32, 1>); break; @@ -303,7 +304,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)                  }                  else                  { -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: QuickCallFunction(X3, SlowRead7<u32, 0>); break;                      case 33: QuickCallFunction(X3, SlowRead7<u32, 1>); break; @@ -452,7 +453,7 @@ void Compiler::T_Comp_LoadPCRel()      u32 offset = ((CurInstr.Instr & 0xFF) << 2);      u32 addr = (R15 & ~0x2) + offset; -    if (!JIT.LiteralOptimizations || !Comp_MemLoadLiteral(32, false, CurInstr.T_Reg(8), addr)) +    if (!NDS.JIT.LiteralOptimizations || !Comp_MemLoadLiteral(32, false, CurInstr.T_Reg(8), addr))          Comp_MemAccess(CurInstr.T_Reg(8), 15, Op2(offset), 32, 0);  } @@ -494,11 +495,11 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc          Comp_AddCycles_CDI();      int expectedTarget = Num == 0 -        ? JIT.Memory.ClassifyAddress9(CurInstr.DataRegion) -        : JIT.Memory.ClassifyAddress7(CurInstr.DataRegion); +        ? NDS.JIT.Memory.ClassifyAddress9(CurInstr.DataRegion) +        : NDS.JIT.Memory.ClassifyAddress7(CurInstr.DataRegion); -    bool compileFastPath = JIT.FastMemory -        && store && !usermode && (CurInstr.Cond() < 0xE || JIT.Memory.IsFastmemCompatible(expectedTarget)); +    bool compileFastPath = NDS.JIT.FastMemory +        && store && !usermode && (CurInstr.Cond() < 0xE || NDS.JIT.Memory.IsFastmemCompatible(expectedTarget));      {          s32 offset = decrement @@ -680,7 +681,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc      if (Num == 0)      {          MOV(X3, RCPU); -        switch ((u32)store * 2 | NDS::ConsoleType) +        switch ((u32)store * 2 | NDS.ConsoleType)          {          case 0: QuickCallFunction(X4, SlowBlockTransfer9<false, 0>); break;          case 1: QuickCallFunction(X4, SlowBlockTransfer9<false, 1>); break; @@ -690,7 +691,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc      }      else      { -        switch ((u32)store * 2 | NDS::ConsoleType) +        switch ((u32)store * 2 | NDS.ConsoleType)          {          case 0: QuickCallFunction(X4, SlowBlockTransfer7<false, 0>); break;          case 1: QuickCallFunction(X4, SlowBlockTransfer7<false, 1>); break; diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index 7ed9b8d..bf1fb06 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -159,12 +159,12 @@ LONG ARMJIT_Memory::ExceptionHandler(EXCEPTION_POINTERS* exceptionInfo)          return EXCEPTION_CONTINUE_SEARCH;      } -    u8* curArea = (u8*)(NDS::CurCPU == 0 ? NDS::JIT->Memory.FastMem9Start : NDS::JIT->Memory.FastMem7Start); +    u8* curArea = (u8*)(NDS::Current->CurCPU == 0 ? NDS::Current->JIT.Memory.FastMem9Start : NDS::Current->JIT.Memory.FastMem7Start);      FaultDescription desc {};      desc.EmulatedFaultAddr = (u8*)exceptionInfo->ExceptionRecord->ExceptionInformation[1] - curArea;      desc.FaultPC = (u8*)exceptionInfo->ContextRecord->CONTEXT_PC; -    if (FaultHandler(desc, *NDS::JIT)) +    if (FaultHandler(desc, *NDS::Current))      {          exceptionInfo->ContextRecord->CONTEXT_PC = (u64)desc.FaultPC;          return EXCEPTION_CONTINUE_EXECUTION; @@ -194,12 +194,12 @@ void ARMJIT_Memory::SigsegvHandler(int sig, siginfo_t* info, void* rawContext)      ucontext_t* context = (ucontext_t*)rawContext;      FaultDescription desc {}; -    u8* curArea = (u8*)(NDS::CurCPU == 0 ? NDS::JIT->Memory.FastMem9Start : NDS::JIT->Memory.FastMem7Start); +    u8* curArea = (u8*)(NDS::Current->CurCPU == 0 ? NDS::Current->JIT.Memory.FastMem9Start : NDS::Current->JIT.Memory.FastMem7Start);      desc.EmulatedFaultAddr = (u8*)info->si_addr - curArea;      desc.FaultPC = (u8*)context->CONTEXT_PC; -    if (FaultHandler(desc, *NDS::JIT)) +    if (FaultHandler(desc, *NDS::Current))      {          context->CONTEXT_PC = (u64)desc.FaultPC;          return; @@ -319,12 +319,12 @@ void ARMJIT_Memory::SetCodeProtectionRange(u32 addr, u32 size, u32 num, int prot  }  #endif -void ARMJIT_Memory::Mapping::Unmap(int region, ARMJIT_Memory& memory) noexcept +void ARMJIT_Memory::Mapping::Unmap(int region, melonDS::NDS& nds) noexcept  { -    u32 dtcmStart = NDS::ARM9->DTCMBase; -    u32 dtcmSize = ~NDS::ARM9->DTCMMask + 1; +    u32 dtcmStart = nds.ARM9.DTCMBase; +    u32 dtcmSize = ~nds.ARM9.DTCMMask + 1;      bool skipDTCM = Num == 0 && region != memregion_DTCM; -    u8* statuses = Num == 0 ? memory.MappingStatus9 : memory.MappingStatus7; +    u8* statuses = Num == 0 ? nds.JIT.Memory.MappingStatus9 : nds.JIT.Memory.MappingStatus7;      u32 offset = 0;      while (offset < Size)      { @@ -367,20 +367,20 @@ void ARMJIT_Memory::Mapping::Unmap(int region, ARMJIT_Memory& memory) noexcept          bool success;          if (dtcmStart > Addr)          { -            success = memory.UnmapFromRange(Addr, 0, OffsetsPerRegion[region] + LocalOffset, dtcmStart - Addr); +            success = nds.JIT.Memory.UnmapFromRange(Addr, 0, OffsetsPerRegion[region] + LocalOffset, dtcmStart - Addr);              assert(success);          }          if (dtcmEnd < Addr + Size)          {              u32 offset = dtcmStart - Addr + dtcmSize; -            success = memory.UnmapFromRange(dtcmEnd, 0, OffsetsPerRegion[region] + LocalOffset + offset, Size - offset); +            success = nds.JIT.Memory.UnmapFromRange(dtcmEnd, 0, OffsetsPerRegion[region] + LocalOffset + offset, Size - offset);              assert(success);          }      }      else  #endif      { -        bool succeded = memory.UnmapFromRange(Addr, Num, OffsetsPerRegion[region] + LocalOffset, Size); +        bool succeded = nds.JIT.Memory.UnmapFromRange(Addr, Num, OffsetsPerRegion[region] + LocalOffset, Size);          assert(succeded);      }  #endif @@ -401,7 +401,7 @@ void ARMJIT_Memory::SetCodeProtection(int region, u32 offset, bool protect) noex          u32 effectiveAddr = mapping.Addr + (offset - mapping.LocalOffset);          if (mapping.Num == 0              && region != memregion_DTCM -            && (effectiveAddr & NDS::ARM9->DTCMMask) == NDS::ARM9->DTCMBase) +            && (effectiveAddr & NDS.ARM9.DTCMMask) == NDS.ARM9.DTCMBase)              continue;          u8* states = (u8*)(mapping.Num == 0 ? MappingStatus9 : MappingStatus7); @@ -427,9 +427,9 @@ void ARMJIT_Memory::RemapDTCM(u32 newBase, u32 newSize) noexcept  {      // this first part could be made more efficient      // by unmapping DTCM first and then map the holes -    u32 oldDTCMBase = NDS::ARM9->DTCMBase; -    u32 oldDTCMSize = ~NDS::ARM9->DTCMMask + 1; -    u32 oldDTCMEnd = oldDTCMBase + NDS::ARM9->DTCMMask; +    u32 oldDTCMBase = NDS.ARM9.DTCMBase; +    u32 oldDTCMSize = ~NDS.ARM9.DTCMMask + 1; +    u32 oldDTCMEnd = oldDTCMBase + NDS.ARM9.DTCMMask;      u32 newEnd = newBase + newSize; @@ -454,7 +454,7 @@ void ARMJIT_Memory::RemapDTCM(u32 newBase, u32 newSize) noexcept              if (mapping.Num == 0 && overlap)              { -                mapping.Unmap(region, *this); +                mapping.Unmap(region, NDS);                  Mappings[region].Remove(i);              }              else @@ -466,20 +466,22 @@ void ARMJIT_Memory::RemapDTCM(u32 newBase, u32 newSize) noexcept      for (int i = 0; i < Mappings[memregion_DTCM].Length; i++)      { -        Mappings[memregion_DTCM][i].Unmap(memregion_DTCM, *this); +        Mappings[memregion_DTCM][i].Unmap(memregion_DTCM, NDS);      }      Mappings[memregion_DTCM].Clear();  }  void ARMJIT_Memory::RemapNWRAM(int num) noexcept  { +    auto* dsi = dynamic_cast<DSi*>(&NDS); +    assert(dsi != nullptr);      for (int i = 0; i < Mappings[memregion_SharedWRAM].Length;)      {          Mapping& mapping = Mappings[memregion_SharedWRAM][i]; -        if (DSi::NWRAMStart[mapping.Num][num] < mapping.Addr + mapping.Size -            && DSi::NWRAMEnd[mapping.Num][num] > mapping.Addr) +        if (dsi->NWRAMStart[mapping.Num][num] < mapping.Addr + mapping.Size +            && dsi->NWRAMEnd[mapping.Num][num] > mapping.Addr)          { -            mapping.Unmap(memregion_SharedWRAM, *this); +            mapping.Unmap(memregion_SharedWRAM, NDS);              Mappings[memregion_SharedWRAM].Remove(i);          }          else @@ -489,7 +491,7 @@ void ARMJIT_Memory::RemapNWRAM(int num) noexcept      }      for (int i = 0; i < Mappings[memregion_NewSharedWRAM_A + num].Length; i++)      { -        Mappings[memregion_NewSharedWRAM_A + num][i].Unmap(memregion_NewSharedWRAM_A + num, *this); +        Mappings[memregion_NewSharedWRAM_A + num][i].Unmap(memregion_NewSharedWRAM_A + num, NDS);      }      Mappings[memregion_NewSharedWRAM_A + num].Clear();  } @@ -502,7 +504,7 @@ void ARMJIT_Memory::RemapSWRAM() noexcept          Mapping& mapping = Mappings[memregion_WRAM7][i];          if (mapping.Addr + mapping.Size <= 0x03800000)          { -            mapping.Unmap(memregion_WRAM7, *this); +            mapping.Unmap(memregion_WRAM7, NDS);              Mappings[memregion_WRAM7].Remove(i);          }          else @@ -510,14 +512,14 @@ void ARMJIT_Memory::RemapSWRAM() noexcept      }      for (int i = 0; i < Mappings[memregion_SharedWRAM].Length; i++)      { -        Mappings[memregion_SharedWRAM][i].Unmap(memregion_SharedWRAM, *this); +        Mappings[memregion_SharedWRAM][i].Unmap(memregion_SharedWRAM, NDS);      }      Mappings[memregion_SharedWRAM].Clear();  }  bool ARMJIT_Memory::MapAtAddress(u32 addr) noexcept  { -    u32 num = NDS::CurCPU; +    u32 num = NDS.CurCPU;      int region = num == 0          ? ClassifyAddress9(addr) @@ -533,10 +535,10 @@ bool ARMJIT_Memory::MapAtAddress(u32 addr) noexcept      u8* states = num == 0 ? MappingStatus9 : MappingStatus7;      //printf("mapping mirror %x, %x %x %d %d\n", mirrorStart, mirrorSize, memoryOffset, region, num); -    bool isExecutable = JIT.CodeMemRegions[region]; +    bool isExecutable = NDS.JIT.CodeMemRegions[region]; -    u32 dtcmStart = NDS::ARM9->DTCMBase; -    u32 dtcmSize = ~NDS::ARM9->DTCMMask + 1; +    u32 dtcmStart = NDS.ARM9.DTCMBase; +    u32 dtcmSize = ~NDS.ARM9.DTCMMask + 1;      u32 dtcmEnd = dtcmStart + dtcmSize;  #ifndef __SWITCH__  #ifndef _WIN32 @@ -565,7 +567,7 @@ bool ARMJIT_Memory::MapAtAddress(u32 addr) noexcept      }  #endif -    AddressRange* range = JIT.CodeMemRegions[region] + memoryOffset / 512; +    AddressRange* range = NDS.JIT.CodeMemRegions[region] + memoryOffset / 512;      // this overcomplicated piece of code basically just finds whole pieces of code memory      // which can be mapped/protected @@ -586,7 +588,7 @@ bool ARMJIT_Memory::MapAtAddress(u32 addr) noexcept              bool hasCode = isExecutable && PageContainsCode(&range[offset / 512]);              while (offset < mirrorSize                  && (!isExecutable || PageContainsCode(&range[offset / 512]) == hasCode) -                && (!skipDTCM || mirrorStart + offset != NDS::ARM9->DTCMBase)) +                && (!skipDTCM || mirrorStart + offset != NDS.ARM9.DTCMBase))              {                  assert(states[(mirrorStart + offset) >> 12] == memstate_Unmapped);                  states[(mirrorStart + offset) >> 12] = hasCode ? memstate_MappedProtected : memstate_MappedRW; @@ -620,19 +622,19 @@ bool ARMJIT_Memory::MapAtAddress(u32 addr) noexcept      return true;  } -bool ARMJIT_Memory::FaultHandler(FaultDescription& faultDesc, ARMJIT& jit) +bool ARMJIT_Memory::FaultHandler(FaultDescription& faultDesc, melonDS::NDS& nds)  { -    if (jit.JITCompiler.IsJITFault(faultDesc.FaultPC)) +    if (nds.JIT.JITCompiler.IsJITFault(faultDesc.FaultPC))      {          bool rewriteToSlowPath = true; -        u8* memStatus = NDS::CurCPU == 0 ? jit.Memory.MappingStatus9 : jit.Memory.MappingStatus7; +        u8* memStatus = nds.CurCPU == 0 ? nds.JIT.Memory.MappingStatus9 : nds.JIT.Memory.MappingStatus7;          if (memStatus[faultDesc.EmulatedFaultAddr >> 12] == memstate_Unmapped) -            rewriteToSlowPath = !jit.Memory.MapAtAddress(faultDesc.EmulatedFaultAddr); +            rewriteToSlowPath = !nds.JIT.Memory.MapAtAddress(faultDesc.EmulatedFaultAddr);          if (rewriteToSlowPath) -            faultDesc.FaultPC = jit.JITCompiler.RewriteMemAccess(faultDesc.FaultPC); +            faultDesc.FaultPC = nds.JIT.JITCompiler.RewriteMemAccess(faultDesc.FaultPC);          return true;      } @@ -641,7 +643,7 @@ bool ARMJIT_Memory::FaultHandler(FaultDescription& faultDesc, ARMJIT& jit)  const u64 AddrSpaceSize = 0x100000000; -ARMJIT_Memory::ARMJIT_Memory(ARMJIT& jit) noexcept : JIT(jit) +ARMJIT_Memory::ARMJIT_Memory(melonDS::NDS& nds) : NDS(nds)  {  #if defined(__SWITCH__)      MemoryBase = (u8*)aligned_alloc(0x1000, MemoryTotalSize); @@ -815,7 +817,7 @@ void ARMJIT_Memory::Reset() noexcept      for (int region = 0; region < memregions_Count; region++)      {          for (int i = 0; i < Mappings[region].Length; i++) -            Mappings[region][i].Unmap(region, *this); +            Mappings[region][i].Unmap(region, NDS);          Mappings[region].Clear();      } @@ -866,8 +868,8 @@ bool ARMJIT_Memory::GetMirrorLocation(int region, u32 num, u32 addr, u32& memory          }          return false;      case memregion_MainRAM: -        mirrorStart = addr & ~NDS::MainRAMMask; -        mirrorSize = NDS::MainRAMMask + 1; +        mirrorStart = addr & ~NDS.MainRAMMask; +        mirrorSize = NDS.MainRAMMask + 1;          return true;      case memregion_BIOS9:          if (num == 0) @@ -886,26 +888,26 @@ bool ARMJIT_Memory::GetMirrorLocation(int region, u32 num, u32 addr, u32& memory          }          return false;      case memregion_SharedWRAM: -        if (num == 0 && NDS::SWRAM_ARM9.Mem) +        if (num == 0 && NDS.SWRAM_ARM9.Mem)          { -            mirrorStart = addr & ~NDS::SWRAM_ARM9.Mask; -            mirrorSize = NDS::SWRAM_ARM9.Mask + 1; -            memoryOffset = NDS::SWRAM_ARM9.Mem - GetSharedWRAM(); +            mirrorStart = addr & ~NDS.SWRAM_ARM9.Mask; +            mirrorSize = NDS.SWRAM_ARM9.Mask + 1; +            memoryOffset = NDS.SWRAM_ARM9.Mem - GetSharedWRAM();              return true;          } -        else if (num == 1 && NDS::SWRAM_ARM7.Mem) +        else if (num == 1 && NDS.SWRAM_ARM7.Mem)          { -            mirrorStart = addr & ~NDS::SWRAM_ARM7.Mask; -            mirrorSize = NDS::SWRAM_ARM7.Mask + 1; -            memoryOffset = NDS::SWRAM_ARM7.Mem - GetSharedWRAM(); +            mirrorStart = addr & ~NDS.SWRAM_ARM7.Mask; +            mirrorSize = NDS.SWRAM_ARM7.Mask + 1; +            memoryOffset = NDS.SWRAM_ARM7.Mem - GetSharedWRAM();              return true;          }          return false;      case memregion_WRAM7:          if (num == 1)          { -            mirrorStart = addr & ~(NDS::ARM7WRAMSize - 1); -            mirrorSize = NDS::ARM7WRAMSize; +            mirrorStart = addr & ~(ARM7WRAMSize - 1); +            mirrorSize = ARM7WRAMSize;              return true;          }          return false; @@ -927,7 +929,9 @@ bool ARMJIT_Memory::GetMirrorLocation(int region, u32 num, u32 addr, u32& memory          return false;      case memregion_NewSharedWRAM_A:          { -            u8* ptr = DSi::NWRAMMap_A[num][(addr >> 16) & DSi::NWRAMMask[num][0]]; +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr); +            u8* ptr = dsi->NWRAMMap_A[num][(addr >> 16) & dsi->NWRAMMask[num][0]];              if (ptr)              {                  memoryOffset = ptr - GetNWRAM_A(); @@ -939,7 +943,9 @@ bool ARMJIT_Memory::GetMirrorLocation(int region, u32 num, u32 addr, u32& memory          }      case memregion_NewSharedWRAM_B:          { -            u8* ptr = DSi::NWRAMMap_B[num][(addr >> 15) & DSi::NWRAMMask[num][1]]; +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr); +            u8* ptr = dsi->NWRAMMap_B[num][(addr >> 15) & dsi->NWRAMMask[num][1]];              if (ptr)              {                  memoryOffset = ptr - GetNWRAM_B(); @@ -951,7 +957,9 @@ bool ARMJIT_Memory::GetMirrorLocation(int region, u32 num, u32 addr, u32& memory          }      case memregion_NewSharedWRAM_C:          { -            u8* ptr = DSi::NWRAMMap_C[num][(addr >> 15) & DSi::NWRAMMask[num][2]]; +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr); +            u8* ptr = dsi->NWRAMMap_C[num][(addr >> 15) & dsi->NWRAMMask[num][2]];              if (ptr)              {                  memoryOffset = ptr - GetNWRAM_C(); @@ -964,16 +972,20 @@ bool ARMJIT_Memory::GetMirrorLocation(int region, u32 num, u32 addr, u32& memory      case memregion_BIOS9DSi:          if (num == 0)          { +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr);              mirrorStart = addr & ~0xFFFF; -            mirrorSize = DSi::SCFG_BIOS & (1<<0) ? 0x8000 : 0x10000; +            mirrorSize = dsi->SCFG_BIOS & (1<<0) ? 0x8000 : 0x10000;              return true;          }          return false;      case memregion_BIOS7DSi:          if (num == 1)          { +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr);              mirrorStart = addr & ~0xFFFF; -            mirrorSize = DSi::SCFG_BIOS & (1<<8) ? 0x8000 : 0x10000; +            mirrorSize = dsi->SCFG_BIOS & (1<<8) ? 0x8000 : 0x10000;              return true;          }          return false; @@ -990,18 +1002,18 @@ u32 ARMJIT_Memory::LocaliseAddress(int region, u32 num, u32 addr) const noexcept      case memregion_ITCM:          return (addr & (ITCMPhysicalSize - 1)) | (memregion_ITCM << 27);      case memregion_MainRAM: -        return (addr & NDS::MainRAMMask) | (memregion_MainRAM << 27); +        return (addr & NDS.MainRAMMask) | (memregion_MainRAM << 27);      case memregion_BIOS9:          return (addr & 0xFFF) | (memregion_BIOS9 << 27);      case memregion_BIOS7:          return (addr & 0x3FFF) | (memregion_BIOS7 << 27);      case memregion_SharedWRAM:          if (num == 0) -            return ((addr & NDS::SWRAM_ARM9.Mask) + (NDS::SWRAM_ARM9.Mem - GetSharedWRAM())) | (memregion_SharedWRAM << 27); +            return ((addr & NDS.SWRAM_ARM9.Mask) + (NDS.SWRAM_ARM9.Mem - GetSharedWRAM())) | (memregion_SharedWRAM << 27);          else -            return ((addr & NDS::SWRAM_ARM7.Mask) + (NDS::SWRAM_ARM7.Mem - GetSharedWRAM())) | (memregion_SharedWRAM << 27); +            return ((addr & NDS.SWRAM_ARM7.Mask) + (NDS.SWRAM_ARM7.Mem - GetSharedWRAM())) | (memregion_SharedWRAM << 27);      case memregion_WRAM7: -        return (addr & (NDS::ARM7WRAMSize - 1)) | (memregion_WRAM7 << 27); +        return (addr & (melonDS::ARM7WRAMSize - 1)) | (memregion_WRAM7 << 27);      case memregion_VRAM:          // TODO: take mapping properly into account          return (addr & 0xFFFFF) | (memregion_VRAM << 27); @@ -1010,7 +1022,9 @@ u32 ARMJIT_Memory::LocaliseAddress(int region, u32 num, u32 addr) const noexcept          return (addr & 0x3FFFF) | (memregion_VWRAM << 27);      case memregion_NewSharedWRAM_A:          { -            u8* ptr = DSi::NWRAMMap_A[num][(addr >> 16) & DSi::NWRAMMask[num][0]]; +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr); +            u8* ptr = dsi->NWRAMMap_A[num][(addr >> 16) & dsi->NWRAMMask[num][0]];              if (ptr)                  return (ptr - GetNWRAM_A() + (addr & 0xFFFF)) | (memregion_NewSharedWRAM_A << 27);              else @@ -1018,7 +1032,9 @@ u32 ARMJIT_Memory::LocaliseAddress(int region, u32 num, u32 addr) const noexcept          }      case memregion_NewSharedWRAM_B:          { -            u8* ptr = DSi::NWRAMMap_B[num][(addr >> 15) & DSi::NWRAMMask[num][1]]; +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr); +            u8* ptr = dsi->NWRAMMap_B[num][(addr >> 15) & dsi->NWRAMMask[num][1]];              if (ptr)                  return (ptr - GetNWRAM_B() + (addr & 0x7FFF)) | (memregion_NewSharedWRAM_B << 27);              else @@ -1026,7 +1042,9 @@ u32 ARMJIT_Memory::LocaliseAddress(int region, u32 num, u32 addr) const noexcept          }      case memregion_NewSharedWRAM_C:          { -            u8* ptr = DSi::NWRAMMap_C[num][(addr >> 15) & DSi::NWRAMMask[num][2]]; +            auto* dsi = dynamic_cast<DSi*>(&NDS); +            assert(dsi != nullptr); +            u8* ptr = dsi->NWRAMMap_C[num][(addr >> 15) & dsi->NWRAMMask[num][2]];              if (ptr)                  return (ptr - GetNWRAM_C() + (addr & 0x7FFF)) | (memregion_NewSharedWRAM_C << 27);              else @@ -1043,19 +1061,20 @@ u32 ARMJIT_Memory::LocaliseAddress(int region, u32 num, u32 addr) const noexcept  int ARMJIT_Memory::ClassifyAddress9(u32 addr) const noexcept  { -    if (addr < NDS::ARM9->ITCMSize) +    if (addr < NDS.ARM9.ITCMSize)      {          return memregion_ITCM;      } -    else if ((addr & NDS::ARM9->DTCMMask) == NDS::ARM9->DTCMBase) +    else if ((addr & NDS.ARM9.DTCMMask) == NDS.ARM9.DTCMBase)      {          return memregion_DTCM;      }      else      { -        if (NDS::ConsoleType == 1 && addr >= 0xFFFF0000 && !(DSi::SCFG_BIOS & (1<<1))) +        auto& dsi = static_cast<DSi&>(NDS); // ONLY use this if ConsoleType == 1! +        if (NDS.ConsoleType == 1 && addr >= 0xFFFF0000 && !(dsi.SCFG_BIOS & (1<<1)))          { -            if ((addr >= 0xFFFF8000) && (DSi::SCFG_BIOS & (1<<0))) +            if ((addr >= 0xFFFF8000) && (dsi.SCFG_BIOS & (1<<0)))                  return memregion_Other;              return memregion_BIOS9DSi; @@ -1070,17 +1089,17 @@ int ARMJIT_Memory::ClassifyAddress9(u32 addr) const noexcept          case 0x02000000:              return memregion_MainRAM;          case 0x03000000: -            if (NDS::ConsoleType == 1) +            if (NDS.ConsoleType == 1)              { -                if (addr >= DSi::NWRAMStart[0][0] && addr < DSi::NWRAMEnd[0][0]) +                if (addr >= dsi.NWRAMStart[0][0] && addr < dsi.NWRAMEnd[0][0])                      return memregion_NewSharedWRAM_A; -                if (addr >= DSi::NWRAMStart[0][1] && addr < DSi::NWRAMEnd[0][1]) +                if (addr >= dsi.NWRAMStart[0][1] && addr < dsi.NWRAMEnd[0][1])                      return memregion_NewSharedWRAM_B; -                if (addr >= DSi::NWRAMStart[0][2] && addr < DSi::NWRAMEnd[0][2]) +                if (addr >= dsi.NWRAMStart[0][2] && addr < dsi.NWRAMEnd[0][2])                      return memregion_NewSharedWRAM_C;              } -            if (NDS::SWRAM_ARM9.Mem) +            if (NDS.SWRAM_ARM9.Mem)                  return memregion_SharedWRAM;              return memregion_Other;          case 0x04000000: @@ -1088,7 +1107,7 @@ int ARMJIT_Memory::ClassifyAddress9(u32 addr) const noexcept          case 0x06000000:              return memregion_VRAM;          case 0x0C000000: -            return (NDS::ConsoleType==1) ? memregion_MainRAM : memregion_Other; +            return (NDS.ConsoleType==1) ? memregion_MainRAM : memregion_Other;          default:              return memregion_Other;          } @@ -1097,9 +1116,10 @@ int ARMJIT_Memory::ClassifyAddress9(u32 addr) const noexcept  int ARMJIT_Memory::ClassifyAddress7(u32 addr) const noexcept  { -    if (NDS::ConsoleType == 1 && addr < 0x00010000 && !(DSi::SCFG_BIOS & (1<<9))) +    auto& dsi = static_cast<DSi&>(NDS); +    if (NDS.ConsoleType == 1 && addr < 0x00010000 && !(dsi.SCFG_BIOS & (1<<9)))      { -        if (addr >= 0x00008000 && DSi::SCFG_BIOS & (1<<8)) +        if (addr >= 0x00008000 && dsi.SCFG_BIOS & (1<<8))              return memregion_Other;          return memregion_BIOS7DSi; @@ -1116,17 +1136,17 @@ int ARMJIT_Memory::ClassifyAddress7(u32 addr) const noexcept          case 0x02800000:              return memregion_MainRAM;          case 0x03000000: -            if (NDS::ConsoleType == 1) +            if (NDS.ConsoleType == 1)              { -                if (addr >= DSi::NWRAMStart[1][0] && addr < DSi::NWRAMEnd[1][0]) +                if (addr >= dsi.NWRAMStart[1][0] && addr < dsi.NWRAMEnd[1][0])                      return memregion_NewSharedWRAM_A; -                if (addr >= DSi::NWRAMStart[1][1] && addr < DSi::NWRAMEnd[1][1]) +                if (addr >= dsi.NWRAMStart[1][1] && addr < dsi.NWRAMEnd[1][1])                      return memregion_NewSharedWRAM_B; -                if (addr >= DSi::NWRAMStart[1][2] && addr < DSi::NWRAMEnd[1][2]) +                if (addr >= dsi.NWRAMStart[1][2] && addr < dsi.NWRAMEnd[1][2])                      return memregion_NewSharedWRAM_C;              } -            if (NDS::SWRAM_ARM7.Mem) +            if (NDS.SWRAM_ARM7.Mem)                  return memregion_SharedWRAM;              return memregion_WRAM7;          case 0x03800000: @@ -1140,7 +1160,7 @@ int ARMJIT_Memory::ClassifyAddress7(u32 addr) const noexcept              return memregion_VWRAM;          case 0x0C000000:          case 0x0C800000: -            return (NDS::ConsoleType==1) ? memregion_MainRAM : memregion_Other; +            return (NDS.ConsoleType==1) ? memregion_MainRAM : memregion_Other;          default:              return memregion_Other;          } @@ -1163,11 +1183,11 @@ void VRAMWrite(u32 addr, T val)  {      switch (addr & 0x00E00000)      { -    case 0x00000000: NDS::GPU->WriteVRAM_ABG<T>(addr, val); return; -    case 0x00200000: NDS::GPU->WriteVRAM_BBG<T>(addr, val); return; -    case 0x00400000: NDS::GPU->WriteVRAM_AOBJ<T>(addr, val); return; -    case 0x00600000: NDS::GPU->WriteVRAM_BOBJ<T>(addr, val); return; -    default: NDS::GPU->WriteVRAM_LCDC<T>(addr, val); return; +    case 0x00000000: NDS::Current->GPU.WriteVRAM_ABG<T>(addr, val); return; +    case 0x00200000: NDS::Current->GPU.WriteVRAM_BBG<T>(addr, val); return; +    case 0x00400000: NDS::Current->GPU.WriteVRAM_AOBJ<T>(addr, val); return; +    case 0x00600000: NDS::Current->GPU.WriteVRAM_BOBJ<T>(addr, val); return; +    default: NDS::Current->GPU.WriteVRAM_LCDC<T>(addr, val); return;      }  }  template <typename T> @@ -1175,59 +1195,119 @@ T VRAMRead(u32 addr)  {      switch (addr & 0x00E00000)      { -    case 0x00000000: return NDS::GPU->ReadVRAM_ABG<T>(addr); -    case 0x00200000: return NDS::GPU->ReadVRAM_BBG<T>(addr); -    case 0x00400000: return NDS::GPU->ReadVRAM_AOBJ<T>(addr); -    case 0x00600000: return NDS::GPU->ReadVRAM_BOBJ<T>(addr); -    default: return NDS::GPU->ReadVRAM_LCDC<T>(addr); +    case 0x00000000: return NDS::Current->GPU.ReadVRAM_ABG<T>(addr); +    case 0x00200000: return NDS::Current->GPU.ReadVRAM_BBG<T>(addr); +    case 0x00400000: return NDS::Current->GPU.ReadVRAM_AOBJ<T>(addr); +    case 0x00600000: return NDS::Current->GPU.ReadVRAM_BOBJ<T>(addr); +    default: return NDS::Current->GPU.ReadVRAM_LCDC<T>(addr);      }  }  static u8 GPU3D_Read8(u32 addr) noexcept  { -    return NDS::GPU->GPU3D.Read8(addr); +    return NDS::Current->GPU.GPU3D.Read8(addr);  }  static u16 GPU3D_Read16(u32 addr) noexcept  { -    return NDS::GPU->GPU3D.Read16(addr); +    return NDS::Current->GPU.GPU3D.Read16(addr);  }  static u32 GPU3D_Read32(u32 addr) noexcept  { -    return NDS::GPU->GPU3D.Read32(addr); +    return NDS::Current->GPU.GPU3D.Read32(addr);  }  static void GPU3D_Write8(u32 addr, u8 val) noexcept  { -    NDS::GPU->GPU3D.Write8(addr, val); +    NDS::Current->GPU.GPU3D.Write8(addr, val);  }  static void GPU3D_Write16(u32 addr, u16 val) noexcept  { -    NDS::GPU->GPU3D.Write16(addr, val); +    NDS::Current->GPU.GPU3D.Write16(addr, val);  }  static void GPU3D_Write32(u32 addr, u32 val) noexcept  { -    NDS::GPU->GPU3D.Write32(addr, val); +    NDS::Current->GPU.GPU3D.Write32(addr, val);  }  template<class T>  static T GPU_ReadVRAM_ARM7(u32 addr) noexcept  { -    return NDS::GPU->ReadVRAM_ARM7<T>(addr); +    return NDS::Current->GPU.ReadVRAM_ARM7<T>(addr);  }  template<class T>  static void GPU_WriteVRAM_ARM7(u32 addr, T val) noexcept  { -    NDS::GPU->WriteVRAM_ARM7<T>(addr, val); +    NDS::Current->GPU.WriteVRAM_ARM7<T>(addr, val);  }  u32 NDSCartSlot_ReadROMData()  { // TODO: Add a NDS* parameter, when NDS* is eventually implemented -    return NDS::NDSCartSlot->ReadROMData(); +    return NDS::Current->NDSCartSlot.ReadROMData(); +} + +static u8 NDS_ARM9IORead8(u32 addr) +{ +    return NDS::Current->ARM9IORead8(addr); +} + +static u16 NDS_ARM9IORead16(u32 addr) +{ +    return NDS::Current->ARM9IORead16(addr); +} + +static u32 NDS_ARM9IORead32(u32 addr) +{ +    return NDS::Current->ARM9IORead32(addr); +} + +static void NDS_ARM9IOWrite8(u32 addr, u8 val) +{ +    NDS::Current->ARM9IOWrite8(addr, val); +} + +static void NDS_ARM9IOWrite16(u32 addr, u16 val) +{ +    NDS::Current->ARM9IOWrite16(addr, val); +} + +static void NDS_ARM9IOWrite32(u32 addr, u32 val) +{ +    NDS::Current->ARM9IOWrite32(addr, val); +} + +static u8 NDS_ARM7IORead8(u32 addr) +{ +    return NDS::Current->ARM7IORead8(addr); +} + +static u16 NDS_ARM7IORead16(u32 addr) +{ +    return NDS::Current->ARM7IORead16(addr); +} + +static u32 NDS_ARM7IORead32(u32 addr) +{ +    return NDS::Current->ARM7IORead32(addr); +} + +static void NDS_ARM7IOWrite8(u32 addr, u8 val) +{ +    NDS::Current->ARM7IOWrite8(addr, val); +} + +static void NDS_ARM7IOWrite16(u32 addr, u16 val) +{ +    NDS::Current->ARM7IOWrite16(addr, val); +} + +static void NDS_ARM7IOWrite32(u32 addr, u32 val) +{ +    NDS::Current->ARM7IOWrite32(addr, val);  }  void* ARMJIT_Memory::GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) const noexcept @@ -1237,7 +1317,7 @@ void* ARMJIT_Memory::GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) co          switch (addr & 0xFF000000)          {          case 0x04000000: -            if (!store && size == 32 && addr == 0x04100010 && NDS::ExMemCnt[0] & (1<<11)) +            if (!store && size == 32 && addr == 0x04100010 && NDS.ExMemCnt[0] & (1<<11))                  return (void*)NDSCartSlot_ReadROMData;              /* @@ -1259,30 +1339,17 @@ void* ARMJIT_Memory::GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) co                  }              } -            if (NDS::ConsoleType == 0) -            { -                switch (size | store) -                { -                case 8: return (void*)NDS::ARM9IORead8; -                case 9: return (void*)NDS::ARM9IOWrite8; -                case 16: return (void*)NDS::ARM9IORead16; -                case 17: return (void*)NDS::ARM9IOWrite16; -                case 32: return (void*)NDS::ARM9IORead32; -                case 33: return (void*)NDS::ARM9IOWrite32; -                } -            } -            else +            switch (size | store)              { -                switch (size | store) -                { -                case 8: return (void*)DSi::ARM9IORead8; -                case 9: return (void*)DSi::ARM9IOWrite8; -                case 16: return (void*)DSi::ARM9IORead16; -                case 17: return (void*)DSi::ARM9IOWrite16; -                case 32: return (void*)DSi::ARM9IORead32; -                case 33: return (void*)DSi::ARM9IOWrite32; -                } +            case 8: return (void*)NDS_ARM9IORead8; +            case 9: return (void*)NDS_ARM9IOWrite8; +            case 16: return (void*)NDS_ARM9IORead16; +            case 17: return (void*)NDS_ARM9IOWrite16; +            case 32: return (void*)NDS_ARM9IORead32; +            case 33: return (void*)NDS_ARM9IOWrite32;              } +            // NDS::Current will delegate to the DSi versions of these methods +            // if it's really a DSi              break;          case 0x06000000:              switch (size | store) @@ -1315,29 +1382,14 @@ void* ARMJIT_Memory::GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) co                  }              }*/ -            if (NDS::ConsoleType == 0) -            { -                switch (size | store) -                { -                case 8: return (void*)NDS::ARM7IORead8; -                case 9: return (void*)NDS::ARM7IOWrite8; -                case 16: return (void*)NDS::ARM7IORead16; -                case 17: return (void*)NDS::ARM7IOWrite16; -                case 32: return (void*)NDS::ARM7IORead32; -                case 33: return (void*)NDS::ARM7IOWrite32; -                } -            } -            else +            switch (size | store)              { -                switch (size | store) -                { -                case 8: return (void*)DSi::ARM7IORead8; -                case 9: return (void*)DSi::ARM7IOWrite8; -                case 16: return (void*)DSi::ARM7IORead16; -                case 17: return (void*)DSi::ARM7IOWrite16; -                case 32: return (void*)DSi::ARM7IORead32; -                case 33: return (void*)DSi::ARM7IOWrite32; -                } +            case 8: return (void*)NDS_ARM7IORead8; +            case 9: return (void*)NDS_ARM7IOWrite8; +            case 16: return (void*)NDS_ARM7IORead16; +            case 17: return (void*)NDS_ARM7IOWrite16; +            case 32: return (void*)NDS_ARM7IORead32; +            case 33: return (void*)NDS_ARM7IOWrite32;              }              break;              // TODO: the wifi funcs also ought to check POWCNT diff --git a/src/ARMJIT_Memory.h b/src/ARMJIT_Memory.h index ed48437..487005b 100644 --- a/src/ARMJIT_Memory.h +++ b/src/ARMJIT_Memory.h @@ -23,7 +23,7 @@  #include "TinyVector.h"  #include "ARM.h" -#include "DSi.h" +#include "MemConstants.h"  #if defined(__SWITCH__)  #include <switch.h> @@ -44,6 +44,7 @@  namespace melonDS  { +namespace Platform { struct DynamicLibrary; }  class Compiler;  class ARMJIT; @@ -57,13 +58,13 @@ constexpr u32 RoundUp(u32 size) noexcept  }  const u32 MemBlockMainRAMOffset = 0; -const u32 MemBlockSWRAMOffset = RoundUp(NDS::MainRAMMaxSize); -const u32 MemBlockARM7WRAMOffset = MemBlockSWRAMOffset + RoundUp(NDS::SharedWRAMSize); -const u32 MemBlockDTCMOffset = MemBlockARM7WRAMOffset + RoundUp(NDS::ARM7WRAMSize); +const u32 MemBlockSWRAMOffset = RoundUp(MainRAMMaxSize); +const u32 MemBlockARM7WRAMOffset = MemBlockSWRAMOffset + RoundUp(SharedWRAMSize); +const u32 MemBlockDTCMOffset = MemBlockARM7WRAMOffset + RoundUp(ARM7WRAMSize);  const u32 MemBlockNWRAM_AOffset = MemBlockDTCMOffset + RoundUp(DTCMPhysicalSize); -const u32 MemBlockNWRAM_BOffset = MemBlockNWRAM_AOffset + RoundUp(DSi::NWRAMSize); -const u32 MemBlockNWRAM_COffset = MemBlockNWRAM_BOffset + RoundUp(DSi::NWRAMSize); -const u32 MemoryTotalSize = MemBlockNWRAM_COffset + RoundUp(DSi::NWRAMSize); +const u32 MemBlockNWRAM_BOffset = MemBlockNWRAM_AOffset + RoundUp(NWRAMSize); +const u32 MemBlockNWRAM_COffset = MemBlockNWRAM_BOffset + RoundUp(NWRAMSize); +const u32 MemoryTotalSize = MemBlockNWRAM_COffset + RoundUp(NWRAMSize);  class ARMJIT_Memory  { @@ -96,7 +97,7 @@ public:  #ifdef JIT_ENABLED  public: -    explicit ARMJIT_Memory(ARMJIT& jit) noexcept; +    explicit ARMJIT_Memory(melonDS::NDS& nds);      ~ARMJIT_Memory() noexcept;      ARMJIT_Memory(const ARMJIT_Memory&) = delete;      ARMJIT_Memory(ARMJIT_Memory&&) = delete; @@ -144,7 +145,7 @@ private:          u32 Size, LocalOffset;          u32 Num; -        void Unmap(int region, ARMJIT_Memory& memory) noexcept; +        void Unmap(int region, NDS& nds) noexcept;      };      struct FaultDescription @@ -152,12 +153,12 @@ private:          u32 EmulatedFaultAddr;          u8* FaultPC;      }; -    static bool FaultHandler(FaultDescription& faultDesc, ARMJIT& jit); +    static bool FaultHandler(FaultDescription& faultDesc, melonDS::NDS& nds);      bool MapIntoRange(u32 addr, u32 num, u32 offset, u32 size) noexcept;      bool UnmapFromRange(u32 addr, u32 num, u32 offset, u32 size) noexcept;      void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection) noexcept; -    ARMJIT& JIT; +    melonDS::NDS& NDS;      void* FastMem9Start;      void* FastMem7Start;      u8* MemoryBase = nullptr; @@ -180,7 +181,7 @@ private:      TinyVector<Mapping> Mappings[memregions_Count] {};  #else  public: -    explicit ARMJIT_Memory(ARMJIT&) {}; +    explicit ARMJIT_Memory(melonDS::NDS&) {};      ~ARMJIT_Memory() = default;      ARMJIT_Memory(const ARMJIT_Memory&) = delete;      ARMJIT_Memory(ARMJIT_Memory&&) = delete; @@ -214,13 +215,13 @@ public:      [[nodiscard]] u8* GetNWRAM_C() noexcept { return NWRAM_C.data(); }      [[nodiscard]] const u8* GetNWRAM_C() const noexcept { return NWRAM_C.data(); }  private: -    std::array<u8, NDS::MainRAMMaxSize> MainRAM {}; -    std::array<u8, NDS::ARM7WRAMSize> ARM7WRAM {}; -    std::array<u8, NDS::SharedWRAMSize> SharedWRAM {}; +    std::array<u8, MainRAMMaxSize> MainRAM {}; +    std::array<u8, ARM7WRAMSize> ARM7WRAM {}; +    std::array<u8, SharedWRAMSize> SharedWRAM {};      std::array<u8, DTCMPhysicalSize> DTCM {}; -    std::array<u8, DSi::NWRAMSize> NWRAM_A {}; -    std::array<u8, DSi::NWRAMSize> NWRAM_B {}; -    std::array<u8, DSi::NWRAMSize> NWRAM_C {}; +    std::array<u8, NWRAMSize> NWRAM_A {}; +    std::array<u8, NWRAMSize> NWRAM_B {}; +    std::array<u8, NWRAMSize> NWRAM_C {};  #endif  };  } diff --git a/src/ARMJIT_x64/ARMJIT_Branch.cpp b/src/ARMJIT_x64/ARMJIT_Branch.cpp index 5d76447..f7a01f4 100644 --- a/src/ARMJIT_x64/ARMJIT_Branch.cpp +++ b/src/ARMJIT_x64/ARMJIT_Branch.cpp @@ -18,6 +18,7 @@  #include "ARMJIT_Compiler.h"  #include "../ARM.h" +#include "../NDS.h"  using namespace Gen; @@ -120,7 +121,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles)              u32 compileTimePC = CurCPU->R[15];              CurCPU->R[15] = newPC; -            cycles += NDS::ARM7MemTimings[codeCycles][0] + NDS::ARM7MemTimings[codeCycles][1]; +            cycles += NDS.ARM7MemTimings[codeCycles][0] + NDS.ARM7MemTimings[codeCycles][1];              CurCPU->R[15] = compileTimePC;          } @@ -132,7 +133,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles)              u32 compileTimePC = CurCPU->R[15];              CurCPU->R[15] = newPC; -            cycles += NDS::ARM7MemTimings[codeCycles][2] + NDS::ARM7MemTimings[codeCycles][3]; +            cycles += NDS.ARM7MemTimings[codeCycles][2] + NDS.ARM7MemTimings[codeCycles][3];              CurCPU->R[15] = compileTimePC;          } diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp index 9fc7237..eec4d7d 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp +++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp @@ -20,6 +20,7 @@  #include "../ARMJIT.h"  #include "../ARMInterpreter.h" +#include "../NDS.h"  #include <assert.h>  #include <stdarg.h> @@ -234,7 +235,7 @@ void Compiler::A_Comp_MSR()   */  u8 CodeMemory[1024 * 1024 * 32]; -Compiler::Compiler(ARMJIT& jit) : XEmitter(), JIT(jit) +Compiler::Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds)  {      {      #ifdef _WIN32 @@ -714,12 +715,12 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]      if (NearSize - (GetCodePtr() - NearStart) < 1024 * 32) // guess...      {          Log(LogLevel::Debug, "near reset\n"); -        JIT.ResetBlockCache(); +        NDS.JIT.ResetBlockCache();      }      if (FarSize - (FarCode - FarStart) < 1024 * 32) // guess...      {          Log(LogLevel::Debug, "far reset\n"); -        JIT.ResetBlockCache(); +        NDS.JIT.ResetBlockCache();      }      ConstantCycles = 0; @@ -863,7 +864,7 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]  void Compiler::Comp_AddCycles_C(bool forceNonConstant)  {      s32 cycles = Num ? -        NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 1 : 3] +        NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 1 : 3]          : ((R15 & 0x2) ? 0 : CurInstr.CodeCycles);      if ((!Thumb && CurInstr.Cond() < 0xE) || forceNonConstant) @@ -875,7 +876,7 @@ void Compiler::Comp_AddCycles_C(bool forceNonConstant)  void Compiler::Comp_AddCycles_CI(u32 i)  {      s32 cycles = (Num ? -        NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2] +        NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]          : ((R15 & 0x2) ? 0 : CurInstr.CodeCycles)) + i;      if (!Thumb && CurInstr.Cond() < 0xE) @@ -887,7 +888,7 @@ void Compiler::Comp_AddCycles_CI(u32 i)  void Compiler::Comp_AddCycles_CI(Gen::X64Reg i, int add)  {      s32 cycles = Num ? -        NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2] +        NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]          : ((R15 & 0x2) ? 0 : CurInstr.CodeCycles);      if (!Thumb && CurInstr.Cond() < 0xE) @@ -912,7 +913,7 @@ void Compiler::Comp_AddCycles_CDI()          s32 cycles; -        s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]; +        s32 numC = NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2];          s32 numD = CurInstr.DataCycles;          if ((CurInstr.DataRegion >> 24) == 0x02) // mainRAM @@ -957,7 +958,7 @@ void Compiler::Comp_AddCycles_CD()      }      else      { -        s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]; +        s32 numC = NDS.ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2];          s32 numD = CurInstr.DataCycles;          if ((CurInstr.DataRegion >> 4) == 0x02) diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.h b/src/ARMJIT_x64/ARMJIT_Compiler.h index f38a6c3..fa6d78a 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.h +++ b/src/ARMJIT_x64/ARMJIT_Compiler.h @@ -35,6 +35,7 @@ namespace melonDS  {  class ARMJIT;  class ARMJIT_Memory; +class NDS;  const Gen::X64Reg RCPU = Gen::RBP;  const Gen::X64Reg RCPSR = Gen::R15; @@ -81,9 +82,9 @@ class Compiler : public Gen::XEmitter  {  public:  #ifdef JIT_ENABLED -    explicit Compiler(ARMJIT& jit); +    explicit Compiler(melonDS::NDS& nds);  #else -    explicit Compiler(ARMJIT& jit) : XEmitter(), JIT(jit) {} +    explicit Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds) {}  #endif      void Reset(); @@ -243,7 +244,7 @@ public:      void CreateMethod(const char* namefmt, void* start, ...);  #endif -    ARMJIT& JIT; +    melonDS::NDS& NDS;      u8* FarCode {};      u8* NearCode {};      u32 FarSize {}; diff --git a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp index 9b7d865..72a073d 100644 --- a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp @@ -18,6 +18,7 @@  #include "ARMJIT_Compiler.h"  #include "../ARMJIT.h" +#include "../NDS.h"  using namespace Gen; @@ -68,9 +69,9 @@ u8* Compiler::RewriteMemAccess(u8* pc)  bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr)  { -    u32 localAddr = JIT.LocaliseCodeAddress(Num, addr); +    u32 localAddr = NDS.JIT.LocaliseCodeAddress(Num, addr); -    int invalidLiteralIdx = JIT.InvalidLiterals.Find(localAddr); +    int invalidLiteralIdx = NDS.JIT.InvalidLiterals.Find(localAddr);      if (invalidLiteralIdx != -1)      {          return false; @@ -118,7 +119,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag      if (size == 16)          addressMask = ~1; -    if (JIT.LiteralOptimizations && rn == 15 && rd != 15 && op2.IsImm && !(flags & (memop_Post|memop_Store|memop_Writeback))) +    if (NDS.JIT.LiteralOptimizations && rn == 15 && rd != 15 && op2.IsImm && !(flags & (memop_Post|memop_Store|memop_Writeback)))      {          u32 addr = R15 + op2.Imm * ((flags & memop_SubtractOffset) ? -1 : 1); @@ -135,7 +136,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag          Comp_AddCycles_CDI();      } -    bool addrIsStatic = JIT.LiteralOptimizations +    bool addrIsStatic = NDS.JIT.LiteralOptimizations          && RegCache.IsLiteral(rn) && op2.IsImm && !(flags & (memop_Writeback|memop_Post));      u32 staticAddress;      if (addrIsStatic) @@ -196,10 +197,10 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag          MOV(32, rnMapped, R(finalAddr));      u32 expectedTarget = Num == 0 -        ? JIT.Memory.ClassifyAddress9(CurInstr.DataRegion) -        : JIT.Memory.ClassifyAddress7(CurInstr.DataRegion); +        ? NDS.JIT.Memory.ClassifyAddress9(CurInstr.DataRegion) +        : NDS.JIT.Memory.ClassifyAddress7(CurInstr.DataRegion); -    if (JIT.FastMemory && ((!Thumb && CurInstr.Cond() != 0xE) || JIT.Memory.IsFastmemCompatible(expectedTarget))) +    if (NDS.JIT.FastMemory && ((!Thumb && CurInstr.Cond() != 0xE) || NDS.JIT.Memory.IsFastmemCompatible(expectedTarget)))      {          if (rdMapped.IsImm())          { @@ -212,12 +213,12 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag          assert(rdMapped.GetSimpleReg() >= 0 && rdMapped.GetSimpleReg() < 16);          patch.PatchFunc = flags & memop_Store -            ? PatchedStoreFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped.GetSimpleReg()] -            : PatchedLoadFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped.GetSimpleReg()]; +            ? PatchedStoreFuncs[NDS.ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped.GetSimpleReg()] +            : PatchedLoadFuncs[NDS.ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped.GetSimpleReg()];          assert(patch.PatchFunc != NULL); -        MOV(64, R(RSCRATCH), ImmPtr(Num == 0 ? JIT.Memory.FastMem9Start : JIT.Memory.FastMem7Start)); +        MOV(64, R(RSCRATCH), ImmPtr(Num == 0 ? NDS.JIT.Memory.FastMem9Start : NDS.JIT.Memory.FastMem7Start));          X64Reg maskedAddr = RSCRATCH3;          if (size > 8) @@ -268,7 +269,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag          void* func = NULL;          if (addrIsStatic) -            func = JIT.Memory.GetFuncForAddr(CurCPU, staticAddress, flags & memop_Store, size); +            func = NDS.JIT.Memory.GetFuncForAddr(CurCPU, staticAddress, flags & memop_Store, size);          if (func)          { @@ -313,7 +314,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag                      MOV(32, R(ABI_PARAM1), R(RSCRATCH3));                  if (flags & memop_Store)                  { -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: CALL((void*)&SlowWrite9<u32, 0>); break;                      case 16: CALL((void*)&SlowWrite9<u16, 0>); break; @@ -325,7 +326,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag                  }                  else                  { -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: CALL((void*)&SlowRead9<u32, 0>); break;                      case 16: CALL((void*)&SlowRead9<u16, 0>); break; @@ -344,7 +345,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag                  {                      MOV(32, R(ABI_PARAM2), rdMapped); -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: CALL((void*)&SlowWrite7<u32, 0>); break;                      case 16: CALL((void*)&SlowWrite7<u16, 0>); break; @@ -356,7 +357,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag                  }                  else                  { -                    switch (size | NDS::ConsoleType) +                    switch (size | NDS.ConsoleType)                      {                      case 32: CALL((void*)&SlowRead7<u32, 0>); break;                      case 16: CALL((void*)&SlowRead7<u16, 0>); break; @@ -422,16 +423,16 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc      s32 offset = (regsCount * 4) * (decrement ? -1 : 1);      int expectedTarget = Num == 0 -        ? JIT.Memory.ClassifyAddress9(CurInstr.DataRegion) -        : JIT.Memory.ClassifyAddress7(CurInstr.DataRegion); +        ? NDS.JIT.Memory.ClassifyAddress9(CurInstr.DataRegion) +        : NDS.JIT.Memory.ClassifyAddress7(CurInstr.DataRegion);      if (!store)          Comp_AddCycles_CDI();      else          Comp_AddCycles_CD(); -    bool compileFastPath = JIT.FastMemory -        && !usermode && (CurInstr.Cond() < 0xE || JIT.Memory.IsFastmemCompatible(expectedTarget)); +    bool compileFastPath = NDS.JIT.FastMemory +        && !usermode && (CurInstr.Cond() < 0xE || NDS.JIT.Memory.IsFastmemCompatible(expectedTarget));      // we need to make sure that the stack stays aligned to 16 bytes  #ifdef _WIN32 @@ -454,7 +455,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc          u8* fastPathStart = GetWritableCodePtr();          u8* loadStoreAddr[16]; -        MOV(64, R(RSCRATCH2), ImmPtr(Num == 0 ? JIT.Memory.FastMem9Start : JIT.Memory.FastMem7Start)); +        MOV(64, R(RSCRATCH2), ImmPtr(Num == 0 ? NDS.JIT.Memory.FastMem9Start : NDS.JIT.Memory.FastMem7Start));          ADD(64, R(RSCRATCH2), R(RSCRATCH4));          u32 offset = 0; @@ -523,7 +524,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc          if (Num == 0)              MOV(64, R(ABI_PARAM4), R(RCPU)); -        switch (Num * 2 | NDS::ConsoleType) +        switch (Num * 2 | NDS.ConsoleType)          {          case 0: CALL((void*)&SlowBlockTransfer9<false, 0>); break;          case 1: CALL((void*)&SlowBlockTransfer9<false, 1>); break; @@ -627,7 +628,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc          if (Num == 0)              MOV(64, R(ABI_PARAM4), R(RCPU)); -        switch (Num * 2 | NDS::ConsoleType) +        switch (Num * 2 | NDS.ConsoleType)          {          case 0: CALL((void*)&SlowBlockTransfer9<true, 0>); break;          case 1: CALL((void*)&SlowBlockTransfer9<true, 1>); break; @@ -808,7 +809,7 @@ void Compiler::T_Comp_LoadPCRel()  {      u32 offset = (CurInstr.Instr & 0xFF) << 2;      u32 addr = (R15 & ~0x2) + offset; -    if (!JIT.LiteralOptimizations || !Comp_MemLoadLiteral(32, false, CurInstr.T_Reg(8), addr)) +    if (!NDS.JIT.LiteralOptimizations || !Comp_MemLoadLiteral(32, false, CurInstr.T_Reg(8), addr))          Comp_MemAccess(CurInstr.T_Reg(8), 15, Op2(offset), 32, 0);  } diff --git a/src/CP15.cpp b/src/CP15.cpp index af23da3..7cea845 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -124,7 +124,7 @@ void ARMv5::UpdateDTCMSetting()      if (newDTCMBase != DTCMBase || newDTCMMask != DTCMMask)      { -        JIT.Memory.RemapDTCM(newDTCMBase, newDTCMSize); +        NDS.JIT.Memory.RemapDTCM(newDTCMBase, newDTCMSize);          DTCMBase = newDTCMBase;          DTCMMask = newDTCMMask;      } @@ -295,7 +295,7 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)      for (u32 i = addrstart; i < addrend; i++)      {          u8 pu = PU_Map[i]; -        u8* bustimings = NDS::ARM9MemTimings[i >> 2]; +        u8* bustimings = NDS.ARM9MemTimings[i >> 2];          if (pu & 0x40)          { @@ -303,7 +303,7 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)          }          else          { -            MemTimings[i][0] = bustimings[2] << NDS::ARM9ClockShift; +            MemTimings[i][0] = bustimings[2] << NDS.ARM9ClockShift;          }          if (pu & 0x10) @@ -314,9 +314,9 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)          }          else          { -            MemTimings[i][1] = bustimings[0] << NDS::ARM9ClockShift; -            MemTimings[i][2] = bustimings[2] << NDS::ARM9ClockShift; -            MemTimings[i][3] = bustimings[3] << NDS::ARM9ClockShift; +            MemTimings[i][1] = bustimings[0] << NDS.ARM9ClockShift; +            MemTimings[i][2] = bustimings[2] << NDS.ARM9ClockShift; +            MemTimings[i][3] = bustimings[3] << NDS.ARM9ClockShift;          }      }  } @@ -388,14 +388,14 @@ void ARMv5::ICacheLookup(u32 addr)      else      {          for (int i = 0; i < 32; i+=4) -            *(u32*)&ptr[i] = NDS::ARM9Read32(addr+i); +            *(u32*)&ptr[i] = NDS.ARM9Read32(addr+i);      }      ICacheTags[line] = tag;      // ouch :/      //printf("cache miss %08X: %d/%d\n", addr, NDS::ARM9MemTimings[addr >> 14][2], NDS::ARM9MemTimings[addr >> 14][3]); -    CodeCycles = (NDS::ARM9MemTimings[addr >> 14][2] + (NDS::ARM9MemTimings[addr >> 14][3] * 7)) << NDS::ARM9ClockShift; +    CodeCycles = (NDS.ARM9MemTimings[addr >> 14][2] + (NDS.ARM9MemTimings[addr >> 14][3] * 7)) << NDS.ARM9ClockShift;      CurICacheLine = ptr;  } @@ -923,7 +923,7 @@ void ARMv5::DataWrite8(u32 addr, u8 val)      {          DataCycles = 1;          *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; -        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +        NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);          return;      }      if ((addr & DTCMMask) == DTCMBase) @@ -953,7 +953,7 @@ void ARMv5::DataWrite16(u32 addr, u16 val)      {          DataCycles = 1;          *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; -        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +        NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);          return;      }      if ((addr & DTCMMask) == DTCMBase) @@ -983,7 +983,7 @@ void ARMv5::DataWrite32(u32 addr, u32 val)      {          DataCycles = 1;          *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; -        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +        NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);          return;      }      if ((addr & DTCMMask) == DTCMBase) @@ -1006,7 +1006,7 @@ void ARMv5::DataWrite32S(u32 addr, u32 val)          DataCycles += 1;          *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;  #ifdef JIT_ENABLED -        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +        NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);  #endif          return;      } @@ -1021,7 +1021,7 @@ void ARMv5::DataWrite32S(u32 addr, u32 val)      DataCycles += MemTimings[addr >> 12][3];  } -void ARMv5::GetCodeMemRegion(u32 addr, NDS::MemRegion* region) +void ARMv5::GetCodeMemRegion(u32 addr, MemRegion* region)  {      /*if (addr < ITCMSize)      { @@ -1030,7 +1030,7 @@ void ARMv5::GetCodeMemRegion(u32 addr, NDS::MemRegion* region)          return;      }*/ -    GetMemRegion(addr, false, &CodeMem); +    NDS.ARM9GetMemRegion(addr, false, &CodeMem);  }  } diff --git a/src/DMA.cpp b/src/DMA.cpp index 8afc897..717b38f 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -49,10 +49,10 @@ using Platform::LogLevel;  // TODO: timings are nonseq when address is fixed/decrementing -DMA::DMA(u32 cpu, u32 num, melonDS::GPU& gpu) : +DMA::DMA(u32 cpu, u32 num, melonDS::NDS& nds) :      CPU(cpu),      Num(num), -    GPU(gpu) +    NDS(nds)  {      if (cpu == 0)          CountMask = 0x001FFFFF; @@ -145,7 +145,7 @@ void DMA::WriteCnt(u32 val)          if ((StartMode & 0x7) == 0)              Start();          else if (StartMode == 0x07) -            GPU.GPU3D.CheckFIFODMA(); +            NDS.GPU.GPU3D.CheckFIFODMA();          if (StartMode==0x06 || StartMode==0x13)              Log(LogLevel::Warn, "UNIMPLEMENTED ARM%d DMA%d START MODE %02X, %08X->%08X\n", CPU?7:9, Num, StartMode, SrcAddr, DstAddr); @@ -192,7 +192,7 @@ void DMA::Start()      MRAMBurstTable = DMATiming::MRAMDummy;      InProgress = true; -    NDS::StopCPU(CPU, 1<<Num); +    NDS.StopCPU(CPU, 1<<Num);  }  u32 DMA::UnitTimings9_16(bool burststart) @@ -200,18 +200,18 @@ u32 DMA::UnitTimings9_16(bool burststart)      u32 src_id = CurSrcAddr >> 14;      u32 dst_id = CurDstAddr >> 14; -    u32 src_rgn = NDS::ARM9Regions[src_id]; -    u32 dst_rgn = NDS::ARM9Regions[dst_id]; +    u32 src_rgn = NDS.ARM9Regions[src_id]; +    u32 dst_rgn = NDS.ARM9Regions[dst_id];      u32 src_n, src_s, dst_n, dst_s; -    src_n = NDS::ARM9MemTimings[src_id][4]; -    src_s = NDS::ARM9MemTimings[src_id][5]; -    dst_n = NDS::ARM9MemTimings[dst_id][4]; -    dst_s = NDS::ARM9MemTimings[dst_id][5]; +    src_n = NDS.ARM9MemTimings[src_id][4]; +    src_s = NDS.ARM9MemTimings[src_id][5]; +    dst_n = NDS.ARM9MemTimings[dst_id][4]; +    dst_s = NDS.ARM9MemTimings[dst_id][5]; -    if (src_rgn == NDS::Mem9_MainRAM) +    if (src_rgn == Mem9_MainRAM)      { -        if (dst_rgn == NDS::Mem9_MainRAM) +        if (dst_rgn == Mem9_MainRAM)              return 16;          if (SrcAddrInc > 0) @@ -220,7 +220,7 @@ u32 DMA::UnitTimings9_16(bool burststart)              {                  MRAMBurstCount = 0; -                if (dst_rgn == NDS::Mem9_GBAROM) +                if (dst_rgn == Mem9_GBAROM)                  {                      if (dst_s == 4)                          MRAMBurstTable = DMATiming::MRAMRead16Bursts[1]; @@ -241,7 +241,7 @@ u32 DMA::UnitTimings9_16(bool burststart)                     (burststart ? dst_n : dst_s);          }      } -    else if (dst_rgn == NDS::Mem9_MainRAM) +    else if (dst_rgn == Mem9_MainRAM)      {          if (DstAddrInc > 0)          { @@ -249,7 +249,7 @@ u32 DMA::UnitTimings9_16(bool burststart)              {                  MRAMBurstCount = 0; -                if (src_rgn == NDS::Mem9_GBAROM) +                if (src_rgn == Mem9_GBAROM)                  {                      if (src_s == 4)                          MRAMBurstTable = DMATiming::MRAMWrite16Bursts[1]; @@ -286,18 +286,18 @@ u32 DMA::UnitTimings9_32(bool burststart)      u32 src_id = CurSrcAddr >> 14;      u32 dst_id = CurDstAddr >> 14; -    u32 src_rgn = NDS::ARM9Regions[src_id]; -    u32 dst_rgn = NDS::ARM9Regions[dst_id]; +    u32 src_rgn = NDS.ARM9Regions[src_id]; +    u32 dst_rgn = NDS.ARM9Regions[dst_id];      u32 src_n, src_s, dst_n, dst_s; -    src_n = NDS::ARM9MemTimings[src_id][6]; -    src_s = NDS::ARM9MemTimings[src_id][7]; -    dst_n = NDS::ARM9MemTimings[dst_id][6]; -    dst_s = NDS::ARM9MemTimings[dst_id][7]; +    src_n = NDS.ARM9MemTimings[src_id][6]; +    src_s = NDS.ARM9MemTimings[src_id][7]; +    dst_n = NDS.ARM9MemTimings[dst_id][6]; +    dst_s = NDS.ARM9MemTimings[dst_id][7]; -    if (src_rgn == NDS::Mem9_MainRAM) +    if (src_rgn == Mem9_MainRAM)      { -        if (dst_rgn == NDS::Mem9_MainRAM) +        if (dst_rgn == Mem9_MainRAM)              return 18;          if (SrcAddrInc > 0) @@ -306,7 +306,7 @@ u32 DMA::UnitTimings9_32(bool burststart)              {                  MRAMBurstCount = 0; -                if (dst_rgn == NDS::Mem9_GBAROM) +                if (dst_rgn == Mem9_GBAROM)                  {                      if (dst_s == 8)                          MRAMBurstTable = DMATiming::MRAMRead32Bursts[2]; @@ -329,7 +329,7 @@ u32 DMA::UnitTimings9_32(bool burststart)                     (burststart ? dst_n : dst_s);          }      } -    else if (dst_rgn == NDS::Mem9_MainRAM) +    else if (dst_rgn == Mem9_MainRAM)      {          if (DstAddrInc > 0)          { @@ -337,7 +337,7 @@ u32 DMA::UnitTimings9_32(bool burststart)              {                  MRAMBurstCount = 0; -                if (src_rgn == NDS::Mem9_GBAROM) +                if (src_rgn == Mem9_GBAROM)                  {                      if (src_s == 8)                          MRAMBurstTable = DMATiming::MRAMWrite32Bursts[2]; @@ -378,18 +378,18 @@ u32 DMA::UnitTimings7_16(bool burststart)      u32 src_id = CurSrcAddr >> 15;      u32 dst_id = CurDstAddr >> 15; -    u32 src_rgn = NDS::ARM7Regions[src_id]; -    u32 dst_rgn = NDS::ARM7Regions[dst_id]; +    u32 src_rgn = NDS.ARM7Regions[src_id]; +    u32 dst_rgn = NDS.ARM7Regions[dst_id];      u32 src_n, src_s, dst_n, dst_s; -    src_n = NDS::ARM7MemTimings[src_id][0]; -    src_s = NDS::ARM7MemTimings[src_id][1]; -    dst_n = NDS::ARM7MemTimings[dst_id][0]; -    dst_s = NDS::ARM7MemTimings[dst_id][1]; +    src_n = NDS.ARM7MemTimings[src_id][0]; +    src_s = NDS.ARM7MemTimings[src_id][1]; +    dst_n = NDS.ARM7MemTimings[dst_id][0]; +    dst_s = NDS.ARM7MemTimings[dst_id][1]; -    if (src_rgn == NDS::Mem7_MainRAM) +    if (src_rgn == Mem7_MainRAM)      { -        if (dst_rgn == NDS::Mem7_MainRAM) +        if (dst_rgn == Mem7_MainRAM)              return 16;          if (SrcAddrInc > 0) @@ -398,7 +398,7 @@ u32 DMA::UnitTimings7_16(bool burststart)              {                  MRAMBurstCount = 0; -                if (dst_rgn == NDS::Mem7_GBAROM || dst_rgn == NDS::Mem7_Wifi0 || dst_rgn == NDS::Mem7_Wifi1) +                if (dst_rgn == Mem7_GBAROM || dst_rgn == Mem7_Wifi0 || dst_rgn == Mem7_Wifi1)                  {                      if (dst_s == 4)                          MRAMBurstTable = DMATiming::MRAMRead16Bursts[1]; @@ -419,7 +419,7 @@ u32 DMA::UnitTimings7_16(bool burststart)                     (burststart ? dst_n : dst_s);          }      } -    else if (dst_rgn == NDS::Mem7_MainRAM) +    else if (dst_rgn == Mem7_MainRAM)      {          if (DstAddrInc > 0)          { @@ -427,7 +427,7 @@ u32 DMA::UnitTimings7_16(bool burststart)              {                  MRAMBurstCount = 0; -                if (src_rgn == NDS::Mem7_GBAROM || src_rgn == NDS::Mem7_Wifi0 || src_rgn == NDS::Mem7_Wifi1) +                if (src_rgn == Mem7_GBAROM || src_rgn == Mem7_Wifi0 || src_rgn == Mem7_Wifi1)                  {                      if (src_s == 4)                          MRAMBurstTable = DMATiming::MRAMWrite16Bursts[1]; @@ -464,18 +464,18 @@ u32 DMA::UnitTimings7_32(bool burststart)      u32 src_id = CurSrcAddr >> 15;      u32 dst_id = CurDstAddr >> 15; -    u32 src_rgn = NDS::ARM7Regions[src_id]; -    u32 dst_rgn = NDS::ARM7Regions[dst_id]; +    u32 src_rgn = NDS.ARM7Regions[src_id]; +    u32 dst_rgn = NDS.ARM7Regions[dst_id];      u32 src_n, src_s, dst_n, dst_s; -    src_n = NDS::ARM7MemTimings[src_id][2]; -    src_s = NDS::ARM7MemTimings[src_id][3]; -    dst_n = NDS::ARM7MemTimings[dst_id][2]; -    dst_s = NDS::ARM7MemTimings[dst_id][3]; +    src_n = NDS.ARM7MemTimings[src_id][2]; +    src_s = NDS.ARM7MemTimings[src_id][3]; +    dst_n = NDS.ARM7MemTimings[dst_id][2]; +    dst_s = NDS.ARM7MemTimings[dst_id][3]; -    if (src_rgn == NDS::Mem7_MainRAM) +    if (src_rgn == Mem7_MainRAM)      { -        if (dst_rgn == NDS::Mem7_MainRAM) +        if (dst_rgn == Mem7_MainRAM)              return 18;          if (SrcAddrInc > 0) @@ -484,7 +484,7 @@ u32 DMA::UnitTimings7_32(bool burststart)              {                  MRAMBurstCount = 0; -                if (dst_rgn == NDS::Mem7_GBAROM || dst_rgn == NDS::Mem7_Wifi0 || dst_rgn == NDS::Mem7_Wifi1) +                if (dst_rgn == Mem7_GBAROM || dst_rgn == Mem7_Wifi0 || dst_rgn == Mem7_Wifi1)                  {                      if (dst_s == 8)                          MRAMBurstTable = DMATiming::MRAMRead32Bursts[2]; @@ -507,7 +507,7 @@ u32 DMA::UnitTimings7_32(bool burststart)                     (burststart ? dst_n : dst_s);          }      } -    else if (dst_rgn == NDS::Mem7_MainRAM) +    else if (dst_rgn == Mem7_MainRAM)      {          if (DstAddrInc > 0)          { @@ -515,7 +515,7 @@ u32 DMA::UnitTimings7_32(bool burststart)              {                  MRAMBurstCount = 0; -                if (src_rgn == NDS::Mem7_GBAROM || src_rgn == NDS::Mem7_Wifi0 || src_rgn == NDS::Mem7_Wifi1) +                if (src_rgn == Mem7_GBAROM || src_rgn == Mem7_Wifi0 || src_rgn == Mem7_Wifi1)                  {                      if (src_s == 8)                          MRAMBurstTable = DMATiming::MRAMWrite32Bursts[2]; @@ -549,10 +549,9 @@ u32 DMA::UnitTimings7_32(bool burststart)      }  } -template <int ConsoleType>  void DMA::Run9()  { -    if (NDS::ARM9Timestamp >= NDS::ARM9Target) return; +    if (NDS.ARM9Timestamp >= NDS.ARM9Target) return;      Executing = true; @@ -564,40 +563,34 @@ void DMA::Run9()      {          while (IterCount > 0 && !Stall)          { -            NDS::ARM9Timestamp += (UnitTimings9_16(burststart) << NDS::ARM9ClockShift); +            NDS.ARM9Timestamp += (UnitTimings9_16(burststart) << NDS.ARM9ClockShift);              burststart = false; -            if (ConsoleType == 1) -                DSi::ARM9Write16(CurDstAddr, DSi::ARM9Read16(CurSrcAddr)); -            else -                NDS::ARM9Write16(CurDstAddr, NDS::ARM9Read16(CurSrcAddr)); +            NDS.ARM9Write16(CurDstAddr, NDS.ARM9Read16(CurSrcAddr));              CurSrcAddr += SrcAddrInc<<1;              CurDstAddr += DstAddrInc<<1;              IterCount--;              RemCount--; -            if (NDS::ARM9Timestamp >= NDS::ARM9Target) break; +            if (NDS.ARM9Timestamp >= NDS.ARM9Target) break;          }      }      else      {          while (IterCount > 0 && !Stall)          { -            NDS::ARM9Timestamp += (UnitTimings9_32(burststart) << NDS::ARM9ClockShift); +            NDS.ARM9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift);              burststart = false; -            if (ConsoleType == 1) -                DSi::ARM9Write32(CurDstAddr, DSi::ARM9Read32(CurSrcAddr)); -            else -                NDS::ARM9Write32(CurDstAddr, NDS::ARM9Read32(CurSrcAddr)); +            NDS.ARM9Write32(CurDstAddr, NDS.ARM9Read32(CurSrcAddr));              CurSrcAddr += SrcAddrInc<<2;              CurDstAddr += DstAddrInc<<2;              IterCount--;              RemCount--; -            if (NDS::ARM9Timestamp >= NDS::ARM9Target) break; +            if (NDS.ARM9Timestamp >= NDS.ARM9Target) break;          }      } @@ -609,10 +602,10 @@ void DMA::Run9()          if (IterCount == 0)          {              Running = 0; -            NDS::ResumeCPU(0, 1<<Num); +            NDS.ResumeCPU(0, 1<<Num);              if (StartMode == 0x07) -                GPU.GPU3D.CheckFIFODMA(); +                NDS.GPU.GPU3D.CheckFIFODMA();          }          return; @@ -622,17 +615,16 @@ void DMA::Run9()          Cnt &= ~(1<<31);      if (Cnt & (1<<30)) -        NDS::SetIRQ(0, NDS::IRQ_DMA0 + Num); +        NDS.SetIRQ(0, IRQ_DMA0 + Num);      Running = 0;      InProgress = false; -    NDS::ResumeCPU(0, 1<<Num); +    NDS.ResumeCPU(0, 1<<Num);  } -template <int ConsoleType>  void DMA::Run7()  { -    if (NDS::ARM7Timestamp >= NDS::ARM7Target) return; +    if (NDS.ARM7Timestamp >= NDS.ARM7Target) return;      Executing = true; @@ -644,40 +636,34 @@ void DMA::Run7()      {          while (IterCount > 0 && !Stall)          { -            NDS::ARM7Timestamp += UnitTimings7_16(burststart); +            NDS.ARM7Timestamp += UnitTimings7_16(burststart);              burststart = false; -            if (ConsoleType == 1) -                DSi::ARM7Write16(CurDstAddr, DSi::ARM7Read16(CurSrcAddr)); -            else -                NDS::ARM7Write16(CurDstAddr, NDS::ARM7Read16(CurSrcAddr)); +            NDS.ARM7Write16(CurDstAddr, NDS.ARM7Read16(CurSrcAddr));              CurSrcAddr += SrcAddrInc<<1;              CurDstAddr += DstAddrInc<<1;              IterCount--;              RemCount--; -            if (NDS::ARM7Timestamp >= NDS::ARM7Target) break; +            if (NDS.ARM7Timestamp >= NDS.ARM7Target) break;          }      }      else      {          while (IterCount > 0 && !Stall)          { -            NDS::ARM7Timestamp += UnitTimings7_32(burststart); +            NDS.ARM7Timestamp += UnitTimings7_32(burststart);              burststart = false; -            if (ConsoleType == 1) -                DSi::ARM7Write32(CurDstAddr, DSi::ARM7Read32(CurSrcAddr)); -            else -                NDS::ARM7Write32(CurDstAddr, NDS::ARM7Read32(CurSrcAddr)); +            NDS.ARM7Write32(CurDstAddr, NDS.ARM7Read32(CurSrcAddr));              CurSrcAddr += SrcAddrInc<<2;              CurDstAddr += DstAddrInc<<2;              IterCount--;              RemCount--; -            if (NDS::ARM7Timestamp >= NDS::ARM7Target) break; +            if (NDS.ARM7Timestamp >= NDS.ARM7Target) break;          }      } @@ -689,7 +675,7 @@ void DMA::Run7()          if (IterCount == 0)          {              Running = 0; -            NDS::ResumeCPU(1, 1<<Num); +            NDS.ResumeCPU(1, 1<<Num);          }          return; @@ -699,22 +685,18 @@ void DMA::Run7()          Cnt &= ~(1<<31);      if (Cnt & (1<<30)) -        NDS::SetIRQ(1, NDS::IRQ_DMA0 + Num); +        NDS.SetIRQ(1, IRQ_DMA0 + Num);      Running = 0;      InProgress = false; -    NDS::ResumeCPU(1, 1<<Num); +    NDS.ResumeCPU(1, 1<<Num);  } -template <int ConsoleType>  void DMA::Run()  {      if (!Running) return; -    if (CPU == 0) return Run9<ConsoleType>(); -    else          return Run7<ConsoleType>(); +    if (CPU == 0) return Run9(); +    else          return Run7();  } -template void DMA::Run<0>(); -template void DMA::Run<1>(); -  }
\ No newline at end of file @@ -21,17 +21,16 @@  #include <array>  #include "types.h" -#include "Savestate.h" -#include "DMA_Timings.h"  namespace melonDS  { -class GPU; +class NDS; +class Savestate;  class DMA  {  public: -    DMA(u32 cpu, u32 num, GPU& gpu); +    DMA(u32 cpu, u32 num, NDS& nds);      ~DMA() = default;      void Reset(); @@ -46,12 +45,8 @@ public:      u32 UnitTimings7_16(bool burststart);      u32 UnitTimings7_32(bool burststart); -    template <int ConsoleType>      void Run(); - -    template <int ConsoleType>      void Run9(); -    template <int ConsoleType>      void Run7();      bool IsInMode(u32 mode) const noexcept @@ -83,7 +78,7 @@ public:      u32 Cnt {};  private: -    melonDS::GPU& GPU; +    melonDS::NDS& NDS;      u32 CPU {};      u32 Num {}; diff --git a/src/DSi.cpp b/src/DSi.cpp index 351d5ed..f2781e4 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -45,135 +45,88 @@ namespace melonDS  {  using namespace Platform; -namespace DSi +// matching NDMA modes for DSi +const u32 NDMAModes[] =  { - -u16 SCFG_BIOS; -u16 SCFG_Clock9; -u16 SCFG_Clock7; -u32 SCFG_EXT[2]; -u32 SCFG_MC; -u16 SCFG_RST; - -u8 ARM9iBIOS[0x10000] = { 0 }; -u8 ARM7iBIOS[0x10000] = { 0 }; - -u32 MBK[2][9]; - -u8* NWRAM_A; -u8* NWRAM_B; -u8* NWRAM_C; - -u8* NWRAMMap_A[2][4]; -u8* NWRAMMap_B[3][8]; -u8* NWRAMMap_C[3][8]; - -u32 NWRAMStart[2][3]; -u32 NWRAMEnd[2][3]; -u32 NWRAMMask[2][3]; - -u32 NDMACnt[2]; -DSi_NDMA* NDMAs[8]; - -std::unique_ptr<DSi_NAND::NANDImage> NANDImage; -DSi_SDHost* SDMMC; -DSi_SDHost* SDIO; - -DSi_I2CHost* I2C; -DSi_CamModule* CamModule; -DSi_AES* AES; -DSi_DSP* DSP; - -// FIXME: these currently have no effect (and aren't stored in a savestate) -//        ... not that they matter all that much -u8 GPIO_Data; -u8 GPIO_Dir; -u8 GPIO_IEdgeSel; -u8 GPIO_IE; -u8 GPIO_WiFi; - - -void Set_SCFG_Clock9(u16 val); -void Set_SCFG_MC(u32 val); - - -bool Init() +    // ARM9 + +    0x10, // immediate +    0x06, // VBlank +    0x07, // HBlank +    0x08, // scanline start +    0x09, // mainmem FIFO +    0x04, // DS cart slot +    0xFF, // GBA cart slot +    0x0A, // GX FIFO +    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + +    // ARM7 + +    0x30, // immediate +    0x26, // VBlank +    0x24, // DS cart slot +    0xFF, // wifi / GBA cart slot (TODO) +}; + +DSi::DSi() noexcept : +    NDS(1), +    NDMAs { +        DSi_NDMA(0, 0, *this), +        DSi_NDMA(0, 1, *this), +        DSi_NDMA(0, 2, *this), +        DSi_NDMA(0, 3, *this), +        DSi_NDMA(1, 0, *this), +        DSi_NDMA(1, 1, *this), +        DSi_NDMA(1, 2, *this), +        DSi_NDMA(1, 3, *this), +    }, +    DSP(*this), +    SDMMC(*this, 0), +    SDIO(*this, 1), +    I2C(*this), +    CamModule(*this), +    AES(*this)  {      // Memory is owned by ARMJIT_Memory, don't free it -    NWRAM_A = NDS::JIT->Memory.GetNWRAM_A(); -    NWRAM_B = NDS::JIT->Memory.GetNWRAM_B(); -    NWRAM_C = NDS::JIT->Memory.GetNWRAM_C(); - -    NDMAs[0] = new DSi_NDMA(0, 0, *NDS::GPU); -    NDMAs[1] = new DSi_NDMA(0, 1, *NDS::GPU); -    NDMAs[2] = new DSi_NDMA(0, 2, *NDS::GPU); -    NDMAs[3] = new DSi_NDMA(0, 3, *NDS::GPU); -    NDMAs[4] = new DSi_NDMA(1, 0, *NDS::GPU); -    NDMAs[5] = new DSi_NDMA(1, 1, *NDS::GPU); -    NDMAs[6] = new DSi_NDMA(1, 2, *NDS::GPU); -    NDMAs[7] = new DSi_NDMA(1, 3, *NDS::GPU); - -    SDMMC = new DSi_SDHost(0); -    SDIO = new DSi_SDHost(1); - -    I2C = new DSi_I2CHost(); -    CamModule = new DSi_CamModule(); -    AES = new DSi_AES(); -    DSP = new DSi_DSP(); - -    return true; +    NWRAM_A = JIT.Memory.GetNWRAM_A(); +    NWRAM_B = JIT.Memory.GetNWRAM_B(); +    NWRAM_C = NDS::JIT.Memory.GetNWRAM_C();  } -void DeInit() +DSi::~DSi() noexcept  {      // Memory is owned externally      NWRAM_A = nullptr;      NWRAM_B = nullptr;      NWRAM_C = nullptr; - -    for (int i = 0; i < 8; i++) -    { -        delete NDMAs[i]; -        NDMAs[i] = nullptr; -    } - -    delete SDMMC; SDMMC = nullptr; -    delete SDIO; SDIO = nullptr; - -    delete I2C; I2C = nullptr; -    delete CamModule; CamModule = nullptr; -    delete AES; AES = nullptr; -    delete DSP; DSP = nullptr; - -    NANDImage = nullptr; -    // The NANDImage is cleaned up (and its underlying file closed) -    // as part of unique_ptr's destructor  } -void Reset() +void DSi::Reset()  { -    //NDS::ARM9->CP15Write(0x910, 0x0D00000A); -    //NDS::ARM9->CP15Write(0x911, 0x00000020); -    //NDS::ARM9->CP15Write(0x100, NDS::ARM9->CP15Read(0x100) | 0x00050000); +    //ARM9.CP15Write(0x910, 0x0D00000A); +    //ARM9.CP15Write(0x911, 0x00000020); +    //ARM9.CP15Write(0x100, ARM9.CP15Read(0x100) | 0x00050000); +    NDS::Reset(); -    NDS::MapSharedWRAM(3); +    KeyInput &= ~(1 << (16+6)); +    MapSharedWRAM(3);      NDMACnt[0] = 0; NDMACnt[1] = 0; -    for (int i = 0; i < 8; i++) NDMAs[i]->Reset(); +    for (int i = 0; i < 8; i++) NDMAs[i].Reset(); -    I2C->Reset(); -    CamModule->Reset(); -    DSP->Reset(); +    I2C.Reset(); +    CamModule.Reset(); +    DSP.Reset(); -    SDMMC->CloseHandles(); -    SDIO->CloseHandles(); +    SDMMC.CloseHandles(); +    SDIO.CloseHandles();      LoadNAND(); -    SDMMC->Reset(); -    SDIO->Reset(); +    SDMMC.Reset(); +    SDIO.Reset(); -    AES->Reset(); +    AES.Reset();      if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot))      { @@ -187,10 +140,10 @@ void Reset()      SCFG_Clock7 = 0x0187;      SCFG_EXT[0] = 0x8307F100;      SCFG_EXT[1] = 0x93FFFB06; -    SCFG_MC = 0x0010 | (~((u32)(NDS::NDSCartSlot->GetCart() != nullptr))&1);//0x0011; +    SCFG_MC = 0x0010 | (~((u32)(NDSCartSlot.GetCart() != nullptr))&1);//0x0011;      SCFG_RST = 0; -    DSP->SetRstLine(false); +    DSP.SetRstLine(false);      GPIO_Data = 0xff; // these actually initialize to high after reset      GPIO_Dir = 0x80; // enable sound out, all others input @@ -199,16 +152,44 @@ void Reset()      GPIO_WiFi = 0;      // LCD init flag -    NDS::GPU->DispStat[0] |= (1<<6); -    NDS::GPU->DispStat[1] |= (1<<6); +    GPU.DispStat[0] |= (1<<6); +    GPU.DispStat[1] |= (1<<6); +} + +void DSi::Stop(Platform::StopReason reason) +{ +    NDS::Stop(reason); +    CamModule.Stop(); +} + +bool DSi::LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) +{ +    if (NDS::LoadCart(romdata, romlen, savedata, savelen)) +    { +        SetCartInserted(true); +        return true; +    } + +    return false;  } -void Stop() + +void DSi::EjectCart() +{ +    NDS::EjectCart(); + +    SetCartInserted(false); +} +void DSi::CamInputFrame(int cam, u32* data, int width, int height, bool rgb)  { -    CamModule->Stop(); +    switch (cam) +    { +    case 0: return I2C.GetOuterCamera()->InputFrame(data, width, height, rgb); +    case 1: return I2C.GetInnerCamera()->InputFrame(data, width, height, rgb); +    }  } -void DoSavestate(Savestate* file) +void DSi::DoSavestateExtra(Savestate* file)  {      file->Section("DSIG"); @@ -232,7 +213,7 @@ void DoSavestate(Savestate* file)      {          Set_SCFG_Clock9(SCFG_Clock9);          Set_SCFG_MC(SCFG_MC); -        DSP->SetRstLine(SCFG_RST & 0x0001); +        DSP.SetRstLine(SCFG_RST & 0x0001);          MBK[0][8] = 0;          MBK[1][8] = 0; @@ -277,17 +258,17 @@ void DoSavestate(Savestate* file)      }      for (int i = 0; i < 8; i++) -        NDMAs[i]->DoSavestate(file); - -    AES->DoSavestate(file); -    CamModule->DoSavestate(file); -    DSP->DoSavestate(file); -    I2C->DoSavestate(file); -    SDMMC->DoSavestate(file); -    SDIO->DoSavestate(file); +        NDMAs[i].DoSavestate(file); + +    AES.DoSavestate(file); +    CamModule.DoSavestate(file); +    DSP.DoSavestate(file); +    I2C.DoSavestate(file); +    SDMMC.DoSavestate(file); +    SDIO.DoSavestate(file);  } -void SetCartInserted(bool inserted) +void DSi::SetCartInserted(bool inserted)  {      if (inserted)          SCFG_MC &= ~1; @@ -295,7 +276,7 @@ void SetCartInserted(bool inserted)          SCFG_MC |= 1;  } -void DecryptModcryptArea(u32 offset, u32 size, u8* iv) +void DSi::DecryptModcryptArea(u32 offset, u32 size, u8* iv)  {      AES_ctx ctx;      u8 key[16]; @@ -304,13 +285,13 @@ void DecryptModcryptArea(u32 offset, u32 size, u8* iv)      if ((offset == 0) || (size == 0))          return; -    const NDSHeader& header = NDS::NDSCartSlot->GetCart()->GetHeader(); +    const NDSHeader& header = NDSCartSlot.GetCart()->GetHeader();      if ((header.DSiCryptoFlags & (1<<4)) ||          (header.AppFlags & (1<<7)))      {          // dev key -        const u8* cartrom = NDS::NDSCartSlot->GetCart()->GetROM(); +        const u8* cartrom = NDSCartSlot.GetCart()->GetROM();          memcpy(key, &cartrom[0], 16);      }      else @@ -394,13 +375,13 @@ void DecryptModcryptArea(u32 offset, u32 size, u8* iv)      }  } -void SetupDirectBoot() +void DSi::SetupDirectBoot()  {      bool dsmode = false; -    NDSHeader& header = NDS::NDSCartSlot->GetCart()->GetHeader(); -    const u8* cartrom = NDS::NDSCartSlot->GetCart()->GetROM(); -    u32 cartid = NDS::NDSCartSlot->GetCart()->ID(); -    DSi_TSC* tsc = (DSi_TSC*)NDS::SPI->GetTSC(); +    NDSHeader& header = NDSCartSlot.GetCart()->GetHeader(); +    const u8* cartrom = NDSCartSlot.GetCart()->GetROM(); +    u32 cartid = NDSCartSlot.GetCart()->ID(); +    DSi_TSC* tsc = (DSi_TSC*)SPI.GetTSC();      // TODO: add controls for forcing DS or DSi mode?      if (!(header.UnitCode & 0x02)) @@ -550,7 +531,7 @@ void SetupDirectBoot()              }          } -        Firmware::WifiBoard nwifiver = NDS::SPI->GetFirmware()->GetHeader().WifiBoard; +        Firmware::WifiBoard nwifiver = SPI.GetFirmware()->GetHeader().WifiBoard;          ARM9Write8(0x020005E0, static_cast<u8>(nwifiver));          // TODO: these should be taken from the wifi firmware in NAND @@ -576,7 +557,7 @@ void SetupDirectBoot()          ARM9Write32(0x02FFFC00, cartid);          ARM9Write16(0x02FFFC40, 0x0001); // boot indicator -        ARM9Write8(0x02FFFDFA, I2C->GetBPTWL()->GetBootFlag() | 0x80); +        ARM9Write8(0x02FFFDFA, I2C.GetBPTWL()->GetBootFlag() | 0x80);          ARM9Write8(0x02FFFDFB, 0x01);      } @@ -588,7 +569,7 @@ void SetupDirectBoot()      if (header.ARM9ROMOffset >= 0x4000 && header.ARM9ROMOffset < 0x8000)      {          u8 securearea[0x800]; -        NDS::NDSCartSlot->DecryptSecureArea(securearea); +        NDSCartSlot.DecryptSecureArea(securearea);          for (u32 i = 0; i < 0x800; i+=4)          { @@ -638,37 +619,37 @@ void SetupDirectBoot()          }      } -    NDS::ARM7BIOSProt = 0x20; - -    NDS::SPI->GetFirmwareMem()->SetupDirectBoot(true); - -    NDS::ARM9->CP15Write(0x100, 0x00056078); -    NDS::ARM9->CP15Write(0x200, 0x0000004A); -    NDS::ARM9->CP15Write(0x201, 0x0000004A); -    NDS::ARM9->CP15Write(0x300, 0x0000000A); -    NDS::ARM9->CP15Write(0x502, 0x15111011); -    NDS::ARM9->CP15Write(0x503, 0x05101011); -    NDS::ARM9->CP15Write(0x600, 0x04000033); -    NDS::ARM9->CP15Write(0x601, 0x04000033); -    NDS::ARM9->CP15Write(0x610, 0x02000031); -    NDS::ARM9->CP15Write(0x611, 0x02000031); -    NDS::ARM9->CP15Write(0x620, 0x00000000); -    NDS::ARM9->CP15Write(0x621, 0x00000000); -    NDS::ARM9->CP15Write(0x630, 0x08000033); -    NDS::ARM9->CP15Write(0x631, 0x08000033); -    NDS::ARM9->CP15Write(0x640, 0x0E00001B); -    NDS::ARM9->CP15Write(0x641, 0x0E00001B); -    NDS::ARM9->CP15Write(0x650, 0x00000000); -    NDS::ARM9->CP15Write(0x651, 0x00000000); -    NDS::ARM9->CP15Write(0x660, 0xFFFF001D); -    NDS::ARM9->CP15Write(0x661, 0xFFFF001D); -    NDS::ARM9->CP15Write(0x670, 0x02FFC01B); -    NDS::ARM9->CP15Write(0x671, 0x02FFC01B); -    NDS::ARM9->CP15Write(0x910, 0x0E00000A); -    NDS::ARM9->CP15Write(0x911, 0x00000020); +    ARM7BIOSProt = 0x20; + +    SPI.GetFirmwareMem()->SetupDirectBoot(); + +    ARM9.CP15Write(0x100, 0x00056078); +    ARM9.CP15Write(0x200, 0x0000004A); +    ARM9.CP15Write(0x201, 0x0000004A); +    ARM9.CP15Write(0x300, 0x0000000A); +    ARM9.CP15Write(0x502, 0x15111011); +    ARM9.CP15Write(0x503, 0x05101011); +    ARM9.CP15Write(0x600, 0x04000033); +    ARM9.CP15Write(0x601, 0x04000033); +    ARM9.CP15Write(0x610, 0x02000031); +    ARM9.CP15Write(0x611, 0x02000031); +    ARM9.CP15Write(0x620, 0x00000000); +    ARM9.CP15Write(0x621, 0x00000000); +    ARM9.CP15Write(0x630, 0x08000033); +    ARM9.CP15Write(0x631, 0x08000033); +    ARM9.CP15Write(0x640, 0x0E00001B); +    ARM9.CP15Write(0x641, 0x0E00001B); +    ARM9.CP15Write(0x650, 0x00000000); +    ARM9.CP15Write(0x651, 0x00000000); +    ARM9.CP15Write(0x660, 0xFFFF001D); +    ARM9.CP15Write(0x661, 0xFFFF001D); +    ARM9.CP15Write(0x670, 0x02FFC01B); +    ARM9.CP15Write(0x671, 0x02FFC01B); +    ARM9.CP15Write(0x910, 0x0E00000A); +    ARM9.CP15Write(0x911, 0x00000020);  } -void SoftReset() +void DSi::SoftReset()  {      // TODO: check exactly what is reset      // presumably, main RAM isn't reset, since the DSi can be told @@ -678,30 +659,30 @@ void SoftReset()      // also, BPTWL[0x70] could be abused to quickly boot specific titles -    NDS::JIT->Reset(); -    NDS::JIT->CheckAndInvalidateITCM(); +    JIT.Reset(); +    JIT.CheckAndInvalidateITCM(); -    NDS::ARM9->Reset(); -    NDS::ARM7->Reset(); +    ARM9.Reset(); +    ARM7.Reset(); -    NDS::ARM9->CP15Reset(); +    ARM9.CP15Reset();      NDS::MapSharedWRAM(3);      // TODO: does the DSP get reset? NWRAM doesn't, so I'm assuming no      // *HOWEVER*, the bootrom (which does get rerun) does remap NWRAM, and thus      // the DSP most likely gets reset -    DSP->Reset(); +    DSP.Reset(); -    SDMMC->CloseHandles(); -    SDIO->CloseHandles(); +    SDMMC.CloseHandles(); +    SDIO.CloseHandles();      LoadNAND(); -    SDMMC->Reset(); -    SDIO->Reset(); +    SDMMC.Reset(); +    SDIO.Reset(); -    AES->Reset(); +    AES.Reset();      if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot))      { @@ -718,15 +699,15 @@ void SoftReset()      SCFG_MC = 0x0010;//0x0011;      // TODO: is this actually reset?      SCFG_RST = 0; -    DSP->SetRstLine(false); +    DSP.SetRstLine(false);      // LCD init flag -    NDS::GPU->DispStat[0] |= (1<<6); -    NDS::GPU->DispStat[1] |= (1<<6); +    GPU.DispStat[0] |= (1<<6); +    GPU.DispStat[1] |= (1<<6);  } -bool LoadNAND() +bool DSi::LoadNAND()  {      if (!NANDImage)      { @@ -905,8 +886,8 @@ bool LoadNAND()      if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot))      {          // point CPUs to boot ROM reset vectors -        NDS::ARM9->JumpTo(0xFFFF0000); -        NDS::ARM7->JumpTo(0x00000000); +        ARM9.JumpTo(0xFFFF0000); +        ARM7.JumpTo(0x00000000);      }      else      { @@ -921,10 +902,10 @@ bool LoadNAND()          ARM7Write16(eaddr+0x3E, 0x40E0);          ARM7Write16(eaddr+0x42, 0x0001); -        memcpy(&NDS::ARM9->ITCM[0x4400], &ARM9iBIOS[0x87F4], 0x400); -        memcpy(&NDS::ARM9->ITCM[0x4800], &ARM9iBIOS[0x9920], 0x80); -        memcpy(&NDS::ARM9->ITCM[0x4894], &ARM9iBIOS[0x99A0], 0x1048); -        memcpy(&NDS::ARM9->ITCM[0x58DC], &ARM9iBIOS[0xA9E8], 0x1048); +        memcpy(&ARM9.ITCM[0x4400], &ARM9iBIOS[0x87F4], 0x400); +        memcpy(&ARM9.ITCM[0x4800], &ARM9iBIOS[0x9920], 0x80); +        memcpy(&ARM9.ITCM[0x4894], &ARM9iBIOS[0x99A0], 0x1048); +        memcpy(&ARM9.ITCM[0x58DC], &ARM9iBIOS[0xA9E8], 0x1048);          u8 ARM7Init[0x3C00];          memset(ARM7Init, 0, 0x3C00); @@ -937,8 +918,8 @@ bool LoadNAND()              ARM7Write32(0x03FFC400+i, *(u32*)&ARM7Init[i]);          // repoint the CPUs to the boot2 binaries -        NDS::ARM9->JumpTo(bootparams[2]); -        NDS::ARM7->JumpTo(bootparams[6]); +        ARM9.JumpTo(bootparams[2]); +        ARM7.JumpTo(bootparams[6]);      }      // user data is now expected to be patched by the frontend @@ -947,78 +928,104 @@ bool LoadNAND()  } -void RunNDMAs(u32 cpu) +void DSi::RunNDMAs(u32 cpu)  {      // TODO: round-robin mode (requires DMA channels to have a subblock delay set)      if (cpu == 0)      { -        if (NDS::ARM9Timestamp >= NDS::ARM9Target) return; +        if (ARM9Timestamp >= ARM9Target) return; -        if (!(NDS::CPUStop & NDS::CPUStop_GXStall)) NDMAs[0]->Run(); -        if (!(NDS::CPUStop & NDS::CPUStop_GXStall)) NDMAs[1]->Run(); -        if (!(NDS::CPUStop & NDS::CPUStop_GXStall)) NDMAs[2]->Run(); -        if (!(NDS::CPUStop & NDS::CPUStop_GXStall)) NDMAs[3]->Run(); +        if (!(CPUStop & CPUStop_GXStall)) NDMAs[0].Run(); +        if (!(CPUStop & CPUStop_GXStall)) NDMAs[1].Run(); +        if (!(CPUStop & CPUStop_GXStall)) NDMAs[2].Run(); +        if (!(CPUStop & CPUStop_GXStall)) NDMAs[3].Run();      }      else      { -        if (NDS::ARM7Timestamp >= NDS::ARM7Target) return; +        if (ARM7Timestamp >= ARM7Target) return; -        NDMAs[4]->Run(); -        NDMAs[5]->Run(); -        NDMAs[6]->Run(); -        NDMAs[7]->Run(); +        NDMAs[4].Run(); +        NDMAs[5].Run(); +        NDMAs[6].Run(); +        NDMAs[7].Run();      }  } -void StallNDMAs() +void DSi::StallNDMAs()  {      // TODO  } -bool NDMAsInMode(u32 cpu, u32 mode) + +bool DSi::DMAsInMode(u32 cpu, u32 mode) +{ +    if (NDS::DMAsInMode(cpu, mode)) return true; + +    return NDMAsInMode(cpu, NDMAModes[mode]); +} + +bool DSi::DMAsRunning(u32 cpu) +{ +    if (NDS::DMAsRunning(cpu)) return true; + +    return NDMAsRunning(cpu); +} + +bool DSi::NDMAsInMode(u32 cpu, u32 mode)  {      cpu <<= 2; -    if (NDMAs[cpu+0]->IsInMode(mode)) return true; -    if (NDMAs[cpu+1]->IsInMode(mode)) return true; -    if (NDMAs[cpu+2]->IsInMode(mode)) return true; -    if (NDMAs[cpu+3]->IsInMode(mode)) return true; +    if (NDMAs[cpu+0].IsInMode(mode)) return true; +    if (NDMAs[cpu+1].IsInMode(mode)) return true; +    if (NDMAs[cpu+2].IsInMode(mode)) return true; +    if (NDMAs[cpu+3].IsInMode(mode)) return true;      return false;  } -bool NDMAsRunning(u32 cpu) +bool DSi::NDMAsRunning(u32 cpu)  {      cpu <<= 2; -    if (NDMAs[cpu+0]->IsRunning()) return true; -    if (NDMAs[cpu+1]->IsRunning()) return true; -    if (NDMAs[cpu+2]->IsRunning()) return true; -    if (NDMAs[cpu+3]->IsRunning()) return true; +    if (NDMAs[cpu+0].IsRunning()) return true; +    if (NDMAs[cpu+1].IsRunning()) return true; +    if (NDMAs[cpu+2].IsRunning()) return true; +    if (NDMAs[cpu+3].IsRunning()) return true;      return false;  } -void CheckNDMAs(u32 cpu, u32 mode) +void DSi::CheckNDMAs(u32 cpu, u32 mode)  {      cpu <<= 2; -    NDMAs[cpu+0]->StartIfNeeded(mode); -    NDMAs[cpu+1]->StartIfNeeded(mode); -    NDMAs[cpu+2]->StartIfNeeded(mode); -    NDMAs[cpu+3]->StartIfNeeded(mode); +    NDMAs[cpu+0].StartIfNeeded(mode); +    NDMAs[cpu+1].StartIfNeeded(mode); +    NDMAs[cpu+2].StartIfNeeded(mode); +    NDMAs[cpu+3].StartIfNeeded(mode);  } -void StopNDMAs(u32 cpu, u32 mode) +void DSi::StopNDMAs(u32 cpu, u32 mode)  {      cpu <<= 2; -    NDMAs[cpu+0]->StopIfNeeded(mode); -    NDMAs[cpu+1]->StopIfNeeded(mode); -    NDMAs[cpu+2]->StopIfNeeded(mode); -    NDMAs[cpu+3]->StopIfNeeded(mode); +    NDMAs[cpu+0].StopIfNeeded(mode); +    NDMAs[cpu+1].StopIfNeeded(mode); +    NDMAs[cpu+2].StopIfNeeded(mode); +    NDMAs[cpu+3].StopIfNeeded(mode); +} + +void DSi::StopDMAs(u32 cpu, u32 mode) +{ +    NDS::StopDMAs(cpu, mode); +    StopNDMAs(cpu, mode);  } +void DSi::CheckDMAs(u32 cpu, u32 mode) +{ +    NDS::CheckDMAs(cpu, mode); +    CheckNDMAs(cpu, NDMAModes[mode]); +}  // new WRAM mapping  // TODO: find out what happens upon overlapping slots!! -void MapNWRAM_A(u32 num, u8 val) +void DSi::MapNWRAM_A(u32 num, u8 val)  {      // NWRAM Bank A does not allow all bits to be set      // possible non working combinations are caught by later code, but these are not set-able at all @@ -1035,7 +1042,7 @@ void MapNWRAM_A(u32 num, u8 val)      u8 oldval = (MBK[0][mbkn] >> mbks) & 0xFF;      if (oldval == val) return; -    NDS::JIT->Memory.RemapNWRAM(0); +    JIT.Memory.RemapNWRAM(0);      MBK[0][mbkn] &= ~(0xFF << mbks);      MBK[0][mbkn] |= (val << mbks); @@ -1063,7 +1070,7 @@ void MapNWRAM_A(u32 num, u8 val)      }  } -void MapNWRAM_B(u32 num, u8 val) +void DSi::MapNWRAM_B(u32 num, u8 val)  {      // NWRAM Bank B does not allow all bits to be set      // possible non working combinations are caught by later code, but these are not set-able at all @@ -1080,7 +1087,7 @@ void MapNWRAM_B(u32 num, u8 val)      u8 oldval = (MBK[0][mbkn] >> mbks) & 0xFF;      if (oldval == val) return; -    NDS::JIT->Memory.RemapNWRAM(1); +    JIT.Memory.RemapNWRAM(1);      MBK[0][mbkn] &= ~(0xFF << mbks);      MBK[0][mbkn] |= (val << mbks); @@ -1110,7 +1117,7 @@ void MapNWRAM_B(u32 num, u8 val)      }  } -void MapNWRAM_C(u32 num, u8 val) +void DSi::MapNWRAM_C(u32 num, u8 val)  {      // NWRAM Bank C does not allow all bits to be set      // possible non working combinations are caught by later code, but these are not set-able at all @@ -1127,7 +1134,7 @@ void MapNWRAM_C(u32 num, u8 val)      u8 oldval = (MBK[0][mbkn] >> mbks) & 0xFF;      if (oldval == val) return; -    NDS::JIT->Memory.RemapNWRAM(2); +    JIT.Memory.RemapNWRAM(2);      MBK[0][mbkn] &= ~(0xFF << mbks);      MBK[0][mbkn] |= (val << mbks); @@ -1157,7 +1164,7 @@ void MapNWRAM_C(u32 num, u8 val)      }  } -void MapNWRAMRange(u32 cpu, u32 num, u32 val) +void DSi::MapNWRAMRange(u32 cpu, u32 num, u32 val)  {      // The windowing registers are not writeable in all bits      // We need to do this before the change test, so we do not @@ -1176,7 +1183,7 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val)      u32 oldval = MBK[cpu][5+num];      if (oldval == val) return; -    NDS::JIT->Memory.RemapNWRAM(num); +    JIT.Memory.RemapNWRAM(num);      MBK[cpu][5+num] = val; @@ -1228,41 +1235,41 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val)      }  } -void ApplyNewRAMSize(u32 size) +void DSi::ApplyNewRAMSize(u32 size)  {      switch (size)      {      case 0:      case 1: -        NDS::MainRAMMask = 0x3FFFFF; +        MainRAMMask = 0x3FFFFF;          Log(LogLevel::Debug, "RAM: 4MB\n");          break;      case 2:      case 3: // TODO: debug console w/ 32MB? -        NDS::MainRAMMask = 0xFFFFFF; +        MainRAMMask = 0xFFFFFF;          Log(LogLevel::Debug, "RAM: 16MB\n");          break;      }  } -void Set_SCFG_Clock9(u16 val) +void DSi::Set_SCFG_Clock9(u16 val)  { -    NDS::ARM9Timestamp >>= NDS::ARM9ClockShift; -    NDS::ARM9Target    >>= NDS::ARM9ClockShift; +    ARM9Timestamp >>= ARM9ClockShift; +    ARM9Target    >>= ARM9ClockShift;      Log(LogLevel::Debug, "CLOCK9=%04X\n", val);      SCFG_Clock9 = val & 0x0187; -    if (SCFG_Clock9 & (1<<0)) NDS::ARM9ClockShift = 2; -    else                      NDS::ARM9ClockShift = 1; +    if (SCFG_Clock9 & (1<<0)) ARM9ClockShift = 2; +    else                      ARM9ClockShift = 1; -    NDS::ARM9Timestamp <<= NDS::ARM9ClockShift; -    NDS::ARM9Target    <<= NDS::ARM9ClockShift; -    NDS::ARM9->UpdateRegionTimings(0x00000, 0x100000); +    ARM9Timestamp <<= ARM9ClockShift; +    ARM9Target    <<= ARM9ClockShift; +    ARM9.UpdateRegionTimings(0x00000, 0x100000);  } -void Set_SCFG_MC(u32 val) +void DSi::Set_SCFG_MC(u32 val)  {      u32 oldslotstatus = SCFG_MC & 0xC; @@ -1273,13 +1280,14 @@ void Set_SCFG_MC(u32 val)      if ((oldslotstatus == 0x0) && ((SCFG_MC & 0xC) == 0x4))      { -        NDS::NDSCartSlot->ResetCart(); +        NDSCartSlot.ResetCart();      }  } -u8 ARM9Read8(u32 addr) +u8 DSi::ARM9Read8(u32 addr)  { +    assert(ConsoleType == 1);      if ((addr >= 0xFFFF0000) && (!(SCFG_BIOS & (1<<1))))      {          if ((addr >= 0xFFFF8000) && (SCFG_BIOS & (1<<0))) @@ -1317,17 +1325,18 @@ u8 ARM9Read8(u32 addr)      case 0x08000000:      case 0x09000000:      case 0x0A000000: -        return (NDS::ExMemCnt[0] & (1<<7)) ? 0 : 0xFF; +        return (ExMemCnt[0] & (1<<7)) ? 0 : 0xFF;      case 0x0C000000: -        return *(u8*)&NDS::MainRAM[addr & NDS::MainRAMMask]; +        return *(u8*)&MainRAM[addr & MainRAMMask];      }      return NDS::ARM9Read8(addr);  } -u16 ARM9Read16(u32 addr) +u16 DSi::ARM9Read16(u32 addr)  { +    assert(ConsoleType == 1);      addr &= ~0x1;      if ((addr >= 0xFFFF0000) && (!(SCFG_BIOS & (1<<1)))) @@ -1367,17 +1376,18 @@ u16 ARM9Read16(u32 addr)      case 0x08000000:      case 0x09000000:      case 0x0A000000: -        return (NDS::ExMemCnt[0] & (1<<7)) ? 0 : 0xFFFF; +        return (ExMemCnt[0] & (1<<7)) ? 0 : 0xFFFF;      case 0x0C000000: -        return *(u16*)&NDS::MainRAM[addr & NDS::MainRAMMask]; +        return *(u16*)&MainRAM[addr & MainRAMMask];      }      return NDS::ARM9Read16(addr);  } -u32 ARM9Read32(u32 addr) +u32 DSi::ARM9Read32(u32 addr)  { +    assert(ConsoleType == 1);      addr &= ~0x3;      if ((addr >= 0xFFFF0000) && (!(SCFG_BIOS & (1<<1)))) @@ -1422,17 +1432,18 @@ u32 ARM9Read32(u32 addr)      case 0x08000000:      case 0x09000000:      case 0x0A000000: -        return (NDS::ExMemCnt[0] & (1<<7)) ? 0 : 0xFFFFFFFF; +        return (ExMemCnt[0] & (1<<7)) ? 0 : 0xFFFFFFFF;      case 0x0C000000: -        return *(u32*)&NDS::MainRAM[addr & NDS::MainRAMMask]; +        return *(u32*)&MainRAM[addr & MainRAMMask];      }      return NDS::ARM9Read32(addr);  } -void ARM9Write8(u32 addr, u8 val) +void DSi::ARM9Write8(u32 addr, u8 val)  { +    assert(ConsoleType == 1);      switch (addr & 0xFF000000)      {      case 0x03000000: @@ -1452,7 +1463,7 @@ void ARM9Write8(u32 addr, u8 val)                          continue;                      u8* ptr = &NWRAM_A[page * 0x10000];                      *(u8*)&ptr[addr & 0xFFFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);                  }                  return;              } @@ -1470,7 +1481,7 @@ void ARM9Write8(u32 addr, u8 val)                          continue;                      u8* ptr = &NWRAM_B[page * 0x8000];                      *(u8*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);                  }                  return;              } @@ -1488,7 +1499,7 @@ void ARM9Write8(u32 addr, u8 val)                          continue;                      u8* ptr = &NWRAM_C[page * 0x8000];                      *(u8*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);                  }                  return;              } @@ -1501,14 +1512,14 @@ void ARM9Write8(u32 addr, u8 val)      case 0x06000000:          if (!(SCFG_EXT[0] & (1<<13))) return; -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr); +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr);          switch (addr & 0x00E00000)          { -        case 0x00000000: NDS::GPU->WriteVRAM_ABG<u8>(addr, val); return; -        case 0x00200000: NDS::GPU->WriteVRAM_BBG<u8>(addr, val); return; -        case 0x00400000: NDS::GPU->WriteVRAM_AOBJ<u8>(addr, val); return; -        case 0x00600000: NDS::GPU->WriteVRAM_BOBJ<u8>(addr, val); return; -        default: NDS::GPU->WriteVRAM_LCDC<u8>(addr, val); return; +        case 0x00000000: GPU.WriteVRAM_ABG<u8>(addr, val); return; +        case 0x00200000: GPU.WriteVRAM_BBG<u8>(addr, val); return; +        case 0x00400000: GPU.WriteVRAM_AOBJ<u8>(addr, val); return; +        case 0x00600000: GPU.WriteVRAM_BOBJ<u8>(addr, val); return; +        default: GPU.WriteVRAM_LCDC<u8>(addr, val); return;          }      case 0x08000000: @@ -1517,16 +1528,17 @@ void ARM9Write8(u32 addr, u8 val)          return;      case 0x0C000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); -        *(u8*)&NDS::MainRAM[addr & NDS::MainRAMMask] = val; +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); +        *(u8*)&MainRAM[addr & MainRAMMask] = val;          return;      }      return NDS::ARM9Write8(addr, val);  } -void ARM9Write16(u32 addr, u16 val) +void DSi::ARM9Write16(u32 addr, u16 val)  { +    assert(ConsoleType == 1);      addr &= ~0x1;      switch (addr & 0xFF000000) @@ -1548,7 +1560,7 @@ void ARM9Write16(u32 addr, u16 val)                          continue;                      u8* ptr = &NWRAM_A[page * 0x10000];                      *(u16*)&ptr[addr & 0xFFFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);                  }                  return;              } @@ -1566,7 +1578,7 @@ void ARM9Write16(u32 addr, u16 val)                          continue;                      u8* ptr = &NWRAM_B[page * 0x8000];                      *(u16*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);                  }                  return;              } @@ -1584,7 +1596,7 @@ void ARM9Write16(u32 addr, u16 val)                          continue;                      u8* ptr = &NWRAM_C[page * 0x8000];                      *(u16*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);                  }                  return;              } @@ -1601,16 +1613,17 @@ void ARM9Write16(u32 addr, u16 val)          return;      case 0x0C000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); -        *(u16*)&NDS::MainRAM[addr & NDS::MainRAMMask] = val; +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); +        *(u16*)&MainRAM[addr & MainRAMMask] = val;          return;      }      return NDS::ARM9Write16(addr, val);  } -void ARM9Write32(u32 addr, u32 val) +void DSi::ARM9Write32(u32 addr, u32 val)  { +    assert(ConsoleType == 1);      addr &= ~0x3;      switch (addr & 0xFF000000) @@ -1632,7 +1645,7 @@ void ARM9Write32(u32 addr, u32 val)                          continue;                      u8* ptr = &NWRAM_A[page * 0x10000];                      *(u32*)&ptr[addr & 0xFFFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);                  }                  return;              } @@ -1650,7 +1663,7 @@ void ARM9Write32(u32 addr, u32 val)                          continue;                      u8* ptr = &NWRAM_B[page * 0x8000];                      *(u32*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);                  }                  return;              } @@ -1668,7 +1681,7 @@ void ARM9Write32(u32 addr, u32 val)                          continue;                      u8* ptr = &NWRAM_C[page * 0x8000];                      *(u32*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr); +                    JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);                  }                  return;              } @@ -1685,22 +1698,23 @@ void ARM9Write32(u32 addr, u32 val)          return;      case 0x0C000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); -        *(u32*)&NDS::MainRAM[addr & NDS::MainRAMMask] = val; +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); +        *(u32*)&MainRAM[addr & MainRAMMask] = val;          return;      }      return NDS::ARM9Write32(addr, val);  } -bool ARM9GetMemRegion(u32 addr, bool write, NDS::MemRegion* region) +bool DSi::ARM9GetMemRegion(u32 addr, bool write, MemRegion* region)  { +    assert(ConsoleType == 1);      switch (addr & 0xFF000000)      {      case 0x02000000:      case 0x0C000000: -        region->Mem = NDS::MainRAM; -        region->Mask = NDS::MainRAMMask; +        region->Mem = MainRAM; +        region->Mask = MainRAMMask;          return true;      } @@ -1714,7 +1728,7 @@ bool ARM9GetMemRegion(u32 addr, bool write, NDS::MemRegion* region)                  return false;              } -            region->Mem = NDS::ARM9BIOS; +            region->Mem = ARM9BIOS;              region->Mask = 0xFFF;          }          else @@ -1731,15 +1745,15 @@ bool ARM9GetMemRegion(u32 addr, bool write, NDS::MemRegion* region) -u8 ARM7Read8(u32 addr) +u8 DSi::ARM7Read8(u32 addr)  {      if ((addr < 0x00010000) && (!(SCFG_BIOS & (1<<9))))      {          if ((addr >= 0x00008000) && (SCFG_BIOS & (1<<8)))              return 0xFF; -        if (NDS::ARM7->R[15] >= 0x00010000) +        if (ARM7.R[15] >= 0x00010000)              return 0xFF; -        if (addr < NDS::ARM7BIOSProt && NDS::ARM7->R[15] >= NDS::ARM7BIOSProt) +        if (addr < ARM7BIOSProt && ARM7.R[15] >= ARM7BIOSProt)              return 0xFF;          return *(u8*)&ARM7iBIOS[addr & 0xFFFF]; @@ -1778,27 +1792,28 @@ u8 ARM7Read8(u32 addr)      case 0x09800000:      case 0x0A000000:      case 0x0A800000: -        return (NDS::ExMemCnt[0] & (1<<7)) ? 0xFF : 0; +        return (ExMemCnt[0] & (1<<7)) ? 0xFF : 0;      case 0x0C000000:      case 0x0C800000: -        return *(u8*)&NDS::MainRAM[addr & NDS::MainRAMMask]; +        return *(u8*)&MainRAM[addr & MainRAMMask];      }      return NDS::ARM7Read8(addr);  } -u16 ARM7Read16(u32 addr) +u16 DSi::ARM7Read16(u32 addr)  { +    assert(ConsoleType == 1);      addr &= ~0x1;      if ((addr < 0x00010000) && (!(SCFG_BIOS & (1<<9))))      {          if ((addr >= 0x00008000) && (SCFG_BIOS & (1<<8)))              return 0xFFFF; -        if (NDS::ARM7->R[15] >= 0x00010000) +        if (ARM7.R[15] >= 0x00010000)              return 0xFFFF; -        if (addr < NDS::ARM7BIOSProt && NDS::ARM7->R[15] >= NDS::ARM7BIOSProt) +        if (addr < ARM7BIOSProt && ARM7.R[15] >= ARM7BIOSProt)              return 0xFFFF;          return *(u16*)&ARM7iBIOS[addr & 0xFFFF]; @@ -1837,17 +1852,17 @@ u16 ARM7Read16(u32 addr)      case 0x09800000:      case 0x0A000000:      case 0x0A800000: -        return (NDS::ExMemCnt[0] & (1<<7)) ? 0xFFFF : 0; +        return (ExMemCnt[0] & (1<<7)) ? 0xFFFF : 0;      case 0x0C000000:      case 0x0C800000: -        return *(u16*)&NDS::MainRAM[addr & NDS::MainRAMMask]; +        return *(u16*)&MainRAM[addr & MainRAMMask];      }      return NDS::ARM7Read16(addr);  } -u32 ARM7Read32(u32 addr) +u32 DSi::ARM7Read32(u32 addr)  {      addr &= ~0x3; @@ -1855,9 +1870,9 @@ u32 ARM7Read32(u32 addr)      {          if ((addr >= 0x00008000) && (SCFG_BIOS & (1<<8)))              return 0xFFFFFFFF; -        if (NDS::ARM7->R[15] >= 0x00010000) +        if (ARM7.R[15] >= 0x00010000)              return 0xFFFFFFFF; -        if (addr < NDS::ARM7BIOSProt && NDS::ARM7->R[15] >= NDS::ARM7BIOSProt) +        if (addr < ARM7BIOSProt && ARM7.R[15] >= ARM7BIOSProt)              return 0xFFFFFFFF;          return *(u32*)&ARM7iBIOS[addr & 0xFFFF]; @@ -1906,8 +1921,9 @@ u32 ARM7Read32(u32 addr)      return NDS::ARM7Read32(addr);  } -void ARM7Write8(u32 addr, u8 val) +void DSi::ARM7Write8(u32 addr, u8 val)  { +    assert(ConsoleType == 1);      switch (addr & 0xFF800000)      {      case 0x03000000: @@ -1928,7 +1944,7 @@ void ARM7Write8(u32 addr, u8 val)                          continue;                      u8* ptr = &NWRAM_A[page * 0x10000];                      *(u8*)&ptr[addr & 0xFFFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);                  }                  return;              } @@ -1946,7 +1962,7 @@ void ARM7Write8(u32 addr, u8 val)                          continue;                      u8* ptr = &NWRAM_B[page * 0x8000];                      *(u8*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);                  }                  return;              } @@ -1964,7 +1980,7 @@ void ARM7Write8(u32 addr, u8 val)                          continue;                      u8* ptr = &NWRAM_C[page * 0x8000];                      *(u8*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);                  }                  return;              } @@ -1985,7 +2001,7 @@ void ARM7Write8(u32 addr, u8 val)      case 0x0C000000:      case 0x0C800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u8*)&NDS::MainRAM[addr & NDS::MainRAMMask] = val;          return;      } @@ -1993,8 +2009,9 @@ void ARM7Write8(u32 addr, u8 val)      return NDS::ARM7Write8(addr, val);  } -void ARM7Write16(u32 addr, u16 val) +void DSi::ARM7Write16(u32 addr, u16 val)  { +    assert(ConsoleType == 1);      addr &= ~0x1;      switch (addr & 0xFF800000) @@ -2017,7 +2034,7 @@ void ARM7Write16(u32 addr, u16 val)                          continue;                      u8* ptr = &NWRAM_A[page * 0x10000];                      *(u16*)&ptr[addr & 0xFFFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);                  }                  return;              } @@ -2035,7 +2052,7 @@ void ARM7Write16(u32 addr, u16 val)                          continue;                      u8* ptr = &NWRAM_B[page * 0x8000];                      *(u16*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);                  }                  return;              } @@ -2053,7 +2070,7 @@ void ARM7Write16(u32 addr, u16 val)                          continue;                      u8* ptr = &NWRAM_C[page * 0x8000];                      *(u16*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);                  }                  return;              } @@ -2074,7 +2091,7 @@ void ARM7Write16(u32 addr, u16 val)      case 0x0C000000:      case 0x0C800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u16*)&NDS::MainRAM[addr & NDS::MainRAMMask] = val;          return;      } @@ -2082,8 +2099,9 @@ void ARM7Write16(u32 addr, u16 val)      return NDS::ARM7Write16(addr, val);  } -void ARM7Write32(u32 addr, u32 val) +void DSi::ARM7Write32(u32 addr, u32 val)  { +    assert(ConsoleType == 1);      addr &= ~0x3;      switch (addr & 0xFF800000) @@ -2106,7 +2124,7 @@ void ARM7Write32(u32 addr, u32 val)                          continue;                      u8* ptr = &NWRAM_A[page * 0x10000];                      *(u32*)&ptr[addr & 0xFFFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);                  }                  return;              } @@ -2124,7 +2142,7 @@ void ARM7Write32(u32 addr, u32 val)                          continue;                      u8* ptr = &NWRAM_B[page * 0x8000];                      *(u32*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);                  }                  return;              } @@ -2142,7 +2160,7 @@ void ARM7Write32(u32 addr, u32 val)                          continue;                      u8* ptr = &NWRAM_C[page * 0x8000];                      *(u32*)&ptr[addr & 0x7FFF] = val; -                    NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr); +                    JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);                  }                  return;              } @@ -2163,7 +2181,7 @@ void ARM7Write32(u32 addr, u32 val)      case 0x0C000000:      case 0x0C800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u32*)&NDS::MainRAM[addr & NDS::MainRAMMask] = val;          return;      } @@ -2171,8 +2189,9 @@ void ARM7Write32(u32 addr, u32 val)      return NDS::ARM7Write32(addr, val);  } -bool ARM7GetMemRegion(u32 addr, bool write, NDS::MemRegion* region) +bool DSi::ARM7GetMemRegion(u32 addr, bool write, MemRegion* region)  { +    assert(ConsoleType == 1);      switch (addr & 0xFF800000)      {      case 0x02000000: @@ -2216,7 +2235,7 @@ bool ARM7GetMemRegion(u32 addr, bool write, NDS::MemRegion* region)      case (addr): return (val) & 0xFFFF; \      case (addr+2): return (val) >> 16; -u8 ARM9IORead8(u32 addr) +u8 DSi::ARM9IORead8(u32 addr)  {      switch (addr)      { @@ -2237,20 +2256,21 @@ u8 ARM9IORead8(u32 addr)      if ((addr & 0xFFFFFF00) == 0x04004200)      {          if (!(SCFG_EXT[0] & (1<<17))) return 0; -        return CamModule->Read8(addr); +        return CamModule.Read8(addr);      }      if ((addr & 0xFFFFFF00) == 0x04004300)      {          if (!(SCFG_EXT[0] & (1<<18))) return 0; -        return DSP->Read8(addr); +        return DSP.Read8(addr);      }      return NDS::ARM9IORead8(addr);  } -u16 ARM9IORead16(u32 addr) +u16 DSi::ARM9IORead16(u32 addr)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04004000: return SCFG_BIOS & 0xFF; @@ -2272,20 +2292,21 @@ u16 ARM9IORead16(u32 addr)      if ((addr & 0xFFFFFF00) == 0x04004200)      {          if (!(SCFG_EXT[0] & (1<<17))) return 0; -        return CamModule->Read16(addr); +        return CamModule.Read16(addr);      }      if ((addr & 0xFFFFFF00) == 0x04004300)      {          if (!(SCFG_EXT[0] & (1<<18))) return 0; -        return DSP->Read16(addr); +        return DSP.Read16(addr);      }      return NDS::ARM9IORead16(addr);  } -u32 ARM9IORead32(u32 addr) +u32 DSi::ARM9IORead32(u32 addr)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04004000: return SCFG_BIOS & 0xFF; @@ -2304,53 +2325,54 @@ u32 ARM9IORead32(u32 addr)      case 0x04004060: return MBK[0][8];      case 0x04004100: return NDMACnt[0]; -    case 0x04004104: return NDMAs[0]->SrcAddr; -    case 0x04004108: return NDMAs[0]->DstAddr; -    case 0x0400410C: return NDMAs[0]->TotalLength; -    case 0x04004110: return NDMAs[0]->BlockLength; -    case 0x04004114: return NDMAs[0]->SubblockTimer; -    case 0x04004118: return NDMAs[0]->FillData; -    case 0x0400411C: return NDMAs[0]->Cnt; -    case 0x04004120: return NDMAs[1]->SrcAddr; -    case 0x04004124: return NDMAs[1]->DstAddr; -    case 0x04004128: return NDMAs[1]->TotalLength; -    case 0x0400412C: return NDMAs[1]->BlockLength; -    case 0x04004130: return NDMAs[1]->SubblockTimer; -    case 0x04004134: return NDMAs[1]->FillData; -    case 0x04004138: return NDMAs[1]->Cnt; -    case 0x0400413C: return NDMAs[2]->SrcAddr; -    case 0x04004140: return NDMAs[2]->DstAddr; -    case 0x04004144: return NDMAs[2]->TotalLength; -    case 0x04004148: return NDMAs[2]->BlockLength; -    case 0x0400414C: return NDMAs[2]->SubblockTimer; -    case 0x04004150: return NDMAs[2]->FillData; -    case 0x04004154: return NDMAs[2]->Cnt; -    case 0x04004158: return NDMAs[3]->SrcAddr; -    case 0x0400415C: return NDMAs[3]->DstAddr; -    case 0x04004160: return NDMAs[3]->TotalLength; -    case 0x04004164: return NDMAs[3]->BlockLength; -    case 0x04004168: return NDMAs[3]->SubblockTimer; -    case 0x0400416C: return NDMAs[3]->FillData; -    case 0x04004170: return NDMAs[3]->Cnt; +    case 0x04004104: return NDMAs[0].SrcAddr; +    case 0x04004108: return NDMAs[0].DstAddr; +    case 0x0400410C: return NDMAs[0].TotalLength; +    case 0x04004110: return NDMAs[0].BlockLength; +    case 0x04004114: return NDMAs[0].SubblockTimer; +    case 0x04004118: return NDMAs[0].FillData; +    case 0x0400411C: return NDMAs[0].Cnt; +    case 0x04004120: return NDMAs[1].SrcAddr; +    case 0x04004124: return NDMAs[1].DstAddr; +    case 0x04004128: return NDMAs[1].TotalLength; +    case 0x0400412C: return NDMAs[1].BlockLength; +    case 0x04004130: return NDMAs[1].SubblockTimer; +    case 0x04004134: return NDMAs[1].FillData; +    case 0x04004138: return NDMAs[1].Cnt; +    case 0x0400413C: return NDMAs[2].SrcAddr; +    case 0x04004140: return NDMAs[2].DstAddr; +    case 0x04004144: return NDMAs[2].TotalLength; +    case 0x04004148: return NDMAs[2].BlockLength; +    case 0x0400414C: return NDMAs[2].SubblockTimer; +    case 0x04004150: return NDMAs[2].FillData; +    case 0x04004154: return NDMAs[2].Cnt; +    case 0x04004158: return NDMAs[3].SrcAddr; +    case 0x0400415C: return NDMAs[3].DstAddr; +    case 0x04004160: return NDMAs[3].TotalLength; +    case 0x04004164: return NDMAs[3].BlockLength; +    case 0x04004168: return NDMAs[3].SubblockTimer; +    case 0x0400416C: return NDMAs[3].FillData; +    case 0x04004170: return NDMAs[3].Cnt;      }      if ((addr & 0xFFFFFF00) == 0x04004200)      {          if (!(SCFG_EXT[0] & (1<<17))) return 0; -        return CamModule->Read32(addr); +        return CamModule.Read32(addr);      }      if ((addr & 0xFFFFFF00) == 0x04004300)      {          if (!(SCFG_EXT[0] & (1<<18))) return 0; -        return DSP->Read32(addr); +        return DSP.Read32(addr);      }      return NDS::ARM9IORead32(addr);  } -void ARM9IOWrite8(u32 addr, u8 val) +void DSi::ARM9IOWrite8(u32 addr, u8 val)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04000301: @@ -2367,7 +2389,7 @@ void ARM9IOWrite8(u32 addr, u8 val)          if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/              return;          SCFG_RST = (SCFG_RST & 0xFF00) | val; -        DSP->SetRstLine(val & 1); +        DSP.SetRstLine(val & 1);          return;      case 0x04004040: @@ -2407,20 +2429,21 @@ void ARM9IOWrite8(u32 addr, u8 val)      if ((addr & 0xFFFFFF00) == 0x04004200)      {          if (!(SCFG_EXT[0] & (1<<17))) return; -        return CamModule->Write8(addr, val); +        return CamModule.Write8(addr, val);      }      if ((addr & 0xFFFFFF00) == 0x04004300)      {          if (!(SCFG_EXT[0] & (1<<18))) return; -        return DSP->Write8(addr, val); +        return DSP.Write8(addr, val);      }      return NDS::ARM9IOWrite8(addr, val);  } -void ARM9IOWrite16(u32 addr, u16 val) +void DSi::ARM9IOWrite16(u32 addr, u16 val)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04004004: @@ -2433,7 +2456,7 @@ void ARM9IOWrite16(u32 addr, u16 val)          if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/              return;          SCFG_RST = val; -        DSP->SetRstLine(val & 1); +        DSP.SetRstLine(val & 1);          return;      case 0x04004040: @@ -2467,20 +2490,21 @@ void ARM9IOWrite16(u32 addr, u16 val)      if ((addr & 0xFFFFFF00) == 0x04004200)      {          if (!(SCFG_EXT[0] & (1<<17))) return; -        return CamModule->Write16(addr, val); +        return CamModule.Write16(addr, val);      }      if ((addr & 0xFFFFFF00) == 0x04004300)      {          if (!(SCFG_EXT[0] & (1<<18))) return; -        return DSP->Write16(addr, val); +        return DSP.Write16(addr, val);      }      return NDS::ARM9IOWrite16(addr, val);  } -void ARM9IOWrite32(u32 addr, u32 val) +void DSi::ARM9IOWrite32(u32 addr, u32 val)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04004004: @@ -2488,7 +2512,7 @@ void ARM9IOWrite32(u32 addr, u32 val)              return;          Set_SCFG_Clock9(val & 0xFFFF);          SCFG_RST = val >> 16; -        DSP->SetRstLine((val >> 16) & 1); +        DSP.SetRstLine((val >> 16) & 1);          break;      case 0x04004008: @@ -2523,7 +2547,7 @@ void ARM9IOWrite32(u32 addr, u32 val)              // is still busy clearing/relocating shit              //if (newram != oldram)              //    NDS::ScheduleEvent(NDS::Event_DSi_RAMSizeChange, false, 512*512*512, ApplyNewRAMSize, newram); -            Log(LogLevel::Debug, "from %08X, ARM7 %08X, %08X\n", NDS::GetPC(0), NDS::GetPC(1), NDS::ARM7->R[1]); +            Log(LogLevel::Debug, "from %08X, ARM7 %08X, %08X\n", NDS::GetPC(0), NDS::GetPC(1), ARM7.R[1]);          }          return; @@ -2584,54 +2608,55 @@ void ARM9IOWrite32(u32 addr, u32 val)          return;      case 0x04004100: NDMACnt[0] = val & 0x800F0000; return; -    case 0x04004104: NDMAs[0]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x04004108: NDMAs[0]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x0400410C: NDMAs[0]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x04004110: NDMAs[0]->BlockLength = val & 0x00FFFFFF; return; -    case 0x04004114: NDMAs[0]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x04004118: NDMAs[0]->FillData = val; return; -    case 0x0400411C: NDMAs[0]->WriteCnt(val); return; -    case 0x04004120: NDMAs[1]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x04004124: NDMAs[1]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x04004128: NDMAs[1]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x0400412C: NDMAs[1]->BlockLength = val & 0x00FFFFFF; return; -    case 0x04004130: NDMAs[1]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x04004134: NDMAs[1]->FillData = val; return; -    case 0x04004138: NDMAs[1]->WriteCnt(val); return; -    case 0x0400413C: NDMAs[2]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x04004140: NDMAs[2]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x04004144: NDMAs[2]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x04004148: NDMAs[2]->BlockLength = val & 0x00FFFFFF; return; -    case 0x0400414C: NDMAs[2]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x04004150: NDMAs[2]->FillData = val; return; -    case 0x04004154: NDMAs[2]->WriteCnt(val); return; -    case 0x04004158: NDMAs[3]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x0400415C: NDMAs[3]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x04004160: NDMAs[3]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x04004164: NDMAs[3]->BlockLength = val & 0x00FFFFFF; return; -    case 0x04004168: NDMAs[3]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x0400416C: NDMAs[3]->FillData = val; return; -    case 0x04004170: NDMAs[3]->WriteCnt(val); return; +    case 0x04004104: NDMAs[0].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x04004108: NDMAs[0].DstAddr = val & 0xFFFFFFFC; return; +    case 0x0400410C: NDMAs[0].TotalLength = val & 0x0FFFFFFF; return; +    case 0x04004110: NDMAs[0].BlockLength = val & 0x00FFFFFF; return; +    case 0x04004114: NDMAs[0].SubblockTimer = val & 0x0003FFFF; return; +    case 0x04004118: NDMAs[0].FillData = val; return; +    case 0x0400411C: NDMAs[0].WriteCnt(val); return; +    case 0x04004120: NDMAs[1].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x04004124: NDMAs[1].DstAddr = val & 0xFFFFFFFC; return; +    case 0x04004128: NDMAs[1].TotalLength = val & 0x0FFFFFFF; return; +    case 0x0400412C: NDMAs[1].BlockLength = val & 0x00FFFFFF; return; +    case 0x04004130: NDMAs[1].SubblockTimer = val & 0x0003FFFF; return; +    case 0x04004134: NDMAs[1].FillData = val; return; +    case 0x04004138: NDMAs[1].WriteCnt(val); return; +    case 0x0400413C: NDMAs[2].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x04004140: NDMAs[2].DstAddr = val & 0xFFFFFFFC; return; +    case 0x04004144: NDMAs[2].TotalLength = val & 0x0FFFFFFF; return; +    case 0x04004148: NDMAs[2].BlockLength = val & 0x00FFFFFF; return; +    case 0x0400414C: NDMAs[2].SubblockTimer = val & 0x0003FFFF; return; +    case 0x04004150: NDMAs[2].FillData = val; return; +    case 0x04004154: NDMAs[2].WriteCnt(val); return; +    case 0x04004158: NDMAs[3].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x0400415C: NDMAs[3].DstAddr = val & 0xFFFFFFFC; return; +    case 0x04004160: NDMAs[3].TotalLength = val & 0x0FFFFFFF; return; +    case 0x04004164: NDMAs[3].BlockLength = val & 0x00FFFFFF; return; +    case 0x04004168: NDMAs[3].SubblockTimer = val & 0x0003FFFF; return; +    case 0x0400416C: NDMAs[3].FillData = val; return; +    case 0x04004170: NDMAs[3].WriteCnt(val); return;      }      if ((addr & 0xFFFFFF00) == 0x04004200)      {          if (!(SCFG_EXT[0] & (1<<17))) return; -        return CamModule->Write32(addr, val); +        return CamModule.Write32(addr, val);      }      if ((addr & 0xFFFFFF00) == 0x04004300)      {          if (!(SCFG_EXT[0] & (1<<18))) return; -        return DSP->Write32(addr, val); +        return DSP.Write32(addr, val);      }      return NDS::ARM9IOWrite32(addr, val);  } -u8 ARM7IORead8(u32 addr) +u8 DSi::ARM7IORead8(u32 addr)  { +    assert(ConsoleType == 1);      switch (addr)      { @@ -2650,8 +2675,8 @@ u8 ARM7IORead8(u32 addr)      CASE_READ8_32BIT(0x0400405C, MBK[1][7])      CASE_READ8_32BIT(0x04004060, MBK[1][8]) -    case 0x04004500: return I2C->ReadData(); -    case 0x04004501: return I2C->ReadCnt(); +    case 0x04004500: return I2C.ReadData(); +    case 0x04004501: return I2C.ReadCnt();      case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() & 0xFF;      case 0x04004D01: if (SCFG_BIOS & (1<<10)) return 0; return (NANDImage->GetConsoleID() >> 8) & 0xFF; @@ -2663,8 +2688,8 @@ u8 ARM7IORead8(u32 addr)      case 0x04004D07: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 56;      case 0x04004D08: return 0; -    case 0x4004700: return DSP->ReadSNDExCnt() & 0xFF; -    case 0x4004701: return DSP->ReadSNDExCnt() >> 8; +    case 0x4004700: return DSP.ReadSNDExCnt() & 0xFF; +    case 0x4004701: return DSP.ReadSNDExCnt() >> 8;      case 0x04004C00: return GPIO_Data;      case 0x04004C01: return GPIO_Dir; @@ -2677,8 +2702,9 @@ u8 ARM7IORead8(u32 addr)      return NDS::ARM7IORead8(addr);  } -u16 ARM7IORead16(u32 addr) +u16 DSi::ARM7IORead16(u32 addr)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04000218: return NDS::IE2; @@ -2706,7 +2732,7 @@ u16 ARM7IORead16(u32 addr)      case 0x04004D06: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 48;      case 0x04004D08: return 0; -    case 0x4004700: return DSP->ReadSNDExCnt(); +    case 0x4004700: return DSP.ReadSNDExCnt();      case 0x04004C00: return GPIO_Data | ((u16)GPIO_Dir << 8);      case 0x04004C02: return GPIO_IEdgeSel | ((u16)GPIO_IE << 8); @@ -2715,18 +2741,19 @@ u16 ARM7IORead16(u32 addr)      if (addr >= 0x04004800 && addr < 0x04004A00)      { -        return SDMMC->Read(addr); +        return SDMMC.Read(addr);      }      if (addr >= 0x04004A00 && addr < 0x04004C00)      { -        return SDIO->Read(addr); +        return SDIO.Read(addr);      }      return NDS::ARM7IORead16(addr);  } -u32 ARM7IORead32(u32 addr) +u32 DSi::ARM7IORead32(u32 addr)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04000218: return NDS::IE2; @@ -2747,63 +2774,64 @@ u32 ARM7IORead32(u32 addr)      case 0x04004060: return MBK[1][8];      case 0x04004100: return NDMACnt[1]; -    case 0x04004104: return NDMAs[4]->SrcAddr; -    case 0x04004108: return NDMAs[4]->DstAddr; -    case 0x0400410C: return NDMAs[4]->TotalLength; -    case 0x04004110: return NDMAs[4]->BlockLength; -    case 0x04004114: return NDMAs[4]->SubblockTimer; -    case 0x04004118: return NDMAs[4]->FillData; -    case 0x0400411C: return NDMAs[4]->Cnt; -    case 0x04004120: return NDMAs[5]->SrcAddr; -    case 0x04004124: return NDMAs[5]->DstAddr; -    case 0x04004128: return NDMAs[5]->TotalLength; -    case 0x0400412C: return NDMAs[5]->BlockLength; -    case 0x04004130: return NDMAs[5]->SubblockTimer; -    case 0x04004134: return NDMAs[5]->FillData; -    case 0x04004138: return NDMAs[5]->Cnt; -    case 0x0400413C: return NDMAs[6]->SrcAddr; -    case 0x04004140: return NDMAs[6]->DstAddr; -    case 0x04004144: return NDMAs[6]->TotalLength; -    case 0x04004148: return NDMAs[6]->BlockLength; -    case 0x0400414C: return NDMAs[6]->SubblockTimer; -    case 0x04004150: return NDMAs[6]->FillData; -    case 0x04004154: return NDMAs[6]->Cnt; -    case 0x04004158: return NDMAs[7]->SrcAddr; -    case 0x0400415C: return NDMAs[7]->DstAddr; -    case 0x04004160: return NDMAs[7]->TotalLength; -    case 0x04004164: return NDMAs[7]->BlockLength; -    case 0x04004168: return NDMAs[7]->SubblockTimer; -    case 0x0400416C: return NDMAs[7]->FillData; -    case 0x04004170: return NDMAs[7]->Cnt; - -    case 0x04004400: return AES->ReadCnt(); -    case 0x0400440C: return AES->ReadOutputFIFO(); +    case 0x04004104: return NDMAs[4].SrcAddr; +    case 0x04004108: return NDMAs[4].DstAddr; +    case 0x0400410C: return NDMAs[4].TotalLength; +    case 0x04004110: return NDMAs[4].BlockLength; +    case 0x04004114: return NDMAs[4].SubblockTimer; +    case 0x04004118: return NDMAs[4].FillData; +    case 0x0400411C: return NDMAs[4].Cnt; +    case 0x04004120: return NDMAs[5].SrcAddr; +    case 0x04004124: return NDMAs[5].DstAddr; +    case 0x04004128: return NDMAs[5].TotalLength; +    case 0x0400412C: return NDMAs[5].BlockLength; +    case 0x04004130: return NDMAs[5].SubblockTimer; +    case 0x04004134: return NDMAs[5].FillData; +    case 0x04004138: return NDMAs[5].Cnt; +    case 0x0400413C: return NDMAs[6].SrcAddr; +    case 0x04004140: return NDMAs[6].DstAddr; +    case 0x04004144: return NDMAs[6].TotalLength; +    case 0x04004148: return NDMAs[6].BlockLength; +    case 0x0400414C: return NDMAs[6].SubblockTimer; +    case 0x04004150: return NDMAs[6].FillData; +    case 0x04004154: return NDMAs[6].Cnt; +    case 0x04004158: return NDMAs[7].SrcAddr; +    case 0x0400415C: return NDMAs[7].DstAddr; +    case 0x04004160: return NDMAs[7].TotalLength; +    case 0x04004164: return NDMAs[7].BlockLength; +    case 0x04004168: return NDMAs[7].SubblockTimer; +    case 0x0400416C: return NDMAs[7].FillData; +    case 0x04004170: return NDMAs[7].Cnt; + +    case 0x04004400: return AES.ReadCnt(); +    case 0x0400440C: return AES.ReadOutputFIFO();      case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() & 0xFFFFFFFF;      case 0x04004D04: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 32;      case 0x04004D08: return 0;      case 0x4004700: -        Log(LogLevel::Debug, "32-Bit SNDExCnt read? %08X\n", NDS::ARM7->R[15]); -        return DSP->ReadSNDExCnt(); +        Log(LogLevel::Debug, "32-Bit SNDExCnt read? %08X\n", ARM7.R[15]); +        return DSP.ReadSNDExCnt();      }      if (addr >= 0x04004800 && addr < 0x04004A00)      { -        if (addr == 0x0400490C) return SDMMC->ReadFIFO32(); -        return SDMMC->Read(addr) | (SDMMC->Read(addr+2) << 16); +        if (addr == 0x0400490C) return SDMMC.ReadFIFO32(); +        return SDMMC.Read(addr) | (SDMMC.Read(addr+2) << 16);      }      if (addr >= 0x04004A00 && addr < 0x04004C00)      { -        if (addr == 0x04004B0C) return SDIO->ReadFIFO32(); -        return SDIO->Read(addr) | (SDIO->Read(addr+2) << 16); +        if (addr == 0x04004B0C) return SDIO.ReadFIFO32(); +        return SDIO.Read(addr) | (SDIO.Read(addr+2) << 16);      }      return NDS::ARM7IORead32(addr);  } -void ARM7IOWrite8(u32 addr, u8 val) +void DSi::ARM7IOWrite8(u32 addr, u8 val)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04004000: @@ -2834,14 +2862,14 @@ void ARM7IOWrite8(u32 addr, u8 val)          return;      } -    case 0x04004500: I2C->WriteData(val); return; -    case 0x04004501: I2C->WriteCnt(val); return; +    case 0x04004500: I2C.WriteData(val); return; +    case 0x04004501: I2C.WriteCnt(val); return;      case 0x4004700: -        DSP->WriteSNDExCnt((u16)val, 0xFF); +        DSP.WriteSNDExCnt((u16)val, 0xFF);          return;      case 0x4004701: -        DSP->WriteSNDExCnt(((u16)val << 8), 0xFF00); +        DSP.WriteSNDExCnt(((u16)val << 8), 0xFF00);          return;      case 0x04004C00: @@ -2866,7 +2894,7 @@ void ARM7IOWrite8(u32 addr, u8 val)          u32 shift = (addr&3)*8;          addr -= 0x04004420;          addr &= ~3; -        AES->WriteIV(addr, (u32)val << shift, 0xFF << shift); +        AES.WriteIV(addr, (u32)val << shift, 0xFF << shift);          return;      }      if (addr >= 0x04004430 && addr < 0x04004440) @@ -2874,7 +2902,7 @@ void ARM7IOWrite8(u32 addr, u8 val)          u32 shift = (addr&3)*8;          addr -= 0x04004430;          addr &= ~3; -        AES->WriteMAC(addr, (u32)val << shift, 0xFF << shift); +        AES.WriteMAC(addr, (u32)val << shift, 0xFF << shift);          return;      }      if (addr >= 0x04004440 && addr < 0x04004500) @@ -2888,17 +2916,18 @@ void ARM7IOWrite8(u32 addr, u8 val)          switch (addr >> 4)          { -        case 0: AES->WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; -        case 1: AES->WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; -        case 2: AES->WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; +        case 0: AES.WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; +        case 1: AES.WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; +        case 2: AES.WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFF << shift); return;          }      }      return NDS::ARM7IOWrite8(addr, val);  } -void ARM7IOWrite16(u32 addr, u16 val) +void DSi::ARM7IOWrite16(u32 addr, u16 val)  { +    assert(ConsoleType == 1);      switch (addr)      {          case 0x04000218: NDS::IE2 = (val & 0x7FF7); NDS::UpdateIRQ(1); return; @@ -2936,11 +2965,11 @@ void ARM7IOWrite16(u32 addr, u16 val)              return;          case 0x04004406: -            AES->WriteBlkCnt(val<<16); +            AES.WriteBlkCnt(val<<16);              return;          case 0x4004700: -            DSP->WriteSNDExCnt(val, 0xFFFF); +            DSP.WriteSNDExCnt(val, 0xFFFF);              return;          case 0x04004C00: @@ -2961,7 +2990,7 @@ void ARM7IOWrite16(u32 addr, u16 val)          u32 shift = (addr&1)*16;          addr -= 0x04004420;          addr &= ~1; -        AES->WriteIV(addr, (u32)val << shift, 0xFFFF << shift); +        AES.WriteIV(addr, (u32)val << shift, 0xFFFF << shift);          return;      }      if (addr >= 0x04004430 && addr < 0x04004440) @@ -2969,7 +2998,7 @@ void ARM7IOWrite16(u32 addr, u16 val)          u32 shift = (addr&1)*16;          addr -= 0x04004430;          addr &= ~1; -        AES->WriteMAC(addr, (u32)val << shift, 0xFFFF << shift); +        AES.WriteMAC(addr, (u32)val << shift, 0xFFFF << shift);          return;      }      if (addr >= 0x04004440 && addr < 0x04004500) @@ -2983,28 +3012,29 @@ void ARM7IOWrite16(u32 addr, u16 val)          switch (addr >> 4)          { -        case 0: AES->WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; -        case 1: AES->WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; -        case 2: AES->WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; +        case 0: AES.WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; +        case 1: AES.WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; +        case 2: AES.WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return;          }      }      if (addr >= 0x04004800 && addr < 0x04004A00)      { -        SDMMC->Write(addr, val); +        SDMMC.Write(addr, val);          return;      }      if (addr >= 0x04004A00 && addr < 0x04004C00)      { -        SDIO->Write(addr, val); +        SDIO.Write(addr, val);          return;      }      return NDS::ARM7IOWrite16(addr, val);  } -void ARM7IOWrite32(u32 addr, u32 val) +void DSi::ARM7IOWrite32(u32 addr, u32 val)  { +    assert(ConsoleType == 1);      switch (addr)      {      case 0x04000218: NDS::IE2 = (val & 0x7FF7); NDS::UpdateIRQ(1); return; @@ -3054,55 +3084,55 @@ void ARM7IOWrite32(u32 addr, u32 val)          return;      case 0x04004100: NDMACnt[1] = val & 0x800F0000; return; -    case 0x04004104: NDMAs[4]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x04004108: NDMAs[4]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x0400410C: NDMAs[4]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x04004110: NDMAs[4]->BlockLength = val & 0x00FFFFFF; return; -    case 0x04004114: NDMAs[4]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x04004118: NDMAs[4]->FillData = val; return; -    case 0x0400411C: NDMAs[4]->WriteCnt(val); return; -    case 0x04004120: NDMAs[5]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x04004124: NDMAs[5]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x04004128: NDMAs[5]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x0400412C: NDMAs[5]->BlockLength = val & 0x00FFFFFF; return; -    case 0x04004130: NDMAs[5]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x04004134: NDMAs[5]->FillData = val; return; -    case 0x04004138: NDMAs[5]->WriteCnt(val); return; -    case 0x0400413C: NDMAs[6]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x04004140: NDMAs[6]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x04004144: NDMAs[6]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x04004148: NDMAs[6]->BlockLength = val & 0x00FFFFFF; return; -    case 0x0400414C: NDMAs[6]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x04004150: NDMAs[6]->FillData = val; return; -    case 0x04004154: NDMAs[6]->WriteCnt(val); return; -    case 0x04004158: NDMAs[7]->SrcAddr = val & 0xFFFFFFFC; return; -    case 0x0400415C: NDMAs[7]->DstAddr = val & 0xFFFFFFFC; return; -    case 0x04004160: NDMAs[7]->TotalLength = val & 0x0FFFFFFF; return; -    case 0x04004164: NDMAs[7]->BlockLength = val & 0x00FFFFFF; return; -    case 0x04004168: NDMAs[7]->SubblockTimer = val & 0x0003FFFF; return; -    case 0x0400416C: NDMAs[7]->FillData = val; return; -    case 0x04004170: NDMAs[7]->WriteCnt(val); return; - -    case 0x04004400: AES->WriteCnt(val); return; -    case 0x04004404: AES->WriteBlkCnt(val); return; -    case 0x04004408: AES->WriteInputFIFO(val); return; +    case 0x04004104: NDMAs[4].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x04004108: NDMAs[4].DstAddr = val & 0xFFFFFFFC; return; +    case 0x0400410C: NDMAs[4].TotalLength = val & 0x0FFFFFFF; return; +    case 0x04004110: NDMAs[4].BlockLength = val & 0x00FFFFFF; return; +    case 0x04004114: NDMAs[4].SubblockTimer = val & 0x0003FFFF; return; +    case 0x04004118: NDMAs[4].FillData = val; return; +    case 0x0400411C: NDMAs[4].WriteCnt(val); return; +    case 0x04004120: NDMAs[5].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x04004124: NDMAs[5].DstAddr = val & 0xFFFFFFFC; return; +    case 0x04004128: NDMAs[5].TotalLength = val & 0x0FFFFFFF; return; +    case 0x0400412C: NDMAs[5].BlockLength = val & 0x00FFFFFF; return; +    case 0x04004130: NDMAs[5].SubblockTimer = val & 0x0003FFFF; return; +    case 0x04004134: NDMAs[5].FillData = val; return; +    case 0x04004138: NDMAs[5].WriteCnt(val); return; +    case 0x0400413C: NDMAs[6].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x04004140: NDMAs[6].DstAddr = val & 0xFFFFFFFC; return; +    case 0x04004144: NDMAs[6].TotalLength = val & 0x0FFFFFFF; return; +    case 0x04004148: NDMAs[6].BlockLength = val & 0x00FFFFFF; return; +    case 0x0400414C: NDMAs[6].SubblockTimer = val & 0x0003FFFF; return; +    case 0x04004150: NDMAs[6].FillData = val; return; +    case 0x04004154: NDMAs[6].WriteCnt(val); return; +    case 0x04004158: NDMAs[7].SrcAddr = val & 0xFFFFFFFC; return; +    case 0x0400415C: NDMAs[7].DstAddr = val & 0xFFFFFFFC; return; +    case 0x04004160: NDMAs[7].TotalLength = val & 0x0FFFFFFF; return; +    case 0x04004164: NDMAs[7].BlockLength = val & 0x00FFFFFF; return; +    case 0x04004168: NDMAs[7].SubblockTimer = val & 0x0003FFFF; return; +    case 0x0400416C: NDMAs[7].FillData = val; return; +    case 0x04004170: NDMAs[7].WriteCnt(val); return; + +    case 0x04004400: AES.WriteCnt(val); return; +    case 0x04004404: AES.WriteBlkCnt(val); return; +    case 0x04004408: AES.WriteInputFIFO(val); return;      case 0x4004700: -        Log(LogLevel::Debug, "32-Bit SNDExCnt write? %08X %08X\n", val, NDS::ARM7->R[15]); -        DSP->WriteSNDExCnt(val, 0xFFFF); +        Log(LogLevel::Debug, "32-Bit SNDExCnt write? %08X %08X\n", val, ARM7.R[15]); +        DSP.WriteSNDExCnt(val, 0xFFFF);          return;      }      if (addr >= 0x04004420 && addr < 0x04004430)      {          addr -= 0x04004420; -        AES->WriteIV(addr, val, 0xFFFFFFFF); +        AES.WriteIV(addr, val, 0xFFFFFFFF);          return;      }      if (addr >= 0x04004430 && addr < 0x04004440)      {          addr -= 0x04004430; -        AES->WriteMAC(addr, val, 0xFFFFFFFF); +        AES.WriteMAC(addr, val, 0xFFFFFFFF);          return;      }      if (addr >= 0x04004440 && addr < 0x04004500) @@ -3113,31 +3143,31 @@ void ARM7IOWrite32(u32 addr, u32 val)          switch (addr >> 4)          { -        case 0: AES->WriteKeyNormal(n, addr&0xF, val, 0xFFFFFFFF); return; -        case 1: AES->WriteKeyX(n, addr&0xF, val, 0xFFFFFFFF); return; -        case 2: AES->WriteKeyY(n, addr&0xF, val, 0xFFFFFFFF); return; +        case 0: AES.WriteKeyNormal(n, addr&0xF, val, 0xFFFFFFFF); return; +        case 1: AES.WriteKeyX(n, addr&0xF, val, 0xFFFFFFFF); return; +        case 2: AES.WriteKeyY(n, addr&0xF, val, 0xFFFFFFFF); return;          }      }      if (addr >= 0x04004800 && addr < 0x04004A00)      { -        if (addr == 0x0400490C) { SDMMC->WriteFIFO32(val); return; } -        SDMMC->Write(addr, val & 0xFFFF); -        SDMMC->Write(addr+2, val >> 16); +        if (addr == 0x0400490C) { SDMMC.WriteFIFO32(val); return; } +        SDMMC.Write(addr, val & 0xFFFF); +        SDMMC.Write(addr+2, val >> 16);          return;      }      if (addr >= 0x04004A00 && addr < 0x04004C00)      { -        if (addr == 0x04004B0C) { SDIO->WriteFIFO32(val); return; } -        SDIO->Write(addr, val & 0xFFFF); -        SDIO->Write(addr+2, val >> 16); +        if (addr == 0x04004B0C) { SDIO.WriteFIFO32(val); return; } +        SDIO.Write(addr, val & 0xFFFF); +        SDIO.Write(addr+2, val >> 16);          return;      }      if (addr >= 0x04004300 && addr <= 0x04004400)      { -        DSP->Write32(addr, val); +        DSP.Write32(addr, val);          return;      } @@ -3145,5 +3175,3 @@ void ARM7IOWrite32(u32 addr, u32 val)  }  } - -}
\ No newline at end of file @@ -20,7 +20,12 @@  #define DSI_H  #include "NDS.h" +#include "DSi_NDMA.h"  #include "DSi_SD.h" +#include "DSi_DSP.h" +#include "DSi_AES.h" +#include "DSi_Camera.h" +#include "DSi_NAND.h"  namespace melonDS  { @@ -34,99 +39,135 @@ namespace DSi_NAND      class NANDImage;  } -namespace DSi +class DSi final : public NDS  { - -extern u16 SCFG_BIOS; -extern u16 SCFG_Clock9; -extern u32 SCFG_EXT[2]; - - -extern u8 ARM9iBIOS[0x10000]; -extern u8 ARM7iBIOS[0x10000]; - -extern std::unique_ptr<DSi_NAND::NANDImage> NANDImage; -extern DSi_SDHost* SDMMC; -extern DSi_SDHost* SDIO; - -const u32 NWRAMSize = 0x40000; - -extern u8* NWRAM_A; -extern u8* NWRAM_B; -extern u8* NWRAM_C; - -extern u8* NWRAMMap_A[2][4]; -extern u8* NWRAMMap_B[3][8]; -extern u8* NWRAMMap_C[3][8]; - -extern u32 NWRAMStart[2][3]; -extern u32 NWRAMEnd[2][3]; -extern u32 NWRAMMask[2][3]; - -extern DSi_I2CHost* I2C; -extern DSi_CamModule* CamModule; -extern DSi_AES* AES; -extern DSi_DSP* DSP; - -bool Init(); -void DeInit(); -void Reset(); -void Stop(); - -void DoSavestate(Savestate* file); - -void SetCartInserted(bool inserted); - -void SetupDirectBoot(); -void SoftReset(); - -bool LoadNAND(); - -void RunNDMAs(u32 cpu); -void StallNDMAs(); -bool NDMAsInMode(u32 cpu, u32 mode); -bool NDMAsRunning(u32 cpu); -void CheckNDMAs(u32 cpu, u32 mode); -void StopNDMAs(u32 cpu, u32 mode); - -void MapNWRAM_A(u32 num, u8 val); -void MapNWRAM_B(u32 num, u8 val); -void MapNWRAM_C(u32 num, u8 val); -void MapNWRAMRange(u32 cpu, u32 num, u32 val); - -u8 ARM9Read8(u32 addr); -u16 ARM9Read16(u32 addr); -u32 ARM9Read32(u32 addr); -void ARM9Write8(u32 addr, u8 val); -void ARM9Write16(u32 addr, u16 val); -void ARM9Write32(u32 addr, u32 val); - -bool ARM9GetMemRegion(u32 addr, bool write, NDS::MemRegion* region); - -u8 ARM7Read8(u32 addr); -u16 ARM7Read16(u32 addr); -u32 ARM7Read32(u32 addr); -void ARM7Write8(u32 addr, u8 val); -void ARM7Write16(u32 addr, u16 val); -void ARM7Write32(u32 addr, u32 val); - -bool ARM7GetMemRegion(u32 addr, bool write, NDS::MemRegion* region); - -u8 ARM9IORead8(u32 addr); -u16 ARM9IORead16(u32 addr); -u32 ARM9IORead32(u32 addr); -void ARM9IOWrite8(u32 addr, u8 val); -void ARM9IOWrite16(u32 addr, u16 val); -void ARM9IOWrite32(u32 addr, u32 val); - -u8 ARM7IORead8(u32 addr); -u16 ARM7IORead16(u32 addr); -u32 ARM7IORead32(u32 addr); -void ARM7IOWrite8(u32 addr, u8 val); -void ARM7IOWrite16(u32 addr, u16 val); -void ARM7IOWrite32(u32 addr, u32 val); - -} +protected: +    void DoSavestateExtra(Savestate* file) override; +public: +    u16 SCFG_BIOS; +    u16 SCFG_Clock9; +    u32 SCFG_EXT[2]; + +    u8 ARM9iBIOS[0x10000]; +    u8 ARM7iBIOS[0x10000]; +    std::unique_ptr<DSi_NAND::NANDImage> NANDImage; +    DSi_SDHost SDMMC; +    DSi_SDHost SDIO; + +    const u32 NWRAMSize = 0x40000; + +    u8* NWRAM_A; +    u8* NWRAM_B; +    u8* NWRAM_C; + +    u8* NWRAMMap_A[2][4]; +    u8* NWRAMMap_B[3][8]; +    u8* NWRAMMap_C[3][8]; + +    u32 NWRAMStart[2][3]; +    u32 NWRAMEnd[2][3]; +    u32 NWRAMMask[2][3]; + +    DSi_I2CHost I2C; +    DSi_CamModule CamModule; +    DSi_AES AES; +    DSi_DSP DSP; + +    void Reset() override; +    void Stop(Platform::StopReason reason) override; + +    bool DoSavestate(Savestate* file); + +    void SetCartInserted(bool inserted); + +    void SetupDirectBoot() override; +    void SoftReset(); + +    bool LoadNAND(); + +    void RunNDMAs(u32 cpu); +    void StallNDMAs(); +    bool NDMAsInMode(u32 cpu, u32 mode); +    bool NDMAsRunning(u32 cpu); +    void CheckNDMAs(u32 cpu, u32 mode); +    void StopNDMAs(u32 cpu, u32 mode); + +    void MapNWRAM_A(u32 num, u8 val); +    void MapNWRAM_B(u32 num, u8 val); +    void MapNWRAM_C(u32 num, u8 val); +    void MapNWRAMRange(u32 cpu, u32 num, u32 val); + +    u8 ARM9Read8(u32 addr) override; +    u16 ARM9Read16(u32 addr) override; +    u32 ARM9Read32(u32 addr) override; +    void ARM9Write8(u32 addr, u8 val) override; +    void ARM9Write16(u32 addr, u16 val) override; +    void ARM9Write32(u32 addr, u32 val) override; + +    bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region) override; + +    u8 ARM7Read8(u32 addr) override; +    u16 ARM7Read16(u32 addr) override; +    u32 ARM7Read32(u32 addr) override; +    void ARM7Write8(u32 addr, u8 val) override; +    void ARM7Write16(u32 addr, u16 val) override; +    void ARM7Write32(u32 addr, u32 val) override; + +    bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region) override; + +    u8 ARM9IORead8(u32 addr) override; +    u16 ARM9IORead16(u32 addr) override; +    u32 ARM9IORead32(u32 addr) override; +    void ARM9IOWrite8(u32 addr, u8 val) override; +    void ARM9IOWrite16(u32 addr, u16 val) override; +    void ARM9IOWrite32(u32 addr, u32 val) override; + +    u8 ARM7IORead8(u32 addr) override; +    u16 ARM7IORead16(u32 addr) override; +    u32 ARM7IORead32(u32 addr) override; +    void ARM7IOWrite8(u32 addr, u8 val) override; +    void ARM7IOWrite16(u32 addr, u16 val) override; +    void ARM7IOWrite32(u32 addr, u32 val) override; + +public: +    DSi() noexcept; +    ~DSi() noexcept override; +    DSi(const DSi&) = delete; +    DSi& operator=(const DSi&) = delete; +    DSi(DSi&&) = delete; +    DSi& operator=(DSi&&) = delete; +    bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) override; +    void EjectCart() override; +    bool NeedsDirectBoot() override +    { +        // for now, DSi mode requires original BIOS/NAND +        return false; +    } +    void CamInputFrame(int cam, u32* data, int width, int height, bool rgb) override; +    bool DMAsInMode(u32 cpu, u32 mode) override; +    bool DMAsRunning(u32 cpu) override; +    void StopDMAs(u32 cpu, u32 mode) override; +    void CheckDMAs(u32 cpu, u32 mode) override; +    u16 SCFG_Clock7; +    u32 SCFG_MC; +    u16 SCFG_RST; +    u32 MBK[2][9]; +    u32 NDMACnt[2]; +    std::array<DSi_NDMA, 8> NDMAs; +    // FIXME: these currently have no effect (and aren't stored in a savestate) +    //        ... not that they matter all that much +    u8 GPIO_Data; +    u8 GPIO_Dir; +    u8 GPIO_IEdgeSel; +    u8 GPIO_IE; +    u8 GPIO_WiFi; + +private: +    void Set_SCFG_Clock9(u16 val); +    void Set_SCFG_MC(u32 val); +    void DecryptModcryptArea(u32 offset, u32 size, u8* iv); +    void ApplyNewRAMSize(u32 size); +};  }  #endif // DSI_H diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index a29e43f..8e04586 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -36,7 +36,7 @@ using Platform::LogLevel;  #define _printhex2R(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[((size)-1)-z]); } -DSi_AES::DSi_AES() +DSi_AES::DSi_AES(melonDS::DSi& dsi) : DSi(dsi)  {      const u8 zero[16] = {0};      AES_init_ctx_iv(&Ctx, zero, zero); @@ -78,7 +78,7 @@ void DSi_AES::Reset()      OutputMACDue = false;      // initialize keys -    u64 consoleid = DSi::NANDImage->GetConsoleID(); +    u64 consoleid = DSi.NANDImage->GetConsoleID();      // slot 0: modcrypt      *(u32*)&KeyX[0][0] = 0x746E694E; @@ -313,7 +313,7 @@ void DSi_AES::WriteCnt(u32 val)                  AES_init_ctx_iv(&Ctx, key, iv);              } -            DSi::CheckNDMAs(1, 0x2A); +            DSi.CheckNDMAs(1, 0x2A);          }          else          { @@ -347,9 +347,9 @@ u32 DSi_AES::ReadOutputFIFO()      else      {          if (OutputFIFO.Level() > 0) -            DSi::CheckNDMAs(1, 0x2B); +            DSi.CheckNDMAs(1, 0x2B);          else -            DSi::StopNDMAs(1, 0x2B); +            DSi.StopNDMAs(1, 0x2B);          if (OutputMACDue && OutputFIFO.Level() <= 12)          { @@ -384,7 +384,7 @@ void DSi_AES::CheckInputDMA()      if (InputFIFO.Level() <= InputDMASize)      {          // trigger input DMA -        DSi::CheckNDMAs(1, 0x2A); +        DSi.CheckNDMAs(1, 0x2A);      }      Update(); @@ -395,7 +395,7 @@ void DSi_AES::CheckOutputDMA()      if (OutputFIFO.Level() >= OutputDMASize)      {          // trigger output DMA -        DSi::CheckNDMAs(1, 0x2B); +        DSi.CheckNDMAs(1, 0x2B);      }  } @@ -475,13 +475,13 @@ void DSi_AES::Update()          }          Cnt &= ~(1<<31); -        if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES); -        DSi::StopNDMAs(1, 0x2A); +        if (Cnt & (1<<30)) DSi.SetIRQ2(IRQ2_DSi_AES); +        DSi.StopNDMAs(1, 0x2A);          if (!OutputFIFO.IsEmpty()) -            DSi::CheckNDMAs(1, 0x2B); +            DSi.CheckNDMAs(1, 0x2B);          else -            DSi::StopNDMAs(1, 0x2B); +            DSi.StopNDMAs(1, 0x2B);          OutputFlush = false;      }  } diff --git a/src/DSi_AES.h b/src/DSi_AES.h index 9c0a63f..4df8269 100644 --- a/src/DSi_AES.h +++ b/src/DSi_AES.h @@ -45,10 +45,11 @@ __attribute((always_inline)) static void Bswap128(void* Dst, const void* Src)  #endif  #pragma GCC diagnostic pop +class DSi;  class DSi_AES  {  public: -    DSi_AES(); +    DSi_AES(melonDS::DSi& dsi);      ~DSi_AES();      void Reset();      void DoSavestate(Savestate* file); @@ -73,6 +74,7 @@ public:      static void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey);  private: +    melonDS::DSi& DSi;      u32 Cnt;      u32 BlkCnt; diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp index 708875c..225bea8 100644 --- a/src/DSi_Camera.cpp +++ b/src/DSi_Camera.cpp @@ -38,13 +38,13 @@ const u32 DSi_CamModule::kIRQInterval = 1120000; // ~30 FPS  const u32 DSi_CamModule::kTransferStart = 60000; -DSi_CamModule::DSi_CamModule() +DSi_CamModule::DSi_CamModule(melonDS::DSi& dsi) : DSi(dsi)  { -    NDS::RegisterEventFunc(NDS::Event_DSi_CamIRQ, 0, MemberEventFunc(DSi_CamModule, IRQ)); -    NDS::RegisterEventFunc(NDS::Event_DSi_CamTransfer, 0, MemberEventFunc(DSi_CamModule, TransferScanline)); +    DSi.RegisterEventFunc(Event_DSi_CamIRQ, 0, MemberEventFunc(DSi_CamModule, IRQ)); +    DSi.RegisterEventFunc(Event_DSi_CamTransfer, 0, MemberEventFunc(DSi_CamModule, TransferScanline)); -    Camera0 = DSi::I2C->GetOuterCamera(); -    Camera1 = DSi::I2C->GetInnerCamera(); +    Camera0 = DSi.I2C.GetOuterCamera(); +    Camera1 = DSi.I2C.GetInnerCamera();  }  DSi_CamModule::~DSi_CamModule() @@ -52,8 +52,8 @@ DSi_CamModule::~DSi_CamModule()      Camera0 = nullptr;      Camera1 = nullptr; -    NDS::UnregisterEventFunc(NDS::Event_DSi_CamIRQ, 0); -    NDS::UnregisterEventFunc(NDS::Event_DSi_CamTransfer, 0); +    DSi.UnregisterEventFunc(Event_DSi_CamIRQ, 0); +    DSi.UnregisterEventFunc(Event_DSi_CamTransfer, 0);  }  void DSi_CamModule::Reset() @@ -70,7 +70,7 @@ void DSi_CamModule::Reset()      BufferNumLines = 0;      CurCamera = nullptr; -    NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, false, kIRQInterval, 0, 0); +    DSi.ScheduleEvent(Event_DSi_CamIRQ, false, kIRQInterval, 0, 0);  }  void DSi_CamModule::Stop() @@ -106,7 +106,7 @@ void DSi_CamModule::IRQ(u32 param)          activecam->StartTransfer();          if (Cnt & (1<<11)) -            NDS::SetIRQ(0, NDS::IRQ_DSi_Camera); +            DSi.SetIRQ(0, IRQ_DSi_Camera);          if (Cnt & (1<<15))          { @@ -114,11 +114,11 @@ void DSi_CamModule::IRQ(u32 param)              BufferWritePos = 0;              BufferNumLines = 0;              CurCamera = activecam; -            NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, kTransferStart, 0, 0); +            DSi.ScheduleEvent(Event_DSi_CamTransfer, false, kTransferStart, 0, 0);          }      } -    NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, 0, 0); +    DSi.ScheduleEvent(Event_DSi_CamIRQ, true, kIRQInterval, 0, 0);  }  void DSi_CamModule::TransferScanline(u32 line) @@ -144,7 +144,7 @@ void DSi_CamModule::TransferScanline(u32 line)          if (line < ystart || line > yend)          {              if (!CurCamera->TransferDone()) -                NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, delay, 0, line+1); +                DSi.ScheduleEvent(Event_DSi_CamTransfer, false, delay, 0, line+1);              return;          } @@ -212,7 +212,7 @@ void DSi_CamModule::TransferScanline(u32 line)          BufferReadPos = 0; // checkme          BufferWritePos = 0;          BufferNumLines = 0; -        DSi::CheckNDMAs(0, 0x0B); +        DSi.CheckNDMAs(0, 0x0B);      }      else      { @@ -224,7 +224,7 @@ void DSi_CamModule::TransferScanline(u32 line)      if (CurCamera->TransferDone())          return; -    NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, delay, 0, line+1); +    DSi.ScheduleEvent(Event_DSi_CamTransfer, false, delay, 0, line+1);  } @@ -379,7 +379,7 @@ void DSi_CamModule::Write32(u32 addr, u32 val) -DSi_Camera::DSi_Camera(DSi_I2CHost* host, u32 num) : DSi_I2CDevice(host), Num(num) +DSi_Camera::DSi_Camera(melonDS::DSi& dsi, DSi_I2CHost* host, u32 num) : DSi_I2CDevice(dsi, host), Num(num)  {  } diff --git a/src/DSi_Camera.h b/src/DSi_Camera.h index 8a62e47..ec40922 100644 --- a/src/DSi_Camera.h +++ b/src/DSi_Camera.h @@ -25,17 +25,18 @@  namespace melonDS  { +class DSi;  class DSi_CamModule;  class DSi_Camera : public DSi_I2CDevice  {  public: -    DSi_Camera(DSi_I2CHost* host, u32 num); +    DSi_Camera(melonDS::DSi& dsi, DSi_I2CHost* host, u32 num);      ~DSi_Camera(); -    void DoSavestate(Savestate* file); +    void DoSavestate(Savestate* file) override; -    void Reset(); +    void Reset() override;      void Stop();      bool IsActivated(); @@ -45,9 +46,9 @@ public:      // lengths in words      int TransferScanline(u32* buffer, int maxlen); -    void Acquire(); -    u8 Read(bool last); -    void Write(u8 val, bool last); +    void Acquire() override; +    u8 Read(bool last) override; +    void Write(u8 val, bool last) override;      void InputFrame(u32* data, int width, int height, bool rgb); @@ -84,7 +85,7 @@ private:  class DSi_CamModule  {  public: -    DSi_CamModule(); +    DSi_CamModule(melonDS::DSi& dsi);      ~DSi_CamModule();      void Reset();      void Stop(); @@ -105,6 +106,7 @@ public:      void Write32(u32 addr, u32 val);  private: +    melonDS::DSi& DSi;      DSi_Camera* Camera0; // 78 / facing outside      DSi_Camera* Camera1; // 7A / selfie cam diff --git a/src/DSi_DSP.cpp b/src/DSi_DSP.cpp index 61d2b16..088943a 100644 --- a/src/DSi_DSP.cpp +++ b/src/DSi_DSP.cpp @@ -55,33 +55,33 @@ u16 DSi_DSP::GetPSTS()  void DSi_DSP::IrqRep0()  { -    if (DSP_PCFG & (1<< 9)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); +    if (DSP_PCFG & (1<< 9)) DSi.SetIRQ(0, IRQ_DSi_DSP);  }  void DSi_DSP::IrqRep1()  { -    if (DSP_PCFG & (1<<10)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); +    if (DSP_PCFG & (1<<10)) DSi.SetIRQ(0, IRQ_DSi_DSP);  }  void DSi_DSP::IrqRep2()  { -    if (DSP_PCFG & (1<<11)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); +    if (DSP_PCFG & (1<<11)) DSi.SetIRQ(0, IRQ_DSi_DSP);  }  void DSi_DSP::IrqSem()  {      DSP_PSTS |= 1<<9;      // apparently these are always fired? -    NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); +    DSi.SetIRQ(0, IRQ_DSi_DSP);  }  u16 DSi_DSP::DSPRead16(u32 addr)  {      if (!(addr & 0x40000))      { -        u8* ptr = DSi::NWRAMMap_B[2][(addr >> 15) & 0x7]; +        u8* ptr = DSi.NWRAMMap_B[2][(addr >> 15) & 0x7];          return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;      }      else      { -        u8* ptr = DSi::NWRAMMap_C[2][(addr >> 15) & 0x7]; +        u8* ptr = DSi.NWRAMMap_C[2][(addr >> 15) & 0x7];          return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;      }  } @@ -92,12 +92,12 @@ void DSi_DSP::DSPWrite16(u32 addr, u16 val)      if (!(addr & 0x40000))      { -        u8* ptr = DSi::NWRAMMap_B[2][(addr >> 15) & 0x7]; +        u8* ptr = DSi.NWRAMMap_B[2][(addr >> 15) & 0x7];          if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val;      }      else      { -        u8* ptr = DSi::NWRAMMap_C[2][(addr >> 15) & 0x7]; +        u8* ptr = DSi.NWRAMMap_C[2][(addr >> 15) & 0x7];          if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val;      }  } @@ -107,9 +107,9 @@ void DSi_DSP::AudioCb(std::array<s16, 2> frame)      // TODO  } -DSi_DSP::DSi_DSP() +DSi_DSP::DSi_DSP(melonDS::DSi& dsi) : DSi(dsi)  { -    NDS::RegisterEventFunc(NDS::Event_DSi_DSP, 0, MemberEventFunc(DSi_DSP, DSPCatchUpU32)); +    DSi.RegisterEventFunc(Event_DSi_DSP, 0, MemberEventFunc(DSi_DSP, DSPCatchUpU32));      TeakraCore = new Teakra::Teakra();      SCFG_RST = false; @@ -133,12 +133,12 @@ DSi_DSP::DSi_DSP()      // these happen instantaneously and without too much regard for bus aribtration      // rules, so, this might have to be changed later on      Teakra::AHBMCallback cb; -    cb.read8 = DSi::ARM9Read8; -    cb.write8 = DSi::ARM9Write8; -    cb.read16 = DSi::ARM9Read16; -    cb.write16 = DSi::ARM9Write16; -    cb.read32 = DSi::ARM9Read32; -    cb.write32 = DSi::ARM9Write32; +    cb.read8 = [this](auto addr) { return DSi.ARM9Read8(addr); }; +    cb.write8 = [this](auto addr, auto val) { DSi.ARM9Write8(addr, val); }; +    cb.read16 = [this](auto addr) { return DSi.ARM9Read16(addr); }; +    cb.write16 = [this](auto addr, auto val) { DSi.ARM9Write16(addr, val); }; +    cb.read32 = [this](auto addr) { return DSi.ARM9Read32(addr); }; +    cb.write32 = [this](auto addr, auto val) { DSi.ARM9Write32(addr, val); };      TeakraCore->SetAHBMCallback(cb);      TeakraCore->SetAudioCallback(std::bind(&DSi_DSP::AudioCb, this, _1)); @@ -156,7 +156,7 @@ DSi_DSP::~DSi_DSP()      //PDATAWriteFifo = NULL;      TeakraCore = NULL; -    NDS::UnregisterEventFunc(NDS::Event_DSi_DSP, 0); +    DSi.UnregisterEventFunc(Event_DSi_DSP, 0);  }  void DSi_DSP::Reset() @@ -177,7 +177,7 @@ void DSi_DSP::Reset()      //PDATAWriteFifo->Clear();      TeakraCore->Reset(); -    NDS::CancelEvent(NDS::Event_DSi_DSP); +    DSi.CancelEvent(Event_DSi_DSP);      SNDExCnt = 0;  } @@ -190,17 +190,17 @@ void DSi_DSP::SetRstLine(bool release)  {      SCFG_RST = release;      Reset(); -    DSPTimestamp = NDS::ARM9Timestamp; // only start now! +    DSPTimestamp = DSi.ARM9Timestamp; // only start now!  }  inline bool DSi_DSP::IsDSPCoreEnabled()  { -    return (DSi::SCFG_Clock9 & (1<<1)) && SCFG_RST && (!(DSP_PCFG & (1<<0))); +    return (DSi.SCFG_Clock9 & (1<<1)) && SCFG_RST && (!(DSP_PCFG & (1<<0)));  }  inline bool DSi_DSP::IsDSPIOEnabled()  { -    return (DSi::SCFG_Clock9 & (1<<1)) && SCFG_RST; +    return (DSi.SCFG_Clock9 & (1<<1)) && SCFG_RST;  }  bool DSi_DSP::DSPCatchUp() @@ -210,13 +210,13 @@ bool DSi_DSP::DSPCatchUp()      {          // nothing to do, but advance the current time so that we don't do an          // unreasonable amount of cycles when rst is released -        if (DSPTimestamp < NDS::ARM9Timestamp) -            DSPTimestamp = NDS::ARM9Timestamp; +        if (DSPTimestamp < DSi.ARM9Timestamp) +            DSPTimestamp = DSi.ARM9Timestamp;          return false;      } -    u64 curtime = NDS::ARM9Timestamp; +    u64 curtime = DSi.ARM9Timestamp;      if (DSPTimestamp >= curtime) return true; // ummmm?! @@ -257,7 +257,7 @@ void DSi_DSP::PDataDMAWrite(u16 wrval)          {              switch (TeakraCore->AHBMGetUnitSize(0))              { -            case 0: /* 8bit */        DSi::ARM9Write8 (addr, (u8)wrval); break; +            case 0: /* 8bit */        DSi.ARM9Write8 (addr, (u8)wrval); break;              case 1: /* 16 b */ TeakraCore->AHBMWrite16(addr,     wrval); break;              // does it work like this, or should it first buffer two u16's              // until it has enough data to write to the actual destination? @@ -272,7 +272,7 @@ void DSi_DSP::PDataDMAWrite(u16 wrval)      if (DSP_PCFG & (1<<1)) // auto-increment          ++DSP_PADR; // overflows and stays within a 64k 'page' // TODO: is this +1 or +2? -    NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); // wrfifo empty +    DSi.SetIRQ(0, IRQ_DSi_DSP); // wrfifo empty  }  // TODO: FIFO interrupts! (rd full, nonempty)  u16 DSi_DSP::PDataDMARead() @@ -299,7 +299,7 @@ u16 DSi_DSP::PDataDMARead()          {              switch (TeakraCore->AHBMGetUnitSize(0))              { -            case 0: /* 8bit */ r =             DSi::ARM9Read8 (addr); break; +            case 0: /* 8bit */ r =             DSi.ARM9Read8 (addr); break;              case 1: /* 16 b */ r =      TeakraCore->AHBMRead16(addr); break;              case 2: /* 32 b */ r = (u16)TeakraCore->AHBMRead32(addr); break;              } @@ -337,7 +337,7 @@ void DSi_DSP::PDataDMAStart()      for (int i = 0; i < amt; ++i)          PDataDMAFetch(); -    NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); +    DSi.SetIRQ(0, IRQ_DSi_DSP);  }  void DSi_DSP::PDataDMACancel() @@ -372,7 +372,7 @@ u16 DSi_DSP::PDataDMAReadMMIO()      }      if (!PDATAReadFifo.IsEmpty() || PDATAReadFifo.IsFull()) -        NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); +        DSi.SetIRQ(0, IRQ_DSi_DSP);      return ret;  } @@ -477,7 +477,7 @@ void DSi_DSP::Write8(u32 addr, u8 val)  }  void DSi_DSP::Write16(u32 addr, u16 val)  { -    Log(LogLevel::Debug,"DSP WRITE16 %d %08X %08X  %08X\n", IsDSPCoreEnabled(), addr, val, NDS::GetPC(0)); +    Log(LogLevel::Debug,"DSP WRITE16 %d %08X %08X  %08X\n", IsDSPCoreEnabled(), addr, val, DSi.GetPC(0));      //if (!IsDSPIOEnabled()) return;      DSPCatchUp(); @@ -565,8 +565,8 @@ void DSi_DSP::Run(u32 cycles)      DSPTimestamp += cycles; -    NDS::CancelEvent(NDS::Event_DSi_DSP); -    NDS::ScheduleEvent(NDS::Event_DSi_DSP, false, +    DSi.CancelEvent(Event_DSi_DSP); +    DSi.ScheduleEvent(Event_DSi_DSP, false,              16384/*from citra (TeakraSlice)*/, 0, 0);  } diff --git a/src/DSi_DSP.h b/src/DSi_DSP.h index 18ad3d1..a18dabf 100644 --- a/src/DSi_DSP.h +++ b/src/DSi_DSP.h @@ -29,10 +29,11 @@ namespace Teakra { class Teakra; }  namespace melonDS  { +class DSi;  class DSi_DSP  {  public: -    DSi_DSP(); +    DSi_DSP(melonDS::DSi& dsi);      ~DSi_DSP();      void Reset();      void DoSavestate(Savestate* file); @@ -68,6 +69,7 @@ public:      void AudioCb(std::array<s16, 2> frame);  private: +    melonDS::DSi& DSi;      // not sure whether to not rather put it somewhere else      u16 SNDExCnt; diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp index 678c8be..d5ea60c 100644 --- a/src/DSi_I2C.cpp +++ b/src/DSi_I2C.cpp @@ -57,7 +57,7 @@ const u8 DSi_BPTWL::VolumeUpTable[32] =  }; -DSi_BPTWL::DSi_BPTWL(DSi_I2CHost* host) : DSi_I2CDevice(host) +DSi_BPTWL::DSi_BPTWL(melonDS::DSi& dsi, DSi_I2CHost* host) : DSi_I2CDevice(dsi, host)  {  } @@ -177,19 +177,19 @@ void DSi_BPTWL::DoHardwareReset(bool direct)      if (direct)      {          // TODO: This doesn't seem to stop the SPU -        DSi::SoftReset(); +        DSi.SoftReset();          return;      }      // TODO: soft-reset might need to be scheduled later!      // TODO: this has been moved for the JIT to work, nothing is confirmed here -    NDS::ARM7->Halt(4); +    DSi.ARM7.Halt(4);  }  void DSi_BPTWL::DoShutdown()  {      ResetButtonState(); -    NDS::Stop(Platform::StopReason::PowerOff); +    DSi.Stop(Platform::StopReason::PowerOff);  } @@ -369,7 +369,7 @@ void DSi_BPTWL::SetIRQ(u8 irqFlag)      if (GetIRQMode())      { -        NDS::SetIRQ2(NDS::IRQ2_DSi_BPTWL); +        DSi.SetIRQ2(IRQ2_DSi_BPTWL);      }  } @@ -451,11 +451,11 @@ void DSi_BPTWL::Write(u8 val, bool last)  } -DSi_I2CHost::DSi_I2CHost() +DSi_I2CHost::DSi_I2CHost(melonDS::DSi& dsi) : DSi(dsi)  { -    BPTWL = new DSi_BPTWL(this); -    Camera0 = new DSi_Camera(this, 0); -    Camera1 = new DSi_Camera(this, 1); +    BPTWL = new DSi_BPTWL(dsi, this); +    Camera0 = new DSi_Camera(dsi, this, 0); +    Camera1 = new DSi_Camera(dsi, this, 1);  }  DSi_I2CHost::~DSi_I2CHost() diff --git a/src/DSi_I2C.h b/src/DSi_I2C.h index 83d7e02..51fe78e 100644 --- a/src/DSi_I2C.h +++ b/src/DSi_I2C.h @@ -26,11 +26,11 @@ namespace melonDS  {  class DSi_I2CHost;  class DSi_Camera; - +class DSi;  class DSi_I2CDevice  {  public: -    DSi_I2CDevice(DSi_I2CHost* host) : Host(host) {} +    DSi_I2CDevice(melonDS::DSi& dsi, DSi_I2CHost* host) : DSi(dsi), Host(host) {}      virtual ~DSi_I2CDevice() {}      virtual void Reset() = 0;      virtual void DoSavestate(Savestate* file) = 0; @@ -40,6 +40,7 @@ public:      virtual void Write(u8 val, bool last) = 0;  protected: +    melonDS::DSi& DSi;      DSi_I2CHost* Host;  }; @@ -80,7 +81,7 @@ public:          IRQ_ValidMask           = 0x7B,      }; -    DSi_BPTWL(DSi_I2CHost* host); +    DSi_BPTWL(melonDS::DSi& dsi, DSi_I2CHost* host);      ~DSi_BPTWL() override;      void Reset() override;      void DoSavestate(Savestate* file) override; @@ -153,7 +154,7 @@ private:  class DSi_I2CHost  {  public: -    DSi_I2CHost(); +    DSi_I2CHost(melonDS::DSi& dsi);      ~DSi_I2CHost();      void Reset();      void DoSavestate(Savestate* file); @@ -169,6 +170,7 @@ public:      void WriteData(u8 val);  private: +    melonDS::DSi& DSi;      u8 Cnt;      u8 Data; diff --git a/src/DSi_NDMA.cpp b/src/DSi_NDMA.cpp index 4f248ea..fe1f0ba 100644 --- a/src/DSi_NDMA.cpp +++ b/src/DSi_NDMA.cpp @@ -28,7 +28,7 @@ namespace melonDS  using Platform::Log;  using Platform::LogLevel; -DSi_NDMA::DSi_NDMA(u32 cpu, u32 num, melonDS::GPU& gpu) : GPU(gpu) +DSi_NDMA::DSi_NDMA(u32 cpu, u32 num, melonDS::DSi& dsi) : DSi(dsi), CPU(cpu), Num(num)  {      CPU = cpu;      Num = num; @@ -127,7 +127,7 @@ void DSi_NDMA::WriteCnt(u32 val)          if ((StartMode & 0x1F) == 0x10)              Start();          else if (StartMode == 0x0A) -            GPU.GPU3D.CheckFIFODMA(); +            DSi.GPU.GPU3D.CheckFIFODMA();          // TODO: unsupported start modes:          // * timers (00-03) @@ -181,13 +181,13 @@ void DSi_NDMA::Start()      //if (SubblockTimer & 0xFFFF)      //    printf("TODO! NDMA SUBBLOCK TIMER: %08X\n", SubblockTimer); -    if (NDS::DMAsRunning(CPU)) +    if (DSi.DMAsRunning(CPU))          Running = 1;      else          Running = 2;      InProgress = true; -    NDS::StopCPU(CPU, 1<<(Num+4)); +    DSi.StopCPU(CPU, 1<<(Num+4));  }  void DSi_NDMA::Run() @@ -199,7 +199,7 @@ void DSi_NDMA::Run()  void DSi_NDMA::Run9()  { -    if (NDS::ARM9Timestamp >= NDS::ARM9Target) return; +    if (DSi.ARM9Timestamp >= DSi.ARM9Target) return;      Executing = true; @@ -214,11 +214,11 @@ void DSi_NDMA::Run9()      if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)      { -        unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][2] + NDS::ARM9MemTimings[CurDstAddr >> 14][2]; +        unitcycles = DSi.ARM9MemTimings[CurSrcAddr >> 14][2] + DSi.ARM9MemTimings[CurDstAddr >> 14][2];      }      else      { -        unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][3] + NDS::ARM9MemTimings[CurDstAddr >> 14][3]; +        unitcycles = DSi.ARM9MemTimings[CurSrcAddr >> 14][3] + DSi.ARM9MemTimings[CurDstAddr >> 14][3];          if ((CurSrcAddr >> 24) == (CurDstAddr >> 24))              unitcycles++;          else if ((CurSrcAddr >> 24) == 0x02) @@ -234,12 +234,12 @@ void DSi_NDMA::Run9()      while (IterCount > 0 && !Stall)      { -        NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift); +        DSi.ARM9Timestamp += (unitcycles << DSi.ARM9ClockShift);          if (dofill) -            DSi::ARM9Write32(CurDstAddr, FillData); +            DSi.ARM9Write32(CurDstAddr, FillData);          else -            DSi::ARM9Write32(CurDstAddr, DSi::ARM9Read32(CurSrcAddr)); +            DSi.ARM9Write32(CurDstAddr, DSi.ARM9Read32(CurSrcAddr));          CurSrcAddr += SrcAddrInc<<2;          CurDstAddr += DstAddrInc<<2; @@ -247,7 +247,7 @@ void DSi_NDMA::Run9()          RemCount--;          TotalRemCount--; -        if (NDS::ARM9Timestamp >= NDS::ARM9Target) break; +        if (DSi.ARM9Timestamp >= DSi.ARM9Target) break;      }      Executing = false; @@ -258,10 +258,10 @@ void DSi_NDMA::Run9()          if (IterCount == 0)          {              Running = 0; -            NDS::ResumeCPU(0, 1<<(Num+4)); +            DSi.ResumeCPU(0, 1<<(Num+4));              if (StartMode == 0x0A) -                GPU.GPU3D.CheckFIFODMA(); +                DSi.GPU.GPU3D.CheckFIFODMA();          }          return; @@ -270,25 +270,25 @@ void DSi_NDMA::Run9()      if ((StartMode & 0x1F) == 0x10) // CHECKME      {          Cnt &= ~(1<<31); -        if (Cnt & (1<<30)) NDS::SetIRQ(0, NDS::IRQ_DSi_NDMA0 + Num); +        if (Cnt & (1<<30)) DSi.SetIRQ(0, IRQ_DSi_NDMA0 + Num);      }      else if (!(Cnt & (1<<29)))      {          if (TotalRemCount == 0)          {              Cnt &= ~(1<<31); -            if (Cnt & (1<<30)) NDS::SetIRQ(0, NDS::IRQ_DSi_NDMA0 + Num); +            if (Cnt & (1<<30)) DSi.SetIRQ(0, IRQ_DSi_NDMA0 + Num);          }      }      Running = 0;      InProgress = false; -    NDS::ResumeCPU(0, 1<<(Num+4)); +    DSi.ResumeCPU(0, 1<<(Num+4));  }  void DSi_NDMA::Run7()  { -    if (NDS::ARM7Timestamp >= NDS::ARM7Target) return; +    if (DSi.ARM7Timestamp >= DSi.ARM7Target) return;      Executing = true; @@ -303,11 +303,11 @@ void DSi_NDMA::Run7()      if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)      { -        unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][2] + NDS::ARM7MemTimings[CurDstAddr >> 15][2]; +        unitcycles = DSi.ARM7MemTimings[CurSrcAddr >> 15][2] + DSi.ARM7MemTimings[CurDstAddr >> 15][2];      }      else      { -        unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][3] + NDS::ARM7MemTimings[CurDstAddr >> 15][3]; +        unitcycles = DSi.ARM7MemTimings[CurSrcAddr >> 15][3] + DSi.ARM7MemTimings[CurDstAddr >> 15][3];          if ((CurSrcAddr >> 23) == (CurDstAddr >> 23))              unitcycles++;          else if ((CurSrcAddr >> 24) == 0x02) @@ -323,12 +323,12 @@ void DSi_NDMA::Run7()      while (IterCount > 0 && !Stall)      { -        NDS::ARM7Timestamp += unitcycles; +        DSi.ARM7Timestamp += unitcycles;          if (dofill) -            DSi::ARM7Write32(CurDstAddr, FillData); +            DSi.ARM7Write32(CurDstAddr, FillData);          else -            DSi::ARM7Write32(CurDstAddr, DSi::ARM7Read32(CurSrcAddr)); +            DSi.ARM7Write32(CurDstAddr, DSi.ARM7Read32(CurSrcAddr));          CurSrcAddr += SrcAddrInc<<2;          CurDstAddr += DstAddrInc<<2; @@ -336,7 +336,7 @@ void DSi_NDMA::Run7()          RemCount--;          TotalRemCount--; -        if (NDS::ARM7Timestamp >= NDS::ARM7Target) break; +        if (DSi.ARM7Timestamp >= DSi.ARM7Target) break;      }      Executing = false; @@ -347,10 +347,10 @@ void DSi_NDMA::Run7()          if (IterCount == 0)          {              Running = 0; -            NDS::ResumeCPU(1, 1<<(Num+4)); +            DSi.ResumeCPU(1, 1<<(Num+4)); -            DSi::AES->CheckInputDMA(); -            DSi::AES->CheckOutputDMA(); +            DSi.AES.CheckInputDMA(); +            DSi.AES.CheckOutputDMA();          }          return; @@ -359,23 +359,23 @@ void DSi_NDMA::Run7()      if ((StartMode & 0x1F) == 0x10) // CHECKME      {          Cnt &= ~(1<<31); -        if (Cnt & (1<<30)) NDS::SetIRQ(1, NDS::IRQ_DSi_NDMA0 + Num); +        if (Cnt & (1<<30)) DSi.SetIRQ(1, IRQ_DSi_NDMA0 + Num);      }      else if (!(Cnt & (1<<29)))      {          if (TotalRemCount == 0)          {              Cnt &= ~(1<<31); -            if (Cnt & (1<<30)) NDS::SetIRQ(1, NDS::IRQ_DSi_NDMA0 + Num); +            if (Cnt & (1<<30)) DSi.SetIRQ(1, IRQ_DSi_NDMA0 + Num);          }      }      Running = 0;      InProgress = false; -    NDS::ResumeCPU(1, 1<<(Num+4)); +    DSi.ResumeCPU(1, 1<<(Num+4)); -    DSi::AES->CheckInputDMA(); -    DSi::AES->CheckOutputDMA(); +    DSi.AES.CheckInputDMA(); +    DSi.AES.CheckOutputDMA();  }  }
\ No newline at end of file diff --git a/src/DSi_NDMA.h b/src/DSi_NDMA.h index 4479341..7e87da7 100644 --- a/src/DSi_NDMA.h +++ b/src/DSi_NDMA.h @@ -24,12 +24,12 @@  namespace melonDS  { -class GPU; +class DSi;  class DSi_NDMA  {  public: -    DSi_NDMA(u32 cpu, u32 num, GPU& gpu); +    DSi_NDMA(u32 cpu, u32 num, melonDS::DSi& dsi);      ~DSi_NDMA();      void Reset(); @@ -77,7 +77,7 @@ public:      u32 Cnt;  private: -    melonDS::GPU& GPU; +    melonDS::DSi& DSi;      u32 CPU, Num;      u32 StartMode; diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 66320ba..9e006e2 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -119,21 +119,22 @@ const u8 CIS1[256] =  }; -DSi_NWifi::DSi_NWifi(DSi_SDHost* host) -    : DSi_SDDevice(host), -        Mailbox -        { -            // HACK -            // the mailboxes are supposed to be 0x80 bytes -            // however, as we do things instantly, emulating this is meaningless -            // and only adds complication -            DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), -            DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), -            // mailbox 8: extra mailbox acting as a bigger RX buffer -            DynamicFIFO<u8>(0x8000) -        } +DSi_NWifi::DSi_NWifi(melonDS::DSi& dsi, DSi_SDHost* host) : +    DSi_SDDevice(host), +    Mailbox +    { +        // HACK +        // the mailboxes are supposed to be 0x80 bytes +        // however, as we do things instantly, emulating this is meaningless +        // and only adds complication +        DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), +        DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), +        // mailbox 8: extra mailbox acting as a bigger RX buffer +        DynamicFIFO<u8>(0x8000) +    }, +    DSi(dsi)  { -    NDS::RegisterEventFunc(NDS::Event_DSi_NWifi, 0, MemberEventFunc(DSi_NWifi, MSTimer)); +    DSi.RegisterEventFunc(Event_DSi_NWifi, 0, MemberEventFunc(DSi_NWifi, MSTimer));      // this seems to control whether the firmware upload is done      EEPROMReady = 0; @@ -141,9 +142,9 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host)  DSi_NWifi::~DSi_NWifi()  { -    NDS::CancelEvent(NDS::Event_DSi_NWifi); +    DSi.CancelEvent(Event_DSi_NWifi); -    NDS::UnregisterEventFunc(NDS::Event_DSi_NWifi, 0); +    DSi.UnregisterEventFunc(Event_DSi_NWifi, 0);  }  void DSi_NWifi::Reset() @@ -164,7 +165,7 @@ void DSi_NWifi::Reset()      for (int i = 0; i < 9; i++)          Mailbox[i].Clear(); -    const Firmware* fw = NDS::SPI->GetFirmware(); +    const Firmware* fw = DSi.SPI.GetFirmware();      MacAddress mac = fw->GetHeader().MacAddr;      Log(LogLevel::Info, "NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", @@ -226,7 +227,7 @@ void DSi_NWifi::Reset()      BeaconTimer = 0x10A2220ULL;      ConnectionStatus = 0; -    NDS::CancelEvent(NDS::Event_DSi_NWifi); +    DSi.CancelEvent(Event_DSi_NWifi);  }  void DSi_NWifi::DoSavestate(Savestate* file) @@ -909,7 +910,7 @@ void DSi_NWifi::HTC_Command()              SendWMIEvent(1, 0x1006, regdomain_evt, 4);              BootPhase = 2; -            NDS::ScheduleEvent(NDS::Event_DSi_NWifi, false, 33611, 0, 0); +            DSi.ScheduleEvent(Event_DSi_NWifi, false, 33611, 0, 0);          }          break; @@ -1608,7 +1609,7 @@ void DSi_NWifi::MSTimer(u32 param)              CheckRX();      } -    NDS::ScheduleEvent(NDS::Event_DSi_NWifi, true, 33611, 0, 0); +    DSi.ScheduleEvent(Event_DSi_NWifi, true, 33611, 0, 0);  }  }
\ No newline at end of file diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h index f3e5e15..39e9459 100644 --- a/src/DSi_NWifi.h +++ b/src/DSi_NWifi.h @@ -28,7 +28,7 @@ namespace melonDS  class DSi_NWifi : public DSi_SDDevice  {  public: -    DSi_NWifi(DSi_SDHost* host); +    DSi_NWifi(melonDS::DSi& dsi, DSi_SDHost* host);      ~DSi_NWifi();      void Reset(); @@ -45,6 +45,7 @@ public:      void MSTimer(u32 param);  private: +    melonDS::DSi& DSi;      u32 TransferCmd;      u32 TransferAddr;      u32 RemSize; diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index 54f03ce..4cbf595 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -57,13 +57,13 @@ enum  }; -DSi_SDHost::DSi_SDHost(u32 num) +DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi, u32 num) : DSi(dsi)  {      Num = num; -    NDS::RegisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, +    DSi.RegisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer,                             Transfer_TX, MemberEventFunc(DSi_SDHost, FinishTX)); -    NDS::RegisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, +    DSi.RegisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer,                             Transfer_RX, MemberEventFunc(DSi_SDHost, FinishRX));      Ports[0] = nullptr; @@ -75,9 +75,9 @@ DSi_SDHost::~DSi_SDHost()      if (Ports[0]) delete Ports[0];      if (Ports[1]) delete Ports[1]; -    NDS::UnregisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, +    DSi.UnregisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer,                             Transfer_TX); -    NDS::UnregisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, +    DSi.UnregisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer,                             Transfer_RX);  } @@ -156,15 +156,15 @@ void DSi_SDHost::Reset()          else              sd = nullptr; -        mmc = new DSi_MMCStorage(this, *DSi::NANDImage); -        mmc->SetCID(DSi::NANDImage->GetEMMCID().data()); +        mmc = new DSi_MMCStorage(this, *DSi.NANDImage); +        mmc->SetCID(DSi.NANDImage->GetEMMCID().data());          Ports[0] = sd;          Ports[1] = mmc;      }      else      { -        DSi_NWifi* nwifi = new DSi_NWifi(this); +        DSi_NWifi* nwifi = new DSi_NWifi(DSi, this);          Ports[0] = nwifi;      } @@ -228,7 +228,7 @@ void DSi_SDHost::UpdateData32IRQ()      newflags &= (Data32IRQ >> 11);      if ((oldflags == 0) && (newflags != 0)) -        NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC); +        DSi.SetIRQ2(Num ? IRQ2_DSi_SDIO : IRQ2_DSi_SDMMC);  }  void DSi_SDHost::ClearIRQ(u32 irq) @@ -244,7 +244,7 @@ void DSi_SDHost::SetIRQ(u32 irq)      u32 newflags = IRQStatus & ~IRQMask;      if ((oldflags == 0) && (newflags != 0)) -        NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC); +        DSi.SetIRQ2(Num ? IRQ2_DSi_SDIO : IRQ2_DSi_SDMMC);  }  void DSi_SDHost::UpdateIRQ(u32 oldmask) @@ -253,7 +253,7 @@ void DSi_SDHost::UpdateIRQ(u32 oldmask)      u32 newflags = IRQStatus & ~IRQMask;      if ((oldflags == 0) && (newflags != 0)) -        NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC); +        DSi.SetIRQ2(Num ? IRQ2_DSi_SDIO : IRQ2_DSi_SDMMC);  }  void DSi_SDHost::SetCardIRQ() @@ -270,8 +270,8 @@ void DSi_SDHost::SetCardIRQ()      if ((oldflags == 0) && (newflags != 0)) // checkme      { -        NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC); -        NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO_Data1 : NDS::IRQ2_DSi_SD_Data1); +        DSi.SetIRQ2(Num ? IRQ2_DSi_SDIO : IRQ2_DSi_SDMMC); +        DSi.SetIRQ2(Num ? IRQ2_DSi_SDIO_Data1 : IRQ2_DSi_SD_Data1);      }  } @@ -282,8 +282,8 @@ void DSi_SDHost::UpdateCardIRQ(u16 oldmask)      if ((oldflags == 0) && (newflags != 0)) // checkme      { -        NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC); -        NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO_Data1 : NDS::IRQ2_DSi_SD_Data1); +        DSi.SetIRQ2(Num ? IRQ2_DSi_SDIO : IRQ2_DSi_SDMMC); +        DSi.SetIRQ2(Num ? IRQ2_DSi_SDIO_Data1 : IRQ2_DSi_SD_Data1);      }  } @@ -324,7 +324,7 @@ u32 DSi_SDHost::DataRX(u8* data, u32 len)      // we need a delay because DSi boot2 will send a command and then wait for IRQ0      // but if IRQ24 is thrown instantly, the handler clears IRQ0 before the      // send-command function starts polling IRQ status -    NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, +    DSi.ScheduleEvent(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer,                         false, 512, Transfer_RX, 0);      return len; @@ -366,7 +366,7 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)              if (DataFIFO32.IsEmpty())              {                  SetIRQ(25); -                DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); +                DSi.CheckNDMAs(1, Num ? 0x29 : 0x28);              }              return 0;          } @@ -405,7 +405,7 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)      CurFIFO ^= 1;      BlockCountInternal--; -    NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, +    DSi.ScheduleEvent(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer,                         false, 512, Transfer_TX, 0);      return len; @@ -536,7 +536,7 @@ u16 DSi_SDHost::Read(u32 addr)      case 0x10A: return 0;      } -    Log(LogLevel::Warn, "unknown %s read %08X @ %08X\n", SD_DESC, addr, NDS::GetPC(1)); +    Log(LogLevel::Warn, "unknown %s read %08X @ %08X\n", SD_DESC, addr, DSi.GetPC(1));      return 0;  } @@ -761,7 +761,7 @@ void DSi_SDHost::UpdateFIFO32()      if ((DataFIFO32.Level() << 2) >= BlockLen32)      { -        DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); +        DSi.CheckNDMAs(1, Num ? 0x29 : 0x28);      }  } diff --git a/src/DSi_SD.h b/src/DSi_SD.h index faa4296..17ba8d3 100644 --- a/src/DSi_SD.h +++ b/src/DSi_SD.h @@ -32,12 +32,13 @@ namespace DSi_NAND  }  class DSi_SDDevice; +class DSi;  class DSi_SDHost  {  public: -    DSi_SDHost(u32 num); +    DSi_SDHost(melonDS::DSi& dsi, u32 num);      ~DSi_SDHost();      void CloseHandles(); @@ -69,6 +70,7 @@ public:      void CheckSwapFIFO();  private: +    melonDS::DSi& DSi;      u32 Num;      u16 PortSelect; diff --git a/src/DSi_SPI_TSC.cpp b/src/DSi_SPI_TSC.cpp index 520e57b..6c7a15c 100644 --- a/src/DSi_SPI_TSC.cpp +++ b/src/DSi_SPI_TSC.cpp @@ -28,7 +28,7 @@ using Platform::Log;  using Platform::LogLevel; -DSi_TSC::DSi_TSC(SPIHost* host) : TSC(host) +DSi_TSC::DSi_TSC(melonDS::DSi& dsi) : TSC(dsi)  {  } @@ -198,7 +198,7 @@ void DSi_TSC::Write(u8 val)                      {                          Log(LogLevel::Debug, "DSi_SPI_TSC: DS-compatibility mode\n");                          DataPos = 0; -                        NDS::KeyInput |= (1 << (16+6)); +                        NDS.KeyInput |= (1 << (16+6));                          return;                      }                  } diff --git a/src/DSi_SPI_TSC.h b/src/DSi_SPI_TSC.h index 8e9ff91..47777da 100644 --- a/src/DSi_SPI_TSC.h +++ b/src/DSi_SPI_TSC.h @@ -25,10 +25,11 @@  namespace melonDS  { +class DSi;  class DSi_TSC : public TSC  {  public: -    DSi_TSC(SPIHost* host); +    DSi_TSC(melonDS::DSi& dsi);      ~DSi_TSC() override;      void Reset() override; diff --git a/src/GBACart.cpp b/src/GBACart.cpp index a0c5467..f5e320f 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -850,7 +850,7 @@ void GBACartSlot::LoadAddon(int type) noexcept  {
      switch (type)
      {
 -    case NDS::GBAAddon_RAMExpansion:
 +    case GBAAddon_RAMExpansion:
          Cart = std::make_unique<CartRAMExpansion>();
          break;
 diff --git a/src/GPU.cpp b/src/GPU.cpp index 27dcbfb..7a81f7d 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -64,12 +64,12 @@ enum                  VRAMDirty need to be reset for the respective VRAM bank.  */ -GPU::GPU(ARMJIT& jit) noexcept : GPU2D_A(0, *this), GPU2D_B(1, *this), JIT(jit) +GPU::GPU(melonDS::NDS& nds) noexcept : NDS(nds), GPU2D_A(0, *this), GPU2D_B(1, *this), GPU3D(nds)  { -    NDS::RegisterEventFunc(NDS::Event_LCD, LCD_StartHBlank, MemberEventFunc(GPU, StartHBlank)); -    NDS::RegisterEventFunc(NDS::Event_LCD, LCD_StartScanline, MemberEventFunc(GPU, StartScanline)); -    NDS::RegisterEventFunc(NDS::Event_LCD, LCD_FinishFrame, MemberEventFunc(GPU, FinishFrame)); -    NDS::RegisterEventFunc(NDS::Event_DisplayFIFO, 0, MemberEventFunc(GPU, DisplayFIFO)); +    NDS.RegisterEventFunc(Event_LCD, LCD_StartHBlank, MemberEventFunc(GPU, StartHBlank)); +    NDS.RegisterEventFunc(Event_LCD, LCD_StartScanline, MemberEventFunc(GPU, StartScanline)); +    NDS.RegisterEventFunc(Event_LCD, LCD_FinishFrame, MemberEventFunc(GPU, FinishFrame)); +    NDS.RegisterEventFunc(Event_DisplayFIFO, 0, MemberEventFunc(GPU, DisplayFIFO));      GPU2D_Renderer = std::make_unique<GPU2D::SoftRenderer>(*this); @@ -92,10 +92,10 @@ GPU::~GPU() noexcept      Framebuffer[1][0] = nullptr;      Framebuffer[1][1] = nullptr; -    NDS::UnregisterEventFunc(NDS::Event_LCD, LCD_StartHBlank); -    NDS::UnregisterEventFunc(NDS::Event_LCD, LCD_StartScanline); -    NDS::UnregisterEventFunc(NDS::Event_LCD, LCD_FinishFrame); -    NDS::UnregisterEventFunc(NDS::Event_DisplayFIFO, 0); +    NDS.UnregisterEventFunc(Event_LCD, LCD_StartHBlank); +    NDS.UnregisterEventFunc(Event_LCD, LCD_StartScanline); +    NDS.UnregisterEventFunc(Event_LCD, LCD_FinishFrame); +    NDS.UnregisterEventFunc(Event_DisplayFIFO, 0);  }  void GPU::ResetVRAMCache() noexcept @@ -298,7 +298,7 @@ void GPU::DoSavestate(Savestate* file) noexcept  void GPU::AssignFramebuffers() noexcept  {      int backbuf = FrontBuffer ? 0 : 1; -    if (NDS::PowerControl9 & (1<<15)) +    if (NDS.PowerControl9 & (1<<15))      {          GPU2D_Renderer->SetFramebuffer(Framebuffer[backbuf][0], Framebuffer[backbuf][1]);      } @@ -588,7 +588,7 @@ void GPU::MapVRAM_CD(u32 bank, u8 cnt) noexcept              VRAMMap_ARM7[ofs] |= bankmask;              memset(VRAMDirty[bank].Data, 0xFF, sizeof(VRAMDirty[bank].Data));              VRAMSTAT |= (1 << (bank-2)); -            JIT.CheckAndInvalidateWVRAM(ofs); +            NDS.JIT.CheckAndInvalidateWVRAM(ofs);              break;          case 3: // texture @@ -942,8 +942,8 @@ void GPU::DisplayFIFO(u32 x) noexcept      if (x < 256)      {          // transfer the next 8 pixels -        NDS::CheckDMAs(0, 0x04); -        NDS::ScheduleEvent(NDS::Event_DisplayFIFO, true, 6*8, 0, x+8); +        NDS.CheckDMAs(0, 0x04); +        NDS.ScheduleEvent(Event_DisplayFIFO, true, 6*8, 0, x+8);      }      else          GPU2D_A.SampleFIFO(253, 3); // sample the remaining pixels @@ -954,7 +954,7 @@ void GPU::StartFrame() noexcept      // 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); @@ -982,7 +982,7 @@ void GPU::StartHBlank(u32 line) noexcept              GPU2D_Renderer->DrawSprites(line+1, &GPU2D_B);          } -        NDS::CheckDMAs(0, 0x02); +        NDS.CheckDMAs(0, 0x02);      }      else if (VCount == 215)      { @@ -994,13 +994,13 @@ void GPU::StartHBlank(u32 line) noexcept          GPU2D_Renderer->DrawSprites(0, &GPU2D_B);      } -    if (DispStat[0] & (1<<4)) NDS::SetIRQ(0, NDS::IRQ_HBlank); -    if (DispStat[1] & (1<<4)) NDS::SetIRQ(1, NDS::IRQ_HBlank); +    if (DispStat[0] & (1<<4)) NDS.SetIRQ(0, IRQ_HBlank); +    if (DispStat[1] & (1<<4)) NDS.SetIRQ(1, IRQ_HBlank);      if (VCount < 262) -        NDS::ScheduleEvent(NDS::Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), LCD_StartScanline, line+1); +        NDS.ScheduleEvent(Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), LCD_StartScanline, line+1);      else -        NDS::ScheduleEvent(NDS::Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), LCD_FinishFrame, line+1); +        NDS.ScheduleEvent(Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), LCD_FinishFrame, line+1);  }  void GPU::FinishFrame(u32 lines) noexcept @@ -1053,7 +1053,7 @@ void GPU::StartScanline(u32 line) noexcept      {          DispStat[0] |= (1<<2); -        if (DispStat[0] & (1<<5)) NDS::SetIRQ(0, NDS::IRQ_VCount); +        if (DispStat[0] & (1<<5)) NDS.SetIRQ(0, IRQ_VCount);      }      else          DispStat[0] &= ~(1<<2); @@ -1062,7 +1062,7 @@ void GPU::StartScanline(u32 line) noexcept      {          DispStat[1] |= (1<<2); -        if (DispStat[1] & (1<<5)) NDS::SetIRQ(1, NDS::IRQ_VCount); +        if (DispStat[1] & (1<<5)) NDS.SetIRQ(1, IRQ_VCount);      }      else          DispStat[1] &= ~(1<<2); @@ -1071,9 +1071,9 @@ void GPU::StartScanline(u32 line) noexcept      GPU2D_B.CheckWindows(VCount);      if (VCount >= 2 && VCount < 194) -        NDS::CheckDMAs(0, 0x03); +        NDS.CheckDMAs(0, 0x03);      else if (VCount == 194) -        NDS::StopDMAs(0, 0x03); +        NDS.StopDMAs(0, 0x03);      if (line < 192)      { @@ -1085,7 +1085,7 @@ void GPU::StartScanline(u32 line) noexcept          }          if (RunFIFO) -            NDS::ScheduleEvent(NDS::Event_DisplayFIFO, false, 32, 0, 0); +            NDS.ScheduleEvent(Event_DisplayFIFO, false, 32, 0, 0);      }      if (VCount == 262) @@ -1111,13 +1111,13 @@ void GPU::StartScanline(u32 line) noexcept              DispStat[0] |= (1<<0);              DispStat[1] |= (1<<0); -            NDS::StopDMAs(0, 0x04); +            NDS.StopDMAs(0, 0x04); -            NDS::CheckDMAs(0, 0x01); -            NDS::CheckDMAs(1, 0x11); +            NDS.CheckDMAs(0, 0x01); +            NDS.CheckDMAs(1, 0x11); -            if (DispStat[0] & (1<<3)) NDS::SetIRQ(0, NDS::IRQ_VBlank); -            if (DispStat[1] & (1<<3)) NDS::SetIRQ(1, NDS::IRQ_VBlank); +            if (DispStat[0] & (1<<3)) NDS.SetIRQ(0, IRQ_VBlank); +            if (DispStat[1] & (1<<3)) NDS.SetIRQ(1, IRQ_VBlank);              GPU2D_A.VBlank();              GPU2D_B.VBlank(); @@ -1131,7 +1131,7 @@ void GPU::StartScanline(u32 line) noexcept          }      } -    NDS::ScheduleEvent(NDS::Event_LCD, true, HBLANK_CYCLES, LCD_StartHBlank, line); +    NDS.ScheduleEvent(Event_LCD, true, HBLANK_CYCLES, LCD_StartHBlank, line);  } @@ -67,7 +67,7 @@ struct RenderSettings  class GPU  {  public: -    GPU(ARMJIT& jit) noexcept; +    GPU(melonDS::NDS& nds) noexcept;      ~GPU() noexcept;      void Reset() noexcept;      void Stop() noexcept; @@ -536,7 +536,7 @@ public:      void SyncDirtyFlags() noexcept; -    ARMJIT& JIT; +    melonDS::NDS& NDS;      u16 VCount = 0;      u16 TotalScanlines = 0;      u16 DispStat[2] {}; @@ -582,7 +582,7 @@ public:      GPU2D::Unit GPU2D_A;      GPU2D::Unit GPU2D_B; -    melonDS::GPU3D GPU3D {}; +    melonDS::GPU3D GPU3D;      NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMDirty[9] {};      VRAMTrackingSet<512*1024, 16*1024> VRAMDirty_ABG {}; diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index b00e6fd..5603a13 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -139,6 +139,10 @@ const u8 CmdNumParams[256] =  void MatrixLoadIdentity(s32* m); +GPU3D::GPU3D(melonDS::NDS& nds) noexcept : NDS(nds) +{ +} +  void GPU3D::ResetRenderingState() noexcept  {      RenderNumPolygons = 0; @@ -1596,7 +1600,7 @@ void GPU3D::CmdFIFOWrite(CmdFIFOEntry& entry) noexcept              // has 64 entries. this is less complicated than trying to make STMxx stall-able.              CmdStallQueue.Write(entry); -            NDS::GXFIFOStall(); +            NDS.GXFIFOStall();              return;          } @@ -1640,7 +1644,7 @@ GPU3D::CmdFIFOEntry GPU3D::CmdFIFORead() noexcept              }              if (CmdStallQueue.IsEmpty()) -                NDS::GXFIFOUnstall(); +                NDS.GXFIFOUnstall();          }          CheckFIFODMA(); @@ -2273,13 +2277,13 @@ void GPU3D::Run() noexcept      if (!GeometryEnabled || FlushRequest ||          (CmdPIPE.IsEmpty() && !(GXStat & (1<<27))))      { -        Timestamp = NDS::ARM9Timestamp >> NDS::ARM9ClockShift; +        Timestamp = NDS.ARM9Timestamp >> NDS.ARM9ClockShift;          return;      } -    s32 cycles = (NDS::ARM9Timestamp >> NDS::ARM9ClockShift) - Timestamp; +    s32 cycles = (NDS.ARM9Timestamp >> NDS.ARM9ClockShift) - Timestamp;      CycleCount -= cycles; -    Timestamp = NDS::ARM9Timestamp >> NDS::ARM9ClockShift; +    Timestamp = NDS.ARM9Timestamp >> NDS.ARM9ClockShift;      if (CycleCount <= 0)      { @@ -2312,14 +2316,14 @@ void GPU3D::CheckFIFOIRQ() noexcept      case 2: irq = CmdFIFO.IsEmpty(); break;      } -    if (irq) NDS::SetIRQ(0, NDS::IRQ_GXFIFO); -    else     NDS::ClearIRQ(0, NDS::IRQ_GXFIFO); +    if (irq) NDS.SetIRQ(0, IRQ_GXFIFO); +    else     NDS.ClearIRQ(0, IRQ_GXFIFO);  }  void GPU3D::CheckFIFODMA() noexcept  {      if (CmdFIFO.Level() < 128) -        NDS::CheckDMAs(0, 0x07); +        NDS.CheckDMAs(0, 0x07);  }  void GPU3D::VCount144() noexcept diff --git a/src/GPU3D.h b/src/GPU3D.h index f543ff8..1d3e126 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -81,11 +81,12 @@ struct Polygon  };  class Renderer3D; +class NDS;  class GPU3D  {  public: -    GPU3D() noexcept = default; +    GPU3D(melonDS::NDS& nds) noexcept;      ~GPU3D() noexcept = default;      void Reset() noexcept; @@ -124,6 +125,7 @@ public:      void Write16(u32 addr, u16 val) noexcept;      void Write32(u32 addr, u32 val) noexcept;  private: +    melonDS::NDS& NDS;      typedef union      {          u64 _contents; diff --git a/src/MemConstants.h b/src/MemConstants.h new file mode 100644 index 0000000..ab80fab --- /dev/null +++ b/src/MemConstants.h @@ -0,0 +1,35 @@ +/* +    Copyright 2016-2023 melonDS team + +    This file is part of melonDS. + +    melonDS is free software: you can redistribute it and/or modify it under +    the terms of the GNU General Public License as published by the Free +    Software Foundation, either version 3 of the License, or (at your option) +    any later version. + +    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY +    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +    You should have received a copy of the GNU General Public License along +    with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MELONDS_MEMCONSTANTS_H +#define MELONDS_MEMCONSTANTS_H + +#include "types.h" + +namespace melonDS +{ +constexpr u32 MainRAMMaxSize = 0x1000000; +constexpr u32 SharedWRAMSize = 0x8000; +constexpr u32 ARM7WRAMSize = 0x10000; +constexpr u32 NWRAMSize = 0x40000; +constexpr u32 ARM9BIOSSize = 0x1000; +constexpr u32 ARM7BIOSSize = 0x4000; +constexpr u32 DSiBIOSSize = 0x10000; +} + +#endif // MELONDS_MEMCONSTANTS_H
\ No newline at end of file diff --git a/src/MemRegion.h b/src/MemRegion.h new file mode 100644 index 0000000..11b3d1d --- /dev/null +++ b/src/MemRegion.h @@ -0,0 +1,33 @@ +/* +    Copyright 2016-2023 melonDS team + +    This file is part of melonDS. + +    melonDS is free software: you can redistribute it and/or modify it under +    the terms of the GNU General Public License as published by the Free +    Software Foundation, either version 3 of the License, or (at your option) +    any later version. + +    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY +    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +    You should have received a copy of the GNU General Public License along +    with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MELONDS_MEMREGION_H +#define MELONDS_MEMREGION_H + +#include "types.h" + +// this file exists to break #include cycle loops +namespace melonDS +{ +struct MemRegion +{ +    u8* Mem; +    u32 Mask; +}; +} +#endif //MELONDS_MEMREGION_H diff --git a/src/NDS.cpp b/src/NDS.cpp index 576eb9c..3aa4a52 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -47,8 +47,8 @@ namespace melonDS  {  using namespace Platform; -namespace NDS -{ +const s32 kMaxIterationCycles = 64; +const s32 kIterationCycleMargin = 8;  // timing notes  // @@ -72,204 +72,49 @@ namespace NDS  //  // timings for GBA slot and wifi are set up at runtime -int ConsoleType; - -u8 ARM9MemTimings[0x40000][8]; -u32 ARM9Regions[0x40000]; -u8 ARM7MemTimings[0x20000][4]; -u32 ARM7Regions[0x20000]; - -ARMv5* ARM9; -ARMv4* ARM7; - -#ifdef JIT_ENABLED -bool EnableJIT; -#endif - -u32 NumFrames; -u32 NumLagFrames; -bool LagFrameFlag; -u64 LastSysClockCycles; -u64 FrameStartTimestamp; - -int CurCPU; - -const s32 kMaxIterationCycles = 64; -const s32 kIterationCycleMargin = 8; - -u32 ARM9ClockShift; - -// no need to worry about those overflowing, they can keep going for atleast 4350 years -u64 ARM9Timestamp, ARM9Target; -u64 ARM7Timestamp, ARM7Target; -u64 SysTimestamp; - -struct SchedEvent -{ -    std::map<u32, EventFunc> Funcs; -    u64 Timestamp; -    u32 FuncID; -    u32 Param; -}; - -SchedEvent SchedList[Event_MAX]; -u32 SchedListMask; - -u32 CPUStop; - -u8 ARM9BIOS[0x1000]; -u8 ARM7BIOS[0x4000]; - -u8* MainRAM; -u32 MainRAMMask; - -u8* SharedWRAM; -u8 WRAMCnt; - -// putting them together so they're always next to each other -MemRegion SWRAM_ARM9; -MemRegion SWRAM_ARM7; - -u8* ARM7WRAM; - -u16 ExMemCnt[2]; - -// TODO: these belong in NDSCart! -u8 ROMSeed0[2*8]; -u8 ROMSeed1[2*8]; - -// IO shit -u32 IME[2]; -u32 IE[2], IF[2]; -u32 IE2, IF2; - -u8 PostFlag9; -u8 PostFlag7; -u16 PowerControl9; -u16 PowerControl7; - -u16 WifiWaitCnt; - -u16 ARM7BIOSProt; - -Timer Timers[8]; -u8 TimerCheckMask[2]; -u64 TimerTimestamp[2]; - -DMA* DMAs[8]; -u32 DMA9Fill[4]; - -u16 IPCSync9, IPCSync7; -u16 IPCFIFOCnt9, IPCFIFOCnt7; -FIFO<u32, 16> IPCFIFO9; // FIFO in which the ARM9 writes -FIFO<u32, 16> IPCFIFO7; - -u16 DivCnt; -u32 DivNumerator[2]; -u32 DivDenominator[2]; -u32 DivQuotient[2]; -u32 DivRemainder[2]; - -u16 SqrtCnt; -u32 SqrtVal[2]; -u32 SqrtRes; - -u32 KeyInput; -u16 KeyCnt[2]; -u16 RCnt; - -class SPU* SPU; -class SPIHost* SPI; -class RTC* RTC; -class Wifi* Wifi; -std::unique_ptr<NDSCart::NDSCartSlot> NDSCartSlot; -std::unique_ptr<GBACart::GBACartSlot> GBACartSlot; -std::unique_ptr<melonDS::GPU> GPU; -std::unique_ptr<ARMJIT> JIT; -class AREngine* AREngine; - -bool Running; - -bool RunningGame; - -void DivDone(u32 param); -void SqrtDone(u32 param); -void RunTimer(u32 tid, s32 cycles); -void UpdateWifiTimings(); -void SetWifiWaitCnt(u16 val); -void SetGBASlotTimings(); - - -bool Init() +NDS* NDS::Current = nullptr; + +NDS::NDS(int type) noexcept : +    ConsoleType(type), +    JIT(*this), +    SPU(*this), +    GPU(*this), +    SPI(*this), +    RTC(*this), +    Wifi(*this), +    NDSCartSlot(*this), +    GBACartSlot(), +    AREngine(*this), +    ARM9(*this), +    ARM7(*this), +    DMAs { +        DMA(0, 0, *this), +        DMA(0, 1, *this), +        DMA(0, 2, *this), +        DMA(0, 3, *this), +        DMA(1, 0, *this), +        DMA(1, 1, *this), +        DMA(1, 2, *this), +        DMA(1, 3, *this), +    }  { -    RegisterEventFunc(Event_Div, 0, DivDone); -    RegisterEventFunc(Event_Sqrt, 0, SqrtDone); - -    JIT = std::make_unique<ARMJIT>(); -    GPU = std::make_unique<melonDS::GPU>(*JIT); +    RegisterEventFunc(Event_Div, 0, MemberEventFunc(NDS, DivDone)); +    RegisterEventFunc(Event_Sqrt, 0, MemberEventFunc(NDS, SqrtDone)); -    MainRAM = JIT->Memory.GetMainRAM(); -    SharedWRAM = JIT->Memory.GetSharedWRAM(); -    ARM7WRAM = JIT->Memory.GetARM7WRAM(); - -    ARM9 = new ARMv5(*JIT, *GPU); -    ARM7 = new ARMv4(*JIT, *GPU); - -    DMAs[0] = new DMA(0, 0, *GPU); -    DMAs[1] = new DMA(0, 1, *GPU); -    DMAs[2] = new DMA(0, 2, *GPU); -    DMAs[3] = new DMA(0, 3, *GPU); -    DMAs[4] = new DMA(1, 0, *GPU); -    DMAs[5] = new DMA(1, 1, *GPU); -    DMAs[6] = new DMA(1, 2, *GPU); -    DMAs[7] = new DMA(1, 3, *GPU); - -    SPU = new class SPU; -    SPI = new class SPIHost(); -    RTC = new class RTC(); -    Wifi = new class Wifi(); -    NDSCartSlot = std::make_unique<NDSCart::NDSCartSlot>(); -    GBACartSlot = std::make_unique<GBACart::GBACartSlot>(); - -    if (!DSi::Init()) return false; - -    AREngine = new class AREngine(); - -    return true; +    MainRAM = JIT.Memory.GetMainRAM(); +    SharedWRAM = JIT.Memory.GetSharedWRAM(); +    ARM7WRAM = JIT.Memory.GetARM7WRAM();  } -void DeInit() +NDS::~NDS() noexcept  { -    delete ARM9; ARM9 = nullptr; -    delete ARM7; ARM7 = nullptr; - -    for (int i = 0; i < 8; i++) -    { -        delete DMAs[i]; -        DMAs[i] = nullptr; -    } - -    delete SPU; SPU = nullptr; -    delete SPI; SPI = nullptr; -    delete RTC; RTC = nullptr; -    delete Wifi; Wifi = nullptr; - -    NDSCartSlot = nullptr; -    GBACartSlot = nullptr; -    GPU = nullptr; - -    DSi::DeInit(); - -    delete AREngine; AREngine = nullptr; -      UnregisterEventFunc(Event_Div, 0);      UnregisterEventFunc(Event_Sqrt, 0); -     -    JIT = nullptr; +    // The destructor for each component is automatically called by the compiler  } -void SetARM9RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq) +void NDS::SetARM9RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq)  {      addrstart >>= 2;      addrend   >>= 2; @@ -308,10 +153,10 @@ void SetARM9RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth,          ARM9Regions[i] = region;      } -    ARM9->UpdateRegionTimings(addrstart<<2, addrend<<2); +    ARM9.UpdateRegionTimings(addrstart<<2, addrend<<2);  } -void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq) +void NDS::SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq)  {      addrstart >>= 3;      addrend   >>= 3; @@ -342,7 +187,7 @@ void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth,      }  } -void InitTimings() +void NDS::InitTimings()  {      // TODO, eventually:      // VRAM is initially unmapped. The timings should be those of void regions. @@ -379,7 +224,7 @@ void InitTimings()      // handled later: GBA slot, wifi  } -bool NeedsDirectBoot() +bool NDS::NeedsDirectBoot()  {      if (ConsoleType == 1)      { @@ -393,144 +238,142 @@ bool NeedsDirectBoot()              return true;          // DSi/3DS firmwares aren't bootable -        if (!SPI->GetFirmware()->IsBootable()) +        if (!SPI.GetFirmware()->IsBootable())              return true;          return false;      }  } -void SetupDirectBoot(const std::string& romname) +void NDS::SetupDirectBoot()  { -    const NDSHeader& header = NDSCartSlot->GetCart()->GetHeader(); +    const NDSHeader& header = NDSCartSlot.GetCart()->GetHeader(); +    u32 cartid = NDSCartSlot.GetCart()->ID(); +    const u8* cartrom = NDSCartSlot.GetCart()->GetROM(); +    MapSharedWRAM(3); -    if (ConsoleType == 1) +    // setup main RAM data + +    for (u32 i = 0; i < 0x170; i+=4)      { -        DSi::SetupDirectBoot(); +        u32 tmp = *(u32*)&cartrom[i]; +        NDS::ARM9Write32(0x027FFE00+i, tmp);      } -    else -    { -        u32 cartid = NDSCartSlot->GetCart()->ID(); -        const u8* cartrom = NDSCartSlot->GetCart()->GetROM(); -        MapSharedWRAM(3); - -        // setup main RAM data -        for (u32 i = 0; i < 0x170; i+=4) -        { -            u32 tmp = *(u32*)&cartrom[i]; -            ARM9Write32(0x027FFE00+i, tmp); -        } +    NDS::ARM9Write32(0x027FF800, cartid); +    NDS::ARM9Write32(0x027FF804, cartid); +    NDS::ARM9Write16(0x027FF808, header.HeaderCRC16); +    NDS::ARM9Write16(0x027FF80A, header.SecureAreaCRC16); -        ARM9Write32(0x027FF800, cartid); -        ARM9Write32(0x027FF804, cartid); -        ARM9Write16(0x027FF808, header.HeaderCRC16); -        ARM9Write16(0x027FF80A, header.SecureAreaCRC16); +    NDS::ARM9Write16(0x027FF850, 0x5835); -        ARM9Write16(0x027FF850, 0x5835); +    NDS::ARM9Write32(0x027FFC00, cartid); +    NDS::ARM9Write32(0x027FFC04, cartid); +    NDS::ARM9Write16(0x027FFC08, header.HeaderCRC16); +    NDS::ARM9Write16(0x027FFC0A, header.SecureAreaCRC16); -        ARM9Write32(0x027FFC00, cartid); -        ARM9Write32(0x027FFC04, cartid); -        ARM9Write16(0x027FFC08, header.HeaderCRC16); -        ARM9Write16(0x027FFC0A, header.SecureAreaCRC16); +    NDS::ARM9Write16(0x027FFC10, 0x5835); +    NDS::ARM9Write16(0x027FFC30, 0xFFFF); +    NDS::ARM9Write16(0x027FFC40, 0x0001); -        ARM9Write16(0x027FFC10, 0x5835); -        ARM9Write16(0x027FFC30, 0xFFFF); -        ARM9Write16(0x027FFC40, 0x0001); +    u32 arm9start = 0; -        u32 arm9start = 0; +    // load the ARM9 secure area +    if (header.ARM9ROMOffset >= 0x4000 && header.ARM9ROMOffset < 0x8000) +    { +        u8 securearea[0x800]; +        NDSCartSlot.DecryptSecureArea(securearea); -        // load the ARM9 secure area -        if (header.ARM9ROMOffset >= 0x4000 && header.ARM9ROMOffset < 0x8000) +        for (u32 i = 0; i < 0x800; i+=4)          { -            u8 securearea[0x800]; -            NDSCartSlot->DecryptSecureArea(securearea); - -            for (u32 i = 0; i < 0x800; i+=4) -            { -                ARM9Write32(header.ARM9RAMAddress+i, *(u32*)&securearea[i]); -                arm9start += 4; -            } +            NDS::ARM9Write32(header.ARM9RAMAddress+i, *(u32*)&securearea[i]); +            arm9start += 4;          } +    } -        // CHECKME: firmware seems to load this in 0x200 byte chunks +    // CHECKME: firmware seems to load this in 0x200 byte chunks -        for (u32 i = arm9start; i < header.ARM9Size; i+=4) -        { -            u32 tmp = *(u32*)&cartrom[header.ARM9ROMOffset+i]; -            ARM9Write32(header.ARM9RAMAddress+i, tmp); -        } - -        for (u32 i = 0; i < header.ARM7Size; i+=4) -        { -            u32 tmp = *(u32*)&cartrom[header.ARM7ROMOffset+i]; -            ARM7Write32(header.ARM7RAMAddress+i, tmp); -        } +    for (u32 i = arm9start; i < header.ARM9Size; i+=4) +    { +        u32 tmp = *(u32*)&cartrom[header.ARM9ROMOffset+i]; +        NDS::ARM9Write32(header.ARM9RAMAddress+i, tmp); +    } -        ARM7BIOSProt = 0x1204; - -        SPI->GetFirmwareMem()->SetupDirectBoot(false); - -        ARM9->CP15Write(0x100, 0x00012078); -        ARM9->CP15Write(0x200, 0x00000042); -        ARM9->CP15Write(0x201, 0x00000042); -        ARM9->CP15Write(0x300, 0x00000002); -        ARM9->CP15Write(0x502, 0x15111011); -        ARM9->CP15Write(0x503, 0x05100011); -        ARM9->CP15Write(0x600, 0x04000033); -        ARM9->CP15Write(0x601, 0x04000033); -        ARM9->CP15Write(0x610, 0x0200002B); -        ARM9->CP15Write(0x611, 0x0200002B); -        ARM9->CP15Write(0x620, 0x00000000); -        ARM9->CP15Write(0x621, 0x00000000); -        ARM9->CP15Write(0x630, 0x08000035); -        ARM9->CP15Write(0x631, 0x08000035); -        ARM9->CP15Write(0x640, 0x0300001B); -        ARM9->CP15Write(0x641, 0x0300001B); -        ARM9->CP15Write(0x650, 0x00000000); -        ARM9->CP15Write(0x651, 0x00000000); -        ARM9->CP15Write(0x660, 0xFFFF001D); -        ARM9->CP15Write(0x661, 0xFFFF001D); -        ARM9->CP15Write(0x670, 0x027FF017); -        ARM9->CP15Write(0x671, 0x027FF017); -        ARM9->CP15Write(0x910, 0x0300000A); -        ARM9->CP15Write(0x911, 0x00000020); +    for (u32 i = 0; i < header.ARM7Size; i+=4) +    { +        u32 tmp = *(u32*)&cartrom[header.ARM7ROMOffset+i]; +        NDS::ARM7Write32(header.ARM7RAMAddress+i, tmp);      } -    NDSCartSlot->SetupDirectBoot(romname); +    ARM7BIOSProt = 0x1204; + +    SPI.GetFirmwareMem()->SetupDirectBoot(); + +    ARM9.CP15Write(0x100, 0x00012078); +    ARM9.CP15Write(0x200, 0x00000042); +    ARM9.CP15Write(0x201, 0x00000042); +    ARM9.CP15Write(0x300, 0x00000002); +    ARM9.CP15Write(0x502, 0x15111011); +    ARM9.CP15Write(0x503, 0x05100011); +    ARM9.CP15Write(0x600, 0x04000033); +    ARM9.CP15Write(0x601, 0x04000033); +    ARM9.CP15Write(0x610, 0x0200002B); +    ARM9.CP15Write(0x611, 0x0200002B); +    ARM9.CP15Write(0x620, 0x00000000); +    ARM9.CP15Write(0x621, 0x00000000); +    ARM9.CP15Write(0x630, 0x08000035); +    ARM9.CP15Write(0x631, 0x08000035); +    ARM9.CP15Write(0x640, 0x0300001B); +    ARM9.CP15Write(0x641, 0x0300001B); +    ARM9.CP15Write(0x650, 0x00000000); +    ARM9.CP15Write(0x651, 0x00000000); +    ARM9.CP15Write(0x660, 0xFFFF001D); +    ARM9.CP15Write(0x661, 0xFFFF001D); +    ARM9.CP15Write(0x670, 0x027FF017); +    ARM9.CP15Write(0x671, 0x027FF017); +    ARM9.CP15Write(0x910, 0x0300000A); +    ARM9.CP15Write(0x911, 0x00000020); +} + +void NDS::SetupDirectBoot(const std::string& romname) +{ +    const NDSHeader& header = NDSCartSlot.GetCart()->GetHeader(); +    SetupDirectBoot(); + +    NDSCartSlot.SetupDirectBoot(romname); -    ARM9->R[12] = header.ARM9EntryAddress; -    ARM9->R[13] = 0x03002F7C; -    ARM9->R[14] = header.ARM9EntryAddress; -    ARM9->R_IRQ[0] = 0x03003F80; -    ARM9->R_SVC[0] = 0x03003FC0; +    ARM9.R[12] = header.ARM9EntryAddress; +    ARM9.R[13] = 0x03002F7C; +    ARM9.R[14] = header.ARM9EntryAddress; +    ARM9.R_IRQ[0] = 0x03003F80; +    ARM9.R_SVC[0] = 0x03003FC0; -    ARM7->R[12] = header.ARM7EntryAddress; -    ARM7->R[13] = 0x0380FD80; -    ARM7->R[14] = header.ARM7EntryAddress; -    ARM7->R_IRQ[0] = 0x0380FF80; -    ARM7->R_SVC[0] = 0x0380FFC0; +    ARM7.R[12] = header.ARM7EntryAddress; +    ARM7.R[13] = 0x0380FD80; +    ARM7.R[14] = header.ARM7EntryAddress; +    ARM7.R_IRQ[0] = 0x0380FF80; +    ARM7.R_SVC[0] = 0x0380FFC0; -    ARM9->JumpTo(header.ARM9EntryAddress); -    ARM7->JumpTo(header.ARM7EntryAddress); +    ARM9.JumpTo(header.ARM9EntryAddress); +    ARM7.JumpTo(header.ARM7EntryAddress);      PostFlag9 = 0x01;      PostFlag7 = 0x01;      PowerControl9 = 0x820F; -    GPU->SetPowerCnt(PowerControl9); +    GPU.SetPowerCnt(PowerControl9);      // checkme      RCnt = 0x8000; -    NDSCartSlot->SetSPICnt(0x8000); +    NDSCartSlot.SetSPICnt(0x8000); -    SPU->SetBias(0x200); +    SPU.SetBias(0x200);      SetWifiWaitCnt(0x0030);  } -void Reset() +void NDS::Reset()  {      Platform::FileHandle* f;      u32 i; @@ -544,7 +387,7 @@ void Reset()      // BIOS files are now loaded by the frontend -    JIT->Reset(); +    JIT.Reset();      if (ConsoleType == 1)      { @@ -561,7 +404,7 @@ void Reset()      // has to be called before InitTimings      // otherwise some PU settings are completely      // unitialised on the first run -    ARM9->CP15Reset(); +    ARM9.CP15Reset();      ARM9Timestamp = 0; ARM9Target = 0;      ARM7Timestamp = 0; ARM7Target = 0; @@ -610,8 +453,8 @@ void Reset()      DivCnt = 0;      SqrtCnt = 0; -    ARM9->Reset(); -    ARM7->Reset(); +    ARM9.Reset(); +    ARM7.Reset();      CPUStop = 0; @@ -621,7 +464,7 @@ void Reset()      TimerTimestamp[0] = 0;      TimerTimestamp[1] = 0; -    for (i = 0; i < 8; i++) DMAs[i]->Reset(); +    for (i = 0; i < 8; i++) DMAs[i].Reset();      memset(DMA9Fill, 0, 4*4);      for (i = 0; i < Event_MAX; i++) @@ -639,24 +482,24 @@ void Reset()      KeyCnt[1] = 0;      RCnt = 0; -    GPU->Reset(); -    NDSCartSlot->Reset(); -    GBACartSlot->Reset(); -    SPU->Reset(); -    SPI->Reset(); -    RTC->Reset(); -    Wifi->Reset(); +    GPU.Reset(); +    NDSCartSlot.Reset(); +    GBACartSlot.Reset(); +    SPU.Reset(); +    SPI.Reset(); +    RTC.Reset(); +    Wifi.Reset();      // TODO: move the SOUNDBIAS/degrade logic to SPU?      // The SOUNDBIAS register does nothing on DSi -    SPU->SetApplyBias(ConsoleType == 0); +    SPU.SetApplyBias(ConsoleType == 0);      bool degradeAudio = true;      if (ConsoleType == 1)      { -        DSi::Reset(); +        //DSi::Reset();          KeyInput &= ~(1 << (16+6));          degradeAudio = false;      } @@ -667,12 +510,10 @@ void Reset()      else if (bitDepth == 2) // Always 16-bit          degradeAudio = false; -    SPU->SetDegrade10Bit(degradeAudio); - -    AREngine->Reset(); +    SPU.SetDegrade10Bit(degradeAudio);  } -void Start() +void NDS::Start()  {      Running = true;  } @@ -694,7 +535,7 @@ static const char* StopReasonName(Platform::StopReason reason)      }  } -void Stop(Platform::StopReason reason) +void NDS::Stop(Platform::StopReason reason)  {      Platform::LogLevel level;      switch (reason) @@ -715,14 +556,11 @@ void Stop(Platform::StopReason reason)      Log(level, "Stopping emulated console (Reason: %s)\n", StopReasonName(reason));      Running = false;      Platform::SignalStop(reason); -    GPU->Stop(); -    SPU->Stop(); - -    if (ConsoleType == 1) -        DSi::Stop(); +    GPU.Stop(); +    SPU.Stop();  } -bool DoSavestate(Savestate* file) +bool NDS::DoSavestate(Savestate* file)  {      file->Section("NDSG"); @@ -835,36 +673,35 @@ bool DoSavestate(Savestate* file)      }      for (int i = 0; i < 8; i++) -        DMAs[i]->DoSavestate(file); +        DMAs[i].DoSavestate(file); -    ARM9->DoSavestate(file); -    ARM7->DoSavestate(file); +    ARM9.DoSavestate(file); +    ARM7.DoSavestate(file); -    NDSCartSlot->DoSavestate(file); +    NDSCartSlot.DoSavestate(file);      if (ConsoleType == 0) -        GBACartSlot->DoSavestate(file); -    GPU->DoSavestate(file); -    SPU->DoSavestate(file); -    SPI->DoSavestate(file); -    RTC->DoSavestate(file); -    Wifi->DoSavestate(file); +        GBACartSlot.DoSavestate(file); +    GPU.DoSavestate(file); +    SPU.DoSavestate(file); +    SPI.DoSavestate(file); +    RTC.DoSavestate(file); +    Wifi.DoSavestate(file); -    if (ConsoleType == 1) -        DSi::DoSavestate(file); +    DoSavestateExtra(file); // Handles DSi state if applicable      if (!file->Saving)      { -        GPU->SetPowerCnt(PowerControl9); +        GPU.SetPowerCnt(PowerControl9); -        SPU->SetPowerCnt(PowerControl7 & 0x0001); -        Wifi->SetPowerCnt(PowerControl7 & 0x0002); +        SPU.SetPowerCnt(PowerControl7 & 0x0001); +        Wifi.SetPowerCnt(PowerControl7 & 0x0002);      }  #ifdef JIT_ENABLED      if (!file->Saving)      { -        JIT->ResetBlockCache(); -        JIT->Memory.Reset(); +        JIT.ResetBlockCache(); +        JIT.Memory.Reset();      }  #endif @@ -873,80 +710,70 @@ bool DoSavestate(Savestate* file)      return true;  } -void SetConsoleType(int type) +bool NDS::LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen)  { -    ConsoleType = type; -} - -bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) -{ -    if (!NDSCartSlot->LoadROM(romdata, romlen)) +    if (!NDSCartSlot.LoadROM(romdata, romlen))          return false;      if (savedata && savelen) -        NDSCartSlot->LoadSave(savedata, savelen); +        NDSCartSlot.LoadSave(savedata, savelen);      return true;  } -void LoadSave(const u8* savedata, u32 savelen) +void NDS::LoadSave(const u8* savedata, u32 savelen)  {      if (savedata && savelen) -        NDSCartSlot->LoadSave(savedata, savelen); +        NDSCartSlot.LoadSave(savedata, savelen);  } -void EjectCart() +void NDS::EjectCart()  { -    NDSCartSlot->EjectCart(); +    NDSCartSlot.EjectCart();  } -bool CartInserted() +bool NDS::CartInserted()  { -    return NDSCartSlot->GetCart() != nullptr; +    return NDSCartSlot.GetCart() != nullptr;  } -bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) +bool NDS::LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen)  { -    if (!GBACartSlot) -        return false; - -    if (!GBACartSlot->LoadROM(romdata, romlen)) +    if (!GBACartSlot.LoadROM(romdata, romlen))          return false;      if (savedata && savelen) -        GBACartSlot->LoadSave(savedata, savelen); +        GBACartSlot.LoadSave(savedata, savelen);      return true;  } -void LoadGBAAddon(int type) +void NDS::LoadGBAAddon(int type)  { -    if (GBACartSlot) -        GBACartSlot->LoadAddon(type); +    GBACartSlot.LoadAddon(type);  } -void EjectGBACart() +void NDS::EjectGBACart()  { -    if (GBACartSlot) -        GBACartSlot->EjectCart(); +    GBACartSlot.EjectCart();  } -void LoadBIOS() +void NDS::LoadBIOS()  {      Reset();  } -bool IsLoadedARM9BIOSBuiltIn() +bool NDS::IsLoadedARM9BIOSBuiltIn()  { -    return memcmp(NDS::ARM9BIOS, bios_arm9_bin, sizeof(NDS::ARM9BIOS)) == 0; +    return memcmp(ARM9BIOS, bios_arm9_bin, sizeof(NDS::ARM9BIOS)) == 0;  } -bool IsLoadedARM7BIOSBuiltIn() +bool NDS::IsLoadedARM7BIOSBuiltIn()  { -    return memcmp(NDS::ARM7BIOS, bios_arm7_bin, sizeof(NDS::ARM7BIOS)) == 0; +    return memcmp(ARM7BIOS, bios_arm7_bin, sizeof(NDS::ARM7BIOS)) == 0;  } -u64 NextTarget() +u64 NDS::NextTarget()  {      u64 minEvent = UINT64_MAX; @@ -971,7 +798,7 @@ u64 NextTarget()      return max;  } -void RunSystem(u64 timestamp) +void NDS::RunSystem(u64 timestamp)  {      SysTimestamp = timestamp; @@ -996,7 +823,7 @@ void RunSystem(u64 timestamp)      }  } -u64 NextTargetSleep() +u64 NDS::NextTargetSleep()  {      u64 minEvent = UINT64_MAX; @@ -1019,7 +846,7 @@ u64 NextTargetSleep()      return minEvent;  } -void RunSystemSleep(u64 timestamp) +void NDS::RunSystemSleep(u64 timestamp)  {      u64 offset = timestamp - SysTimestamp;      SysTimestamp = timestamp; @@ -1061,12 +888,12 @@ void RunSystemSleep(u64 timestamp)      }  } -template <bool EnableJIT, int ConsoleType> -u32 RunFrame() +template <bool EnableJIT> +u32 NDS::RunFrame()  {      FrameStartTimestamp = SysTimestamp; -    GPU->TotalScanlines = 0; +    GPU.TotalScanlines = 0;      LagFrameFlag = true;      bool runFrame = Running && !(CPUStop & CPUStop_Sleep); @@ -1090,7 +917,7 @@ u32 RunFrame()                  ARM7Timestamp = target;                  TimerTimestamp[0] = target;                  TimerTimestamp[1] = target; -                GPU->GPU3D.Timestamp = target; +                GPU.GPU3D.Timestamp = target;                  RunSystemSleep(target);                  if (!(CPUStop & CPUStop_Sleep)) @@ -1098,20 +925,20 @@ u32 RunFrame()              }              if (SysTimestamp >= frametarget) -                GPU->BlankFrame(); +                GPU.BlankFrame();          }          else          { -            ARM9->CheckGdbIncoming(); -            ARM7->CheckGdbIncoming(); +            ARM9.CheckGdbIncoming(); +            ARM7.CheckGdbIncoming();              if (!(CPUStop & CPUStop_Wakeup))              { -                GPU->StartFrame(); +                GPU.StartFrame();              }              CPUStop &= ~CPUStop_Wakeup; -            while (Running && GPU->TotalScanlines==0) +            while (Running && GPU.TotalScanlines==0)              {                  u64 target = NextTarget();                  ARM9Target = target << ARM9ClockShift; @@ -1120,30 +947,34 @@ u32 RunFrame()                  if (CPUStop & CPUStop_GXStall)                  {                      // GXFIFO stall -                    s32 cycles = GPU->GPU3D.CyclesToRunFor(); +                    s32 cycles = GPU.GPU3D.CyclesToRunFor();                      ARM9Timestamp = std::min(ARM9Target, ARM9Timestamp+(cycles<<ARM9ClockShift));                  }                  else if (CPUStop & CPUStop_DMA9)                  { -                    DMAs[0]->Run<ConsoleType>(); -                    if (!(CPUStop & CPUStop_GXStall)) DMAs[1]->Run<ConsoleType>(); -                    if (!(CPUStop & CPUStop_GXStall)) DMAs[2]->Run<ConsoleType>(); -                    if (!(CPUStop & CPUStop_GXStall)) DMAs[3]->Run<ConsoleType>(); -                    if (ConsoleType == 1) DSi::RunNDMAs(0); +                    DMAs[0].Run(); +                    if (!(CPUStop & CPUStop_GXStall)) DMAs[1].Run(); +                    if (!(CPUStop & CPUStop_GXStall)) DMAs[2].Run(); +                    if (!(CPUStop & CPUStop_GXStall)) DMAs[3].Run(); +                    if (ConsoleType == 1) +                    { +                        auto& dsi = dynamic_cast<melonDS::DSi&>(*this); +                        dsi.RunNDMAs(0); +                    }                  }                  else                  {  #ifdef JIT_ENABLED                      if (EnableJIT) -                        ARM9->ExecuteJIT(); +                        ARM9.ExecuteJIT();                      else  #endif -                        ARM9->Execute(); +                        ARM9.Execute();                  }                  RunTimers(0); -                GPU->GPU3D.Run(); +                GPU.GPU3D.Run();                  target = ARM9Timestamp >> ARM9ClockShift;                  CurCPU = 1; @@ -1154,20 +985,24 @@ u32 RunFrame()                      if (CPUStop & CPUStop_DMA7)                      { -                        DMAs[4]->Run<ConsoleType>(); -                        DMAs[5]->Run<ConsoleType>(); -                        DMAs[6]->Run<ConsoleType>(); -                        DMAs[7]->Run<ConsoleType>(); -                        if (ConsoleType == 1) DSi::RunNDMAs(1); +                        DMAs[4].Run(); +                        DMAs[5].Run(); +                        DMAs[6].Run(); +                        DMAs[7].Run(); +                        if (ConsoleType == 1) +                        { +                            auto& dsi = dynamic_cast<melonDS::DSi&>(*this); +                            dsi.RunNDMAs(1); +                        }                      }                      else                      {  #ifdef JIT_ENABLED                          if (EnableJIT) -                            ARM7->ExecuteJIT(); +                            ARM7.ExecuteJIT();                          else  #endif -                            ARM7->Execute(); +                            ARM7.Execute();                      }                      RunTimers(1); @@ -1182,7 +1017,7 @@ u32 RunFrame()              }          } -        if (GPU->TotalScanlines == 0) +        if (GPU.TotalScanlines == 0)              continue;  #ifdef DEBUG_CHECK_DESYNC @@ -1190,9 +1025,9 @@ u32 RunFrame()              (u32)(SysTimestamp>>32), (u32)SysTimestamp,              (ARM9Timestamp>>1)-SysTimestamp,              ARM7Timestamp-SysTimestamp, -            GPU3D::Timestamp-SysTimestamp); +            GPU.GPU3D.Timestamp-SysTimestamp);  #endif -        SPU->TransferOutput(); +        SPU.TransferOutput();          break;      } @@ -1203,26 +1038,22 @@ u32 RunFrame()          NumLagFrames++;      if (Running) -        return GPU->TotalScanlines; +        return GPU.TotalScanlines;      else          return 263;  } -u32 RunFrame() +u32 NDS::RunFrame()  {  #ifdef JIT_ENABLED      if (EnableJIT) -        return NDS::ConsoleType == 1 -            ? RunFrame<true, 1>() -            : RunFrame<true, 0>(); +        return RunFrame<true>();      else  #endif -        return NDS::ConsoleType == 1 -            ? RunFrame<false, 1>() -            : RunFrame<false, 0>(); +        return RunFrame<false>();  } -void Reschedule(u64 target) +void NDS::Reschedule(u64 target)  {      if (CurCPU == 0)      { @@ -1236,21 +1067,21 @@ void Reschedule(u64 target)      }  } -void RegisterEventFunc(u32 id, u32 funcid, EventFunc func) +void NDS::RegisterEventFunc(u32 id, u32 funcid, EventFunc func)  {      SchedEvent& evt = SchedList[id];      evt.Funcs[funcid] = func;  } -void UnregisterEventFunc(u32 id, u32 funcid) +void NDS::UnregisterEventFunc(u32 id, u32 funcid)  {      SchedEvent& evt = SchedList[id];      evt.Funcs.erase(funcid);  } -void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param) +void NDS::ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param)  {      if (SchedListMask & (1<<id))      { @@ -1278,24 +1109,24 @@ void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param)      Reschedule(evt.Timestamp);  } -void CancelEvent(u32 id) +void NDS::CancelEvent(u32 id)  {      SchedListMask &= ~(1<<id);  } -void TouchScreen(u16 x, u16 y) +void NDS::TouchScreen(u16 x, u16 y)  { -    SPI->GetTSC()->SetTouchCoords(x, y); +    SPI.GetTSC()->SetTouchCoords(x, y);  } -void ReleaseScreen() +void NDS::ReleaseScreen()  { -    SPI->GetTSC()->SetTouchCoords(0x000, 0xFFF); +    SPI.GetTSC()->SetTouchCoords(0x000, 0xFFF);  } -void CheckKeyIRQ(u32 cpu, u32 oldkey, u32 newkey) +void NDS::CheckKeyIRQ(u32 cpu, u32 oldkey, u32 newkey)  {      u16 cnt = KeyCnt[cpu];      if (!(cnt & (1<<14))) // IRQ disabled @@ -1325,7 +1156,7 @@ void CheckKeyIRQ(u32 cpu, u32 oldkey, u32 newkey)          SetIRQ(cpu, IRQ_Keypad);  } -void SetKeyMask(u32 mask) +void NDS::SetKeyMask(u32 mask)  {      u32 key_lo = mask & 0x3FF;      u32 key_hi = (mask >> 10) & 0x3; @@ -1338,13 +1169,13 @@ void SetKeyMask(u32 mask)      CheckKeyIRQ(1, oldkey, KeyInput);  } -bool IsLidClosed() +bool NDS::IsLidClosed()  {      if (KeyInput & (1<<23)) return true;      return false;  } -void SetLidClosed(bool closed) +void NDS::SetLidClosed(bool closed)  {      if (closed)      { @@ -1357,24 +1188,9 @@ void SetLidClosed(bool closed)      }  } -void CamInputFrame(int cam, u32* data, int width, int height, bool rgb) -{ -    // TODO: support things like the GBA-slot camera addon -    // whenever these are emulated - -    if (ConsoleType == 1) -    { -        switch (cam) -        { -        case 0: return DSi::CamModule->GetOuterCamera()->InputFrame(data, width, height, rgb); -        case 1: return DSi::CamModule->GetInnerCamera()->InputFrame(data, width, height, rgb); -        } -    } -} - -void MicInputFrame(s16* data, int samples) +void NDS::MicInputFrame(s16* data, int samples)  { -    return SPI->GetTSC()->MicInputFrame(data, samples); +    return SPI.GetTSC()->MicInputFrame(data, samples);  }  /*int ImportSRAM(u8* data, u32 length) @@ -1383,19 +1199,19 @@ void MicInputFrame(s16* data, int samples)  }*/ -void Halt() +void NDS::Halt()  {      Log(LogLevel::Info, "Halt()\n");      Running = false;  } -void MapSharedWRAM(u8 val) +void NDS::MapSharedWRAM(u8 val)  {      if (val == WRAMCnt)          return; -    NDS::JIT->Memory.RemapSWRAM(); +    JIT.Memory.RemapSWRAM();      WRAMCnt = val; @@ -1432,7 +1248,7 @@ void MapSharedWRAM(u8 val)  } -void UpdateWifiTimings() +void NDS::UpdateWifiTimings()  {      if (PowerControl7 & 0x0002)      { @@ -1449,7 +1265,7 @@ void UpdateWifiTimings()      }  } -void SetWifiWaitCnt(u16 val) +void NDS::SetWifiWaitCnt(u16 val)  {      if (WifiWaitCnt == val) return; @@ -1457,7 +1273,7 @@ void SetWifiWaitCnt(u16 val)      UpdateWifiTimings();  } -void SetGBASlotTimings() +void NDS::SetGBASlotTimings()  {      const int ntimings[4] = {10, 8, 6, 18};      const u16 openbus[4] = {0xFE08, 0x0000, 0x0000, 0xFFFF}; @@ -1492,28 +1308,27 @@ void SetGBASlotTimings()      // for example, the Cartridge Construction Kit relies on this to determine that      // the GBA slot is empty -    assert(GBACartSlot != nullptr); -    GBACartSlot->SetOpenBusDecay(openbus[(curcnt>>2) & 0x3]); +    GBACartSlot.SetOpenBusDecay(openbus[(curcnt>>2) & 0x3]);  } -void UpdateIRQ(u32 cpu) +void NDS::UpdateIRQ(u32 cpu)  { -    ARM* arm = cpu ? (ARM*)ARM7 : (ARM*)ARM9; +    ARM& arm = cpu ? (ARM&)ARM7 : (ARM&)ARM9;      if (IME[cpu] & 0x1)      { -        arm->IRQ = !!(IE[cpu] & IF[cpu]); +        arm.IRQ = !!(IE[cpu] & IF[cpu]);          if ((ConsoleType == 1) && cpu) -            arm->IRQ |= !!(IE2 & IF2); +            arm.IRQ |= !!(IE2 & IF2);      }      else      { -        arm->IRQ = 0; +        arm.IRQ = 0;      }  } -void SetIRQ(u32 cpu, u32 irq) +void NDS::SetIRQ(u32 cpu, u32 irq)  {      IF[cpu] |= (1 << irq);      UpdateIRQ(cpu); @@ -1524,30 +1339,30 @@ void SetIRQ(u32 cpu, u32 irq)          {              CPUStop &= ~CPUStop_Sleep;              CPUStop |= CPUStop_Wakeup; -            GPU->GPU3D.RestartFrame(); +            GPU.GPU3D.RestartFrame();          }      }  } -void ClearIRQ(u32 cpu, u32 irq) +void NDS::ClearIRQ(u32 cpu, u32 irq)  {      IF[cpu] &= ~(1 << irq);      UpdateIRQ(cpu);  } -void SetIRQ2(u32 irq) +void NDS::SetIRQ2(u32 irq)  {      IF2 |= (1 << irq);      UpdateIRQ(1);  } -void ClearIRQ2(u32 irq) +void NDS::ClearIRQ2(u32 irq)  {      IF2 &= ~(1 << irq);      UpdateIRQ(1);  } -bool HaltInterrupted(u32 cpu) +bool NDS::HaltInterrupted(u32 cpu)  {      if (cpu == 0)      { @@ -1564,62 +1379,66 @@ bool HaltInterrupted(u32 cpu)      return false;  } -void StopCPU(u32 cpu, u32 mask) +void NDS::StopCPU(u32 cpu, u32 mask)  {      if (cpu)      {          CPUStop |= (mask << 16); -        ARM7->Halt(2); +        ARM7.Halt(2);      }      else      {          CPUStop |= mask; -        ARM9->Halt(2); +        ARM9.Halt(2);      }  } -void ResumeCPU(u32 cpu, u32 mask) +void NDS::ResumeCPU(u32 cpu, u32 mask)  {      if (cpu) mask <<= 16;      CPUStop &= ~mask;  } -void GXFIFOStall() +void NDS::GXFIFOStall()  {      if (CPUStop & CPUStop_GXStall) return;      CPUStop |= CPUStop_GXStall; -    if (CurCPU == 1) ARM9->Halt(2); +    if (CurCPU == 1) ARM9.Halt(2);      else      { -        DMAs[0]->StallIfRunning(); -        DMAs[1]->StallIfRunning(); -        DMAs[2]->StallIfRunning(); -        DMAs[3]->StallIfRunning(); -        if (ConsoleType == 1) DSi::StallNDMAs(); +        DMAs[0].StallIfRunning(); +        DMAs[1].StallIfRunning(); +        DMAs[2].StallIfRunning(); +        DMAs[3].StallIfRunning(); +        if (ConsoleType == 1) +        { +            auto& dsi = dynamic_cast<melonDS::DSi&>(*this); +            dsi.StallNDMAs(); +        }      }  } -void GXFIFOUnstall() +void NDS::GXFIFOUnstall()  {      CPUStop &= ~CPUStop_GXStall;  } -void EnterSleepMode() +void NDS::EnterSleepMode()  {      if (CPUStop & CPUStop_Sleep) return;      CPUStop |= CPUStop_Sleep; -    ARM7->Halt(2); +    ARM7.Halt(2);  } -u32 GetPC(u32 cpu) +u32 NDS::GetPC(u32 cpu)  { -    return cpu ? ARM7->R[15] : ARM9->R[15]; +    return cpu ? ARM7.R[15] : ARM9.R[15];  } -u64 GetSysClockCycles(int num) +u64 NDS::GetSysClockCycles(int num)  {      u64 ret; @@ -1646,19 +1465,19 @@ u64 GetSysClockCycles(int num)      return ret;  } -void NocashPrint(u32 ncpu, u32 addr) +void NDS::NocashPrint(u32 ncpu, u32 addr)  {      // addr: debug string -    ARM* cpu = ncpu ? (ARM*)ARM7 : (ARM*)ARM9; -    u8 (*readfn)(u32) = ncpu ? NDS::ARM7Read8 : NDS::ARM9Read8; +    ARM* cpu = ncpu ? (ARM*)&ARM7 : (ARM*)&ARM9; +    u8 (NDS::*readfn)(u32) = ncpu ? &NDS::ARM7Read8 : &NDS::ARM9Read8;      char output[1024];      int ptr = 0;      for (int i = 0; i < 120 && ptr < 1023; )      { -        char ch = readfn(addr++); +        char ch = (this->*readfn)(addr++);          i++;          if (ch == '%') @@ -1666,7 +1485,7 @@ void NocashPrint(u32 ncpu, u32 addr)              char cmd[16]; int j;              for (j = 0; j < 15; )              { -                char ch2 = readfn(addr++); +                char ch2 = (this->*readfn)(addr++);                  i++;                  if (i >= 120) break;                  if (ch2 == '%') break; @@ -1701,7 +1520,7 @@ void NocashPrint(u32 ncpu, u32 addr)                  else if (!strcmp(cmd, "lr")) sprintf(subs, "%08X", cpu->R[14]);                  else if (!strcmp(cmd, "pc")) sprintf(subs, "%08X", cpu->R[15]);                  else if (!strcmp(cmd, "frame")) sprintf(subs, "%u", NumFrames); -                else if (!strcmp(cmd, "scanline")) sprintf(subs, "%u", GPU->VCount); +                else if (!strcmp(cmd, "scanline")) sprintf(subs, "%u", GPU.VCount);                  else if (!strcmp(cmd, "totalclks")) sprintf(subs, "%" PRIu64, GetSysClockCycles(0));                  else if (!strcmp(cmd, "lastclks")) sprintf(subs, "%" PRIu64, GetSysClockCycles(1));                  else if (!strcmp(cmd, "zeroclks")) @@ -1727,16 +1546,14 @@ void NocashPrint(u32 ncpu, u32 addr)      Log(LogLevel::Debug, "%s", output);  } - - -void MonitorARM9Jump(u32 addr) +void NDS::MonitorARM9Jump(u32 addr)  {      // checkme: can the entrypoint addr be THUMB?      // also TODO: make it work in DSi mode -    if ((!RunningGame) && NDSCartSlot->GetCart()) +    if ((!RunningGame) && NDSCartSlot.GetCart())      { -        const NDSHeader& header = NDSCartSlot->GetCart()->GetHeader(); +        const NDSHeader& header = NDSCartSlot.GetCart()->GetHeader();          if (addr == header.ARM9EntryAddress)          {              Log(LogLevel::Info, "Game is now booting\n"); @@ -1747,7 +1564,7 @@ void MonitorARM9Jump(u32 addr) -void HandleTimerOverflow(u32 tid) +void NDS::HandleTimerOverflow(u32 tid)  {      Timer* timer = &Timers[tid]; @@ -1780,7 +1597,7 @@ void HandleTimerOverflow(u32 tid)      }  } -void RunTimer(u32 tid, s32 cycles) +void NDS::RunTimer(u32 tid, s32 cycles)  {      Timer* timer = &Timers[tid]; @@ -1792,7 +1609,7 @@ void RunTimer(u32 tid, s32 cycles)      }  } -void RunTimers(u32 cpu) +void NDS::RunTimers(u32 cpu)  {      u32 timermask = TimerCheckMask[cpu];      s32 cycles; @@ -1812,7 +1629,7 @@ void RunTimers(u32 cpu)  const s32 TimerPrescaler[4] = {0, 6, 8, 10}; -u16 TimerGetCounter(u32 timer) +u16 NDS::TimerGetCounter(u32 timer)  {      RunTimers(timer>>2);      u32 ret = Timers[timer].Counter; @@ -1820,7 +1637,7 @@ u16 TimerGetCounter(u32 timer)      return ret >> 10;  } -void TimerStart(u32 id, u16 cnt) +void NDS::TimerStart(u32 id, u16 cnt)  {      Timer* timer = &Timers[id];      u16 curstart = timer->Cnt & (1<<7); @@ -1844,93 +1661,49 @@ void TimerStart(u32 id, u16 cnt) -// matching NDMA modes for DSi -const u32 NDMAModes[] = -{ -    // ARM9 - -    0x10, // immediate -    0x06, // VBlank -    0x07, // HBlank -    0x08, // scanline start -    0x09, // mainmem FIFO -    0x04, // DS cart slot -    0xFF, // GBA cart slot -    0x0A, // GX FIFO -    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - -    // ARM7 - -    0x30, // immediate -    0x26, // VBlank -    0x24, // DS cart slot -    0xFF, // wifi / GBA cart slot (TODO) -}; - -bool DMAsInMode(u32 cpu, u32 mode) +bool NDS::DMAsInMode(u32 cpu, u32 mode)  {      cpu <<= 2; -    if (DMAs[cpu+0]->IsInMode(mode)) return true; -    if (DMAs[cpu+1]->IsInMode(mode)) return true; -    if (DMAs[cpu+2]->IsInMode(mode)) return true; -    if (DMAs[cpu+3]->IsInMode(mode)) return true; - -    if (ConsoleType == 1) -    { -        cpu >>= 2; -        return DSi::NDMAsInMode(cpu, NDMAModes[mode]); -    } +    if (DMAs[cpu+0].IsInMode(mode)) return true; +    if (DMAs[cpu+1].IsInMode(mode)) return true; +    if (DMAs[cpu+2].IsInMode(mode)) return true; +    if (DMAs[cpu+3].IsInMode(mode)) return true;      return false;  } -bool DMAsRunning(u32 cpu) +bool NDS::DMAsRunning(u32 cpu)  {      cpu <<= 2; -    if (DMAs[cpu+0]->IsRunning()) return true; -    if (DMAs[cpu+1]->IsRunning()) return true; -    if (DMAs[cpu+2]->IsRunning()) return true; -    if (DMAs[cpu+3]->IsRunning()) return true; -    if (ConsoleType == 1) -    { -        if (DSi::NDMAsRunning(cpu>>2)) return true; -    } +    if (DMAs[cpu+0].IsRunning()) return true; +    if (DMAs[cpu+1].IsRunning()) return true; +    if (DMAs[cpu+2].IsRunning()) return true; +    if (DMAs[cpu+3].IsRunning()) return true; +      return false;  } -void CheckDMAs(u32 cpu, u32 mode) +void NDS::CheckDMAs(u32 cpu, u32 mode)  {      cpu <<= 2; -    DMAs[cpu+0]->StartIfNeeded(mode); -    DMAs[cpu+1]->StartIfNeeded(mode); -    DMAs[cpu+2]->StartIfNeeded(mode); -    DMAs[cpu+3]->StartIfNeeded(mode); - -    if (ConsoleType == 1) -    { -        cpu >>= 2; -        DSi::CheckNDMAs(cpu, NDMAModes[mode]); -    } +    DMAs[cpu+0].StartIfNeeded(mode); +    DMAs[cpu+1].StartIfNeeded(mode); +    DMAs[cpu+2].StartIfNeeded(mode); +    DMAs[cpu+3].StartIfNeeded(mode);  } -void StopDMAs(u32 cpu, u32 mode) +void NDS::StopDMAs(u32 cpu, u32 mode)  {      cpu <<= 2; -    DMAs[cpu+0]->StopIfNeeded(mode); -    DMAs[cpu+1]->StopIfNeeded(mode); -    DMAs[cpu+2]->StopIfNeeded(mode); -    DMAs[cpu+3]->StopIfNeeded(mode); - -    if (ConsoleType == 1) -    { -        cpu >>= 2; -        DSi::StopNDMAs(cpu, NDMAModes[mode]); -    } +    DMAs[cpu+0].StopIfNeeded(mode); +    DMAs[cpu+1].StopIfNeeded(mode); +    DMAs[cpu+2].StopIfNeeded(mode); +    DMAs[cpu+3].StopIfNeeded(mode);  } -void DivDone(u32 param) +void NDS::DivDone(u32 param)  {      DivCnt &= ~0xC000; @@ -2008,15 +1781,15 @@ void DivDone(u32 param)          DivCnt |= 0x4000;  } -void StartDiv() +void NDS::StartDiv()  { -    NDS::CancelEvent(NDS::Event_Div); +    CancelEvent(Event_Div);      DivCnt |= 0x8000; -    NDS::ScheduleEvent(NDS::Event_Div, false, ((DivCnt&0x3)==0) ? 18:34, 0, 0); +    ScheduleEvent(Event_Div, false, ((DivCnt&0x3)==0) ? 18:34, 0, 0);  }  // http://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2 -void SqrtDone(u32 param) +void NDS::SqrtDone(u32 param)  {      u64 val;      u32 res = 0; @@ -2056,19 +1829,19 @@ void SqrtDone(u32 param)      SqrtRes = res;  } -void StartSqrt() +void NDS::StartSqrt()  { -    NDS::CancelEvent(NDS::Event_Sqrt); +    CancelEvent(Event_Sqrt);      SqrtCnt |= 0x8000; -    NDS::ScheduleEvent(NDS::Event_Sqrt, false, 13, 0, 0); +    ScheduleEvent(Event_Sqrt, false, 13, 0, 0);  } -void debug(u32 param) +void NDS::debug(u32 param)  { -    Log(LogLevel::Debug, "ARM9 PC=%08X LR=%08X %08X\n", ARM9->R[15], ARM9->R[14], ARM9->R_IRQ[1]); -    Log(LogLevel::Debug, "ARM7 PC=%08X LR=%08X %08X\n", ARM7->R[15], ARM7->R[14], ARM7->R_IRQ[1]); +    Log(LogLevel::Debug, "ARM9 PC=%08X LR=%08X %08X\n", ARM9.R[15], ARM9.R[14], ARM9.R_IRQ[1]); +    Log(LogLevel::Debug, "ARM7 PC=%08X LR=%08X %08X\n", ARM7.R[15], ARM7.R[14], ARM7.R_IRQ[1]);      Log(LogLevel::Debug, "ARM9 IME=%08X IE=%08X IF=%08X\n", IME[0], IE[0], IF[0]);      Log(LogLevel::Debug, "ARM7 IME=%08X IE=%08X IF=%08X IE2=%04X IF2=%04X\n", IME[1], IE[1], IF[1], IE2, IF2); @@ -2077,20 +1850,20 @@ void debug(u32 param)      //    printf("VRAM %c: %02X\n", 'A'+i, GPU->VRAMCNT[i]);      Platform::FileHandle* shit = Platform::OpenFile("debug/DSfirmware.bin", FileMode::Write); -    Platform::FileWrite(ARM9->ITCM, 0x8000, 1, shit); +    Platform::FileWrite(ARM9.ITCM, 0x8000, 1, shit);      for (u32 i = 0x02000000; i < 0x02400000; i+=4)      { -        u32 val = ARM7Read32(i); +        u32 val = NDS::ARM7Read32(i);          Platform::FileWrite(&val, 4, 1, shit);      }      for (u32 i = 0x037F0000; i < 0x03810000; i+=4)      { -        u32 val = ARM7Read32(i); +        u32 val = NDS::ARM7Read32(i);          Platform::FileWrite(&val, 4, 1, shit);      }      for (u32 i = 0x06000000; i < 0x06040000; i+=4)      { -        u32 val = ARM7Read32(i); +        u32 val = NDS::ARM7Read32(i);          Platform::FileWrite(&val, 4, 1, shit);      }      Platform::CloseFile(shit); @@ -2114,7 +1887,7 @@ void debug(u32 param) -u8 ARM9Read8(u32 addr) +u8 NDS::ARM9Read8(u32 addr)  {      if ((addr & 0xFFFFF000) == 0xFFFF0000)      { @@ -2137,44 +1910,43 @@ u8 ARM9Read8(u32 addr)          }      case 0x04000000: -        return ARM9IORead8(addr); +        // Specifically want to call the NDS version, not a subclass +        return NDS::ARM9IORead8(addr);      case 0x05000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; -        return GPU->ReadPalette<u8>(addr); +        return GPU.ReadPalette<u8>(addr);      case 0x06000000:          switch (addr & 0x00E00000)          { -        case 0x00000000: return GPU->ReadVRAM_ABG<u8>(addr); -        case 0x00200000: return GPU->ReadVRAM_BBG<u8>(addr); -        case 0x00400000: return GPU->ReadVRAM_AOBJ<u8>(addr); -        case 0x00600000: return GPU->ReadVRAM_BOBJ<u8>(addr); -        default:         return GPU->ReadVRAM_LCDC<u8>(addr); +        case 0x00000000: return GPU.ReadVRAM_ABG<u8>(addr); +        case 0x00200000: return GPU.ReadVRAM_BBG<u8>(addr); +        case 0x00400000: return GPU.ReadVRAM_AOBJ<u8>(addr); +        case 0x00600000: return GPU.ReadVRAM_BOBJ<u8>(addr); +        default:         return GPU.ReadVRAM_LCDC<u8>(addr);          }      case 0x07000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; -        return GPU->ReadOAM<u8>(addr); +        return GPU.ReadOAM<u8>(addr);      case 0x08000000:      case 0x09000000:          if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        if (addr & 0x1) return GBACartSlot->ROMRead(addr-1) >> 8; -        return GBACartSlot->ROMRead(addr) & 0xFF; +        if (addr & 0x1) return GBACartSlot.ROMRead(addr-1) >> 8; +        return GBACartSlot.ROMRead(addr) & 0xFF;      case 0x0A000000:          if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->SRAMRead(addr); +        return GBACartSlot.SRAMRead(addr);      }      Log(LogLevel::Debug, "unknown arm9 read8 %08X\n", addr);      return 0;  } -u16 ARM9Read16(u32 addr) +u16 NDS::ARM9Read16(u32 addr)  {      addr &= ~0x1; @@ -2199,44 +1971,42 @@ u16 ARM9Read16(u32 addr)          }      case 0x04000000: -        return ARM9IORead16(addr); +        return NDS::ARM9IORead16(addr);      case 0x05000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; -        return GPU->ReadPalette<u16>(addr); +        return GPU.ReadPalette<u16>(addr);      case 0x06000000:          switch (addr & 0x00E00000)          { -        case 0x00000000: return GPU->ReadVRAM_ABG<u16>(addr); -        case 0x00200000: return GPU->ReadVRAM_BBG<u16>(addr); -        case 0x00400000: return GPU->ReadVRAM_AOBJ<u16>(addr); -        case 0x00600000: return GPU->ReadVRAM_BOBJ<u16>(addr); -        default:         return GPU->ReadVRAM_LCDC<u16>(addr); +        case 0x00000000: return GPU.ReadVRAM_ABG<u16>(addr); +        case 0x00200000: return GPU.ReadVRAM_BBG<u16>(addr); +        case 0x00400000: return GPU.ReadVRAM_AOBJ<u16>(addr); +        case 0x00600000: return GPU.ReadVRAM_BOBJ<u16>(addr); +        default:         return GPU.ReadVRAM_LCDC<u16>(addr);          }      case 0x07000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; -        return GPU->ReadOAM<u16>(addr); +        return GPU.ReadOAM<u16>(addr);      case 0x08000000:      case 0x09000000:          if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->ROMRead(addr); +        return GBACartSlot.ROMRead(addr);      case 0x0A000000:          if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->SRAMRead(addr) | -              (GBACartSlot->SRAMRead(addr+1) << 8); +        return GBACartSlot.SRAMRead(addr) | +              (GBACartSlot.SRAMRead(addr+1) << 8);      } -    //if (addr) Log(LogLevel::Warn, "unknown arm9 read16 %08X %08X\n", addr, ARM9->R[15]); +    //if (addr) Log(LogLevel::Warn, "unknown arm9 read16 %08X %08X\n", addr, ARM9.R[15]);      return 0;  } -u32 ARM9Read32(u32 addr) +u32 NDS::ARM9Read32(u32 addr)  {      addr &= ~0x3; @@ -2261,65 +2031,63 @@ u32 ARM9Read32(u32 addr)          }      case 0x04000000: -        return ARM9IORead32(addr); +        return NDS::ARM9IORead32(addr);      case 0x05000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; -        return GPU->ReadPalette<u32>(addr); +        return GPU.ReadPalette<u32>(addr);      case 0x06000000:          switch (addr & 0x00E00000)          { -        case 0x00000000: return GPU->ReadVRAM_ABG<u32>(addr); -        case 0x00200000: return GPU->ReadVRAM_BBG<u32>(addr); -        case 0x00400000: return GPU->ReadVRAM_AOBJ<u32>(addr); -        case 0x00600000: return GPU->ReadVRAM_BOBJ<u32>(addr); -        default:         return GPU->ReadVRAM_LCDC<u32>(addr); +        case 0x00000000: return GPU.ReadVRAM_ABG<u32>(addr); +        case 0x00200000: return GPU.ReadVRAM_BBG<u32>(addr); +        case 0x00400000: return GPU.ReadVRAM_AOBJ<u32>(addr); +        case 0x00600000: return GPU.ReadVRAM_BOBJ<u32>(addr); +        default:         return GPU.ReadVRAM_LCDC<u32>(addr);          }      case 0x07000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; -        return GPU->ReadOAM<u32>(addr & 0x7FF); +        return GPU.ReadOAM<u32>(addr & 0x7FF);      case 0x08000000:      case 0x09000000:          if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->ROMRead(addr) | -              (GBACartSlot->ROMRead(addr+2) << 16); +        return GBACartSlot.ROMRead(addr) | +              (GBACartSlot.ROMRead(addr+2) << 16);      case 0x0A000000:          if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->SRAMRead(addr) | -              (GBACartSlot->SRAMRead(addr+1) << 8) | -              (GBACartSlot->SRAMRead(addr+2) << 16) | -              (GBACartSlot->SRAMRead(addr+3) << 24); +        return GBACartSlot.SRAMRead(addr) | +              (GBACartSlot.SRAMRead(addr+1) << 8) | +              (GBACartSlot.SRAMRead(addr+2) << 16) | +              (GBACartSlot.SRAMRead(addr+3) << 24);      } -    //Log(LogLevel::Warn, "unknown arm9 read32 %08X | %08X %08X\n", addr, ARM9->R[15], ARM9->R[12]); +    //Log(LogLevel::Warn, "unknown arm9 read32 %08X | %08X %08X\n", addr, ARM9.R[15], ARM9.R[12]);      return 0;  } -void ARM9Write8(u32 addr, u8 val) +void NDS::ARM9Write8(u32 addr, u8 val)  {      switch (addr & 0xFF000000)      {      case 0x02000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u8*)&MainRAM[addr & MainRAMMask] = val;          return;      case 0x03000000:          if (SWRAM_ARM9.Mem)          { -            NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr); +            JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);              *(u8*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask] = val;          }          return;      case 0x04000000: -        ARM9IOWrite8(addr, val); +        NDS::ARM9IOWrite8(addr, val);          return;      case 0x05000000: @@ -2333,142 +2101,137 @@ void ARM9Write8(u32 addr, u8 val)      case 0x0A000000:          if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->SRAMWrite(addr, val); +        GBACartSlot.SRAMWrite(addr, val);          return;      }      Log(LogLevel::Debug, "unknown arm9 write8 %08X %02X\n", addr, val);  } -void ARM9Write16(u32 addr, u16 val) +void NDS::ARM9Write16(u32 addr, u16 val)  {      addr &= ~0x1;      switch (addr & 0xFF000000)      {      case 0x02000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u16*)&MainRAM[addr & MainRAMMask] = val;          return;      case 0x03000000:          if (SWRAM_ARM9.Mem)          { -            NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr); +            JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);              *(u16*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask] = val;          }          return;      case 0x04000000: -        ARM9IOWrite16(addr, val); +        NDS::ARM9IOWrite16(addr, val);          return;      case 0x05000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; -        GPU->WritePalette<u16>(addr, val); +        GPU.WritePalette<u16>(addr, val);          return;      case 0x06000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr); +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr);          switch (addr & 0x00E00000)          { -        case 0x00000000: GPU->WriteVRAM_ABG<u16>(addr, val); return; -        case 0x00200000: GPU->WriteVRAM_BBG<u16>(addr, val); return; -        case 0x00400000: GPU->WriteVRAM_AOBJ<u16>(addr, val); return; -        case 0x00600000: GPU->WriteVRAM_BOBJ<u16>(addr, val); return; -        default: GPU->WriteVRAM_LCDC<u16>(addr, val); return; +        case 0x00000000: GPU.WriteVRAM_ABG<u16>(addr, val); return; +        case 0x00200000: GPU.WriteVRAM_BBG<u16>(addr, val); return; +        case 0x00400000: GPU.WriteVRAM_AOBJ<u16>(addr, val); return; +        case 0x00600000: GPU.WriteVRAM_BOBJ<u16>(addr, val); return; +        default: GPU.WriteVRAM_LCDC<u16>(addr, val); return;          }      case 0x07000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; -        GPU->WriteOAM<u16>(addr, val); +        GPU.WriteOAM<u16>(addr, val);          return;      case 0x08000000:      case 0x09000000:          if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->ROMWrite(addr, val); +        GBACartSlot.ROMWrite(addr, val);          return;      case 0x0A000000:          if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->SRAMWrite(addr, val & 0xFF); -        GBACartSlot->SRAMWrite(addr+1, val >> 8); +        GBACartSlot.SRAMWrite(addr, val & 0xFF); +        GBACartSlot.SRAMWrite(addr+1, val >> 8);          return;      }      //if (addr) Log(LogLevel::Warn, "unknown arm9 write16 %08X %04X\n", addr, val);  } -void ARM9Write32(u32 addr, u32 val) +void NDS::ARM9Write32(u32 addr, u32 val)  {      addr &= ~0x3;      switch (addr & 0xFF000000)      {      case 0x02000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u32*)&MainRAM[addr & MainRAMMask] = val;          return ;      case 0x03000000:          if (SWRAM_ARM9.Mem)          { -            NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr); +            JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);              *(u32*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask] = val;          }          return;      case 0x04000000: -        ARM9IOWrite32(addr, val); +        NDS::ARM9IOWrite32(addr, val);          return;      case 0x05000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; -        GPU->WritePalette(addr, val); +        GPU.WritePalette(addr, val);          return;      case 0x06000000: -        NDS::JIT->CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr); +        JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr);          switch (addr & 0x00E00000)          { -        case 0x00000000: GPU->WriteVRAM_ABG<u32>(addr, val); return; -        case 0x00200000: GPU->WriteVRAM_BBG<u32>(addr, val); return; -        case 0x00400000: GPU->WriteVRAM_AOBJ<u32>(addr, val); return; -        case 0x00600000: GPU->WriteVRAM_BOBJ<u32>(addr, val); return; -        default: GPU->WriteVRAM_LCDC<u32>(addr, val); return; +        case 0x00000000: GPU.WriteVRAM_ABG<u32>(addr, val); return; +        case 0x00200000: GPU.WriteVRAM_BBG<u32>(addr, val); return; +        case 0x00400000: GPU.WriteVRAM_AOBJ<u32>(addr, val); return; +        case 0x00600000: GPU.WriteVRAM_BOBJ<u32>(addr, val); return; +        default: GPU.WriteVRAM_LCDC<u32>(addr, val); return;          }      case 0x07000000:          if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; -        GPU->WriteOAM<u32>(addr, val); +        GPU.WriteOAM<u32>(addr, val);          return;      case 0x08000000:      case 0x09000000:          if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->ROMWrite(addr, val & 0xFFFF); -        GBACartSlot->ROMWrite(addr+2, val >> 16); +        GBACartSlot.ROMWrite(addr, val & 0xFFFF); +        GBACartSlot.ROMWrite(addr+2, val >> 16);          return;      case 0x0A000000:          if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->SRAMWrite(addr, val & 0xFF); -        GBACartSlot->SRAMWrite(addr+1, (val >> 8) & 0xFF); -        GBACartSlot->SRAMWrite(addr+2, (val >> 16) & 0xFF); -        GBACartSlot->SRAMWrite(addr+3, val >> 24); +        GBACartSlot.SRAMWrite(addr, val & 0xFF); +        GBACartSlot.SRAMWrite(addr+1, (val >> 8) & 0xFF); +        GBACartSlot.SRAMWrite(addr+2, (val >> 16) & 0xFF); +        GBACartSlot.SRAMWrite(addr+3, val >> 24);          return;      } -    //Log(LogLevel::Warn, "unknown arm9 write32 %08X %08X | %08X\n", addr, val, ARM9->R[15]); +    //Log(LogLevel::Warn, "unknown arm9 write32 %08X %08X | %08X\n", addr, val, ARM9.R[15]);  } -bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region) +bool NDS::ARM9GetMemRegion(u32 addr, bool write, MemRegion* region)  {      switch (addr & 0xFF000000)      { @@ -2500,14 +2263,14 @@ bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region) -u8 ARM7Read8(u32 addr) +u8 NDS::ARM7Read8(u32 addr)  {      if (addr < 0x00004000)      {          // TODO: check the boundary? is it 4000 or higher on regular DS? -        if (ARM7->R[15] >= 0x00004000) +        if (ARM7.R[15] >= 0x00004000)              return 0xFF; -        if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt) +        if (addr < ARM7BIOSProt && ARM7.R[15] >= ARM7BIOSProt)              return 0xFF;          return *(u8*)&ARM7BIOS[addr]; @@ -2533,50 +2296,48 @@ u8 ARM7Read8(u32 addr)          return *(u8*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];      case 0x04000000: -        return ARM7IORead8(addr); +        return NDS::ARM7IORead8(addr);      case 0x04800000:          if (addr < 0x04810000)          {              if (!(PowerControl7 & (1<<1))) return 0; -            if (addr & 0x1) return Wifi->Read(addr-1) >> 8; -            return Wifi->Read(addr) & 0xFF; +            if (addr & 0x1) return Wifi.Read(addr-1) >> 8; +            return Wifi.Read(addr) & 0xFF;          }          break;      case 0x06000000:      case 0x06800000: -        return GPU->ReadVRAM_ARM7<u8>(addr); +        return GPU.ReadVRAM_ARM7<u8>(addr);      case 0x08000000:      case 0x08800000:      case 0x09000000:      case 0x09800000:          if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        if (addr & 0x1) return GBACartSlot->ROMRead(addr-1) >> 8; -        return GBACartSlot->ROMRead(addr) & 0xFF; +        if (addr & 0x1) return GBACartSlot.ROMRead(addr-1) >> 8; +        return GBACartSlot.ROMRead(addr) & 0xFF;      case 0x0A000000:      case 0x0A800000:          if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->SRAMRead(addr); +        return GBACartSlot.SRAMRead(addr);      } -    Log(LogLevel::Debug, "unknown arm7 read8 %08X %08X %08X/%08X\n", addr, ARM7->R[15], ARM7->R[0], ARM7->R[1]); +    Log(LogLevel::Debug, "unknown arm7 read8 %08X %08X %08X/%08X\n", addr, ARM7.R[15], ARM7.R[0], ARM7.R[1]);      return 0;  } -u16 ARM7Read16(u32 addr) +u16 NDS::ARM7Read16(u32 addr)  {      addr &= ~0x1;      if (addr < 0x00004000)      { -        if (ARM7->R[15] >= 0x00004000) +        if (ARM7.R[15] >= 0x00004000)              return 0xFFFF; -        if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt) +        if (addr < ARM7BIOSProt && ARM7.R[15] >= ARM7BIOSProt)              return 0xFFFF;          return *(u16*)&ARM7BIOS[addr]; @@ -2602,49 +2363,47 @@ u16 ARM7Read16(u32 addr)          return *(u16*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];      case 0x04000000: -        return ARM7IORead16(addr); +        return NDS::ARM7IORead16(addr);      case 0x04800000:          if (addr < 0x04810000)          {              if (!(PowerControl7 & (1<<1))) return 0; -            return Wifi->Read(addr); +            return Wifi.Read(addr);          }          break;      case 0x06000000:      case 0x06800000: -        return GPU->ReadVRAM_ARM7<u16>(addr); +        return GPU.ReadVRAM_ARM7<u16>(addr);      case 0x08000000:      case 0x08800000:      case 0x09000000:      case 0x09800000:          if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->ROMRead(addr); +        return GBACartSlot.ROMRead(addr);      case 0x0A000000:      case 0x0A800000:          if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->SRAMRead(addr) | -              (GBACartSlot->SRAMRead(addr+1) << 8); +        return GBACartSlot.SRAMRead(addr) | +              (GBACartSlot.SRAMRead(addr+1) << 8);      } -    Log(LogLevel::Debug, "unknown arm7 read16 %08X %08X\n", addr, ARM7->R[15]); +    Log(LogLevel::Debug, "unknown arm7 read16 %08X %08X\n", addr, ARM7.R[15]);      return 0;  } -u32 ARM7Read32(u32 addr) +u32 NDS::ARM7Read32(u32 addr)  {      addr &= ~0x3;      if (addr < 0x00004000)      { -        if (ARM7->R[15] >= 0x00004000) +        if (ARM7.R[15] >= 0x00004000)              return 0xFFFFFFFF; -        if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt) +        if (addr < ARM7BIOSProt && ARM7.R[15] >= ARM7BIOSProt)              return 0xFFFFFFFF;          return *(u32*)&ARM7BIOS[addr]; @@ -2670,80 +2429,78 @@ u32 ARM7Read32(u32 addr)          return *(u32*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];      case 0x04000000: -        return ARM7IORead32(addr); +        return NDS::ARM7IORead32(addr);      case 0x04800000:          if (addr < 0x04810000)          {              if (!(PowerControl7 & (1<<1))) return 0; -            return Wifi->Read(addr) | (Wifi->Read(addr+2) << 16); +            return Wifi.Read(addr) | (Wifi.Read(addr+2) << 16);          }          break;      case 0x06000000:      case 0x06800000: -        return GPU->ReadVRAM_ARM7<u32>(addr); +        return GPU.ReadVRAM_ARM7<u32>(addr);      case 0x08000000:      case 0x08800000:      case 0x09000000:      case 0x09800000:          if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->ROMRead(addr) | -              (GBACartSlot->ROMRead(addr+2) << 16); +        return GBACartSlot.ROMRead(addr) | +              (GBACartSlot.ROMRead(addr+2) << 16);      case 0x0A000000:      case 0x0A800000:          if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled -        assert(GBACartSlot != nullptr); -        return GBACartSlot->SRAMRead(addr) | -              (GBACartSlot->SRAMRead(addr+1) << 8) | -              (GBACartSlot->SRAMRead(addr+2) << 16) | -              (GBACartSlot->SRAMRead(addr+3) << 24); +        return GBACartSlot.SRAMRead(addr) | +              (GBACartSlot.SRAMRead(addr+1) << 8) | +              (GBACartSlot.SRAMRead(addr+2) << 16) | +              (GBACartSlot.SRAMRead(addr+3) << 24);      } -    //Log(LogLevel::Warn, "unknown arm7 read32 %08X | %08X\n", addr, ARM7->R[15]); +    //Log(LogLevel::Warn, "unknown arm7 read32 %08X | %08X\n", addr, ARM7.R[15]);      return 0;  } -void ARM7Write8(u32 addr, u8 val) +void NDS::ARM7Write8(u32 addr, u8 val)  {      switch (addr & 0xFF800000)      {      case 0x02000000:      case 0x02800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u8*)&MainRAM[addr & MainRAMMask] = val;          return;      case 0x03000000:          if (SWRAM_ARM7.Mem)          { -            NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr); +            JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);              *(u8*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask] = val;              return;          }          else          { -            NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr); +            JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);              *(u8*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;              return;          }      case 0x03800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);          *(u8*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;          return;      case 0x04000000: -        ARM7IOWrite8(addr, val); +        NDS::ARM7IOWrite8(addr, val);          return;      case 0x06000000:      case 0x06800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr); -        GPU->WriteVRAM_ARM7<u8>(addr, val); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr); +        GPU.WriteVRAM_ARM7<u8>(addr, val);          return;      case 0x08000000: @@ -2755,17 +2512,16 @@ void ARM7Write8(u32 addr, u8 val)      case 0x0A000000:      case 0x0A800000:          if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->SRAMWrite(addr, val); +        GBACartSlot.SRAMWrite(addr, val);          return;      } -    //if (ARM7->R[15] > 0x00002F30) // ARM7 BIOS bug +    //if (ARM7.R[15] > 0x00002F30) // ARM7 BIOS bug      if (addr >= 0x01000000) -        Log(LogLevel::Debug, "unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7->R[15]); +        Log(LogLevel::Debug, "unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7.R[15]);  } -void ARM7Write16(u32 addr, u16 val) +void NDS::ARM7Write16(u32 addr, u16 val)  {      addr &= ~0x1; @@ -2773,46 +2529,46 @@ void ARM7Write16(u32 addr, u16 val)      {      case 0x02000000:      case 0x02800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u16*)&MainRAM[addr & MainRAMMask] = val;          return;      case 0x03000000:          if (SWRAM_ARM7.Mem)          { -            NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr); +            JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);              *(u16*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask] = val;              return;          }          else          { -            NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr); +            JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);              *(u16*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;              return;          }      case 0x03800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);          *(u16*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;          return;      case 0x04000000: -        ARM7IOWrite16(addr, val); +        NDS::ARM7IOWrite16(addr, val);          return;      case 0x04800000:          if (addr < 0x04810000)          {              if (!(PowerControl7 & (1<<1))) return; -            Wifi->Write(addr, val); +            Wifi.Write(addr, val);              return;          }          break;      case 0x06000000:      case 0x06800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr); -        GPU->WriteVRAM_ARM7<u16>(addr, val); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr); +        GPU.WriteVRAM_ARM7<u16>(addr, val);          return;      case 0x08000000: @@ -2820,23 +2576,22 @@ void ARM7Write16(u32 addr, u16 val)      case 0x09000000:      case 0x09800000:          if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->ROMWrite(addr, val); +        GBACartSlot.ROMWrite(addr, val);          return;      case 0x0A000000:      case 0x0A800000:          if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write -        GBACartSlot->SRAMWrite(addr, val & 0xFF); -        GBACartSlot->SRAMWrite(addr+1, val >> 8); +        GBACartSlot.SRAMWrite(addr, val & 0xFF); +        GBACartSlot.SRAMWrite(addr+1, val >> 8);          return;      }      if (addr >= 0x01000000) -        Log(LogLevel::Debug, "unknown arm7 write16 %08X %04X @ %08X\n", addr, val, ARM7->R[15]); +        Log(LogLevel::Debug, "unknown arm7 write16 %08X %04X @ %08X\n", addr, val, ARM7.R[15]);  } -void ARM7Write32(u32 addr, u32 val) +void NDS::ARM7Write32(u32 addr, u32 val)  {      addr &= ~0x3; @@ -2844,47 +2599,47 @@ void ARM7Write32(u32 addr, u32 val)      {      case 0x02000000:      case 0x02800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);          *(u32*)&MainRAM[addr & MainRAMMask] = val;          return;      case 0x03000000:          if (SWRAM_ARM7.Mem)          { -            NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr); +            JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);              *(u32*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask] = val;              return;          }          else          { -            NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr); +            JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);              *(u32*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;              return;          }      case 0x03800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);          *(u32*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;          return;      case 0x04000000: -        ARM7IOWrite32(addr, val); +        NDS::ARM7IOWrite32(addr, val);          return;      case 0x04800000:          if (addr < 0x04810000)          {              if (!(PowerControl7 & (1<<1))) return; -            Wifi->Write(addr, val & 0xFFFF); -            Wifi->Write(addr+2, val >> 16); +            Wifi.Write(addr, val & 0xFFFF); +            Wifi.Write(addr+2, val >> 16);              return;          }          break;      case 0x06000000:      case 0x06800000: -        NDS::JIT->CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr); -        GPU->WriteVRAM_ARM7<u32>(addr, val); +        JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr); +        GPU.WriteVRAM_ARM7<u32>(addr, val);          return;      case 0x08000000: @@ -2892,27 +2647,25 @@ void ARM7Write32(u32 addr, u32 val)      case 0x09000000:      case 0x09800000:          if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->ROMWrite(addr, val & 0xFFFF); -        GBACartSlot->ROMWrite(addr+2, val >> 16); +        GBACartSlot.ROMWrite(addr, val & 0xFFFF); +        GBACartSlot.ROMWrite(addr+2, val >> 16);          return;      case 0x0A000000:      case 0x0A800000:          if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write -        assert(GBACartSlot != nullptr); -        GBACartSlot->SRAMWrite(addr, val & 0xFF); -        GBACartSlot->SRAMWrite(addr+1, (val >> 8) & 0xFF); -        GBACartSlot->SRAMWrite(addr+2, (val >> 16) & 0xFF); -        GBACartSlot->SRAMWrite(addr+3, val >> 24); +        GBACartSlot.SRAMWrite(addr, val & 0xFF); +        GBACartSlot.SRAMWrite(addr+1, (val >> 8) & 0xFF); +        GBACartSlot.SRAMWrite(addr+2, (val >> 16) & 0xFF); +        GBACartSlot.SRAMWrite(addr+3, val >> 24);          return;      }      if (addr >= 0x01000000) -        Log(LogLevel::Debug, "unknown arm7 write32 %08X %08X @ %08X\n", addr, val, ARM7->R[15]); +        Log(LogLevel::Debug, "unknown arm7 write32 %08X %08X @ %08X\n", addr, val, ARM7.R[15]);  } -bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region) +bool NDS::ARM7GetMemRegion(u32 addr, bool write, MemRegion* region)  {      switch (addr & 0xFF800000)      { @@ -2945,7 +2698,7 @@ bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region)      // BIOS. ARM7 PC has to be within range.      if (addr < 0x00004000 && !write)      { -        if (ARM7->R[15] < 0x4000 && (addr >= ARM7BIOSProt || ARM7->R[15] < ARM7BIOSProt)) +        if (ARM7.R[15] < 0x4000 && (addr >= ARM7BIOSProt || ARM7.R[15] < ARM7BIOSProt))          {              region->Mem = ARM7BIOS;              region->Mask = 0x3FFF; @@ -2970,7 +2723,7 @@ bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region)      case (addr+2): return ((val) >> 16) & 0xFF; \      case (addr+3): return (val) >> 24; -u8 ARM9IORead8(u32 addr) +u8 NDS::ARM9IORead8(u32 addr)  {      switch (addr)      { @@ -2981,54 +2734,54 @@ u8 ARM9IORead8(u32 addr)      case 0x040001A2:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->ReadSPIData(); +            return NDSCartSlot.ReadSPIData();          return 0;      case 0x040001A8:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(0); +            return NDSCartSlot.GetROMCommand(0);          return 0;      case 0x040001A9:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(1); +            return NDSCartSlot.GetROMCommand(1);          return 0;      case 0x040001AA:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(2); +            return NDSCartSlot.GetROMCommand(2);          return 0;      case 0x040001AB:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(3); +            return NDSCartSlot.GetROMCommand(3);          return 0;      case 0x040001AC:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(4); +            return NDSCartSlot.GetROMCommand(4);          return 0;      case 0x040001AD:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(5); +            return NDSCartSlot.GetROMCommand(5);          return 0;      case 0x040001AE:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(6); +            return NDSCartSlot.GetROMCommand(6);          return 0;      case 0x040001AF:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(7); +            return NDSCartSlot.GetROMCommand(7);          return 0;      case 0x04000208: return IME[0]; -    case 0x04000240: return GPU->VRAMCNT[0]; -    case 0x04000241: return GPU->VRAMCNT[1]; -    case 0x04000242: return GPU->VRAMCNT[2]; -    case 0x04000243: return GPU->VRAMCNT[3]; -    case 0x04000244: return GPU->VRAMCNT[4]; -    case 0x04000245: return GPU->VRAMCNT[5]; -    case 0x04000246: return GPU->VRAMCNT[6]; +    case 0x04000240: return GPU.VRAMCNT[0]; +    case 0x04000241: return GPU.VRAMCNT[1]; +    case 0x04000242: return GPU.VRAMCNT[2]; +    case 0x04000243: return GPU.VRAMCNT[3]; +    case 0x04000244: return GPU.VRAMCNT[4]; +    case 0x04000245: return GPU.VRAMCNT[5]; +    case 0x04000246: return GPU.VRAMCNT[6];      case 0x04000247: return WRAMCnt; -    case 0x04000248: return GPU->VRAMCNT[7]; -    case 0x04000249: return GPU->VRAMCNT[8]; +    case 0x04000248: return GPU.VRAMCNT[7]; +    case 0x04000249: return GPU.VRAMCNT[8];      CASE_READ8_16BIT(0x04000280, DivCnt)      CASE_READ8_32BIT(0x04000290, DivNumerator[0]) @@ -3050,15 +2803,15 @@ 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)      { -        return GPU->GPU3D.Read8(addr); +        return GPU.GPU3D.Read8(addr);      }      // NO$GBA debug register "Emulation ID"      if(addr >= 0x04FFFA00 && addr < 0x04FFFA10) @@ -3070,29 +2823,29 @@ u8 ARM9IORead8(u32 addr)      }      if ((addr & 0xFFFFF000) != 0x04004000) -        Log(LogLevel::Debug, "unknown ARM9 IO read8 %08X %08X\n", addr, ARM9->R[15]); +        Log(LogLevel::Debug, "unknown ARM9 IO read8 %08X %08X\n", addr, ARM9.R[15]);      return 0;  } -u16 ARM9IORead16(u32 addr) +u16 NDS::ARM9IORead16(u32 addr)  {      switch (addr)      { -    case 0x04000004: return GPU->DispStat[0]; -    case 0x04000006: return GPU->VCount; +    case 0x04000004: return GPU.DispStat[0]; +    case 0x04000006: return GPU.VCount; -    case 0x04000060: return GPU->GPU3D.Read16(addr); +    case 0x04000060: return GPU.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; -    case 0x040000C4: return DMAs[1]->Cnt & 0xFFFF; -    case 0x040000C6: return DMAs[1]->Cnt >> 16; -    case 0x040000D0: return DMAs[2]->Cnt & 0xFFFF; -    case 0x040000D2: return DMAs[2]->Cnt >> 16; -    case 0x040000DC: return DMAs[3]->Cnt & 0xFFFF; -    case 0x040000DE: return DMAs[3]->Cnt >> 16; +    case 0x040000B8: return DMAs[0].Cnt & 0xFFFF; +    case 0x040000BA: return DMAs[0].Cnt >> 16; +    case 0x040000C4: return DMAs[1].Cnt & 0xFFFF; +    case 0x040000C6: return DMAs[1].Cnt >> 16; +    case 0x040000D0: return DMAs[2].Cnt & 0xFFFF; +    case 0x040000D2: return DMAs[2].Cnt >> 16; +    case 0x040000DC: return DMAs[3].Cnt & 0xFFFF; +    case 0x040000DE: return DMAs[3].Cnt >> 16;      case 0x040000E0: return ((u16*)DMA9Fill)[0];      case 0x040000E2: return ((u16*)DMA9Fill)[1]; @@ -3128,32 +2881,32 @@ u16 ARM9IORead16(u32 addr)      case 0x040001A0:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetSPICnt(); +            return NDSCartSlot.GetSPICnt();          return 0;      case 0x040001A2:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->ReadSPIData(); +            return NDSCartSlot.ReadSPIData();          return 0;      case 0x040001A8:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(0) | -                  (NDSCartSlot->GetROMCommand(1) << 8); +            return NDSCartSlot.GetROMCommand(0) | +                  (NDSCartSlot.GetROMCommand(1) << 8);          return 0;      case 0x040001AA:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(2) | -                  (NDSCartSlot->GetROMCommand(3) << 8); +            return NDSCartSlot.GetROMCommand(2) | +                  (NDSCartSlot.GetROMCommand(3) << 8);          return 0;      case 0x040001AC:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(4) | -                  (NDSCartSlot->GetROMCommand(5) << 8); +            return NDSCartSlot.GetROMCommand(4) | +                  (NDSCartSlot.GetROMCommand(5) << 8);          return 0;      case 0x040001AE:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(6) | -                  (NDSCartSlot->GetROMCommand(7) << 8); +            return NDSCartSlot.GetROMCommand(6) | +                  (NDSCartSlot.GetROMCommand(7) << 8);          return 0;      case 0x04000204: return ExMemCnt[0]; @@ -3161,11 +2914,11 @@ u16 ARM9IORead16(u32 addr)      case 0x04000210: return IE[0] & 0xFFFF;      case 0x04000212: return IE[0] >> 16; -    case 0x04000240: return GPU->VRAMCNT[0] | (GPU->VRAMCNT[1] << 8); -    case 0x04000242: return GPU->VRAMCNT[2] | (GPU->VRAMCNT[3] << 8); -    case 0x04000244: return GPU->VRAMCNT[4] | (GPU->VRAMCNT[5] << 8); -    case 0x04000246: return GPU->VRAMCNT[6] | (WRAMCnt << 8); -    case 0x04000248: return GPU->VRAMCNT[7] | (GPU->VRAMCNT[8] << 8); +    case 0x04000240: return GPU.VRAMCNT[0] | (GPU.VRAMCNT[1] << 8); +    case 0x04000242: return GPU.VRAMCNT[2] | (GPU.VRAMCNT[3] << 8); +    case 0x04000244: return GPU.VRAMCNT[4] | (GPU.VRAMCNT[5] << 8); +    case 0x04000246: return GPU.VRAMCNT[6] | (WRAMCnt << 8); +    case 0x04000248: return GPU.VRAMCNT[7] | (GPU.VRAMCNT[8] << 8);      case 0x04000280: return DivCnt;      case 0x04000290: return DivNumerator[0] & 0xFFFF; @@ -3205,43 +2958,43 @@ 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)      { -        return GPU->GPU3D.Read16(addr); +        return GPU.GPU3D.Read16(addr);      }      if ((addr & 0xFFFFF000) != 0x04004000) -        Log(LogLevel::Debug, "unknown ARM9 IO read16 %08X %08X\n", addr, ARM9->R[15]); +        Log(LogLevel::Debug, "unknown ARM9 IO read16 %08X %08X\n", addr, ARM9.R[15]);      return 0;  } -u32 ARM9IORead32(u32 addr) +u32 NDS::ARM9IORead32(u32 addr)  {      switch (addr)      { -    case 0x04000004: return GPU->DispStat[0] | (GPU->VCount << 16); - -    case 0x04000060: return GPU->GPU3D.Read32(addr); -    case 0x04000064: return GPU->GPU2D_A.Read32(addr); - -    case 0x040000B0: return DMAs[0]->SrcAddr; -    case 0x040000B4: return DMAs[0]->DstAddr; -    case 0x040000B8: return DMAs[0]->Cnt; -    case 0x040000BC: return DMAs[1]->SrcAddr; -    case 0x040000C0: return DMAs[1]->DstAddr; -    case 0x040000C4: return DMAs[1]->Cnt; -    case 0x040000C8: return DMAs[2]->SrcAddr; -    case 0x040000CC: return DMAs[2]->DstAddr; -    case 0x040000D0: return DMAs[2]->Cnt; -    case 0x040000D4: return DMAs[3]->SrcAddr; -    case 0x040000D8: return DMAs[3]->DstAddr; -    case 0x040000DC: return DMAs[3]->Cnt; +    case 0x04000004: return GPU.DispStat[0] | (GPU.VCount << 16); + +    case 0x04000060: return GPU.GPU3D.Read32(addr); +    case 0x04000064: return GPU.GPU2D_A.Read32(addr); + +    case 0x040000B0: return DMAs[0].SrcAddr; +    case 0x040000B4: return DMAs[0].DstAddr; +    case 0x040000B8: return DMAs[0].Cnt; +    case 0x040000BC: return DMAs[1].SrcAddr; +    case 0x040000C0: return DMAs[1].DstAddr; +    case 0x040000C4: return DMAs[1].Cnt; +    case 0x040000C8: return DMAs[2].SrcAddr; +    case 0x040000CC: return DMAs[2].DstAddr; +    case 0x040000D0: return DMAs[2].Cnt; +    case 0x040000D4: return DMAs[3].SrcAddr; +    case 0x040000D8: return DMAs[3].DstAddr; +    case 0x040000DC: return DMAs[3].Cnt;      case 0x040000E0: return DMA9Fill[0];      case 0x040000E4: return DMA9Fill[1]; @@ -3258,39 +3011,39 @@ u32 ARM9IORead32(u32 addr)      case 0x04000130: LagFrameFlag = false; return (KeyInput & 0xFFFF) | (KeyCnt[0] << 16);      case 0x04000180: return IPCSync9; -    case 0x04000184: return ARM9IORead16(addr); +    case 0x04000184: return NDS::ARM9IORead16(addr);      case 0x040001A0:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetSPICnt() | (NDSCartSlot->ReadSPIData() << 16); +            return NDSCartSlot.GetSPICnt() | (NDSCartSlot.ReadSPIData() << 16);          return 0;      case 0x040001A4:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCnt(); +            return NDSCartSlot.GetROMCnt();          return 0;      case 0x040001A8:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(0) | -                  (NDSCartSlot->GetROMCommand(1) << 8) | -                  (NDSCartSlot->GetROMCommand(2) << 16) | -                  (NDSCartSlot->GetROMCommand(3) << 24); +            return NDSCartSlot.GetROMCommand(0) | +                  (NDSCartSlot.GetROMCommand(1) << 8) | +                  (NDSCartSlot.GetROMCommand(2) << 16) | +                  (NDSCartSlot.GetROMCommand(3) << 24);          return 0;      case 0x040001AC:          if (!(ExMemCnt[0] & (1<<11))) -            return NDSCartSlot->GetROMCommand(4) | -                  (NDSCartSlot->GetROMCommand(5) << 8) | -                  (NDSCartSlot->GetROMCommand(6) << 16) | -                  (NDSCartSlot->GetROMCommand(7) << 24); +            return NDSCartSlot.GetROMCommand(4) | +                  (NDSCartSlot.GetROMCommand(5) << 8) | +                  (NDSCartSlot.GetROMCommand(6) << 16) | +                  (NDSCartSlot.GetROMCommand(7) << 24);          return 0;      case 0x04000208: return IME[0];      case 0x04000210: return IE[0];      case 0x04000214: return IF[0]; -    case 0x04000240: return GPU->VRAMCNT[0] | (GPU->VRAMCNT[1] << 8) | (GPU->VRAMCNT[2] << 16) | (GPU->VRAMCNT[3] << 24); -    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 0x04000240: return GPU.VRAMCNT[0] | (GPU.VRAMCNT[1] << 8) | (GPU.VRAMCNT[2] << 16) | (GPU.VRAMCNT[3] << 24); +    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]; @@ -3332,7 +3085,7 @@ u32 ARM9IORead32(u32 addr)              return IPCFIFO7.Peek();      case 0x04100010: -        if (!(ExMemCnt[0] & (1<<11))) return NDSCartSlot->ReadROMData(); +        if (!(ExMemCnt[0] & (1<<11))) return NDSCartSlot.ReadROMData();          return 0;      case 0x04004000: @@ -3349,30 +3102,30 @@ 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)      { -        return GPU->GPU3D.Read32(addr); +        return GPU.GPU3D.Read32(addr);      }      if ((addr & 0xFFFFF000) != 0x04004000) -        Log(LogLevel::Debug, "unknown ARM9 IO read32 %08X %08X\n", addr, ARM9->R[15]); +        Log(LogLevel::Debug, "unknown ARM9 IO read32 %08X %08X\n", addr, ARM9.R[15]);      return 0;  } -void ARM9IOWrite8(u32 addr, u8 val) +void NDS::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[0] = (KeyCnt[0] & 0xFF00) | val; @@ -3382,43 +3135,43 @@ void ARM9IOWrite8(u32 addr, u8 val)          return;      case 0x04000188: -        ARM9IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24)); +        NDS::ARM9IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24));          return;      case 0x040001A0:          if (!(ExMemCnt[0] & (1<<11))) -            NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0xFF00) | val); +            NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 0xFF00) | val);          return;      case 0x040001A1:          if (!(ExMemCnt[0] & (1<<11))) -            NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0x00FF) | (val << 8)); +            NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 0x00FF) | (val << 8));          return;      case 0x040001A2:          if (!(ExMemCnt[0] & (1<<11))) -            NDSCartSlot->WriteSPIData(val); +            NDSCartSlot.WriteSPIData(val);          return; -    case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(0, val); return; -    case 0x040001A9: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(1, val); return; -    case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(2, val); return; -    case 0x040001AB: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(3, val); return; -    case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(4, val); return; -    case 0x040001AD: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(5, val); return; -    case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(6, val); return; -    case 0x040001AF: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(7, val); return; +    case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(0, val); return; +    case 0x040001A9: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(1, val); return; +    case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(2, val); return; +    case 0x040001AB: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(3, val); return; +    case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(4, val); return; +    case 0x040001AD: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(5, val); return; +    case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(6, val); return; +    case 0x040001AF: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(7, val); return;      case 0x04000208: IME[0] = val & 0x1; UpdateIRQ(0); return; -    case 0x04000240: GPU->MapVRAM_AB(0, val); return; -    case 0x04000241: GPU->MapVRAM_AB(1, val); return; -    case 0x04000242: GPU->MapVRAM_CD(2, val); return; -    case 0x04000243: GPU->MapVRAM_CD(3, val); return; -    case 0x04000244: GPU->MapVRAM_E(4, val); return; -    case 0x04000245: GPU->MapVRAM_FG(5, val); return; -    case 0x04000246: GPU->MapVRAM_FG(6, val); return; +    case 0x04000240: GPU.MapVRAM_AB(0, val); return; +    case 0x04000241: GPU.MapVRAM_AB(1, val); return; +    case 0x04000242: GPU.MapVRAM_CD(2, val); return; +    case 0x04000243: GPU.MapVRAM_CD(3, val); return; +    case 0x04000244: GPU.MapVRAM_E(4, val); return; +    case 0x04000245: GPU.MapVRAM_FG(5, val); return; +    case 0x04000246: GPU.MapVRAM_FG(6, val); return;      case 0x04000247: MapSharedWRAM(val); return; -    case 0x04000248: GPU->MapVRAM_H(7, val); return; -    case 0x04000249: GPU->MapVRAM_I(8, val); return; +    case 0x04000248: GPU.MapVRAM_H(7, val); return; +    case 0x04000249: GPU.MapVRAM_I(8, val); return;      case 0x04000300:          if (PostFlag9 & 0x01) val |= 0x01; @@ -3428,46 +3181,46 @@ 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)      { -        GPU->GPU3D.Write8(addr, val); +        GPU.GPU3D.Write8(addr, val);          return;      } -    Log(LogLevel::Debug, "unknown ARM9 IO write8 %08X %02X %08X\n", addr, val, ARM9->R[15]); +    Log(LogLevel::Debug, "unknown ARM9 IO write8 %08X %02X %08X\n", addr, val, ARM9.R[15]);  } -void ARM9IOWrite16(u32 addr, u16 val) +void NDS::ARM9IOWrite16(u32 addr, u16 val)  {      switch (addr)      { -    case 0x04000004: GPU->SetDispStat(0, val); return; -    case 0x04000006: GPU->SetVCount(val); return; +    case 0x04000004: GPU.SetDispStat(0, val); return; +    case 0x04000006: GPU.SetVCount(val); return; -    case 0x04000060: GPU->GPU3D.Write16(addr, val); return; +    case 0x04000060: GPU.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; -    case 0x040000C4: DMAs[1]->WriteCnt((DMAs[1]->Cnt & 0xFFFF0000) | val); return; -    case 0x040000C6: DMAs[1]->WriteCnt((DMAs[1]->Cnt & 0x0000FFFF) | (val << 16)); return; -    case 0x040000D0: DMAs[2]->WriteCnt((DMAs[2]->Cnt & 0xFFFF0000) | val); return; -    case 0x040000D2: DMAs[2]->WriteCnt((DMAs[2]->Cnt & 0x0000FFFF) | (val << 16)); return; -    case 0x040000DC: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0xFFFF0000) | val); return; -    case 0x040000DE: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0x0000FFFF) | (val << 16)); return; +    case 0x040000B8: DMAs[0].WriteCnt((DMAs[0].Cnt & 0xFFFF0000) | val); return; +    case 0x040000BA: DMAs[0].WriteCnt((DMAs[0].Cnt & 0x0000FFFF) | (val << 16)); return; +    case 0x040000C4: DMAs[1].WriteCnt((DMAs[1].Cnt & 0xFFFF0000) | val); return; +    case 0x040000C6: DMAs[1].WriteCnt((DMAs[1].Cnt & 0x0000FFFF) | (val << 16)); return; +    case 0x040000D0: DMAs[2].WriteCnt((DMAs[2].Cnt & 0xFFFF0000) | val); return; +    case 0x040000D2: DMAs[2].WriteCnt((DMAs[2].Cnt & 0x0000FFFF) | (val << 16)); return; +    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; @@ -3515,44 +3268,44 @@ void ARM9IOWrite16(u32 addr, u16 val)          return;      case 0x04000188: -        ARM9IOWrite32(addr, val | (val << 16)); +        NDS::ARM9IOWrite32(addr, val | (val << 16));          return;      case 0x040001A0:          if (!(ExMemCnt[0] & (1<<11))) -            NDSCartSlot->WriteSPICnt(val); +            NDSCartSlot.WriteSPICnt(val);          return;      case 0x040001A2:          if (!(ExMemCnt[0] & (1<<11))) -            NDSCartSlot->WriteSPIData(val & 0xFF); +            NDSCartSlot.WriteSPIData(val & 0xFF);          return;      case 0x040001A8:          if (!(ExMemCnt[0] & (1<<11)))          { -            NDSCartSlot->SetROMCommand(0, val & 0xFF); -            NDSCartSlot->SetROMCommand(1, val >> 8); +            NDSCartSlot.SetROMCommand(0, val & 0xFF); +            NDSCartSlot.SetROMCommand(1, val >> 8);          }          return;      case 0x040001AA:          if (!(ExMemCnt[0] & (1<<11)))          { -            NDSCartSlot->SetROMCommand(2, val & 0xFF); -            NDSCartSlot->SetROMCommand(3, val >> 8); +            NDSCartSlot.SetROMCommand(2, val & 0xFF); +            NDSCartSlot.SetROMCommand(3, val >> 8);          }          return;      case 0x040001AC:          if (!(ExMemCnt[0] & (1<<11)))          { -            NDSCartSlot->SetROMCommand(4, val & 0xFF); -            NDSCartSlot->SetROMCommand(5, val >> 8); +            NDSCartSlot.SetROMCommand(4, val & 0xFF); +            NDSCartSlot.SetROMCommand(5, val >> 8);          }          return;      case 0x040001AE:          if (!(ExMemCnt[0] & (1<<11)))          { -            NDSCartSlot->SetROMCommand(6, val & 0xFF); -            NDSCartSlot->SetROMCommand(7, val >> 8); +            NDSCartSlot.SetROMCommand(6, val & 0xFF); +            NDSCartSlot.SetROMCommand(7, val >> 8);          }          return; @@ -3575,24 +3328,24 @@ void ARM9IOWrite16(u32 addr, u16 val)      // TODO: what happens when writing to IF this way??      case 0x04000240: -        GPU->MapVRAM_AB(0, val & 0xFF); -        GPU->MapVRAM_AB(1, val >> 8); +        GPU.MapVRAM_AB(0, val & 0xFF); +        GPU.MapVRAM_AB(1, val >> 8);          return;      case 0x04000242: -        GPU->MapVRAM_CD(2, val & 0xFF); -        GPU->MapVRAM_CD(3, val >> 8); +        GPU.MapVRAM_CD(2, val & 0xFF); +        GPU.MapVRAM_CD(3, val >> 8);          return;      case 0x04000244: -        GPU->MapVRAM_E(4, val & 0xFF); -        GPU->MapVRAM_FG(5, val >> 8); +        GPU.MapVRAM_E(4, val & 0xFF); +        GPU.MapVRAM_FG(5, val >> 8);          return;      case 0x04000246: -        GPU->MapVRAM_FG(6, val & 0xFF); +        GPU.MapVRAM_FG(6, val & 0xFF);          MapSharedWRAM(val >> 8);          return;      case 0x04000248: -        GPU->MapVRAM_H(7, val & 0xFF); -        GPU->MapVRAM_I(8, val >> 8); +        GPU.MapVRAM_H(7, val & 0xFF); +        GPU.MapVRAM_I(8, val >> 8);          return;      case 0x04000280: DivCnt = val; StartDiv(); return; @@ -3606,57 +3359,57 @@ void ARM9IOWrite16(u32 addr, u16 val)      case 0x04000304:          PowerControl9 = val & 0x820F; -        GPU->SetPowerCnt(PowerControl9); +        GPU.SetPowerCnt(PowerControl9);          return;      }      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)      { -        GPU->GPU3D.Write16(addr, val); +        GPU.GPU3D.Write16(addr, val);          return;      } -    Log(LogLevel::Debug, "unknown ARM9 IO write16 %08X %04X %08X\n", addr, val, ARM9->R[15]); +    Log(LogLevel::Debug, "unknown ARM9 IO write16 %08X %04X %08X\n", addr, val, ARM9.R[15]);  } -void ARM9IOWrite32(u32 addr, u32 val) +void NDS::ARM9IOWrite32(u32 addr, u32 val)  {      switch (addr)      {      case 0x04000004: -        GPU->SetDispStat(0, val & 0xFFFF); -        GPU->SetVCount(val >> 16); +        GPU.SetDispStat(0, val & 0xFFFF); +        GPU.SetVCount(val >> 16);          return; -    case 0x04000060: GPU->GPU3D.Write32(addr, val); return; +    case 0x04000060: GPU.GPU3D.Write32(addr, val); return;      case 0x04000064: -    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 0x040000B0: DMAs[0]->SrcAddr = val; return; -    case 0x040000B4: DMAs[0]->DstAddr = val; return; -    case 0x040000B8: DMAs[0]->WriteCnt(val); return; -    case 0x040000BC: DMAs[1]->SrcAddr = val; return; -    case 0x040000C0: DMAs[1]->DstAddr = val; return; -    case 0x040000C4: DMAs[1]->WriteCnt(val); return; -    case 0x040000C8: DMAs[2]->SrcAddr = val; return; -    case 0x040000CC: DMAs[2]->DstAddr = val; return; -    case 0x040000D0: DMAs[2]->WriteCnt(val); return; -    case 0x040000D4: DMAs[3]->SrcAddr = val; return; -    case 0x040000D8: DMAs[3]->DstAddr = val; return; -    case 0x040000DC: DMAs[3]->WriteCnt(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 0x040000B0: DMAs[0].SrcAddr = val; return; +    case 0x040000B4: DMAs[0].DstAddr = val; return; +    case 0x040000B8: DMAs[0].WriteCnt(val); return; +    case 0x040000BC: DMAs[1].SrcAddr = val; return; +    case 0x040000C0: DMAs[1].DstAddr = val; return; +    case 0x040000C4: DMAs[1].WriteCnt(val); return; +    case 0x040000C8: DMAs[2].SrcAddr = val; return; +    case 0x040000CC: DMAs[2].DstAddr = val; return; +    case 0x040000D0: DMAs[2].WriteCnt(val); return; +    case 0x040000D4: DMAs[3].SrcAddr = val; return; +    case 0x040000D8: DMAs[3].DstAddr = val; return; +    case 0x040000DC: DMAs[3].WriteCnt(val); return;      case 0x040000E0: DMA9Fill[0] = val; return;      case 0x040000E4: DMA9Fill[1] = val; return; @@ -3686,7 +3439,7 @@ void ARM9IOWrite32(u32 addr, u32 val)      case 0x04000180:      case 0x04000184: -        ARM9IOWrite16(addr, val); +        NDS::ARM9IOWrite16(addr, val);          return;      case 0x04000188:          if (IPCFIFOCnt9 & 0x8000) @@ -3706,31 +3459,31 @@ void ARM9IOWrite32(u32 addr, u32 val)      case 0x040001A0:          if (!(ExMemCnt[0] & (1<<11)))          { -            NDSCartSlot->WriteSPICnt(val & 0xFFFF); -            NDSCartSlot->WriteSPIData((val >> 16) & 0xFF); +            NDSCartSlot.WriteSPICnt(val & 0xFFFF); +            NDSCartSlot.WriteSPIData((val >> 16) & 0xFF);          }          return;      case 0x040001A4:          if (!(ExMemCnt[0] & (1<<11))) -            NDSCartSlot->WriteROMCnt(val); +            NDSCartSlot.WriteROMCnt(val);          return;      case 0x040001A8:          if (!(ExMemCnt[0] & (1<<11)))          { -            NDSCartSlot->SetROMCommand(0, val & 0xFF); -            NDSCartSlot->SetROMCommand(1, (val >> 8) & 0xFF); -            NDSCartSlot->SetROMCommand(2, (val >> 16) & 0xFF); -            NDSCartSlot->SetROMCommand(3, val >> 24); +            NDSCartSlot.SetROMCommand(0, val & 0xFF); +            NDSCartSlot.SetROMCommand(1, (val >> 8) & 0xFF); +            NDSCartSlot.SetROMCommand(2, (val >> 16) & 0xFF); +            NDSCartSlot.SetROMCommand(3, val >> 24);          }          return;      case 0x040001AC:          if (!(ExMemCnt[0] & (1<<11)))          { -            NDSCartSlot->SetROMCommand(4, val & 0xFF); -            NDSCartSlot->SetROMCommand(5, (val >> 8) & 0xFF); -            NDSCartSlot->SetROMCommand(6, (val >> 16) & 0xFF); -            NDSCartSlot->SetROMCommand(7, val >> 24); +            NDSCartSlot.SetROMCommand(4, val & 0xFF); +            NDSCartSlot.SetROMCommand(5, (val >> 8) & 0xFF); +            NDSCartSlot.SetROMCommand(6, (val >> 16) & 0xFF); +            NDSCartSlot.SetROMCommand(7, val >> 24);          }          return; @@ -3739,23 +3492,23 @@ void ARM9IOWrite32(u32 addr, u32 val)      case 0x04000208: IME[0] = val & 0x1; UpdateIRQ(0); return;      case 0x04000210: IE[0] = val; UpdateIRQ(0); return; -    case 0x04000214: IF[0] &= ~val; GPU->GPU3D.CheckFIFOIRQ(); UpdateIRQ(0); return; +    case 0x04000214: IF[0] &= ~val; GPU.GPU3D.CheckFIFOIRQ(); UpdateIRQ(0); return;      case 0x04000240: -        GPU->MapVRAM_AB(0, val & 0xFF); -        GPU->MapVRAM_AB(1, (val >> 8) & 0xFF); -        GPU->MapVRAM_CD(2, (val >> 16) & 0xFF); -        GPU->MapVRAM_CD(3, val >> 24); +        GPU.MapVRAM_AB(0, val & 0xFF); +        GPU.MapVRAM_AB(1, (val >> 8) & 0xFF); +        GPU.MapVRAM_CD(2, (val >> 16) & 0xFF); +        GPU.MapVRAM_CD(3, val >> 24);          return;      case 0x04000244: -        GPU->MapVRAM_E(4, val & 0xFF); -        GPU->MapVRAM_FG(5, (val >> 8) & 0xFF); -        GPU->MapVRAM_FG(6, (val >> 16) & 0xFF); +        GPU.MapVRAM_E(4, val & 0xFF); +        GPU.MapVRAM_FG(5, (val >> 8) & 0xFF); +        GPU.MapVRAM_FG(6, (val >> 16) & 0xFF);          MapSharedWRAM(val >> 24);          return;      case 0x04000248: -        GPU->MapVRAM_H(7, val & 0xFF); -        GPU->MapVRAM_I(8, (val >> 8) & 0xFF); +        GPU.MapVRAM_H(7, val & 0xFF); +        GPU.MapVRAM_I(8, (val >> 8) & 0xFF);          return;      case 0x04000280: DivCnt = val; StartDiv(); return; @@ -3772,11 +3525,11 @@ void ARM9IOWrite32(u32 addr, u32 val)      case 0x04000304:          PowerControl9 = val & 0x820F; -        GPU->SetPowerCnt(PowerControl9); +        GPU.SetPowerCnt(PowerControl9);          return;      case 0x04100010: -        if (!(ExMemCnt[0] & (1<<11)))  NDSCartSlot->WriteROMData(val); +        if (!(ExMemCnt[0] & (1<<11)))  NDSCartSlot.WriteROMData(val);          return;      // NO$GBA debug register "String Out (raw)" @@ -3810,25 +3563,25 @@ 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)      { -        GPU->GPU3D.Write32(addr, val); +        GPU.GPU3D.Write32(addr, val);          return;      } -    Log(LogLevel::Debug, "unknown ARM9 IO write32 %08X %08X %08X\n", addr, val, ARM9->R[15]); +    Log(LogLevel::Debug, "unknown ARM9 IO write32 %08X %08X %08X\n", addr, val, ARM9.R[15]);  } -u8 ARM7IORead8(u32 addr) +u8 NDS::ARM7IORead8(u32 addr)  {      switch (addr)      { @@ -3841,51 +3594,51 @@ u8 ARM7IORead8(u32 addr)      case 0x04000136: return (KeyInput >> 16) & 0xFF;      case 0x04000137: return KeyInput >> 24; -    case 0x04000138: return RTC->Read() & 0xFF; +    case 0x04000138: return RTC.Read() & 0xFF;      case 0x040001A2:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->ReadSPIData(); +            return NDSCartSlot.ReadSPIData();          return 0;      case 0x040001A8:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(0); +            return NDSCartSlot.GetROMCommand(0);          return 0;      case 0x040001A9:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(1); +            return NDSCartSlot.GetROMCommand(1);          return 0;      case 0x040001AA:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(2); +            return NDSCartSlot.GetROMCommand(2);          return 0;      case 0x040001AB:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(3); +            return NDSCartSlot.GetROMCommand(3);          return 0;      case 0x040001AC:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(4); +            return NDSCartSlot.GetROMCommand(4);          return 0;      case 0x040001AD:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(5); +            return NDSCartSlot.GetROMCommand(5);          return 0;      case 0x040001AE:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(6); +            return NDSCartSlot.GetROMCommand(6);          return 0;      case 0x040001AF:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(7); +            return NDSCartSlot.GetROMCommand(7);          return 0; -    case 0x040001C2: return SPI->ReadData(); +    case 0x040001C2: return SPI.ReadData();      case 0x04000208: return IME[1]; -    case 0x04000240: return GPU->VRAMSTAT; +    case 0x04000240: return GPU.VRAMSTAT;      case 0x04000241: return WRAMCnt;      case 0x04000300: return PostFlag7; @@ -3894,29 +3647,29 @@ u8 ARM7IORead8(u32 addr)      if (addr >= 0x04000400 && addr < 0x04000520)      { -        return SPU->Read8(addr); +        return SPU.Read8(addr);      }      if ((addr & 0xFFFFF000) != 0x04004000) -        Log(LogLevel::Debug, "unknown ARM7 IO read8 %08X %08X\n", addr, ARM7->R[15]); +        Log(LogLevel::Debug, "unknown ARM7 IO read8 %08X %08X\n", addr, ARM7.R[15]);      return 0;  } -u16 ARM7IORead16(u32 addr) +u16 NDS::ARM7IORead16(u32 addr)  {      switch (addr)      { -    case 0x04000004: return GPU->DispStat[1]; -    case 0x04000006: return GPU->VCount; - -    case 0x040000B8: return DMAs[4]->Cnt & 0xFFFF; -    case 0x040000BA: return DMAs[4]->Cnt >> 16; -    case 0x040000C4: return DMAs[5]->Cnt & 0xFFFF; -    case 0x040000C6: return DMAs[5]->Cnt >> 16; -    case 0x040000D0: return DMAs[6]->Cnt & 0xFFFF; -    case 0x040000D2: return DMAs[6]->Cnt >> 16; -    case 0x040000DC: return DMAs[7]->Cnt & 0xFFFF; -    case 0x040000DE: return DMAs[7]->Cnt >> 16; +    case 0x04000004: return GPU.DispStat[1]; +    case 0x04000006: return GPU.VCount; + +    case 0x040000B8: return DMAs[4].Cnt & 0xFFFF; +    case 0x040000BA: return DMAs[4].Cnt >> 16; +    case 0x040000C4: return DMAs[5].Cnt & 0xFFFF; +    case 0x040000C6: return DMAs[5].Cnt >> 16; +    case 0x040000D0: return DMAs[6].Cnt & 0xFFFF; +    case 0x040000D2: return DMAs[6].Cnt >> 16; +    case 0x040000DC: return DMAs[7].Cnt & 0xFFFF; +    case 0x040000DE: return DMAs[7].Cnt >> 16;      case 0x04000100: return TimerGetCounter(4);      case 0x04000102: return Timers[4].Cnt; @@ -3932,7 +3685,7 @@ u16 ARM7IORead16(u32 addr)      case 0x04000134: return RCnt;      case 0x04000136: return KeyInput >> 16; -    case 0x04000138: return RTC->Read(); +    case 0x04000138: return RTC.Read();      case 0x04000180: return IPCSync7;      case 0x04000184: @@ -3945,32 +3698,32 @@ u16 ARM7IORead16(u32 addr)              return val;          } -    case 0x040001A0: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot->GetSPICnt();   return 0; -    case 0x040001A2: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot->ReadSPIData(); return 0; +    case 0x040001A0: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot.GetSPICnt();   return 0; +    case 0x040001A2: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot.ReadSPIData(); return 0;      case 0x040001A8:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(0) | -                  (NDSCartSlot->GetROMCommand(1) << 8); +            return NDSCartSlot.GetROMCommand(0) | +                  (NDSCartSlot.GetROMCommand(1) << 8);          return 0;      case 0x040001AA:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(2) | -                  (NDSCartSlot->GetROMCommand(3) << 8); +            return NDSCartSlot.GetROMCommand(2) | +                  (NDSCartSlot.GetROMCommand(3) << 8);          return 0;      case 0x040001AC:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(4) | -                  (NDSCartSlot->GetROMCommand(5) << 8); +            return NDSCartSlot.GetROMCommand(4) | +                  (NDSCartSlot.GetROMCommand(5) << 8);          return 0;      case 0x040001AE:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(6) | -                  (NDSCartSlot->GetROMCommand(7) << 8); +            return NDSCartSlot.GetROMCommand(6) | +                  (NDSCartSlot.GetROMCommand(7) << 8);          return 0; -    case 0x040001C0: return SPI->ReadCnt(); -    case 0x040001C2: return SPI->ReadData(); +    case 0x040001C0: return SPI.ReadCnt(); +    case 0x040001C2: return SPI.ReadData();      case 0x04000204: return ExMemCnt[1];      case 0x04000206: @@ -3988,32 +3741,32 @@ u16 ARM7IORead16(u32 addr)      if (addr >= 0x04000400 && addr < 0x04000520)      { -        return SPU->Read16(addr); +        return SPU.Read16(addr);      }      if ((addr & 0xFFFFF000) != 0x04004000) -        Log(LogLevel::Debug, "unknown ARM7 IO read16 %08X %08X\n", addr, ARM7->R[15]); +        Log(LogLevel::Debug, "unknown ARM7 IO read16 %08X %08X\n", addr, ARM7.R[15]);      return 0;  } -u32 ARM7IORead32(u32 addr) +u32 NDS::ARM7IORead32(u32 addr)  {      switch (addr)      { -    case 0x04000004: return GPU->DispStat[1] | (GPU->VCount << 16); - -    case 0x040000B0: return DMAs[4]->SrcAddr; -    case 0x040000B4: return DMAs[4]->DstAddr; -    case 0x040000B8: return DMAs[4]->Cnt; -    case 0x040000BC: return DMAs[5]->SrcAddr; -    case 0x040000C0: return DMAs[5]->DstAddr; -    case 0x040000C4: return DMAs[5]->Cnt; -    case 0x040000C8: return DMAs[6]->SrcAddr; -    case 0x040000CC: return DMAs[6]->DstAddr; -    case 0x040000D0: return DMAs[6]->Cnt; -    case 0x040000D4: return DMAs[7]->SrcAddr; -    case 0x040000D8: return DMAs[7]->DstAddr; -    case 0x040000DC: return DMAs[7]->Cnt; +    case 0x04000004: return GPU.DispStat[1] | (GPU.VCount << 16); + +    case 0x040000B0: return DMAs[4].SrcAddr; +    case 0x040000B4: return DMAs[4].DstAddr; +    case 0x040000B8: return DMAs[4].Cnt; +    case 0x040000BC: return DMAs[5].SrcAddr; +    case 0x040000C0: return DMAs[5].DstAddr; +    case 0x040000C4: return DMAs[5].Cnt; +    case 0x040000C8: return DMAs[6].SrcAddr; +    case 0x040000CC: return DMAs[6].DstAddr; +    case 0x040000D0: return DMAs[6].Cnt; +    case 0x040000D4: return DMAs[7].SrcAddr; +    case 0x040000D8: return DMAs[7].DstAddr; +    case 0x040000DC: return DMAs[7].Cnt;      case 0x04000100: return TimerGetCounter(4) | (Timers[4].Cnt << 16);      case 0x04000104: return TimerGetCounter(5) | (Timers[5].Cnt << 16); @@ -4022,37 +3775,37 @@ u32 ARM7IORead32(u32 addr)      case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt[1] << 16);      case 0x04000134: return RCnt | (KeyInput & 0xFFFF0000); -    case 0x04000138: return RTC->Read(); +    case 0x04000138: return RTC.Read();      case 0x04000180: return IPCSync7; -    case 0x04000184: return ARM7IORead16(addr); +    case 0x04000184: return NDS::ARM7IORead16(addr);      case 0x040001A0:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetSPICnt() | (NDSCartSlot->ReadSPIData() << 16); +            return NDSCartSlot.GetSPICnt() | (NDSCartSlot.ReadSPIData() << 16);          return 0;      case 0x040001A4:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCnt(); +            return NDSCartSlot.GetROMCnt();          return 0;      case 0x040001A8:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(0) | -                  (NDSCartSlot->GetROMCommand(1) << 8) | -                  (NDSCartSlot->GetROMCommand(2) << 16) | -                  (NDSCartSlot->GetROMCommand(3) << 24); +            return NDSCartSlot.GetROMCommand(0) | +                  (NDSCartSlot.GetROMCommand(1) << 8) | +                  (NDSCartSlot.GetROMCommand(2) << 16) | +                  (NDSCartSlot.GetROMCommand(3) << 24);          return 0;      case 0x040001AC:          if (ExMemCnt[0] & (1<<11)) -            return NDSCartSlot->GetROMCommand(4) | -                  (NDSCartSlot->GetROMCommand(5) << 8) | -                  (NDSCartSlot->GetROMCommand(6) << 16) | -                  (NDSCartSlot->GetROMCommand(7) << 24); +            return NDSCartSlot.GetROMCommand(4) | +                  (NDSCartSlot.GetROMCommand(5) << 8) | +                  (NDSCartSlot.GetROMCommand(6) << 16) | +                  (NDSCartSlot.GetROMCommand(7) << 24);          return 0;      case 0x040001C0: -        return SPI->ReadCnt() | (SPI->ReadData() << 16); +        return SPI.ReadCnt() | (SPI.ReadData() << 16);      case 0x04000208: return IME[1];      case 0x04000210: return IE[1]; @@ -4083,21 +3836,21 @@ u32 ARM7IORead32(u32 addr)              return IPCFIFO9.Peek();      case 0x04100010: -        if (ExMemCnt[0] & (1<<11)) return NDSCartSlot->ReadROMData(); +        if (ExMemCnt[0] & (1<<11)) return NDSCartSlot.ReadROMData();          return 0;      }      if (addr >= 0x04000400 && addr < 0x04000520)      { -        return SPU->Read32(addr); +        return SPU.Read32(addr);      }      if ((addr & 0xFFFFF000) != 0x04004000) -        Log(LogLevel::Debug, "unknown ARM7 IO read32 %08X %08X\n", addr, ARM7->R[15]); +        Log(LogLevel::Debug, "unknown ARM7 IO read32 %08X %08X\n", addr, ARM7.R[15]);      return 0;  } -void ARM7IOWrite8(u32 addr, u8 val) +void NDS::ARM7IOWrite8(u32 addr, u8 val)  {      switch (addr)      { @@ -4114,44 +3867,44 @@ void ARM7IOWrite8(u32 addr, u8 val)          RCnt = (RCnt & 0x00FF) | (val << 8);          return; -    case 0x04000138: RTC->Write(val, true); return; +    case 0x04000138: RTC.Write(val, true); return;      case 0x04000188: -        ARM7IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24)); +        NDS::ARM7IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24));          return;      case 0x040001A0:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0xFF00) | val); +            NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 0xFF00) | val);          }          return;      case 0x040001A1:          if (ExMemCnt[0] & (1<<11)) -            NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0x00FF) | (val << 8)); +            NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 0x00FF) | (val << 8));          return;      case 0x040001A2:          if (ExMemCnt[0] & (1<<11)) -            NDSCartSlot->WriteSPIData(val); +            NDSCartSlot.WriteSPIData(val);          return; -    case 0x040001A8: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(0, val); return; -    case 0x040001A9: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(1, val); return; -    case 0x040001AA: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(2, val); return; -    case 0x040001AB: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(3, val); return; -    case 0x040001AC: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(4, val); return; -    case 0x040001AD: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(5, val); return; -    case 0x040001AE: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(6, val); return; -    case 0x040001AF: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(7, val); return; +    case 0x040001A8: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(0, val); return; +    case 0x040001A9: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(1, val); return; +    case 0x040001AA: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(2, val); return; +    case 0x040001AB: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(3, val); return; +    case 0x040001AC: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(4, val); return; +    case 0x040001AD: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(5, val); return; +    case 0x040001AE: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(6, val); return; +    case 0x040001AF: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(7, val); return;      case 0x040001C2: -        SPI->WriteData(val); +        SPI.WriteData(val);          return;      case 0x04000208: IME[1] = val & 0x1; UpdateIRQ(1); return;      case 0x04000300: -        if (ARM7->R[15] >= 0x4000) +        if (ARM7.R[15] >= 0x4000)              return;          if (!(PostFlag7 & 0x01))              PostFlag7 = val & 0x01; @@ -4160,35 +3913,35 @@ void ARM7IOWrite8(u32 addr, u8 val)      case 0x04000301:          val &= 0xC0;          if      (val == 0x40) Stop(StopReason::GBAModeNotSupported); -        else if (val == 0x80) ARM7->Halt(1); +        else if (val == 0x80) ARM7.Halt(1);          else if (val == 0xC0) EnterSleepMode();          return;      }      if (addr >= 0x04000400 && addr < 0x04000520)      { -        SPU->Write8(addr, val); +        SPU.Write8(addr, val);          return;      } -    Log(LogLevel::Debug, "unknown ARM7 IO write8 %08X %02X %08X\n", addr, val, ARM7->R[15]); +    Log(LogLevel::Debug, "unknown ARM7 IO write8 %08X %02X %08X\n", addr, val, ARM7.R[15]);  } -void ARM7IOWrite16(u32 addr, u16 val) +void NDS::ARM7IOWrite16(u32 addr, u16 val)  {      switch (addr)      { -    case 0x04000004: GPU->SetDispStat(1, val); return; -    case 0x04000006: GPU->SetVCount(val); return; - -    case 0x040000B8: DMAs[4]->WriteCnt((DMAs[4]->Cnt & 0xFFFF0000) | val); return; -    case 0x040000BA: DMAs[4]->WriteCnt((DMAs[4]->Cnt & 0x0000FFFF) | (val << 16)); return; -    case 0x040000C4: DMAs[5]->WriteCnt((DMAs[5]->Cnt & 0xFFFF0000) | val); return; -    case 0x040000C6: DMAs[5]->WriteCnt((DMAs[5]->Cnt & 0x0000FFFF) | (val << 16)); return; -    case 0x040000D0: DMAs[6]->WriteCnt((DMAs[6]->Cnt & 0xFFFF0000) | val); return; -    case 0x040000D2: DMAs[6]->WriteCnt((DMAs[6]->Cnt & 0x0000FFFF) | (val << 16)); return; -    case 0x040000DC: DMAs[7]->WriteCnt((DMAs[7]->Cnt & 0xFFFF0000) | val); return; -    case 0x040000DE: DMAs[7]->WriteCnt((DMAs[7]->Cnt & 0x0000FFFF) | (val << 16)); return; +    case 0x04000004: GPU.SetDispStat(1, val); return; +    case 0x04000006: GPU.SetVCount(val); return; + +    case 0x040000B8: DMAs[4].WriteCnt((DMAs[4].Cnt & 0xFFFF0000) | val); return; +    case 0x040000BA: DMAs[4].WriteCnt((DMAs[4].Cnt & 0x0000FFFF) | (val << 16)); return; +    case 0x040000C4: DMAs[5].WriteCnt((DMAs[5].Cnt & 0xFFFF0000) | val); return; +    case 0x040000C6: DMAs[5].WriteCnt((DMAs[5].Cnt & 0x0000FFFF) | (val << 16)); return; +    case 0x040000D0: DMAs[6].WriteCnt((DMAs[6].Cnt & 0xFFFF0000) | val); return; +    case 0x040000D2: DMAs[6].WriteCnt((DMAs[6].Cnt & 0x0000FFFF) | (val << 16)); return; +    case 0x040000DC: DMAs[7].WriteCnt((DMAs[7].Cnt & 0xFFFF0000) | val); return; +    case 0x040000DE: DMAs[7].WriteCnt((DMAs[7].Cnt & 0x0000FFFF) | (val << 16)); return;      case 0x04000100: Timers[4].Reload = val; return;      case 0x04000102: TimerStart(4, val); return; @@ -4202,7 +3955,7 @@ void ARM7IOWrite16(u32 addr, u16 val)      case 0x04000132: KeyCnt[1] = val; return;      case 0x04000134: RCnt = val; return; -    case 0x04000138: RTC->Write(val, false); return; +    case 0x04000138: RTC.Write(val, false); return;      case 0x04000180:          IPCSync9 &= 0xFFF0; @@ -4228,44 +3981,44 @@ void ARM7IOWrite16(u32 addr, u16 val)          return;      case 0x04000188: -        ARM7IOWrite32(addr, val | (val << 16)); +        NDS::ARM7IOWrite32(addr, val | (val << 16));          return;      case 0x040001A0:          if (ExMemCnt[0] & (1<<11)) -            NDSCartSlot->WriteSPICnt(val); +            NDSCartSlot.WriteSPICnt(val);          return;      case 0x040001A2:          if (ExMemCnt[0] & (1<<11)) -            NDSCartSlot->WriteSPIData(val & 0xFF); +            NDSCartSlot.WriteSPIData(val & 0xFF);          return;      case 0x040001A8:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->SetROMCommand(0, val & 0xFF); -            NDSCartSlot->SetROMCommand(1, val >> 8); +            NDSCartSlot.SetROMCommand(0, val & 0xFF); +            NDSCartSlot.SetROMCommand(1, val >> 8);          }          return;      case 0x040001AA:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->SetROMCommand(2, val & 0xFF); -            NDSCartSlot->SetROMCommand(3, val >> 8); +            NDSCartSlot.SetROMCommand(2, val & 0xFF); +            NDSCartSlot.SetROMCommand(3, val >> 8);          }          return;      case 0x040001AC:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->SetROMCommand(4, val & 0xFF); -            NDSCartSlot->SetROMCommand(5, val >> 8); +            NDSCartSlot.SetROMCommand(4, val & 0xFF); +            NDSCartSlot.SetROMCommand(5, val >> 8);          }          return;      case 0x040001AE:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->SetROMCommand(6, val & 0xFF); -            NDSCartSlot->SetROMCommand(7, val >> 8); +            NDSCartSlot.SetROMCommand(6, val & 0xFF); +            NDSCartSlot.SetROMCommand(7, val >> 8);          }          return; @@ -4273,10 +4026,10 @@ void ARM7IOWrite16(u32 addr, u16 val)      case 0x040001BA: ROMSeed1[12] = val & 0x7F; return;      case 0x040001C0: -        SPI->WriteCnt(val); +        SPI.WriteCnt(val);          return;      case 0x040001C2: -        SPI->WriteData(val & 0xFF); +        SPI.WriteData(val & 0xFF);          return;      case 0x04000204: @@ -4298,7 +4051,7 @@ void ARM7IOWrite16(u32 addr, u16 val)      // TODO: what happens when writing to IF this way??      case 0x04000300: -        if (ARM7->R[15] >= 0x4000) +        if (ARM7.R[15] >= 0x4000)              return;          if (!(PostFlag7 & 0x01))              PostFlag7 = val & 0x01; @@ -4308,8 +4061,8 @@ void ARM7IOWrite16(u32 addr, u16 val)          {              u16 change = PowerControl7 ^ val;              PowerControl7 = val & 0x0003; -            SPU->SetPowerCnt(val & 0x0001); -            Wifi->SetPowerCnt(val & 0x0002); +            SPU.SetPowerCnt(val & 0x0001); +            Wifi.SetPowerCnt(val & 0x0002);              if (change & 0x0002) UpdateWifiTimings();          }          return; @@ -4322,34 +4075,34 @@ void ARM7IOWrite16(u32 addr, u16 val)      if (addr >= 0x04000400 && addr < 0x04000520)      { -        SPU->Write16(addr, val); +        SPU.Write16(addr, val);          return;      } -    Log(LogLevel::Debug, "unknown ARM7 IO write16 %08X %04X %08X\n", addr, val, ARM7->R[15]); +    Log(LogLevel::Debug, "unknown ARM7 IO write16 %08X %04X %08X\n", addr, val, ARM7.R[15]);  } -void ARM7IOWrite32(u32 addr, u32 val) +void NDS::ARM7IOWrite32(u32 addr, u32 val)  {      switch (addr)      {      case 0x04000004: -        GPU->SetDispStat(1, val & 0xFFFF); -        GPU->SetVCount(val >> 16); -        return; - -    case 0x040000B0: DMAs[4]->SrcAddr = val; return; -    case 0x040000B4: DMAs[4]->DstAddr = val; return; -    case 0x040000B8: DMAs[4]->WriteCnt(val); return; -    case 0x040000BC: DMAs[5]->SrcAddr = val; return; -    case 0x040000C0: DMAs[5]->DstAddr = val; return; -    case 0x040000C4: DMAs[5]->WriteCnt(val); return; -    case 0x040000C8: DMAs[6]->SrcAddr = val; return; -    case 0x040000CC: DMAs[6]->DstAddr = val; return; -    case 0x040000D0: DMAs[6]->WriteCnt(val); return; -    case 0x040000D4: DMAs[7]->SrcAddr = val; return; -    case 0x040000D8: DMAs[7]->DstAddr = val; return; -    case 0x040000DC: DMAs[7]->WriteCnt(val); return; +        GPU.SetDispStat(1, val & 0xFFFF); +        GPU.SetVCount(val >> 16); +        return; + +    case 0x040000B0: DMAs[4].SrcAddr = val; return; +    case 0x040000B4: DMAs[4].DstAddr = val; return; +    case 0x040000B8: DMAs[4].WriteCnt(val); return; +    case 0x040000BC: DMAs[5].SrcAddr = val; return; +    case 0x040000C0: DMAs[5].DstAddr = val; return; +    case 0x040000C4: DMAs[5].WriteCnt(val); return; +    case 0x040000C8: DMAs[6].SrcAddr = val; return; +    case 0x040000CC: DMAs[6].DstAddr = val; return; +    case 0x040000D0: DMAs[6].WriteCnt(val); return; +    case 0x040000D4: DMAs[7].SrcAddr = val; return; +    case 0x040000D8: DMAs[7].DstAddr = val; return; +    case 0x040000DC: DMAs[7].WriteCnt(val); return;      case 0x04000100:          Timers[4].Reload = val & 0xFFFF; @@ -4370,11 +4123,11 @@ void ARM7IOWrite32(u32 addr, u32 val)      case 0x04000130: KeyCnt[1] = val >> 16; return;      case 0x04000134: RCnt = val & 0xFFFF; return; -    case 0x04000138: RTC->Write(val & 0xFFFF, false); return; +    case 0x04000138: RTC.Write(val & 0xFFFF, false); return;      case 0x04000180:      case 0x04000184: -        ARM7IOWrite16(addr, val); +        NDS::ARM7IOWrite16(addr, val);          return;      case 0x04000188:          if (IPCFIFOCnt7 & 0x8000) @@ -4394,31 +4147,31 @@ void ARM7IOWrite32(u32 addr, u32 val)      case 0x040001A0:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->WriteSPICnt(val & 0xFFFF); -            NDSCartSlot->WriteSPIData((val >> 16) & 0xFF); +            NDSCartSlot.WriteSPICnt(val & 0xFFFF); +            NDSCartSlot.WriteSPIData((val >> 16) & 0xFF);          }          return;      case 0x040001A4:          if (ExMemCnt[0] & (1<<11)) -            NDSCartSlot->WriteROMCnt(val); +            NDSCartSlot.WriteROMCnt(val);          return;      case 0x040001A8:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->SetROMCommand(0, val & 0xFF); -            NDSCartSlot->SetROMCommand(1, (val >> 8) & 0xFF); -            NDSCartSlot->SetROMCommand(2, (val >> 16) & 0xFF); -            NDSCartSlot->SetROMCommand(3, val >> 24); +            NDSCartSlot.SetROMCommand(0, val & 0xFF); +            NDSCartSlot.SetROMCommand(1, (val >> 8) & 0xFF); +            NDSCartSlot.SetROMCommand(2, (val >> 16) & 0xFF); +            NDSCartSlot.SetROMCommand(3, val >> 24);          }          return;      case 0x040001AC:          if (ExMemCnt[0] & (1<<11))          { -            NDSCartSlot->SetROMCommand(4, val & 0xFF); -            NDSCartSlot->SetROMCommand(5, (val >> 8) & 0xFF); -            NDSCartSlot->SetROMCommand(6, (val >> 16) & 0xFF); -            NDSCartSlot->SetROMCommand(7, val >> 24); +            NDSCartSlot.SetROMCommand(4, val & 0xFF); +            NDSCartSlot.SetROMCommand(5, (val >> 8) & 0xFF); +            NDSCartSlot.SetROMCommand(6, (val >> 16) & 0xFF); +            NDSCartSlot.SetROMCommand(7, val >> 24);          }          return; @@ -4426,8 +4179,8 @@ void ARM7IOWrite32(u32 addr, u32 val)      case 0x040001B4: *(u32*)&ROMSeed1[8] = val; return;      case 0x040001C0: -        SPI->WriteCnt(val & 0xFFFF); -        SPI->WriteData((val >> 16) & 0xFF); +        SPI.WriteCnt(val & 0xFFFF); +        SPI.WriteData((val >> 16) & 0xFF);          return;      case 0x04000208: IME[1] = val & 0x1; UpdateIRQ(1); return; @@ -4438,8 +4191,8 @@ void ARM7IOWrite32(u32 addr, u32 val)          {              u16 change = PowerControl7 ^ val;              PowerControl7 = val & 0x0003; -            SPU->SetPowerCnt(val & 0x0001); -            Wifi->SetPowerCnt(val & 0x0002); +            SPU.SetPowerCnt(val & 0x0001); +            Wifi.SetPowerCnt(val & 0x0002);              if (change & 0x0002) UpdateWifiTimings();          }          return; @@ -4450,19 +4203,17 @@ void ARM7IOWrite32(u32 addr, u32 val)          return;      case 0x04100010: -        if (ExMemCnt[0] & (1<<11))  NDSCartSlot->WriteROMData(val); +        if (ExMemCnt[0] & (1<<11))  NDSCartSlot.WriteROMData(val);          return;      }      if (addr >= 0x04000400 && addr < 0x04000520)      { -        SPU->Write32(addr, val); +        SPU.Write32(addr, val);          return;      } -    Log(LogLevel::Debug, "unknown ARM7 IO write32 %08X %08X %08X\n", addr, val, ARM7->R[15]); -} - +    Log(LogLevel::Debug, "unknown ARM7 IO write32 %08X %08X %08X\n", addr, val, ARM7.R[15]);  }  }
\ No newline at end of file @@ -29,6 +29,14 @@  #include "types.h"  #include "NDSCart.h"  #include "GBACart.h" +#include "SPU.h" +#include "SPI.h" +#include "RTC.h" +#include "Wifi.h" +#include "AREngine.h" +#include "GPU.h" +#include "ARMJIT.h" +#include "DMA.h"  // when touching the main loop/timing code, pls test a lot of shit  // with this enabled, to make sure it doesn't desync @@ -36,17 +44,6 @@  namespace melonDS  { -class SPU; -class SPIHost; -class RTC; -class Wifi; - -class AREngine; -class GPU; -class ARMJIT; - -namespace NDS -{  enum  { @@ -75,7 +72,13 @@ enum  typedef std::function<void(u32)> EventFunc;  #define MemberEventFunc(cls,func) std::bind(&cls::func,this,std::placeholders::_1) - +struct SchedEvent +{ +    std::map<u32, EventFunc> Funcs; +    u64 Timestamp; +    u32 FuncID; +    u32 Param; +};  enum  {      IRQ_VBlank = 0, @@ -197,196 +200,274 @@ enum      // TODO: add DSi regions!  }; -struct MemRegion -{ -    u8* Mem; -    u32 Mask; -}; -  // supported GBA slot addon types  enum  {      GBAAddon_RAMExpansion = 1,  }; -#ifdef JIT_ENABLED -extern bool EnableJIT; -#endif -extern int ConsoleType; -extern int CurCPU; - -extern u8 ARM9MemTimings[0x40000][8]; -extern u32 ARM9Regions[0x40000]; -extern u8 ARM7MemTimings[0x20000][4]; -extern u32 ARM7Regions[0x20000]; - -extern u32 NumFrames; -extern u32 NumLagFrames; -extern bool LagFrameFlag; - -extern u64 ARM9Timestamp, ARM9Target; -extern u64 ARM7Timestamp, ARM7Target; -extern u32 ARM9ClockShift; - -extern u32 IME[2]; -extern u32 IE[2]; -extern u32 IF[2]; -extern u32 IE2; -extern u32 IF2; -extern Timer Timers[8]; - -extern u32 CPUStop; - -extern u16 PowerControl9; - -extern u16 ExMemCnt[2]; -extern u8 ROMSeed0[2*8]; -extern u8 ROMSeed1[2*8]; - -extern u8 ARM9BIOS[0x1000]; -extern u8 ARM7BIOS[0x4000]; -extern u16 ARM7BIOSProt; - -extern u8* MainRAM; -extern u32 MainRAMMask; - -const u32 MainRAMMaxSize = 0x1000000; - -const u32 SharedWRAMSize = 0x8000; -extern u8* SharedWRAM; - -extern MemRegion SWRAM_ARM9; -extern MemRegion SWRAM_ARM7; - -extern u32 KeyInput; -extern u16 RCnt; - -extern class SPU* SPU; -extern class SPIHost* SPI; -extern class RTC* RTC; -extern class Wifi* Wifi; -extern std::unique_ptr<NDSCart::NDSCartSlot> NDSCartSlot; -extern std::unique_ptr<GBACart::GBACartSlot> GBACartSlot; -extern std::unique_ptr<GPU> GPU; -extern std::unique_ptr<ARMJIT> JIT; -extern class AREngine* AREngine; - -const u32 ARM7WRAMSize = 0x10000; -extern u8* ARM7WRAM; - -bool Init(); -void DeInit(); -void Reset(); -void Start(); - -/// Stop the emulator. -void Stop(Platform::StopReason reason = Platform::StopReason::External); - -bool DoSavestate(Savestate* file); - -void SetARM9RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq); -void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq); - -// 0=DS  1=DSi -void SetConsoleType(int type); - -void LoadBIOS(); -bool IsLoadedARM9BIOSBuiltIn(); -bool IsLoadedARM7BIOSBuiltIn(); +class SPU; +class SPIHost; +class RTC; +class Wifi; -bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen); -void LoadSave(const u8* savedata, u32 savelen); -void EjectCart(); -bool CartInserted(); +class AREngine; +class GPU; +class ARMJIT; -bool NeedsDirectBoot(); -void SetupDirectBoot(const std::string& romname); +class NDS +{ +public: -bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen); -void LoadGBAAddon(int type); -void EjectGBACart(); +#ifdef JIT_ENABLED +    bool EnableJIT; +#endif +    int ConsoleType; +    int CurCPU; -u32 RunFrame(); +    SchedEvent SchedList[Event_MAX] {}; +    u8 ARM9MemTimings[0x40000][8]; +    u32 ARM9Regions[0x40000]; +    u8 ARM7MemTimings[0x20000][4]; +    u32 ARM7Regions[0x20000]; -void TouchScreen(u16 x, u16 y); -void ReleaseScreen(); +    u32 NumFrames; +    u32 NumLagFrames; +    bool LagFrameFlag; -void SetKeyMask(u32 mask); +    // no need to worry about those overflowing, they can keep going for atleast 4350 years +    u64 ARM9Timestamp, ARM9Target; +    u64 ARM7Timestamp, ARM7Target; +    u32 ARM9ClockShift; -bool IsLidClosed(); -void SetLidClosed(bool closed); +    u32 IME[2]; +    u32 IE[2]; +    u32 IF[2]; +    u32 IE2; +    u32 IF2; +    Timer Timers[8]; -void CamInputFrame(int cam, u32* data, int width, int height, bool rgb); -void MicInputFrame(s16* data, int samples); +    u32 CPUStop; -void RegisterEventFunc(u32 id, u32 funcid, EventFunc func); -void UnregisterEventFunc(u32 id, u32 funcid); -void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param); -void CancelEvent(u32 id); +    u16 PowerControl9; -void debug(u32 p); +    u16 ExMemCnt[2]; +    u8 ROMSeed0[2*8]; +    u8 ROMSeed1[2*8]; -void Halt(); +    u8 ARM9BIOS[0x1000]; +    u8 ARM7BIOS[0x4000]; +    u16 ARM7BIOSProt; -void MapSharedWRAM(u8 val); +    u8* MainRAM; +    u32 MainRAMMask; -void UpdateIRQ(u32 cpu); -void SetIRQ(u32 cpu, u32 irq); -void ClearIRQ(u32 cpu, u32 irq); -void SetIRQ2(u32 irq); -void ClearIRQ2(u32 irq); -bool HaltInterrupted(u32 cpu); -void StopCPU(u32 cpu, u32 mask); -void ResumeCPU(u32 cpu, u32 mask); -void GXFIFOStall(); -void GXFIFOUnstall(); +    const u32 MainRAMMaxSize = 0x1000000; -u32 GetPC(u32 cpu); -u64 GetSysClockCycles(int num); -void NocashPrint(u32 cpu, u32 addr); +    const u32 SharedWRAMSize = 0x8000; +    u8* SharedWRAM; -void MonitorARM9Jump(u32 addr); +    MemRegion SWRAM_ARM9; +    MemRegion SWRAM_ARM7; -bool DMAsInMode(u32 cpu, u32 mode); -bool DMAsRunning(u32 cpu); -void CheckDMAs(u32 cpu, u32 mode); -void StopDMAs(u32 cpu, u32 mode); +    u32 KeyInput; +    u16 RCnt; -void RunTimers(u32 cpu); +    // JIT MUST be declared before all other component objects, +    // as they'll need the memory that it allocates in its constructor! +    // (Reminder: C++ fields are initialized in the order they're declared, +    // regardless of what the constructor's initializer list says.) +    melonDS::ARMJIT JIT; +    ARMv5 ARM9; +    ARMv4 ARM7; +    melonDS::SPU SPU; +    SPIHost SPI; +    melonDS::RTC RTC; +    melonDS::Wifi Wifi; +    NDSCart::NDSCartSlot NDSCartSlot; +    GBACart::GBACartSlot GBACartSlot; +    melonDS::GPU GPU; +    melonDS::AREngine AREngine; -u8 ARM9Read8(u32 addr); -u16 ARM9Read16(u32 addr); -u32 ARM9Read32(u32 addr); -void ARM9Write8(u32 addr, u8 val); -void ARM9Write16(u32 addr, u16 val); -void ARM9Write32(u32 addr, u32 val); +    const u32 ARM7WRAMSize = 0x10000; +    u8* ARM7WRAM; -bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region); +    virtual void Reset(); +    void Start(); -u8 ARM7Read8(u32 addr); -u16 ARM7Read16(u32 addr); -u32 ARM7Read32(u32 addr); -void ARM7Write8(u32 addr, u8 val); -void ARM7Write16(u32 addr, u16 val); -void ARM7Write32(u32 addr, u32 val); +    /// Stop the emulator. +    virtual void Stop(Platform::StopReason reason = Platform::StopReason::External); -bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region); +    bool DoSavestate(Savestate* file); -u8 ARM9IORead8(u32 addr); -u16 ARM9IORead16(u32 addr); -u32 ARM9IORead32(u32 addr); -void ARM9IOWrite8(u32 addr, u8 val); -void ARM9IOWrite16(u32 addr, u16 val); -void ARM9IOWrite32(u32 addr, u32 val); +    void SetARM9RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq); +    void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq); -u8 ARM7IORead8(u32 addr); -u16 ARM7IORead16(u32 addr); -u32 ARM7IORead32(u32 addr); -void ARM7IOWrite8(u32 addr, u8 val); -void ARM7IOWrite16(u32 addr, u16 val); -void ARM7IOWrite32(u32 addr, u32 val); +    // 0=DS  1=DSi +    void SetConsoleType(int type); -} +    void LoadBIOS(); +    bool IsLoadedARM9BIOSBuiltIn(); +    bool IsLoadedARM7BIOSBuiltIn(); + +    virtual bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen); +    void LoadSave(const u8* savedata, u32 savelen); +    virtual void EjectCart(); +    bool CartInserted(); + +    virtual bool NeedsDirectBoot(); +    void SetupDirectBoot(const std::string& romname); +    virtual void SetupDirectBoot(); + +    bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen); +    void LoadGBAAddon(int type); +    void EjectGBACart(); + +    u32 RunFrame(); + +    bool IsRunning() const noexcept { return Running; } + +    void TouchScreen(u16 x, u16 y); +    void ReleaseScreen(); + +    void SetKeyMask(u32 mask); + +    bool IsLidClosed(); +    void SetLidClosed(bool closed); + +    virtual void CamInputFrame(int cam, u32* data, int width, int height, bool rgb) {} +    void MicInputFrame(s16* data, int samples); + +    void RegisterEventFunc(u32 id, u32 funcid, EventFunc func); +    void UnregisterEventFunc(u32 id, u32 funcid); +    void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param); +    void CancelEvent(u32 id); + +    void debug(u32 p); + +    void Halt(); + +    void MapSharedWRAM(u8 val); + +    void UpdateIRQ(u32 cpu); +    void SetIRQ(u32 cpu, u32 irq); +    void ClearIRQ(u32 cpu, u32 irq); +    void SetIRQ2(u32 irq); +    void ClearIRQ2(u32 irq); +    bool HaltInterrupted(u32 cpu); +    void StopCPU(u32 cpu, u32 mask); +    void ResumeCPU(u32 cpu, u32 mask); +    void GXFIFOStall(); +    void GXFIFOUnstall(); + +    u32 GetPC(u32 cpu); +    u64 GetSysClockCycles(int num); +    void NocashPrint(u32 cpu, u32 addr); + +    void MonitorARM9Jump(u32 addr); + +    virtual bool DMAsInMode(u32 cpu, u32 mode); +    virtual bool DMAsRunning(u32 cpu); +    virtual void CheckDMAs(u32 cpu, u32 mode); +    virtual void StopDMAs(u32 cpu, u32 mode); + +    void RunTimers(u32 cpu); + +    virtual u8 ARM9Read8(u32 addr); +    virtual u16 ARM9Read16(u32 addr); +    virtual u32 ARM9Read32(u32 addr); +    virtual void ARM9Write8(u32 addr, u8 val); +    virtual void ARM9Write16(u32 addr, u16 val); +    virtual void ARM9Write32(u32 addr, u32 val); + +    virtual bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region); + +    virtual u8 ARM7Read8(u32 addr); +    virtual u16 ARM7Read16(u32 addr); +    virtual u32 ARM7Read32(u32 addr); +    virtual void ARM7Write8(u32 addr, u8 val); +    virtual void ARM7Write16(u32 addr, u16 val); +    virtual void ARM7Write32(u32 addr, u32 val); + +    virtual bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region); + +    virtual u8 ARM9IORead8(u32 addr); +    virtual u16 ARM9IORead16(u32 addr); +    virtual u32 ARM9IORead32(u32 addr); +    virtual void ARM9IOWrite8(u32 addr, u8 val); +    virtual void ARM9IOWrite16(u32 addr, u16 val); +    virtual void ARM9IOWrite32(u32 addr, u32 val); + +    virtual u8 ARM7IORead8(u32 addr); +    virtual u16 ARM7IORead16(u32 addr); +    virtual u32 ARM7IORead32(u32 addr); +    virtual void ARM7IOWrite8(u32 addr, u8 val); +    virtual void ARM7IOWrite16(u32 addr, u16 val); +    virtual void ARM7IOWrite32(u32 addr, u32 val); + +private: +    void InitTimings(); +    u32 SchedListMask; +    u64 SysTimestamp; +    u8 WRAMCnt; +    u8 PostFlag9; +    u8 PostFlag7; +    u16 PowerControl7; +    u16 WifiWaitCnt; +    u8 TimerCheckMask[2]; +    u64 TimerTimestamp[2]; +    DMA DMAs[8]; +    u32 DMA9Fill[4]; +    u16 IPCSync9, IPCSync7; +    u16 IPCFIFOCnt9, IPCFIFOCnt7; +    FIFO<u32, 16> IPCFIFO9; // FIFO in which the ARM9 writes +    FIFO<u32, 16> IPCFIFO7; +    u16 DivCnt; +    u32 DivNumerator[2]; +    u32 DivDenominator[2]; +    u32 DivQuotient[2]; +    u32 DivRemainder[2]; +    u16 SqrtCnt; +    u32 SqrtVal[2]; +    u32 SqrtRes; +    u16 KeyCnt[2]; +    bool Running; +    bool RunningGame; +    u64 LastSysClockCycles; +    u64 FrameStartTimestamp; +    u64 NextTarget(); +    u64 NextTargetSleep(); +    void CheckKeyIRQ(u32 cpu, u32 oldkey, u32 newkey); +    void Reschedule(u64 target); +    void RunSystemSleep(u64 timestamp); +    void RunSystem(u64 timestamp); +    void HandleTimerOverflow(u32 tid); +    u16 TimerGetCounter(u32 timer); +    void TimerStart(u32 id, u16 cnt); +    void StartDiv(); +    void DivDone(u32 param); +    void SqrtDone(u32 param); +    void StartSqrt(); +    void RunTimer(u32 tid, s32 cycles); +    void UpdateWifiTimings(); +    void SetWifiWaitCnt(u16 val); +    void SetGBASlotTimings(); +    void EnterSleepMode(); +    template <bool EnableJIT> +    u32 RunFrame(); +public: +    NDS() noexcept : NDS(0) {} +    virtual ~NDS() noexcept; +    NDS(const NDS&) = delete; +    NDS& operator=(const NDS&) = delete; +    NDS(NDS&&) = delete; +    NDS& operator=(NDS&&) = delete; +    // The frontend should set and unset this manually after creating and destroying the NDS object. +    [[deprecated("Temporary workaround until JIT code generation is revised to accommodate multiple NDS objects.")]] static NDS* Current; +protected: +    explicit NDS(int type) noexcept; +    virtual void DoSavestateExtra(Savestate* file) {} +};  }  #endif // NDS_H diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 77262a7..95306fc 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -214,11 +214,11 @@ void CartCommon::Reset()      DSiMode = false;  } -void CartCommon::SetupDirectBoot(const std::string& romname) +void CartCommon::SetupDirectBoot(const std::string& romname, NDS& nds)  {      CmdEncMode = 2;      DataEncMode = 2; -    DSiMode = IsDSi && (NDS::ConsoleType==1); +    DSiMode = IsDSi && (nds.ConsoleType==1);  }  void CartCommon::DoSavestate(Savestate* file) @@ -238,7 +238,7 @@ void CartCommon::LoadSave(const u8* savedata, u32 savelen)  {  } -int CartCommon::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) +int CartCommon::ROMCommandStart(NDS& nds, NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len)  {      if (CmdEncMode == 0)      { @@ -267,15 +267,16 @@ int CartCommon::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* dat          case 0x3C:              CmdEncMode = 1; -            cartslot.Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2, NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS)); +            cartslot.Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2, nds.ARM7BIOS, sizeof(NDS::ARM7BIOS));              DSiMode = false;              return 0;          case 0x3D:              if (IsDSi)              { +                auto& dsi = static_cast<DSi&>(nds);                  CmdEncMode = 1; -                cartslot.Key1_InitKeycode(true, *(u32*)&ROM[0xC], 1, 2, DSi::ARM7iBIOS, sizeof(DSi::ARM7iBIOS)); +                cartslot.Key1_InitKeycode(true, *(u32*)&ROM[0xC], 1, 2, dsi.ARM7iBIOS, sizeof(DSi::ARM7iBIOS));                  DSiMode = true;              }              return 0; @@ -359,12 +360,6 @@ u8 CartCommon::SPIWrite(u8 val, u32 pos, bool last)      return 0xFF;  } -void CartCommon::SetIRQ() -{ -    NDS::SetIRQ(0, NDS::IRQ_CartIREQMC); -    NDS::SetIRQ(1, NDS::IRQ_CartIREQMC); -} -  u8 *CartCommon::GetSaveMemory() const  {      return nullptr; @@ -496,9 +491,9 @@ void CartRetail::LoadSave(const u8* savedata, u32 savelen)      Platform::WriteNDSSave(savedata, len, 0, len);  } -int CartRetail::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) +int CartRetail::ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len)  { -    if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cartslot, cmd, data, len); +    if (CmdEncMode != 2) return CartCommon::ROMCommandStart(nds, cartslot, cmd, data, len);      switch (cmd[0])      { @@ -519,7 +514,7 @@ int CartRetail::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* dat          return 0;      default: -        return CartCommon::ROMCommandStart(cartslot, cmd, data, len); +        return CartCommon::ROMCommandStart(nds, cartslot, cmd, data, len);      }  } @@ -900,9 +895,9 @@ void CartRetailNAND::LoadSave(const u8* savedata, u32 savelen)      BuildSRAMID();  } -int CartRetailNAND::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) +int CartRetailNAND::ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len)  { -    if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cartslot, cmd, data, len); +    if (CmdEncMode != 2) return CartCommon::ROMCommandStart(nds, cartslot, cmd, data, len);      switch (cmd[0])      { @@ -1032,7 +1027,7 @@ int CartRetailNAND::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8*          return 0;      default: -        return CartRetail::ROMCommandStart(cartslot, cmd, data, len); +        return CartRetail::ROMCommandStart(nds, cartslot, cmd, data, len);      }  } @@ -1152,7 +1147,7 @@ void CartRetailBT::DoSavestate(Savestate* file)  u8 CartRetailBT::SPIWrite(u8 val, u32 pos, bool last)  { -    Log(LogLevel::Debug,"POKETYPE SPI: %02X %d %d - %08X\n", val, pos, last, NDS::GetPC(0)); +    //Log(LogLevel::Debug,"POKETYPE SPI: %02X %d %d - %08X\n", val, pos, last, NDS::GetPC(0));      /*if (pos == 0)      { @@ -1210,9 +1205,9 @@ void CartHomebrew::Reset()          SD = nullptr;  } -void CartHomebrew::SetupDirectBoot(const std::string& romname) +void CartHomebrew::SetupDirectBoot(const std::string& romname, NDS& nds)  { -    CartCommon::SetupDirectBoot(romname); +    CartCommon::SetupDirectBoot(romname, nds);      if (SD)      { @@ -1231,17 +1226,17 @@ void CartHomebrew::SetupDirectBoot(const std::string& romname)          argvlen = strlen(argv);          const NDSHeader& header = GetHeader(); -        void (*writefn)(u32,u32) = (NDS::ConsoleType==1) ? DSi::ARM9Write32 : NDS::ARM9Write32;          u32 argvbase = header.ARM9RAMAddress + header.ARM9Size;          argvbase = (argvbase + 0xF) & ~0xF;          for (u32 i = 0; i <= argvlen; i+=4) -            writefn(argvbase+i, *(u32*)&argv[i]); +            nds.ARM9Write32(argvbase+i, *(u32*)&argv[i]); -        writefn(0x02FFFE70, 0x5F617267); -        writefn(0x02FFFE74, argvbase); -        writefn(0x02FFFE78, argvlen+1); +        nds.ARM9Write32(0x02FFFE70, 0x5F617267); +        nds.ARM9Write32(0x02FFFE74, argvbase); +        nds.ARM9Write32(0x02FFFE78, argvlen+1); +        // The DSi version of ARM9Write32 will be called if nds is really a DSi      }  } @@ -1250,9 +1245,9 @@ void CartHomebrew::DoSavestate(Savestate* file)      CartCommon::DoSavestate(file);  } -int CartHomebrew::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) +int CartHomebrew::ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len)  { -    if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cartslot, cmd, data, len); +    if (CmdEncMode != 2) return CartCommon::ROMCommandStart(nds, cartslot, cmd, data, len);      switch (cmd[0])      { @@ -1283,7 +1278,7 @@ int CartHomebrew::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* d          return 1;      default: -        return CartCommon::ROMCommandStart(cartslot, cmd, data, len); +        return CartCommon::ROMCommandStart(nds, cartslot, cmd, data, len);      }  } @@ -1449,19 +1444,19 @@ void CartHomebrew::ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset) -NDSCartSlot::NDSCartSlot() noexcept +NDSCartSlot::NDSCartSlot(melonDS::NDS& nds) noexcept : NDS(nds)  { -    NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_PrepareData, MemberEventFunc(NDSCartSlot, ROMPrepareData)); -    NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_End, MemberEventFunc(NDSCartSlot, ROMEndTransfer)); -    NDS::RegisterEventFunc(NDS::Event_ROMSPITransfer, 0, MemberEventFunc(NDSCartSlot, SPITransferDone)); +    NDS.RegisterEventFunc(Event_ROMTransfer, ROMTransfer_PrepareData, MemberEventFunc(NDSCartSlot, ROMPrepareData)); +    NDS.RegisterEventFunc(Event_ROMTransfer, ROMTransfer_End, MemberEventFunc(NDSCartSlot, ROMEndTransfer)); +    NDS.RegisterEventFunc(Event_ROMSPITransfer, 0, MemberEventFunc(NDSCartSlot, SPITransferDone));      // All fields are default-constructed because they're listed as such in the class declaration  }  NDSCartSlot::~NDSCartSlot() noexcept  { -    NDS::UnregisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_PrepareData); -    NDS::UnregisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_End); -    NDS::UnregisterEventFunc(NDS::Event_ROMSPITransfer, 0); +    NDS.UnregisterEventFunc(Event_ROMTransfer, ROMTransfer_PrepareData); +    NDS.UnregisterEventFunc(Event_ROMTransfer, ROMTransfer_End); +    NDS.UnregisterEventFunc(Event_ROMSPITransfer, 0);      // Cart is cleaned up automatically because it's a unique_ptr  } @@ -1574,10 +1569,10 @@ void NDSCartSlot::DecryptSecureArea(u8* out) noexcept      memcpy(out, &cartrom[arm9base], 0x800); -    Key1_InitKeycode(false, gamecode, 2, 2, NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS)); +    Key1_InitKeycode(false, gamecode, 2, 2, NDS.ARM7BIOS, sizeof(NDS::ARM7BIOS));      Key1_Decrypt((u32*)&out[0]); -    Key1_InitKeycode(false, gamecode, 3, 2, NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS)); +    Key1_InitKeycode(false, gamecode, 3, 2, NDS.ARM7BIOS, sizeof(NDS::ARM7BIOS));      for (u32 i = 0; i < 0x800; i += 8)          Key1_Decrypt((u32*)&out[i]); @@ -1744,11 +1739,11 @@ bool NDSCartSlot::InsertROM(std::unique_ptr<CartCommon>&& cart) noexcept              strncpy((char*)&cartrom[header.ARM9ROMOffset], "encryObj", 8); -            Key1_InitKeycode(false, romparams.GameCode, 3, 2, NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS)); +            Key1_InitKeycode(false, romparams.GameCode, 3, 2, NDS.ARM7BIOS, sizeof(NDS::ARM7BIOS));              for (u32 i = 0; i < 0x800; i += 8)                  Key1_Encrypt((u32*)&cartrom[header.ARM9ROMOffset + i]); -            Key1_InitKeycode(false, romparams.GameCode, 2, 2, NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS)); +            Key1_InitKeycode(false, romparams.GameCode, 2, 2, NDS.ARM7BIOS, sizeof(NDS::ARM7BIOS));              Key1_Encrypt((u32*)&cartrom[header.ARM9ROMOffset]);              Log(LogLevel::Debug, "Re-encrypted cart secure area\n"); @@ -1763,8 +1758,6 @@ bool NDSCartSlot::InsertROM(std::unique_ptr<CartCommon>&& cart) noexcept      Log(LogLevel::Info, "Inserted cart with ID: %08X\n", Cart->ID());      Log(LogLevel::Info, "ROM entry: %08X %08X\n", romparams.ROMSize, romparams.SaveMemType); -    DSi::SetCartInserted(true); -      return true;  } @@ -1784,7 +1777,7 @@ void NDSCartSlot::LoadSave(const u8* savedata, u32 savelen) noexcept  void NDSCartSlot::SetupDirectBoot(const std::string& romname) noexcept  {      if (Cart) -        Cart->SetupDirectBoot(romname); +        Cart->SetupDirectBoot(romname, NDS);  }  void NDSCartSlot::EjectCart() noexcept @@ -1792,13 +1785,11 @@ void NDSCartSlot::EjectCart() noexcept      if (!Cart) return;      // ejecting the cart triggers the gamecard IRQ -    NDS::SetIRQ(0, NDS::IRQ_CartIREQMC); -    NDS::SetIRQ(1, NDS::IRQ_CartIREQMC); +    NDS.SetIRQ(0, IRQ_CartIREQMC); +    NDS.SetIRQ(1, IRQ_CartIREQMC);      Cart = nullptr; -    DSi::SetCartInserted(false); -      // CHECKME: does an eject imply anything for the ROM/SPI transfer registers?  } @@ -1835,7 +1826,7 @@ void NDSCartSlot::ROMEndTransfer(u32 param) noexcept      ROMCnt &= ~(1<<31);      if (SPICnt & (1<<14)) -        NDS::SetIRQ((NDS::ExMemCnt[0]>>11)&0x1, NDS::IRQ_CartXferDone); +        NDS.SetIRQ((NDS.ExMemCnt[0]>>11)&0x1, IRQ_CartXferDone);      if (Cart)          Cart->ROMCommandFinish(TransferCmd.data(), TransferData.data(), TransferLen); @@ -1855,10 +1846,10 @@ void NDSCartSlot::ROMPrepareData(u32 param) noexcept      ROMCnt |= (1<<23); -    if (NDS::ExMemCnt[0] & (1<<11)) -        NDS::CheckDMAs(1, 0x12); +    if (NDS.ExMemCnt[0] & (1<<11)) +        NDS.CheckDMAs(1, 0x12);      else -        NDS::CheckDMAs(0, 0x05); +        NDS.CheckDMAs(0, 0x05);  }  void NDSCartSlot::WriteROMCnt(u32 val) noexcept @@ -1870,9 +1861,9 @@ void NDSCartSlot::WriteROMCnt(u32 val) noexcept      // a DS cart reader      if (val & (1<<15))      { -        u32 snum = (NDS::ExMemCnt[0]>>8)&0x8; -        u64 seed0 = *(u32*)&NDS::ROMSeed0[snum] | ((u64)NDS::ROMSeed0[snum+4] << 32); -        u64 seed1 = *(u32*)&NDS::ROMSeed1[snum] | ((u64)NDS::ROMSeed1[snum+4] << 32); +        u32 snum = (NDS.ExMemCnt[0]>>8)&0x8; +        u64 seed0 = *(u32*)&NDS.ROMSeed0[snum] | ((u64)NDS.ROMSeed0[snum+4] << 32); +        u64 seed1 = *(u32*)&NDS.ROMSeed1[snum] | ((u64)NDS.ROMSeed1[snum+4] << 32);          Key2_X = 0;          Key2_Y = 0; @@ -1919,7 +1910,7 @@ void NDSCartSlot::WriteROMCnt(u32 val) noexcept      TransferDir = 0;      if (Cart) -        TransferDir = Cart->ROMCommandStart(*this, TransferCmd.data(), TransferData.data(), TransferLen); +        TransferDir = Cart->ROMCommandStart(NDS, *this, TransferCmd.data(), TransferData.data(), TransferLen);      if ((datasize > 0) && (((ROMCnt >> 30) & 0x1) != TransferDir))          Log(LogLevel::Debug, "NDSCART: !! BAD TRANSFER DIRECTION FOR CMD %02X, DIR=%d, ROMCNT=%08X\n", ROMCommand[0], TransferDir, ROMCnt); @@ -1945,9 +1936,9 @@ void NDSCartSlot::WriteROMCnt(u32 val) noexcept      }      if (datasize == 0) -        NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*cmddelay, ROMTransfer_End, 0); +        NDS.ScheduleEvent(Event_ROMTransfer, false, xfercycle*cmddelay, ROMTransfer_End, 0);      else -        NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*(cmddelay+4), ROMTransfer_PrepareData, 0); +        NDS.ScheduleEvent(Event_ROMTransfer, false, xfercycle*(cmddelay+4), ROMTransfer_PrepareData, 0);  }  void NDSCartSlot::AdvanceROMTransfer() noexcept @@ -1964,7 +1955,7 @@ void NDSCartSlot::AdvanceROMTransfer() noexcept                  delay += ((ROMCnt >> 16) & 0x3F);          } -        NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*delay, ROMTransfer_PrepareData, 0); +        NDS.ScheduleEvent(Event_ROMTransfer, false, xfercycle*delay, ROMTransfer_PrepareData, 0);      }      else          ROMEndTransfer(0); @@ -2066,7 +2057,7 @@ void NDSCartSlot::WriteSPIData(u8 val) noexcept      // SPI transfers one bit per cycle -> 8 cycles per byte      u32 delay = 8 * (8 << (SPICnt & 0x3)); -    NDS::ScheduleEvent(NDS::Event_ROMSPITransfer, false, delay, 0, 0); +    NDS.ScheduleEvent(Event_ROMSPITransfer, false, delay, 0, 0);  }  } diff --git a/src/NDSCart.h b/src/NDSCart.h index 18d1fb6..24f9f9e 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -30,6 +30,10 @@  #include "FATStorage.h"  #include "ROMList.h" +namespace melonDS +{ +class NDS; +}  namespace melonDS::NDSCart  { @@ -56,14 +60,14 @@ public:      [[nodiscard]] u32 Checksum() const;      virtual void Reset(); -    virtual void SetupDirectBoot(const std::string& romname); +    virtual void SetupDirectBoot(const std::string& romname, NDS& nds);      virtual void DoSavestate(Savestate* file);      virtual void SetupSave(u32 type);      virtual void LoadSave(const u8* savedata, u32 savelen); -    virtual int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len); +    virtual int ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len);      virtual void ROMCommandFinish(u8* cmd, u8* data, u32 len);      virtual u8 SPIWrite(u8 val, u32 pos, bool last); @@ -83,8 +87,6 @@ public:  protected:      void ReadROM(u32 addr, u32 len, u8* data, u32 offset); -    void SetIRQ(); -      u8* ROM;      u32 ROMLength;      u32 ChipID; @@ -116,7 +118,7 @@ public:      virtual void SetupSave(u32 type) override;      virtual void LoadSave(const u8* savedata, u32 savelen) override; -    virtual int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override; +    virtual int ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override;      virtual u8 SPIWrite(u8 val, u32 pos, bool last) override; @@ -155,7 +157,7 @@ public:      void LoadSave(const u8* savedata, u32 savelen) override; -    int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override; +    int ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override;      void ROMCommandFinish(u8* cmd, u8* data, u32 len) override;      u8 SPIWrite(u8 val, u32 pos, bool last) override; @@ -216,11 +218,11 @@ public:      virtual u32 Type() const override { return CartType::Homebrew; }      void Reset() override; -    void SetupDirectBoot(const std::string& romname) override; +    void SetupDirectBoot(const std::string& romname, NDS& nds) override;      void DoSavestate(Savestate* file) override; -    int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override; +    int ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override;      void ROMCommandFinish(u8* cmd, u8* data, u32 len) override;  private: @@ -235,7 +237,7 @@ private:  class NDSCartSlot  {  public: -    NDSCartSlot() noexcept; +    NDSCartSlot(melonDS::NDS& nds) noexcept;      ~NDSCartSlot() noexcept;      void Reset() noexcept;      void ResetCart() noexcept; @@ -303,6 +305,7 @@ public:      void SetSPICnt(u16 val) noexcept { SPICnt = val; }  private:      friend class CartCommon; +    melonDS::NDS& NDS;      u16 SPICnt {};      u32 ROMCnt {};      std::array<u8, 8> ROMCommand {}; diff --git a/src/RTC.cpp b/src/RTC.cpp index 747348c..b5e497a 100644 --- a/src/RTC.cpp +++ b/src/RTC.cpp @@ -32,9 +32,9 @@ using Platform::LogLevel;  void WriteDateTime(int num, u8 val); -RTC::RTC() +RTC::RTC(melonDS::NDS& nds) : NDS(nds)  { -    NDS::RegisterEventFunc(NDS::Event_RTC, 0, MemberEventFunc(RTC, ClockTimer)); +    NDS.RegisterEventFunc(Event_RTC, 0, MemberEventFunc(RTC, ClockTimer));      ResetState(); @@ -45,7 +45,7 @@ RTC::RTC()  RTC::~RTC()  { -    NDS::UnregisterEventFunc(NDS::Event_RTC, 0); +    NDS.UnregisterEventFunc(Event_RTC, 0);  }  void RTC::Reset() @@ -221,10 +221,10 @@ void RTC::SetIRQ(u8 irq)      if ((!(oldstat & 0x30)) && (State.IRQFlag & 0x30))      { -        if ((NDS::RCnt & 0xC100) == 0x8100) +        if ((NDS.RCnt & 0xC100) == 0x8100)          {              // CHECKME: is the IRQ status readable in RCNT? -            NDS::SetIRQ(1, NDS::IRQ_RTC); +            NDS.SetIRQ(1, IRQ_RTC);          }      }  } @@ -306,7 +306,7 @@ void RTC::ProcessIRQ(int type) // 0=minute carry 1=periodic 2=status reg write              if (State.Alarm1[2] & (1<<7))                  cond = cond && ((State.Alarm1[2] & 0x7F) == State.DateTime[5]); -            if (NDS::ConsoleType == 1) +            if (NDS.ConsoleType == 1)              {                  if (State.AlarmDate1[1] & (1<<6))                      cond = cond && (State.AlarmDate1[0] == State.DateTime[0]); @@ -348,7 +348,7 @@ void RTC::ProcessIRQ(int type) // 0=minute carry 1=periodic 2=status reg write              if (State.Alarm2[2] & (1<<7))                  cond = cond && ((State.Alarm2[2] & 0x7F) == State.DateTime[5]); -            if (NDS::ConsoleType == 1) +            if (NDS.ConsoleType == 1)              {                  if (State.AlarmDate2[1] & (1<<6))                      cond = cond && (State.AlarmDate2[0] == State.DateTime[0]); @@ -520,7 +520,7 @@ void RTC::ScheduleTimer(bool first)      s32 delay = sysclock >> 15;      TimerError = sysclock & 0x7FFF; -    NDS::ScheduleEvent(NDS::Event_RTC, !first, delay, 0, 0); +    NDS.ScheduleEvent(Event_RTC, !first, delay, 0, 0);  }  void RTC::ClockTimer(u32 param) @@ -647,7 +647,7 @@ void RTC::CmdRead()      }      else if ((CurCmd & 0x0F) == 0x0E)      { -        if (NDS::ConsoleType != 1) +        if (NDS.ConsoleType != 1)          {              Log(LogLevel::Debug, "RTC: unknown read command %02X\n", CurCmd);              return; @@ -797,7 +797,7 @@ void RTC::CmdWrite(u8 val)      }      else if ((CurCmd & 0x0F) == 0x0E)      { -        if (NDS::ConsoleType != 1) +        if (NDS.ConsoleType != 1)          {              Log(LogLevel::Debug, "RTC: unknown write command %02X\n", CurCmd);              return; @@ -852,7 +852,7 @@ void RTC::ByteIn(u8 val)          else              CurCmd = val; -        if (NDS::ConsoleType == 1) +        if (NDS.ConsoleType == 1)          {              // for DSi: handle extra commands @@ -48,7 +48,7 @@ public:          u8 AlarmDate2[3];      }; -    RTC(); +    RTC(melonDS::NDS& nds);      ~RTC();      void Reset(); @@ -66,9 +66,7 @@ public:      void Write(u16 val, bool byte);  private: -    /// This value represents the Nintendo DS IO register, -    /// \em not the value of the system's clock. -    /// The actual system time is taken directly from the host. +    melonDS::NDS& NDS;      u16 IO;      u8 Input; diff --git a/src/SPI.cpp b/src/SPI.cpp index 3ded7bc..b3e5b4e 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -65,7 +65,7 @@ bool FirmwareMem::VerifyCRC16(u32 start, u32 offset, u32 len, u32 crcoffset)  } -FirmwareMem::FirmwareMem(SPIHost* host) : SPIDevice(host) +FirmwareMem::FirmwareMem(melonDS::NDS& nds) : SPIDevice(nds)  {  } @@ -79,7 +79,7 @@ void FirmwareMem::Reset()      if (!Firmware)      {          Log(LogLevel::Warn, "SPI firmware: no firmware loaded! Using default\n"); -        Firmware = std::make_unique<class Firmware>(NDS::ConsoleType); +        Firmware = std::make_unique<class Firmware>(NDS.ConsoleType);      }      // fix touchscreen coords @@ -134,31 +134,32 @@ void FirmwareMem::DoSavestate(Savestate* file)      file->Var32(&Addr);  } -void FirmwareMem::SetupDirectBoot(bool dsi) +void FirmwareMem::SetupDirectBoot()  {      const auto& header = Firmware->GetHeader();      const auto& userdata = Firmware->GetEffectiveUserData(); -    if (dsi) +    if (NDS.ConsoleType == 1)      { +        // The ARMWrite methods are virtual, they'll delegate to DSi if necessary          for (u32 i = 0; i < 6; i += 2) -            DSi::ARM9Write16(0x02FFFCF4, *(u16*)&header.MacAddr[i]); // MAC address +            NDS.ARM9Write16(0x02FFFCF4, *(u16*)&header.MacAddr[i]); // MAC address          // checkme -        DSi::ARM9Write16(0x02FFFCFA, header.EnabledChannels); // enabled channels +        NDS.ARM9Write16(0x02FFFCFA, header.EnabledChannels); // enabled channels          for (u32 i = 0; i < 0x70; i += 4) -            DSi::ARM9Write32(0x02FFFC80+i, *(u32*)&userdata.Bytes[i]); +            NDS.ARM9Write32(0x02FFFC80+i, *(u32*)&userdata.Bytes[i]);      }      else      { -        NDS::ARM9Write32(0x027FF864, 0); -        NDS::ARM9Write32(0x027FF868, header.UserSettingsOffset << 3); // user settings offset +        NDS.ARM9Write32(0x027FF864, 0); +        NDS.ARM9Write32(0x027FF868, header.UserSettingsOffset << 3); // user settings offset -        NDS::ARM9Write16(0x027FF874, header.DataGfxChecksum); // CRC16 for data/gfx -        NDS::ARM9Write16(0x027FF876, header.GUIWifiCodeChecksum); // CRC16 for GUI/wifi code +        NDS.ARM9Write16(0x027FF874, header.DataGfxChecksum); // CRC16 for data/gfx +        NDS.ARM9Write16(0x027FF876, header.GUIWifiCodeChecksum); // CRC16 for GUI/wifi code          for (u32 i = 0; i < 0x70; i += 4) -            NDS::ARM9Write32(0x027FFC80+i, *(u32*)&userdata.Bytes[i]); +            NDS.ARM9Write32(0x027FFC80+i, *(u32*)&userdata.Bytes[i]);      }  } @@ -326,7 +327,7 @@ void FirmwareMem::Release() -PowerMan::PowerMan(SPIHost* host) : SPIDevice(host) +PowerMan::PowerMan(melonDS::NDS& nds) : SPIDevice(nds)  {  } @@ -395,7 +396,7 @@ void PowerMan::Write(u8 val)              switch (regid)              {              case 0: -                if (val & 0x40) NDS::Stop(StopReason::PowerOff); // shutdown +                if (val & 0x40) NDS.Stop(StopReason::PowerOff); // shutdown                  //printf("power %02X\n", val);                  break;              case 4: @@ -410,7 +411,7 @@ void PowerMan::Write(u8 val) -TSC::TSC(SPIHost* host) : SPIDevice(host) +TSC::TSC(melonDS::NDS& nds) : SPIDevice(nds)  {  } @@ -452,13 +453,13 @@ void TSC::SetTouchCoords(u16 x, u16 y)      if (y == 0xFFF)      {          // released -        NDS::KeyInput |= (1 << (16+6)); +        NDS.KeyInput |= (1 << (16+6));          return;      }      TouchX <<= 4;      TouchY <<= 4; -    NDS::KeyInput &= ~(1 << (16+6)); +    NDS.KeyInput &= ~(1 << (16+6));  }  void TSC::MicInputFrame(s16* data, int samples) @@ -500,7 +501,7 @@ void TSC::Write(u8 val)                  else                  {                      // 560190 cycles per frame -                    u32 cyclepos = (u32)NDS::GetSysClockCycles(2); +                    u32 cyclepos = (u32)NDS.GetSysClockCycles(2);                      u32 samplepos = (cyclepos * MicBufferLen) / 560190;                      if (samplepos >= MicBufferLen) samplepos = MicBufferLen-1;                      s16 sample = MicBuffer[samplepos]; @@ -529,17 +530,17 @@ void TSC::Write(u8 val) -SPIHost::SPIHost() +SPIHost::SPIHost(melonDS::NDS& nds) : NDS(nds)  { -    NDS::RegisterEventFunc(NDS::Event_SPITransfer, 0, MemberEventFunc(SPIHost, TransferDone)); +    NDS.RegisterEventFunc(Event_SPITransfer, 0, MemberEventFunc(SPIHost, TransferDone)); -    Devices[SPIDevice_FirmwareMem] = new FirmwareMem(this); -    Devices[SPIDevice_PowerMan] = new PowerMan(this); +    Devices[SPIDevice_FirmwareMem] = new FirmwareMem(NDS); +    Devices[SPIDevice_PowerMan] = new PowerMan(NDS); -    if (NDS::ConsoleType == 1) -        Devices[SPIDevice_TSC] = new DSi_TSC(this); +    if (NDS.ConsoleType == 1) +        Devices[SPIDevice_TSC] = new DSi_TSC(static_cast<DSi&>(NDS));      else -        Devices[SPIDevice_TSC] = new TSC(this); +        Devices[SPIDevice_TSC] = new TSC(NDS);  }  SPIHost::~SPIHost() @@ -552,7 +553,7 @@ SPIHost::~SPIHost()          Devices[i] = nullptr;      } -    NDS::UnregisterEventFunc(NDS::Event_SPITransfer, 0); +    NDS.UnregisterEventFunc(Event_SPITransfer, 0);  }  void SPIHost::Reset() @@ -603,7 +604,7 @@ void SPIHost::TransferDone(u32 param)      Cnt &= ~(1<<7);      if (Cnt & (1<<14)) -        NDS::SetIRQ(1, NDS::IRQ_SPI); +        NDS.SetIRQ(1, IRQ_SPI);  }  u8 SPIHost::ReadData() @@ -641,7 +642,7 @@ void SPIHost::WriteData(u8 val)      // SPI transfers one bit per cycle -> 8 cycles per byte      u32 delay = 8 * (8 << (Cnt & 0x3)); -    NDS::ScheduleEvent(NDS::Event_SPITransfer, false, delay, 0, 0); +    NDS.ScheduleEvent(Event_SPITransfer, false, delay, 0, 0);  }  }
\ No newline at end of file @@ -42,11 +42,11 @@ enum  u16 CRC16(const u8* data, u32 len, u32 start);  class SPIHost; - +class NDS;  class SPIDevice  {  public: -    SPIDevice(SPIHost* host) : Host(host), Hold(false), DataPos(0) {} +    SPIDevice(melonDS::NDS& nds) : NDS(nds), Hold(false), DataPos(0) {}      virtual ~SPIDevice() {}      virtual void Reset() = 0;      virtual void DoSavestate(Savestate* file) = 0; @@ -56,7 +56,7 @@ public:      virtual void Release() { Hold = false; DataPos = 0; }  protected: -    SPIHost* Host; +    melonDS::NDS& NDS;      bool Hold;      u32 DataPos; @@ -66,12 +66,12 @@ protected:  class FirmwareMem : public SPIDevice  {  public: -    FirmwareMem(SPIHost* host); +    FirmwareMem(melonDS::NDS& nds);      ~FirmwareMem() override;      void Reset() override;      void DoSavestate(Savestate* file) override; -    void SetupDirectBoot(bool dsi); +    void SetupDirectBoot();      const class Firmware* GetFirmware();      bool IsLoadedFirmwareBuiltIn(); @@ -96,7 +96,7 @@ private:  class PowerMan : public SPIDevice  {  public: -    PowerMan(SPIHost* host); +    PowerMan(melonDS::NDS& nds);      ~PowerMan() override;      void Reset() override;      void DoSavestate(Savestate* file) override; @@ -116,7 +116,7 @@ private:  class TSC : public SPIDevice  {  public: -    TSC(SPIHost* host); +    TSC(melonDS::NDS& nds);      virtual ~TSC() override;      virtual void Reset() override;      virtual void DoSavestate(Savestate* file) override; @@ -141,7 +141,7 @@ protected:  class SPIHost  {  public: -    SPIHost(); +    SPIHost(melonDS::NDS& nds);      ~SPIHost();      void Reset();      void DoSavestate(Savestate* file); @@ -161,6 +161,7 @@ public:      void TransferDone(u32 param);  private: +    melonDS::NDS& NDS;      u16 Cnt;      SPIDevice* Devices[3]; diff --git a/src/SPU.cpp b/src/SPU.cpp index a5570d6..00db369 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -70,15 +70,15 @@ s16 SPUChannel::InterpCubic[0x100][4];  bool SPUChannel::InterpInited = false; -SPU::SPU() +SPU::SPU(melonDS::NDS& nds) : NDS(nds)  { -    NDS::RegisterEventFunc(NDS::Event_SPU, 0, MemberEventFunc(SPU, Mix)); +    NDS.RegisterEventFunc(Event_SPU, 0, MemberEventFunc(SPU, Mix));      for (int i = 0; i < 16; i++) -        Channels[i] = new SPUChannel(i); +        Channels[i] = new SPUChannel(i, NDS); -    Capture[0] = new SPUCaptureUnit(0); -    Capture[1] = new SPUCaptureUnit(1); +    Capture[0] = new SPUCaptureUnit(0, NDS); +    Capture[1] = new SPUCaptureUnit(1, NDS);      AudioLock = Platform::Mutex_Create(); @@ -137,7 +137,7 @@ SPU::~SPU()      Platform::Mutex_Free(AudioLock);      AudioLock = nullptr; -    NDS::UnregisterEventFunc(NDS::Event_SPU, 0); +    NDS.UnregisterEventFunc(Event_SPU, 0);  }  void SPU::Reset() @@ -154,7 +154,7 @@ void SPU::Reset()      Capture[0]->Reset();      Capture[1]->Reset(); -    NDS::ScheduleEvent(NDS::Event_SPU, false, 1024, 0, 0); +    NDS.ScheduleEvent(Event_SPU, false, 1024, 0, 0);  }  void SPU::Stop() @@ -212,7 +212,7 @@ void SPU::SetDegrade10Bit(bool enable)  } -SPUChannel::SPUChannel(u32 num) +SPUChannel::SPUChannel(u32 num, melonDS::NDS& nds) : NDS(nds)  {      Num = num; @@ -225,11 +225,6 @@ SPUChannel::~SPUChannel()  void SPUChannel::Reset()  { -    if (NDS::ConsoleType == 1) -        BusRead32 = DSi::ARM7Read32; -    else -        BusRead32 = NDS::ARM7Read32; -      KeyOn = false;      SetCnt(0); @@ -299,7 +294,7 @@ void SPUChannel::FIFO_BufferData()      {          for (u32 i = 0; i < burstlen; i += 4)          { -            FIFO[FIFOWritePos] = BusRead32(SrcAddr + FIFOReadOffset); +            FIFO[FIFOWritePos] = NDS.ARM7Read32(SrcAddr + FIFOReadOffset);              FIFOReadOffset += 4;              FIFOWritePos++;              FIFOWritePos &= 0x7; @@ -583,7 +578,7 @@ void SPUChannel::PanOutput(s32 in, s32& left, s32& right)  } -SPUCaptureUnit::SPUCaptureUnit(u32 num) +SPUCaptureUnit::SPUCaptureUnit(u32 num, melonDS::NDS& nds) : NDS(nds), Num(num)  {      Num = num;  } @@ -594,11 +589,6 @@ SPUCaptureUnit::~SPUCaptureUnit()  void SPUCaptureUnit::Reset()  { -    if (NDS::ConsoleType == 1) -        BusWrite32 = DSi::ARM7Write32; -    else -        BusWrite32 = NDS::ARM7Write32; -      SetCnt(0);      DstAddr = 0;      TimerReload = 0; @@ -634,7 +624,8 @@ void SPUCaptureUnit::FIFO_FlushData()  {      for (u32 i = 0; i < 4; i++)      { -        BusWrite32(DstAddr + FIFOWriteOffset, FIFO[FIFOReadPos]); +        NDS.ARM7Write32(DstAddr + FIFOWriteOffset, FIFO[FIFOReadPos]); +        // Calls the NDS or DSi version, depending on the class          FIFOReadPos++;          FIFOReadPos &= 0x3; @@ -858,7 +849,7 @@ void SPU::Mix(u32 dummy)          OutputBackbufferWritePosition += 2;      } -    NDS::ScheduleEvent(NDS::Event_SPU, true, 1024, 0, 0); +    NDS.ScheduleEvent(Event_SPU, true, 1024, 0, 0);  }  void SPU::TransferOutput() @@ -24,12 +24,13 @@  namespace melonDS  { +class NDS;  class SPU;  class SPUChannel  {  public: -    SPUChannel(u32 num); +    SPUChannel(u32 num, melonDS::NDS& nds);      ~SPUChannel();      void Reset();      void DoSavestate(Savestate* file); @@ -142,13 +143,13 @@ public:      void PanOutput(s32 in, s32& left, s32& right);  private: -    u32 (*BusRead32)(u32 addr); +    melonDS::NDS& NDS;  };  class SPUCaptureUnit  {  public: -    SPUCaptureUnit(u32 num); +    SPUCaptureUnit(u32 num, melonDS::NDS&);      ~SPUCaptureUnit();      void Reset();      void DoSavestate(Savestate* file); @@ -199,13 +200,13 @@ public:      void Run(s32 sample);  private: -    void (*BusWrite32)(u32 addr, u32 val); +    melonDS::NDS& NDS;  };  class SPU  {  public: -    SPU(); +    SPU(melonDS::NDS& nds);      ~SPU();      void Reset();      void DoSavestate(Savestate* file); @@ -240,6 +241,7 @@ public:  private:      static const u32 OutputBufferSize = 2*2048; +    melonDS::NDS& NDS;      s16 OutputBackbuffer[2 * OutputBufferSize];      u32 OutputBackbufferWritePosition; diff --git a/src/Wifi.cpp b/src/Wifi.cpp index 1441d1d..5027523 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -89,9 +89,9 @@ bool MACIsBroadcast(u8* a)  } -Wifi::Wifi() +Wifi::Wifi(melonDS::NDS& nds) : NDS(nds)  { -    NDS::RegisterEventFunc(NDS::Event_Wifi, 0, MemberEventFunc(Wifi, USTimer)); +    NDS.RegisterEventFunc(Event_Wifi, 0, MemberEventFunc(Wifi, USTimer));      //MPInited = false;      //LANInited = false; @@ -114,7 +114,7 @@ Wifi::~Wifi()      delete WifiAP; WifiAP = nullptr; -    NDS::UnregisterEventFunc(NDS::Event_Wifi, 0); +    NDS.UnregisterEventFunc(Event_Wifi, 0);  }  void Wifi::Reset() @@ -158,7 +158,7 @@ void Wifi::Reset()      }      #undef BBREG_FIXED -    const Firmware* fw = NDS::SPI->GetFirmware(); +    const Firmware* fw = NDS.SPI.GetFirmware();      RFVersion = fw->GetHeader().RFChipType;      memset(RFRegs, 0, 4*0x40); @@ -168,7 +168,7 @@ void Wifi::Reset()          IOPORT(0x000) = 0x1440;      else if (console == Firmware::FirmwareConsoleType::DSLite)          IOPORT(0x000) = 0xC340; -    else if (NDS::ConsoleType == 1 && console == Firmware::FirmwareConsoleType::DSi) +    else if (NDS.ConsoleType == 1 && console == Firmware::FirmwareConsoleType::DSi)          IOPORT(0x000) = 0xC340; // DSi has the modern DS-wifi variant      else      { @@ -303,14 +303,14 @@ void Wifi::ScheduleTimer(bool first)      s32 delay = (cycles + 999999) / 1000000;      TimerError = (delay * 1000000) - cycles; -    NDS::ScheduleEvent(NDS::Event_Wifi, !first, delay, 0, 0); +    NDS.ScheduleEvent(Event_Wifi, !first, delay, 0, 0);  }  void Wifi::UpdatePowerOn()  {      bool on = Enabled; -    if (NDS::ConsoleType == 1) +    if (NDS.ConsoleType == 1)      {          // TODO for DSi:          // * W_POWER_US doesn't work (atleast on DWM-W024) @@ -338,7 +338,7 @@ void Wifi::UpdatePowerOn()      {          Log(LogLevel::Debug, "WIFI: OFF\n"); -        NDS::CancelEvent(NDS::Event_Wifi); +        NDS.CancelEvent(Event_Wifi);          Platform::MP_End();      } @@ -359,7 +359,7 @@ void Wifi::SetIRQ(u32 irq)      u32 newflags = IOPORT(W_IF) & IOPORT(W_IE);      if ((oldflags == 0) && (newflags != 0)) -        NDS::SetIRQ(1, NDS::IRQ_Wifi); +        NDS.SetIRQ(1, IRQ_Wifi);  }  void Wifi::SetIRQ13() @@ -24,7 +24,7 @@  namespace melonDS  {  class WifiAP; - +class NDS;  class Wifi  {  public: @@ -157,7 +157,7 @@ public:          W_RXTXAddr = 0x268,      }; -    Wifi(); +    Wifi(melonDS::NDS& nds);      ~Wifi();      void Reset();      void DoSavestate(Savestate* file); @@ -173,6 +173,7 @@ public:      u8* GetBSSID();  private: +    melonDS::NDS& NDS;      u8 RAM[0x2000];      u16 IO[0x1000>>1]; diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 8d94b37..6f09d4b 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -24,6 +24,10 @@  #include <string>
  #include <vector>
 +namespace melonDS
 +{
 +class NDS;
 +}
  namespace Frontend
  {
  using namespace melonDS;
 @@ -105,14 +109,14 @@ int AudioOut_GetNumSamples(int outlen);  void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen, int volume);
  // feed silence to the microphone input
 -void Mic_FeedSilence();
 +void Mic_FeedSilence(NDS& nds);
  // feed random noise to the microphone input
 -void Mic_FeedNoise();
 +void Mic_FeedNoise(NDS& nds);
  // feed an external buffer to the microphone input
  // buffer should be mono
 -void Mic_FeedExternalBuffer();
 +void Mic_FeedExternalBuffer(NDS& nds);
  void Mic_SetExternalBuffer(s16* buffer, u32 len);
  }
 diff --git a/src/frontend/Util_Audio.cpp b/src/frontend/Util_Audio.cpp index 4a1d089..02b3026 100644 --- a/src/frontend/Util_Audio.cpp +++ b/src/frontend/Util_Audio.cpp @@ -82,13 +82,13 @@ void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen, int volum  } -void Mic_FeedSilence() +void Mic_FeedSilence(NDS& nds)  {      MicBufferReadPos = 0; -    NDS::MicInputFrame(NULL, 0); +    nds.MicInputFrame(NULL, 0);  } -void Mic_FeedNoise() +void Mic_FeedNoise(NDS& nds)  {      int sample_len = sizeof(mic_blow) / sizeof(u16);      static int sample_pos = 0; @@ -102,12 +102,12 @@ void Mic_FeedNoise()          if (sample_pos >= sample_len) sample_pos = 0;      } -    NDS::MicInputFrame(tmp, 735); +    nds.MicInputFrame(tmp, 735);  } -void Mic_FeedExternalBuffer() +void Mic_FeedExternalBuffer(NDS& nds)  { -    if (!MicBuffer) return Mic_FeedSilence(); +    if (!MicBuffer) return Mic_FeedSilence(nds);      if ((MicBufferReadPos + 735) > MicBufferLength)      { @@ -116,12 +116,12 @@ void Mic_FeedExternalBuffer()          memcpy(&tmp[0], &MicBuffer[MicBufferReadPos], len1*sizeof(s16));          memcpy(&tmp[len1], &MicBuffer[0], (735 - len1)*sizeof(s16)); -        NDS::MicInputFrame(tmp, 735); +        nds.MicInputFrame(tmp, 735);          MicBufferReadPos = 735 - len1;      }      else      { -        NDS::MicInputFrame(&MicBuffer[MicBufferReadPos], 735); +        nds.MicInputFrame(&MicBuffer[MicBufferReadPos], 735);          MicBufferReadPos += 735;      }  } diff --git a/src/frontend/qt_sdl/AudioInOut.cpp b/src/frontend/qt_sdl/AudioInOut.cpp index 90708b2..ae5529d 100644 --- a/src/frontend/qt_sdl/AudioInOut.cpp +++ b/src/frontend/qt_sdl/AudioInOut.cpp @@ -55,8 +55,9 @@ void AudioCallback(void* data, Uint8* stream, int len)      s16 buf_in[1024*2];      int num_in; +    EmuThread* emuThread = (EmuThread*)data;      SDL_LockMutex(audioSyncLock); -    num_in = NDS::SPU->ReadOutput(buf_in, len_in); +    num_in = emuThread->NDS->SPU.ReadOutput(buf_in, len_in);      SDL_CondSignal(audioSync);      SDL_UnlockMutex(audioSyncLock); @@ -244,7 +245,7 @@ void MicLoadWav(const std::string& name)      SDL_FreeWAV(buf);  } -void MicProcess() +void MicProcess(melonDS::NDS& nds)  {      int type = Config::MicInputType;      bool cmd = Input::HotkeyDown(HK_Mic); @@ -257,16 +258,16 @@ void MicProcess()      switch (type)      {      case micInputType_Silence: // no mic -        Frontend::Mic_FeedSilence(); +        Frontend::Mic_FeedSilence(nds);          break;      case micInputType_External: // host mic      case micInputType_Wav: // WAV -        Frontend::Mic_FeedExternalBuffer(); +        Frontend::Mic_FeedExternalBuffer(nds);          break;      case micInputType_Noise: // blowing noise -        Frontend::Mic_FeedNoise(); +        Frontend::Mic_FeedNoise(nds);          break;      }  } @@ -296,7 +297,7 @@ void SetupMicInputData()      }  } -void Init() +void Init(EmuThread* thread)  {      audioMuted = false;      audioSync = SDL_CreateCond(); @@ -310,6 +311,7 @@ void Init()      whatIwant.channels = 2;      whatIwant.samples = 1024;      whatIwant.callback = AudioCallback; +    whatIwant.userdata = thread;      audioDevice = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);      if (!audioDevice)      { @@ -349,12 +351,12 @@ void DeInit()      micWavBuffer = nullptr;  } -void AudioSync() +void AudioSync(NDS& nds)  {      if (audioDevice)      {          SDL_LockMutex(audioSyncLock); -        while (NDS::SPU->GetOutputSize() > 1024) +        while (nds.SPU.GetOutputSize() > 1024)          {              int ret = SDL_CondWaitTimeout(audioSync, audioSyncLock, 500);              if (ret == SDL_MUTEX_TIMEDOUT) break; @@ -363,11 +365,11 @@ void AudioSync()      }  } -void UpdateSettings() +void UpdateSettings(NDS& nds)  {      MicClose(); -    NDS::SPU->SetInterpolation(Config::AudioInterp); +    nds.SPU.SetInterpolation(Config::AudioInterp);      SetupMicInputData();      MicOpen(); diff --git a/src/frontend/qt_sdl/AudioInOut.h b/src/frontend/qt_sdl/AudioInOut.h index cc38625..0bf3654 100644 --- a/src/frontend/qt_sdl/AudioInOut.h +++ b/src/frontend/qt_sdl/AudioInOut.h @@ -23,18 +23,23 @@  #include <QMainWindow> +class EmuThread; +namespace melonDS +{ +class NDS; +}  namespace AudioInOut  { -void Init(); +void Init(EmuThread* thread);  void DeInit(); -void MicProcess(); +void MicProcess(melonDS::NDS& nds);  void AudioMute(QMainWindow* mainWindow); -void AudioSync(); +void AudioSync(melonDS::NDS& nds); -void UpdateSettings(); +void UpdateSettings(melonDS::NDS& nds);  void Enable();  void Disable(); diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.cpp b/src/frontend/qt_sdl/AudioSettingsDialog.cpp index cb42e64..5e8812e 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.cpp +++ b/src/frontend/qt_sdl/AudioSettingsDialog.cpp @@ -29,7 +29,7 @@  #include "AudioSettingsDialog.h"  #include "ui_AudioSettingsDialog.h" - +#include "main.h"  using namespace melonDS;  AudioSettingsDialog* AudioSettingsDialog::currentDlg = nullptr; @@ -37,7 +37,7 @@ AudioSettingsDialog* AudioSettingsDialog::currentDlg = nullptr;  extern std::string EmuDirectory; -AudioSettingsDialog::AudioSettingsDialog(QWidget* parent, bool emuActive) : QDialog(parent), ui(new Ui::AudioSettingsDialog) +AudioSettingsDialog::AudioSettingsDialog(QWidget* parent, bool emuActive, EmuThread* emuThread) : QDialog(parent), ui(new Ui::AudioSettingsDialog), emuThread(emuThread)  {      ui->setupUi(this);      setAttribute(Qt::WA_DeleteOnClose); @@ -65,7 +65,7 @@ AudioSettingsDialog::AudioSettingsDialog(QWidget* parent, bool emuActive) : QDia      ui->chkSyncDSiVolume->setChecked(Config::DSiVolumeSync);      // Setup volume slider accordingly -    if (emuActive && NDS::ConsoleType == 1) +    if (emuActive && emuThread->NDS->ConsoleType == 1)      {          on_chkSyncDSiVolume_clicked(Config::DSiVolumeSync);      } @@ -125,10 +125,11 @@ AudioSettingsDialog::~AudioSettingsDialog()  void AudioSettingsDialog::onSyncVolumeLevel()  { -    if (Config::DSiVolumeSync && NDS::ConsoleType == 1) +    if (Config::DSiVolumeSync && emuThread->NDS->ConsoleType == 1)      { +        auto& dsi = static_cast<DSi&>(*emuThread->NDS);          bool state = ui->slVolume->blockSignals(true); -        ui->slVolume->setValue(DSi::I2C->GetBPTWL()->GetVolumeLevel()); +        ui->slVolume->setValue(dsi.I2C.GetBPTWL()->GetVolumeLevel());          ui->slVolume->blockSignals(state);      }  } @@ -136,7 +137,7 @@ void AudioSettingsDialog::onSyncVolumeLevel()  void AudioSettingsDialog::onConsoleReset()  {      on_chkSyncDSiVolume_clicked(Config::DSiVolumeSync); -    ui->chkSyncDSiVolume->setEnabled(NDS::ConsoleType == 1); +    ui->chkSyncDSiVolume->setEnabled(emuThread->NDS->ConsoleType == 1);  }  void AudioSettingsDialog::on_AudioSettingsDialog_accepted() @@ -181,9 +182,10 @@ void AudioSettingsDialog::on_cbInterpolation_currentIndexChanged(int idx)  void AudioSettingsDialog::on_slVolume_valueChanged(int val)  { -    if (Config::DSiVolumeSync && NDS::ConsoleType == 1) +    if (Config::DSiVolumeSync && emuThread->NDS->ConsoleType == 1)      { -        DSi::I2C->GetBPTWL()->SetVolumeLevel(val); +        auto& dsi = static_cast<DSi&>(*emuThread->NDS); +        dsi.I2C.GetBPTWL()->SetVolumeLevel(val);          return;      } @@ -195,10 +197,11 @@ void AudioSettingsDialog::on_chkSyncDSiVolume_clicked(bool checked)      Config::DSiVolumeSync = checked;      bool state = ui->slVolume->blockSignals(true); -    if (Config::DSiVolumeSync && NDS::ConsoleType == 1) +    if (Config::DSiVolumeSync && emuThread->NDS->ConsoleType == 1)      { +        auto& dsi = static_cast<DSi&>(*emuThread->NDS);          ui->slVolume->setMaximum(31); -        ui->slVolume->setValue(DSi::I2C->GetBPTWL()->GetVolumeLevel()); +        ui->slVolume->setValue(dsi.I2C.GetBPTWL()->GetVolumeLevel());          ui->slVolume->setPageStep(4);          ui->slVolume->setTickPosition(QSlider::TicksBelow);      } diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.h b/src/frontend/qt_sdl/AudioSettingsDialog.h index 98060b2..ced9bae 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.h +++ b/src/frontend/qt_sdl/AudioSettingsDialog.h @@ -24,17 +24,18 @@  namespace Ui { class AudioSettingsDialog; }  class AudioSettingsDialog; +class EmuThread;  class AudioSettingsDialog : public QDialog  {      Q_OBJECT  public: -    explicit AudioSettingsDialog(QWidget* parent, bool emuActive); +    explicit AudioSettingsDialog(QWidget* parent, bool emuActive, EmuThread* emuThread);      ~AudioSettingsDialog();      static AudioSettingsDialog* currentDlg; -    static AudioSettingsDialog* openDlg(QWidget* parent, bool emuActive) +    static AudioSettingsDialog* openDlg(QWidget* parent, bool emuActive, EmuThread* emuThread)      {          if (currentDlg)          { @@ -42,7 +43,7 @@ public:              return currentDlg;          } -        currentDlg = new AudioSettingsDialog(parent, emuActive); +        currentDlg = new AudioSettingsDialog(parent, emuActive, emuThread);          currentDlg->show();          return currentDlg;      } @@ -69,6 +70,7 @@ private slots:      void on_btnMicWavBrowse_clicked();  private: +    EmuThread* emuThread;      Ui::AudioSettingsDialog* ui;      int oldInterp; diff --git a/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.cpp b/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.cpp index 14ccd51..3d47c45 100644 --- a/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.cpp +++ b/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.cpp @@ -29,45 +29,59 @@  #include "types.h"  #include <QtDebug> +#include "main.h"  using namespace melonDS;  PowerManagementDialog* PowerManagementDialog::currentDlg = nullptr; -PowerManagementDialog::PowerManagementDialog(QWidget* parent) : QDialog(parent), ui(new Ui::PowerManagementDialog) +PowerManagementDialog::PowerManagementDialog(QWidget* parent, EmuThread* emuThread) : QDialog(parent), emuThread(emuThread), ui(new Ui::PowerManagementDialog)  {      inited = false;      ui->setupUi(this);      setAttribute(Qt::WA_DeleteOnClose); -    if (NDS::ConsoleType == 1) +    if (emuThread->NDS->ConsoleType == 1)      {          ui->grpDSBattery->setEnabled(false); -        oldDSiBatteryLevel = DSi::I2C->GetBPTWL()->GetBatteryLevel(); -        oldDSiBatteryCharging = DSi::I2C->GetBPTWL()->GetBatteryCharging(); +        auto& dsi = static_cast<DSi&>(*emuThread->NDS); +        oldDSiBatteryLevel = dsi.I2C.GetBPTWL()->GetBatteryLevel(); +        oldDSiBatteryCharging = dsi.I2C.GetBPTWL()->GetBatteryCharging();      }      else      {          ui->grpDSiBattery->setEnabled(false); -        oldDSBatteryLevel = NDS::SPI->GetPowerMan()->GetBatteryLevelOkay(); +        oldDSBatteryLevel = emuThread->NDS->SPI.GetPowerMan()->GetBatteryLevelOkay();      }      updateDSBatteryLevelControls(); -    ui->cbDSiBatteryCharging->setChecked(DSi::I2C->GetBPTWL()->GetBatteryCharging()); -    int dsiBatterySliderPos; -    switch (DSi::I2C->GetBPTWL()->GetBatteryLevel()) +    bool defaultDSiBatteryCharging = (emuThread->NDS->ConsoleType == 1) ? Config::DSiBatteryCharging : false; + +    if (emuThread->NDS->ConsoleType == 1)      { +        auto& dsi = static_cast<DSi&>(*emuThread->NDS); +        ui->cbDSiBatteryCharging->setChecked(dsi.I2C.GetBPTWL()->GetBatteryCharging()); +        int dsiBatterySliderPos = 4; +        switch (dsi.I2C.GetBPTWL()->GetBatteryLevel()) +        {          case DSi_BPTWL::batteryLevel_AlmostEmpty:   dsiBatterySliderPos = 0; break;          case DSi_BPTWL::batteryLevel_Low:           dsiBatterySliderPos = 1; break;          case DSi_BPTWL::batteryLevel_Half:          dsiBatterySliderPos = 2; break;          case DSi_BPTWL::batteryLevel_ThreeQuarters: dsiBatterySliderPos = 3; break;          case DSi_BPTWL::batteryLevel_Full:          dsiBatterySliderPos = 4; break; +        } +        ui->sliderDSiBatteryLevel->setValue(dsiBatterySliderPos); +    } +    else +    { +        ui->cbDSiBatteryCharging->setChecked(Config::DSiBatteryCharging); +        ui->sliderDSiBatteryLevel->setValue(Config::DSiBatteryLevel);      } -    ui->sliderDSiBatteryLevel->setValue(dsiBatterySliderPos); +      int inst = Platform::InstanceID();      if (inst > 0) @@ -87,26 +101,28 @@ void PowerManagementDialog::done(int r)  {      if (r == QDialog::Accepted)      { -        if (NDS::ConsoleType == 1) +        if (emuThread->NDS->ConsoleType == 1)          { -            Config::DSiBatteryLevel = DSi::I2C->GetBPTWL()->GetBatteryLevel(); -            Config::DSiBatteryCharging = DSi::I2C->GetBPTWL()->GetBatteryCharging(); +            auto& dsi = static_cast<DSi&>(*emuThread->NDS); +            Config::DSiBatteryLevel = dsi.I2C.GetBPTWL()->GetBatteryLevel(); +            Config::DSiBatteryCharging = dsi.I2C.GetBPTWL()->GetBatteryCharging();          }          else          { -            Config::DSBatteryLevelOkay = NDS::SPI->GetPowerMan()->GetBatteryLevelOkay(); +            Config::DSBatteryLevelOkay = emuThread->NDS->SPI.GetPowerMan()->GetBatteryLevelOkay();          }      }      else      { -        if (NDS::ConsoleType == 1) +        if (emuThread->NDS->ConsoleType == 1)          { -            DSi::I2C->GetBPTWL()->SetBatteryLevel(oldDSiBatteryLevel); -            DSi::I2C->GetBPTWL()->SetBatteryCharging(oldDSiBatteryCharging); +            auto& dsi = static_cast<DSi&>(*emuThread->NDS); +            dsi.I2C.GetBPTWL()->SetBatteryLevel(oldDSiBatteryLevel); +            dsi.I2C.GetBPTWL()->SetBatteryCharging(oldDSiBatteryCharging);          }          else          { -            NDS::SPI->GetPowerMan()->SetBatteryLevelOkay(oldDSBatteryLevel); +            emuThread->NDS->SPI.GetPowerMan()->SetBatteryLevelOkay(oldDSBatteryLevel);          }      } @@ -117,17 +133,17 @@ void PowerManagementDialog::done(int r)  void PowerManagementDialog::on_rbDSBatteryLow_clicked()  { -    NDS::SPI->GetPowerMan()->SetBatteryLevelOkay(false); +    emuThread->NDS->SPI.GetPowerMan()->SetBatteryLevelOkay(false);  }  void PowerManagementDialog::on_rbDSBatteryOkay_clicked()  { -    NDS::SPI->GetPowerMan()->SetBatteryLevelOkay(true); +    emuThread->NDS->SPI.GetPowerMan()->SetBatteryLevelOkay(true);  }  void PowerManagementDialog::updateDSBatteryLevelControls()  { -    if (NDS::SPI->GetPowerMan()->GetBatteryLevelOkay()) +    if (emuThread->NDS->SPI.GetPowerMan()->GetBatteryLevelOkay())          ui->rbDSBatteryOkay->setChecked(true);      else          ui->rbDSBatteryLow->setChecked(true); @@ -135,23 +151,32 @@ void PowerManagementDialog::updateDSBatteryLevelControls()  void PowerManagementDialog::on_cbDSiBatteryCharging_toggled()  { -    DSi::I2C->GetBPTWL()->SetBatteryCharging(ui->cbDSiBatteryCharging->isChecked()); +    if (emuThread->NDS->ConsoleType == 1) +    { +        auto& dsi = static_cast<DSi&>(*emuThread->NDS); +        dsi.I2C.GetBPTWL()->SetBatteryCharging(ui->cbDSiBatteryCharging->isChecked()); +    }  }  void PowerManagementDialog::on_sliderDSiBatteryLevel_valueChanged(int value)  {      if (!inited) return; -    u8 newBatteryLevel; -    switch (value) +    if (emuThread->NDS->ConsoleType == 1)      { -        case 0: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_AlmostEmpty; break; -        case 1: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Low; break; -        case 2: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Half; break; -        case 3: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_ThreeQuarters; break; -        case 4: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Full; break; +        auto& dsi = static_cast<DSi&>(*emuThread->NDS); +        u8 newBatteryLevel = DSi_BPTWL::batteryLevel_Full; +        switch (value) +        { +        case 0: newBatteryLevel = DSi_BPTWL::batteryLevel_AlmostEmpty; break; +        case 1: newBatteryLevel = DSi_BPTWL::batteryLevel_Low; break; +        case 2: newBatteryLevel = DSi_BPTWL::batteryLevel_Half; break; +        case 3: newBatteryLevel = DSi_BPTWL::batteryLevel_ThreeQuarters; break; +        case 4: newBatteryLevel = DSi_BPTWL::batteryLevel_Full; break; +        } +        dsi.I2C.GetBPTWL()->SetBatteryLevel(newBatteryLevel);      } -    DSi::I2C->GetBPTWL()->SetBatteryLevel(newBatteryLevel); +      updateDSBatteryLevelControls();  } diff --git a/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.h b/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.h index cd2954a..bc2abc3 100644 --- a/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.h +++ b/src/frontend/qt_sdl/PowerManagement/PowerManagementDialog.h @@ -25,6 +25,7 @@  #include "types.h"  namespace Ui { class PowerManagementDialog; } +class EmuThread;  class PowerManagementDialog;  class PowerManagementDialog : public QDialog @@ -32,11 +33,11 @@ class PowerManagementDialog : public QDialog      Q_OBJECT  public: -    explicit PowerManagementDialog(QWidget* parent); +    explicit PowerManagementDialog(QWidget* parent, EmuThread* emu_thread);      ~PowerManagementDialog();      static PowerManagementDialog* currentDlg; -    static PowerManagementDialog* openDlg(QWidget* parent) +    static PowerManagementDialog* openDlg(QWidget* parent, EmuThread* emu_thread)      {          if (currentDlg)          { @@ -44,7 +45,7 @@ public:              return currentDlg;          } -        currentDlg = new PowerManagementDialog(parent); +        currentDlg = new PowerManagementDialog(parent, emu_thread);          currentDlg->open();          return currentDlg;      } @@ -64,6 +65,7 @@ private slots:  private:      Ui::PowerManagementDialog* ui; +    EmuThread* emuThread;      bool inited;      bool oldDSBatteryLevel; diff --git a/src/frontend/qt_sdl/RAMInfoDialog.cpp b/src/frontend/qt_sdl/RAMInfoDialog.cpp index b58662c..5bff99a 100644 --- a/src/frontend/qt_sdl/RAMInfoDialog.cpp +++ b/src/frontend/qt_sdl/RAMInfoDialog.cpp @@ -24,16 +24,16 @@  using namespace melonDS;  extern EmuThread* emuThread; -s32 GetMainRAMValue(const u32& addr, const ramInfo_ByteType& byteType) +s32 GetMainRAMValue(NDS& nds, const u32& addr, const ramInfo_ByteType& byteType)  {      switch (byteType)      {      case ramInfo_OneByte: -        return *(s8*)(NDS::MainRAM + (addr&NDS::MainRAMMask)); +        return *(s8*)(nds.MainRAM + (addr&nds.MainRAMMask));      case ramInfo_TwoBytes: -        return *(s16*)(NDS::MainRAM + (addr&NDS::MainRAMMask)); +        return *(s16*)(nds.MainRAM + (addr&nds.MainRAMMask));      case ramInfo_FourBytes: -        return *(s32*)(NDS::MainRAM + (addr&NDS::MainRAMMask)); +        return *(s32*)(nds.MainRAM + (addr&nds.MainRAMMask));      default:          return 0;      } @@ -41,7 +41,7 @@ s32 GetMainRAMValue(const u32& addr, const ramInfo_ByteType& byteType)  RAMInfoDialog* RAMInfoDialog::currentDlg = nullptr; -RAMInfoDialog::RAMInfoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::RAMInfoDialog) +RAMInfoDialog::RAMInfoDialog(QWidget* parent, EmuThread* emuThread) : QDialog(parent), emuThread(emuThread), ui(new Ui::RAMInfoDialog)  {      ui->setupUi(this);      setAttribute(Qt::WA_DeleteOnClose); @@ -91,7 +91,7 @@ void RAMInfoDialog::ShowRowsInTable()      for (u32 row = scrollValue; row < std::min<u32>(scrollValue+25, RowDataVector->size()); row++)      {          ramInfo_RowData& rowData = RowDataVector->at(row); -        rowData.Update(SearchThread->GetSearchByteType()); +        rowData.Update(*emuThread->NDS, SearchThread->GetSearchByteType());          if (ui->ramTable->item(row, ramInfo_Address) == nullptr)          { @@ -186,7 +186,7 @@ void RAMInfoDialog::on_ramTable_itemChanged(QTableWidgetItem *item)      s32 itemValue = item->text().toInt();      if (rowData.Value != itemValue) -        rowData.SetValue(itemValue); +        rowData.SetValue(*emuThread->NDS, itemValue);  }  /** @@ -241,14 +241,14 @@ void RAMSearchThread::run()      if (SearchMode == ramInfoSTh_SearchAll || RowDataVector->size() == 0)      {          // First search mode -        for (u32 addr = 0x02000000; SearchRunning && addr < 0x02000000+NDS::MainRAMMaxSize; addr += SearchByteType) +        for (u32 addr = 0x02000000; SearchRunning && addr < 0x02000000+MainRAMMaxSize; addr += SearchByteType)          { -            const s32& value = GetMainRAMValue(addr, SearchByteType); +            const s32& value = GetMainRAMValue(*emuThread->NDS, addr, SearchByteType);              RowDataVector->push_back({ addr, value, value });              // A solution to prevent to call too many slot. -            u32 newProgress = (int)((addr-0x02000000) / (NDS::MainRAMMaxSize-1.0f) * 100); +            u32 newProgress = (int)((addr-0x02000000) / (MainRAMMaxSize-1.0f) * 100);              if (progress < newProgress)              {                  progress = newProgress; @@ -264,7 +264,7 @@ void RAMSearchThread::run()          for (u32 row = 0; SearchRunning && row < RowDataVector->size(); row++)          {              const u32& addr = RowDataVector->at(row).Address; -            const s32& value = GetMainRAMValue(addr, SearchByteType); +            const s32& value = GetMainRAMValue(*emuThread->NDS, addr, SearchByteType);              if (SearchValue == value)                  newRowDataVector->push_back({ addr, value, value }); diff --git a/src/frontend/qt_sdl/RAMInfoDialog.h b/src/frontend/qt_sdl/RAMInfoDialog.h index adc9b28..2a5b162 100644 --- a/src/frontend/qt_sdl/RAMInfoDialog.h +++ b/src/frontend/qt_sdl/RAMInfoDialog.h @@ -32,6 +32,7 @@ namespace Ui { class RAMInfoDialog; }  class RAMInfoDialog;  class RAMSearchThread;  class RAMUpdateThread; +class EmuThread;  enum ramInfo_ByteType  { @@ -53,7 +54,7 @@ enum      ramInfo_Previous  }; -melonDS::s32 GetMainRAMValue(const melonDS::u32& addr, const ramInfo_ByteType& byteType); +melonDS::s32 GetMainRAMValue(melonDS::NDS& nds, const melonDS::u32& addr, const ramInfo_ByteType& byteType);  struct ramInfo_RowData  { @@ -61,14 +62,14 @@ struct ramInfo_RowData      melonDS::s32 Value;      melonDS::s32 Previous; -    void Update(const ramInfo_ByteType& byteType) +    void Update(melonDS::NDS& nds, const ramInfo_ByteType& byteType)      { -        Value = GetMainRAMValue(Address, byteType); +        Value = GetMainRAMValue(nds, Address, byteType);      } -    void SetValue(const melonDS::s32& value) +    void SetValue(melonDS::NDS& nds, const melonDS::s32& value)      { -        melonDS::NDS::MainRAM[Address&melonDS::NDS::MainRAMMask] = (melonDS::u32)value; +        nds.MainRAM[Address&nds.MainRAMMask] = (melonDS::u32)value;          Value = value;      }  }; @@ -78,11 +79,11 @@ class RAMInfoDialog : public QDialog      Q_OBJECT  public: -    explicit RAMInfoDialog(QWidget* parent); +    explicit RAMInfoDialog(QWidget* parent, EmuThread* emuThread);      ~RAMInfoDialog();      static RAMInfoDialog* currentDlg; -    static RAMInfoDialog* openDlg(QWidget* parent) +    static RAMInfoDialog* openDlg(QWidget* parent, EmuThread* emuThread)      {          if (currentDlg)          { @@ -90,7 +91,7 @@ public:              return currentDlg;          } -        currentDlg = new RAMInfoDialog(parent); +        currentDlg = new RAMInfoDialog(parent, emuThread);          currentDlg->show();          return currentDlg;      } @@ -118,6 +119,7 @@ private slots:      void SetProgressbarValue(const melonDS::u32& value);  private: +    EmuThread* emuThread;      Ui::RAMInfoDialog* ui;      RAMSearchThread* SearchThread; diff --git a/src/frontend/qt_sdl/ROMInfoDialog.cpp b/src/frontend/qt_sdl/ROMInfoDialog.cpp index 6a46b18..0f10b2f 100644 --- a/src/frontend/qt_sdl/ROMInfoDialog.cpp +++ b/src/frontend/qt_sdl/ROMInfoDialog.cpp @@ -42,14 +42,13 @@ QString QStringBytes(u64 num)  ROMInfoDialog* ROMInfoDialog::currentDlg = nullptr;
 -ROMInfoDialog::ROMInfoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ROMInfoDialog)
 +ROMInfoDialog::ROMInfoDialog(QWidget* parent, const melonDS::NDSCart::CartCommon& rom) : QDialog(parent), ui(new Ui::ROMInfoDialog)
  {
      ui->setupUi(this);
      setAttribute(Qt::WA_DeleteOnClose);
 -    const NDSBanner* banner = NDS::NDSCartSlot->GetCart()->Banner();
 -    const NDSHeader& header = NDS::NDSCartSlot->GetCart()->GetHeader();
 -
 +    const NDSBanner* banner = rom.Banner();
 +    const NDSHeader& header = rom.GetHeader();
      u32 iconData[32 * 32];
      ROMManager::ROMIcon(banner->Icon, banner->Palette, iconData);
      iconImage = QImage(reinterpret_cast<u8*>(iconData), 32, 32, QImage::Format_RGBA8888).copy();
 diff --git a/src/frontend/qt_sdl/ROMInfoDialog.h b/src/frontend/qt_sdl/ROMInfoDialog.h index 7316e98..f7e3b5f 100644 --- a/src/frontend/qt_sdl/ROMInfoDialog.h +++ b/src/frontend/qt_sdl/ROMInfoDialog.h @@ -29,17 +29,17 @@  namespace Ui { class ROMInfoDialog; }
  class ROMInfoDialog;
 -
 +namespace melonDS::NDSCart { class CartCommon; }
  class ROMInfoDialog : public QDialog
  {
      Q_OBJECT
  public:
 -    explicit ROMInfoDialog(QWidget* parent);
 +    explicit ROMInfoDialog(QWidget* parent, const melonDS::NDSCart::CartCommon& rom);
      ~ROMInfoDialog();
      static ROMInfoDialog* currentDlg;
 -    static ROMInfoDialog* openDlg(QWidget* parent)
 +    static ROMInfoDialog* openDlg(QWidget* parent, const melonDS::NDSCart::CartCommon& rom)
      {
          if (currentDlg)
          {
 @@ -47,7 +47,7 @@ public:              return currentDlg;
          }
 -        currentDlg = new ROMInfoDialog(parent);
 +        currentDlg = new ROMInfoDialog(parent, rom);
          currentDlg->open();
          return currentDlg;
      }
 diff --git a/src/frontend/qt_sdl/ROMManager.cpp b/src/frontend/qt_sdl/ROMManager.cpp index 9584c38..2c0cee2 100644 --- a/src/frontend/qt_sdl/ROMManager.cpp +++ b/src/frontend/qt_sdl/ROMManager.cpp @@ -44,6 +44,7 @@  #include "RTC.h"  #include "DSi_I2C.h"  #include "FreeBIOS.h" +#include "main.h"  using std::make_unique;  using std::pair; @@ -316,7 +317,7 @@ bool SavestateExists(int slot)      return Platform::FileExists(ssfile);  } -bool LoadState(const std::string& filename) +bool LoadState(NDS& nds, const std::string& filename)  {      FILE* file = fopen(filename.c_str(), "rb");      if (file == nullptr) @@ -333,7 +334,7 @@ bool LoadState(const std::string& filename)          return false;      } -    if (!NDS::DoSavestate(backup.get()) || backup->Error) +    if (!nds.DoSavestate(backup.get()) || backup->Error)      { // Back up the emulator's state. If that failed...          Platform::Log(Platform::LogLevel::Error, "Failed to back up state, aborting load (from \"%s\")\n", filename.c_str());          fclose(file); @@ -365,7 +366,7 @@ bool LoadState(const std::string& filename)      // Get ready to load the state from the buffer into the emulator      std::unique_ptr<Savestate> state = std::make_unique<Savestate>(buffer.data(), size, false); -    if (!NDS::DoSavestate(state.get()) || state->Error) +    if (!nds.DoSavestate(state.get()) || state->Error)      { // If we couldn't load the savestate from the buffer...          Platform::Log(Platform::LogLevel::Error, "Failed to load state file \"%s\" into emulator\n", filename.c_str());          return false; @@ -390,7 +391,7 @@ bool LoadState(const std::string& filename)      return true;  } -bool SaveState(const std::string& filename) +bool SaveState(NDS& nds, const std::string& filename)  {      FILE* file = fopen(filename.c_str(), "wb"); @@ -407,7 +408,7 @@ bool SaveState(const std::string& filename)      }      // Write the savestate to the in-memory buffer -    NDS::DoSavestate(&state); +    nds.DoSavestate(&state);      if (state.Error)      { @@ -439,7 +440,7 @@ bool SaveState(const std::string& filename)      return true;  } -void UndoStateLoad() +void UndoStateLoad(NDS& nds)  {      if (!SavestateLoaded || !BackupState) return; @@ -448,7 +449,7 @@ void UndoStateLoad()      // pray that this works      // what do we do if it doesn't???      // but it should work. -    NDS::DoSavestate(BackupState.get()); +    nds.DoSavestate(BackupState.get());      if (NDSSave && (!PreviousSaveFile.empty()))      { @@ -457,36 +458,264 @@ void UndoStateLoad()  } -void UnloadCheats() +void UnloadCheats(NDS& nds)  {      if (CheatFile)      {          delete CheatFile;          CheatFile = nullptr; -        NDS::AREngine->SetCodeFile(nullptr); +        nds.AREngine.SetCodeFile(nullptr);      }  } -void LoadCheats() +void LoadCheats(NDS& nds)  { -    UnloadCheats(); +    UnloadCheats(nds);      std::string filename = GetAssetPath(false, Config::CheatFilePath, ".mch");      // TODO: check for error (malformed cheat file, ...)      CheatFile = new ARCodeFile(filename); -    NDS::AREngine->SetCodeFile(CheatsOn ? CheatFile : nullptr); +    nds.AREngine.SetCodeFile(CheatsOn ? CheatFile : nullptr);  } -void LoadBIOSFiles() +std::optional<std::array<u8, ARM9BIOSSize>> LoadARM9BIOS() noexcept +{ +    if (FileHandle* f = OpenLocalFile(Config::BIOS9Path, Read)) +    { +        std::array<u8, ARM9BIOSSize> bios {}; +        FileRewind(f); +        FileRead(bios.data(), sizeof(bios), 1, f); +        CloseFile(f); +        Log(Info, "ARM9 BIOS loaded from %s\n", Config::BIOS9Path.c_str()); +        return bios; +    } + +    Log(Warn, "ARM9 BIOS not found\n"); +    return std::nullopt; +} + +std::optional<std::array<u8, ARM7BIOSSize>> LoadARM7BIOS() noexcept +{ +    if (FileHandle* f = OpenLocalFile(Config::BIOS7Path, Read)) +    { +        std::array<u8, ARM7BIOSSize> bios {}; +        FileRead(bios.data(), sizeof(bios), 1, f); +        CloseFile(f); +        Log(Info, "ARM7 BIOS loaded from %s\n", Config::BIOS7Path.c_str()); +        return bios; +    } + +    Log(Warn, "ARM7 BIOS not found\n"); +    return std::nullopt; +} + +std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM9BIOS() noexcept +{ +    if (FileHandle* f = OpenLocalFile(Config::DSiBIOS9Path, Read)) +    { +        std::array<u8, DSiBIOSSize> bios {}; +        FileRead(bios.data(), sizeof(bios), 1, f); +        CloseFile(f); +        Log(Info, "ARM9i BIOS loaded from %s\n", Config::DSiBIOS9Path.c_str()); +        return bios; +    } + +    Log(Warn, "ARM9i BIOS not found\n"); +    return std::nullopt; +} + +std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM7BIOS() noexcept +{ +    if (FileHandle* f = OpenLocalFile(Config::DSiBIOS7Path, Read)) +    { +        std::array<u8, DSiBIOSSize> bios {}; +        FileRead(bios.data(), sizeof(bios), 1, f); +        CloseFile(f); +        Log(Info, "ARM7i BIOS loaded from %s\n", Config::DSiBIOS7Path.c_str()); +        return bios; +    } + +    Log(Warn, "ARM7i BIOS not found\n"); +    return std::nullopt; +} + +Firmware GenerateFirmware(int type) noexcept +{ +    // Construct the default firmware... +    string settingspath; +    Firmware firmware = Firmware(type); +    assert(firmware.Buffer() != nullptr); + +    // If using generated firmware, we keep the wi-fi settings on the host disk separately. +    // Wi-fi access point data includes Nintendo WFC settings, +    // and if we didn't keep them then the player would have to reset them in each session. +    // We don't need to save the whole firmware, just the part that may actually change. +    if (FileHandle* f = OpenLocalFile(Config::WifiSettingsPath, Read)) +    {// If we have Wi-fi settings to load... +        constexpr unsigned TOTAL_WFC_SETTINGS_SIZE = 3 * (sizeof(Firmware::WifiAccessPoint) + sizeof(Firmware::ExtendedWifiAccessPoint)); + +        if (!FileRead(firmware.GetExtendedAccessPointPosition(), TOTAL_WFC_SETTINGS_SIZE, 1, f)) +        { // If we couldn't read the Wi-fi settings from this file... +            Log(Warn, "Failed to read Wi-fi settings from \"%s\"; using defaults instead\n", Config::WifiSettingsPath.c_str()); + +            // The access point and extended access point segments might +            // be in different locations depending on the firmware revision, +            // but our generated firmware always keeps them next to each other. +            // (Extended access points first, then regular ones.) +            firmware.GetAccessPoints() = { +                Firmware::WifiAccessPoint(type), +                Firmware::WifiAccessPoint(), +                Firmware::WifiAccessPoint(), +            }; + +            firmware.GetExtendedAccessPoints() = { +                Firmware::ExtendedWifiAccessPoint(), +                Firmware::ExtendedWifiAccessPoint(), +                Firmware::ExtendedWifiAccessPoint(), +            }; +            firmware.UpdateChecksums(); +            CloseFile(f); +        } +    } + +    CustomizeFirmware(firmware); + +    // If we don't have Wi-fi settings to load, +    // then the defaults will have already been populated by the constructor. +    return firmware; +} + +std::optional<Firmware> LoadFirmware(int type) noexcept +{ +    const string& firmwarepath = type == 1 ? Config::DSiFirmwarePath : Config::FirmwarePath; + +    Log(Debug, "SPI firmware: loading from file %s\n", firmwarepath.c_str()); + +    FileHandle* file = OpenLocalFile(firmwarepath, Read); + +    if (!file) +    { +        Log(Error, "SPI firmware: couldn't open firmware file!\n"); +        return std::nullopt; +    } +    Firmware firmware(file); +    CloseFile(file); + +    if (!firmware.Buffer()) +    { +        Log(Error, "SPI firmware: couldn't read firmware file!\n"); +        return std::nullopt; +    } + +    CustomizeFirmware(firmware); + +    return firmware; +} + + +std::optional<DSi_NAND::NANDImage> LoadNAND(const std::array<u8, DSiBIOSSize>& arm7ibios) noexcept +{ +    FileHandle* nandfile = OpenLocalFile(Config::DSiNANDPath, ReadWriteExisting); +    if (!nandfile) +        return std::nullopt; + +    DSi_NAND::NANDImage nandImage(nandfile, &arm7ibios[0x8308]); +    if (!nandImage) +    { +        Log(Error, "Failed to parse DSi NAND\n"); +        return std::nullopt; +        // the NANDImage takes ownership of the FileHandle, no need to clean it up here +    } + +    // scoped so that mount isn't alive when we move the NAND image to DSi::NANDImage +    { +        auto mount = DSi_NAND::NANDMount(nandImage); +        if (!mount) +        { +            Log(Error, "Failed to mount DSi NAND\n"); +            return std::nullopt; +        } + +        DSi_NAND::DSiFirmwareSystemSettings settings {}; +        if (!mount.ReadUserData(settings)) +        { +            Log(Error, "Failed to read DSi NAND user data\n"); +            return std::nullopt; +        } + +        // override user settings, if needed +        if (Config::FirmwareOverrideSettings) +        { +            // we store relevant strings as UTF-8, so we need to convert them to UTF-16 +            auto converter = wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}; + +            // setting up username +            std::u16string username = converter.from_bytes(Config::FirmwareUsername); +            size_t usernameLength = std::min(username.length(), (size_t) 10); +            memset(&settings.Nickname, 0, sizeof(settings.Nickname)); +            memcpy(&settings.Nickname, username.data(), usernameLength * sizeof(char16_t)); + +            // setting language +            settings.Language = static_cast<Firmware::Language>(Config::FirmwareLanguage); + +            // setting up color +            settings.FavoriteColor = Config::FirmwareFavouriteColour; + +            // setting up birthday +            settings.BirthdayMonth = Config::FirmwareBirthdayMonth; +            settings.BirthdayDay = Config::FirmwareBirthdayDay; + +            // setup message +            std::u16string message = converter.from_bytes(Config::FirmwareMessage); +            size_t messageLength = std::min(message.length(), (size_t) 26); +            memset(&settings.Message, 0, sizeof(settings.Message)); +            memcpy(&settings.Message, message.data(), messageLength * sizeof(char16_t)); + +            // TODO: make other items configurable? +        } + +        // fix touchscreen coords +        settings.TouchCalibrationADC1 = {0, 0}; +        settings.TouchCalibrationPixel1 = {0, 0}; +        settings.TouchCalibrationADC2 = {255 << 4, 191 << 4}; +        settings.TouchCalibrationPixel2 = {255, 191}; + +        settings.UpdateHash(); + +        if (!mount.ApplyUserData(settings)) +        { +            Log(LogLevel::Error, "Failed to write patched DSi NAND user data\n"); +            return std::nullopt; +        } +    } + +    return nandImage; +} + +constexpr int imgsizes[] = {0, 256, 512, 1024, 2048, 4096}; +std::optional<FATStorage> LoadDSiSDCard() noexcept +{ +    if (!Config::DSiSDEnable) +        return std::nullopt; + +    return FATStorage( +        Config::DSiSDPath, +        imgsizes[Config::DSiSDSize], +        Config::DSiSDReadOnly, +        Config::DSiSDFolderSync ? Config::DSiSDFolderPath : "" +    ); +} + +void LoadBIOSFiles(NDS& nds)  {      if (Config::ExternalBIOSEnable)      {          if (FileHandle* f = Platform::OpenLocalFile(Config::BIOS9Path, FileMode::Read))          {              FileRewind(f); -            FileRead(NDS::ARM9BIOS, sizeof(NDS::ARM9BIOS), 1, f); +            FileRead(nds.ARM9BIOS, sizeof(NDS::ARM9BIOS), 1, f);              Log(LogLevel::Info, "ARM9 BIOS loaded from %s\n", Config::BIOS9Path.c_str());              Platform::CloseFile(f); @@ -496,12 +725,12 @@ void LoadBIOSFiles()              Log(LogLevel::Warn, "ARM9 BIOS not found\n");              for (int i = 0; i < 16; i++) -                ((u32*)NDS::ARM9BIOS)[i] = 0xE7FFDEFF; +                ((u32*)nds.ARM9BIOS)[i] = 0xE7FFDEFF;          }          if (FileHandle* f = Platform::OpenLocalFile(Config::BIOS7Path, FileMode::Read))          { -            FileRead(NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS), 1, f); +            FileRead(nds.ARM7BIOS, sizeof(NDS::ARM7BIOS), 1, f);              Log(LogLevel::Info, "ARM7 BIOS loaded from\n", Config::BIOS7Path.c_str());              Platform::CloseFile(f); @@ -511,21 +740,22 @@ void LoadBIOSFiles()              Log(LogLevel::Warn, "ARM7 BIOS not found\n");              for (int i = 0; i < 16; i++) -                ((u32*)NDS::ARM7BIOS)[i] = 0xE7FFDEFF; +                ((u32*)nds.ARM7BIOS)[i] = 0xE7FFDEFF;          }      }      else      {          Log(LogLevel::Info, "Using built-in ARM7 and ARM9 BIOSes\n"); -        memcpy(NDS::ARM9BIOS, bios_arm9_bin, sizeof(bios_arm9_bin)); -        memcpy(NDS::ARM7BIOS, bios_arm7_bin, sizeof(bios_arm7_bin)); +        memcpy(nds.ARM9BIOS, bios_arm9_bin, sizeof(bios_arm9_bin)); +        memcpy(nds.ARM7BIOS, bios_arm7_bin, sizeof(bios_arm7_bin));      }      if (Config::ConsoleType == 1)      { +        DSi& dsi = static_cast<DSi&>(nds);          if (FileHandle* f = Platform::OpenLocalFile(Config::DSiBIOS9Path, FileMode::Read))          { -            FileRead(DSi::ARM9iBIOS, sizeof(DSi::ARM9iBIOS), 1, f); +            FileRead(dsi.ARM9iBIOS, sizeof(DSi::ARM9iBIOS), 1, f);              Log(LogLevel::Info, "ARM9i BIOS loaded from %s\n", Config::DSiBIOS9Path.c_str());              Platform::CloseFile(f); @@ -535,13 +765,13 @@ void LoadBIOSFiles()              Log(LogLevel::Warn, "ARM9i BIOS not found\n");              for (int i = 0; i < 16; i++) -                ((u32*)DSi::ARM9iBIOS)[i] = 0xE7FFDEFF; +                ((u32*)dsi.ARM9iBIOS)[i] = 0xE7FFDEFF;          }          if (FileHandle* f = Platform::OpenLocalFile(Config::DSiBIOS7Path, FileMode::Read))          {          // TODO: check if the first 32 bytes are crapoed -            FileRead(DSi::ARM7iBIOS, sizeof(DSi::ARM7iBIOS), 1, f); +            FileRead(dsi.ARM7iBIOS, sizeof(DSi::ARM7iBIOS), 1, f);              Log(LogLevel::Info, "ARM7i BIOS loaded from %s\n", Config::DSiBIOS7Path.c_str());              CloseFile(f); @@ -551,14 +781,14 @@ void LoadBIOSFiles()              Log(LogLevel::Warn, "ARM7i BIOS not found\n");              for (int i = 0; i < 16; i++) -                ((u32*)DSi::ARM7iBIOS)[i] = 0xE7FFDEFF; +                ((u32*)dsi.ARM7iBIOS)[i] = 0xE7FFDEFF;          }          if (!Config::DSiFullBIOSBoot)          {              // herp -            *(u32*)&DSi::ARM9iBIOS[0] = 0xEAFFFFFE; -            *(u32*)&DSi::ARM7iBIOS[0] = 0xEAFFFFFE; +            *(u32*)&dsi.ARM9iBIOS[0] = 0xEAFFFFFE; +            *(u32*)&dsi.ARM7iBIOS[0] = 0xEAFFFFFE;              // TODO!!!!              // hax the upper 32K out of the goddamn DSi @@ -567,11 +797,11 @@ void LoadBIOSFiles()      }  } -void EnableCheats(bool enable) +void EnableCheats(NDS& nds, bool enable)  {      CheatsOn = enable;      if (CheatFile) -        NDS::AREngine->SetCodeFile(CheatsOn ? CheatFile : nullptr); +        nds.AREngine.SetCodeFile(CheatsOn ? CheatFile : nullptr);  }  ARCodeFile* GetCheatFile() @@ -580,42 +810,44 @@ ARCodeFile* GetCheatFile()  } -void SetBatteryLevels() +void SetBatteryLevels(NDS& nds)  { -    if (NDS::ConsoleType == 1) +    if (nds.ConsoleType == 1)      { -        DSi::I2C->GetBPTWL()->SetBatteryLevel(Config::DSiBatteryLevel); -        DSi::I2C->GetBPTWL()->SetBatteryCharging(Config::DSiBatteryCharging); +        auto& dsi = static_cast<DSi&>(nds); +        dsi.I2C.GetBPTWL()->SetBatteryLevel(Config::DSiBatteryLevel); +        dsi.I2C.GetBPTWL()->SetBatteryCharging(Config::DSiBatteryCharging);      }      else      { -        NDS::SPI->GetPowerMan()->SetBatteryLevelOkay(Config::DSBatteryLevelOkay); +        nds.SPI.GetPowerMan()->SetBatteryLevelOkay(Config::DSBatteryLevelOkay);      }  } -void SetDateTime() +void SetDateTime(NDS& nds)  {      QDateTime hosttime = QDateTime::currentDateTime();      QDateTime time = hosttime.addSecs(Config::RTCOffset); -    NDS::RTC->SetDateTime(time.date().year(), time.date().month(), time.date().day(), +    nds.RTC.SetDateTime(time.date().year(), time.date().month(), time.date().day(),                            time.time().hour(), time.time().minute(), time.time().second());  } -void Reset() +void Reset(EmuThread* thread)  { -    NDS::SetConsoleType(Config::ConsoleType); -    if (Config::ConsoleType == 1) EjectGBACart(); -    LoadBIOSFiles(); +    thread->RecreateConsole(); + +    if (Config::ConsoleType == 1) EjectGBACart(*thread->NDS); +    LoadBIOSFiles(*thread->NDS); -    InstallFirmware(); +    InstallFirmware(*thread->NDS);      if (Config::ConsoleType == 1)      { -        InstallNAND(&DSi::ARM7iBIOS[0x8308]); +        InstallNAND(static_cast<DSi&>(*thread->NDS));      } -    NDS::Reset(); -    SetBatteryLevels(); -    SetDateTime(); +    thread->NDS->Reset(); +    SetBatteryLevels(*thread->NDS); +    SetDateTime(*thread->NDS);      if ((CartType != -1) && NDSSave)      { @@ -659,27 +891,27 @@ void Reset()      if (!BaseROMName.empty())      { -        if (Config::DirectBoot || NDS::NeedsDirectBoot()) +        if (Config::DirectBoot || thread->NDS->NeedsDirectBoot())          { -            NDS::SetupDirectBoot(BaseROMName); +            thread->NDS->SetupDirectBoot(BaseROMName);          }      }  } -bool LoadBIOS() +bool LoadBIOS(EmuThread* thread)  { -    NDS::SetConsoleType(Config::ConsoleType); +    thread->RecreateConsole(); -    LoadBIOSFiles(); +    LoadBIOSFiles(*thread->NDS); -    if (!InstallFirmware()) +    if (!InstallFirmware(*thread->NDS))          return false; -    if (Config::ConsoleType == 1 && !InstallNAND(&DSi::ARM7iBIOS[0x8308])) +    if (Config::ConsoleType == 1 && !InstallNAND(static_cast<DSi&>(*thread->NDS)))          return false; -    if (NDS::NeedsDirectBoot()) +    if (thread->NDS->NeedsDirectBoot())          return false;      /*if (NDSSave) delete NDSSave; @@ -690,9 +922,9 @@ bool LoadBIOS()      BaseROMName = "";      BaseAssetName = "";*/ -    NDS::Reset(); -    SetBatteryLevels(); -    SetDateTime(); +    thread->NDS->Reset(); +    SetBatteryLevels(*thread->NDS); +    SetDateTime(*thread->NDS);      return true;  } @@ -884,7 +1116,7 @@ pair<unique_ptr<Firmware>, string> GenerateDefaultFirmware()      return std::make_pair(std::move(firmware), std::move(wfcsettingspath));  } -void LoadUserSettingsFromConfig(Firmware& firmware) +void CustomizeFirmware(Firmware& firmware) noexcept  {      auto& currentData = firmware.GetEffectiveUserData(); @@ -992,13 +1224,13 @@ static Platform::FileHandle* OpenNANDFile() noexcept      return nandfile;  } -bool InstallNAND(const u8* es_keyY) +bool InstallNAND(DSi& dsi)  {      Platform::FileHandle* nandfile = OpenNANDFile();      if (!nandfile)          return false; -    DSi_NAND::NANDImage nandImage(nandfile, es_keyY); +    DSi_NAND::NANDImage nandImage(nandfile, &dsi.ARM7iBIOS[0x8308]);      if (!nandImage)      {          Log(LogLevel::Error, "Failed to parse DSi NAND\n"); @@ -1067,11 +1299,11 @@ bool InstallNAND(const u8* es_keyY)          }      } -    DSi::NANDImage = std::make_unique<DSi_NAND::NANDImage>(std::move(nandImage)); +    dsi.NANDImage = std::make_unique<DSi_NAND::NANDImage>(std::move(nandImage));      return true;  } -bool InstallFirmware() +bool InstallFirmware(NDS& nds)  {      FirmwareSave.reset();      unique_ptr<Firmware> firmware; @@ -1098,15 +1330,15 @@ bool InstallFirmware()      if (Config::FirmwareOverrideSettings)      { -        LoadUserSettingsFromConfig(*firmware); +        CustomizeFirmware(*firmware);      }      FirmwareSave = std::make_unique<SaveManager>(firmwarepath); -    return NDS::SPI->GetFirmwareMem()->InstallFirmware(std::move(firmware)); +    return nds.SPI.GetFirmwareMem()->InstallFirmware(std::move(firmware));  } -bool LoadROM(QStringList filepath, bool reset) +bool LoadROM(EmuThread* emuthread, QStringList filepath, bool reset)  {      if (filepath.empty()) return false; @@ -1201,22 +1433,22 @@ bool LoadROM(QStringList filepath, bool reset)      BaseROMName = romname;      BaseAssetName = romname.substr(0, romname.rfind('.')); -    if (!InstallFirmware()) +    emuthread->RecreateConsole(); +    if (!InstallFirmware(*emuthread->NDS))      {          return false;      }      if (reset)      { -        NDS::SetConsoleType(Config::ConsoleType); -        NDS::EjectCart(); -        LoadBIOSFiles(); +        emuthread->NDS->EjectCart(); +        LoadBIOSFiles(*emuthread->NDS);          if (Config::ConsoleType == 1) -            InstallNAND(&DSi::ARM7iBIOS[0x8308]); +            InstallNAND(static_cast<DSi&>(*emuthread->NDS)); -        NDS::Reset(); -        SetBatteryLevels(); -        SetDateTime(); +        emuthread->NDS->Reset(); +        SetBatteryLevels(*emuthread->NDS); +        SetDateTime(*emuthread->NDS);      }      u32 savelen = 0; @@ -1238,12 +1470,12 @@ bool LoadROM(QStringList filepath, bool reset)          CloseFile(sav);      } -    bool res = NDS::LoadCart(filedata, filelen, savedata, savelen); +    bool res =  emuthread->NDS->LoadCart(filedata, filelen, savedata, savelen);      if (res && reset)      { -        if (Config::DirectBoot || NDS::NeedsDirectBoot()) +        if (Config::DirectBoot || emuthread->NDS->NeedsDirectBoot())          { -            NDS::SetupDirectBoot(romname); +            emuthread->NDS->SetupDirectBoot(romname);          }      } @@ -1252,7 +1484,7 @@ bool LoadROM(QStringList filepath, bool reset)          CartType = 0;          NDSSave = new SaveManager(savname); -        LoadCheats(); +        LoadCheats(*emuthread->NDS);      }      if (savedata) delete[] savedata; @@ -1260,14 +1492,14 @@ bool LoadROM(QStringList filepath, bool reset)      return res;  } -void EjectCart() +void EjectCart(NDS& nds)  {      if (NDSSave) delete NDSSave;      NDSSave = nullptr; -    UnloadCheats(); +    UnloadCheats(nds); -    NDS::EjectCart(); +    nds.EjectCart();      CartType = -1;      BaseROMDir = ""; @@ -1295,7 +1527,7 @@ QString CartLabel()  } -bool LoadGBAROM(QStringList filepath) +bool LoadGBAROM(NDS& nds, QStringList filepath)  {      if (Config::ConsoleType == 1) return false;      if (filepath.empty()) return false; @@ -1408,7 +1640,7 @@ bool LoadGBAROM(QStringList filepath)          CloseFile(sav);      } -    bool res = NDS::LoadGBACart(filedata, filelen, savedata, savelen); +    bool res = nds.LoadGBACart(filedata, filelen, savedata, savelen);      if (res)      { @@ -1421,14 +1653,14 @@ bool LoadGBAROM(QStringList filepath)      return res;  } -void LoadGBAAddon(int type) +void LoadGBAAddon(NDS& nds, int type)  {      if (Config::ConsoleType == 1) return;      if (GBASave) delete GBASave;      GBASave = nullptr; -    NDS::LoadGBAAddon(type); +    nds.LoadGBAAddon(type);      GBACartType = type;      BaseGBAROMDir = ""; @@ -1436,12 +1668,12 @@ void LoadGBAAddon(int type)      BaseGBAAssetName = "";  } -void EjectGBACart() +void EjectGBACart(NDS& nds)  {      if (GBASave) delete GBASave;      GBASave = nullptr; -    NDS::EjectGBACart(); +    nds.EjectGBACart();      GBACartType = -1;      BaseGBAROMDir = ""; @@ -1471,7 +1703,7 @@ QString GBACartLabel()              return ret;          } -    case NDS::GBAAddon_RAMExpansion: +    case GBAAddon_RAMExpansion:          return "Memory expansion";      } diff --git a/src/frontend/qt_sdl/ROMManager.h b/src/frontend/qt_sdl/ROMManager.h index 9228560..2163a68 100644 --- a/src/frontend/qt_sdl/ROMManager.h +++ b/src/frontend/qt_sdl/ROMManager.h @@ -24,10 +24,19 @@  #include "AREngine.h"  #include "DSi_NAND.h" +#include "MemConstants.h" +#include <optional>  #include <string>  #include <memory>  #include <vector> +namespace melonDS +{ +class NDS; +class DSi; +class FATStorage; +} +class EmuThread;  namespace ROMManager  { @@ -37,30 +46,41 @@ extern SaveManager* GBASave;  extern std::unique_ptr<SaveManager> FirmwareSave;  QString VerifySetup(); -void Reset(); -bool LoadBIOS(); +void Reset(EmuThread* thread); +bool LoadBIOS(EmuThread* thread);  void ClearBackupState(); -bool InstallFirmware(); -bool InstallNAND(const u8* es_keyY); -bool LoadROM(QStringList filepath, bool reset); -void EjectCart(); +std::optional<std::array<u8, ARM9BIOSSize>> LoadARM9BIOS() noexcept; +std::optional<std::array<u8, ARM7BIOSSize>> LoadARM7BIOS() noexcept; +std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM9BIOS() noexcept; +std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM7BIOS() noexcept; +std::optional<FATStorage> LoadDSiSDCard() noexcept; +void CustomizeFirmware(Firmware& firmware) noexcept; +Firmware GenerateFirmware(int type) noexcept; +/// Loads and customizes a firmware image based on the values in Config +std::optional<Firmware> LoadFirmware(int type) noexcept; +/// Loads and customizes a NAND image based on the values in Config +std::optional<DSi_NAND::NANDImage> LoadNAND(const std::array<u8, DSiBIOSSize>& arm7ibios) noexcept; +bool InstallFirmware(NDS& nds); +bool InstallNAND(DSi& dsi); +bool LoadROM(EmuThread*, QStringList filepath, bool reset); +void EjectCart(NDS& nds);  bool CartInserted();  QString CartLabel(); -bool LoadGBAROM(QStringList filepath); -void LoadGBAAddon(int type); -void EjectGBACart(); +bool LoadGBAROM(NDS& nds, QStringList filepath); +void LoadGBAAddon(NDS& nds, int type); +void EjectGBACart(NDS& nds);  bool GBACartInserted();  QString GBACartLabel();  std::string GetSavestateName(int slot);  bool SavestateExists(int slot); -bool LoadState(const std::string& filename); -bool SaveState(const std::string& filename); -void UndoStateLoad(); +bool LoadState(NDS& nds, const std::string& filename); +bool SaveState(NDS& nds, const std::string& filename); +void UndoStateLoad(NDS& nds); -void EnableCheats(bool enable); +void EnableCheats(NDS& nds, bool enable);  ARCodeFile* GetCheatFile();  void ROMIcon(const u8 (&data)[512], const u16 (&palette)[16], u32 (&iconRef)[32*32]); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 4286498..54a6f14 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -203,6 +203,30 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)      static_cast<ScreenPanelGL*>(mainWindow->panel)->transferLayout(this);  } +std::unique_ptr<NDS> EmuThread::CreateConsole() +{ +    if (Config::ConsoleType == 1) +    { +        return std::make_unique<melonDS::DSi>(); +    } + +    return std::make_unique<melonDS::NDS>(); +} + +void EmuThread::RecreateConsole() +{ +    if (!NDS || NDS->ConsoleType != Config::ConsoleType) +    { +        NDS = nullptr; // To ensure the destructor is called before a new one is created +        NDS::Current = nullptr; + +        NDS = CreateConsole(); +        // TODO: Insert ROMs +        NDS::Current = NDS.get(); +    } +} + +  void EmuThread::updateScreenSettings(bool filter, const WindowInfo& windowInfo, int numScreens, int* screenKind, float* screenMatrix)  {      screenSettingsLock.lock(); @@ -318,7 +342,7 @@ void EmuThread::run()      u32 mainScreenPos[3];      Platform::FileHandle* file; -    NDS::Init(); +    RecreateConsole();      mainScreenPos[0] = 0;      mainScreenPos[1] = 0; @@ -340,10 +364,10 @@ void EmuThread::run()          videoRenderer = 0;      } -    NDS::GPU->InitRenderer(videoRenderer); -    NDS::GPU->SetRenderSettings(videoRenderer, videoSettings); +    NDS->GPU.InitRenderer(videoRenderer); +    NDS->GPU.SetRenderSettings(videoRenderer, videoSettings); -    NDS::SPU->SetInterpolation(Config::AudioInterp); +    NDS->SPU.SetInterpolation(Config::AudioInterp);      Input::Init(); @@ -362,7 +386,7 @@ void EmuThread::run()          RTC::StateData state;          Platform::FileRead(&state, sizeof(state), 1, file);          Platform::CloseFile(file); -        NDS::RTC->SetState(state); +        NDS->RTC.SetState(state);      }      char melontitle[100]; @@ -384,8 +408,7 @@ void EmuThread::run()          if (Input::HotkeyPressed(HK_SolarSensorDecrease))          { -            assert(NDS::GBACartSlot != nullptr); -            int level = NDS::GBACartSlot->SetInput(GBACart::Input_SolarSensorDown, true); +            int level = NDS->GBACartSlot.SetInput(GBACart::Input_SolarSensorDown, true);              if (level != -1)              {                  char msg[64]; @@ -395,8 +418,7 @@ void EmuThread::run()          }          if (Input::HotkeyPressed(HK_SolarSensorIncrease))          { -            assert(NDS::GBACartSlot != nullptr); -            int level = NDS::GBACartSlot->SetInput(GBACart::Input_SolarSensorUp, true); +            int level = NDS->GBACartSlot.SetInput(GBACart::Input_SolarSensorUp, true);              if (level != -1)              {                  char msg[64]; @@ -405,40 +427,41 @@ void EmuThread::run()              }          } -        if (NDS::ConsoleType == 1) +        if (NDS->ConsoleType == 1)          { +            DSi& dsi = static_cast<DSi&>(*NDS);              double currentTime = SDL_GetPerformanceCounter() * perfCountsSec;              // Handle power button              if (Input::HotkeyDown(HK_PowerButton))              { -                DSi::I2C->GetBPTWL()->SetPowerButtonHeld(currentTime); +                dsi.I2C.GetBPTWL()->SetPowerButtonHeld(currentTime);              }              else if (Input::HotkeyReleased(HK_PowerButton))              { -                DSi::I2C->GetBPTWL()->SetPowerButtonReleased(currentTime); +                dsi.I2C.GetBPTWL()->SetPowerButtonReleased(currentTime);              }              // Handle volume buttons              if (Input::HotkeyDown(HK_VolumeUp))              { -                DSi::I2C->GetBPTWL()->SetVolumeSwitchHeld(DSi::I2C->GetBPTWL()->volumeKey_Up); +                dsi.I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Up);              }              else if (Input::HotkeyReleased(HK_VolumeUp))              { -                DSi::I2C->GetBPTWL()->SetVolumeSwitchReleased(DSi::I2C->GetBPTWL()->volumeKey_Up); +                dsi.I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Up);              }              if (Input::HotkeyDown(HK_VolumeDown))              { -                DSi::I2C->GetBPTWL()->SetVolumeSwitchHeld(DSi::I2C->GetBPTWL()->volumeKey_Down); +                dsi.I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Down);              }              else if (Input::HotkeyReleased(HK_VolumeDown))              { -                DSi::I2C->GetBPTWL()->SetVolumeSwitchReleased(DSi::I2C->GetBPTWL()->volumeKey_Down); +                dsi.I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Down);              } -            DSi::I2C->GetBPTWL()->ProcessVolumeSwitchInput(currentTime); +            dsi.I2C.GetBPTWL()->ProcessVolumeSwitchInput(currentTime);          }          if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep) @@ -472,28 +495,28 @@ void EmuThread::run()                  videoSettings.GL_ScaleFactor = Config::GL_ScaleFactor;                  videoSettings.GL_BetterPolygons = Config::GL_BetterPolygons; -                NDS::GPU->SetRenderSettings(videoRenderer, videoSettings); +                NDS->GPU.SetRenderSettings(videoRenderer, videoSettings);              }              // process input and hotkeys -            NDS::SetKeyMask(Input::InputMask); +            NDS->SetKeyMask(Input::InputMask);              if (Input::HotkeyPressed(HK_Lid))              { -                bool lid = !NDS::IsLidClosed(); -                NDS::SetLidClosed(lid); +                bool lid = !NDS->IsLidClosed(); +                NDS->SetLidClosed(lid);                  OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened");              }              // microphone input -            AudioInOut::MicProcess(); +            AudioInOut::MicProcess(*NDS);              // auto screen layout              if (Config::ScreenSizing == Frontend::screenSizing_Auto)              {                  mainScreenPos[2] = mainScreenPos[1];                  mainScreenPos[1] = mainScreenPos[0]; -                mainScreenPos[0] = NDS::PowerControl9 >> 15; +                mainScreenPos[0] = NDS->PowerControl9 >> 15;                  int guess;                  if (mainScreenPos[0] == mainScreenPos[2] && @@ -520,7 +543,7 @@ void EmuThread::run()              // emulate -            u32 nlines = NDS::RunFrame(); +            u32 nlines = NDS->RunFrame();              if (ROMManager::NDSSave)                  ROMManager::NDSSave->CheckFlush(); @@ -534,12 +557,12 @@ void EmuThread::run()              if (!oglContext)              {                  FrontBufferLock.lock(); -                FrontBuffer = NDS::GPU->FrontBuffer; +                FrontBuffer = NDS->GPU.FrontBuffer;                  FrontBufferLock.unlock();              }              else              { -                FrontBuffer = NDS::GPU->FrontBuffer; +                FrontBuffer = NDS->GPU.FrontBuffer;                  drawScreenGL();              } @@ -563,9 +586,10 @@ void EmuThread::run()                  oglContext->SetSwapInterval(0);              } -            if (Config::DSiVolumeSync && NDS::ConsoleType == 1) +            if (Config::DSiVolumeSync && NDS->ConsoleType == 1)              { -                u8 volumeLevel = DSi::I2C->GetBPTWL()->GetVolumeLevel(); +                DSi& dsi = static_cast<DSi&>(*NDS); +                u8 volumeLevel = dsi.I2C.GetBPTWL()->GetVolumeLevel();                  if (volumeLevel != dsiVolumeLevel)                  {                      dsiVolumeLevel = volumeLevel; @@ -576,7 +600,7 @@ void EmuThread::run()              }              if (Config::AudioSync && !fastforward) -                AudioInOut::AudioSync(); +                AudioInOut::AudioSync(*emuThread->NDS);              double frametimeStep = nlines / (60.0 * 263.0); @@ -669,16 +693,15 @@ void EmuThread::run()      if (file)      {          RTC::StateData state; -        NDS::RTC->GetState(state); +        NDS->RTC.GetState(state);          Platform::FileWrite(&state, sizeof(state), 1, file);          Platform::CloseFile(file);      }      EmuStatus = emuStatus_Exit; -    NDS::GPU->DeInitRenderer(); -    NDS::DeInit(); -    //Platform::LAN_DeInit(); +    NDS::Current = nullptr; +    // nds is out of scope, so unique_ptr cleans it up for us  }  void EmuThread::changeWindowTitle(char* title) @@ -759,6 +782,7 @@ bool EmuThread::emuIsActive()  void EmuThread::drawScreenGL()  { +    if (!NDS) return;      int w = windowInfo.surface_width;      int h = windowInfo.surface_height;      float factor = windowInfo.surface_scale; @@ -780,10 +804,10 @@ void EmuThread::drawScreenGL()      glActiveTexture(GL_TEXTURE0);  #ifdef OGLRENDERER_ENABLED -    if (NDS::GPU->Renderer != 0) +    if (NDS->GPU.Renderer != 0)      {          // hardware-accelerated render -        NDS::GPU->CurGLCompositor->BindOutputTexture(frontbuf); +        NDS->GPU.CurGLCompositor->BindOutputTexture(frontbuf);      }      else  #endif @@ -791,12 +815,12 @@ void EmuThread::drawScreenGL()          // regular render          glBindTexture(GL_TEXTURE_2D, screenTexture); -        if (NDS::GPU->Framebuffer[frontbuf][0] && NDS::GPU->Framebuffer[frontbuf][1]) +        if (NDS->GPU.Framebuffer[frontbuf][0] && NDS->GPU.Framebuffer[frontbuf][1])          {              glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, -                            GL_UNSIGNED_BYTE, NDS::GPU->Framebuffer[frontbuf][0]); +                            GL_UNSIGNED_BYTE, NDS->GPU.Framebuffer[frontbuf][0]);              glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192+2, 256, 192, GL_RGBA, -                            GL_UNSIGNED_BYTE, NDS::GPU->Framebuffer[frontbuf][1]); +                            GL_UNSIGNED_BYTE, NDS->GPU.Framebuffer[frontbuf][1]);          }      } @@ -927,7 +951,8 @@ void ScreenHandler::screenOnMousePress(QMouseEvent* event)      if (Frontend::GetTouchCoords(x, y, false))      {          touching = true; -        NDS::TouchScreen(x, y); +        assert(emuThread->NDS != nullptr); +        emuThread->NDS->TouchScreen(x, y);      }  } @@ -939,7 +964,8 @@ void ScreenHandler::screenOnMouseRelease(QMouseEvent* event)      if (touching)      {          touching = false; -        NDS::ReleaseScreen(); +        assert(emuThread->NDS != nullptr); +        emuThread->NDS->ReleaseScreen();      }  } @@ -956,7 +982,10 @@ void ScreenHandler::screenOnMouseMove(QMouseEvent* event)      int y = event->pos().y();      if (Frontend::GetTouchCoords(x, y, true)) -        NDS::TouchScreen(x, y); +    { +        assert(emuThread->NDS != nullptr); +        emuThread->NDS->TouchScreen(x, y); +    }  }  void ScreenHandler::screenHandleTablet(QTabletEvent* event) @@ -974,14 +1003,16 @@ void ScreenHandler::screenHandleTablet(QTabletEvent* event)              if (Frontend::GetTouchCoords(x, y, event->type()==QEvent::TabletMove))              {                  touching = true; -                NDS::TouchScreen(x, y); +                assert(emuThread->NDS != nullptr); +                emuThread->NDS->TouchScreen(x, y);              }          }          break;      case QEvent::TabletRelease:          if (touching)          { -            NDS::ReleaseScreen(); +            assert(emuThread->NDS != nullptr); +            emuThread->NDS->ReleaseScreen();              touching = false;          }          break; @@ -1007,14 +1038,16 @@ void ScreenHandler::screenHandleTouch(QTouchEvent* event)              if (Frontend::GetTouchCoords(x, y, event->type()==QEvent::TouchUpdate))              {                  touching = true; -                NDS::TouchScreen(x, y); +                assert(emuThread->NDS != nullptr); +                emuThread->NDS->TouchScreen(x, y);              }          }          break;      case QEvent::TouchEnd:          if (touching)          { -            NDS::ReleaseScreen(); +            assert(emuThread->NDS != nullptr); +            emuThread->NDS->ReleaseScreen();              touching = false;          }          break; @@ -1080,16 +1113,17 @@ void ScreenPanelNative::paintEvent(QPaintEvent* event)      if (emuThread->emuIsActive())      { +        assert(emuThread->NDS != nullptr);          emuThread->FrontBufferLock.lock();          int frontbuf = emuThread->FrontBuffer; -        if (!NDS::GPU->Framebuffer[frontbuf][0] || !NDS::GPU->Framebuffer[frontbuf][1]) +        if (!emuThread->NDS->GPU.Framebuffer[frontbuf][0] || !emuThread->NDS->GPU.Framebuffer[frontbuf][1])          {              emuThread->FrontBufferLock.unlock();              return;          } -        memcpy(screen[0].scanLine(0), NDS::GPU->Framebuffer[frontbuf][0], 256 * 192 * 4); -        memcpy(screen[1].scanLine(0), NDS::GPU->Framebuffer[frontbuf][1], 256 * 192 * 4); +        memcpy(screen[0].scanLine(0), emuThread->NDS->GPU.Framebuffer[frontbuf][0], 256 * 192 * 4); +        memcpy(screen[1].scanLine(0), emuThread->NDS->GPU.Framebuffer[frontbuf][1], 256 * 192 * 4);          emuThread->FrontBufferLock.unlock();          QRect screenrc(0, 0, 256, 192); @@ -1472,7 +1506,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)              QMenu* submenu = menu->addMenu("Insert add-on cart");              actInsertGBAAddon[0] = submenu->addAction("Memory expansion"); -            actInsertGBAAddon[0]->setData(QVariant(NDS::GBAAddon_RAMExpansion)); +            actInsertGBAAddon[0]->setData(QVariant(GBAAddon_RAMExpansion));              connect(actInsertGBAAddon[0], &QAction::triggered, this, &MainWindow::onInsertGBAAddon);          } @@ -2025,7 +2059,7 @@ void MainWindow::dropEvent(QDropEvent* event)      if (isNdsRom)      { -        if (!ROMManager::LoadROM(file, true)) +        if (!ROMManager::LoadROM(emuThread, file, true))          {              // TODO: better error reporting?              QMessageBox::critical(this, "melonDS", "Failed to load the DS ROM."); @@ -2038,14 +2072,15 @@ void MainWindow::dropEvent(QDropEvent* event)          recentFileList.prepend(barredFilename);          updateRecentFilesMenu(); -        NDS::Start(); +        assert(emuThread->NDS != nullptr); +        emuThread->NDS->Start();          emuThread->emuRun();          updateCartInserted(false);      }      else if (isGbaRom)      { -        if (!ROMManager::LoadGBAROM(file)) +        if (!ROMManager::LoadGBAROM(*emuThread->NDS, file))          {              // TODO: better error reporting?              QMessageBox::critical(this, "melonDS", "Failed to load the GBA ROM."); @@ -2111,7 +2146,7 @@ bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot)      bool gbaloaded = false;      if (!gbafile.isEmpty())      { -        if (!ROMManager::LoadGBAROM(gbafile)) +        if (!ROMManager::LoadGBAROM(*emuThread->NDS, gbafile))          {              // TODO: better error reporting?              QMessageBox::critical(this, "melonDS", "Failed to load the GBA ROM."); @@ -2124,7 +2159,7 @@ bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot)      bool ndsloaded = false;      if (!file.isEmpty())      { -        if (!ROMManager::LoadROM(file, true)) +        if (!ROMManager::LoadROM(emuThread, file, true))          {              // TODO: better error reporting?              QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); @@ -2140,7 +2175,7 @@ bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot)      {          if (ndsloaded)          { -            NDS::Start(); +            emuThread->NDS->Start();              emuThread->emuRun();          }          else @@ -2333,7 +2368,7 @@ void MainWindow::onOpenFile()          return;      } -    if (!ROMManager::LoadROM(file, true)) +    if (!ROMManager::LoadROM(emuThread, file, true))      {          // TODO: better error reporting?          QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); @@ -2346,7 +2381,8 @@ void MainWindow::onOpenFile()      recentFileList.prepend(filename);      updateRecentFilesMenu(); -    NDS::Start(); +    assert(emuThread->NDS != nullptr); +    emuThread->NDS->Start();      emuThread->emuRun();      updateCartInserted(false); @@ -2431,7 +2467,7 @@ void MainWindow::onClickRecentFile()          return;      } -    if (!ROMManager::LoadROM(file, true)) +    if (!ROMManager::LoadROM(emuThread, file, true))      {          // TODO: better error reporting?          QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); @@ -2443,7 +2479,8 @@ void MainWindow::onClickRecentFile()      recentFileList.prepend(filename);      updateRecentFilesMenu(); -    NDS::Start(); +    assert(emuThread->NDS != nullptr); +    emuThread->NDS->Start();      emuThread->emuRun();      updateCartInserted(false); @@ -2459,7 +2496,7 @@ void MainWindow::onBootFirmware()          return;      } -    if (!ROMManager::LoadBIOS()) +    if (!ROMManager::LoadBIOS(emuThread))      {          // TODO: better error reporting?          QMessageBox::critical(this, "melonDS", "This firmware is not bootable."); @@ -2467,7 +2504,8 @@ void MainWindow::onBootFirmware()          return;      } -    NDS::Start(); +    assert(emuThread->NDS != nullptr); +    emuThread->NDS->Start();      emuThread->emuRun();  } @@ -2482,7 +2520,7 @@ void MainWindow::onInsertCart()          return;      } -    if (!ROMManager::LoadROM(file, false)) +    if (!ROMManager::LoadROM(emuThread, file, false))      {          // TODO: better error reporting?          QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); @@ -2499,7 +2537,7 @@ void MainWindow::onEjectCart()  {      emuThread->emuPause(); -    ROMManager::EjectCart(); +    ROMManager::EjectCart(*emuThread->NDS);      emuThread->emuUnpause(); @@ -2517,7 +2555,7 @@ void MainWindow::onInsertGBACart()          return;      } -    if (!ROMManager::LoadGBAROM(file)) +    if (!ROMManager::LoadGBAROM(*emuThread->NDS, file))      {          // TODO: better error reporting?          QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); @@ -2537,7 +2575,7 @@ void MainWindow::onInsertGBAAddon()      emuThread->emuPause(); -    ROMManager::LoadGBAAddon(type); +    ROMManager::LoadGBAAddon(*emuThread->NDS, type);      emuThread->emuUnpause(); @@ -2548,7 +2586,7 @@ void MainWindow::onEjectGBACart()  {      emuThread->emuPause(); -    ROMManager::EjectGBACart(); +    ROMManager::EjectGBACart(*emuThread->NDS);      emuThread->emuUnpause(); @@ -2582,7 +2620,7 @@ void MainWindow::onSaveState()          filename = qfilename.toStdString();      } -    if (ROMManager::SaveState(filename)) +    if (ROMManager::SaveState(*emuThread->NDS, filename))      {          char msg[64];          if (slot > 0) sprintf(msg, "State saved to slot %d", slot); @@ -2637,7 +2675,7 @@ void MainWindow::onLoadState()          return;      } -    if (ROMManager::LoadState(filename)) +    if (ROMManager::LoadState(*emuThread->NDS, filename))      {          char msg[64];          if (slot > 0) sprintf(msg, "State loaded from slot %d", slot); @@ -2657,7 +2695,7 @@ void MainWindow::onLoadState()  void MainWindow::onUndoStateLoad()  {      emuThread->emuPause(); -    ROMManager::UndoStateLoad(); +    ROMManager::UndoStateLoad(*emuThread->NDS);      emuThread->emuUnpause();      OSD::AddMessage(0, "State load undone"); @@ -2696,7 +2734,7 @@ void MainWindow::onImportSavefile()              return;          } -        ROMManager::Reset(); +        ROMManager::Reset(emuThread);      }      u32 len = FileLength(f); @@ -2705,7 +2743,8 @@ void MainWindow::onImportSavefile()      Platform::FileRewind(f);      Platform::FileRead(data, len, 1, f); -    NDS::LoadSave(data, len); +    assert(emuThread->NDS != nullptr); +    emuThread->NDS->LoadSave(data, len);      delete[] data;      CloseFile(f); @@ -2747,7 +2786,7 @@ void MainWindow::onReset()      actUndoStateLoad->setEnabled(false); -    ROMManager::Reset(); +    ROMManager::Reset(emuThread);      OSD::AddMessage(0, "Reset");      emuThread->emuRun(); @@ -2758,7 +2797,7 @@ void MainWindow::onStop()      if (!RunningSomething) return;      emuThread->emuPause(); -    NDS::Stop(); +    emuThread->NDS->Stop();  }  void MainWindow::onFrameStep() @@ -2775,13 +2814,13 @@ void MainWindow::onOpenDateTime()  void MainWindow::onOpenPowerManagement()  { -    PowerManagementDialog* dlg = PowerManagementDialog::openDlg(this); +    PowerManagementDialog* dlg = PowerManagementDialog::openDlg(this, emuThread);  }  void MainWindow::onEnableCheats(bool checked)  {      Config::EnableCheats = checked?1:0; -    ROMManager::EnableCheats(Config::EnableCheats != 0); +    ROMManager::EnableCheats(*emuThread->NDS, Config::EnableCheats != 0);  }  void MainWindow::onSetupCheats() @@ -2799,12 +2838,14 @@ void MainWindow::onCheatsDialogFinished(int res)  void MainWindow::onROMInfo()  { -    ROMInfoDialog* dlg = ROMInfoDialog::openDlg(this); +    auto cart = emuThread->NDS->NDSCartSlot.GetCart(); +    if (cart) +        ROMInfoDialog* dlg = ROMInfoDialog::openDlg(this, *cart);  }  void MainWindow::onRAMInfo()  { -    RAMInfoDialog* dlg = RAMInfoDialog::openDlg(this); +    RAMInfoDialog* dlg = RAMInfoDialog::openDlg(this, emuThread);  }  void MainWindow::onOpenTitleManager() @@ -2907,7 +2948,7 @@ void MainWindow::onCameraSettingsFinished(int res)  void MainWindow::onOpenAudioSettings()  { -    AudioSettingsDialog* dlg = AudioSettingsDialog::openDlg(this, emuThread->emuIsActive()); +    AudioSettingsDialog* dlg = AudioSettingsDialog::openDlg(this, emuThread->emuIsActive(), emuThread);      connect(emuThread, &EmuThread::syncVolumeLevel, dlg, &AudioSettingsDialog::onSyncVolumeLevel);      connect(emuThread, &EmuThread::windowEmuStart, dlg, &AudioSettingsDialog::onConsoleReset);      connect(dlg, &AudioSettingsDialog::updateAudioSettings, this, &MainWindow::onUpdateAudioSettings); @@ -2948,17 +2989,18 @@ void MainWindow::onPathSettingsFinished(int res)  void MainWindow::onUpdateAudioSettings()  { -    NDS::SPU->SetInterpolation(Config::AudioInterp); +    assert(emuThread->NDS != nullptr); +    emuThread->NDS->SPU.SetInterpolation(Config::AudioInterp);      if (Config::AudioBitDepth == 0) -        NDS::SPU->SetDegrade10Bit(NDS::ConsoleType == 0); +        emuThread->NDS->SPU.SetDegrade10Bit(emuThread->NDS->ConsoleType == 0);      else -        NDS::SPU->SetDegrade10Bit(Config::AudioBitDepth == 1); +        emuThread->NDS->SPU.SetDegrade10Bit(Config::AudioBitDepth == 1);  }  void MainWindow::onAudioSettingsFinished(int res)  { -    AudioInOut::UpdateSettings(); +    AudioInOut::UpdateSettings(*emuThread->NDS);  }  void MainWindow::onOpenMPSettings() @@ -3313,13 +3355,11 @@ int main(int argc, char** argv)  #define SANITIZE(var, min, max)  { var = std::clamp(var, min, max); }      SANITIZE(Config::ConsoleType, 0, 1); -    SANITIZE(Config::_3DRenderer, -    0, -    0 // Minimum, Software renderer -    #ifdef OGLRENDERER_ENABLED -    + 1 // OpenGL Renderer -    #endif -    ); +#ifdef OGLRENDERER_ENABLED +    SANITIZE(Config::_3DRenderer, 0, 1); // 0 is the software renderer, 1 is the OpenGL renderer +#else +    SANITIZE(Config::_3DRenderer, 0, 0); +#endif      SANITIZE(Config::ScreenVSyncInterval, 1, 20);      SANITIZE(Config::GL_ScaleFactor, 1, 16);      SANITIZE(Config::AudioInterp, 0, 3); @@ -3333,7 +3373,6 @@ int main(int argc, char** argv)      SANITIZE(Config::ScreenAspectBot, 0, AspectRatiosNum);  #undef SANITIZE -    AudioInOut::Init();      camStarted[0] = false;      camStarted[1] = false;      camManager[0] = new CameraManager(0, 640, 480, true); @@ -3341,7 +3380,6 @@ int main(int argc, char** argv)      camManager[0]->setXFlip(Config::Camera[0].XFlip);      camManager[1]->setXFlip(Config::Camera[1].XFlip); -    ROMManager::EnableCheats(Config::EnableCheats != 0);      Input::JoystickID = Config::JoystickID;      Input::OpenJoystick(); @@ -3354,6 +3392,8 @@ int main(int argc, char** argv)      emuThread->start();      emuThread->emuPause(); +    AudioInOut::Init(emuThread); +    ROMManager::EnableCheats(*emuThread->NDS, Config::EnableCheats != 0);      AudioInOut::AudioMute(mainWindow);      QObject::connect(&melon, &QApplication::applicationStateChanged, mainWindow, &MainWindow::onAppStateChanged); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 500aec1..72ebfb1 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -40,6 +40,11 @@  #include "FrontendUtil.h"  #include "duckstation/gl/context.h" +namespace melonDS +{ +class NDS; +} +  class EmuThread : public QThread  {      Q_OBJECT @@ -67,7 +72,8 @@ public:      QMutex FrontBufferLock;      void updateScreenSettings(bool filter, const WindowInfo& windowInfo, int numScreens, int* screenKind, float* screenMatrix); - +    void RecreateConsole(); +    std::unique_ptr<melonDS::NDS> NDS; // TODO: Proper encapsulation and synchronization  signals:      void windowUpdate();      void windowTitleChange(QString title); @@ -90,6 +96,7 @@ signals:      void syncVolumeLevel();  private: +    std::unique_ptr<melonDS::NDS> CreateConsole();      void drawScreenGL();      void initOpenGL();      void deinitOpenGL();  |