Started cleaning up the ext_op code

Trying to get rid of the case and use a table like the main opcodes
not sure how to handle epilog/prolog... maybe another table?



git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2951 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-04-10 14:40:25 +00:00
parent c1fe6def46
commit 4fa154bb56
4 changed files with 651 additions and 458 deletions

View File

@ -1752,8 +1752,7 @@ void msubx(const UDSPInstruction& opc)
// MADDC $acS.m, $axT.h // MADDC $acS.m, $axT.h
// 1110 10st xxxx xxxx // 1110 10st xxxx xxxx
// Multiply middle part of accumulator $acS.m by high part of secondary // Multiply middle part of accumulator $acS.m by high part of secondary
// accumulator $axT.h (treat them both as signed) and add result to product // accumulator $axT.h (treat them both as signed) and add result to product register.
// register.
void maddc(const UDSPInstruction& opc) void maddc(const UDSPInstruction& opc)
{ {
u32 sreg = (opc.hex >> 9) & 0x1; u32 sreg = (opc.hex >> 9) & 0x1;
@ -1789,28 +1788,28 @@ void msubc(const UDSPInstruction& opc)
Update_SR_Register64(prod); Update_SR_Register64(prod);
} }
// SRS @M, $(0x18+S) // SRS @M, $(DSP_REG_AXL0+S)
// 0010 1sss mmmm mmmm // 0010 1sss mmmm mmmm
// Store value from register $(0x18+S) to a memory pointed by address M. // Store value from register $(DSP_REG_AXL0+S) to a memory pointed by address M.
// (8-bit sign extended). // (8-bit sign extended).
// FIXME: Perform additional operation depending on destination register. // FIXME: Perform additional operation depending on destination register.
// Note: pc+=2 in duddie's doc seems wrong // Note: pc+=2 in duddie's doc seems wrong
void srs(const UDSPInstruction& opc) void srs(const UDSPInstruction& opc)
{ {
u8 reg = ((opc.hex >> 8) & 0x7) + 0x18; u8 reg = ((opc.hex >> 8) & 0x7) + DSP_REG_AXL0;
u16 addr = (u16)(s16)(s8)opc.hex; u16 addr = (u16)(s16)(s8)opc.hex;
dsp_dmem_write(addr, g_dsp.r[reg]); dsp_dmem_write(addr, g_dsp.r[reg]);
} }
// LRS $(0x18+D), @M // LRS $(DSP_REG_AXL0+D), @M
// 0010 0ddd mmmm mmmm // 0010 0ddd mmmm mmmm
// Move value from data memory pointed by address M (8-bit sign // Move value from data memory pointed by address M (8-bit sign
// extended) to register $(0x18+D). // extended) to register $(DSP_REG_AXL0+D).
// FIXME: Perform additional operation depending on destination register. // FIXME: Perform additional operation depending on destination register.
// Note: pc+=2 in duddie's doc seems wrong // Note: pc+=2 in duddie's doc seems wrong
void lrs(const UDSPInstruction& opc) void lrs(const UDSPInstruction& opc)
{ {
u8 reg = ((opc.hex >> 8) & 0x7) + 0x18; u8 reg = ((opc.hex >> 8) & 0x7) + DSP_REG_AXL0;
u16 addr = (u16)(s16)(s8)opc.hex; u16 addr = (u16)(s16)(s8)opc.hex;
g_dsp.r[reg] = dsp_dmem_read(addr); g_dsp.r[reg] = dsp_dmem_read(addr);
} }

View File

@ -62,7 +62,6 @@ void nop(const UDSPInstruction& opc) {if(opc.hex) DSPInterpreter::unknown(opc);}
// Zelda Four Swords: 02ca // Zelda Four Swords: 02ca
// TODO: Fill up the tables with the corresponding instructions
DSPOPCTemplate opcodes[] = DSPOPCTemplate opcodes[] =
{ {
{"NOP", 0x0000, 0xffff, nop, nop, 1, 0, {}, NULL, NULL}, {"NOP", 0x0000, 0xffff, nop, nop, 1, 0, {}, NULL, NULL},
@ -306,30 +305,39 @@ DSPOPCTemplate opcodes[] =
DSPOPCTemplate opcodes_ext[] = DSPOPCTemplate opcodes_ext[] =
{ {
{"L", 0x0040, 0x00c4, nop, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"LN", 0x0044, 0x00c4, nop, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,}, {"DR", 0x0004, 0x00fc, DSPInterpreter::Ext::dr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"IR", 0x0008, 0x00fc, DSPInterpreter::Ext::ir, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"NR", 0x000c, 0x00fc, DSPInterpreter::Ext::nr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"MV", 0x0010, 0x00f0, DSPInterpreter::Ext::mv, nop, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"S", 0x0020, 0x00e4, DSPInterpreter::Ext::s, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,},
{"SN", 0x0024, 0x00e4, DSPInterpreter::Ext::sn, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,},
{"L", 0x0040, 0x00c4, DSPInterpreter::Ext::l, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"LN", 0x0044, 0x00c4, DSPInterpreter::Ext::ln, nop, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"LS", 0x0080, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,}, {"LS", 0x0080, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
{"LSN", 0x0084, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
{"LSM", 0x0088, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
{"LSNM", 0x008c, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
{"SL", 0x0082, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,}, {"SL", 0x0082, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
{"LSN", 0x0084, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
{"SLN", 0x0086, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,}, {"SLN", 0x0086, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
{"LSM", 0x0088, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
{"SLM", 0x008a, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,}, {"SLM", 0x008a, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
{"LSNM", 0x008c, 0x00ce, nop, nop, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, NULL, NULL,},
{"SLNM", 0x008e, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,}, {"SLNM", 0x008e, 0x00ce, nop, nop, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, NULL, NULL,},
{"S", 0x0020, 0x00e4, nop, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,},
{"SN", 0x0024, 0x00e4, nop, nop, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}}, NULL, NULL,}, // FIXME what are the LDx? for?
{"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}}, NULL, NULL,}, /* {"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}}, NULL, NULL,},
{"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}}, NULL, NULL,}, {"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}}, NULL, NULL,},
{"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}}, NULL, NULL,}, {"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}}, NULL, NULL,},
{"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}}, NULL, NULL,}, {"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}}, NULL, NULL,},*/
{"LD", 0x00c0, 0x00cc, nop, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"LDN", 0x00c4, 0x00cc, nop, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,}, {"LD", 0x00c0, 0x00cc, DSPInterpreter::Ext::ld, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"LDM", 0x00c8, 0x00cc, nop, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,}, {"LDN", 0x00c4, 0x00cc, DSPInterpreter::Ext::ldn, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"LDNM", 0x00cc, 0x00cc, nop, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,}, {"LDM", 0x00c8, 0x00cc, DSPInterpreter::Ext::ldm, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"MV", 0x0010, 0x00f0, nop, nop, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}}, NULL, NULL,}, {"LDNM", 0x00cc, 0x00cc, DSPInterpreter::Ext::ldnm, nop, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"DR", 0x0004, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"IR", 0x0008, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"NR", 0x000c, 0x00fc, nop, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
{"XXX", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}}, NULL, NULL,}, {"XXX", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}}, NULL, NULL,},
}; };

View File

@ -22,39 +22,192 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 "Globals.h"
#include "Globals.h"
#include "gdsp_opcodes_helper.h" #include "gdsp_opcodes_helper.h"
// Extended opcodes do not exist on their own. These opcodes can only be
// attached to opcodes that allow extending (8 lower bits of opcode not used by
// opcode). Extended opcodes do not modify program counter $pc register.
namespace DSPInterpreter
{
namespace Ext
{
// DR $arR
// xxxx xxxx 0000 01rr
// Decrement addressing register $arR.
void dr(const UDSPInstruction& opc) {
u8 reg = opc.hex & 0x3;
g_dsp.r[reg]--;
}
// IR $arR
// xxxx xxxx 0000 10rr
// Increment addressing register $arR.
void ir(const UDSPInstruction& opc) {
u8 reg = opc.hex & 0x3;
g_dsp.r[reg]++;
}
// NR $arR
// xxxx xxxx 0000 11rr
// Add corresponding indexing register $ixR to addressing register $arR.
void nr(const UDSPInstruction& opc) {
u8 reg = opc.hex & 0x3;
g_dsp.r[reg] += g_dsp.r[reg + DSP_REG_IX0];
}
// MV $axD, $acS.l
// xxxx xxxx 0001 ddss
// Move value of $acS.l to the $axD.l.
void mv(const UDSPInstruction& opc)
{
u8 sreg = opc.hex & 0x3;
u8 dreg = ((opc.hex >> 2) & 0x3);
g_dsp.r[dreg + DSP_REG_AXL0] = g_dsp.r[sreg + DSP_REG_ACC0];
}
// S @$D, $acD.l
// xxxx xxxx 001s s0dd
// Store value of $(acS.l) in the memory pointed by register $D.
// Post increment register $D.
void s(const UDSPInstruction& opc)
{
u8 dreg = opc.hex & 0x3;
u8 sreg = ((opc.hex >> 3) & 0x3) + DSP_REG_ACC0;
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
g_dsp.r[dreg]++;
}
// SN @$D, $acD.l
// xxxx xxxx 001s s1dd
// Store value of register $acS in the memory pointed by register $D.
// Add indexing register $ixD to register $D.
void sn(const UDSPInstruction& opc)
{
u8 dreg = opc.hex & 0x3;
u8 sreg = ((opc.hex >> 3) & 0x3) + DSP_REG_ACC0;
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
g_dsp.r[dreg] += g_dsp.r[dreg + DSP_REG_IX0];
}
// L axD.l, @$S
// xxxx xxxx 01dd d0ss
// Load $axD with value from memory pointed by register $S.
// Post increment register $S.
void l(const UDSPInstruction& opc)
{
u8 sreg = opc.hex & 0x3;
u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0;
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg] = val;
g_dsp.r[sreg]++;
}
// LN axD.l, @$S
// xxxx xxxx 01dd d0ss
// Load $axD with value from memory pointed by register $S.
// Add indexing register register $ixS to register $S.
void ln(const UDSPInstruction& opc)
{
u8 sreg = opc.hex & 0x3;
u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0;
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg] = val;
g_dsp.r[sreg] += g_dsp.r[sreg + DSP_REG_IX0];
}
// Not in duddie's doc
void ld(const UDSPInstruction& opc)
{
u8 dreg1 = (((opc.hex >> 5) & 0x1) << 1) + DSP_REG_AXL0;
u8 dreg2 = (((opc.hex >> 4) & 0x1) << 1) + DSP_REG_AXL1;
u8 sreg = opc.hex & 0x3;
g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[DSP_REG_AR3]);
g_dsp.r[sreg]++;
g_dsp.r[DSP_REG_AR3]++;
}
// Not in duddie's doc
void ldn(const UDSPInstruction& opc)
{
u8 dreg1 = (((opc.hex >> 5) & 0x1) << 1) + DSP_REG_AXL0;
u8 dreg2 = (((opc.hex >> 4) & 0x1) << 1) + DSP_REG_AXL1;
u8 sreg = opc.hex & 0x3;
g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[DSP_REG_AR3]);
g_dsp.r[sreg] += g_dsp.r[sreg + DSP_REG_IX0];
g_dsp.r[DSP_REG_AR3]++;
}
// Not in duddie's doc
void ldm(const UDSPInstruction& opc)
{
u8 dreg1 = (((opc.hex >> 5) & 0x1) << 1) + DSP_REG_AXL0;
u8 dreg2 = (((opc.hex >> 4) & 0x1) << 1) + DSP_REG_AXL1;
u8 sreg = opc.hex & 0x3;
g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[DSP_REG_AR3]);
g_dsp.r[sreg]++;
g_dsp.r[DSP_REG_AR3] += g_dsp.r[DSP_REG_IX3];
}
// Not in duddie's doc
void ldnm(const UDSPInstruction& opc)
{
u8 dreg1 = (((opc.hex >> 5) & 0x1) << 1) + DSP_REG_AXL0;
u8 dreg2 = (((opc.hex >> 4) & 0x1) << 1) + DSP_REG_AXL1;
u8 sreg = opc.hex & 0x3;
g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[DSP_REG_AR3]);
g_dsp.r[sreg] += g_dsp.r[sreg + DSP_REG_IX0];
g_dsp.r[DSP_REG_AR3] += g_dsp.r[DSP_REG_IX3];
}
} // end namespace ext
} // end namespace DSPInterpeter
//
void dsp_op_ext_r_epi(const UDSPInstruction& opc) void dsp_op_ext_r_epi(const UDSPInstruction& opc)
{ {
u8 op = (opc.hex >> 2) & 0x3; u8 op = (opc.hex >> 2) & 0x3;
u8 reg = opc.hex & 0x3; u8 reg = opc.hex & 0x3;
switch (op) switch (op) {
{ case 0x00: //
case 0x00: ERROR_LOG(DSPLLE, "dsp_op_ext_r_epi");
ERROR_LOG(DSPLLE, "dsp_op_ext_r_epi"); break;
break;
case 0x01: case 0x01: // DR
g_dsp.r[reg]--; g_dsp.r[reg]--;
break; break;
case 0x02: case 0x02: // IR
g_dsp.r[reg]++; g_dsp.r[reg]++;
break; break;
case 0x03: case 0x03: // NR
g_dsp.r[reg] += g_dsp.r[reg + 4]; g_dsp.r[reg] += g_dsp.r[reg + 4];
break; break;
} }
} }
@ -75,13 +228,13 @@ void dsp_op_ext_s(const UDSPInstruction& opc)
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]); dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
if (opc.hex & 0x04) if (opc.hex & 0x04) // SN
{ {
g_dsp.r[dreg] += g_dsp.r[dreg + 4]; g_dsp.r[dreg] += g_dsp.r[dreg + 4];
} }
else else
{ {
g_dsp.r[dreg]++; g_dsp.r[dreg]++; // S
} }
} }
@ -94,13 +247,13 @@ void dsp_op_ext_l(const UDSPInstruction& opc)
u16 val = dsp_dmem_read(g_dsp.r[sreg]); u16 val = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg] = val; g_dsp.r[dreg] = val;
if (opc.hex & 0x04) if (opc.hex & 0x04) // LN/LSMN
{ {
g_dsp.r[sreg] += g_dsp.r[sreg + 4]; g_dsp.r[sreg] += g_dsp.r[sreg + 4];
} }
else else
{ {
g_dsp.r[sreg]++; g_dsp.r[sreg]++; // LS
} }
} }
@ -110,11 +263,11 @@ void dsp_op_ext_ls_pro(const UDSPInstruction& opc)
u8 areg = (opc.hex & 0x1) + 0x1e; u8 areg = (opc.hex & 0x1) + 0x1e;
dsp_dmem_write(g_dsp.r[0x03], g_dsp.r[areg]); dsp_dmem_write(g_dsp.r[0x03], g_dsp.r[areg]);
if (opc.hex & 0x8) if (opc.hex & 0x8) // LSM/LSMN
{ {
g_dsp.r[0x03] += g_dsp.r[0x07]; g_dsp.r[0x03] += g_dsp.r[0x07];
} }
else else // LS
{ {
g_dsp.r[0x03]++; g_dsp.r[0x03]++;
} }
@ -127,11 +280,11 @@ void dsp_op_ext_ls_epi(const UDSPInstruction& opc)
u16 val = dsp_dmem_read(g_dsp.r[0x00]); u16 val = dsp_dmem_read(g_dsp.r[0x00]);
dsp_op_write_reg(dreg, val); dsp_op_write_reg(dreg, val);
if (opc.hex & 0x4) if (opc.hex & 0x4) // LSN/LSMN
{ {
g_dsp.r[0x00] += g_dsp.r[0x04]; g_dsp.r[0x00] += g_dsp.r[0x04];
} }
else else // LS
{ {
g_dsp.r[0x00]++; g_dsp.r[0x00]++;
} }
@ -143,11 +296,11 @@ void dsp_op_ext_sl_pro(const UDSPInstruction& opc)
u8 areg = (opc.hex & 0x1) + 0x1e; u8 areg = (opc.hex & 0x1) + 0x1e;
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
if (opc.hex & 0x4) if (opc.hex & 0x4) // SLN/SLNM
{ {
g_dsp.r[0x00] += g_dsp.r[0x04]; g_dsp.r[0x00] += g_dsp.r[0x04];
} }
else else // SL
{ {
g_dsp.r[0x00]++; g_dsp.r[0x00]++;
} }
@ -160,11 +313,11 @@ void dsp_op_ext_sl_epi(const UDSPInstruction& opc)
u16 val = dsp_dmem_read(g_dsp.r[0x03]); u16 val = dsp_dmem_read(g_dsp.r[0x03]);
dsp_op_write_reg(dreg, val); dsp_op_write_reg(dreg, val);
if (opc.hex & 0x8) if (opc.hex & 0x8) // SLM/SLMN
{ {
g_dsp.r[0x03] += g_dsp.r[0x07]; g_dsp.r[0x03] += g_dsp.r[0x07];
} }
else else // SL
{ {
g_dsp.r[0x03]++; g_dsp.r[0x03]++;
} }
@ -179,7 +332,7 @@ void dsp_op_ext_ld(const UDSPInstruction& opc)
g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]); g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[0x03]); g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[0x03]);
if (opc.hex & 0x04) if (opc.hex & 0x04) // N
{ {
g_dsp.r[sreg] += g_dsp.r[sreg + 0x04]; g_dsp.r[sreg] += g_dsp.r[sreg + 0x04];
} }
@ -188,7 +341,7 @@ void dsp_op_ext_ld(const UDSPInstruction& opc)
g_dsp.r[sreg]++; g_dsp.r[sreg]++;
} }
if (opc.hex & 0x08) if (opc.hex & 0x08) // M
{ {
g_dsp.r[0x03] += g_dsp.r[0x07]; g_dsp.r[0x03] += g_dsp.r[0x07];
} }
@ -263,21 +416,22 @@ void dsp_op_ext_ops_epi(const UDSPInstruction& opc)
switch ((opc.hex >> 4) & 0xf) switch ((opc.hex >> 4) & 0xf)
{ {
case 0x08: case 0x08:
case 0x09: case 0x09:
case 0x0a: case 0x0a:
case 0x0b: case 0x0b:
if (opc.hex & 0x2) if (opc.hex & 0x2)
{ {
dsp_op_ext_sl_epi(opc.hex); dsp_op_ext_sl_epi(opc.hex);
} }
else else
{ {
dsp_op_ext_ls_epi(opc.hex); dsp_op_ext_ls_epi(opc.hex);
} }
break;
return; return;
} }
} }

View File

@ -37,5 +37,37 @@
void dsp_op_ext_ops_pro(const UDSPInstruction& opc); // run any prologs void dsp_op_ext_ops_pro(const UDSPInstruction& opc); // run any prologs
void dsp_op_ext_ops_epi(const UDSPInstruction& opc); // run any epilogs void dsp_op_ext_ops_epi(const UDSPInstruction& opc); // run any epilogs
namespace DSPInterpreter
{
namespace Ext
{
void l(const UDSPInstruction& opc);
void ln(const UDSPInstruction& opc);
void ls(const UDSPInstruction& opc);
void lsn(const UDSPInstruction& opc);
void lsm(const UDSPInstruction& opc);
void lsnm(const UDSPInstruction& opc);
void sl(const UDSPInstruction& opc);
void sln(const UDSPInstruction& opc);
void slm(const UDSPInstruction& opc);
void slnm(const UDSPInstruction& opc);
void s(const UDSPInstruction& opc);
void sn(const UDSPInstruction& opc);
void ldx(const UDSPInstruction& opc);
void ldxn(const UDSPInstruction& opc);
void ldxm(const UDSPInstruction& opc);
void ldxnm(const UDSPInstruction& opc);
void ld(const UDSPInstruction& opc);
void ldn(const UDSPInstruction& opc);
void ldm(const UDSPInstruction& opc);
void ldnm(const UDSPInstruction& opc);
void mv(const UDSPInstruction& opc);
void dr(const UDSPInstruction& opc);
void ir(const UDSPInstruction& opc);
void nr(const UDSPInstruction& opc);
} // end namespace Ext
} // end namespace DSPinterpeter
#endif #endif