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

View file

@ -58,37 +58,57 @@ inline u16 ToMask(u16 a)
return a | (a >> 1); 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]); u16 tmb = ToMask(g_dsp.r[DSP_REG_WR0 + reg]);
if ((g_dsp.r[reg] & tmb) == tmb) u16 tmp;
g_dsp.r[reg] ^= g_dsp.r[DSP_REG_WR0 + reg]; if (value == -1)
tmp = g_dsp.r[reg];
else 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 // 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... u16 tmp;
if ((g_dsp.r[reg] & g_dsp.r[DSP_REG_WR0 + reg]) == 0) if (value == -1)
g_dsp.r[reg] |= g_dsp.r[DSP_REG_WR0 + reg]; tmp = g_dsp.r[reg];
else 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! // TODO: DO RIGHT!
if (value > 0) { if (value > 0) {
for (int i = 0; i < value; i++) { for (int i = 0; i < value; i++) {
dsp_increment_addr_reg(reg); tmp = dsp_increment_addr_reg(reg, tmp);
} }
} else if (value < 0) { } else if (value < 0) {
for (int i = 0; i < (int)(-value); i++) { 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 opTable[OPTABLE_SIZE];
dspInstFunc extOpTable[EXT_OPTABLE_SIZE]; dspInstFunc extOpTable[EXT_OPTABLE_SIZE];
bool opTableUseExt[OPTABLE_SIZE]; bool opTableUseExt[OPTABLE_SIZE];
u16 writeBackLog[WRITEBACKLOGSIZE];
dspInstFunc currentEpilogeFunc = NULL; int writeBackLogIdx[WRITEBACKLOGSIZE];
const char* pdname(u16 val) const char* pdname(u16 val)
{ {
@ -577,10 +577,6 @@ void InitInstructionTable()
for (int j = 0; j < opcodes_size; j++) for (int j = 0; j < opcodes_size; j++)
{ {
u16 mask = opcodes[j].opcode_mask; u16 mask = opcodes[j].opcode_mask;
// if (opcodes[j].size & P_EXT) {
// Ignore extension bits.
// mask &= 0xFF00;
// }
if ((mask & i) == opcodes[j].opcode) if ((mask & i) == opcodes[j].opcode)
{ {
if (opTable[i] == DSPInterpreter::unknown) 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 u8 opSize[OPTABLE_SIZE];
extern const DSPOPCTemplate cw; extern const DSPOPCTemplate cw;
#define WRITEBACKLOGSIZE 7
extern dspInstFunc opTable[]; extern dspInstFunc opTable[];
extern bool opTableUseExt[OPTABLE_SIZE]; extern bool opTableUseExt[OPTABLE_SIZE];
extern dspInstFunc extOpTable[EXT_OPTABLE_SIZE]; extern dspInstFunc extOpTable[EXT_OPTABLE_SIZE];
extern dspInstFunc currentEpilogeFunc; extern u16 writeBackLog[WRITEBACKLOGSIZE];
extern int writeBackLogIdx[WRITEBACKLOGSIZE];
// Predefined labels // Predefined labels
struct pdlabel_t struct pdlabel_t
@ -151,15 +153,16 @@ const char *pdregname(int val);
const char *pdregnamelong(int val); const char *pdregnamelong(int val);
void InitInstructionTable(); void InitInstructionTable();
void applyWriteBackLog();
void zeroWriteBackLog();
inline void ExecuteInstruction(const UDSPInstruction& inst) inline void ExecuteInstruction(const UDSPInstruction& inst)
{ {
if (opTableUseExt[inst.hex]) if (opTableUseExt[inst.hex])
extOpTable[inst.hex & 0xFF](inst); extOpTable[inst.hex & 0xFF](inst);
opTable[inst.hex](inst); opTable[inst.hex](inst);
if (currentEpilogeFunc) { if (opTableUseExt[inst.hex]) {
currentEpilogeFunc(inst); applyWriteBackLog();
currentEpilogeFunc = NULL;
} }
} }

View file

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

View file

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

View file

@ -97,7 +97,7 @@ void addarn(const UDSPInstruction& opc)
u8 dreg = opc.hex & 0x3; u8 dreg = opc.hex & 0x3;
u8 sreg = (opc.hex >> 2) & 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. // 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. // No operation, but can be extended with extended opcode.
void nx(const UDSPInstruction& opc) void nx(const UDSPInstruction& opc)
{ {
zeroWriteBackLog();
// This opcode is supposed to do nothing - it's used if you want to use // 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. // 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. // Decrement address register $arD.
void dar(const UDSPInstruction& opc) 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 ? // IAR $arD ?
@ -125,7 +126,7 @@ void dar(const UDSPInstruction& opc)
// Increment address register $arD. // Increment address register $arD.
void iar(const UDSPInstruction& opc) 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 // SBCLR #I
@ -153,6 +154,7 @@ void sbset(const UDSPInstruction& opc)
// but it's harder to know exactly what effect they have. // but it's harder to know exactly what effect they have.
void srbith(const UDSPInstruction& opc) void srbith(const UDSPInstruction& opc)
{ {
zeroWriteBackLog();
switch ((opc.hex >> 8) & 0xf) switch ((opc.hex >> 8) & 0xf)
{ {
// M0/M2 change the multiplier mode (it can multiply by 2 for free). // 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 // Magic numbers taken from duddie's doc
// These are probably a bad idea to put here. // These are probably a bad idea to put here.
zeroWriteBackLog();
g_dsp.r[0x14] = 0x0000; g_dsp.r[0x14] = 0x0000;
g_dsp.r[0x15] = 0xfff0; g_dsp.r[0x15] = 0xfff0;
g_dsp.r[0x16] = 0x00ff; g_dsp.r[0x16] = 0x00ff;
@ -117,6 +118,7 @@ void movp(const UDSPInstruction& opc)
u8 dreg = (opc.hex >> 8) & 0x1; u8 dreg = (opc.hex >> 8) & 0x1;
s64 prod = dsp_get_long_prod(); s64 prod = dsp_get_long_prod();
zeroWriteBackLog();
dsp_set_long_acc(dreg, prod); dsp_set_long_acc(dreg, prod);
Update_SR_Register64(prod); Update_SR_Register64(prod);
@ -132,6 +134,7 @@ void movnp(const UDSPInstruction& opc)
s64 prod = dsp_get_long_prod(); s64 prod = dsp_get_long_prod();
s64 acc = -prod; s64 acc = -prod;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc); dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc); Update_SR_Register64(acc);
@ -150,6 +153,7 @@ void addpaxz(const UDSPInstruction& opc)
s64 ax = dsp_get_long_acx(sreg); s64 ax = dsp_get_long_acx(sreg);
s64 acc = (prod + ax) & ~0xffff; s64 acc = (prod + ax) & ~0xffff;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc); dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc); Update_SR_Register64(acc);
@ -166,6 +170,8 @@ void movpz(const UDSPInstruction& opc)
// overwrite acc and clear low part // overwrite acc and clear low part
s64 prod = dsp_get_long_prod(); s64 prod = dsp_get_long_prod();
s64 acc = prod & ~0xffff; s64 acc = prod & ~0xffff;
zeroWriteBackLog();
dsp_set_long_acc(dreg, acc); dsp_set_long_acc(dreg, acc);
Update_SR_Register64(acc); Update_SR_Register64(acc);
@ -180,7 +186,12 @@ void mulc(const UDSPInstruction& opc)
{ {
u8 sreg = (opc.hex >> 11) & 0x1; u8 sreg = (opc.hex >> 11) & 0x1;
u8 treg = (opc.hex >> 12) & 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); Update_SR_Register64(prod);
} }
@ -198,8 +209,13 @@ void mulcmvz(const UDSPInstruction& opc)
// update prod // update prod
u8 sreg = (opc.hex >> 12) & 0x1; u8 sreg = (opc.hex >> 12) & 0x1;
u8 treg = (opc.hex >> 11) & 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 // update acc
u8 rreg = (opc.hex >> 8) & 0x1; u8 rreg = (opc.hex >> 8) & 0x1;
s64 acc = TempProd & ~0xffff; // clear lower 4 bytes s64 acc = TempProd & ~0xffff; // clear lower 4 bytes
@ -221,7 +237,12 @@ void mulcmv(const UDSPInstruction& opc)
// update prod // update prod
u8 sreg = (opc.hex >> 12) & 0x1; u8 sreg = (opc.hex >> 12) & 0x1;
u8 treg = (opc.hex >> 11) & 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 // update acc
u8 rreg = (opc.hex >> 8) & 0x1; u8 rreg = (opc.hex >> 8) & 0x1;
@ -242,7 +263,12 @@ void mulcac(const UDSPInstruction& opc)
// update prod // update prod
u8 sreg = (opc.hex >> 12) & 0x1; u8 sreg = (opc.hex >> 12) & 0x1;
u8 treg = (opc.hex >> 11) & 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 // update acc
u8 rreg = (opc.hex >> 8) & 0x1; u8 rreg = (opc.hex >> 8) & 0x1;
@ -260,7 +286,12 @@ void mulcac(const UDSPInstruction& opc)
void mul(const UDSPInstruction& opc) void mul(const UDSPInstruction& opc)
{ {
u8 sreg = (opc.hex >> 11) & 0x1; 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 // FIXME: no update in duddie's docs
Update_SR_Register64(prod); Update_SR_Register64(prod);
} }
@ -274,12 +305,19 @@ void mulac(const UDSPInstruction& opc)
{ {
// add old prod to acc // add old prod to acc
u8 rreg = (opc.hex >> 8) & 0x1; u8 rreg = (opc.hex >> 8) & 0x1;
u8 sreg = (opc.hex >> 11) & 0x1;
s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod(); 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); dsp_set_long_acc(rreg, acR);
// calculate new prod // calculate new prod
u8 sreg = (opc.hex >> 11) & 0x1; s64 prod = dsp_multiply(axl, axh);
s64 prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg));
// FIXME: no update in duddie's docs // FIXME: no update in duddie's docs
Update_SR_Register64(prod); Update_SR_Register64(prod);
@ -296,9 +334,13 @@ void mulmv(const UDSPInstruction& opc)
u8 sreg = ((opc.hex >> 11) & 0x1); u8 sreg = ((opc.hex >> 11) & 0x1);
s64 prod = dsp_get_long_prod(); s64 prod = dsp_get_long_prod();
s64 acc = 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); 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); Update_SR_Register64(prod);
} }
@ -316,10 +358,15 @@ void mulmvz(const UDSPInstruction& opc)
// overwrite acc and clear low part // overwrite acc and clear low part
s64 prod = dsp_get_long_prod(); s64 prod = dsp_get_long_prod();
s64 acc = prod & ~0xffff; 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); dsp_set_long_acc(rreg, acc);
// math prod // math prod
prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg)); prod = dsp_multiply(axl, axh);
Update_SR_Register64(prod); 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 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); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_conditional_unsigned(val1, val2); s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod); 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 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); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_conditional_unsigned(val1, val2); s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod); 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 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); s16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_conditional_unsigned(val1, val2); s64 prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod); 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 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); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
prod = dsp_multiply_conditional_unsigned(val1, val2); prod = dsp_multiply_conditional_unsigned(val1, val2);
Update_SR_Register64(prod); 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 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); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_add(val1, val2); s64 prod = dsp_multiply_add(val1, val2);
Update_SR_Register64(prod); 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 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); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
zeroWriteBackLog();
s64 prod = dsp_multiply_sub(val1, val2); s64 prod = dsp_multiply_sub(val1, val2);
Update_SR_Register64(prod); Update_SR_Register64(prod);
} }
@ -453,8 +502,10 @@ void maddc(const UDSPInstruction& opc)
{ {
u32 sreg = (opc.hex >> 9) & 0x1; u32 sreg = (opc.hex >> 9) & 0x1;
u32 treg = (opc.hex >> 8) & 0x1; u32 treg = (opc.hex >> 8) & 0x1;
u16 accm = dsp_get_acc_m(sreg);
s64 prod = dsp_multiply_add(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
s64 prod = dsp_multiply_add(accm, axh);
Update_SR_Register64(prod); Update_SR_Register64(prod);
} }
@ -467,8 +518,10 @@ void msubc(const UDSPInstruction& opc)
{ {
u32 sreg = (opc.hex >> 9) & 0x1; u32 sreg = (opc.hex >> 9) & 0x1;
u32 treg = (opc.hex >> 8) & 0x1; u32 treg = (opc.hex >> 8) & 0x1;
u16 accm = dsp_get_acc_m(sreg);
s64 prod = dsp_multiply_sub(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); u16 axh = dsp_get_ax_h(treg);
zeroWriteBackLog();
s64 prod = dsp_multiply_sub(accm, axh);
Update_SR_Register64(prod); Update_SR_Register64(prod);
} }
@ -480,8 +533,12 @@ void msubc(const UDSPInstruction& opc)
void madd(const UDSPInstruction& opc) void madd(const UDSPInstruction& opc)
{ {
u8 sreg = (opc.hex >> 8) & 0x1; 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); Update_SR_Register64(prod);
} }
@ -493,8 +550,12 @@ void madd(const UDSPInstruction& opc)
void msub(const UDSPInstruction& opc) void msub(const UDSPInstruction& opc)
{ {
u8 sreg = (opc.hex >> 8) & 0x1; 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); Update_SR_Register64(prod);
} }