summaryrefslogtreecommitdiff
path: root/src/boot_O2_g3
diff options
context:
space:
mode:
authorrozlette <uberpanzermensch@gmail.com>2020-01-22 21:47:05 -0600
committerrozlette <uberpanzermensch@gmail.com>2020-01-22 21:47:05 -0600
commitbb4123c073c13e105fd0c602165343cad4f3f1a2 (patch)
tree4458eb7ea4d9131cd075ad6d560fc7fa89ff3226 /src/boot_O2_g3
parent36f1c42bf9dc2886a9184e978d701b70bc08f3ff (diff)
Decompile irqmgr
Diffstat (limited to 'src/boot_O2_g3')
-rw-r--r--src/boot_O2_g3/idle.c2
-rw-r--r--src/boot_O2_g3/irqmgr.c173
-rw-r--r--src/boot_O2_g3/z_std_dma.c2
3 files changed, 175 insertions, 2 deletions
diff --git a/src/boot_O2_g3/idle.c b/src/boot_O2_g3/idle.c
index d359f5144..8fe2cfe34 100644
--- a/src/boot_O2_g3/idle.c
+++ b/src/boot_O2_g3/idle.c
@@ -63,7 +63,7 @@ GLOBAL_ASM("./asm/nonmatching/idle/Idle_InitCodeAndMemory.asm")
void Idle_MainThreadEntry(void* arg) {
StackCheck_Init(&irqmgrStackEntry, (u32)&irqmgrStack, (u32)&irqmgrStack[1280], 0, 256, "irqmgr");
- Irqmgr_Start(&irqmgrContext, &irqmgrStackEntry, 18, 1);
+ IrqMgr_Start(&irqmgrContext, &irqmgrStackEntry, 18, 1);
Dmamgr_Start();
Idle_InitCodeAndMemory();
main(arg);
diff --git a/src/boot_O2_g3/irqmgr.c b/src/boot_O2_g3/irqmgr.c
new file mode 100644
index 000000000..18e1b262f
--- /dev/null
+++ b/src/boot_O2_g3/irqmgr.c
@@ -0,0 +1,173 @@
+#include <ultra64.h>
+#include <global.h>
+
+// TODO move out
+#define OS_CLOCK_RATE 62500000LL
+#define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4)
+#define OS_USEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625LL))/(1000000LL/15625LL))
+
+// TODO .data section
+//vs32 gPrenmiStage;
+//volatile OSTime sLastPrenmiTime;
+//vu64 gLastFrameDuration;
+//s32 sFrameCount;
+
+void IrqMgr_AddCallback(IrqMgr* irqmgr, OSMesgQueueListNode* param_2, OSMesgQueue* param_3) {
+ u32 saveMask;
+
+ saveMask = osSetIntMask(1);
+
+ param_2->queue = param_3;
+ param_2->next = irqmgr->callbacks;
+ irqmgr->callbacks = param_2;
+
+ osSetIntMask(saveMask);
+
+ if (irqmgr->prenmiStage > 0) {
+ osSendMesg(param_2->queue, &irqmgr->prenmi1Msg, 0);
+ }
+ if (irqmgr->prenmiStage > 1) {
+ osSendMesg(param_2->queue, &irqmgr->prenmi2Msg, 0);
+ }
+}
+
+void IrqMgr_RemoveCallback(IrqMgr* irqmgr, OSMesgQueueListNode* remove) {
+ OSMesgQueueListNode* iter;
+ OSMesgQueueListNode* last;
+ u32 saveMask;
+
+ iter = irqmgr->callbacks;
+ last = NULL;
+
+ saveMask = osSetIntMask(1);
+
+ while (iter != NULL) {
+ if (iter == remove) {
+ if (last != NULL) {
+ last->next = remove->next;
+ } else {
+ irqmgr->callbacks = remove->next;
+ }
+ break;
+ }
+ last = iter;
+ iter = iter->next;
+ }
+
+ osSetIntMask(saveMask);
+}
+
+void IrqMgr_NotifyAllCallbacks(IrqMgr* irqmgr, OSMesg msg) {
+ OSMesgQueueListNode* iter = irqmgr->callbacks;
+
+ while (iter != NULL) {
+ osSendMesg(iter->queue, msg, 0);
+ iter = iter->next;
+ }
+}
+
+void IrqMgr_NotifyAllCallbacksWithCapacity(IrqMgr* irqmgr, OSMesg msg) {
+ OSMesgQueueListNode* iter = irqmgr->callbacks;
+
+ while (iter != NULL) {
+ if (iter->queue->validCount < iter->queue->msgCount) {
+ osSendMesg(iter->queue, msg, 0);
+ }
+ iter = iter->next;
+ }
+}
+
+void IrqMgr_HandlePrenmi1(IrqMgr* irqmgr) {
+ gPrenmiStage = 1;
+ irqmgr->prenmiStage = 1;
+
+ sLastPrenmiTime = irqmgr->lastPrenmiTime = osGetTime();
+
+ // Wait .45 seconds then generate a stage 2 prenmi interrupt
+ osSetTimer(&irqmgr->prenmiTimer, OS_USEC_TO_CYCLES(450000), 0, &irqmgr->irqQueue, (OSMesg)0x29F);
+
+ IrqMgr_NotifyAllCallbacksWithCapacity(irqmgr, &irqmgr->prenmi1Msg);
+}
+
+void IrqMgr_CheckThreadStatusImpl(void) {
+ StackCheck_Check(NULL);
+}
+
+void IrqMgr_HandlePrenmi2(IrqMgr* irqmgr) {
+ gPrenmiStage = 2;
+ irqmgr->prenmiStage = 2;
+
+ // Wait .03 seconds then generate a stage 3 prenmi interrupt
+ osSetTimer(&irqmgr->prenmiTimer, OS_USEC_TO_CYCLES(30000), 0, &irqmgr->irqQueue, (OSMesg)0x2A0);
+
+ IrqMgr_NotifyAllCallbacks(irqmgr, &irqmgr->prenmi2Msg);
+}
+
+void IrqMgr_HandlePrenmi3(IrqMgr* irqmgr) {
+ // Wait .52 seconds. After this we will have waited an entire second
+ osSetTimer(&irqmgr->prenmiTimer, OS_USEC_TO_CYCLES(520000), 0, &irqmgr->irqQueue, (OSMesg)0x2A1);
+
+ func_8008D710();
+}
+
+void IrqMgr_CheckThreadStatus(IrqMgr* irqmgr) {
+ IrqMgr_CheckThreadStatusImpl();
+}
+void IrqMgr_HandleFrame(IrqMgr* irqmgr) {
+ if (gLastFrameDuration == 0) {
+ if (irqmgr->lastFrameTime == 0) {
+ irqmgr->lastFrameTime = osGetTime();
+ } else {
+ gLastFrameDuration = osGetTime() - irqmgr->lastFrameTime;
+ }
+ }
+
+ sFrameCount += 1;
+ IrqMgr_NotifyAllCallbacks(irqmgr,irqmgr);
+}
+
+void IrqMgr_ThreadEntry(IrqMgr* irqmgr) {
+ u32 interrupt;
+ u32 stop;
+
+ interrupt = 0;
+ stop = 0;
+ while (stop == 0) {
+ if (stop);
+
+ osRecvMesg(&irqmgr->irqQueue, (OSMesg*)&interrupt, 1);
+ switch (interrupt) {
+ case 0x29A:
+ IrqMgr_HandleFrame(irqmgr);
+ break;
+ case 0x29D:
+ IrqMgr_HandlePrenmi1(irqmgr);
+ break;
+ case 0x29F:
+ IrqMgr_HandlePrenmi2(irqmgr);
+ break;
+ case 0x2A0:
+ IrqMgr_HandlePrenmi3(irqmgr);
+ break;
+ case 0x2A1:
+ IrqMgr_CheckThreadStatus(irqmgr);
+ break;
+ }
+ }
+}
+
+void IrqMgr_Start(IrqMgr* irqmgr, void* stack, OSPri pri, u8 retraceCount) {
+ irqmgr->callbacks = NULL;
+ irqmgr->verticalRetraceMesg = 1;
+ irqmgr->prenmi1Msg = 4;
+ irqmgr->prenmi2Msg = 3;
+ irqmgr->prenmiStage = 0;
+ irqmgr->lastPrenmiTime = 0;
+
+ osCreateMesgQueue(&irqmgr->irqQueue,(OSMesg *)irqmgr->irqBuffer,8);
+ osSetEventMesg(0xE, &irqmgr->irqQueue, (OSMesg)0x29D);
+ osViSetEvent(&irqmgr->irqQueue, (OSMesg)0x29A, retraceCount);
+
+ osCreateThread(&irqmgr->thread, 0x13, (osCreateThread_func)IrqMgr_ThreadEntry, irqmgr, stack, pri);
+ osStartThread(&irqmgr->thread);
+}
diff --git a/src/boot_O2_g3/z_std_dma.c b/src/boot_O2_g3/z_std_dma.c
index cd0146077..8b4ed863e 100644
--- a/src/boot_O2_g3/z_std_dma.c
+++ b/src/boot_O2_g3/z_std_dma.c
@@ -158,7 +158,7 @@ void Dmamgr_ThreadEntry(void* a0) {
}
s32 Dmamgr_SendRequest(DmaRequest* request, u32 vramStart, u32 vromStart, u32 size, UNK_TYPE4 unused, OSMesgQueue* callback, void* callbackMesg) {
- if (prenmiStage >= 2) {
+ if (gPrenmiStage >= 2) {
return -2;
}