diff --git a/src/emu/i8088.rs b/src/emu/i8088.rs index 91fd1d5..c30e5a5 100644 --- a/src/emu/i8088.rs +++ b/src/emu/i8088.rs @@ -190,6 +190,14 @@ macro_rules! step { step!(@arg $cookie, &mut $cpu.flags) }; + (@form=nullary_byte $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { + step!(@form $cookie, form=(u8)); + }; + + (@form=nullary_word $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { + step!(@form $cookie, form=(u16)); + }; + (@form=ternary_byte $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { step!(@form $cookie, form=(u8, _, _, _)); }; @@ -496,16 +504,16 @@ impl i8088 { 0xA1 => mov[reg=a, addr] / 14, 0xA2 => mov[addr, reglo=a] / 14, 0xA3 => mov[addr, reg=a] / 14, - 0xA4 => movsb[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "18/9+17n", - 0xA5 => movsw[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "26/9+25n", - 0xA6 => cmpsb[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "22/9+22n", - 0xA7 => cmpsw[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "30/9+30n", - 0xAA => stosb[flags, bus, rep, reg=c, reg=es, reg=di, reglo=a] / "11/9+10n", - 0xAB => stosw[flags, bus, rep, reg=c, reg=es, reg=di, reg=a] / "15/9+14n", - 0xAC => lodsb[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reglo=a] / "12/9+13n", - 0xAD => lodsw[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=a] / "16/9+17n", - 0xAE => scasb[flags, bus, rep, reg=c, reg=es, reg=di, reglo=a] / "15/9+15n", - 0xAF => scasw[flags, bus, rep, reg=c, reg=es, reg=di, reg=a] / "19/9+19n", + 0xA4 => movs[form=nullary_byte, flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "18/9+17n", + 0xA5 => movs[form=nullary_word, flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "26/9+25n", + 0xA6 => cmps[form=nullary_byte, flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "22/9+22n", + 0xA7 => cmps[form=nullary_word, flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=es, reg=di] / "30/9+30n", + 0xAA => stos[flags, bus, rep, reg=c, reg=es, reg=di, reglo=a] / "11/9+10n", + 0xAB => stos[flags, bus, rep, reg=c, reg=es, reg=di, reg=a] / "15/9+14n", + 0xAC => lods[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reglo=a] / "12/9+13n", + 0xAD => lods[flags, bus, rep, reg=c, seg=ds, seg, reg=si, reg=a] / "16/9+17n", + 0xAE => scas[flags, bus, rep, reg=c, reg=es, reg=di, reglo=a] / "15/9+15n", + 0xAF => scas[flags, bus, rep, reg=c, reg=es, reg=di, reg=a] / "19/9+19n", 0xB0 => mov[reglo=a, d8] / 4, 0xB1 => mov[reglo=c, d8] / 4, 0xB2 => mov[reglo=d, d8] / 4, diff --git a/src/emu/operations.rs b/src/emu/operations.rs index fa47f48..6495738 100644 --- a/src/emu/operations.rs +++ b/src/emu/operations.rs @@ -80,33 +80,20 @@ pub fn cmp(flags: &mut Flags, dst: impl RValue, src: impl RValue< flags.update(FlagOp::SUB, dst.into(), src.into(), res.into(), T::WIDTH); } -pub fn cmpsb(flags: &mut Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - seg: u16, - mut si: Reg, - es: Reg, - mut di: Reg) { - string_op!((u8, flags, rep, cx, si=si, di=di, zf=flags.zf()), { - let src = >::read(&FarPtr { bus: bus, segment: seg, offset: si.read() }); - let dst = >::read(&FarPtr { bus: bus, segment: es.read(), offset: di.read() }); - - cmp(flags, dst, src); - }); -} - -pub fn cmpsw(flags: &mut Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - seg: u16, - mut si: Reg, - es: Reg, - mut di: Reg) { - string_op!((u16, flags, rep, cx, si=si, di=di, zf=flags.zf()), { - let src = >::read(&FarPtr { bus: bus, segment: seg, offset: si.read() }); - let dst = >::read(&FarPtr { bus: bus, segment: es.read(), offset: di.read() }); +pub fn cmps(flags: &mut Flags, + bus: &mut Bus, + rep: RepPrefix, + mut cx: Reg, + seg: u16, + mut si: Reg, + es: Reg, + mut di: Reg) +where T: Operand + RValue, + for<'a> FarPtr<'a>: RValue +{ + string_op!((T, flags, rep, cx, si=si, di=di, zf=flags.zf()), { + let src = >::read(&FarPtr { bus: bus, segment: seg, offset: si.read() }); + let dst = >::read(&FarPtr { bus: bus, segment: es.read(), offset: di.read() }); cmp(flags, dst, src); }); @@ -244,26 +231,16 @@ pub fn lea(mut dst: Reg, addr: FarPtr) { dst.write(addr.offset) } -pub fn lodsb(flags: &Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - seg: u16, - mut si: Reg, - mut al: impl LValue) { - string_op!((u8, flags, rep, cx, si=si), { - al.write(FarPtr { bus: bus, segment: seg, offset: si.read() }.read()); - }); -} - -pub fn lodsw(flags: &Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - seg: u16, - mut si: Reg, - mut ax: impl LValue) { - string_op!((u16, flags, rep, cx, si=si), { +pub fn lods(flags: &Flags, + bus: &mut Bus, + rep: RepPrefix, + mut cx: Reg, + seg: u16, + mut si: Reg, + mut ax: impl LValue) +where for<'a> FarPtr<'a>: RValue +{ + string_op!((T, flags, rep, cx, si=si), { ax.write(FarPtr { bus: bus, segment: seg, offset: si.read() }.read()); }); } @@ -272,33 +249,20 @@ pub fn mov(mut dst: impl LValue, src: impl RValue) { dst.write(src.read()); } -pub fn movsb(flags: &Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - seg: u16, - mut si: Reg, - es: Reg, - mut di: Reg) { - string_op!((u8, flags, rep, cx, si=si, di=di), { - let src = >::read(&FarPtr { bus: bus, segment: seg, offset: si.read() }); +pub fn movs(flags: &Flags, + bus: &mut Bus, + rep: RepPrefix, + mut cx: Reg, + seg: u16, + mut si: Reg, + es: Reg, + mut di: Reg) +where for<'a> FarPtr<'a>: RValue + LValue +{ + string_op!((T, flags, rep, cx, si=si, di=di), { + let src = >::read(&FarPtr { bus: bus, segment: seg, offset: si.read() }); let mut dst = FarPtr { bus: bus, segment: es.read(), offset: di.read() }; - >::write(&mut dst, src); - }); -} - -pub fn movsw(flags: &Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - seg: u16, - mut si: Reg, - es: Reg, - mut di: Reg) { - string_op!((u16, flags, rep, cx, si=si, di=di), { - let src = >::read(&FarPtr { bus: bus, segment: seg, offset: si.read() }); - let mut dst = FarPtr { bus: bus, segment: es.read(), offset: di.read() }; - >::write(&mut dst, src); + >::write(&mut dst, src); }); } @@ -407,29 +371,19 @@ where T: Operand, flags.update(FlagOp::SHIFT, dst_before.into(), src_before.into(), res.into(), T::WIDTH); } -pub fn scasb(flags: &mut Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - es: Reg, - mut di: Reg, - needle: impl RValue) { +pub fn scas(flags: &mut Flags, + bus: &mut Bus, + rep: RepPrefix, + mut cx: Reg, + es: Reg, + mut di: Reg, + needle: RVal) +where RVal: RValue, + T: Operand + RValue, + for<'a> FarPtr<'a>: RValue +{ let needle = needle.read(); - string_op!((u8, flags, rep, cx, di=di, zf=flags.zf()), { - let elem = FarPtr { bus: bus, segment: es.read(), offset: di.read() }; - cmp(flags, elem, needle); - }); -} - -pub fn scasw(flags: &mut Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - es: Reg, - mut di: Reg, - needle: impl RValue) { - let needle = needle.read(); - string_op!((u16, flags, rep, cx, di=di, zf=flags.zf()), { + string_op!((T, flags, rep, cx, di=di, zf=flags.zf()), { let elem = FarPtr { bus: bus, segment: es.read(), offset: di.read() }; cmp(flags, elem, needle); }); @@ -481,27 +435,17 @@ where T: Operand, flags.update(FlagOp::SHIFT, dst_before.into(), src_before.into(), res.into(), T::WIDTH); } -pub fn stosb(flags: &Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - es: Reg, - mut di: Reg, - val: impl RValue) { - string_op!((u8, flags, rep, cx, di=di), { - let mut dst = FarPtr { bus: bus, segment: es.read(), offset: di.read() }; - dst.write(val.read()); - }); -} - -pub fn stosw(flags: &Flags, - bus: &mut Bus, - rep: RepPrefix, - mut cx: Reg, - es: Reg, - mut di: Reg, - val: impl RValue) { - string_op!((u16, flags, rep, cx, di=di), { +pub fn stos(flags: &Flags, + bus: &mut Bus, + rep: RepPrefix, + mut cx: Reg, + es: Reg, + mut di: Reg, + val: RVal) +where RVal: RValue, + for<'a> FarPtr<'a>: LValue +{ + string_op!((T, flags, rep, cx, di=di), { let mut dst = FarPtr { bus: bus, segment: es.read(), offset: di.read() }; dst.write(val.read()); });