mirror of
https://github.com/livingcomputermuseum/ContrAlto.git
synced 2026-01-18 00:52:47 +00:00
Some fixes to emulator task dispatch functions, added Nova disassembler, nova instruction single-step and nova instruction breakpoint support. Penciled in DNS (Nova Shift) support in emulator task. Added skeleton for Logging.
This commit is contained in:
parent
1dfd1e0be9
commit
2918ede7ce
@ -134,8 +134,8 @@ namespace Contralto.CPU
|
||||
}
|
||||
}
|
||||
|
||||
// And invert.
|
||||
return (~mappedData) & 0xff;
|
||||
// And invert lines 1-7
|
||||
return ((~mappedData) & 0x7f) | (mappedData & 0x80);
|
||||
}
|
||||
|
||||
private static RomFile[] _constantRoms =
|
||||
|
||||
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Contralto.CPU
|
||||
namespace Contralto.CPU.Nova
|
||||
{
|
||||
/// <summary>
|
||||
/// Quick and dirty disassembler for Nova instructions, so we can
|
||||
@ -12,6 +12,324 @@ namespace Contralto.CPU
|
||||
/// </summary>
|
||||
public static class NovaDisassembler
|
||||
{
|
||||
/// <summary>
|
||||
/// Disassembles the specified instruction
|
||||
/// </summary>
|
||||
/// <param name="instructionWord"></param>
|
||||
/// <returns></returns>
|
||||
public static string DisassembleInstruction(ushort address, ushort instructionWord)
|
||||
{
|
||||
string disassembly = null;
|
||||
|
||||
|
||||
switch ((InstructionClass)(instructionWord & 0xe000))
|
||||
{
|
||||
case InstructionClass.MEM:
|
||||
disassembly = DisassembleMem(address, instructionWord);
|
||||
break;
|
||||
|
||||
case InstructionClass.LDA:
|
||||
case InstructionClass.STA:
|
||||
disassembly = DisassembleLoadStore(address, instructionWord);
|
||||
break;
|
||||
|
||||
case InstructionClass.IO:
|
||||
disassembly = DisassembleIO(instructionWord);
|
||||
break;
|
||||
|
||||
default:
|
||||
// None of the above, must be ALC
|
||||
disassembly = DisassembleALC(instructionWord);
|
||||
break;
|
||||
}
|
||||
|
||||
return disassembly;
|
||||
}
|
||||
|
||||
private static string DisassembleMem(ushort address, ushort instructionWord)
|
||||
{
|
||||
StringBuilder d = new StringBuilder();
|
||||
|
||||
// Function
|
||||
MemFunction func = (MemFunction)(instructionWord & 0x1800);
|
||||
|
||||
// Indirect bit
|
||||
bool indirect = (instructionWord & 0x400) != 0;
|
||||
|
||||
// Indexing mode
|
||||
MemIndex index = (MemIndex)(instructionWord & 0x300);
|
||||
|
||||
// Displacement
|
||||
int disp = (instructionWord & 0xff);
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case MemIndex.PageZero:
|
||||
d.AppendFormat("{0}{1} {2}",
|
||||
func,
|
||||
indirect ? "@" : String.Empty,
|
||||
OctalHelpers.ToOctal(disp));
|
||||
break;
|
||||
|
||||
case MemIndex.PCRelative:
|
||||
d.AppendFormat("{0}{1} .+{2} ;({3})",
|
||||
func,
|
||||
indirect ? "@" : String.Empty,
|
||||
OctalHelpers.ToOctal((sbyte)disp),
|
||||
OctalHelpers.ToOctal((sbyte)disp + address));
|
||||
break;
|
||||
|
||||
case MemIndex.AC2Relative:
|
||||
d.AppendFormat("{0}{1} AC2+{2}",
|
||||
func,
|
||||
indirect ? "@" : String.Empty,
|
||||
OctalHelpers.ToOctal((sbyte)disp));
|
||||
break;
|
||||
|
||||
case MemIndex.AC3Relative:
|
||||
d.AppendFormat("{0}{1} AC3+{2}",
|
||||
func,
|
||||
indirect ? "@" : String.Empty,
|
||||
OctalHelpers.ToOctal((sbyte)disp));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("unexpected index type.");
|
||||
}
|
||||
|
||||
return d.ToString();
|
||||
}
|
||||
|
||||
private static string DisassembleLoadStore(ushort address, ushort instructionWord)
|
||||
{
|
||||
StringBuilder d = new StringBuilder();
|
||||
|
||||
// Accumulator
|
||||
int ac = (instructionWord & 0x1800) >> 11;
|
||||
|
||||
// Indirect bit
|
||||
bool indirect = (instructionWord & 0x400) != 0;
|
||||
|
||||
// Indexing mode
|
||||
MemIndex index = (MemIndex)(instructionWord & 0x300);
|
||||
|
||||
// Displacement
|
||||
int disp = (instructionWord & 0xff);
|
||||
|
||||
// instruction (LDA or STA)
|
||||
string inst = (InstructionClass)(instructionWord & 0x6000) == InstructionClass.LDA ? "LDA" : "STA";
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case MemIndex.PageZero:
|
||||
d.AppendFormat("{0}{1} {2},{3}",
|
||||
inst,
|
||||
indirect ? "@" : String.Empty,
|
||||
ac,
|
||||
OctalHelpers.ToOctal(disp));
|
||||
break;
|
||||
|
||||
case MemIndex.PCRelative:
|
||||
d.AppendFormat("{0}{1} {2},.+{3} ;({4})",
|
||||
inst,
|
||||
indirect ? "@" : String.Empty,
|
||||
ac,
|
||||
OctalHelpers.ToOctal((sbyte)disp),
|
||||
OctalHelpers.ToOctal((sbyte)disp + address));
|
||||
break;
|
||||
|
||||
case MemIndex.AC2Relative:
|
||||
d.AppendFormat("{0}{1} {2},AC2+{3}",
|
||||
inst,
|
||||
indirect ? "@" : String.Empty,
|
||||
ac,
|
||||
OctalHelpers.ToOctal((sbyte)disp));
|
||||
break;
|
||||
|
||||
case MemIndex.AC3Relative:
|
||||
d.AppendFormat("{0}{1} {2},AC3+{3}",
|
||||
inst,
|
||||
indirect ? "@" : String.Empty,
|
||||
ac,
|
||||
OctalHelpers.ToOctal((sbyte)disp));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("unexpected index type.");
|
||||
}
|
||||
|
||||
return d.ToString();
|
||||
}
|
||||
|
||||
private static string DisassembleIO(ushort instructionWord)
|
||||
{
|
||||
StringBuilder d = new StringBuilder();
|
||||
|
||||
// Accumulator
|
||||
int ac = (instructionWord & 0x1800) >> 11;
|
||||
|
||||
// Transfer
|
||||
IOTransfer trans = (IOTransfer)(instructionWord & 0x700);
|
||||
|
||||
// Control
|
||||
IOControl cont = (IOControl)(instructionWord & 0xc0);
|
||||
|
||||
// Device code
|
||||
int deviceCode = (instructionWord & 0x3f);
|
||||
|
||||
if (trans != IOTransfer.SKP)
|
||||
{
|
||||
d.AppendFormat("{0}{1} {2},{3}",
|
||||
trans,
|
||||
cont == IOControl.None ? String.Empty : cont.ToString(),
|
||||
ac,
|
||||
OctalHelpers.ToOctal(deviceCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
d.AppendFormat("{0} {1}",
|
||||
(IOSkip)cont,
|
||||
OctalHelpers.ToOctal(deviceCode));
|
||||
}
|
||||
|
||||
return d.ToString();
|
||||
}
|
||||
|
||||
private static string DisassembleALC(ushort instructionWord)
|
||||
{
|
||||
StringBuilder d = new StringBuilder();
|
||||
|
||||
// Grab source/dest accumulators
|
||||
int srcAC = (instructionWord & 0x6000) >> 13;
|
||||
int dstAC = (instructionWord & 0x1800) >> 11;
|
||||
|
||||
// Function
|
||||
ALCFunctions func = (ALCFunctions)(instructionWord & 0x700);
|
||||
|
||||
// Shift
|
||||
ALCShift shift = (ALCShift)(instructionWord & 0xc0);
|
||||
|
||||
// Carry
|
||||
ALCCarry carry = (ALCCarry)(instructionWord & 0x30);
|
||||
|
||||
// No load
|
||||
bool noLoad = ((instructionWord & 0x8) != 0);
|
||||
|
||||
// Skip
|
||||
ALCSkip skip = (ALCSkip)(instructionWord & 0x7);
|
||||
|
||||
// initial format (minus skip):
|
||||
// FUNC[shift][carry][noload] src, dest
|
||||
d.AppendFormat(
|
||||
"{0}{1}{2}{3} {4},{5}",
|
||||
func,
|
||||
shift == ALCShift.None ? String.Empty : shift.ToString(),
|
||||
carry == ALCCarry.None ? String.Empty : carry.ToString(),
|
||||
noLoad ? "#" : String.Empty,
|
||||
srcAC,
|
||||
dstAC);
|
||||
|
||||
// If a skip is specified, tack it on
|
||||
if (skip != ALCSkip.None)
|
||||
{
|
||||
d.AppendFormat(",{0}", skip);
|
||||
}
|
||||
|
||||
|
||||
return d.ToString();
|
||||
}
|
||||
|
||||
private enum InstructionClass
|
||||
{
|
||||
MEM = 0x0000,
|
||||
LDA = 0x2000,
|
||||
STA = 0x4000,
|
||||
IO = 0x6000,
|
||||
}
|
||||
|
||||
private enum ALCFunctions
|
||||
{
|
||||
COM = 0x000,
|
||||
NEG = 0x100,
|
||||
MOV = 0x200,
|
||||
INC = 0x300,
|
||||
ADC = 0x400,
|
||||
SUB = 0x500,
|
||||
ADD = 0x600,
|
||||
AND = 0x700,
|
||||
}
|
||||
|
||||
private enum ALCShift
|
||||
{
|
||||
None = 0x00,
|
||||
L = 0x40,
|
||||
R = 0x80,
|
||||
S = 0xc0,
|
||||
}
|
||||
|
||||
private enum ALCCarry
|
||||
{
|
||||
None = 0x00,
|
||||
Z = 0x10,
|
||||
O = 0x20,
|
||||
C = 0x30,
|
||||
}
|
||||
|
||||
private enum ALCSkip
|
||||
{
|
||||
None = 0x0,
|
||||
SKP = 0x1,
|
||||
SZC = 0x2,
|
||||
SNC = 0x3,
|
||||
SZR = 0x4,
|
||||
SNR = 0x5,
|
||||
SEZ = 0x6,
|
||||
SBN = 0x7,
|
||||
}
|
||||
|
||||
private enum IOTransfer
|
||||
{
|
||||
NIO = 0x000,
|
||||
DIA = 0x100,
|
||||
DOA = 0x200,
|
||||
DIB = 0x300,
|
||||
DOB = 0x400,
|
||||
DIC = 0x500,
|
||||
DOC = 0x600,
|
||||
SKP = 0x700,
|
||||
}
|
||||
|
||||
private enum IOControl
|
||||
{
|
||||
None = 0x00,
|
||||
S = 0x40,
|
||||
C = 0x80,
|
||||
P = 0xc0,
|
||||
}
|
||||
|
||||
private enum IOSkip
|
||||
{
|
||||
SKPBN = 0x00,
|
||||
SKPBZ = 0x40,
|
||||
SKPDN = 0x80,
|
||||
SKPDZ = 0xc0,
|
||||
}
|
||||
|
||||
private enum MemFunction
|
||||
{
|
||||
JMP = 0x0000,
|
||||
JSR = 0x0800,
|
||||
ISZ = 0x1000,
|
||||
DSZ = 0x1800,
|
||||
}
|
||||
|
||||
private enum MemIndex
|
||||
{
|
||||
PageZero = 0x000,
|
||||
PCRelative = 0x100,
|
||||
AC2Relative = 0x200,
|
||||
AC3Relative = 0x300,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,16 @@ namespace Contralto.CPU
|
||||
_magic = magic;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TODO: this is still kind of clumsy.
|
||||
/// </summary>
|
||||
/// <param name="dns"></param>
|
||||
public static void SetDNS(bool dns)
|
||||
{
|
||||
_dns = dns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the last specified operation to the specified inputs
|
||||
/// </summary>
|
||||
@ -55,6 +65,12 @@ namespace Contralto.CPU
|
||||
/// <returns></returns>
|
||||
public static ushort DoOperation(ushort input, ushort t)
|
||||
{
|
||||
// Sanity check: MAGIC and DNS cannot be set at the same time.
|
||||
if (_magic && _dns)
|
||||
{
|
||||
throw new InvalidOperationException("Both MAGIC and DNS bits are set.");
|
||||
}
|
||||
|
||||
ushort output = 0;
|
||||
switch(_op)
|
||||
{
|
||||
@ -74,6 +90,10 @@ namespace Contralto.CPU
|
||||
// shifter output on left shifts..."
|
||||
output |= (ushort)((t & 0x8000) >> 15);
|
||||
}
|
||||
else if (_dns)
|
||||
{
|
||||
throw new NotImplementedException("DNS LSH 1");
|
||||
}
|
||||
break;
|
||||
|
||||
case ShifterOp.ShiftRight:
|
||||
@ -85,6 +105,10 @@ namespace Contralto.CPU
|
||||
// of the shifter output on right shifts."
|
||||
output |= (ushort)((t & 0x1) << 15);
|
||||
}
|
||||
else if (_dns)
|
||||
{
|
||||
throw new NotImplementedException("DNS RSH 1");
|
||||
}
|
||||
break;
|
||||
|
||||
case ShifterOp.RotateLeft:
|
||||
@ -95,6 +119,11 @@ namespace Contralto.CPU
|
||||
int c = (output & 0x8000) >> 15;
|
||||
output = (ushort)((output << 1) | c);
|
||||
}
|
||||
|
||||
if (_dns)
|
||||
{
|
||||
throw new NotImplementedException("DNS LCY");
|
||||
}
|
||||
break;
|
||||
|
||||
case ShifterOp.RotateRight:
|
||||
@ -117,5 +146,6 @@ namespace Contralto.CPU
|
||||
private static ShifterOp _op;
|
||||
private static int _count;
|
||||
private static bool _magic;
|
||||
private static bool _dns;
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,8 +45,7 @@ namespace Contralto.CPU
|
||||
return _cpu._system.DiskController.KSTAT;
|
||||
|
||||
case DiskBusSource.ReadKDATA:
|
||||
ushort kdata = _cpu._system.DiskController.KDATA;
|
||||
Console.WriteLine("kdata read {0}", OctalHelpers.ToOctal(kdata));
|
||||
ushort kdata = _cpu._system.DiskController.KDATA;
|
||||
return kdata;
|
||||
|
||||
default:
|
||||
@ -89,9 +88,7 @@ namespace Contralto.CPU
|
||||
// KSTAT[13].)"
|
||||
|
||||
// OR in BUS[12-15] after masking in KSTAT[13] so it is ORed in properly.
|
||||
_cpu._system.DiskController.KSTAT = (ushort)(((_cpu._system.DiskController.KSTAT & 0xfff4)) | (_busData & 0xf));
|
||||
|
||||
Console.WriteLine("KSTAT loaded with {0}, is now {1}", (_busData & 0xf), _cpu._system.DiskController.KSTAT);
|
||||
_cpu._system.DiskController.KSTAT = (ushort)(((_cpu._system.DiskController.KSTAT & 0xfff4)) | (_busData & 0xf));
|
||||
break;
|
||||
|
||||
case DiskF1.STROBE:
|
||||
|
||||
@ -198,12 +198,23 @@ namespace Contralto.CPU
|
||||
// There is considerably more that goes into determining the dispatch, which is controlled by a 256x8
|
||||
// PROM. We just use the PROM rather than implementing the above logic (because it works.)
|
||||
//
|
||||
_nextModifier = ControlROM.ACSourceROM[(_cpu._ir & 0xff00) >> 8];
|
||||
|
||||
|
||||
if ((_cpu._ir & 0x8000) != 0)
|
||||
{
|
||||
// 3-IR[8-9] (shift field of arithmetic instruction)
|
||||
_nextModifier = (ushort)(3 - ((_cpu._ir & 0xc0) >> 6));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the PROM.
|
||||
// We OR in 0x80 because the top address line is controlled by the value of ACSOURCE(2), which is always
|
||||
// 1 here (since ACSOURCE is 14 decimal).
|
||||
_nextModifier = ControlROM.ACSourceROM[((_cpu._ir & 0x7f00) >> 8) | 0x80];
|
||||
}
|
||||
break;
|
||||
|
||||
case EmulatorF2.ACDEST:
|
||||
// Handled in early handler
|
||||
// Handled in early handler, nothing to do here.
|
||||
break;
|
||||
|
||||
case EmulatorF2.BUSODD:
|
||||
@ -215,10 +226,15 @@ namespace Contralto.CPU
|
||||
case EmulatorF2.MAGIC:
|
||||
Shifter.SetMagic(true);
|
||||
break;
|
||||
|
||||
|
||||
case EmulatorF2.LoadDNS:
|
||||
// DNS<- modifies the normal shift operations.
|
||||
Shifter.SetDNS(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException(String.Format("Unhandled emulator F2 {0}.", ef2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,7 +72,13 @@ namespace Contralto.CPU
|
||||
{
|
||||
// TODO: cache microinstructions (or pre-decode them) to save consing all these up every time.
|
||||
MicroInstruction instruction = new MicroInstruction(UCodeMemory.UCodeROM[_mpc]);
|
||||
|
||||
// Grab BLOCK bit so that other tasks can look at it
|
||||
_block = instruction.F1 == SpecialFunction1.Block;
|
||||
|
||||
//Console.WriteLine("R5:{0},R6:{1},IR:{2} - {3}:{4}", OctalHelpers.ToOctal(_cpu._r[5]), OctalHelpers.ToOctal(_cpu._r[6]), OctalHelpers.ToOctal(_cpu._ir), OctalHelpers.ToOctal(_mpc), UCodeDisassembler.DisassembleInstruction(instruction, _taskType));
|
||||
|
||||
|
||||
return ExecuteInstruction(instruction);
|
||||
}
|
||||
|
||||
@ -100,9 +106,11 @@ namespace Contralto.CPU
|
||||
// the memory isn't ready yet.
|
||||
// TODO: this needs to be seriously cleaned up.
|
||||
//
|
||||
if (instruction.BS == BusSource.ReadMD ||
|
||||
if ((instruction.BS == BusSource.ReadMD &&
|
||||
(instruction.F1 != SpecialFunction1.Constant &&
|
||||
instruction.F2 != SpecialFunction2.Constant)) || // ReadMD only occurs if not reading from constant ROM.
|
||||
instruction.F1 == SpecialFunction1.LoadMAR ||
|
||||
instruction.F2 == SpecialFunction2.StoreMD)
|
||||
instruction.F2 == SpecialFunction2.StoreMD)
|
||||
{
|
||||
|
||||
MemoryOperation op;
|
||||
@ -336,12 +344,7 @@ namespace Contralto.CPU
|
||||
// Do writeback to selected R register from shifter output
|
||||
if (loadR)
|
||||
{
|
||||
_cpu._r[_rSelect] = Shifter.DoOperation(_cpu._l, _cpu._t);
|
||||
|
||||
if(_rSelect == 26)
|
||||
{
|
||||
Console.WriteLine("cksum is now {0}", OctalHelpers.ToOctal(_cpu._r[_rSelect]));
|
||||
}
|
||||
_cpu._r[_rSelect] = Shifter.DoOperation(_cpu._l, _cpu._t);
|
||||
}
|
||||
|
||||
// Do writeback to selected R register from M
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
<Compile Include="IO\DiskController.cs" />
|
||||
<Compile Include="IO\DiabloPack.cs" />
|
||||
<Compile Include="IO\Keyboard.cs" />
|
||||
<Compile Include="Logging\Log.cs" />
|
||||
<Compile Include="Memory\IMemoryMappedDevice.cs" />
|
||||
<Compile Include="Memory\Memory.cs" />
|
||||
<Compile Include="Memory\MemoryBus.cs" />
|
||||
@ -78,9 +79,15 @@
|
||||
<None Include="Disassembly\altoIIcode3.mu">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Disk\diag.dsk">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Disk\games.dsk">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Disk\tdisk4.dsk">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="ROM\2kctl.u3">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
180
Contralto/Debugger.Designer.cs
generated
180
Contralto/Debugger.Designer.cs
generated
@ -43,8 +43,6 @@
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle13 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle14 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle15 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle16 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle17 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
this.Microcode = new System.Windows.Forms.GroupBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.JumpToAddress = new System.Windows.Forms.TextBox();
|
||||
@ -73,8 +71,6 @@
|
||||
this.RegValue = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
||||
this._memoryData = new System.Windows.Forms.DataGridView();
|
||||
this.Address = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.Data = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.ExecutionStateLabel = new System.Windows.Forms.Label();
|
||||
this.groupBox5 = new System.Windows.Forms.GroupBox();
|
||||
@ -82,11 +78,12 @@
|
||||
this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.ResetButton = new System.Windows.Forms.Button();
|
||||
this.groupBox6 = new System.Windows.Forms.GroupBox();
|
||||
this._debugTasks = new System.Windows.Forms.DataGridView();
|
||||
this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||
this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.RunToNextTaskButton = new System.Windows.Forms.Button();
|
||||
this.B = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||
this.Address = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.Data = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.Disassembly = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.NovaStep = new System.Windows.Forms.Button();
|
||||
this.Microcode.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._sourceViewer)).BeginInit();
|
||||
this.groupBox1.SuspendLayout();
|
||||
@ -99,8 +96,6 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this._memoryData)).BeginInit();
|
||||
this.groupBox5.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._diskData)).BeginInit();
|
||||
this.groupBox6.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._debugTasks)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// Microcode
|
||||
@ -329,7 +324,7 @@
|
||||
//
|
||||
// StopButton
|
||||
//
|
||||
this.StopButton.Location = new System.Drawing.Point(207, 954);
|
||||
this.StopButton.Location = new System.Drawing.Point(351, 955);
|
||||
this.StopButton.Name = "StopButton";
|
||||
this.StopButton.Size = new System.Drawing.Size(43, 23);
|
||||
this.StopButton.TabIndex = 6;
|
||||
@ -475,9 +470,9 @@
|
||||
// groupBox4
|
||||
//
|
||||
this.groupBox4.Controls.Add(this._memoryData);
|
||||
this.groupBox4.Location = new System.Drawing.Point(319, 634);
|
||||
this.groupBox4.Location = new System.Drawing.Point(172, 634);
|
||||
this.groupBox4.Name = "groupBox4";
|
||||
this.groupBox4.Size = new System.Drawing.Size(144, 344);
|
||||
this.groupBox4.Size = new System.Drawing.Size(291, 298);
|
||||
this.groupBox4.TabIndex = 8;
|
||||
this.groupBox4.TabStop = false;
|
||||
this.groupBox4.Text = "Memory";
|
||||
@ -490,8 +485,10 @@
|
||||
this._memoryData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle12;
|
||||
this._memoryData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
this._memoryData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.B,
|
||||
this.Address,
|
||||
this.Data});
|
||||
this.Data,
|
||||
this.Disassembly});
|
||||
dataGridViewCellStyle13.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||
dataGridViewCellStyle13.BackColor = System.Drawing.SystemColors.Window;
|
||||
dataGridViewCellStyle13.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
@ -513,25 +510,9 @@
|
||||
this._memoryData.ShowCellToolTips = false;
|
||||
this._memoryData.ShowEditingIcon = false;
|
||||
this._memoryData.ShowRowErrors = false;
|
||||
this._memoryData.Size = new System.Drawing.Size(132, 319);
|
||||
this._memoryData.Size = new System.Drawing.Size(279, 273);
|
||||
this._memoryData.TabIndex = 0;
|
||||
//
|
||||
// Address
|
||||
//
|
||||
this.Address.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
|
||||
this.Address.HeaderText = "Addr";
|
||||
this.Address.MinimumWidth = 16;
|
||||
this.Address.Name = "Address";
|
||||
this.Address.ReadOnly = true;
|
||||
this.Address.Width = 54;
|
||||
//
|
||||
// Data
|
||||
//
|
||||
this.Data.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||
this.Data.HeaderText = "Data";
|
||||
this.Data.MinimumWidth = 16;
|
||||
this.Data.Name = "Data";
|
||||
this.Data.ReadOnly = true;
|
||||
this._memoryData.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.MemoryViewCellClick);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
@ -554,7 +535,7 @@
|
||||
// groupBox5
|
||||
//
|
||||
this.groupBox5.Controls.Add(this._diskData);
|
||||
this.groupBox5.Location = new System.Drawing.Point(150, 634);
|
||||
this.groupBox5.Location = new System.Drawing.Point(3, 634);
|
||||
this.groupBox5.Name = "groupBox5";
|
||||
this.groupBox5.Size = new System.Drawing.Size(163, 298);
|
||||
this.groupBox5.TabIndex = 11;
|
||||
@ -614,7 +595,7 @@
|
||||
//
|
||||
// ResetButton
|
||||
//
|
||||
this.ResetButton.Location = new System.Drawing.Point(256, 955);
|
||||
this.ResetButton.Location = new System.Drawing.Point(400, 955);
|
||||
this.ResetButton.Name = "ResetButton";
|
||||
this.ResetButton.Size = new System.Drawing.Size(57, 23);
|
||||
this.ResetButton.TabIndex = 12;
|
||||
@ -622,69 +603,6 @@
|
||||
this.ResetButton.UseVisualStyleBackColor = true;
|
||||
this.ResetButton.Click += new System.EventHandler(this.ResetButton_Click);
|
||||
//
|
||||
// groupBox6
|
||||
//
|
||||
this.groupBox6.Controls.Add(this._debugTasks);
|
||||
this.groupBox6.Location = new System.Drawing.Point(3, 634);
|
||||
this.groupBox6.Name = "groupBox6";
|
||||
this.groupBox6.Size = new System.Drawing.Size(141, 298);
|
||||
this.groupBox6.TabIndex = 12;
|
||||
this.groupBox6.TabStop = false;
|
||||
this.groupBox6.Text = "Debug Tasks";
|
||||
//
|
||||
// _debugTasks
|
||||
//
|
||||
this._debugTasks.AllowUserToAddRows = false;
|
||||
this._debugTasks.AllowUserToDeleteRows = false;
|
||||
dataGridViewCellStyle16.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
|
||||
this._debugTasks.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle16;
|
||||
this._debugTasks.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
this._debugTasks.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.dataGridViewTextBoxColumn3,
|
||||
this.dataGridViewTextBoxColumn4});
|
||||
dataGridViewCellStyle17.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||
dataGridViewCellStyle17.BackColor = System.Drawing.SystemColors.Window;
|
||||
dataGridViewCellStyle17.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
dataGridViewCellStyle17.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
dataGridViewCellStyle17.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle17.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle17.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this._debugTasks.DefaultCellStyle = dataGridViewCellStyle17;
|
||||
this._debugTasks.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
|
||||
this._debugTasks.Location = new System.Drawing.Point(6, 19);
|
||||
this._debugTasks.MultiSelect = false;
|
||||
this._debugTasks.Name = "_debugTasks";
|
||||
this._debugTasks.ReadOnly = true;
|
||||
this._debugTasks.RowHeadersVisible = false;
|
||||
this._debugTasks.RowTemplate.DefaultCellStyle.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this._debugTasks.RowTemplate.Height = 18;
|
||||
this._debugTasks.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||
this._debugTasks.ShowCellErrors = false;
|
||||
this._debugTasks.ShowCellToolTips = false;
|
||||
this._debugTasks.ShowEditingIcon = false;
|
||||
this._debugTasks.ShowRowErrors = false;
|
||||
this._debugTasks.Size = new System.Drawing.Size(129, 273);
|
||||
this._debugTasks.TabIndex = 1;
|
||||
//
|
||||
// dataGridViewTextBoxColumn3
|
||||
//
|
||||
this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
|
||||
this.dataGridViewTextBoxColumn3.HeaderText = "Debug";
|
||||
this.dataGridViewTextBoxColumn3.MinimumWidth = 16;
|
||||
this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3";
|
||||
this.dataGridViewTextBoxColumn3.ReadOnly = true;
|
||||
this.dataGridViewTextBoxColumn3.Resizable = System.Windows.Forms.DataGridViewTriState.True;
|
||||
this.dataGridViewTextBoxColumn3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
|
||||
this.dataGridViewTextBoxColumn3.Width = 16;
|
||||
//
|
||||
// dataGridViewTextBoxColumn4
|
||||
//
|
||||
this.dataGridViewTextBoxColumn4.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||
this.dataGridViewTextBoxColumn4.HeaderText = "Task";
|
||||
this.dataGridViewTextBoxColumn4.MinimumWidth = 16;
|
||||
this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4";
|
||||
this.dataGridViewTextBoxColumn4.ReadOnly = true;
|
||||
//
|
||||
// RunToNextTaskButton
|
||||
//
|
||||
this.RunToNextTaskButton.Location = new System.Drawing.Point(150, 954);
|
||||
@ -695,13 +613,66 @@
|
||||
this.RunToNextTaskButton.UseVisualStyleBackColor = true;
|
||||
this.RunToNextTaskButton.Click += new System.EventHandler(this.RunToNextTaskButton_Click);
|
||||
//
|
||||
// B
|
||||
//
|
||||
this.B.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
|
||||
this.B.FalseValue = "false";
|
||||
this.B.HeaderText = "B";
|
||||
this.B.Name = "B";
|
||||
this.B.ReadOnly = true;
|
||||
this.B.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.B.ToolTipText = "Breakpoint";
|
||||
this.B.TrueValue = "true";
|
||||
this.B.Width = 20;
|
||||
//
|
||||
// Address
|
||||
//
|
||||
this.Address.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
|
||||
this.Address.HeaderText = "Addr";
|
||||
this.Address.MinimumWidth = 16;
|
||||
this.Address.Name = "Address";
|
||||
this.Address.ReadOnly = true;
|
||||
this.Address.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.Address.ToolTipText = "Address";
|
||||
this.Address.Width = 54;
|
||||
//
|
||||
// Data
|
||||
//
|
||||
this.Data.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
|
||||
this.Data.HeaderText = "Data";
|
||||
this.Data.MinimumWidth = 16;
|
||||
this.Data.Name = "Data";
|
||||
this.Data.ReadOnly = true;
|
||||
this.Data.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.Data.ToolTipText = "Data";
|
||||
this.Data.Width = 55;
|
||||
//
|
||||
// Disassembly
|
||||
//
|
||||
this.Disassembly.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||
this.Disassembly.HeaderText = "Disassembly";
|
||||
this.Disassembly.Name = "Disassembly";
|
||||
this.Disassembly.ReadOnly = true;
|
||||
this.Disassembly.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.Disassembly.ToolTipText = "Disassembly";
|
||||
//
|
||||
// NovaStep
|
||||
//
|
||||
this.NovaStep.Location = new System.Drawing.Point(207, 954);
|
||||
this.NovaStep.Name = "NovaStep";
|
||||
this.NovaStep.Size = new System.Drawing.Size(66, 23);
|
||||
this.NovaStep.TabIndex = 14;
|
||||
this.NovaStep.Text = "Nova Step";
|
||||
this.NovaStep.UseVisualStyleBackColor = true;
|
||||
this.NovaStep.Click += new System.EventHandler(this.NovaStep_Click);
|
||||
//
|
||||
// Debugger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(753, 997);
|
||||
this.Controls.Add(this.NovaStep);
|
||||
this.Controls.Add(this.RunToNextTaskButton);
|
||||
this.Controls.Add(this.groupBox6);
|
||||
this.Controls.Add(this.ResetButton);
|
||||
this.Controls.Add(this.groupBox5);
|
||||
this.Controls.Add(this.ExecutionStateLabel);
|
||||
@ -731,8 +702,6 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this._memoryData)).EndInit();
|
||||
this.groupBox5.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this._diskData)).EndInit();
|
||||
this.groupBox6.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this._debugTasks)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@ -762,8 +731,6 @@
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn RegValue;
|
||||
private System.Windows.Forms.GroupBox groupBox4;
|
||||
private System.Windows.Forms.DataGridView _memoryData;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Address;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Data;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn Breakpoint;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn T;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Addr;
|
||||
@ -777,10 +744,11 @@
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
|
||||
private System.Windows.Forms.Button ResetButton;
|
||||
private System.Windows.Forms.GroupBox groupBox6;
|
||||
private System.Windows.Forms.DataGridView _debugTasks;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn dataGridViewTextBoxColumn3;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4;
|
||||
private System.Windows.Forms.Button RunToNextTaskButton;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn B;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Address;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Data;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Disassembly;
|
||||
private System.Windows.Forms.Button NovaStep;
|
||||
}
|
||||
}
|
||||
@ -21,7 +21,8 @@ namespace Contralto
|
||||
public Debugger(AltoSystem system)
|
||||
{
|
||||
_system = system;
|
||||
_breakpointEnabled = new bool[1024];
|
||||
_microcodeBreakpointEnabled = new bool[1024];
|
||||
_novaBreakpointEnabled = new bool[65536];
|
||||
|
||||
InitializeComponent();
|
||||
InitControls();
|
||||
@ -113,11 +114,18 @@ namespace Contralto
|
||||
|
||||
for (ushort i = 0; i < 1024; i++)
|
||||
{
|
||||
_memoryData.Rows[i].Cells[1].Value = OctalHelpers.ToOctal(_system.MemoryBus.DebugReadWord(i), 6);
|
||||
_memoryData.Rows[i].Cells[2].Value = OctalHelpers.ToOctal(_system.MemoryBus.DebugReadWord(i), 6);
|
||||
_memoryData.Rows[i].Cells[3].Value = Contralto.CPU.Nova.NovaDisassembler.DisassembleInstruction(i, _system.MemoryBus.DebugReadWord(i));
|
||||
}
|
||||
|
||||
// Find the right source line
|
||||
HighlightSourceLine(_system.CPU.CurrentTask.MPC);
|
||||
// Find the right source line.
|
||||
HighlightMicrocodeSourceLine(_system.CPU.CurrentTask.MPC);
|
||||
|
||||
// Highlight the nova memory location corresponding to the emulator PC.
|
||||
// TODO: this should be configurable
|
||||
ushort pc = _system.CPU.R[6];
|
||||
|
||||
HighlightNovaSourceLine(pc);
|
||||
|
||||
// Exec state
|
||||
switch(_execState)
|
||||
@ -141,6 +149,10 @@ namespace Contralto
|
||||
case ExecutionState.BreakpointStop:
|
||||
ExecutionStateLabel.Text = "Stopped (bkpt)";
|
||||
break;
|
||||
|
||||
case ExecutionState.InternalError:
|
||||
ExecutionStateLabel.Text = String.Format("Stopped (error {0})", _lastExceptionText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +171,11 @@ namespace Contralto
|
||||
|
||||
for (ushort i=0;i<1024;i++)
|
||||
{
|
||||
_memoryData.Rows.Add(OctalHelpers.ToOctal(i, 6), OctalHelpers.ToOctal(_system.MemoryBus.DebugReadWord(i), 6));
|
||||
_memoryData.Rows.Add(
|
||||
false,
|
||||
OctalHelpers.ToOctal(i, 6),
|
||||
OctalHelpers.ToOctal(_system.MemoryBus.DebugReadWord(i), 6),
|
||||
Contralto.CPU.Nova.NovaDisassembler.DisassembleInstruction(i, _system.MemoryBus.DebugReadWord(i)));
|
||||
}
|
||||
|
||||
_otherRegs.Rows.Add("L", "0");
|
||||
@ -180,12 +196,7 @@ namespace Contralto
|
||||
_diskData.Rows.Add("KADR", "0");
|
||||
_diskData.Rows.Add("KCOM", "0");
|
||||
_diskData.Rows.Add("KSTAT", "0");
|
||||
_diskData.Rows.Add("RECNO", "0");
|
||||
|
||||
for (int i=0;i<16;i++)
|
||||
{
|
||||
_debugTasks.Rows.Add(true, GetTextForTask((TaskType)i));
|
||||
}
|
||||
_diskData.Rows.Add("RECNO", "0");
|
||||
|
||||
}
|
||||
|
||||
@ -206,13 +217,27 @@ namespace Contralto
|
||||
bool value = (bool)_sourceViewer.Rows[e.RowIndex].Cells[0].Value;
|
||||
_sourceViewer.Rows[e.RowIndex].Cells[0].Value = !value;
|
||||
|
||||
ModifyBreakpoint((UInt16)_sourceViewer.Rows[e.RowIndex].Tag, !value);
|
||||
ModifyMicrocodeBreakpoint((UInt16)_sourceViewer.Rows[e.RowIndex].Tag, !value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void HighlightSourceLine(UInt16 address)
|
||||
private void MemoryViewCellClick(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
// Check for breakpoint column click.
|
||||
if (e.ColumnIndex == 0)
|
||||
{
|
||||
// Check/uncheck the box and set/unset a breakpoint for the line
|
||||
bool value = (bool)_memoryData.Rows[e.RowIndex].Cells[0].Value;
|
||||
_memoryData.Rows[e.RowIndex].Cells[0].Value = !value;
|
||||
|
||||
ModifyNovaBreakpoint((UInt16)e.RowIndex, !value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void HighlightMicrocodeSourceLine(UInt16 address)
|
||||
{
|
||||
foreach (DataGridViewRow row in _sourceViewer.Rows)
|
||||
{
|
||||
@ -227,9 +252,24 @@ namespace Contralto
|
||||
}
|
||||
}
|
||||
|
||||
private void ModifyBreakpoint(UInt16 address, bool set)
|
||||
private void HighlightNovaSourceLine(UInt16 address)
|
||||
{
|
||||
_breakpointEnabled[address] = set;
|
||||
if (address < _memoryData.Rows.Count)
|
||||
{
|
||||
_memoryData.ClearSelection();
|
||||
_memoryData.Rows[address].Selected = true;
|
||||
_memoryData.CurrentCell = _memoryData.Rows[address].Cells[0];
|
||||
}
|
||||
}
|
||||
|
||||
private void ModifyMicrocodeBreakpoint(UInt16 address, bool set)
|
||||
{
|
||||
_microcodeBreakpointEnabled[address] = set;
|
||||
}
|
||||
|
||||
private void ModifyNovaBreakpoint(UInt16 address, bool set)
|
||||
{
|
||||
_novaBreakpointEnabled[address] = set;
|
||||
}
|
||||
|
||||
private string GetTextForTaskState(AltoCPU.Task task)
|
||||
@ -429,22 +469,7 @@ namespace Contralto
|
||||
private void Debugger_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void JumpToButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
UInt16 address = Convert.ToUInt16(JumpToAddress.Text, 8);
|
||||
|
||||
// find the source address that matches this, if any.
|
||||
HighlightSourceLine(address);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// eh, just do nothing for now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnJumpAddressKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
@ -456,7 +481,7 @@ namespace Contralto
|
||||
UInt16 address = Convert.ToUInt16(JumpToAddress.Text, 8);
|
||||
|
||||
// find the source address that matches this, if any.
|
||||
HighlightSourceLine(address);
|
||||
HighlightMicrocodeSourceLine(address);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -511,6 +536,23 @@ namespace Contralto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs microcode until next Nova instruction is started
|
||||
/// This is done by simply breaking whenever the uPC for the emulator
|
||||
/// task returns to 20(octal) -- this is the restart point for the emulator
|
||||
/// task.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void NovaStep_Click(object sender, EventArgs e)
|
||||
{
|
||||
{
|
||||
_execThread = new Thread(new System.Threading.ParameterizedThreadStart(ExecuteProc));
|
||||
_execThread.Start(ExecutionType.NextNovaInstruction);
|
||||
SetExecutionState(ExecutionState.Running);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStopButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (_execThread != null &&
|
||||
@ -547,36 +589,66 @@ namespace Contralto
|
||||
StepDelegate inv = new StepDelegate(Invalidate);
|
||||
while (true)
|
||||
{
|
||||
switch (execType)
|
||||
bool internalError = false;
|
||||
|
||||
try
|
||||
{
|
||||
case ExecutionType.Auto:
|
||||
{
|
||||
// Execute a single step, then update UI and
|
||||
// sleep to give messages time to run.
|
||||
_system.SingleStep();
|
||||
switch (execType)
|
||||
{
|
||||
case ExecutionType.Auto:
|
||||
{
|
||||
// Execute a single step, then update UI and
|
||||
// sleep to give messages time to run.
|
||||
_system.SingleStep();
|
||||
|
||||
this.BeginInvoke(refUI);
|
||||
this.BeginInvoke(inv);
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
break;
|
||||
this.BeginInvoke(refUI);
|
||||
this.BeginInvoke(inv);
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
break;
|
||||
|
||||
case ExecutionType.Step:
|
||||
case ExecutionType.Normal:
|
||||
case ExecutionType.NextTask:
|
||||
{
|
||||
// Just execute one step, do not update UI.
|
||||
_system.SingleStep();
|
||||
}
|
||||
break;
|
||||
case ExecutionType.Step:
|
||||
case ExecutionType.Normal:
|
||||
case ExecutionType.NextTask:
|
||||
case ExecutionType.NextNovaInstruction:
|
||||
{
|
||||
// Just execute one step, do not update UI.
|
||||
_system.SingleStep();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
internalError = true;
|
||||
_lastExceptionText = e.Message;
|
||||
}
|
||||
|
||||
if (_execAbort ||
|
||||
_breakpointEnabled[_system.CPU.CurrentTask.MPC] ||
|
||||
(execType == ExecutionType.NextTask && _system.CPU.NextTask != null && _system.CPU.NextTask != _system.CPU.CurrentTask))
|
||||
if (internalError)
|
||||
{
|
||||
// Stop here as we've hit a breakpoint or have been stopped Update UI
|
||||
// to indicate where we stopped.
|
||||
//
|
||||
// Stop here because of an execution error.
|
||||
//
|
||||
this.BeginInvoke(refUI);
|
||||
this.BeginInvoke(inv);
|
||||
|
||||
|
||||
SetExecutionState(ExecutionState.InternalError);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (_execAbort || // The Stop button was hit
|
||||
_microcodeBreakpointEnabled[_system.CPU.CurrentTask.MPC] || // A microcode breakpoint was hit
|
||||
(execType == ExecutionType.NextTask &&
|
||||
_system.CPU.NextTask != null &&
|
||||
_system.CPU.NextTask != _system.CPU.CurrentTask) || // The next task was switched to
|
||||
(_system.CPU.CurrentTask.MPC == 0x10 && // MPC is 20(octal) meaning a new Nova instruction and...
|
||||
(_novaBreakpointEnabled[_system.CPU.R[6]] || // A breakpoint is set here
|
||||
execType == ExecutionType.NextNovaInstruction))) // or we're running only a single Nova instruction.
|
||||
{
|
||||
// Stop here as we've hit a breakpoint or have been stopped
|
||||
// Update UI to indicate where we stopped.
|
||||
this.BeginInvoke(refUI);
|
||||
this.BeginInvoke(inv);
|
||||
|
||||
@ -587,7 +659,7 @@ namespace Contralto
|
||||
|
||||
_execAbort = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -605,6 +677,7 @@ namespace Contralto
|
||||
Auto,
|
||||
Normal,
|
||||
NextTask,
|
||||
NextNovaInstruction,
|
||||
}
|
||||
|
||||
private enum ExecutionState
|
||||
@ -614,6 +687,7 @@ namespace Contralto
|
||||
AutoStep,
|
||||
Running,
|
||||
BreakpointStop,
|
||||
InternalError,
|
||||
}
|
||||
|
||||
private delegate void StepDelegate();
|
||||
@ -627,12 +701,15 @@ namespace Contralto
|
||||
private Thread _execThread;
|
||||
private bool _execAbort;
|
||||
private ExecutionState _execState;
|
||||
private string _lastExceptionText;
|
||||
|
||||
|
||||
|
||||
// Debugger breakpoints; one entry per address since we only need
|
||||
// Microcode Debugger breakpoints; one entry per address since we only need
|
||||
// to worry about a 10 bit address space, this is fast and uses little memory.
|
||||
private bool[] _breakpointEnabled;
|
||||
private bool[] _microcodeBreakpointEnabled;
|
||||
|
||||
// Nova Debugger breakpoints; same as above
|
||||
private bool[] _novaBreakpointEnabled;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -153,22 +153,22 @@
|
||||
<metadata name="RegValue.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="B.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="Address.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="Data.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="Disassembly.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
BIN
Contralto/Disk/diag.dsk
Normal file
BIN
Contralto/Disk/diag.dsk
Normal file
Binary file not shown.
BIN
Contralto/Disk/tdisk4.dsk
Normal file
BIN
Contralto/Disk/tdisk4.dsk
Normal file
Binary file not shown.
@ -105,6 +105,7 @@ namespace Contralto.IO
|
||||
// TODO: should support different formats ("correct" raw, Alto CopyDisk format, etc.)
|
||||
//
|
||||
imageStream.Seek(2, SeekOrigin.Current);
|
||||
|
||||
if (imageStream.Read(header, 0, header.Length) != header.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Short read while reading sector header.");
|
||||
|
||||
@ -20,12 +20,12 @@ namespace Contralto.IO
|
||||
_pack = new DiabloPack(DiabloDiskType.Diablo31);
|
||||
|
||||
// TODO: this does not belong here.
|
||||
FileStream fs = new FileStream("Disk\\games.dsk", FileMode.Open, FileAccess.Read);
|
||||
FileStream fs = new FileStream("Disk\\tdisk4.dsk", FileMode.Open, FileAccess.Read);
|
||||
|
||||
_pack.Load(fs);
|
||||
|
||||
fs.Close();
|
||||
|
||||
|
||||
// Wakeup the sector task first thing
|
||||
_system.CPU.WakeupTask(CPU.TaskType.DiskSector);
|
||||
}
|
||||
@ -70,15 +70,6 @@ namespace Contralto.IO
|
||||
_wffo = (_kCom & 0x02) == 0x02;
|
||||
_sendAdr = (_kCom & 0x01) == 0x01;
|
||||
|
||||
Console.WriteLine(
|
||||
"sst {0}, xferOff {1}, wdInhib {2}, bClkSource {3}, wffo {4}, sendAdr {5}",
|
||||
_sectorWordTime,
|
||||
_xferOff,
|
||||
_wdInhib,
|
||||
_bClkSource,
|
||||
_wffo,
|
||||
_sendAdr);
|
||||
|
||||
_diskBitCounterEnable = _wffo;
|
||||
|
||||
// Update WDINIT state based on _wdInhib.
|
||||
@ -200,7 +191,7 @@ namespace Contralto.IO
|
||||
// Reset internal state machine for sector data
|
||||
_sectorWordIndex = 0;
|
||||
_sectorWordTime = 0.0;
|
||||
Console.WriteLine("New sector ({0}), switching to HeaderReadDelay state.", _sector);
|
||||
|
||||
_kData = 13;
|
||||
|
||||
// Load new sector in
|
||||
@ -371,16 +362,13 @@ namespace Contralto.IO
|
||||
//
|
||||
ushort diskWord = _sectorData[_sectorWordIndex].Data;
|
||||
|
||||
Console.WriteLine("Sector Word {0}:{1}", _sectorWordIndex, OctalHelpers.ToOctal(diskWord));
|
||||
|
||||
bool bWakeup = false;
|
||||
//
|
||||
// If the word task is enabled AND the write ("crystal") clock is enabled
|
||||
// then we will wake up the word task now.
|
||||
//
|
||||
if (!_wdInhib && !_bClkSource)
|
||||
{
|
||||
Console.WriteLine("Disk Word task wakeup due to word clock.");
|
||||
{
|
||||
bWakeup = true;
|
||||
}
|
||||
|
||||
@ -392,14 +380,12 @@ namespace Contralto.IO
|
||||
if (_wffo || _diskBitCounterEnable)
|
||||
{
|
||||
if (!_xferOff)
|
||||
{
|
||||
Console.WriteLine("KDATA loaded.");
|
||||
{
|
||||
_kData = diskWord;
|
||||
}
|
||||
|
||||
if (!_wdInhib)
|
||||
{
|
||||
Console.WriteLine("Disk Word task wakeup due to word read.");
|
||||
bWakeup = true;
|
||||
}
|
||||
}
|
||||
@ -411,8 +397,7 @@ namespace Contralto.IO
|
||||
// (not the sync word) is actually read. TODO: this should only happen on reads.
|
||||
//
|
||||
if (!_wffo && diskWord == 1)
|
||||
{
|
||||
Console.WriteLine("Sync word hit; starting bit clock for next word");
|
||||
{
|
||||
_diskBitCounterEnable = true;
|
||||
}
|
||||
|
||||
|
||||
@ -19,8 +19,7 @@ namespace Contralto.Memory
|
||||
}
|
||||
|
||||
public void Load(int address, ushort data)
|
||||
{
|
||||
Console.WriteLine("wrote {0} to {1}", OctalHelpers.ToOctal(data), OctalHelpers.ToOctal(address));
|
||||
{
|
||||
_mem[address] = data;
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,18 @@ namespace Contralto
|
||||
return Convert.ToString(i, 8);
|
||||
}
|
||||
|
||||
public static string ToOctal(sbyte s)
|
||||
{
|
||||
if (s < 0)
|
||||
{
|
||||
return "-" + Convert.ToString(-s, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToString(s, 8);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToOctal(int i, int digits)
|
||||
{
|
||||
string octalString = Convert.ToString(i, 8);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user