Skip to content

Instantly share code, notes, and snippets.

@Pokechu22
Last active June 6, 2022 23:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pokechu22/09185fcdad7466fa8fcd9ba75c62c484 to your computer and use it in GitHub Desktop.
Save Pokechu22/09185fcdad7466fa8fcd9ba75c62c484 to your computer and use it in GitHub Desktop.
__OSInitAudioSystem in SMS vs Datel Code
void os::__OSInitAudioSystem(void)
{
ushort uVar1;
ushort uVar2;
undefined2 uVar3;
ushort uVar4;
int iVar5;
int iVar6;
iVar5 = OSGetArenaHi();
Runtime.PPCEABI.H::memcpy((void *)(iVar5 + -0x80),(void *)0x81000000,0x80);
Runtime.PPCEABI.H::memcpy((void *)0x81000000,&DSPInitCode,0x80);
DCFlushRange(0x81000000,0x80);
write_volatile_2(DAT_cc005012,0x43);
write_volatile_2(DAT_cc00500a,0x8ac);
uVar1 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar1 | 1);
do {
uVar1 = read_volatile_2(DAT_cc00500a);
} while ((uVar1 & 1) != 0);
write_volatile_2(DAT_cc005000,0);
do {
uVar1 = read_volatile_2(DAT_cc005004);
} while ((uVar1 & 0x8000) != 0);
write_volatile_4(DAT_cc005020,0x1000000);
write_volatile_4(DAT_cc005024,0);
write_volatile_4(DAT_cc005028,0x20);
uVar1 = read_volatile_2(DAT_cc00500a);
while( true ) {
if ((uVar1 & 0x20) != 0) break;
uVar1 = read_volatile_2(DAT_cc00500a);
}
write_volatile_2(DAT_cc00500a,uVar1);
iVar5 = OSGetTick();
do {
iVar6 = OSGetTick();
} while (iVar6 - iVar5 < 0x892);
write_volatile_4(DAT_cc005020,0x1000000);
write_volatile_4(DAT_cc005024,0);
write_volatile_4(DAT_cc005028,0x20);
uVar1 = read_volatile_2(DAT_cc00500a);
while( true ) {
if ((uVar1 & 0x20) != 0) break;
uVar1 = read_volatile_2(DAT_cc00500a);
}
write_volatile_2(DAT_cc00500a,uVar1);
uVar2 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar2 & 0xf7ff);
do {
uVar2 = read_volatile_2(DAT_cc00500a);
} while ((uVar2 & 0x400) != 0);
uVar2 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar2 & 0xfffb);
uVar2 = read_volatile_2(DAT_cc005004);
while( true ) {
if ((uVar2 & 0x8000) != 0) break;
uVar2 = read_volatile_2(DAT_cc005004);
}
uVar4 = read_volatile_2(DAT_cc00500a);
uVar3 = read_volatile_2(DAT_cc005006);
write_volatile_2(DAT_cc00500a,uVar4 | 4);
write_volatile_2(DAT_cc00500a,0x8ac);
uVar4 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar4 | 1);
do {
uVar4 = read_volatile_2(DAT_cc00500a);
} while ((uVar4 & 1) != 0);
iVar5 = OSGetArenaHi(uVar1,uVar3,uVar2);
Runtime.PPCEABI.H::memcpy((void *)0x81000000,(void *)(iVar5 + -0x80),0x80);
return;
}
void FUN_800164f4(void)
{
ushort uVar1;
int iVar2;
int iVar3;
FUN_8002c004(&DAT_81000000,&DAT_80016bdc,0x80);
FUN_800158e4(&DAT_81000000,0x80);
write_volatile_2(DAT_cc005012,0x43);
write_volatile_2(DAT_cc00500a,0x8ac);
uVar1 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar1 | 1);
do {
uVar1 = read_volatile_2(DAT_cc00500a);
} while ((uVar1 & 1) != 0);
write_volatile_2(DAT_cc005000,uVar1 & 1);
do {
uVar1 = read_volatile_2(DAT_cc005004);
} while ((uVar1 & 0x8000) != 0);
write_volatile_4(DAT_cc005020,0x1000000);
write_volatile_4(DAT_cc005024,(uint)(uVar1 & 0x8000) << 0x10);
write_volatile_4(DAT_cc005028,0x20);
do {
uVar1 = read_volatile_2(DAT_cc00500a);
} while ((uVar1 & 0x20) == 0);
write_volatile_2(DAT_cc00500a,uVar1);
iVar2 = FUN_8001435c();
do {
iVar3 = FUN_8001435c();
} while (iVar3 == iVar2);
write_volatile_4(DAT_cc005020,0x1000000);
write_volatile_4(DAT_cc005024,0);
write_volatile_4(DAT_cc005028,0x20);
do {
uVar1 = read_volatile_2(DAT_cc00500a);
} while ((uVar1 & 0x20) == 0);
write_volatile_2(DAT_cc00500a,uVar1);
uVar1 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar1 & 0xff7f);
do {
uVar1 = read_volatile_2(DAT_cc00500a);
} while ((uVar1 & 0x400) != 0);
uVar1 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar1 & 0xfffb);
do {
uVar1 = read_volatile_2(DAT_cc005004);
} while ((uVar1 & 0x8000) == 0);
uVar1 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar1 | 4);
write_volatile_2(DAT_cc00500a,0x8ac);
uVar1 = read_volatile_2(DAT_cc00500a);
write_volatile_2(DAT_cc00500a,uVar1 | 1);
do {
uVar1 = read_volatile_2(DAT_cc00500a);
} while ((uVar1 & 1) != 0);
return;
}
void os::__OSInitAudioSystem(void)
{
memcpy((void *)(OSGetArenaHi() + -0x80),(void *)0x81000000,0x80);
memcpy((void *)0x81000000,&DSPInitCode,0x80);
DCFlushRange((void*)0x81000000,0x80);
write_volatile_2(AR_INFO,0x43);
write_volatile_2(DSP_CONTROL,(DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT));
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_RESET);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_RESET) != 0) { /* wait for reset bit to clear*/ }
write_volatile_2(DSP_MAIL_TO_DSP_HI,0);
while ((read_volatile_2(DSP_MAIL_FROM_DSP_HI) & 0x8000) != 0) { /* wait for there to be no pending mail(?) */ }
read_volatile_2(DSP_MAIL_FROM_DSP_LO); // Wasn't shown in decompiler before; did https://github.com/NationalSecurityAgency/ghidra/issues/1832 regress?
write_volatile_4(AR_DMA_MMADDR,0x1000000);
write_volatile_4(AR_DMA_ARADDR,0);
write_volatile_4(AR_DMA_CNT,0x20);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_ARINT) == 0) { /* wait for AR interrupt */ }
write_volatile_2(DSP_CONTROL, DSP_CONTROL); // clear interrupts (this is done using the value read from the loop above)
u64 start_tick = OSGetTick();
while (OSGetTick() - start_tick < 0x892) { /* delay a bit */ }
write_volatile_4(AR_DMA_MMADDR,0x1000000);
write_volatile_4(AR_DMA_ARADDR,0);
write_volatile_4(AR_DMA_CNT,0x20);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_ARINT) == 0) { /* wait for AR interrupt */ }
write_volatile_2(DSP_CONTROL, DSP_CONTROL); // clear interrupts (this is done using the value read from the loop above)
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) & ~DSPCR_DSPINIT); // ~0x800, also called DSPCR_DSPRESET by libogc
while ((read_volatile_2(DSP_CONTROL) & DSPCR_DSPINITCODE) != 0) { /* wait for 0x400 bit to clear, not named by libogc */ }
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) & ~DSPCR_HALT);
while ((read_volatile_2(DSP_MAIL_FROM_DSP_HI) & 0x8000) == 0) { /* wait for the DSP to send mail */ }
read_volatile_2(DSP_MAIL_FROM_DSP_LO);
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_HALT);
write_volatile_2(DSP_CONTROL,(DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT));
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_RESET);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_RESET) != 0) { /* wait for reset bit to clear */ }
memcpy((void *)0x81000000,(void *)(OSGetArenaHi() + -0x80),0x80);
}
void FUN_800164f4(void)
{
// Datel doesn't care about saving what's already at 0x81000000
memcpy((void *)0x81000000,&DAT_80016bdc,0x80);
DCFlushRange((void*)0x81000000,0x80);
write_volatile_2(AR_INFO,0x43);
write_volatile_2(DSP_CONTROL,(DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT));
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_RESET);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_RESET) != 0) { /* wait for reset bit to clear*/ }
write_volatile_2(DSP_MAIL_TO_DSP_HI,0);
while ((read_volatile_2(DSP_MAIL_FROM_DSP_HI) & 0x8000) != 0) { /* wait for there to be no pending mail(?) */ }
read_volatile_2(DSP_MAIL_FROM_DSP_LO); // Wasn't shown in decompiler before; did https://github.com/NationalSecurityAgency/ghidra/issues/1832 regress?
write_volatile_4(AR_DMA_MMADDR,0x1000000);
write_volatile_4(AR_DMA_ARADDR,0);
write_volatile_4(AR_DMA_CNT,0x20);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_ARINT) == 0) { /* wait for AR interrupt */ }
write_volatile_2(DSP_CONTROL, DSP_CONTROL); // clear interrupts (this is done using the value read from the loop above)
u32 time = FUN_8001435c();
while (FUN_8001435c() == time) { /* delay a bit - this is different logic from SMS. This function returns DAT_800ba834, which is incremented by a different function (maybe once each frame?) */ }
write_volatile_4(AR_DMA_MMADDR,0x1000000);
write_volatile_4(AR_DMA_ARADDR,0);
write_volatile_4(AR_DMA_CNT,0x20);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_ARINT) == 0) { /* wait for AR interrupt */ }
write_volatile_2(DSP_CONTROL, DSP_CONTROL); // clear interrupts (this is done using the value read from the loop above)
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) & ~DSPCR_DSPINT); // ~0x80, this is a different value and probably a typo!
while ((read_volatile_2(DSP_CONTROL) & DSPCR_DSPINITCODE) != 0) { /* wait for 0x400 bit to clear, not named by libogc */ }
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) & ~DSPCR_HALT);
// The hang happens in this loop
while ((read_volatile_2(DSP_MAIL_FROM_DSP_HI) & 0x8000) == 0) { /* wait for the DSP to send mail */ }
read_volatile_2(DSP_MAIL_FROM_DSP_LO);
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_HALT);
write_volatile_2(DSP_CONTROL,(DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT));
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_RESET);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_RESET) != 0) { /* wait for reset bit to clear */ }
// Datel didn't save the existing contents of 0x81000000, so they don't restore it either
}
-void os::__OSInitAudioSystem(void)
+void FUN_800164f4(void)
{
- memcpy((void *)(OSGetArenaHi() + -0x80),(void *)0x81000000,0x80);
- memcpy((void *)0x81000000,&DSPInitCode,0x80);
+ // Datel doesn't care about saving what's already at 0x81000000
+ memcpy((void *)0x81000000,&DAT_80016bdc,0x80);
DCFlushRange((void*)0x81000000,0x80);
write_volatile_2(AR_INFO,0x43);
write_volatile_2(DSP_CONTROL,(DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT));
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_RESET);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_RESET) != 0) { /* wait for reset bit to clear*/ }
write_volatile_2(DSP_MAIL_TO_DSP_HI,0);
while ((read_volatile_2(DSP_MAIL_FROM_DSP_HI) & 0x8000) != 0) { /* wait for there to be no pending mail(?) */ }
read_volatile_2(DSP_MAIL_FROM_DSP_LO); // Wasn't shown in decompiler before; did https://github.com/NationalSecurityAgency/ghidra/issues/1832 regress?
write_volatile_4(AR_DMA_MMADDR,0x1000000);
write_volatile_4(AR_DMA_ARADDR,0);
write_volatile_4(AR_DMA_CNT,0x20);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_ARINT) == 0) { /* wait for AR interrupt */ }
write_volatile_2(DSP_CONTROL, DSP_CONTROL); // clear interrupts (this is done using the value read from the loop above)
- u64 start_tick = OSGetTick();
- while (OSGetTick() - start_tick < 0x892) { /* delay a bit */ }
+ u32 time = FUN_8001435c();
+ while (FUN_8001435c() == time) { /* delay a bit - this is different logic from SMS. This function returns DAT_800ba834, which is incremented by a different function (maybe once each frame?) */ }
write_volatile_4(AR_DMA_MMADDR,0x1000000);
write_volatile_4(AR_DMA_ARADDR,0);
write_volatile_4(AR_DMA_CNT,0x20);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_ARINT) == 0) { /* wait for AR interrupt */ }
write_volatile_2(DSP_CONTROL, DSP_CONTROL); // clear interrupts (this is done using the value read from the loop above)
- write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) & ~DSPCR_DSPINIT); // ~0x800, also called DSPCR_DSPRESET by libogc
+ write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) & ~DSPCR_DSPINT); // ~0x80, this is a different value and probably a typo!
while ((read_volatile_2(DSP_CONTROL) & DSPCR_DSPINITCODE) != 0) { /* wait for 0x400 bit to clear, not named by libogc */ }
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) & ~DSPCR_HALT);
+ // The hang happens in this loop
while ((read_volatile_2(DSP_MAIL_FROM_DSP_HI) & 0x8000) == 0) { /* wait for the DSP to send mail */ }
read_volatile_2(DSP_MAIL_FROM_DSP_LO);
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_HALT);
write_volatile_2(DSP_CONTROL,(DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT));
write_volatile_2(DSP_CONTROL,read_volatile_2(DSP_CONTROL) | DSPCR_RESET);
while ((read_volatile_2(DSP_CONTROL) & DSPCR_RESET) != 0) { /* wait for reset bit to clear */ }
- memcpy((void *)0x81000000,(void *)(OSGetArenaHi() + -0x80),0x80);
+ // Datel didn't save the existing contents of 0x81000000, so they don't restore it either
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment