The SPU regs are apparently accessed as both volatile and nonvolatile,
couldn't find a different solution.
This commit is contained in:
sozud 2024-02-19 11:15:39 -08:00 committed by GitHub
parent d6dd9f1891
commit 437856d545
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 168 additions and 32 deletions

View File

@ -3,6 +3,8 @@
#include "psxsdk/libspu.h"
#define NUM_SPU_CHANNELS 24
void InterruptCallback(s32, s32);
void _SpuInit(s32);
s32 _spu_read(s32 arg0, s32 arg1);
@ -28,16 +30,16 @@ extern void (* volatile _spu_transferCallback)();
extern s32 _spu_inTransfer;
void _SpuCallback(s32 arg0);
extern void (*_spu_IRQCallback)();
extern void (* volatile _spu_IRQCallback)();
void SpuSetAnyVoice(s32, s32, u16, u16);
s32 SpuSetAnyVoice(s32 on_off, u32 bits, s32 addr1, s32 addr2);
s32 _spu_t(s32, ...);
s32 _spu_writeByIO(s32, s32);
extern s32 _spu_transMode;
extern u16 _spu_tsa;
u16 _spu_FsetRXXa(s32, s32);
u32 _spu_FsetRXXa(s32 arg0, u32 arg1);
s32 _spu_write(u32, u32);
extern s32 _spu_inTransfer;
@ -93,24 +95,24 @@ typedef struct tagSpuControl {
SpuVolume main_vol; // 180
SpuVolume rev_vol; // 184
// bit flags
volatile u16 key_on[2]; // 188
u16 key_off[2]; // 18C
u16 chan_fm[2]; // 190
u16 noise_mode[2]; // 194
u16 rev_mode[2]; // 198
u32 chan_on; // 19C
u16 unk; // 1A0
u16 rev_work_addr; // 1A2
u16 irq_addr; // 1A4
volatile u16 trans_addr; // 1A6
u16 trans_fifo; // 1A8
u16 spucnt; // 1AA SPUCNT
u16 data_trans; // 1AC
u16 spustat; // 1AE SPUSTAT
SpuVolume cd_vol; // 1B0
SpuVolume ex_vol; // 1B4
SpuVolume main_volx; // 1B8
SpuVolume unk_vol; // 1BC
u16 key_on[2]; // 188
u16 key_off[2]; // 18C
u16 chan_fm[2]; // 190
u16 noise_mode[2]; // 194
u16 rev_mode[2]; // 198
u32 chan_on; // 19C
u16 unk; // 1A0
u16 rev_work_addr; // 1A2
u16 irq_addr; // 1A4
u16 trans_addr; // 1A6
u16 trans_fifo; // 1A8
u16 spucnt; // 1AA SPUCNT
u16 data_trans; // 1AC
u16 spustat; // 1AE SPUSTAT
SpuVolume cd_vol; // 1B0
SpuVolume ex_vol; // 1B4
SpuVolume main_volx; // 1B8
SpuVolume unk_vol; // 1BC
u16 dAPF1; // Starting at 0x1F801DC0
u16 dAPF2;
@ -147,7 +149,8 @@ typedef struct tagSpuControl {
} SPU_RXX;
union SpuUnion {
SPU_RXX rxx;
SPU_RXX rxxnv;
volatile SPU_RXX rxx;
volatile u16 raw[0x100];
};

View File

@ -1,3 +1,28 @@
#include "common.h"
#include "libspu_internal.h"
INCLUDE_ASM("main/nonmatchings/psxsdk/libspu/s_sav", SpuSetAnyVoice);
s32 SpuSetAnyVoice(s32 on_off, u32 bits, s32 addr1, s32 addr2) {
s32 var_t0;
u16 var_v1;
u16* temp_a2;
u16* temp_a3;
u16 temp;
temp_a3 = &_spu_RXX->raw[addr2];
temp_a2 = &_spu_RXX->raw[addr1];
var_t0 = *temp_a2 | ((_spu_RXX->raw[addr2] & 0xff) << 0x10);
if (on_off != 0) {
if (on_off == 1) {
var_t0 |= bits & 0xFFFFFF;
*temp_a2 |= bits;
var_v1 = *temp_a3 | ((bits >> 0x10) & 0xFF);
*temp_a3 = var_v1;
}
} else {
var_t0 &= ~(bits & 0xFFFFFF);
*temp_a2 &= ~bits;
var_v1 = *temp_a3 & ~((bits >> 0x10) & 0xFF);
*temp_a3 = var_v1;
}
return var_t0 & 0xFFFFFF;
}

View File

@ -7,23 +7,23 @@ s32 SpuSetReverb(s32 on_off) {
switch (on_off) {
case 0:
_spu_rev_flag = 0;
var_v1 = _spu_RXX->rxx.spucnt;
var_v1 = _spu_RXX->rxxnv.spucnt;
var_v1 = var_v1 & 0xFF7F;
_spu_RXX->rxx.spucnt = var_v1;
_spu_RXX->rxxnv.spucnt = var_v1;
break;
case 1:
if ((_spu_rev_reserve_wa != on_off) &&
(_SpuIsInAllocateArea_(_spu_rev_offsetaddr) != 0)) {
_spu_rev_flag = 0;
var_v1 = _spu_RXX->rxx.spucnt;
var_v1 = _spu_RXX->rxxnv.spucnt;
var_v1 = var_v1 & 0xFF7F;
new_var = var_v1;
_spu_RXX->rxx.spucnt = new_var;
_spu_RXX->rxxnv.spucnt = new_var;
} else {
_spu_rev_flag = on_off;
var_v1 = (new_var = _spu_RXX->rxx.spucnt) | 0x80;
_spu_RXX->rxx.spucnt = var_v1;
var_v1 = (new_var = _spu_RXX->rxxnv.spucnt) | 0x80;
_spu_RXX->rxxnv.spucnt = var_v1;
}
break;
}

View File

@ -21,7 +21,95 @@ s32 _spu_reset(void) {
return 0;
}
INCLUDE_ASM("main/nonmatchings/psxsdk/libspu/spu", _spu_init);
extern s32 D_80010CEC;
extern s32 D_800334FC;
extern s32* D_80033514;
extern s32 D_80033540;
extern s32 _spu_addrMode;
extern s32 _spu_mem_mode;
extern s32 _spu_mem_mode_unit;
extern s32 _spu_mem_mode_unitM;
extern s32 aWaitReset;
s32 _spu_init(s32 arg0) {
volatile s32 sp0;
volatile s32 sp4;
s32 wait_count;
s32 channel;
s16 temp;
*D_80033514 |= 0xB0000;
_spu_RXX->rxx.main_vol.left = 0;
_spu_RXX->rxx.main_vol.right = 0;
_spu_RXX->rxx.spucnt = 0;
_spu_transMode = 0;
_spu_addrMode = 0;
_spu_tsa = 0;
WASTE_TIME();
_spu_RXX->rxx.main_vol.left = 0;
_spu_RXX->rxx.main_vol.right = 0;
D_800334FC = 0;
if (_spu_RXX->rxx.spustat & 0x7FF) {
do {
wait_count = D_800334FC + 1;
D_800334FC = wait_count;
if (wait_count > 5000) {
printf(&D_80010CEC, &aWaitReset);
break;
}
} while (_spu_RXX->rxx.spustat & 0x7FF);
}
_spu_mem_mode = 2;
_spu_mem_mode_plus = 3;
_spu_mem_mode_unit = 8;
_spu_mem_mode_unitM = 7;
_spu_RXX->rxx.data_trans = 4;
_spu_RXX->rxx.rev_vol.left = 0;
_spu_RXX->rxx.rev_vol.right = 0;
_spu_RXX->rxx.key_off[0] = 0xFFFF;
_spu_RXX->rxx.key_off[1] = 0xFFFF;
_spu_RXX->rxx.rev_mode[0] = 0;
_spu_RXX->rxx.rev_mode[1] = 0;
if (arg0 == 0) {
_spu_RXX->rxx.chan_fm[0] = 0;
_spu_RXX->rxx.chan_fm[1] = 0;
_spu_RXX->rxx.noise_mode[0] = 0;
_spu_RXX->rxx.noise_mode[1] = 0;
_spu_RXX->rxx.cd_vol.left = 0;
_spu_RXX->rxx.cd_vol.right = 0;
_spu_RXX->rxx.ex_vol.left = 0;
_spu_RXX->rxx.ex_vol.right = 0;
_spu_tsa = 0x200;
_spu_writeByIO((s32)&D_80033540, 0x10);
for (channel = 0; channel < NUM_SPU_CHANNELS; channel++) {
_spu_RXX->raw[channel * 8 + 0] = 0; /* left volume */
_spu_RXX->raw[channel * 8 + 1] = 0; /* right volume */
_spu_RXX->raw[channel * 8 + 2] = 0x3fff; /* pitch */
_spu_RXX->raw[channel * 8 + 3] = 0x200; /* addr */
_spu_RXX->raw[channel * 8 + 4] = 0; /* adsr1 */
_spu_RXX->raw[channel * 8 + 5] = 0; /* adsr2 */
}
temp = _spu_RXX->rxx.key_on[0];
_spu_RXX->rxx.key_on[0] = 0xFFFF;
_spu_RXX->rxx.key_on[1] |= 0xFF;
WASTE_TIME();
WASTE_TIME();
WASTE_TIME();
WASTE_TIME();
temp = _spu_RXX->rxx.key_off[0];
_spu_RXX->rxx.key_off[0] = 0xFFFF;
_spu_RXX->rxx.key_off[1] |= 0xFF;
WASTE_TIME();
WASTE_TIME();
WASTE_TIME();
WASTE_TIME();
}
_spu_inTransfer = 1;
_spu_RXX->rxx.spucnt = 0xC000;
_spu_transferCallback = NULL;
_spu_IRQCallback = NULL;
return 0;
}
INCLUDE_ASM("main/nonmatchings/psxsdk/libspu/spu", _spu_writeByIO);
@ -110,7 +198,27 @@ void _spu_FsetRXX(s32 arg0, u32 arg1, s32 arg2) {
_spu_RXX->raw[arg0] = (arg1 >> _spu_mem_mode_plus);
}
INCLUDE_ASM("main/nonmatchings/psxsdk/libspu/spu", _spu_FsetRXXa);
u32 _spu_FsetRXXa(s32 arg0, u32 arg1) {
u32 temp_a3;
u32 var_a1;
var_a1 = arg1;
if ((_spu_mem_mode != 0) && ((var_a1 % _spu_mem_mode_unit) != 0)) {
var_a1 += _spu_mem_mode_unit;
var_a1 &= ~_spu_mem_mode_unitM;
}
temp_a3 = var_a1 >> _spu_mem_mode_plus;
switch (arg0) {
case -1:
return temp_a3 & 0xFFFF;
case -2:
return var_a1;
default:
_spu_RXX->raw[arg0] = temp_a3;
return var_a1;
}
}
u32 _spu_FgetRXXa(s32 arg0, s32 arg1) {
u16 temp = _spu_RXX->raw[arg0];

@ -1 +1 @@
Subproject commit c263a0436517e6aeb5d0fc434527295161838b8b
Subproject commit d19cddd9ed40e389e1e7c35e46fd5a768504a66f