From f4bca6e21c86543d189694c4d46f2453fdc4addc Mon Sep 17 00:00:00 2001 From: Marko Pusljar Date: Tue, 8 Dec 2009 22:44:11 +0000 Subject: [PATCH] DSPLLE stuff (2 new opcodes) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4660 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/DSP.cpp | 12 ++- Source/Core/DSPCore/Src/DSPInterpreter.h | 2 + Source/Core/DSPCore/Src/DSPTables.cpp | 21 ++-- Source/Core/DSPCore/Src/DspIntArithmetic.cpp | 103 ++++++++++++++----- Source/Core/DSPCore/Src/disassemble.cpp | 2 +- 5 files changed, 99 insertions(+), 41 deletions(-) diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 8d23a5b841..6ce570e2d6 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -417,10 +417,16 @@ void Write16(const u16 _Value, const u32 _Address) break; case AUDIO_DMA_CONTROL_LEN: // called by AIStartDMA() + { + UAudioDMAControl old_control = g_audioDMA.AudioDMAControl; g_audioDMA.AudioDMAControl.Hex = _Value; - g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; - g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; - INFO_LOG(DSPINTERFACE, "AID DMA started - source address %08x, length %i blocks", g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks); + if (!old_control.Enabled && g_audioDMA.AudioDMAControl.Enabled) //needed for some AX games under LLE (Crazy Taxi) + { + g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; + g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; + INFO_LOG(DSPINTERFACE, "AID DMA started - source address %08x, length %i blocks", g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks); + } + } break; case AUDIO_DMA_BYTES_LEFT: diff --git a/Source/Core/DSPCore/Src/DSPInterpreter.h b/Source/Core/DSPCore/Src/DSPInterpreter.h index ce54a3d09e..37d464ea4d 100644 --- a/Source/Core/DSPCore/Src/DSPInterpreter.h +++ b/Source/Core/DSPCore/Src/DSPInterpreter.h @@ -92,7 +92,9 @@ void orc(const UDSPInstruction& opc); void xorc(const UDSPInstruction& opc); void notc(const UDSPInstruction& opc); void lsrnrx(const UDSPInstruction& opc); +void asrnrx(const UDSPInstruction& opc); void lsrnr(const UDSPInstruction& opc); +void asrnr(const UDSPInstruction& opc); void orf(const UDSPInstruction& opc); void add(const UDSPInstruction& opc); void addp(const UDSPInstruction& opc); diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index f4d62794e1..e23cba3765 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -182,16 +182,17 @@ const DSPOPCTemplate opcodes[] = // extended opcodes, note size of opcode will be set to 0 //3 - main opcode defined by 9 bits, extension defined by last 7 bits!! - {"XORR", 0x3000, 0xfc80, DSPInterpreter::xorr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true}, - {"ANDR", 0x3400, 0xfc80, DSPInterpreter::andr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true}, - {"ORR", 0x3800, 0xfc80, DSPInterpreter::orr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true}, - {"ANDC", 0x3c00, 0xfe80, DSPInterpreter::andc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true}, - {"ORC", 0x3e00, 0xfe80, DSPInterpreter::orc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true}, - {"XORC", 0x3080, 0xfe80, DSPInterpreter::xorc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true}, //new - {"NOT", 0x3280, 0xfe80, DSPInterpreter::notc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true}, //new - {"LSRNRX", 0x3480, 0xfc80, DSPInterpreter::lsrnrx, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true}, //new - {"LSRNRX", 0x3880, 0xfc80, DSPInterpreter::lsrnrx, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true}, //new - {"LSRNR", 0x3c80, 0xfc80, DSPInterpreter::lsrnr, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true}, // discovered by luigi! + {"XORR", 0x3000, 0xfc80, DSPInterpreter::xorr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100},{P_REG1A, 1, 0, 9, 0x0200}}, true}, + {"ANDR", 0x3400, 0xfc80, DSPInterpreter::andr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100},{P_REG1A, 1, 0, 9, 0x0200}}, true}, + {"ORR", 0x3800, 0xfc80, DSPInterpreter::orr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100},{P_REG1A, 1, 0, 9, 0x0200}}, true}, + {"ANDC", 0x3c00, 0xfe80, DSPInterpreter::andc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100},{P_ACCM_D, 1, 0, 8, 0x0100}}, true}, + {"ORC", 0x3e00, 0xfe80, DSPInterpreter::orc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100},{P_ACCM_D, 1, 0, 8, 0x0100}}, true}, + {"XORC", 0x3080, 0xfe80, DSPInterpreter::xorc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100},{P_ACCM_D, 1, 0, 8, 0x0100}}, true}, + {"NOT", 0x3280, 0xfe80, DSPInterpreter::notc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true}, + {"LSRNRX", 0x3480, 0xfc80, DSPInterpreter::lsrnrx, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100},{P_REG1A, 1, 0, 9, 0x0200}}, true}, + {"ASRNRX", 0x3880, 0xfc80, DSPInterpreter::asrnrx, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100},{P_REG1A, 1, 0, 9, 0x0200}}, true}, + {"LSRNR", 0x3c80, 0xfe80, DSPInterpreter::lsrnr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100},{P_ACCM_D, 1, 0, 8, 0x0100}}, true}, + {"ASRNR", 0x3e80, 0xfe80, DSPInterpreter::asrnr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100},{P_ACCM_D, 1, 0, 8, 0x0100}}, true}, //4 {"ADDR", 0x4000, 0xf800, DSPInterpreter::addr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, true}, diff --git a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp index 458e51d529..d83356fab8 100644 --- a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp +++ b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp @@ -615,6 +615,8 @@ void addi(const UDSPInstruction& opc) Update_SR_Register64(acc); } +// shifts + // LSL16 $acR // 1111 000r xxxx xxxx // Logically shifts left accumulator $acR by 16. @@ -771,40 +773,65 @@ void asrn(const UDSPInstruction& opc) // LSRNRX // 0011 01sd 1xxx xxxx -// 0011 10sd 1xxx xxxx -// Logically shifts right accumulator $ACC[D] by signed 16-bit value $AX[S].H -// Not described by Duddie's doc. +// Logically shifts left/right accumulator $ACC[D] by signed 16-bit value $AX[S].H // x = extension (7 bits!!) void lsrnrx(const UDSPInstruction& opc) { - u8 dreg = (opc.hex >> 8) & 0x1; //accD - u8 sreg = (opc.hex >> 9) & 0x1; //axhS - u64 acc = dsp_get_long_acc(dreg); - s16 shift = g_dsp.r[DSP_REG_AXH0 + sreg]; - acc &= 0x000000FFFFFFFFFFULL; - if (shift > 0) { - acc <<= shift; - } else if (shift < 0) { - acc >>= -shift; - } + u8 dreg = (opc.hex >> 8) & 0x1; + u8 sreg = (opc.hex >> 9) & 0x1; - zeroWriteBackLog(); - - dsp_set_long_acc(dreg, acc); - Update_SR_Register64(acc); + s16 shift = g_dsp.r[DSP_REG_AXH0 + sreg]; + u64 acc = dsp_get_long_acc(dreg); + acc &= 0x000000FFFFFFFFFFULL; + + if (shift > 0) { + acc <<= shift; + } else if (shift < 0) { + acc >>= -shift; + } + + zeroWriteBackLog(); + + dsp_set_long_acc(dreg, (s64)acc); + Update_SR_Register64((s64)acc); } -// LSRNR $acR -// 0011 11?d 1xxx xxxx -// Logically shifts right accumulator $ACC[D] by signed 16-bit value $AC[1-D].M -// Not described by Duddie's doc - at least not as a separate instruction. +// ASRNRX +// 0011 10sd 1xxx xxxx +// Arithmetically shifts left/right accumulator $ACC[D] by signed 16-bit value $AX[S].H +// x = extension (7 bits!!) +void asrnrx(const UDSPInstruction& opc) +{ + u8 dreg = (opc.hex >> 8) & 0x1; + u8 sreg = (opc.hex >> 9) & 0x1; + + s16 shift = g_dsp.r[DSP_REG_AXH0 + sreg]; + s64 acc = dsp_get_long_acc(dreg); + + if (shift > 0) { + acc <<= shift; + } else if (shift < 0) { + acc >>= -shift; + } + + zeroWriteBackLog(); + + dsp_set_long_acc(dreg, acc); + Update_SR_Register64(acc); +} + +// LSRNR $acD +// 0011 110d 1xxx xxxx +// Logically shifts left/right accumulator $ACC[D] by signed 16-bit value $AC[1-D].M // x = extension (7 bits!!) void lsrnr(const UDSPInstruction& opc) { - u8 D = (opc.hex >> 8) & 0x1; - s16 shift = dsp_get_acc_m(1-D); - u64 acc = dsp_get_long_acc(D); + u8 dreg = (opc.hex >> 8) & 0x1; + + s16 shift = dsp_get_acc_m(1 - dreg); + u64 acc = dsp_get_long_acc(dreg); acc &= 0x000000FFFFFFFFFFULL; + if (shift > 0) { acc <<= shift; } else if (shift < 0) { @@ -813,7 +840,30 @@ void lsrnr(const UDSPInstruction& opc) zeroWriteBackLog(); - dsp_set_long_acc(D, acc); + dsp_set_long_acc(dreg, (s64)acc); + Update_SR_Register64((s64)acc); +} + +// ASRNR $acD +// 0011 111d 1xxx xxxx +// Arithmeticaly shift left/right accumulator $ACC[D] by signed 16-bit value $AC[1-D].M +// x = extension (7 bits!!) +void asrnr(const UDSPInstruction& opc) +{ + u8 dreg = (opc.hex >> 8) & 0x1; + + s16 shift = dsp_get_acc_m(1 - dreg); + s64 acc = dsp_get_long_acc(dreg); + + if (shift > 0) { + acc <<= shift; + } else if (shift < 0) { + acc >>= -shift; + } + + zeroWriteBackLog(); + + dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); } @@ -835,7 +885,6 @@ void cmpar(const UDSPInstruction& opc) Update_SR_Register64(sr - rr); zeroWriteBackLog(); } - // CMP // 1000 0010 xxxx xxxx @@ -854,7 +903,7 @@ void cmp(const UDSPInstruction& opc) // Test accumulator %acR. void tst(const UDSPInstruction& opc) { - s8 reg = (opc.hex >> 11) & 0x1; + u8 reg = (opc.hex >> 11) & 0x1; s64 acc = dsp_get_long_acc(reg); Update_SR_Register64(acc); diff --git a/Source/Core/DSPCore/Src/disassemble.cpp b/Source/Core/DSPCore/Src/disassemble.cpp index 7019131a69..3081bbefcf 100644 --- a/Source/Core/DSPCore/Src/disassemble.cpp +++ b/Source/Core/DSPCore/Src/disassemble.cpp @@ -111,7 +111,7 @@ char *DSPDisassembler::DisParams(const DSPOPCTemplate& opc, u16 op1, u16 op2, ch if (type & P_REG) { // Check for _D parameter - if so flip. - if (type == P_ACC_D) // Used to be P_ACCM_D TODO verify + if ((type == P_ACC_D) || (type == P_ACCM_D)) // Used to be P_ACCM_D TODO verify val = (~val & 0x1) | ((type & P_REGS_MASK) >> 8); else val |= (type & P_REGS_MASK) >> 8;