mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-27 00:00:07 -06:00
basic ideas for actual HLE functionality. do the init handshake.
This commit is contained in:
@ -40,7 +40,11 @@ DSPHLE_UcodeBase::~DSPHLE_UcodeBase()
|
|||||||
|
|
||||||
void DSPHLE_UcodeBase::Reset()
|
void DSPHLE_UcodeBase::Reset()
|
||||||
{
|
{
|
||||||
//
|
memset(CmdReg, 0, sizeof(CmdReg));
|
||||||
|
memset(CmdWritten, 0, sizeof(CmdWritten));
|
||||||
|
memset(ReplyReg, 0, sizeof(ReplyReg));
|
||||||
|
memset(ReplyWritten, 0, sizeof(ReplyWritten));
|
||||||
|
memset(ReplyReadCb, 0, sizeof(ReplyReadCb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPHLE_UcodeBase::DoSavestate(Savestate *file)
|
void DSPHLE_UcodeBase::DoSavestate(Savestate *file)
|
||||||
@ -48,18 +52,67 @@ void DSPHLE_UcodeBase::DoSavestate(Savestate *file)
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPHLE_UcodeBase::SendDataIsEmpty(u8 index)
|
|
||||||
|
bool DSPHLE_UcodeBase::RecvDataIsReady(u8 index)
|
||||||
{
|
{
|
||||||
//
|
return ReplyWritten[index];
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPHLE_UcodeBase::RecvDataIsEmpty(u8 index)
|
bool DSPHLE_UcodeBase::SendDataIsEmpty(u8 index)
|
||||||
{
|
{
|
||||||
//
|
return !CmdWritten[index];
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 DSPHLE_UcodeBase::RecvData(u8 index)
|
||||||
|
{
|
||||||
|
if (!ReplyWritten[index]) return 0; // CHECKME
|
||||||
|
|
||||||
|
u16 ret = ReplyReg[index];
|
||||||
|
ReplyWritten[index] = false;
|
||||||
|
|
||||||
|
if (ReplyReadCb[index])
|
||||||
|
{
|
||||||
|
ReplyReadCb[index]();
|
||||||
|
ReplyReadCb[index] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPHLE_UcodeBase::SendData(u8 index, u16 val)
|
||||||
|
{
|
||||||
|
if (CmdWritten[index])
|
||||||
|
{
|
||||||
|
printf("??? trying to write cmd but there's already one\n");
|
||||||
|
return; // CHECKME
|
||||||
|
}
|
||||||
|
|
||||||
|
CmdReg[index] = val;
|
||||||
|
CmdWritten[index] = true;
|
||||||
|
printf("DSP: send cmd%d %04X\n", index, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DSPHLE_UcodeBase::SendReply(u8 index, u16 val)
|
||||||
|
{
|
||||||
|
if (ReplyWritten[index])
|
||||||
|
{
|
||||||
|
printf("??? trying to write reply but there's already one\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplyReg[index] = val;
|
||||||
|
ReplyWritten[index] = true;
|
||||||
|
|
||||||
|
// TODO add callback for when it is successfully written
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPHLE_UcodeBase::SetReplyReadCallback(u8 index, fnReplyReadCb callback)
|
||||||
|
{
|
||||||
|
ReplyReadCb[index] = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
u16 DSPHLE_UcodeBase::DMAChan0GetDstHigh()
|
u16 DSPHLE_UcodeBase::DMAChan0GetDstHigh()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -160,16 +213,26 @@ void DSPHLE_UcodeBase::MaskSemaphore(u16 val)
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 DSPHLE_UcodeBase::RecvData(u8 index)
|
|
||||||
|
void DSPHLE_UcodeBase::Start()
|
||||||
{
|
{
|
||||||
//
|
printf("DSP HLE: start\n");
|
||||||
return 0;
|
// TODO later: detect which ucode it is and create the right class!
|
||||||
|
// (and fall back to Teakra if not a known ucode)
|
||||||
|
|
||||||
|
SendReply(0, 1);
|
||||||
|
SendReply(1, 1);
|
||||||
|
SendReply(2, 1);
|
||||||
|
SetReplyReadCallback(2, [=]()
|
||||||
|
{
|
||||||
|
printf("reply 2 was read\n");
|
||||||
|
|
||||||
|
SendReply(2, 0x0800);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO more shit
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPHLE_UcodeBase::SendData(u8 index, u16 val)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSPHLE_UcodeBase::Run(u32 cycles)
|
void DSPHLE_UcodeBase::Run(u32 cycles)
|
||||||
{
|
{
|
||||||
|
@ -35,11 +35,19 @@ public:
|
|||||||
void Reset();
|
void Reset();
|
||||||
void DoSavestate(Savestate* file);
|
void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
|
typedef std::function<void()> fnReplyReadCb;
|
||||||
|
|
||||||
//void SetRecvDataHandler(u8 index, std::function<void()> func);
|
//void SetRecvDataHandler(u8 index, std::function<void()> func);
|
||||||
//void SetSemaphoreHandler(std::function<void()> func);
|
//void SetSemaphoreHandler(std::function<void()> func);
|
||||||
|
|
||||||
|
bool RecvDataIsReady(u8 index);
|
||||||
bool SendDataIsEmpty(u8 index);
|
bool SendDataIsEmpty(u8 index);
|
||||||
bool RecvDataIsEmpty(u8 index);
|
u16 RecvData(u8 index);
|
||||||
|
void SendData(u8 index, u16 val);
|
||||||
|
|
||||||
|
// TODO receive cmd
|
||||||
|
void SendReply(u8 index, u16 val);
|
||||||
|
void SetReplyReadCallback(u8 index, fnReplyReadCb callback);
|
||||||
|
|
||||||
u16 DMAChan0GetDstHigh();
|
u16 DMAChan0GetDstHigh();
|
||||||
u16 AHBMGetDmaChannel(u16 index);
|
u16 AHBMGetDmaChannel(u16 index);
|
||||||
@ -62,10 +70,16 @@ public:
|
|||||||
void ClearSemaphore(u16 val);
|
void ClearSemaphore(u16 val);
|
||||||
void MaskSemaphore(u16 val);
|
void MaskSemaphore(u16 val);
|
||||||
|
|
||||||
u16 RecvData(u8 index);
|
void Start();
|
||||||
void SendData(u8 index, u16 val);
|
|
||||||
|
|
||||||
void Run(u32 cycles);
|
void Run(u32 cycles);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
u16 CmdReg[3];
|
||||||
|
bool CmdWritten[3];
|
||||||
|
u16 ReplyReg[3];
|
||||||
|
bool ReplyWritten[3];
|
||||||
|
fnReplyReadCb ReplyReadCb[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
133
src/DSi_DSP.cpp
133
src/DSi_DSP.cpp
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "teakra/include/teakra/teakra.h"
|
#include "teakra/include/teakra/teakra.h"
|
||||||
|
#include "DSP_HLE/Ucode_Base.h"
|
||||||
|
|
||||||
#include "DSi.h"
|
#include "DSi.h"
|
||||||
#include "DSi_DSP.h"
|
#include "DSi_DSP.h"
|
||||||
@ -43,12 +44,18 @@ u16 DSi_DSP::GetPSTS() const
|
|||||||
if ( PDATAReadFifo.IsFull ()) r |= 1<<5;
|
if ( PDATAReadFifo.IsFull ()) r |= 1<<5;
|
||||||
if (!PDATAReadFifo.IsEmpty()) r |=(1<<6)|(1<<0);
|
if (!PDATAReadFifo.IsEmpty()) r |=(1<<6)|(1<<0);
|
||||||
|
|
||||||
if (!TeakraCore->SendDataIsEmpty(0)) r |= 1<<13;
|
/*if (!TeakraCore->SendDataIsEmpty(0)) r |= 1<<13;
|
||||||
if (!TeakraCore->SendDataIsEmpty(1)) r |= 1<<14;
|
if (!TeakraCore->SendDataIsEmpty(1)) r |= 1<<14;
|
||||||
if (!TeakraCore->SendDataIsEmpty(2)) r |= 1<<15;
|
if (!TeakraCore->SendDataIsEmpty(2)) r |= 1<<15;
|
||||||
if ( TeakraCore->RecvDataIsReady(0)) r |= 1<<10;
|
if ( TeakraCore->RecvDataIsReady(0)) r |= 1<<10;
|
||||||
if ( TeakraCore->RecvDataIsReady(1)) r |= 1<<11;
|
if ( TeakraCore->RecvDataIsReady(1)) r |= 1<<11;
|
||||||
if ( TeakraCore->RecvDataIsReady(2)) r |= 1<<12;
|
if ( TeakraCore->RecvDataIsReady(2)) r |= 1<<12;*/
|
||||||
|
if (!HleCore->SendDataIsEmpty(0)) r |= 1<<13;
|
||||||
|
if (!HleCore->SendDataIsEmpty(1)) r |= 1<<14;
|
||||||
|
if (!HleCore->SendDataIsEmpty(2)) r |= 1<<15;
|
||||||
|
if ( HleCore->RecvDataIsReady(0)) r |= 1<<10;
|
||||||
|
if ( HleCore->RecvDataIsReady(1)) r |= 1<<11;
|
||||||
|
if ( HleCore->RecvDataIsReady(2)) r |= 1<<12;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -111,7 +118,8 @@ DSi_DSP::DSi_DSP(melonDS::DSi& dsi) : DSi(dsi)
|
|||||||
{
|
{
|
||||||
DSi.RegisterEventFuncs(Event_DSi_DSP, this, {MakeEventThunk(DSi_DSP, DSPCatchUpU32)});
|
DSi.RegisterEventFuncs(Event_DSi_DSP, this, {MakeEventThunk(DSi_DSP, DSPCatchUpU32)});
|
||||||
|
|
||||||
TeakraCore = new Teakra::Teakra();
|
//TeakraCore = new Teakra::Teakra();
|
||||||
|
HleCore = new DSPHLE_UcodeBase();
|
||||||
SCFG_RST = false;
|
SCFG_RST = false;
|
||||||
|
|
||||||
// ????
|
// ????
|
||||||
@ -119,7 +127,7 @@ DSi_DSP::DSi_DSP(melonDS::DSi& dsi) : DSi(dsi)
|
|||||||
|
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
TeakraCore->SetRecvDataHandler(0, std::bind(&DSi_DSP::IrqRep0, this));
|
/*TeakraCore->SetRecvDataHandler(0, std::bind(&DSi_DSP::IrqRep0, this));
|
||||||
TeakraCore->SetRecvDataHandler(1, std::bind(&DSi_DSP::IrqRep1, this));
|
TeakraCore->SetRecvDataHandler(1, std::bind(&DSi_DSP::IrqRep1, this));
|
||||||
TeakraCore->SetRecvDataHandler(2, std::bind(&DSi_DSP::IrqRep2, this));
|
TeakraCore->SetRecvDataHandler(2, std::bind(&DSi_DSP::IrqRep2, this));
|
||||||
|
|
||||||
@ -141,7 +149,7 @@ DSi_DSP::DSi_DSP(melonDS::DSi& dsi) : DSi(dsi)
|
|||||||
cb.write32 = [this](auto addr, auto val) { DSi.ARM9Write32(addr, val); };
|
cb.write32 = [this](auto addr, auto val) { DSi.ARM9Write32(addr, val); };
|
||||||
TeakraCore->SetAHBMCallback(cb);
|
TeakraCore->SetAHBMCallback(cb);
|
||||||
|
|
||||||
TeakraCore->SetAudioCallback(std::bind(&DSi_DSP::AudioCb, this, _1));
|
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);
|
||||||
@ -150,11 +158,13 @@ DSi_DSP::DSi_DSP(melonDS::DSi& dsi) : DSi(dsi)
|
|||||||
DSi_DSP::~DSi_DSP()
|
DSi_DSP::~DSi_DSP()
|
||||||
{
|
{
|
||||||
//if (PDATAWriteFifo) delete PDATAWriteFifo;
|
//if (PDATAWriteFifo) delete PDATAWriteFifo;
|
||||||
if (TeakraCore) delete TeakraCore;
|
//if (TeakraCore) delete TeakraCore;
|
||||||
|
if (HleCore) delete HleCore;
|
||||||
|
|
||||||
//PDATAReadFifo = NULL;
|
//PDATAReadFifo = NULL;
|
||||||
//PDATAWriteFifo = NULL;
|
//PDATAWriteFifo = NULL;
|
||||||
TeakraCore = NULL;
|
//TeakraCore = NULL;
|
||||||
|
HleCore = nullptr;
|
||||||
|
|
||||||
DSi.UnregisterEventFuncs(Event_DSi_DSP);
|
DSi.UnregisterEventFuncs(Event_DSi_DSP);
|
||||||
}
|
}
|
||||||
@ -175,7 +185,8 @@ void DSi_DSP::Reset()
|
|||||||
|
|
||||||
PDATAReadFifo.Clear();
|
PDATAReadFifo.Clear();
|
||||||
//PDATAWriteFifo->Clear();
|
//PDATAWriteFifo->Clear();
|
||||||
TeakraCore->Reset();
|
//TeakraCore->Reset();
|
||||||
|
HleCore->Reset();
|
||||||
|
|
||||||
DSi.CancelEvent(Event_DSi_DSP);
|
DSi.CancelEvent(Event_DSi_DSP);
|
||||||
|
|
||||||
@ -240,17 +251,23 @@ void DSi_DSP::PDataDMAWrite(u16 wrval)
|
|||||||
switch (DSP_PCFG & (7<<12)) // memory region select
|
switch (DSP_PCFG & (7<<12)) // memory region select
|
||||||
{
|
{
|
||||||
case 0<<12: // data
|
case 0<<12: // data
|
||||||
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
//addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
||||||
TeakraCore->DataWriteA32(addr, wrval);
|
//TeakraCore->DataWriteA32(addr, wrval);
|
||||||
|
addr |= (u32)HleCore->DMAChan0GetDstHigh() << 16;
|
||||||
|
HleCore->DataWriteA32(addr, wrval);
|
||||||
break;
|
break;
|
||||||
case 1<<12: // mmio
|
case 1<<12: // mmio
|
||||||
TeakraCore->MMIOWrite(addr & 0x7FF, wrval);
|
//TeakraCore->MMIOWrite(addr & 0x7FF, wrval);
|
||||||
|
HleCore->MMIOWrite(addr & 0x7FF, wrval);
|
||||||
break;
|
break;
|
||||||
case 5<<12: // program
|
case 5<<12: // program
|
||||||
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
//addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
||||||
TeakraCore->ProgramWrite(addr, wrval);
|
//TeakraCore->ProgramWrite(addr, wrval);
|
||||||
|
addr |= (u32)HleCore->DMAChan0GetDstHigh() << 16;
|
||||||
|
HleCore->ProgramWrite(addr, wrval);
|
||||||
break;
|
break;
|
||||||
case 7<<12:
|
case 7<<12:
|
||||||
|
#if 0
|
||||||
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
||||||
// only do stuff when AHBM is configured correctly
|
// only do stuff when AHBM is configured correctly
|
||||||
if (TeakraCore->AHBMGetDmaChannel(0) == 0 && TeakraCore->AHBMGetDirection(0) == 1/*W*/)
|
if (TeakraCore->AHBMGetDmaChannel(0) == 0 && TeakraCore->AHBMGetDirection(0) == 1/*W*/)
|
||||||
@ -265,6 +282,21 @@ void DSi_DSP::PDataDMAWrite(u16 wrval)
|
|||||||
case 2: /* 32 b */ TeakraCore->AHBMWrite32(addr, wrval); break;
|
case 2: /* 32 b */ TeakraCore->AHBMWrite32(addr, wrval); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
addr |= (u32)HleCore->DMAChan0GetDstHigh() << 16;
|
||||||
|
// only do stuff when AHBM is configured correctly
|
||||||
|
if (HleCore->AHBMGetDmaChannel(0) == 0 && HleCore->AHBMGetDirection(0) == 1/*W*/)
|
||||||
|
{
|
||||||
|
switch (HleCore->AHBMGetUnitSize(0))
|
||||||
|
{
|
||||||
|
case 0: /* 8bit */ DSi.ARM9Write8 (addr, (u8)wrval); break;
|
||||||
|
case 1: /* 16 b */ HleCore->AHBMWrite16(addr, wrval); break;
|
||||||
|
// does it work like this, or should it first buffer two u16's
|
||||||
|
// until it has enough data to write to the actual destination?
|
||||||
|
// -> this seems to be correct behavior!
|
||||||
|
case 2: /* 32 b */ HleCore->AHBMWrite32(addr, wrval); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default: return;
|
default: return;
|
||||||
}printf("DSP: PDATA write %08X -> %04X\n", addr, wrval);
|
}printf("DSP: PDATA write %08X -> %04X\n", addr, wrval);
|
||||||
@ -282,17 +314,23 @@ u16 DSi_DSP::PDataDMARead()
|
|||||||
switch (DSP_PCFG & (7<<12)) // memory region select
|
switch (DSP_PCFG & (7<<12)) // memory region select
|
||||||
{
|
{
|
||||||
case 0<<12: // data
|
case 0<<12: // data
|
||||||
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
//addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
||||||
r = TeakraCore->DataReadA32(addr);
|
//r = TeakraCore->DataReadA32(addr);
|
||||||
|
addr |= (u32)HleCore->DMAChan0GetDstHigh() << 16;
|
||||||
|
r = HleCore->DataReadA32(addr);
|
||||||
break;
|
break;
|
||||||
case 1<<12: // mmio
|
case 1<<12: // mmio
|
||||||
r = TeakraCore->MMIORead(addr & 0x7FF);
|
//r = TeakraCore->MMIORead(addr & 0x7FF);
|
||||||
|
r = HleCore->MMIORead(addr & 0x7FF);
|
||||||
break;
|
break;
|
||||||
case 5<<12: // program
|
case 5<<12: // program
|
||||||
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
//addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
||||||
r = TeakraCore->ProgramRead(addr);
|
//r = TeakraCore->ProgramRead(addr);
|
||||||
|
addr |= (u32)HleCore->DMAChan0GetDstHigh() << 16;
|
||||||
|
r = HleCore->ProgramRead(addr);
|
||||||
break;
|
break;
|
||||||
case 7<<12:
|
case 7<<12:
|
||||||
|
#if 0
|
||||||
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
addr |= (u32)TeakraCore->DMAChan0GetDstHigh() << 16;
|
||||||
// only do stuff when AHBM is configured correctly
|
// only do stuff when AHBM is configured correctly
|
||||||
if (TeakraCore->AHBMGetDmaChannel(0) == 0 && TeakraCore->AHBMGetDirection(0) == 0/*R*/)
|
if (TeakraCore->AHBMGetDmaChannel(0) == 0 && TeakraCore->AHBMGetDirection(0) == 0/*R*/)
|
||||||
@ -304,6 +342,18 @@ u16 DSi_DSP::PDataDMARead()
|
|||||||
case 2: /* 32 b */ r = (u16)TeakraCore->AHBMRead32(addr); break;
|
case 2: /* 32 b */ r = (u16)TeakraCore->AHBMRead32(addr); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
addr |= (u32)HleCore->DMAChan0GetDstHigh() << 16;
|
||||||
|
// only do stuff when AHBM is configured correctly
|
||||||
|
if (HleCore->AHBMGetDmaChannel(0) == 0 && HleCore->AHBMGetDirection(0) == 0/*R*/)
|
||||||
|
{
|
||||||
|
switch (HleCore->AHBMGetUnitSize(0))
|
||||||
|
{
|
||||||
|
case 0: /* 8bit */ r = DSi.ARM9Read8 (addr); break;
|
||||||
|
case 1: /* 16 b */ r = HleCore->AHBMRead16(addr); break;
|
||||||
|
case 2: /* 32 b */ r = (u16)HleCore->AHBMRead32(addr); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default: return r;
|
default: return r;
|
||||||
}printf("DSP: PDATA read %08X -> %04X\n", addr, r);
|
}printf("DSP: PDATA read %08X -> %04X\n", addr, r);
|
||||||
@ -392,8 +442,10 @@ u8 DSi_DSP::Read8(u32 addr)
|
|||||||
case 0x14: return DSP_PMASK & 0xFF;
|
case 0x14: return DSP_PMASK & 0xFF;
|
||||||
case 0x15: return DSP_PMASK >> 8;
|
case 0x15: return DSP_PMASK >> 8;
|
||||||
// no DSP_PCLEAR read
|
// no DSP_PCLEAR read
|
||||||
case 0x1C: return TeakraCore->GetSemaphore() & 0xFF; // SEM
|
//case 0x1C: return TeakraCore->GetSemaphore() & 0xFF; // SEM
|
||||||
case 0x1D: return TeakraCore->GetSemaphore() >> 8;
|
//case 0x1D: return TeakraCore->GetSemaphore() >> 8;
|
||||||
|
case 0x1C: return HleCore->GetSemaphore() & 0xFF; // SEM
|
||||||
|
case 0x1D: return HleCore->GetSemaphore() >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -416,7 +468,8 @@ u16 DSi_DSP::Read16(u32 addr)
|
|||||||
case 0x10: return DSP_PSEM;
|
case 0x10: return DSP_PSEM;
|
||||||
case 0x14: return DSP_PMASK;
|
case 0x14: return DSP_PMASK;
|
||||||
// no DSP_PCLEAR read
|
// no DSP_PCLEAR read
|
||||||
case 0x1C: return TeakraCore->GetSemaphore(); // SEM
|
//case 0x1C: return TeakraCore->GetSemaphore(); // SEM
|
||||||
|
case 0x1C: return HleCore->GetSemaphore(); // SEM
|
||||||
|
|
||||||
case 0x20: return DSP_CMD[0];
|
case 0x20: return DSP_CMD[0];
|
||||||
case 0x28: return DSP_CMD[1];
|
case 0x28: return DSP_CMD[1];
|
||||||
@ -424,17 +477,20 @@ u16 DSi_DSP::Read16(u32 addr)
|
|||||||
|
|
||||||
case 0x24:
|
case 0x24:
|
||||||
{
|
{
|
||||||
u16 r = TeakraCore->RecvData(0);printf("DSP: read CMD0, %04X\n", r);
|
//u16 r = TeakraCore->RecvData(0);printf("DSP: read CMD0, %04X\n", r);
|
||||||
|
u16 r = HleCore->RecvData(0);printf("DSP: read CMD0, %04X\n", r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
case 0x2C:
|
case 0x2C:
|
||||||
{
|
{
|
||||||
u16 r = TeakraCore->RecvData(1);printf("DSP: read CMD1, %04X\n", r);
|
//u16 r = TeakraCore->RecvData(1);printf("DSP: read CMD1, %04X\n", r);
|
||||||
|
u16 r = HleCore->RecvData(1);printf("DSP: read CMD1, %04X\n", r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
case 0x34:
|
case 0x34:
|
||||||
{
|
{
|
||||||
u16 r = TeakraCore->RecvData(2);printf("DSP: read CMD2, %04X\n", r);
|
//u16 r = TeakraCore->RecvData(2);printf("DSP: read CMD2, %04X\n", r);
|
||||||
|
u16 r = HleCore->RecvData(2);printf("DSP: read CMD2, %04X\n", r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,9 +539,12 @@ void DSi_DSP::Write16(u32 addr, u16 val)
|
|||||||
case 0x04: DSP_PADR = val; break;
|
case 0x04: DSP_PADR = val; break;
|
||||||
|
|
||||||
case 0x08:
|
case 0x08:
|
||||||
|
if ((DSP_PCFG & (1<<0)) && (!(val & (1<<0))))
|
||||||
|
HleCore->Start();
|
||||||
DSP_PCFG = val;
|
DSP_PCFG = val;
|
||||||
if (DSP_PCFG & (1<<0))
|
if (DSP_PCFG & (1<<0))
|
||||||
TeakraCore->Reset();
|
//TeakraCore->Reset();
|
||||||
|
HleCore->Reset();
|
||||||
/*else if (!fazil)
|
/*else if (!fazil)
|
||||||
{
|
{
|
||||||
fazil = true;
|
fazil = true;
|
||||||
@ -499,15 +558,19 @@ void DSi_DSP::Write16(u32 addr, u16 val)
|
|||||||
// no PSTS writes
|
// no PSTS writes
|
||||||
case 0x10:
|
case 0x10:
|
||||||
DSP_PSEM = val;
|
DSP_PSEM = val;
|
||||||
TeakraCore->SetSemaphore(val);
|
//TeakraCore->SetSemaphore(val);
|
||||||
|
HleCore->SetSemaphore(val);
|
||||||
break;
|
break;
|
||||||
case 0x14:
|
case 0x14:
|
||||||
DSP_PMASK = val;
|
DSP_PMASK = val;
|
||||||
TeakraCore->MaskSemaphore(val);
|
//TeakraCore->MaskSemaphore(val);
|
||||||
|
HleCore->MaskSemaphore(val);
|
||||||
break;
|
break;
|
||||||
case 0x18: // PCLEAR
|
case 0x18: // PCLEAR
|
||||||
TeakraCore->ClearSemaphore(val);
|
//TeakraCore->ClearSemaphore(val);
|
||||||
if (TeakraCore->GetSemaphore() == 0)
|
HleCore->ClearSemaphore(val);
|
||||||
|
//if (TeakraCore->GetSemaphore() == 0)
|
||||||
|
if (HleCore->GetSemaphore() == 0)
|
||||||
DSP_PSTS &= ~(1<<9);
|
DSP_PSTS &= ~(1<<9);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -515,15 +578,18 @@ void DSi_DSP::Write16(u32 addr, u16 val)
|
|||||||
|
|
||||||
case 0x20: // CMD0
|
case 0x20: // CMD0
|
||||||
DSP_CMD[0] = val;printf("DSP: CMD0 = %04X\n", val);
|
DSP_CMD[0] = val;printf("DSP: CMD0 = %04X\n", val);
|
||||||
TeakraCore->SendData(0, val);
|
//TeakraCore->SendData(0, val);
|
||||||
|
HleCore->SendData(0, val);
|
||||||
break;
|
break;
|
||||||
case 0x28: // CMD1
|
case 0x28: // CMD1
|
||||||
DSP_CMD[1] = val;printf("DSP: CMD1 = %04X\n", val);
|
DSP_CMD[1] = val;printf("DSP: CMD1 = %04X\n", val);
|
||||||
TeakraCore->SendData(1, val);
|
//TeakraCore->SendData(1, val);
|
||||||
|
HleCore->SendData(1, val);
|
||||||
break;
|
break;
|
||||||
case 0x30: // CMD2
|
case 0x30: // CMD2
|
||||||
DSP_CMD[2] = val;printf("DSP: CMD2 = %04X\n", val);
|
DSP_CMD[2] = val;printf("DSP: CMD2 = %04X\n", val);
|
||||||
TeakraCore->SendData(2, val);
|
//TeakraCore->SendData(2, val);
|
||||||
|
HleCore->SendData(2, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// no REPx writes
|
// no REPx writes
|
||||||
@ -561,7 +627,8 @@ void DSi_DSP::Run(u32 cycles)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TeakraCore->Run(cycles);
|
//TeakraCore->Run(cycles);
|
||||||
|
HleCore->Run(cycles);
|
||||||
|
|
||||||
DSPTimestamp += cycles;
|
DSPTimestamp += cycles;
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ namespace Teakra { class Teakra; }
|
|||||||
namespace melonDS
|
namespace melonDS
|
||||||
{
|
{
|
||||||
class DSi;
|
class DSi;
|
||||||
|
class DSPHLE_UcodeBase;
|
||||||
class DSi_DSP
|
class DSi_DSP
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -74,6 +75,7 @@ private:
|
|||||||
u16 SNDExCnt;
|
u16 SNDExCnt;
|
||||||
|
|
||||||
Teakra::Teakra* TeakraCore;
|
Teakra::Teakra* TeakraCore;
|
||||||
|
DSPHLE_UcodeBase* HleCore;
|
||||||
|
|
||||||
bool SCFG_RST;
|
bool SCFG_RST;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user