int Or::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); unsigned int srcVal = src->GetValue(); unsigned int newVal = dstVal | srcVal; unsigned int sign = (dst->GetBitmask() == 0xFF) ? 0x80 : 0x8000; proc->SetFlag(FLAGS_OF, 0); proc->SetFlag(FLAGS_CF, 0); proc->SetFlag(FLAGS_SF, newVal >= sign); proc->SetFlag(FLAGS_ZF, newVal == 0x00); proc->SetFlag(FLAGS_PF, Parity(newVal)); dst->SetValue(newVal); return 0; }
int Adc::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); unsigned int srcVal = src->GetValue(); unsigned int sign = dst->GetBitmask() == 0xFF ? 0x80 : 0x8000; unsigned int newVal = dstVal + srcVal + (proc->GetFlag(FLAGS_CF) ? 1 : 0); proc->SetFlag(FLAGS_CF, newVal > dst->GetBitmask()); newVal &= dst->GetBitmask(); proc->SetFlag(FLAGS_OF, OverflowAdd(dstVal, srcVal, sign == 0x80 ? 1 : 2)); proc->SetFlag(FLAGS_SF, newVal >= sign); proc->SetFlag(FLAGS_ZF, newVal == 0x00); proc->SetFlag(FLAGS_AF, AdjustAdd(dstVal, srcVal)); proc->SetFlag(FLAGS_PF, Parity(newVal)); dst->SetValue(newVal); return 0; }
int In::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return INVALID_ARGS; } if(mOpcode == IN_AL_IMM8 || mOpcode == IN_AL_DX) { dst->SetValue(proc->Inb(src->GetValue())); return 0; } else if(mOpcode == IN_AX_IMM8 || mOpcode == IN_AX_DX) { dst->SetValue(proc->Inw(src->GetValue())); return 0; } return INVALID_ARGS; }
int Not::Execute(Processor*) { Operand* dst = mOperands[Operand::DST]; if(!dst) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); dst->SetValue((~dstVal) & dst->GetBitmask()); return 0; }
int Sub::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return INVALID_ARGS; } dst->SetValue(Cmp::compare(proc, dst, src)); return 0; }
int Xor::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(dst == 0 || src == 0) return -1; unsigned int val = dst->GetValue() ^ src->GetValue(); proc->SetFlag(FLAGS_OF, 0); proc->SetFlag(FLAGS_CF, 0); proc->SetFlag(FLAGS_ZF, val == 0); proc->SetFlag(FLAGS_PF, Parity(val)); proc->SetFlag(FLAGS_SF, val >= (dst->GetBitmask() == 0xFF ? 0x80 : 0x8000)); dst->SetValue(val); return 0; }
int Neg::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; if(!dst) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); unsigned int sign = dst->GetBitmask() == 0xFF ? 0x80 : 0x8000; proc->SetFlag(FLAGS_CF, dstVal != 0); proc->SetFlag(FLAGS_OF, dstVal == 0x80); //only overflow is -128 -> -128 dst->SetValue((~dstVal + 1) & dst->GetBitmask()); dstVal = dst->GetValue(); proc->SetFlag(FLAGS_SF, dstVal >= sign); proc->SetFlag(FLAGS_ZF, dstVal == 0x00); proc->SetFlag(FLAGS_PF, Parity(dstVal)); proc->SetFlag(FLAGS_AF, AdjustSub(dstVal, dstVal*2)); return 0; }