diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE_Test.vcproj b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE_Test.vcproj
index 00d26dd26c..98d75bdca0 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE_Test.vcproj
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE_Test.vcproj
@@ -588,18 +588,34 @@
RelativePath=".\Src\disassemble.h"
>
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -644,14 +660,6 @@
RelativePath=".\Src\gdsp_memory.h"
>
-
-
-
-
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp
new file mode 100644
index 0000000000..4cd48d83f9
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp
@@ -0,0 +1,1376 @@
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie and Tratax (c) 2004
+
+#include "DSPInterpreter.h"
+
+#include "Globals.h"
+#include "gdsp_memory.h"
+#include "gdsp_interpreter.h"
+#include "gdsp_registers.h"
+#include "gdsp_opcodes_helper.h"
+#include "gdsp_ext_op.h"
+
+namespace DSPInterpreter {
+
+ // HELPER FUNCTIONS
+
+ void Update_SR_Register(s64 _Value)
+ {
+ g_dsp.r[R_SR] &= ~SR_CMP_MASK;
+
+ if (_Value < 0)
+ {
+ g_dsp.r[R_SR] |= 0x8;
+ }
+
+ if (_Value == 0)
+ {
+ g_dsp.r[R_SR] |= 0x4;
+ }
+
+ // logic
+ if ((_Value >> 62) == 0)
+ {
+ g_dsp.r[R_SR] |= 0x20;
+ }
+ }
+
+ void Update_SR_Register(s16 _Value)
+ {
+ g_dsp.r[R_SR] &= ~SR_CMP_MASK;
+
+ if (_Value < 0)
+ {
+ g_dsp.r[R_SR] |= 0x8;
+ }
+
+ if (_Value == 0)
+ {
+ g_dsp.r[R_SR] |= 0x4;
+ }
+
+ // logic
+ if ((_Value >> 14) == 0)
+ {
+ g_dsp.r[R_SR] |= 0x20;
+ }
+ }
+
+ s8 GetMultiplyModifier()
+ {
+ if (g_dsp.r[R_SR] & (1 << 13))
+ {
+ return(1);
+ }
+
+ return(2);
+ }
+
+ bool CheckCondition(u8 _Condition)
+ {
+ bool taken = false;
+
+ switch (_Condition & 0xf)
+ {
+ case 0x0:
+
+ if ((!(g_dsp.r[R_SR] & 0x02)) && (!(g_dsp.r[R_SR] & 0x08)))
+ {
+ taken = true;
+ }
+
+ break;
+
+ case 0x3:
+
+ if ((g_dsp.r[R_SR] & 0x02) || (g_dsp.r[R_SR] & 0x04) || (g_dsp.r[R_SR] & 0x08))
+ {
+ taken = true;
+ }
+
+ break;
+
+ // old from duddie
+ case 0x1: // seems okay
+
+ if ((!(g_dsp.r[R_SR] & 0x02)) && (g_dsp.r[R_SR] & 0x08))
+ {
+ taken = true;
+ }
+
+ break;
+
+ case 0x2:
+
+ if (!(g_dsp.r[R_SR] & 0x08))
+ {
+ taken = true;
+ }
+
+ break;
+
+ case 0x4:
+
+ if (!(g_dsp.r[R_SR] & 0x04))
+ {
+ taken = true;
+ }
+
+ break;
+
+ case 0x5:
+
+ if (g_dsp.r[R_SR] & 0x04)
+ {
+ taken = true;
+ }
+
+ break;
+
+ case 0xc:
+
+ if (!(g_dsp.r[R_SR] & 0x40))
+ {
+ taken = true;
+ }
+
+ break;
+
+ case 0xd:
+
+ if (g_dsp.r[R_SR] & 0x40)
+ {
+ taken = true;
+ }
+
+ break;
+
+ case 0xf:
+ taken = true;
+ break;
+
+ default:
+ // DEBUG_LOG(DSPHLE, "Unknown condition check: 0x%04x\n", _Condition & 0xf);
+ break;
+ }
+
+ return(taken);
+ }
+
+ // END OF HELPER FUNCTIONS
+
+ void unknown(UDSPInstruction& opc)
+ {
+ _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
+ ERROR_LOG(DSPHLE, "unknown opcode %d", opc.hex);
+ g_dsp.pc = g_dsp.err_pc;
+ }
+
+ void call(UDSPInstruction& opc)
+ {
+ u16 dest = dsp_fetch_code();
+
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
+ g_dsp.pc = dest;
+ }
+ }
+
+ void ifcc(UDSPInstruction& opc)
+ {
+ if (!CheckCondition(opc.hex & 0xf))
+ {
+ dsp_fetch_code(); // skip the next opcode
+ }
+ }
+
+ void jcc(UDSPInstruction& opc)
+ {
+ u16 dest = dsp_fetch_code();
+
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ g_dsp.pc = dest;
+ }
+ }
+
+ // FIXME inside
+ void jmpa(UDSPInstruction& opc)
+ {
+ u8 reg;
+ u16 addr;
+
+ if ((opc.hex & 0xf) != 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp jmpa opcode");
+ }
+
+ reg = (opc.hex >> 5) & 0x7;
+ addr = dsp_op_read_reg(reg);
+
+ if (opc.hex & 0x0010)
+ {
+ // CALLA
+ dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
+ }
+
+ g_dsp.pc = addr;
+ }
+
+ void ret(UDSPInstruction& opc)
+ {
+ if (CheckCondition(opc.hex & 0xf))
+ {
+ g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
+ }
+ }
+
+ // FIXME inside
+ void rti(UDSPInstruction& opc)
+ {
+ if ((opc.hex & 0xf) != 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp rti opcode");
+ }
+
+ g_dsp.r[R_SR] = dsp_reg_load_stack(DSP_STACK_D);
+ g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
+
+ g_dsp.exception_in_progress_hack = false;
+ }
+
+ void halt(UDSPInstruction& opc)
+ {
+ g_dsp.cr |= 0x4;
+ g_dsp.pc = g_dsp.err_pc;
+ }
+
+ void loop(UDSPInstruction& opc)
+ {
+ u16 reg = opc.hex & 0x1f;
+ u16 cnt = g_dsp.r[reg];
+ u16 loop_pc = g_dsp.pc;
+
+ while (cnt--)
+ {
+ gdsp_loop_step();
+ g_dsp.pc = loop_pc;
+ }
+
+ g_dsp.pc = loop_pc + 1;
+ }
+
+ void loopi(UDSPInstruction& opc)
+ {
+ u16 cnt = opc.hex & 0xff;
+ u16 loop_pc = g_dsp.pc;
+
+ while (cnt--)
+ {
+ gdsp_loop_step();
+ g_dsp.pc = loop_pc;
+ }
+
+ g_dsp.pc = loop_pc + 1;
+ }
+
+ void bloop(UDSPInstruction& opc)
+ {
+ u16 reg = opc.hex & 0x1f;
+ u16 cnt = g_dsp.r[reg];
+ u16 loop_pc = dsp_fetch_code();
+
+ if (cnt)
+ {
+ dsp_reg_store_stack(0, g_dsp.pc);
+ dsp_reg_store_stack(2, loop_pc);
+ dsp_reg_store_stack(3, cnt);
+ }
+ else
+ {
+ g_dsp.pc = loop_pc + 1;
+ }
+ }
+
+ void bloopi(UDSPInstruction& opc)
+ {
+ u16 cnt = opc.hex & 0xff;
+ u16 loop_pc = dsp_fetch_code();
+
+ if (cnt)
+ {
+ dsp_reg_store_stack(0, g_dsp.pc);
+ dsp_reg_store_stack(2, loop_pc);
+ dsp_reg_store_stack(3, cnt);
+ }
+ else
+ {
+ g_dsp.pc = loop_pc + 1;
+ }
+ }
+
+ //-------------------------------------------------------------
+
+ void mrr(UDSPInstruction& opc)
+ {
+ u8 sreg = opc.hex & 0x1f;
+ u8 dreg = (opc.hex >> 5) & 0x1f;
+
+ u16 val = dsp_op_read_reg(sreg);
+ dsp_op_write_reg(dreg, val);
+ }
+
+ void lrr(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 5) & 0x3;
+ u8 dreg = opc.hex & 0x1f;
+
+ u16 val = dsp_dmem_read(g_dsp.r[sreg]);
+ dsp_op_write_reg(dreg, val);
+
+ // post processing of source reg
+ switch ((opc.hex >> 7) & 0x3)
+ {
+ case 0x0: // LRR
+ break;
+
+ case 0x1: // LRRD
+ g_dsp.r[sreg]--;
+ break;
+
+ case 0x2: // LRRI
+ g_dsp.r[sreg]++;
+ break;
+
+ case 0x3:
+ g_dsp.r[sreg] += g_dsp.r[sreg + 4];
+ break;
+ }
+ }
+
+ void srr(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 5) & 0x3;
+ u8 sreg = opc.hex & 0x1f;
+
+ u16 val = dsp_op_read_reg(sreg);
+ dsp_dmem_write(g_dsp.r[dreg], val);
+
+ // post processing of dest reg
+ switch ((opc.hex >> 7) & 0x3)
+ {
+ case 0x0: // SRR
+ break;
+
+ case 0x1: // SRRD
+ g_dsp.r[dreg]--;
+ break;
+
+ case 0x2: // SRRI
+ g_dsp.r[dreg]++;
+ break;
+
+ case 0x3: // SRRX
+ g_dsp.r[dreg] += g_dsp.r[dreg + 4];
+ break;
+ }
+ }
+
+ // FIXME inside
+ void ilrr(UDSPInstruction& opc)
+ {
+ u16 reg = opc.hex & 0x3;
+ u16 dreg = 0x1e + ((opc.hex >> 8) & 1);
+
+ // always to acc0 ?
+ g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
+
+ switch ((opc.hex >> 2) & 0x3)
+ {
+ case 0x0: // no change
+ break;
+
+ case 0x1: // post decrement
+ g_dsp.r[reg]--;
+ break;
+
+ case 0x2: // post increment
+ g_dsp.r[reg]++;
+ break;
+
+ default:
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp_opc.hex_ilrr");
+ }
+ }
+
+
+ void lri(UDSPInstruction& opc)
+ {
+ u8 reg = opc.hex & DSP_REG_MASK;
+ u16 imm = dsp_fetch_code();
+ dsp_op_write_reg(reg, imm);
+ }
+
+ void lris(UDSPInstruction& opc)
+ {
+ u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;
+ u16 imm = (s8)opc.hex;
+ dsp_op_write_reg(reg, imm);
+ }
+
+ void lr(UDSPInstruction& opc)
+ {
+ u8 reg = opc.hex & DSP_REG_MASK;
+ u16 addr = dsp_fetch_code();
+ u16 val = dsp_dmem_read(addr);
+ dsp_op_write_reg(reg, val);
+ }
+
+ void sr(UDSPInstruction& opc)
+ {
+ u8 reg = opc.hex & DSP_REG_MASK;
+ u16 addr = dsp_fetch_code();
+ u16 val = dsp_op_read_reg(reg);
+ dsp_dmem_write(addr, val);
+ }
+
+ void si(UDSPInstruction& opc)
+ {
+ u16 addr = (s8)opc.hex;
+ u16 imm = dsp_fetch_code();
+ dsp_dmem_write(addr, imm);
+ }
+
+ void tstaxh(UDSPInstruction& opc)
+ {
+ u8 reg = (opc.hex >> 8) & 0x1;
+ s16 val = dsp_get_ax_h(reg);
+
+ Update_SR_Register(val);
+ }
+
+ void clr(UDSPInstruction& opc)
+ {
+ u8 reg = (opc.hex >> 11) & 0x1;
+
+ dsp_set_long_acc(reg, 0);
+
+ Update_SR_Register((s64)0);
+ }
+
+ void clrp(UDSPInstruction& opc)
+ {
+ g_dsp.r[0x14] = 0x0000;
+ g_dsp.r[0x15] = 0xfff0;
+ g_dsp.r[0x16] = 0x00ff;
+ g_dsp.r[0x17] = 0x0010;
+ }
+
+ void mulc(UDSPInstruction& opc)
+ {
+ // math new prod
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ u8 treg = (opc.hex >> 12) & 0x1;
+
+ s64 prod = dsp_get_acc_m(sreg) * dsp_get_ax_h(treg) * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ // TODO: Implement
+ void mulcmvz(UDSPInstruction& opc)
+ {
+ ERROR_LOG(DSPHLE, "dsp_opc.hex_mulcmvz ni");
+ }
+
+ // TODO: Implement
+ void mulcmv(UDSPInstruction& opc)
+ {
+ ERROR_LOG(DSPHLE, "dsp_opc.hex_mulcmv ni");
+ }
+
+ void cmpar(UDSPInstruction& opc)
+ {
+ u8 rreg = ((opc.hex >> 12) & 0x1) + 0x1a;
+ u8 areg = (opc.hex >> 11) & 0x1;
+
+ // we compare
+ s64 rr = (s16)g_dsp.r[rreg];
+ rr <<= 16;
+
+ s64 ar = dsp_get_long_acc(areg);
+
+ Update_SR_Register(ar - rr);
+ }
+
+ void cmp(UDSPInstruction& opc)
+ {
+ s64 acc0 = dsp_get_long_acc(0);
+ s64 acc1 = dsp_get_long_acc(1);
+
+ Update_SR_Register(acc0 - acc1);
+ }
+
+ void tsta(UDSPInstruction& opc)
+ {
+ u8 reg = (opc.hex >> 11) & 0x1;
+ s64 acc = dsp_get_long_acc(reg);
+
+ Update_SR_Register(acc);
+ }
+
+ void addaxl(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(dreg);
+ s64 acx = dsp_get_ax_l(sreg);
+
+ acc += acx;
+
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void addarn(UDSPInstruction& opc)
+ {
+ u8 dreg = opc.hex & 0x3;
+ u8 sreg = (opc.hex >> 2) & 0x3;
+
+ g_dsp.r[dreg] += (s16)g_dsp.r[0x04 + sreg];
+ }
+
+ void mulcac(UDSPInstruction& opc)
+ {
+ s64 TempProd = dsp_get_long_prod();
+
+ // update prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_acc_h(sreg) * GetMultiplyModifier();
+ dsp_set_long_prod(Prod);
+
+ // update acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ dsp_set_long_acc(rreg, TempProd);
+ }
+
+ void movr(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = ((opc.hex >> 9) & 0x3) + 0x18;
+
+ s64 acc = (s16)g_dsp.r[sreg];
+ acc <<= 16;
+ acc &= ~0xffff;
+
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void movax(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ g_dsp.r[0x1c + dreg] = g_dsp.r[0x18 + sreg];
+ g_dsp.r[0x1e + dreg] = g_dsp.r[0x1a + sreg];
+
+ if ((s16)g_dsp.r[0x1a + sreg] < 0)
+ {
+ g_dsp.r[0x10 + dreg] = 0xffff;
+ }
+ else
+ {
+ g_dsp.r[0x10 + dreg] = 0;
+ }
+
+ tsta(UDSPInstruction(dreg << 11));
+ }
+
+ void xorr(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ g_dsp.r[0x1e + dreg] ^= g_dsp.r[0x1a + sreg];
+
+ tsta(UDSPInstruction(dreg << 11));
+ }
+
+ void andr(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ g_dsp.r[0x1e + dreg] &= g_dsp.r[0x1a + sreg];
+
+ tsta(UDSPInstruction(dreg << 11));
+ }
+
+ void orr(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ g_dsp.r[0x1e + dreg] |= g_dsp.r[0x1a + sreg];
+
+ tsta(UDSPInstruction(dreg << 11));
+ }
+
+ void andc(UDSPInstruction& opc)
+ {
+ u8 D = (opc.hex >> 8) & 0x1;
+
+ u16 ac1 = dsp_get_acc_m(D);
+ u16 ac2 = dsp_get_acc_m(1 - D);
+
+ dsp_set_long_acc(D, ac1 & ac2);
+
+ if ((ac1 & ac2) == 0)
+ {
+ g_dsp.r[R_SR] |= 0x20;
+ }
+ else
+ {
+ g_dsp.r[R_SR] &= ~0x20;
+ }
+ }
+
+
+ //-------------------------------------------------------------
+
+ // TODO: Implement
+ void nx(UDSPInstruction& opc)
+ {}
+
+
+ // FIXME inside
+ void andfc(UDSPInstruction& opc)
+ {
+ if (opc.hex & 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp_opc.hex_andfc");
+ }
+
+ u8 reg = (opc.hex >> 8) & 0x1;
+ u16 imm = dsp_fetch_code();
+ u16 val = dsp_get_acc_m(reg);
+
+ if ((val & imm) == imm)
+ {
+ g_dsp.r[R_SR] |= 0x40;
+ }
+ else
+ {
+ g_dsp.r[R_SR] &= ~0x40;
+ }
+ }
+
+ // FIXME inside
+ void andf(UDSPInstruction& opc)
+ {
+ u8 reg;
+ u16 imm;
+ u16 val;
+
+ if (opc.hex & 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp andf opcode");
+ }
+
+ reg = 0x1e + ((opc.hex >> 8) & 0x1);
+ imm = dsp_fetch_code();
+ val = g_dsp.r[reg];
+
+ if ((val & imm) == 0)
+ {
+ g_dsp.r[R_SR] |= 0x40;
+ }
+ else
+ {
+ g_dsp.r[R_SR] &= ~0x40;
+ }
+ }
+
+ // FIXME inside
+ void subf(UDSPInstruction& opc)
+ {
+ if (opc.hex & 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp subf opcode");
+ }
+
+ u8 reg = 0x1e + ((opc.hex >> 8) & 0x1);
+ s64 imm = (s16)dsp_fetch_code();
+
+ s64 val = (s16)g_dsp.r[reg];
+ s64 res = val - imm;
+
+ Update_SR_Register(res);
+ }
+
+ // FIXME inside
+ void xori(UDSPInstruction& opc)
+ {
+ if (opc.hex & 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp xori opcode");
+ }
+
+ u8 reg = 0x1e + ((opc.hex >> 8) & 0x1);
+ u16 imm = dsp_fetch_code();
+ g_dsp.r[reg] ^= imm;
+
+ Update_SR_Register((s16)g_dsp.r[reg]);
+ }
+
+ //FIXME inside
+ void andi(UDSPInstruction& opc)
+ {
+ if (opc.hex & 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp andi opcode");
+ }
+
+ u8 reg = 0x1e + ((opc.hex >> 8) & 0x1);
+ u16 imm = dsp_fetch_code();
+ g_dsp.r[reg] &= imm;
+
+ Update_SR_Register((s16)g_dsp.r[reg]);
+ }
+
+
+ // F|RES: i am not sure if this shouldnt be the whole ACC
+ //
+ //FIXME inside
+ void ori(UDSPInstruction& opc)
+ {
+ if (opc.hex & 0xf)
+ {
+ // FIXME: Implement
+ ERROR_LOG(DSPHLE, "dsp ori opcode");
+ return;
+ }
+
+ u8 reg = 0x1e + ((opc.hex >> 8) & 0x1);
+ u16 imm = dsp_fetch_code();
+ g_dsp.r[reg] |= imm;
+
+ Update_SR_Register((s16)g_dsp.r[reg]);
+ }
+
+ //-------------------------------------------------------------
+
+ void add(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+ s64 acc0 = dsp_get_long_acc(0);
+ s64 acc1 = dsp_get_long_acc(1);
+
+ s64 res = acc0 + acc1;
+
+ dsp_set_long_acc(areg, res);
+
+ Update_SR_Register(res);
+ }
+
+ //-------------------------------------------------------------
+
+ void addp(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x1;
+ s64 acc = dsp_get_long_acc(dreg);
+ acc = acc + dsp_get_long_prod();
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void cmpis(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ s64 val = (s8)opc.hex;
+ val <<= 16;
+
+ s64 res = acc - val;
+
+ Update_SR_Register(res);
+ }
+
+ void addpaxz(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x1;
+ u8 sreg = (opc.hex >> 9) & 0x1;
+
+ s64 prod = dsp_get_long_prod() & ~0x0ffff;
+ s64 ax_h = dsp_get_long_acx(sreg);
+ s64 acc = (prod + ax_h) & ~0x0ffff;
+
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void movpz(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x01;
+
+ // overwrite acc and clear low part
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod & ~0xffff;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void decm(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x01;
+
+ s64 sub = 0x10000;
+ s64 acc = dsp_get_long_acc(dreg);
+ acc -= sub;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void dec(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x01;
+
+ s64 acc = dsp_get_long_acc(dreg) - 1;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void incm(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 sub = 0x10000;
+ s64 acc = dsp_get_long_acc(dreg);
+ acc += sub;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void inc(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(dreg);
+ acc++;
+ dsp_set_long_acc(dreg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void neg(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc = 0 - acc;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ // TODO: Implement
+ void movnp(UDSPInstruction& opc)
+ {
+ // UNIMPLEMENTED
+ ERROR_LOG(DSPHLE, "dsp_opc.hex_movnp\n");
+ }
+
+ void addax(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = (opc.hex >> 9) & 0x1;
+
+ s64 ax = dsp_get_long_acx(sreg);
+ s64 acc = dsp_get_long_acc(areg);
+ acc += ax;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void addr(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = ((opc.hex >> 9) & 0x3) + 0x18;
+
+ s64 ax = (s16)g_dsp.r[sreg];
+ ax <<= 16;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc += ax;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void subr(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+ u8 sreg = ((opc.hex >> 9) & 0x3) + 0x18;
+
+ s64 ax = (s16)g_dsp.r[sreg];
+ ax <<= 16;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc -= ax;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void subax(UDSPInstruction& opc)
+ {
+ int regD = (opc.hex >> 8) & 0x1;
+ int regT = (opc.hex >> 9) & 0x1;
+
+ s64 Acc = dsp_get_long_acc(regD) - dsp_get_long_acx(regT);
+
+ dsp_set_long_acc(regD, Acc);
+ Update_SR_Register(Acc);
+ }
+
+ void addis(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 Imm = (s8)opc.hex;
+ Imm <<= 16;
+ s64 acc = dsp_get_long_acc(areg);
+ acc += Imm;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void addi(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 sub = (s16)dsp_fetch_code();
+ sub <<= 16;
+ s64 acc = dsp_get_long_acc(areg);
+ acc += sub;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void lsl16(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc <<= 16;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void madd(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_get_long_prod();
+ prod += (s64)dsp_get_ax_l(sreg) * (s64)dsp_get_ax_h(sreg) * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+ }
+
+ void lsr16(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 8) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc >>= 16;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void asr16(UDSPInstruction& opc)
+ {
+ u8 areg = (opc.hex >> 11) & 0x1;
+
+ s64 acc = dsp_get_long_acc(areg);
+ acc >>= 16;
+ dsp_set_long_acc(areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ void shifti(UDSPInstruction& opc)
+ {
+ // direction: left
+ bool ShiftLeft = true;
+ u16 shift = opc.ushift;
+
+ if ((opc.negating) && (opc.shift < 0))
+ {
+ ShiftLeft = false;
+ shift = -opc.shift;
+ }
+
+ s64 acc;
+ u64 uacc;
+
+ if (opc.arithmetic)
+ {
+ // arithmetic shift
+ uacc = dsp_get_long_acc(opc.areg);
+
+ if (!ShiftLeft)
+ {
+ uacc >>= shift;
+ }
+ else
+ {
+ uacc <<= shift;
+ }
+
+ acc = uacc;
+ }
+ else
+ {
+ acc = dsp_get_long_acc(opc.areg);
+
+ if (!ShiftLeft)
+ {
+ acc >>= shift;
+ }
+ else
+ {
+ acc <<= shift;
+ }
+ }
+
+ dsp_set_long_acc(opc.areg, acc);
+
+ Update_SR_Register(acc);
+ }
+
+ //-------------------------------------------------------------
+
+ // hcs give me this code!!
+ void dar(UDSPInstruction& opc)
+ {
+ u8 reg = opc.hex & 0x3;
+
+ int temp = g_dsp.r[reg] + g_dsp.r[8];
+
+ if (temp <= 0x7ff){g_dsp.r[reg] = temp;}
+ else {g_dsp.r[reg]--;}
+ }
+
+
+ // hcs give me this code!!
+ void iar(UDSPInstruction& opc)
+ {
+ u8 reg = opc.hex & 0x3;
+
+ int temp = g_dsp.r[reg] + g_dsp.r[8];
+
+ if (temp <= 0x7ff){g_dsp.r[reg] = temp;}
+ else {g_dsp.r[reg]++;}
+ }
+
+ //-------------------------------------------------------------
+
+ void sbclr(UDSPInstruction& opc)
+ {
+ u8 bit = (opc.hex & 0xff) + 6;
+ g_dsp.r[R_SR] &= ~(1 << bit);
+ }
+
+
+ void sbset(UDSPInstruction& opc)
+ {
+ u8 bit = (opc.hex & 0xff) + 6;
+ g_dsp.r[R_SR] |= (1 << bit);
+ }
+
+
+ // FIXME inside
+ void srbith(UDSPInstruction& opc)
+ {
+ switch ((opc.hex >> 8) & 0xf)
+ {
+ case 0xe: // SET40
+ g_dsp.r[R_SR] &= ~(1 << 14);
+ break;
+
+ // FIXME: Both of these appear in the beginning of the Wind Waker
+ //case 0xb:
+ //case 0xc:
+
+ /* case 0xf: // SET16 // that doesnt happen on a real console
+ g_dsp.r[R_SR] |= (1 << 14);
+ break;*/
+
+ default:
+ break;
+ }
+ }
+
+ //-------------------------------------------------------------
+
+ void movp(UDSPInstruction& opc)
+ {
+ u8 dreg = (opc.hex >> 8) & 0x1;
+
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod;
+ dsp_set_long_acc(dreg, acc);
+ }
+
+ void mul(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ s64 prod = (s64)dsp_get_ax_h(sreg) * (s64)dsp_get_ax_l(sreg) * GetMultiplyModifier();
+
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void mulac(UDSPInstruction& opc)
+ {
+ // add old prod to acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
+ dsp_set_long_acc(rreg, acR);
+
+ // math new prod
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ s64 prod = dsp_get_ax_l(sreg) * dsp_get_ax_h(sreg) * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void mulmv(UDSPInstruction& opc)
+ {
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod;
+ dsp_set_long_acc(rreg, acc);
+
+ u8 areg = ((opc.hex >> 11) & 0x1) + 0x18;
+ u8 breg = ((opc.hex >> 11) & 0x1) + 0x1a;
+ s64 val1 = (s16)g_dsp.r[areg];
+ s64 val2 = (s16)g_dsp.r[breg];
+
+ prod = val1 * val2 * GetMultiplyModifier();
+
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void mulmvz(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 11) & 0x1;
+ u8 rreg = (opc.hex >> 8) & 0x1;
+
+ // overwrite acc and clear low part
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod & ~0xffff;
+ dsp_set_long_acc(rreg, acc);
+
+ // math prod
+ prod = (s64)g_dsp.r[0x18 + sreg] * (s64)g_dsp.r[0x1a + sreg] * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void mulx(UDSPInstruction& opc)
+ {
+ u8 sreg = ((opc.hex >> 12) & 0x1);
+ u8 treg = ((opc.hex >> 11) & 0x1);
+
+ s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void mulxac(UDSPInstruction& opc)
+ {
+ // add old prod to acc
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
+ dsp_set_long_acc(rreg, acR);
+
+ // math new prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+
+ s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void mulxmv(UDSPInstruction& opc)
+ {
+ // add old prod to acc
+ u8 rreg = ((opc.hex >> 8) & 0x1);
+ s64 acR = dsp_get_long_prod();
+ dsp_set_long_acc(rreg, acR);
+
+ // math new prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+
+ s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void mulxmvz(UDSPInstruction& opc)
+ {
+ // overwrite acc and clear low part
+ u8 rreg = (opc.hex >> 8) & 0x1;
+ s64 prod = dsp_get_long_prod();
+ s64 acc = prod & ~0xffff;
+ dsp_set_long_acc(rreg, acc);
+
+ // math prod
+ u8 sreg = (opc.hex >> 12) & 0x1;
+ u8 treg = (opc.hex >> 11) & 0x1;
+
+ s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ prod = val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+
+ Update_SR_Register(prod);
+ }
+
+ void sub(UDSPInstruction& opc)
+ {
+ u8 D = (opc.hex >> 8) & 0x1;
+ s64 Acc1 = dsp_get_long_acc(D);
+ s64 Acc2 = dsp_get_long_acc(1 - D);
+
+ Acc1 -= Acc2;
+
+ dsp_set_long_acc(D, Acc1);
+ }
+
+
+ //-------------------------------------------------------------
+ //
+ // --- Table E
+ //
+ //-------------------------------------------------------------
+
+ void maddx(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 treg = (opc.hex >> 8) & 0x1;
+
+ s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = dsp_get_long_prod();
+ prod += val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+ }
+
+ void msubx(UDSPInstruction& opc)
+ {
+ u8 sreg = (opc.hex >> 9) & 0x1;
+ u8 treg = (opc.hex >> 8) & 0x1;
+
+ s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
+ s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
+
+ s64 prod = dsp_get_long_prod();
+ prod -= val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+ }
+
+ void maddc(UDSPInstruction& opc)
+ {
+ u32 sreg = (opc.hex >> 9) & 0x1;
+ u32 treg = (opc.hex >> 8) & 0x1;
+
+ s64 val1 = dsp_get_acc_m(sreg);
+ s64 val2 = dsp_get_ax_h(treg);
+
+ s64 prod = dsp_get_long_prod();
+ prod += val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+ }
+
+ void msubc(UDSPInstruction& opc)
+ {
+ u32 sreg = (opc.hex >> 9) & 0x1;
+ u32 treg = (opc.hex >> 8) & 0x1;
+
+ s64 val1 = dsp_get_acc_m(sreg);
+ s64 val2 = dsp_get_ax_h(treg);
+
+ s64 prod = dsp_get_long_prod();
+ prod -= val1 * val2 * GetMultiplyModifier();
+ dsp_set_long_prod(prod);
+ }
+
+
+
+
+
+};
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h
new file mode 100644
index 0000000000..c633c18635
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h
@@ -0,0 +1,133 @@
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPINTERPRETER_H
+#define _DSPINTERPRETER_H
+
+#include "DSPTables.h"
+
+#define SR_CMP_MASK 0x3f
+#define DSP_REG_MASK 0x1f
+
+#define R_SR 0x13
+#define FLAG_ENABLE_INTERUPT 11
+
+namespace DSPInterpreter {
+
+ // GLOBAL HELPER FUNCTIONS
+ void Update_SR_Register(s64 _Value);
+ s8 GetMultiplyModifier();
+ // END OF HELPER FUNCTIONS
+
+ void unknown(UDSPInstruction& opc);
+ void call(UDSPInstruction& opc);
+ void ifcc(UDSPInstruction& opc);
+ void jcc(UDSPInstruction& opc);
+ void ret(UDSPInstruction& opc);
+ void halt(UDSPInstruction& opc);
+ void loop(UDSPInstruction& opc);
+ void loopi(UDSPInstruction& opc);
+ void bloop(UDSPInstruction& opc);
+ void bloopi(UDSPInstruction& opc);
+ void mrr(UDSPInstruction& opc);
+ void lrr(UDSPInstruction& opc);
+ void srr(UDSPInstruction& opc);
+ void lri(UDSPInstruction& opc);
+ void lris(UDSPInstruction& opc);
+ void lr(UDSPInstruction& opc);
+ void sr(UDSPInstruction& opc);
+ void si(UDSPInstruction& opc);
+ void tstaxh(UDSPInstruction& opc);
+ void clr(UDSPInstruction& opc);
+ void clrp(UDSPInstruction& opc);
+ void mulc(UDSPInstruction& opc);
+ void cmpar(UDSPInstruction& opc);
+ void cmp(UDSPInstruction& opc);
+ void tsta(UDSPInstruction& opc);
+ void addaxl(UDSPInstruction& opc);
+ void addarn(UDSPInstruction& opc);
+ void mulcac(UDSPInstruction& opc);
+ void movr(UDSPInstruction& opc);
+ void movax(UDSPInstruction& opc);
+ void xorr(UDSPInstruction& opc);
+ void andr(UDSPInstruction& opc);
+ void orr(UDSPInstruction& opc);
+ void andc(UDSPInstruction& opc);
+ void add(UDSPInstruction& opc);
+ void addp(UDSPInstruction& opc);
+ void cmpis(UDSPInstruction& opc);
+ void addpaxz(UDSPInstruction& opc);
+ void movpz(UDSPInstruction& opc);
+ void decm(UDSPInstruction& opc);
+ void dec(UDSPInstruction& opc);
+ void inc(UDSPInstruction& opc);
+ void incm(UDSPInstruction& opc);
+ void neg(UDSPInstruction& opc);
+ void addax(UDSPInstruction& opc);
+ void addr(UDSPInstruction& opc);
+ void subr(UDSPInstruction& opc);
+ void subax(UDSPInstruction& opc);
+ void addis(UDSPInstruction& opc);
+ void addi(UDSPInstruction& opc);
+ void lsl16(UDSPInstruction& opc);
+ void madd(UDSPInstruction& opc);
+ void lsr16(UDSPInstruction& opc);
+ void asr16(UDSPInstruction& opc);
+ void shifti(UDSPInstruction& opc);
+ void dar(UDSPInstruction& opc);
+ void iar(UDSPInstruction& opc);
+ void sbclr(UDSPInstruction& opc);
+ void sbset(UDSPInstruction& opc);
+ void movp(UDSPInstruction& opc);
+ void mul(UDSPInstruction& opc);
+ void mulac(UDSPInstruction& opc);
+ void mulmv(UDSPInstruction& opc);
+ void mulmvz(UDSPInstruction& opc);
+ void mulx(UDSPInstruction& opc);
+ void mulxac(UDSPInstruction& opc);
+ void mulxmv(UDSPInstruction& opc);
+ void mulxmvz(UDSPInstruction& opc);
+ void sub(UDSPInstruction& opc);
+ void maddx(UDSPInstruction& opc);
+ void msubx(UDSPInstruction& opc);
+ void maddc(UDSPInstruction& opc);
+ void msubc(UDSPInstruction& opc);
+
+
+ // FIXME inside
+ void jmpa(UDSPInstruction& opc);
+ void rti(UDSPInstruction& opc);
+ void ilrr(UDSPInstruction& opc);
+ void srbith(UDSPInstruction& opc);
+
+ void andfc(UDSPInstruction& opc);
+ void andf(UDSPInstruction& opc);
+ void subf(UDSPInstruction& opc);
+ void xori(UDSPInstruction& opc);
+ void andi(UDSPInstruction& opc);
+ void ori(UDSPInstruction& opc);
+ // END OF FIXMEs
+
+ // TODO: PENDING IMPLEMENTATION / UNIMPLEMENTED
+ void mulcmvz(UDSPInstruction& opc);
+ void mulcmv(UDSPInstruction& opc);
+ void nx(UDSPInstruction& opc);
+ void movnp(UDSPInstruction& opc);
+ // END OF UNIMPLEMENTED
+};
+
+#endif // _DSPINTERPRETER_H
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.cpp
new file mode 100644
index 0000000000..cbf7d1ebeb
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.cpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "DSPJit.h"
+
+namespace DSPJit {
+
+};
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.h
new file mode 100644
index 0000000000..93564925eb
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPJIT_H
+#define _DSPJIT_H
+
+namespace DSPJit {
+ // TODO(XK): Fill
+
+
+};
+
+#endif // _DSPJIT_H
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp
similarity index 89%
rename from Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.cpp
rename to Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp
index 23e58b55b4..9934f88e84 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp
@@ -1,243 +1,253 @@
-/*====================================================================
-
- filename: opcodes.cpp
- project: GameCube DSP Tool (gcdsp)
- created: 2005.03.04
- mail: duddie@walla.com
-
- Copyright (c) 2005 Duddie
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- ====================================================================*/
-
-#include "Globals.h"
-#include "opcodes.h"
-
-void unimplementedInst(UDSPInstruction& inst) {
- PanicAlert("Unimplemented instruction %d", inst.hex);
-}
-
-void nop(UDSPInstruction&) {}
-
-DSPOPCTemplate opcodes[] =
-{
- {"NOP", 0x0000, 0xffff, nop, nop, 1, 0, {},},
- {"HALT", 0x0021, 0xffff, nop, nop, 1, 0, {},},
- {"RET", 0x02df, 0xffff, nop, nop, 1, 0, {},},
- {"RETEQ", 0x02d5, 0xffff, nop, nop, 1, 0, {},},
- {"RETNZ", 0x02dd, 0xffff, nop, nop, 1, 0, {},},
- {"RTI", 0x02ff, 0xffff, nop, nop, 1, 0, {},},
- {"CALL", 0x02bf, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
-
- {"CALLNE", 0x02b4, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
-
- {"IF_0", 0x0270, 0xffff, nop, nop, 1, 0, {},},
- {"IF_1", 0x0271, 0xffff, nop, nop, 1, 0, {},},
- {"IF_2", 0x0272, 0xffff, nop, nop, 1, 0, {},},
- {"IF_3", 0x0273, 0xffff, nop, nop, 1, 0, {},},
- {"IF_E", 0x0274, 0xffff, nop, nop, 1, 0, {},},
- {"IF_Q", 0x0275, 0xffff, nop, nop, 1, 0, {},},
- {"IF_R", 0x027c, 0xffff, nop, nop, 1, 0, {},},
- {"IF_Z", 0x027d, 0xffff, nop, nop, 1, 0, {},},
- {"IF_P", 0x027f, 0xffff, nop, nop, 1, 0, {},},
-
- {"JX0", 0x0290, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JX1", 0x0291, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JX2", 0x0292, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JX3", 0x0293, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JNE", 0x0294, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JEQ", 0x0295, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JZR", 0x029c, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JNZ", 0x029d, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
- {"JMP", 0x029f, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
-
- {"DAR", 0x0004, 0xfffc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
- {"IAR", 0x0008, 0xfffc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
-
- {"CALLR", 0x171f, 0xff1f, nop, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},},
- {"JMPR", 0x170f, 0xff1f, nop, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},},
-
- {"SBCLR", 0x1200, 0xfff8, nop, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},},
- {"SBSET", 0x1300, 0xfff8, nop, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},},
-
- {"LSL", 0x1400, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},},
- {"LSR", 0x1440, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},},
- {"ASL", 0x1480, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},},
- {"ASR", 0x14c0, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},},
-
-
- {"LRI", 0x0080, 0xffe0, nop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}},},
- {"LR", 0x00c0, 0xffe0, nop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}},},
- {"SR", 0x00e0, 0xffe0, nop, nop, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}},},
-
- {"MRR", 0x1c00, 0xfc00, nop, nop, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}},},
-
- {"SI", 0x1600, 0xff00, nop, nop, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}},},
-
- {"LRS", 0x2000, 0xf800, nop, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}},},
- {"SRS", 0x2800, 0xf800, nop, nop, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}},},
-
- {"LRIS", 0x0800, 0xf800, nop, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}},},
-
- {"ADDIS", 0x0400, 0xfe00, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},},
- {"CMPIS", 0x0600, 0xfe00, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},},
-
- {"ANDI", 0x0240, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
- {"ANDF", 0x02c0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
-
- {"XORI", 0x0220, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
- {"ANDCF", 0x02a0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
-
- {"ORI", 0x0260, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
- {"ORF", 0x02e0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
-
- {"ADDI", 0x0200, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64
- {"CMPI", 0x0280, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64
-
- {"ILRR", 0x0210, 0xfedc, nop, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},},
- {"ILRRI", 0x0218, 0xfedc, nop, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},},
-
- // load and store value pointed by indexing reg and increment; LRR/SRR variants
- {"LRRI", 0x1900, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
- {"LRRD", 0x1880, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
- {"LRRN", 0x1980, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
- {"LRR", 0x1800, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
- {"SRRI", 0x1b00, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
- {"SRRD", 0x1a80, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
- {"SRRN", 0x1b80, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
- {"SRR", 0x1a00, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
-
- {"LOOPI", 0x1000, 0xff00, nop, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x00ff}},},
- {"BLOOPI", 0x1100, 0xff00, nop, nop, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_VAL, 2, 1, 0, 0xffff}},},
- {"LOOP", 0x0040, 0xffe0, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x001f}},},
- {"BLOOP", 0x0060, 0xffe0, nop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_VAL, 2, 1, 0, 0xffff}},},
-
-
-
- // opcodes that can be extended
- // extended opcodes, note size of opcode will be set to 0
-
- {"NX", 0x8000, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
-
- {"S40", 0x8e00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
- {"S16", 0x8f00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
- {"M2", 0x8a00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
- {"M0", 0x8b00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
- {"CLR15", 0x8c00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
- {"SET15", 0x8d00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
-
- {"DECM", 0x7800, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
- {"INCM", 0x7400, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
- {"DEC", 0x7a00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
- {"INC", 0x7600, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"NEG", 0x7c00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"TST", 0xb100, 0xf7ff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
- {"TSTAXH", 0x8600, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_REG1A, 1, 0, 8, 0x0100}},},
- {"CMP", 0x8200, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
- {"CMPAXH", 0xc100, 0xe7ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}},},
-
- {"CLR", 0x8100, 0xf7ff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
- {"CLRP", 0x8400, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
-
- {"MOV", 0x6c00, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
- {"MOVAX", 0x6800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
- {"MOVR", 0x6000, 0xf8ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
- {"MOVP", 0x6e00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
- {"MOVPZ", 0xfe00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"ADDPAXZ", 0xf800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG1A, 1, 0, 8, 0x0100}},},
- {"ADDP", 0x4e00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"LSL16", 0xf000, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
- {"LSR16", 0xf400, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
- {"ASR16", 0x9100, 0xf7ff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
-
- {"XORR", 0x3000, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
- {"ANDR", 0x3400, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
- {"ORR", 0x3800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
- {"ANDC", 0x3C00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
- {"ORC", 0x3E00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"MULX", 0xa000, 0xe7ff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}},},
- {"MULXAC", 0xa400, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
- {"MULXMV", 0xa600, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
- {"MULXMVZ", 0xa200, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"MUL", 0x9000, 0xf7ff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}},},
- {"MULAC", 0x9400, 0xf6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
- {"MULMV", 0x9600, 0xf6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
- {"MULMVZ", 0x9200, 0xf6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"MULC", 0xc000, 0xe7ff, nop, nop, 1 | P_EXT, 2, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}},},
- {"MULCAC", 0xc400, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
- {"MULCMV", 0xc600, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
- {"MULCMVZ", 0xc200, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
-
- {"ADDR", 0x4000, 0xf8ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
- {"ADDAX", 0x4800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
- {"ADD", 0x4c00, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
- {"ADDAXL", 0x7000, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
-
- {"SUBR", 0x5000, 0xf8ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
- {"SUBAX", 0x5800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
- {"SUB", 0x5c00, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
-
- {"MADD", 0xf200, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},},
- {"MSUB", 0xf600, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},},
- {"MADDX", 0xe000, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
- {"MSUBX", 0xe400, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
- {"MADDC", 0xe800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
- {"MSUBC", 0xec00, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
-
- // assemble CW
- {"CW", 0x0000, 0xffff, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},},
- // unknown opcode for disassemble
- {"CW", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},},
-};
-DSPOPCTemplate opcodes_ext[] =
-{
- {"L", 0x0040, 0x00c4, nop, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},},
- {"LN", 0x0044, 0x00c4, nop, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},},
- {"LS", 0x0080, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
- {"LSN", 0x0084, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
- {"LSM", 0x0088, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
- {"LSNM", 0x008c, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
- {"SL", 0x0082, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
- {"SLN", 0x0086, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
- {"SLM", 0x008a, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
- {"SLNM", 0x008e, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
- {"S", 0x0020, 0x00e4, nop, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},},
- {"SN", 0x0024, 0x00e4, nop, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},},
- {"LDX", 0x00c0, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
- {"LDXN", 0x00c4, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
- {"LDXM", 0x00c8, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
- {"LDXNM", 0x00cc, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
- {"LD", 0x00c0, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
- {"LDN", 0x00c4, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
- {"LDM", 0x00c8, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
- {"LDNM", 0x00cc, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
- {"MV", 0x0010, 0x00f0, nop, nop, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}},},
- {"DR", 0x0004, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
- {"IR", 0x0008, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
- {"NR", 0x000c, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
- {"XXX", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}},},
-};
-
-const u32 opcodes_size = sizeof(opcodes) / sizeof(opc_t);
-const u32 opcodes_ext_size = sizeof(opcodes_ext) / sizeof(opc_t);
-
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie (c) 2005 (duddie@walla.com)
+
+#include "Globals.h"
+#include "DSPTables.h"
+
+#include "DSPInterpreter.h"
+#include "DSPJit.h"
+
+void unimplementedInst(UDSPInstruction& inst) {
+ PanicAlert("Unimplemented instruction %d", inst.hex);
+}
+
+void nop(UDSPInstruction&) {}
+
+// TODO(XK): Fill up the tables with the corresponding instructions
+DSPOPCTemplate opcodes[] =
+{
+ {"NOP", 0x0000, 0xffff, nop, nop, 1, 0, {},},
+ {"HALT", 0x0021, 0xffff, DSPInterpreter::halt, nop, 1, 0, {},},
+ {"RET", 0x02df, 0xffff, DSPInterpreter::ret, nop, 1, 0, {},},
+ {"RETEQ", 0x02d5, 0xffff, nop, nop, 1, 0, {},},
+ {"RETNZ", 0x02dd, 0xffff, nop, nop, 1, 0, {},},
+ {"RTI", 0x02ff, 0xffff, DSPInterpreter::rti, nop, 1, 0, {},},
+ {"CALL", 0x02bf, 0xffff, DSPInterpreter::call, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+
+ {"CALLNE", 0x02b4, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+
+ {"IF_0", 0x0270, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_1", 0x0271, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_2", 0x0272, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_3", 0x0273, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_E", 0x0274, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_Q", 0x0275, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_R", 0x027c, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_Z", 0x027d, 0xffff, nop, nop, 1, 0, {},},
+ {"IF_P", 0x027f, 0xffff, nop, nop, 1, 0, {},},
+
+ {"JX0", 0x0290, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JX1", 0x0291, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JX2", 0x0292, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JX3", 0x0293, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JNE", 0x0294, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JEQ", 0x0295, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JZR", 0x029c, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JNZ", 0x029d, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+ {"JMP", 0x029f, 0xffff, nop, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
+
+ {"DAR", 0x0004, 0xfffc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
+ {"IAR", 0x0008, 0xfffc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
+
+ {"CALLR", 0x171f, 0xff1f, nop, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},},
+ {"JMPR", 0x170f, 0xff1f, nop, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},},
+
+ {"SBCLR", 0x1200, 0xfff8, nop, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},},
+ {"SBSET", 0x1300, 0xfff8, nop, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},},
+
+ {"LSL", 0x1400, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},},
+ {"LSR", 0x1440, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},},
+ {"ASL", 0x1480, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},},
+ {"ASR", 0x14c0, 0xfec0, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},},
+
+
+ {"LRI", 0x0080, 0xffe0, nop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}},},
+ {"LR", 0x00c0, 0xffe0, nop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}},},
+ {"SR", 0x00e0, 0xffe0, nop, nop, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}},},
+
+ {"MRR", 0x1c00, 0xfc00, nop, nop, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}},},
+
+ {"SI", 0x1600, 0xff00, nop, nop, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}},},
+
+ {"LRS", 0x2000, 0xf800, nop, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}},},
+ {"SRS", 0x2800, 0xf800, nop, nop, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}},},
+
+ {"LRIS", 0x0800, 0xf800, nop, nop, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}},},
+
+ {"ADDIS", 0x0400, 0xfe00, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},},
+ {"CMPIS", 0x0600, 0xfe00, nop, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},},
+
+ {"ANDI", 0x0240, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
+ {"ANDF", 0x02c0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
+
+ {"XORI", 0x0220, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
+ {"ANDCF", 0x02a0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
+
+ {"ORI", 0x0260, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
+ {"ORF", 0x02e0, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
+
+ {"ADDI", 0x0200, 0xfeff, nop, nop, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64
+ {"CMPI", 0x0280, 0xfeff, nop, nop, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64
+
+ {"ILRR", 0x0210, 0xfedc, nop, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},},
+ {"ILRRI", 0x0218, 0xfedc, nop, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},},
+
+ // load and store value pointed by indexing reg and increment; LRR/SRR variants
+ {"LRRI", 0x1900, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
+ {"LRRD", 0x1880, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
+ {"LRRN", 0x1980, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
+ {"LRR", 0x1800, 0xff80, nop, nop, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
+ {"SRRI", 0x1b00, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
+ {"SRRD", 0x1a80, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
+ {"SRRN", 0x1b80, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
+ {"SRR", 0x1a00, 0xff80, nop, nop, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
+
+ {"LOOPI", 0x1000, 0xff00, nop, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x00ff}},},
+ {"BLOOPI", 0x1100, 0xff00, nop, nop, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_VAL, 2, 1, 0, 0xffff}},},
+ {"LOOP", 0x0040, 0xffe0, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x001f}},},
+ {"BLOOP", 0x0060, 0xffe0, nop, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_VAL, 2, 1, 0, 0xffff}},},
+
+
+
+ // opcodes that can be extended
+ // extended opcodes, note size of opcode will be set to 0
+
+ {"NX", 0x8000, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+
+ {"S40", 0x8e00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+ {"S16", 0x8f00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+ {"M2", 0x8a00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+ {"M0", 0x8b00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+ {"CLR15", 0x8c00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+ {"SET15", 0x8d00, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+
+ {"DECM", 0x7800, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+ {"INCM", 0x7400, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+ {"DEC", 0x7a00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+ {"INC", 0x7600, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"NEG", 0x7c00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"TST", 0xb100, 0xf7ff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
+ {"TSTAXH", 0x8600, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_REG1A, 1, 0, 8, 0x0100}},},
+ {"CMP", 0x8200, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+ {"CMPAXH", 0xc100, 0xe7ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}},},
+
+ {"CLR", 0x8100, 0xf7ff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
+ {"CLRP", 0x8400, 0xffff, nop, nop, 1 | P_EXT, 0, {},},
+
+ {"MOV", 0x6c00, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
+ {"MOVAX", 0x6800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
+ {"MOVR", 0x6000, 0xf8ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
+ {"MOVP", 0x6e00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+ {"MOVPZ", 0xfe00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"ADDPAXZ", 0xf800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG1A, 1, 0, 8, 0x0100}},},
+ {"ADDP", 0x4e00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"LSL16", 0xf000, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+ {"LSR16", 0xf400, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+ {"ASR16", 0x9100, 0xf7ff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
+
+ {"XORR", 0x3000, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
+ {"ANDR", 0x3400, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
+ {"ORR", 0x3800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
+ {"ANDC", 0x3C00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+ {"ORC", 0x3E00, 0xfeff, nop, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"MULX", 0xa000, 0xe7ff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}},},
+ {"MULXAC", 0xa400, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
+ {"MULXMV", 0xa600, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
+ {"MULXMVZ", 0xa200, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"MUL", 0x9000, 0xf7ff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}},},
+ {"MULAC", 0x9400, 0xf6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
+ {"MULMV", 0x9600, 0xf6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
+ {"MULMVZ", 0x9200, 0xf6ff, nop, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"MULC", 0xc000, 0xe7ff, nop, nop, 1 | P_EXT, 2, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}},},
+ {"MULCAC", 0xc400, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
+ {"MULCMV", 0xc600, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
+ {"MULCMVZ", 0xc200, 0xe6ff, nop, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
+
+ {"ADDR", 0x4000, 0xf8ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
+ {"ADDAX", 0x4800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
+ {"ADD", 0x4c00, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
+ {"ADDAXL", 0x7000, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
+
+ {"SUBR", 0x5000, 0xf8ff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
+ {"SUBAX", 0x5800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
+ {"SUB", 0x5c00, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
+
+ {"MADD", 0xf200, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},},
+ {"MSUB", 0xf600, 0xfeff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},},
+ {"MADDX", 0xe000, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
+ {"MSUBX", 0xe400, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
+ {"MADDC", 0xe800, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
+ {"MSUBC", 0xec00, 0xfcff, nop, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
+
+ // assemble CW
+ {"CW", 0x0000, 0xffff, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},},
+ // unknown opcode for disassemble
+ {"CW", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},},
+};
+DSPOPCTemplate opcodes_ext[] =
+{
+ {"L", 0x0040, 0x00c4, nop, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},},
+ {"LN", 0x0044, 0x00c4, nop, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},},
+ {"LS", 0x0080, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
+ {"LSN", 0x0084, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
+ {"LSM", 0x0088, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
+ {"LSNM", 0x008c, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
+ {"SL", 0x0082, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
+ {"SLN", 0x0086, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
+ {"SLM", 0x008a, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
+ {"SLNM", 0x008e, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
+ {"S", 0x0020, 0x00e4, nop, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},},
+ {"SN", 0x0024, 0x00e4, nop, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},},
+ {"LDX", 0x00c0, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
+ {"LDXN", 0x00c4, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
+ {"LDXM", 0x00c8, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
+ {"LDXNM", 0x00cc, 0x00cf, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
+ {"LD", 0x00c0, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
+ {"LDN", 0x00c4, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
+ {"LDM", 0x00c8, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
+ {"LDNM", 0x00cc, 0x00cc, nop, nop, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
+ {"MV", 0x0010, 0x00f0, nop, nop, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}},},
+ {"DR", 0x0004, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
+ {"IR", 0x0008, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
+ {"NR", 0x000c, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
+ {"XXX", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}},},
+};
+
+const u32 opcodes_size = sizeof(opcodes) / sizeof(opc_t);
+const u32 opcodes_ext_size = sizeof(opcodes_ext) / sizeof(opc_t);
+
+void InitInstructionTable() {
+ // TODO(XK): Fill
+}
+
+void DestroyInstructionTable() {
+ // TODO(XK): Fill
+}
+
+void ComputeInstruction(UDSPInstruction& inst) {
+ // TODO(XK): Fill
+ DSPInterpreter::unknown(inst);
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h
new file mode 100644
index 0000000000..7ff762d26e
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h
@@ -0,0 +1,108 @@
+// Copyright (C) 2003-2009 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Additional copyrights go to Duddie (c) 2005 (duddie@walla.com)
+
+#ifndef _DSPTABLES_H
+#define _DSPTABLES_H
+
+enum parameterType
+{
+ P_NONE = 0x0000,
+ P_VAL = 0x0001,
+ P_IMM = 0x0002,
+ P_MEM = 0x0003,
+ P_STR = 0x0004,
+ P_REG = 0x8000,
+ P_REG08 = P_REG | 0x0800,
+ P_REG10 = P_REG | 0x1000,
+ P_REG18 = P_REG | 0x1800,
+ P_REG19 = P_REG | 0x1900,
+ P_REG1A = P_REG | 0x1a00,
+ P_REG1C = P_REG | 0x1c00,
+ P_ACCM = P_REG | 0x1e00,
+ P_ACCM_D = P_REG | 0x1e80,
+ P_ACC = P_REG | 0x2000,
+ P_ACC_D = P_REG | 0x2080,
+ P_AX = P_REG | 0x2200,
+ P_AX_D = P_REG | 0x2280,
+ P_REGS_MASK = 0x03f80,
+ P_REF = P_REG | 0x4000,
+ P_PRG = P_REF | P_REG,
+};
+
+#define P_EXT 0x80
+
+union UDSPInstruction
+{
+ u16 hex;
+
+ UDSPInstruction(u16 _hex) { hex = _hex; }
+ UDSPInstruction() { hex = 0; }
+
+ struct
+ {
+ signed shift : 6;
+ unsigned negating : 1;
+ unsigned arithmetic : 1;
+ unsigned areg : 1;
+ unsigned op : 7;
+ };
+ struct
+ {
+ unsigned ushift : 6;
+ };
+
+ // TODO(XK): Figure out more instruction structures (add structs here)
+};
+
+typedef void (*dspInstFunc)(UDSPInstruction&);
+
+typedef struct DSPOParams
+{
+ parameterType type;
+ u8 size;
+ u8 loc;
+ s8 lshift;
+ u16 mask;
+} opcpar_t;
+
+typedef struct DSPOPCTemplate
+{
+ const char *name;
+ u16 opcode;
+ u16 opcode_mask;
+
+ dspInstFunc interpFunc;
+ dspInstFunc jitFunc;
+
+ u8 size;
+ u8 param_count;
+ DSPOParams params[8];
+} opc_t;
+
+extern DSPOPCTemplate opcodes[];
+extern const u32 opcodes_size;
+extern opc_t opcodes_ext[];
+extern const u32 opcodes_ext_size;
+
+void InitInstructionTable();
+void DestroyInstructionTable();
+
+void ComputeInstruction(UDSPInstruction& inst);
+
+#endif // _DSPTABLES_H
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Functions.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Functions.cpp
index c5bd81dda8..579bcdcaef 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Functions.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Functions.cpp
@@ -20,6 +20,10 @@
#endif
#include "Globals.h"
#include "HLE_Helper.h"
+#include "DSPInterpreter.h"
+
+// Avoid adding "DSPInterpreter::" to every instruction
+using namespace DSPInterpreter;
u16& R00 = g_dsp.r[0x00];
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.h
index 90137a076f..b9d1c27311 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.h
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.h
@@ -22,8 +22,6 @@
bool WriteDMEM(u16 addr, u16 val);
u16 ReadDMEM(u16 addr);
-void Update_SR_Register(s64 _Value);
-s8 GetMultiplyModifier();
template
class TAccumulator
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.cpp
index 495c5a72ef..b28fb7c274 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.cpp
@@ -30,7 +30,7 @@
#include "Globals.h"
#include "disassemble.h"
-#include "opcodes.h"
+#include "DSPTables.h"
// #include "gdsp_tool.h"
#ifdef _MSC_VER
@@ -39,8 +39,6 @@
u32 unk_opcodes[0x10000];
-u16 swap16(u16 x);
-
// predefined labels
typedef struct pdlabel_t
@@ -289,7 +287,7 @@ u16 gd_dis_get_opcode_size(gd_globals_t* gdg)
return(1);
}
- u32 op1 = swap16(gdg->binbuf[gdg->pc & 0x0fff]);
+ u32 op1 = Common::swap16(gdg->binbuf[gdg->pc & 0x0fff]);
for (u32 j = 0; j < opcodes_size; j++)
{
@@ -371,7 +369,7 @@ char* gd_dis_opcode(gd_globals_t* gdg)
}
pc &= 0x0fff;
- op1 = swap16(gdg->binbuf[pc]);
+ op1 = Common::swap16(gdg->binbuf[pc]);
// find opcode
for (j = 0; j < opcodes_size; j++)
@@ -425,7 +423,7 @@ char* gd_dis_opcode(gd_globals_t* gdg)
if ((opc->size & ~P_EXT) == 2)
{
- op2 = swap16(gdg->binbuf[pc + 1]);
+ op2 = Common::swap16(gdg->binbuf[pc + 1]);
if (gdg->show_hex){sprintf(buf, "%04x %04x ", op1, op2);}
}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp
index fec4ee6353..91e10325e8 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp
@@ -1,4 +1,3 @@
-// April Fools!
/*====================================================================
filename: gdsp_interpreter.cpp
@@ -27,6 +26,8 @@
#include
#include
+#include "DSPTables.h"
+
#include "gdsp_interface.h"
#include "gdsp_opcodes_helper.h"
#include "Tools.h"
@@ -67,23 +68,13 @@ void UpdateCachedCR()
CR_EXTERNAL_INT = (g_dsp.cr & 0x02) != 0;
}
-
-
//-------------------------------------------------------------------------------
-void (*dsp_op[])(u16 opc) =
-{
- dsp_op0, dsp_op1, dsp_op2, dsp_op3,
- dsp_op4, dsp_op5, dsp_op6, dsp_op7,
- dsp_op8, dsp_op9, dsp_opab, dsp_opab,
- dsp_opcd, dsp_opcd, dsp_ope, dsp_opf,
-};
void dbg_error(char* err_msg)
{
return;
}
-
void gdsp_init()
{
g_dsp.irom = (u16*)malloc(DSP_IROM_SIZE * sizeof(u16));
@@ -218,7 +209,7 @@ void gdsp_loop_step()
{
g_dsp.err_pc = g_dsp.pc;
u16 opc = dsp_fetch_code();
- dsp_op[opc >> 12](opc);
+ ComputeInstruction(UDSPInstruction(opc));
}
u16 HLE_ROM_80E7_81F8();
@@ -249,7 +240,7 @@ void gdsp_step()
#endif
u16 opc = dsp_fetch_code();
- dsp_op[opc >> 12](opc);
+ ComputeInstruction(UDSPInstruction(opc));
u16& rLoopCounter = g_dsp.r[DSP_REG_ST0 + 3];
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.cpp
deleted file mode 100644
index 8869b74533..0000000000
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.cpp
+++ /dev/null
@@ -1,2251 +0,0 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-// Change Log
-
-// fixed dsp_opc_mulx (regarding DSP 0.0.4.pdf)
-// fixed dsp_opc_mulxmv (regarding DSP 0.0.4.pdf)
-// fixed dsp_opc_mulxmvz (regarding DSP 0.0.4.pdf)
-// dsp_opc_shifti: removed strange " >> 9"
-// added masking for SR_COMPARE_FLAGS
-// added "UNKNOWN_CW" but without a function (yet? :)
-// added missing compare type to MISSING_COMPARES_JX ... but i dunno what it does
-
-// added "MULXMV" to another function table
-
-/*====================================================================
-
- filename: gdsp_opcodes.cpp
- project: GCemu
- created: 2004-6-18
- mail: duddie@walla.com
-
- Copyright (c) 2005 Duddie & Tratax
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- ====================================================================*/
-
-#include
-#include "Globals.h"
-#include "gdsp_opcodes.h"
-#include "gdsp_memory.h"
-#include "gdsp_interpreter.h"
-#include "gdsp_registers.h"
-#include "gdsp_opcodes_helper.h"
-#include "gdsp_ext_op.h"
-
-#define SR_CMP_MASK 0x3f
-#define DSP_REG_MASK 0x1f
-
-void Update_SR_Register(s64 _Value)
-{
- g_dsp.r[R_SR] &= ~SR_CMP_MASK;
-
- if (_Value < 0)
- {
- g_dsp.r[R_SR] |= 0x8;
- }
-
- if (_Value == 0)
- {
- g_dsp.r[R_SR] |= 0x4;
- }
-
- // logic
- if ((_Value >> 62) == 0)
- {
- g_dsp.r[R_SR] |= 0x20;
- }
-}
-
-
-void Update_SR_Register(s16 _Value)
-{
- g_dsp.r[R_SR] &= ~SR_CMP_MASK;
-
- if (_Value < 0)
- {
- g_dsp.r[R_SR] |= 0x8;
- }
-
- if (_Value == 0)
- {
- g_dsp.r[R_SR] |= 0x4;
- }
-
- // logic
- if ((_Value >> 14) == 0)
- {
- g_dsp.r[R_SR] |= 0x20;
- }
-}
-
-
-s8 GetMultiplyModifier()
-{
- if (g_dsp.r[R_SR] & (1 << 13))
- {
- return(1);
- }
-
- return(2);
-}
-
-
-bool CheckCondition(u8 _Condition)
-{
- bool taken = false;
-
- switch (_Condition & 0xf)
- {
- case 0x0:
-
- if ((!(g_dsp.r[R_SR] & 0x02)) && (!(g_dsp.r[R_SR] & 0x08)))
- {
- taken = true;
- }
-
- break;
-
- case 0x3:
-
- if ((g_dsp.r[R_SR] & 0x02) || (g_dsp.r[R_SR] & 0x04) || (g_dsp.r[R_SR] & 0x08))
- {
- taken = true;
- }
-
- break;
-
- // old from duddie
- case 0x1: // seems okay
-
- if ((!(g_dsp.r[R_SR] & 0x02)) && (g_dsp.r[R_SR] & 0x08))
- {
- taken = true;
- }
-
- break;
-
- case 0x2:
-
- if (!(g_dsp.r[R_SR] & 0x08))
- {
- taken = true;
- }
-
- break;
-
- case 0x4:
-
- if (!(g_dsp.r[R_SR] & 0x04))
- {
- taken = true;
- }
-
- break;
-
- case 0x5:
-
- if (g_dsp.r[R_SR] & 0x04)
- {
- taken = true;
- }
-
- break;
-
- case 0xc:
-
- if (!(g_dsp.r[R_SR] & 0x40))
- {
- taken = true;
- }
-
- break;
-
- case 0xd:
-
- if (g_dsp.r[R_SR] & 0x40)
- {
- taken = true;
- }
-
- break;
-
- case 0xf:
- taken = true;
- break;
-
- default:
- // DEBUG_LOG(DSPHLE, "Unknown condition check: 0x%04x\n", _Condition & 0xf);
- break;
- }
-
- return(taken);
-}
-
-
-// =======================================================================
-
-void dsp_op_unknown(u16 opc)
-{
- _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
- ERROR_LOG(DSPHLE, "dsp_op_unknown somewhere");
- g_dsp.pc = g_dsp.err_pc;
-}
-
-
-void dsp_opc_call(u16 opc)
-{
- u16 dest = dsp_fetch_code();
-
- if (CheckCondition(opc & 0xf))
- {
- dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
- g_dsp.pc = dest;
- }
-}
-
-
-void dsp_opc_ifcc(u16 opc)
-{
- if (!CheckCondition(opc & 0xf))
- {
- dsp_fetch_code(); // skip the next opcode
- }
-}
-
-
-void dsp_opc_jcc(u16 opc)
-{
- u16 dest = dsp_fetch_code();
-
- if (CheckCondition(opc & 0xf))
- {
- g_dsp.pc = dest;
- }
-}
-
-
-void dsp_opc_jmpa(u16 opc)
-{
- u8 reg;
- u16 addr;
-
- if ((opc & 0xf) != 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_jmpa");
- }
-
- reg = (opc >> 5) & 0x7;
- addr = dsp_op_read_reg(reg);
-
- if (opc & 0x0010)
- {
- // CALLA
- dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
- }
-
- g_dsp.pc = addr;
-}
-
-
-// NEW (added condition check)
-void dsp_opc_ret(u16 opc)
-{
- if (CheckCondition(opc & 0xf))
- {
- g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
- }
-}
-
-
-void dsp_opc_rti(u16 opc)
-{
- if ((opc & 0xf) != 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_rti");
- }
-
- g_dsp.r[R_SR] = dsp_reg_load_stack(DSP_STACK_D);
- g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
-
- g_dsp.exception_in_progress_hack = false;
-}
-
-
-void dsp_opc_halt(u16 opc)
-{
- g_dsp.cr |= 0x4;
- g_dsp.pc = g_dsp.err_pc;
-}
-
-
-void dsp_opc_loop(u16 opc)
-{
- u16 reg = opc & 0x1f;
- u16 cnt = g_dsp.r[reg];
- u16 loop_pc = g_dsp.pc;
-
- while (cnt--)
- {
- gdsp_loop_step();
- g_dsp.pc = loop_pc;
- }
-
- g_dsp.pc = loop_pc + 1;
-}
-
-
-void dsp_opc_loopi(u16 opc)
-{
- u16 cnt = opc & 0xff;
- u16 loop_pc = g_dsp.pc;
-
- while (cnt--)
- {
- gdsp_loop_step();
- g_dsp.pc = loop_pc;
- }
-
- g_dsp.pc = loop_pc + 1;
-}
-
-
-void dsp_opc_bloop(u16 opc)
-{
- u16 reg = opc & 0x1f;
- u16 cnt = g_dsp.r[reg];
- u16 loop_pc = dsp_fetch_code();
-
- if (cnt)
- {
- dsp_reg_store_stack(0, g_dsp.pc);
- dsp_reg_store_stack(2, loop_pc);
- dsp_reg_store_stack(3, cnt);
- }
- else
- {
- g_dsp.pc = loop_pc + 1;
- }
-}
-
-
-void dsp_opc_bloopi(u16 opc)
-{
- u16 cnt = opc & 0xff;
- u16 loop_pc = dsp_fetch_code();
-
- if (cnt)
- {
- dsp_reg_store_stack(0, g_dsp.pc);
- dsp_reg_store_stack(2, loop_pc);
- dsp_reg_store_stack(3, cnt);
- }
- else
- {
- g_dsp.pc = loop_pc + 1;
- }
-}
-
-
-//-------------------------------------------------------------
-
-
-void dsp_opc_mrr(u16 opc)
-{
- u8 sreg = opc & 0x1f;
- u8 dreg = (opc >> 5) & 0x1f;
-
- u16 val = dsp_op_read_reg(sreg);
- dsp_op_write_reg(dreg, val);
-}
-
-
-void dsp_opc_lrr(u16 opc)
-{
- u8 sreg = (opc >> 5) & 0x3;
- u8 dreg = opc & 0x1f;
-
- u16 val = dsp_dmem_read(g_dsp.r[sreg]);
- dsp_op_write_reg(dreg, val);
-
- // post processing of source reg
- switch ((opc >> 7) & 0x3)
- {
- case 0x0: // LRR
- break;
-
- case 0x1: // LRRD
- g_dsp.r[sreg]--;
- break;
-
- case 0x2: // LRRI
- g_dsp.r[sreg]++;
- break;
-
- case 0x3:
- g_dsp.r[sreg] += g_dsp.r[sreg + 4];
- break;
- }
-}
-
-
-void dsp_opc_srr(u16 opc)
-{
- u8 dreg = (opc >> 5) & 0x3;
- u8 sreg = opc & 0x1f;
-
- u16 val = dsp_op_read_reg(sreg);
- dsp_dmem_write(g_dsp.r[dreg], val);
-
- // post processing of dest reg
- switch ((opc >> 7) & 0x3)
- {
- case 0x0: // SRR
- break;
-
- case 0x1: // SRRD
- g_dsp.r[dreg]--;
- break;
-
- case 0x2: // SRRI
- g_dsp.r[dreg]++;
- break;
-
- case 0x3: // SRRX
- g_dsp.r[dreg] += g_dsp.r[dreg + 4];
- break;
- }
-}
-
-
-void dsp_opc_ilrr(u16 opc)
-{
- u16 reg = opc & 0x3;
- u16 dreg = 0x1e + ((opc >> 8) & 1);
-
- // always to acc0 ?
- g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
-
- switch ((opc >> 2) & 0x3)
- {
- case 0x0: // no change
- break;
-
- case 0x1: // post decrement
- g_dsp.r[reg]--;
- break;
-
- case 0x2: // post increment
- g_dsp.r[reg]++;
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_opc_ilrr");
- }
-}
-
-
-void dsp_opc_lri(u16 opc)
-{
- u8 reg = opc & DSP_REG_MASK;
- u16 imm = dsp_fetch_code();
- dsp_op_write_reg(reg, imm);
-}
-
-
-void dsp_opc_lris(u16 opc)
-{
- u8 reg = ((opc >> 8) & 0x7) + 0x18;
- u16 imm = (s8)opc;
- dsp_op_write_reg(reg, imm);
-}
-
-
-void dsp_opc_lr(u16 opc)
-{
- u8 reg = opc & DSP_REG_MASK;
- u16 addr = dsp_fetch_code();
- u16 val = dsp_dmem_read(addr);
- dsp_op_write_reg(reg, val);
-}
-
-
-void dsp_opc_sr(u16 opc)
-{
- u8 reg = opc & DSP_REG_MASK;
- u16 addr = dsp_fetch_code();
- u16 val = dsp_op_read_reg(reg);
- dsp_dmem_write(addr, val);
-}
-
-
-void dsp_opc_si(u16 opc)
-{
- u16 addr = (s8)opc;
- u16 imm = dsp_fetch_code();
- dsp_dmem_write(addr, imm);
-}
-
-
-void dsp_opc_tstaxh(u16 opc)
-{
- u8 reg = (opc >> 8) & 0x1;
- s16 val = dsp_get_ax_h(reg);
-
- Update_SR_Register(val);
-}
-
-
-void dsp_opc_clr(u16 opc)
-{
- u8 reg = (opc >> 11) & 0x1;
-
- dsp_set_long_acc(reg, 0);
-
- Update_SR_Register((s64)0);
-}
-
-
-void dsp_opc_clrp(u16 opc)
-{
- g_dsp.r[0x14] = 0x0000;
- g_dsp.r[0x15] = 0xfff0;
- g_dsp.r[0x16] = 0x00ff;
- g_dsp.r[0x17] = 0x0010;
-}
-
-
-// NEW
-void dsp_opc_mulc(u16 opc)
-{
- // math new prod
- u8 sreg = (opc >> 11) & 0x1;
- u8 treg = (opc >> 12) & 0x1;
-
- s64 prod = dsp_get_acc_m(sreg) * dsp_get_ax_h(treg) * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-// NEW
-void dsp_opc_mulcmvz(u16 opc)
-{
- ERROR_LOG(DSPHLE, "dsp_opc_mulcmvz ni");
-}
-
-
-// NEW
-void dsp_opc_mulcmv(u16 opc)
-{
- ERROR_LOG(DSPHLE, "dsp_opc_mulcmv ni");
-}
-
-
-void dsp_opc_cmpar(u16 opc)
-{
- u8 rreg = ((opc >> 12) & 0x1) + 0x1a;
- u8 areg = (opc >> 11) & 0x1;
-
- // we compare
- s64 rr = (s16)g_dsp.r[rreg];
- rr <<= 16;
-
- s64 ar = dsp_get_long_acc(areg);
-
- Update_SR_Register(ar - rr);
-}
-
-
-void dsp_opc_cmp(u16 opc)
-{
- s64 acc0 = dsp_get_long_acc(0);
- s64 acc1 = dsp_get_long_acc(1);
-
- Update_SR_Register(acc0 - acc1);
-}
-
-
-void dsp_opc_tsta(u16 opc)
-{
- u8 reg = (opc >> 11) & 0x1;
- s64 acc = dsp_get_long_acc(reg);
-
- Update_SR_Register(acc);
-}
-
-
-// NEW
-void dsp_opc_addaxl(u16 opc)
-{
- u8 sreg = (opc >> 9) & 0x1;
- u8 dreg = (opc >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(dreg);
- s64 acx = dsp_get_ax_l(sreg);
-
- acc += acx;
-
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-// NEW
-void dsp_opc_addarn(u16 opc)
-{
- u8 dreg = opc & 0x3;
- u8 sreg = (opc >> 2) & 0x3;
-
- g_dsp.r[dreg] += (s16)g_dsp.r[0x04 + sreg];
-}
-
-
-// NEW
-void dsp_opc_mulcac(u16 opc)
-{
- s64 TempProd = dsp_get_long_prod();
-
- // update prod
- u8 sreg = (opc >> 12) & 0x1;
- s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_acc_h(sreg) * GetMultiplyModifier();
- dsp_set_long_prod(Prod);
-
- // update acc
- u8 rreg = (opc >> 8) & 0x1;
- dsp_set_long_acc(rreg, TempProd);
-}
-
-
-// NEW
-void dsp_opc_movr(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
- u8 sreg = ((opc >> 9) & 0x3) + 0x18;
-
- s64 acc = (s16)g_dsp.r[sreg];
- acc <<= 16;
- acc &= ~0xffff;
-
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_movax(u16 opc)
-{
- u8 sreg = (opc >> 9) & 0x1;
- u8 dreg = (opc >> 8) & 0x1;
-
- g_dsp.r[0x1c + dreg] = g_dsp.r[0x18 + sreg];
- g_dsp.r[0x1e + dreg] = g_dsp.r[0x1a + sreg];
-
- if ((s16)g_dsp.r[0x1a + sreg] < 0)
- {
- g_dsp.r[0x10 + dreg] = 0xffff;
- }
- else
- {
- g_dsp.r[0x10 + dreg] = 0;
- }
-
- dsp_opc_tsta(dreg << 11);
-}
-
-
-// NEW
-void dsp_opc_xorr(u16 opc)
-{
- u8 sreg = (opc >> 9) & 0x1;
- u8 dreg = (opc >> 8) & 0x1;
-
- g_dsp.r[0x1e + dreg] ^= g_dsp.r[0x1a + sreg];
-
- dsp_opc_tsta(dreg << 11);
-}
-
-
-void dsp_opc_andr(u16 opc)
-{
- u8 sreg = (opc >> 9) & 0x1;
- u8 dreg = (opc >> 8) & 0x1;
-
- g_dsp.r[0x1e + dreg] &= g_dsp.r[0x1a + sreg];
-
- dsp_opc_tsta(dreg << 11);
-}
-
-
-// NEW
-void dsp_opc_orr(u16 opc)
-{
- u8 sreg = (opc >> 9) & 0x1;
- u8 dreg = (opc >> 8) & 0x1;
-
- g_dsp.r[0x1e + dreg] |= g_dsp.r[0x1a + sreg];
-
- dsp_opc_tsta(dreg << 11);
-}
-
-
-// NEW
-void dsp_opc_andc(u16 opc)
-{
- u8 D = (opc >> 8) & 0x1;
-
- u16 ac1 = dsp_get_acc_m(D);
- u16 ac2 = dsp_get_acc_m(1 - D);
-
- dsp_set_long_acc(D, ac1 & ac2);
-
- if ((ac1 & ac2) == 0)
- {
- g_dsp.r[R_SR] |= 0x20;
- }
- else
- {
- g_dsp.r[R_SR] &= ~0x20;
- }
-}
-
-
-//-------------------------------------------------------------
-
-void dsp_opc_nx(u16 opc)
-{}
-
-
-// NEW
-void dsp_opc_andfc(u16 opc)
-{
- if (opc & 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_andfc");
- }
-
- u8 reg = (opc >> 8) & 0x1;
- u16 imm = dsp_fetch_code();
- u16 val = dsp_get_acc_m(reg);
-
- if ((val & imm) == imm)
- {
- g_dsp.r[R_SR] |= 0x40;
- }
- else
- {
- g_dsp.r[R_SR] &= ~0x40;
- }
-}
-
-
-void dsp_opc_andf(u16 opc)
-{
- u8 reg;
- u16 imm;
- u16 val;
-
- if (opc & 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_andf");
- }
-
- reg = 0x1e + ((opc >> 8) & 0x1);
- imm = dsp_fetch_code();
- val = g_dsp.r[reg];
-
- if ((val & imm) == 0)
- {
- g_dsp.r[R_SR] |= 0x40;
- }
- else
- {
- g_dsp.r[R_SR] &= ~0x40;
- }
-}
-
-
-void dsp_opc_subf(u16 opc)
-{
- if (opc & 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_subf");
- }
-
- u8 reg = 0x1e + ((opc >> 8) & 0x1);
- s64 imm = (s16)dsp_fetch_code();
-
- s64 val = (s16)g_dsp.r[reg];
- s64 res = val - imm;
-
- Update_SR_Register(res);
-}
-
-
-void dsp_opc_xori(u16 opc)
-{
- if (opc & 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_xori");
- }
-
- u8 reg = 0x1e + ((opc >> 8) & 0x1);
- u16 imm = dsp_fetch_code();
- g_dsp.r[reg] ^= imm;
-
- Update_SR_Register((s16)g_dsp.r[reg]);
-}
-
-
-void dsp_opc_andi(u16 opc)
-{
- if (opc & 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_andi");
- }
-
- u8 reg = 0x1e + ((opc >> 8) & 0x1);
- u16 imm = dsp_fetch_code();
- g_dsp.r[reg] &= imm;
-
- Update_SR_Register((s16)g_dsp.r[reg]);
-}
-
-
-// F|RES: i am not sure if this shouldnt be the whole ACC
-//
-void dsp_opc_ori(u16 opc)
-{
- if (opc & 0xf)
- {
- ERROR_LOG(DSPHLE, "dsp_opc_ori");
- return;
- }
-
- u8 reg = 0x1e + ((opc >> 8) & 0x1);
- u16 imm = dsp_fetch_code();
- g_dsp.r[reg] |= imm;
-
- Update_SR_Register((s16)g_dsp.r[reg]);
-}
-
-
-//-------------------------------------------------------------
-
-void dsp_opc_add(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
- s64 acc0 = dsp_get_long_acc(0);
- s64 acc1 = dsp_get_long_acc(1);
-
- s64 res = acc0 + acc1;
-
- dsp_set_long_acc(areg, res);
-
- Update_SR_Register(res);
-}
-
-
-//-------------------------------------------------------------
-
-void dsp_opc_addp(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x1;
- s64 acc = dsp_get_long_acc(dreg);
- acc = acc + dsp_get_long_prod();
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_cmpis(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- s64 val = (s8)opc;
- val <<= 16;
-
- s64 res = acc - val;
-
- Update_SR_Register(res);
-}
-
-
-// NEW
-// verified at the console
-void dsp_opc_addpaxz(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x1;
- u8 sreg = (opc >> 9) & 0x1;
-
- s64 prod = dsp_get_long_prod() & ~0x0ffff;
- s64 ax_h = dsp_get_long_acx(sreg);
- s64 acc = (prod + ax_h) & ~0x0ffff;
-
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-// NEW
-void dsp_opc_movpz(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x01;
-
- // overwrite acc and clear low part
- s64 prod = dsp_get_long_prod();
- s64 acc = prod & ~0xffff;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_decm(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x01;
-
- s64 sub = 0x10000;
- s64 acc = dsp_get_long_acc(dreg);
- acc -= sub;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_dec(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x01;
-
- s64 acc = dsp_get_long_acc(dreg) - 1;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_incm(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x1;
-
- s64 sub = 0x10000;
- s64 acc = dsp_get_long_acc(dreg);
- acc += sub;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_inc(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(dreg);
- acc++;
- dsp_set_long_acc(dreg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_neg(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- acc = 0 - acc;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_movnp(u16 opc)
-{
- ERROR_LOG(DSPHLE, "dsp_opc_movnp\n");
-}
-
-
-// NEW
-void dsp_opc_addax(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
- u8 sreg = (opc >> 9) & 0x1;
-
- s64 ax = dsp_get_long_acx(sreg);
- s64 acc = dsp_get_long_acc(areg);
- acc += ax;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_addr(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
- u8 sreg = ((opc >> 9) & 0x3) + 0x18;
-
- s64 ax = (s16)g_dsp.r[sreg];
- ax <<= 16;
-
- s64 acc = dsp_get_long_acc(areg);
- acc += ax;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_subr(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
- u8 sreg = ((opc >> 9) & 0x3) + 0x18;
-
- s64 ax = (s16)g_dsp.r[sreg];
- ax <<= 16;
-
- s64 acc = dsp_get_long_acc(areg);
- acc -= ax;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-// NEW
-void dsp_opc_subax(u16 opc)
-{
- int regD = (opc >> 8) & 0x1;
- int regT = (opc >> 9) & 0x1;
-
- s64 Acc = dsp_get_long_acc(regD) - dsp_get_long_acx(regT);
-
- dsp_set_long_acc(regD, Acc);
- Update_SR_Register(Acc);
-}
-
-void dsp_opc_addis(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
-
- s64 Imm = (s8)opc;
- Imm <<= 16;
- s64 acc = dsp_get_long_acc(areg);
- acc += Imm;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_addi(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
-
- s64 sub = (s16)dsp_fetch_code();
- sub <<= 16;
- s64 acc = dsp_get_long_acc(areg);
- acc += sub;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_lsl16(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- acc <<= 16;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-// NEW
-void dsp_opc_madd(u16 opc)
-{
- u8 sreg = (opc >> 8) & 0x1;
-
- s64 prod = dsp_get_long_prod();
- prod += (s64)dsp_get_ax_l(sreg) * (s64)dsp_get_ax_h(sreg) * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-}
-
-
-void dsp_opc_lsr16(u16 opc)
-{
- u8 areg = (opc >> 8) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- acc >>= 16;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-void dsp_opc_asr16(u16 opc)
-{
- u8 areg = (opc >> 11) & 0x1;
-
- s64 acc = dsp_get_long_acc(areg);
- acc >>= 16;
- dsp_set_long_acc(areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-union UOpcodeShifti
-{
- u16 Hex;
- struct
- {
- signed shift : 6;
- unsigned negating : 1;
- unsigned arithmetic : 1;
- unsigned areg : 1;
- unsigned op : 7;
- };
- struct
- {
- unsigned ushift : 6;
- };
- UOpcodeShifti(u16 _Hex)
- : Hex(_Hex) {}
-};
-
-void dsp_opc_shifti(u16 opc)
-{
- UOpcodeShifti Opcode(opc);
-
- // direction: left
- bool ShiftLeft = true;
- u16 shift = Opcode.ushift;
-
- if ((Opcode.negating) && (Opcode.shift < 0))
- {
- ShiftLeft = false;
- shift = -Opcode.shift;
- }
-
- s64 acc;
- u64 uacc;
-
- if (Opcode.arithmetic)
- {
- // arithmetic shift
- uacc = dsp_get_long_acc(Opcode.areg);
-
- if (!ShiftLeft)
- {
- uacc >>= shift;
- }
- else
- {
- uacc <<= shift;
- }
-
- acc = uacc;
- }
- else
- {
- acc = dsp_get_long_acc(Opcode.areg);
-
- if (!ShiftLeft)
- {
- acc >>= shift;
- }
- else
- {
- acc <<= shift;
- }
- }
-
- dsp_set_long_acc(Opcode.areg, acc);
-
- Update_SR_Register(acc);
-}
-
-
-//-------------------------------------------------------------
-// hcs give me this code!!
-void dsp_opc_dar(u16 opc)
-{
- u8 reg = opc & 0x3;
-
- int temp = g_dsp.r[reg] + g_dsp.r[8];
-
- if (temp <= 0x7ff){g_dsp.r[reg] = temp;}
- else {g_dsp.r[reg]--;}
-}
-
-
-// hcs give me this code!!
-void dsp_opc_iar(u16 opc)
-{
- u8 reg = opc & 0x3;
-
- int temp = g_dsp.r[reg] + g_dsp.r[8];
-
- if (temp <= 0x7ff){g_dsp.r[reg] = temp;}
- else {g_dsp.r[reg]++;}
-}
-
-
-//-------------------------------------------------------------
-
-void dsp_opc_sbclr(u16 opc)
-{
- u8 bit = (opc & 0xff) + 6;
- g_dsp.r[R_SR] &= ~(1 << bit);
-}
-
-
-void dsp_opc_sbset(u16 opc)
-{
- u8 bit = (opc & 0xff) + 6;
- g_dsp.r[R_SR] |= (1 << bit);
-}
-
-
-void dsp_opc_srbith(u16 opc)
-{
- switch ((opc >> 8) & 0xf)
- {
- case 0xe: // SET40
- g_dsp.r[R_SR] &= ~(1 << 14);
- break;
-
- // FIXME: Both of these appear in the beginning of the Wind Waker
- //case 0xb:
- //case 0xc:
-
-/* case 0xf: // SET16 // that doesnt happen on a real console
- g_dsp.r[R_SR] |= (1 << 14);
- break;*/
-
- default:
- break;
- }
-}
-
-
-//-------------------------------------------------------------
-
-void dsp_opc_movp(u16 opc)
-{
- u8 dreg = (opc >> 8) & 0x1;
-
- s64 prod = dsp_get_long_prod();
- s64 acc = prod;
- dsp_set_long_acc(dreg, acc);
-}
-
-
-void dsp_opc_mul(u16 opc)
-{
- u8 sreg = (opc >> 11) & 0x1;
- s64 prod = (s64)dsp_get_ax_h(sreg) * (s64)dsp_get_ax_l(sreg) * GetMultiplyModifier();
-
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-// NEW
-void dsp_opc_mulac(u16 opc)
-{
- // add old prod to acc
- u8 rreg = (opc >> 8) & 0x1;
- s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
- dsp_set_long_acc(rreg, acR);
-
- // math new prod
- u8 sreg = (opc >> 11) & 0x1;
- s64 prod = dsp_get_ax_l(sreg) * dsp_get_ax_h(sreg) * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-void dsp_opc_mulmv(u16 opc)
-{
- u8 rreg = (opc >> 8) & 0x1;
- s64 prod = dsp_get_long_prod();
- s64 acc = prod;
- dsp_set_long_acc(rreg, acc);
-
- u8 areg = ((opc >> 11) & 0x1) + 0x18;
- u8 breg = ((opc >> 11) & 0x1) + 0x1a;
- s64 val1 = (s16)g_dsp.r[areg];
- s64 val2 = (s16)g_dsp.r[breg];
-
- prod = val1 * val2 * GetMultiplyModifier();
-
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-// NEW
-void dsp_opc_mulmvz(u16 opc)
-{
- u8 sreg = (opc >> 11) & 0x1;
- u8 rreg = (opc >> 8) & 0x1;
-
- // overwrite acc and clear low part
- s64 prod = dsp_get_long_prod();
- s64 acc = prod & ~0xffff;
- dsp_set_long_acc(rreg, acc);
-
- // math prod
- prod = (s64)g_dsp.r[0x18 + sreg] * (s64)g_dsp.r[0x1a + sreg] * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-// NEW
-void dsp_opc_mulx(u16 opc)
-{
- u8 sreg = ((opc >> 12) & 0x1);
- u8 treg = ((opc >> 11) & 0x1);
-
- s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-// NEW
-void dsp_opc_mulxac(u16 opc)
-{
- // add old prod to acc
- u8 rreg = (opc >> 8) & 0x1;
- s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod();
- dsp_set_long_acc(rreg, acR);
-
- // math new prod
- u8 sreg = (opc >> 12) & 0x1;
- u8 treg = (opc >> 11) & 0x1;
-
- s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-// NEW
-void dsp_opc_mulxmv(u16 opc)
-{
- // add old prod to acc
- u8 rreg = ((opc >> 8) & 0x1);
- s64 acR = dsp_get_long_prod();
- dsp_set_long_acc(rreg, acR);
-
- // math new prod
- u8 sreg = (opc >> 12) & 0x1;
- u8 treg = (opc >> 11) & 0x1;
-
- s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-// NEW
-void dsp_opc_mulxmvz(u16 opc)
-{
- // overwrite acc and clear low part
- u8 rreg = (opc >> 8) & 0x1;
- s64 prod = dsp_get_long_prod();
- s64 acc = prod & ~0xffff;
- dsp_set_long_acc(rreg, acc);
-
- // math prod
- u8 sreg = (opc >> 12) & 0x1;
- u8 treg = (opc >> 11) & 0x1;
-
- s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- prod = val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-
- Update_SR_Register(prod);
-}
-
-
-// NEW
-void dsp_opc_sub(u16 opc)
-{
- u8 D = (opc >> 8) & 0x1;
- s64 Acc1 = dsp_get_long_acc(D);
- s64 Acc2 = dsp_get_long_acc(1 - D);
-
- Acc1 -= Acc2;
-
- dsp_set_long_acc(D, Acc1);
-}
-
-
-//-------------------------------------------------------------
-//
-// --- Table E
-//
-//-------------------------------------------------------------
-
-// NEW
-void dsp_opc_maddx(u16 opc)
-{
- u8 sreg = (opc >> 9) & 0x1;
- u8 treg = (opc >> 8) & 0x1;
-
- s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = dsp_get_long_prod();
- prod += val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-}
-
-
-// NEW
-void dsp_opc_msubx(u16 opc)
-{
- u8 sreg = (opc >> 9) & 0x1;
- u8 treg = (opc >> 8) & 0x1;
-
- s64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
- s64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
-
- s64 prod = dsp_get_long_prod();
- prod -= val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-}
-
-
-// NEW
-void dsp_opc_maddc(u16 opc)
-{
- u32 sreg = (opc >> 9) & 0x1;
- u32 treg = (opc >> 8) & 0x1;
-
- s64 val1 = dsp_get_acc_m(sreg);
- s64 val2 = dsp_get_ax_h(treg);
-
- s64 prod = dsp_get_long_prod();
- prod += val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-}
-
-
-// NEW
-void dsp_opc_msubc(u16 opc)
-{
- u32 sreg = (opc >> 9) & 0x1;
- u32 treg = (opc >> 8) & 0x1;
-
- s64 val1 = dsp_get_acc_m(sreg);
- s64 val2 = dsp_get_ax_h(treg);
-
- s64 prod = dsp_get_long_prod();
- prod -= val1 * val2 * GetMultiplyModifier();
- dsp_set_long_prod(prod);
-}
-
-
-//-------------------------------------------------------------
-void dsp_op0(u16 opc)
-{
- if (opc == 0)
- {
- return;
- }
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
-
- switch ((opc >> 4) & 0xf)
- {
- case 0x0:
-
- switch (opc & 0xf)
- {
- case 0x4:
- case 0x5:
- case 0x6:
- case 0x7:
- dsp_opc_dar(opc);
- break;
-
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- dsp_opc_iar(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op0");
- break;
- }
-
- break;
-
- case 0x1:
- dsp_opc_addarn(opc);
- break;
-
- case 0x2: // HALT
- dsp_opc_halt(opc);
- break;
-
- case 0x4: // LOOP
- case 0x5: // LOOP
- dsp_opc_loop(opc);
- break;
-
- case 0x6: // BLOOP
- case 0x7: // BLOOP
- dsp_opc_bloop(opc);
- break;
-
- case 0x8: // LRI
- case 0x9: // LRI
- dsp_opc_lri(opc);
- break;
-
- case 0xC: // LR
- case 0xD: // LR
- dsp_opc_lr(opc);
- break;
-
- case 0xE: // SR
- case 0xF: // SR
- dsp_opc_sr(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op0");
- break;
- }
-
- break;
-
- case 0x2:
-
- switch ((opc >> 4) & 0xf)
- {
- case 0x0: // ADDI
- dsp_opc_addi(opc);
- break;
-
- case 0x1: // IL
- dsp_opc_ilrr(opc);
- break;
-
- case 0x2: // XORI
- dsp_opc_xori(opc);
- break;
-
- case 0x4: // ANDI
- dsp_opc_andi(opc);
- break;
-
- case 0x6: // ORI
- dsp_opc_ori(opc);
- break;
-
- case 0x7: //
- dsp_opc_ifcc(opc);
- break;
-
- case 0x8: // SUBF
- dsp_opc_subf(opc);
- break;
-
- case 0x9: // Jxx
- dsp_opc_jcc(opc);
- break;
-
- case 0xa: // ANDF
- dsp_opc_andf(opc);
- break;
-
- case 0xb: // CALL
- dsp_opc_call(opc);
- break;
-
- case 0xc:
- dsp_opc_andfc(opc);
- break;
-
- case 0xd: // RET
- dsp_opc_ret(opc);
- break;
-
- case 0xf: // RTI
- dsp_opc_rti(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op0");
- break;
- }
-
- break;
-
- case 0x3:
-
- switch ((opc >> 4) & 0xf)
- {
- case 0x0: // ADDAI
- dsp_opc_addi(opc);
- break;
-
- case 0x1: // ILR
- dsp_opc_ilrr(opc);
- break;
-
- case 0x2: // XORI
- dsp_opc_xori(opc);
- break;
-
- case 0x4: // ANDI
- dsp_opc_andi(opc);
- break;
-
- case 0x6: // ORI
- dsp_opc_ori(opc);
- break;
-
- case 0x8: // SUBF
- dsp_opc_subf(opc);
- break;
-
- case 0xa: // ANDF
- dsp_opc_andf(opc);
- break;
-
- case 0xc: // ANDFC
- dsp_opc_andfc(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op0");
- break;
- }
-
- break;
-
- case 0x4:
- case 0x5:
- dsp_opc_addis(opc);
- break;
-
- case 0x6: // SUBISF
- case 0x7:
- dsp_opc_cmpis(opc);
- break;
-
- case 0x8: // LRIS
- case 0x9:
- case 0xa:
- case 0xb:
- case 0xc:
- case 0xd:
- case 0xe:
- case 0xf:
- dsp_opc_lris(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op0");
- break;
- }
-}
-
-
-void dsp_op1(u16 opc)
-{
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
- dsp_opc_loopi(opc);
- break;
-
- case 0x1: // BLOOPI
- dsp_opc_bloopi(opc);
- break;
-
- case 0x2: // SBCLR
- dsp_opc_sbclr(opc);
- break;
-
- case 0x3: // SBSET
- dsp_opc_sbset(opc);
- break;
-
- case 0x4: // shifti
- case 0x5:
- dsp_opc_shifti(opc);
- break;
-
- case 0x6: // SI
- dsp_opc_si(opc);
- break;
-
- case 0x7: // JMPA/CALLA
- dsp_opc_jmpa(opc);
- break;
-
- case 0x8: // LRRx
- case 0x9: // LRRx
- dsp_opc_lrr(opc);
- break;
-
- case 0xa: // SRRx
- case 0xb: // SRRx
- dsp_opc_srr(opc);
- break;
-
- case 0xc: // MRR
- case 0xd: // MRR
- case 0xe: // MRR
- case 0xf: // MRR
- dsp_opc_mrr(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op1");
- break;
- }
-}
-
-
-void dsp_op2(u16 opc)
-{
- // lrs, srs
- u8 reg = ((opc >> 8) & 0x7) + 0x18;
- u16 addr = (s8) opc;
-
- if (opc & 0x0800)
- {
- // srs
- dsp_dmem_write(addr, g_dsp.r[reg]);
- }
- else
- {
- // lrs
- g_dsp.r[reg] = dsp_dmem_read(addr);
- }
-}
-
-
-void dsp_op3(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
- case 0x1:
- case 0x2:
- case 0x3:
- dsp_opc_xorr(opc);
- break;
-
- case 0x4:
- case 0x5:
- case 0x6:
- case 0x7:
- dsp_opc_andr(opc);
- break;
-
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- dsp_opc_orr(opc);
- break;
-
- case 0xc:
- case 0xd:
- dsp_opc_andc(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op3");
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_op4(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
- case 0x1:
- case 0x2:
- case 0x3:
- case 0x4:
- case 0x5:
- case 0x6:
- case 0x7:
- dsp_opc_addr(opc);
- break;
-
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- dsp_opc_addax(opc);
- break;
-
- case 0xc:
- case 0xd:
- dsp_opc_add(opc);
- break;
-
- case 0xe:
- case 0xf:
- dsp_opc_addp(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op4");
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_op5(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
- case 0x1:
- case 0x2:
- case 0x3:
- case 0x4:
- case 0x5:
- case 0x6:
- case 0x7:
- dsp_opc_subr(opc);
- break;
-
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- dsp_opc_subax(opc);
- break;
-
- case 0xc:
- case 0xd:
- dsp_opc_sub(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op5: %x", (opc >> 8) & 0xf);
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_op6(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x00: // MOVR
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- dsp_opc_movr(opc);
- break;
-
- case 0x8: // MVAXA
- case 0x9:
- case 0xa:
- case 0xb:
- dsp_opc_movax(opc);
- break;
-
- case 0xe:
- case 0xf:
- dsp_opc_movp(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op6");
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_op7(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
- case 0x1:
- case 0x2:
- case 0x3:
- dsp_opc_addaxl(opc);
- break;
-
- case 0x4:
- case 0x5:
- dsp_opc_incm(opc);
- break;
-
- case 0x6:
- case 0x7:
- dsp_opc_inc(opc);
- break;
-
- case 0x8:
- case 0x9:
- dsp_opc_decm(opc);
- break;
-
- case 0xa:
- case 0xb:
- dsp_opc_dec(opc);
- break;
-
- case 0xc:
- case 0xd:
- dsp_opc_neg(opc);
- break;
-
- case 0xe:
- case 0xf:
- dsp_opc_movnp(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op7");
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_op8(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
- case 0x8:
- dsp_opc_nx(opc);
- break;
-
- case 0x1: // CLR 0
- case 0x9: // CLR 1
- dsp_opc_clr(opc);
- break;
-
- case 0x2: // CMP
- dsp_opc_cmp(opc);
- break;
-
- case 0x4: // CLRP
- dsp_opc_clrp(opc);
- break;
-
- case 0x6:
- case 0x7:
- dsp_opc_tstaxh(opc);
- break;
-
- case 0xc:
- case 0xb:
- case 0xe: // SET40
- case 0xd:
- case 0xa:
- case 0xf:
- dsp_opc_srbith(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op8");
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_op9(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x02:
- case 0x03:
- case 0x0a:
- case 0x0b:
- dsp_opc_mulmvz(opc);
- break;
-
- case 0x04:
- case 0x05:
- case 0x0c:
- case 0x0d:
- dsp_opc_mulac(opc);
- break;
-
- case 0x6:
- case 0x7:
- case 0xe:
- case 0xf:
- dsp_opc_mulmv(opc);
- break;
-
- case 0x0:
- case 0x8:
- dsp_opc_mul(opc);
- break;
-
- case 0x1:
- case 0x9:
- dsp_opc_asr16(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_op9");
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_opab(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0x7)
- {
- case 0x0:
- dsp_opc_mulx(opc);
- break;
-
- case 0x1:
- dsp_opc_tsta(opc);
- break;
-
- case 0x2:
- case 0x3:
- dsp_opc_mulxmvz(opc);
- break;
-
- case 0x4:
- case 0x5:
- dsp_opc_mulxac(opc);
- break;
-
- case 0x6:
- case 0x7:
- dsp_opc_mulxmv(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_opab");
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_opcd(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0x7)
- {
- case 0x0: // MULC
- dsp_opc_mulc(opc);
- break;
-
- case 0x1: // CMPAR
- dsp_opc_cmpar(opc);
- break;
-
- case 0x2: // MULCMVZ
- case 0x3:
- dsp_opc_mulcmvz(opc);
- break;
-
- case 0x4: // MULCAC
- case 0x5:
- dsp_opc_mulcac(opc);
- break;
-
- case 0x6: // MULCMV
- case 0x7:
- dsp_opc_mulcmv(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_opcd");
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_ope(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 10) & 0x3)
- {
- case 0x00: // MADDX
- dsp_opc_maddx(opc);
- break;
-
- case 0x01: // MSUBX
- dsp_opc_msubx(opc);
- break;
-
- case 0x02: // MADDC
- dsp_opc_maddc(opc);
- break;
-
- case 0x03: // MSUBC
- dsp_opc_msubc(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_ope");
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
-void dsp_opf(u16 opc)
-{
- dsp_op_ext_ops_pro(opc);
-
- switch ((opc >> 8) & 0xf)
- {
- case 0x0:
- case 0x1:
- dsp_opc_lsl16(opc);
- break;
-
- case 0x02:
- case 0x03:
- dsp_opc_madd(opc);
- break;
-
- case 0x4:
- case 0x5:
- dsp_opc_lsr16(opc);
- break;
-
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- dsp_opc_addpaxz(opc);
- break;
-
- case 0xe:
- case 0xf:
- dsp_opc_movpz(opc);
- break;
-
- default:
- ERROR_LOG(DSPHLE, "dsp_opf");
- break;
- }
-
- dsp_op_ext_ops_epi(opc);
-}
-
-
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h
deleted file mode 100644
index 8ee4e2131e..0000000000
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2003-2009 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-/*====================================================================
-
- filename: gdsp_opcodes.h
- project: GCemu
- created: 2004-6-18
- mail: duddie@walla.com
-
- Copyright (c) 2005 Duddie & Tratax
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- ====================================================================*/
-#ifndef _GDSP_OPCODES_H
-#define _GDSP_OPCODES_H
-
-#include "Globals.h"
-
-void dsp_op0(u16 opc);
-void dsp_op1(u16 opc);
-void dsp_op2(u16 opc);
-void dsp_op3(u16 opc);
-void dsp_op4(u16 opc);
-void dsp_op5(u16 opc);
-void dsp_op6(u16 opc);
-void dsp_op7(u16 opc);
-void dsp_op8(u16 opc);
-void dsp_op9(u16 opc);
-void dsp_opab(u16 opc);
-void dsp_opcd(u16 opc);
-void dsp_ope(u16 opc);
-void dsp_opf(u16 opc);
-
-
-#define R_SR 0x13
-
-#define FLAG_ENABLE_INTERUPT 11
-
-#endif
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes_helper.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes_helper.h
index 5d920474ef..f0f1e77430 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes_helper.h
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes_helper.h
@@ -28,7 +28,8 @@
#include "Globals.h"
-#include "gdsp_opcodes.h"
+#include "DSPInterpreter.h"
+
#include "gdsp_memory.h"
#include "gdsp_interpreter.h"
#include "gdsp_registers.h"
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp
index 738f6d6ff3..3a4d93e2e0 100644
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp
@@ -32,6 +32,8 @@
#include "Thread.h"
#include "ChunkFile.h"
+#include "DSPTables.h"
+
#if defined(HAVE_WX) && HAVE_WX
#include "DSPConfigDlgLLE.h"
#include "Debugger/Debugger.h" // For the CDebugger class
@@ -243,6 +245,8 @@ void Initialize(void *init)
g_hDSPThread = new Common::Thread(dsp_thread, NULL);
soundStream = AudioCommon::InitSoundStream();
+
+ InitInstructionTable();
}
void DSP_StopSoundStream()
@@ -255,6 +259,7 @@ void Shutdown(void)
{
bIsRunning = false;
gdsp_stop();
+ DestroyInstructionTable();
AudioCommon::ShutdownSoundStream();
}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.h
deleted file mode 100644
index 06e5810802..0000000000
--- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*====================================================================
-
- filename: opcodes.h
- project: GameCube DSP Tool (gcdsp)
- created: 2005.03.04
- mail: duddie@walla.com
-
- Copyright (c) 2005 Duddie
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- ====================================================================*/
-#ifndef _OPCODES_H
-#define _OPCODES_H
-
-enum parameterType
-{
- P_NONE = 0x0000,
- P_VAL = 0x0001,
- P_IMM = 0x0002,
- P_MEM = 0x0003,
- P_STR = 0x0004,
- P_REG = 0x8000,
- P_REG08 = P_REG | 0x0800,
- P_REG10 = P_REG | 0x1000,
- P_REG18 = P_REG | 0x1800,
- P_REG19 = P_REG | 0x1900,
- P_REG1A = P_REG | 0x1a00,
- P_REG1C = P_REG | 0x1c00,
- P_ACCM = P_REG | 0x1e00,
- P_ACCM_D = P_REG | 0x1e80,
- P_ACC = P_REG | 0x2000,
- P_ACC_D = P_REG | 0x2080,
- P_AX = P_REG | 0x2200,
- P_AX_D = P_REG | 0x2280,
- P_REGS_MASK = 0x03f80,
- P_REF = P_REG | 0x4000,
- P_PRG = P_REF | P_REG,
-};
-
-#define P_EXT 0x80
-
-union UDSPInstruction
-{
- u16 hex;
-
- UDSPInstruction(u16 _hex) { hex = _hex; }
- UDSPInstruction() { hex = 0; }
-
- // TODO(XK): Figure out the instruction structure better (add structs here)
-};
-
-typedef void (*dspInstFunc)(UDSPInstruction&);
-
-typedef struct DSPOParams
-{
- parameterType type;
- u8 size;
- u8 loc;
- s8 lshift;
- u16 mask;
-} opcpar_t;
-
-typedef struct DSPOPCTemplate
-{
- const char *name;
- u16 opcode;
- u16 opcode_mask;
-
- dspInstFunc interpFunc;
- dspInstFunc jitFunc;
-
- u8 size;
- u8 param_count;
- DSPOParams params[8];
-} opc_t;
-
-extern DSPOPCTemplate opcodes[];
-extern const u32 opcodes_size;
-extern opc_t opcodes_ext[];
-extern const u32 opcodes_ext_size;
-
-inline u16 swap16(u16 x)
-{
- return((x >> 8) | (x << 8));
-}
-
-
-#endif
-