SsVabOpenHeadWithMode Attempt (#1362)

This PR is trying to get SsVabOpenHeadWithMode running, but I'm getting
the wrong result vs. my test app. I'm putting this up to see if others
have ideas.
c7484b6800/test.c (L154)

I check a bunch of preconditions on the test app and the implementation
so I think they are starting from the same state. The test app is able
to play the library song so I think it's OK.

The problem is that SpuMalloc returns the wrong value. See
```
_svm_vab_start[vabId] = spuAllocMem;
```

_svm_vab_start[0] is supposed to be 0x00001010 but instead we get
0x11010.


c7484b6800/test.c (L201)

```
69648 != 4112 in check_ss_vab_open_head_with_mode /home/d/sotn-decomp-2/src/pc/psxsdk/emu.cpp:306
```

The scratch for SpuMalloc is https://decomp.me/scratch/UjIPd

The version here is based off this one since I think that scratch isn't
usable yet.
4ff48d4660/psx_seq_player/lib_spu.cpp (L2462)

The scratch for func_800286E0 is https://decomp.me/scratch/msP8t
This commit is contained in:
sozud 2024-07-01 11:23:21 -07:00 committed by GitHub
parent 574c61381f
commit e517944ab0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 634 additions and 31 deletions

View File

@ -271,10 +271,9 @@ segments:
start: 0x9B6A0
vram: 0x8013B6A0
subsegments:
- [0x0, raw, vb_0] # D_8013B6A0
- [0x41CB0, raw, vb_1] # D_8017D350
- [0x4FE40, raw, vb_2] # D_8018B4E0
- [0x5FA30]
- [0x6E5E0, raw, vb_3] # D_801A9C80
- [0x88BF0]
- [0x9B6A0, raw, vb_0] # D_8013B6A0
- [0xDD350, raw, vb_1] # D_8017D350
- [0xEB4E0, raw, vb_2] # D_8018B4E0 (len 108048)
- [0x105AF0]
- [0x109C80, raw, vb_3] # D_801A9C80 (len 64496)
- [0x119870]

View File

@ -697,8 +697,8 @@ extern s16 D_8013B678[];
extern s16 D_8013B698;
extern u8 D_8013B6A0[269488]; // VAB file
extern u8 D_8017D350[57744]; // VAB file
extern u8 D_8018B4E0[64496]; // VAB file
extern u8 D_801A9C80[108048]; // VAB file
extern u8 D_8018B4E0[108048]; // VAB file
extern u8 D_801A9C80[64496]; // VAB file
extern u16 D_8013AEE0;
extern s8 D_8013AEE8;
extern u8 g_SoundInitialized;

View File

@ -54,7 +54,6 @@ extern s32 _svm_vab_total[];
extern s32 _svm_vab_start[];
extern u8 _svm_vab_used[];
int SsVabOpenHeadWithMode(unsigned char* pAddr, int vabId, s32 pFn, long mode);
void SpuFree(s32);
extern u16 _svm_vab_count;
@ -246,7 +245,7 @@ typedef struct ProgAtr { /* Program Headdings */
unsigned char mpan; /* program pan */
char reserved0; /* system reserved */
short attr; /* program attribute */
unsigned long reserved1; // "fake" program index (skips empties)
u32 reserved1; // "fake" program index (skips empties)
unsigned short reserved2; // even vag spu ptr
unsigned short reserved3; // odd vag spu ptr
} ProgAtr; /* 16 byte */

View File

@ -1,6 +1,8 @@
#include "common.h"
#include "libsnd_i.h"
s16 SsVabOpenHeadWithMode(u8* addr, s16 vabid, s16 arg2, u32 sbaddr);
s16 SsVabOpenHead(u8* arg1, s16 vabid) {
return SsVabOpenHeadWithMode(arg1, vabid, 0, 0);
}
@ -13,4 +15,133 @@ s16 SsVabFakeHead(u8* addr, s16 vabid, u32 sbaddr) {
return SsVabOpenHeadWithMode(addr, vabid, 1, sbaddr);
}
INCLUDE_ASM("main/nonmatchings/psxsdk/libsnd/vs_vh", SsVabOpenHeadWithMode);
s16 SsVabOpenHeadWithMode(u8* addr, s16 vabid, s16 arg2, u32 sbaddr) {
int vagLens[256];
s32 i;
s32 var_s0;
s16 vabId_2;
u16 temp_v1;
u16* ptr_vag_off_table;
u32 magic;
u32 spuAllocMem;
u8 num_vags;
ProgAtr* pProgTable;
u8* var_a2;
VabHdr* vab_hdr_2;
vabId_2 = 0x10;
if (_spu_getInTransfer() == 1) {
return -1;
}
_spu_setInTransfer(1);
if (!(vabid < 0x10)) {
_spu_setInTransfer(0);
return -1;
}
if (vabid == (-1)) {
for (i = 0; i < 16; i++) {
if (_svm_vab_used[i] == 0) {
_svm_vab_used[i] = 1;
vabId_2 = i;
_svm_vab_count++;
break;
}
}
} else {
var_a2 = _svm_vab_used;
if (var_a2[vabid] == 0) {
_svm_vab_used[vabid] = 1;
vabId_2 = vabid;
_svm_vab_count++;
}
}
if (vabId_2 >= 0x10) {
_spu_setInTransfer(0);
return -1;
}
var_a2 = addr;
_svm_vab_vh[vabId_2] = var_a2;
var_a2 = var_a2 + 0x20;
vab_hdr_2 = addr;
magic = vab_hdr_2->form;
if ((magic >> 8) != 0x564142) {
_svm_vab_used[vabId_2] = 0;
_spu_setInTransfer(0);
_svm_vab_count -= 1;
return -1;
}
if ((magic & 0xFF) == 0x70) {
if (vab_hdr_2->ver >= 5) {
kMaxPrograms = 0x80;
} else {
kMaxPrograms = 0x40;
}
} else {
kMaxPrograms = 0x40;
}
if (vab_hdr_2->ps <= kMaxPrograms) {
_svm_vab_pg[vabId_2] = var_a2;
pProgTable = var_a2;
var_a2 = var_a2 + (kMaxPrograms * 0x10);
var_s0 = 0;
for (i = 0; i < kMaxPrograms; i++) {
pProgTable[i].reserved1 = var_s0;
if (pProgTable[i].tones != 0) {
var_s0++;
}
}
var_s0 = 0;
_svm_vab_tn[vabId_2] = var_a2;
ptr_vag_off_table = var_a2 + (vab_hdr_2->ps << 9);
num_vags = vab_hdr_2->vs;
for (i = 0; i < 256; i++) {
if (num_vags >= i) {
temp_v1 = *ptr_vag_off_table;
if (vab_hdr_2->ver >= 5) {
vagLens[i] = temp_v1 * 8;
} else {
vagLens[i] = temp_v1 * 4;
}
var_s0 += vagLens[i];
}
ptr_vag_off_table++;
}
_svm_brr_start_addr[vabId_2] = ptr_vag_off_table;
spuAllocMem = sbaddr;
if (arg2 == 0) {
spuAllocMem = SpuMalloc(var_s0);
if (spuAllocMem == -1) {
_svm_vab_used[vabId_2] = 0;
_spu_setInTransfer(0);
_svm_vab_count -= 1;
return -1;
}
}
if ((spuAllocMem + var_s0) > 0x80000U) {
end:
_svm_vab_used[vabId_2] = 0;
_spu_setInTransfer(0);
_svm_vab_count -= 1;
return -1;
}
_svm_vab_start[vabId_2] = spuAllocMem;
var_s0 = 0;
for (i = 0; i <= num_vags; i++) {
var_s0 += vagLens[i];
if (!(i & 1)) {
pProgTable[i / 2].reserved2 = (spuAllocMem + var_s0) >> 3;
} else {
pProgTable[i / 2].reserved3 = (spuAllocMem + var_s0) >> 3;
}
}
_svm_vab_total[vabId_2] = var_s0;
_svm_vab_used[vabId_2] = 2;
} else {
goto end;
}
return vabId_2;
}

View File

@ -40,7 +40,7 @@ extern s32 _spu_transMode;
extern u16 _spu_tsa;
u32 _spu_FsetRXXa(s32 arg0, u32 arg1);
s32 _spu_write(u32, u32);
s32 _spu_write(u8*, u32);
extern s32 _spu_inTransfer;
void _SpuSetVoiceAttr(SpuVoiceAttr* arg, s32, s32, s32);

View File

@ -347,7 +347,7 @@ void _spu_r_(s32 arg0, u16 arg1, s32 arg2) {
INCLUDE_ASM("main/nonmatchings/psxsdk/libspu/spu", _spu_t);
s32 _spu_write(u32 arg0, u32 arg1) {
s32 _spu_write(u8* arg0, u32 arg1) {
if (_spu_transMode != 0) {
_spu_writeByIO(arg0, arg1);

View File

@ -52,7 +52,7 @@ void CheckWrites(char* filename)
if(expected.size() != writes.size())
{
printf("warning expected size vs. writes size not the same %d vs. %d\n", expected.size(), writes.size());
printf("warning expected size vs. writes size not the same %d vs. %d %s\n", expected.size(), writes.size(), filename);
exit(1);
}
@ -79,21 +79,29 @@ void CheckWrites(char* filename)
printf("OK: %s\n", filename);
}
bool test_mode = false;
bool init = false;
extern "C" void MySsInitHot(void);
extern "C" void mednafen_init()
{
// MDFN_IEN_PSX::DMA_Init();
// MDFN_IEN_PSX::DMA_Power();
if(!test_mode)
{
MySsInitHot();
}
SPU = new PS_SPU();
SPU->Power();
}
extern "C" void write_16(u32 addr, u16 data, char* file, int line)
{
writes.push_back({addr, data, file, line, 0});
printf("write16 %08X %04X %s:%d\n", addr, data, file, line);
if(test_mode)
{
writes.push_back({addr, data, file, line, 0});
printf("write16 %08X %04X %s:%d\n", addr, data, file, line);
}
if(!init)
{
mednafen_init();
@ -115,7 +123,6 @@ extern "C" u16 read_16(u32 addr, char* file, int line)
extern "C" void write_dma(u32 data, char* file, int line)
{
printf("write_dma %08X %04X %s:%d\n", SPU->RWAddr, data, file, line);
writes.push_back({SPU->RWAddr, data, file, line, 1});
SPU->WriteDMA(data);
}
@ -364,8 +371,161 @@ void test_spu_vm_do_allocate()
CheckWrites("./src/pc/psxsdk/expected/spu_vm_do_allocate.txt");
}
extern "C" void SsInitHot(void);
extern u8 aPbav[0x3000];
extern s32 g_VabAddrs[];
extern u8 D_8013B6A0[269488];
extern "C" void SsVabClose(s16 vabid);
extern "C" s32 SsVabTransCompleted(short immediateFlag);
extern "C" s32 SsVabOpenHeadSticky(u_char* addr, u_long vabid, u_long sbaddr);
#define SS_IMEDIATE 0
#define LOAD_VAB(vab_id, name, addr, data, dataLen) \
SsVabClose(vab_id); \
while (SsVabTransCompleted(SS_IMEDIATE) != 1) \
; \
\
if (SsVabOpenHeadSticky(name, vab_id, addr) < 0) { \
return -1; \
} \
if (SsVabTransBodyPartly((u_char*)data, (u_long)dataLen, (u_long)vab_id) < 0) { \
return -1; \
} \
while (SsVabTransCompleted(SS_IMEDIATE) != 1)
void SsVabClose(short vab_id);
int load_it()
{
LOAD_VAB(0, aPbav, g_VabAddrs[0], D_8013B6A0, 269488);
return 0;
}
extern "C" void ReadToArray(const char* path, char* content, size_t maxlen);
extern "C" s32 _spu_mem_mode_unitM;
extern "C" s32 D_8003355C;
void check_ss_vab_open_head_with_mode()
{
// SPU->Power();
s8 temp[0x1000] = {0};
SpuInitMalloc(32, temp);
ReadToArray("assets/dra/vh_0.bin", (char*)aPbav, LEN(aPbav));
SsInitHot();
SpuMallocWithStartAddr(0x1010, 0x10000);
ASSERT_EQ(_spu_rev_reserve_wa, 0);
ASSERT_EQ(_spu_rev_offsetaddr, 65534);
ASSERT_EQ(_spu_mem_mode_unitM, 7);
ASSERT_EQ(_spu_mem_mode_plus, 3);
ASSERT_EQ(D_8003355C, 32);
ASSERT_EQ(_spu_memList[0].addr, 0x00001010);
ASSERT_EQ(_spu_memList[1].addr, 0x40011010);
ASSERT_EQ(_spu_memList[2].addr, 0);
ASSERT_EQ(_spu_memList[0].size, 65536);
ASSERT_EQ(_spu_memList[1].size, 454640);
ASSERT_EQ(_spu_memList[2].size, 0);
load_it();
printf("_svm_vab_pg[vabId] %08X diff %d\n", _svm_vab_pg[0], (size_t)_svm_vab_pg[0] - (size_t)aPbav);
printf("_svm_vab_vh[vabId] %08X diff %d\n", _svm_vab_vh[0], (size_t)_svm_vab_vh[0] - (size_t)aPbav);
printf("_svm_vab_tn[vabId] %08X diff %d\n", _svm_vab_tn[0], (size_t)_svm_vab_tn[0] - (size_t)aPbav);
ASSERT_EQ((size_t)_svm_vab_pg[0] - (size_t)aPbav, 32);
ASSERT_EQ((size_t)_svm_vab_vh[0] - (size_t)aPbav, 0);
ASSERT_EQ((size_t)_svm_vab_tn[0] - (size_t)aPbav, 2080);
printf(" _svm_vab_tn[0].prior %08X\n", _svm_vab_tn[0]->prior);
ASSERT_EQ(_svm_vab_tn[0]->prior, 8);
ASSERT_EQ(_svm_vab_start[0], 0x00001010);
ASSERT_EQ(_svm_vab_total[0], 269488);
ASSERT_EQ(_svm_vab_used[0], 1);
printf(" _svm_vab_start[0] %08X\n", _svm_vab_start[0]);
printf("_svm_vab_total[0] %d\n", _svm_vab_total[0]);
printf("_svm_vab_used[0] %d\n", _svm_vab_used[0]);
for(int i = 0; i < 32; i++)
{
printf("_spu_memList[%d] addr %08X size %d\n", i, _spu_memList[i].addr, _spu_memList[i].size);
}
ASSERT_EQ(_spu_memList[0].addr, 0x00001010);
ASSERT_EQ(_spu_memList[1].addr, 0x40011010);
ASSERT_EQ(_spu_memList[2].addr, 0);
ASSERT_EQ(_spu_memList[0].size, 65536);
ASSERT_EQ(_spu_memList[1].size, 454640);
ASSERT_EQ(_spu_memList[2].size, 0);
}
void print_memlist()
{
int i;
printf("-----------------------------------------\n");
for (i = 0; i < 5; i++)
{
printf("_spu_memList[%d] addr %08X size %d\n", i, _spu_memList[i].addr, _spu_memList[i].size);
}
}
extern "C" s32 SpuMalloc(s32 size);
void check_spu_malloc()
{
s8 temp[0x1000] = {0};
s32 result;
SpuInitMalloc(32, temp);
ASSERT_EQ(_spu_memList[0].addr, 0x40001010);
ASSERT_EQ(_spu_memList[0].size, 520176);
ASSERT_EQ(_spu_memList[1].addr, 0);
ASSERT_EQ(_spu_memList[1].size, 0);
print_memlist();
SpuMallocWithStartAddr(0x1010, 0x10000);
print_memlist();
ASSERT_EQ(_spu_memList[0].addr, 0x00001010);
ASSERT_EQ(_spu_memList[0].size, 65536);
ASSERT_EQ(_spu_memList[1].addr, 0x40011010);
ASSERT_EQ(_spu_memList[1].size, 454640);
ASSERT_EQ(_spu_memList[2].addr, 0);
ASSERT_EQ(_spu_memList[2].size, 0);
result = SpuMalloc(269488);
ASSERT_EQ(result, 0x11010);
print_memlist();
ASSERT_EQ(_spu_memList[0].addr, 0x00001010);
ASSERT_EQ(_spu_memList[0].size, 65536);
ASSERT_EQ(_spu_memList[1].addr, 0x00011010);
ASSERT_EQ(_spu_memList[1].size, 269488);
ASSERT_EQ(_spu_memList[2].addr, 0x40052CC0);
ASSERT_EQ(_spu_memList[2].size, 185152);
ASSERT_EQ(_spu_memList[3].addr, 0);
ASSERT_EQ(_spu_memList[3].size, 0);
}
extern "C" void run_tests()
{
test_mode = true;
_spu_init(0);
CheckWrites("./src/pc/psxsdk/expected/_spu_init.txt");
@ -381,5 +541,40 @@ extern "C" void run_tests()
test_spu_vm_do_allocate();
check_ss_vab_open_head_with_mode();
check_spu_malloc();
exit(0);
}
double accum = 0;
extern "C" void SsSeqCalledTbyT(void);
#include <string.h>
extern "C" void SoundRevCallback(void *userdata, u8 *stream, int len)
{
if(!init)
{
printf("not ready\n");
return;
}
for(int i = 0; i < len / 4; i++)
{
// generate one sample
SPU->UpdateFromCDC(768);
if(accum >= 735.735)
{
SsSeqCalledTbyT();
accum -= 735.735;
}
accum += 1;
}
memcpy(stream, IntermediateBuffer, len);
if (IntermediateBufferPos >= 1024)
{
IntermediateBufferPos = 0;
}
}

View File

@ -844,17 +844,291 @@ s32 _spu_mem_mode_unitM;
s32 _spu_rev_offsetaddr;
s32 _spu_rev_reserve_wa;
void func_800286E0(void);
#define _spu_AllocBlockNum D_8003355C
#define _spu_AllocLastNum D_80033560
void _spu_gcSPU() { func_800286E0(); }
long SpuMalloc(long size) {
assert(false);
return 0;
long pAllocated;
printf("SpuMalloc size %d\n", size);
unsigned int rev_size_zero = 0;
if (_spu_rev_reserve_wa) {
rev_size_zero = (0x10000 - _spu_rev_offsetaddr) << _spu_mem_mode_plus;
} else {
rev_size_zero = 0;
}
int size_adjusted = size;
if ((size & ~_spu_mem_mode_unitM) != 0) {
size_adjusted = size + _spu_mem_mode_unitM;
}
const u32 calc_alloc_size =
size_adjusted >> _spu_mem_mode_plus << _spu_mem_mode_plus;
printf("memlist is:\n");
for (int i = 0; i < 32; i++) {
printf("_spu_memList[%d].addr %08X size %08X\n", i,
_spu_memList[i].addr, _spu_memList[i].size);
}
int found_block_idx = -1;
if ((_spu_memList->addr & 0x40000000) != 0) {
found_block_idx = 0;
} else {
printf("! _spu_memList->addr & 0x40000000 _spu_AllocBlockNum %d\n",
_spu_AllocBlockNum);
_spu_gcSPU();
if (_spu_AllocBlockNum > 0) {
s32 cur_idx = 0;
SPU_MALLOC* pListIter = _spu_memList;
while ((pListIter->addr & 0x40000000) == 0 &&
((pListIter->addr & 0x80000000) == 0 ||
pListIter->size < calc_alloc_size)) {
printf("next block\n");
++cur_idx;
++pListIter;
if (cur_idx >= _spu_AllocBlockNum) {
goto out_of_blocks;
}
}
found_block_idx = cur_idx;
}
}
out_of_blocks:
pAllocated = -1;
printf("found_block_idx %d\n", found_block_idx);
if (found_block_idx != -1) {
printf("SpuMalloc:%d\n", __LINE__);
if ((_spu_memList[found_block_idx].addr & 0x40000000) != 0) {
printf("SpuMalloc:%d _spu_AllocBlockNum %d\n", __LINE__,
_spu_AllocBlockNum);
if (found_block_idx < (int)_spu_AllocBlockNum) {
printf("SpuMalloc:%d\n", __LINE__);
if (_spu_memList[found_block_idx].size - rev_size_zero >=
calc_alloc_size) {
printf("SpuMalloc:%d\n", __LINE__);
_spu_AllocLastNum = found_block_idx + 1;
SPU_MALLOC* pLastBlock = &_spu_memList[_spu_AllocLastNum];
pLastBlock->addr =
((_spu_memList[found_block_idx].addr & 0xFFFFFFF) +
calc_alloc_size) |
0x40000000;
pLastBlock->size =
_spu_memList[found_block_idx].size - calc_alloc_size;
_spu_memList[found_block_idx].size = calc_alloc_size;
_spu_memList[found_block_idx].addr &= 0xFFFFFFF;
_spu_gcSPU();
pAllocated = _spu_memList[found_block_idx].addr;
printf(
"SpuMalloc:%d pAllocated %d\n", __LINE__, pAllocated);
}
}
} else {
printf("SpuMalloc:%d\n", __LINE__);
if (calc_alloc_size < _spu_memList[found_block_idx].size) {
printf("SpuMalloc:%d\n", __LINE__);
const u32 pAllocEndAddr =
_spu_memList[found_block_idx].addr + calc_alloc_size;
if (_spu_AllocLastNum < _spu_AllocBlockNum) {
printf("SpuMalloc:%d\n", __LINE__);
const u32 last_addr = _spu_memList[_spu_AllocLastNum].addr;
const u32 last_alloc_size =
_spu_memList[_spu_AllocLastNum].size;
_spu_memList[_spu_AllocLastNum].addr =
pAllocEndAddr | 0x80000000;
_spu_memList[_spu_AllocLastNum].size =
_spu_memList[found_block_idx].size - calc_alloc_size;
_spu_AllocLastNum++;
_spu_memList[_spu_AllocLastNum].addr = last_addr;
_spu_memList[_spu_AllocLastNum].size = last_alloc_size;
}
}
_spu_memList[found_block_idx].size = calc_alloc_size;
_spu_memList[found_block_idx].addr &= 0xFFFFFFF;
_spu_gcSPU();
pAllocated = _spu_memList[found_block_idx].addr;
printf("SpuMalloc:%d pAllocated %d\n", __LINE__, pAllocated);
}
}
return pAllocated;
}
int SsVabOpenHeadWithMode(unsigned char* pAddr, int vabId, s32 pFn, long mode) {
assert(false);
return 0;
}
void func_800286E0(void) {
int last_alloc_idx; // $v0
int counter; // $t1
SPU_MALLOC* pMemList; // $t0
int last_alloc_idx_; // $t5
SPU_MALLOC* pMemList_Iter; // $a3
int list_idx; // $a2
SPU_MALLOC* pCurBlock; // $v1
bool bIsntMagicAddr; // dc
SPU_MALLOC* pCurBlock_; // $a1
int counter_; // $t1
SPU_MALLOC* pMemList__; // $v1
int last_alloc_idx__; // $v1
int counter__; // $t1
SPU_MALLOC* pMemList___; // $t5
SPU_MALLOC* pMemListIter_; // $t2
int counter_next; // $a2
int last_alloc_idx___; // $t3
SPU_MALLOC* pNextBlock_; // $a0
int mem_addr; // $a3
int mem_size; // $v1
int last_alloc_idx____; // $a1
int idx; // $t1
SPU_MALLOC* pMemListIter; // $a0
SPU_MALLOC* pCurBlock__; // $v0
SPU_MALLOC* pPrevBlock; // $a0
void func_800286E0(void) {}
last_alloc_idx = _spu_AllocLastNum;
counter = 0;
if (_spu_AllocLastNum >= 0) {
pMemList = _spu_memList;
last_alloc_idx_ = _spu_AllocLastNum;
pMemList_Iter = _spu_memList;
do {
list_idx = counter + 1;
if ((pMemList_Iter->addr & 0x80000000) == 0) {
goto next_item;
}
pCurBlock = &pMemList[list_idx];
while (1) {
bIsntMagicAddr = pCurBlock->addr != 0x2FFFFFFF;
++pCurBlock;
if (bIsntMagicAddr) {
break;
}
++list_idx;
}
pCurBlock_ = &pMemList[list_idx];
if ((pCurBlock_->addr & 0x80000000) != 0 &&
(pCurBlock_->addr & 0xFFFFFFF) ==
(pMemList_Iter->addr & 0xFFFFFFF) + pMemList_Iter->size) {
pCurBlock_->addr = 0x2FFFFFFF;
pMemList_Iter->size += pCurBlock_->size;
} else {
next_item:
++pMemList_Iter;
++counter;
}
} while (last_alloc_idx_ >= counter);
last_alloc_idx = _spu_AllocLastNum;
}
counter_ = 0;
if (last_alloc_idx >= 0) {
pMemList__ = _spu_memList;
do {
if (!pMemList__->size) {
pMemList__->addr = 0x2FFFFFFF;
}
++counter_;
++pMemList__;
} while (last_alloc_idx >= counter_);
}
last_alloc_idx__ = _spu_AllocLastNum;
counter__ = 0;
if (_spu_AllocLastNum >= 0) {
pMemList___ = _spu_memList;
pMemListIter_ = _spu_memList;
do {
if ((pMemListIter_->addr & 0x40000000) != 0) {
break;
}
counter_next = counter__ + 1;
if (last_alloc_idx__ >= counter__ + 1) {
last_alloc_idx___ = _spu_AllocLastNum;
pNextBlock_ = &pMemList___[counter__ + 1];
do {
if ((pNextBlock_->addr & 0x40000000) != 0) {
break;
}
mem_addr = pMemListIter_->addr;
if ((pNextBlock_->addr & 0xFFFFFFFu) <
(pMemListIter_->addr & 0xFFFFFFFu)) {
pMemListIter_->addr = pNextBlock_->addr;
mem_size = pMemListIter_->size;
pMemListIter_->size = pNextBlock_->size;
pNextBlock_->addr = mem_addr;
pNextBlock_->size = mem_size;
}
++counter_next;
++pNextBlock_;
} while (last_alloc_idx___ >= counter_next);
}
last_alloc_idx__ = _spu_AllocLastNum;
++counter__;
++pMemListIter_;
} while (_spu_AllocLastNum >= counter__);
}
last_alloc_idx____ = _spu_AllocLastNum;
idx = 0;
if (_spu_AllocLastNum >= 0) {
pMemListIter = _spu_memList;
while ((pMemListIter->addr & 0x40000000) == 0) // not last entry
{
if (pMemListIter->addr == 0x2FFFFFFF) {
pCurBlock__ = &_spu_memList[last_alloc_idx____];
pMemListIter->addr = pCurBlock__->addr;
pMemListIter->size = pCurBlock__->size;
_spu_AllocLastNum = idx;
break;
}
last_alloc_idx____ = _spu_AllocLastNum;
++idx;
++pMemListIter;
if (_spu_AllocLastNum < idx) {
break;
}
}
}
// Merged tail unused blocks
if (_spu_AllocLastNum - 1 >= 0) {
pPrevBlock = &_spu_memList[_spu_AllocLastNum - 1];
do {
if ((pPrevBlock->addr & 0x80000000) == 0) {
break;
}
// Found unused block, merge it and set as last entry
pPrevBlock->addr = pPrevBlock->addr & 0xFFFFFFF | 0x40000000;
pPrevBlock->size += _spu_memList[_spu_AllocLastNum].size;
_spu_AllocLastNum--;
pPrevBlock--;
} while (_spu_AllocLastNum >= 0);
}
}
u16 _spu_tsa;
void (* volatile _spu_transferCallback)();
@ -917,6 +1191,7 @@ int _spu_t(int mode, ...) {
for (i = 0; i < count / 4; i++) {
write_dma(source_address[i], __FILE__, __LINE__);
}
return 0;
break;
}

View File

@ -300,6 +300,6 @@ long SpuMallocWithStartAddr(unsigned long addr, long size) {
return var_v0;
}
void _SpuSetVoiceAttr(SpuVoiceAttr* arg, s32, s32, s32) {}
#include <assert.h>
void _SpuSetVoiceAttr(SpuVoiceAttr* arg, s32, s32, s32) { assert(false); }
#endif

View File

@ -87,10 +87,14 @@ void ResetPlatform(void) {
}
int MyResetGraph(int arg0) { return 0; }
void SoundRevCallback(void* userdata, u8* stream, int len);
void MyAudioCallback(void* data, Uint8* buffer, int length);
void SDLAudioCallback(void* data, Uint8* buffer, int length) {
#ifdef WANT_LIBSND_LLE
SoundRevCallback(data, buffer, length);
#else
MyAudioCallback(data, buffer, length);
#endif
}
void MySsInitHot(void) {

View File

@ -227,8 +227,8 @@ s32 g_DebugWaitInfoTimer;
s32 g_DebugRecordVideoFid;
u8 D_8013B6A0[269488] = {0}; // VB file
u8 D_8017D350[57744] = {0}; // VB file
u8 D_8018B4E0[64496] = {0}; // VB file
u8 D_801A9C80[108048] = {0}; // VB file
u8 D_8018B4E0[108048] = {0}; // VB file
u8 D_801A9C80[64496] = {0}; // VB file
u8 aPbav[0x3000] = {0}; // VH file
u8 aPbav_0[0x2000] = {0}; // VH file
u8 aPbav_1[0x2000] = {0}; // VH file