emu: PUSHF/POPF ops
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
use emu::operands::{LValue, RValue};
|
||||||
|
|
||||||
const CF_BIT: u8 = 0; // Carry Flag
|
const CF_BIT: u8 = 0; // Carry Flag
|
||||||
const PF_BIT: u8 = 2; // Parity Flag
|
const PF_BIT: u8 = 2; // Parity Flag
|
||||||
const AF_BIT: u8 = 4; // Adjust Flag
|
const AF_BIT: u8 = 4; // Adjust Flag
|
||||||
@@ -184,17 +186,21 @@ impl Default for FlagOp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for Flags {
|
impl LValue<u16> for Flags {
|
||||||
fn from(flags: u16) -> Self {
|
fn write(&mut self, flags: u16) {
|
||||||
Self {
|
self.tf = flags & 1 << TF_BIT != 0;
|
||||||
tf: flags & 1 << TF_BIT != 0,
|
self.ie = flags & 1 << IF_BIT != 0;
|
||||||
ie: flags & 1 << IF_BIT != 0,
|
self.df = flags & 1 << DF_BIT != 0;
|
||||||
df: flags & 1 << DF_BIT != 0,
|
|
||||||
|
|
||||||
flag_op: FlagOp::POPF,
|
self.flag_op = FlagOp::POPF;
|
||||||
res: flags,
|
self.res = flags;
|
||||||
sign_mask: 0,
|
self.sign_mask = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RValue<u16> for Flags {
|
||||||
|
fn read(&self) -> u16 {
|
||||||
|
(*self).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -488,6 +488,10 @@ impl i8088 {
|
|||||||
0x18 => mov[reg=ds, modrm16] / "2/12+", }, // MOV ds, r/m16
|
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
|
0x8F: { 0x00 => pop_modrm[regval=ss, reg=sp, modrm16, convert, bus] / "12/25+" }, // POP r/m16
|
||||||
0x90 => nop[] / 3,
|
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]
|
0xA0 => mov[seg=ds, reglo=a, addr] / 14, // MOV al, [addr]
|
||||||
0xA1 => mov[seg=ds, reg=a, addr] / 14, // MOV ax, [addr]
|
0xA1 => mov[seg=ds, reg=a, addr] / 14, // MOV ax, [addr]
|
||||||
0xA2 => mov[seg=ds, addr, reglo=a] / 14, // MOV [addr], al
|
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 }
|
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 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() };
|
let ptr = FarPtr { bus: bus, segment: ss, offset: sp.read() };
|
||||||
dst.write(ptr.read());
|
dst.write(ptr.read());
|
||||||
// XXX: Not checking for stack faults or anything
|
// 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
|
// XXX: Not checking for stack faults or anything
|
||||||
sp.write(sp.read() - 2);
|
sp.write(sp.read() - 2);
|
||||||
let mut ptr = FarPtr { bus: bus, segment: ss, offset: sp.read() };
|
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.
|
// Ugly hack for the ModR/M case. See the comments on pop_modrm.
|
||||||
|
|||||||
Reference in New Issue
Block a user