tp/libs/dolphin/ai/ai.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())
;
}