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:
@@ -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) => {
|
||||||
|
|||||||
@@ -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 },
|
||||||
|
|||||||
Reference in New Issue
Block a user