mirror of https://github.com/zeldaret/tp.git
381 lines
11 KiB
C
381 lines
11 KiB
C
//
|
|
// Generated By: dol2asm
|
|
// Translation Unit: ai
|
|
//
|
|
|
|
#include "dolphin/ai/ai.h"
|
|
#include "dol2asm.h"
|
|
#include "dolphin/dsp/dsp.h"
|
|
#include "dolphin/os/OS.h"
|
|
|
|
void __AISHandler(s16 interrupt, OSContext* context);
|
|
void __AIDHandler(s16 interrupt, OSContext* context);
|
|
void __AICallbackStackSwitch(AIDCallback callback);
|
|
void __AI_SRC_INIT(void);
|
|
|
|
/* ############################################################################################## */
|
|
/* 80451878-8045187C 000D78 0004+00 2/2 0/0 0/0 .sbss __AIS_Callback */
|
|
static AISCallback __AIS_Callback;
|
|
|
|
/* 8045187C-80451880 000D7C 0004+00 3/3 0/0 0/0 .sbss __AID_Callback */
|
|
static AIDCallback __AID_Callback;
|
|
|
|
/* 8034FC70-8034FCB4 34A5B0 0044+00 0/0 1/1 0/0 .text AIRegisterDMACallback */
|
|
AIDCallback AIRegisterDMACallback(AIDCallback callback) {
|
|
s32 oldInts;
|
|
AIDCallback ret;
|
|
|
|
ret = __AID_Callback;
|
|
oldInts = OSDisableInterrupts();
|
|
__AID_Callback = callback;
|
|
OSRestoreInterrupts(oldInts);
|
|
return ret;
|
|
}
|
|
|
|
/* 8034FCB4-8034FD3C 34A5F4 0088+00 0/0 2/2 0/0 .text AIInitDMA */
|
|
void AIInitDMA(u32 addr, u32 length) {
|
|
s32 oldInts;
|
|
oldInts = OSDisableInterrupts();
|
|
__DSPRegs[24] = (u16)((__DSPRegs[24] & ~0x3FF) | (addr >> 16));
|
|
__DSPRegs[25] = (u16)((__DSPRegs[25] & ~0xFFE0) | (0xffff & addr));
|
|
__DSPRegs[27] = (u16)((__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF));
|
|
OSRestoreInterrupts(oldInts);
|
|
}
|
|
|
|
/* 8034FD3C-8034FD54 34A67C 0018+00 0/0 1/1 0/0 .text AIStartDMA */
|
|
void AIStartDMA(void) {
|
|
__DSPRegs[27] |= 0x8000;
|
|
}
|
|
|
|
/* 8034FD54-8034FD6C 34A694 0018+00 0/0 1/1 0/0 .text AIStopDMA */
|
|
|
|
void AIStopDMA(void) {
|
|
__DSPRegs[27] &= ~0x8000;
|
|
}
|
|
|
|
/* 8034FD6C-8034FE44 34A6AC 00D8+00 1/1 1/1 0/0 .text AISetStreamPlayState */
|
|
void AISetStreamPlayState(u32 state) {
|
|
s32 oldInts;
|
|
u8 volRight;
|
|
u8 volLeft;
|
|
|
|
if (state == AIGetStreamPlayState()) {
|
|
return;
|
|
}
|
|
|
|
if (AIGetStreamSampleRate() == 0 && state == 1) {
|
|
volRight = AIGetStreamVolRight();
|
|
volLeft = AIGetStreamVolLeft();
|
|
AISetStreamVolRight(0);
|
|
AISetStreamVolLeft(0);
|
|
oldInts = OSDisableInterrupts();
|
|
__AI_SRC_INIT();
|
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
|
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
|
OSRestoreInterrupts(oldInts);
|
|
AISetStreamVolLeft(volRight);
|
|
AISetStreamVolRight(volLeft);
|
|
} else {
|
|
__AIRegs[0] = (__AIRegs[0] & ~1) | state;
|
|
}
|
|
}
|
|
|
|
/* 8034FE44-8034FE54 34A784 0010+00 1/1 0/0 0/0 .text AIGetStreamPlayState */
|
|
inline u32 AIGetStreamPlayState(void) {
|
|
return __AIRegs[0] & 1;
|
|
}
|
|
|
|
/* 8034FE54-8034FF34 34A794 00E0+00 1/1 1/1 0/0 .text AISetDSPSampleRate */
|
|
void AISetDSPSampleRate(u32 rate) {
|
|
u32 state;
|
|
s32 oldInts;
|
|
u8 left;
|
|
u8 right;
|
|
u32 sampleRate;
|
|
|
|
if (rate == AIGetDSPSampleRate()) {
|
|
return;
|
|
}
|
|
|
|
__AIRegs[0] &= ~0x40;
|
|
if (rate == 0) {
|
|
left = AIGetStreamVolLeft();
|
|
right = AIGetStreamVolRight();
|
|
state = AIGetStreamPlayState();
|
|
sampleRate = AIGetStreamSampleRate();
|
|
AISetStreamVolLeft(0);
|
|
AISetStreamVolRight(0);
|
|
oldInts = OSDisableInterrupts();
|
|
__AI_SRC_INIT();
|
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
|
__AIRegs[0] = (__AIRegs[0] & ~2) | (sampleRate * 2);
|
|
__AIRegs[0] = (__AIRegs[0] & ~1) | state;
|
|
__AIRegs[0] |= 0x40;
|
|
OSRestoreInterrupts(oldInts);
|
|
AISetStreamVolLeft(left);
|
|
AISetStreamVolRight(right);
|
|
}
|
|
}
|
|
|
|
/* 8034FF34-8034FF48 34A874 0014+00 1/1 0/0 1/1 .text AIGetDSPSampleRate */
|
|
u32 AIGetDSPSampleRate(void) {
|
|
return ((__AIRegs[0] >> 6) & 1) ^ 1;
|
|
}
|
|
|
|
/* 8034FF48-8035001C 34A888 00D4+00 1/1 0/1 0/0 .text __AI_set_stream_sample_rate */
|
|
void __AI_set_stream_sample_rate(u32 rate) {
|
|
s32 oldInts;
|
|
s32 state;
|
|
u8 left;
|
|
u8 right;
|
|
s32 temp_r26;
|
|
|
|
if (rate == AIGetStreamSampleRate()) {
|
|
return;
|
|
}
|
|
|
|
state = AIGetStreamPlayState();
|
|
left = AIGetStreamVolLeft();
|
|
right = AIGetStreamVolRight();
|
|
AISetStreamVolRight(0);
|
|
AISetStreamVolLeft(0);
|
|
temp_r26 = __AIRegs[0] & 0x40;
|
|
__AIRegs[0] &= ~0x40;
|
|
oldInts = OSDisableInterrupts();
|
|
__AI_SRC_INIT();
|
|
__AIRegs[0] |= temp_r26;
|
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
|
__AIRegs[0] = (__AIRegs[0] & ~2) | (rate * 2);
|
|
OSRestoreInterrupts(oldInts);
|
|
AISetStreamPlayState(state);
|
|
AISetStreamVolLeft(left);
|
|
AISetStreamVolRight(right);
|
|
}
|
|
|
|
/* 8035001C-8035002C 34A95C 0010+00 3/3 0/0 0/0 .text AIGetStreamSampleRate */
|
|
u32 AIGetStreamSampleRate(void) {
|
|
return (__AIRegs[0] >> 1) & 1;
|
|
}
|
|
|
|
/* 8035002C-80350048 34A96C 001C+00 3/3 1/1 0/0 .text AISetStreamVolLeft */
|
|
void AISetStreamVolLeft(u8 vol) {
|
|
__AIRegs[1] = (__AIRegs[1] & ~0xFF) | (vol & 0xFF);
|
|
}
|
|
|
|
/* 80350048-80350058 34A988 0010+00 3/3 0/0 0/0 .text AIGetStreamVolLeft */
|
|
u8 AIGetStreamVolLeft(void) {
|
|
return __AIRegs[1];
|
|
}
|
|
|
|
/* 80350058-80350074 34A998 001C+00 3/3 1/1 0/0 .text AISetStreamVolRight */
|
|
void AISetStreamVolRight(u8 vol) {
|
|
__AIRegs[1] = (__AIRegs[1] & ~0xFF00) | ((vol & 0xFF) << 8);
|
|
}
|
|
|
|
/* 80350074-80350084 34A9B4 0010+00 3/3 0/0 0/0 .text AIGetStreamVolRight */
|
|
u8 AIGetStreamVolRight(void) {
|
|
return __AIRegs[1] >> 8;
|
|
}
|
|
|
|
/* ############################################################################################## */
|
|
/* 803D1BA0-803D1BE8 02ECC0 0044+04 1/0 0/0 0/0 .data @1 */
|
|
SECTION_DATA static char lit_1[] =
|
|
"<< Dolphin SDK - AI\trelease build: Apr 5 2004 04:15:02 (0x2301) >>";
|
|
|
|
/* 80450A40-80450A48 -00001 0004+04 1/1 0/0 0/0 .sdata __AIVersion */
|
|
SECTION_SDATA static const char* __AIVersion = lit_1;
|
|
|
|
/* 80451880-80451884 000D80 0004+00 3/3 0/0 0/0 .sbss __CallbackStack */
|
|
static u8* __CallbackStack;
|
|
|
|
/* 80451884-80451888 000D84 0004+00 1/1 0/0 0/0 .sbss __OldStack */
|
|
static u8* __OldStack;
|
|
|
|
/* 80451888-8045188C 000D88 0004+00 1/1 0/0 0/0 .sbss __AI_init_flag */
|
|
static volatile s32 __AI_init_flag;
|
|
|
|
/* 8045188C-80451890 000D8C 0004+00 1/1 0/0 0/0 .sbss __AID_Active */
|
|
static volatile s32 __AID_Active;
|
|
|
|
/* 80451890-80451894 000D90 0004+00 2/2 0/0 0/0 .sbss bound_32KHz */
|
|
static OSTime bound_32KHz;
|
|
|
|
/* 80451898-8045189C 000D98 0004+00 2/2 0/0 0/0 .sbss bound_48KHz */
|
|
static OSTime bound_48KHz;
|
|
|
|
/* 804518A0-804518A4 000DA0 0004+00 2/2 0/0 0/0 .sbss min_wait */
|
|
static OSTime min_wait;
|
|
|
|
/* 804518A8-804518AC 000DA8 0004+00 2/2 0/0 0/0 .sbss max_wait */
|
|
static OSTime max_wait;
|
|
|
|
/* 804518B0-804518B4 000DB0 0004+00 2/2 0/0 0/0 .sbss buffer */
|
|
static OSTime buffer;
|
|
|
|
inline void AIResetStreamSampleCount(void) { __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; }
|
|
|
|
inline void AISetStreamTrigger(u32 trigger) { __AIRegs[3] = trigger; }
|
|
|
|
/* 80350084-803501F0 34A9C4 016C+00 0/0 1/1 0/0 .text AIInit */
|
|
void AIInit(u8* stack) {
|
|
if (__AI_init_flag == TRUE) {
|
|
return;
|
|
}
|
|
|
|
OSRegisterVersion(__AIVersion);
|
|
bound_32KHz = OSNanosecondsToTicks(31524);
|
|
bound_48KHz = OSNanosecondsToTicks(42024);
|
|
min_wait = OSNanosecondsToTicks(42000);
|
|
max_wait = OSNanosecondsToTicks(63000);
|
|
buffer = OSNanosecondsToTicks(3000);
|
|
|
|
AISetStreamVolRight(0);
|
|
AISetStreamVolLeft(0);
|
|
AISetStreamTrigger(0);
|
|
AIResetStreamSampleCount();
|
|
__AI_set_stream_sample_rate(1);
|
|
AISetDSPSampleRate(0);
|
|
__AIS_Callback = 0;
|
|
__AID_Callback = 0;
|
|
__CallbackStack = stack;
|
|
__OSSetInterruptHandler(5, __AIDHandler);
|
|
__OSUnmaskInterrupts(0x04000000);
|
|
__OSSetInterruptHandler(8, __AISHandler);
|
|
__OSUnmaskInterrupts(0x800000);
|
|
__AI_init_flag = TRUE;
|
|
}
|
|
|
|
/* 803501F0-8035026C 34AB30 007C+00 1/1 0/0 0/0 .text __AISHandler */
|
|
void __AISHandler(s16 interrupt, OSContext* context) {
|
|
OSContext tmpContext;
|
|
__AIRegs[0] |= 8;
|
|
OSClearContext(&tmpContext);
|
|
OSSetCurrentContext(&tmpContext);
|
|
|
|
if (__AIS_Callback != NULL) {
|
|
__AIS_Callback(__AIRegs[2]);
|
|
}
|
|
|
|
OSClearContext(&tmpContext);
|
|
OSSetCurrentContext(context);
|
|
}
|
|
|
|
/* 8035026C-80350318 34ABAC 00AC+00 1/1 0/0 0/0 .text __AIDHandler */
|
|
void __AIDHandler(s16 interrupt, OSContext* context) {
|
|
OSContext tempContext;
|
|
u32 temp = __DSPRegs[5];
|
|
__DSPRegs[5] = (temp & ~0xA0) | 8;
|
|
OSClearContext(&tempContext);
|
|
OSSetCurrentContext(&tempContext);
|
|
|
|
if (__AID_Callback && !__AID_Active) {
|
|
__AID_Active = TRUE;
|
|
|
|
if (__CallbackStack) {
|
|
__AICallbackStackSwitch(__AID_Callback);
|
|
} else {
|
|
__AID_Callback();
|
|
}
|
|
|
|
__AID_Active = FALSE;
|
|
}
|
|
|
|
OSClearContext(&tempContext);
|
|
OSSetCurrentContext(context);
|
|
}
|
|
|
|
/* 80350318-80350370 34AC58 0058+00 1/1 0/0 0/0 .text __AICallbackStackSwitch */
|
|
// clang-format off
|
|
asm void __AICallbackStackSwitch(register AIDCallback cb) {
|
|
// Allocate stack frame
|
|
fralloc
|
|
|
|
// Store current stack
|
|
lis r5, __OldStack@ha
|
|
addi r5, r5, __OldStack@l
|
|
stw r1, 0(r5)
|
|
|
|
// Load stack for callback
|
|
lis r5, __CallbackStack@ha
|
|
addi r5, r5, __CallbackStack@l
|
|
lwz r1,0(r5)
|
|
|
|
// Move stack down 8 bytes
|
|
subi r1, r1, 8
|
|
// Call callback
|
|
mtlr cb
|
|
blrl
|
|
|
|
// Restore old stack
|
|
lis r5, __OldStack @ha
|
|
addi r5, r5, __OldStack@l
|
|
lwz r1,0(r5)
|
|
|
|
// Free stack frame
|
|
frfree
|
|
|
|
blr
|
|
}
|
|
// clang-format on
|
|
|
|
/* 80350370-80350554 34ACB0 01E4+00 3/3 0/0 0/0 .text __AI_SRC_INIT */
|
|
void __AI_SRC_INIT(void) {
|
|
OSTime rise32 = 0;
|
|
OSTime rise48 = 0;
|
|
OSTime diff = 0;
|
|
OSTime unused1 = 0;
|
|
OSTime temp = 0;
|
|
u32 temp0 = 0;
|
|
u32 temp1 = 0;
|
|
u32 done = 0;
|
|
u32 walking = 0;
|
|
u32 unused2 = 0;
|
|
u32 initCnt = 0;
|
|
|
|
walking = 0;
|
|
initCnt = 0;
|
|
temp = 0;
|
|
|
|
while (!done) {
|
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
|
__AIRegs[0] &= ~2;
|
|
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
|
|
|
temp0 = __AIRegs[2];
|
|
|
|
while (temp0 == __AIRegs[2])
|
|
;
|
|
rise32 = OSGetTime();
|
|
|
|
__AIRegs[0] = (__AIRegs[0] & ~2) | 2;
|
|
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
|
|
|
temp1 = __AIRegs[2];
|
|
while (temp1 == __AIRegs[2])
|
|
;
|
|
|
|
rise48 = OSGetTime();
|
|
|
|
diff = rise48 - rise32;
|
|
__AIRegs[0] &= ~2;
|
|
__AIRegs[0] &= ~1;
|
|
|
|
if (diff < (bound_32KHz - buffer)) {
|
|
temp = min_wait;
|
|
done = 1;
|
|
++initCnt;
|
|
} else if (diff >= (bound_32KHz + buffer) && diff < (bound_48KHz - buffer)) {
|
|
temp = max_wait;
|
|
done = 1;
|
|
++initCnt;
|
|
} else {
|
|
done = 0;
|
|
walking = 1;
|
|
++initCnt;
|
|
}
|
|
}
|
|
|
|
while ((rise48 + temp) > OSGetTime())
|
|
;
|
|
}
|