emu: INC/DEC opcodes. width={byte,word} argtypes for disambig

Also made all LValues also RValues for brevity (so INC/DEC don't have
to bound their destination arguments by both, but this is not required
if it causes problems for some reason down the road).
This commit is contained in:
2021-03-19 00:07:49 -07:00
parent c8d6a3312a
commit ff7e8a7fb9
3 changed files with 50 additions and 3 deletions

View File

@@ -1,4 +1,5 @@
use std::fmt::Debug;
use std::marker::PhantomData;
use emu::dos;
use emu::i8088::{Flags, RepPrefix, i8088};
@@ -69,8 +70,8 @@ macro_rules! update_flags {
// Entry Point
($flags:expr, $t:ty, $eval:expr $(, $flagnames:ident)* ) => { {
let (dst, carry) = $eval;
update_flags!(@recur $flags, $t, dst, carry $(, $flagnames)*);
let (dst, _carry) = $eval; // _carry used iff CF flag being updated
update_flags!(@recur $flags, $t, dst, _carry $(, $flagnames)*);
dst
} }
}
@@ -135,6 +136,22 @@ pub fn cmpsw(flags: &mut Flags,
});
}
pub fn dec<T: Operand>(_width: PhantomData<T>, // Needed to disambiguate when dst is a FarPtr
flags: &mut Flags,
dst: &mut impl LValue<T>) {
let res = update_flags!(flags, T, dst.read().overflowing_sub(&T::one()), sf, zf, af, pf);
flags.of = res == T::HI_BIT_MASK - T::one();
dst.write(res);
}
pub fn inc<T: Operand>(_width: PhantomData<T>, // Needed to disambiguate when dst is a FarPtr
flags: &mut Flags,
dst: &mut impl LValue<T>) {
let res = update_flags!(flags, T, dst.read().overflowing_add(&T::one()), sf, zf, af, pf);
flags.of = res == T::HI_BIT_MASK;
dst.write(res);
}
pub fn int(cpu: &mut i8088, bus: &mut Bus, num: &u8) {
match num {
0x21 => dos::interrupt(cpu, bus),