emu: PUSHF/POPF ops

This commit is contained in:
2021-04-07 00:38:10 -07:00
parent 4833b44074
commit 49e0132b2e
4 changed files with 34 additions and 13 deletions

View File

@@ -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<u16> 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<u16> 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<u16> for Flags {
fn read(&self) -> u16 {
(*self).into()
}
}

View File

@@ -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

View File

@@ -192,3 +192,14 @@ impl<'a> From<FarPtr<'_>> for DynLValue<'a> {
DynLValue::FarPtr { segment: farptr.segment, offset: farptr.offset }
}
}
impl<LVal: LValue<T>, T> LValue<T> for &mut LVal {
fn write(&mut self, val: T) {
(**self).write(val);
}
}
impl<RVal: RValue<T>, T> RValue<T> for &mut RVal {
fn read(&self) -> T {
(**self).read()
}
}

View File

@@ -294,7 +294,7 @@ where for<'a> FarPtr<'a>: RValue<T> + LValue<T>
pub fn nop() {}
pub fn pop(bus: &mut Bus, ss: u16, mut sp: Reg, mut dst: Reg) {
pub fn pop<LVal: LValue<u16>>(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<RVal: RValue<u16>>(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.