diff --git a/src/devices/cpu/sharc/compute.hxx b/src/devices/cpu/sharc/compute.hxx index ddea8a2f265..278212a3f43 100644 --- a/src/devices/cpu/sharc/compute.hxx +++ b/src/devices/cpu/sharc/compute.hxx @@ -1272,7 +1272,45 @@ void adsp21062_device::compute_fmul_avg(int fm, int fxm, int fym, int fa, int fx r_mul.f = FREG(fxm) * FREG(fym); r_alu.f = (FREG(fxa) * FREG(fya))/((float) 2.0); - /* TODO: are flags right for this? */ + // TODO: are flags right for this? + if (m_core->mode1 & MODE1_TRUNCATE) + { + alu_i = (int32_t)(r_alu.f); + } + else + { + alu_i = (int32_t)(r_alu.f < 0 ? (r_alu.f - 0.5f) : (r_alu.f + 0.5f)); + } + + CLEAR_MULTIPLIER_FLAGS(); + SET_FLAG_MN(r_mul.r); + /* TODO: MV flag */ + /* TODO: MU flag */ + /* TODO: MI flag */ + + CLEAR_ALU_FLAGS(); + SET_FLAG_AN(alu_i); + // AZ + SET_FLAG_AZ(alu_i); + // AU + m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0; + // AI + m_core->astat |= (IS_FLOAT_NAN(REG(fxa))) ? AI : 0; + /* TODO: AV flag */ + + FREG(fm) = r_mul.f; + REG(fa) = alu_i; + m_core->astat |= AF; +} + +void adsp21062_device::compute_fmul_abs(int fm, int fxm, int fym, int fa, int fxa, int fya) +{ + int32_t alu_i; + SHARC_REG r_mul, r_alu; + r_mul.f = FREG(fxm) * FREG(fym); + r_alu.f = (float) fabs(FREG(fxa)); + + // TODO: are flags right for this? if (m_core->mode1 & MODE1_TRUNCATE) { alu_i = (int32_t)(r_alu.f); diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h index e183fb6a866..8699d6d3455 100644 --- a/src/devices/cpu/sharc/sharc.h +++ b/src/devices/cpu/sharc/sharc.h @@ -589,6 +589,7 @@ private: inline void compute_fmul_float_scaled(int fm, int fxm, int fym, int fa, int fxa, int fya); inline void compute_fmul_fix_scaled(int fm, int fxm, int fym, int fa, int fxa, int fya); inline void compute_fmul_avg(int fm, int fxm, int fym, int fa, int fxa, int fya); + inline void compute_fmul_abs(int fm, int fxm, int fym, int fa, int fxa, int fya); inline void compute_fmul_fmax(int fm, int fxm, int fym, int fa, int fxa, int fya); inline void compute_fmul_fmin(int fm, int fxm, int fym, int fa, int fxa, int fya); inline void compute_fmul_dual_fadd_fsub(int fm, int fxm, int fym, int fa, int fs, int fxa, int fya); diff --git a/src/devices/cpu/sharc/sharcops.hxx b/src/devices/cpu/sharc/sharcops.hxx index 16597aad5a5..9ebf017659c 100644 --- a/src/devices/cpu/sharc/sharcops.hxx +++ b/src/devices/cpu/sharc/sharcops.hxx @@ -739,12 +739,20 @@ void adsp21062_device::COMPUTE(uint32_t opcode) break; } - case 0x1c: /* TODO! fmul_avg */ + // TODO: verify this (last bronx) + case 0x1c: { compute_fmul_avg(fm, fxm, fym, fa, fxa, fya); break; } + // TODO: verify this (Gunblade NY Score Attack Remix mode) + case 0x1d: + { + compute_fmul_abs(fm, fxm, fym, fa, fxa, fya); + break; + } + case 0x1e: /* Fm = Fxm * Fym, Fa = MAX(Fxa, Fya) */ { compute_fmul_fmax(fm, fxm, fym, fa, fxa, fya);