dsp: map TEMP/MEMS/MIXS regs to sh4 and aica address space. Clean up
This commit is contained in:
parent
2a849ccba5
commit
ca17717af7
|
@ -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;
|
||||
|
|
|
@ -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*)®base[0x2890 + timer*4];
|
||||
|
@ -334,6 +336,7 @@ public:
|
|||
m_step=1<<(data->md);
|
||||
c_step=m_step;
|
||||
}
|
||||
|
||||
void StepTimer(u32 samples)
|
||||
{
|
||||
do
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -473,5 +473,6 @@ enum serialize_version_enum {
|
|||
V15 = 810,
|
||||
V16 = 811,
|
||||
V17 = 812,
|
||||
VCUR_FLYCAST = V17,
|
||||
V18 = 813,
|
||||
VCUR_FLYCAST = V18,
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue