dsp: map TEMP/MEMS/MIXS regs to sh4 and aica address space. Clean up

This commit is contained in:
Flyinghead 2021-08-26 10:16:07 +02:00
parent 2a849ccba5
commit ca17717af7
15 changed files with 399 additions and 464 deletions

View File

@ -35,7 +35,6 @@
#include "hw/pvr/Renderer_if.h"
#include "rend/CustomTexture.h"
#include "hw/arm7/arm7_rec.h"
#include "hw/aica/dsp.h"
extern int screen_width, screen_height;
@ -721,7 +720,6 @@ bool dc_loadstate(const void **data, u32 size)
mmu_set_state();
sh4_cpu.ResetCache();
dsp.dyndirty = true;
sh4_sched_ffts();
return true;

View File

@ -212,7 +212,6 @@ struct CommonData_struct
u32 :16;
};
//should be 0x15C8 in size
struct DSPData_struct
{
//+0x000
@ -222,13 +221,13 @@ struct DSPData_struct
u32 MADRS[64]; //15:0
//+0x300
u8 PAD0[0x100];
u8 _PAD0[0x100];
//+0x400
u32 MPRO[128*4]; //15:0
//+0xC00
u8 PAD1[0x400];
u8 _PAD1[0x400];
//+0x1000
struct
@ -260,6 +259,8 @@ struct DSPData_struct
//+0x15C0
u32 EXTS[2]; //15:0
};
static_assert(sizeof(DSPData_struct) == 0x15C8, "Wrong DSPData size");
union InterruptInfo
{
struct
@ -305,28 +306,29 @@ extern DSPData_struct* DSPData;
template<u32 sz>
void WriteAicaReg(u32 reg,u32 data);
//Timers :)
struct AicaTimerData
{
union
{
struct
{
u32 count:8;
u32 md:3;
u32 nil:5;
u32 pad:16;
};
u32 data;
};
};
class AicaTimer
{
public:
struct AicaTimerData
{
union
{
struct
{
u32 count:8;
u32 md:3;
u32 nil:5;
u32 pad:16;
};
u32 data;
};
};
AicaTimerData* data;
u32 id;
public:
s32 c_step;
u32 m_step;
u32 id;
void Init(u8* regbase,u32 timer)
{
data=(AicaTimerData*)&regbase[0x2890 + timer*4];
@ -334,6 +336,7 @@ public:
m_step=1<<(data->md);
c_step=m_step;
}
void StepTimer(u32 samples)
{
do

View File

@ -20,6 +20,42 @@ u32 ReadReg(u32 addr)
else
ReadCommonReg(addr, false);
}
else if (addr >= 0x4000 && addr < 0x4580)
{
if (addr & 2)
{
INFO_LOG(AICA, "Unaligned DSP register read @ %x", addr);
return 0;
}
DEBUG_LOG(AICA, "DSP register read @ %x", addr);
// DSP TEMP/MEMS
u32 v;
if (addr < 0x4500)
{
v = addr < 0x4400 ? dsp::state.TEMP[(addr - 0x4000) / 8] : dsp::state.MEMS[(addr - 0x4400) / 8];
if (addr & 4)
v = (v >> 8) & 0xffff;
else
v &= 0xff;
}
// DSP MIXS
else
{
v = dsp::state.MIXS[(addr - 0x4500) / 8];
if (addr & 4)
v = (v >> 4) & 0xffff;
else
v &= 0xf;
}
if (sz == 1)
{
if (addr & 1)
v >>= 8;
else
v &= 0xff;
}
return v;
}
return ReadMemArr<sz>(aica_reg, addr);
}
@ -36,9 +72,9 @@ void WriteReg(u32 addr,u32 data)
return;
}
if (addr<0x2800)
if (addr < 0x2800)
{
if (sz==1)
if (sz == 1)
WriteMemArr<1>(aica_reg, addr, data);
else
WriteMemArr<2>(aica_reg, addr, data);
@ -47,38 +83,101 @@ void WriteReg(u32 addr,u32 data)
if (addr < 0x2818)
{
if (sz==1)
if (sz == 1)
{
WriteCommonReg8(addr,data);
WriteCommonReg8(addr, data);
}
else
{
WriteCommonReg8(addr,data&0xFF);
WriteCommonReg8(addr+1,data>>8);
WriteCommonReg8(addr, data & 0xFF);
WriteCommonReg8(addr + 1, data >> 8);
}
return;
}
if (addr>=0x3000)
if (addr >= 0x3000)
{
if (sz==1)
if (addr & 2)
{
INFO_LOG(AICA, "Unaligned DSP register write @ %x", addr);
return;
}
if (addr >= 0x4000 && addr < 0x4580)
{
// DSP TEMP/MEMS
if (addr < 0x4500)
{
s32 &v = addr < 0x4400 ? dsp::state.TEMP[(addr - 0x4000) / 8] : dsp::state.MEMS[(addr - 0x4400) / 8];
if (addr & 4)
{
if (sz == 1)
{
if (addr & 1)
v = (v & 0x0000ffff) | (((s32)data << 24) >> 8);
else
v = (v & 0xffff00ff) | ((data & 0xff) << 8);
}
else
{
v = (v & 0xff) | (((s32)data << 16) >> 8);
}
}
else
{
if (sz != 1 || (addr & 1) == 0)
v = (v & ~0xff) | (data & 0xff);
// else ignored
}
DEBUG_LOG(AICA, "DSP TEMP/MEMS register write<%d> @ %x = %d", sz, addr, v);
}
// DSP MIXS
else
{
s32 &v = dsp::state.MIXS[(addr - 0x4500) / 8];
if (addr & 4)
{
if (sz == 1)
{
if (addr & 1)
v = (v & 0x00000fff) | (((s32)data << 24) >> 12);
else
v = (v & 0xfffff00f) | ((data & 0xff) << 4);
}
else
{
v = (v & 0xf) | (((s32)data << 16) >> 12);
}
}
else
{
if (sz != 1 || (addr & 1) == 0)
v = (v & ~0xf) | (data & 0xf);
// else ignored
}
DEBUG_LOG(AICA, "DSP MIXS register write<%d> @ %x = %d", sz, addr, v);
}
return;
}
if (sz == 1)
{
WriteMemArr<1>(aica_reg, addr, data);
dsp_writenmem(addr);
dsp::writeProg(addr);
}
else
{
WriteMemArr<2>(aica_reg, addr, data);
dsp_writenmem(addr);
dsp_writenmem(addr+1);
dsp::writeProg(addr);
dsp::writeProg(addr + 1);
}
return;
}
if (sz==1)
WriteAicaReg<1>(addr,data);
if (sz == 1)
WriteAicaReg<1>(addr, data);
else
WriteAicaReg<2>(addr,data);
WriteAicaReg<2>(addr, data);
}
//Aica reads (both sh4&arm)
u32 libAICA_ReadReg(u32 addr, u32 size)
{
@ -88,24 +187,22 @@ u32 libAICA_ReadReg(u32 addr, u32 size)
return ReadReg<2>(addr & 0x7FFF);
}
void libAICA_WriteReg(u32 addr,u32 data,u32 size)
void libAICA_WriteReg(u32 addr, u32 data, u32 size)
{
if (size==1)
WriteReg<1>(addr & 0x7FFF,data);
if (size == 1)
WriteReg<1>(addr & 0x7FFF, data);
else
WriteReg<2>(addr & 0x7FFF,data);
WriteReg<2>(addr & 0x7FFF, data);
}
//Map using _vmem .. yay
void init_mem()
{
memset(aica_reg,0,sizeof(aica_reg));
aica_ram.data[ARAM_SIZE-1]=1;
memset(aica_reg, 0, sizeof(aica_reg));
aica_ram.data[ARAM_SIZE - 1] = 1;
aica_ram.Zero();
}
//kill mem map & free used mem ;)
void term_mem()
{
}

View File

@ -1,5 +1,5 @@
#include "dsp.h"
#include "aica.h"
/*
DSP rec_v1
@ -17,7 +17,10 @@
See LICENSE & COPYRIGHT files further details
*/
alignas(4096) dsp_t dsp;
namespace dsp
{
DSPState state;
//float format is ?
u16 DYNACALL PACK(s32 val)
@ -62,7 +65,7 @@ s32 DYNACALL UNPACK(u16 val)
return uval;
}
void DecodeInst(const u32 *IPtr, _INST *i)
void DecodeInst(const u32 *IPtr, Instruction *i)
{
i->TRA = (IPtr[0] >> 9) & 0x7F;
i->TWT = IPtr[0] & 0x100;
@ -93,51 +96,54 @@ void DecodeInst(const u32 *IPtr, _INST *i)
i->NXADR = IPtr[3] & 0x80;
}
#if FEAT_DSPREC != DYNAREC_NONE
void dsp_init()
{
memset(&dsp, 0, sizeof(dsp));
dsp.RBL = 0x8000 - 1;
dsp.RBP = 0;
dsp.regs.MDEC_CT = 1;
dsp.dyndirty = true;
dsp_rec_init();
#if FEAT_DSPREC == DYNAREC_NONE
void recInit() {
}
void dsp_step()
void recompile() {
}
#endif
void init()
{
if (dsp.dyndirty)
{
dsp.dyndirty = false;
dsp_recompile();
}
if (dsp.Stopped)
return;
dsp_rec_step();
memset(&state, 0, sizeof(state));
state.RBL = 0x8000 - 1;
state.RBP = 0;
state.MDEC_CT = 1;
state.dirty = true;
recInit();
}
void dsp_writenmem(u32 addr)
void writeProg(u32 addr)
{
if (addr >= 0x3400 && addr < 0x3C00)
{
dsp.dyndirty = true;
}
else if (addr >= 0x4000 && addr < 0x4400)
{
// TODO proper sharing of memory with sh4 through DSPData
memset(dsp.TEMP, 0, sizeof(dsp.TEMP));
}
else if (addr >= 0x4400 && addr < 0x4500)
{
// TODO proper sharing of memory with sh4 through DSPData
memset(dsp.MEMS, 0, sizeof(dsp.MEMS));
}
state.dirty = true;
}
void dsp_term()
void term()
{
state.stopped = true;
}
#endif
void step()
{
if (state.dirty)
{
state.dirty = false;
state.stopped = true;
for (u32 instr : DSPData->MPRO)
if (instr != 0)
{
state.stopped = false;
break;
}
if (!state.stopped)
recompile();
}
if (state.stopped)
return;
runStep();
}
}

View File

@ -1,102 +1,77 @@
#pragma once
#include "types.h"
struct dsp_t
namespace dsp
{
//Dynarec
u8 DynCode[4096*8]; //32 kb, 8 pages
//buffered DSP state
//24 bit wide
s32 TEMP[128];
//24 bit wide
s32 MEMS[32];
//20 bit wide
s32 MIXS[16];
struct DSPState
{
// buffered DSP state
s32 TEMP[128]; // 24 bits
s32 MEMS[32]; // 24 bits
s32 MIXS[16]; // 20 bits
//RBL/RBP (decoded)
// RBL/RBP (decoded, from aica common regs)
u32 RBP;
u32 RBL;
struct
u32 MDEC_CT;
// volatile dsp regs
int SHIFTED; // 24 bit
int B; // 26 bit
int MEMVAL[4];
int FRC_REG; // 13 bit
int Y_REG; // 24 bit
u32 ADRS_REG; // 13 bit
bool stopped; // DSP program is a no-op
bool dirty; // DSP program has changed
bool serialize(void **data, unsigned int *total_size)
{
bool MAD_OUT;
bool MEM_ADDR;
bool MEM_RD_DATA;
bool MEM_WT_DATA;
bool FRC_REG;
bool ADRS_REG;
bool Y_REG;
REICAST_S(TEMP);
REICAST_S(MEMS);
REICAST_S(MIXS);
REICAST_S(RBP);
REICAST_S(RBL);
REICAST_S(MDEC_CT);
bool MDEC_CT;
bool MWT_1;
bool MRD_1;
//bool MADRS;
bool MEMS;
bool NOFL_1;
bool NOFL_2;
return true;
}
bool TEMPS;
bool EFREG;
}regs_init;
//s32 -> stored as signed extended to 32 bits
struct
bool deserialize(void **data, unsigned int *total_size, serialize_version_enum version)
{
s32 MAD_OUT;
s32 MEM_ADDR;
s32 MEM_RD_DATA;
s32 MEM_WT_DATA;
s32 FRC_REG;
s32 ADRS_REG;
s32 Y_REG;
if (version < V18)
REICAST_SKIP(4096 * 8); // DynCode
REICAST_US(TEMP);
REICAST_US(MEMS);
REICAST_US(MIXS);
REICAST_US(RBP);
REICAST_US(RBL);
if (version < V18)
REICAST_SKIP(44);
REICAST_US(MDEC_CT);
if (version < V18)
REICAST_SKIP(33596 - 4096 * 8 - sizeof(TEMP) - sizeof(MEMS) - sizeof(MIXS) - 4 * 3 - 44); // other dsp stuff
dirty = true;
u32 MDEC_CT;
u32 MWT_1;
u32 MRD_1;
u32 MADRS;
u32 NOFL_1;
u32 NOFL_2;
}regs;
//DEC counter :)
//u32 DEC;
//various dsp regs
signed int ACC; //26 bit
signed int SHIFTED; //24 bit
signed int B; //26 bit
signed int MEMVAL[4];
signed int FRC_REG; //13 bit
signed int Y_REG; //24 bit
unsigned int ADDR;
unsigned int ADRS_REG; //13 bit
//Direct Mapped data :
//COEF *128
//MADRS *64
//MPRO(dsp code) *4 *128
//EFREG *16
//EXTS *2
// Interpreter flags
bool Stopped;
//Dynarec flags
bool dyndirty;
return true;
}
};
alignas(4096) extern dsp_t dsp;
extern DSPState state;
void dsp_init();
void dsp_term();
void dsp_step();
void dsp_writenmem(u32 addr);
void init();
void term();
void step();
void writeProg(u32 addr);
void dsp_rec_init();
void dsp_rec_step();
void dsp_recompile();
void recInit();
void runStep();
void recompile();
struct _INST
struct Instruction
{
u8 TRA;
bool TWT;
@ -127,6 +102,8 @@ struct _INST
bool NXADR; //MRQ set
};
void DecodeInst(const u32 *IPtr, _INST *i);
void DecodeInst(const u32 *IPtr, Instruction *i);
u16 DYNACALL PACK(s32 val);
s32 DYNACALL UNPACK(u16 val);
}

View File

@ -27,6 +27,9 @@
#include <aarch32/macro-assembler-aarch32.h>
using namespace vixl::aarch32;
namespace dsp
{
constexpr size_t CodeSize = 4096 * 8; //32 kb, 8 pages
#if defined(__unix__)
@ -40,7 +43,7 @@ class DSPAssembler : public MacroAssembler
public:
DSPAssembler(u8 *code_buffer, size_t size) : MacroAssembler(code_buffer, size, A32) {}
void compile(dsp_t *DSP)
void compile(DSPState *DSP)
{
this->DSP = DSP;
DEBUG_LOG(AICA_ARM, "DSPAssembler::compile recompiling for arm32 at %p", GetBuffer()->GetStartAddress<void*>());
@ -66,7 +69,7 @@ public:
for (int step = 0; step < 128; ++step)
{
u32 *mpro = &DSPData->MPRO[step * 4];
_INST op;
Instruction op;
DecodeInst(mpro, &op);
const u32 COEF = step;
@ -109,8 +112,8 @@ public:
Mov(B, ACC);
else
{
//B = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
Ldr(r1, dsp_operand(&DSP->regs.MDEC_CT));
//B = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
Ldr(r1, dsp_operand(&DSP->MDEC_CT));
if (op.TRA)
Add(r1, r1, op.TRA);
Bfc(r1, 7, 25);
@ -128,12 +131,12 @@ public:
X_alias = &INPUTS;
else
{
//X = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
//X = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
if (!op.ZERO && !op.BSEL && !op.NEGB)
X_alias = &B;
else
{
Ldr(r1, dsp_operand(&DSP->regs.MDEC_CT));
Ldr(r1, dsp_operand(&DSP->MDEC_CT));
if (op.TRA)
Add(r1, r1, op.TRA);
Bfc(r1, 7, 25);
@ -208,9 +211,9 @@ public:
if (op.TWT)
{
//DSP->TEMP[(op.TWA + DSP->regs.MDEC_CT) & 0x7F] = SHIFTED;
//DSP->TEMP[(op.TWA + DSP->MDEC_CT) & 0x7F] = SHIFTED;
Ldr(r2, dsp_operand(&DSP->SHIFTED));
Ldr(r1, dsp_operand(&DSP->regs.MDEC_CT));
Ldr(r1, dsp_operand(&DSP->MDEC_CT));
if (op.TWA)
Add(r1, r1, op.TWA);
Bfc(r1, 7, 25);
@ -279,13 +282,13 @@ public:
Str(r1, dspdata_operand(DSPData->EFREG, op.EWA));
}
}
Ldr(r1, dsp_operand(&DSP->regs.MDEC_CT));
// DSP->regs.MDEC_CT--
Ldr(r1, dsp_operand(&DSP->MDEC_CT));
// DSP->MDEC_CT--
Subs(r1, r1, 1);
//if (dsp.regs.MDEC_CT == 0)
// dsp.regs.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
Mov(eq, r1, dsp.RBL + 1);
Str(r1, dsp_operand(&DSP->regs.MDEC_CT));
//if (dsp.MDEC_CT == 0)
// dsp.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
Mov(eq, r1, DSP->RBL + 1);
Str(r1, dsp_operand(&DSP->MDEC_CT));
Pop(regList);
Mov(pc, lr);
@ -300,7 +303,7 @@ public:
private:
MemOperand dsp_operand(void *data, int index = 0, u32 element_size = 4)
{
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(dsp_t, TEMP) + index * element_size;
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(DSPState, TEMP) + index * element_size;
if (offset <= 4095)
return MemOperand(r8, offset);
Mov(r0, offset);
@ -309,7 +312,7 @@ private:
MemOperand dsp_operand(void *data, const Register& offset_reg, u32 element_size = 4)
{
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(dsp_t, TEMP);
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(DSPState, TEMP);
if (offset == 0)
return MemOperand(r8, offset_reg, LSL, element_size == 4 ? 2 : element_size == 2 ? 1 : 0);
@ -344,7 +347,7 @@ private:
}
}
void calculateADDR(const Register& ADDR, const _INST& op)
void calculateADDR(const Register& ADDR, const Instruction& op)
{
//u32 ADDR = DSPData->MADRS[op.MASA];
Ldr(ADDR, dspdata_operand(DSPData->MADRS, op.MASA));
@ -360,8 +363,8 @@ private:
Add(ADDR, ADDR, 1);
if (!op.TABLE)
{
//ADDR += DSP->regs.MDEC_CT;
Ldr(r1, dsp_operand(&DSP->regs.MDEC_CT));
//ADDR += DSP->MDEC_CT;
Ldr(r1, dsp_operand(&DSP->MDEC_CT));
Add(ADDR, ADDR, r1);
//ADDR &= DSP->RBL;
// RBL is constant for this program
@ -387,40 +390,30 @@ private:
uintptr_t getAicaRam()
{
return (uintptr_t)&aica_ram[0];
return reinterpret_cast<uintptr_t>(&aica_ram[0]);
}
dsp_t *DSP = nullptr;
DSPState *DSP = nullptr;
};
void dsp_recompile()
void recompile()
{
dsp.Stopped = true;
for (int i = 127; i >= 0; --i)
{
u32 *IPtr = DSPData->MPRO + i * 4;
if (IPtr[0] != 0 || IPtr[1] != 0 || IPtr[2 ]!= 0 || IPtr[3] != 0)
{
dsp.Stopped = false;
break;
}
}
JITWriteProtect(false);
DSPAssembler assembler(DynCode, CodeSize);
assembler.compile(&dsp);
assembler.compile(&state);
JITWriteProtect(true);
}
void dsp_rec_init()
void recInit()
{
u8 *pCodeBuffer;
verify(vmem_platform_prepare_jit_block(DynCode, CodeSize, (void**)&pCodeBuffer));
}
void dsp_rec_step()
void runStep()
{
((void (*)())(DynCode))();
((void (*)())DynCode)();
}
}
#endif

View File

@ -28,6 +28,9 @@
#include <aarch64/macro-assembler-aarch64.h>
using namespace vixl::aarch64;
namespace dsp
{
constexpr size_t CodeSize = 4096 * 8; //32 kb, 8 pages
#if defined(__unix__) || defined(__SWITCH__)
@ -62,13 +65,11 @@ class DSPAssembler : public MacroAssembler
public:
DSPAssembler(u8 *code_buffer, size_t size) : MacroAssembler(code_buffer, size), aica_ram_lit(NULL) {}
void Compile(struct dsp_t *DSP)
void Compile(DSPState *DSP)
{
this->DSP = DSP;
DEBUG_LOG(AICA_ARM, "DSPAssembler::DSPCompile recompiling for arm64 at %p", GetBuffer()->GetStartAddress<void*>());
Instruction* instr_start = GetBuffer()->GetStartAddress<Instruction*>();
Stp(x29, x30, MemOperand(sp, -96, PreIndex));
Stp(x21, x22, MemOperand(sp, 16));
Stp(x23, x24, MemOperand(sp, 32));
@ -93,18 +94,12 @@ public:
Mov(FRC_REG, 0);
Mov(Y_REG, 0);
Mov(ADRS_REG, 0);
Ldr(MDEC_CT, dsp_operand(&DSP->regs.MDEC_CT));
Ldr(MDEC_CT, dsp_operand(&DSP->MDEC_CT));
#if 0
Instruction* instr_cur = GetBuffer()->GetEndAddress<Instruction*>();
DEBUG_LOG(AICA_ARM, "DSP PROLOGUE");
Disassemble(instr_start, instr_cur);
instr_start = instr_cur;
#endif
for (int step = 0; step < 128; ++step)
{
u32 *mpro = &DSPData->MPRO[step * 4];
_INST op;
Instruction op;
DecodeInst(mpro, &op);
const u32 COEF = step;
@ -147,7 +142,7 @@ public:
Mov(B, ACC);
else
{
//B = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
//B = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
if (op.TRA)
Add(w1, MDEC_CT, op.TRA);
else
@ -167,7 +162,7 @@ public:
X_alias = &INPUTS;
else
{
//X = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
//X = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
if (!op.ZERO && !op.BSEL && !op.NEGB)
X_alias = &B;
else
@ -259,7 +254,7 @@ public:
if (op.TWT)
{
//DSP->TEMP[(op.TWA + DSP->regs.MDEC_CT) & 0x7F] = SHIFTED;
//DSP->TEMP[(op.TWA + DSP->MDEC_CT) & 0x7F] = SHIFTED;
if (op.TWA)
Add(w1, MDEC_CT, op.TWA);
else
@ -323,20 +318,14 @@ public:
Asr(w1, SHIFTED, 8);
Str(w1, mem_operand);
}
#if 0
instr_cur = GetBuffer()->GetEndAddress<Instruction*>();
DEBUG_LOG(AICA_ARM, "DSP STEP %d: %04x %04x %04x %04x", step, mpro[0], mpro[1], mpro[2], mpro[3]);
Disassemble(instr_start, instr_cur);
instr_start = instr_cur;
#endif
}
// DSP->regs.MDEC_CT--
// DSP->MDEC_CT--
Subs(MDEC_CT, MDEC_CT, 1);
//if (dsp.regs.MDEC_CT == 0)
// dsp.regs.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
Mov(w0, dsp.RBL + 1);
//if (dsp.MDEC_CT == 0)
// dsp.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
Mov(w0, DSP->RBL + 1);
Csel(MDEC_CT, w0, MDEC_CT, eq);
Str(MDEC_CT, dsp_operand(&DSP->regs.MDEC_CT));
Str(MDEC_CT, dsp_operand(&DSP->MDEC_CT));
Ldp(x21, x22, MemOperand(sp, 16));
Ldp(x23, x24, MemOperand(sp, 32));
@ -345,12 +334,7 @@ public:
Ldp(x19, x20, MemOperand(sp, 80));
Ldp(x29, x30, MemOperand(sp, 96, PostIndex));
Ret();
#if 0
instr_cur = GetBuffer()->GetEndAddress<Instruction*>();
DEBUG_LOG(AICA_ARM, "DSP EPILOGUE");
Disassemble(instr_start, instr_cur);
instr_start = instr_cur;
#endif
FinalizeCode();
vmem_platform_flush_cache(
@ -361,7 +345,7 @@ public:
private:
MemOperand dsp_operand(void *data, int index = 0, u32 element_size = 4)
{
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(dsp_t, TEMP) + index * element_size;
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(DSPState, TEMP) + index * element_size;
if (offset < 16384)
return MemOperand(x28, offset);
Mov(x0, offset);
@ -370,7 +354,7 @@ private:
MemOperand dsp_operand(void *data, const Register& offset_reg, u32 element_size = 4)
{
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(dsp_t, TEMP);
ptrdiff_t offset = ((u8*)data - (u8*)DSP) - offsetof(DSPState, TEMP);
if (offset == 0)
return MemOperand(x28, offset_reg, LSL, element_size == 4 ? 2 : element_size == 2 ? 1 : 0);
@ -406,7 +390,7 @@ private:
}
}
void CalculateADDR(const Register& ADDR, const _INST& op, const Register& ADRS_REG, const Register& MDEC_CT)
void CalculateADDR(const Register& ADDR, const Instruction& op, const Register& ADRS_REG, const Register& MDEC_CT)
{
//u32 ADDR = DSPData->MADRS[op.MASA];
Ldr(ADDR, dspdata_operand(DSPData->MADRS, op.MASA));
@ -421,7 +405,7 @@ private:
Add(ADDR, ADDR, 1);
if (!op.TABLE)
{
//ADDR += DSP->regs.MDEC_CT;
//ADDR += DSP->MDEC_CT;
Add(ADDR, ADDR, MDEC_CT);
//ADDR &= DSP->RBL;
// RBL is constant for this program
@ -452,42 +436,19 @@ private:
return aica_ram_lit;
}
void Disassemble(Instruction* instr_start, Instruction* instr_end)
{
Decoder decoder;
Disassembler disasm;
decoder.AppendVisitor(&disasm);
Instruction* instr;
for (instr = instr_start; instr < instr_end; instr += kInstructionSize) {
decoder.Decode(instr);
DEBUG_LOG(AICA_ARM, " %p:\t%s", reinterpret_cast<void*>(instr), disasm.GetOutput());
}
}
struct dsp_t *DSP;
DSPState *DSP;
Literal<u8*> *aica_ram_lit;
};
void dsp_recompile()
void recompile()
{
dsp.Stopped = true;
for (int i = 127; i >= 0; --i)
{
u32 *IPtr = DSPData->MPRO + i * 4;
if (IPtr[0] != 0 || IPtr[1] != 0 || IPtr[2 ]!= 0 || IPtr[3] != 0)
{
dsp.Stopped = false;
break;
}
}
JITWriteProtect(false);
DSPAssembler assembler(pCodeBuffer, CodeSize);
assembler.Compile(&dsp);
assembler.Compile(&state);
JITWriteProtect(true);
}
void dsp_rec_init()
void recInit()
{
#ifdef FEAT_NO_RWX_PAGES
verify(vmem_platform_prepare_jit_block(DynCode, CodeSize, (void**)&pCodeBuffer, &rx_offset));
@ -500,8 +461,10 @@ void dsp_rec_init()
#endif
}
void dsp_rec_step()
void runStep()
{
((void (*)())(DynCode))();
((void (*)())DynCode)();
}
}
#endif

View File

@ -13,21 +13,14 @@
#include "aica.h"
#include "aica_if.h"
#ifdef NDEBUG
#undef verify
#define verify(...)
#endif
void AICADSP_Init(struct dsp_t *DSP)
namespace dsp
{
memset(DSP, 0, sizeof(*DSP));
DSP->RBL = 0x8000 - 1;
DSP->Stopped = 1;
dsp.regs.MDEC_CT = 1;
}
void AICADSP_Step(struct dsp_t *DSP)
void runStep()
{
if (state.stopped)
return;
s32 ACC = 0; //26 bit
s32 SHIFTED = 0; //24 bit
s32 X = 0; //24 bit
@ -39,16 +32,6 @@ void AICADSP_Step(struct dsp_t *DSP)
s32 Y_REG = 0; //24 bit
u32 ADRS_REG = 0; //13 bit
if (DSP->Stopped)
return;
#if 0
int dump = 0;
FILE *f = NULL;
if (dump)
f = fopen("dsp.txt", "wt");
#endif
for (int step = 0; step < 128; ++step)
{
u32 *IPtr = DSPData->MPRO + step * 4;
@ -56,7 +39,7 @@ void AICADSP_Step(struct dsp_t *DSP)
if (IPtr[0] == 0 && IPtr[1] == 0 && IPtr[2] == 0 && IPtr[3] == 0)
{
// Empty instruction shortcut
X = DSP->TEMP[DSP->regs.MDEC_CT & 0x7F];
X = state.TEMP[state.MDEC_CT & 0x7F];
Y = FRC_REG;
ACC = (((s64)X * (s64)Y) >> 12) + X;
@ -84,29 +67,12 @@ void AICADSP_Step(struct dsp_t *DSP)
u32 COEF = step;
// operations are done at 24 bit precision
#if 0
#define DUMP(v) printf(" " #v ": %04X",v);
printf("%d: ",step);
DUMP(ACC);
DUMP(SHIFTED);
DUMP(X);
DUMP(Y);
DUMP(B);
DUMP(INPUTS);
DUMP(MEMVAL);
DUMP(FRC_REG);
DUMP(Y_REG);
DUMP(ADDR);
DUMP(ADRS_REG);
printf("\n");
#endif
// INPUTS RW
if (IRA <= 0x1f)
INPUTS = DSP->MEMS[IRA];
INPUTS = state.MEMS[IRA];
else if (IRA <= 0x2F)
INPUTS = DSP->MIXS[IRA - 0x20] << 4; // MIXS is 20 bit
INPUTS = state.MIXS[IRA - 0x20] << 4; // MIXS is 20 bit
else if (IRA <= 0x31)
INPUTS = DSPData->EXTS[IRA - 0x30] << 8; // EXTS is 16 bits
else
@ -115,7 +81,7 @@ void AICADSP_Step(struct dsp_t *DSP)
if (IWT)
{
u32 IWA = (IPtr[1] >> 1) & 0x1F;
DSP->MEMS[IWA] = MEMVAL[step & 3]; // MEMVAL was selected in previous MRD
state.MEMS[IWA] = MEMVAL[step & 3]; // MEMVAL was selected in previous MRD
}
// Operand sel
@ -125,7 +91,7 @@ void AICADSP_Step(struct dsp_t *DSP)
if (BSEL)
B = ACC;
else
B = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
B = state.TEMP[(TRA + state.MDEC_CT) & 0x7F];
if (NEGB)
B = -B;
}
@ -138,7 +104,7 @@ void AICADSP_Step(struct dsp_t *DSP)
if (XSEL)
X = INPUTS;
else
X = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
X = state.TEMP[(TRA + state.MDEC_CT) & 0x7F];
// Y
if (YSEL == 0)
@ -169,7 +135,7 @@ void AICADSP_Step(struct dsp_t *DSP)
if (TWT)
{
u32 TWA = (IPtr[0] >> 1) & 0x7F;
DSP->TEMP[(TWA + DSP->regs.MDEC_CT) & 0x7F] = SHIFTED;
state.TEMP[(TWA + state.MDEC_CT) & 0x7F] = SHIFTED;
}
if (FRCL)
@ -202,14 +168,14 @@ void AICADSP_Step(struct dsp_t *DSP)
ADDR++;
if (!TABLE)
{
ADDR += DSP->regs.MDEC_CT;
ADDR &= DSP->RBL; // RBL is ring buffer length - 1
ADDR += state.MDEC_CT;
ADDR &= state.RBL; // RBL is ring buffer length - 1
}
else
ADDR &= 0xFFFF;
ADDR <<= 1; // Word -> byte address
ADDR += DSP->RBP; // RBP is already a byte address
ADDR += state.RBP; // RBP is already a byte address
if (MRD) // memory only allowed on odd. DoA inserts NOPs on even
{
//if (NOFL)
@ -243,64 +209,10 @@ void AICADSP_Step(struct dsp_t *DSP)
}
}
--DSP->regs.MDEC_CT;
if (dsp.regs.MDEC_CT == 0)
dsp.regs.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
// memset(DSP->MIXS, 0, sizeof(DSP->MIXS));
// if(f)
// fclose(f);
--state.MDEC_CT;
if (state.MDEC_CT == 0)
state.MDEC_CT = state.RBL + 1; // RBL is ring buffer length - 1
}
void AICADSP_Start(struct dsp_t *DSP)
{
dsp.Stopped = 1;
for (int i = 127; i >= 0; --i)
{
u32 *IPtr = DSPData->MPRO + i * 4;
if (IPtr[0] != 0 || IPtr[1] != 0 || IPtr[2 ]!= 0 || IPtr[3] != 0)
{
DSP->Stopped = 0;
//printf("DSP: starting %d steps\n", i + 1);
break;
}
}
}
void dsp_init()
{
AICADSP_Init(&dsp);
AICADSP_Start(&dsp);
}
void dsp_term()
{
dsp.Stopped = 1;
}
void dsp_step()
{
AICADSP_Step(&dsp);
}
void dsp_writenmem(u32 addr)
{
if (addr >= 0x3400 && addr < 0x3C00)
{
AICADSP_Start(&dsp);
}
else if (addr >= 0x4000 && addr < 0x4400)
{
// TODO proper sharing of memory with sh4 through DSPData
memset(dsp.TEMP, 0, sizeof(dsp.TEMP));
}
else if (addr >= 0x4400 && addr < 0x4500)
{
// TODO proper sharing of memory with sh4 through DSPData
memset(dsp.MEMS, 0, sizeof(dsp.MEMS));
}
}
#endif

View File

@ -27,8 +27,8 @@
#include "aica_if.h"
#include "hw/mem/_vmem.h"
#define CC_RW2RX(ptr) (ptr)
#define CC_RX2RW(ptr) (ptr)
namespace dsp
{
alignas(4096) static u8 CodeBuffer[32 * 1024]
#if defined(_WIN32)
@ -41,13 +41,14 @@ alignas(4096) static u8 CodeBuffer[32 * 1024]
#error CodeBuffer code section unknown
#endif
static u8 *pCodeBuffer;
static ptrdiff_t rx_offset;
class X64DSPAssembler : public Xbyak::CodeGenerator
{
public:
X64DSPAssembler(u8 *code_buffer, size_t size) : Xbyak::CodeGenerator(size, code_buffer) {}
void Compile(struct dsp_t *DSP)
void Compile(DSPState *DSP)
{
this->DSP = DSP;
DEBUG_LOG(AICA_ARM, "DSPAssembler::DSPCompile recompiling for x86/64 at %p", this->getCode());
@ -83,12 +84,12 @@ public:
mov(dword[rbx + dsp_operand(&DSP->FRC_REG)], 0);
xor_(Y_REG, Y_REG);
xor_(ADRS_REG, ADRS_REG);
mov(MDEC_CT, dword[rbx + dsp_operand(&DSP->regs.MDEC_CT)]);
mov(MDEC_CT, dword[rbx + dsp_operand(&DSP->MDEC_CT)]);
for (int step = 0; step < 128; ++step)
{
u32 *mpro = &DSPData->MPRO[step * 4];
_INST op;
Instruction op;
DecodeInst(mpro, &op);
const u32 COEF = step;
@ -131,7 +132,7 @@ public:
mov(B, ACC);
else
{
//B = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
//B = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
mov(eax, MDEC_CT);
if (op.TRA)
add(eax, op.TRA);
@ -150,7 +151,7 @@ public:
X_alias = INPUTS;
else
{
//X = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
//X = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
if (!op.ZERO && !op.BSEL && !op.NEGB)
X_alias = B;
else
@ -247,7 +248,7 @@ public:
if (op.TWT)
{
//DSP->TEMP[(op.TWA + DSP->regs.MDEC_CT) & 0x7F] = SHIFTED;
//DSP->TEMP[(op.TWA + DSP->MDEC_CT) & 0x7F] = SHIFTED;
mov(ecx, MDEC_CT);
if (op.TWA)
add(ecx, op.TWA);
@ -328,13 +329,13 @@ public:
mov(dword[rbp + dspdata_operand(DSPData->EFREG, op.EWA)], edx);
}
}
// DSP->regs.MDEC_CT--
mov(eax, dsp.RBL + 1);
// DSP->MDEC_CT--
mov(eax, DSP->RBL + 1);
sub(MDEC_CT, 1);
//if (dsp.regs.MDEC_CT == 0)
// dsp.regs.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
//if (dsp.MDEC_CT == 0)
// dsp.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
cmove(MDEC_CT, eax);
mov(dword[rbx + dsp_operand(&DSP->regs.MDEC_CT)], MDEC_CT);
mov(dword[rbx + dsp_operand(&DSP->MDEC_CT)], MDEC_CT);
#ifdef _WIN32
add(rsp, 40);
@ -355,14 +356,14 @@ public:
private:
ptrdiff_t dsp_operand(void *data, int index = 0, u32 element_size = 4)
{
return ((u8*)data - (u8*)DSP) - offsetof(dsp_t, TEMP) + index * element_size;
return ((u8*)data - (u8*)DSP) - offsetof(DSPState, TEMP) + index * element_size;
}
ptrdiff_t dspdata_operand(void *data, int index = 0, u32 element_size = 4)
{
return ((u8*)data - (u8*)DSPData) + index * element_size;
}
void CalculateADDR(const Xbyak::Reg32 ADDR, const _INST& op, const Xbyak::Reg32 ADRS_REG, const Xbyak::Reg32 MDEC_CT)
void CalculateADDR(const Xbyak::Reg32 ADDR, const Instruction& op, const Xbyak::Reg32 ADRS_REG, const Xbyak::Reg32 MDEC_CT)
{
//u32 ADDR = DSPData->MADRS[op.MASA];
mov(ADDR, dword[rbp + dspdata_operand(DSPData->MADRS, op.MASA)]);
@ -378,7 +379,7 @@ private:
add(ADDR, 1);
if (!op.TABLE)
{
//ADDR += DSP->regs.MDEC_CT;
//ADDR += DSP->MDEC_CT;
add(ADDR, MDEC_CT);
//ADDR &= DSP->RBL;
// RBL is constant for this program
@ -400,37 +401,32 @@ private:
template<class Ret, class... Params>
void GenCall(Ret(*function)(Params...))
{
call(CC_RX2RW(function));
call(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(function) - rx_offset));
}
struct dsp_t *DSP = nullptr;
DSPState *DSP = nullptr;
};
void dsp_recompile()
void recompile()
{
dsp.Stopped = true;
for (int i = 127; i >= 0; --i)
{
u32 *IPtr = DSPData->MPRO + i * 4;
if (IPtr[0] != 0 || IPtr[1] != 0 || IPtr[2 ]!= 0 || IPtr[3] != 0)
{
dsp.Stopped = false;
break;
}
}
X64DSPAssembler assembler(pCodeBuffer, sizeof(CodeBuffer));
assembler.Compile(&dsp);
assembler.Compile(&state);
}
void dsp_rec_init()
void recInit()
{
#ifdef FEAT_NO_RWX_PAGES
if (!vmem_platform_prepare_jit_block(CodeBuffer, sizeof(CodeBuffer), (void**)&pCodeBuffer, &rx_offset))
#else
if (!vmem_platform_prepare_jit_block(CodeBuffer, sizeof(CodeBuffer), (void**)&pCodeBuffer))
die("mprotect failed in x64 dsp");
#endif
die("vmem_platform_prepare_jit_block failed in x64 dsp");
}
void dsp_rec_step()
void runStep()
{
((void (*)())&pCodeBuffer[0])();
((void (*)())CodeBuffer)();
}
}
#endif

View File

@ -27,8 +27,8 @@
#include "aica_if.h"
#include "hw/mem/_vmem.h"
#define CC_RW2RX(ptr) (ptr)
#define CC_RX2RW(ptr) (ptr)
namespace dsp
{
alignas(4096) static u8 CodeBuffer[32 * 1024]
#if defined(_WIN32)
@ -47,7 +47,7 @@ class X86DSPAssembler : public Xbyak::CodeGenerator
public:
X86DSPAssembler(u8 *code_buffer, size_t size) : Xbyak::CodeGenerator(size, code_buffer) {}
void Compile(struct dsp_t *DSP)
void Compile(DSPState *DSP)
{
this->DSP = DSP;
DEBUG_LOG(AICA_ARM, "X86DSPAssembler::Compile recompiling for x86 at %p", this->getCode());
@ -73,7 +73,7 @@ public:
for (int step = 0; step < 128; ++step)
{
u32 *mpro = &DSPData->MPRO[step * 4];
_INST op;
Instruction op;
DecodeInst(mpro, &op);
const u32 COEF = step;
@ -116,8 +116,8 @@ public:
mov(dword[&DSP->B], ACC);
else
{
//B = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
mov(eax, dword[&DSP->regs.MDEC_CT]);
//B = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
mov(eax, dword[&DSP->MDEC_CT]);
if (op.TRA)
add(eax, op.TRA);
and_(eax, 0x7f);
@ -136,12 +136,12 @@ public:
X_alias = INPUTS;
else
{
//X = DSP->TEMP[(TRA + DSP->regs.MDEC_CT) & 0x7F];
//X = DSP->TEMP[(TRA + DSP->MDEC_CT) & 0x7F];
if (!op.ZERO && !op.BSEL && !op.NEGB)
mov(X, dword[&DSP->B]);
else
{
mov(eax, dword[&DSP->regs.MDEC_CT]);
mov(eax, dword[&DSP->MDEC_CT]);
if (op.TRA)
add(eax, op.TRA);
and_(eax, 0x7f);
@ -233,8 +233,8 @@ public:
if (op.TWT)
{
//DSP->TEMP[(op.TWA + DSP->regs.MDEC_CT) & 0x7F] = SHIFTED;
mov(edx, dword[&DSP->regs.MDEC_CT]);
//DSP->TEMP[(op.TWA + DSP->MDEC_CT) & 0x7F] = SHIFTED;
mov(edx, dword[&DSP->MDEC_CT]);
if (op.TWA)
add(edx, op.TWA);
and_(edx, 0x7f);
@ -265,7 +265,7 @@ public:
{
// *(u16 *)&aica_ram[ADDR & ARAM_MASK] = PACK(SHIFTED);
// SHIFTED is in ecx
call(CC_RW2RX((const void *)PACK));
call((const void *)PACK);
CalculateADDR(ADDR, op);
mov(ecx, (uintptr_t)&aica_ram[0]);
@ -277,7 +277,7 @@ public:
CalculateADDR(ADDR, op);
mov(ecx, (uintptr_t)&aica_ram[0]);
movzx(ecx, word[ecx + ADDR]);
call(CC_RW2RX((const void *)UNPACK));
call((const void *)UNPACK);
mov(dword[&DSP->MEMVAL[(step + 2) & 3]], eax);
}
if (op.MRD || op.MWT)
@ -310,14 +310,14 @@ public:
mov(dword[&DSPData->EFREG[op.EWA]], ecx);
}
}
// DSP->regs.MDEC_CT--
mov(eax, dsp.RBL + 1);
mov(ecx, dword[&DSP->regs.MDEC_CT]);
// DSP->MDEC_CT--
mov(eax, DSP->RBL + 1);
mov(ecx, dword[&DSP->MDEC_CT]);
sub(ecx, 1);
//if (dsp.regs.MDEC_CT == 0)
// dsp.regs.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
//if (dsp.MDEC_CT == 0)
// dsp.MDEC_CT = dsp.RBL + 1; // RBL is ring buffer length - 1
cmove(ecx, eax);
mov(dword[&DSP->regs.MDEC_CT], ecx);
mov(dword[&DSP->MDEC_CT], ecx);
#ifndef _WIN32
// 16-byte alignment
@ -333,7 +333,7 @@ public:
}
private:
void CalculateADDR(const Xbyak::Reg32 ADDR, const _INST& op)
void CalculateADDR(const Xbyak::Reg32 ADDR, const Instruction& op)
{
//u32 ADDR = DSPData->MADRS[op.MASA];
mov(ADDR, dword[&DSPData->MADRS[op.MASA]]);
@ -349,8 +349,8 @@ private:
add(ADDR, 1);
if (!op.TABLE)
{
//ADDR += DSP->regs.MDEC_CT;
add(ADDR, dword[&DSP->regs.MDEC_CT]);
//ADDR += DSP->MDEC_CT;
add(ADDR, dword[&DSP->MDEC_CT]);
//ADDR &= DSP->RBL;
// RBL is constant for this program
and_(ADDR, DSP->RBL);
@ -368,34 +368,25 @@ private:
and_(ADDR, ARAM_MASK);
}
struct dsp_t *DSP = nullptr;
DSPState *DSP = nullptr;
};
void dsp_recompile()
void recompile()
{
dsp.Stopped = true;
for (int i = 127; i >= 0; --i)
{
u32 *IPtr = DSPData->MPRO + i * 4;
if (IPtr[0] != 0 || IPtr[1] != 0 || IPtr[2 ]!= 0 || IPtr[3] != 0)
{
dsp.Stopped = false;
break;
}
}
X86DSPAssembler assembler(pCodeBuffer, sizeof(CodeBuffer));
assembler.Compile(&dsp);
assembler.Compile(&state);
}
void dsp_rec_init()
void recInit()
{
if (!vmem_platform_prepare_jit_block(CodeBuffer, sizeof(CodeBuffer), (void**)&pCodeBuffer))
die("mprotect failed in x86 dsp");
}
void dsp_rec_step()
void runStep()
{
((void (*)())&pCodeBuffer[0])();
((void (*)())CodeBuffer)();
}
}
#endif

View File

@ -711,7 +711,7 @@ struct ChannelEx
//ISEL
void UpdateDSPMIX()
{
VolMix.DSPOut = &dsp.MIXS[ccd->ISEL];
VolMix.DSPOut = &dsp::state.MIXS[ccd->ISEL];
}
//TL,DISDL,DIPAN,IMXL
void UpdateAtts()
@ -1286,12 +1286,12 @@ void sgc_Init()
PLFO_Scales[s][i + 128] = (u32)((1 << 10) * powf(2.0f, limit * i / 128.0f / 1200.0f));
}
dsp_init();
dsp::init();
}
void sgc_Term()
{
dsp_term();
dsp::term();
}
void WriteChannelReg(u32 channel, u32 reg, int size)
@ -1343,11 +1343,12 @@ void ReadCommonReg(u32 reg,bool byte)
void WriteCommonReg8(u32 reg,u32 data)
{
WriteMemArr<1>(aica_reg, reg, data);
if (reg==0x2804 || reg==0x2805)
if (reg == 0x2804 || reg == 0x2805)
{
dsp.RBL = (8192 << CommonData->RBL) - 1;
dsp.RBP = (CommonData->RBP * 2048) & ARAM_MASK;
dsp.dyndirty=true;
using namespace dsp;
state.RBL = (8192 << CommonData->RBL) - 1;
state.RBP = (CommonData->RBP * 2048) & ARAM_MASK;
state.dirty = true;
}
}
@ -1409,7 +1410,7 @@ void AICA_Sample32()
no dsp for now -- needs special handling of oDSP for ch paraller version ...
if (config::DSPEnabled)
{
dsp_step();
dsp::step();
for (int i=0;i<16;i++)
{
@ -1463,7 +1464,7 @@ void AICA_Sample()
SampleType mixl,mixr;
mixl = 0;
mixr = 0;
memset(dsp.MIXS,0,sizeof(dsp.MIXS));
memset(dsp::state.MIXS, 0, sizeof(dsp::state.MIXS));
ChannelEx::StepAll(mixl,mixr);
@ -1491,7 +1492,7 @@ void AICA_Sample()
if (config::DSPEnabled)
{
dsp_step();
dsp::step();
for (int i=0;i<16;i++)
VOLPAN(*(s16*)&DSPData->EFREG[i], dsp_out_vol[i].EFSDL, dsp_out_vol[i].EFPAN, mixl, mixr);

View File

@ -36,9 +36,7 @@ extern bool armFiqEnable;
extern int armMode;
extern bool Arm7Enabled;
//./core/hw/aica/dsp.o
alignas(4096) extern dsp_t dsp;
//./core/hw/aica/aica.o
extern AicaTimer timers[3];
//./core/hw/aica/aica_if.o
@ -263,7 +261,7 @@ bool dc_serialize(void **data, unsigned int *total_size)
REICAST_S(armMode);
REICAST_S(Arm7Enabled);
REICAST_S(dsp); // FIXME could save 32KB
dsp::state.serialize(data, total_size);
for ( i = 0 ; i < 3 ; i++)
{
@ -496,7 +494,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size, seria
REICAST_SKIP(1); // holdState
}
REICAST_US(dsp);
dsp::state.deserialize(data, total_size, version);
for ( i = 0 ; i < 3 ; i++)
{
@ -904,7 +902,7 @@ bool dc_unserialize(void **data, unsigned int *total_size)
if (version < V5)
REICAST_SKIP(256 + 3);
REICAST_US(dsp);
dsp::state.deserialize(data, total_size, version);
for ( i = 0 ; i < 3 ; i++)
{

View File

@ -473,5 +473,6 @@ enum serialize_version_enum {
V15 = 810,
V16 = 811,
V17 = 812,
VCUR_FLYCAST = V17,
V18 = 813,
VCUR_FLYCAST = V18,
};

View File

@ -51,7 +51,6 @@
#include "hw/pvr/spg.h"
#include "hw/naomi/naomi_cart.h"
#include "imgread/common.h"
#include "hw/aica/dsp.h"
#include "LogManager.h"
#include "cheats.h"
#include "rend/CustomTexture.h"

View File

@ -31,7 +31,7 @@ TEST_F(SerializeTest, SizeTest)
unsigned int total_size = 0;
void *data = nullptr;
ASSERT_TRUE(dc_serialize(&data, &total_size));
ASSERT_EQ(28220759u, total_size);
ASSERT_EQ(28187879u, total_size);
}