diff --git a/src/DSi.cpp b/src/DSi.cpp index 638ecdc9..cde86bae 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -94,6 +94,7 @@ bool Init() #endif if (!DSi_I2C::Init()) return false; + if (!DSi_CamModule::Init()) return false; if (!DSi_AES::Init()) return false; if (!DSi_DSP::Init()) return false; @@ -121,6 +122,7 @@ void DeInit() #endif DSi_I2C::DeInit(); + DSi_CamModule::DeInit(); DSi_AES::DeInit(); DSi_DSP::DeInit(); @@ -142,6 +144,7 @@ void Reset() for (int i = 0; i < 8; i++) NDMAs[i]->Reset(); DSi_I2C::Reset(); + DSi_CamModule::Reset(); DSi_DSP::Reset(); SDMMC->CloseHandles(); @@ -241,7 +244,7 @@ void DoSavestate(Savestate* file) NDMAs[i]->DoSavestate(file); DSi_AES::DoSavestate(file); - DSi_Camera::DoSavestate(file); + DSi_CamModule::DoSavestate(file); DSi_DSP::DoSavestate(file); DSi_I2C::DoSavestate(file); SDMMC->DoSavestate(file); @@ -2233,7 +2236,7 @@ u8 ARM9IORead8(u32 addr) if ((addr & 0xFFFFFF00) == 0x04004200) { if (!(SCFG_EXT[0] & (1<<17))) return 0; - return DSi_Camera::Read8(addr); + return DSi_CamModule::Read8(addr); } if (addr >= 0x04004300 && addr <= 0x04004400) @@ -2265,7 +2268,7 @@ u16 ARM9IORead16(u32 addr) if ((addr & 0xFFFFFF00) == 0x04004200) { if (!(SCFG_EXT[0] & (1<<17))) return 0; - return DSi_Camera::Read16(addr); + return DSi_CamModule::Read16(addr); } if (addr >= 0x04004300 && addr <= 0x04004400) @@ -2327,7 +2330,7 @@ u32 ARM9IORead32(u32 addr) if ((addr & 0xFFFFFF00) == 0x04004200) { if (!(SCFG_EXT[0] & (1<<17))) return 0; - return DSi_Camera::Read32(addr); + return DSi_CamModule::Read32(addr); } return NDS::ARM9IORead32(addr); @@ -2391,7 +2394,7 @@ void ARM9IOWrite8(u32 addr, u8 val) if ((addr & 0xFFFFFF00) == 0x04004200) { if (!(SCFG_EXT[0] & (1<<17))) return; - return DSi_Camera::Write8(addr, val); + return DSi_CamModule::Write8(addr, val); } if (addr >= 0x04004300 && addr <= 0x04004400) @@ -2451,7 +2454,7 @@ void ARM9IOWrite16(u32 addr, u16 val) if ((addr & 0xFFFFFF00) == 0x04004200) { if (!(SCFG_EXT[0] & (1<<17))) return; - return DSi_Camera::Write16(addr, val); + return DSi_CamModule::Write16(addr, val); } if (addr >= 0x04004300 && addr <= 0x04004400) @@ -2601,7 +2604,7 @@ void ARM9IOWrite32(u32 addr, u32 val) if ((addr & 0xFFFFFF00) == 0x04004200) { if (!(SCFG_EXT[0] & (1<<17))) return; - return DSi_Camera::Write32(addr, val); + return DSi_CamModule::Write32(addr, val); } return NDS::ARM9IOWrite32(addr, val); diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp index 2c696b49..70f58bc9 100644 --- a/src/DSi_Camera.cpp +++ b/src/DSi_Camera.cpp @@ -22,15 +22,18 @@ #include "DSi_Camera.h" -DSi_Camera* DSi_Camera0; // 78 / facing outside -DSi_Camera* DSi_Camera1; // 7A / selfie cam +namespace DSi_CamModule +{ -u16 DSi_Camera::ModuleCnt; -u16 DSi_Camera::Cnt; +Camera* Camera0; // 78 / facing outside +Camera* Camera1; // 7A / selfie cam -u8 DSi_Camera::FrameBuffer[640*480*4]; -u32 DSi_Camera::FrameLength; -u32 DSi_Camera::TransferPos; +u16 ModuleCnt; +u16 Cnt; + +u8 FrameBuffer[640*480*4]; +u32 FrameLength; +u32 TransferPos; // note on camera data/etc intervals // on hardware those are likely affected by several factors @@ -41,24 +44,24 @@ const u32 kIRQInterval = 1120000; // ~30 FPS const u32 kTransferStart = 60000; -bool DSi_Camera::Init() +bool Init() { - DSi_Camera0 = new DSi_Camera(0); - DSi_Camera1 = new DSi_Camera(1); + Camera0 = new Camera(0); + Camera1 = new Camera(1); return true; } -void DSi_Camera::DeInit() +void DeInit() { - delete DSi_Camera0; - delete DSi_Camera1; + delete Camera0; + delete Camera1; } -void DSi_Camera::Reset() +void Reset() { - DSi_Camera0->ResetCam(); - DSi_Camera1->ResetCam(); + Camera0->Reset(); + Camera1->Reset(); ModuleCnt = 0; // CHECKME Cnt = 0; @@ -70,7 +73,7 @@ void DSi_Camera::Reset() NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, IRQ, 0); } -void DSi_Camera::DoSavestate(Savestate* file) +void DoSavestate(Savestate* file) { file->Section("CAMi"); @@ -81,20 +84,20 @@ void DSi_Camera::DoSavestate(Savestate* file) file->Var32(&TransferPos); file->Var32(&FrameLength); - DSi_Camera0->DoCamSavestate(file); - DSi_Camera1->DoCamSavestate(file); + Camera0->DoSavestate(file); + Camera1->DoSavestate(file); } -void DSi_Camera::IRQ(u32 param) +void IRQ(u32 param) { - DSi_Camera* activecam = nullptr; + Camera* activecam = nullptr; // TODO: check which camera has priority if both are activated // (or does it just jumble both data sources together, like it // does for, say, overlapping VRAM?) - if (DSi_Camera0->IsActivated()) activecam = DSi_Camera0; - else if (DSi_Camera1->IsActivated()) activecam = DSi_Camera1; + if (Camera0->IsActivated()) activecam = Camera0; + else if (Camera1->IsActivated()) activecam = Camera1; if (activecam) { @@ -110,7 +113,7 @@ void DSi_Camera::IRQ(u32 param) NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, IRQ, 0); } -void DSi_Camera::RequestFrame(u32 cam) +void RequestFrame(u32 cam) { if (!(Cnt & (1<<13))) printf("CAMERA: !! REQUESTING YUV FRAME\n"); @@ -131,7 +134,7 @@ void DSi_Camera::RequestFrame(u32 cam) } } -void DSi_Camera::Transfer(u32 pos) +void Transfer(u32 pos) { u32 numscan = (Cnt & 0x000F) + 1; u32 numpix = numscan * 256; // CHECKME @@ -158,16 +161,133 @@ void DSi_Camera::Transfer(u32 pos) } -DSi_Camera::DSi_Camera(u32 num) +u8 Read8(u32 addr) +{ + // + + printf("unknown DSi cam read8 %08X\n", addr); + return 0; +} + +u16 Read16(u32 addr) +{ + switch (addr) + { + case 0x04004200: return ModuleCnt; + case 0x04004202: return Cnt; + } + + printf("unknown DSi cam read16 %08X\n", addr); + return 0; +} + +u32 Read32(u32 addr) +{ + switch (addr) + { + case 0x04004204: + { + // TODO + return 0xFC00801F; + /*if (!(Cnt & (1<<15))) return 0; // CHECKME + u32 ret = *(u32*)&FrameBuffer[TransferPos]; + TransferPos += 4; + if (TransferPos >= FrameLength) TransferPos = 0; + dorp += 4; + //if (dorp >= (256*4*2)) + if (TransferPos == 0) + { + dorp = 0; + Cnt &= ~(1<<4); + } + return ret;*/ + } + } + + printf("unknown DSi cam read32 %08X\n", addr); + return 0; +} + +void Write8(u32 addr, u8 val) +{ + // + + printf("unknown DSi cam write8 %08X %02X\n", addr, val); +} + +void Write16(u32 addr, u16 val) +{printf("ASS CAMERA REG: %08X %04X\n", addr, val); + switch (addr) + { + case 0x04004200: + { + u16 oldcnt = ModuleCnt; + ModuleCnt = val; + + if ((ModuleCnt & (1<<1)) && !(oldcnt & (1<<1))) + { + // reset shit to zero + // CHECKME + + Cnt = 0; + } + + if ((ModuleCnt & (1<<5)) && !(oldcnt & (1<<5))) + { + // TODO: reset I2C?? + } + } + return; + + case 0x04004202: + { + // checkme + u16 oldmask; + if (Cnt & 0x8000) + { + val &= 0x8F20; + oldmask = 0x601F; + } + else + { + val &= 0xEF2F; + oldmask = 0x0010; + } + + Cnt = (Cnt & oldmask) | (val & ~0x0020); + if (val & (1<<5)) Cnt &= ~(1<<4); + + if ((val & (1<<15)) && !(Cnt & (1<<15))) + { + // start transfer + //DSi::CheckNDMAs(0, 0x0B); + } + } + return; + } + + printf("unknown DSi cam write16 %08X %04X\n", addr, val); +} + +void Write32(u32 addr, u32 val) +{ + // + + printf("unknown DSi cam write32 %08X %08X\n", addr, val); +} + + + +Camera::Camera(u32 num) { Num = num; } -DSi_Camera::~DSi_Camera() +Camera::~Camera() { } -void DSi_Camera::DoCamSavestate(Savestate* file) +void Camera::DoSavestate(Savestate* file) { char magic[5] = "CAMx"; magic[3] = '0' + Num; @@ -190,7 +310,7 @@ void DSi_Camera::DoCamSavestate(Savestate* file) file->VarArray(MCURegs, 0x8000); } -void DSi_Camera::ResetCam() +void Camera::Reset() { DataPos = 0; RegAddr = 0; @@ -204,9 +324,12 @@ void DSi_Camera::ResetCam() MiscCnt = 0; memset(MCURegs, 0, 0x8000); + + // default state is preview mode (checkme) + MCURegs[0x2104] = 3; } -bool DSi_Camera::IsActivated() +bool Camera::IsActivated() { if (StandbyCnt & (1<<14)) return false; // standby if (!(MiscCnt & (1<<9))) return false; // data transfer not enabled @@ -215,11 +338,11 @@ bool DSi_Camera::IsActivated() } -void DSi_Camera::I2C_Start() +void Camera::I2C_Start() { } -u8 DSi_Camera::I2C_Read(bool last) +u8 Camera::I2C_Read(bool last) { u8 ret; @@ -248,7 +371,7 @@ u8 DSi_Camera::I2C_Read(bool last) return ret; } -void DSi_Camera::I2C_Write(u8 val, bool last) +void Camera::I2C_Write(u8 val, bool last) { if (DataPos < 2) { @@ -277,7 +400,7 @@ void DSi_Camera::I2C_Write(u8 val, bool last) else DataPos++; } -u16 DSi_Camera::I2C_ReadReg(u16 addr) +u16 Camera::I2C_ReadReg(u16 addr) { switch (addr) { @@ -313,7 +436,7 @@ u16 DSi_Camera::I2C_ReadReg(u16 addr) return 0; } -void DSi_Camera::I2C_WriteReg(u16 addr, u16 val) +void Camera::I2C_WriteReg(u16 addr, u16 val) { switch (addr) { @@ -370,15 +493,26 @@ void DSi_Camera::I2C_WriteReg(u16 addr, u16 val) // TODO: not sure at all what is the accessible range // or if there is any overlap in the address range -u8 DSi_Camera::MCU_Read(u16 addr) +u8 Camera::MCU_Read(u16 addr) { addr &= 0x7FFF; - printf("CAM%d MCU READ %04X\n", Num, addr); + printf("CAM%d MCU READ %04X -- %08X\n", Num, addr, NDS::GetPC(1)); + + switch (addr) + { + //case 0x2104: // SEQ_STATUS + // TODO!!! + // initial value 3 + // value 7 after writing 2 to 2103 + // preview mode: 256x512, DMA chunk size = 512 + // capture mode: 640x480, DMA chunk size = 320 + //return 7; + } return MCURegs[addr]; } -void DSi_Camera::MCU_Write(u16 addr, u8 val) +void Camera::MCU_Write(u16 addr, u8 val) { addr &= 0x7FFF; printf("CAM%d MCU WRITE %04X %02X\n", Num, addr, val); @@ -386,129 +520,29 @@ void DSi_Camera::MCU_Write(u16 addr, u8 val) switch (addr) { case 0x2103: // SEQ_CMD - { - MCURegs[addr] = 0; - //MCURegs[0x2104] = 3; - } + MCURegs[addr] = 0; + if (val == 2) MCURegs[0x2104] = 7; // capture mode + else if (val == 1) MCURegs[0x2104] = 3; // preview mode + else if (val != 5 && val != 6) + printf("CAM%d: atypical SEQ_CMD %04X\n", Num, val); return; } MCURegs[addr] = val; } - - -u8 DSi_Camera::Read8(u32 addr) -{ - // - - printf("unknown DSi cam read8 %08X\n", addr); - return 0; } -u16 DSi_Camera::Read16(u32 addr) -{ - switch (addr) - { - case 0x04004200: return ModuleCnt; - case 0x04004202: return Cnt; - } - printf("unknown DSi cam read16 %08X\n", addr); - return 0; -} -u32 DSi_Camera::Read32(u32 addr) -{ - switch (addr) - { - case 0x04004204: - { - // TODO - return 0xFC00801F; - /*if (!(Cnt & (1<<15))) return 0; // CHECKME - u32 ret = *(u32*)&FrameBuffer[TransferPos]; - TransferPos += 4; - if (TransferPos >= FrameLength) TransferPos = 0; - dorp += 4; - //if (dorp >= (256*4*2)) - if (TransferPos == 0) - { - dorp = 0; - Cnt &= ~(1<<4); - } - return ret;*/ - } - } - printf("unknown DSi cam read32 %08X\n", addr); - return 0; -} -void DSi_Camera::Write8(u32 addr, u8 val) -{ - // - printf("unknown DSi cam write8 %08X %02X\n", addr, val); -} -void DSi_Camera::Write16(u32 addr, u16 val) -{ - switch (addr) - { - case 0x04004200: - { - u16 oldcnt = ModuleCnt; - ModuleCnt = val; - if ((ModuleCnt & (1<<1)) && !(oldcnt & (1<<1))) - { - // reset shit to zero - // CHECKME - Cnt = 0; - } - if ((ModuleCnt & (1<<5)) && !(oldcnt & (1<<5))) - { - // TODO: reset I2C?? - } - } - return; - case 0x04004202: - { - // checkme - u16 oldmask; - if (Cnt & 0x8000) - { - val &= 0x8F20; - oldmask = 0x601F; - } - else - { - val &= 0xEF2F; - oldmask = 0x0010; - } - Cnt = (Cnt & oldmask) | (val & ~0x0020); - if (val & (1<<5)) Cnt &= ~(1<<4); - if ((val & (1<<15)) && !(Cnt & (1<<15))) - { - // start transfer - //DSi::CheckNDMAs(0, 0x0B); - } - } - return; - } - printf("unknown DSi cam write16 %08X %04X\n", addr, val); -} - -void DSi_Camera::Write32(u32 addr, u32 val) -{ - // - - printf("unknown DSi cam write32 %08X %08X\n", addr, val); -} diff --git a/src/DSi_Camera.h b/src/DSi_Camera.h index ce8885e6..daabfae6 100644 --- a/src/DSi_Camera.h +++ b/src/DSi_Camera.h @@ -21,39 +21,47 @@ #include "types.h" -class DSi_Camera +namespace DSi_CamModule +{ + +class Camera; + +extern Camera* Camera0; +extern Camera* Camera1; + +bool Init(); +void DeInit(); +void Reset(); + +void DoSavestate(Savestate* file); + +void IRQ(u32 param); +void RequestFrame(u32 cam); + +void Transfer(u32 pos); + +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: - static bool Init(); - static void DeInit(); - static void Reset(); + Camera(u32 num); + ~Camera(); - static void DoSavestate(Savestate* file); + void DoSavestate(Savestate* file); - static void IRQ(u32 param); - static void RequestFrame(u32 cam); - - static void Transfer(u32 pos); - - DSi_Camera(u32 num); - ~DSi_Camera(); - - void DoCamSavestate(Savestate* file); - - void ResetCam(); + void Reset(); bool IsActivated(); void I2C_Start(); u8 I2C_Read(bool last); void I2C_Write(u8 val, bool last); - static u8 Read8(u32 addr); - static u16 Read16(u32 addr); - static u32 Read32(u32 addr); - static void Write8(u32 addr, u8 val); - static void Write16(u32 addr, u16 val); - static void Write32(u32 addr, u32 val); - u32 Num; private: @@ -78,17 +86,8 @@ private: u8 MCU_Read(u16 addr); void MCU_Write(u16 addr, u8 val); - - static u16 ModuleCnt; - static u16 Cnt; - - static u8 FrameBuffer[640*480*4]; - static u32 TransferPos; - static u32 FrameLength; }; - -extern DSi_Camera* DSi_Camera0; -extern DSi_Camera* DSi_Camera1; +} #endif // DSI_CAMERA_H diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp index 5d13b2a6..09b95748 100644 --- a/src/DSi_I2C.cpp +++ b/src/DSi_I2C.cpp @@ -169,7 +169,6 @@ u32 Device; bool Init() { if (!DSi_BPTWL::Init()) return false; - if (!DSi_Camera::Init()) return false; return true; } @@ -177,7 +176,6 @@ bool Init() void DeInit() { DSi_BPTWL::DeInit(); - DSi_Camera::DeInit(); } void Reset() @@ -188,7 +186,6 @@ void Reset() Device = -1; DSi_BPTWL::Reset(); - DSi_Camera::Reset(); } void DoSavestate(Savestate* file) @@ -200,7 +197,6 @@ void DoSavestate(Savestate* file) file->Var32(&Device); DSi_BPTWL::DoSavestate(file); - // cameras are savestated from the DSi_Camera module } void WriteCnt(u8 val) @@ -224,8 +220,8 @@ void WriteCnt(u8 val) switch (Device) { case 0x4A: Data = DSi_BPTWL::Read(islast); break; - case 0x78: Data = DSi_Camera0->I2C_Read(islast); break; - case 0x7A: Data = DSi_Camera1->I2C_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: @@ -250,8 +246,8 @@ void WriteCnt(u8 val) switch (Device) { case 0x4A: DSi_BPTWL::Start(); break; - case 0x78: DSi_Camera0->I2C_Start(); break; - case 0x7A: DSi_Camera1->I2C_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: @@ -267,8 +263,8 @@ void WriteCnt(u8 val) switch (Device) { case 0x4A: DSi_BPTWL::Write(Data, islast); break; - case 0x78: DSi_Camera0->I2C_Write(Data, islast); break; - case 0x7A: DSi_Camera1->I2C_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: diff --git a/src/NDS.cpp b/src/NDS.cpp index 2ff8ffe2..6a6d8f82 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -722,8 +722,8 @@ bool DoSavestate_Scheduler(Savestate* file) DSi_SDHost::FinishRX, DSi_SDHost::FinishTX, DSi_NWifi::MSTimer, - DSi_Camera::IRQ, - DSi_Camera::Transfer, + DSi_CamModule::IRQ, + DSi_CamModule::Transfer, DSi_DSP::DSPCatchUpU32, nullptr @@ -1957,14 +1957,14 @@ void debug(u32 param) fclose(shit);*/ FILE* - shit = fopen("debug/directboot9.bin", "wb"); + shit = fopen("debug/camera9.bin", "wb"); for (u32 i = 0x02000000; i < 0x04000000; i+=4) { u32 val = DSi::ARM9Read32(i); fwrite(&val, 4, 1, shit); } fclose(shit); - shit = fopen("debug/directboot7.bin", "wb"); + shit = fopen("debug/camera7.bin", "wb"); for (u32 i = 0x02000000; i < 0x04000000; i+=4) { u32 val = DSi::ARM7Read32(i);