BizHawk/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Chip6510.IDebuggable.cs

112 lines
2.2 KiB
C#

using System.Collections.Generic;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
{
public sealed partial class Chip6510 : IDebuggable
{
IDictionary<string, RegisterValue> 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" });
}
}