using System.Collections.Generic; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS { public sealed partial class Chip6510 : IDebuggable { IDictionary IDebuggable.GetCpuFlagsAndRegisters() => _cpu.GetCpuFlagsAndRegisters(); void IDebuggable.SetCpuRegister(string register, int value) => _cpu.SetCpuRegister(register, value); bool IDebuggable.CanStep(StepType type) { switch (type) { case StepType.Into: case StepType.Over: case StepType.Out: return DebuggerStep != null; default: return false; } } void IDebuggable.Step(StepType type) { switch (type) { case StepType.Into: StepInto(); break; case StepType.Out: StepOut(); break; case StepType.Over: StepOver(); break; } } long IDebuggable.TotalExecutedCycles => _cpu.TotalExecutedCycles; private void StepInto() { while (_cpu.AtInstructionStart()) { DebuggerStep(); } while (!_cpu.AtInstructionStart()) { DebuggerStep(); } } private void StepOver() { var instruction = Peek(_cpu.PC); if (instruction == Jsr) { var destination = _cpu.PC + JsrSize; while (_cpu.PC != destination) { StepInto(); } } else { StepInto(); } } private void StepOut() { var instructionsBeforeBailout = 1000000; var instr = Peek(_cpu.PC); _jsrCount = instr == Jsr ? 1 : 0; while (--instructionsBeforeBailout > 0) { StepInto(); instr = Peek(_cpu.PC); if (instr == Jsr) { _jsrCount++; } else if ((instr == Rts || instr == Rti) && _jsrCount <= 0) { StepInto(); _jsrCount = 0; break; } else if (instr == Rts || instr == Rti) { _jsrCount--; } } } private int _jsrCount; private const byte Jsr = 0x20; private const byte Rti = 0x40; private const byte Rts = 0x60; private const byte JsrSize = 3; IMemoryCallbackSystem IDebuggable.MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" }); } }