emu: MOV generic. Drop Reg16 register wrapper type
This commit is contained in:
@@ -8,10 +8,10 @@ use emu::pc::Bus;
|
|||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct i8088 {
|
pub struct i8088 {
|
||||||
// Data Registers
|
// Data Registers
|
||||||
pub a: Reg16,
|
pub a: u16,
|
||||||
pub b: Reg16,
|
pub b: u16,
|
||||||
pub c: Reg16,
|
pub c: u16,
|
||||||
pub d: Reg16,
|
pub d: u16,
|
||||||
|
|
||||||
// Index Registers
|
// Index Registers
|
||||||
pub si: u16, // Source Index
|
pub si: u16, // Source Index
|
||||||
@@ -50,18 +50,17 @@ pub struct Flags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod ops {
|
mod ops {
|
||||||
use emu::i8088::segoff_to_addr;
|
use emu::i8088::{LValue, RValue, segoff_to_addr};
|
||||||
use emu::byteorder::{ByteOrder, LittleEndian};
|
use emu::byteorder::{ByteOrder, LittleEndian};
|
||||||
|
|
||||||
pub fn call(ip: &mut u16, ss: u16, sp: &mut u16, mem: &mut [u8], addr: i16) {
|
pub fn call(ip: &mut u16, ss: u16, sp: &mut u16, mem: &mut [u8], addr: i16) {
|
||||||
let target = ip.wrapping_add(addr as u16);
|
let target = ip.wrapping_add(addr as u16);
|
||||||
trace!("CALL 0x{:04X}", target);
|
|
||||||
push16(ss, sp, mem, *ip);
|
push16(ss, sp, mem, *ip);
|
||||||
*ip = target;
|
*ip = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mov(reg: &mut super::Reg16, val: u16) {
|
pub fn mov<T>(dst: &mut impl LValue<T>, src: &impl RValue<T>) {
|
||||||
reg.x = val;
|
dst.write(src.read());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop16(ss: u16, sp: &mut u16, mem: &[u8]) -> u16 {
|
pub fn pop16(ss: u16, sp: &mut u16, mem: &[u8]) -> u16 {
|
||||||
@@ -77,10 +76,28 @@ mod ops {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn ret(ip: &mut u16, ss: u16, sp: &mut u16, mem: &[u8]) {
|
pub fn ret(ip: &mut u16, ss: u16, sp: &mut u16, mem: &[u8]) {
|
||||||
trace!("RET");
|
|
||||||
*ip = pop16(ss, sp, mem);
|
*ip = pop16(ss, sp, mem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LValue<T> {
|
||||||
|
fn write(&mut self, val: T);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait RValue<T> {
|
||||||
|
fn read(&self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LValue<u16> for u16 {
|
||||||
|
fn write(&mut self, val: u16) {
|
||||||
|
*self = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RValue<u16> for u16 {
|
||||||
|
fn read(&self) -> u16 {
|
||||||
|
*self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! step {
|
macro_rules! step {
|
||||||
@@ -110,7 +127,7 @@ macro_rules! step {
|
|||||||
let mut buf = [0; 2];
|
let mut buf = [0; 2];
|
||||||
buf[0] = $cpu.next_ip($bus);
|
buf[0] = $cpu.next_ip($bus);
|
||||||
buf[1] = $cpu.next_ip($bus);
|
buf[1] = $cpu.next_ip($bus);
|
||||||
step!(@arg $cookie, LittleEndian::read_u16(&buf))
|
step!(@arg $cookie, &LittleEndian::read_u16(&buf))
|
||||||
} };
|
} };
|
||||||
|
|
||||||
(@mem $cookie:tt, $cpu:ident, $bus:ident) => {
|
(@mem $cookie:tt, $cpu:ident, $bus:ident) => {
|
||||||
@@ -222,20 +239,3 @@ impl Debug for Flags {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub union Reg16 {
|
|
||||||
x: u16,
|
|
||||||
lh: [u8; 2],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Reg16 {
|
|
||||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
|
|
||||||
unsafe { self.x.fmt(fmt) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Reg16 {
|
|
||||||
fn default() -> Self { Self { x: 0u16 } }
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user