diff --git a/Source/Core/DSPCore/Src/DSPInterpreter.cpp b/Source/Core/DSPCore/Src/DSPInterpreter.cpp index a5ec0505c4..2886f09ccb 100644 --- a/Source/Core/DSPCore/Src/DSPInterpreter.cpp +++ b/Source/Core/DSPCore/Src/DSPInterpreter.cpp @@ -1452,14 +1452,13 @@ void srbith(const UDSPInstruction& opc) g_dsp.r[DSP_REG_SR] |= SR_MUL_MODIFY; break; - // 15-bit precision? clamping? no idea :( - // CLR15 seems to be the default. - // It seems to come around mul operation, + // If set, treat multiplicands as unsigned 16-bit ints. + // If clear, treat them as signed. case 0xc: // CLR15 - g_dsp.r[DSP_REG_SR] &= ~SR_TOP_BIT_UNK; + g_dsp.r[DSP_REG_SR] &= ~SR_MUL_UNSIGNED; break; case 0xd: // SET15 - g_dsp.r[DSP_REG_SR] |= SR_TOP_BIT_UNK; + g_dsp.r[DSP_REG_SR] |= SR_MUL_UNSIGNED; break; // Automatic 40-bit sign extension when loading ACx.M. diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index 21acdfddaf..058f50671a 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -154,10 +154,10 @@ const DSPOPCTemplate opcodes[] = {"SBSET", 0x1300, 0xfff8, DSPInterpreter::sbset, nop, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}}, NULL, NULL}, // actually, given the masks these should probably be 0x3f. need investigation. - {"LSL", 0x1400, 0xfec0, DSPInterpreter::lsl, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, - {"LSR", 0x1440, 0xfec0, DSPInterpreter::lsr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, - {"ASL", 0x1480, 0xfec0, DSPInterpreter::asl, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, - {"ASR", 0x14c0, 0xfec0, DSPInterpreter::asr, nop, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, + {"LSL", 0x1400, 0xfec0, DSPInterpreter::lsl, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, + {"LSR", 0x1440, 0xfec0, DSPInterpreter::lsr, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, + {"ASL", 0x1480, 0xfec0, DSPInterpreter::asl, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, + {"ASR", 0x14c0, 0xfec0, DSPInterpreter::asr, nop, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, NULL, NULL}, {"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, {"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, NULL, NULL}, diff --git a/Source/Core/DSPCore/Src/gdsp_registers.h b/Source/Core/DSPCore/Src/gdsp_registers.h index 8b60e02183..f1c11b5c8e 100644 --- a/Source/Core/DSPCore/Src/gdsp_registers.h +++ b/Source/Core/DSPCore/Src/gdsp_registers.h @@ -98,18 +98,18 @@ #define CR_EXTERNAL_INT 0x0002 // SR bits -#define SR_CARRY 0x0001 -#define SR_2 0x0002 // overflow??? -#define SR_ARITH_ZERO 0x0004 -#define SR_SIGN 0x0008 -#define SR_10 0x0010 // seem to be set by tst -#define SR_TOP2BITS 0x0020 // this is an odd one. (set by tst) -#define SR_LOGIC_ZERO 0x0040 -#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so. -#define SR_800 0x0800 // Appears in zelda -#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2) -#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums. -#define SR_TOP_BIT_UNK 0x8000 // 1 = normal. 0 = x2 (CLR15, SET15) ???????? +#define SR_CARRY 0x0001 +#define SR_2 0x0002 // overflow??? +#define SR_ARITH_ZERO 0x0004 +#define SR_SIGN 0x0008 +#define SR_10 0x0010 // seem to be set by tst +#define SR_TOP2BITS 0x0020 // this is an odd one. (set by tst) +#define SR_LOGIC_ZERO 0x0040 +#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so. +#define SR_800 0x0800 // Appears in zelda - what is it? where in the zelda ucode? +#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2) +#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums. +#define SR_MUL_UNSIGNED 0x8000 // 0 = normal. 1 = unsigned (CLR15, SET15) If set, treats operands as unsigned. Tested with mulx only so far. void dsp_reg_store_stack(u8 stack_reg, u16 val); u16 dsp_reg_load_stack(u8 stack_reg); diff --git a/Source/DSPSpy/main_spy.cpp b/Source/DSPSpy/main_spy.cpp index da81d42f67..75bdc3e467 100644 --- a/Source/DSPSpy/main_spy.cpp +++ b/Source/DSPSpy/main_spy.cpp @@ -139,13 +139,20 @@ void print_reg_block(int x, int y, int sel, const u16 *regs, const u16 *compare_ for (int i = 0; i < 8 ; i++) { // Do not even display the loop stack registers. + const int reg = j * 8 + i; + ds_set_colour(sel == reg ? COLOR_YELLOW : COLOR_GREEN, COLOR_BLACK); + ds_printf(x + j * 8, i + y, "%02x ", reg); if (j != 1 || i < 4) { - const int reg = j * 8 + i; - ds_set_colour(sel == reg ? COLOR_YELLOW : COLOR_GREEN, COLOR_BLACK); - ds_printf(x + j * 8, i + y, "%02x ", reg); - ds_set_colour(regs_equal(reg, regs[reg], compare_regs[reg]) ? COLOR_WHITE : COLOR_RED, COLOR_BLACK); - ds_printf(x + 3 + j * 8, i + y, "%04x", regs[reg]); + u32 color1 = regs_equal(reg, regs[reg], compare_regs[reg]) ? COLOR_WHITE : COLOR_RED; + for (int k = 0; k < 4; k++) + { + if (sel == reg && k == small_cursor_x && ui_mode == UIM_EDIT_REG) + ds_set_colour(COLOR_BLACK, color1); + else + ds_set_colour(color1, COLOR_BLACK); + ds_printf(x + 3 + j * 8 + k, i + y, "%01x", (regs[reg] >> ((3 - k) * 4)) & 0xf); + } } } } @@ -162,8 +169,8 @@ void print_regs(int _step, int _dsp_steps) const u16 *regs = _step == 0 ? dspreg_in : dspreg_out[_step - 1]; const u16 *regs2 = dspreg_out[_step]; - print_reg_block(0, 2, cursor_reg, regs, regs2); - print_reg_block(33, 2, cursor_reg, regs2, regs); + print_reg_block(0, 2, _step == 0 ? cursor_reg : -1, regs, regs2); + print_reg_block(33, 2, -1, regs2, regs); ds_set_colour(COLOR_WHITE, COLOR_BLACK); ds_printf(33, 17, "%i / %i ", _step + 1, _dsp_steps); @@ -214,7 +221,7 @@ void ui_pad_sel(void) if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A) { ui_mode = UIM_EDIT_REG; - reg_value = &dspreg_in[cursor_reg * 8]; + reg_value = &dspreg_in[cursor_reg]; } }