diff --git a/Contralto/CPU/ConstantMemory.cs b/Contralto/CPU/ConstantMemory.cs
index 1f6a6b8..f2a8501 100644
--- a/Contralto/CPU/ConstantMemory.cs
+++ b/Contralto/CPU/ConstantMemory.cs
@@ -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 =
diff --git a/Contralto/CPU/NovaDisassembler.cs b/Contralto/CPU/NovaDisassembler.cs
index f19b466..7e8052d 100644
--- a/Contralto/CPU/NovaDisassembler.cs
+++ b/Contralto/CPU/NovaDisassembler.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Contralto.CPU
+namespace Contralto.CPU.Nova
{
///
/// Quick and dirty disassembler for Nova instructions, so we can
@@ -12,6 +12,324 @@ namespace Contralto.CPU
///
public static class NovaDisassembler
{
+ ///
+ /// Disassembles the specified instruction
+ ///
+ ///
+ ///
+ 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,
+ }
}
}
diff --git a/Contralto/CPU/Shifter.cs b/Contralto/CPU/Shifter.cs
index 2f75fa4..743e6fa 100644
--- a/Contralto/CPU/Shifter.cs
+++ b/Contralto/CPU/Shifter.cs
@@ -47,6 +47,16 @@ namespace Contralto.CPU
_magic = magic;
}
+
+ ///
+ /// TODO: this is still kind of clumsy.
+ ///
+ ///
+ public static void SetDNS(bool dns)
+ {
+ _dns = dns;
+ }
+
///
/// Does the last specified operation to the specified inputs
///
@@ -55,6 +65,12 @@ namespace Contralto.CPU
///
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;
}
}
diff --git a/Contralto/CPU/Tasks/DiskTask.cs b/Contralto/CPU/Tasks/DiskTask.cs
index e65d6e3..4e98c4a 100644
--- a/Contralto/CPU/Tasks/DiskTask.cs
+++ b/Contralto/CPU/Tasks/DiskTask.cs
@@ -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:
diff --git a/Contralto/CPU/Tasks/EmulatorTask.cs b/Contralto/CPU/Tasks/EmulatorTask.cs
index 82448a9..4c20df4 100644
--- a/Contralto/CPU/Tasks/EmulatorTask.cs
+++ b/Contralto/CPU/Tasks/EmulatorTask.cs
@@ -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;
}
}
diff --git a/Contralto/CPU/Tasks/Task.cs b/Contralto/CPU/Tasks/Task.cs
index e9451fd..45b3721 100644
--- a/Contralto/CPU/Tasks/Task.cs
+++ b/Contralto/CPU/Tasks/Task.cs
@@ -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
diff --git a/Contralto/Contralto.csproj b/Contralto/Contralto.csproj
index 85897e0..faacf86 100644
--- a/Contralto/Contralto.csproj
+++ b/Contralto/Contralto.csproj
@@ -65,6 +65,7 @@
+
@@ -78,9 +79,15 @@
PreserveNewest
+
+ PreserveNewest
+
Always
+
+ Always
+
Always
diff --git a/Contralto/Debugger.Designer.cs b/Contralto/Debugger.Designer.cs
index 3c21969..da2809d 100644
--- a/Contralto/Debugger.Designer.cs
+++ b/Contralto/Debugger.Designer.cs
@@ -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;
}
}
\ No newline at end of file
diff --git a/Contralto/Debugger.cs b/Contralto/Debugger.cs
index 5d8ebc4..2362ccb 100644
--- a/Contralto/Debugger.cs
+++ b/Contralto/Debugger.cs
@@ -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
}
}
+ ///
+ /// 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.
+ ///
+ ///
+ ///
+ 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;
}
diff --git a/Contralto/Debugger.resx b/Contralto/Debugger.resx
index 5a5826b..f85eb74 100644
--- a/Contralto/Debugger.resx
+++ b/Contralto/Debugger.resx
@@ -153,22 +153,22 @@
True
+
+ True
+
True
True
+
+ True
+
True
True
-
- True
-
-
- True
-
\ No newline at end of file
diff --git a/Contralto/Disk/diag.dsk b/Contralto/Disk/diag.dsk
new file mode 100644
index 0000000..01373f2
Binary files /dev/null and b/Contralto/Disk/diag.dsk differ
diff --git a/Contralto/Disk/tdisk4.dsk b/Contralto/Disk/tdisk4.dsk
new file mode 100644
index 0000000..81321bf
Binary files /dev/null and b/Contralto/Disk/tdisk4.dsk differ
diff --git a/Contralto/IO/DiabloPack.cs b/Contralto/IO/DiabloPack.cs
index 2b583af..3fac793 100644
--- a/Contralto/IO/DiabloPack.cs
+++ b/Contralto/IO/DiabloPack.cs
@@ -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.");
diff --git a/Contralto/IO/DiskController.cs b/Contralto/IO/DiskController.cs
index dded8f3..32979f8 100644
--- a/Contralto/IO/DiskController.cs
+++ b/Contralto/IO/DiskController.cs
@@ -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;
}
diff --git a/Contralto/Memory/Memory.cs b/Contralto/Memory/Memory.cs
index 2ed1ee6..7d097bc 100644
--- a/Contralto/Memory/Memory.cs
+++ b/Contralto/Memory/Memory.cs
@@ -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;
}
diff --git a/Contralto/OctalHelpers.cs b/Contralto/OctalHelpers.cs
index bafaf12..c7c833e 100644
--- a/Contralto/OctalHelpers.cs
+++ b/Contralto/OctalHelpers.cs
@@ -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);