diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs index bbfdb5e569..0bb4f9c11c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs @@ -21,7 +21,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 private IController _controller; private int _frame; private int _lastAddress; - private bool _frameStartPending = true; private bool _leftDifficultySwitchPressed; private bool _rightDifficultySwitchPressed; @@ -34,6 +33,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 internal byte[] Rom { get; } internal int DistinctAccessCount { get; private set; } + // keeps track of tia cycles, 3 cycles per CPU cycle + private int cyc_counter; + private static MapperBase SetMultiCartMapper(int romLength, int gameTotal) { switch (romLength / gameTotal) @@ -319,17 +321,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 _m6532 = new M6532(this); - // Set up the system state here. for instance.. - // Read from the reset vector for where to start - Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC + HardReset(); // Show mapper class on romstatusdetails CoreComm.RomStatusDetails = $"{this._game.Name}\r\nSHA1:{Rom.HashSHA1()}\r\nMD5:{Rom.HashMD5()}\r\nMapper Impl \"{_mapper.GetType()}\""; - - // as it turns out, the stack pointer cannot be set to 0 for some games as they do not initilize it themselves. - // some documentation seems to indicate it should beset to FD, but currently there is no documentation of the 6532 - // executing a reset sequence at power on, but it's needed so let's hard code it for now - Cpu.S = 0xFD; } private bool _pal; @@ -349,96 +344,28 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 }; _tia.Reset(); - _m6532 = new M6532(this); - Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC - - // as it turns out, the stack pointer cannot be set to 0 for some games as they do not initilize it themselves. - // some documentation seems to indicate it should beset to FD, but currently there is no documentation of the 6532 - // executing a reset sequence at power on, but it's needed so let's hard code it for now - Cpu.S = 0xFD; - SetupMemoryDomains(); - } - - private void VFrameAdvance() // advance up to 500 lines looking for end of video frame - // after vsync falling edge, continues to end of next line - { - bool frameend = false; - _tia.FrameEndCallBack = (n) => frameend = true; - for (int i = 0; i < 500 && !frameend; i++) - { - ScanlineAdvance(); - } - - _tia.FrameEndCallBack = null; - } - - private void StartFrameCond() - { - if (_frameStartPending) - { - _frame++; - _islag = true; - - if (_controller.IsPressed("Power")) - { - HardReset(); - } - - if (_controller.IsPressed("Toggle Left Difficulty") && !_leftDifficultySwitchHeld) - { - _leftDifficultySwitchPressed ^= true; - _leftDifficultySwitchHeld = true; - } - else if (!_controller.IsPressed("Toggle Left Difficulty")) - { - _leftDifficultySwitchHeld = false; - } - - if (_controller.IsPressed("Toggle Right Difficulty") && !_rightDifficultySwitchHeld) - { - _rightDifficultySwitchPressed ^= true; - _rightDifficultySwitchHeld = true; - } - else if (!_controller.IsPressed("Toggle Right Difficulty")) - { - _rightDifficultySwitchHeld = false; - } - - _tia.BeginAudioFrame(); - _frameStartPending = false; - } - } - - private void FinishFrameCond() - { - if (_tia.LineCount >= _tia.NominalNumScanlines) - { - _tia.CompleteAudioFrame(); - if (_islag) - { - _lagcount++; - } - - _tia.LineCount = 0; - _frameStartPending = true; - } + cyc_counter = 0; } private void Cycle() { - _tia.Execute(1); - _tia.Execute(1); - _tia.Execute(1); - _m6532.Timer.Tick(); - if (Tracer.Enabled) + _tia.Execute(); + cyc_counter++; + if (cyc_counter == 3) { - Tracer.Put(Cpu.TraceState()); - } + _m6532.Timer.Tick(); + if (Tracer.Enabled) + { + Tracer.Put(Cpu.TraceState()); + } - Cpu.ExecuteOne(); - _mapper.ClockCpu(); + Cpu.ExecuteOne(); + _mapper.ClockCpu(); + + cyc_counter = 0; + } } internal byte ReadControls1(bool peek) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IDebuggable.cs index cf7ae45ba1..52c2c313a7 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IDebuggable.cs @@ -60,97 +60,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public bool CanStep(StepType type) { - switch (type) - { - case StepType.Into: - case StepType.Out: - case StepType.Over: - return true; - default: - return false; - } + return false; } [FeatureNotImplemented] public void Step(StepType type) { - switch (type) - { - case StepType.Into: - StepInto(); - break; - case StepType.Out: - StepOut(); - break; - case StepType.Over: - StepOver(); - break; - } + throw new NotImplementedException(); } + public int TotalExecutedCycles => Cpu.TotalExecutedCycles; - private void StepInto() - { - do - { - CycleAdvance(); - } while (!Cpu.AtStart); - } - - private void StepOver() - { - var instruction = Cpu.PeekMemory(Cpu.PC); - - if (instruction == JSR) - { - var destination = Cpu.PC + opsize[JSR]; - while (Cpu.PC != destination) - { - StepInto(); - } - } - else - { - StepInto(); - } - } - - private void StepOut() - { - var instruction = Cpu.PeekMemory(Cpu.PC); - - JSRCount = instruction == JSR ? 1 : 0; - - var bailOutFrame = Frame + 1; - while (true) - { - StepInto(); - var instr = Cpu.PeekMemory(Cpu.PC); - if (instr == JSR) - { - JSRCount++; - } - else if (instr == RTS && JSRCount <= 0) - { - StepInto(); - JSRCount = 0; - break; - } - else if (instr == RTS) - { - JSRCount--; - } - else // Emergency bail out logic - { - if (Frame == bailOutFrame) - { - break; - } - } - } - } - private int JSRCount = 0; private const byte JSR = 0x20; @@ -212,22 +133,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 #region Currently Unused Debug hooks - private void ScanlineAdvance() - { - StartFrameCond(); - int currentLine = _tia.LineCount; - while (_tia.LineCount == currentLine) - Cycle(); - FinishFrameCond(); - } - - private void CycleAdvance() - { - StartFrameCond(); - Cycle(); - FinishFrameCond(); - } - private int CurrentScanLine { get { return _tia.LineCount; } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IEmulator.cs index 65d910b1c1..cfcd8176bc 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IEmulator.cs @@ -12,18 +12,53 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { _controller = controller; - StartFrameCond(); - while (_tia.LineCount < _tia.NominalNumScanlines) + _frame++; + _islag = true; + + // Handle all the console controls here + if (_controller.IsPressed("Power")) + { + HardReset(); + } + + if (_controller.IsPressed("Toggle Left Difficulty") && !_leftDifficultySwitchHeld) + { + _leftDifficultySwitchPressed ^= true; + _leftDifficultySwitchHeld = true; + } + else if (!_controller.IsPressed("Toggle Left Difficulty")) + { + _leftDifficultySwitchHeld = false; + } + + if (_controller.IsPressed("Toggle Right Difficulty") && !_rightDifficultySwitchHeld) + { + _rightDifficultySwitchPressed ^= true; + _rightDifficultySwitchHeld = true; + } + else if (!_controller.IsPressed("Toggle Right Difficulty")) + { + _rightDifficultySwitchHeld = false; + } + + while (!_tia.New_Frame) { Cycle(); } + _tia.New_Frame = false; + if (rendersound == false) { _tia.AudioClocks = 0; // we need this here since the async sound provider won't check in this case } - FinishFrameCond(); + if (_islag) + { + _lagcount++; + } + + _tia.LineCount = 0; } public int Frame => _frame; diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IStatable.cs index aa6d4e78b4..dcff99f432 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IStatable.cs @@ -46,7 +46,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 ser.Sync("Lag", ref _lagcount); ser.Sync("Frame", ref _frame); ser.Sync("IsLag", ref _islag); - ser.Sync("frameStartPending", ref _frameStartPending); + ser.Sync("cyc_counter", ref cyc_counter); ser.Sync("leftDifficultySwitchPressed", ref _leftDifficultySwitchPressed); ser.Sync("rightDifficultySwitchPressed", ref _rightDifficultySwitchPressed); ser.Sync("leftDifficultySwitchHeld", ref _leftDifficultySwitchHeld); diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs index 5a7d466c6f..e44db03cf7 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs @@ -102,18 +102,25 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // give the emu a minimal of input\output connections so it doesn't crash var comm = new CoreComm(null, null); + + // here we advance past start up irregularities to see how long a frame is based on calls to Vsync + // we run 72 frames, then run 270 scanlines worth of cycles. + // if we don't hit a new frame, we can be pretty confident we are in PAL using (Atari2600 emu = new Atari2600(new CoreComm(null, null), newgame, rom, null, null)) { - List framecounts = new List(); - emu._tia.FrameEndCallBack = (i) => framecounts.Add(i); - for (int i = 0; i < 71; i++) // run for 71 * 262 lines, since we're in NTSC mode + for (int i = 0; i < 72; i++) { emu.FrameAdvance(NullController.Instance, false, false); } - int numpal = framecounts.Count((i) => i > 287); - bool pal = numpal >= 25; - Console.WriteLine("PAL Detection: {0} lines, {1}", numpal, pal); + for (int i = 0; i < 61560; i++) + { + emu.Cycle(); + } + + bool pal = !emu._tia.New_Frame; + + Console.WriteLine("PAL Detection: {0}", pal); return pal; } }