public CPU(MMU mmu, Clock clock) { this.clock = clock; this.mmu = mmu; this.Registers = new Registers(mmu); this.ControlUnit = new ControlUnit(mmu, this.Registers); }
public Cpu(IRegisters registers, IRam ram) { this.registers = registers; this.ram = ram; this.destinationProvider = new DestinationProvider(registers, ram); this.sourceProvider = new SourceProvider(registers, ram); }
/// <summary> /// Constructor for injecting an observed set of registers for unit testing. /// </summary> /// <param name="mmu"> /// Memory subsystem of the Game Boy /// </param> /// <param name="reg"> /// A Set of registers that the CPU needs. Here the registers are being injected, /// so that they can be observed by unit tests. /// </param> public CPU(MMU mmu, IRegisters reg) { Registers = reg; clock = new Clock(); this.mmu = mmu; ControlUnit = new ControlUnit(mmu, reg); }
void IPipeline.DecodeAndExecute( byte instruction, IRegisters registers, IMemory memory) { mLog.Info( "Decoding and executing: {0:D8}", Convert.ToString(instruction, 2)); switch (instruction) { case 0x00: NopInstr.ExecuteNop(registers); return; //case 0xAF: // LoadInstr.Execute_Ld_r_r(instruction, registers); // return; case 0xC3: JumpInstr.Execute_Jp_nn(registers, memory); return; default: mLog.Error("Instruction not implemented."); throw new NotImplementedException(); } }
/// <summary> /// Initializes a new instance of the <see cref="InterpreterHelper"/> class. /// </summary> /// <param name="operation">The operation.</param> /// <param name="registers">The registers.</param> /// <param name="mmu">The mmu.</param> /// <param name="alu">The alu.</param> /// <param name="peripheralManager">The peripheral manager.</param> public InterpreterHelper(IRegisters registers, IMmu mmu, IAlu alu, IPeripheralManager peripheralManager) { _registers = registers; _mmu = mmu; _alu = alu; _peripheralManager = peripheralManager; }
public ushort LoadRegistersFromMemory(IRegisters registers, ushort startAddress) { ushort address = startAddress; registers.AF = GetSWordAtAddress(address); address += 2; registers.BC = GetSWordAtAddress(address); address += 2; registers.DE = GetSWordAtAddress(address); address += 2; registers.HL = GetSWordAtAddress(address); address += 2; registers.IX = GetSWordAtAddress(address); address += 2; registers.IY = GetSWordAtAddress(address); address += 2; registers.SP = GetSWordAtAddress(address); address += 2; registers.PC = GetWordAtAddress(address); address += 2; registers.AltAF = GetSWordAtAddress(address); address += 2; registers.AltBC = GetSWordAtAddress(address); address += 2; registers.AltDE = GetSWordAtAddress(address); address += 2; registers.AltHL = GetSWordAtAddress(address); return(address); }
public ushort SaveRegistersToMemory(IRegisters registers, ushort startAddress) { ushort address = startAddress; SetSWordAtAddress(address, registers.AF); address += 2; SetSWordAtAddress(address, registers.BC); address += 2; SetSWordAtAddress(address, registers.DE); address += 2; SetSWordAtAddress(address, registers.HL); address += 2; SetSWordAtAddress(address, registers.IX); address += 2; SetSWordAtAddress(address, registers.IY); address += 2; SetSWordAtAddress(address, registers.SP); address += 2; SetWordAtAddress(address, registers.PC); address += 2; SetSWordAtAddress(address, registers.AltAF); address += 2; SetSWordAtAddress(address, registers.AltBC); address += 2; SetSWordAtAddress(address, registers.AltDE); address += 2; SetSWordAtAddress(address, registers.AltHL); return(address); }
/// <summary> /// Initializes a new instance of the <see cref="CpuCoreBase" /> class. /// </summary> /// <param name="registers">The registers.</param> /// <param name="interruptManager">The interrupt manager.</param> /// <param name="peripheralManager">The peripheral manager.</param> /// <param name="mmu">The mmu.</param> /// <param name="instructionTimer">The instruction timer.</param> /// <param name="alu">The alu.</param> /// <param name="opCodeDecoder">The opcode decoder.</param> /// <param name="instructionBlockFactory">The instruction block decoder.</param> /// <param name="dmaController">The dma controller.</param> /// <param name="messageBus">The message bus.</param> /// <param name="requireInstructionBlockCaching">if set to <c>true</c> [require instruction block caching].</param> /// <exception cref="ArgumentException">Instruction block decoder must support caching</exception> protected CpuCoreBase(IRegisters registers, IInterruptManager interruptManager, IPeripheralManager peripheralManager, IMmu mmu, IInstructionTimer instructionTimer, IAlu alu, IOpCodeDecoder opCodeDecoder, IInstructionBlockFactory instructionBlockFactory, IDmaController dmaController, IMessageBus messageBus, bool requireInstructionBlockCaching) { CoreId = Guid.NewGuid(); _registers = registers; _interruptManager = interruptManager; _peripheralManager = peripheralManager; _mmu = mmu; _instructionTimer = instructionTimer; _alu = alu; _opCodeDecoder = opCodeDecoder; _instructionBlockFactory = instructionBlockFactory; _dmaController = dmaController; _messageBus = messageBus; messageBus.RegisterHandler(Message.PauseCpu, Pause); messageBus.RegisterHandler(Message.ResumeCpu, Resume); if (requireInstructionBlockCaching && !_instructionBlockFactory.SupportsInstructionBlockCaching) { throw new ArgumentException("Instruction block decoder must support caching"); } }
public void SetUp() { mmu = new MMU(); regs = new Registers(mmu); cpu = new CPU(mmu, regs); regs.SP--; }
public Processor(IRegisters registers, IIntreruptQueue intreruptQueue, IMemory memory, IDiagnosticsService diagnosticsService) { _registers = registers; _intreruptQueue = intreruptQueue; _memory = memory; _diagnosticsService = diagnosticsService; }
private string GetFlags(IRegisters registers) { var flags = Convert.ToString(registers.F, 2).PadLeft(8, '0'); flags = flags.Substring(0, 2) + "X" + flags.Substring(3, 1) + "X" + flags.Substring(5, 3); return(flags); }
public Cpu(IRandomAccessMemory memory, IRegisters registers, IFlags flags, IEmulatorInstructionFactory instructionFactory) { Memory = memory ?? throw new ArgumentNullException(nameof(memory)); Registers = registers; this.instructionFactory = instructionFactory; Flags = flags; }
public void TestBitByte(IRegisters registers, int bit, byte value) { if ((value & (1 << bit)) > 0) { registers.ZeroFlag = true; } registers.NegativeFlag = false; registers.HalfCarryFlag = true; }
/// <summary> /// Initializes a new instance of the <see cref="InterruptManager"/> class. /// </summary> /// <param name="registers">The registers.</param> /// <param name="instructionTimer">The instruction timer.</param> public InterruptManager(IRegisters registers, IInstructionTimer instructionTimer) { _registers = registers; _instructionTimer = instructionTimer; _haltTaskSource = new TaskCompletionSource <bool>(); _nextInterruptSource = new TaskCompletionSource <ushort>(); _cancellationSource = new CancellationTokenSource(); Task.Factory.StartNew(InterruptTask, TaskCreationOptions.LongRunning); }
public static void Execute_Ld_r_r(byte instruction, IRegisters registers) { mLog.Info("LD r,r'"); byte destination = (byte)(instruction & 0x38); byte source = (byte)(instruction & 0x07); throw new NotImplementedException(); }
static void PrintProcessorState(IMemory memory, IRegisters registers) { var registerPointingColors = new Dictionary <RegisterType, ConsoleColor>() { [RegisterType.Ip] = ConsoleColor.Blue, [RegisterType.Pip] = ConsoleColor.DarkYellow }; var regDict = new Dictionary <RegisterType, int>(); ConsoleColor GetConsoleColor(RegisterType registerType) { if (registerPointingColors.ContainsKey(registerType)) { return(registerPointingColors[registerType]); } return(ConsoleColor.Black); } // print registers foreach (var regType in Enum.GetValues(typeof(RegisterType))) { var typedRegisterType = (RegisterType)regType; var regValue = registers.Read(typedRegisterType); regDict[typedRegisterType] = regValue; PrintInColor(GetConsoleColor(typedRegisterType), $"{typedRegisterType} = {regValue}\n"); } Console.Write("\n"); for (int i = 0; i < 256; i++) { if (i % 16 == 0) { Console.Write($"\n|"); } var regMatching = regDict.Where(x => x.Value == i && registerPointingColors.ContainsKey(x.Key)).ToList(); var color = regMatching.Any() ? GetConsoleColor(regMatching.First().Key) : ConsoleColor.Black; Console.Write(" "); PrintInColor(color, $"{memory.Read(i): 000}"); Console.Write(" |"); } Console.WriteLine(); // print memory }
private void WriteTrace(IRegisters registers, object instruction, string flags) { Console.WriteLine("{0:X4} : {1} FLG: {2} A:{3:X2} BC:{4:X4} DE:{5:X4} HL:{6:X4} IX:{7:X4} IY:{8:X4}", registers.PC, instruction, flags, registers.A, registers.BC, registers.DE, registers.HL, registers.IX, registers.IY); }
public Cpu( IClock clock, IMemory memory, IRegisters registers, IPipeline pipeline) { mClock = clock; mMemory = memory; mRegisters = registers; mPipeline = pipeline; }
public Mmu(IMemoryMap memoryMap, IRegisters registers) { this.MemoryMap = memoryMap; this.Registers = registers; // TODO: Initialize IO memory this.Stack = new Stack(this.MemoryMap, this.Registers.Sp); this.Reset(); }
public static void Execute_Jp_nn(IRegisters registers, IMemory memory) { mLog.Info("JP nn"); registers.PC++; byte l = memory[registers.PC]; registers.PC++; byte h = memory[registers.PC]; registers.PC = BitConverter.ToUInt16(new byte[] { l, h }, 0); }
public static void ToConsole(this IRegisters registers) { WriteRegister("PC", registers.ProgramCounter); WriteRegister("SP", registers.StackPointer); Console.WriteLine(); for (byte index = 0; index < 8; index++) { WriteRegister($"R{index}", registers[index]); } Console.WriteLine(); }
private InstructionTimings Interpret(IRegisters registers, IMmu mmu, IAlu alu, IPeripheralManager peripherals, DecodedBlock block) { var helper = new InterpreterHelper(registers, mmu, alu, peripherals); var result = block.Operations.Select(o => Interpret(registers, mmu, alu, peripherals, helper, o, block)).Aggregate((t0, t1) => t0 + t1); if (_cpuMode == CpuMode.Z80) { // Add the block length to the 7 lsb of memory refresh register. registers.R = (byte)((registers.R + block.Length) & 0x7f); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="CpuCore" /> class. /// </summary> /// <param name="registers">The registers.</param> /// <param name="interruptManager">The interrupt manager.</param> /// <param name="peripheralManager">The peripheral manager.</param> /// <param name="mmu">The mmu.</param> /// <param name="instructionTimer">The instruction timer.</param> /// <param name="alu">The alu.</param> /// <param name="opCodeDecoder">The opcode decoder.</param> /// <param name="instructionBlockFactory">The instruction block decoder.</param> /// <param name="dmaController">The dma controller.</param> /// <param name="messageBus">The message bus.</param> public CpuCore(IRegisters registers, IInterruptManager interruptManager, IPeripheralManager peripheralManager, IMmu mmu, IInstructionTimer instructionTimer, IAlu alu, IOpCodeDecoder opCodeDecoder, IInstructionBlockFactory instructionBlockFactory, IDmaController dmaController, IMessageBus messageBus) : base(registers, interruptManager, peripheralManager, mmu, instructionTimer, alu, opCodeDecoder, instructionBlockFactory, dmaController, messageBus, false) { }
public InterpreterEngine() { Registers = new Registers(); _instructions = new Dictionary <string, IExecutableInstruction>(); _instructions.Add("LD", new LoadInstruction()); _instructions.Add("ADD", new AddInstruction()); _instructions.Add("MOV", new MovInstruction()); _instructions.Add("SUB", new SubInstruction()); _instructions.Add("BR", new BrInstruction()); _instructions.Add("BRGZ", new BrGzInstruction()); _instructions.Add("CLEAR", new ClearInstruction()); _instructions.Add("SYSCALL", new SyscallInstruction()); _ip = 0; }
private void RefreshRegisters() { _registers = businessLogic.GetRegisters(); afRegisterLabel.Content = $"0x{_registers.AF.ToString("X4")}"; bcRegisterLabel.Content = $"0x{_registers.BC.ToString("X4")}"; deRegisterLabel.Content = $"0x{_registers.DE.ToString("X4")}"; hlRegisterLabel.Content = $"0x{_registers.HL.ToString("X4")}"; spRegisterLabel.Content = $"0x{_registers.SP.ToString("X4")}"; pcRegisterLabel.Content = $"0x{_registers.PC.ToString("X4")}"; zFlagCheckbox.IsChecked = _registers.ZFlag == 1; nFlagCheckbox.IsChecked = _registers.NFlag == 1; hFlagCheckbox.IsChecked = _registers.HFlag == 1; cFlagCheckbox.IsChecked = _registers.CFlag == 1; imeCheckbox.IsChecked = _registers.IME; cycleCountLabel.Content = _registers.CycleCount; }
public void DecrementMemory(IRegisters registers, IMemory memory, ushort address) { int result = memory.ReadByte(address); int originalValue = result; result -= 1; registers.NegativeFlag = false; if ((result & 0xFF) == 0) { registers.ZeroFlag = true; } if (!(((originalValue & 0x0F) - (1 & 0x0F)) < 0)) { registers.HalfCarryFlag = true; } //ignore carry flag memory.WriteByte(address, (byte)result); }
public Processor(IMemory memory, IRegisters registers, ITeleprinter teleprinter) { Memory = memory ?? throw new ArgumentNullException(nameof(memory)); Teleprinter = teleprinter ?? throw new ArgumentNullException(nameof(teleprinter)); Registers = registers ?? throw new ArgumentNullException(nameof(registers)); Interrupts = new Interrupts(registers, memory, teleprinter); group1Instructions = new Group1Instructions(this); group3Instructions = new Group3Instructions(this); memoryReferenceInstructions = new MemoryReferenceInstructions(this); noOperationInstruction = new NoOperationInstruction(this); group2ANDInstructions = new Group2ANDInstructions(this); group2ORInstructions = new Group2ORInstructions(this); memoryManagementInstructions = new MemoryManagementInstructions(this); keyboardInstructions = new KeyboardInstructions(this); teleprinterInstructions = new TeleprinterInstructions(this); interruptInstructions = new InterruptInstructions(this); privilegedNoOperationInstruction = new PrivilegedNoOperationInstruction(this); }
static void PrintMemory(IMemory memory, IRegisters registers) { for (int i = 0; i < 256; i++) { if (registers.Read(RegisterType.Ip) == i) { Console.BackgroundColor = ConsoleColor.Blue; } if (registers.Read(RegisterType.Pip) == i) { Console.BackgroundColor = ConsoleColor.DarkBlue; } if (i % 16 == 0) { Console.Write($"\n|"); } Console.Write($" {memory.Read(i) : 000} |"); Console.BackgroundColor = ConsoleColor.Black; } Console.WriteLine(); }
public Interrupts(IRegisters registers, IMemory memory, ITeleprinter teleprinter) { this.registers = registers; this.memory = memory; this.teleprinter = teleprinter; }
private InstructionTimings Interpret(IRegisters registers, IMmu mmu, IAlu alu, IPeripheralManager peripherals, InterpreterHelper helper, Operation operation, DecodedBlock block) { helper.Operation = operation; var timer = new InstructionTimingsBuilder(); switch (operation.OpCode) { case OpCode.NoOperation: break; case OpCode.Stop: case OpCode.Halt: SyncProgramCounter(registers, block); break; case OpCode.Load: if (operation.Operand1 == operation.Operand2) { break; } helper.Operand1 = helper.Operand2; if (operation.Operand2 == Operand.I || operation.Operand2 == Operand.R) { // LD A, R & LD A, I also reset H & N and copy IFF2 to P/V registers.AccumulatorAndFlagsRegisters.Flags.SetResultFlags(registers.AccumulatorAndFlagsRegisters.A); registers.AccumulatorAndFlagsRegisters.Flags.HalfCarry = false; registers.AccumulatorAndFlagsRegisters.Flags.Subtract = false; registers.AccumulatorAndFlagsRegisters.Flags.ParityOverflow = registers.InterruptFlipFlop2; } break; case OpCode.Load16: helper.WordOperand1 = helper.WordOperand2; break; case OpCode.Push: helper.PushStackPointer(); mmu.WriteWord(registers.StackPointer, helper.WordOperand1); break; case OpCode.Pop: helper.WordOperand1 = mmu.ReadWord(registers.StackPointer); helper.PopStackPointer(); break; case OpCode.Add: helper.Alu8BitOperation(alu.Add); break; case OpCode.AddWithCarry: helper.Alu8BitOperation(alu.AddWithCarry); break; case OpCode.Subtract: helper.Alu8BitOperation(alu.Subtract); break; case OpCode.SubtractWithCarry: helper.Alu8BitOperation(alu.SubtractWithCarry); break; case OpCode.And: helper.Alu8BitOperation(alu.And); break; case OpCode.Or: helper.Alu8BitOperation(alu.Or); break; case OpCode.Xor: helper.Alu8BitOperation(alu.Xor); break; case OpCode.Compare: alu.Compare(registers.AccumulatorAndFlagsRegisters.A, helper.Operand1); break; case OpCode.Increment: helper.Operand1 = alu.Increment(helper.Operand1); break; case OpCode.Decrement: helper.Operand1 = alu.Decrement(helper.Operand1); break; case OpCode.Add16: helper.Alu16BitOperation(alu.Add); break; case OpCode.AddWithCarry16: helper.Alu16BitOperation(alu.AddWithCarry); break; case OpCode.SubtractWithCarry16: helper.Alu16BitOperation(alu.SubtractWithCarry); break; case OpCode.Increment16: // INC ss (no flags changes so implemented directly) helper.WordOperand1 = (ushort)(helper.WordOperand1 + 1); break; case OpCode.Decrement16: // DEC ss (no flags changes so implemented directly) helper.WordOperand1 = (ushort)(helper.WordOperand1 - 1); break; case OpCode.Exchange: { var w = helper.WordOperand2; helper.WordOperand2 = helper.WordOperand1; helper.WordOperand1 = w; } break; case OpCode.ExchangeAccumulatorAndFlags: registers.SwitchToAlternativeAccumulatorAndFlagsRegisters(); break; case OpCode.ExchangeGeneralPurpose: registers.SwitchToAlternativeGeneralPurposeRegisters(); break; case OpCode.Jump: if (operation.FlagTest == FlagTest.None || helper.DoFlagTest()) { registers.ProgramCounter = helper.WordOperand1; } else { SyncProgramCounter(registers, block); } break; case OpCode.JumpRelative: if (operation.FlagTest == FlagTest.None || helper.DoFlagTest()) { helper.JumpToDisplacement(); if (operation.FlagTest != FlagTest.None) { timer.Add(1, 5); } } SyncProgramCounter(registers, block); break; case OpCode.DecrementJumpRelativeIfNonZero: registers.GeneralPurposeRegisters.B--; if (registers.GeneralPurposeRegisters.B != 0) { helper.JumpToDisplacement(); timer.Add(1, 5); } SyncProgramCounter(registers, block); break; case OpCode.Call: SyncProgramCounter(registers, block); if (operation.FlagTest == FlagTest.None || helper.DoFlagTest()) { helper.PushStackPointer(); mmu.WriteWord(registers.StackPointer, registers.ProgramCounter); registers.ProgramCounter = helper.WordOperand1; if (operation.FlagTest != FlagTest.None) { timer.Add(2, 7); } } break; case OpCode.Return: if (operation.FlagTest == FlagTest.None || helper.DoFlagTest()) { registers.ProgramCounter = mmu.ReadWord(registers.StackPointer); helper.PopStackPointer(); if (operation.FlagTest != FlagTest.None) { timer.Add(2, 6); } } else { SyncProgramCounter(registers, block); } break; case OpCode.ReturnFromInterrupt: registers.ProgramCounter = mmu.ReadWord(registers.StackPointer); helper.PopStackPointer(); registers.InterruptFlipFlop1 = true; break; case OpCode.ReturnFromNonmaskableInterrupt: registers.ProgramCounter = mmu.ReadWord(registers.StackPointer); helper.PopStackPointer(); registers.InterruptFlipFlop1 = registers.InterruptFlipFlop2; break; case OpCode.Reset: SyncProgramCounter(registers, block); helper.PushStackPointer(); mmu.WriteWord(registers.StackPointer, registers.ProgramCounter); registers.ProgramCounter = helper.WordOperand1; break; case OpCode.Input: helper.Operand1 = peripherals.ReadByteFromPort(helper.Operand2, operation.Operand2 == Operand.n ? registers.AccumulatorAndFlagsRegisters.A : registers.GeneralPurposeRegisters.B); break; case OpCode.Output: peripherals.WriteByteToPort(helper.Operand2, operation.Operand2 == Operand.n ? registers.AccumulatorAndFlagsRegisters.A : registers.GeneralPurposeRegisters.B, helper.Operand1); break; case OpCode.RotateLeftWithCarry: helper.Operand1 = alu.RotateLeftWithCarry(helper.Operand1); if (operation.OpCodeMeta == OpCodeMeta.UseAlternativeFlagAffection) { registers.AccumulatorAndFlagsRegisters.Flags.Zero = false; registers.AccumulatorAndFlagsRegisters.Flags.Sign = false; } break; case OpCode.RotateLeft: helper.Operand1 = alu.RotateLeft(helper.Operand1); if (operation.OpCodeMeta == OpCodeMeta.UseAlternativeFlagAffection) { registers.AccumulatorAndFlagsRegisters.Flags.Zero = false; registers.AccumulatorAndFlagsRegisters.Flags.Sign = false; } break; case OpCode.RotateRightWithCarry: helper.Operand1 = alu.RotateRightWithCarry(helper.Operand1); if (operation.OpCodeMeta == OpCodeMeta.UseAlternativeFlagAffection) { registers.AccumulatorAndFlagsRegisters.Flags.Zero = false; registers.AccumulatorAndFlagsRegisters.Flags.Sign = false; } break; case OpCode.RotateRight: helper.Operand1 = alu.RotateRight(helper.Operand1); if (operation.OpCodeMeta == OpCodeMeta.UseAlternativeFlagAffection) { registers.AccumulatorAndFlagsRegisters.Flags.Zero = false; registers.AccumulatorAndFlagsRegisters.Flags.Sign = false; } break; case OpCode.RotateLeftDigit: { var result = alu.RotateLeftDigit(registers.AccumulatorAndFlagsRegisters.A, mmu.ReadByte(registers.GeneralPurposeRegisters.HL)); registers.AccumulatorAndFlagsRegisters.A = result.Accumulator; mmu.WriteByte(registers.GeneralPurposeRegisters.HL, result.Result); } break; case OpCode.RotateRightDigit: { var result = alu.RotateRightDigit(registers.AccumulatorAndFlagsRegisters.A, mmu.ReadByte(registers.GeneralPurposeRegisters.HL)); registers.AccumulatorAndFlagsRegisters.A = result.Accumulator; mmu.WriteByte(registers.GeneralPurposeRegisters.HL, result.Result); } break; case OpCode.ShiftLeft: helper.Operand1 = alu.ShiftLeft(helper.Operand1); break; case OpCode.ShiftLeftSet: helper.Operand1 = alu.ShiftLeftSet(helper.Operand1); break; case OpCode.ShiftRight: helper.Operand1 = alu.ShiftRight(helper.Operand1); break; case OpCode.ShiftRightLogical: helper.Operand1 = alu.ShiftRightLogical(helper.Operand1); break; case OpCode.BitTest: alu.BitTest(helper.Operand1, operation.ByteLiteral); break; case OpCode.BitSet: helper.Operand1 = alu.BitSet(helper.Operand1, operation.ByteLiteral); break; case OpCode.BitReset: helper.Operand1 = alu.BitReset(helper.Operand1, operation.ByteLiteral); break; case OpCode.TransferIncrement: helper.BlockTransfer(); break; case OpCode.TransferIncrementRepeat: helper.BlockTransferRepeat(timer); break; case OpCode.TransferDecrement: helper.BlockTransfer(true); break; case OpCode.TransferDecrementRepeat: helper.BlockTransferRepeat(timer, true); break; case OpCode.SearchIncrement: helper.BlockSearch(); break; case OpCode.SearchIncrementRepeat: helper.BlockSearchRepeat(timer); break; case OpCode.SearchDecrement: helper.BlockSearch(true); break; case OpCode.SearchDecrementRepeat: helper.BlockSearchRepeat(timer, true); break; case OpCode.InputTransferIncrement: helper.InputTransfer(); break; case OpCode.InputTransferIncrementRepeat: helper.InputTransferRepeat(timer); break; case OpCode.InputTransferDecrement: helper.InputTransfer(true); break; case OpCode.InputTransferDecrementRepeat: helper.InputTransferRepeat(timer, true); break; case OpCode.OutputTransferIncrement: helper.OutputTransfer(); break; case OpCode.OutputTransferIncrementRepeat: helper.OutputTransferRepeat(timer); break; case OpCode.OutputTransferDecrement: helper.OutputTransfer(true); break; case OpCode.OutputTransferDecrementRepeat: helper.OutputTransferRepeat(timer, true); break; case OpCode.DecimalArithmeticAdjust: registers.AccumulatorAndFlagsRegisters.A = alu.DecimalAdjust(registers.AccumulatorAndFlagsRegisters.A, _cpuMode == CpuMode.Z80); break; case OpCode.NegateOnesComplement: registers.AccumulatorAndFlagsRegisters.A = (byte)~registers.AccumulatorAndFlagsRegisters.A; registers.AccumulatorAndFlagsRegisters.Flags.SetUndocumentedFlags(registers.AccumulatorAndFlagsRegisters.A); registers.AccumulatorAndFlagsRegisters.Flags.HalfCarry = true; registers.AccumulatorAndFlagsRegisters.Flags.Subtract = true; break; case OpCode.NegateTwosComplement: registers.AccumulatorAndFlagsRegisters.A = alu.Subtract(0, registers.AccumulatorAndFlagsRegisters.A); break; case OpCode.InvertCarryFlag: registers.AccumulatorAndFlagsRegisters.Flags.SetUndocumentedFlags(registers.AccumulatorAndFlagsRegisters.A); registers.AccumulatorAndFlagsRegisters.Flags.HalfCarry = _cpuMode != CpuMode.GameBoy && registers.AccumulatorAndFlagsRegisters.Flags.Carry; registers.AccumulatorAndFlagsRegisters.Flags.Subtract = false; registers.AccumulatorAndFlagsRegisters.Flags.Carry = !registers.AccumulatorAndFlagsRegisters.Flags.Carry; break; case OpCode.SetCarryFlag: registers.AccumulatorAndFlagsRegisters.Flags.SetUndocumentedFlags(registers.AccumulatorAndFlagsRegisters.A); registers.AccumulatorAndFlagsRegisters.Flags.HalfCarry = false; registers.AccumulatorAndFlagsRegisters.Flags.Subtract = false; registers.AccumulatorAndFlagsRegisters.Flags.Carry = true; break; case OpCode.DisableInterrupts: registers.InterruptFlipFlop1 = false; registers.InterruptFlipFlop2 = false; break; case OpCode.EnableInterrupts: registers.InterruptFlipFlop1 = true; registers.InterruptFlipFlop2 = true; break; case OpCode.InterruptMode0: registers.InterruptMode = InterruptMode.InterruptMode0; break; case OpCode.InterruptMode1: registers.InterruptMode = InterruptMode.InterruptMode1; break; case OpCode.InterruptMode2: registers.InterruptMode = InterruptMode.InterruptMode2; break; case OpCode.Swap: helper.Operand1 = alu.Swap(helper.Operand1); break; case OpCode.LoadIncrement: helper.Operand1 = helper.Operand2; registers.GeneralPurposeRegisters.HL++; break; case OpCode.LoadDecrement: helper.Operand1 = helper.Operand2; registers.GeneralPurposeRegisters.HL--; break; default: throw new ArgumentOutOfRangeException(); } if (operation.OpCodeMeta == OpCodeMeta.AutoCopy) { // Autocopy for DD/FD prefix helper.Operand2 = helper.Operand1; } return(timer.GetInstructionTimings()); }
private static void SyncProgramCounter(IRegisters registers, DecodedBlock block) => registers.ProgramCounter = (ushort)(registers.ProgramCounter + block.Length);
public DestinationProvider(IRegisters registers, IRam ram) { this.registers = registers; this.ram = ram; }
public SourceProvider(IRegisters registers, IRam ram) { this.registers = registers; this.ram = ram; }