diff --git a/src/emu/flags.rs b/src/emu/flags.rs index 463be84..90bf760 100644 --- a/src/emu/flags.rs +++ b/src/emu/flags.rs @@ -38,8 +38,12 @@ impl Flags { FlagOp::Eager => { self.res & 1 << CF_BIT != 0 }, FlagOp::DEC { cf } => { cf }, FlagOp::INC { cf } => { cf }, - FlagOp::ROL { dst, src, bits, .. } => { dst & (self.sign_mask >> ((src - 1) % bits as u16)) != 0 }, - FlagOp::ROR { dst, src, bits, .. } => { dst & (1 << ((src - 1) % bits as u16)) != 0 }, + FlagOp::ROL { dst, src, rot_mask, .. } => { + dst & (self.sign_mask >> ((src.wrapping_sub(1)) & rot_mask as u16)) != 0 + }, + FlagOp::ROR { dst, src, rot_mask, .. } => { + dst & (1 << ((src.wrapping_sub(1)) & rot_mask as u16)) != 0 + }, FlagOp::SAR { dst, src, sign_bit } => { match 1u16.checked_shl(src as u32 - 1) { Some(carrymask) => dst & carrymask != 0, @@ -126,8 +130,8 @@ pub enum FlagOp { Eager, // precomputed into result, for e.g. POPF DEC { cf: bool }, INC { cf: bool }, - ROL { dst: u16, src: u16, bits: u8, cf: bool, pf: bool, af: bool, zf: bool, sf: bool }, - ROR { dst: u16, src: u16, bits: u8, cf: bool, pf: bool, af: bool, zf: bool, sf: bool }, + ROL { dst: u16, src: u16, rot_mask: u16, cf: bool, pf: bool, af: bool, zf: bool, sf: bool }, + ROR { dst: u16, src: u16, rot_mask: u16, cf: bool, pf: bool, af: bool, zf: bool, sf: bool }, SAR { dst: u16, src: u16, sign_bit: bool }, SHL { dst: u16, src: u16 }, SHR { dst: u16, src: u16 }, diff --git a/src/emu/operands.rs b/src/emu/operands.rs index bdde70f..e12227c 100644 --- a/src/emu/operands.rs +++ b/src/emu/operands.rs @@ -19,7 +19,7 @@ pub trait Operand: Copy + 'static + { type Signed: nt::ops::checked::CheckedShr; const HI_BIT_MASK: Self; - const BITS: u8; + const ROTATE_MASK: u16 = (std::mem::size_of::() * 8 - 1) as _; fn hi_bit(self) -> bool; fn as_signed(self) -> Self::Signed; @@ -29,7 +29,6 @@ pub trait Operand: Copy + 'static + impl Operand for u8 { type Signed = i8; const HI_BIT_MASK: u8 = 0x80; - const BITS: u8 = 8; fn hi_bit(self) -> bool { self >> 7 == 1 @@ -47,7 +46,6 @@ impl Operand for u8 { impl Operand for u16 { type Signed = i16; const HI_BIT_MASK: u16 = 0x8000; - const BITS: u8 = 16; fn hi_bit(self) -> bool { self >> 15 == 1 diff --git a/src/emu/operations.rs b/src/emu/operations.rs index 9a92438..c194a58 100644 --- a/src/emu/operations.rs +++ b/src/emu/operations.rs @@ -345,7 +345,7 @@ where T: Operand, dst.write(res); flags.update(FlagOp::ROL { dst: dst_before.into(), src: src_before.into(), - bits: T::BITS, + rot_mask: T::ROTATE_MASK, cf: flags.cf(), pf: flags.pf(), af: flags.af(), @@ -370,7 +370,7 @@ where T: Operand, dst.write(res); flags.update(FlagOp::ROR { dst: dst_before.into(), src: src_before.into(), - bits: T::BITS, + rot_mask: T::ROTATE_MASK, cf: flags.cf(), pf: flags.pf(), af: flags.af(), @@ -438,6 +438,7 @@ where T: Operand, { let dst_before = dst.read(); let src_before = src.read(); // may alias dst + if src_before == U::zero() { return } let res = match dst_before.checked_shl(src_before.as_()) { Some(shifted) => shifted, None => T::zero() @@ -459,6 +460,7 @@ where T: Operand, { let dst_before = dst.read(); let src_before = src.read(); // may alias dst + if src_before == U::zero() { return } let res = match dst_before.checked_shr(src_before.as_()) { Some(shifted) => shifted, None => T::zero()