From e099934a855d7d382b4ba7eebc4438b0576536fb Mon Sep 17 00:00:00 2001 From: "XTra.KrazzY" Date: Wed, 1 Apr 2009 20:22:43 +0000 Subject: [PATCH] DSP LLE: MAJOR LLE revamp. Interpreter/JIT infrastructure done. Still left to mix and match the correct functions to the correct instruction hexcodes. More changes: -Tagged unimplemented instructions and FIXME instructions in the DSP interpreter header -Expanded the DSP instruction union to be viewable as helpful instruction structures git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2817 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugin_DSP_LLE_Test.vcproj | 40 +- .../Src/DSPInterpreter.cpp | 1376 ++++++++++ .../Src/DSPInterpreter.h | 133 + .../Plugin_DSP_LLE-testing/Src/DSPJit.cpp | 22 + .../Plugin_DSP_LLE-testing/Src/DSPJit.h | 27 + .../Src/{opcodes.cpp => DSPTables.cpp} | 496 ++-- .../Plugin_DSP_LLE-testing/Src/DSPTables.h | 108 + .../Src/HLE_Functions.cpp | 4 + .../Plugin_DSP_LLE-testing/Src/HLE_Helper.h | 2 - .../Src/disassemble.cpp | 10 +- .../Src/gdsp_interpreter.cpp | 17 +- .../Src/gdsp_opcodes.cpp | 2251 ----------------- .../Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h | 67 - .../Src/gdsp_opcodes_helper.h | 3 +- .../Plugin_DSP_LLE-testing/Src/main.cpp | 5 + .../Plugin_DSP_LLE-testing/Src/opcodes.h | 102 - 16 files changed, 1962 insertions(+), 2701 deletions(-) create mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp create mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h create mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.cpp create mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPJit.h rename Source/Plugins/Plugin_DSP_LLE-testing/Src/{opcodes.cpp => DSPTables.cpp} (89%) create mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h delete mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.cpp delete mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h delete mode 100644 Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.h 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 -