/// <summary> /// The gatearray runs on a 16Mhz clock /// (for the purposes of emulation, we will use a 4Mhz clock) /// From this it generates: /// 1Mhz clock for the CRTC chip /// 1Mhz clock for the AY-3-8912 PSG /// 4Mhz clock for the Z80 CPU /// </summary> public void ClockCycle() { // 4-phase clock for (int i = 1; i < 5; i++) { switch (i) { // Phase 1 case 1: CRCT.ClockCycle(); CPU.ExecuteOne(); break; // Phase 2 case 2: CPU.ExecuteOne(); break; // Phase 3 case 3: // video fetch break; // Phase 4 case 4: // video fetch break; } } }
/// <summary> /// Handles the ULA and CPU cycle clocks, along with any memory and port contention /// </summary> public void ExecuteCycle() { // simulate the ULA clock cycle before the CPU cycle _machine.ULADevice.CycleClock(TotalExecutedCycles); // is the next CPU cycle causing a BUSRQ or IORQ? if (BUSRQ > 0) { // check for IORQ if (!CheckIO()) { // is the memory address of the BUSRQ potentially contended? if (_machine.IsContended(AscertainBUSRQAddress())) { var cont = _machine.ULADevice.GetContentionValue((int)_machine.CurrentFrameCycle); if (cont > 0) { _cpu.TotalExecutedCycles += cont; NextMemReadContended = true; } } } } _cpu.ExecuteOne(); }
public void ExecFrame(bool render) { int scanlinesPerFrame = DisplayType == DisplayType.NTSC ? 262 : 313; SpriteLimit = Sms.Settings.SpriteLimit; for (ScanLine = 0; ScanLine < scanlinesPerFrame; ScanLine++) { RenderCurrentScanline(render); ProcessFrameInterrupt(); ProcessLineInterrupt(); Sms.ProcessLineControls(); //Console.Write(Cpu.cur_instr.Length); //Console.Write(" "); //Console.WriteLine(Cpu.instr_pntr); for (int j = 0; j < IPeriod; j++) { Cpu.ExecuteOne(); } if (ScanLine == scanlinesPerFrame - 1) { ProcessGGScreen(); ProcessOverscan(); } } }