Rename some scheduler symbols and message queues

This commit is contained in:
Ryan Dwyer 2023-04-24 20:13:33 +10:00
parent 8e131f3aa4
commit 63c57f9075
18 changed files with 122 additions and 78 deletions

View File

@ -83,7 +83,7 @@ typedef struct OSScTask_s {
typedef struct SCClient_s { typedef struct SCClient_s {
struct SCClient_s *next; /* next client in the list */ struct SCClient_s *next; /* next client in the list */
OSMesgQueue *msgQ; /* where to send the frame msg */ OSMesgQueue *msgQ; /* where to send the frame msg */
s32 is8mb; s32 is30fps;
} OSScClient; } OSScClient;
typedef struct { typedef struct {
@ -106,7 +106,7 @@ typedef struct {
} OSSched; } OSSched;
void osCreateScheduler(OSSched *s, OSThread *thread, u8 mode, u32 numFields); void osCreateScheduler(OSSched *s, OSThread *thread, u8 mode, u32 numFields);
void osScAddClient(OSSched *s, OSScClient *c, OSMesgQueue *msgQ, int is8mb); void osScAddClient(OSSched *s, OSScClient *c, OSMesgQueue *msgQ, s32 is30fps);
void osScRemoveClient(OSSched *s, OSScClient *c); void osScRemoveClient(OSSched *s, OSScClient *c);
OSMesgQueue *osScGetCmdQ(OSSched *s); OSMesgQueue *osScGetCmdQ(OSSched *s);

View File

@ -1880,7 +1880,7 @@ void casingCreateForHand(s32 handnum, f32 ground, Mtxf *mtx)
} }
sp5c = ((s32)((random() >> 24) * magic) >> 10) + magic; sp5c = ((s32)((random() >> 24) * magic) >> 10) + magic;
f0 = (random() % sp5c) / PALUP(781250.0f); f0 = (random() % sp5c) / PALUP((f32) (OS_CPU_COUNTER / 60));
newyspeed = casing->speed.y - f0 * 0.2777778f; newyspeed = casing->speed.y - f0 * 0.2777778f;
@ -1937,7 +1937,7 @@ void casingCreateForHand(s32 handnum, f32 ground, Mtxf *mtx)
} }
sp4c = ((s32) ((random() >> 24) * magic) >> 10) + magic; sp4c = ((s32) ((random() >> 24) * magic) >> 10) + magic;
f0 = (random() % sp4c) / PALUP(781250.0f); f0 = (random() % sp4c) / PALUP((f32) (OS_CPU_COUNTER / 60));
newyspeed = casing->speed.y - f0 * 0.2777778f; newyspeed = casing->speed.y - f0 * 0.2777778f;

View File

@ -5,7 +5,7 @@
#include "types.h" #include "types.h"
extern OSThread g_MainThread; extern OSThread g_MainThread;
extern OSMesgQueue g_SchedMesgQueue; extern OSMesgQueue g_MainMesgQueue;
extern OSSched g_Sched; extern OSSched g_Sched;
extern OSViMode var8008dcc0[2]; extern OSViMode var8008dcc0[2];
extern OSViMode *var8008dd60[2]; extern OSViMode *var8008dd60[2];
@ -18,7 +18,7 @@ extern OSPiHandle CartRomHandle;
extern OSPiHandle LeoDiskHandle; extern OSPiHandle LeoDiskHandle;
extern OSTimer var80090ab0; extern OSTimer var80090ab0;
extern OSMesgQueue g_GbpakMesgQueue; extern OSMesgQueue g_GbpakMesgQueue;
extern OSMesg var80090ae8; extern OSMesg g_GbpakMesg;
extern u8 g_Is4Mb; extern u8 g_Is4Mb;
extern u32 g_VmNumTlbMisses; extern u32 g_VmNumTlbMisses;
extern u32 g_VmNumPageMisses; extern u32 g_VmNumPageMisses;

View File

@ -24,7 +24,7 @@ void joy00014238(void);
void joyDebugJoy(void); void joyDebugJoy(void);
s32 joyStartReadData(OSMesgQueue *mq); s32 joyStartReadData(OSMesgQueue *mq);
void joyReadData(void); void joyReadData(void);
void joysTick(void); void joysHandleRetrace(void);
void joy00014810(bool value); void joy00014810(bool value);
s32 joyGetNumSamples(void); s32 joyGetNumSamples(void);
s32 joyGetStickXOnSample(s32 samplenum, s8 contpadnum); s32 joyGetStickXOnSample(s32 samplenum, s8 contpadnum);

View File

@ -5,7 +5,7 @@
#include "types.h" #include "types.h"
void schedSetCrashEnable2(s32 enable); void schedSetCrashEnable2(s32 enable);
void schedAppendTasks(OSSched *sc, OSScTask *t); void schedSubmitTask(OSSched *sc, OSScTask *t);
void __scHandleRetrace(OSSched *sc); void __scHandleRetrace(OSSched *sc);
void __scHandleRSP(OSSched *sc); void __scHandleRSP(OSSched *sc);
void __scHandleRDP(OSSched *sc); void __scHandleRDP(OSSched *sc);

View File

@ -26,7 +26,7 @@ bool snd0000fbc4(s16 arg0);
bool seqPlay(struct seqinstance *seq, s32 tracknum); bool seqPlay(struct seqinstance *seq, s32 tracknum);
u16 seqGetVolume(struct seqinstance *seq); u16 seqGetVolume(struct seqinstance *seq);
void seqSetVolume(struct seqinstance *seq, u16 volume); void seqSetVolume(struct seqinstance *seq, u16 volume);
void snd0000fe18(void); void sndHandleRetrace(void);
void snd0000fe20(void); void snd0000fe20(void);
void snd0000fe50(void); void snd0000fe50(void);
void sndTick(void); void sndTick(void);

View File

@ -9,7 +9,7 @@ void viConfigureForCopyright(u16 *fb);
void viConfigureForLegal(void); void viConfigureForLegal(void);
void viReset(s32 stagenum); void viReset(s32 stagenum);
void viBlack(bool black); void viBlack(bool black);
void vi00009ed4(void); void viHandleRetrace(void);
void viUpdateMode(void); void viUpdateMode(void);
void viShake(f32 intensity); void viShake(f32 intensity);
void viSetMode(s32 mode); void viSetMode(s32 mode);

View File

@ -31,7 +31,7 @@ u32 var800915bc;
u32 var800915c0; u32 var800915c0;
u32 var800915c4; u32 var800915c4;
AMAudioMgr g_AudioManager; AMAudioMgr g_AudioManager;
OSScClient var800918d0; OSScClient g_AudioSchedClient;
u32 var800918dc; u32 var800918dc;
u32 g_AmgrFreqPerTick; u32 g_AmgrFreqPerTick;
u32 var800918e4; u32 var800918e4;
@ -182,9 +182,12 @@ void amgrMain(void *arg)
static u32 var8005d514 = 1; static u32 var8005d514 = 1;
#if PAL #if PAL
osScAddClient(&g_Sched, &var800918d0, &g_AudioManager.audioFrameMsgQ, true); // Receive retrace events every second retrace
osScAddClient(&g_Sched, &g_AudioSchedClient, &g_AudioManager.audioFrameMsgQ, true);
#else #else
osScAddClient(&g_Sched, &var800918d0, &g_AudioManager.audioFrameMsgQ, !IS4MB()); // 8MB - Receive retrace events every second retrace
// 4MB - Receive retrace events every retrace due to smaller command buffer
osScAddClient(&g_Sched, &g_AudioSchedClient, &g_AudioManager.audioFrameMsgQ, !IS4MB());
#endif #endif
while (!done) { while (!done) {
@ -246,7 +249,7 @@ void amgrHandleFrameMsg(AudioInfo *info, AudioInfo *previnfo)
extern u8 aspDataStart; extern u8 aspDataStart;
if (g_AmgrCurrentCmdList) { if (g_AmgrCurrentCmdList) {
schedAppendTasks(&g_Sched, g_AmgrCurrentCmdList); schedSubmitTask(&g_Sched, g_AmgrCurrentCmdList);
} }
admaBeginFrame(); admaBeginFrame();

View File

@ -22,12 +22,12 @@ OSThread g_RmonThread;
OSThread g_IdleThread; OSThread g_IdleThread;
OSThread g_MainThread; OSThread g_MainThread;
OSThread g_SchedThread; OSThread g_SchedThread;
OSMesgQueue g_SchedMesgQueue; OSMesgQueue g_MainMesgQueue;
OSMesg var8008db48[32]; OSMesg g_MainMesgBuf[32];
OSMesgQueue *g_SchedCmdQ; OSMesgQueue *g_SchedCmdQ;
u32 var8008dbcc; u32 var8008dbcc;
OSSched g_Sched; OSSched g_Sched;
OSScClient var8008dca8; OSScClient g_MainSchedClient;
#if VERSION >= VERSION_NTSC_1_0 #if VERSION >= VERSION_NTSC_1_0
u32 g_OsMemSize; u32 g_OsMemSize;
#else #else
@ -254,7 +254,7 @@ void bootCreateRmonThread(void)
void bootCreateSchedThread(void) void bootCreateSchedThread(void)
{ {
osCreateMesgQueue(&g_SchedMesgQueue, var8008db48, ARRAYCOUNT(var8008db48)); osCreateMesgQueue(&g_MainMesgQueue, g_MainMesgBuf, ARRAYCOUNT(g_MainMesgBuf));
if (osTvType == OS_TV_MPAL) { if (osTvType == OS_TV_MPAL) {
osCreateScheduler(&g_Sched, &g_SchedThread, OS_VI_MPAL_LAN1, 1); osCreateScheduler(&g_Sched, &g_SchedThread, OS_VI_MPAL_LAN1, 1);
@ -262,7 +262,7 @@ void bootCreateSchedThread(void)
osCreateScheduler(&g_Sched, &g_SchedThread, OS_VI_NTSC_LAN1, 1); osCreateScheduler(&g_Sched, &g_SchedThread, OS_VI_NTSC_LAN1, 1);
} }
osScAddClient(&g_Sched, &var8008dca8, &g_SchedMesgQueue, 0); osScAddClient(&g_Sched, &g_MainSchedClient, &g_MainMesgQueue, false);
g_SchedCmdQ = osScGetCmdQ(&g_Sched); g_SchedCmdQ = osScGetCmdQ(&g_Sched);
} }

View File

@ -34,14 +34,14 @@
struct joydata g_JoyData[2]; struct joydata g_JoyData[2];
s32 g_JoyDisableCooldown[4]; s32 g_JoyDisableCooldown[4];
OSMesgQueue g_PiMesgQueue; OSMesgQueue g_PiMesgQueue;
OSMesg var80099e90[10]; OSMesg g_PiMesgBuf[10];
OSMesg var80099eb8[2]; OSMesg g_JoyStopCyclicPollingMesgBuf[1];
OSMesgQueue g_JoyStopCyclicPollingMesgQueue; OSMesgQueue g_JoyStopCyclicPollingMesgQueue;
OSMesg var80099ed8[2]; OSMesg g_JoyStopCyclicPollingDoneMesgBuf[1];
OSMesgQueue g_JoyStopCyclicPollingDoneMesgQueue; OSMesgQueue g_JoyStopCyclicPollingDoneMesgQueue;
OSMesg var80099ef8[2]; OSMesg g_JoyStartCyclicPollingMesgBuf[1];
OSMesgQueue g_JoyStartCyclicPollingMesgQueue; OSMesgQueue g_JoyStartCyclicPollingMesgQueue;
OSMesg var80099f18[2]; OSMesg g_JoyStartCyclicPollingDoneMesgBuf[1];
OSMesgQueue g_JoyStartCyclicPollingDoneMesgQueue; OSMesgQueue g_JoyStartCyclicPollingDoneMesgQueue;
OSContStatus var80099f38[4]; OSContStatus var80099f38[4];
#if VERSION >= VERSION_NTSC_1_0 #if VERSION >= VERSION_NTSC_1_0
@ -279,11 +279,11 @@ void joyInit(void)
s32 i; s32 i;
s32 j; s32 j;
osCreateMesgQueue(&g_JoyStopCyclicPollingMesgQueue, var80099eb8, 1); osCreateMesgQueue(&g_JoyStopCyclicPollingMesgQueue, g_JoyStopCyclicPollingMesgBuf, ARRAYCOUNT(g_JoyStopCyclicPollingMesgBuf));
osCreateMesgQueue(&g_JoyStopCyclicPollingDoneMesgQueue, var80099ed8, 1); osCreateMesgQueue(&g_JoyStopCyclicPollingDoneMesgQueue, g_JoyStopCyclicPollingDoneMesgBuf, ARRAYCOUNT(g_JoyStopCyclicPollingDoneMesgBuf));
osCreateMesgQueue(&g_JoyStartCyclicPollingMesgQueue, var80099ef8, 1); osCreateMesgQueue(&g_JoyStartCyclicPollingMesgQueue, g_JoyStartCyclicPollingMesgBuf, ARRAYCOUNT(g_JoyStartCyclicPollingMesgBuf));
osCreateMesgQueue(&g_JoyStartCyclicPollingDoneMesgQueue, var80099f18, 1); osCreateMesgQueue(&g_JoyStartCyclicPollingDoneMesgQueue, g_JoyStartCyclicPollingDoneMesgBuf, ARRAYCOUNT(g_JoyStartCyclicPollingDoneMesgBuf));
osCreateMesgQueue(&g_PiMesgQueue, var80099e90, ARRAYCOUNT(var80099e90)); osCreateMesgQueue(&g_PiMesgQueue, g_PiMesgBuf, ARRAYCOUNT(g_PiMesgBuf));
osSetEventMesg(OS_EVENT_SI, &g_PiMesgQueue, NULL); osSetEventMesg(OS_EVENT_SI, &g_PiMesgQueue, NULL);
@ -601,7 +601,7 @@ void joyReadData(void)
g_JoyData[0].nextsecondlast = (g_JoyData[0].nextlast + 19) % 20; g_JoyData[0].nextsecondlast = (g_JoyData[0].nextlast + 19) % 20;
} }
void joysTick(void) void joysHandleRetrace(void)
{ {
OSMesg msg; OSMesg msg;
s8 i; s8 i;
@ -984,7 +984,7 @@ void joyDestroy(void)
{ {
s32 i; s32 i;
osCreateMesgQueue(&g_PiMesgQueue, var80099e90, ARRAYCOUNT(var80099e90)); osCreateMesgQueue(&g_PiMesgQueue, g_PiMesgBuf, ARRAYCOUNT(g_PiMesgBuf));
osSetEventMesg(OS_EVENT_SI, &g_PiMesgQueue, 0); osSetEventMesg(OS_EVENT_SI, &g_PiMesgQueue, 0);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {

View File

@ -345,7 +345,7 @@ void mainInit(void)
// Wait a bit, reset the controllers and wait a bit more // Wait a bit, reset the controllers and wait a bit more
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
osSetTimer(&timer, 781250 * 6, 0, &queue, &msg); osSetTimer(&timer, OS_CPU_COUNTER / 60 * 6, 0, &queue, &msg);
osRecvMesg(&queue, &msg, OS_MESG_BLOCK); osRecvMesg(&queue, &msg, OS_MESG_BLOCK);
if (i == 1) { if (i == 1) {
@ -485,18 +485,18 @@ void mainInit(void)
g_RdpOutBufferStart = texture; g_RdpOutBufferStart = texture;
g_RdpOutBufferEnd = texture + 0x400; // 0x800 bytes, because texture is u16 g_RdpOutBufferEnd = texture + 0x400; // 0x800 bytes, because texture is u16
while (osRecvMesg(&g_SchedMesgQueue, &receivedmsg, OS_MESG_NOBLOCK) == 0) { while (osRecvMesg(&g_MainMesgQueue, &receivedmsg, OS_MESG_NOBLOCK) == 0) {
// empty // empty
} }
j = 0; j = 0;
while (j < 6) { while (j < 6) {
osRecvMesg(&g_SchedMesgQueue, &receivedmsg, OS_MESG_BLOCK); osRecvMesg(&g_MainMesgQueue, &receivedmsg, OS_MESG_BLOCK);
i = (s32) &scdonemsg; i = (s32) &scdonemsg;
if (*(s16 *) receivedmsg == 1) { if (*(s16 *) receivedmsg == OS_SC_RETRACE_MSG) {
viUpdateMode(); viUpdateMode();
rdpCreateTask(var8005dcc8, var8005dcf0, 0, (void *) i); rdpCreateTask(var8005dcc8, var8005dcf0, 0, (void *) i);
j++; j++;
@ -612,18 +612,18 @@ void mainInit(void)
g_RdpOutBufferStart = texture; g_RdpOutBufferStart = texture;
g_RdpOutBufferEnd = texture + 0x400; // 0x800 bytes, because texture is u16 g_RdpOutBufferEnd = texture + 0x400; // 0x800 bytes, because texture is u16
while (osRecvMesg(&g_SchedMesgQueue, &receivedmsg, OS_MESG_NOBLOCK) == 0) { while (osRecvMesg(&g_MainMesgQueue, &receivedmsg, OS_MESG_NOBLOCK) == 0) {
if (i); if (i);
} }
i = 0; i = 0;
while (i < 6) { while (i < 6) {
osRecvMesg(&g_SchedMesgQueue, &receivedmsg, OS_MESG_BLOCK); osRecvMesg(&g_MainMesgQueue, &receivedmsg, OS_MESG_BLOCK);
j = (s32) &scdonemsg; j = (s32) &scdonemsg;
if (*(s16 *) receivedmsg == 1) { if (*(s16 *) receivedmsg == OS_SC_RETRACE_MSG) {
viUpdateMode(); viUpdateMode();
rdpCreateTask(var8005dcc8, var8005dcf0, 0, (void *) j); rdpCreateTask(var8005dcc8, var8005dcf0, 0, (void *) j);
i++; i++;
@ -919,9 +919,9 @@ glabel mainInit
/* dd8c: 0c00273c */ jal viConfigureForCopyright /* dd8c: 0c00273c */ jal viConfigureForCopyright
/* dd90: 02202025 */ or $a0,$s1,$zero /* dd90: 02202025 */ or $a0,$s1,$zero
/* dd94: 3c018006 */ lui $at,%hi(g_RdpOutBufferStart) /* dd94: 3c018006 */ lui $at,%hi(g_RdpOutBufferStart)
/* dd98: 3c118009 */ lui $s1,%hi(g_SchedMesgQueue) /* dd98: 3c118009 */ lui $s1,%hi(g_MainMesgQueue)
/* dd9c: ac321554 */ sw $s2,%lo(g_RdpOutBufferStart)($at) /* dd9c: ac321554 */ sw $s2,%lo(g_RdpOutBufferStart)($at)
/* dda0: 26310160 */ addiu $s1,$s1,%lo(g_SchedMesgQueue) /* dda0: 26310160 */ addiu $s1,$s1,%lo(g_MainMesgQueue)
/* dda4: 3c018006 */ lui $at,%hi(g_RdpOutBufferEnd) /* dda4: 3c018006 */ lui $at,%hi(g_RdpOutBufferEnd)
/* dda8: 264c0800 */ addiu $t4,$s2,0x800 /* dda8: 264c0800 */ addiu $t4,$s2,0x800
/* ddac: ac2c1550 */ sw $t4,%lo(g_RdpOutBufferEnd)($at) /* ddac: ac2c1550 */ sw $t4,%lo(g_RdpOutBufferEnd)($at)
@ -1346,14 +1346,14 @@ void mainLoop(void)
frametimeCalculate(); frametimeCalculate();
profileReset(); profileReset();
while (osRecvMesg(&g_SchedMesgQueue, &msg, OS_MESG_NOBLOCK) != -1) { while (osRecvMesg(&g_MainMesgQueue, &msg, OS_MESG_NOBLOCK) != -1) {
// empty // empty
} }
while (g_MainChangeToStageNum < 0 || g_MainNumGfxTasks != 0) { while (g_MainChangeToStageNum < 0 || g_MainNumGfxTasks != 0) {
s32 cycles; s32 cycles;
osRecvMesg(&g_SchedMesgQueue, &msg, OS_MESG_BLOCK); osRecvMesg(&g_MainMesgQueue, &msg, OS_MESG_BLOCK);
#if VERSION < VERSION_NTSC_1_0 #if VERSION < VERSION_NTSC_1_0
bootCheckStackOverflow(); bootCheckStackOverflow();

View File

@ -99,12 +99,12 @@ void rdpCreateTask(Gfx *gdlstart, Gfx *gdlend, u32 arg2, void *msg)
sctask->next = NULL; sctask->next = NULL;
sctask->flags = OS_SC_NEEDS_RSP | OS_SC_NEEDS_RDP | OS_SC_LAST_TASK | OS_SC_SWAPBUFFER; sctask->flags = OS_SC_NEEDS_RSP | OS_SC_NEEDS_RDP | OS_SC_LAST_TASK | OS_SC_SWAPBUFFER;
sctask->msgQ = &g_SchedMesgQueue; sctask->msgQ = &g_MainMesgQueue;
sctask->msg = msg; sctask->msg = msg;
sctask->framebuffer = g_RdpCurTask->framebuffer; sctask->framebuffer = g_RdpCurTask->framebuffer;
osWritebackDCacheAll(); osWritebackDCacheAll();
schedAppendTasks(&g_Sched, sctask); schedSubmitTask(&g_Sched, sctask);
// Swap g_RdpCurTask // Swap g_RdpCurTask
g_RdpCurTask = (struct rdptask *)((uintptr_t) g_RdpCurTask ^ (uintptr_t) &g_RdpTaskA ^ (uintptr_t) &g_RdpTaskB); g_RdpCurTask = (struct rdptask *)((uintptr_t) g_RdpCurTask ^ (uintptr_t) &g_RdpTaskA ^ (uintptr_t) &g_RdpTaskB);

View File

@ -177,14 +177,14 @@ void osCreateScheduler(OSSched *sc, OSThread *thread, u8 mode, u32 numFields)
osStartThread(sc->thread); osStartThread(sc->thread);
} }
void osScAddClient(OSSched *sc, OSScClient *c, OSMesgQueue *msgQ, int is8mb) void osScAddClient(OSSched *sc, OSScClient *c, OSMesgQueue *msgQ, bool is30fps)
{ {
OSIntMask mask; OSIntMask mask;
mask = osSetIntMask(1); mask = osSetIntMask(1);
c->msgQ = msgQ; c->msgQ = msgQ;
c->is8mb = is8mb; c->is30fps = is30fps;
c->next = sc->clientList; c->next = sc->clientList;
sc->clientList = c; sc->clientList = c;
@ -243,18 +243,29 @@ void __scMain(void *arg)
switch ((int) msg) { switch ((int) msg) {
case VIDEO_MSG: case VIDEO_MSG:
/**
* The freeze bit is set when a VI swap is pending, and unset here
* when the swap is completed. It prevents the scheduler from
* executing another graphics task during a VI swap.
*/
if (osViGetCurrentFramebuffer() == osViGetNextFramebuffer()) { if (osViGetCurrentFramebuffer() == osViGetNextFramebuffer()) {
osDpSetStatus(DPC_STATUS_FLUSH); osDpSetStatus(DPC_CLR_FREEZE);
} }
__scHandleRetrace(sc); __scHandleRetrace(sc);
__scHandleTasks(sc); __scHandleTasks(sc);
break; break;
case RSP_DONE_MSG: case RSP_DONE_MSG:
__scHandleRSP(sc); __scHandleRSP(sc);
break; break;
case RDP_DONE_MSG: case RDP_DONE_MSG:
osDpSetStatus(DPC_STATUS_START_GCLK); /**
* The RDP has completed a graphics task. Set the freeze bit so the
* scheduler doesn't executing another task until the swap is done.
*/
osDpSetStatus(DPC_SET_FREEZE);
__scHandleRDP(sc); __scHandleRDP(sc);
__scHandleTasks(sc); __scHandleTasks(sc);
break; break;
@ -262,7 +273,16 @@ void __scMain(void *arg)
} }
} }
void schedAppendTasks(OSSched *sc, OSScTask *t) /**
* Nintendo's sheduler accepts tasks on a "command" message queue.
* This isn't used here.
*
* In PD, the main and audio threads submit tasks by calling this function
* instead. It temporarily increases the calling thread's priority above the
* scheduler, adds the task to the linked list directly and attempts to execute
* it. This is faster than the queue method because it avoids switching threads.
*/
void schedSubmitTask(OSSched *sc, OSScTask *t)
{ {
s32 state; s32 state;
OSScTask *sp = 0; OSScTask *sp = 0;
@ -274,6 +294,13 @@ void schedAppendTasks(OSSched *sc, OSScTask *t)
__scAppendList(sc, t); __scAppendList(sc, t);
if (sc->doAudio && sc->curRSPTask) { if (sc->doAudio && sc->curRSPTask) {
/**
* Preempt the running gfx task. Note: if the RSP
* component of the graphics task has finished, but the
* RDP component is still running, we can start an audio
* task which will freeze the RDP (and save the RDP cmd
* FIFO) while the audio RSP code is running.
*/
__scYield(sc); __scYield(sc);
} else { } else {
state = ((sc->curRSPTask == 0) << 1) | (sc->curRDPTask == 0); state = ((sc->curRSPTask == 0) << 1) | (sc->curRDPTask == 0);
@ -317,11 +344,11 @@ void __scHandleRetrace(OSSched *sc)
#endif #endif
if (!g_Resetting) { if (!g_Resetting) {
vi00009ed4(); viHandleRetrace();
} }
joysTick(); joysHandleRetrace();
snd0000fe18(); sndHandleRetrace();
schedRenderCrashPeriodically(sc->frameCount); schedRenderCrashPeriodically(sc->frameCount);
} }
@ -341,20 +368,16 @@ void __scHandleTasks(OSSched *sc)
profileTick(); profileTick();
/** /**
* Read the task command queue and schedule tasks * This is default scheduler code. In PD, clients pass tasks to the
* scheduler using schedSubmitTask. Nothing writes to the cmdQ in PD
* so the condition in this loop never passes.
*/ */
while (osRecvMesg(&sc->cmdQ, (OSMesg*)&rspTask, OS_MESG_NOBLOCK) != -1) { while (osRecvMesg(&sc->cmdQ, (OSMesg*)&rspTask, OS_MESG_NOBLOCK) != -1) {
__scAppendList(sc, rspTask); __scAppendList(sc, rspTask);
} }
if (sc->doAudio && sc->curRSPTask) { if (sc->doAudio && sc->curRSPTask) {
/** // This is unreachable because no tasks are submitted above
* Preempt the running gfx task. Note: if the RSP
* component of the graphics task has finished, but the
* RDP component is still running, we can start an audio
* task which will freeze the RDP (and save the RDP cmd
* FIFO) while the audio RSP code is running.
*/
__scYield(sc); __scYield(sc);
} else { } else {
state = ((sc->curRSPTask == 0) << 1) | (sc->curRDPTask == 0); state = ((sc->curRSPTask == 0) << 1) | (sc->curRDPTask == 0);
@ -370,7 +393,7 @@ void __scHandleTasks(OSSched *sc)
* build the list in overrun case) * build the list in overrun case)
*/ */
for (client = sc->clientList; client != 0; client = client->next) { for (client = sc->clientList; client != 0; client = client->next) {
if ((*((s32*)client + 2) == 0) || ((sc->frameCount & 1) == 0)) { if (!client->is30fps || (sc->frameCount & 1) == 0) {
osSendMesg(client->msgQ, (OSMesg) &sc->retraceMsg, OS_MESG_NOBLOCK); osSendMesg(client->msgQ, (OSMesg) &sc->retraceMsg, OS_MESG_NOBLOCK);
} }
} }
@ -575,6 +598,9 @@ void __scHandleRDP(OSSched *sc)
/** /**
* __scTaskReady checks to see if the graphics task is able to run * __scTaskReady checks to see if the graphics task is able to run
* based on the current state of the RCP. * based on the current state of the RCP.
*
* PD adds the freeze bit check to avoid executing graphics tasks on the RDP
* when there is already a VI swap pending.
*/ */
OSScTask *__scTaskReady(OSScTask *t) OSScTask *__scTaskReady(OSScTask *t)
{ {
@ -602,7 +628,7 @@ OSScTask *__scTaskReady(OSScTask *t)
s32 __scTaskComplete(OSSched *sc, OSScTask *t) s32 __scTaskComplete(OSSched *sc, OSScTask *t)
{ {
if ((t->state & OS_SC_RCP_MASK) == 0) { if ((t->state & OS_SC_RCP_MASK) == 0) {
if (t->list.t.type == 1 if (t->list.t.type == M_GFXTASK
&& (t->flags & OS_SC_SWAPBUFFER) && (t->flags & OS_SC_SWAPBUFFER)
&& (t->flags & OS_SC_LAST_TASK)) { && (t->flags & OS_SC_LAST_TASK)) {
if (g_SchedIsFirstTask) { if (g_SchedIsFirstTask) {
@ -619,7 +645,7 @@ s32 __scTaskComplete(OSSched *sc, OSScTask *t)
|| var8008dd60[1 - var8005ce74]->fldRegs[1].yScale != var8008dcc0[1 - var8005ce74].fldRegs[1].yScale || var8008dd60[1 - var8005ce74]->fldRegs[1].yScale != var8008dcc0[1 - var8005ce74].fldRegs[1].yScale
|| var8008dd60[1 - var8005ce74]->fldRegs[0].origin != var8008dcc0[1 - var8005ce74].fldRegs[0].origin || var8008dd60[1 - var8005ce74]->fldRegs[0].origin != var8008dcc0[1 - var8005ce74].fldRegs[0].origin
|| var8008dd60[1 - var8005ce74]->fldRegs[1].origin != var8008dcc0[1 - var8005ce74].fldRegs[1].origin) { || var8008dd60[1 - var8005ce74]->fldRegs[1].origin != var8008dcc0[1 - var8005ce74].fldRegs[1].origin) {
s32 mask = osSetIntMask(0x80401); s32 mask = osSetIntMask(OS_IM_VI);
*var8008dd60[1 - var8005ce74] = var8008dcc0[1 - var8005ce74]; *var8008dd60[1 - var8005ce74] = var8008dcc0[1 - var8005ce74];
@ -681,6 +707,13 @@ void __scAppendList(OSSched *sc, OSScTask *t)
t->state = t->flags & OS_SC_RCP_MASK; t->state = t->flags & OS_SC_RCP_MASK;
} }
/**
* Execute a task on the RCP.
*
* Audio tasks use the RSP only, while graphics tasks use both the RSP and RDP.
* Graphics tasks commonly finish the RSP work before the RDP work, in which
* case the RSP can be given an audio task while the graphics task is completing.
*/
void __scExec(OSSched *sc, OSScTask *sp, OSScTask *dp) void __scExec(OSSched *sc, OSScTask *sp, OSScTask *dp)
{ {
if (sp) { if (sp) {
@ -688,8 +721,9 @@ void __scExec(OSSched *sc, OSScTask *sp, OSScTask *dp)
osWritebackDCacheAll(); osWritebackDCacheAll();
} }
// Clear RDP timing counters for graphics tasks, unless they're being resumed
if (sp->list.t.type != M_AUDTASK && (sp->state & OS_SC_YIELD) == 0) { if (sp->list.t.type != M_AUDTASK && (sp->state & OS_SC_YIELD) == 0) {
osDpSetStatus(DPC_STATUS_CMD_BUSY | DPC_STATUS_CBUF_READY | DPC_STATUS_DMA_BUSY | DPC_STATUS_END_VALID); osDpSetStatus(DPC_CLR_TMEM_CTR | DPC_CLR_PIPE_CTR | DPC_CLR_CMD_CTR | DPC_CLR_CLOCK_CTR);
} }
if (sp->list.t.type == M_AUDTASK) { if (sp->list.t.type == M_AUDTASK) {
@ -723,6 +757,13 @@ bool schedIsCurTaskAudio(OSSched *sc)
} }
#endif #endif
/**
* Tell the RSP to pause the currently executing graphics task.
* The RSP will pause it shortly and __scHandleRSP will be called.
*
* Graphics tasks are yielded so an audio task can take priority.
* The graphics task is resumed afterwards.
*/
void __scYield(OSSched *sc) void __scYield(OSSched *sc)
{ {
if (sc->curRSPTask->list.t.type == M_GFXTASK) { if (sc->curRSPTask->list.t.type == M_GFXTASK) {

View File

@ -1679,7 +1679,7 @@ void seqSetVolume(struct seqinstance *seq, u16 volume)
} }
} }
void snd0000fe18(void) void sndHandleRetrace(void)
{ {
// empty // empty
} }

View File

@ -34,9 +34,9 @@ s32 osContInit(OSMesgQueue *mq, u8 *bitpattern, OSContStatus *data)
__osContInitialized = TRUE; __osContInitialized = TRUE;
t = osGetTime(); t = osGetTime();
if (t < 23437500) { if (t < OS_CPU_COUNTER / 2) {
osCreateMesgQueue(&timerMesgQueue, &dummy, 1); osCreateMesgQueue(&timerMesgQueue, &dummy, 1);
osSetTimer(&mytimer, 23437500 - t, 0, &timerMesgQueue, &dummy); osSetTimer(&mytimer, OS_CPU_COUNTER / 2 - t, 0, &timerMesgQueue, &dummy);
osRecvMesg(&timerMesgQueue, &dummy, OS_MESG_BLOCK); osRecvMesg(&timerMesgQueue, &dummy, OS_MESG_BLOCK);
} }

View File

@ -4,7 +4,7 @@
OSTimer var80090ab0; OSTimer var80090ab0;
OSMesgQueue g_GbpakMesgQueue; OSMesgQueue g_GbpakMesgQueue;
OSMesg var80090ae8; OSMesg g_GbpakMesg;
s32 osGbpakInit(OSMesgQueue *queue, OSPfs *pfs, int channel) s32 osGbpakInit(OSMesgQueue *queue, OSPfs *pfs, int channel)
{ {
@ -76,17 +76,17 @@ s32 osGbpakInit(OSMesgQueue *queue, OSPfs *pfs, int channel)
return ret; return ret;
} }
osCreateMesgQueue(&g_GbpakMesgQueue, &var80090ae8, 1); osCreateMesgQueue(&g_GbpakMesgQueue, &g_GbpakMesg, 1);
osSetTimer(&var80090ab0, 937500, 0, &g_GbpakMesgQueue, &var80090ae8); osSetTimer(&var80090ab0, OS_CPU_COUNTER / 50, 0, &g_GbpakMesgQueue, &g_GbpakMesg);
osRecvMesg(&g_GbpakMesgQueue, 0, OS_MESG_BLOCK); osRecvMesg(&g_GbpakMesgQueue, 0, OS_MESG_BLOCK);
pfs->queue = queue; pfs->queue = queue;
pfs->status = 0x10; pfs->status = PFS_GBPAK_INITIALIZED;
pfs->channel = channel; pfs->channel = channel;
pfs->activebank = 0x84; pfs->activebank = 132;
pfs->banks = 0xff; pfs->banks = 255;
pfs->version = 0xff; pfs->version = 255;
pfs->dir_size = 0xff; pfs->dir_size = 255;
return 0; return 0;
} }

View File

@ -4,7 +4,7 @@
extern OSTimer var80090ab0; extern OSTimer var80090ab0;
extern OSMesgQueue g_GbpakMesgQueue; extern OSMesgQueue g_GbpakMesgQueue;
extern OSMesg var80090ae8; extern OSMesg g_GbpakMesg;
s32 osGbpakPower(OSPfs *pfs, s32 flag) s32 osGbpakPower(OSPfs *pfs, s32 flag)
{ {
@ -31,7 +31,7 @@ s32 osGbpakPower(OSPfs *pfs, s32 flag)
} }
if (flag != OS_GBPAK_POWER_OFF) { if (flag != OS_GBPAK_POWER_OFF) {
osSetTimer(&var80090ab0, 937500, 0, &g_GbpakMesgQueue, &var80090ae8); osSetTimer(&var80090ab0, OS_CPU_COUNTER / 50, 0, &g_GbpakMesgQueue, &g_GbpakMesg);
osRecvMesg(&g_GbpakMesgQueue, NULL, OS_MESG_BLOCK); osRecvMesg(&g_GbpakMesgQueue, NULL, OS_MESG_BLOCK);
} }

View File

@ -258,7 +258,7 @@ void viBlack(bool black)
g_ViUnblackTimer = black; g_ViUnblackTimer = black;
} }
void vi00009ed4(void) void viHandleRetrace(void)
{ {
s32 prevmask; s32 prevmask;
s32 offset; s32 offset;