public int Process(ICpu cpu, byte instruction) { var ins = Instructions.Get(instruction); if (ins is null) { throw new UnknownInstructionException(instruction); } var(mode, insType, cycles) = ins.OpCodes[instruction]; var addrMode = AddressingModes.Get(mode); var(address, pageCrossed) = addrMode.Addressing(cpu.CpuRegisters, cpu.Bus); var extraCycles = ins.Invoke(cpu, instruction, address); var cyclesIncrement = insType switch { InstructionType.Common => extraCycles, InstructionType.CrossingPage => InstructionUtil.GetCrossingPageClockCycles(pageCrossed) + extraCycles, InstructionType.Branch => InstructionUtil.GetBranchClockCycle(Convert.ToBoolean(extraCycles), pageCrossed), _ => extraCycles }; return(cycles + cyclesIncrement); } }
public static byte ReadData(this IInstruction ins, ushort address, ICpu cpu, byte instruction) { if (!ins.OpCodes.TryGetValue(instruction, out var value)) { throw new UnknownInstructionException(instruction); } var addressingMode = AddressingModes.Get(value.mode); if (addressingMode.AddressingType == AddressingType.Address) { return(cpu.Bus.ReadByte(address)); } return((byte)address); }
public static void WriteData(this IInstruction ins, ushort address, byte data, ICpu cpu, byte instruction) { if (!ins.OpCodes.TryGetValue(instruction, out var value)) { throw new UnknownInstructionException(instruction); } var addressingMode = AddressingModes.Get(value.mode); if (value.mode == AddressingMode.AccumulatorAddressingMode) { cpu.CpuRegisters.A = data; return; } if (addressingMode.AddressingType == AddressingType.Address) { cpu.Bus.WriteByte(address, data); } }