using System; using System.Collections.Generic; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial { public sealed partial class Drive1541 : IDebuggable { IDictionary IDebuggable.GetCpuFlagsAndRegisters() { return new Dictionary { { "A", _cpu.A }, { "X", _cpu.X }, { "Y", _cpu.Y }, { "S", _cpu.S }, { "PC", _cpu.PC }, { "Flag C", _cpu.FlagC }, { "Flag Z", _cpu.FlagZ }, { "Flag I", _cpu.FlagI }, { "Flag D", _cpu.FlagD }, { "Flag B", _cpu.FlagB }, { "Flag V", _cpu.FlagV }, { "Flag N", _cpu.FlagN }, { "Flag T", _cpu.FlagT } }; } void IDebuggable.SetCpuRegister(string register, int value) { switch (register) { default: throw new InvalidOperationException(); case "A": _cpu.A = (byte)value; break; case "X": _cpu.X = (byte)value; break; case "Y": _cpu.Y = (byte)value; break; case "S": _cpu.S = (byte)value; break; case "PC": _cpu.PC = (ushort)value; break; } } 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; } } int IDebuggable.TotalExecutedCycles { get { return _cpu.TotalExecutedCycles; } } private void StepInto() { while (_cpu.AtInstructionStart()) { DebuggerStep(); } while (!_cpu.AtInstructionStart()) { DebuggerStep(); } } private void StepOver() { var instruction = CpuPeek(_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 = CpuPeek(_cpu.PC); _jsrCount = instr == Jsr ? 1 : 0; while (--instructionsBeforeBailout > 0) { StepInto(); instr = CpuPeek(_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; public IMemoryCallbackSystem MemoryCallbacks { get; private set; } } }