emu: PUSHF/POPF ops
This commit is contained in:
@@ -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,18 +186,22 @@ 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()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Flags> for u16 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user