Emulator Issues #12062
closedPossible DSP instruction ADDPAXZ bug
0%
Description
Game Name?
Any game which uses AX Ucode (for example Bust-a-Move 3000). I will not fill in further since other information does not apply to the problem.
I reversed the AX mixer procedure (huge procedure called by Command 0x03 handler) and found that the ADDPAXZ instruction does not work as it is guessed by context.
At the very end of the mixer is a small code from a series of ADDPAXZ instructions that increment pointers of current Sample Buffers.
Original disassembled code, according to the Duddie document and the current implementation of ADDPAXZ in Dolphin:
0457 00 83 0E 08 lri ar3, #0x0E08
0459 1C 03 mrr ar0, ar3
045A 1F F5 mrr ac1.m, prod.m1
045B 19 1A lrri ax1.l, @ar0
045C F8 58 addpaxz ac0, ax0 l ax1.h, @ar0
045D FB A0 addpaxz ac1, ax1 ls ax1.l, ac0.m
045E F8 B1 addpaxz ac0, ax0 ls ax1.h, ac1.m
045F FB A0 addpaxz ac1, ax1 ls ax1.l, ac0.m
0460 F8 B1 addpaxz ac0, ax0 ls ax1.h, ac1.m
0461 FB A0 addpaxz ac1, ax1 ls ax1.l, ac0.m
0462 F8 B1 addpaxz ac0, ax0 ls ax1.h, ac1.m
0463 FB A0 addpaxz ac1, ax1 ls ax1.l, ac0.m
0464 F8 3B addpaxz ac0, ax0 s @ar3, ac1.m
0465 1B 7E srri @ar3, ac0.m
If you try to decompile it, then it will do absolutely not what it intended.
But if you fix the ADDPAXZ decoding as follows:
ADDPAXZ * 1111 10sd xxxx xxxx // ADDPAXZ $acD, $ax1.[l|h]
That disassembled code will look like this:
045B 19 1A lrri ax1.l, @ar0
045C F8 58 addpaxz ac0, ax1.l l ax1.h, @ar0
045D FB A0 addpaxz ac1, ax1.h ls ax1.l, ac0.m
045E F8 B1 addpaxz ac0, ax1.l ls ax1.h, ac1.m
045F FB A0 addpaxz ac1, ax1.h ls ax1.l, ac0.m
0460 F8 B1 addpaxz ac0, ax1.l ls ax1.h, ac1.m
0461 FB A0 addpaxz ac1, ax1.h ls ax1.l, ac0.m
0462 F8 B1 addpaxz ac0, ax1.l ls ax1.h, ac1.m
0463 FB A0 addpaxz ac1, ax1.h ls ax1.l, ac0.m
0464 F8 3B addpaxz ac0, ax1.l s @ar3, ac1.m
0465 1B 7E srri @ar3, ac0.m
And if you translate this into c, now it works as intended:
AdvanceSampleBufPtr() // 0459
{
ar3 = 0xE08;
ar0 = ar3;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
*ar3++ = *ar0++ + 0x40;
}