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

@ -79,7 +79,7 @@ namespace Audio {
u16 recvData(u32 regId) override { return teakra.RecvData(regId); }
bool recvDataIsReady(u32 regId) override { return teakra.RecvDataIsReady(regId); }
void setSemaphore(u16 value) override { return teakra.SetSemaphore(value); }
void setSemaphore(u16 value) override { teakra.SetSemaphore(value); }
void setSemaphoreMask(u16 value) override { teakra.MaskSemaphore(value); }
void writeProcessPipe(u32 channel, u32 size, u32 buffer) override;

View file

@ -66,15 +66,20 @@ class Kernel {
Handle makeMemoryBlock(u32 addr, u32 size, u32 myPermission, u32 otherPermission);
public:
Handle makeEvent(ResetType resetType); // Needs to be public to be accessible to the APT/HID services
Handle makeMutex(bool locked = false); // Needs to be public to be accessible to the APT/DSP services
Handle makeSemaphore(u32 initialCount, u32 maximumCount); // Needs to be public to be accessible to the service manager port
// Needs to be public to be accessible to the APT/HID services
Handle makeEvent(ResetType resetType, Event::CallbackType callback = Event::CallbackType::None);
// Needs to be public to be accessible to the APT/DSP services
Handle makeMutex(bool locked = false);
// Needs to be public to be accessible to the service manager port
Handle makeSemaphore(u32 initialCount, u32 maximumCount);
Handle makeTimer(ResetType resetType);
void pollTimers();
// Signals an event, returns true on success or false if the event does not exist
bool signalEvent(Handle e);
// Run the callback for "special" events that have callbacks
void runEventCallback(Event::CallbackType callback);
void clearEvent(Handle e) {
KernelObject* object = getObject(e, KernelObjectType::Event);
if (object != nullptr) {

View file

@ -62,11 +62,19 @@ struct Process {
};
struct Event {
// Some events (for now, only the DSP semaphore events) need to execute a callback when signalled
// This enum stores what kind of callback they should execute
enum class CallbackType : u32 {
None, DSPSemaphore,
};
u64 waitlist; // A bitfield where each bit symbolizes if the thread with thread with the corresponding index is waiting on the event
ResetType resetType = ResetType::OneShot;
CallbackType callback = CallbackType::None;
bool fired = false;
Event(ResetType resetType) : resetType(resetType), waitlist(0) {}
Event(ResetType resetType, CallbackType cb) : resetType(resetType), waitlist(0), callback(cb) {}
};
struct Port {

View file

@ -27,6 +27,7 @@ class DSPService {
DSPEvent interrupt0;
DSPEvent interrupt1;
std::array<DSPEvent, pipeCount> pipeEvents;
u16 semaphoreMask = 0;
DSPEvent& getEventRef(u32 type, u32 pipe);
static constexpr size_t maxEventCount = 6;
@ -55,6 +56,9 @@ public:
void reset();
void handleSyncRequest(u32 messagePointer);
void setDSPCore(Audio::DSPCore* pointer) { dsp = pointer; }
// Special callback that's ran when the semaphore event is signalled
void onSemaphoreEventSignal() { dsp->setSemaphore(semaphoreMask); }
enum class SoundOutputMode : u8 {
Mono = 0,