diff --git a/Source/Core/DebuggerUICommon/DebuggerUICommon.vcproj b/Source/Core/DebuggerUICommon/DebuggerUICommon.vcproj index 066e1d5629..fcb25c7e4d 100644 --- a/Source/Core/DebuggerUICommon/DebuggerUICommon.vcproj +++ b/Source/Core/DebuggerUICommon/DebuggerUICommon.vcproj @@ -419,6 +419,14 @@ RelativePath=".\Src\DebuggerUIUtil.h" > + + + + diff --git a/Source/Core/DebuggerWX/Src/MemoryView.cpp b/Source/Core/DebuggerUICommon/Src/MemoryView.cpp similarity index 99% rename from Source/Core/DebuggerWX/Src/MemoryView.cpp rename to Source/Core/DebuggerUICommon/Src/MemoryView.cpp index 0a3d2193cd..4e30732c94 100644 --- a/Source/Core/DebuggerWX/Src/MemoryView.cpp +++ b/Source/Core/DebuggerUICommon/Src/MemoryView.cpp @@ -15,7 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "Debugger.h" +#include "DebuggerUIUtil.h" #include "Common.h" #include "MemoryView.h" diff --git a/Source/Core/DebuggerWX/Src/MemoryView.h b/Source/Core/DebuggerUICommon/Src/MemoryView.h similarity index 98% rename from Source/Core/DebuggerWX/Src/MemoryView.h rename to Source/Core/DebuggerUICommon/Src/MemoryView.h index 6a2d1b36e4..852fdc1a23 100644 --- a/Source/Core/DebuggerWX/Src/MemoryView.h +++ b/Source/Core/DebuggerUICommon/Src/MemoryView.h @@ -18,7 +18,7 @@ #ifndef MEMORYVIEW_H_ #define MEMORYVIEW_H_ -#include "Debugger.h" +#include "DebuggerUIUtil.h" #include "Common.h" #include "DebugInterface.h" diff --git a/Source/Core/DebuggerUICommon/Src/SConscript b/Source/Core/DebuggerUICommon/Src/SConscript index 3f7e530e55..66df3477e4 100644 --- a/Source/Core/DebuggerUICommon/Src/SConscript +++ b/Source/Core/DebuggerUICommon/Src/SConscript @@ -4,6 +4,7 @@ Import('env') files = [ 'CodeView.cpp', + 'MemoryView.cpp', 'DebuggerUIUtil.cpp', ] diff --git a/Source/Core/DebuggerWX/DebuggerWX.vcproj b/Source/Core/DebuggerWX/DebuggerWX.vcproj index 3f84875fb0..c550bb320a 100644 --- a/Source/Core/DebuggerWX/DebuggerWX.vcproj +++ b/Source/Core/DebuggerWX/DebuggerWX.vcproj @@ -426,14 +426,6 @@ RelativePath=".\src\BreakpointView.h" > - - - - diff --git a/Source/Core/DebuggerWX/Src/SConscript b/Source/Core/DebuggerWX/Src/SConscript index d9ae5a9566..be39b14e37 100644 --- a/Source/Core/DebuggerWX/Src/SConscript +++ b/Source/Core/DebuggerWX/Src/SConscript @@ -12,7 +12,6 @@ files = [ "CodeWindow.cpp", "CodeWindowSJP.cpp", "MemoryCheckDlg.cpp", - "MemoryView.cpp", "MemoryWindow.cpp", "RegisterWindow.cpp", "RegisterView.cpp", diff --git a/docs/DSP/DSP_UC_Zelda.txt b/docs/DSP/DSP_UC_Zelda.txt index e07922e1bd..9be7ce4615 100644 --- a/docs/DSP/DSP_UC_Zelda.txt +++ b/docs/DSP/DSP_UC_Zelda.txt @@ -143,6 +143,8 @@ There's definitely a bunch of sample data stored in each PB but I don't know exa // It is like this: // (0x04fc + lastRenderedFrame) must be "something" :) +0x0580.. Unresampled audio data is decoded to here + /////////////////////////////////////////// // Initialized at 04c0_Unk()... used by SyncFrame 0x0B00 to 0x0C00 @@ -1093,7 +1095,8 @@ void 0243_COMMAND_02() // sync frame default: GOTO 087C: } - + // This is the common decoding prep for 0x05 and 0x09. + // 02bd 00d8 0402 lr $AX0.L, @0x0402 // delta? // 02bf 8100 clr $ACC0 // 02c0 8900 clr $ACC1 @@ -1105,7 +1108,8 @@ void 0243_COMMAND_02() // sync frame // 02c7 1404 lsl $ACC0, #4 // 02c8 8c00 clr15 - // Might 0402 be the delta, and if so, is this a computation of the starting point for decoding? + // 0x0402 is delta ("Ratio"). + // Is this a computation of the starting point for decoding? // If so 0x430 is the current sample position fraction and AX0.L = *0x0402 ACC0 = *0x430 + (AX0.L * 0x50) @@ -1121,12 +1125,12 @@ void 0243_COMMAND_02() // sync frame // NOP jump here. // 02ce 029f 02d0 jmp 0x02d0 - MixFrom_0580_to_0520: + Resample_From0580To0520: // 02d0 0080 0580 lri $AR0, #0x0580 // 02d2 0081 0520 lri $AR1, #0x0520 // 02d4 0099 0000 lri $AX1.L, #0x0000 // 02d6 02bf 0d7f call 0x0d7f - 0d7f_Unk_MaybeResample(0x0580, 0x0520, 0x0000); + 0d7f_ResampleAudioData(0x0580, 0x0520, 0x0000); } // A block of audio is now present at 0x520. @@ -3036,7 +3040,7 @@ void 087c_DefaultDecoder() 08a3 029f 08b1 jmp 0x08b1 // case 0x9 (can never happen) 08a5 029f 093a jmp 0x093a // case 0xa 08a7 029f 08f3 jmp 0x08f3 // case 0xb -08a9 029f 08f7 jmp 0x08f7 // case 0xc +08a9 029f 08f7 jmp 0x08f7 // case 0xc (Zelda force field in temple of gods) 08ab 029f 08b1 jmp 0x08b1 // case 0xd (unused) 08ad 029f 08b1 jmp 0x08b1 // case 0xe (unused) 08af 029f 08b1 jmp 0x08b1 // case 0xf (unused) @@ -3289,31 +3293,43 @@ void 0983_WriteRamp(ACC0, ACC1, Dest($AR3)) { } //////////////////////////////////////////// 0x08 DECODER +// Hardcoded destination 0x0580. void Decoder0x08() { 098f 0092 0004 lri $CR, #0x0004 0991 2002 lrs $AX0.L, @0x0002 0992 8100 clr $ACC0 0993 8900 clr $ACC1 0994 2430 lrs $AC0.L, @0x0030 // CurSampleFrac - 0995 8d00 set15 - 0996 0950 lris $AX1.L, #0x50 - 0997 a000 mulx $AX0.L, $AX1.L - 0998 a400 mulxac $AX0.L, $AX1.L, $ACC0 - 0999 1404 lsl $ACC0, #4 - 099a 8c00 clr15 + + // 0995 8d00 set15 + // 0996 0950 lris $AX1.L, #0x50 + // 0997 a000 mulx $AX0.L, $AX1.L + // 0998 a400 mulxac $AX0.L, $AX1.L, $ACC0 + // 0999 1404 lsl $ACC0, #4 + // 099a 8c00 clr15 + // Compute how much data we need to read, to get 0x50 samples after resampling. + // AC0.L is cursamplefrace, AX0.L is ratio. + $ACC0 = PB.CurrentSampleFrac + 0x50 * PB.Ratio; + 099b 1ffe mrr $AC1.M, $AC0.M 099c 0083 0580 lri $AR3, #0x0580 099e 2201 lrs $AX0.H, @0x0001 099f 8600 tstaxh $AX0.H 09a0 0294 09b1 jnz 0x09b1 - 09a2 2204 lrs $AX0.H, @0x0004 - 09a3 8600 tstaxh $AX0.H - 09a4 02b4 09f9 callne 0x09f9 + + // 09a2 2204 lrs $AX0.H, @0x0004 + // 09a3 8600 tstaxh $AX0.H + // 09a4 02b4 09f9 callne 0x09f9 + if (*0x0404) { // NeedsReset + 09f9_UpdateSampleCounters8(); + } + 09a6 8100 clr $ACC0 09a7 2605 lrs $AC0.M, @0x0005 09a8 b100 tst $ACC0 09a9 0295 09be jz 0x09be - + +label09ab: 09ab 8100 clr $ACC0 09ac 2e05 srs @0x0005, $AC0.M 09ad 2281 lrs $AX0.H, @0xff81 @@ -3329,35 +3345,44 @@ void Decoder0x08() { 09b9 2489 lrs $AC0.L, @0xff89 09ba 2e34 srs @0x0034, $AC0.M 09bb 2c35 srs @0x0035, $AC0.L - 09bc 02bf 09f9 call 0x09f9 + // 09bc 02bf 09f9 call 0x09f9 + 09f9_UpdateSampleCounters8(); + 09be 00ff 0360 sr @0x0360, $AC1.M 09c0 2638 lrs $AC0.M, @0x0038 09c1 2439 lrs $AC0.L, @0x0039 - 09c2 0f05 lris $AC1.M, #0x05 - 09c3 02bf 05ad call 0x05ad - 05ad_SetupAccelerator(AC0.M, AC0.L, AC1.M) + 09c2 0f05 lris $AC1.M, #0x05 // Sample format 5 + // 09c3 02bf 05ad call 0x05ad + 05ad_SetupAccelerator(AC0.M, AC0.L, AC1.M) 09c5 00df 0360 lr $AC1.M, @0x0360 09c7 8100 clr $ACC0 - 09c8 263a lrs $AC0.M, @0x003a - 09c9 b100 tst $ACC0 - 09ca 0294 09d9 jnz 0x09d9 - 09cc 263b lrs $AC0.M, @0x003b - 09cd 5c00 sub $ACC0, $ACC1 - 09ce 0290 09d9 jns 0x09d9 - 09d0 223b lrs $AX0.H, @0x003b - - 09d1 02bf 0a0a call 0x0a0a // Load more samples. - 09d3 5500 subr $ACC1, $AX0.H - 09d4 0a01 lris $AX0.H, #0x01 - 09d5 00fa 0405 sr @0x0405, $AX0.H - 09d7 029f 09ab jmp 0x09ab - + // 09c8 263a lrs $AC0.M, @0x003a + // 09c9 b100 tst $ACC0 + // 09ca 0294 09d9 jnz 0x09d9 + if (*(0x043a)) { + 09cc 263b lrs $AC0.M, @0x003b + 09cd 5c00 sub $ACC0, $ACC1 + 09ce 0290 09d9 jns 0x09d9 + + 09d0 223b lrs $AX0.H, @0x003b + // 09d1 02bf 0a0a call 0x0a0a // Load more samples. + 0a0a_ReadFromAccelerator8To16(OutBuffer($AR3), Count($AX0.H)) + + 09d3 5500 subr $ACC1, $AX0.H + 09d4 0a01 lris $AX0.H, #0x01 + 09d5 00fa 0405 sr @0x0405, $AX0.H + 09d7 029f 09ab jmp 0x09ab + } + 09d9 1f5f mrr $AX0.H, $AC1.M - 09da 02bf 0a0a call 0x0a0a // Load more samples. + // 09da 02bf 0a0a call 0x0a0a // Load more samples. + 0a0a_ReadFromAccelerator8To16(OutBuffer($AR3), Count($AX0.H)); + // Stash AX0.H away, it gets read again at 09ef. 09dc 00fa 0362 sr @0x0362, $AX0.H + 09de 8100 clr $ACC0 09df 263a lrs $AC0.M, @0x003a 09e0 243b lrs $AC0.L, @0x003b @@ -3376,10 +3401,10 @@ void Decoder0x08() { 09ef 7000 addaxl $ACC0, $AX0.L 09f0 2c39 srs @0x0039, $AC0.L 09f1 2e38 srs @0x0038, $AC0.M - 09f2 0092 00ff lri $CR, #0x00ff - + + // 09f2 0092 00ff lri $CR, #0x00ff // 09f4 029f 02d0 jmp 0x02d0 - GOTO MixFrom_0580_to_0520: + GOTO Resample_From0580To0520: } @@ -3390,7 +3415,7 @@ void Unreachable() { 09f8 2e35 srs @0x0035, $AC0.M } -void 09f9_UsedBy08Decoder() { +void 09f9_UpdateSampleCounters8() { 09f9 2334 lrs $AX1.H, @0x0034 09fa 2135 lrs $AX1.L, @0x0035 09fb 268a lrs $AC0.M, @0xff8a @@ -3410,43 +3435,55 @@ void 09f9_UsedBy08Decoder() { // 0a09 02df ret } -void 0a0a_UsedBy08Decoder() { +void 0a0a_ReadFromAccelerator8To16(OutBuffer($AR3), Count($AX0.H)) { // Read from ARAM. Convert 8-bit samples to 16-bit. - 0a0a 0080 ffd3 lri $AR0, #0xffd3 - 0a0c 0084 0000 lri $IX0, #0x0000 - 0a0e 007a 0a12 bloop $AX0.H, 0x0a12 - 0a10 199e lrrn $AC0.M, @$AR0 - 0a11 1488 asl $ACC0, #8 - 0a12 1b7e srri @$AR3, $AC0.M + // 0a0a 0080 ffd3 lri $AR0, #0xffd3 + // 0a0c 0084 0000 lri $IX0, #0x0000 + // 0a0e 007a 0a12 bloop $AX0.H, 0x0a12 + // 0a10 199e lrrn $AC0.M, @$AR0 + // 0a11 1488 asl $ACC0, #8 + // 0a12 1b7e srri @$AR3, $AC0.M // 0a13 02df ret + for (int i = 0; i < $AX0.H; i++) { + *($AR3++) = (*0xffd3) << 8; // ffd3 is the non-adpcm alternative read address for the accelerator. + } } //////////////////////////////////////////// 0x10 DECODER +// Hardcoded destination 0x0580. // This should be the easiest decoder to decipher in full -- except the really // trivial ones like the synths. -void Decoder_0x10() { - 0a14 0092 0004 lri $CR, #0x0004 +// It's almost identical to Decoder0x08 +void Decoder0x10() { + // 0a14 0092 0004 lri $CR, #0x0004 0a16 2002 lrs $AX0.L, @0x0002 0a17 8100 clr $ACC0 0a18 8900 clr $ACC1 - 0a19 2430 lrs $AC0.L, @0x0030 + // 0a19 2430 lrs $AC0.L, @0x0030 0a1a 8d00 set15 - 0a1b 0950 lris $AX1.L, #0x50 - 0a1c a000 mulx $AX0.L, $AX1.L - 0a1d a400 mulxac $AX0.L, $AX1.L, $ACC0 - 0a1e 1404 lsl $ACC0, #4 - 0a1f 8c00 clr15 + + // 0a1b 0950 lris $AX1.L, #0x50 + // 0a1c a000 mulx $AX0.L, $AX1.L + // 0a1d a400 mulxac $AX0.L, $AX1.L, $ACC0 + // 0a1e 1404 lsl $ACC0, #4 + // 0a1f 8c00 clr15 + + // Compute how much data we need to read, to get 0x50 samples after resampling. + // AC0.L is cursamplefrace, AX0.L is ratio. + $ACC0 = PB.CurrentSampleFrac + 0x50 * PB.Ratio; + 0a20 1ffe mrr $AC1.M, $AC0.M 0a21 0083 0580 lri $AR3, #0x0580 0a23 2201 lrs $AX0.H, @0x0001 0a24 8600 tstaxh $AX0.H - 0a25 0294 0a36 jnz 0x0a36 + 0a25 0294 0a36 jnz 0x0a36 /// Jump! See jump destination below. 0a27 2204 lrs $AX0.H, @0x0004 0a28 8600 tstaxh $AX0.H 0a29 02b4 0a7f callne 0x0a7f - if (*0x0404) { + if (*0x0404) // "NeedsReset" + { 0a7f_UpdateSampleCounters10() } @@ -3463,13 +3500,13 @@ void Decoder_0x10() { 0a32 2281 lrs $AX0.H, @0xff81 0a33 8600 tstaxh $AX0.H 0a34 0294 0a3d jnz 0x0a3d - if (!*401) { + if (!*401) { //// <<<<<<<<<<<< Jump destination 0a36 8100 clr $ACC0 0a37 005f loop $AC1.M 0a38 1b7e srri @$AR3, $AC0.M 0a39 7400 incm $AC0.M 0a3a 2e01 srs @0x0001, $AC0.M - 0a3b 029f 0a78 jmp 0x0a78 + 0a3b 029f 0a78 jmp 0x0a78 // quit } else { // Copy [88,89] to [34,35] 0a3d 2688 lrs $AC0.M, @0xff88 @@ -3485,8 +3522,8 @@ void Decoder_0x10() { 0a43 00ff 0360 sr @0x0360, $AC1.M 0a45 2638 lrs $AC0.M, @0x0038 0a46 2439 lrs $AC0.L, @0x0039 - 0a47 0f06 lris $AC1.M, #0x06 - 0a48 02bf 05ad call 0x05ad + 0a47 0f06 lris $AC1.M, #0x06 // Sample format 6 + // 0a48 02bf 05ad call 0x05ad 05ad_SetupAccelerator(AC0.M, AC0.L, AC1.M) 0a4a 00df 0360 lr $AC1.M, @0x0360 @@ -3500,7 +3537,8 @@ void Decoder_0x10() { 0a53 0290 0a5e jns 0x0a5e if (0x43b <= ACC1) { // not sure, but .. not enough samples? 0a55 223b lrs $AX0.H, @0x003b - 0a56 02bf 0a91 call 0x0a91 // Read more samples + // 0a56 02bf 0a91 call 0x0a91 // Read more samples + 0a91_ReadFromAccelerator(OutBuffer($AR3), Count($AX0.H)); 0a58 5500 subr $ACC1, $AX0.H 0a59 0a01 lris $AX0.H, #0x01 0a5a 00fa 0405 sr @0x0405, $AX0.H @@ -3509,8 +3547,12 @@ void Decoder_0x10() { } 0a5e 1f5f mrr $AX0.H, $AC1.M - 0a5f 02bf 0a91 call 0x0a91 // Read even more samples? + // 0a5f 02bf 0a91 call 0x0a91 // Read more samples + 0a91_ReadFromAccelerator(OutBuffer($AR3), Count($AX0.H)) + + // Stash AX0.H away, it gets read again at 0a72. 0a61 00fa 0362 sr @0x0362, $AX0.H + 0a63 8100 clr $ACC0 0a64 263a lrs $AC0.M, @0x003a 0a65 243b lrs $AC0.L, @0x003b @@ -3530,18 +3572,19 @@ void Decoder_0x10() { 0a75 7000 addaxl $ACC0, $AX0.L 0a76 2c39 srs @0x0039, $AC0.L 0a77 2e38 srs @0x0038, $AC0.M - 0a78 0092 00ff lri $CR, #0x00ff + + // 0a78 0092 00ff lri $CR, #0x00ff // 0a7a 029f 02d0 jmp 0x02d0 - GOTO MixFrom_0580_to_0520: + GOTO Resample_From0580To0520: } -void 0a7c_Unk() { +void 0a7c_UnkUnused() { 0a7c 8100 clr $ACC0 0a7d 2e34 srs @0x0034, $AC0.M 0a7e 2e35 srs @0x0035, $AC0.M // used by 0x10 decoder -void 0a7f_UpdateSampleCounters() { +void 0a7f_UpdateSampleCounters10() { 0a7f 2334 lrs $AX1.H, @0x0034 0a80 2135 lrs $AX1.L, @0x0035 0a81 268a lrs $AC0.M, @0xff8a @@ -3551,7 +3594,7 @@ void 0a7f_UpdateSampleCounters() { 0a85 2c3b srs @0x003b, $AC0.L 0a86 2634 lrs $AC0.M, @0x0034 0a87 2435 lrs $AC0.L, @0x0035 - 0a88 1401 lsl $ACC0, #1 + 0a88 1401 lsl $ACC0, #1 // This shift is not done in UpdateSampleCounters8. 0a89 238c lrs $AX1.H, @0xff8c 0a8a 218d lrs $AX1.L, @0xff8d 0a8b 4a00 addax $ACC0, $AX1 // Add [34,35]<<1 to [8c, 8d] @@ -3563,17 +3606,22 @@ void 0a7f_UpdateSampleCounters() { } -// Could this be the thing that pulls samples from the accelerator? -void 0a91_Unk() { - 0a91 0080 ffd3 lri $AR0, #0xffd3 - 0a93 0084 0000 lri $IX0, #0x0000 - 0a95 007a 0a98 bloop $AX0.H, 0x0a98 - 0a97 199e lrrn $AC0.M, @$AR0 - 0a98 1b7e srri @$AR3, $AC0.M - 0a99 02df ret +// Read AX0.H samples from the accelerator. +void 0a91_ReadFromAccelerator(OutBuffer($AR3), Count($AX0.H)) { + // 0a91 0080 ffd3 lri $AR0, #0xffd3 + // 0a93 0084 0000 lri $IX0, #0x0000 + // 0a95 007a 0a98 bloop $AX0.H, 0x0a98 + // 0a97 199e lrrn $AC0.M, @$AR0 + // 0a98 1b7e srri @$AR3, $AC0.M + // 0a99 02df ret + + for (int i = 0; i < $AX0.H; i++) { + *($AR3++) = *0xffd3; // ffd3 is the non-adpcm alternative read address for the accelerator. + } } //////////////////////////////////////////// 0x20 DECODER +// Same as 0x21 but with no resampling. { // 0a9a 8900 clr $ACC1 // 0a9b 0f50 lris $AC1.M, #0x50 @@ -3611,13 +3659,14 @@ void 0aa2_Decoder0x21() { // 0aad 0083 0580 lri $AR3, #0x0580 // 0aaf 02bf 0ab3 call 0x0ab3 // 0ab3_Decoder0x21Core 0ab3_Decoder0x21Core(AC1.M, AR3=#0x0580); + // 0ab1 029f 02d0 jmp 0x02d0 - GOTO MixFrom_0580_to_0520: + GOTO Resample_From0580To0520: } // 0x21 Decoder Core -// I get the feeling that decoder 0x21 simply streams raw audio -// by using DMA. Lots of buffer wrap trickery etc but no actual decoding. +// Decoder 0x21 simply streams raw audio from RAM (not ARAM!) by using DMA. +// Lots of buffer wrap trickery etc but no actual decoding. void 0ab3_Decoder0x21Core(AC1.M, AR3) { // 0ab3 0092 0004 lri $CR, #0x0004 // 0ab5 8100 clr $ACC0 @@ -3729,7 +3778,6 @@ void 0ab3_Decoder0x21Core(AC1.M, AR3) { AR0 = (ACC0 & 0xFFFF0000) >> 16; ACC0 = 0; *0x0434 = 0; - // 0ae7 2688 lrs $AC0.M, @0xff88 // 0x0488 // 0ae8 2489 lrs $AC0.L, @0xff89 // 0x0489 @@ -3753,12 +3801,12 @@ void 0ab3_Decoder0x21Core(AC1.M, AR3) { AR0 = AX0.L; 0af6_Decoder0x21_MoreStuff(AR0=AX0.L, AR3); - 0af3 0092 00ff lri $CR, #0x00ff // 0af5 02df ret } + // CR = 0x4 // Does strange stuff with PB[0x34] and the address PB[0x8c,d] // Does not touch AX0.L @@ -4533,7 +4581,7 @@ void 0cd3_VolumeMixer1() // 0d4d 00e1 0b24 sr @0x0b24, $AR1 // 0d4f 00e2 0b25 sr @0x0b25, $AR2 - // 0d51 021b ilrri $AC0.M, @$AR3 // Buffer address table lookup (see above) + // 0d51 021b ilrri $AC0.M, @$AR3 // Buffer address table lookup (see below) // 0d52 00e3 0b26 sr @0x0b26, $AR3 (Stash AR1, AR2, AR3) // 0d54 1c7e mrr $AR3, $AC0.M @@ -4600,39 +4648,60 @@ short table = {0x0d00, 0x0d60, 0x0f40, 0x0ca0, 0x0e80, 0x0ee0, 0x0c00, 0x0c50}; 0d7d 0c00 0d7e 0c50 -void 0d7f_Unk_MaybeResample(_src($AR0), _dest($AR1), param(AX1.L) = 0, _option??) +void 0d7f_ResampleAudioData(_src($AR0), _dest($AR1), param(AX1.L) = 0, _option??) { 0d7f 00f9 0361 sr @0x0361, $AX1.L // always 0 - 0d81 1fc0 mrr $AC0.M, $AR0 - 0d82 0200 fffc addi $AC0.M, #0xfffc - 0d84 1c1e mrr $AR0, $AC0.M - 0d85 1c5e mrr $AR2, $AC0.M + // 0d81 1fc0 mrr $AC0.M, $AR0 + // 0d82 0200 fffc addi $AC0.M, #0xfffc + // 0d84 1c1e mrr $AR0, $AC0.M + // 0d85 1c5e mrr $AR2, $AC0.M + + // We read a little bit BEFORE the input. The next piece of code takes care of that... + $AR0 = $AR0 - 4; + $AR2 = $AR0; + + // 0x043c in the PBs apparently is a pointer, INTO the PB itself - where it + // has stored the data from the last frame. 0d86 0083 043c lri $AR3, #0x043c - 0d88 197e lrri $AC0.M, @$AR3 - 0d89 197f lrri $AC1.M, @$AR3 - 0d8a 80a2 nx'sl : $AC0.M, $AX0.H - 0d8b 64a3 movr'sl $ACC0, $AX0.H : $AC1.M, $AX0.H - 0d8c 6530 movr's $ACC1, $AX0.H : @$AR0, $AC0.M - 0d8d 1b1f srri @$AR0, $AC1.M - 0d8e 1c02 mrr $AR0, $AR2 + + // Pipelined tiny memcpy - first four are loads, last four are stores. middle two overlap. + // 0d88 197e lrri $AC0.M, @$AR3 + // 0d89 197f lrri $AC1.M, @$AR3 + // 0d8a 80a2 nx'sl : $AC0.M, $AX0.H + // 0d8b 64a3 movr'sl $ACC0, $AX0.H : $AC1.M, $AX0.H + // 0d8c 6530 movr's $ACC1, $AX0.H : @$AR0, $AC0.M + // 0d8d 1b1f srri @$AR0, $AC1.M + for (int i = 0; i < 4; i++) + *($AR0++) = *($AR3++); + + // Point $AR0 back at 4 words before the start of the in buffer. + // 0d8e 1c02 mrr $AR0, $AR2 + 0d8f 8100 clr $ACC0 - 0d90 00de 0402 lr $AC0.M, @0x0402 // Ratio int - 0d92 00fe 0362 sr @0x0362, $AC0.M - 0d94 1474 lsr $ACC0, #-12 - 0d95 1f7e mrr $AX1.H, $AC0.M - 0d96 1f3c mrr $AX1.L, $AC0.L + // 0d90 00de 0402 lr $AC0.M, @0x0402 // Ratio int + // 0d92 00fe 0362 sr @0x0362, $AC0.M + // 0d94 1474 lsr $ACC0, #-12 + // 0d95 1f7e mrr $AX1.H, $AC0.M + // 0d96 1f3c mrr $AX1.L, $AC0.L + *0x0362 = PB.Ratio; + $AX1 = PB.Ratio << 4; + 0d97 8900 clr $ACC1 - 0d98 00dd 0430 lr $AC1.L, @0x0430 // Ratio frac + 0d98 00dd 0430 lr $AC1.L, @0x0430 // Sample position frac 0d9a 1504 lsl $ACC1, #4 + + // $ACC0 here still contains ratio << 12; 0d9b 0604 cmpis $ACC0, #0x04 // 0d9c 0290 0df3 jns 0x0df3 // subroutine - GOTONS subroutine; + + // If ratio too low, don't bother resampling? + GOTONS JustCopyWithoutResampling; 0d9e 1fdd mrr $AC0.M, $AC1.L 0d9f 0082 02b0 lri $AR2, #0x02b0 - // Store a ramp? + // Store a ramp at 0x2b0? Lookup table for read addresses? 0da1 1050 loopi #0x50 0da2 4b2a addax's $ACC1, $AX1 : @$AR2, $AC1.L @@ -4640,13 +4709,17 @@ void 0d7f_Unk_MaybeResample(_src($AR0), _dest($AR1), param(AX1.L) = 0, _option?? 0da4 00fe 0360 sr @0x0360, $AC0.M 0da6 8900 clr $ACC1 0da7 1fbe mrr $AC1.L, $AC0.M + 0da8 0af8 lris $AX0.H, #0xf8 0da9 009b 00fc lri $AX1.H, #0x00fc 0dab 00d8 0361 lr $AX0.L, @0x0361 // parameter was stashed here. - + + // 0x02b0 is where the ramp from above is stored. 0dad 0082 02b0 lri $AR2, #0x02b0 0daf 0083 02b0 lri $AR3, #0x02b0 0db1 195e lrri $AC0.M, @$AR2 + + // I really don't understand what the purpose of this loop is. 0db2 3480 andr'ls $AC0.M, $AX0.H : $AX0.L, $AC0.M // 0db3 1128 0db8 bloopi #0x28, 0x0db8 for (int i = 0; i < 0x50; i += 2) { @@ -4655,8 +4728,12 @@ void 0d7f_Unk_MaybeResample(_src($AR0), _dest($AR1), param(AX1.L) = 0, _option?? 0db7 3772 andr'l $AC1.M, $AX1.H : $AC0.M, @$AR2 0db8 34bb andr'slm $AC0.M, $AX0.H : $AC1.M, $AX1.H } - 0db9 8a00 m2 + + 0db9 8a00 m2 // All muls doubled. + + // 0x02b0 is where the ramp from above is stored. 0dba 0082 02b0 lri $AR2, #0x02b0 + 0dbc 00dd 0430 lr $AC1.L, @0x0430 0dbe 1504 lsl $ACC1, #4 0dbf 1fe0 mrr $AC1.M, $AR0 @@ -4665,7 +4742,13 @@ void 0d7f_Unk_MaybeResample(_src($AR0), _dest($AR1), param(AX1.L) = 0, _option?? 0dc3 1474 lsr $ACC0, #-12 0dc4 1f7e mrr $AX1.H, $AC0.M 0dc5 1f3c mrr $AX1.L, $AC0.L - 0dc6 8f00 set40 + + // Resample with some nice filter of some sort, using unreadable + // pipelined DSP code... gah. + + 0dc6 8f00 set40 // Loaded ACx.M values extend to the entire ACC. Don't see any actual use though. + + // Yep, this pretty much confirms that 0x02b0 is precomputed read addresses. 0dc7 1943 lrri $AR3, @$AR2 0dc8 4bc3 addax'ld $ACC1, $AX1 : $AX0.L, $AX1.L, @$AR3 0dc9 90c3 mul'ld $AX0.L, $AX0.H : $AX0.L, $AX1.L, @$AR3 @@ -4678,6 +4761,8 @@ void 0d7f_Unk_MaybeResample(_src($AR0), _dest($AR1), param(AX1.L) = 0, _option?? 0dd0 4bc3 addax'ld $ACC1, $AX1 : $AX0.L, $AX1.L, @$AR3 0dd1 90c3 mul'ld $AX0.L, $AX0.H : $AX0.L, $AX1.L, @$AR3 // 0dd2 114e 0dda bloopi #0x4e, 0x0dda + // Count the stores - 0x4e stores in the main loop, two more afterwards. + // Deeply pipelined. for (int i = 0; i < 0x4e; i++) { 0dd4 f2c3 madd'ld $AX0.L, $AX0.H : $AX0.L, $AX1.L, @$AR3 0dd5 f2c3 madd'ld $AX0.L, $AX0.H : $AX0.L, $AX1.L, @$AR3 @@ -4692,15 +4777,20 @@ void 0d7f_Unk_MaybeResample(_src($AR0), _dest($AR1), param(AX1.L) = 0, _option?? 0ddd f231 madd's $AX0.L, $AX0.H : @$AR1, $AC0.M 0dde fe00 movpz $ACC0 0ddf 1b3e srri @$AR1, $AC0.M - 0de0 8b00 m0 - 0de1 8e00 set16 -back_from_subroutine: + // Things back to normal. + // 0de0 8b00 m0 + // 0de1 8e00 set16 + +back_from_JustCopyWithoutResampling: 0de2 00fe 0433 sr @0x0433, $AC0.M 0de4 1c1f mrr $AR0, $AC1.M 0de5 150c lsl $ACC1, #12 0de6 0340 0fff andi $AC1.M, #0x0fff 0de8 00ff 0430 sr @0x0430, $AC1.M + + // Store the last 4 samples or something undecoded + // back into the PB. 0dea 0083 043c lri $AR3, #0x043c 0dec 191e lrri $AC0.M, @$AR0 0ded 191f lrri $AC1.M, @$AR0 @@ -4711,19 +4801,25 @@ back_from_subroutine: // 0df2 02df ret return; -subroutine: - 0df3 1fe0 mrr $AC1.M, $AR0 - 0df4 1c1f mrr $AR0, $AC1.M +JustCopyWithoutResampling: + // 0df3 1fe0 mrr $AC1.M, $AR0 + // 0df4 1c1f mrr $AR0, $AC1.M // This instruction looks very pointless. - // add two buffers? - 0df5 1128 0dfc bloopi #0x28, 0x0dfc - 0df7 4b70 addax'l $ACC1, $AX1 : $AC0.M, @$AR0 - 0df8 1b3e srri @$AR1, $AC0.M - 0df9 1c1f mrr $AR0, $AC1.M - 0dfa 4b70 addax'l $ACC1, $AX1 : $AC0.M, @$AR0 - 0dfb 1b3e srri @$AR1, $AC0.M - 0dfc 1c1f mrr $AR0, $AC1.M - + // 0df5 1128 0dfc bloopi #0x28, 0x0dfc + // 0df7 4b70 addax'l $ACC1, $AX1 : $AC0.M, @$AR0 + // 0df8 1b3e srri @$AR1, $AC0.M + // 0df9 1c1f mrr $AR0, $AC1.M + // 0dfa 4b70 addax'l $ACC1, $AX1 : $AC0.M, @$AR0 + // 0dfb 1b3e srri @$AR1, $AC0.M + // 0dfc 1c1f mrr $AR0, $AC1.M + for (int i = 0; i < 0x50; i++) { + $ACC1 += $AX1; // This is to still advance the playback position. + $AC0.M = *($AR0++); + *($AR1++) = $AC0.M; + $AR0 = $AC1.M; // Undo the increment + } + + // Looks like $AR0 stays unchanged, while $AR1 gets incremented by 0x50. 0dfd 029f 0de2 jmp 0x0de2 }