public void Run(Action <Bitmap> drawFrame) { var sw = new Stopwatch(); while (true) { sw.Start(); var cpuCyclesSpent = Cpu.Step(); // If we get null back, the program has ended/hit unknown opcode. if (cpuCyclesSpent == null) { return; } // Step PPU 3x as many as CPU used. for (var i = 0; i < 3 * cpuCyclesSpent.Value; i++) { if (Ppu.Step()) { drawFrame?.Invoke(Screen); } } // Sleep until it's time for the next cycle. var timeToSleep = cpuCyclesSpent.Value * (CpuCycleDurationMilliseconds - sw.ElapsedMilliseconds); if (timeToSleep > 0) { Thread.Sleep((int)timeToSleep); } } }
public Nes() { PpuRam = new PpuMemoryMap(); Ppu = new Ppu(PpuRam, Screen); Ram = new MemoryMap(Ppu); Cpu = new Cpu(Ram, programCounter: InitialProgramCounter, stackPointer: InitialStackPointer); var cpuSpeed = 21.477272 / 12; CpuCycleDurationMilliseconds = 1.0f / cpuSpeed; }
public MemoryMap(Ppu ppu) { this.ppu = ppu; }