public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { switch (instruction.Argument1) { case (int)Register.AX: case (int)Register.CX: case (int)Register.DX: case (int)Register.BX: case (int)Register.SP: case (int)Register.BP: case (int)Register.SI: case (int)Register.DI: case (int)Register.IP: case (int)Register.CS: case (int)Register.DS: case (int)Register.ES: case (int)Register.SS: cpu.SetRegister((Register)instruction.Argument1, ProcessExchangeSecond(cpu, instruction, cpu.GetRegister((Register)instruction.Argument1))); break; case OpCodeManager.ARG_BYTE_REGISTER: cpu.SetRegister((Register)instruction.Argument1Value, (byte)ProcessExchangeSecond(cpu, instruction, cpu.GetRegisterU8((Register)instruction.Argument1Value))); break; default: throw new NotImplementedException(); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { switch (instruction.Argument1) { case (int)Register.AX: case (int)Register.CX: case (int)Register.DX: case (int)Register.BX: case (int)Register.SP: case (int)Register.BP: case (int)Register.SI: case (int)Register.DI: case (int)Register.IP: case (int)Register.CS: case (int)Register.DS: case (int)Register.ES: case (int)Register.SS: //case unchecked((int)Register.FLAGS): cpu.SetRegister((Register)instruction.Argument1, cpu.Pop()); break; case unchecked ((int)Register.FLAGS): cpu.SetRegister((Register)instruction.Argument1, cpu.Pop()); break; case OpCodeManager.ARG_DEREFERENCE: case OpCodeManager.ARG_MEMORY: var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); cpu.WriteU16(address, cpu.Pop()); break; default: throw new ArgumentOutOfRangeException(); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement); var memory = cpu.ReadU16(address); var segment = cpu.ReadU16(address + 2); cpu.SetRegister(_register, segment); switch ((Register)instruction.Argument1) { case Register.AX: case Register.CX: case Register.DX: case Register.BX: case Register.SP: case Register.BP: case Register.SI: case Register.DI: case Register.IP: case Register.CS: case Register.DS: case Register.ES: case Register.SS: cpu.SetRegister((Register)instruction.Argument1, memory); break; default: throw new NotImplementedException(); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var value1 = cpu.GetRegister(Register.AX); var value2 = InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { value1 &= 0xFF; value2 &= 0xFF; } uint result; switch (instruction.Type) { case OpCodeManager.InstructionType.Multiply: result = (uint)value1 * value2; break; case OpCodeManager.InstructionType.SignedMultiply: result = (uint)(value1 * value2); break; default: throw new ArgumentOutOfRangeException(); } InstructionHelper.CalculateAddFlags(cpu, instruction.Flag, value1, value2, (int)result); cpu.SetRegister(Register.AX, (ushort)result); if (!instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { cpu.SetRegister(Register.DX, (ushort)(result >> 16)); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var prefix = instruction.SegmentPrefix; if (prefix == Register.Invalid) { prefix = Register.DS; } var sourceAddress = InstructionHelper.SegmentToAddress(cpu.GetRegister(prefix), cpu.GetRegister(Register.SI)); byte size; if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { cpu.SetRegisterU8(Register.AL, cpu.ReadU8(sourceAddress)); size = 1; } else { cpu.SetRegister(Register.AX, cpu.ReadU16(sourceAddress)); size = 2; } if (!cpu.GetFlags().Has(FlagsRegister.Direction)) { cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) + size)); } else { cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) - size)); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { cpu.SetRegister(Register.IP, cpu.Pop()); cpu.SetRegister(Register.CS, cpu.Pop()); cpu.SetRegister(Register.FLAGS, cpu.Pop()); //cpu._interruptStack.Pop(); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var al = cpu.GetRegister(Register.AL); cpu.SetRegister(Register.AH, (byte)(al / 10)); cpu.SetRegister(Register.AL, (byte)(al % 10)); InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, al, 0, cpu.GetRegister(Register.AX)); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { cpu.SetRegister(Register.IP, cpu.Pop()); if (instruction.Argument1 == OpCodeManager.ARG_CONSTANT) { cpu.SetRegister(Register.SP, (ushort)(cpu.GetRegister(Register.SP) + instruction.Argument1Value)); } else { Debug.Assert(instruction.Argument1 == OpCodeManager.ARG_NONE); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var address = InstructionHelper.GetInstructionAddress(cpu, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement); switch ((Register)instruction.Argument1) { case Register.AX: case Register.CX: case Register.DX: case Register.BX: case Register.SP: case Register.BP: case Register.SI: case Register.DI: case Register.IP: case Register.CS: case Register.DS: case Register.ES: case Register.SS: cpu.SetRegister((Register)instruction.Argument1, address); break; default: throw new NotImplementedException(); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var address = InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); cpu.Push(cpu.GetRegister(Register.IP)); cpu.SetRegister(Register.IP, address); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { switch (instruction.Argument1) { case OpCodeManager.ARG_FAR_MEMORY: cpu.SetRegister(Register.CS, (ushort)((uint)instruction.Argument1Value >> 16)); cpu.SetRegister(Register.IP, (ushort)(instruction.Argument1Value & 0xFFFF)); break; case OpCodeManager.ARG_DEREFERENCE: case OpCodeManager.ARG_MEMORY: var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); cpu.SetRegister(Register.CS, cpu.ReadU16(address + 2)); cpu.SetRegister(Register.IP, cpu.ReadU16(address)); break; default: throw new InvalidOperationException(); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var port = InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement); var device = cpu.GetPortDevice(port); if (device == null) { throw new InvalidOperationException($"Tried to read from port 0x{port.ToString("X")}"); } if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { cpu.SetRegister(Register.AL, device.Read(port)); //Console.WriteLine($"IN {port.ToString("X")}:{cpu.GetRegister(Register.AL).ToString("X")}"); } else { cpu.SetRegister(Register.AX, device.Read16(port)); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var segment = Register.DS; if (instruction.SegmentPrefix != Register.Invalid) { segment = instruction.SegmentPrefix; } ushort value1; ushort value2; byte size; if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { value1 = cpu.ReadU8(InstructionHelper.SegmentToAddress(cpu.GetRegister(segment), cpu.GetRegister(Register.SI))); value2 = cpu.ReadU8(InstructionHelper.SegmentToAddress(cpu.GetRegister(Register.ES), cpu.GetRegister(Register.DI))); size = 1; } else { value1 = cpu.ReadU16(InstructionHelper.SegmentToAddress(cpu.GetRegister(segment), cpu.GetRegister(Register.SI))); value2 = cpu.ReadU16(InstructionHelper.SegmentToAddress(cpu.GetRegister(Register.ES), cpu.GetRegister(Register.DI))); size = 2; } var result = value1 - value2; InstructionHelper.CalculateSubFlags(cpu, instruction.Flag, value1, value2, result); if (!cpu.GetFlags().Has(FlagsRegister.Direction)) { cpu.SetRegister(Register.DI, (ushort)(cpu.GetRegister(Register.DI) + size)); cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) + size)); } else { cpu.SetRegister(Register.DI, (ushort)(cpu.GetRegister(Register.DI) - size)); cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) - size)); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var value1 = (int)(((uint)cpu.GetRegister(Register.DX) << 16) | cpu.GetRegister(Register.AX)); int value2 = (short)InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); if ((uint)value1 == 0x80000000 || value2 == 0) { cpu.Interrupt(0); return; } var quotient = value1 / value2; var remainder = value1 % value2; if ((quotient & 0xFFFF) != quotient) { cpu.Interrupt(0); return; } cpu.SetRegister(Register.AX, (ushort)quotient); cpu.SetRegister(Register.DX, (ushort)remainder); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var al = cpu.GetRegisterU8(Register.AL); var oldAl = al; var flags = cpu.GetFlags(); var oldCarry = flags.Has(FlagsRegister.Carry); flags &= ~FlagsRegister.Carry; if ((al & 0xF) > 9 || flags.Has(FlagsRegister.Auxiliary)) { al -= 6; if (oldCarry || (al > oldAl)) { flags |= FlagsRegister.Carry; } else { flags &= ~FlagsRegister.Carry; } flags |= FlagsRegister.Auxiliary; } else { flags &= ~FlagsRegister.Auxiliary; } if (oldAl > 0x99 || oldCarry) { al -= 0x60; flags |= FlagsRegister.Carry; } else { flags &= ~FlagsRegister.Carry; } flags &= ~(FlagsRegister.Parity | FlagsRegister.Zero | FlagsRegister.Sign); flags |= (InstructionHelper.ParityLookup[al] ? FlagsRegister.Parity : 0) | (al == 0 ? FlagsRegister.Zero : 0) | ((al & 0x80) != 0 ? FlagsRegister.Sign : 0); cpu.SetFlags(flags); cpu.SetRegister(Register.AL, al); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var value = InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement); switch (instruction.Argument1) { case (int)Register.AX: case (int)Register.CX: case (int)Register.DX: case (int)Register.BX: case (int)Register.SP: case (int)Register.BP: case (int)Register.SI: case (int)Register.DI: case (int)Register.IP: case (int)Register.CS: case (int)Register.DS: case (int)Register.ES: case (int)Register.SS: cpu.SetRegister((Register)instruction.Argument1, value); break; case OpCodeManager.ARG_BYTE_REGISTER: cpu.SetRegisterU8((Register)instruction.Argument1Value, (byte)value); break; case OpCodeManager.ARG_DEREFERENCE: case OpCodeManager.ARG_MEMORY: var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { cpu.WriteU8(address, (byte)value); } else { cpu.WriteU16(address, value); } break; default: throw new NotImplementedException(); } }
private ushort ProcessExchangeSecond(Cpu8086 cpu, OpCodeManager.Instruction instruction, ushort value) { ushort tmp; switch (instruction.Argument2) { case (int)Register.AX: case (int)Register.CX: case (int)Register.DX: case (int)Register.BX: case (int)Register.SP: case (int)Register.BP: case (int)Register.SI: case (int)Register.DI: case (int)Register.IP: case (int)Register.CS: case (int)Register.DS: case (int)Register.ES: case (int)Register.SS: tmp = cpu.GetRegister((Register)instruction.Argument2); cpu.SetRegister((Register)instruction.Argument2, (byte)value); break; case OpCodeManager.ARG_BYTE_REGISTER: tmp = cpu.GetRegisterU8((Register)instruction.Argument2Value); cpu.SetRegisterU8((Register)instruction.Argument2Value, (byte)value); break; case OpCodeManager.ARG_DEREFERENCE: case OpCodeManager.ARG_MEMORY: var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement); tmp = cpu.ReadU16(address); cpu.WriteU16(address, value); break; default: throw new NotImplementedException(); } return(tmp); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { cpu.SetRegister(Register.AX, (ushort)(sbyte)cpu.GetRegisterU8(Register.AL)); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { cpu.SetRegister(Register.DX, (cpu.GetRegister(Register.AX) & 0x8000) != 0 ? (ushort)0xFFFF : (ushort)0); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var value1 = InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); var value2 = InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement); if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { value1 &= 0xFF; value2 &= 0xFF; } int result; bool carry; switch (instruction.Type) { case OpCodeManager.InstructionType.Adc: result = value1 + value2 + (cpu.GetFlags().Has(FlagsRegister.Carry) ? 1 : 0); InstructionHelper.CalculateAddFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Add: result = value1 + value2; InstructionHelper.CalculateAddFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.And: case OpCodeManager.InstructionType.Test: result = value1 & value2; InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Compare: case OpCodeManager.InstructionType.Subtract: result = value1 - value2; InstructionHelper.CalculateSubFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Or: result = value1 | value2; InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Rcl: if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { const int mask = 0x1FF; var shift = (value2 & 0x1F) % 9; result = (byte)value1; if (cpu.Flags.Has(FlagsRegister.Carry)) { result |= 0x100; } result = (byte)(result << shift) | (byte)(result >> (-shift & mask)); if ((result & 0x100) != 0) { cpu.Flags |= FlagsRegister.Carry; } else { cpu.Flags &= ~FlagsRegister.Carry; } if (value2 == 1) { if (((result & 0x100) != 0) ^ ((result & 0x80) != 0)) { cpu.Flags |= FlagsRegister.Overflow; } else { cpu.Flags &= ~FlagsRegister.Overflow; } } } else { const int mask = 0x1FFFF; var shift = (value2 & 0x1F) % 17; result = value1; if (cpu.Flags.Has(FlagsRegister.Carry)) { result |= 0x10000; } result = (ushort)(result << shift) | (ushort)(result >> (-shift & mask)); if ((result & 0x10000) != 0) { cpu.Flags |= FlagsRegister.Carry; } else { cpu.Flags &= ~FlagsRegister.Carry; } if (value2 == 1) { if (((result & 0x10000) != 0) ^ ((result & 0x8000) != 0)) { cpu.Flags |= FlagsRegister.Overflow; } else { cpu.Flags &= ~FlagsRegister.Overflow; } } } InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Rcr: if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { const int mask = 0x1FF; var shift = (value2 & 0x1F) % 9; result = (byte)value1; if (cpu.Flags.Has(FlagsRegister.Carry)) { result |= 0x100; } if ((result & 0x1) != 0) { cpu.Flags |= FlagsRegister.Carry; } else { cpu.Flags &= ~FlagsRegister.Carry; } result = (byte)(result >> shift) | (byte)(result << (-shift & mask)); if (value2 == 1) { if (((result & 0x80) != 0) ^ ((result & 0x40) != 0)) { cpu.Flags |= FlagsRegister.Overflow; } else { cpu.Flags &= ~FlagsRegister.Overflow; } } } else { const int mask = 0x1FFFF; var shift = (value2 & 0x1F) % 17; result = value1; if (cpu.Flags.Has(FlagsRegister.Carry)) { result |= 0x10000; } if ((result & 0x1) != 0) { cpu.Flags |= FlagsRegister.Carry; } else { cpu.Flags &= ~FlagsRegister.Carry; } result = (ushort)(result >> shift) | (ushort)(result << (-shift & mask)); if (value2 == 1) { if (((result & 0x8000) != 0) ^ ((result & 0x4000) != 0)) { cpu.Flags |= FlagsRegister.Overflow; } else { cpu.Flags &= ~FlagsRegister.Overflow; } } } //cpu.CalculateBitwiseFlags(instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Rol: if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { const int mask = 0xFF; var shift = value2 & mask; result = (byte)(value1 << shift) | (byte)(value1 >> (-shift & mask)); } else { const int mask = 0xFFFF; var shift = value2 & mask; result = (ushort)(value1 << shift) | (ushort)(value1 >> (-shift & mask)); } InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Ror: if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { const int mask = 0xFF; var shift = value2 & mask; result = (byte)(value1 >> shift) | (byte)(value1 << (-shift & mask)); } else { const int mask = 0xFFFF; var shift = value2 & mask; result = (ushort)(value1 >> shift) | (ushort)(value1 << (-shift & mask)); } InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Sbb: result = value1 - (value2 + (cpu.GetFlags().Has(FlagsRegister.Carry) ? 1 : 0)); InstructionHelper.CalculateSubFlags(cpu, instruction.Flag, value1, value2, result); break; case OpCodeManager.InstructionType.Shl: bool overflow; result = value1 << (value2 & 0x1F); InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, (ushort)(value2 & 0x1F), result); if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { carry = (result & 0x100) != 0; overflow = (result & 0x80) != 0; } else { carry = (result & 0x10000) != 0; overflow = (result & 0x8000) != 0; } if (carry) { cpu.Flags |= FlagsRegister.Carry; } if ((value2 & 0x1F) == 1 && overflow ^ carry) { cpu.Flags |= FlagsRegister.Overflow; } break; case OpCodeManager.InstructionType.Sar: if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { carry = (((sbyte)value1 >> ((value2 & 0x1F) - 1)) & 1) != 0; result = (sbyte)value1 >> (value2 & 0x1F); } else { carry = (((short)value1 >> ((value2 & 0x1F) - 1)) & 1) != 0; result = (short)value1 >> (value2 & 0x1F); } InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, (ushort)(value2 & 0x1F), result); if (carry) { cpu.Flags |= FlagsRegister.Carry; } break; case OpCodeManager.InstructionType.Shr: carry = ((value1 >> ((value2 & 0x1F) - 1)) & 1) != 0; result = value1 >> (value2 & 0x1F); InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, (ushort)(value2 & 0x1F), result); if (carry) { cpu.Flags |= FlagsRegister.Carry; } if ((value2 & 0x1F) == 1) { if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { if ((value1 & 0x80) != 0) { cpu.Flags |= FlagsRegister.Overflow; } } else { if ((value1 & 0x8000) != 0) { cpu.Flags |= FlagsRegister.Overflow; } } } break; case OpCodeManager.InstructionType.Xor: result = value1 ^ value2; InstructionHelper.CalculateBitwiseFlags(cpu, instruction.Flag, value1, value2, result); break; default: throw new NotImplementedException(); } var truncResult = instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8) ? (byte)result : (ushort)result; if (instruction.Type != OpCodeManager.InstructionType.Compare && instruction.Type != OpCodeManager.InstructionType.Test) { switch (instruction.Argument1) { case (int)Register.AX: case (int)Register.CX: case (int)Register.DX: case (int)Register.BX: case (int)Register.SP: case (int)Register.BP: case (int)Register.SI: case (int)Register.DI: case (int)Register.IP: case (int)Register.CS: case (int)Register.DS: case (int)Register.ES: case (int)Register.SS: cpu.SetRegister((Register)instruction.Argument1, truncResult); break; case OpCodeManager.ARG_BYTE_REGISTER: cpu.SetRegisterU8((Register)instruction.Argument1Value, (byte)truncResult); break; case OpCodeManager.ARG_DEREFERENCE: case OpCodeManager.ARG_MEMORY: var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { cpu.WriteU8(address, (byte)truncResult); } else { cpu.WriteU16(address, truncResult); } break; default: throw new NotImplementedException(); } } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) => cpu.SetRegister(Register.AH, (byte)cpu.GetFlags());
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { var value = InstructionHelper.GetInstructionValue(cpu, instruction.Flag, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); int result; switch (instruction.Type) { case OpCodeManager.InstructionType.Decrement: result = value - 1; InstructionHelper.CalculateDecFlags(cpu, instruction.Flag, value, 1, result); break; case OpCodeManager.InstructionType.Increment: result = value + 1; InstructionHelper.CalculateIncFlags(cpu, instruction.Flag, value, 1, result); break; case OpCodeManager.InstructionType.Negate: result = ~value + 1; InstructionHelper.CalculateSubFlags(cpu, instruction.Flag, 0, value, result); break; case OpCodeManager.InstructionType.Not: result = ~value; break; default: throw new OutOfMemoryException(); } switch (instruction.Argument1) { case (int)Register.AX: case (int)Register.CX: case (int)Register.DX: case (int)Register.BX: case (int)Register.SP: case (int)Register.BP: case (int)Register.SI: case (int)Register.DI: case (int)Register.IP: case (int)Register.CS: case (int)Register.DS: case (int)Register.ES: case (int)Register.SS: cpu.SetRegister((Register)instruction.Argument1, (ushort)result); break; case OpCodeManager.ARG_BYTE_REGISTER: cpu.SetRegisterU8((Register)instruction.Argument1Value, (byte)result); break; case OpCodeManager.ARG_DEREFERENCE: case OpCodeManager.ARG_MEMORY: var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement); if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8)) { cpu.WriteU8(address, (byte)result); } else { cpu.WriteU16(address, (ushort)result); } break; default: throw new NotImplementedException(); } }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { Debug.Assert(instruction.Argument1 == OpCodeManager.ARG_CONSTANT); cpu.Push(cpu.GetRegister(Register.IP)); cpu.SetRegister(Register.IP, (ushort)(cpu.GetRegister(Register.IP) + instruction.Argument1Value)); }
public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction) { ushort counter; switch (instruction.OpcodePrefix) { case 0: new OneStringOperation().Dispatch(cpu, instruction); break; case 0xF2: counter = cpu.GetRegister(Register.CX); if (instruction.Type == OpCodeManager.InstructionType.Cmps || instruction.Type == OpCodeManager.InstructionType.Scas) { while (counter != 0) { new OneStringOperation().Dispatch(cpu, instruction); counter--; if (cpu.GetFlags().Has(FlagsRegister.Zero)) { break; } } } else { while (counter != 0) { new OneStringOperation().Dispatch(cpu, instruction); counter--; } } cpu.SetRegister(Register.CX, counter); break; case 0xF3: counter = cpu.GetRegister(Register.CX); if (instruction.Type == OpCodeManager.InstructionType.Cmps || instruction.Type == OpCodeManager.InstructionType.Scas) { while (counter != 0) { new OneStringOperation().Dispatch(cpu, instruction); counter--; if (!cpu.GetFlags().Has(FlagsRegister.Zero)) { break; } } } else { while (counter != 0) { new OneStringOperation().Dispatch(cpu, instruction); counter--; } } cpu.SetRegister(Register.CX, counter); break; default: throw new NotImplementedException(); } }