// global system clock public void Clock() { ppu.Clock(); if (clockCounter % 3 == 0) { if (dmaStarted) { if (dmaDummy) { if (clockCounter % 2 == 1) { dmaDummy = false; } } else { if (clockCounter % 2 == 0) { UInt16 address = BitMagic.Combine(dmaPage, dmaAddress); dmaData = CpuRead(address); } else { ppu.Oam[dmaAddress++] = dmaData; // after 256 writes dmaAddress loops back to zero if (dmaAddress == 0) { dmaStarted = false; dmaDummy = true; } } } } else { cpu.Clock(); } } if (ppu.EmitNmi) { cpu.NMI(); } clockCounter++; }
private void Verify(IEnumerable <AccessEntry> accesses) { Cpu.ForceOpcodeSync(); foreach (var access in accesses) { System.Invocations.Clear(); var address = access.Address; Cpu.Clock(); switch (access.AccessType) { case AccessType.Read: if (address >= 0) { Console.WriteLine("Verifying READ at ${0:x4}", address); System.Verify(m => m.Read(It.IsIn(address)), Times.Once); System.Verify(m => m.Read(It.IsNotIn(address)), Times.Never); } else { Console.WriteLine("Verifying READ at any address"); System.Verify(m => m.Read(It.IsAny <int>()), Times.Once); } System.Verify(m => m.Write(It.IsAny <int>(), It.IsAny <int>()), Times.Never); break; case AccessType.Write: if (address >= 0) { Console.WriteLine("Verifying WRITE at ${0:x4}", address); System.Verify(m => m.Write(It.IsIn(address), It.IsAny <int>()), Times.Once); System.Verify(m => m.Write(It.IsNotIn(address), It.IsAny <int>()), Times.Never); } else { Console.WriteLine("Verifying WRITE at any address"); System.Verify(m => m.Write(It.IsAny <int>(), It.IsAny <int>()), Times.Once); } System.Verify(m => m.Read(It.IsAny <int>()), Times.Never); break; } } Cpu.Sync.Should().BeTrue("Sync must occur after opcode finishes."); }
static void Run(byte[] program) { Rom programMemory = new Rom(program); DataBus mainBus = new DataBus(0xFFFF); mainBus.ConnectDevice(programMemory, (uint)(0xFFFF - program.Length), 0xFFFF); Cpu cpu = new Cpu(mainBus); cpu.Reset(); stepMode = StepMode.RUN; ProcessInput(); while (true) { bool isDoStep = doStep; if (stepMode == StepMode.RUN || doStep) { cpu.Clock(); } //if (cpu.RemainingInstructionCycles == 0) //{ if (stepMode == StepMode.RUN || doStep) { Console.WriteLine("A: ${0:X2} | X: ${1:X2} | Y: ${2:X2}", cpu.A, cpu.X, cpu.Y); Console.WriteLine("PC: ${0:X4}", cpu.ProgramCounter); Console.WriteLine("Next: {0}", InstructionSet.InstuctionsByOpcode[programMemory.ReadByte(cpu.ProgramCounter)].Name); } if (stepMode == StepMode.STEP && isDoStep == doStep) { doStep = false; } //} } }
public void CpuCanRunOneCycle() { Cpu.Clock(); }