From 08984104d7a2920676bcc91602fcb9ab42c80bb8 Mon Sep 17 00:00:00 2001 From: "fires.gc" Date: Fri, 10 Oct 2008 13:11:32 +0000 Subject: [PATCH] add first iteration of a small tool that creates pseudo c from DSP UCodes git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@825 8ced0084-cf51-0410-be5f-012b33b47a6e --- Docs/DSP/DSP_InterC/DSP_InterC.sln | 20 + Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.cpp | 320 +++ Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.h | 33 + Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.cpp | 2353 +++++++++++++++++ Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.h | 48 + Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.cpp | 52 + .../DSP_InterC/DSP_InterC/DSP_InterC.vcproj | 249 ++ Docs/DSP/DSP_InterC/DSP_InterC/OutBuffer.cpp | 155 ++ Docs/DSP/DSP_InterC/DSP_InterC/OutBuffer.h | 23 + Docs/DSP/DSP_InterC/DSP_InterC/ReadMe.txt | 33 + .../DSP_InterC/gdsp_opcodes_helper.h | 234 ++ Docs/DSP/DSP_InterC/DSP_InterC/stdafx.cpp | 23 + Docs/DSP/DSP_InterC/DSP_InterC/stdafx.h | 39 + Docs/DSP/DSP_InterC/DSP_InterC/targetver.h | 13 + 14 files changed, 3595 insertions(+) create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC.sln create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.cpp create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.h create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.cpp create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.h create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.cpp create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.vcproj create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/OutBuffer.cpp create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/OutBuffer.h create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/ReadMe.txt create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/gdsp_opcodes_helper.h create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/stdafx.cpp create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/stdafx.h create mode 100644 Docs/DSP/DSP_InterC/DSP_InterC/targetver.h diff --git a/Docs/DSP/DSP_InterC/DSP_InterC.sln b/Docs/DSP/DSP_InterC/DSP_InterC.sln new file mode 100644 index 0000000000..5c7b2aa21d --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSP_InterC", "DSP_InterC\DSP_InterC.vcproj", "{A010425E-9D5E-461E-910D-0804C2A944D5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A010425E-9D5E-461E-910D-0804C2A944D5}.Debug|Win32.ActiveCfg = Debug|Win32 + {A010425E-9D5E-461E-910D-0804C2A944D5}.Debug|Win32.Build.0 = Debug|Win32 + {A010425E-9D5E-461E-910D-0804C2A944D5}.Release|Win32.ActiveCfg = Release|Win32 + {A010425E-9D5E-461E-910D-0804C2A944D5}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.cpp b/Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.cpp new file mode 100644 index 0000000000..e74efc0c6e --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.cpp @@ -0,0 +1,320 @@ +/*==================================================================== + + 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. + + ====================================================================*/ +// +// +// At the moment just ls and sl are using the prolog +// perhaps all actions on r03 must be in the prolog +// +#include + +#include "OutBuffer.h" + + + +// +void dsp_op_ext_r_epi(uint16 _Opcode) +{ + uint8 op = (_Opcode >> 2) & 0x3; + uint8 reg = _Opcode & 0x3; + + switch (op) + { + case 0x00: + OutBuffer::AddCode("Error: dsp_op_ext_r_epi"); + break; + + case 0x01: + OutBuffer::AddCode("%s--", OutBuffer::GetRegName(reg)); + // g_dsp.r[reg]--; + break; + + case 0x02: + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(reg)); + //g_dsp.r[reg]++; + break; + + case 0x03: + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(reg), OutBuffer::GetRegName(reg+4)); + // g_dsp.r[reg] += g_dsp.r[reg + 4]; + break; + } +} + + +void dsp_op_ext_mv(uint16 _Opcode) +{ + uint8 sreg = _Opcode & 0x3; + uint8 dreg = ((_Opcode >> 2) & 0x3); + + OutBuffer::AddCode("%s = %s", OutBuffer::GetRegName(dreg + 0x18), OutBuffer::GetRegName(sreg + 0x1c)); + + // g_dsp.r[dreg + 0x18] = g_dsp.r[sreg + 0x1c]; +} + + +void dsp_op_ext_s(uint16 _Opcode) +{ + uint8 dreg = _Opcode & 0x3; + uint8 sreg = ((_Opcode >> 3) & 0x3) + 0x1c; + + OutBuffer::AddCode("*(%s) = %s", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(sreg)); + // dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]); + + if (_Opcode & 0x04) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(dreg+4)); + // g_dsp.r[dreg] += g_dsp.r[dreg + 4]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(dreg)); + //g_dsp.r[dreg]++; + } +} + + +void dsp_op_ext_l(uint16 _Opcode) +{ + uint8 sreg = _Opcode & 0x3; + uint8 dreg = ((_Opcode >> 3) & 0x7) + 0x18; + + OutBuffer::AddCode("%s = *(%s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(sreg)); + // uint16 val = dsp_dmem_read(g_dsp.r[sreg]); + // g_dsp.r[dreg] = val; + + if (_Opcode & 0x04) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(sreg), OutBuffer::GetRegName(sreg+4)); + // g_dsp.r[sreg] += g_dsp.r[sreg + 4]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(sreg)); + // g_dsp.r[sreg]++; + } +} + + +void dsp_op_ext_ls_pro(uint16 _Opcode) +{ + uint8 areg = (_Opcode & 0x1) + 0x1e; + + OutBuffer::AddCode("*(%s) = %s", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(areg)); + // dsp_dmem_write(g_dsp.r[0x03], g_dsp.r[areg]); + + if (_Opcode & 0x8) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(0x07)); + // g_dsp.r[0x03] += g_dsp.r[0x07]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x03)); + // g_dsp.r[0x03]++; + } +} + + +void dsp_op_ext_ls_epi(uint16 _Opcode) +{ + uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18; + + OutBuffer::AddCode("%s = *(%s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(0x00)); + // uint16 val = dsp_dmem_read(g_dsp.r[0x00]); + // dsp_op_write_reg(dreg, val); + + if (_Opcode & 0x4) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x00), OutBuffer::GetRegName(0x04)); + // g_dsp.r[0x00] += g_dsp.r[0x04]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x00)); + // g_dsp.r[0x00]++; + } +} + + +void dsp_op_ext_sl_pro(uint16 _Opcode) +{ + uint8 areg = (_Opcode & 0x1) + 0x1e; + + OutBuffer::AddCode("*(%s) = %s", OutBuffer::GetRegName(0x00), OutBuffer::GetRegName(areg)); + // dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); + + if (_Opcode & 0x4) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x00), OutBuffer::GetRegName(0x04)); + // g_dsp.r[0x00] += g_dsp.r[0x04]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x00)); + // g_dsp.r[0x00]++; + } +} + + +void dsp_op_ext_sl_epi(uint16 _Opcode) +{ + uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18; + + OutBuffer::AddCode("%s = *(%s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(0x03)); + // uint16 val = dsp_dmem_read(g_dsp.r[0x03]); + // dsp_op_write_reg(dreg, val); + + if (_Opcode & 0x8) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(0x07)); + // g_dsp.r[0x03] += g_dsp.r[0x07]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x03)); + // g_dsp.r[0x03]++; + } +} + + +void dsp_op_ext_ld(uint16 _Opcode) +{ + uint8 dreg1 = (((_Opcode >> 5) & 0x1) << 1) + 0x18; + uint8 dreg2 = (((_Opcode >> 4) & 0x1) << 1) + 0x19; + uint8 sreg = _Opcode & 0x3; + + OutBuffer::AddCode("%s = *(%s)", OutBuffer::GetRegName(dreg1), OutBuffer::GetRegName(sreg)); + OutBuffer::AddCode("%s = *(%s)", OutBuffer::GetRegName(dreg2), OutBuffer::GetRegName(0x03)); + + // g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]); + // g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[0x03]); + + if (_Opcode & 0x04) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(sreg), OutBuffer::GetRegName(sreg + 0x04)); + // g_dsp.r[sreg] += g_dsp.r[sreg + 0x04]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(sreg)); + // g_dsp.r[sreg]++; + } + + if (_Opcode & 0x08) + { + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(sreg + 0x07)); + // g_dsp.r[0x03] += g_dsp.r[0x07]; + } + else + { + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x03)); + // g_dsp.r[0x03]++; + } +} + + +// ================================================================================ +// +// +// +// ================================================================================ + +void dsp_op_ext_ops_pro(uint16 _Opcode) +{ + if ((_Opcode & 0xFF) == 0){return;} + + switch ((_Opcode >> 4) & 0xf) + { + case 0x00: + dsp_op_ext_r_epi(_Opcode); + break; + + case 0x01: + dsp_op_ext_mv(_Opcode); + break; + + case 0x02: + case 0x03: + dsp_op_ext_s(_Opcode); + break; + + case 0x04: + case 0x05: + case 0x06: + case 0x07: + dsp_op_ext_l(_Opcode); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + + if (_Opcode & 0x2) + { + dsp_op_ext_sl_pro(_Opcode); + } + else + { + dsp_op_ext_ls_pro(_Opcode); + } + + return; + + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dsp_op_ext_ld(_Opcode); + break; + } +} + + +void dsp_op_ext_ops_epi(uint16 _Opcode) +{ + if ((_Opcode & 0xFF) == 0){return;} + + switch ((_Opcode >> 4) & 0xf) + { + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + + if (_Opcode & 0x2) + { + dsp_op_ext_sl_epi(_Opcode); + } + else + { + dsp_op_ext_ls_epi(_Opcode); + } + + return; + } +} + + diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.h b/Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.h new file mode 100644 index 0000000000..b6fb8fc9be --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/DSPExt.h @@ -0,0 +1,33 @@ +/*==================================================================== + + 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 _GDSP_EXT_OP_H +#define _GDSP_EXT_OP_H + +void dsp_op_ext_ops_pro(uint16 _Opcode); +void dsp_op_ext_ops_epi(uint16 _Opcode); + + +#endif diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.cpp b/Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.cpp new file mode 100644 index 0000000000..c246e83ce2 --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.cpp @@ -0,0 +1,2353 @@ +#include + +#include "DSPOpcodes.h" +#include "DSPExt.h" + +#define SR_CMP_MASK 0x3f +#define DSP_REG_MASK 0x1f + +/* + +bool CheckCondition(uint8 _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: + // DebugLog("Unknown condition check: 0x%04x\n", _Condition & 0xf); + break; + } + + return(taken); +} +*/ + +// ======================================================================= + +//------------------------------------------------------------------------------- +void (*dsp_op[])(uint16 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 DecodeOpcode(uint16 op) +{ + dsp_op[op >> 12](op); + +} +void dsp_op_unknown(uint16 opc) +{ + ErrorLog("dsp_op_unknown somewhere"); + OutBuffer::AddCode("unknown somewhere"); +} + + +void dsp_opc_call(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_call"); + +/* uint16 dest = FetchOpcode(); + if (CheckCondition(opc & 0xf)) + { + dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); + g_dsp.pc = dest; + } */ +} + + +void dsp_opc_ifcc(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_call"); + +/* if (!CheckCondition(opc & 0xf)) + { + FetchOpcode(); // skip the next opcode + }*/ +} + + +void dsp_opc_jcc(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_call"); + +/* uint16 dest = FetchOpcode(); + + if (CheckCondition(opc & 0xf)) + { + g_dsp.pc = dest; + }*/ +} + + +void dsp_opc_jmpa(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_call"); + +/* uint8 reg; + uint16 addr; + + if ((opc & 0xf) != 0xf) + { + ErrorLog("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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_ret"); + +/* if (CheckCondition(opc & 0xf)) + { + g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C); + }*/ +} + + +void dsp_opc_rti(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_rti"); + +/* if ((opc & 0xf) != 0xf) + { + ErrorLog("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(uint16 opc) +{ + OutBuffer::AddCode("HALT"); + +/* g_dsp.cr |= 0x4; + g_dsp.pc = g_dsp.err_pc;*/ +} + + +void dsp_opc_loop(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_loop"); + +/* uint16 reg = opc & 0x1f; + uint16 cnt = g_dsp.r[reg]; + uint16 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_loopi"); + +/* uint16 cnt = opc & 0xff; + uint16 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_bloop"); + +/* uint16 reg = opc & 0x1f; + uint16 cnt = g_dsp.r[reg]; + uint16 loop_pc = FetchOpcode(); + + 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_bloopi"); + +/* uint16 cnt = opc & 0xff; + uint16 loop_pc = FetchOpcode(); + + 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(uint16 opc) +{ + uint8 sreg = opc & 0x1f; + uint8 dreg = (opc >> 5) & 0x1f; + + OutBuffer::AddCode("%s = %s", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(sreg)); + +// uint16 val = dsp_op_read_reg(sreg); +// dsp_op_write_reg(dreg, val); +} + + +void dsp_opc_lrr(uint16 opc) +{ + uint8 sreg = (opc >> 5) & 0x3; + uint8 dreg = opc & 0x1f; + + OutBuffer::AddCode("%s = *(%s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(sreg)); + +// uint16 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 + OutBuffer::AddCode("%s--", OutBuffer::GetRegName(sreg)); + // g_dsp.r[sreg]--; + break; + + case 0x2: // LRRI + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(sreg)); + //g_dsp.r[sreg]++; + break; + + case 0x3: + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(sreg), OutBuffer::GetRegName(sreg+4)); + // g_dsp.r[sreg] += g_dsp.r[sreg + 4]; + break; + } +} + + +void dsp_opc_srr(uint16 opc) +{ + uint8 dreg = (opc >> 5) & 0x3; + uint8 sreg = opc & 0x1f; + + OutBuffer::AddCode("*(%s) = %s", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(sreg)); + + //uint16 val = dsp_op_read_reg(sreg); + // dsp_dmem_write(g_dsp.r[dreg], val); + + // post processing of source reg + switch ((opc >> 7) & 0x3) + { + case 0x0: // SRR + break; + + case 0x1: // SRRD + OutBuffer::AddCode("%s--", OutBuffer::GetRegName(dreg)); + // g_dsp.r[dreg]--; + break; + + case 0x2: // SRRI + OutBuffer::AddCode("%s++", OutBuffer::GetRegName(dreg)); + // g_dsp.r[dreg]++; + break; + + case 0x3: // SRRX + OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(dreg+4)); + //g_dsp.r[dreg] += g_dsp.r[dreg + 4]; + break; + } +} + + +void dsp_opc_ilrr(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_ilrr"); + +/* uint16 reg = opc & 0x3; + uint16 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: + ErrorLog("dsp_opc_ilrr"); + }*/ +} + + +void dsp_opc_lri(uint16 opc) +{ + uint8 reg = opc & DSP_REG_MASK; + uint16 imm = FetchOpcode(); + + OutBuffer::AddCode("%s = 0x%02x", OutBuffer::GetRegName(reg), imm); + // dsp_op_write_reg(reg, imm); +} + + +void dsp_opc_lris(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_lris"); + +/* uint8 reg = ((opc >> 8) & 0x7) + 0x18; + uint16 imm = (sint8)opc; + dsp_op_write_reg(reg, imm);*/ +} + + +void dsp_opc_lr(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_lr"); + +/* uint8 reg = opc & DSP_REG_MASK; + uint16 addr = FetchOpcode(); + uint16 val = dsp_dmem_read(addr); + dsp_op_write_reg(reg, val);*/ +} + + +void dsp_opc_sr(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_sr"); + + /*uint8 reg = opc & DSP_REG_MASK; + uint16 addr = FetchOpcode(); + uint16 val = dsp_op_read_reg(reg); + dsp_dmem_write(addr, val);*/ +} + + +void dsp_opc_si(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_si"); + + //uint16 addr = (sint8)opc; + //uint16 imm = readimemory(); + //dsp_dmem_write(addr, imm); +} + + +void dsp_opc_tstaxh(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_tstaxh"); + + //uint8 reg = (opc >> 8) & 0x1; + //sint16 val = dsp_get_ax_h(reg); + + //Update_SR_Register(val); +} + + +void dsp_opc_clr(uint16 opc) +{ + uint8 reg = (opc >> 11) & 0x1; + + OutBuffer::AddCode("ACC%i = 0", reg); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", reg); + + //dsp_set_long_acc(reg, 0); + + //Update_SR_Register((sint64)0); +} + + +void dsp_opc_clrp(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_clrp"); + + //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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulc"); + + // math new prod + //uint8 sreg = (opc >> 11) & 0x1; + //uint8 treg = (opc >> 12) & 0x1; + + //sint64 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulcmvz"); + + ErrorLog("dsp_opc_mulcmvz ni"); +} + + +// NEW +void dsp_opc_mulcmv(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulcmv"); + + ErrorLog("dsp_opc_mulcmv ni"); +} + + +void dsp_opc_cmpar(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_cmpar"); + + //uint8 rreg = ((opc >> 12) & 0x1) + 0x1a; + //uint8 areg = (opc >> 11) & 0x1; + + //// we compare + //sint64 rr = (sint16)g_dsp.r[rreg]; + //rr <<= 16; + + //sint64 ar = dsp_get_long_acc(areg); + + //Update_SR_Register(ar - rr); +} + + +void dsp_opc_cmp(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_cmp"); + + //sint64 acc0 = dsp_get_long_acc(0); + //sint64 acc1 = dsp_get_long_acc(1); + + //Update_SR_Register(acc0 - acc1); +} + + +void dsp_opc_tsta(uint16 opc) +{ + uint8 reg = (opc >> 11) & 0x1; + OutBuffer::AddCode("Update_SR_Register(ACC%i)", reg); + + //uint8 reg = (opc >> 11) & 0x1; + //sint64 acc = dsp_get_long_acc(reg); + + //Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_addaxl(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 dreg = (opc >> 8) & 0x1; + + OutBuffer::AddCode("ACC%i += AX%i_l", dreg, sreg); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", dreg); + + //sint64 acc = dsp_get_long_acc(dreg); + //sint64 acx = dsp_get_ax_l(sreg); + + //acc += acx; + + //dsp_set_long_acc(dreg, acc); + + //Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_addarn(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_addarn"); + + //uint8 dreg = opc & 0x3; + //uint8 sreg = (opc >> 2) & 0x3; + + //g_dsp.r[dreg] += (sint16)g_dsp.r[0x04 + sreg]; +} + + +// NEW +void dsp_opc_mulcac(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulcac"); + + //sint64 TempProd = dsp_get_long_prod(); + + //// update prod + //uint8 sreg = (opc >> 12) & 0x1; + //sint64 Prod = (sint64)dsp_get_acc_m(sreg) * (sint64)dsp_get_acc_h(sreg) * GetMultiplyModifier(); + //dsp_set_long_prod(Prod); + + //// update acc + //uint8 rreg = (opc >> 8) & 0x1; + //dsp_set_long_acc(rreg, TempProd); +} + + +// NEW +void dsp_opc_movr(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + uint8 sreg = ((opc >> 9) & 0x3) + 0x18; + + OutBuffer::AddCode("ACC%i = (%s << 16) & ~0xFFFF", areg, OutBuffer::GetRegName(sreg)); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", areg); + + //sint64 acc = (sint16)g_dsp.r[sreg]; + //acc <<= 16; + //acc &= ~0xffff; + + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_movax(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 dreg = (opc >> 8) & 0x1; + + OutBuffer::AddCode("%s = %s", OutBuffer::GetRegName(0x1c + dreg), OutBuffer::GetRegName(0x18 + sreg)); + OutBuffer::AddCode("%s = %s", OutBuffer::GetRegName(0x1e + dreg), OutBuffer::GetRegName(0x1a + sreg)); + + //g_dsp.r[0x1c + dreg] = g_dsp.r[0x18 + sreg]; + //g_dsp.r[0x1e + dreg] = g_dsp.r[0x1a + sreg]; + + OutBuffer::AddCode("%s = (%s < 0) ? 0xFFFF : 0x0000", OutBuffer::GetRegName(0x10 + dreg), + OutBuffer::GetRegName(0x1a + sreg)); + + //if ((sint16)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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_xorr"); + + //uint8 sreg = (opc >> 9) & 0x1; + //uint8 dreg = (opc >> 8) & 0x1; + + //g_dsp.r[0x1e + dreg] ^= g_dsp.r[0x1a + sreg]; + + //dsp_opc_tsta(dreg << 11); +} + + +void dsp_opc_andr(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_andr"); + + //uint8 sreg = (opc >> 9) & 0x1; + //uint8 dreg = (opc >> 8) & 0x1; + + //g_dsp.r[0x1e + dreg] &= g_dsp.r[0x1a + sreg]; + + //dsp_opc_tsta(dreg << 11); +} + + +// NEW +void dsp_opc_orr(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_orr"); + + //uint8 sreg = (opc >> 9) & 0x1; + //uint8 dreg = (opc >> 8) & 0x1; + + //g_dsp.r[0x1e + dreg] |= g_dsp.r[0x1a + sreg]; + + //dsp_opc_tsta(dreg << 11); +} + + +// NEW +void dsp_opc_andc(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_andc"); + + //uint8 D = (opc >> 8) & 0x1; + + //uint16 ac1 = dsp_get_acc_m(D); + //uint16 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(uint16 opc) +{} + + +// NEW +void dsp_opc_andfc(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_andfc"); + + //if (opc & 0xf) + //{ + // ErrorLog("dsp_opc_andfc"); + //} + + //uint8 reg = (opc >> 8) & 0x1; + //uint16 imm = FetchOpcode(); + //uint16 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_andf"); + + //uint8 reg; + //uint16 imm; + //uint16 val; + + //if (opc & 0xf) + //{ + // ErrorLog("dsp_opc_andf"); + //} + + //reg = 0x1e + ((opc >> 8) & 0x1); + //imm = FetchOpcode(); + //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(uint16 opc) +{ + if (opc & 0xf) + { + ErrorLog("dsp_opc_subf"); + } + + uint8 reg = 0x1e + ((opc >> 8) & 0x1); + sint64 imm = (sint16)FetchOpcode(); + + OutBuffer::AddCode("missing: dsp_opc_subf"); + + //sint64 val = (sint16)g_dsp.r[reg]; + //sint64 res = val - imm; + + //Update_SR_Register(res); +} + + +void dsp_opc_xori(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_xori"); + + //if (opc & 0xf) + //{ + // ErrorLog("dsp_opc_xori"); + //} + + //uint8 reg = 0x1e + ((opc >> 8) & 0x1); + //uint16 imm = FetchOpcode(); + //g_dsp.r[reg] ^= imm; + + //Update_SR_Register((sint16)g_dsp.r[reg]); +} + + +void dsp_opc_andi(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_andi"); + + //if (opc & 0xf) + //{ + // ErrorLog("dsp_opc_andi"); + //} + + //uint8 reg = 0x1e + ((opc >> 8) & 0x1); + //uint16 imm = FetchOpcode(); + //g_dsp.r[reg] &= imm; + + //Update_SR_Register((sint16)g_dsp.r[reg]); +} + + +// F|RES: i am not sure if this shouldnt be the whole ACC +// +void dsp_opc_ori(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_ori"); + + //if (opc & 0xf) + //{ + // return(ErrorLog("dsp_opc_ori")); + //} + + //uint8 reg = 0x1e + ((opc >> 8) & 0x1); + //uint16 imm = FetchOpcode(); + //g_dsp.r[reg] |= imm; + + //Update_SR_Register((sint16)g_dsp.r[reg]); +} + + +//------------------------------------------------------------- + +void dsp_opc_add(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_add"); + + //uint8 areg = (opc >> 8) & 0x1; + //sint64 acc0 = dsp_get_long_acc(0); + //sint64 acc1 = dsp_get_long_acc(1); + + //sint64 res = acc0 + acc1; + + //dsp_set_long_acc(areg, res); + + //Update_SR_Register(res); +} + + +//------------------------------------------------------------- + +void dsp_opc_addp(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_addp"); + + //uint8 dreg = (opc >> 8) & 0x1; + //sint64 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_cmpis"); + + //uint8 areg = (opc >> 8) & 0x1; + + //sint64 acc = dsp_get_long_acc(areg); + //sint64 val = (sint8)opc; + //val <<= 16; + + //sint64 res = acc - val; + + //Update_SR_Register(res); +} + + +// NEW +// verified at the console +void dsp_opc_addpaxz(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_addpaxz"); + + //uint8 dreg = (opc >> 8) & 0x1; + //uint8 sreg = (opc >> 9) & 0x1; + + //sint64 prod = dsp_get_long_prod() & ~0x0ffff; + //sint64 ax_h = dsp_get_long_acx(sreg); + //sint64 acc = (prod + ax_h) & ~0x0ffff; + + //dsp_set_long_acc(dreg, acc); + + //Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_movpz(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x01; + + OutBuffer::AddCode("ACC%i = PROD & ~0xffff", dreg); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", dreg); + + //// overwrite acc and clear low part + //sint64 prod = dsp_get_long_prod(); + //sint64 acc = prod & ~0xffff; + //dsp_set_long_acc(dreg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_decm(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x01; + + OutBuffer::AddCode("ACC%i -= 0x10000", dreg); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", dreg); + + //sint64 sub = 0x10000; + //sint64 acc = dsp_get_long_acc(dreg); + //acc -= sub; + //dsp_set_long_acc(dreg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_dec(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x01; + + OutBuffer::AddCode("ACC%i -= 1", dreg); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", dreg); + + //sint64 acc = dsp_get_long_acc(dreg) - 1; + //dsp_set_long_acc(dreg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_incm(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_incm"); + + //uint8 dreg = (opc >> 8) & 0x1; + + //sint64 sub = 0x10000; + //sint64 acc = dsp_get_long_acc(dreg); + //acc += sub; + //dsp_set_long_acc(dreg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_inc(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_inc"); + + //uint8 dreg = (opc >> 8) & 0x1; + + //sint64 acc = dsp_get_long_acc(dreg); + //acc++; + //dsp_set_long_acc(dreg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_neg(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_neg"); + + //uint8 areg = (opc >> 8) & 0x1; + + //sint64 acc = dsp_get_long_acc(areg); + //acc = 0 - acc; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_movnp(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_movnp"); + + ErrorLog("dsp_opc_movnp\n"); +} + + +// NEW +void dsp_opc_addax(uint16 opc) +{ + // OutBuffer::AddCode("missing: dsp_opc_addax"); + + uint8 areg = (opc >> 8) & 0x1; + uint8 sreg = (opc >> 9) & 0x1; + + OutBuffer::AddCode("ACC%i += AX%i", areg, sreg); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", areg); + + //sint64 ax = dsp_get_long_acx(sreg); + //sint64 acc = dsp_get_long_acc(areg); + //acc += ax; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_addr(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_addr"); + + //uint8 areg = (opc >> 8) & 0x1; + //uint8 sreg = ((opc >> 9) & 0x3) + 0x18; + + //sint64 ax = (sint16)g_dsp.r[sreg]; + //ax <<= 16; + + //sint64 acc = dsp_get_long_acc(areg); + //acc += ax; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_subr(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + uint8 sreg = ((opc >> 9) & 0x3) + 0x18; + + OutBuffer::AddCode("ACC%i -= (sint64)((sint16)%s << 16)", areg, OutBuffer::GetRegName(sreg)); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", areg); + + //sint64 ax = (sint16)g_dsp.r[sreg]; + //ax <<= 16; + + //sint64 acc = dsp_get_long_acc(areg); + //acc -= ax; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + +// NEW +void dsp_opc_subax(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_subax"); + + //int regD = (opc >> 8) & 0x1; + //int regT = (opc >> 9) & 0x1; + + //sint64 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_addis"); + + //uint8 areg = (opc >> 8) & 0x1; + + //sint64 Imm = (sint8)opc; + //Imm <<= 16; + //sint64 acc = dsp_get_long_acc(areg); + //acc += Imm; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_addi(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_addi"); + + //uint8 areg = (opc >> 8) & 0x1; + + //sint64 sub = (sint16)FetchOpcode(); + //sub <<= 16; + //sint64 acc = dsp_get_long_acc(areg); + //acc += sub; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_lsl16(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + + OutBuffer::AddCode("ACC%i <<= 16", areg); + OutBuffer::AddCode("Update_SR_Register(ACC%i)", areg); + + //sint64 acc = dsp_get_long_acc(areg); + //acc <<= 16; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_madd(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_madd"); + + //uint8 sreg = (opc >> 8) & 0x1; + + //sint64 prod = dsp_get_long_prod(); + //prod += (sint64)dsp_get_ax_l(sreg) * (sint64)dsp_get_ax_h(sreg) * GetMultiplyModifier(); + //dsp_set_long_prod(prod); +} + + +void dsp_opc_lsr16(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_lsr16"); + + //uint8 areg = (opc >> 8) & 0x1; + + //sint64 acc = dsp_get_long_acc(areg); + //acc >>= 16; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +void dsp_opc_asr16(uint16 opc) +{ + uint8 areg = (opc >> 11) & 0x1; + + OutBuffer::AddCode("ACC%i >>= 16", areg); + OutBuffer::AddCode("Update_SR_Register(AC%i)", areg); + + //sint64 acc = dsp_get_long_acc(areg); + //acc >>= 16; + //dsp_set_long_acc(areg, acc); + + //Update_SR_Register(acc); +} + + +union UOpcodeShifti +{ + uint16 Hex; + struct + { + signed shift : 6; + unsigned negating : 1; + unsigned arithmetic : 1; + unsigned areg : 1; + unsigned op : 7; + }; + struct + { + unsigned ushift : 6; + }; + UOpcodeShifti(uint16 _Hex) + : Hex(_Hex) {} +}; + +void dsp_opc_shifti(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_shifti"); + + //UOpcodeShifti Opcode(opc); + + //// direction: left + //bool ShiftLeft = true; + //uint16 shift = Opcode.ushift; + + //if ((Opcode.negating) && (Opcode.shift < 0)) + //{ + // ShiftLeft = false; + // shift = -Opcode.shift; + //} + + //sint64 acc; + //uint64 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_dar"); + + //uint8 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_iar"); + + //uint8 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_sbclr"); + + //uint8 bit = (opc & 0xff) + 6; + //g_dsp.r[R_SR] &= ~(1 << bit); +} + + +void dsp_opc_sbset(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_sbset"); + + //uint8 bit = (opc & 0xff) + 6; + //g_dsp.r[R_SR] |= (1 << bit); +} + + +void dsp_opc_srbith(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_srbith"); + +// switch ((opc >> 8) & 0xf) +// { +// case 0xe: // SET40 +// g_dsp.r[R_SR] &= ~(1 << 14); +// break; +// +///* case 0xf: // SET16 // that doesnt happen on a real console +// g_dsp.r[R_SR] |= (1 << 14); +// break;*/ +// +// default: +// break; +// } +} + + +//------------------------------------------------------------- + +void dsp_opc_movp(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x1; + + OutBuffer::AddCode("ACC%i = PROD", dreg); + + //sint64 prod = dsp_get_long_prod(); + //sint64 acc = prod; + //dsp_set_long_acc(dreg, acc); +} + + +void dsp_opc_mul(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mul"); + + //uint8 sreg = (opc >> 11) & 0x1; + //sint64 prod = (sint64)dsp_get_ax_h(sreg) * (sint64)dsp_get_ax_l(sreg) * GetMultiplyModifier(); + + //dsp_set_long_prod(prod); + + //Update_SR_Register(prod); +} + +// NEW +void dsp_opc_mulac(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulac"); + + //// add old prod to acc + //uint8 rreg = (opc >> 8) & 0x1; + //sint64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod(); + //dsp_set_long_acc(rreg, acR); + + //// math new prod + //uint8 sreg = (opc >> 11) & 0x1; + //sint64 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(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulmv"); + + //uint8 rreg = (opc >> 8) & 0x1; + //sint64 prod = dsp_get_long_prod(); + //sint64 acc = prod; + //dsp_set_long_acc(rreg, acc); + + //uint8 areg = ((opc >> 11) & 0x1) + 0x18; + //uint8 breg = ((opc >> 11) & 0x1) + 0x1a; + //sint64 val1 = (sint16)g_dsp.r[areg]; + //sint64 val2 = (sint16)g_dsp.r[breg]; + + //prod = val1 * val2 * GetMultiplyModifier(); + + //dsp_set_long_prod(prod); + + //Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulmvz(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulmvz"); + + //uint8 sreg = (opc >> 11) & 0x1; + //uint8 rreg = (opc >> 8) & 0x1; + + //// overwrite acc and clear low part + //sint64 prod = dsp_get_long_prod(); + //sint64 acc = prod & ~0xffff; + //dsp_set_long_acc(rreg, acc); + + //// math prod + //prod = (sint64)g_dsp.r[0x18 + sreg] * (sint64)g_dsp.r[0x1a + sreg] * GetMultiplyModifier(); + //dsp_set_long_prod(prod); + + //Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulx(uint16 opc) +{ + // OutBuffer::AddCode("missing: dsp_opc_mulx"); + + uint8 sreg = ((opc >> 12) & 0x1); + uint8 treg = ((opc >> 11) & 0x1); + + OutBuffer::AddCode("PROD = %s * %s * MultiplyModifier", (sreg == 0) ? "AX0_l" : "AX0_h", + (treg == 0) ? "AX1_l" : "AX1_h"); + OutBuffer::AddCode("Update_SR_Register(PROD)"); + + //sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + //sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + //sint64 prod = val1 * val2 * GetMultiplyModifier(); + //dsp_set_long_prod(prod); + + //Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulxac(uint16 opc) +{ + //// add old prod to acc + uint8 rreg = (opc >> 8) & 0x1; + //sint64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod(); + //dsp_set_long_acc(rreg, acR); + + OutBuffer::AddCode("ACC%i += PROD", rreg); + + //// math new prod + uint8 sreg = (opc >> 12) & 0x1; + uint8 treg = (opc >> 11) & 0x1; + + OutBuffer::AddCode("PROD = %s * %s * MultiplyModifier", (sreg == 0) ? "AX0_l" : "AX0_h", + (treg == 0) ? "AX1_l" : "AX1_h"); + OutBuffer::AddCode("Update_SR_Register(PROD)"); + + //sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + //sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + //sint64 prod = val1 * val2 * GetMultiplyModifier(); + //dsp_set_long_prod(prod); + + //Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulxmv(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulxmv"); + + //// add old prod to acc + //uint8 rreg = ((opc >> 8) & 0x1); + //sint64 acR = dsp_get_long_prod(); + //dsp_set_long_acc(rreg, acR); + + //// math new prod + //uint8 sreg = (opc >> 12) & 0x1; + //uint8 treg = (opc >> 11) & 0x1; + + //sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + //sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + //sint64 prod = val1 * val2 * GetMultiplyModifier(); + //dsp_set_long_prod(prod); + + //Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulxmvz(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_mulxmvz"); + + //// overwrite acc and clear low part + //uint8 rreg = (opc >> 8) & 0x1; + //sint64 prod = dsp_get_long_prod(); + //sint64 acc = prod & ~0xffff; + //dsp_set_long_acc(rreg, acc); + + //// math prod + //uint8 sreg = (opc >> 12) & 0x1; + //uint8 treg = (opc >> 11) & 0x1; + + //sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + //sint64 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(uint16 opc) +{ + uint8 D = (opc >> 8) & 0x1; + + OutBuffer::AddCode("ACC%i -= ACC%i", D, 1-D); + + //sint64 Acc1 = dsp_get_long_acc(D); + //sint64 Acc2 = dsp_get_long_acc(1 - D); + + //Acc1 -= Acc2; + + //dsp_set_long_acc(D, Acc1); +} + + +//------------------------------------------------------------- +// +// --- Table E +// +//------------------------------------------------------------- + +// NEW +void dsp_opc_maddx(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_maddx"); + + //uint8 sreg = (opc >> 9) & 0x1; + //uint8 treg = (opc >> 8) & 0x1; + + //sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + //sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + //sint64 prod = dsp_get_long_prod(); + //prod += val1 * val2 * GetMultiplyModifier(); + //dsp_set_long_prod(prod); +} + + +// NEW +void dsp_opc_msubx(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_msubx"); + + //uint8 sreg = (opc >> 9) & 0x1; + //uint8 treg = (opc >> 8) & 0x1; + + //sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + //sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + //sint64 prod = dsp_get_long_prod(); + //prod -= val1 * val2 * GetMultiplyModifier(); + //dsp_set_long_prod(prod); +} + + +// NEW +void dsp_opc_maddc(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_maddc"); + + //uint sreg = (opc >> 9) & 0x1; + //uint treg = (opc >> 8) & 0x1; + + //sint64 val1 = dsp_get_acc_m(sreg); + //sint64 val2 = dsp_get_ax_h(treg); + + //sint64 prod = dsp_get_long_prod(); + //prod += val1 * val2 * GetMultiplyModifier(); + //dsp_set_long_prod(prod); +} + + +// NEW +void dsp_opc_msubc(uint16 opc) +{ + OutBuffer::AddCode("missing: dsp_opc_msubc"); + + //uint sreg = (opc >> 9) & 0x1; + //uint treg = (opc >> 8) & 0x1; + + //sint64 val1 = dsp_get_acc_m(sreg); + //sint64 val2 = dsp_get_ax_h(treg); + + //sint64 prod = dsp_get_long_prod(); + //prod -= val1 * val2 * GetMultiplyModifier(); + //dsp_set_long_prod(prod); +} + + +//------------------------------------------------------------- +void dsp_op0(uint16 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: + ErrorLog("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: + ErrorLog("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: + ErrorLog("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: + ErrorLog("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: + ErrorLog("dsp_op0"); + break; + } +} + + +void dsp_op1(uint16 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: + ErrorLog("dsp_op1"); + break; + } +} + + +void dsp_op2(uint16 opc) +{ + // lrs, srs + uint8 reg = ((opc >> 8) & 0x7) + 0x18; + uint16 addr = (sint8) opc; + + if (opc & 0x0800) + { + OutBuffer::AddCode("*(%s) = %s", OutBuffer::GetMemName(addr), OutBuffer::GetRegName(reg)); + + // srs + // dsp_dmem_write(addr, g_dsp.r[reg]); + } + else + { + OutBuffer::AddCode("%s = *(%s)", OutBuffer::GetRegName(reg), OutBuffer::GetMemName(addr)); + + // lrs + // g_dsp.r[reg] = dsp_dmem_read(addr); + } +} + + +void dsp_op3(uint16 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: + ErrorLog("dsp_op3"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op4(uint16 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: + ErrorLog("dsp_op4"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op5(uint16 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: + ErrorLog("dsp_op5: %x", (opc >> 8) & 0xf); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op6(uint16 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: + ErrorLog("dsp_op6"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op7(uint16 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: + ErrorLog("dsp_op7"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op8(uint16 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: + ErrorLog("dsp_op8"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op9(uint16 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: + ErrorLog("dsp_op9"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_opab(uint16 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: + ErrorLog("dsp_opab"); + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_opcd(uint16 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: + ErrorLog("dsp_opcd"); + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_ope(uint16 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: + ErrorLog("dsp_ope"); + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_opf(uint16 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: + ErrorLog("dsp_opf"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.h b/Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.h new file mode 100644 index 0000000000..ec250031b6 --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/DSPOpcodes.h @@ -0,0 +1,48 @@ +/*==================================================================== + + 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 + +void dsp_op0(uint16 opc); +void dsp_op1(uint16 opc); +void dsp_op2(uint16 opc); +void dsp_op3(uint16 opc); +void dsp_op4(uint16 opc); +void dsp_op5(uint16 opc); +void dsp_op6(uint16 opc); +void dsp_op7(uint16 opc); +void dsp_op8(uint16 opc); +void dsp_op9(uint16 opc); +void dsp_opab(uint16 opc); +void dsp_opcd(uint16 opc); +void dsp_ope(uint16 opc); +void dsp_opf(uint16 opc); + + +#define R_SR 0x13 + +#define FLAG_ENABLE_INTERUPT 11 + +#endif diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.cpp b/Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.cpp new file mode 100644 index 0000000000..d0811a2183 --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.cpp @@ -0,0 +1,52 @@ +// DSP_InterC.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +#include "DSPOpcodes.h" + +uint16 g_IMemory[0x1000]; +uint16 g_currentAddress; + +uint16 FetchOpcode() +{ + uint16 value = swap16(g_IMemory[g_currentAddress & 0x0FFF]); + g_currentAddress++; + return value; +} + +void DecodeOpcode(uint16 op); + +void Decode(uint16 startAddress, uint16 endAddress) +{ + g_currentAddress = startAddress; + + while (g_currentAddress < endAddress) + { + uint16 oldPC = g_currentAddress; + uint16 op = FetchOpcode(); + + OutBuffer::Add("%4X:", oldPC); + DecodeOpcode(op); + } +} + + +int _tmain(int argc, _TCHAR* argv[]) +{ + FILE* pFile = fopen("c:\\_\\dsp_rom.bin", "rb"); + if (pFile == NULL) + return -1; + + fread(g_IMemory, 0x1000, 1, pFile); + fclose(pFile); + + + ////// + OutBuffer::Init(); + Decode(0x80e7, 0x81f9); + + + return 0; +} + diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.vcproj b/Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.vcproj new file mode 100644 index 0000000000..ec800df5b6 --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/DSP_InterC.vcproj @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/OutBuffer.cpp b/Docs/DSP/DSP_InterC/DSP_InterC/OutBuffer.cpp new file mode 100644 index 0000000000..bf941cf531 --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/OutBuffer.cpp @@ -0,0 +1,155 @@ +// stdafx.cpp : source file that includes just the standard includes +// DSP_InterC.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +#include +#include + +namespace OutBuffer +{ + void Init() + { + + } + + void Add(const char* _fmt, ...) + { + static char Msg[2048]; + va_list ap; + + va_start(ap, _fmt); + vsprintf(Msg, _fmt, ap); + va_end(ap); + + printf("%s\n", Msg); + } + + void AddCode(const char* _fmt, ...) + { + static char Msg[2048]; + va_list ap; + + va_start(ap, _fmt); + vsprintf(Msg, _fmt, ap); + va_end(ap); + + printf(" %s\n", Msg); + } + + // predefined labels + typedef struct pdlabel_t + { + uint16 addr; + const char* name; + const char* description; + } pdlabels_t; + + pdlabel_t regnames[] = + { + {0x00, "R00", "Register 00",}, + {0x01, "R01", "Register 01",}, + {0x02, "R02", "Register 02",}, + {0x03, "R03", "Register 03",}, + {0x04, "R04", "Register 04",}, + {0x05, "R05", "Register 05",}, + {0x06, "R06", "Register 06",}, + {0x07, "R07", "Register 07",}, + {0x08, "R08", "Register 08",}, + {0x09, "R09", "Register 09",}, + {0x0a, "R10", "Register 10",}, + {0x0b, "R11", "Register 11",}, + {0x0c, "ST0", "Call stack",}, + {0x0d, "ST1", "Data stack",}, + {0x0e, "ST2", "Loop address stack",}, + {0x0f, "ST3", "Loop counter",}, + {0x00, "ACH0", "Accumulator High 0",}, + {0x11, "ACH1", "Accumulator High 1",}, + {0x12, "CR", "Config Register",}, + {0x13, "SR", "Special Register",}, + {0x14, "PROD.L", "PROD L",}, + {0x15, "PROD.M1", "PROD M1",}, + {0x16, "PROD.H", "PROD H",}, + {0x17, "PROD.M2", "PROD M2",}, + {0x18, "AX0.L", "Additional Accumulators Low 0",}, + {0x19, "AX1.L", "Additional Accumulators Low 1",}, + {0x1a, "AX0.H", "Additional Accumulators High 0",}, + {0x1b, "AX1.H", "Additional Accumulators High 1",}, + {0x1c, "AC0.L", "Register 28",}, + {0x1d, "AC1.L", "Register 29",}, + {0x1e, "AC0.M", "Register 00",}, + {0x1f, "AC1.M", "Register 00",}, + + // additional to resolve special names + {0x20, "ACC0", "Accumulators 0",}, + {0x21, "ACC1", "Accumulators 1",}, + {0x22, "AX0", "Additional Accumulators 0",}, + {0x23, "AX1", "Additional Accumulators 1",}, + }; + + const pdlabel_t pdlabels[] = + { + {0xffa0, "COEF_A1_0", "COEF_A1_0",}, + {0xffa1, "COEF_A2_0", "COEF_A2_0",}, + {0xffa2, "COEF_A1_1", "COEF_A1_1",}, + {0xffa3, "COEF_A2_1", "COEF_A2_1",}, + {0xffa4, "COEF_A1_2", "COEF_A1_2",}, + {0xffa5, "COEF_A2_2", "COEF_A2_2",}, + {0xffa6, "COEF_A1_3", "COEF_A1_3",}, + {0xffa7, "COEF_A2_3", "COEF_A2_3",}, + {0xffa8, "COEF_A1_4", "COEF_A1_4",}, + {0xffa9, "COEF_A2_4", "COEF_A2_4",}, + {0xffaa, "COEF_A1_5", "COEF_A1_5",}, + {0xffab, "COEF_A2_5", "COEF_A2_5",}, + {0xffac, "COEF_A1_6", "COEF_A1_6",}, + {0xffad, "COEF_A2_6", "COEF_A2_6",}, + {0xffae, "COEF_A1_7", "COEF_A1_7",}, + {0xffaf, "COEF_A2_7", "COEF_A2_7",}, + {0xffc9, "DSCR", "DSP DMA Control Reg",}, + {0xffcb, "DSBL", "DSP DMA Block Length",}, + {0xffcd, "DSPA", "DSP DMA DMEM Address",}, + {0xffce, "DSMAH", "DSP DMA Mem Address H",}, + {0xffcf, "DSMAL", "DSP DMA Mem Address L",}, + {0xffd1, "SampleFormat", "SampleFormat",}, + + {0xffd3, "Unk Zelda", "Unk Zelda writes to it",}, + + {0xffd4, "ACSAH", "Accelerator start address H",}, + {0xffd5, "ACSAL", "Accelerator start address L",}, + {0xffd6, "ACEAH", "Accelerator end address H",}, + {0xffd7, "ACEAL", "Accelerator end address L",}, + {0xffd8, "ACCAH", "Accelerator current address H",}, + {0xffd9, "ACCAL", "Accelerator current address L",}, + {0xffda, "pred_scale", "pred_scale",}, + {0xffdb, "yn1", "yn1",}, + {0xffdc, "yn2", "yn2",}, + {0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",}, + {0xffde, "GAIN", "Gain",}, + {0xffef, "AMDM", "ARAM DMA Request Mask",}, + {0xfffb, "DIRQ", "DSP IRQ Request",}, + {0xfffc, "DMBH", "DSP Mailbox H",}, + {0xfffd, "DMBL", "DSP Mailbox L",}, + {0xfffe, "CMBH", "CPU Mailbox H",}, + {0xffff, "CMBL", "CPU Mailbox L",}, + }; + + const char* GetRegName(uint16 reg) + { + return regnames[reg].name; + } + + const char* GetMemName(uint16 addr) + { + static char Buffer[1024]; + for (int i=0; i 0); +} + + +// --------------------------------------------------------------------------------------- +// +// --- reg +// +// --------------------------------------------------------------------------------------- + +inline uint16 dsp_op_read_reg(uint8 reg) +{ + uint16 val; + + switch (reg & 0x1f) + { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + val = dsp_reg_load_stack(reg - 0x0c); + break; + + default: + val = g_dsp.r[reg]; + break; + } + + return(val); +} + + +inline void dsp_op_write_reg(uint8 reg, uint16 val) +{ + switch (reg & 0x1f) + { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dsp_reg_store_stack(reg - 0x0c, val); + break; + + default: + g_dsp.r[reg] = val; + break; + } +} + + +// --------------------------------------------------------------------------------------- +// +// --- prod +// +// --------------------------------------------------------------------------------------- + + +inline sint64 dsp_get_long_prod() +{ + sint64 val; + sint64 low_prod; + val = (sint8)g_dsp.r[0x16]; + val <<= 32; + low_prod = g_dsp.r[0x15]; + low_prod += g_dsp.r[0x17]; + low_prod <<= 16; + low_prod |= g_dsp.r[0x14]; + val += low_prod; + return(val); +} + + +inline void dsp_set_long_prod(sint64 val) +{ + g_dsp.r[0x14] = (uint16)val; + val >>= 16; + g_dsp.r[0x15] = (uint16)val; + val >>= 16; + g_dsp.r[0x16] = (uint16)val; + g_dsp.r[0x17] = 0; +} + + +// --------------------------------------------------------------------------------------- +// +// --- acc +// +// --------------------------------------------------------------------------------------- + +inline sint64 dsp_get_long_acc(uint8 reg) +{ + _dbg_assert_(reg < 2); + sint64 val; + sint64 low_acc; + val = (sint8)g_dsp.r[0x10 + reg]; + val <<= 32; + low_acc = g_dsp.r[0x1e + reg]; + low_acc <<= 16; + low_acc |= g_dsp.r[0x1c + reg]; + val |= low_acc; + return(val); +} + + +inline uint64 dsp_get_ulong_acc(uint8 reg) +{ + _dbg_assert_(reg < 2); + uint64 val; + uint64 low_acc; + val = (uint8)g_dsp.r[0x10 + reg]; + val <<= 32; + low_acc = g_dsp.r[0x1e + reg]; + low_acc <<= 16; + low_acc |= g_dsp.r[0x1c + reg]; + val |= low_acc; + return(val); +} + + +inline void dsp_set_long_acc(uint8 _reg, sint64 val) +{ + _dbg_assert_(_reg < 2); + g_dsp.r[0x1c + _reg] = (uint16)val; + val >>= 16; + g_dsp.r[0x1e + _reg] = (uint16)val; + val >>= 16; + g_dsp.r[0x10 + _reg] = (uint16)val; +} + + +inline sint16 dsp_get_acc_l(uint8 _reg) +{ + _dbg_assert_(_reg < 2); + return(g_dsp.r[0x1c + _reg]); +} + + +inline sint16 dsp_get_acc_m(uint8 _reg) +{ + _dbg_assert_(_reg < 2); + return(g_dsp.r[0x1e + _reg]); +} + + +inline sint16 dsp_get_acc_h(uint8 _reg) +{ + _dbg_assert_(_reg < 2); + return(g_dsp.r[0x10 + _reg]); +} + + +// --------------------------------------------------------------------------------------- +// +// --- acx +// +// --------------------------------------------------------------------------------------- + + +inline sint64 dsp_get_long_acx(uint8 _reg) +{ + _dbg_assert_(_reg < 2); + sint64 val = (sint16)g_dsp.r[0x1a + _reg]; + val <<= 16; + sint64 low_acc = g_dsp.r[0x18 + _reg]; + val |= low_acc; + return(val); +} + + +inline sint16 dsp_get_ax_l(uint8 _reg) +{ + _dbg_assert_(_reg < 2); + return(g_dsp.r[0x18 + _reg]); +} + + +inline sint16 dsp_get_ax_h(uint8 _reg) +{ + _dbg_assert_(_reg < 2); + return(g_dsp.r[0x1a + _reg]); +} + + +#endif diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/stdafx.cpp b/Docs/DSP/DSP_InterC/DSP_InterC/stdafx.cpp new file mode 100644 index 0000000000..6b8280251a --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/stdafx.cpp @@ -0,0 +1,23 @@ +// stdafx.cpp : source file that includes just the standard includes +// DSP_InterC.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file + +#include + +void ErrorLog(const char* _fmt, ...) +{ + char Msg[512]; + va_list ap; + + va_start(ap, _fmt); + vsprintf(Msg, _fmt, ap); + va_end(ap); + + printf("Error"); + +} \ No newline at end of file diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/stdafx.h b/Docs/DSP/DSP_InterC/DSP_InterC/stdafx.h new file mode 100644 index 0000000000..1d7c35fd96 --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/stdafx.h @@ -0,0 +1,39 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + + + + + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned long long uint64; +typedef unsigned int uint; + +typedef signed char sint8; +typedef signed short sint16; +typedef signed int sint32; +typedef signed long long sint64; + +extern uint16 FetchOpcode(); +extern void ErrorLog(const char* _fmt, ...); + +inline uint16 swap16(uint16 x) +{ + return((x >> 8) | (x << 8)); +} + +#include "OutBuffer.h" + +// TODO: reference additional headers your program requires here diff --git a/Docs/DSP/DSP_InterC/DSP_InterC/targetver.h b/Docs/DSP/DSP_InterC/DSP_InterC/targetver.h new file mode 100644 index 0000000000..a38195a4ef --- /dev/null +++ b/Docs/DSP/DSP_InterC/DSP_InterC/targetver.h @@ -0,0 +1,13 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif +