DSP: Further disasm improvements. Make a few mul ops (only two of which I have seen, both in Zelda) behave like Duddie's doc says they should.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2941 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
0f26228ef2
commit
5166251b2c
|
@ -589,14 +589,21 @@ void mulc(const UDSPInstruction& opc)
|
|||
Update_SR_Register64(prod);
|
||||
}
|
||||
|
||||
|
||||
// MULCMVZ
|
||||
// 110s t01r xxxx xxxx
|
||||
// (fixed possible bug in duddie's description, s->t)
|
||||
// Multiply mid part of accumulator register $acS.m by high part $axT.h of
|
||||
// secondary accumulator $axT (treat them both as signed). Move product
|
||||
// register before multiplication to accumulator $acR, set low part of
|
||||
// accumulator $acR.l to zero.
|
||||
void mulcmvz(const UDSPInstruction& opc)
|
||||
{
|
||||
s64 TempProd = dsp_get_long_prod();
|
||||
|
||||
// update prod
|
||||
u8 sreg = (opc.hex >> 12) & 0x1;
|
||||
s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_acc_h(sreg) * GetMultiplyModifier();
|
||||
u8 treg = (opc.hex >> 11) & 0x1;
|
||||
s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_ax_h(treg) * GetMultiplyModifier();
|
||||
dsp_set_long_prod(Prod);
|
||||
|
||||
// update acc
|
||||
|
@ -607,13 +614,19 @@ void mulcmvz(const UDSPInstruction& opc)
|
|||
Update_SR_Register64(acc);
|
||||
}
|
||||
|
||||
// MULCMV
|
||||
// 110s t11r xxxx xxxx
|
||||
// Multiply mid part of accumulator register $acS.m by high part $axS.h of
|
||||
// secondary accumulator $axT (treat them both as signed). Move product
|
||||
// register before multiplication to accumulator $acR.
|
||||
void mulcmv(const UDSPInstruction& opc)
|
||||
{
|
||||
s64 TempProd = dsp_get_long_prod();
|
||||
|
||||
// update prod
|
||||
u8 sreg = (opc.hex >> 12) & 0x1;
|
||||
s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_acc_h(sreg) * GetMultiplyModifier();
|
||||
u8 treg = (opc.hex >> 11) & 0x1;
|
||||
s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_ax_h(sreg) * GetMultiplyModifier();
|
||||
dsp_set_long_prod(Prod);
|
||||
|
||||
// update acc
|
||||
|
@ -623,6 +636,8 @@ void mulcmv(const UDSPInstruction& opc)
|
|||
Update_SR_Register64(TempProd);
|
||||
}
|
||||
|
||||
// CMPAR
|
||||
// Not described by Duddie's doc - at least not as a separate instruction.
|
||||
void cmpar(const UDSPInstruction& opc)
|
||||
{
|
||||
u8 rreg = ((opc.hex >> 12) & 0x1) + 0x1a;
|
||||
|
@ -637,6 +652,9 @@ void cmpar(const UDSPInstruction& opc)
|
|||
Update_SR_Register64(ar - rr);
|
||||
}
|
||||
|
||||
// CMP
|
||||
// 1000 0010 xxxx xxxx
|
||||
// Compares accumulator $ac0 with accumulator $ac1.
|
||||
void cmp(const UDSPInstruction& opc)
|
||||
{
|
||||
s64 acc0 = dsp_get_long_acc(0);
|
||||
|
@ -645,6 +663,9 @@ void cmp(const UDSPInstruction& opc)
|
|||
Update_SR_Register64(acc0 - acc1);
|
||||
}
|
||||
|
||||
// TST
|
||||
// 1011 r001 xxxx xxxx
|
||||
// Test accumulator %acR.
|
||||
void tst(const UDSPInstruction& opc)
|
||||
{
|
||||
tsta((opc.hex >> 11) & 0x1);
|
||||
|
@ -679,18 +700,24 @@ void addarn(const UDSPInstruction& opc)
|
|||
g_dsp.r[dreg] += (s16)g_dsp.r[DSP_REG_IX0 + sreg];
|
||||
}
|
||||
|
||||
// MULCAC $acS.m, $axT.h, $acR
|
||||
// 110s t10r xxxx xxxx
|
||||
// Multiply mid part of accumulator register $acS.m by high part $axS.h of
|
||||
// secondary accumulator $axS (treat them both as signed). Add product
|
||||
// register before multiplication to accumulator $acR.
|
||||
void mulcac(const UDSPInstruction& opc)
|
||||
{
|
||||
s64 TempProd = dsp_get_long_prod();
|
||||
|
||||
// update prod
|
||||
u8 sreg = (opc.hex >> 12) & 0x1;
|
||||
s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_acc_h(sreg) * GetMultiplyModifier();
|
||||
u8 treg = (opc.hex >> 11) & 0x1;
|
||||
s64 Prod = (s64)dsp_get_acc_m(sreg) * (s64)dsp_get_ax_h(treg) * GetMultiplyModifier();
|
||||
dsp_set_long_prod(Prod);
|
||||
|
||||
// update acc
|
||||
u8 rreg = (opc.hex >> 8) & 0x1;
|
||||
s64 acc = TempProd + g_dsp.r[rreg];
|
||||
s64 acc = TempProd + dsp_get_long_acc(rreg);
|
||||
dsp_set_long_acc(rreg, acc);
|
||||
|
||||
Update_SR_Register64(acc);
|
||||
|
|
|
@ -275,17 +275,15 @@ DSPOPCTemplate opcodes[] =
|
|||
{"MULXAC", 0xa400, 0xe6ff, DSPInterpreter::mulxac, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULXMV", 0xa600, 0xe6ff, DSPInterpreter::mulxmv, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
|
||||
|
||||
{"MUL", 0x9000, 0xf7ff, DSPInterpreter::mul, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULMVZ", 0x9200, 0xf6ff, DSPInterpreter::mulmvz, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULAC", 0x9400, 0xf6ff, DSPInterpreter::mulac, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULMV", 0x9600, 0xf6ff, DSPInterpreter::mulmv, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
|
||||
|
||||
{"MULC", 0xc000, 0xe7ff, DSPInterpreter::mulc, nop, 1 | P_EXT, 2, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULCMVZ", 0xc200, 0xe6ff, DSPInterpreter::mulcmvz, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULCAC", 0xc400, 0xe6ff, DSPInterpreter::mulcac, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULCMV", 0xc600, 0xe6ff, DSPInterpreter::mulcmv, nop, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULC", 0xc000, 0xe7ff, DSPInterpreter::mulc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULCMVZ", 0xc200, 0xe6ff, DSPInterpreter::mulcmvz, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULCAC", 0xc400, 0xe6ff, DSPInterpreter::mulcac, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"MULCMV", 0xc600, 0xe6ff, DSPInterpreter::mulcmv, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
|
||||
{"ADDR", 0x4000, 0xf8ff, DSPInterpreter::addr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
{"ADDAX", 0x4800, 0xfcff, DSPInterpreter::addax, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||
|
|
|
@ -61,6 +61,12 @@ bool DisasmUCodeDump(u32 crc)
|
|||
if (t != NULL)
|
||||
{
|
||||
gd_globals_t gdg;
|
||||
memset(&gdg, 0, sizeof(gdg));
|
||||
gdg.show_hex = true;
|
||||
gdg.show_pc = true;
|
||||
gdg.ext_separator = '\t';
|
||||
gdg.decode_names = true;
|
||||
gdg.decode_registers = true;
|
||||
gd_dis_file(&gdg, binFile, t);
|
||||
fclose(t);
|
||||
return true;
|
||||
|
@ -88,7 +94,7 @@ u32 GenerateCRC(const unsigned char* _pBuffer, int _pLength)
|
|||
CRC = (CRC >> 8) ^ Temp;
|
||||
}
|
||||
|
||||
return(CRC ^ 0xFFFFFFFF);
|
||||
return CRC ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// TODO make this useful :p
|
||||
|
|
|
@ -96,14 +96,14 @@ const pdlabel_t pdlabels[] =
|
|||
|
||||
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",},
|
||||
{0x00, "AR0", "Register 00",},
|
||||
{0x01, "AR1", "Register 01",},
|
||||
{0x02, "AR2", "Register 02",},
|
||||
{0x03, "AR3", "Register 03",},
|
||||
{0x04, "IX0", "Register 04",},
|
||||
{0x05, "IX1", "Register 05",},
|
||||
{0x06, "IX2", "Register 06",},
|
||||
{0x07, "IX3", "Register 07",},
|
||||
{0x08, "R08", "Register 08",},
|
||||
{0x09, "R09", "Register 09",},
|
||||
{0x0a, "R10", "Register 10",},
|
||||
|
@ -112,8 +112,8 @@ pdlabel_t regnames[] =
|
|||
{0x0d, "ST1", "Data stack",},
|
||||
{0x0e, "ST2", "Loop addr stack",},
|
||||
{0x0f, "ST3", "Loop counter",},
|
||||
{0x00, "ACH0", "Accu High 0",},
|
||||
{0x11, "ACH1", "Accu High 1",},
|
||||
{0x00, "AC0.H", "Accu High 0",},
|
||||
{0x11, "AC1.H", "Accu High 1",},
|
||||
{0x12, "CR", "Config Register",},
|
||||
{0x13, "SR", "Special Register",},
|
||||
{0x14, "PROD.L", "Prod L",},
|
||||
|
@ -250,15 +250,6 @@ char* gd_dis_params(gd_globals_t* gdg, const DSPOPCTemplate* opc, u16 op1, u16 o
|
|||
return strbuf;
|
||||
}
|
||||
|
||||
|
||||
gd_globals_t* gd_init()
|
||||
{
|
||||
gd_globals_t* gdg = (gd_globals_t*)malloc(sizeof(gd_globals_t));
|
||||
memset(gdg, 0, sizeof(gd_globals_t));
|
||||
return(gdg);
|
||||
}
|
||||
|
||||
|
||||
u16 gd_dis_get_opcode_size(gd_globals_t* gdg)
|
||||
{
|
||||
DSPOPCTemplate* opc = 0;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "Common.h"
|
||||
|
||||
typedef struct gd_globals_t
|
||||
struct gd_globals_t
|
||||
{
|
||||
bool print_tabs;
|
||||
bool show_hex;
|
||||
|
@ -40,7 +40,7 @@ typedef struct gd_globals_t
|
|||
char* buffer;
|
||||
u16 buffer_size;
|
||||
char ext_separator;
|
||||
} gd_globals_t;
|
||||
};
|
||||
|
||||
|
||||
char* gd_dis_opcode(gd_globals_t* gdg);
|
||||
|
|
|
@ -371,4 +371,3 @@ void gdsp_stop()
|
|||
{
|
||||
gdsp_running = false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue