public ExecutionResult Execute(Processor cpu, InstructionPackage package) { Instruction instruction = package.Instruction; InstructionData data = package.Data; Flags flags = cpu.Flags; Registers r = cpu.Registers; sbyte offset = (sbyte)(data.Argument1); ByteRegister register = instruction.Target.AsByteRegister(); bool previousCarry = flags.Carry; byte original, shifted; if (register != ByteRegister.None) { original = r[register]; shifted = (byte)(original >> 1); shifted = shifted.SetBit(7, previousCarry); setFlags(original, shifted, original.GetBit(0)); r[register] = shifted; } else { ushort address = instruction.Prefix switch { 0xCB => r.HL, 0xDDCB => (ushort)(r.IX + offset), 0xFDCB => (ushort)(r.IY + offset), _ => (ushort)0xFFFF }; original = cpu.Memory.Timed.ReadByteAt(address); shifted = (byte)(original >> 1); shifted = shifted.SetBit(7, previousCarry); setFlags(original, shifted, original.GetBit(0)); if (instruction.IsIndexed) { cpu.Timing.InternalOperationCycle(4); } cpu.Memory.Timed.WriteByteAt(address, shifted); if (instruction.CopyResultTo != ByteRegister.None) { r[instruction.CopyResultTo.Value] = shifted; } } void setFlags(byte original, byte shifted, bool overflowBit) { flags = FlagLookup.BitwiseFlags(original, BitwiseOperation.RotateRightThroughCarry, previousCarry); flags.Carry = overflowBit; flags.HalfCarry = false; flags.Subtract = false; } return(new ExecutionResult(package, flags)); }
public ExecutionResult Execute(Processor cpu, InstructionPackage package) { Instruction instruction = package.Instruction; InstructionData data = package.Data; Registers r = cpu.Registers; Flags flags = cpu.Flags; int result = 0x00 - r.A; flags = FlagLookup.ByteArithmeticFlags(0x00, r.A, false, true); flags.ParityOverflow = r.A == 0x80; flags.Carry = r.A != 0x00; r.A = (byte)result; return(new ExecutionResult(package, flags)); }
public ExecutionResult Execute(Processor cpu, InstructionPackage package) { Instruction instruction = package.Instruction; InstructionData data = package.Data; Flags flags = cpu.Flags; Registers r = cpu.Registers; sbyte offset = (sbyte)(data.Argument1); ByteRegister register = instruction.Target.AsByteRegister(); void setFlags(byte original) { flags = FlagLookup.BitwiseFlags(original, BitwiseOperation.ShiftLeftSetBit0, flags.Carry); flags.Carry = original.GetBit(7); flags.HalfCarry = false; flags.Subtract = false; } byte original, shifted; if (register != ByteRegister.None) { original = r[register]; shifted = (byte)((original << 1) + 1); // bit 0 is always set, adding 1 does this quicker than calling SetBit setFlags(original); r[register] = shifted; } else { ushort address = instruction.Prefix switch { 0xCB => r.HL, 0xDDCB => (ushort)(r.IX + offset), 0xFDCB => (ushort)(r.IY + offset), _ => (ushort)0xFFFF }; original = cpu.Memory.Timed.ReadByteAt(address); shifted = (byte)((original << 1) + 1); setFlags(original); cpu.Memory.Timed.WriteByteAt(address, shifted); if (instruction.CopyResultTo != ByteRegister.None) { r[instruction.CopyResultTo.Value] = shifted; } } return new ExecutionResult(package, flags); }
public ExecutionResult Execute(Processor cpu, InstructionPackage package) { Instruction instruction = package.Instruction; InstructionData data = package.Data; Registers r = cpu.Registers; byte offset = data.Argument1; Flags flags = cpu.Flags; if (instruction.TargetsWordRegister) { // inc 16-bit WordRegister register = instruction.Target.AsWordRegister(); ushort value = r[register]; r[register] = (ushort)(value + 1); } else { byte value = 0; if (instruction.TargetsByteInMemory) { // inc byte in memory if (instruction.IsIndexed) { cpu.Timing.InternalOperationCycle(5); } value = instruction.MarshalSourceByte(data, cpu, out ushort address, out ByteRegister source); cpu.Memory.Timed.WriteByteAt(address, (byte)(value + 1)); } else { // it's an 8-bit inc ByteRegister register = instruction.Target.AsByteRegister(); value = r[register]; r[register] = (byte)(value + 1); } bool carry = flags.Carry; flags = FlagLookup.ByteArithmeticFlags(value, 1, false, false); flags.ParityOverflow = (value == 0x7F); flags.Carry = carry; // always unaffected flags.Subtract = false; } return(new ExecutionResult(package, flags)); }
public ExecutionResult Execute(Processor cpu, InstructionPackage package) { Instruction instruction = package.Instruction; InstructionData data = package.Data; Flags flags = cpu.Flags; Registers r = cpu.Registers; if (instruction.IsIndexed) { cpu.Timing.InternalOperationCycle(5); } byte operand = instruction.MarshalSourceByte(data, cpu, out ushort address, out ByteRegister source); int result = (r.A | operand); flags = FlagLookup.LogicalFlags(r.A, operand, LogicalOperation.Or); r.A = (byte)result; return(new ExecutionResult(package, flags)); }
public static (byte Result, Flags Flags) Add(byte left, byte right, bool carry) { Flags flags = FlagLookup.ByteArithmeticFlags(left, right, carry, false); return((byte)(left + right + (carry ? 1 : 0)), flags); }
public static (ushort Result, Flags Flags) Subtract(ushort left, ushort right, bool carry, bool setSZPV, Flags currentFlags) { Flags flags = FlagLookup.WordArithmeticFlags(currentFlags, left, right, carry, setSZPV, true); return((ushort)(left - right - (carry ? 1 : 0)), flags); }
public static (ushort Result, Flags Flags) Add(ushort left, ushort right, bool carry, bool setSZPV, Flags currentFlags) { Flags flags = FlagLookup.WordArithmeticFlags(currentFlags, left, right, carry, setSZPV, false); return((ushort)(left + right + (carry ? 1 : 0)), flags); }
public static (byte Result, Flags Flags) Subtract(byte left, byte right, bool carry) { Flags flags = FlagLookup.ByteArithmeticFlags(left, right, carry, true); return((byte)(left - right - (carry ? 1 : 0)), flags); }