/// <summary> /// CPUメインループ起動 /// </summary> private void Run() { byte opcode; bool isIRQ = false; var watch = new System.Diagnostics.Stopwatch(); watch.Start(); while (!this.IsThreadExit) { // VBlank終了時に画面情報を作成 if (this.Clock.IsVBlankEnd(true)) { isIRQ = false; this.PpuVblank.CreateImage(); this.PpuVblank.Clear(); if (watch.ElapsedMilliseconds < 16) { // 処理が早くおわりすぎた場合でも60fpsになるように調整 System.Threading.Thread.Sleep((int)(16 - watch.ElapsedMilliseconds)); } watch.Restart(); } // VBlank開始時に割り込み発生させる if (isIRQ == false && this.Clock.IsVBlankStart()) { isIRQ = true; this.PpuVblank.IsVBlank = true; if (this.PpuVblank.IsVBlankNMI) { NMI(); } } // フェッチ opcode = this.MemoryMap.GetByteValue(this.ProgramCounter.Value); this.ProgramCounter.Value++; // CPU命令実行 this.CurrentCommand = CpuCommandTable.Table[opcode]; this.Clock.IncrementClock(CpuCommandTable.Table[opcode]); Execute(opcode); } }
/// <summary> /// クロックを進める /// </summary> /// <param name="cpuCommand"></param> public void IncrementClock(CpuCommand cpuCommand) { this.Clock += cpuCommand.Cycle; this.Ppu.CheckZeroSprite(cpuCommand.Cycle); }