diff --git a/src/emu/flags.rs b/src/emu/flags.rs index 599ddf6..e80c4fa 100644 --- a/src/emu/flags.rs +++ b/src/emu/flags.rs @@ -1,5 +1,7 @@ use std::fmt::{Debug, Formatter}; +use emu::operands::{LValue, RValue}; + const CF_BIT: u8 = 0; // Carry Flag const PF_BIT: u8 = 2; // Parity Flag const AF_BIT: u8 = 4; // Adjust Flag @@ -184,17 +186,21 @@ impl Default for FlagOp { } } -impl From for Flags { - fn from(flags: u16) -> Self { - Self { - tf: flags & 1 << TF_BIT != 0, - ie: flags & 1 << IF_BIT != 0, - df: flags & 1 << DF_BIT != 0, +impl LValue for Flags { + fn write(&mut self, flags: u16) { + self.tf = flags & 1 << TF_BIT != 0; + self.ie = flags & 1 << IF_BIT != 0; + self.df = flags & 1 << DF_BIT != 0; - flag_op: FlagOp::POPF, - res: flags, - sign_mask: 0, - } + self.flag_op = FlagOp::POPF; + self.res = flags; + self.sign_mask = 0; + } +} + +impl RValue for Flags { + fn read(&self) -> u16 { + (*self).into() } } diff --git a/src/emu/i8088.rs b/src/emu/i8088.rs index 32ef010..6370fe0 100644 --- a/src/emu/i8088.rs +++ b/src/emu/i8088.rs @@ -488,6 +488,10 @@ impl i8088 { 0x18 => mov[reg=ds, modrm16] / "2/12+", }, // MOV ds, r/m16 0x8F: { 0x00 => pop_modrm[regval=ss, reg=sp, modrm16, convert, bus] / "12/25+" }, // POP r/m16 0x90 => nop[] / 3, + 0x9C => push[bus, regval=ss, reg=sp, flags] / 14, // PUSHF + 0x9D => pop[bus, regval=ss, reg=sp, flags] / 12, // POPF + // 0x9E SAHF not implemented + // 0x9F LAHF not implemented 0xA0 => mov[seg=ds, reglo=a, addr] / 14, // MOV al, [addr] 0xA1 => mov[seg=ds, reg=a, addr] / 14, // MOV ax, [addr] 0xA2 => mov[seg=ds, addr, reglo=a] / 14, // MOV [addr], al diff --git a/src/emu/operands.rs b/src/emu/operands.rs index 62df980..2e17993 100644 --- a/src/emu/operands.rs +++ b/src/emu/operands.rs @@ -192,3 +192,14 @@ impl<'a> From> for DynLValue<'a> { DynLValue::FarPtr { segment: farptr.segment, offset: farptr.offset } } } +impl, T> LValue for &mut LVal { + fn write(&mut self, val: T) { + (**self).write(val); + } +} + +impl, T> RValue for &mut RVal { + fn read(&self) -> T { + (**self).read() + } +} diff --git a/src/emu/operations.rs b/src/emu/operations.rs index 01eda0a..124d968 100644 --- a/src/emu/operations.rs +++ b/src/emu/operations.rs @@ -294,7 +294,7 @@ where for<'a> FarPtr<'a>: RValue + LValue pub fn nop() {} -pub fn pop(bus: &mut Bus, ss: u16, mut sp: Reg, mut dst: Reg) { +pub fn pop>(bus: &mut Bus, ss: u16, mut sp: Reg, mut dst: LVal) { let ptr = FarPtr { bus: bus, segment: ss, offset: sp.read() }; dst.write(ptr.read()); // XXX: Not checking for stack faults or anything @@ -336,11 +336,11 @@ pub fn pop_modrm<'a>(ss: u16, mut sp: Reg, dst: DynLValue<'a>, bus: &mut Bus) { } } -pub fn push(bus: &mut Bus, ss: u16, mut sp: Reg, val: u16) { +pub fn push>(bus: &mut Bus, ss: u16, mut sp: Reg, val: RVal) { // XXX: Not checking for stack faults or anything sp.write(sp.read() - 2); let mut ptr = FarPtr { bus: bus, segment: ss, offset: sp.read() }; - ptr.write(val); + ptr.write(val.read()); } // Ugly hack for the ModR/M case. See the comments on pop_modrm.