DSPLLE: attempt to fix extended ops please review this patch carefully.

thinks to note
- All ext commands should call zeroWriteBackLog() (before changing any 
reg)
- increase/decrease ar functions now only return a value not actually 
change anything


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4018 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-08-19 21:37:24 +00:00
parent 8155439dd1
commit b787f5f8f7
9 changed files with 340 additions and 266 deletions

View file

@ -40,20 +40,18 @@ namespace DSPInterpreter
namespace Ext
{
u16 cache1;
// DR $arR
// xxxx xxxx 0000 01rr
// Decrement addressing register $arR.
void dr(const UDSPInstruction& opc) {
dsp_decrement_addr_reg(opc.hex & 0x3);
writeToBackLog(0, opc.hex & 0x3, dsp_decrement_addr_reg(opc.hex & 0x3));
}
// IR $arR
// xxxx xxxx 0000 10rr
// Increment addressing register $arR.
void ir(const UDSPInstruction& opc) {
dsp_increment_addr_reg(opc.hex & 0x3);
writeToBackLog(0, opc.hex & 0x3, dsp_increment_addr_reg(opc.hex & 0x3));
}
// NR $arR
@ -61,8 +59,8 @@ void ir(const UDSPInstruction& opc) {
// Add corresponding indexing register $ixR to addressing register $arR.
void nr(const UDSPInstruction& opc) {
u8 reg = opc.hex & 0x3;
dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
writeToBackLog(0, reg, dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]));
}
// MV $axD, $acS.l
@ -71,19 +69,11 @@ void nr(const UDSPInstruction& opc) {
void mv(const UDSPInstruction& opc)
{
u8 sreg = opc.hex & 0x3;
cache1 = g_dsp.r[sreg + DSP_REG_ACC0];
currentEpilogeFunc = mv_epi;
u8 dreg = ((opc.hex >> 2) & 0x3);
writeToBackLog(0, dreg + DSP_REG_AXL0, g_dsp.r[sreg + DSP_REG_ACC0]);
}
void mv_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 2) & 0x3);
g_dsp.r[dreg + DSP_REG_AXL0] = cache1;
}
// S @$D, $acD.l
// xxxx xxxx 001s s0dd
// Store value of $(acS.l) in the memory pointed by register $D.
@ -94,15 +84,7 @@ void s(const UDSPInstruction& opc)
u8 sreg = ((opc.hex >> 3) & 0x3) + DSP_REG_ACC0;
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
currentEpilogeFunc = s_epi;
}
void s_epi(const UDSPInstruction& opc)
{
u8 dreg = opc.hex & 0x3;
dsp_increment_addr_reg(dreg);
writeToBackLog(0, dreg, dsp_increment_addr_reg(dreg));
}
// SN @$D, $acD.l
@ -116,14 +98,7 @@ void sn(const UDSPInstruction& opc)
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
currentEpilogeFunc = sn_epi;
}
void sn_epi(const UDSPInstruction& opc)
{
u8 dreg = opc.hex & 0x3;
dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
writeToBackLog(0, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]));
}
// L axD.l, @$S
@ -133,18 +108,10 @@ void sn_epi(const UDSPInstruction& opc)
void l(const UDSPInstruction& opc)
{
u8 sreg = opc.hex & 0x3;
cache1 = dsp_dmem_read(g_dsp.r[sreg]);
currentEpilogeFunc = l_epi;
}
void l_epi(const UDSPInstruction& opc) {
u8 sreg = opc.hex & 0x3;
u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0;
g_dsp.r[dreg] = cache1;
dsp_increment_addr_reg(sreg);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg));
}
// LN axD.l, @$S
@ -156,17 +123,8 @@ void ln(const UDSPInstruction& opc)
u8 sreg = opc.hex & 0x3;
u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0;
cache1 = dsp_dmem_read(g_dsp.r[sreg]);
currentEpilogeFunc = ln_epi;
}
void ln_epi(const UDSPInstruction& opc)
{
u8 sreg = opc.hex & 0x3;
u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0;
g_dsp.r[dreg] = cache1;
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
}
// LS $axD.l, $acS.m
@ -178,20 +136,15 @@ void ls(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
u8 sreg = 0x03;
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]);
dsp_increment_addr_reg(sreg);
currentEpilogeFunc = ls_epi;
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00]));
writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg));
writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00));
}
void ls_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
u16 val = dsp_dmem_read(g_dsp.r[0x00]);
dsp_op_write_reg(dreg, val);
dsp_increment_addr_reg(0x00);
}
// LSN $acD.l, $acS.m
// xxxx xxxx 10dd 010s
@ -203,19 +156,13 @@ void lsn(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
u8 sreg = 0x03;
dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]);
dsp_increment_addr_reg(sreg);
currentEpilogeFunc = lsn_epi;
}
void lsn_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
u16 val = dsp_dmem_read(g_dsp.r[0x00]);
dsp_op_write_reg(dreg, val);
dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]);
dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00]));
writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg));
writeToBackLog(2, 0x00,dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]));
}
// LSM $acD.l, $acS.m
@ -228,20 +175,13 @@ void lsm(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
u8 sreg = 0x03;
dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]);
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
currentEpilogeFunc = lsm_epi;
}
void lsm_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
u16 val = dsp_dmem_read(g_dsp.r[0x00]);
dsp_op_write_reg(dreg, val);
dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]);
dsp_increment_addr_reg(0x00);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00]));
writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00));
}
// LSMN $acD.l, $acS.m
@ -255,20 +195,13 @@ void lsnm(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
u8 sreg = 0x03;
dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]);
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
currentEpilogeFunc = lsnm_epi;
}
void lsnm_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
u16 val = dsp_dmem_read(g_dsp.r[0x00]);
dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]);
dsp_op_write_reg(dreg, val);
dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00]));
writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
writeToBackLog(2, 0x00, dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]));
}
// SL $acS.m, $acD.l
@ -279,20 +212,14 @@ void lsnm_epi(const UDSPInstruction& opc)
void sl(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
const u8 sreg = 0x03;
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
dsp_increment_addr_reg(0x00);
currentEpilogeFunc = sl_epi;
}
void sl_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18;
const u8 sreg = 0x03;
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
dsp_op_write_reg(dreg, val);
dsp_increment_addr_reg(sreg);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg));
writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00));
}
// SLN $acS.m, $acD.l
@ -304,20 +231,14 @@ void sl_epi(const UDSPInstruction& opc)
void sln(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
const u8 sreg = 0x03;
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]);
currentEpilogeFunc = sln_epi;
}
void sln_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18;
const u8 sreg = 0x03;
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
dsp_op_write_reg(dreg, val);
dsp_increment_addr_reg(sreg);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg));
writeToBackLog(2, 0x00, dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]));
}
// SLM $acS.m, $acD.l
@ -329,20 +250,14 @@ void sln_epi(const UDSPInstruction& opc)
void slm(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
dsp_increment_addr_reg(0x00);
currentEpilogeFunc = slm_epi;
}
void slm_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18;
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
const u8 sreg = 0x03;
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
dsp_op_write_reg(dreg, val);
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00));
}
// SLMN $acS.m, $acD.l
@ -354,21 +269,14 @@ void slm_epi(const UDSPInstruction& opc)
void slnm(const UDSPInstruction& opc)
{
u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0;
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]);
currentEpilogeFunc = slnm_epi;
}
void slnm_epi(const UDSPInstruction& opc)
{
u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18;
u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0;
const u8 sreg = 0x03;
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
dsp_op_write_reg(dreg, val);
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
writeToBackLog(2, 0x00, dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]));
}
// Not in duddie's doc
@ -381,18 +289,16 @@ void ld(const UDSPInstruction& opc)
u8 sreg = opc.hex & 0x3;
if (sreg != 0x03) {
g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]);
dsp_increment_addr_reg(sreg);
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
} else {
g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]);
g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]);
dsp_increment_addr_reg(dreg);
writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
}
dsp_increment_addr_reg(DSP_REG_AR3);
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
}
// Not in duddie's doc
@ -403,20 +309,18 @@ void ldn(const UDSPInstruction& opc)
u8 dreg = (opc.hex >> 5) & 0x1;
u8 rreg = (opc.hex >> 4) & 0x1;
u8 sreg = opc.hex & 0x3;
if (sreg != 0x03) {
g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]);
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
} else {
g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]);
g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]);
dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]));
}
dsp_increment_addr_reg(DSP_REG_AR3);
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
}
@ -430,18 +334,17 @@ void ldm(const UDSPInstruction& opc)
u8 sreg = opc.hex & 0x3;
if (sreg != 0x03) {
g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]);
dsp_increment_addr_reg(sreg);
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
} else {
g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]);
g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]);
dsp_increment_addr_reg(dreg);
writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
}
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3]);
writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3]));
}
// Not in duddie's doc
@ -454,20 +357,20 @@ void ldnm(const UDSPInstruction& opc)
u8 sreg = opc.hex & 0x3;
if (sreg != 0x03) {
g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]);
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
} else {
g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]);
g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]);
dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]));
}
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3]);
writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3]));
}
void nop(const UDSPInstruction& opc)
{
}
@ -475,4 +378,21 @@ void nop(const UDSPInstruction& opc)
} // end namespace ext
} // end namespace DSPInterpeter
void applyWriteBackLog()
{
for (int i=0;i < WRITEBACKLOGSIZE;i++) {
if (writeBackLogIdx[i] != -1) {
dsp_op_write_reg(writeBackLogIdx[i], g_dsp.r[writeBackLogIdx[i]] | writeBackLog[i]);
// Clear back log
writeBackLogIdx[i] = -1;
}
}
}
void zeroWriteBackLog()
{
for (int i=0;i < WRITEBACKLOGSIZE;i++)
if (writeBackLogIdx[i] != -1)
dsp_op_write_reg(writeBackLogIdx[i], 0);
}

View file

@ -39,9 +39,7 @@ namespace DSPInterpreter
namespace Ext
{
void l(const UDSPInstruction& opc);
void l_epi(const UDSPInstruction& opc);
void ln(const UDSPInstruction& opc);
void ln_epi(const UDSPInstruction& opc);
void ls(const UDSPInstruction& opc);
void lsn(const UDSPInstruction& opc);
void lsm(const UDSPInstruction& opc);
@ -52,22 +50,11 @@ void slm(const UDSPInstruction& opc);
void slnm(const UDSPInstruction& opc);
void s(const UDSPInstruction& opc);
void sn(const UDSPInstruction& opc);
void ls_epi(const UDSPInstruction& opc);
void lsn_epi(const UDSPInstruction& opc);
void lsm_epi(const UDSPInstruction& opc);
void lsnm_epi(const UDSPInstruction& opc);
void sl_epi(const UDSPInstruction& opc);
void sln_epi(const UDSPInstruction& opc);
void slm_epi(const UDSPInstruction& opc);
void slnm_epi(const UDSPInstruction& opc);
void s_epi(const UDSPInstruction& opc);
void sn_epi(const UDSPInstruction& opc);
void ld(const UDSPInstruction& opc);
void ldn(const UDSPInstruction& opc);
void ldm(const UDSPInstruction& opc);
void ldnm(const UDSPInstruction& opc);
void mv(const UDSPInstruction& opc);
void mv_epi(const UDSPInstruction& opc);
void dr(const UDSPInstruction& opc);
void ir(const UDSPInstruction& opc);
void nr(const UDSPInstruction& opc);
@ -76,4 +63,10 @@ void nop(const UDSPInstruction& opc);
} // end namespace Ext
} // end namespace DSPinterpeter
inline void writeToBackLog(int i, int idx, u16 value)
{
writeBackLog[i] = value;
writeBackLogIdx[i] = idx;
}
#endif

View file

@ -58,37 +58,57 @@ inline u16 ToMask(u16 a)
return a | (a >> 1);
}
inline void dsp_increment_addr_reg(int reg)
inline u16 dsp_increment_addr_reg(int reg, int value = -1)
{
u16 tmb = ToMask(g_dsp.r[DSP_REG_WR0 + reg]);
if ((g_dsp.r[reg] & tmb) == tmb)
g_dsp.r[reg] ^= g_dsp.r[DSP_REG_WR0 + reg];
u16 tmp;
if (value == -1)
tmp = g_dsp.r[reg];
else
g_dsp.r[reg]++;
tmp = value;
if ((tmp & tmb) == tmb)
tmp ^= g_dsp.r[DSP_REG_WR0 + reg];
else
tmp++;
return tmp;
}
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125
inline void dsp_decrement_addr_reg(int reg)
inline u16 dsp_decrement_addr_reg(int reg, int value = -1)
{
// This one is easy. Looks like a hw implementation. Increment is worse...
if ((g_dsp.r[reg] & g_dsp.r[DSP_REG_WR0 + reg]) == 0)
g_dsp.r[reg] |= g_dsp.r[DSP_REG_WR0 + reg];
u16 tmp;
if (value == -1)
tmp = g_dsp.r[reg];
else
g_dsp.r[reg]--;
tmp = value;
// This one is easy. Looks like a hw implementation. Increment is worse...
if ((tmp & g_dsp.r[DSP_REG_WR0 + reg]) == 0)
tmp |= g_dsp.r[DSP_REG_WR0 + reg];
else
tmp--;
return tmp;
}
inline void dsp_increase_addr_reg(int reg, s16 value)
inline u16 dsp_increase_addr_reg(int reg, s16 value)
{
u16 tmp = - 1;
// TODO: DO RIGHT!
if (value > 0) {
for (int i = 0; i < value; i++) {
dsp_increment_addr_reg(reg);
tmp = dsp_increment_addr_reg(reg, tmp);
}
} else if (value < 0) {
for (int i = 0; i < (int)(-value); i++) {
dsp_decrement_addr_reg(reg);
tmp = dsp_decrement_addr_reg(reg, tmp);
}
}
return tmp;
}

View file

@ -498,8 +498,8 @@ u8 opSize[OPTABLE_SIZE];
dspInstFunc opTable[OPTABLE_SIZE];
dspInstFunc extOpTable[EXT_OPTABLE_SIZE];
bool opTableUseExt[OPTABLE_SIZE];
dspInstFunc currentEpilogeFunc = NULL;
u16 writeBackLog[WRITEBACKLOGSIZE];
int writeBackLogIdx[WRITEBACKLOGSIZE];
const char* pdname(u16 val)
{
@ -577,10 +577,6 @@ void InitInstructionTable()
for (int j = 0; j < opcodes_size; j++)
{
u16 mask = opcodes[j].opcode_mask;
// if (opcodes[j].size & P_EXT) {
// Ignore extension bits.
// mask &= 0xFF00;
// }
if ((mask & i) == opcodes[j].opcode)
{
if (opTable[i] == DSPInterpreter::unknown)
@ -596,4 +592,7 @@ void InitInstructionTable()
}
}
}
for (int i=0; i < WRITEBACKLOGSIZE; i++)
writeBackLogIdx[i] = -1;
}

View file

@ -128,11 +128,13 @@ extern const int opcodes_ext_size;
extern u8 opSize[OPTABLE_SIZE];
extern const DSPOPCTemplate cw;
#define WRITEBACKLOGSIZE 7
extern dspInstFunc opTable[];
extern bool opTableUseExt[OPTABLE_SIZE];
extern dspInstFunc extOpTable[EXT_OPTABLE_SIZE];
extern dspInstFunc currentEpilogeFunc;
extern u16 writeBackLog[WRITEBACKLOGSIZE];
extern int writeBackLogIdx[WRITEBACKLOGSIZE];
// Predefined labels
struct pdlabel_t
@ -151,15 +153,16 @@ const char *pdregname(int val);
const char *pdregnamelong(int val);
void InitInstructionTable();
void applyWriteBackLog();
void zeroWriteBackLog();
inline void ExecuteInstruction(const UDSPInstruction& inst)
{
if (opTableUseExt[inst.hex])
extOpTable[inst.hex & 0xFF](inst);
opTable[inst.hex](inst);
if (currentEpilogeFunc) {
currentEpilogeFunc(inst);
currentEpilogeFunc = NULL;
if (opTableUseExt[inst.hex]) {
applyWriteBackLog();
}
}

View file

@ -33,8 +33,8 @@ void clr(const UDSPInstruction& opc)
u8 reg = (opc.hex >> 11) & 0x1;
dsp_set_long_acc(reg, 0);
Update_SR_Register64((s64)0); // really?
zeroWriteBackLog();
}
// CLRL $acR.l
@ -48,6 +48,7 @@ void clrl(const UDSPInstruction& opc)
// Should this be 64bit?
// nakee: it says the whole reg in duddie's doc sounds weird
Update_SR_Register64((s64)reg);
zeroWriteBackLog();
}
@ -64,8 +65,9 @@ void addaxl(const UDSPInstruction& opc)
acc += acx;
dsp_set_long_acc(dreg, acc);
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
}
@ -78,6 +80,7 @@ void tstaxh(const UDSPInstruction& opc)
s16 val = dsp_get_ax_h(reg);
Update_SR_Register16(val);
zeroWriteBackLog();
}
// SUB $acD, $ac(1-D)
@ -91,8 +94,9 @@ void sub(const UDSPInstruction& opc)
acc1 -= acc2;
dsp_set_long_acc(D, acc1);
zeroWriteBackLog();
dsp_set_long_acc(D, acc1);
Update_SR_Register64(acc1);
}
@ -110,8 +114,9 @@ void movr(const UDSPInstruction& opc)
acc <<= 16;
acc &= ~0xffff;
dsp_set_long_acc(areg, acc);
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
}
@ -124,8 +129,10 @@ void movax(const UDSPInstruction& opc)
u8 sreg = (opc.hex >> 9) & 0x1;
s64 acx = dsp_get_long_acx(sreg);
dsp_set_long_acc(dreg, acx);
zeroWriteBackLog();
dsp_set_long_acc(dreg, acx);
Update_SR_Register64(acx);
}
@ -138,6 +145,8 @@ void xorr(const UDSPInstruction& opc)
u8 sreg = (opc.hex >> 9) & 0x1;
u8 dreg = (opc.hex >> 8) & 0x1;
zeroWriteBackLog();
g_dsp.r[DSP_REG_ACM0 + dreg] ^= g_dsp.r[DSP_REG_AXH0 + sreg];
s64 acc = dsp_get_long_acc(dreg);
@ -153,10 +162,11 @@ void andr(const UDSPInstruction& opc)
u8 sreg = (opc.hex >> 9) & 0x1;
u8 dreg = (opc.hex >> 8) & 0x1;
zeroWriteBackLog();
g_dsp.r[DSP_REG_ACM0 + dreg] &= g_dsp.r[DSP_REG_AXH0 + sreg];
s64 acc = dsp_get_long_acc(dreg);
Update_SR_Register64(acc);
}
@ -169,10 +179,11 @@ void orr(const UDSPInstruction& opc)
u8 sreg = (opc.hex >> 9) & 0x1;
u8 dreg = (opc.hex >> 8) & 0x1;
zeroWriteBackLog();
g_dsp.r[DSP_REG_ACM0 + dreg] |= g_dsp.r[DSP_REG_AXH0 + sreg];
s64 acc = dsp_get_long_acc(dreg);
Update_SR_Register64(acc);
}
@ -184,6 +195,9 @@ void orr(const UDSPInstruction& opc)
void andc(const UDSPInstruction& opc)
{
u8 D = (opc.hex >> 8) & 0x1;
zeroWriteBackLog();
g_dsp.r[DSP_REG_ACM0+D] &= dsp_get_acc_m(1-D);
Update_SR_Register16(dsp_get_acc_m(D));
@ -197,6 +211,9 @@ void andc(const UDSPInstruction& opc)
void orc(const UDSPInstruction& opc)
{
u8 D = (opc.hex >> 8) & 0x1;
zeroWriteBackLog();
g_dsp.r[DSP_REG_ACM0+D] |= dsp_get_acc_m(1-D);
Update_SR_Register16(dsp_get_acc_m(D));
@ -220,6 +237,8 @@ void andcf(const UDSPInstruction& opc)
u16 val = dsp_get_acc_m(reg);
Update_SR_LZ(((val & imm) == imm) ? 0 : 1);
zeroWriteBackLog();
}
// Hermes switched andf and andcf, so check to make sure they are still correct
@ -237,6 +256,8 @@ void andf(const UDSPInstruction& opc)
u16 val = dsp_get_acc_m(reg);
Update_SR_LZ(((val & imm) == 0) ? 0 : 1);
zeroWriteBackLog();
}
// CMPI $amD, #I
@ -252,6 +273,8 @@ void cmpi(const UDSPInstruction& opc)
s64 imm = (s64)(s16)dsp_fetch_code() << 16;
s64 val = dsp_get_long_acc(reg);
Update_SR_Register64(val - imm);
zeroWriteBackLog();
}
// XORI $acD.m, #I
@ -263,6 +286,9 @@ void xori(const UDSPInstruction& opc)
{
u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
u16 imm = dsp_fetch_code();
zeroWriteBackLog();
g_dsp.r[reg] ^= imm;
Update_SR_Register16((s16)g_dsp.r[reg]);
@ -276,13 +302,14 @@ void andi(const UDSPInstruction& opc)
{
u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
u16 imm = dsp_fetch_code();
zeroWriteBackLog();
g_dsp.r[reg] &= imm;
Update_SR_Register16((s16)g_dsp.r[reg]);
}
// F|RES: i am not sure if this shouldnt be the whole ACC
// ORI $acD.m, #I
// 0000 001r 0110 0000
// iiii iiii iiii iiii
@ -291,6 +318,8 @@ void ori(const UDSPInstruction& opc)
{
u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1);
u16 imm = dsp_fetch_code();
zeroWriteBackLog();
g_dsp.r[reg] |= imm;
Update_SR_Register16((s16)g_dsp.r[reg]);
@ -310,6 +339,7 @@ void add(const UDSPInstruction& opc)
s64 res = acc0 + acc1;
zeroWriteBackLog();
dsp_set_long_acc(areg, res);
Update_SR_Register64(res);
@ -323,6 +353,8 @@ void addp(const UDSPInstruction& opc)
u8 dreg = (opc.hex >> 8) & 0x1;
s64 acc = dsp_get_long_acc(dreg);
acc += dsp_get_long_prod();
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -336,6 +368,8 @@ void subp(const UDSPInstruction& opc)
u8 dreg = (opc.hex >> 8) & 0x1;
s64 acc = dsp_get_long_acc(dreg);
acc -= dsp_get_long_prod();
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -358,6 +392,7 @@ void cmpis(const UDSPInstruction& opc)
s64 res = acc - val;
Update_SR_Register64(res);
zeroWriteBackLog();
}
@ -371,6 +406,8 @@ void decm(const UDSPInstruction& opc)
s64 sub = 0x10000;
s64 acc = dsp_get_long_acc(dreg);
acc -= sub;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -384,6 +421,8 @@ void dec(const UDSPInstruction& opc)
u8 dreg = (opc.hex >> 8) & 0x01;
s64 acc = dsp_get_long_acc(dreg) - 1;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -399,6 +438,8 @@ void incm(const UDSPInstruction& opc)
s64 sub = 0x10000;
s64 acc = dsp_get_long_acc(dreg);
acc += sub;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -412,6 +453,8 @@ void inc(const UDSPInstruction& opc)
u8 dreg = (opc.hex >> 8) & 0x1;
s64 acc = dsp_get_long_acc(dreg) + 1;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -426,6 +469,8 @@ void neg(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(areg);
acc = 0 - acc;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
@ -438,6 +483,8 @@ void mov(const UDSPInstruction& opc)
{
u8 D = (opc.hex >> 8) & 0x1;
u64 acc = dsp_get_long_acc(1 - D);
zeroWriteBackLog();
dsp_set_long_acc(D, acc);
Update_SR_Register64(acc);
@ -454,6 +501,8 @@ void addax(const UDSPInstruction& opc)
s64 ax = dsp_get_long_acx(sreg);
s64 acc = dsp_get_long_acc(areg);
acc += ax;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
@ -472,6 +521,8 @@ void addr(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(areg);
acc += ax;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
@ -490,6 +541,8 @@ void subr(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(areg);
acc -= ax;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
@ -505,6 +558,7 @@ void subax(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(regD) - dsp_get_long_acx(regS);
zeroWriteBackLog();
dsp_set_long_acc(regD, acc);
Update_SR_Register64(acc);
}
@ -520,6 +574,8 @@ void addis(const UDSPInstruction& opc)
Imm <<= 16;
s64 acc = dsp_get_long_acc(areg);
acc += Imm;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
@ -537,6 +593,8 @@ void addi(const UDSPInstruction& opc)
sub <<= 16;
s64 acc = dsp_get_long_acc(areg);
acc += sub;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
@ -551,6 +609,8 @@ void lsl16(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(areg);
acc <<= 16;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
}
@ -565,6 +625,8 @@ void lsr16(const UDSPInstruction& opc)
u64 acc = dsp_get_long_acc(areg);
acc >>= 16;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
}
@ -579,6 +641,8 @@ void asr16(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(areg);
acc >>= 16;
zeroWriteBackLog();
dsp_set_long_acc(areg, acc);
Update_SR_Register64(acc);
@ -593,6 +657,8 @@ void lsl(const UDSPInstruction& opc)
u64 acc = dsp_get_long_acc(opc.areg);
acc <<= shift;
zeroWriteBackLog();
dsp_set_long_acc(opc.areg, acc);
Update_SR_Register64(acc);
}
@ -608,6 +674,8 @@ void lsr(const UDSPInstruction& opc)
// Lop off the extraneous sign extension our 64-bit fake accum causes
acc &= 0x000000FFFFFFFFFFULL;
acc >>= shift;
zeroWriteBackLog();
dsp_set_long_acc(opc.areg, (s64)acc);
Update_SR_Register64(acc);
}
@ -623,6 +691,7 @@ void asl(const UDSPInstruction& opc)
u64 acc = dsp_get_long_acc(opc.areg);
acc <<= shift;
zeroWriteBackLog();
dsp_set_long_acc(opc.areg, acc);
Update_SR_Register64(acc);
@ -640,6 +709,7 @@ void asr(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(opc.areg);
acc >>= shift;
zeroWriteBackLog();
dsp_set_long_acc(opc.areg, acc);
Update_SR_Register64(acc);
@ -662,6 +732,7 @@ void lsrn(const UDSPInstruction& opc)
} else if (shift < 0) {
acc <<= -shift;
}
zeroWriteBackLog();
dsp_set_long_acc(0, (s64)acc);
Update_SR_Register64(acc);
}
@ -680,6 +751,7 @@ void asrn(const UDSPInstruction& opc)
} else if (shift < 0) {
acc <<= -shift;
}
zeroWriteBackLog();
dsp_set_long_acc(0, acc);
Update_SR_Register64(acc);
}
@ -699,6 +771,7 @@ void lsrnr(const UDSPInstruction& opc)
} else if (shift < 0) {
acc >>= -shift;
}
zeroWriteBackLog();
dsp_set_long_acc(sreg, acc);
Update_SR_Register64(acc);
}
@ -719,6 +792,7 @@ void cmpar(const UDSPInstruction& opc)
s64 sr = dsp_get_long_acc(sreg);
Update_SR_Register64(sr - rr);
zeroWriteBackLog();
}
@ -731,6 +805,7 @@ void cmp(const UDSPInstruction& opc)
s64 acc1 = dsp_get_long_acc(1);
Update_SR_Register64(acc0 - acc1);
zeroWriteBackLog();
}
// TST
@ -742,6 +817,7 @@ void tst(const UDSPInstruction& opc)
s64 acc = dsp_get_long_acc(reg);
Update_SR_Register64(acc);
zeroWriteBackLog();
}
} // namespace

View file

@ -115,7 +115,7 @@ void lrrd(const UDSPInstruction& opc)
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
dsp_op_write_reg(dreg, val);
dsp_conditional_extend_accum(dreg);
dsp_decrement_addr_reg(sreg);
g_dsp.r[sreg] = dsp_decrement_addr_reg(sreg);
}
// LRRI $D, @$S
@ -131,7 +131,7 @@ void lrri(const UDSPInstruction& opc)
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
dsp_op_write_reg(dreg, val);
dsp_conditional_extend_accum(dreg);
dsp_increment_addr_reg(sreg);
g_dsp.r[sreg] = dsp_increment_addr_reg(sreg);
}
// LRRN $D, @$S
@ -147,7 +147,7 @@ void lrrn(const UDSPInstruction& opc)
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
dsp_op_write_reg(dreg, val);
dsp_conditional_extend_accum(dreg);
dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
g_dsp.r[sreg] = dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
}
// SRR @$D, $S
@ -176,7 +176,7 @@ void srrd(const UDSPInstruction& opc)
u16 val = dsp_op_read_reg(sreg);
dsp_dmem_write(g_dsp.r[dreg], val);
dsp_decrement_addr_reg(dreg);
g_dsp.r[sreg] = dsp_decrement_addr_reg(dreg);
}
// SRRI @$D, $S
@ -191,7 +191,7 @@ void srri(const UDSPInstruction& opc)
u16 val = dsp_op_read_reg(sreg);
dsp_dmem_write(g_dsp.r[dreg], val);
dsp_increment_addr_reg(dreg);
g_dsp.r[dreg] = dsp_increment_addr_reg(dreg);
}
// SRRN @$D, $S
@ -206,7 +206,7 @@ void srrn(const UDSPInstruction& opc)
u16 val = dsp_op_read_reg(sreg);
dsp_dmem_write(g_dsp.r[dreg], val);
dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
}
// ILRR $acD.m, @$arS
@ -234,7 +234,7 @@ void ilrrd(const UDSPInstruction& opc)
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
dsp_conditional_extend_accum(dreg);
dsp_decrement_addr_reg(reg);
g_dsp.r[reg] = dsp_decrement_addr_reg(reg);
}
// ILRRI $acD.m, @$S
@ -248,7 +248,7 @@ void ilrri(const UDSPInstruction& opc)
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
dsp_increment_addr_reg(reg);
g_dsp.r[reg] = dsp_increment_addr_reg(reg);
}
// ILRRN $acD.m, @$arS
@ -263,7 +263,7 @@ void ilrrn(const UDSPInstruction& opc)
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
dsp_conditional_extend_accum(dreg);
dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
g_dsp.r[reg] = dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
}
} // namespace

View file

@ -97,7 +97,7 @@ void addarn(const UDSPInstruction& opc)
u8 dreg = opc.hex & 0x3;
u8 sreg = (opc.hex >> 2) & 0x3;
dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
// It is critical for the Zelda ucode that this one wraps correctly.
}
@ -107,6 +107,7 @@ void addarn(const UDSPInstruction& opc)
// No operation, but can be extended with extended opcode.
void nx(const UDSPInstruction& opc)
{
zeroWriteBackLog();
// This opcode is supposed to do nothing - it's used if you want to use
// an opcode extension but not do anything. At least according to duddie.
}
@ -117,7 +118,7 @@ void nx(const UDSPInstruction& opc)
// Decrement address register $arD.
void dar(const UDSPInstruction& opc)
{
dsp_decrement_addr_reg(opc.hex & 0x3);
g_dsp.r[opc.hex & 0x3] = dsp_decrement_addr_reg(opc.hex & 0x3);
}
// IAR $arD ?
@ -125,7 +126,7 @@ void dar(const UDSPInstruction& opc)
// Increment address register $arD.
void iar(const UDSPInstruction& opc)
{
dsp_increment_addr_reg(opc.hex & 0x3);
g_dsp.r[opc.hex & 0x3] = dsp_increment_addr_reg(opc.hex & 0x3);
}
// SBCLR #I
@ -153,6 +154,7 @@ void sbset(const UDSPInstruction& opc)
// but it's harder to know exactly what effect they have.
void srbith(const UDSPInstruction& opc)
{
zeroWriteBackLog();
switch ((opc.hex >> 8) & 0xf)
{
// M0/M2 change the multiplier mode (it can multiply by 2 for free).

View file

@ -103,6 +103,7 @@ void clrp(const UDSPInstruction& opc)
{
// Magic numbers taken from duddie's doc
// These are probably a bad idea to put here.
zeroWriteBackLog();
g_dsp.r[0x14] = 0x0000;
g_dsp.r[0x15] = 0xfff0;
g_dsp.r[0x16] = 0x00ff;
@ -117,6 +118,7 @@ void movp(const UDSPInstruction& opc)
u8 dreg = (opc.hex >> 8) & 0x1;
s64 prod = dsp_get_long_prod();
zeroWriteBackLog();
dsp_set_long_acc(dreg, prod);
Update_SR_Register64(prod);
@ -132,6 +134,7 @@ void movnp(const UDSPInstruction& opc)
s64 prod = dsp_get_long_prod();
s64 acc = -prod;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -150,6 +153,7 @@ void addpaxz(const UDSPInstruction& opc)
s64 ax = dsp_get_long_acx(sreg);
s64 acc = (prod + ax) & ~0xffff;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -166,6 +170,8 @@ void movpz(const UDSPInstruction& opc)
// overwrite acc and clear low part
s64 prod = dsp_get_long_prod();
s64 acc = prod & ~0xffff;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc);
@ -180,7 +186,12 @@ void mulc(const UDSPInstruction& opc)
{
u8 sreg = (opc.hex >> 11) & 0x1;
u8 treg = (opc.hex >> 12) & 0x1;
s64 prod = dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
u16 accm = dsp_get_acc_m(sreg);
u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
s64 prod = dsp_multiply(accm, axh);
Update_SR_Register64(prod);
}
@ -198,8 +209,13 @@ void mulcmvz(const UDSPInstruction& opc)
// update prod
u8 sreg = (opc.hex >> 12) & 0x1;
u8 treg = (opc.hex >> 11) & 0x1;
dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
u16 accm = dsp_get_acc_m(sreg);
u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
dsp_multiply(accm, axh);
// update acc
u8 rreg = (opc.hex >> 8) & 0x1;
s64 acc = TempProd & ~0xffff; // clear lower 4 bytes
@ -221,7 +237,12 @@ void mulcmv(const UDSPInstruction& opc)
// update prod
u8 sreg = (opc.hex >> 12) & 0x1;
u8 treg = (opc.hex >> 11) & 0x1;
dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
u16 accm = dsp_get_acc_m(sreg);
u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
dsp_multiply(accm, axh);
// update acc
u8 rreg = (opc.hex >> 8) & 0x1;
@ -242,7 +263,12 @@ void mulcac(const UDSPInstruction& opc)
// update prod
u8 sreg = (opc.hex >> 12) & 0x1;
u8 treg = (opc.hex >> 11) & 0x1;
dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
u16 accm = dsp_get_acc_m(sreg);
u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
dsp_multiply(accm, axh);
// update acc
u8 rreg = (opc.hex >> 8) & 0x1;
@ -260,7 +286,12 @@ void mulcac(const UDSPInstruction& opc)
void mul(const UDSPInstruction& opc)
{
u8 sreg = (opc.hex >> 11) & 0x1;
s64 prod = dsp_multiply(dsp_get_ax_h(sreg), dsp_get_ax_l(sreg));
u16 axl = dsp_get_ax_l(sreg);
u16 axh = dsp_get_ax_h(sreg);
zeroWriteBackLog();
s64 prod = dsp_multiply(axh, axl);
// FIXME: no update in duddie's docs
Update_SR_Register64(prod);
}
@ -274,12 +305,19 @@ void mulac(const UDSPInstruction& opc)
{
// add old prod to acc
u8 rreg = (opc.hex >> 8) & 0x1;
u8 sreg = (opc.hex >> 11) & 0x1;
s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
u16 axl = dsp_get_ax_l(sreg);
u16 axh = dsp_get_ax_h(sreg);
zeroWriteBackLog();
dsp_set_long_acc(rreg, acR);
// calculate new prod
u8 sreg = (opc.hex >> 11) & 0x1;
s64 prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
s64 prod = dsp_multiply(axl, axh);
// FIXME: no update in duddie's docs
Update_SR_Register64(prod);
@ -296,9 +334,13 @@ void mulmv(const UDSPInstruction& opc)
u8 sreg = ((opc.hex >> 11) & 0x1);
s64 prod = dsp_get_long_prod();
s64 acc = prod;
u16 axl = dsp_get_ax_l(sreg);
u16 axh = dsp_get_ax_h(sreg);
zeroWriteBackLog();
dsp_set_long_acc(rreg, acc);
prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
prod = dsp_multiply(axl, axh);
Update_SR_Register64(prod);
}
@ -316,10 +358,15 @@ void mulmvz(const UDSPInstruction& opc)
// overwrite acc and clear low part
s64 prod = dsp_get_long_prod();
s64 acc = prod & ~0xffff;
u16 axl = dsp_get_ax_l(sreg);
u16 axh = dsp_get_ax_h(sreg);
zeroWriteBackLog();
dsp_set_long_acc(rreg, acc);
// math prod
prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
prod = dsp_multiply(axl, axh);
Update_SR_Register64(prod);
}
@ -335,6 +382,7 @@ void mulx(const UDSPInstruction& opc)
u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod);
}
@ -357,7 +405,8 @@ void mulxac(const UDSPInstruction& opc)
u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod);
}
@ -380,7 +429,7 @@ void mulxmv(const UDSPInstruction& opc)
s16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
s16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod);
}
@ -405,7 +454,7 @@ void mulxmvz(const UDSPInstruction& opc)
u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod);
}
@ -422,7 +471,7 @@ void maddx(const UDSPInstruction& opc)
u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_add(val1, val2);
Update_SR_Register64(prod);
}
@ -439,7 +488,7 @@ void msubx(const UDSPInstruction& opc)
u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_sub(val1, val2);
Update_SR_Register64(prod);
}
@ -453,8 +502,10 @@ void maddc(const UDSPInstruction& opc)
{
u32 sreg = (opc.hex >> 9) & 0x1;
u32 treg = (opc.hex >> 8) & 0x1;
s64 prod = dsp_multiply_add(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
u16 accm = dsp_get_acc_m(sreg);
u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
s64 prod = dsp_multiply_add(accm, axh);
Update_SR_Register64(prod);
}
@ -467,8 +518,10 @@ void msubc(const UDSPInstruction& opc)
{
u32 sreg = (opc.hex >> 9) & 0x1;
u32 treg = (opc.hex >> 8) & 0x1;
s64 prod = dsp_multiply_sub(dsp_get_acc_m(sreg), dsp_get_ax_h(treg));
u16 accm = dsp_get_acc_m(sreg);
u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
s64 prod = dsp_multiply_sub(accm, axh);
Update_SR_Register64(prod);
}
@ -480,8 +533,12 @@ void msubc(const UDSPInstruction& opc)
void madd(const UDSPInstruction& opc)
{
u8 sreg = (opc.hex >> 8) & 0x1;
u16 axl = dsp_get_ax_l(sreg);
u16 axh = dsp_get_ax_h(sreg);
zeroWriteBackLog();
s64 prod = dsp_multiply_add(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
s64 prod = dsp_multiply_add(axl, axh);
Update_SR_Register64(prod);
}
@ -493,8 +550,12 @@ void madd(const UDSPInstruction& opc)
void msub(const UDSPInstruction& opc)
{
u8 sreg = (opc.hex >> 8) & 0x1;
u16 axl = dsp_get_ax_l(sreg);
u16 axh = dsp_get_ax_h(sreg);
zeroWriteBackLog();
s64 prod = dsp_multiply_sub(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
s64 prod = dsp_multiply_sub(axl, axh);
Update_SR_Register64(prod);
}