Update DSP semaphore on semaphore event signal

Fixes Pokemon X and other DSP-needy games...
This commit is contained in:
wheremyfoodat 2024-02-18 03:54:00 +02:00
parent d3dc9e2f71
commit f58354af06
7 changed files with 53 additions and 15 deletions

View file

@ -38,16 +38,20 @@ TeakraDSP::TeakraDSP(Memory& mem, DSPService& dspService) : DSPCore(mem, dspServ
// Set up callbacks for Teakra
Teakra::AHBMCallback ahbm;
ahbm.read8 = [&](u32 addr) -> u8 { return mem.read8(addr); };
ahbm.read16 = [&](u32 addr) -> u16 { return mem.read16(addr); };
ahbm.read32 = [&](u32 addr) -> u32 { return mem.read32(addr); };
// The AHBM read handlers read from paddrs rather than vaddrs which mem.read8 and the like use
// TODO: When we implement more efficient paddr accesses with a page table or similar, these handlers
// Should be made to properly use it, since this method is hacky and will segfault if given an invalid addr
ahbm.read8 = [&](u32 addr) -> u8 { return mem.getFCRAM()[addr - PhysicalAddrs::FCRAM]; };
ahbm.read16 = [&](u32 addr) -> u16 { return *(u16*)&mem.getFCRAM()[addr - PhysicalAddrs::FCRAM]; };
ahbm.read32 = [&](u32 addr) -> u32 { return *(u32*)&mem.getFCRAM()[addr - PhysicalAddrs::FCRAM]; };
ahbm.write8 = [&](u32 addr, u8 value) { mem.write8(addr, value); };
ahbm.write16 = [&](u32 addr, u16 value) { mem.write16(addr, value); };
ahbm.write32 = [&](u32 addr, u32 value) { mem.write32(addr, value); };
ahbm.write8 = [&](u32 addr, u8 value) { mem.getFCRAM()[addr - PhysicalAddrs::FCRAM] = value; };
ahbm.write16 = [&](u32 addr, u16 value) { *(u16*)&mem.getFCRAM()[addr - PhysicalAddrs::FCRAM] = value; };
ahbm.write32 = [&](u32 addr, u32 value) { *(u32*)&mem.getFCRAM()[addr - PhysicalAddrs::FCRAM] = value; };
teakra.SetAHBMCallback(ahbm);
teakra.SetAudioCallback([=](std::array<s16, 2> sample) {
//printf("%d %d\n", sample[0], sample[1]);
// NOP for now
});

View file

@ -12,9 +12,9 @@ const char* Kernel::resetTypeToString(u32 type) {
}
}
Handle Kernel::makeEvent(ResetType resetType) {
Handle Kernel::makeEvent(ResetType resetType, Event::CallbackType callback) {
Handle ret = makeObject(KernelObjectType::Event);
objects[ret].data = new Event(resetType);
objects[ret].data = new Event(resetType, callback);
return ret;
}
@ -42,8 +42,13 @@ bool Kernel::signalEvent(Handle handle) {
event->fired = false;
}
}
rescheduleThreads();
// Run the callback for events that require a special callback
if (event->callback != Event::CallbackType::None) [[unlikely]] {
runEventCallback(event->callback);
}
return true;
}
@ -230,4 +235,12 @@ void Kernel::waitSynchronizationN() {
} else {
Helpers::panic("WaitSynchronizationN with waitAll");
}
}
void Kernel::runEventCallback(Event::CallbackType callback) {
switch (callback) {
case Event::CallbackType::None: break;
case Event::CallbackType::DSPSemaphore: serviceManager.getDSP().onSemaphoreEventSignal(); break;
default: Helpers::panic("Unimplemented special callback for kernel event!"); break;
}
}

View file

@ -32,6 +32,7 @@ namespace Result {
void DSPService::reset() {
totalEventCount = 0;
semaphoreMask = 0;
semaphoreEvent = std::nullopt;
interrupt0 = std::nullopt;
@ -83,6 +84,7 @@ void DSPService::loadComponent(u32 messagePointer) {
for (u32 i = 0; i < size; i++) {
data[i] = mem.read8(buffer + i);
}
printf("Loado compartment: %08X %08X %08X %08X\n", data[0], data[1], data[2], data[3]);
log("DSP::LoadComponent (size = %08X, program mask = %X, data mask = %X\n", size, programMask, dataMask);
dsp->loadComponent(data, programMask, dataMask);
@ -200,7 +202,7 @@ void DSPService::getSemaphoreEventHandle(u32 messagePointer) {
log("DSP::GetSemaphoreEventHandle\n");
if (!semaphoreEvent.has_value()) {
semaphoreEvent = kernel.makeEvent(ResetType::OneShot);
semaphoreEvent = kernel.makeEvent(ResetType::OneShot, Event::CallbackType::DSPSemaphore);
}
mem.write32(messagePointer, IPC::responseHeader(0x16, 1, 2));
@ -224,6 +226,8 @@ void DSPService::setSemaphoreMask(u32 messagePointer) {
log("DSP::SetSemaphoreMask(mask = %04X)\n", mask);
dsp->setSemaphoreMask(mask);
semaphoreMask = mask;
mem.write32(messagePointer, IPC::responseHeader(0x17, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}