예제 #1
0
파일: Adc.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #2
0
파일: Or.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #3
0
파일: IDiv.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #4
0
파일: Neg.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #5
0
파일: Not.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #6
0
파일: Xor.cpp 프로젝트: rdnelson/Libra
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;
}