convert DSP
This commit is contained in:
parent
54ebf1b1b2
commit
11c22f077d
55
src/DSi.cpp
55
src/DSi.cpp
|
@ -82,6 +82,7 @@ DSi_SDHost* SDIO;
|
||||||
DSi_I2CHost* I2C;
|
DSi_I2CHost* I2C;
|
||||||
DSi_CamModule* CamModule;
|
DSi_CamModule* CamModule;
|
||||||
DSi_AES* AES;
|
DSi_AES* AES;
|
||||||
|
DSi_DSP* DSP;
|
||||||
|
|
||||||
// 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)
|
||||||
// ... not that they matter all that much
|
// ... not that they matter all that much
|
||||||
|
@ -104,8 +105,6 @@ bool Init()
|
||||||
NWRAM_C = new u8[NWRAMSize];
|
NWRAM_C = new u8[NWRAMSize];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!DSi_DSP::Init()) return false;
|
|
||||||
|
|
||||||
NDMAs[0] = new DSi_NDMA(0, 0);
|
NDMAs[0] = new DSi_NDMA(0, 0);
|
||||||
NDMAs[1] = new DSi_NDMA(0, 1);
|
NDMAs[1] = new DSi_NDMA(0, 1);
|
||||||
NDMAs[2] = new DSi_NDMA(0, 2);
|
NDMAs[2] = new DSi_NDMA(0, 2);
|
||||||
|
@ -121,6 +120,7 @@ bool Init()
|
||||||
I2C = new DSi_I2CHost();
|
I2C = new DSi_I2CHost();
|
||||||
CamModule = new DSi_CamModule();
|
CamModule = new DSi_CamModule();
|
||||||
AES = new DSi_AES();
|
AES = new DSi_AES();
|
||||||
|
DSP = new DSi_DSP();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,6 @@ void DeInit()
|
||||||
NWRAM_C = nullptr;
|
NWRAM_C = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DSi_DSP::DeInit();
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
delete NDMAs[i];
|
delete NDMAs[i];
|
||||||
|
@ -151,6 +149,7 @@ void DeInit()
|
||||||
delete I2C; I2C = nullptr;
|
delete I2C; I2C = nullptr;
|
||||||
delete CamModule; CamModule = nullptr;
|
delete CamModule; CamModule = nullptr;
|
||||||
delete AES; AES = nullptr;
|
delete AES; AES = nullptr;
|
||||||
|
delete DSP; DSP = nullptr;
|
||||||
|
|
||||||
NANDImage = nullptr;
|
NANDImage = nullptr;
|
||||||
// The NANDImage is cleaned up (and its underlying file closed)
|
// The NANDImage is cleaned up (and its underlying file closed)
|
||||||
|
@ -170,7 +169,7 @@ void Reset()
|
||||||
|
|
||||||
I2C->Reset();
|
I2C->Reset();
|
||||||
CamModule->Reset();
|
CamModule->Reset();
|
||||||
DSi_DSP::Reset();
|
DSP->Reset();
|
||||||
|
|
||||||
SDMMC->CloseHandles();
|
SDMMC->CloseHandles();
|
||||||
SDIO->CloseHandles();
|
SDIO->CloseHandles();
|
||||||
|
@ -197,7 +196,7 @@ void Reset()
|
||||||
SCFG_MC = 0x0010 | (~((u32)(NDSCart::Cart != nullptr))&1);//0x0011;
|
SCFG_MC = 0x0010 | (~((u32)(NDSCart::Cart != nullptr))&1);//0x0011;
|
||||||
SCFG_RST = 0;
|
SCFG_RST = 0;
|
||||||
|
|
||||||
DSi_DSP::SetRstLine(false);
|
DSP->SetRstLine(false);
|
||||||
|
|
||||||
GPIO_Data = 0xff; // these actually initialize to high after reset
|
GPIO_Data = 0xff; // these actually initialize to high after reset
|
||||||
GPIO_Dir = 0x80; // enable sound out, all others input
|
GPIO_Dir = 0x80; // enable sound out, all others input
|
||||||
|
@ -239,7 +238,7 @@ void DoSavestate(Savestate* file)
|
||||||
{
|
{
|
||||||
Set_SCFG_Clock9(SCFG_Clock9);
|
Set_SCFG_Clock9(SCFG_Clock9);
|
||||||
Set_SCFG_MC(SCFG_MC);
|
Set_SCFG_MC(SCFG_MC);
|
||||||
DSi_DSP::SetRstLine(SCFG_RST & 0x0001);
|
DSP->SetRstLine(SCFG_RST & 0x0001);
|
||||||
|
|
||||||
MBK[0][8] = 0;
|
MBK[0][8] = 0;
|
||||||
MBK[1][8] = 0;
|
MBK[1][8] = 0;
|
||||||
|
@ -288,7 +287,7 @@ void DoSavestate(Savestate* file)
|
||||||
|
|
||||||
AES->DoSavestate(file);
|
AES->DoSavestate(file);
|
||||||
CamModule->DoSavestate(file);
|
CamModule->DoSavestate(file);
|
||||||
DSi_DSP::DoSavestate(file);
|
DSP->DoSavestate(file);
|
||||||
I2C->DoSavestate(file);
|
I2C->DoSavestate(file);
|
||||||
SDMMC->DoSavestate(file);
|
SDMMC->DoSavestate(file);
|
||||||
SDIO->DoSavestate(file);
|
SDIO->DoSavestate(file);
|
||||||
|
@ -700,7 +699,7 @@ void SoftReset()
|
||||||
// TODO: does the DSP get reset? NWRAM doesn't, so I'm assuming no
|
// TODO: does the DSP get reset? NWRAM doesn't, so I'm assuming no
|
||||||
// *HOWEVER*, the bootrom (which does get rerun) does remap NWRAM, and thus
|
// *HOWEVER*, the bootrom (which does get rerun) does remap NWRAM, and thus
|
||||||
// the DSP most likely gets reset
|
// the DSP most likely gets reset
|
||||||
DSi_DSP::Reset();
|
DSP->Reset();
|
||||||
|
|
||||||
SDMMC->CloseHandles();
|
SDMMC->CloseHandles();
|
||||||
SDIO->CloseHandles();
|
SDIO->CloseHandles();
|
||||||
|
@ -727,7 +726,7 @@ void SoftReset()
|
||||||
SCFG_MC = 0x0010;//0x0011;
|
SCFG_MC = 0x0010;//0x0011;
|
||||||
// TODO: is this actually reset?
|
// TODO: is this actually reset?
|
||||||
SCFG_RST = 0;
|
SCFG_RST = 0;
|
||||||
DSi_DSP::SetRstLine(false);
|
DSP->SetRstLine(false);
|
||||||
|
|
||||||
|
|
||||||
// LCD init flag
|
// LCD init flag
|
||||||
|
@ -2310,7 +2309,7 @@ u8 ARM9IORead8(u32 addr)
|
||||||
if ((addr & 0xFFFFFF00) == 0x04004300)
|
if ((addr & 0xFFFFFF00) == 0x04004300)
|
||||||
{
|
{
|
||||||
if (!(SCFG_EXT[0] & (1<<18))) return 0;
|
if (!(SCFG_EXT[0] & (1<<18))) return 0;
|
||||||
return DSi_DSP::Read8(addr);
|
return DSP->Read8(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IORead8(addr);
|
return NDS::ARM9IORead8(addr);
|
||||||
|
@ -2345,7 +2344,7 @@ u16 ARM9IORead16(u32 addr)
|
||||||
if ((addr & 0xFFFFFF00) == 0x04004300)
|
if ((addr & 0xFFFFFF00) == 0x04004300)
|
||||||
{
|
{
|
||||||
if (!(SCFG_EXT[0] & (1<<18))) return 0;
|
if (!(SCFG_EXT[0] & (1<<18))) return 0;
|
||||||
return DSi_DSP::Read16(addr);
|
return DSP->Read16(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IORead16(addr);
|
return NDS::ARM9IORead16(addr);
|
||||||
|
@ -2410,7 +2409,7 @@ u32 ARM9IORead32(u32 addr)
|
||||||
if ((addr & 0xFFFFFF00) == 0x04004300)
|
if ((addr & 0xFFFFFF00) == 0x04004300)
|
||||||
{
|
{
|
||||||
if (!(SCFG_EXT[0] & (1<<18))) return 0;
|
if (!(SCFG_EXT[0] & (1<<18))) return 0;
|
||||||
return DSi_DSP::Read32(addr);
|
return DSP->Read32(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IORead32(addr);
|
return NDS::ARM9IORead32(addr);
|
||||||
|
@ -2434,7 +2433,7 @@ void ARM9IOWrite8(u32 addr, u8 val)
|
||||||
if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
|
if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
|
||||||
return;
|
return;
|
||||||
SCFG_RST = (SCFG_RST & 0xFF00) | val;
|
SCFG_RST = (SCFG_RST & 0xFF00) | val;
|
||||||
DSi_DSP::SetRstLine(val & 1);
|
DSP->SetRstLine(val & 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04004040:
|
case 0x04004040:
|
||||||
|
@ -2480,7 +2479,7 @@ void ARM9IOWrite8(u32 addr, u8 val)
|
||||||
if ((addr & 0xFFFFFF00) == 0x04004300)
|
if ((addr & 0xFFFFFF00) == 0x04004300)
|
||||||
{
|
{
|
||||||
if (!(SCFG_EXT[0] & (1<<18))) return;
|
if (!(SCFG_EXT[0] & (1<<18))) return;
|
||||||
return DSi_DSP::Write8(addr, val);
|
return DSP->Write8(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IOWrite8(addr, val);
|
return NDS::ARM9IOWrite8(addr, val);
|
||||||
|
@ -2500,7 +2499,7 @@ void ARM9IOWrite16(u32 addr, u16 val)
|
||||||
if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
|
if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
|
||||||
return;
|
return;
|
||||||
SCFG_RST = val;
|
SCFG_RST = val;
|
||||||
DSi_DSP::SetRstLine(val & 1);
|
DSP->SetRstLine(val & 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04004040:
|
case 0x04004040:
|
||||||
|
@ -2540,7 +2539,7 @@ void ARM9IOWrite16(u32 addr, u16 val)
|
||||||
if ((addr & 0xFFFFFF00) == 0x04004300)
|
if ((addr & 0xFFFFFF00) == 0x04004300)
|
||||||
{
|
{
|
||||||
if (!(SCFG_EXT[0] & (1<<18))) return;
|
if (!(SCFG_EXT[0] & (1<<18))) return;
|
||||||
return DSi_DSP::Write16(addr, val);
|
return DSP->Write16(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IOWrite16(addr, val);
|
return NDS::ARM9IOWrite16(addr, val);
|
||||||
|
@ -2555,7 +2554,7 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
||||||
return;
|
return;
|
||||||
Set_SCFG_Clock9(val & 0xFFFF);
|
Set_SCFG_Clock9(val & 0xFFFF);
|
||||||
SCFG_RST = val >> 16;
|
SCFG_RST = val >> 16;
|
||||||
DSi_DSP::SetRstLine((val >> 16) & 1);
|
DSP->SetRstLine((val >> 16) & 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04004008:
|
case 0x04004008:
|
||||||
|
@ -2690,7 +2689,7 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
||||||
if ((addr & 0xFFFFFF00) == 0x04004300)
|
if ((addr & 0xFFFFFF00) == 0x04004300)
|
||||||
{
|
{
|
||||||
if (!(SCFG_EXT[0] & (1<<18))) return;
|
if (!(SCFG_EXT[0] & (1<<18))) return;
|
||||||
return DSi_DSP::Write32(addr, val);
|
return DSP->Write32(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IOWrite32(addr, val);
|
return NDS::ARM9IOWrite32(addr, val);
|
||||||
|
@ -2730,8 +2729,8 @@ u8 ARM7IORead8(u32 addr)
|
||||||
case 0x04004D07: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 56;
|
case 0x04004D07: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 56;
|
||||||
case 0x04004D08: return 0;
|
case 0x04004D08: return 0;
|
||||||
|
|
||||||
case 0x4004700: return DSi_DSP::SNDExCnt;
|
case 0x4004700: return DSP->ReadSNDExCnt() & 0xFF;
|
||||||
case 0x4004701: return DSi_DSP::SNDExCnt >> 8;
|
case 0x4004701: return DSP->ReadSNDExCnt() >> 8;
|
||||||
|
|
||||||
case 0x04004C00: return GPIO_Data;
|
case 0x04004C00: return GPIO_Data;
|
||||||
case 0x04004C01: return GPIO_Dir;
|
case 0x04004C01: return GPIO_Dir;
|
||||||
|
@ -2773,7 +2772,7 @@ u16 ARM7IORead16(u32 addr)
|
||||||
case 0x04004D06: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 48;
|
case 0x04004D06: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 48;
|
||||||
case 0x04004D08: return 0;
|
case 0x04004D08: return 0;
|
||||||
|
|
||||||
case 0x4004700: return DSi_DSP::SNDExCnt;
|
case 0x4004700: return DSP->ReadSNDExCnt();
|
||||||
|
|
||||||
case 0x04004C00: return GPIO_Data | ((u16)GPIO_Dir << 8);
|
case 0x04004C00: return GPIO_Data | ((u16)GPIO_Dir << 8);
|
||||||
case 0x04004C02: return GPIO_IEdgeSel | ((u16)GPIO_IE << 8);
|
case 0x04004C02: return GPIO_IEdgeSel | ((u16)GPIO_IE << 8);
|
||||||
|
@ -2852,7 +2851,7 @@ u32 ARM7IORead32(u32 addr)
|
||||||
|
|
||||||
case 0x4004700:
|
case 0x4004700:
|
||||||
Log(LogLevel::Debug, "32-Bit SNDExCnt read? %08X\n", NDS::ARM7->R[15]);
|
Log(LogLevel::Debug, "32-Bit SNDExCnt read? %08X\n", NDS::ARM7->R[15]);
|
||||||
return DSi_DSP::SNDExCnt;
|
return DSP->ReadSNDExCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr >= 0x04004800 && addr < 0x04004A00)
|
if (addr >= 0x04004800 && addr < 0x04004A00)
|
||||||
|
@ -2905,10 +2904,10 @@ void ARM7IOWrite8(u32 addr, u8 val)
|
||||||
case 0x04004501: I2C->WriteCnt(val); return;
|
case 0x04004501: I2C->WriteCnt(val); return;
|
||||||
|
|
||||||
case 0x4004700:
|
case 0x4004700:
|
||||||
DSi_DSP::WriteSNDExCnt((u16)val | (DSi_DSP::SNDExCnt & 0xFF00));
|
DSP->WriteSNDExCnt((u16)val, 0xFF);
|
||||||
return;
|
return;
|
||||||
case 0x4004701:
|
case 0x4004701:
|
||||||
DSi_DSP::WriteSNDExCnt(((u16)val << 8) | (DSi_DSP::SNDExCnt & 0x00FF));
|
DSP->WriteSNDExCnt(((u16)val << 8), 0xFF00);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04004C00:
|
case 0x04004C00:
|
||||||
|
@ -3007,7 +3006,7 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x4004700:
|
case 0x4004700:
|
||||||
DSi_DSP::WriteSNDExCnt(val);
|
DSP->WriteSNDExCnt(val, 0xFFFF);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04004C00:
|
case 0x04004C00:
|
||||||
|
@ -3156,7 +3155,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
||||||
|
|
||||||
case 0x4004700:
|
case 0x4004700:
|
||||||
Log(LogLevel::Debug, "32-Bit SNDExCnt write? %08X %08X\n", val, NDS::ARM7->R[15]);
|
Log(LogLevel::Debug, "32-Bit SNDExCnt write? %08X %08X\n", val, NDS::ARM7->R[15]);
|
||||||
DSi_DSP::WriteSNDExCnt(val);
|
DSP->WriteSNDExCnt(val, 0xFFFF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3204,7 +3203,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
||||||
|
|
||||||
if (addr >= 0x04004300 && addr <= 0x04004400)
|
if (addr >= 0x04004300 && addr <= 0x04004400)
|
||||||
{
|
{
|
||||||
DSi_DSP::Write32(addr, val);
|
DSP->Write32(addr, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
class DSi_I2CHost;
|
class DSi_I2CHost;
|
||||||
class DSi_CamModule;
|
class DSi_CamModule;
|
||||||
class DSi_AES;
|
class DSi_AES;
|
||||||
|
class DSi_DSP;
|
||||||
|
|
||||||
namespace DSi_NAND
|
namespace DSi_NAND
|
||||||
{
|
{
|
||||||
|
@ -63,6 +64,7 @@ extern u32 NWRAMMask[2][3];
|
||||||
extern DSi_I2CHost* I2C;
|
extern DSi_I2CHost* I2C;
|
||||||
extern DSi_CamModule* CamModule;
|
extern DSi_CamModule* CamModule;
|
||||||
extern DSi_AES* AES;
|
extern DSi_AES* AES;
|
||||||
|
extern DSi_DSP* DSP;
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
|
|
119
src/DSi_DSP.cpp
119
src/DSi_DSP.cpp
|
@ -27,34 +27,12 @@
|
||||||
using Platform::Log;
|
using Platform::Log;
|
||||||
using Platform::LogLevel;
|
using Platform::LogLevel;
|
||||||
|
|
||||||
namespace DSi_DSP
|
|
||||||
{
|
|
||||||
|
|
||||||
// not sure whether to not rather put it somewhere else
|
const u32 DSi_DSP::DataMemoryOffset = 0x20000; // from Teakra memory_interface.h
|
||||||
u16 SNDExCnt;
|
|
||||||
|
|
||||||
Teakra::Teakra* TeakraCore;
|
|
||||||
|
|
||||||
bool SCFG_RST;
|
|
||||||
|
|
||||||
u16 DSP_PADR;
|
|
||||||
u16 DSP_PCFG;
|
|
||||||
u16 DSP_PSTS;
|
|
||||||
u16 DSP_PSEM;
|
|
||||||
u16 DSP_PMASK;
|
|
||||||
u16 DSP_PCLEAR;
|
|
||||||
u16 DSP_CMD[3];
|
|
||||||
u16 DSP_REP[3];
|
|
||||||
|
|
||||||
u64 DSPTimestamp;
|
|
||||||
|
|
||||||
FIFO<u16, 16> PDATAReadFifo/*, *PDATAWriteFifo*/;
|
|
||||||
int PDataDMALen = 0;
|
|
||||||
|
|
||||||
constexpr u32 DataMemoryOffset = 0x20000; // from Teakra memory_interface.h
|
|
||||||
// NOTE: ^ IS IN DSP WORDS, NOT IN BYTES!
|
// NOTE: ^ IS IN DSP WORDS, NOT IN BYTES!
|
||||||
|
|
||||||
u16 GetPSTS()
|
|
||||||
|
u16 DSi_DSP::GetPSTS()
|
||||||
{
|
{
|
||||||
u16 r = DSP_PSTS & (1<<9); // this is the only sticky bit
|
u16 r = DSP_PSTS & (1<<9); // this is the only sticky bit
|
||||||
//r &= ~((1<<2)|(1<<7)); // we support instant resets and wrfifo xfers
|
//r &= ~((1<<2)|(1<<7)); // we support instant resets and wrfifo xfers
|
||||||
|
@ -73,26 +51,26 @@ u16 GetPSTS()
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IrqRep0()
|
void DSi_DSP::IrqRep0()
|
||||||
{
|
{
|
||||||
if (DSP_PCFG & (1<< 9)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
if (DSP_PCFG & (1<< 9)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
||||||
}
|
}
|
||||||
void IrqRep1()
|
void DSi_DSP::IrqRep1()
|
||||||
{
|
{
|
||||||
if (DSP_PCFG & (1<<10)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
if (DSP_PCFG & (1<<10)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
||||||
}
|
}
|
||||||
void IrqRep2()
|
void DSi_DSP::IrqRep2()
|
||||||
{
|
{
|
||||||
if (DSP_PCFG & (1<<11)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
if (DSP_PCFG & (1<<11)) NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
||||||
}
|
}
|
||||||
void IrqSem()
|
void DSi_DSP::IrqSem()
|
||||||
{
|
{
|
||||||
DSP_PSTS |= 1<<9;
|
DSP_PSTS |= 1<<9;
|
||||||
// apparently these are always fired?
|
// apparently these are always fired?
|
||||||
NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 DSPRead16(u32 addr)
|
u16 DSi_DSP::DSPRead16(u32 addr)
|
||||||
{
|
{
|
||||||
if (!(addr & 0x40000))
|
if (!(addr & 0x40000))
|
||||||
{
|
{
|
||||||
|
@ -106,7 +84,7 @@ u16 DSPRead16(u32 addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPWrite16(u32 addr, u16 val)
|
void DSi_DSP::DSPWrite16(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
// TODO: does the rule for overlapping NWRAM slots also apply to the DSP side?
|
// TODO: does the rule for overlapping NWRAM slots also apply to the DSP side?
|
||||||
|
|
||||||
|
@ -122,29 +100,32 @@ void DSPWrite16(u32 addr, u16 val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioCb(std::array<s16, 2> frame)
|
void DSi_DSP::AudioCb(std::array<s16, 2> frame)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Init()
|
DSi_DSP::DSi_DSP()
|
||||||
{
|
{
|
||||||
NDS::RegisterEventFunc(NDS::Event_DSi_DSP, 0, DSPCatchUpU32);
|
NDS::RegisterEventFunc(NDS::Event_DSi_DSP, 0, MemberEventFunc(DSi_DSP, DSPCatchUpU32));
|
||||||
|
|
||||||
TeakraCore = new Teakra::Teakra();
|
TeakraCore = new Teakra::Teakra();
|
||||||
SCFG_RST = false;
|
SCFG_RST = false;
|
||||||
|
|
||||||
if (!TeakraCore) return false;
|
// ????
|
||||||
|
//if (!TeakraCore) return false;
|
||||||
|
|
||||||
TeakraCore->SetRecvDataHandler(0, IrqRep0);
|
using namespace std::placeholders;
|
||||||
TeakraCore->SetRecvDataHandler(1, IrqRep1);
|
|
||||||
TeakraCore->SetRecvDataHandler(2, IrqRep2);
|
|
||||||
|
|
||||||
TeakraCore->SetSemaphoreHandler(IrqSem);
|
TeakraCore->SetRecvDataHandler(0, std::bind(&DSi_DSP::IrqRep0, this));
|
||||||
|
TeakraCore->SetRecvDataHandler(1, std::bind(&DSi_DSP::IrqRep1, this));
|
||||||
|
TeakraCore->SetRecvDataHandler(2, std::bind(&DSi_DSP::IrqRep2, this));
|
||||||
|
|
||||||
|
TeakraCore->SetSemaphoreHandler(std::bind(&DSi_DSP::IrqSem, this));
|
||||||
|
|
||||||
Teakra::SharedMemoryCallback smcb;
|
Teakra::SharedMemoryCallback smcb;
|
||||||
smcb.read16 = DSPRead16;
|
smcb.read16 = std::bind(&DSi_DSP::DSPRead16, this, _1);
|
||||||
smcb.write16 = DSPWrite16;
|
smcb.write16 = std::bind(&DSi_DSP::DSPWrite16, this, _1, _2);
|
||||||
TeakraCore->SetSharedMemoryCallback(smcb);
|
TeakraCore->SetSharedMemoryCallback(smcb);
|
||||||
|
|
||||||
// these happen instantaneously and without too much regard for bus aribtration
|
// these happen instantaneously and without too much regard for bus aribtration
|
||||||
|
@ -158,14 +139,13 @@ bool Init()
|
||||||
cb.write32 = DSi::ARM9Write32;
|
cb.write32 = DSi::ARM9Write32;
|
||||||
TeakraCore->SetAHBMCallback(cb);
|
TeakraCore->SetAHBMCallback(cb);
|
||||||
|
|
||||||
TeakraCore->SetAudioCallback(AudioCb);
|
TeakraCore->SetAudioCallback(std::bind(&DSi_DSP::AudioCb, this, _1));
|
||||||
|
|
||||||
//PDATAReadFifo = new FIFO<u16>(16);
|
//PDATAReadFifo = new FIFO<u16>(16);
|
||||||
//PDATAWriteFifo = new FIFO<u16>(16);
|
//PDATAWriteFifo = new FIFO<u16>(16);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
void DeInit()
|
|
||||||
|
DSi_DSP::~DSi_DSP()
|
||||||
{
|
{
|
||||||
//if (PDATAWriteFifo) delete PDATAWriteFifo;
|
//if (PDATAWriteFifo) delete PDATAWriteFifo;
|
||||||
if (TeakraCore) delete TeakraCore;
|
if (TeakraCore) delete TeakraCore;
|
||||||
|
@ -177,7 +157,7 @@ void DeInit()
|
||||||
NDS::UnregisterEventFunc(NDS::Event_DSi_DSP, 0);
|
NDS::UnregisterEventFunc(NDS::Event_DSi_DSP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void DSi_DSP::Reset()
|
||||||
{
|
{
|
||||||
DSPTimestamp = 0;
|
DSPTimestamp = 0;
|
||||||
|
|
||||||
|
@ -200,28 +180,28 @@ void Reset()
|
||||||
SNDExCnt = 0;
|
SNDExCnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRstReleased()
|
bool DSi_DSP::IsRstReleased()
|
||||||
{
|
{
|
||||||
return SCFG_RST;
|
return SCFG_RST;
|
||||||
}
|
}
|
||||||
void SetRstLine(bool release)
|
void DSi_DSP::SetRstLine(bool release)
|
||||||
{
|
{
|
||||||
SCFG_RST = release;
|
SCFG_RST = release;
|
||||||
Reset();
|
Reset();
|
||||||
DSPTimestamp = NDS::ARM9Timestamp; // only start now!
|
DSPTimestamp = NDS::ARM9Timestamp; // only start now!
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsDSPCoreEnabled()
|
inline bool DSi_DSP::IsDSPCoreEnabled()
|
||||||
{
|
{
|
||||||
return (DSi::SCFG_Clock9 & (1<<1)) && SCFG_RST && (!(DSP_PCFG & (1<<0)));
|
return (DSi::SCFG_Clock9 & (1<<1)) && SCFG_RST && (!(DSP_PCFG & (1<<0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsDSPIOEnabled()
|
inline bool DSi_DSP::IsDSPIOEnabled()
|
||||||
{
|
{
|
||||||
return (DSi::SCFG_Clock9 & (1<<1)) && SCFG_RST;
|
return (DSi::SCFG_Clock9 & (1<<1)) && SCFG_RST;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPCatchUp()
|
bool DSi_DSP::DSPCatchUp()
|
||||||
{
|
{
|
||||||
//asm volatile("int3");
|
//asm volatile("int3");
|
||||||
if (!IsDSPCoreEnabled())
|
if (!IsDSPCoreEnabled())
|
||||||
|
@ -249,9 +229,9 @@ bool DSPCatchUp()
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void DSPCatchUpU32(u32 _) { DSPCatchUp(); }
|
void DSi_DSP::DSPCatchUpU32(u32 _) { DSPCatchUp(); }
|
||||||
|
|
||||||
void PDataDMAWrite(u16 wrval)
|
void DSi_DSP::PDataDMAWrite(u16 wrval)
|
||||||
{
|
{
|
||||||
u32 addr = DSP_PADR;
|
u32 addr = DSP_PADR;
|
||||||
|
|
||||||
|
@ -293,7 +273,7 @@ void PDataDMAWrite(u16 wrval)
|
||||||
NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); // wrfifo empty
|
NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); // wrfifo empty
|
||||||
}
|
}
|
||||||
// TODO: FIFO interrupts! (rd full, nonempty)
|
// TODO: FIFO interrupts! (rd full, nonempty)
|
||||||
u16 PDataDMARead()
|
u16 DSi_DSP::PDataDMARead()
|
||||||
{
|
{
|
||||||
u16 r = 0;
|
u16 r = 0;
|
||||||
u32 addr = DSP_PADR;
|
u32 addr = DSP_PADR;
|
||||||
|
@ -331,7 +311,7 @@ u16 PDataDMARead()
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
void PDataDMAFetch()
|
void DSi_DSP::PDataDMAFetch()
|
||||||
{
|
{
|
||||||
if (!PDataDMALen) return;
|
if (!PDataDMALen) return;
|
||||||
|
|
||||||
|
@ -339,7 +319,7 @@ void PDataDMAFetch()
|
||||||
|
|
||||||
if (PDataDMALen > 0) --PDataDMALen;
|
if (PDataDMALen > 0) --PDataDMALen;
|
||||||
}
|
}
|
||||||
void PDataDMAStart()
|
void DSi_DSP::PDataDMAStart()
|
||||||
{
|
{
|
||||||
switch ((DSP_PSTS & (3<<2)) >> 2)
|
switch ((DSP_PSTS & (3<<2)) >> 2)
|
||||||
{
|
{
|
||||||
|
@ -358,13 +338,13 @@ void PDataDMAStart()
|
||||||
NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
NDS::SetIRQ(0, NDS::IRQ_DSi_DSP);
|
||||||
|
|
||||||
}
|
}
|
||||||
void PDataDMACancel()
|
void DSi_DSP::PDataDMACancel()
|
||||||
{
|
{
|
||||||
PDataDMALen = 0;
|
PDataDMALen = 0;
|
||||||
PDATAReadFifo.Clear();
|
PDATAReadFifo.Clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
u16 PDataDMAReadMMIO()
|
u16 DSi_DSP::PDataDMAReadMMIO()
|
||||||
{
|
{
|
||||||
u16 ret;
|
u16 ret;
|
||||||
|
|
||||||
|
@ -395,7 +375,7 @@ u16 PDataDMAReadMMIO()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 Read8(u32 addr)
|
u8 DSi_DSP::Read8(u32 addr)
|
||||||
{
|
{
|
||||||
//if (!IsDSPIOEnabled()) return 0;
|
//if (!IsDSPIOEnabled()) return 0;
|
||||||
DSPCatchUp();
|
DSPCatchUp();
|
||||||
|
@ -422,7 +402,7 @@ u8 Read8(u32 addr)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
u16 Read16(u32 addr)
|
u16 DSi_DSP::Read16(u32 addr)
|
||||||
{
|
{
|
||||||
//printf("DSP READ16 %d %08X %08X\n", IsDSPCoreEnabled(), addr, NDS::GetPC(0));
|
//printf("DSP READ16 %d %08X %08X\n", IsDSPCoreEnabled(), addr, NDS::GetPC(0));
|
||||||
//if (!IsDSPIOEnabled()) return 0;
|
//if (!IsDSPIOEnabled()) return 0;
|
||||||
|
@ -465,14 +445,14 @@ u16 Read16(u32 addr)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
u32 Read32(u32 addr)
|
u32 DSi_DSP::Read32(u32 addr)
|
||||||
{
|
{
|
||||||
addr &= 0x3C;
|
addr &= 0x3C;
|
||||||
return Read16(addr); // *shrug* (doesn't do anything unintended due to the
|
return Read16(addr); // *shrug* (doesn't do anything unintended due to the
|
||||||
// 4byte spacing between regs while they're all 16bit)
|
// 4byte spacing between regs while they're all 16bit)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write8(u32 addr, u8 val)
|
void DSi_DSP::Write8(u32 addr, u8 val)
|
||||||
{
|
{
|
||||||
//if (!IsDSPIOEnabled()) return;
|
//if (!IsDSPIOEnabled()) return;
|
||||||
DSPCatchUp();
|
DSPCatchUp();
|
||||||
|
@ -493,7 +473,7 @@ void Write8(u32 addr, u8 val)
|
||||||
// no REPx writes
|
// no REPx writes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Write16(u32 addr, u16 val)
|
void DSi_DSP::Write16(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
Log(LogLevel::Debug,"DSP WRITE16 %d %08X %08X %08X\n", IsDSPCoreEnabled(), addr, val, NDS::GetPC(0));
|
Log(LogLevel::Debug,"DSP WRITE16 %d %08X %08X %08X\n", IsDSPCoreEnabled(), addr, val, NDS::GetPC(0));
|
||||||
//if (!IsDSPIOEnabled()) return;
|
//if (!IsDSPIOEnabled()) return;
|
||||||
|
@ -548,14 +528,16 @@ void Write16(u32 addr, u16 val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write32(u32 addr, u32 val)
|
void DSi_DSP::Write32(u32 addr, u32 val)
|
||||||
{
|
{
|
||||||
addr &= 0x3C;
|
addr &= 0x3C;
|
||||||
Write16(addr, val & 0xFFFF);
|
Write16(addr, val & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteSNDExCnt(u16 val)
|
void DSi_DSP::WriteSNDExCnt(u16 val, u16 mask)
|
||||||
{
|
{
|
||||||
|
val = (val & mask) | (SNDExCnt & ~mask);
|
||||||
|
|
||||||
// it can be written even in NDS mode
|
// it can be written even in NDS mode
|
||||||
|
|
||||||
// mic frequency can only be changed if it was disabled
|
// mic frequency can only be changed if it was disabled
|
||||||
|
@ -569,7 +551,7 @@ void WriteSNDExCnt(u16 val)
|
||||||
SNDExCnt = val & 0xE00F;
|
SNDExCnt = val & 0xE00F;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run(u32 cycles)
|
void DSi_DSP::Run(u32 cycles)
|
||||||
{
|
{
|
||||||
if (!IsDSPCoreEnabled())
|
if (!IsDSPCoreEnabled())
|
||||||
{
|
{
|
||||||
|
@ -586,7 +568,7 @@ void Run(u32 cycles)
|
||||||
16384/*from citra (TeakraSlice)*/, 0, 0);
|
16384/*from citra (TeakraSlice)*/, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSavestate(Savestate* file)
|
void DSi_DSP::DoSavestate(Savestate* file)
|
||||||
{
|
{
|
||||||
file->Section("DSPi");
|
file->Section("DSPi");
|
||||||
|
|
||||||
|
@ -611,6 +593,3 @@ void DoSavestate(Savestate* file)
|
||||||
|
|
||||||
// TODO: save the Teakra state!!!
|
// TODO: save the Teakra state!!!
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -25,26 +25,14 @@
|
||||||
// TODO: for actual sound output
|
// TODO: for actual sound output
|
||||||
// * audio callbacks
|
// * audio callbacks
|
||||||
|
|
||||||
namespace DSi_DSP
|
namespace Teakra { class Teakra; }
|
||||||
|
|
||||||
|
class DSi_DSP
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
extern u16 SNDExCnt;
|
DSi_DSP();
|
||||||
|
~DSi_DSP();
|
||||||
extern u16 DSP_PDATA;
|
|
||||||
extern u16 DSP_PADR;
|
|
||||||
extern u16 DSP_PCFG;
|
|
||||||
extern u16 DSP_PSTS;
|
|
||||||
extern u16 DSP_PSEM;
|
|
||||||
extern u16 DSP_PMASK;
|
|
||||||
extern u16 DSP_PCLEAR;
|
|
||||||
extern u16 DSP_SEM;
|
|
||||||
extern u16 DSP_CMD[3];
|
|
||||||
extern u16 DSP_REP[3];
|
|
||||||
|
|
||||||
bool Init();
|
|
||||||
void DeInit();
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void DoSavestate(Savestate* file);
|
void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
void DSPCatchUpU32(u32 _);
|
void DSPCatchUpU32(u32 _);
|
||||||
|
@ -63,12 +51,58 @@ void Write16(u32 addr, u16 val);
|
||||||
u32 Read32(u32 addr);
|
u32 Read32(u32 addr);
|
||||||
void Write32(u32 addr, u32 val);
|
void Write32(u32 addr, u32 val);
|
||||||
|
|
||||||
void WriteSNDExCnt(u16 val);
|
u16 ReadSNDExCnt() { return SNDExCnt; }
|
||||||
|
void WriteSNDExCnt(u16 val, u16 mask);
|
||||||
|
|
||||||
// NOTE: checks SCFG_CLK9
|
// NOTE: checks SCFG_CLK9
|
||||||
void Run(u32 cycles);
|
void Run(u32 cycles);
|
||||||
|
|
||||||
}
|
void IrqRep0();
|
||||||
|
void IrqRep1();
|
||||||
|
void IrqRep2();
|
||||||
|
void IrqSem();
|
||||||
|
u16 DSPRead16(u32 addr);
|
||||||
|
void DSPWrite16(u32 addr, u16 val);
|
||||||
|
void AudioCb(std::array<s16, 2> frame);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// not sure whether to not rather put it somewhere else
|
||||||
|
u16 SNDExCnt;
|
||||||
|
|
||||||
|
Teakra::Teakra* TeakraCore;
|
||||||
|
|
||||||
|
bool SCFG_RST;
|
||||||
|
|
||||||
|
u16 DSP_PADR;
|
||||||
|
u16 DSP_PCFG;
|
||||||
|
u16 DSP_PSTS;
|
||||||
|
u16 DSP_PSEM;
|
||||||
|
u16 DSP_PMASK;
|
||||||
|
u16 DSP_PCLEAR;
|
||||||
|
u16 DSP_CMD[3];
|
||||||
|
u16 DSP_REP[3];
|
||||||
|
|
||||||
|
u64 DSPTimestamp;
|
||||||
|
|
||||||
|
FIFO<u16, 16> PDATAReadFifo/*, *PDATAWriteFifo*/;
|
||||||
|
int PDataDMALen;
|
||||||
|
|
||||||
|
static const u32 DataMemoryOffset;
|
||||||
|
|
||||||
|
u16 GetPSTS();
|
||||||
|
|
||||||
|
inline bool IsDSPCoreEnabled();
|
||||||
|
inline bool IsDSPIOEnabled();
|
||||||
|
|
||||||
|
bool DSPCatchUp();
|
||||||
|
|
||||||
|
void PDataDMAWrite(u16 wrval);
|
||||||
|
u16 PDataDMARead();
|
||||||
|
void PDataDMAFetch();
|
||||||
|
void PDataDMAStart();
|
||||||
|
void PDataDMACancel();
|
||||||
|
u16 PDataDMAReadMMIO();
|
||||||
|
};
|
||||||
|
|
||||||
#endif // DSI_DSP_H
|
#endif // DSI_DSP_H
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue