diff options
| author | rozlette <uberpanzermensch@gmail.com> | 2020-01-22 21:47:05 -0600 |
|---|---|---|
| committer | rozlette <uberpanzermensch@gmail.com> | 2020-01-22 21:47:05 -0600 |
| commit | bb4123c073c13e105fd0c602165343cad4f3f1a2 (patch) | |
| tree | 4458eb7ea4d9131cd075ad6d560fc7fa89ff3226 /src/boot_O2_g3 | |
| parent | 36f1c42bf9dc2886a9184e978d701b70bc08f3ff (diff) | |
Decompile irqmgr
Diffstat (limited to 'src/boot_O2_g3')
| -rw-r--r-- | src/boot_O2_g3/idle.c | 2 | ||||
| -rw-r--r-- | src/boot_O2_g3/irqmgr.c | 173 | ||||
| -rw-r--r-- | src/boot_O2_g3/z_std_dma.c | 2 |
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; } |
