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:
parent
c1fe6def46
commit
4fa154bb56
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue