tp/libs/dolphin/gx/GXMisc.c

294 lines
8.6 KiB
C

#include "dolphin/gx/GXMisc.h"
#include "dolphin/gx.h"
#include "dolphin/gx/GXInit.h"
#include "dolphin/os/OSContext.h"
#include "dolphin/os/OSInterrupt.h"
#include "dolphin/os/OSReset.h"
#include "dolphin/os/OSTime.h"
static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context);
static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* pContext);
/* 8035BE38-8035BECC 356778 0094+00 0/0 9/9 0/0 .text GXSetMisc */
void GXSetMisc(GXMiscToken token, u32 val) {
switch (token) {
case GX_MT_NULL:
break;
case GX_MT_XF_FLUSH:
__GXData->vNum = val;
__GXData->vNumNot = !__GXData->vNum;
__GXData->bpSentNot = GX_TRUE;
if (__GXData->vNum) {
__GXData->dirtyState |= GX_DIRTY_VCD;
}
break;
case GX_MT_DL_SAVE_CONTEXT:
__GXData->dlSaveContext = (val != 0);
break;
case GX_MT_ABORT_WAIT_COPYOUT:
__GXData->abtWaitPECopy = (val != 0);
break;
}
}
/* 8035BECC-8035BF28 35680C 005C+00 1/1 10/10 0/0 .text GXFlush */
void GXFlush(void) {
if (__GXData->dirtyState) {
__GXSetDirtyState();
}
GXWGFifo.u32 = 0;
GXWGFifo.u32 = 0;
GXWGFifo.u32 = 0;
GXWGFifo.u32 = 0;
GXWGFifo.u32 = 0;
GXWGFifo.u32 = 0;
GXWGFifo.u32 = 0;
GXWGFifo.u32 = 0;
PPCSync();
}
static void __GXAbortWait(u32 clocks) {
OSTime time0, time1;
time0 = OSGetTime();
do {
time1 = OSGetTime();
} while (time1 - time0 <= clocks / 4);
}
static void __GXAbortWaitPECopyDone(void) {
u32 peCnt0, peCnt1;
peCnt0 = GXReadMEMReg(0x28, 0x27);
do {
peCnt1 = peCnt0;
__GXAbortWait(32);
peCnt0 = GXReadMEMReg(0x28, 0x27);
} while (peCnt0 != peCnt1);
}
/* 8035BF28-8035C094 356868 016C+00 0/0 1/1 0/0 .text __GXAbort */
void __GXAbort(void) {
if (__GXData->abtWaitPECopy && GXGetGPFifo()) {
__GXAbortWaitPECopyDone();
}
__PIRegs[0x18 / 4] = 1;
__GXAbortWait(200);
__PIRegs[0x18 / 4] = 0;
__GXAbortWait(20);
}
/* 8035C094-8035C25C 3569D4 01C8+00 0/0 2/2 0/0 .text GXAbortFrame */
void GXAbortFrame(void) {
__GXAbort();
if (GXGetGPFifo()) {
__GXCleanGPFifo();
__GXInitRevisionBits();
__GXData->dirtyState = 0;
GXFlush();
}
}
/* ############################################################################################## */
/* 80451968-8045196C 000E68 0004+00 2/2 0/0 0/0 .sbss TokenCB */
static GXDrawSyncCallback TokenCB;
/* 8045196C-80451970 000E6C 0004+00 2/2 0/0 0/0 .sbss DrawDoneCB */
static GXDrawDoneCallback DrawDoneCB;
/* 80451970-80451974 000E70 0004+00 3/3 0/0 0/0 .sbss None */
static GXBool DrawDone;
/* 8035C25C-8035C2F4 356B9C 0098+00 0/0 2/2 0/0 .text GXSetDrawDone */
void GXSetDrawDone(void) {
u8 padding[8];
BOOL restore = OSDisableInterrupts();
GFWriteBPCmd(0x45000002);
GXFlush();
DrawDone = 0;
OSRestoreInterrupts(restore);
}
/* ############################################################################################## */
/* 80451974-8045197C 000E74 0008+00 3/3 0/0 0/0 .sbss FinishQueue */
static OSThreadQueue FinishQueue;
static void GXWaitDrawDone(void) {
BOOL restore = OSDisableInterrupts();
while (DrawDone == 0) {
OSSleepThread(&FinishQueue);
}
OSRestoreInterrupts(restore);
}
/* 8035C2F4-8035C374 356C34 0080+00 0/0 3/3 1/1 .text GXDrawDone */
void GXDrawDone(void) {
u8 padding[8];
GXSetDrawDone();
GXWaitDrawDone();
}
/* 8035C374-8035C398 356CB4 0024+00 0/0 9/9 0/0 .text GXPixModeSync */
void GXPixModeSync(void) {
GXWGFifo.u8 = 0x61;
GXWGFifo.u32 = __GXData->peCtrl;
__GXData->bpSentNot = 0;
}
/* 8035C398-8035C3AC 356CD8 0014+00 0/0 1/1 0/0 .text GXPokeAlphaMode */
void GXPokeAlphaMode(GXCompare comp, u8 threshold) {
__peReg[3] = (comp << 8) | threshold;
}
/* 8035C3AC-8035C3CC 356CEC 0020+00 0/0 1/1 0/0 .text GXPokeAlphaRead */
void GXPokeAlphaRead(GXAlphaReadMode mode) {
u32 val = 0;
GX_BITFIELD_SET(val, 0x1e, 2, mode);
GX_BITFIELD_SET(val, 0x1d, 1, 1);
__peReg[4] = val;
}
/* 8035C3CC-8035C3E4 356D0C 0018+00 0/0 1/1 0/0 .text GXPokeAlphaUpdate */
void GXPokeAlphaUpdate(GXBool enable_update) {
GX_BITFIELD_SET(__peReg[1], 0x1b, 1, enable_update);
}
/* 8035C3E4-8035C448 356D24 0064+00 0/0 1/1 0/0 .text GXPokeBlendMode */
void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor srcFactor, GXBlendFactor destFactor,
GXLogicOp op) {
u32 reg;
reg = GX_GET_PE_REG(1);
GX_SET_REG(reg, (mode == GX_BM_BLEND) || (mode == GX_BM_SUBTRACT), 31, 31);
GX_SET_REG(reg, (mode == GX_BM_SUBTRACT), 20, 20);
GX_SET_REG(reg, (mode == GX_BM_LOGIC), 30, 30);
GX_SET_REG(reg, op, 16, 19);
GX_SET_REG(reg, srcFactor, 21, 23);
GX_SET_REG(reg, destFactor, 24, 26);
GX_SET_REG(reg, 0x41, 0, 7);
GX_SET_PE_REG(1, reg);
}
/* 8035C448-8035C460 356D88 0018+00 0/0 1/1 0/0 .text GXPokeColorUpdate */
void GXPokeColorUpdate(GXBool enable_update) {
GX_BITFIELD_SET(__peReg[1], 0x1c, 1, enable_update);
}
/* 8035C460-8035C484 356DA0 0024+00 0/0 1/1 0/0 .text GXPokeDstAlpha */
void GXPokeDstAlpha(GXBool enable, u8 alpha) {
u32 val = 0;
GX_BITFIELD_SET(val, 0x18, 8, alpha);
GX_BITFIELD_SET(val, 0x17, 1, enable);
__peReg[2] = val;
}
/* 8035C484-8035C49C 356DC4 0018+00 0/0 1/1 0/0 .text GXPokeDither */
void GXPokeDither(GXBool enable) {
GX_BITFIELD_SET(__peReg[1], 0x1d, 1, enable);
}
/* 8035C49C-8035C4BC 356DDC 0020+00 0/0 1/1 0/0 .text GXPokeZMode */
void GXPokeZMode(GXBool enable_compare, GXCompare comp, GXBool update_enable) {
u32 val = 0;
GX_BITFIELD_SET(val, 0x1f, 1, enable_compare);
GX_BITFIELD_SET(val, 0x1c, 3, comp);
GX_BITFIELD_SET(val, 0x1b, 1, update_enable);
__peReg[0] = val;
}
/* 8035C4BC-8035C4E0 356DFC 0024+00 0/0 1/1 0/0 .text GXPeekZ */
void GXPeekZ(u16 x, u16 y, u32* z) {
u32 addr = 0xc8000000;
GX_BITFIELD_SET(addr, 0x14, 10, x);
GX_BITFIELD_SET(addr, 0xa, 10, y);
GX_BITFIELD_SET(addr, 8, 2, 1);
*z = *(u32*)addr;
}
/* 8035C4E0-8035C524 356E20 0044+00 0/0 1/1 0/0 .text GXSetDrawSyncCallback */
GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback callback) {
BOOL restore;
GXDrawSyncCallback prevCb = TokenCB;
restore = OSDisableInterrupts();
TokenCB = callback;
OSRestoreInterrupts(restore);
return prevCb;
}
/* 8035C524-8035C5AC 356E64 0088+00 1/1 0/0 0/0 .text GXTokenInterruptHandler */
static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
u16 token;
OSContext exceptContext;
u32 reg;
token = GX_GET_PE_REG(7);
if (TokenCB) {
OSClearContext(&exceptContext);
OSSetCurrentContext(&exceptContext);
TokenCB(token);
OSClearContext(&exceptContext);
OSSetCurrentContext(context);
}
reg = GX_GET_PE_REG(5);
GX_SET_REG(reg, 1, 29, 29);
GX_SET_PE_REG(5, reg);
}
/* 8035C5AC-8035C5F0 356EEC 0044+00 0/0 4/4 0/0 .text GXSetDrawDoneCallback */
GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback callback) {
BOOL restore;
GXDrawDoneCallback prevCb = DrawDoneCB;
restore = OSDisableInterrupts();
DrawDoneCB = callback;
OSRestoreInterrupts(restore);
return prevCb;
}
/* 8035C5F0-8035C670 356F30 0080+00 1/1 0/0 0/0 .text GXFinishInterruptHandler */
static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
OSContext exceptContext;
u32 reg;
reg = GX_GET_PE_REG(5);
GX_SET_REG(reg, 1, 28, 28);
GX_SET_PE_REG(5, reg);
DrawDone = GX_TRUE;
if (DrawDoneCB) {
OSClearContext(&exceptContext);
OSSetCurrentContext(&exceptContext);
DrawDoneCB();
OSClearContext(&exceptContext);
OSSetCurrentContext(context);
}
OSWakeupThread(&FinishQueue);
}
/* 8035C670-8035C6E4 356FB0 0074+00 0/0 1/1 0/0 .text __GXPEInit */
void __GXPEInit(void) {
u32 val;
__OSSetInterruptHandler(OS_INTR_PI_PE_TOKEN, GXTokenInterruptHandler);
__OSSetInterruptHandler(OS_INTR_PI_PE_FINISH, GXFinishInterruptHandler);
OSInitThreadQueue(&FinishQueue);
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_TOKEN);
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_FINISH);
val = __peReg[5];
GX_BITFIELD_SET(val, 0x1d, 1, 1);
GX_BITFIELD_SET(val, 0x1c, 1, 1);
GX_BITFIELD_SET(val, 0x1f, 1, 1);
GX_BITFIELD_SET(val, 0x1e, 1, 1);
__peReg[5] = val;
}