fix(interpreter): set flags correctly for inc/dec/neg
This commit is contained in:
@@ -358,25 +358,39 @@ impl Interpreter {
|
||||
/*
|
||||
* INC
|
||||
*/
|
||||
Mnemonic::INC_Reg(reg) => self
|
||||
.computer
|
||||
.regs
|
||||
.write(reg, self.computer.regs.read(reg) + 1),
|
||||
Mnemonic::INC_Mod(target) => {
|
||||
let val = self.computer.read_modrm(target)?;
|
||||
self.computer.write_modrm(target, val + 1)?
|
||||
Mnemonic::INC_Reg(reg) => {
|
||||
let cf = self.computer.flags.cf;
|
||||
let dest = ModRmTarget::Register(reg);
|
||||
let src = ArithmeticOperand::Immediate(ImmediateOperand::Byte(1));
|
||||
self.computer.add(dest, src)?;
|
||||
// The CF flag is not affected
|
||||
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
|
||||
*/
|
||||
Mnemonic::DEC_Reg(reg) => self
|
||||
.computer
|
||||
.regs
|
||||
.write(reg, self.computer.regs.read(reg) - 1),
|
||||
Mnemonic::DEC_Mod(target) => {
|
||||
let val = self.computer.read_modrm(target)?;
|
||||
self.computer.write_modrm(target, val - 1)?
|
||||
Mnemonic::DEC_Reg(reg) => {
|
||||
let cf = self.computer.flags.cf;
|
||||
let dest = ModRmTarget::Register(reg);
|
||||
let src = ArithmeticOperand::Immediate(ImmediateOperand::Byte(1));
|
||||
self.computer.sub(dest, src)?;
|
||||
// The CF flag is not affected
|
||||
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)?)?;
|
||||
}
|
||||
Mnemonic::NEG(target) => {
|
||||
let val = !self.computer.read_modrm(target)?;
|
||||
self.computer.write_modrm(target, val + 0b1)?;
|
||||
let lhs = !self.computer.read_modrm(target)?;
|
||||
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