diff --git a/src/emu/i8088.rs b/src/emu/i8088.rs index 071069b..5ffeffb 100644 --- a/src/emu/i8088.rs +++ b/src/emu/i8088.rs @@ -179,27 +179,27 @@ macro_rules! step { }; (@form=byte0 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u8)); + step!(@form $cookie, form=(u8)) }; (@form=byte1 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u8, _)); + step!(@form $cookie, form=(u8, _)) }; (@form=byte3 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u8, _, _, _)); + step!(@form $cookie, form=(u8, _, _, _)) }; (@form=word0 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u16)); + step!(@form $cookie, form=(u16)) }; (@form=word1 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u16, _)); + step!(@form $cookie, form=(u16, _)) }; (@form=word3 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u16, _, _, _)); + step!(@form $cookie, form=(u16, _, _, _)) }; (@mem $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { @@ -253,35 +253,45 @@ macro_rules! step { continue $prefix_loop; }; - (@r16 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, ($modrm_val:ident, $modrm:tt, $modrm16:tt, $modrm8:tt)) => { + (@r16 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, ($modrm_val:ident, $($modrm_rest:tt),*)) => { { // TODO: Should these also be passed into the macro like the modrm specs? - match $modrm_val >> 3 & 0x7 { - 0 => step!(@arg $cookie, Reg { reg: &$cpu.a } ), - 1 => step!(@arg $cookie, Reg { reg: &$cpu.c } ), - 2 => step!(@arg $cookie, Reg { reg: &$cpu.d } ), - 3 => step!(@arg $cookie, Reg { reg: &$cpu.b } ), - 4 => step!(@arg $cookie, Reg { reg: &$cpu.sp } ), - 5 => step!(@arg $cookie, Reg { reg: &$cpu.bp } ), - 6 => step!(@arg $cookie, Reg { reg: &$cpu.si } ), - 7 => step!(@arg $cookie, Reg { reg: &$cpu.di } ), + let reg = match $modrm_val >> 3 & 0x7 { + 0 => Reg { reg: &$cpu.a }, + 1 => Reg { reg: &$cpu.c }, + 2 => Reg { reg: &$cpu.d }, + 3 => Reg { reg: &$cpu.b }, + 4 => Reg { reg: &$cpu.sp }, + 5 => Reg { reg: &$cpu.bp }, + 6 => Reg { reg: &$cpu.si }, + 7 => Reg { reg: &$cpu.di }, _ => unreachable!() }; - }; + step!(@arg $cookie, reg) + } }; - (@r8 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, ($modrm_val:ident, $modrm:tt, $modrm16:tt, $modrm8:tt)) => { + (@r8 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, ($modrm_val:ident, $($modrm_rest:tt),*)) => { { + let modrm_shift = $modrm_val >> 3; // TODO: Should these also be passed into the macro like the modrm specs? - match $modrm_val >> 3 & 0x7 { - 0 => step!(@arg $cookie, RegLo { reg: &$cpu.a } ), - 1 => step!(@arg $cookie, RegLo { reg: &$cpu.c } ), - 2 => step!(@arg $cookie, RegLo { reg: &$cpu.d } ), - 3 => step!(@arg $cookie, RegLo { reg: &$cpu.b } ), - 4 => step!(@arg $cookie, RegHi { reg: &$cpu.a } ), - 5 => step!(@arg $cookie, RegHi { reg: &$cpu.c } ), - 6 => step!(@arg $cookie, RegHi { reg: &$cpu.d } ), - 7 => step!(@arg $cookie, RegHi { reg: &$cpu.b } ), - _ => unreachable!() - }; - }; + if modrm_shift & 0x4 == 0 { + let reg = match modrm_shift & 0x3 { + 0 => RegLo { reg: &$cpu.a }, + 1 => RegLo { reg: &$cpu.c }, + 2 => RegLo { reg: &$cpu.d }, + 3 => RegLo { reg: &$cpu.b }, + _ => unreachable!() + }; + step!(@arg $cookie, reg) + } else { + let reg = match modrm_shift & 0x3 { + 0 => RegHi { reg: &$cpu.a }, + 1 => RegHi { reg: &$cpu.c }, + 2 => RegHi { reg: &$cpu.d }, + 3 => RegHi { reg: &$cpu.b }, + _ => unreachable!() + }; + step!(@arg $cookie, reg) + } + } }; (@reg=$reg:ident $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { step!(@arg $cookie, Reg { reg: &$cpu.$reg });