fix(interpreter): set flags correctly for inc/dec/neg
This commit is contained in:
@@ -358,25 +358,39 @@ impl Interpreter {
|
|||||||
/*
|
/*
|
||||||
* INC
|
* INC
|
||||||
*/
|
*/
|
||||||
Mnemonic::INC_Reg(reg) => self
|
Mnemonic::INC_Reg(reg) => {
|
||||||
.computer
|
let cf = self.computer.flags.cf;
|
||||||
.regs
|
let dest = ModRmTarget::Register(reg);
|
||||||
.write(reg, self.computer.regs.read(reg) + 1),
|
let src = ArithmeticOperand::Immediate(ImmediateOperand::Byte(1));
|
||||||
Mnemonic::INC_Mod(target) => {
|
self.computer.add(dest, src)?;
|
||||||
let val = self.computer.read_modrm(target)?;
|
// The CF flag is not affected
|
||||||
self.computer.write_modrm(target, val + 1)?
|
self.computer.flags.cf = cf;
|
||||||
|
}
|
||||||
|
Mnemonic::INC_Mod(dest) => {
|
||||||
|
let cf = self.computer.flags.cf;
|
||||||
|
let src = ArithmeticOperand::Immediate(ImmediateOperand::Byte(1));
|
||||||
|
self.computer.add(dest, src)?;
|
||||||
|
// The CF flag is not affected
|
||||||
|
self.computer.flags.cf = cf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DEC
|
* DEC
|
||||||
*/
|
*/
|
||||||
Mnemonic::DEC_Reg(reg) => self
|
Mnemonic::DEC_Reg(reg) => {
|
||||||
.computer
|
let cf = self.computer.flags.cf;
|
||||||
.regs
|
let dest = ModRmTarget::Register(reg);
|
||||||
.write(reg, self.computer.regs.read(reg) - 1),
|
let src = ArithmeticOperand::Immediate(ImmediateOperand::Byte(1));
|
||||||
Mnemonic::DEC_Mod(target) => {
|
self.computer.sub(dest, src)?;
|
||||||
let val = self.computer.read_modrm(target)?;
|
// The CF flag is not affected
|
||||||
self.computer.write_modrm(target, val - 1)?
|
self.computer.flags.cf = cf;
|
||||||
|
}
|
||||||
|
Mnemonic::DEC_Mod(dest) => {
|
||||||
|
let cf = self.computer.flags.cf;
|
||||||
|
let src = ArithmeticOperand::Immediate(ImmediateOperand::Byte(1));
|
||||||
|
self.computer.sub(dest, src)?;
|
||||||
|
// The CF flag is not affected
|
||||||
|
self.computer.flags.cf = cf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -624,8 +638,17 @@ impl Interpreter {
|
|||||||
.write_modrm(target, !self.computer.read_modrm(target)?)?;
|
.write_modrm(target, !self.computer.read_modrm(target)?)?;
|
||||||
}
|
}
|
||||||
Mnemonic::NEG(target) => {
|
Mnemonic::NEG(target) => {
|
||||||
let val = !self.computer.read_modrm(target)?;
|
let lhs = !self.computer.read_modrm(target)?;
|
||||||
self.computer.write_modrm(target, val + 0b1)?;
|
let rhs = ImmediateOperand::Byte(1);
|
||||||
|
let result = lhs + rhs;
|
||||||
|
self.computer.flags.cf = result < self.computer.read_modrm(target)?;
|
||||||
|
self.computer.flags.of =
|
||||||
|
(lhs.msb() && rhs.msb()) && (result.msb() != lhs.msb());
|
||||||
|
self.computer.flags.zf = result.zero();
|
||||||
|
self.computer.flags.sf = result.msb();
|
||||||
|
self.computer.flags.pf = result.parity();
|
||||||
|
|
||||||
|
self.computer.write_modrm(target, result)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user