diff --git a/hw/xbox/dsp/dsp_cpu.c b/hw/xbox/dsp/dsp_cpu.c index 474e38aa04..24eaeb8d6b 100644 --- a/hw/xbox/dsp/dsp_cpu.c +++ b/hw/xbox/dsp/dsp_cpu.c @@ -228,7 +228,7 @@ static const OpcodeEntry nonparallel_opcodes[] = { { "00001100000111111111gggd", "cmpu S1, S2", dis_cmpu, emu_cmpu }, { "000000000000001000000000", "debug", NULL, NULL }, { "00000000000000110000CCCC", "debugcc", NULL, NULL }, - { "00000000000000000000101d", "dec D", NULL, NULL, /*dis_dec, emu_dec*/ }, + { "00000000000000000000101d", "dec D", NULL /*dis_dec*/, emu_dec }, { "000000011000000001JJd000", "div S, D", dis_div, emu_div }, { "000000010010010s1sdkQQQQ", "dmac S1, S2, D", NULL, NULL }, { "0000011001MMMRRR0S000000", "do [X or Y]:ea, expr", dis_do_ea, emu_do_ea, match_MMMRRR }, diff --git a/hw/xbox/dsp/dsp_emu.inl b/hw/xbox/dsp/dsp_emu.inl index 8da806048b..b18259469d 100644 --- a/hw/xbox/dsp/dsp_emu.inl +++ b/hw/xbox/dsp/dsp_emu.inl @@ -6605,6 +6605,44 @@ static void emu_cmpu(dsp_core_t* dsp) dsp->registers[DSP_REG_SR] |= (dest[0]>>4) & 0x8; } +static void emu_dec(dsp_core_t* dsp) +{ + uint32_t destreg, source[3], dest[3]; + uint16_t newsr; + + destreg = DSP_REG_A + (dsp->cur_inst & 1); + if (destreg == DSP_REG_A) { + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + } else { + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + } + + source[2] = 1; + source[1] = 0; + source[0] = 0; + + newsr = dsp_sub56(source, dest); + + if (destreg == DSP_REG_A) { + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + } else { + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + } + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + static void emu_div(dsp_core_t* dsp) { uint32_t srcreg, destreg, source[3], dest[3];