convert DSi I2C and camera

This commit is contained in:
Arisotura 2023-11-04 19:42:36 +01:00
parent 7837c169a1
commit 54ebf1b1b2
12 changed files with 400 additions and 367 deletions

View File

@ -79,6 +79,8 @@ std::unique_ptr<DSi_NAND::NANDImage> NANDImage;
DSi_SDHost* SDMMC; DSi_SDHost* SDMMC;
DSi_SDHost* SDIO; DSi_SDHost* SDIO;
DSi_I2CHost* I2C;
DSi_CamModule* CamModule;
DSi_AES* AES; DSi_AES* AES;
// FIXME: these currently have no effect (and aren't stored in a savestate) // FIXME: these currently have no effect (and aren't stored in a savestate)
@ -102,8 +104,6 @@ bool Init()
NWRAM_C = new u8[NWRAMSize]; NWRAM_C = new u8[NWRAMSize];
#endif #endif
if (!DSi_I2C::Init()) return false;
if (!DSi_CamModule::Init()) return false;
if (!DSi_DSP::Init()) return false; if (!DSi_DSP::Init()) return false;
NDMAs[0] = new DSi_NDMA(0, 0); NDMAs[0] = new DSi_NDMA(0, 0);
@ -118,6 +118,8 @@ bool Init()
SDMMC = new DSi_SDHost(0); SDMMC = new DSi_SDHost(0);
SDIO = new DSi_SDHost(1); SDIO = new DSi_SDHost(1);
I2C = new DSi_I2CHost();
CamModule = new DSi_CamModule();
AES = new DSi_AES(); AES = new DSi_AES();
return true; return true;
@ -135,8 +137,6 @@ void DeInit()
NWRAM_C = nullptr; NWRAM_C = nullptr;
#endif #endif
DSi_I2C::DeInit();
DSi_CamModule::DeInit();
DSi_DSP::DeInit(); DSi_DSP::DeInit();
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
@ -148,6 +148,8 @@ void DeInit()
delete SDMMC; SDMMC = nullptr; delete SDMMC; SDMMC = nullptr;
delete SDIO; SDIO = nullptr; delete SDIO; SDIO = nullptr;
delete I2C; I2C = nullptr;
delete CamModule; CamModule = nullptr;
delete AES; AES = nullptr; delete AES; AES = nullptr;
NANDImage = nullptr; NANDImage = nullptr;
@ -166,8 +168,8 @@ void Reset()
NDMACnt[0] = 0; NDMACnt[1] = 0; 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();
DSi_I2C::Reset(); I2C->Reset();
DSi_CamModule::Reset(); CamModule->Reset();
DSi_DSP::Reset(); DSi_DSP::Reset();
SDMMC->CloseHandles(); SDMMC->CloseHandles();
@ -210,7 +212,7 @@ void Reset()
void Stop() void Stop()
{ {
DSi_CamModule::Stop(); CamModule->Stop();
} }
void DoSavestate(Savestate* file) void DoSavestate(Savestate* file)
@ -285,9 +287,9 @@ void DoSavestate(Savestate* file)
NDMAs[i]->DoSavestate(file); NDMAs[i]->DoSavestate(file);
AES->DoSavestate(file); AES->DoSavestate(file);
DSi_CamModule::DoSavestate(file); CamModule->DoSavestate(file);
DSi_DSP::DoSavestate(file); DSi_DSP::DoSavestate(file);
DSi_I2C::DoSavestate(file); I2C->DoSavestate(file);
SDMMC->DoSavestate(file); SDMMC->DoSavestate(file);
SDIO->DoSavestate(file); SDIO->DoSavestate(file);
} }
@ -581,7 +583,7 @@ void SetupDirectBoot()
ARM9Write32(0x02FFFC00, cartid); ARM9Write32(0x02FFFC00, cartid);
ARM9Write16(0x02FFFC40, 0x0001); // boot indicator ARM9Write16(0x02FFFC40, 0x0001); // boot indicator
ARM9Write8(0x02FFFDFA, DSi_BPTWL::GetBootFlag() | 0x80); ARM9Write8(0x02FFFDFA, I2C->GetBPTWL()->GetBootFlag() | 0x80);
ARM9Write8(0x02FFFDFB, 0x01); ARM9Write8(0x02FFFDFB, 0x01);
} }
@ -2302,7 +2304,7 @@ u8 ARM9IORead8(u32 addr)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return 0; if (!(SCFG_EXT[0] & (1<<17))) return 0;
return DSi_CamModule::Read8(addr); return CamModule->Read8(addr);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2337,7 +2339,7 @@ u16 ARM9IORead16(u32 addr)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return 0; if (!(SCFG_EXT[0] & (1<<17))) return 0;
return DSi_CamModule::Read16(addr); return CamModule->Read16(addr);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2402,7 +2404,7 @@ u32 ARM9IORead32(u32 addr)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return 0; if (!(SCFG_EXT[0] & (1<<17))) return 0;
return DSi_CamModule::Read32(addr); return CamModule->Read32(addr);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2472,7 +2474,7 @@ void ARM9IOWrite8(u32 addr, u8 val)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return; if (!(SCFG_EXT[0] & (1<<17))) return;
return DSi_CamModule::Write8(addr, val); return CamModule->Write8(addr, val);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2532,7 +2534,7 @@ void ARM9IOWrite16(u32 addr, u16 val)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return; if (!(SCFG_EXT[0] & (1<<17))) return;
return DSi_CamModule::Write16(addr, val); return CamModule->Write16(addr, val);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2682,7 +2684,7 @@ void ARM9IOWrite32(u32 addr, u32 val)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return; if (!(SCFG_EXT[0] & (1<<17))) return;
return DSi_CamModule::Write32(addr, val); return CamModule->Write32(addr, val);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2715,8 +2717,8 @@ u8 ARM7IORead8(u32 addr)
CASE_READ8_32BIT(0x0400405C, MBK[1][7]) CASE_READ8_32BIT(0x0400405C, MBK[1][7])
CASE_READ8_32BIT(0x04004060, MBK[1][8]) CASE_READ8_32BIT(0x04004060, MBK[1][8])
case 0x04004500: return DSi_I2C::ReadData(); case 0x04004500: return I2C->ReadData();
case 0x04004501: return DSi_I2C::Cnt; case 0x04004501: return I2C->ReadCnt();
case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() & 0xFF; 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; case 0x04004D01: if (SCFG_BIOS & (1<<10)) return 0; return (NANDImage->GetConsoleID() >> 8) & 0xFF;
@ -2899,8 +2901,8 @@ void ARM7IOWrite8(u32 addr, u8 val)
return; return;
} }
case 0x04004500: DSi_I2C::WriteData(val); return; case 0x04004500: I2C->WriteData(val); return;
case 0x04004501: DSi_I2C::WriteCnt(val); return; case 0x04004501: I2C->WriteCnt(val); return;
case 0x4004700: case 0x4004700:
DSi_DSP::WriteSNDExCnt((u16)val | (DSi_DSP::SNDExCnt & 0xFF00)); DSi_DSP::WriteSNDExCnt((u16)val | (DSi_DSP::SNDExCnt & 0xFF00));

View File

@ -22,6 +22,8 @@
#include "NDS.h" #include "NDS.h"
#include "DSi_SD.h" #include "DSi_SD.h"
class DSi_I2CHost;
class DSi_CamModule;
class DSi_AES; class DSi_AES;
namespace DSi_NAND namespace DSi_NAND
@ -58,6 +60,8 @@ extern u32 NWRAMStart[2][3];
extern u32 NWRAMEnd[2][3]; extern u32 NWRAMEnd[2][3];
extern u32 NWRAMMask[2][3]; extern u32 NWRAMMask[2][3];
extern DSi_I2CHost* I2C;
extern DSi_CamModule* CamModule;
extern DSi_AES* AES; extern DSi_AES* AES;
bool Init(); bool Init();

View File

@ -25,48 +25,27 @@
using Platform::Log; using Platform::Log;
using Platform::LogLevel; using Platform::LogLevel;
namespace DSi_CamModule
{
Camera* Camera0; // 78 / facing outside
Camera* Camera1; // 7A / selfie cam
u16 ModuleCnt;
u16 Cnt;
u32 CropStart, CropEnd;
// pixel data buffer holds a maximum of 512 words, regardless of how long scanlines are
u32 DataBuffer[512];
u32 BufferReadPos, BufferWritePos;
u32 BufferNumLines;
Camera* CurCamera;
// note on camera data/etc intervals // note on camera data/etc intervals
// on hardware those are likely affected by several factors // on hardware those are likely affected by several factors
// namely, how long cameras take to process frames // namely, how long cameras take to process frames
// camera IRQ is fired at roughly 15FPS with default config // camera IRQ is fired at roughly 15FPS with default config
const u32 kIRQInterval = 1120000; // ~30 FPS const u32 DSi_CamModule::kIRQInterval = 1120000; // ~30 FPS
const u32 kTransferStart = 60000; const u32 DSi_CamModule::kTransferStart = 60000;
bool Init() DSi_CamModule::DSi_CamModule()
{ {
NDS::RegisterEventFunc(NDS::Event_DSi_CamIRQ, 0, IRQ); NDS::RegisterEventFunc(NDS::Event_DSi_CamIRQ, 0, MemberEventFunc(DSi_CamModule, IRQ));
NDS::RegisterEventFunc(NDS::Event_DSi_CamTransfer, 0, TransferScanline); NDS::RegisterEventFunc(NDS::Event_DSi_CamTransfer, 0, MemberEventFunc(DSi_CamModule, TransferScanline));
Camera0 = new Camera(0); Camera0 = DSi::I2C->GetOuterCamera();
Camera1 = new Camera(1); Camera1 = DSi::I2C->GetInnerCamera();
return true;
} }
void DeInit() DSi_CamModule::~DSi_CamModule()
{ {
delete Camera0;
delete Camera1;
Camera0 = nullptr; Camera0 = nullptr;
Camera1 = nullptr; Camera1 = nullptr;
@ -74,11 +53,8 @@ void DeInit()
NDS::UnregisterEventFunc(NDS::Event_DSi_CamTransfer, 0); NDS::UnregisterEventFunc(NDS::Event_DSi_CamTransfer, 0);
} }
void Reset() void DSi_CamModule::Reset()
{ {
Camera0->Reset();
Camera1->Reset();
ModuleCnt = 0; // CHECKME ModuleCnt = 0; // CHECKME
Cnt = 0; Cnt = 0;
@ -94,13 +70,13 @@ void Reset()
NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, false, kIRQInterval, 0, 0); NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, false, kIRQInterval, 0, 0);
} }
void Stop() void DSi_CamModule::Stop()
{ {
Camera0->Stop(); Camera0->Stop();
Camera1->Stop(); Camera1->Stop();
} }
void DoSavestate(Savestate* file) void DSi_CamModule::DoSavestate(Savestate* file)
{ {
file->Section("CAMi"); file->Section("CAMi");
@ -110,15 +86,12 @@ void DoSavestate(Savestate* file)
/*file->VarArray(FrameBuffer, sizeof(FrameBuffer)); /*file->VarArray(FrameBuffer, sizeof(FrameBuffer));
file->Var32(&TransferPos); file->Var32(&TransferPos);
file->Var32(&FrameLength);*/ file->Var32(&FrameLength);*/
Camera0->DoSavestate(file);
Camera1->DoSavestate(file);
} }
void IRQ(u32 param) void DSi_CamModule::IRQ(u32 param)
{ {
Camera* activecam = nullptr; DSi_Camera* activecam = nullptr;
// TODO: cameras don't have any priority! // TODO: cameras don't have any priority!
// activating both together will jumble the image data together // activating both together will jumble the image data together
@ -145,7 +118,7 @@ void IRQ(u32 param)
NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, 0, 0); NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, 0, 0);
} }
void TransferScanline(u32 line) void DSi_CamModule::TransferScanline(u32 line)
{ {
u32* dstbuf = &DataBuffer[BufferWritePos]; u32* dstbuf = &DataBuffer[BufferWritePos];
int maxlen = 512 - BufferWritePos; int maxlen = 512 - BufferWritePos;
@ -252,7 +225,7 @@ void TransferScanline(u32 line)
} }
u8 Read8(u32 addr) u8 DSi_CamModule::Read8(u32 addr)
{ {
// //
@ -260,7 +233,7 @@ u8 Read8(u32 addr)
return 0; return 0;
} }
u16 Read16(u32 addr) u16 DSi_CamModule::Read16(u32 addr)
{ {
switch (addr) switch (addr)
{ {
@ -272,7 +245,7 @@ u16 Read16(u32 addr)
return 0; return 0;
} }
u32 Read32(u32 addr) u32 DSi_CamModule::Read32(u32 addr)
{ {
switch (addr) switch (addr)
{ {
@ -298,14 +271,14 @@ u32 Read32(u32 addr)
return 0; return 0;
} }
void Write8(u32 addr, u8 val) void DSi_CamModule::Write8(u32 addr, u8 val)
{ {
// //
Log(LogLevel::Debug, "unknown DSi cam write8 %08X %02X\n", addr, val); Log(LogLevel::Debug, "unknown DSi cam write8 %08X %02X\n", addr, val);
} }
void Write16(u32 addr, u16 val) void DSi_CamModule::Write16(u32 addr, u16 val)
{ {
switch (addr) switch (addr)
{ {
@ -384,7 +357,7 @@ void Write16(u32 addr, u16 val)
Log(LogLevel::Debug, "unknown DSi cam write16 %08X %04X\n", addr, val); Log(LogLevel::Debug, "unknown DSi cam write16 %08X %04X\n", addr, val);
} }
void Write32(u32 addr, u32 val) void DSi_CamModule::Write32(u32 addr, u32 val)
{ {
switch (addr) switch (addr)
{ {
@ -403,16 +376,15 @@ void Write32(u32 addr, u32 val)
Camera::Camera(u32 num) DSi_Camera::DSi_Camera(DSi_I2CHost* host, u32 num) : DSi_I2CDevice(host), Num(num)
{
Num = num;
}
Camera::~Camera()
{ {
} }
void Camera::DoSavestate(Savestate* file) DSi_Camera::~DSi_Camera()
{
}
void DSi_Camera::DoSavestate(Savestate* file)
{ {
char magic[5] = "CAMx"; char magic[5] = "CAMx";
magic[3] = '0' + Num; magic[3] = '0' + Num;
@ -433,7 +405,7 @@ void Camera::DoSavestate(Savestate* file)
file->VarArray(MCURegs, 0x8000); file->VarArray(MCURegs, 0x8000);
} }
void Camera::Reset() void DSi_Camera::Reset()
{ {
Platform::Camera_Stop(Num); Platform::Camera_Stop(Num);
@ -458,12 +430,12 @@ void Camera::Reset()
memset(FrameBuffer, 0, (640*480/2)*sizeof(u32)); memset(FrameBuffer, 0, (640*480/2)*sizeof(u32));
} }
void Camera::Stop() void DSi_Camera::Stop()
{ {
Platform::Camera_Stop(Num); Platform::Camera_Stop(Num);
} }
bool Camera::IsActivated() bool DSi_Camera::IsActivated()
{ {
if (StandbyCnt & (1<<14)) return false; // standby if (StandbyCnt & (1<<14)) return false; // standby
if (!(MiscCnt & (1<<9))) return false; // data transfer not enabled if (!(MiscCnt & (1<<9))) return false; // data transfer not enabled
@ -472,7 +444,7 @@ bool Camera::IsActivated()
} }
void Camera::StartTransfer() void DSi_Camera::StartTransfer()
{ {
TransferY = 0; TransferY = 0;
@ -502,12 +474,12 @@ void Camera::StartTransfer()
Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true); Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true);
} }
bool Camera::TransferDone() bool DSi_Camera::TransferDone()
{ {
return TransferY >= FrameHeight; return TransferY >= FrameHeight;
} }
int Camera::TransferScanline(u32* buffer, int maxlen) int DSi_Camera::TransferScanline(u32* buffer, int maxlen)
{ {
if (TransferY >= FrameHeight) if (TransferY >= FrameHeight)
return 0; return 0;
@ -560,12 +532,12 @@ int Camera::TransferScanline(u32* buffer, int maxlen)
} }
void Camera::I2C_Start() void DSi_Camera::Acquire()
{ {
DataPos = 0; DataPos = 0;
} }
u8 Camera::I2C_Read(bool last) u8 DSi_Camera::Read(bool last)
{ {
u8 ret; u8 ret;
@ -586,7 +558,7 @@ u8 Camera::I2C_Read(bool last)
return ret; return ret;
} }
void Camera::I2C_Write(u8 val, bool last) void DSi_Camera::Write(u8 val, bool last)
{ {
if (DataPos < 2) if (DataPos < 2)
{ {
@ -615,7 +587,7 @@ void Camera::I2C_Write(u8 val, bool last)
else DataPos++; else DataPos++;
} }
u16 Camera::I2C_ReadReg(u16 addr) u16 DSi_Camera::I2C_ReadReg(u16 addr)
{ {
switch (addr) switch (addr)
{ {
@ -651,7 +623,7 @@ u16 Camera::I2C_ReadReg(u16 addr)
return 0; return 0;
} }
void Camera::I2C_WriteReg(u16 addr, u16 val) void DSi_Camera::I2C_WriteReg(u16 addr, u16 val)
{ {
switch (addr) switch (addr)
{ {
@ -720,14 +692,14 @@ void Camera::I2C_WriteReg(u16 addr, u16 val)
// TODO: not sure at all what is the accessible range // TODO: not sure at all what is the accessible range
// or if there is any overlap in the address range // or if there is any overlap in the address range
u8 Camera::MCU_Read(u16 addr) u8 DSi_Camera::MCU_Read(u16 addr)
{ {
addr &= 0x7FFF; addr &= 0x7FFF;
return MCURegs[addr]; return MCURegs[addr];
} }
void Camera::MCU_Write(u16 addr, u8 val) void DSi_Camera::MCU_Write(u16 addr, u8 val)
{ {
addr &= 0x7FFF; addr &= 0x7FFF;
@ -749,7 +721,7 @@ void Camera::MCU_Write(u16 addr, u8 val)
} }
void Camera::InputFrame(u32* data, int width, int height, bool rgb) void DSi_Camera::InputFrame(u32* data, int width, int height, bool rgb)
{ {
// TODO: double-buffering? // TODO: double-buffering?
@ -820,19 +792,3 @@ void Camera::InputFrame(u32* data, int width, int height, bool rgb)
} }
} }
} }
}

View File

@ -21,38 +21,15 @@
#include "types.h" #include "types.h"
#include "Savestate.h" #include "Savestate.h"
#include "DSi_I2C.h"
namespace DSi_CamModule class DSi_CamModule;
{
class Camera; class DSi_Camera : public DSi_I2CDevice
extern Camera* Camera0;
extern Camera* Camera1;
bool Init();
void DeInit();
void Reset();
void Stop();
void DoSavestate(Savestate* file);
void IRQ(u32 param);
void TransferScanline(u32 line);
u8 Read8(u32 addr);
u16 Read16(u32 addr);
u32 Read32(u32 addr);
void Write8(u32 addr, u8 val);
void Write16(u32 addr, u16 val);
void Write32(u32 addr, u32 val);
class Camera
{ {
public: public:
Camera(u32 num); DSi_Camera(DSi_I2CHost* host, u32 num);
~Camera(); ~DSi_Camera();
void DoSavestate(Savestate* file); void DoSavestate(Savestate* file);
@ -66,9 +43,9 @@ public:
// lengths in words // lengths in words
int TransferScanline(u32* buffer, int maxlen); int TransferScanline(u32* buffer, int maxlen);
void I2C_Start(); void Acquire();
u8 I2C_Read(bool last); u8 Read(bool last);
void I2C_Write(u8 val, bool last); void Write(u8 val, bool last);
void InputFrame(u32* data, int width, int height, bool rgb); void InputFrame(u32* data, int width, int height, bool rgb);
@ -101,6 +78,47 @@ private:
u32 FrameBuffer[640*480/2]; // YUYV framebuffer, two pixels per word u32 FrameBuffer[640*480/2]; // YUYV framebuffer, two pixels per word
}; };
}
class DSi_CamModule
{
public:
DSi_CamModule();
~DSi_CamModule();
void Reset();
void Stop();
void DoSavestate(Savestate* file);
DSi_Camera* GetOuterCamera() { return Camera0; }
DSi_Camera* GetInnerCamera() { return Camera1; }
void IRQ(u32 param);
void TransferScanline(u32 line);
u8 Read8(u32 addr);
u16 Read16(u32 addr);
u32 Read32(u32 addr);
void Write8(u32 addr, u8 val);
void Write16(u32 addr, u16 val);
void Write32(u32 addr, u32 val);
private:
DSi_Camera* Camera0; // 78 / facing outside
DSi_Camera* Camera1; // 7A / selfie cam
u16 ModuleCnt;
u16 Cnt;
u32 CropStart, CropEnd;
// pixel data buffer holds a maximum of 512 words, regardless of how long scanlines are
u32 DataBuffer[512];
u32 BufferReadPos, BufferWritePos;
u32 BufferNumLines;
DSi_Camera* CurCamera;
static const u32 kIRQInterval;
static const u32 kTransferStart;
};
#endif // DSI_CAMERA_H #endif // DSI_CAMERA_H

View File

@ -29,18 +29,16 @@
using Platform::Log; using Platform::Log;
using Platform::LogLevel; using Platform::LogLevel;
namespace DSi_BPTWL
{
// TODO: These are purely approximations // TODO: These are purely approximations
const double PowerButtonShutdownTime = 0.5; const double DSi_BPTWL::PowerButtonShutdownTime = 0.5;
const double PowerButtonForcedShutdownTime = 5.0; const double DSi_BPTWL::PowerButtonForcedShutdownTime = 5.0;
const double VolumeSwitchRepeatStart = 0.5; const double DSi_BPTWL::VolumeSwitchRepeatStart = 0.5;
const double VolumeSwitchRepeatRate = 1.0 / 6; const double DSi_BPTWL::VolumeSwitchRepeatRate = 1.0 / 6;
// Could not find a pattern or a decent formula for these, // Could not find a pattern or a decent formula for these,
// regardless, they're only 64 bytes in size // regardless, they're only 64 bytes in size
const u8 VolumeDownTable[32] = const u8 DSi_BPTWL::VolumeDownTable[32] =
{ {
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03,
0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0A,
@ -48,7 +46,7 @@ const u8 VolumeDownTable[32] =
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
}; };
const u8 VolumeUpTable[32] = const u8 DSi_BPTWL::VolumeUpTable[32] =
{ {
0x02, 0x03, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x02, 0x03, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
@ -56,27 +54,16 @@ const u8 VolumeUpTable[32] =
0x1D, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1D, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
}; };
double PowerButtonTime = 0.0;
bool PowerButtonDownFlag = false;
bool PowerButtonShutdownFlag = false;
double VolumeSwitchTime = 0.0;
double VolumeSwitchRepeatTime = 0.0;
bool VolumeSwitchDownFlag = false;
u32 VolumeSwitchKeysDown = 0;
u8 Registers[0x100]; DSi_BPTWL::DSi_BPTWL(DSi_I2CHost* host) : DSi_I2CDevice(host)
u32 CurPos;
bool Init()
{
return true;
}
void DeInit()
{ {
} }
void Reset() DSi_BPTWL::~DSi_BPTWL()
{
}
void DSi_BPTWL::Reset()
{ {
CurPos = -1; CurPos = -1;
memset(Registers, 0x5A, 0x100); memset(Registers, 0x5A, 0x100);
@ -115,10 +102,11 @@ void Reset()
VolumeSwitchTime = 0.0; VolumeSwitchTime = 0.0;
VolumeSwitchRepeatTime = 0.0; VolumeSwitchRepeatTime = 0.0;
VolumeSwitchKeysDown = 0; VolumeSwitchKeysDown = 0;
VolumeSwitchDownFlag = false;
} }
void DoSavestate(Savestate* file) void DSi_BPTWL::DoSavestate(Savestate* file)
{ {
file->Section("I2BP"); file->Section("I2BP");
@ -127,21 +115,21 @@ void DoSavestate(Savestate* file)
} }
// TODO: Needs more investigation on the other bits // TODO: Needs more investigation on the other bits
inline bool GetIRQMode() inline bool DSi_BPTWL::GetIRQMode()
{ {
return Registers[0x12] & 0x01; return Registers[0x12] & 0x01;
} }
u8 GetBootFlag() { return Registers[0x70]; } u8 DSi_BPTWL::GetBootFlag() { return Registers[0x70]; }
bool GetBatteryCharging() { return Registers[0x20] >> 7; } bool DSi_BPTWL::GetBatteryCharging() { return Registers[0x20] >> 7; }
void SetBatteryCharging(bool charging) void DSi_BPTWL::SetBatteryCharging(bool charging)
{ {
Registers[0x20] = (((charging ? 0x8 : 0x0) << 4) | (Registers[0x20] & 0x0F)); Registers[0x20] = (((charging ? 0x8 : 0x0) << 4) | (Registers[0x20] & 0x0F));
} }
u8 GetBatteryLevel() { return Registers[0x20] & 0xF; } u8 DSi_BPTWL::GetBatteryLevel() { return Registers[0x20] & 0xF; }
void SetBatteryLevel(u8 batteryLevel) void DSi_BPTWL::SetBatteryLevel(u8 batteryLevel)
{ {
Registers[0x20] = ((Registers[0x20] & 0xF0) | (batteryLevel & 0x0F)); Registers[0x20] = ((Registers[0x20] & 0xF0) | (batteryLevel & 0x0F));
//SPI_Powerman::SetBatteryLevelOkay(batteryLevel > batteryLevel_Low ? true : false); //SPI_Powerman::SetBatteryLevelOkay(batteryLevel > batteryLevel_Low ? true : false);
@ -153,20 +141,20 @@ void SetBatteryLevel(u8 batteryLevel)
} }
u8 GetVolumeLevel() { return Registers[0x40]; } u8 DSi_BPTWL::GetVolumeLevel() { return Registers[0x40]; }
void SetVolumeLevel(u8 volume) void DSi_BPTWL::SetVolumeLevel(u8 volume)
{ {
Registers[0x40] = volume & 0x1F; Registers[0x40] = volume & 0x1F;
} }
u8 GetBacklightLevel() { return Registers[0x41]; } u8 DSi_BPTWL::GetBacklightLevel() { return Registers[0x41]; }
void SetBacklightLevel(u8 backlight) void DSi_BPTWL::SetBacklightLevel(u8 backlight)
{ {
Registers[0x41] = backlight > 4 ? 4 : backlight; Registers[0x41] = backlight > 4 ? 4 : backlight;
} }
void ResetButtonState() void DSi_BPTWL::ResetButtonState()
{ {
PowerButtonTime = 0.0; PowerButtonTime = 0.0;
PowerButtonDownFlag = false; PowerButtonDownFlag = false;
@ -178,7 +166,7 @@ void ResetButtonState()
VolumeSwitchRepeatTime = 0.0; VolumeSwitchRepeatTime = 0.0;
} }
void DoHardwareReset(bool direct) void DSi_BPTWL::DoHardwareReset(bool direct)
{ {
ResetButtonState(); ResetButtonState();
@ -196,14 +184,14 @@ void DoHardwareReset(bool direct)
NDS::ARM7->Halt(4); NDS::ARM7->Halt(4);
} }
void DoShutdown() void DSi_BPTWL::DoShutdown()
{ {
ResetButtonState(); ResetButtonState();
NDS::Stop(Platform::StopReason::PowerOff); NDS::Stop(Platform::StopReason::PowerOff);
} }
void SetPowerButtonHeld(double time) void DSi_BPTWL::SetPowerButtonHeld(double time)
{ {
if (!PowerButtonDownFlag) if (!PowerButtonDownFlag)
{ {
@ -230,7 +218,7 @@ void SetPowerButtonHeld(double time)
} }
} }
void SetPowerButtonReleased(double time) void DSi_BPTWL::SetPowerButtonReleased(double time)
{ {
double elapsed = time - PowerButtonTime; double elapsed = time - PowerButtonTime;
if (elapsed >= 0 && elapsed < PowerButtonShutdownTime) if (elapsed >= 0 && elapsed < PowerButtonShutdownTime)
@ -243,12 +231,12 @@ void SetPowerButtonReleased(double time)
PowerButtonShutdownFlag = false; PowerButtonShutdownFlag = false;
} }
void SetVolumeSwitchHeld(u32 key) void DSi_BPTWL::SetVolumeSwitchHeld(u32 key)
{ {
VolumeSwitchKeysDown |= (1 << key); VolumeSwitchKeysDown |= (1 << key);
} }
void SetVolumeSwitchReleased(u32 key) void DSi_BPTWL::SetVolumeSwitchReleased(u32 key)
{ {
VolumeSwitchKeysDown &= ~(1 << key); VolumeSwitchKeysDown &= ~(1 << key);
VolumeSwitchDownFlag = false; VolumeSwitchDownFlag = false;
@ -256,7 +244,7 @@ void SetVolumeSwitchReleased(u32 key)
VolumeSwitchRepeatTime = 0.0; VolumeSwitchRepeatTime = 0.0;
} }
inline bool CheckVolumeSwitchKeysValid() inline bool DSi_BPTWL::CheckVolumeSwitchKeysValid()
{ {
bool up = VolumeSwitchKeysDown & (1 << volumeKey_Up); bool up = VolumeSwitchKeysDown & (1 << volumeKey_Up);
bool down = VolumeSwitchKeysDown & (1 << volumeKey_Down); bool down = VolumeSwitchKeysDown & (1 << volumeKey_Down);
@ -264,7 +252,7 @@ inline bool CheckVolumeSwitchKeysValid()
return up != down; return up != down;
} }
s32 ProcessVolumeSwitchInput(double time) s32 DSi_BPTWL::ProcessVolumeSwitchInput(double time)
{ {
if (!CheckVolumeSwitchKeysValid()) if (!CheckVolumeSwitchKeysValid())
return -1; return -1;
@ -303,7 +291,7 @@ s32 ProcessVolumeSwitchInput(double time)
} }
void DoPowerButtonPress() void DSi_BPTWL::DoPowerButtonPress()
{ {
// Set button pressed IRQ // Set button pressed IRQ
SetIRQ(IRQ_PowerButtonPressed); SetIRQ(IRQ_PowerButtonPressed);
@ -311,7 +299,7 @@ void DoPowerButtonPress()
// There is no default hardware behavior for pressing the power button // There is no default hardware behavior for pressing the power button
} }
void DoPowerButtonReset() void DSi_BPTWL::DoPowerButtonReset()
{ {
// Reset via IRQ, handled by software // Reset via IRQ, handled by software
SetIRQ(IRQ_PowerButtonReset); SetIRQ(IRQ_PowerButtonReset);
@ -324,7 +312,7 @@ void DoPowerButtonReset()
} }
} }
void DoPowerButtonShutdown() void DSi_BPTWL::DoPowerButtonShutdown()
{ {
// Shutdown via IRQ, handled by software // Shutdown via IRQ, handled by software
if (!PowerButtonShutdownFlag) if (!PowerButtonShutdownFlag)
@ -346,12 +334,12 @@ void DoPowerButtonShutdown()
// down the power button, the DSi will still shut down // down the power button, the DSi will still shut down
} }
void DoPowerButtonForceShutdown() void DSi_BPTWL::DoPowerButtonForceShutdown()
{ {
DoShutdown(); DoShutdown();
} }
void DoVolumeSwitchPress(u32 key) void DSi_BPTWL::DoVolumeSwitchPress(u32 key)
{ {
u8 volume = Registers[0x40]; u8 volume = Registers[0x40];
@ -373,7 +361,7 @@ void DoVolumeSwitchPress(u32 key)
SetIRQ(IRQ_VolumeSwitchPressed); SetIRQ(IRQ_VolumeSwitchPressed);
} }
void SetIRQ(u8 irqFlag) void DSi_BPTWL::SetIRQ(u8 irqFlag)
{ {
Registers[0x10] |= irqFlag & IRQ_ValidMask; Registers[0x10] |= irqFlag & IRQ_ValidMask;
@ -383,12 +371,12 @@ void SetIRQ(u8 irqFlag)
} }
} }
void Start() void DSi_BPTWL::Acquire()
{ {
//printf("BPTWL: start\n"); //printf("BPTWL: start\n");
} }
u8 Read(bool last) u8 DSi_BPTWL::Read(bool last)
{ {
//printf("BPTWL: read %02X -> %02X @ %08X\n", CurPos, Registers[CurPos], NDS::GetPC(1)); //printf("BPTWL: read %02X -> %02X @ %08X\n", CurPos, Registers[CurPos], NDS::GetPC(1));
u8 ret = Registers[CurPos]; u8 ret = Registers[CurPos];
@ -409,7 +397,7 @@ u8 Read(bool last)
return ret; return ret;
} }
void Write(u8 val, bool last) void DSi_BPTWL::Write(u8 val, bool last)
{ {
if (last) if (last)
{ {
@ -460,51 +448,69 @@ void Write(u8 val, bool last)
CurPos++; // CHECKME CurPos++; // CHECKME
} }
DSi_I2CHost::DSi_I2CHost()
{
BPTWL = new DSi_BPTWL(this);
Camera0 = new DSi_Camera(this, 0);
Camera1 = new DSi_Camera(this, 1);
} }
DSi_I2CHost::~DSi_I2CHost()
namespace DSi_I2C
{ {
delete BPTWL; BPTWL = nullptr;
u8 Cnt; delete Camera0; Camera0 = nullptr;
u8 Data; delete Camera1; Camera1 = nullptr;
u32 Device;
bool Init()
{
if (!DSi_BPTWL::Init()) return false;
return true;
} }
void DeInit() void DSi_I2CHost::Reset()
{
DSi_BPTWL::DeInit();
}
void Reset()
{ {
Cnt = 0; Cnt = 0;
Data = 0; Data = 0;
Device = -1; CurDeviceID = 0;
CurDevice = nullptr;
DSi_BPTWL::Reset(); BPTWL->Reset();
Camera0->Reset();
Camera1->Reset();
} }
void DoSavestate(Savestate* file) void DSi_I2CHost::DoSavestate(Savestate* file)
{ {
file->Section("I2Ci"); file->Section("I2Ci");
file->Var8(&Cnt); file->Var8(&Cnt);
file->Var8(&Data); file->Var8(&Data);
file->Var32(&Device); file->Var8(&CurDeviceID);
DSi_BPTWL::DoSavestate(file); if (!file->Saving)
{
GetCurDevice();
}
BPTWL->DoSavestate(file);
Camera0->DoSavestate(file);
Camera1->DoSavestate(file);
} }
void WriteCnt(u8 val) void DSi_I2CHost::GetCurDevice()
{
switch (CurDeviceID)
{
case 0x4A: CurDevice = BPTWL; break;
case 0x78: CurDevice = Camera0; break;
case 0x7A: CurDevice = Camera1; break;
case 0xA0:
case 0xE0: CurDevice = nullptr; break;
default:
Log(LogLevel::Warn, "I2C: unknown device %02X\n", CurDeviceID);
CurDevice = nullptr;
break;
}
}
void DSi_I2CHost::WriteCnt(u8 val)
{ {
//printf("I2C: write CNT %02X, %02X, %08X\n", val, Data, NDS::GetPC(1)); //printf("I2C: write CNT %02X, %02X, %08X\n", val, Data, NDS::GetPC(1));
@ -522,17 +528,13 @@ void WriteCnt(u8 val)
// read // read
val &= 0xF7; val &= 0xF7;
switch (Device) if (CurDevice)
{
Data = CurDevice->Read(islast);
}
else
{ {
case 0x4A: Data = DSi_BPTWL::Read(islast); break;
case 0x78: Data = DSi_CamModule::Camera0->I2C_Read(islast); break;
case 0x7A: Data = DSi_CamModule::Camera1->I2C_Read(islast); break;
case 0xA0:
case 0xE0: Data = 0xFF; break;
default:
Log(LogLevel::Warn, "I2C: read on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, 0, islast);
Data = 0xFF; Data = 0xFF;
break;
} }
//printf("I2C read, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); //printf("I2C read, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
@ -545,37 +547,30 @@ void WriteCnt(u8 val)
if (val & (1<<1)) if (val & (1<<1))
{ {
Device = Data & 0xFE; CurDeviceID = Data & 0xFE;
//printf("I2C: %s start, device=%02X\n", (Data&0x01)?"read":"write", Device); //printf("I2C: %s start, device=%02X\n", (Data&0x01)?"read":"write", Device);
switch (Device) GetCurDevice();
if (CurDevice)
{
CurDevice->Acquire();
}
else
{ {
case 0x4A: DSi_BPTWL::Start(); break;
case 0x78: DSi_CamModule::Camera0->I2C_Start(); break;
case 0x7A: DSi_CamModule::Camera1->I2C_Start(); break;
case 0xA0:
case 0xE0: ack = false; break;
default:
Log(LogLevel::Warn, "I2C: %s start on unknown device %02X\n", (Data&0x01)?"read":"write", Device);
ack = false; ack = false;
break;
} }
} }
else else
{ {
//printf("I2C write, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); //printf("I2C write, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
switch (Device) if (CurDevice)
{
CurDevice->Write(Data, islast);
}
else
{ {
case 0x4A: DSi_BPTWL::Write(Data, islast); break;
case 0x78: DSi_CamModule::Camera0->I2C_Write(Data, islast); break;
case 0x7A: DSi_CamModule::Camera1->I2C_Write(Data, islast); break;
case 0xA0:
case 0xE0: ack = false; break;
default:
Log(LogLevel::Warn, "I2C: write on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
ack = false; ack = false;
break;
} }
} }
@ -588,14 +583,12 @@ void WriteCnt(u8 val)
Cnt = val; Cnt = val;
} }
u8 ReadData() u8 DSi_I2CHost::ReadData()
{ {
return Data; return Data;
} }
void WriteData(u8 val) void DSi_I2CHost::WriteData(u8 val)
{ {
Data = val; Data = val;
} }
}

View File

@ -22,95 +22,162 @@
#include "types.h" #include "types.h"
#include "Savestate.h" #include "Savestate.h"
namespace DSi_BPTWL class DSi_I2CHost;
class DSi_Camera;
class DSi_I2CDevice
{ {
public:
DSi_I2CDevice(DSi_I2CHost* host) : Host(host) {}
virtual ~DSi_I2CDevice() {}
virtual void Reset() = 0;
virtual void DoSavestate(Savestate* file) = 0;
u8 GetBootFlag(); virtual void Acquire() = 0;
virtual u8 Read(bool last) = 0;
virtual void Write(u8 val, bool last) = 0;
bool GetBatteryCharging(); protected:
void SetBatteryCharging(bool charging); DSi_I2CHost* Host;
enum
{
batteryLevel_Critical = 0x0,
batteryLevel_AlmostEmpty = 0x1,
batteryLevel_Low = 0x3,
batteryLevel_Half = 0x7,
batteryLevel_ThreeQuarters = 0xB,
batteryLevel_Full = 0xF
}; };
u8 GetBatteryLevel(); class DSi_BPTWL : public DSi_I2CDevice
void SetBatteryLevel(u8 batteryLevel);
// 0-31
u8 GetVolumeLevel();
void SetVolumeLevel(u8 volume);
// 0-4
u8 GetBacklightLevel();
void SetBacklightLevel(u8 backlight);
void DoHardwareReset(bool direct);
void DoShutdown();
enum
{ {
volumeKey_Up, public:
volumeKey_Down,
enum
{
batteryLevel_Critical = 0x0,
batteryLevel_AlmostEmpty = 0x1,
batteryLevel_Low = 0x3,
batteryLevel_Half = 0x7,
batteryLevel_ThreeQuarters = 0xB,
batteryLevel_Full = 0xF
};
enum
{
volumeKey_Up,
volumeKey_Down,
};
enum
{
IRQ_PowerButtonReset = 0x01, // Triggered after releasing the power button quickly
IRQ_PowerButtonShutdown = 0x02, // Triggered after holding the power button for less than a second
IRQ_PowerButtonPressed = 0x08, // Triggered after pressing the power button
IRQ_BatteryEmpty = 0x10, //
IRQ_BatteryLow = 0x20, // Triggered when the battery level reaches 1
IRQ_VolumeSwitchPressed = 0x40, // Triggered once when the volume sliders are first pressed and repeatedly when held down
/*
Bit 2 (0x04) could be set when holding the power button for more than 5 seconds? (forced power off)
It is unknown whether it is set as the console powers off immediately.
Bit 7 (0x80) is unused?
Both bits are never used by the official ARM7 libraries, but could have some undocumented hardware functionality (?).
*/
IRQ_ValidMask = 0x7B,
};
DSi_BPTWL(DSi_I2CHost* host);
~DSi_BPTWL() override;
void Reset() override;
void DoSavestate(Savestate* file) override;
u8 GetBootFlag();
bool GetBatteryCharging();
void SetBatteryCharging(bool charging);
u8 GetBatteryLevel();
void SetBatteryLevel(u8 batteryLevel);
// 0-31
u8 GetVolumeLevel();
void SetVolumeLevel(u8 volume);
// 0-4
u8 GetBacklightLevel();
void SetBacklightLevel(u8 backlight);
void DoHardwareReset(bool direct);
void DoShutdown();
// Used by hotkeys
void SetPowerButtonHeld(double time);
void SetPowerButtonReleased(double time);
void SetVolumeSwitchHeld(u32 key);
void SetVolumeSwitchReleased(u32 key);
s32 ProcessVolumeSwitchInput(double time);
void DoPowerButtonPress();
void DoPowerButtonReset();
void DoPowerButtonShutdown();
void DoPowerButtonForceShutdown();
void DoVolumeSwitchPress(u32 key);
void SetIRQ(u8 irqFlag);
void Acquire() override;
u8 Read(bool last) override;
void Write(u8 val, bool last) override;
private:
static const double PowerButtonShutdownTime;
static const double PowerButtonForcedShutdownTime;
static const double VolumeSwitchRepeatStart;
static const double VolumeSwitchRepeatRate;
static const u8 VolumeDownTable[32];
static const u8 VolumeUpTable[32];
double PowerButtonTime;
bool PowerButtonDownFlag;
bool PowerButtonShutdownFlag;
double VolumeSwitchTime;
double VolumeSwitchRepeatTime;
bool VolumeSwitchDownFlag ;
u32 VolumeSwitchKeysDown;
u8 Registers[0x100];
u32 CurPos;
bool GetIRQMode();
void ResetButtonState();
bool CheckVolumeSwitchKeysValid();
}; };
// Used by hotkeys
void SetPowerButtonHeld(double time);
void SetPowerButtonReleased(double time);
void SetVolumeSwitchHeld(u32 key);
void SetVolumeSwitchReleased(u32 key);
s32 ProcessVolumeSwitchInput(double time);
void DoPowerButtonPress(); class DSi_I2CHost
void DoPowerButtonReset();
void DoPowerButtonShutdown();
void DoPowerButtonForceShutdown();
void DoVolumeSwitchPress(u32 key);
enum
{ {
IRQ_PowerButtonReset = 0x01, // Triggered after releasing the power button quickly public:
IRQ_PowerButtonShutdown = 0x02, // Triggered after holding the power button for less than a second DSi_I2CHost();
IRQ_PowerButtonPressed = 0x08, // Triggered after pressing the power button ~DSi_I2CHost();
IRQ_BatteryEmpty = 0x10, // void Reset();
IRQ_BatteryLow = 0x20, // Triggered when the battery level reaches 1 void DoSavestate(Savestate* file);
IRQ_VolumeSwitchPressed = 0x40, // Triggered once when the volume sliders are first pressed and repeatedly when held down
/* DSi_BPTWL* GetBPTWL() { return BPTWL; }
Bit 2 (0x04) could be set when holding the power button for more than 5 seconds? (forced power off) DSi_Camera* GetOuterCamera() { return Camera0; }
It is unknown whether it is set as the console powers off immediately. DSi_Camera* GetInnerCamera() { return Camera1; }
Bit 7 (0x80) is unused?
Both bits are never used by the official ARM7 libraries, but could have some undocumented hardware functionality (?). u8 ReadCnt() { return Cnt; }
*/ void WriteCnt(u8 val);
IRQ_ValidMask = 0x7B,
u8 ReadData();
void WriteData(u8 val);
private:
u8 Cnt;
u8 Data;
DSi_BPTWL* BPTWL; // 4A / BPTWL IC
DSi_Camera* Camera0; // 78 / facing outside
DSi_Camera* Camera1; // 7A / selfie cam
u8 CurDeviceID;
DSi_I2CDevice* CurDevice;
void GetCurDevice();
}; };
void SetIRQ(u8 irqFlag);
}
namespace DSi_I2C
{
extern u8 Cnt;
bool Init();
void DeInit();
void Reset();
void DoSavestate(Savestate* file);
void WriteCnt(u8 val);
u8 ReadData();
void WriteData(u8 val);
//void TransferDone(u32 param);
}
#endif // DSI_I2C_H #endif // DSI_I2C_H

View File

@ -1365,8 +1365,8 @@ void CamInputFrame(int cam, u32* data, int width, int height, bool rgb)
{ {
switch (cam) switch (cam)
{ {
case 0: return DSi_CamModule::Camera0->InputFrame(data, width, height, rgb); case 0: return DSi::CamModule->GetOuterCamera()->InputFrame(data, width, height, rgb);
case 1: return DSi_CamModule::Camera1->InputFrame(data, width, height, rgb); case 1: return DSi::CamModule->GetInnerCamera()->InputFrame(data, width, height, rgb);
} }
} }
} }

View File

@ -46,9 +46,7 @@ class SPIDevice
public: public:
SPIDevice(SPIHost* host) : Host(host), Hold(false), DataPos(0) {} SPIDevice(SPIHost* host) : Host(host), Hold(false), DataPos(0) {}
virtual ~SPIDevice() {} virtual ~SPIDevice() {}
virtual void Reset() = 0; virtual void Reset() = 0;
virtual void DoSavestate(Savestate* file) = 0; virtual void DoSavestate(Savestate* file) = 0;
virtual u8 Read() { return Data; } virtual u8 Read() { return Data; }
@ -68,9 +66,7 @@ class FirmwareMem : public SPIDevice
public: public:
FirmwareMem(SPIHost* host); FirmwareMem(SPIHost* host);
~FirmwareMem() override; ~FirmwareMem() override;
void Reset() override; void Reset() override;
void DoSavestate(Savestate* file) override; void DoSavestate(Savestate* file) override;
void SetupDirectBoot(bool dsi); void SetupDirectBoot(bool dsi);
@ -100,9 +96,7 @@ class PowerMan : public SPIDevice
public: public:
PowerMan(SPIHost* host); PowerMan(SPIHost* host);
~PowerMan() override; ~PowerMan() override;
void Reset() override; void Reset() override;
void DoSavestate(Savestate* file) override; void DoSavestate(Savestate* file) override;
bool GetBatteryLevelOkay(); bool GetBatteryLevelOkay();
@ -122,9 +116,7 @@ class TSC : public SPIDevice
public: public:
TSC(SPIHost* host); TSC(SPIHost* host);
virtual ~TSC() override; virtual ~TSC() override;
virtual void Reset() override; virtual void Reset() override;
virtual void DoSavestate(Savestate* file) override; virtual void DoSavestate(Savestate* file) override;
virtual void SetTouchCoords(u16 x, u16 y); virtual void SetTouchCoords(u16 x, u16 y);
@ -149,9 +141,7 @@ class SPIHost
public: public:
SPIHost(); SPIHost();
~SPIHost(); ~SPIHost();
void Reset(); void Reset();
void DoSavestate(Savestate* file); void DoSavestate(Savestate* file);
FirmwareMem* GetFirmwareMem() { return (FirmwareMem*)Devices[SPIDevice_FirmwareMem]; } FirmwareMem* GetFirmwareMem() { return (FirmwareMem*)Devices[SPIDevice_FirmwareMem]; }

View File

@ -24,6 +24,7 @@
#include "Platform.h" #include "Platform.h"
#include "Config.h" #include "Config.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h"
#include "DSi_I2C.h" #include "DSi_I2C.h"
#include "AudioSettingsDialog.h" #include "AudioSettingsDialog.h"
@ -126,7 +127,7 @@ void AudioSettingsDialog::onSyncVolumeLevel()
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
bool state = ui->slVolume->blockSignals(true); bool state = ui->slVolume->blockSignals(true);
ui->slVolume->setValue(DSi_BPTWL::GetVolumeLevel()); ui->slVolume->setValue(DSi::I2C->GetBPTWL()->GetVolumeLevel());
ui->slVolume->blockSignals(state); ui->slVolume->blockSignals(state);
} }
} }
@ -181,7 +182,7 @@ void AudioSettingsDialog::on_slVolume_valueChanged(int val)
{ {
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
DSi_BPTWL::SetVolumeLevel(val); DSi::I2C->GetBPTWL()->SetVolumeLevel(val);
return; return;
} }
@ -196,7 +197,7 @@ void AudioSettingsDialog::on_chkSyncDSiVolume_clicked(bool checked)
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
ui->slVolume->setMaximum(31); ui->slVolume->setMaximum(31);
ui->slVolume->setValue(DSi_BPTWL::GetVolumeLevel()); ui->slVolume->setValue(DSi::I2C->GetBPTWL()->GetVolumeLevel());
ui->slVolume->setPageStep(4); ui->slVolume->setPageStep(4);
ui->slVolume->setTickPosition(QSlider::TicksBelow); ui->slVolume->setTickPosition(QSlider::TicksBelow);
} }

View File

@ -22,6 +22,7 @@
#include "SPI.h" #include "SPI.h"
#include "DSi_I2C.h" #include "DSi_I2C.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h"
#include "Config.h" #include "Config.h"
#include "Platform.h" #include "Platform.h"
@ -42,8 +43,8 @@ PowerManagementDialog::PowerManagementDialog(QWidget* parent) : QDialog(parent),
{ {
ui->grpDSBattery->setEnabled(false); ui->grpDSBattery->setEnabled(false);
oldDSiBatteryLevel = DSi_BPTWL::GetBatteryLevel(); oldDSiBatteryLevel = DSi::I2C->GetBPTWL()->GetBatteryLevel();
oldDSiBatteryCharging = DSi_BPTWL::GetBatteryCharging(); oldDSiBatteryCharging = DSi::I2C->GetBPTWL()->GetBatteryCharging();
} }
else else
{ {
@ -54,9 +55,9 @@ PowerManagementDialog::PowerManagementDialog(QWidget* parent) : QDialog(parent),
updateDSBatteryLevelControls(); updateDSBatteryLevelControls();
ui->cbDSiBatteryCharging->setChecked(DSi_BPTWL::GetBatteryCharging()); ui->cbDSiBatteryCharging->setChecked(DSi::I2C->GetBPTWL()->GetBatteryCharging());
int dsiBatterySliderPos; int dsiBatterySliderPos;
switch (DSi_BPTWL::GetBatteryLevel()) switch (DSi::I2C->GetBPTWL()->GetBatteryLevel())
{ {
case DSi_BPTWL::batteryLevel_AlmostEmpty: dsiBatterySliderPos = 0; break; case DSi_BPTWL::batteryLevel_AlmostEmpty: dsiBatterySliderPos = 0; break;
case DSi_BPTWL::batteryLevel_Low: dsiBatterySliderPos = 1; break; case DSi_BPTWL::batteryLevel_Low: dsiBatterySliderPos = 1; break;
@ -86,8 +87,8 @@ void PowerManagementDialog::done(int r)
{ {
if (NDS::ConsoleType == 1) if (NDS::ConsoleType == 1)
{ {
Config::DSiBatteryLevel = DSi_BPTWL::GetBatteryLevel(); Config::DSiBatteryLevel = DSi::I2C->GetBPTWL()->GetBatteryLevel();
Config::DSiBatteryCharging = DSi_BPTWL::GetBatteryCharging(); Config::DSiBatteryCharging = DSi::I2C->GetBPTWL()->GetBatteryCharging();
} }
else else
{ {
@ -98,8 +99,8 @@ void PowerManagementDialog::done(int r)
{ {
if (NDS::ConsoleType == 1) if (NDS::ConsoleType == 1)
{ {
DSi_BPTWL::SetBatteryLevel(oldDSiBatteryLevel); DSi::I2C->GetBPTWL()->SetBatteryLevel(oldDSiBatteryLevel);
DSi_BPTWL::SetBatteryCharging(oldDSiBatteryCharging); DSi::I2C->GetBPTWL()->SetBatteryCharging(oldDSiBatteryCharging);
} }
else else
{ {
@ -132,7 +133,7 @@ void PowerManagementDialog::updateDSBatteryLevelControls()
void PowerManagementDialog::on_cbDSiBatteryCharging_toggled() void PowerManagementDialog::on_cbDSiBatteryCharging_toggled()
{ {
DSi_BPTWL::SetBatteryCharging(ui->cbDSiBatteryCharging->isChecked()); DSi::I2C->GetBPTWL()->SetBatteryCharging(ui->cbDSiBatteryCharging->isChecked());
} }
void PowerManagementDialog::on_sliderDSiBatteryLevel_valueChanged(int value) void PowerManagementDialog::on_sliderDSiBatteryLevel_valueChanged(int value)
@ -142,13 +143,13 @@ void PowerManagementDialog::on_sliderDSiBatteryLevel_valueChanged(int value)
u8 newBatteryLevel; u8 newBatteryLevel;
switch (value) switch (value)
{ {
case 0: newBatteryLevel = DSi_BPTWL::batteryLevel_AlmostEmpty; break; case 0: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_AlmostEmpty; break;
case 1: newBatteryLevel = DSi_BPTWL::batteryLevel_Low; break; case 1: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Low; break;
case 2: newBatteryLevel = DSi_BPTWL::batteryLevel_Half; break; case 2: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Half; break;
case 3: newBatteryLevel = DSi_BPTWL::batteryLevel_ThreeQuarters; break; case 3: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_ThreeQuarters; break;
case 4: newBatteryLevel = DSi_BPTWL::batteryLevel_Full; break; case 4: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Full; break;
} }
DSi_BPTWL::SetBatteryLevel(newBatteryLevel); DSi::I2C->GetBPTWL()->SetBatteryLevel(newBatteryLevel);
updateDSBatteryLevelControls(); updateDSBatteryLevelControls();
} }

View File

@ -583,8 +583,8 @@ void SetBatteryLevels()
{ {
if (NDS::ConsoleType == 1) if (NDS::ConsoleType == 1)
{ {
DSi_BPTWL::SetBatteryLevel(Config::DSiBatteryLevel); DSi::I2C->GetBPTWL()->SetBatteryLevel(Config::DSiBatteryLevel);
DSi_BPTWL::SetBatteryCharging(Config::DSiBatteryCharging); DSi::I2C->GetBPTWL()->SetBatteryCharging(Config::DSiBatteryCharging);
} }
else else
{ {

View File

@ -90,8 +90,9 @@
#include "Platform.h" #include "Platform.h"
#include "LocalMP.h" #include "LocalMP.h"
#include "Config.h" #include "Config.h"
#include "DSi_I2C.h"
#include "RTC.h" #include "RTC.h"
#include "DSi.h"
#include "DSi_I2C.h"
#include "Savestate.h" #include "Savestate.h"
@ -409,33 +410,33 @@ void EmuThread::run()
// Handle power button // Handle power button
if (Input::HotkeyDown(HK_PowerButton)) if (Input::HotkeyDown(HK_PowerButton))
{ {
DSi_BPTWL::SetPowerButtonHeld(currentTime); DSi::I2C->GetBPTWL()->SetPowerButtonHeld(currentTime);
} }
else if (Input::HotkeyReleased(HK_PowerButton)) else if (Input::HotkeyReleased(HK_PowerButton))
{ {
DSi_BPTWL::SetPowerButtonReleased(currentTime); DSi::I2C->GetBPTWL()->SetPowerButtonReleased(currentTime);
} }
// Handle volume buttons // Handle volume buttons
if (Input::HotkeyDown(HK_VolumeUp)) if (Input::HotkeyDown(HK_VolumeUp))
{ {
DSi_BPTWL::SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Up); DSi::I2C->GetBPTWL()->SetVolumeSwitchHeld(DSi::I2C->GetBPTWL()->volumeKey_Up);
} }
else if (Input::HotkeyReleased(HK_VolumeUp)) else if (Input::HotkeyReleased(HK_VolumeUp))
{ {
DSi_BPTWL::SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Up); DSi::I2C->GetBPTWL()->SetVolumeSwitchReleased(DSi::I2C->GetBPTWL()->volumeKey_Up);
} }
if (Input::HotkeyDown(HK_VolumeDown)) if (Input::HotkeyDown(HK_VolumeDown))
{ {
DSi_BPTWL::SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Down); DSi::I2C->GetBPTWL()->SetVolumeSwitchHeld(DSi::I2C->GetBPTWL()->volumeKey_Down);
} }
else if (Input::HotkeyReleased(HK_VolumeDown)) else if (Input::HotkeyReleased(HK_VolumeDown))
{ {
DSi_BPTWL::SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Down); DSi::I2C->GetBPTWL()->SetVolumeSwitchReleased(DSi::I2C->GetBPTWL()->volumeKey_Down);
} }
DSi_BPTWL::ProcessVolumeSwitchInput(currentTime); DSi::I2C->GetBPTWL()->ProcessVolumeSwitchInput(currentTime);
} }
if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep) if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep)
@ -562,7 +563,7 @@ void EmuThread::run()
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
u8 volumeLevel = DSi_BPTWL::GetVolumeLevel(); u8 volumeLevel = DSi::I2C->GetBPTWL()->GetVolumeLevel();
if (volumeLevel != dsiVolumeLevel) if (volumeLevel != dsiVolumeLevel)
{ {
dsiVolumeLevel = volumeLevel; dsiVolumeLevel = volumeLevel;