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 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 IDiv::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; if(dst == 0) return INVALID_ARGS; if(dst->GetValue() == 0) { return IDIV_BY_ZERO; } unsigned int dividend = proc->GetRegister(REG_AX) + (mOpcode == IDIV_MOD8 ? 0 : proc->GetRegister(REG_DX) << 0x10); unsigned int divisor = dst->GetValue(); unsigned int divisorNeg = dst->GetBitmask() == 0xFF ? 0x80 : 0x8000; unsigned int dividendNeg = dst->GetBitmask() == 0xFF ? 0x8000 : 0x80000000; unsigned int dividendBm = dst->GetBitmask() == 0xFF ? 0xFFFF : 0xFFFFFFFF; int rem, val; bool neg = (((dividend & dividendNeg) >> 8) ^ (divisor & divisorNeg)) != 0; //positivize everything if(dividend & dividendNeg) { //if dividend is negative dividend = (~dividend + 1) & dividendBm; // +ve it and ensure within bitmask } if(divisor & divisorNeg) { divisor = (~divisor + 1) & dst->GetBitmask(); //all operands are positive rem = -(int)(dividend % divisor); //remainder is negative } else { rem = (dividend % divisor); //remainder is positive } //calc result val = dividend / divisor; // if((unsigned int)val >= divisorNeg) { //operands are positive, so anything this big is overflow return IDIV_DIV_ERR; } //invert if necessary if(neg) val = -val; val &= dst->GetBitmask(); proc->SetRegister(mOpcode == IDIV_MOD8 ? REG_AL : REG_AX, val); proc->SetRegister(mOpcode == IDIV_MOD8 ? REG_AH : REG_DX, rem); 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; }
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 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; }