// -------------------- // --- INSTRUCTIONS --- // -------------------- /// <summary> /// Add with carry /// </summary> /// <param name="step">Step.</param> private void ADC(StepInfo step) { byte a = this.a; byte b = memory.Read(step.address); byte c = this.c; int sum = a + b + c; this.a = (byte)sum; SetZN(this.a); if (sum > 0xFF) { this.c = 1; } else { this.c = 0; } if (((a ^ b) & 0x80) == 0 && ((a ^ this.a) & 0x80) != 0) { v = 1; } else { v = 0; } }
/// <summary> /// Subtract with carry flag /// </summary> /// <param name="step">Step.</param> private void SBC(StepInfo step) { byte a = this.a; byte b = memory.Read(step.address); byte c = this.c; int sum = a - b - (1 - c); this.a = (byte)sum; SetZN(this.a); if (sum >= 0) { c = 1; } else { c = 0; } if (((a ^ b) & 0x80) != 0 && ((a ^ this.a) & 0x80) != 0) { v = 1; } else { v = 0; } }
/// <summary> /// Prints out the instruction /// </summary> private void LogInstruction(byte opCode, StepInfo step) { byte bytes = INSTRUCTION_SIZES [opCode]; string name = INSTRUCITON_NAMES [opCode]; string w0 = memory.Read((UInt16)(step.pc - 1)).ToString("X2"); string w1 = memory.Read(step.pc).ToString("X2"); string w2 = memory.Read((UInt16)(step.pc + 1)).ToString("X2"); if (bytes < 2) { w1 = " "; } if (bytes < 3) { w2 = " "; } string logString = string.Format("{0} {1} {2} {3} {4} {5,28} A:{6} X:{7} Y:{8} P:{9} SP:{10} CYC:{11}", (step.pc - 1).ToString("X4"), w0, w1, w2, name, "", a.ToString("X2"), x.ToString("X2"), y.ToString("X2"), GetFlags().ToString("X2"), sp.ToString("X2"), (cycles * 3) % 341); console.Log(logString); /* * fmt.Printf( * "%4X %s %s %s %s %28s"+ * "A:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%3d\n", * cpu.PC, w0, w1, w2, name, "", * cpu.A, cpu.X, cpu.Y, cpu.Flags(), cpu.SP, (cpu.Cycles*3)%341) * } */ }
/// <summary> /// Break (force interrupt) /// </summary> /// <param name="step">Step.</param> private void BRK(StepInfo step) { Push16(pc); PHP(step); SEI(step); pc = Read16(0xFFFE); }
/// <summary> /// Branch if overflow clear /// </summary> /// <param name="step">Step.</param> private void BVC(StepInfo step) { if (v == 0) { pc = step.address; AddBranchCycles(step); } }
/// <summary> /// Increment memory /// </summary> /// <param name="step">Step.</param> private void INC(StepInfo step) { byte value = (byte)(memory.Read(step.address) + 1); memory.Write(step.address, value); SetZN(value); }
/// <summary> /// Branch if minus /// </summary> /// <param name="step">Step.</param> private void BMI(StepInfo step) { if (n != 0) { pc = step.address; AddBranchCycles(step); } }
/// <summary> /// Adds a cycle for branching and adds another cycle if the branch jumps /// to a new page. /// </summary> /// <param name="info">Step Info.</param> private void AddBranchCycles(StepInfo info) { ++cycles; if (PagesDiffer(info.pc, info.address)) { ++cycles; } }
/// <summary> /// Bit test /// </summary> /// <param name="step">Step.</param> private void BIT(StepInfo step) { byte value = memory.Read(step.address); v = (byte)((value >> 6) & 1); SetZ((byte)(value & a)); SetN(value); }
/// <summary> /// Logical shift right /// </summary> /// <param name="step">Step.</param> private void LSR(StepInfo step) { if (step.mode == AddressMode.Accumulator) { c = (byte)(a & 1); a = (byte)(a >> 1); SetZN(a); } else { byte value = memory.Read(step.address); c = (byte)(value & 1); value = (byte)(value >> 1); memory.Write(step.address, value); SetZN(value); } }
/// <summary> /// Rotate right /// </summary> /// <param name="step">Step.</param> private void ROR(StepInfo step) { byte c = this.c; if (step.mode == AddressMode.Accumulator) { this.c = (byte)(a & 1); a = (byte)((a >> 1) | (c << 7)); SetZN(a); } else { byte value = memory.Read(step.address); this.c = (byte)(value & 1); value = (byte)((value >> 1) | (c << 7)); memory.Write(step.address, value); SetZN(value); } }
public int Step() { // If we are stalling, stall for a cycle if (stall > 0) { --stall; return(1); } UInt64 startCycles = cycles; HandleInterrupt(); byte opCode = memory.Read(pc); AddressMode mode = (AddressMode)INSTRUCTION_MODES [opCode]; AddressInfo info = GetAddress(mode); pc += INSTRUCTION_SIZES [opCode]; cycles += INSTRUCTION_CYCLES [opCode]; if (info.pageCrossed) { cycles += INSTRUCTION_PAGE_CYCLES [opCode]; } StepInfo step = new StepInfo { address = info.address, pc = pc, mode = mode }; #if UNITY_EDITOR LogInstruction(opCode, step); #endif table [opCode] (step); return((int)(cycles - startCycles)); }
/// <summary> /// Transfer x to stack pointer /// </summary> /// <param name="step">Step.</param> private void TXS(StepInfo step) { sp = x; }
private void ANC(StepInfo step) { }
private void XAA(StepInfo step) { }
private void TAS(StepInfo step) { }
private void AHX(StepInfo step) { }
/// <summary> /// Transfer x to accumulator /// </summary> /// <param name="step">Step.</param> private void TXA(StepInfo step) { a = x; SetZN(a); }
private void ARR(StepInfo step) { }
private void RRA(StepInfo step) { }
private void KIL(StepInfo step) { }
private void ISC(StepInfo step) { }
private void DCP(StepInfo step) { }
private void AXS(StepInfo step) { }
/// <summary> /// Logical AND /// </summary> /// <param name="step">Step.</param> private void AND(StepInfo step) { a = (byte)(a & memory.Read(step.address)); SetZN(a); }
private void SHY(StepInfo step) { }
private void SLO(StepInfo step) { }
private void SRE(StepInfo step) { }
private void SAX(StepInfo step) { }
/// <summary> /// Transfer Y to accumulator /// </summary> /// <param name="step">Step.</param> private void TYA(StepInfo step) { a = y; SetZN(a); }