Merge pull request #837 from Arisotura/dsi_camera
merge DSi camera branch
This commit is contained in:
commit
c572996426
10
src/ARM.cpp
10
src/ARM.cpp
|
@ -570,6 +570,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 +594,7 @@ void ARMv5::Execute()
|
|||
else
|
||||
AddCycles_C();
|
||||
}
|
||||
|
||||
|
||||
// TODO optimize this shit!!!
|
||||
if (Halted)
|
||||
{
|
||||
|
@ -651,7 +653,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 +804,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 +881,4 @@ void ARMv4::FillPipeline()
|
|||
NextInstr[0] = CodeRead32(R[15] - 4);
|
||||
NextInstr[1] = CodeRead32(R[15]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
37
src/DSi.cpp
37
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,28 @@
|
|||
|
||||
#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;
|
||||
|
||||
// note on camera data/etc intervals
|
||||
// on hardware those are likely affected by several factors
|
||||
// namely, how long cameras take to process frames
|
||||
// camera IRQ is fired at roughly 15FPS with default config
|
||||
|
||||
const u32 kIRQInterval = 1120000; // ~30 FPS
|
||||
const u32 kTransferStart = 60000;
|
||||
|
||||
|
||||
bool DSi_Camera::Init()
|
||||
{
|
||||
|
@ -43,6 +59,87 @@ 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_CamIRQ, true, kIRQInterval, IRQ, 0);
|
||||
}
|
||||
|
||||
|
||||
void DSi_Camera::IRQ(u32 param)
|
||||
{
|
||||
DSi_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 (activecam)
|
||||
{
|
||||
RequestFrame(activecam->Num);
|
||||
|
||||
if (Cnt & (1<<11))
|
||||
NDS::SetIRQ(0, NDS::IRQ_DSi_Camera);
|
||||
|
||||
if (Cnt & (1<<15))
|
||||
NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, kTransferStart, Transfer, 0);
|
||||
}
|
||||
|
||||
NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, IRQ, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DSi_Camera::Transfer(u32 pos)
|
||||
{
|
||||
u32 numscan = (Cnt & 0x000F) + 1;
|
||||
u32 numpix = numscan * 256; // CHECKME
|
||||
|
||||
// TODO: present data
|
||||
//printf("CAM TRANSFER POS=%d/%d\n", pos, 0x6000*2);
|
||||
|
||||
DSi::CheckNDMAs(0, 0x0B);
|
||||
|
||||
pos += numpix;
|
||||
if (pos >= 0x6000*2) // HACK
|
||||
{
|
||||
// transfer done
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep going
|
||||
|
||||
// TODO: must be tweaked such that each block has enough time to transfer
|
||||
u32 delay = numpix*2 + 16;
|
||||
|
||||
NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, delay, Transfer, pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,16 +159,28 @@ void DSi_Camera::ResetCam()
|
|||
RegAddr = 0;
|
||||
RegData = 0;
|
||||
|
||||
PLLCnt = 0;
|
||||
PLLDiv = 0x0366;
|
||||
PLLPDiv = 0x00F5;
|
||||
PLLCnt = 0x21F9;
|
||||
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 +198,7 @@ u8 DSi_Camera::Read(bool last)
|
|||
}
|
||||
else
|
||||
{
|
||||
RegData = ReadReg(RegAddr);
|
||||
RegData = I2C_ReadReg(RegAddr);
|
||||
ret = RegData >> 8;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +209,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 +225,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,38 +238,172 @@ 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 0x0010: return PLLDiv;
|
||||
case 0x0012: return PLLPDiv;
|
||||
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)
|
||||
{
|
||||
case 0x0010:
|
||||
PLLDiv = val & 0x3FFF;
|
||||
return;
|
||||
case 0x0012:
|
||||
PLLPDiv = val & 0xBFFF;
|
||||
return;
|
||||
case 0x0014:
|
||||
// shouldn't be instant either?
|
||||
val &= 0x7FFF;
|
||||
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;
|
||||
}
|
||||
|
||||
//printf("DSi_Camera%d: unknown write %04X %04X\n", Num, addr, val);
|
||||
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:
|
||||
{
|
||||
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)
|
||||
{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 &= 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);
|
||||
}
|
||||
|
|
|
@ -28,27 +28,56 @@ public:
|
|||
static void DeInit();
|
||||
static void Reset();
|
||||
|
||||
static void IRQ(u32 param);
|
||||
static void RequestFrame(u32 cam);
|
||||
|
||||
static void Transfer(u32 pos);
|
||||
|
||||
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 PLLDiv;
|
||||
u16 PLLPDiv;
|
||||
u16 PLLCnt;
|
||||
u16 ClocksCnt;
|
||||
u16 StandbyCnt;
|
||||
u16 MiscCnt;
|
||||
|
||||
u16 MCUAddr;
|
||||
u16* MCUData;
|
||||
|
||||
u8 MCURegs[0x8000];
|
||||
|
||||
static u16 ModuleCnt;
|
||||
static u16 Cnt;
|
||||
|
||||
static u8 FrameBuffer[640*480*4];
|
||||
static u32 TransferPos;
|
||||
static u32 FrameLength;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
case 0xA0:
|
||||
case 0xE0: Data = 0xFF; break;
|
||||
default:
|
||||
|
@ -213,8 +213,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;
|
||||
case 0xA0:
|
||||
case 0xE0: ack = false; break;
|
||||
default:
|
||||
|
@ -230,8 +230,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;
|
||||
case 0xA0:
|
||||
case 0xE0: ack = false; break;
|
||||
default:
|
||||
|
|
|
@ -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);
|
||||
|
|
34
src/NDS.cpp
34
src/NDS.cpp
|
@ -1477,7 +1477,7 @@ void HandleTimerOverflow(u32 tid)
|
|||
{
|
||||
Timer* timer = &Timers[tid];
|
||||
|
||||
timer->Counter += timer->Reload << 16;
|
||||
timer->Counter += (timer->Reload << 10);
|
||||
if (timer->Cnt & (1<<6))
|
||||
SetIRQ(tid >> 2, IRQ_Timer0 + (tid & 0x3));
|
||||
|
||||
|
@ -1493,11 +1493,11 @@ void HandleTimerOverflow(u32 tid)
|
|||
if ((timer->Cnt & 0x84) != 0x84)
|
||||
break;
|
||||
|
||||
timer->Counter += 0x10000;
|
||||
if (timer->Counter >> 16)
|
||||
timer->Counter += (1 << 10);
|
||||
if (!(timer->Counter >> 26))
|
||||
break;
|
||||
|
||||
timer->Counter = timer->Reload << 16;
|
||||
timer->Counter = timer->Reload << 10;
|
||||
if (timer->Cnt & (1<<6))
|
||||
SetIRQ(tid >> 2, IRQ_Timer0 + (tid & 0x3));
|
||||
|
||||
|
@ -1512,8 +1512,13 @@ void RunTimer(u32 tid, s32 cycles)
|
|||
|
||||
u32 oldcount = timer->Counter;
|
||||
timer->Counter += (cycles << timer->CycleShift);
|
||||
if (timer->Counter < oldcount)
|
||||
//if (timer->Counter < oldcount)
|
||||
// HandleTimerOverflow(tid);
|
||||
while (timer->Counter >> 26)
|
||||
{
|
||||
timer->Counter -= (1 << 26);
|
||||
HandleTimerOverflow(tid);
|
||||
}
|
||||
}
|
||||
|
||||
void RunTimers(u32 cpu)
|
||||
|
@ -1630,7 +1635,7 @@ u16 TimerGetCounter(u32 timer)
|
|||
RunTimers(timer>>2);
|
||||
u32 ret = Timers[timer].Counter;
|
||||
|
||||
return ret >> 16;
|
||||
return ret >> 10;
|
||||
}
|
||||
|
||||
void TimerStart(u32 id, u16 cnt)
|
||||
|
@ -1640,11 +1645,11 @@ void TimerStart(u32 id, u16 cnt)
|
|||
u16 newstart = cnt & (1<<7);
|
||||
|
||||
timer->Cnt = cnt;
|
||||
timer->CycleShift = 16 - TimerPrescaler[cnt & 0x03];
|
||||
timer->CycleShift = 10 - TimerPrescaler[cnt & 0x03];
|
||||
|
||||
if ((!curstart) && newstart)
|
||||
{
|
||||
timer->Counter = timer->Reload << 16;
|
||||
timer->Counter = timer->Reload << 10;
|
||||
|
||||
/*if ((cnt & 0x84) == 0x80)
|
||||
{
|
||||
|
@ -1806,6 +1811,15 @@ void StartSqrt()
|
|||
|
||||
void debug(u32 param)
|
||||
{
|
||||
if (param==1312)
|
||||
{
|
||||
u32 timer = 0x10000 - (Timers[3].Counter >> 16);
|
||||
timer *= 16;
|
||||
timer += (0x10000 - (Timers[2].Counter >> 16));
|
||||
printf("TIMER=%d (%04X/%04X)\n", timer, (Timers[2].Counter >> 16), (Timers[3].Counter >> 16));
|
||||
return;
|
||||
}
|
||||
|
||||
printf("ARM9 PC=%08X LR=%08X %08X\n", ARM9->R[15], ARM9->R[14], ARM9->R_IRQ[1]);
|
||||
printf("ARM7 PC=%08X LR=%08X %08X\n", ARM7->R[15], ARM7->R[14], ARM7->R_IRQ[1]);
|
||||
|
||||
|
@ -1831,14 +1845,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);
|
||||
|
|
|
@ -46,6 +46,8 @@ enum
|
|||
Event_DSi_SDMMCTransfer,
|
||||
Event_DSi_SDIOTransfer,
|
||||
Event_DSi_NWifi,
|
||||
Event_DSi_CamIRQ,
|
||||
Event_DSi_CamTransfer,
|
||||
|
||||
Event_DSi_RAMSizeChange,
|
||||
|
||||
|
@ -82,7 +84,7 @@ enum
|
|||
IRQ_IPCSendDone,
|
||||
IRQ_IPCRecv,
|
||||
IRQ_CartSendDone, // TODO: less misleading name
|
||||
IRQ_CartIREQMC, // IRQ triggered by game cart (example: Pok<EFBFBD>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,
|
||||
|
|
Loading…
Reference in New Issue