BizHawk/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.IDebuggable.cs

153 lines
2.9 KiB
C#
Raw Normal View History

2016-02-22 23:50:11 +00:00
using System;
using System.Collections.Generic;
2016-02-22 23:50:11 +00:00
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
{
2017-04-24 13:35:05 +00:00
public sealed partial class Drive1541 : IDebuggable
{
IDictionary<string, RegisterValue> IDebuggable.GetCpuFlagsAndRegisters()
{
return new Dictionary<string, RegisterValue>
{
2017-05-30 17:09:46 +00:00
["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
2017-04-24 13:35:05 +00:00
};
}
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-05-30 17:09:46 +00:00
int IDebuggable.TotalExecutedCycles => _cpu.TotalExecutedCycles;
2017-04-24 13:35:05 +00:00
private void StepInto()
{
while (_cpu.AtInstructionStart())
{
DebuggerStep();
}
2017-05-30 17:09:46 +00:00
2017-04-24 13:35:05 +00:00
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
private int _jsrCount;
2017-04-24 13:35:05 +00:00
private const byte Jsr = 0x20;
private const byte Rti = 0x40;
private const byte Rts = 0x60;
private const byte JsrSize = 3;
2016-02-22 23:50:11 +00:00
2017-04-24 13:35:05 +00:00
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
}
2016-02-22 23:50:11 +00:00
}