emu: CBW/CWD sign extension operations

This commit is contained in:
2021-04-27 02:21:04 -07:00
parent d42603501f
commit 27aa49e249
2 changed files with 11 additions and 1 deletions

View File

@@ -588,6 +588,8 @@ impl i8088 {
0x95 => xchg[reg=a, reg=bp] / 3, // XCHG ax, bp 0x95 => xchg[reg=a, reg=bp] / 3, // XCHG ax, bp
0x96 => xchg[reg=a, reg=si] / 3, // XCHG ax, si 0x96 => xchg[reg=a, reg=si] / 3, // XCHG ax, si
0x97 => xchg[reg=a, reg=di] / 3, // XCHG ax, di 0x97 => xchg[reg=a, reg=di] / 3, // XCHG ax, di
0x98 => cbw[reg=a, reglo=a] / 2, // CBW
0x99 => cwd[reg=d, reg=a] / 5, // CWD
0x9C => push[bus, regval=ss, reg=sp, flags] / 14, // PUSHF 0x9C => push[bus, regval=ss, reg=sp, flags] / 14, // PUSHF
0x9D => pop[bus, regval=ss, reg=sp, flags] / 12, // POPF 0x9D => pop[bus, regval=ss, reg=sp, flags] / 12, // POPF
// 0x9E SAHF not implemented // 0x9E SAHF not implemented

View File

@@ -6,7 +6,7 @@ use emu::num_traits::CheckedShr;
use emu::dos; use emu::dos;
use emu::flags::{FlagOp, Flags}; use emu::flags::{FlagOp, Flags};
use emu::i8088::{RepPrefix, i8088}; use emu::i8088::{RepPrefix, i8088};
use emu::operands::{Address, DynLValue, FarPtr, LValue, Operand, Reg, RValue}; use emu::operands::{Address, DynLValue, FarPtr, LValue, Operand, Reg, RegLo, RValue};
use emu::pc::Bus; use emu::pc::Bus;
macro_rules! string_op { macro_rules! string_op {
@@ -101,6 +101,10 @@ pub fn call(mut ip: Reg, bus: &mut Bus, ss: u16, sp: Reg, rel16: u16) {
ip.write(target); ip.write(target);
} }
pub fn cbw(mut ax: Reg, al: RegLo) {
ax.write(al.read() as i8 as u16);
}
pub fn clc(flags: &mut Flags) { pub fn clc(flags: &mut Flags) {
flags.update(FlagOp::Eager { cf: false, flags.update(FlagOp::Eager { cf: false,
pf: flags.pf(), pf: flags.pf(),
@@ -152,6 +156,10 @@ where T: Operand + RValue<T>,
}); });
} }
pub fn cwd(mut dx: Reg, ax: Reg) {
dx.write(if ax.read() < 0x8000 { 0x0000 } else { 0xFFFF });
}
pub fn dec<T: Operand, LVal: LValue<T>>(flags: &mut Flags, mut dst: LVal) { pub fn dec<T: Operand, LVal: LValue<T>>(flags: &mut Flags, mut dst: LVal) {
let dst_before = dst.read(); let dst_before = dst.read();
let res = dst_before.wrapping_sub(&T::one()); let res = dst_before.wrapping_sub(&T::one());