/// <summary> /// test BITs /// </summary> private static void Bit(Cpu cpu, InstructionData data) { var value = cpu.ReadByte(data.ArgumentAddress); cpu.SetFlag(CpuFlags.Overflow, ((value >> 6) & 1) != 0); cpu.SetZero((byte)(value & cpu.accumulator)); cpu.SetNegative(value); }
/// <summary> /// Load Accumulator and X register /// </summary> private static void Lax(Cpu cpu, InstructionData data) { var value = cpu.ReadByte(data.ArgumentAddress); cpu.accumulator = value; cpu.x = value; cpu.SetZeroNegative(value); }
/// <summary> /// ADd with Carry /// </summary> private static void Adc(Cpu cpu, InstructionData data) { var a = cpu.accumulator; var b = cpu.ReadByte(data.ArgumentAddress); var c = cpu.GetFlag(CpuFlags.Carry) ? 1 : 0; var result = a + b + c; cpu.accumulator = (byte)result; cpu.SetZeroNegative(cpu.accumulator); cpu.SetFlag(CpuFlags.Carry, result > 0xff); cpu.SetFlag(CpuFlags.Overflow, (((a ^ b) & 0x80) == 0) && (((a ^ cpu.accumulator) & 0x80) != 0)); }
/// <summary> /// ROtate Right /// </summary> private static void Ror(Cpu cpu, InstructionData data) { if (data.AddressingMode == AddressingMode.Accumulator) { cpu.RotateRight(ref cpu.accumulator); } else { var value = cpu.ReadByte(data.ArgumentAddress); cpu.RotateRight(ref value); cpu.WriteByte(data.ArgumentAddress, value); } }
/// <summary> /// SuBtract with Carry /// </summary> private static void Sbc(Cpu cpu, InstructionData data) { var a = cpu.accumulator; var b = cpu.ReadByte(data.ArgumentAddress); var result = a - b; if (!cpu.GetFlag(CpuFlags.Carry)) { result -= 1; } cpu.accumulator = (byte)result; cpu.SetZeroNegative(cpu.accumulator); cpu.SetFlag(CpuFlags.Carry, result >= 0); cpu.SetFlag(CpuFlags.Overflow, (((a ^ b) & 0x80) != 0) && (((a ^ cpu.accumulator) & 0x80) != 0)); }
public bool Advance() { if (waitCycles > 0) { waitCycles--; return(false); } var log = new StringBuilder(); log.Append($"0x{programCounter:X4}"); var opCode = ReadByte(programCounter); var instruction = Instructions[opCode]; var adressingMode = InstructionAdressingModes[opCode]; var instructionData = new InstructionData { ArgumentAddress = GetInstructionArgumentAddress(adressingMode), ProgramCounter = programCounter, AddressingMode = adressingMode }; var instructionSize = GetInstructionSize(adressingMode); for (int i = 0; i < 3; i++) { if (i <= instructionSize) { log.Append($" {ReadByte((ushort) (programCounter + i)):X2}"); } else { log.Append(" "); } } programCounter += instructionSize; waitCycles = InstructionCycles[opCode]; if (IsPageCrossed(adressingMode, instructionData.ArgumentAddress)) { waitCycles += InstructionPageCrossCycles[opCode]; } log.Append($" {opCode:X2} {instruction.Method.Name.ToUpper()} {adressingMode} 0x{instructionData.ArgumentAddress:X4}"); instruction(this, instructionData); System.Console.Out.WriteLine(log.ToString()); return(true); }
/// <summary> /// Jump to SubRoutine /// </summary> private static void Jsr(Cpu cpu, InstructionData data) { cpu.PushShort((ushort)(cpu.programCounter - 1)); cpu.programCounter = data.ArgumentAddress; }
/// <summary> /// PuLl Processor status /// </summary> private static void Plp(Cpu cpu, InstructionData data) { cpu.flags = (CpuFlags)(cpu.PullByte() & 0xEF | 0x20); }
/// <summary> /// STore Y register /// </summary> private static void Sty(Cpu cpu, InstructionData data) { cpu.Store(data.ArgumentAddress, cpu.y); }
/// <summary> /// Rotate Right, then Add memory to accumulator with carry /// </summary> private static void Rra(Cpu cpu, InstructionData data) { Ror(cpu, data); Adc(cpu, data); }
/// <summary> /// Transfer Y to A /// </summary> private static void Tya(Cpu cpu, InstructionData data) { cpu.Transfer(cpu.y, out cpu.accumulator); }
/// <summary> /// Increment memory and Subtract with Carry /// </summary> private static void Isb(Cpu cpu, InstructionData data) { Inc(cpu, data); Sbc(cpu, data); }
/// <summary> /// Rotate Left then And accumulator with memory /// </summary> private static void Rla(Cpu cpu, InstructionData data) { Rol(cpu, data); And(cpu, data); }
/// <summary> /// STore Accumulator /// </summary> private static void Sta(Cpu cpu, InstructionData data) { cpu.Store(data.ArgumentAddress, cpu.accumulator); }
/// <summary> /// Transfer X to Stack ptr /// </summary> private static void Txs(Cpu cpu, InstructionData data) { cpu.stackPointer = cpu.x; }
/// <summary> /// ReTurn from Subroutine /// </summary> private static void Rts(Cpu cpu, InstructionData data) { cpu.programCounter = (ushort)(cpu.PullShort() + 1); }
/// <summary> /// LoaD Y register /// </summary> private static void Ldy(Cpu cpu, InstructionData data) { cpu.Load(out cpu.y, data.ArgumentAddress); }
/// <summary> /// No OPeration /// </summary> private static void Nop(Cpu cpu, InstructionData data) { }
/// <summary> /// INcrement Y /// </summary> private static void Iny(Cpu cpu, InstructionData data) { cpu.Increment(ref cpu.y); }
/// <summary> /// DEcrement Y /// </summary> private static void Dey(Cpu cpu, InstructionData data) { cpu.Decrement(ref cpu.y); }
/// <summary> /// Store Accumulator and X register /// </summary> private static void Sax(Cpu cpu, InstructionData data) { cpu.Store(data.ArgumentAddress, (byte)(cpu.accumulator & cpu.x)); }
/// <summary> /// LoaD Accumulator /// </summary> private static void Lda(Cpu cpu, InstructionData data) { cpu.Load(out cpu.accumulator, data.ArgumentAddress); }
/// <summary> /// Decrease memory and ComPare with accumulator /// </summary> private static void Dcp(Cpu cpu, InstructionData data) { Dec(cpu, data); Cmp(cpu, data); }
/// <summary> /// PusH Accumulator /// </summary> private static void Pha(Cpu cpu, InstructionData data) { cpu.PushByte(cpu.accumulator); }
/// <summary> /// arithmetic Shift Left then Or accumulator with memory /// </summary> private static void Slo(Cpu cpu, InstructionData data) { Asl(cpu, data); Ora(cpu, data); }
/// <summary> /// PuLl Accumulator /// </summary> private static void Pla(Cpu cpu, InstructionData data) { cpu.accumulator = cpu.PullByte(); cpu.SetZeroNegative(cpu.accumulator); }
/// <summary> /// logical Shift Right then Eor accumulator with memory /// </summary> private static void Sre(Cpu cpu, InstructionData data) { Lsr(cpu, data); Eor(cpu, data); }
/// <summary> /// PusH Processor status /// </summary> private static void Php(Cpu cpu, InstructionData data) { cpu.PushByte((byte)((byte)cpu.flags | 0x10)); }
/// <summary> /// Transfer Stack ptr to X /// </summary> private static void Tsx(Cpu cpu, InstructionData data) { cpu.x = cpu.stackPointer; cpu.SetZeroNegative(cpu.x); }
/// <summary> /// bitwise OR with Accumulator /// </summary> private static void Ora(Cpu cpu, InstructionData data) { cpu.accumulator = (byte)(cpu.accumulator | cpu.ReadByte(data.ArgumentAddress)); cpu.SetZeroNegative(cpu.accumulator); }