emu: RegHalf dispatcher to re-merge @r8 op directive

Keeps the macro recursion from branching. In effect this just moves a
conditional from @r8's output to the RegHalf wrapper, so this is
usually a wash except with less code generated.
This commit is contained in:
2021-04-17 23:29:34 -07:00
parent 7b00a8e708
commit c66feda360
2 changed files with 36 additions and 21 deletions

View File

@@ -3,7 +3,7 @@ use std::fmt::Debug;
use super::byteorder::{ByteOrder, LittleEndian}; use super::byteorder::{ByteOrder, LittleEndian};
use emu::operands::{FarPtr, Reg, RegHi, RegLo}; use emu::operands::{FarPtr, Reg, RegHalf, RegHi, RegLo};
use emu::operations as ops; use emu::operations as ops;
use emu::flags::Flags; use emu::flags::Flags;
use emu::pc::Bus; use emu::pc::Bus;
@@ -270,27 +270,19 @@ macro_rules! step {
} }; } };
(@r8 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, ($modrm_val:ident, $($modrm_rest: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? // TODO: Should these also be passed into the macro like the modrm specs?
if modrm_shift & 0x4 == 0 { let reg = match $modrm_val >> 3 & 0x7 {
let reg = match modrm_shift & 0x3 { 0 => RegHalf::Lo(RegLo { reg: &$cpu.a }),
0 => RegLo { reg: &$cpu.a }, 1 => RegHalf::Lo(RegLo { reg: &$cpu.c }),
1 => RegLo { reg: &$cpu.c }, 2 => RegHalf::Lo(RegLo { reg: &$cpu.d }),
2 => RegLo { reg: &$cpu.d }, 3 => RegHalf::Lo(RegLo { reg: &$cpu.b }),
3 => RegLo { reg: &$cpu.b }, 4 => RegHalf::Hi(RegHi { reg: &$cpu.a }),
5 => RegHalf::Hi(RegHi { reg: &$cpu.c }),
6 => RegHalf::Hi(RegHi { reg: &$cpu.d }),
7 => RegHalf::Hi(RegHi { reg: &$cpu.b }),
_ => unreachable!() _ => unreachable!()
}; };
step!(@arg $cookie, reg) 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) => { (@reg=$reg:ident $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {

View File

@@ -177,6 +177,29 @@ impl RValue<u8> for RegLo<'_> {
} }
} }
pub enum RegHalf<'a> {
Hi(RegHi<'a>),
Lo(RegLo<'a>)
}
impl LValue<u8> for RegHalf<'_> {
fn write(&mut self, val: u8) {
match self {
RegHalf::Hi(hi) => hi.write(val),
RegHalf::Lo(lo) => lo.write(val)
}
}
}
impl RValue<u8> for RegHalf<'_> {
fn read(&self) -> u8 {
match self {
RegHalf::Hi(hi) => hi.read(),
RegHalf::Lo(lo) => lo.read()
}
}
}
pub enum DynLValue<'a> { pub enum DynLValue<'a> {
Reg(Reg<'a>), Reg(Reg<'a>),
FarPtr { segment: u16, offset: u16 }, FarPtr { segment: u16, offset: u16 },