diff --git a/Contralto/AltoSystem.cs b/Contralto/AltoSystem.cs
index 89a8779..1226e06 100644
--- a/Contralto/AltoSystem.cs
+++ b/Contralto/AltoSystem.cs
@@ -51,6 +51,17 @@ namespace Contralto
_displayController.Reset();
}
+ ///
+ /// Attaches an emulated display device to the system.
+ /// TODO: This is currently tightly-coupled with the Debugger, make
+ /// more general.
+ ///
+ ///
+ public void AttachDisplay(Debugger d)
+ {
+ _displayController.AttachDisplay(d);
+ }
+
public void SingleStep()
{
// Run every device that needs attention for a single clock cycle.
@@ -75,6 +86,11 @@ namespace Contralto
get { return _diskController; }
}
+ public DisplayController DisplayController
+ {
+ get { return _displayController; }
+ }
+
///
/// Time (in msec) for one system clock
///
diff --git a/Contralto/CPU/CPU.cs b/Contralto/CPU/CPU.cs
index c85efb6..70b1da1 100644
--- a/Contralto/CPU/CPU.cs
+++ b/Contralto/CPU/CPU.cs
@@ -31,11 +31,28 @@ namespace Contralto.CPU
_tasks[(int)TaskType.Emulator] = new EmulatorTask(this);
_tasks[(int)TaskType.DiskSector] = new DiskTask(this, true);
_tasks[(int)TaskType.DiskWord] = new DiskTask(this, false);
- _tasks[(int)TaskType.DisplayWord] = new DisplayWordTask(this);
+ //_tasks[(int)TaskType.DisplayWord] = new DisplayWordTask(this);
+ //_tasks[(int)TaskType.DisplayHorizontal] = new DisplayHorizontalTask(this);
+ //_tasks[(int)TaskType.DisplayVertical] = new DisplayVerticalTask(this);
+ //_tasks[(int)TaskType.Cursor] = new CursorTask(this);
+ _tasks[(int)TaskType.MemoryRefresh] = new MemoryRefreshTask(this);
Reset();
}
+ public void Hack()
+ {
+ _tasks[(int)TaskType.DisplayWord] = new DisplayWordTask(this);
+ _tasks[(int)TaskType.DisplayHorizontal] = new DisplayHorizontalTask(this);
+ _tasks[(int)TaskType.DisplayVertical] = new DisplayVerticalTask(this);
+ _tasks[(int)TaskType.Cursor] = new CursorTask(this);
+
+ _tasks[(int)TaskType.DisplayWord].Reset();
+ _tasks[(int)TaskType.DisplayHorizontal].Reset();
+ _tasks[(int)TaskType.DisplayVertical].Reset();
+ _tasks[(int)TaskType.Cursor].Reset();
+ }
+
public Task[] Tasks
{
get { return _tasks; }
@@ -148,6 +165,18 @@ namespace Contralto.CPU
}
}
+ public bool IsBlocked(TaskType task)
+ {
+ if (_tasks[(int)task] != null)
+ {
+ return _tasks[(int)task].Wakeup;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
///
/// Used by the debugger to determine if a task switch is taking
/// place.
diff --git a/Contralto/CPU/Tasks/CursorTask.cs b/Contralto/CPU/Tasks/CursorTask.cs
new file mode 100644
index 0000000..b5bcae7
--- /dev/null
+++ b/Contralto/CPU/Tasks/CursorTask.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Contralto.Memory;
+
+namespace Contralto.CPU
+{
+ public partial class AltoCPU
+ {
+ ///
+ /// DisplayWordTask provides functionality for the DWT task
+ ///
+ private class CursorTask : Task
+ {
+ public CursorTask(AltoCPU cpu) : base(cpu)
+ {
+ _taskType = TaskType.DisplayWord;
+
+ // The Wakeup signal is always true for the Emulator task.
+ _wakeup = false;
+ }
+
+ protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
+ {
+ DisplayWordF2 ef2 = (DisplayWordF2)instruction.F2;
+ switch (ef2)
+ {
+ case DisplayWordF2.LoadDDR:
+
+ break;
+
+ default:
+ throw new InvalidOperationException(String.Format("Unhandled display word F2 {0}.", ef2));
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/Contralto/CPU/Tasks/DisplayHorizontalTask.cs b/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
index 543d77a..4905a32 100644
--- a/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
+++ b/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
@@ -11,25 +11,27 @@ namespace Contralto.CPU
public partial class AltoCPU
{
///
- /// DisplayWordTask provides functionality for the DWT task
+ /// DisplayWordTask provides functionality for the DHT task
///
private class DisplayHorizontalTask : Task
{
public DisplayHorizontalTask(AltoCPU cpu) : base(cpu)
{
- _taskType = TaskType.DisplayHorizontal;
-
- // The Wakeup signal is always true for the Emulator task.
+ _taskType = TaskType.DisplayHorizontal;
_wakeup = false;
}
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
{
- DisplayWordF2 ef2 = (DisplayWordF2)instruction.F2;
+ DisplayHorizontalF2 ef2 = (DisplayHorizontalF2)instruction.F2;
switch (ef2)
{
- case DisplayWordF2.LoadDDR:
+ case DisplayHorizontalF2.EVENFIELD:
+ _nextModifier |= (ushort)(_cpu._system.DisplayController.EVENFIELD ? 1 : 0);
+ break;
+ case DisplayHorizontalF2.SETMODE:
+ // NO-op for now
break;
default:
diff --git a/Contralto/CPU/Tasks/DisplayVerticalTask.cs b/Contralto/CPU/Tasks/DisplayVerticalTask.cs
new file mode 100644
index 0000000..5c48279
--- /dev/null
+++ b/Contralto/CPU/Tasks/DisplayVerticalTask.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Contralto.Memory;
+
+namespace Contralto.CPU
+{
+ public partial class AltoCPU
+ {
+ ///
+ /// DisplayVerticalTask provides functionality for the DVT task
+ ///
+ private class DisplayVerticalTask : Task
+ {
+ public DisplayVerticalTask(AltoCPU cpu) : base(cpu)
+ {
+ _taskType = TaskType.DisplayVertical;
+ _wakeup = false;
+ }
+
+ protected override bool ExecuteInstruction(MicroInstruction instruction)
+ {
+ // We put ourselves back to sleep immediately once we've started running
+ _wakeup = false;
+
+ return base.ExecuteInstruction(instruction);
+ }
+
+ protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
+ {
+ DisplayVerticalF2 ef2 = (DisplayVerticalF2)instruction.F2;
+ switch (ef2)
+ {
+ case DisplayVerticalF2.EVENFIELD:
+ _nextModifier |= (ushort)(_cpu._system.DisplayController.EVENFIELD ? 1 : 0);
+ break;
+
+ default:
+ throw new InvalidOperationException(String.Format("Unhandled display vertical F2 {0}.", ef2));
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/Contralto/CPU/Tasks/DisplayWordTask.cs b/Contralto/CPU/Tasks/DisplayWordTask.cs
index 8f1768d..d2bf2b0 100644
--- a/Contralto/CPU/Tasks/DisplayWordTask.cs
+++ b/Contralto/CPU/Tasks/DisplayWordTask.cs
@@ -17,19 +17,17 @@ namespace Contralto.CPU
{
public DisplayWordTask(AltoCPU cpu) : base(cpu)
{
- _taskType = TaskType.DisplayWord;
-
- // The Wakeup signal is always true for the Emulator task.
+ _taskType = TaskType.DisplayWord;
_wakeup = false;
}
-
+
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
{
DisplayWordF2 ef2 = (DisplayWordF2)instruction.F2;
switch (ef2)
{
case DisplayWordF2.LoadDDR:
-
+ _cpu._system.DisplayController.LoadDDR(_busData);
break;
default:
diff --git a/Contralto/CPU/Tasks/MemoryRefreshTask.cs b/Contralto/CPU/Tasks/MemoryRefreshTask.cs
new file mode 100644
index 0000000..1342c35
--- /dev/null
+++ b/Contralto/CPU/Tasks/MemoryRefreshTask.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Contralto.Memory;
+
+namespace Contralto.CPU
+{
+ public partial class AltoCPU
+ {
+ ///
+ /// DisplayWordTask provides functionality for the Memory Refresh task
+ ///
+ private class MemoryRefreshTask : Task
+ {
+ public MemoryRefreshTask(AltoCPU cpu) : base(cpu)
+ {
+ _taskType = TaskType.MemoryRefresh;
+
+ _wakeup = false;
+ }
+ }
+ }
+}
diff --git a/Contralto/CPU/Tasks/Task.cs b/Contralto/CPU/Tasks/Task.cs
index 35d3145..d185751 100644
--- a/Contralto/CPU/Tasks/Task.cs
+++ b/Contralto/CPU/Tasks/Task.cs
@@ -71,9 +71,9 @@ namespace Contralto.CPU
public bool ExecuteNext()
{
// TODO: cache microinstructions (or pre-decode them) to save consing all these up every time.
- MicroInstruction instruction = new MicroInstruction(UCodeMemory.UCodeROM[_mpc]);
+ MicroInstruction instruction = UCodeMemory.DecodeCache[_mpc];
- // Grab BLOCK bit so that other tasks can look at it
+ // Grab BLOCK bit so that other tasks / hardware 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));
diff --git a/Contralto/CPU/UCodeMemory.cs b/Contralto/CPU/UCodeMemory.cs
index 279bb94..640f48a 100644
--- a/Contralto/CPU/UCodeMemory.cs
+++ b/Contralto/CPU/UCodeMemory.cs
@@ -32,6 +32,9 @@ namespace Contralto.CPU
{
_uCodeRam = new UInt32[1024];
LoadMicrocode(_uCodeRoms);
+
+ _decodeCache = new MicroInstruction[2048];
+ CacheMicrocodeDecode();
}
public static UInt32[] UCodeROM
@@ -44,6 +47,11 @@ namespace Contralto.CPU
get { return _uCodeRam; }
}
+ public static MicroInstruction[] DecodeCache
+ {
+ get { return _decodeCache; }
+ }
+
private static void LoadMicrocode(RomFile[] romInfo)
{
_uCodeRom = new UInt32[2048];
@@ -90,6 +98,14 @@ namespace Contralto.CPU
return mappedAddress;
}
+ private static void CacheMicrocodeDecode()
+ {
+ for(int i=0;i<_uCodeRom.Length;i++)
+ {
+ _decodeCache[i] = new MicroInstruction(_uCodeRom[i]);
+ }
+ }
+
private static RomFile[] _uCodeRoms =
{
// first K
@@ -114,7 +130,10 @@ namespace Contralto.CPU
};
private static UInt32[] _uCodeRom;
- private static UInt32[] _uCodeRam;
+ private static UInt32[] _uCodeRam;
+
+
+ private static MicroInstruction[] _decodeCache;
}
diff --git a/Contralto/Contralto.csproj b/Contralto/Contralto.csproj
index 99f9a4c..7e61926 100644
--- a/Contralto/Contralto.csproj
+++ b/Contralto/Contralto.csproj
@@ -48,7 +48,10 @@
+
+
+
diff --git a/Contralto/Debugger.Designer.cs b/Contralto/Debugger.Designer.cs
index 554b743..ba51e8c 100644
--- a/Contralto/Debugger.Designer.cs
+++ b/Contralto/Debugger.Designer.cs
@@ -28,21 +28,21 @@
///
private void InitializeComponent()
{
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle10 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle11 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle12 = new System.Windows.Forms.DataGridViewCellStyle();
- 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 dataGridViewCellStyle20 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle17 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle18 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle19 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle21 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle22 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle23 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle24 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle25 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle26 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle27 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle28 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle29 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle30 = 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();
@@ -84,6 +84,9 @@
this.Address = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Data = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Disassembly = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.groupBox6 = new System.Windows.Forms.GroupBox();
+ this.DisplayBox = new System.Windows.Forms.PictureBox();
+ this.button1 = new System.Windows.Forms.Button();
this.Microcode.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._sourceViewer)).BeginInit();
this.groupBox1.SuspendLayout();
@@ -96,6 +99,8 @@
((System.ComponentModel.ISupportInitialize)(this._memoryData)).BeginInit();
this.groupBox5.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._diskData)).BeginInit();
+ this.groupBox6.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.DisplayBox)).BeginInit();
this.SuspendLayout();
//
// Microcode
@@ -133,8 +138,8 @@
this._sourceViewer.AllowUserToDeleteRows = false;
this._sourceViewer.AllowUserToResizeColumns = false;
this._sourceViewer.AllowUserToResizeRows = false;
- dataGridViewCellStyle1.BackColor = System.Drawing.Color.Silver;
- this._sourceViewer.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;
+ dataGridViewCellStyle16.BackColor = System.Drawing.Color.Silver;
+ this._sourceViewer.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle16;
this._sourceViewer.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.SingleVertical;
this._sourceViewer.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._sourceViewer.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
@@ -147,14 +152,14 @@
this._sourceViewer.Name = "_sourceViewer";
this._sourceViewer.ReadOnly = true;
this._sourceViewer.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
- dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle5.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this._sourceViewer.RowHeadersDefaultCellStyle = dataGridViewCellStyle5;
+ dataGridViewCellStyle20.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle20.BackColor = System.Drawing.SystemColors.Control;
+ dataGridViewCellStyle20.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle20.ForeColor = System.Drawing.SystemColors.WindowText;
+ dataGridViewCellStyle20.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle20.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle20.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
+ this._sourceViewer.RowHeadersDefaultCellStyle = dataGridViewCellStyle20;
this._sourceViewer.RowHeadersVisible = false;
this._sourceViewer.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
this._sourceViewer.RowTemplate.Height = 18;
@@ -182,9 +187,9 @@
// T
//
this.T.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
- dataGridViewCellStyle2.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.T.DefaultCellStyle = dataGridViewCellStyle2;
+ dataGridViewCellStyle17.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle17.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
+ this.T.DefaultCellStyle = dataGridViewCellStyle17;
this.T.HeaderText = "T";
this.T.Name = "T";
this.T.ReadOnly = true;
@@ -195,8 +200,8 @@
// Addr
//
this.Addr.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
- dataGridViewCellStyle3.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.Addr.DefaultCellStyle = dataGridViewCellStyle3;
+ dataGridViewCellStyle18.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.Addr.DefaultCellStyle = dataGridViewCellStyle18;
this.Addr.HeaderText = "Addr";
this.Addr.Name = "Addr";
this.Addr.ReadOnly = true;
@@ -207,8 +212,8 @@
// Source
//
this.Source.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
- dataGridViewCellStyle4.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.Source.DefaultCellStyle = dataGridViewCellStyle4;
+ dataGridViewCellStyle19.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.Source.DefaultCellStyle = dataGridViewCellStyle19;
this.Source.HeaderText = "Source Code";
this.Source.Name = "Source";
this.Source.ReadOnly = true;
@@ -231,21 +236,21 @@
this._registerData.AllowUserToDeleteRows = false;
this._registerData.AllowUserToResizeColumns = false;
this._registerData.AllowUserToResizeRows = false;
- dataGridViewCellStyle6.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
- this._registerData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle6;
+ dataGridViewCellStyle21.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+ this._registerData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle21;
this._registerData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._registerData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.RegNum,
this.R,
this.S});
- dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle7.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle7.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- dataGridViewCellStyle7.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this._registerData.DefaultCellStyle = dataGridViewCellStyle7;
+ dataGridViewCellStyle22.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle22.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle22.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle22.ForeColor = System.Drawing.SystemColors.ControlText;
+ dataGridViewCellStyle22.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle22.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle22.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
+ this._registerData.DefaultCellStyle = dataGridViewCellStyle22;
this._registerData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._registerData.Location = new System.Drawing.Point(7, 19);
this._registerData.MultiSelect = false;
@@ -346,21 +351,21 @@
//
this._taskData.AllowUserToAddRows = false;
this._taskData.AllowUserToDeleteRows = false;
- dataGridViewCellStyle8.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
- this._taskData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle8;
+ dataGridViewCellStyle23.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+ this._taskData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle23;
this._taskData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._taskData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.TaskName,
this.TaskState,
this.TaskPC});
- dataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle9.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle9.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- dataGridViewCellStyle9.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle9.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle9.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this._taskData.DefaultCellStyle = dataGridViewCellStyle9;
+ dataGridViewCellStyle24.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle24.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle24.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle24.ForeColor = System.Drawing.SystemColors.ControlText;
+ dataGridViewCellStyle24.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle24.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle24.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
+ this._taskData.DefaultCellStyle = dataGridViewCellStyle24;
this._taskData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._taskData.Location = new System.Drawing.Point(7, 19);
this._taskData.MultiSelect = false;
@@ -416,20 +421,20 @@
//
this._otherRegs.AllowUserToAddRows = false;
this._otherRegs.AllowUserToDeleteRows = false;
- dataGridViewCellStyle10.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
- this._otherRegs.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle10;
+ dataGridViewCellStyle25.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+ this._otherRegs.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle25;
this._otherRegs.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._otherRegs.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Reg,
this.RegValue});
- dataGridViewCellStyle11.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle11.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle11.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- dataGridViewCellStyle11.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle11.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle11.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle11.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this._otherRegs.DefaultCellStyle = dataGridViewCellStyle11;
+ dataGridViewCellStyle26.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle26.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle26.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle26.ForeColor = System.Drawing.SystemColors.ControlText;
+ dataGridViewCellStyle26.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle26.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle26.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
+ this._otherRegs.DefaultCellStyle = dataGridViewCellStyle26;
this._otherRegs.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._otherRegs.Location = new System.Drawing.Point(7, 19);
this._otherRegs.MultiSelect = false;
@@ -482,8 +487,8 @@
this._memoryData.AllowUserToAddRows = false;
this._memoryData.AllowUserToDeleteRows = false;
this._memoryData.AllowUserToResizeRows = false;
- dataGridViewCellStyle12.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
- this._memoryData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle12;
+ dataGridViewCellStyle27.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+ this._memoryData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle27;
this._memoryData.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
this._memoryData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._memoryData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
@@ -491,14 +496,14 @@
this.Address,
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)));
- dataGridViewCellStyle13.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle13.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle13.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle13.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this._memoryData.DefaultCellStyle = dataGridViewCellStyle13;
+ dataGridViewCellStyle28.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle28.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle28.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle28.ForeColor = System.Drawing.SystemColors.ControlText;
+ dataGridViewCellStyle28.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle28.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle28.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
+ this._memoryData.DefaultCellStyle = dataGridViewCellStyle28;
this._memoryData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._memoryData.Location = new System.Drawing.Point(6, 19);
this._memoryData.MultiSelect = false;
@@ -551,20 +556,20 @@
//
this._diskData.AllowUserToAddRows = false;
this._diskData.AllowUserToDeleteRows = false;
- dataGridViewCellStyle14.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
- this._diskData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle14;
+ dataGridViewCellStyle29.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+ this._diskData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle29;
this._diskData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._diskData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.dataGridViewTextBoxColumn1,
this.dataGridViewTextBoxColumn2});
- dataGridViewCellStyle15.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle15.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle15.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- dataGridViewCellStyle15.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle15.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle15.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle15.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this._diskData.DefaultCellStyle = dataGridViewCellStyle15;
+ dataGridViewCellStyle30.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle30.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle30.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle30.ForeColor = System.Drawing.SystemColors.ControlText;
+ dataGridViewCellStyle30.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle30.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle30.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
+ this._diskData.DefaultCellStyle = dataGridViewCellStyle30;
this._diskData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._diskData.Location = new System.Drawing.Point(6, 19);
this._diskData.MultiSelect = false;
@@ -671,11 +676,42 @@
this.Disassembly.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Disassembly.ToolTipText = "Disassembly";
//
+ // groupBox6
+ //
+ this.groupBox6.Controls.Add(this.DisplayBox);
+ this.groupBox6.Location = new System.Drawing.Point(758, 3);
+ this.groupBox6.Name = "groupBox6";
+ this.groupBox6.Size = new System.Drawing.Size(617, 834);
+ this.groupBox6.TabIndex = 15;
+ this.groupBox6.TabStop = false;
+ this.groupBox6.Text = "Display";
+ //
+ // DisplayBox
+ //
+ this.DisplayBox.BackColor = System.Drawing.SystemColors.Window;
+ this.DisplayBox.Location = new System.Drawing.Point(6, 19);
+ this.DisplayBox.Name = "DisplayBox";
+ this.DisplayBox.Size = new System.Drawing.Size(606, 808);
+ this.DisplayBox.TabIndex = 0;
+ this.DisplayBox.TabStop = false;
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(799, 873);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(75, 23);
+ this.button1.TabIndex = 1;
+ this.button1.Text = "HACK";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_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.ClientSize = new System.Drawing.Size(1376, 997);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.groupBox6);
this.Controls.Add(this.NovaStep);
this.Controls.Add(this.RunToNextTaskButton);
this.Controls.Add(this.ResetButton);
@@ -707,6 +743,8 @@
((System.ComponentModel.ISupportInitialize)(this._memoryData)).EndInit();
this.groupBox5.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this._diskData)).EndInit();
+ this.groupBox6.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.DisplayBox)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@@ -755,5 +793,8 @@
private System.Windows.Forms.DataGridViewTextBoxColumn Address;
private System.Windows.Forms.DataGridViewTextBoxColumn Data;
private System.Windows.Forms.DataGridViewTextBoxColumn Disassembly;
+ private System.Windows.Forms.GroupBox groupBox6;
+ private System.Windows.Forms.PictureBox DisplayBox;
+ private System.Windows.Forms.Button button1;
}
}
\ No newline at end of file
diff --git a/Contralto/Debugger.cs b/Contralto/Debugger.cs
index e4125e2..e8bf5a2 100644
--- a/Contralto/Debugger.cs
+++ b/Contralto/Debugger.cs
@@ -10,6 +10,7 @@ using System.Windows.Forms;
using Contralto.CPU;
using System.Threading;
+using System.Drawing.Imaging;
namespace Contralto
{
@@ -69,6 +70,43 @@ namespace Contralto
base.Refresh();
RefreshUI();
+ }
+
+ public void RefreshAltoDisplay()
+ {
+ BeginInvoke(new StepDelegate(RefreshDisplayBox));
+ }
+
+ private void RefreshDisplayBox()
+ {
+ // Update the display
+ BitmapData data = _displayBuffer.LockBits(_displayRect, ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
+
+ IntPtr ptr = data.Scan0;
+ System.Runtime.InteropServices.Marshal.Copy(_displayData, 0, ptr, _displayData.Length);
+
+ _displayBuffer.UnlockBits(data);
+ DisplayBox.Refresh();
+ }
+
+ ///
+ /// Invoked by the DisplayController to put a word on the emulated screen.
+ ///
+ ///
+ ///
+ ///
+ public void DrawDisplayWord(int scanline, int wordOffset, ushort word)
+ {
+ // TODO: move magic numbers to constants
+ int address = scanline * 76 + wordOffset * 2;
+
+ if (address > _displayData.Length)
+ {
+ throw new InvalidOperationException("Display word address is out of bounds.");
+ }
+
+ _displayData[address] = (byte)(word >> 8);
+ _displayData[address + 1] = (byte)(word);
}
private void RefreshUI()
@@ -150,6 +188,15 @@ namespace Contralto
ExecutionStateLabel.Text = String.Format("Stopped (error {0})", _lastExceptionText);
break;
}
+
+ // Update the display
+ BitmapData data = _displayBuffer.LockBits(_displayRect, ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
+
+ IntPtr ptr = data.Scan0;
+ System.Runtime.InteropServices.Marshal.Copy(_displayData, 0, ptr, _displayData.Length);
+
+ _displayBuffer.UnlockBits(data);
+
}
private void InitControls()
@@ -187,7 +234,11 @@ namespace Contralto
_diskData.Rows.Add("KADR", "0");
_diskData.Rows.Add("KCOM", "0");
_diskData.Rows.Add("KSTAT", "0");
- _diskData.Rows.Add("RECNO", "0");
+ _diskData.Rows.Add("RECNO", "0");
+
+ _displayBuffer = new Bitmap(608, 808, PixelFormat.Format1bppIndexed);
+
+ DisplayBox.Image = _displayBuffer;
}
@@ -375,7 +426,7 @@ namespace Contralto
Color.LightSeaGreen,// 8 - memory refresh
Color.LightYellow, // 9 - display word
Color.LightPink, // 10 - cursor
- Color.LightGoldenrodYellow, // 11 - display horizontal
+ Color.Chartreuse, // 11 - display horizontal
Color.LightCoral, // 12 - display vertical
Color.LightSteelBlue, // 13 - parity
Color.Gray, // 14 - disk word
@@ -763,6 +814,16 @@ namespace Contralto
// Nova Debugger breakpoints; same as above
private bool[] _novaBreakpointEnabled;
+ // Display related data.
+ // At some point this should move elsewhere.
+ // Note: display is actually 606 pixels wide, but that's not an even multiple of 8, so we round up.
+ private byte[] _displayData = new byte[808 * 76];
+ private Bitmap _displayBuffer;
+ private Rectangle _displayRect = new Rectangle(0, 0, 608, 808);
+ private void button1_Click(object sender, EventArgs e)
+ {
+ _system.CPU.Hack();
+ }
}
}
diff --git a/Contralto/Display/DisplayController.cs b/Contralto/Display/DisplayController.cs
index 12d9df9..cd3d671 100644
--- a/Contralto/Display/DisplayController.cs
+++ b/Contralto/Display/DisplayController.cs
@@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Contralto.Logging;
+using Contralto.CPU;
namespace Contralto.Display
{
@@ -17,25 +18,240 @@ namespace Contralto.Display
{
public DisplayController(AltoSystem system)
{
- _system = system;
+ _system = system;
Reset();
}
+ public void AttachDisplay(Debugger display)
+ {
+ _display = display;
+ }
+
public void Reset()
{
_evenField = true;
+ _clocks = 0;
+ _totalClocks = 0;
+ _state = DisplayState.VerticalBlank;
+ _scanline = 0;
+ _word = 0;
+ _dwtBlocked = false;
+ _dhtBlocked = false;
}
public void Clock()
{
- // TODO: Move the electron beam appropriately and wake up the display tasks
- // as necessary.
+
+ //
+ // Move the electron beam appropriately and wake up the display tasks
+ // as necessary. Render the display at the end of the field.
+ //
+
+ //
+ // "The display control hardware also generates wakeup requests to the microprocessor
+ // tasking hardware. The vertical task DVT is awakened once per field, at the beginning
+ // of vertical retrace. The display horizontal task is awakened once at the beginning of
+ // each field, and thereafter whenever the display word task blocks. DHT can block itself,
+ // in which case neither it nor the word task can be awakened until the start of the next
+ // field. The wakeup request for the display word task (DWT) is controlled by the state
+ // of the 16 word buffer. If DWT has not executed a BLOCK, if DHT is not blocked, and if
+ // the buffer is not full, DWT wakeups are generated. The hardware sets the buffer empty
+ // and clears the DWT block flip-flop at the beginning of horizontal retrace for every
+ // scan line."
+ //
+
+ //
+ // Check the BLOCK status of the DWT and DHT tasks for the last executed uInstruction.
+ //
+ _dhtBlocked = _system.CPU.CurrentTask.Priority == (int)CPU.TaskType.DisplayHorizontal &&
+ _system.CPU.CurrentTask.BLOCK;
+
+ if (_system.CPU.CurrentTask.Priority == (int)CPU.TaskType.DisplayWord &&
+ _system.CPU.CurrentTask.BLOCK)
+ {
+ //Console.WriteLine("DWT BLOCK");
+ _dwtBlocked = true;
+
+ //
+ // Wake up DHT if it has not blocked itself.
+ //
+ if (!_dhtBlocked)
+ {
+ _system.CPU.WakeupTask(TaskType.DisplayHorizontal);
+ }
+ }
+
+ _clocks++;
+ _totalClocks++;
+
+ switch (_state)
+ {
+ case DisplayState.VerticalBlank:
+ // Just killing time
+ if (_clocks > _verticalBlankClocks)
+ {
+ // End of VBlank
+ _clocks -= _verticalBlankClocks;
+ _scanline = _evenField ? 0 : 1;
+ _word = 0;
+ _dataBuffer.Clear();
+
+ // Wake up DVT, DHT
+ _dwtBlocked = false;
+ _dhtBlocked = false;
+ _system.CPU.WakeupTask(TaskType.DisplayVertical);
+ _system.CPU.WakeupTask(TaskType.DisplayHorizontal);
+ _system.CPU.BlockTask(TaskType.DisplayWord);
+
+ // Run MRT
+ _system.CPU.WakeupTask(TaskType.MemoryRefresh);
+
+ // TODO: clear DWT, DHT block flip-flop
+ _state = DisplayState.VisibleScanline;
+
+ //Console.WriteLine("Frame");
+ }
+ break;
+
+ case DisplayState.VisibleScanline:
+ //
+ // "If the DWT has not executed a BLOCK, if DHT is not blocked, and if the
+ // buffer is not full, DWT wakeups are generated."
+ //
+ if (_dataBuffer.Count < 16 &&
+ !_system.CPU.IsBlocked(TaskType.DisplayHorizontal) &&
+ !_dwtBlocked)
+ {
+ //Console.WriteLine("DWT wakeup, {0}", _dataBuffer.Count);
+ _system.CPU.WakeupTask(TaskType.DisplayWord);
+ }
+ else
+ {
+ // We can't take any words right now, remove Wakeup from
+ // the DWT.
+ if (_dataBuffer.Count >= 16)
+ {
+ //Log.Write(LogComponent.Display, "buffer full, blocking DWT.");
+ }
+ _system.CPU.BlockTask(TaskType.DisplayWord);
+ }
+
+ //
+ // A scanline is 38 words wide; we clock in each word
+ // from the buffer (if present).
+ //
+ if (_clocks > _wordClocks)
+ {
+ _clocks -= _wordClocks;
+
+ ushort displayWord = 0xaaaa;
+ if (_dataBuffer.Count > 0)
+ {
+ // Dequeue a word and draw it to the screen
+ displayWord = _dataBuffer.Dequeue();
+ }
+
+ _display.DrawDisplayWord(_scanline, _word, displayWord);
+
+ _word++;
+ if (_word > 37)
+ {
+ // Done with this line
+ _dwtBlocked = false;
+ _dataBuffer.Clear();
+ _state = DisplayState.HorizontalBlank;
+ }
+ }
+ break;
+
+ case DisplayState.HorizontalBlank:
+ // Kill time until end of HBlank
+ if (_clocks > _horizontalBlankClocks)
+ {
+ _clocks -= _horizontalBlankClocks;
+
+ // Move to next scanline
+ _scanline += 2;
+ _word = 0;
+
+ if (_scanline > 807)
+ {
+ // Done with field, move to vblank, tell display to render
+ _state = DisplayState.VerticalBlank;
+ _evenField = !_evenField;
+
+ _system.CPU.BlockTask(TaskType.DisplayVertical);
+ _system.CPU.BlockTask(TaskType.DisplayHorizontal);
+ _system.CPU.BlockTask(TaskType.DisplayWord);
+
+ _display.RefreshAltoDisplay();
+
+ _frames++;
+ //Log.Write(LogComponent.Display, "Display field completed. {0} total clocks elapsed.", _totalClocks);
+ _totalClocks = 0;
+ }
+ else
+ {
+ _state = DisplayState.VisibleScanline;
+ }
+ }
+ break;
+ }
}
+ public void LoadDDR(ushort word)
+ {
+ _dataBuffer.Enqueue(word);
- bool _evenField;
+ //Console.WriteLine("Enqueue {0}", _dataBuffer.Count);
+ // Sanity check: data length should never exceed 16 words.
+ if (_dataBuffer.Count > 16)
+ {
+ _dataBuffer.Dequeue();
+ _system.CPU.BlockTask(TaskType.DisplayWord);
+ }
+ }
+
+ public bool EVENFIELD
+ {
+ get { return _evenField; }
+ }
+
+ private enum DisplayState
+ {
+ Invalid = 0,
+ VerticalBlank,
+ VisibleScanline,
+ HorizontalBlank,
+ }
+
+ private bool _evenField;
+ private double _clocks;
+ private double _totalClocks;
+ private int _frames;
+ private DisplayState _state;
+
+ // Indicates whether the DWT or DHT blocked itself
+ // in which case they cannot be reawakened until the next field.
+ private bool _dwtBlocked;
+ private bool _dhtBlocked;
+
+ private int _scanline;
+ private int _word;
+
+ private Queue _dataBuffer = new Queue(16);
private AltoSystem _system;
+ private Debugger _display;
+
+ // Timing constants
+ // 38uS per scanline; 4uS for hblank.
+ // ~35 scanlines for vblank (1330uS)
+ private const double _wordClocks = (34.0 / 38.0) / 0.17; // uSec to clocks
+ private const double _horizontalBlankClocks = 4.0 / 0.17;
+ private const double _verticalBlankClocks = 1333.0 / 0.17;
+
+
}
}
diff --git a/Contralto/IO/DiskController.cs b/Contralto/IO/DiskController.cs
index 804d851..a760426 100644
--- a/Contralto/IO/DiskController.cs
+++ b/Contralto/IO/DiskController.cs
@@ -297,7 +297,7 @@ namespace Contralto.IO
// Update the WDINIT signal; this is based on WDALLOW (!_wdInhib) which sets WDINIT (this is done
// in KCOM way above).
// WDINIT is reset when BLOCK (a BLOCK F1 is being executed) and WDTSKACT (the disk word task is running) are 1.
- //
+ //
if (_system.CPU.CurrentTask.Priority == (int)CPU.TaskType.DiskWord &&
_system.CPU.CurrentTask.BLOCK)
{
@@ -639,7 +639,7 @@ namespace Contralto.IO
// Sector timing. Based on table on pg. 43 of the Alto Hardware Manual
private double _elapsedSectorTime; // elapsed time in this sector (in clocks)
private const double _sectorDuration = (40.0 / 12.0); // time in msec for one sector
- private const double _sectorClocks = _sectorDuration / 0.00017; // number of clock cycles per sector time.
+ private const double _sectorClocks = _sectorDuration / (0.00017); // number of clock cycles per sector time.
private int _sectorWordIndex;
diff --git a/Contralto/Logging/Log.cs b/Contralto/Logging/Log.cs
new file mode 100644
index 0000000..679891c
--- /dev/null
+++ b/Contralto/Logging/Log.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contralto.Logging
+{
+ ///
+ /// Specifies a component to specify logging for
+ ///
+ [Flags]
+ public enum LogComponent
+ {
+ None = 0,
+ EmulatorTask = 0x1,
+ DiskSectorTask = 0x2,
+ DiskWordTask = 0x4,
+ DiskController = 0x8,
+ Alu = 0x10,
+ Memory = 0x20,
+ Keyboard = 0x40,
+ Display = 0x80,
+
+ All = 0x7fffffff
+ }
+
+ ///
+ /// Specifies the type (or severity) of a given log message
+ ///
+ [Flags]
+ public enum LogType
+ {
+ None = 0,
+ Normal = 0x1,
+ Warning = 0x2,
+ Error = 0x4,
+ Verbose = 0x8,
+ All = 0x7fffffff
+ }
+
+ ///
+ /// Provides basic functionality for logging messages of all types.
+ ///
+ public static class Log
+ {
+ static Log()
+ {
+ // TODO: make configurable
+ _components = LogComponent.All;
+ _type = LogType.Normal | LogType.Warning | LogType.Error;
+ }
+
+ ///
+ /// Logs a message without specifying type/severity for terseness;
+ /// will not log if Type has been set to None.
+ ///
+ ///
+ ///
+ ///
+ public static void Write(LogComponent component, string message, params object[] args)
+ {
+ Write(LogType.Normal, component, message, args);
+ }
+
+ public static void Write(LogType type, LogComponent component, string message, params object[] args)
+ {
+ if ((_type & type) != 0 &&
+ (_components & component) != 0)
+ {
+ //
+ // My log has something to tell you...
+ // TODO: color based on type, etc.
+ Console.WriteLine(component.ToString() + ": " + message, args);
+ }
+ }
+
+
+
+ private static LogComponent _components;
+ private static LogType _type;
+ }
+}
diff --git a/Contralto/Memory/Memory.cs b/Contralto/Memory/Memory.cs
index 6434663..ae6a595 100644
--- a/Contralto/Memory/Memory.cs
+++ b/Contralto/Memory/Memory.cs
@@ -60,6 +60,11 @@ namespace Contralto.Memory
address += 0x10000 * GetBankNumber(task, extendedMemory);
_mem[address] = data;
+ if (address == 0x110 && data != 0)
+ {
+ Console.WriteLine("DASTART WRITE!");
+ }
+
/*
if (extendedMemory)
{
diff --git a/Contralto/Program.cs b/Contralto/Program.cs
index dc09fff..d712372 100644
--- a/Contralto/Program.cs
+++ b/Contralto/Program.cs
@@ -14,31 +14,11 @@ namespace Contralto
static void Main(string[] args)
{
- AltoSystem system = new AltoSystem();
-
-
- /*
- for(int address=0; address < 1024; address++)
- {
-
- MicroInstruction inst = new MicroInstruction(UCodeMemory.UCodeROM[address]);
-
- Console.WriteLine("{0}: {1} - RSEL:{2} ALUF:{3} BS:{4} F1:{5} F2:{6} T:{7} L:{8} NEXT:{9}",
- OctalHelpers.ToOctal(address, 4),
- OctalHelpers.ToOctal((int)UCodeMemory.UCodeROM[address], 11),
- OctalHelpers.ToOctal((int)inst.RSELECT, 2),
- OctalHelpers.ToOctal((int)inst.ALUF, 2),
- OctalHelpers.ToOctal((int)inst.BS),
- OctalHelpers.ToOctal((int)inst.F1, 2),
- OctalHelpers.ToOctal((int)inst.F2, 2),
- inst.LoadT ? 1 : 0,
- inst.LoadL ? 1 : 0,
- OctalHelpers.ToOctal((int)inst.NEXT, 4));
- } */
-
+ AltoSystem system = new AltoSystem();
// for now everything is driven through the debugger
Debugger d = new Debugger(system);
+ system.AttachDisplay(d);
d.LoadSourceCode("Disassembly\\altoIIcode3.mu");
d.ShowDialog();