aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ARM.cpp22
-rw-r--r--src/DSi.cpp37
-rw-r--r--src/DSi_Camera.cpp220
-rw-r--r--src/DSi_Camera.h32
-rw-r--r--src/DSi_I2C.cpp12
-rw-r--r--src/DSi_NDMA.cpp2
-rw-r--r--src/NDS.cpp4
-rw-r--r--src/NDS.h3
8 files changed, 303 insertions, 29 deletions
diff --git a/src/ARM.cpp b/src/ARM.cpp
index 7eeacb7..7fe3497 100644
--- a/src/ARM.cpp
+++ b/src/ARM.cpp
@@ -256,6 +256,18 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
// aging cart debug crap
//if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]);
//if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]);
+ if(addr==0x0219BA2D) printf("CAM RESET FROM %08X\n", R[15]);
+ if(addr==0x0219BB69) printf("CAM SHITO FROM %08X\n", R[15]);
+ if(addr==0x0200BA45) printf("CAM SHITO2 FROM %08X\n", R[15]);
+ if(addr==0x0200B9ED) printf("CAM SHITO3 FROM %08X\n", R[15]);
+ if(addr==0x0200B9BD) printf("CAM SETUP START FROM %08X\n", R[15]);
+ if(R[15]==0x0200B9E6) printf("CAM SETUP END FROM %08X\n", addr);
+ if(addr==0x0219AA5B) printf("CAM LOOP BACK FROM %08X\n", R[15]);
+ if(addr==0x0200BD0D) printf("GUILLOTINE FIVE MILLION %08X\n", R[15]);
+ if(addr==0x0200512D) printf("GUILLOTINE SIX MILLION %08X\n", R[15]);
+ if(addr==0x0219A585) printf("GUILLOTINE SEVEN MILLION %08X\n", R[15]);
+ if(addr==0x0219BAF1) printf("CAM GET DRQ BIT %08X\n", R[15]);
+ if(addr==0x0219BA91) printf("CAM STOP TRANSFER %08X\n", R[15]);
u32 oldregion = R[15] >> 24;
u32 newregion = addr >> 24;
@@ -570,6 +582,8 @@ void ARMv5::Execute()
// actually execute
u32 icode = (CurInstr >> 6) & 0x3FF;
ARMInterpreter::THUMBInstrTable[icode](this);
+
+ if (R[15]==0x0219A6B0) printf("CAM THREAD MSG: %02X %08X -> %08X\n", R[1], R[0], 0x0219A6B6+R[0]);
}
else
{
@@ -592,7 +606,7 @@ void ARMv5::Execute()
else
AddCycles_C();
}
-
+
// TODO optimize this shit!!!
if (Halted)
{
@@ -651,7 +665,7 @@ void ARMv5::ExecuteJIT()
return;
}
- ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlock(0, FastBlockLookup,
+ ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlock(0, FastBlockLookup,
instrAddr - FastBlockLookupStart, instrAddr);
if (block)
ARM_Dispatch(this, block);
@@ -802,7 +816,7 @@ void ARMv4::ExecuteJIT()
return;
}
- ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlock(1, FastBlockLookup,
+ ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlock(1, FastBlockLookup,
instrAddr - FastBlockLookupStart, instrAddr);
if (block)
ARM_Dispatch(this, block);
@@ -879,4 +893,4 @@ void ARMv4::FillPipeline()
NextInstr[0] = CodeRead32(R[15] - 4);
NextInstr[1] = CodeRead32(R[15]);
}
-} \ No newline at end of file
+}
diff --git a/src/DSi.cpp b/src/DSi.cpp
index a96322b..259a447 100644
--- a/src/DSi.cpp
+++ b/src/DSi.cpp
@@ -35,6 +35,7 @@
#include "DSi_I2C.h"
#include "DSi_SD.h"
#include "DSi_AES.h"
+#include "DSi_Camera.h"
#include "tiny-AES-c/aes.hpp"
@@ -1406,6 +1407,12 @@ u8 ARM9IORead8(u32 addr)
CASE_READ8_32BIT(0x04004060, MBK[0][8])
}
+ if ((addr & 0xFFFFFF00) == 0x04004200)
+ {
+ if (!(SCFG_EXT[0] & (1<<17))) return 0;
+ return DSi_Camera::Read8(addr);
+ }
+
return NDS::ARM9IORead8(addr);
}
@@ -1428,6 +1435,12 @@ u16 ARM9IORead16(u32 addr)
CASE_READ16_32BIT(0x04004060, MBK[0][8])
}
+ if ((addr & 0xFFFFFF00) == 0x04004200)
+ {
+ if (!(SCFG_EXT[0] & (1<<17))) return 0;
+ return DSi_Camera::Read16(addr);
+ }
+
return NDS::ARM9IORead16(addr);
}
@@ -1480,6 +1493,12 @@ u32 ARM9IORead32(u32 addr)
case 0x04004170: return NDMAs[3]->Cnt;
}
+ if ((addr & 0xFFFFFF00) == 0x04004200)
+ {
+ if (!(SCFG_EXT[0] & (1<<17))) return 0;
+ return DSi_Camera::Read32(addr);
+ }
+
return NDS::ARM9IORead32(addr);
}
@@ -1519,6 +1538,12 @@ void ARM9IOWrite8(u32 addr, u8 val)
case 0x04004053: MapNWRAM_C(7, val); return;
}
+ if ((addr & 0xFFFFFF00) == 0x04004200)
+ {
+ if (!(SCFG_EXT[0] & (1<<17))) return;
+ return DSi_Camera::Write8(addr, val);
+ }
+
return NDS::ARM9IOWrite8(addr, val);
}
@@ -1572,6 +1597,12 @@ void ARM9IOWrite16(u32 addr, u16 val)
return;
}
+ if ((addr & 0xFFFFFF00) == 0x04004200)
+ {
+ if (!(SCFG_EXT[0] & (1<<17))) return;
+ return DSi_Camera::Write16(addr, val);
+ }
+
return NDS::ARM9IOWrite16(addr, val);
}
@@ -1678,6 +1709,12 @@ void ARM9IOWrite32(u32 addr, u32 val)
case 0x04004170: NDMAs[3]->WriteCnt(val); return;
}
+ if ((addr & 0xFFFFFF00) == 0x04004200)
+ {
+ if (!(SCFG_EXT[0] & (1<<17))) return;
+ return DSi_Camera::Write32(addr, val);
+ }
+
return NDS::ARM9IOWrite32(addr, val);
}
diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp
index 56cba1c..dd8dea7 100644
--- a/src/DSi_Camera.cpp
+++ b/src/DSi_Camera.cpp
@@ -18,12 +18,22 @@
#include <stdio.h>
#include <string.h>
+#include "DSi.h"
#include "DSi_Camera.h"
DSi_Camera* DSi_Camera0; // 78 / facing outside
DSi_Camera* DSi_Camera1; // 7A / selfie cam
+u16 DSi_Camera::ModuleCnt;
+u16 DSi_Camera::Cnt;
+
+u8 DSi_Camera::FrameBuffer[640*480*4];
+u32 DSi_Camera::FrameLength;
+u32 DSi_Camera::TransferPos;
+
+const u32 kCameraInterval = 1024*16; // interval between camera data blocks
+
bool DSi_Camera::Init()
{
@@ -43,6 +53,63 @@ void DSi_Camera::Reset()
{
DSi_Camera0->ResetCam();
DSi_Camera1->ResetCam();
+
+ ModuleCnt = 0; // CHECKME
+ Cnt = 0;
+
+ memset(FrameBuffer, 0, 640*480*4);
+ TransferPos = 0;
+ FrameLength = 256*192*2; // TODO: make it check frame size, data type, etc
+
+ NDS::ScheduleEvent(NDS::Event_DSi_Camera, true, kCameraInterval, Process, 0);
+}
+
+
+void DSi_Camera::Process(u32 param)
+{
+ DSi_Camera* activecam = nullptr;
+
+ // TODO: check which camera has priority if both are activated
+ if (DSi_Camera0->IsActivated()) activecam = DSi_Camera0;
+ else if (DSi_Camera1->IsActivated()) activecam = DSi_Camera1;
+
+ if (activecam)
+ {
+ if (TransferPos == 0)
+ RequestFrame(activecam->Num);
+
+ Cnt |= (1<<4);
+ if (Cnt & (1<<11)) NDS::SetIRQ(0, NDS::IRQ_DSi_Camera);
+ }
+ else
+ {
+ TransferPos = 0;
+ }
+
+ // TODO: check the interval for this?
+ // on hardware the delay is likely determined by how long the camera takes to process raw data
+ NDS::ScheduleEvent(NDS::Event_DSi_Camera, true, kCameraInterval, Process, 0);
+}
+
+void DSi_Camera::RequestFrame(u32 cam)
+{
+ if (!(Cnt & (1<<13))) printf("CAMERA: !! REQUESTING YUV FRAME\n");
+
+ // TODO: picture size, data type, cropping, etc
+ // generate test pattern
+ // TODO: get picture from platform (actual camera, video file, whatever source)
+ for (u32 y = 0; y < 192; y++)
+ {
+ for (u32 x = 0; x < 256; x++)
+ {
+ u16* px = (u16*)&FrameBuffer[((y*256) + x) * 2];
+
+ if ((x & 0x8) ^ (y & 0x8))
+ *px = 0x8000;
+ else
+ *px = 0xFC00 | ((y >> 3) << 5);
+ }
+ }
}
@@ -63,15 +130,25 @@ void DSi_Camera::ResetCam()
RegData = 0;
PLLCnt = 0;
+ ClocksCnt = 0;
StandbyCnt = 0x4029; // checkme
+ MiscCnt = 0;
+}
+
+bool DSi_Camera::IsActivated()
+{
+ if (StandbyCnt & (1<<14)) return false; // standby
+ if (!(MiscCnt & (1<<9))) return false; // data transfer not enabled
+
+ return true;
}
-void DSi_Camera::Start()
+void DSi_Camera::I2C_Start()
{
}
-u8 DSi_Camera::Read(bool last)
+u8 DSi_Camera::I2C_Read(bool last)
{
u8 ret;
@@ -89,7 +166,7 @@ u8 DSi_Camera::Read(bool last)
}
else
{
- RegData = ReadReg(RegAddr);
+ RegData = I2C_ReadReg(RegAddr);
ret = RegData >> 8;
}
}
@@ -100,7 +177,7 @@ u8 DSi_Camera::Read(bool last)
return ret;
}
-void DSi_Camera::Write(u8 val, bool last)
+void DSi_Camera::I2C_Write(u8 val, bool last)
{
if (DataPos < 2)
{
@@ -116,7 +193,7 @@ void DSi_Camera::Write(u8 val, bool last)
if (DataPos & 0x1)
{
RegData |= val;
- WriteReg(RegAddr, RegData);
+ I2C_WriteReg(RegAddr, RegData);
RegAddr += 2; // checkme
}
else
@@ -129,22 +206,24 @@ void DSi_Camera::Write(u8 val, bool last)
else DataPos++;
}
-u16 DSi_Camera::ReadReg(u16 addr)
+u16 DSi_Camera::I2C_ReadReg(u16 addr)
{
switch (addr)
{
case 0x0000: return 0x2280; // chip ID
case 0x0014: return PLLCnt;
+ case 0x0016: return ClocksCnt;
case 0x0018: return StandbyCnt;
+ case 0x001A: return MiscCnt;
case 0x301A: return ((~StandbyCnt) & 0x4000) >> 12;
}
- //printf("DSi_Camera%d: unknown read %04X\n", Num, addr);
+ if(Num==1)printf("DSi_Camera%d: unknown read %04X\n", Num, addr);
return 0;
}
-void DSi_Camera::WriteReg(u16 addr, u16 val)
+void DSi_Camera::I2C_WriteReg(u16 addr, u16 val)
{
switch (addr)
{
@@ -154,13 +233,136 @@ void DSi_Camera::WriteReg(u16 addr, u16 val)
val |= ((val & 0x0002) << 14);
PLLCnt = val;
return;
+ case 0x0016:
+ ClocksCnt = val;
+ printf("ClocksCnt=%04X\n", val);
+ return;
case 0x0018:
// TODO: this shouldn't be instant, but uh
val &= 0x003F;
val |= ((val & 0x0001) << 14);
StandbyCnt = val;
+ printf("CAM%d STBCNT=%04X (%04X)\n", Num, StandbyCnt, val);
+ return;
+ case 0x001A:
+ MiscCnt = val & 0x0B7B;
+ printf("CAM%d MISCCNT=%04X (%04X)\n", Num, MiscCnt, val);
+ return;
+ }
+
+ if(Num==1)printf("DSi_Camera%d: unknown write %04X %04X\n", Num, addr, val);
+}
+
+
+u8 DSi_Camera::Read8(u32 addr)
+{
+ //
+
+ printf("unknown DSi cam read8 %08X\n", addr);
+ return 0;
+}
+
+u16 DSi_Camera::Read16(u32 addr)
+{printf("CAM READ %08X %08X\n", addr, NDS::GetPC(0));
+ switch (addr)
+ {
+ case 0x04004200: return ModuleCnt;
+ case 0x04004202: return Cnt;
+ }
+
+ printf("unknown DSi cam read16 %08X\n", addr);
+ return 0;
+}
+u32 dorp = 0;
+u32 DSi_Camera::Read32(u32 addr)
+{
+ switch (addr)
+ {
+ case 0x04004204:
+ {
+ 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)
+{printf("CAM WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(0));
+ 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 &= 0x8F00;
+ oldmask = 0x601F;
+ }
+ else
+ {
+ val &= 0xEF0F;
+ oldmask = 0x0010;
+ }
+
+ Cnt = (Cnt & oldmask) | val;
+ if (val & (1<<5)) Cnt &= ~(1<<4);
+
+ if ((val & (1<<15)) && !(Cnt & (1<<15)))
+ {
+ // start transfer
+ DSi::CheckNDMAs(0, 0x0B);
+ }
+ }
return;
}
- //printf("DSi_Camera%d: unknown write %04X %04X\n", Num, addr, val);
+ 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 844a4d2..8e44db1 100644
--- a/src/DSi_Camera.h
+++ b/src/DSi_Camera.h
@@ -28,27 +28,47 @@ public:
static void DeInit();
static void Reset();
+ static void Process(u32 param);
+ static void RequestFrame(u32 cam);
+
DSi_Camera(u32 num);
~DSi_Camera();
void ResetCam();
+ bool IsActivated();
- void Start();
- u8 Read(bool last);
- void Write(u8 val, bool last);
+ 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);
-private:
u32 Num;
+private:
u32 DataPos;
u32 RegAddr;
u16 RegData;
- u16 ReadReg(u16 addr);
- void WriteReg(u16 addr, u16 val);
+ u16 I2C_ReadReg(u16 addr);
+ void I2C_WriteReg(u16 addr, u16 val);
u16 PLLCnt;
+ u16 ClocksCnt;
u16 StandbyCnt;
+ u16 MiscCnt;
+
+ static u16 ModuleCnt;
+ static u16 Cnt;
+
+ static u8 FrameBuffer[640*480*4];
+ static u32 TransferPos;
+ static u32 FrameLength;
};
diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp
index d58a38c..faa3d16 100644
--- a/src/DSi_I2C.cpp
+++ b/src/DSi_I2C.cpp
@@ -187,8 +187,8 @@ void WriteCnt(u8 val)
switch (Device)
{
case 0x4A: Data = DSi_BPTWL::Read(islast); break;
- case 0x78: Data = DSi_Camera0->Read(islast); break;
- case 0x7A: Data = DSi_Camera1->Read(islast); break;
+ case 0x78: Data = DSi_Camera0->I2C_Read(islast); break;
+ case 0x7A: Data = DSi_Camera1->I2C_Read(islast); break;
default:
printf("I2C: read on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, 0, islast);
Data = 0xFF;
@@ -211,8 +211,8 @@ void WriteCnt(u8 val)
switch (Device)
{
case 0x4A: DSi_BPTWL::Start(); break;
- case 0x78: DSi_Camera0->Start(); break;
- case 0x7A: DSi_Camera1->Start(); break;
+ case 0x78: DSi_Camera0->I2C_Start(); break;
+ case 0x7A: DSi_Camera1->I2C_Start(); break;
default:
printf("I2C: %s start on unknown device %02X\n", (Data&0x01)?"read":"write", Device);
ack = false;
@@ -226,8 +226,8 @@ void WriteCnt(u8 val)
switch (Device)
{
case 0x4A: DSi_BPTWL::Write(Data, islast); break;
- case 0x78: DSi_Camera0->Write(Data, islast); break;
- case 0x7A: DSi_Camera1->Write(Data, islast); break;
+ case 0x78: DSi_Camera0->I2C_Write(Data, islast); break;
+ case 0x7A: DSi_Camera1->I2C_Write(Data, islast); break;
default:
printf("I2C: write on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
ack = false;
diff --git a/src/DSi_NDMA.cpp b/src/DSi_NDMA.cpp
index 707c777..d6d289d 100644
--- a/src/DSi_NDMA.cpp
+++ b/src/DSi_NDMA.cpp
@@ -101,7 +101,7 @@ void DSi_NDMA::WriteCnt(u32 val)
Start();
if (StartMode != 0x10 && StartMode != 0x30 &&
- StartMode != 0x04 && StartMode != 0x06 && StartMode != 0x07 && StartMode != 0x08 && StartMode != 0x09 &&
+ StartMode != 0x04 && StartMode != 0x06 && StartMode != 0x07 && StartMode != 0x08 && StartMode != 0x09 && StartMode != 0x0B &&
StartMode != 0x24 && StartMode != 0x26 && StartMode != 0x28 && StartMode != 0x29 && StartMode != 0x2A && StartMode != 0x2B)
printf("UNIMPLEMENTED ARM%d NDMA%d START MODE %02X, %08X->%08X LEN=%d BLK=%d CNT=%08X\n",
CPU?7:9, Num, StartMode, SrcAddr, DstAddr, TotalLength, BlockLength, Cnt);
diff --git a/src/NDS.cpp b/src/NDS.cpp
index f926399..90eaac5 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -1819,14 +1819,14 @@ void debug(u32 param)
fclose(shit);*/
FILE*
- shit = fopen("debug/picto9.bin", "wb");
+ shit = fopen("debug/cam9.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/picto7.bin", "wb");
+ shit = fopen("debug/cam7.bin", "wb");
for (u32 i = 0x02000000; i < 0x04000000; i+=4)
{
u32 val = DSi::ARM7Read32(i);
diff --git a/src/NDS.h b/src/NDS.h
index 91bfd1c..a66dde5 100644
--- a/src/NDS.h
+++ b/src/NDS.h
@@ -46,6 +46,7 @@ enum
Event_DSi_SDMMCTransfer,
Event_DSi_SDIOTransfer,
Event_DSi_NWifi,
+ Event_DSi_Camera,
Event_DSi_RAMSizeChange,
@@ -82,7 +83,7 @@ enum
IRQ_IPCSendDone,
IRQ_IPCRecv,
IRQ_CartSendDone, // TODO: less misleading name
- IRQ_CartIREQMC, // IRQ triggered by game cart (example: Pok�mon Typing Adventure, BT controller)
+ IRQ_CartIREQMC, // IRQ triggered by game cart (example: Pokémon Typing Adventure, BT controller)
IRQ_GXFIFO,
IRQ_LidOpen,
IRQ_SPI,