2016-02-22 23:50:11 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using BizHawk.Emulation.Common;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|
|
|
|
{
|
2017-04-24 13:35:05 +00:00
|
|
|
|
public sealed partial class Chip6510 : IDebuggable
|
|
|
|
|
{
|
|
|
|
|
IDictionary<string, RegisterValue> IDebuggable.GetCpuFlagsAndRegisters()
|
|
|
|
|
{
|
|
|
|
|
return new Dictionary<string, RegisterValue>
|
|
|
|
|
{
|
|
|
|
|
{ "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 }
|
|
|
|
|
};
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
bool IDebuggable.CanStep(StepType type)
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case StepType.Into:
|
|
|
|
|
case StepType.Over:
|
|
|
|
|
case StepType.Out:
|
|
|
|
|
return DebuggerStep != null;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
void IDebuggable.Step(StepType type)
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case StepType.Into:
|
|
|
|
|
StepInto();
|
|
|
|
|
break;
|
|
|
|
|
case StepType.Out:
|
|
|
|
|
StepOut();
|
|
|
|
|
break;
|
|
|
|
|
case StepType.Over:
|
|
|
|
|
StepOver();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-01-10 01:23:05 +00:00
|
|
|
|
int IDebuggable.TotalExecutedCycles
|
|
|
|
|
{
|
|
|
|
|
get { return _cpu.TotalExecutedCycles; }
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
private void StepInto()
|
|
|
|
|
{
|
|
|
|
|
while (_cpu.AtInstructionStart())
|
|
|
|
|
{
|
|
|
|
|
DebuggerStep();
|
|
|
|
|
}
|
|
|
|
|
while (!_cpu.AtInstructionStart())
|
|
|
|
|
{
|
|
|
|
|
DebuggerStep();
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
private void StepOver()
|
|
|
|
|
{
|
|
|
|
|
var instruction = CpuPeek(_cpu.PC);
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
if (instruction == Jsr)
|
|
|
|
|
{
|
|
|
|
|
var destination = _cpu.PC + JsrSize;
|
|
|
|
|
while (_cpu.PC != destination)
|
|
|
|
|
{
|
|
|
|
|
StepInto();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
StepInto();
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
private void StepOut()
|
|
|
|
|
{
|
|
|
|
|
var instructionsBeforeBailout = 1000000;
|
|
|
|
|
var instr = CpuPeek(_cpu.PC);
|
|
|
|
|
_jsrCount = instr == Jsr ? 1 : 0;
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
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--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
[SaveState.DoNotSave]
|
|
|
|
|
private int _jsrCount;
|
|
|
|
|
[SaveState.DoNotSave]
|
|
|
|
|
private const byte Jsr = 0x20;
|
|
|
|
|
[SaveState.DoNotSave]
|
|
|
|
|
private const byte Rti = 0x40;
|
|
|
|
|
[SaveState.DoNotSave]
|
|
|
|
|
private const byte Rts = 0x60;
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
[SaveState.DoNotSave]
|
|
|
|
|
private const byte JsrSize = 3;
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
[SaveState.DoNotSave] private IMemoryCallbackSystem _memoryCallbacks = new MemoryCallbackSystem();
|
2016-02-22 23:50:11 +00:00
|
|
|
|
|
2017-04-24 13:35:05 +00:00
|
|
|
|
[SaveState.DoNotSave]
|
|
|
|
|
IMemoryCallbackSystem IDebuggable.MemoryCallbacks { get { return _memoryCallbacks; } }
|
|
|
|
|
}
|
2016-02-22 23:50:11 +00:00
|
|
|
|
}
|