1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-17 00:23:24 +00:00

Built basic debugger UI and execution framework; a few bugfixes. CPU now executes uCode up until the first STARTF (unimplemented).

This commit is contained in:
Josh Dersch 2015-09-01 17:06:57 -07:00
parent c4f8fe951f
commit 0ced1a2ef8
10 changed files with 1283 additions and 52 deletions

50
Contralto/AltoSystem.cs Normal file
View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Contralto.CPU;
using Contralto.Memory;
namespace Contralto
{
/// <summary>
/// Encapsulates all Alto hardware; represents a complete Alto system.
/// Provides interfaces for controlling and debugging the system externally.
/// </summary>
public class AltoSystem
{
public AltoSystem()
{
_cpu = new AltoCPU(this);
_mem = new MemoryBus();
Reset();
}
public void Reset()
{
_cpu.Reset();
_mem.Reset();
}
public void SingleStep()
{
_mem.Clock();
_cpu.ExecuteNext();
}
public AltoCPU CPU
{
get { return _cpu; }
}
public MemoryBus MemoryBus
{
get { return _mem; }
}
private AltoCPU _cpu;
private MemoryBus _mem;
}
}

View File

@ -9,25 +9,76 @@ namespace Contralto.CPU
{
public enum TaskType
{
Invalid = -1,
Emulator = 0,
DiskSector = 4,
Ethernet = 5,
DiskWord = 9,
Ethernet = 7,
MemoryRefresh = 8,
DisplayWord = 9,
Cursor = 10,
DisplayHorizontal = 11,
DisplayVertical = 12,
Refresh = 14,
Parity = 13,
DiskWord = 14,
}
public class AltoCPU
{
public AltoCPU()
public AltoCPU(AltoSystem system)
{
_system = system;
_tasks[(int)TaskType.Emulator] = new EmulatorTask(this);
Reset();
}
public Task[] Tasks
{
get { return _tasks; }
}
public Task CurrentTask
{
get { return _currentTask; }
}
public ushort[] R
{
get { return _r; }
}
public ushort[][] S
{
get { return _s; }
}
public ushort T
{
get { return _t; }
}
public ushort L
{
get { return _l; }
}
public ushort M
{
get { return _m; }
}
public ushort IR
{
get { return _ir; }
}
public ushort ALUC0
{
get { return _aluC0; }
}
public void Reset()
{
// Reset registers
@ -126,7 +177,7 @@ namespace Contralto.CPU
// Base task class: provides implementation for non-task-specific microcode execution and
// state. Task subclasses implement and execute Task-specific behavior and are called into
// by the base class as necessary.
private abstract class Task
public abstract class Task
{
public Task(AltoCPU cpu)
{
@ -146,6 +197,11 @@ namespace Contralto.CPU
get { return _wakeup; }
}
public ushort MPC
{
get { return _mpc; }
}
public virtual void Reset()
{
// From The Alto Hardware Manual (section 2, "Initialization"):
@ -183,6 +239,7 @@ namespace Contralto.CPU
bool nextTask = false;
bool loadR = false;
ushort aluData = 0;
ushort nextModifier = 0;
_loadS = false;
_rSelect = 0;
_busData = 0;
@ -193,16 +250,39 @@ namespace Contralto.CPU
//
// Wait for memory state machine if a memory operation is requested by this instruction and
// 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.LoadMAR ||
instruction.F2 == SpecialFunction2.StoreMD)
&& !MemoryBus.Ready(MemoryOperation.Load)) //TODO: fix
instruction.F2 == SpecialFunction2.StoreMD)
{
// Suspend operation for this cycle.
return false;
MemoryOperation op;
if (instruction.BS == BusSource.ReadMD)
{
op = MemoryOperation.Read;
}
else if(instruction.F1 == SpecialFunction1.LoadMAR)
{
op = MemoryOperation.LoadAddress;
}
else
{
op = MemoryOperation.Store;
}
if (!_cpu._system.MemoryBus.Ready(op))
{
// Suspend operation for this cycle.
return false;
}
}
// If we have a modified next field from the last instruction, make sure it gets applied to this one.
nextModifier = _nextModifier;
_nextModifier = 0;
_rSelect = instruction.RSELECT;
// Give tasks the chance to modify parameters early on (like RSELECT)
@ -234,17 +314,31 @@ namespace Contralto.CPU
break;
case BusSource.ReadMD:
_busData = MemoryBus.ReadMD();
_busData = _cpu._system.MemoryBus.ReadMD();
break;
case BusSource.ReadMouse:
throw new NotImplementedException("ReadMouse bus source not implemented.");
_busData = 0; // TODO: implement
//throw new NotImplementedException("ReadMouse bus source not implemented.");
_busData = 0; // TODO: implement;
break;
case BusSource.ReadDisp:
throw new NotImplementedException("ReadDisp bus source not implemented.");
_busData = 0; // TODO: implement;
// "The high-order bits of IR cannot be read directly, but the displacement field of IR (8 low order bits),
// may be read with the <-DISP bus source. If the X field of the instruction is zero (i.e. it specifies page 0
// addressing) then the DISP field of the instruction is put on BUS[8-15] and BUS[0-7] is zeroed. If the X
// field of the instruction is nonzero (i.e. it specifies PC-relative or base-register addressing) then the DISP
// field is sign-extended and put on the bus."
// NB: the "X" field of the NOVA instruction is IR[6-7]
_busData = (ushort)(_cpu._ir & 0xff);
if ((_cpu._ir & 0x300) != 0)
{
// sign extend if necessary
if ((_cpu._ir & 0x80) == 0x80)
{
_busData |= (0xff00);
}
}
break;
default:
@ -291,7 +385,7 @@ namespace Contralto.CPU
break;
case SpecialFunction1.LoadMAR:
MemoryBus.LoadMAR(aluData); // Start main memory reference
_cpu._system.MemoryBus.LoadMAR(aluData); // Start main memory reference
break;
case SpecialFunction1.Task:
@ -373,7 +467,7 @@ namespace Contralto.CPU
break;
case SpecialFunction2.StoreMD:
MemoryBus.LoadMD(_busData);
_cpu._system.MemoryBus.LoadMD(_busData);
break;
case SpecialFunction2.Constant:
@ -382,7 +476,7 @@ namespace Contralto.CPU
default:
// Let the specific task implementation take a crack at this.
ExecuteSpecialFunction2((int)instruction.F1);
ExecuteSpecialFunction2((int)instruction.F2);
break;
}
@ -434,9 +528,9 @@ namespace Contralto.CPU
}
//
// Select next address -- TODO: this is incorrect! _nextModifer should be applied to the *NEXT* instruction, not the current one!
// Select next address, using the address modifier from the last instruction.
//
_mpc = (ushort)(instruction.NEXT | _nextModifier);
_mpc = (ushort)(instruction.NEXT | nextModifier);
return nextTask;
}
@ -743,5 +837,8 @@ namespace Contralto.CPU
private long _clocks;
// The system this CPU belongs to
private AltoSystem _system;
}
}

View File

@ -34,6 +34,8 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -41,6 +43,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AltoSystem.cs" />
<Compile Include="CPU\ALU.cs" />
<Compile Include="CPU\ConstantMemory.cs" />
<Compile Include="CPU\CPU.cs" />
@ -48,6 +51,12 @@
<Compile Include="CPU\MicroInstruction.cs" />
<Compile Include="CPU\Shifter.cs" />
<Compile Include="CPU\UCodeMemory.cs" />
<Compile Include="Debugger.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger.Designer.cs">
<DependentUpon>Debugger.cs</DependentUpon>
</Compile>
<Compile Include="Memory\IMemoryMappedDevice.cs" />
<Compile Include="Memory\Memory.cs" />
<Compile Include="Memory\MemoryBus.cs" />
@ -170,6 +179,11 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Debugger.resx">
<DependentUpon>Debugger.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

538
Contralto/Debugger.Designer.cs generated Normal file
View File

@ -0,0 +1,538 @@
namespace Contralto
{
partial class Debugger
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle14 = 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 dataGridViewCellStyle20 = 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 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();
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();
this.Microcode = new System.Windows.Forms.GroupBox();
this._sourceViewer = new System.Windows.Forms.DataGridView();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.StepButton = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this._registerData = new System.Windows.Forms.DataGridView();
this.RegNum = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.R = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.S = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this._taskData = new System.Windows.Forms.DataGridView();
this.TaskName = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.TaskState = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.TaskPC = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.T = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Addr = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Source = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this._otherRegs = new System.Windows.Forms.DataGridView();
this.Reg = new System.Windows.Forms.DataGridViewTextBoxColumn();
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.Microcode.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._sourceViewer)).BeginInit();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._registerData)).BeginInit();
this.groupBox2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._taskData)).BeginInit();
this.groupBox3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._otherRegs)).BeginInit();
this.groupBox4.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._memoryData)).BeginInit();
this.SuspendLayout();
//
// Microcode
//
this.Microcode.Controls.Add(this._sourceViewer);
this.Microcode.Location = new System.Drawing.Point(3, 3);
this.Microcode.Name = "Microcode";
this.Microcode.Size = new System.Drawing.Size(603, 625);
this.Microcode.TabIndex = 0;
this.Microcode.TabStop = false;
this.Microcode.Text = "Microcode Source";
//
// _sourceViewer
//
this._sourceViewer.AllowUserToAddRows = false;
this._sourceViewer.AllowUserToDeleteRows = false;
this._sourceViewer.AllowUserToResizeColumns = false;
this._sourceViewer.AllowUserToResizeRows = false;
dataGridViewCellStyle14.BackColor = System.Drawing.Color.Silver;
this._sourceViewer.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle14;
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[] {
this.T,
this.Addr,
this.Source});
this._sourceViewer.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._sourceViewer.Location = new System.Drawing.Point(10, 19);
this._sourceViewer.Name = "_sourceViewer";
this._sourceViewer.ReadOnly = true;
this._sourceViewer.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
dataGridViewCellStyle18.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle18.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle18.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle18.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle18.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle18.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle18.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this._sourceViewer.RowHeadersDefaultCellStyle = dataGridViewCellStyle18;
this._sourceViewer.RowHeadersVisible = false;
this._sourceViewer.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
this._sourceViewer.RowTemplate.Height = 18;
this._sourceViewer.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this._sourceViewer.ShowCellErrors = false;
this._sourceViewer.ShowEditingIcon = false;
this._sourceViewer.ShowRowErrors = false;
this._sourceViewer.Size = new System.Drawing.Size(584, 600);
this._sourceViewer.TabIndex = 1;
this._sourceViewer.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
//
// groupBox1
//
this.groupBox1.Controls.Add(this._registerData);
this.groupBox1.Location = new System.Drawing.Point(614, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(137, 625);
this.groupBox1.TabIndex = 2;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "General Registers";
//
// StepButton
//
this.StepButton.Location = new System.Drawing.Point(3, 634);
this.StepButton.Name = "StepButton";
this.StepButton.Size = new System.Drawing.Size(44, 23);
this.StepButton.TabIndex = 3;
this.StepButton.Text = "Step";
this.StepButton.UseVisualStyleBackColor = true;
this.StepButton.Click += new System.EventHandler(this.OnStepButtonClicked);
//
// button2
//
this.button2.Location = new System.Drawing.Point(54, 634);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(47, 23);
this.button2.TabIndex = 4;
this.button2.Text = "Auto";
this.button2.UseVisualStyleBackColor = true;
//
// button3
//
this.button3.Location = new System.Drawing.Point(108, 634);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(53, 23);
this.button3.TabIndex = 5;
this.button3.Text = "Run";
this.button3.UseVisualStyleBackColor = true;
//
// button4
//
this.button4.Location = new System.Drawing.Point(168, 634);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(49, 23);
this.button4.TabIndex = 6;
this.button4.Text = "Stop";
this.button4.UseVisualStyleBackColor = true;
//
// _registerData
//
this._registerData.AllowUserToAddRows = false;
this._registerData.AllowUserToDeleteRows = false;
this._registerData.AllowUserToResizeColumns = false;
this._registerData.AllowUserToResizeRows = false;
dataGridViewCellStyle19.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this._registerData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle19;
this._registerData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._registerData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.RegNum,
this.R,
this.S});
dataGridViewCellStyle20.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle20.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle20.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle20.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle20.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle20.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle20.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this._registerData.DefaultCellStyle = dataGridViewCellStyle20;
this._registerData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._registerData.Location = new System.Drawing.Point(7, 19);
this._registerData.MultiSelect = false;
this._registerData.Name = "_registerData";
this._registerData.ReadOnly = true;
this._registerData.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
this._registerData.RowHeadersVisible = false;
this._registerData.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
this._registerData.RowTemplate.Height = 18;
this._registerData.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
this._registerData.ShowCellErrors = false;
this._registerData.ShowCellToolTips = false;
this._registerData.ShowEditingIcon = false;
this._registerData.ShowRowErrors = false;
this._registerData.Size = new System.Drawing.Size(123, 600);
this._registerData.TabIndex = 0;
//
// RegNum
//
this.RegNum.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
this.RegNum.HeaderText = "#";
this.RegNum.Name = "RegNum";
this.RegNum.ReadOnly = true;
this.RegNum.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.RegNum.Width = 20;
//
// R
//
this.R.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.R.HeaderText = "R";
this.R.Name = "R";
this.R.ReadOnly = true;
this.R.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.R.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.R.Width = 50;
//
// S
//
this.S.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.S.HeaderText = "S";
this.S.Name = "S";
this.S.ReadOnly = true;
this.S.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.S.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.S.Width = 50;
//
// groupBox2
//
this.groupBox2.Controls.Add(this._taskData);
this.groupBox2.Location = new System.Drawing.Point(469, 634);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(137, 344);
this.groupBox2.TabIndex = 7;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Tasks";
//
// _taskData
//
this._taskData.AllowUserToAddRows = false;
this._taskData.AllowUserToDeleteRows = false;
dataGridViewCellStyle21.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this._taskData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle21;
this._taskData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._taskData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.TaskName,
this.TaskState,
this.TaskPC});
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._taskData.DefaultCellStyle = dataGridViewCellStyle22;
this._taskData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._taskData.Location = new System.Drawing.Point(7, 19);
this._taskData.MultiSelect = false;
this._taskData.Name = "_taskData";
this._taskData.ReadOnly = true;
this._taskData.RowHeadersVisible = false;
this._taskData.RowTemplate.DefaultCellStyle.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this._taskData.RowTemplate.Height = 18;
this._taskData.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this._taskData.ShowCellErrors = false;
this._taskData.ShowCellToolTips = false;
this._taskData.ShowEditingIcon = false;
this._taskData.ShowRowErrors = false;
this._taskData.Size = new System.Drawing.Size(123, 319);
this._taskData.TabIndex = 0;
//
// TaskName
//
this.TaskName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
this.TaskName.HeaderText = "T";
this.TaskName.MinimumWidth = 16;
this.TaskName.Name = "TaskName";
this.TaskName.ReadOnly = true;
this.TaskName.Width = 16;
//
// TaskState
//
this.TaskState.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
this.TaskState.HeaderText = "S";
this.TaskState.MinimumWidth = 16;
this.TaskState.Name = "TaskState";
this.TaskState.ReadOnly = true;
this.TaskState.Width = 16;
//
// TaskPC
//
this.TaskPC.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.TaskPC.HeaderText = "uPC";
this.TaskPC.Name = "TaskPC";
this.TaskPC.ReadOnly = true;
//
// T
//
this.T.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
dataGridViewCellStyle15.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle15.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.T.DefaultCellStyle = dataGridViewCellStyle15;
this.T.HeaderText = "T";
this.T.Name = "T";
this.T.ReadOnly = true;
this.T.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.T.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.T.Width = 5;
//
// Addr
//
this.Addr.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
dataGridViewCellStyle16.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Addr.DefaultCellStyle = dataGridViewCellStyle16;
this.Addr.HeaderText = "Addr";
this.Addr.Name = "Addr";
this.Addr.ReadOnly = true;
this.Addr.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Addr.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.Addr.Width = 5;
//
// Source
//
this.Source.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
dataGridViewCellStyle17.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Source.DefaultCellStyle = dataGridViewCellStyle17;
this.Source.HeaderText = "Source Code";
this.Source.Name = "Source";
this.Source.ReadOnly = true;
this.Source.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Source.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// groupBox3
//
this.groupBox3.Controls.Add(this._otherRegs);
this.groupBox3.Location = new System.Drawing.Point(612, 634);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(137, 344);
this.groupBox3.TabIndex = 8;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Other Registers";
//
// _otherRegs
//
this._otherRegs.AllowUserToAddRows = false;
this._otherRegs.AllowUserToDeleteRows = false;
dataGridViewCellStyle23.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this._otherRegs.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle23;
this._otherRegs.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._otherRegs.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Reg,
this.RegValue});
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._otherRegs.DefaultCellStyle = dataGridViewCellStyle24;
this._otherRegs.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._otherRegs.Location = new System.Drawing.Point(7, 19);
this._otherRegs.MultiSelect = false;
this._otherRegs.Name = "_otherRegs";
this._otherRegs.ReadOnly = true;
this._otherRegs.RowHeadersVisible = false;
this._otherRegs.RowTemplate.DefaultCellStyle.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this._otherRegs.RowTemplate.Height = 18;
this._otherRegs.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this._otherRegs.ShowCellErrors = false;
this._otherRegs.ShowCellToolTips = false;
this._otherRegs.ShowEditingIcon = false;
this._otherRegs.ShowRowErrors = false;
this._otherRegs.Size = new System.Drawing.Size(123, 319);
this._otherRegs.TabIndex = 0;
//
// Reg
//
this.Reg.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
this.Reg.HeaderText = "Reg";
this.Reg.MinimumWidth = 16;
this.Reg.Name = "Reg";
this.Reg.ReadOnly = true;
this.Reg.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Reg.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.Reg.Width = 16;
//
// RegValue
//
this.RegValue.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.RegValue.HeaderText = "Value";
this.RegValue.MinimumWidth = 16;
this.RegValue.Name = "RegValue";
this.RegValue.ReadOnly = true;
this.RegValue.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.RegValue.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// groupBox4
//
this.groupBox4.Controls.Add(this._memoryData);
this.groupBox4.Location = new System.Drawing.Point(223, 634);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(240, 344);
this.groupBox4.TabIndex = 8;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Memory";
//
// _memoryData
//
this._memoryData.AllowUserToAddRows = false;
this._memoryData.AllowUserToDeleteRows = false;
dataGridViewCellStyle25.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this._memoryData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle25;
this._memoryData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this._memoryData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Address,
this.Data});
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._memoryData.DefaultCellStyle = dataGridViewCellStyle26;
this._memoryData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this._memoryData.Location = new System.Drawing.Point(7, 19);
this._memoryData.MultiSelect = false;
this._memoryData.Name = "_memoryData";
this._memoryData.ReadOnly = true;
this._memoryData.RowHeadersVisible = false;
this._memoryData.RowTemplate.DefaultCellStyle.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this._memoryData.RowTemplate.Height = 18;
this._memoryData.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this._memoryData.ShowCellErrors = false;
this._memoryData.ShowCellToolTips = false;
this._memoryData.ShowEditingIcon = false;
this._memoryData.ShowRowErrors = false;
this._memoryData.Size = new System.Drawing.Size(227, 319);
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;
//
// 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.groupBox4);
this.Controls.Add(this.groupBox3);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.button4);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.StepButton);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.Microcode);
this.Name = "Debugger";
this.Text = "Debugger";
this.Load += new System.EventHandler(this.Debugger_Load);
this.Microcode.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this._sourceViewer)).EndInit();
this.groupBox1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this._registerData)).EndInit();
this.groupBox2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this._taskData)).EndInit();
this.groupBox3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this._otherRegs)).EndInit();
this.groupBox4.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this._memoryData)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox Microcode;
private System.Windows.Forms.DataGridView _sourceViewer;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Button StepButton;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.DataGridView _registerData;
private System.Windows.Forms.DataGridViewTextBoxColumn RegNum;
private System.Windows.Forms.DataGridViewTextBoxColumn R;
private System.Windows.Forms.DataGridViewTextBoxColumn S;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.DataGridView _taskData;
private System.Windows.Forms.DataGridViewTextBoxColumn TaskName;
private System.Windows.Forms.DataGridViewTextBoxColumn TaskState;
private System.Windows.Forms.DataGridViewTextBoxColumn TaskPC;
private System.Windows.Forms.DataGridViewTextBoxColumn T;
private System.Windows.Forms.DataGridViewTextBoxColumn Addr;
private System.Windows.Forms.DataGridViewTextBoxColumn Source;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.DataGridView _otherRegs;
private System.Windows.Forms.DataGridViewTextBoxColumn Reg;
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;
}
}

347
Contralto/Debugger.cs Normal file
View File

@ -0,0 +1,347 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Contralto.CPU;
namespace Contralto
{
public partial class Debugger : Form
{
public Debugger(AltoSystem system)
{
_system = system;
InitializeComponent();
InitControls();
RefreshUI();
}
public void LoadSourceCode(string path)
{
if (path == null)
{
throw new ArgumentNullException(path, "Microcode path must be specified.");
}
StreamReader sr = new StreamReader(path);
while(!sr.EndOfStream)
{
string line = sr.ReadLine();
SourceLine src = new SourceLine(line);
int i = _sourceViewer.Rows.Add(
GetTextForTask(src.Task),
src.Address,
src.Text);
// Give the row a color based on the task
_sourceViewer.Rows[i].DefaultCellStyle.BackColor = GetColorForTask(src.Task);
// Tag the row based on the PROM address (if any) to make it easy to find.
if (!String.IsNullOrEmpty(src.Address))
{
_sourceViewer.Rows[i].Tag = Convert.ToUInt16(src.Address, 8);
}
}
// Ensure the UI view gets refreshed to display the current MPC source
Refresh();
}
public override void Refresh()
{
base.Refresh();
RefreshUI();
}
private void RefreshUI()
{
// Registers
for(int i=0;i<32;i++)
{
_registerData.Rows[i].Cells[0].Value = OctalHelpers.ToOctal(i,2);
_registerData.Rows[i].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.R[i], 6);
_registerData.Rows[i].Cells[2].Value = OctalHelpers.ToOctal(_system.CPU.S[0][i], 6);
}
// Tasks
for (int i=0;i<16;i++)
{
_taskData.Rows[i].Cells[0].Value = GetTextForTask((TaskType)i);
_taskData.Rows[i].Cells[1].Value = GetTextForTaskState(_system.CPU.Tasks[i]);
_taskData.Rows[i].Cells[2].Value =
_system.CPU.Tasks[i] != null ? OctalHelpers.ToOctal(_system.CPU.Tasks[i].MPC, 4) : String.Empty;
}
// Other registers
_otherRegs.Rows[0].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.L, 6);
_otherRegs.Rows[1].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.T, 6);
_otherRegs.Rows[2].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.M, 6);
_otherRegs.Rows[3].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.IR, 6);
_otherRegs.Rows[4].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.ALUC0, 1);
_otherRegs.Rows[5].Cells[1].Value = OctalHelpers.ToOctal(_system.MemoryBus.MAR, 6);
_otherRegs.Rows[6].Cells[1].Value = OctalHelpers.ToOctal(_system.MemoryBus.MD, 6);
_otherRegs.Rows[7].Cells[1].Value = OctalHelpers.ToOctal(_system.MemoryBus.Cycle, 2);
// Find the right source line
foreach(DataGridViewRow row in _sourceViewer.Rows)
{
if (row.Tag != null &&
(ushort)(row.Tag) == _system.CPU.CurrentTask.MPC)
{
_sourceViewer.ClearSelection();
row.Selected = true;
_sourceViewer.CurrentCell = row.Cells[0];
break;
}
}
}
private void InitControls()
{
for (int i = 0; i < 32; i++)
{
_registerData.Rows.Add(-1, -1 ,-1);
}
for (int i = 0; i < 16; i++)
{
_taskData.Rows.Add("0", "0", "0");
}
/*
for (int i=0;i<65536;i++)
{
_memoryData.Rows.Add();
} */
_otherRegs.Rows.Add("L", "0");
_otherRegs.Rows.Add("T", "0");
_otherRegs.Rows.Add("M", "0");
_otherRegs.Rows.Add("IR", "0");
_otherRegs.Rows.Add("ALUC0", "0");
_otherRegs.Rows.Add("MAR", "0");
_otherRegs.Rows.Add("MD", "0");
_otherRegs.Rows.Add("MCycle", "0");
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private string GetTextForTaskState(AltoCPU.Task task)
{
if (task == null)
{
return String.Empty;
}
else
{
// TODO: block status
return task.Wakeup ? "W" : String.Empty;
}
}
private string GetTextForTask(TaskType task)
{
string[] taskText =
{
"EM", // 0 - emulator
String.Empty,
String.Empty,
String.Empty,
"KS", // 4 - disk sector
String.Empty,
String.Empty,
"EN", // 7 - ethernet
"MR", // 8 - memory refresh
"DW", // 9 - display word
"CU", // 10 - cursor
"DH", // 11 - display horizontal
"DV", // 12 - display vertical
"PA", // 13 - parity
"KW", // 14 - disk word
String.Empty,
};
if (task == TaskType.Invalid)
{
return String.Empty;
}
else
{
return taskText[(int)task];
}
}
private Color GetColorForTask(TaskType task)
{
Color[] taskColors =
{
Color.LightBlue, // 0 - emulator
Color.LightGray, // 1 - unused
Color.LightGray, // 2 - unused
Color.LightGray, // 3 - unused
Color.LightGreen, // 4 - disk sector
Color.LightGray, // 5 - unused
Color.LightGray, // 6 - unused
Color.LightSalmon, // 7 - ethernet
Color.LightSeaGreen,// 8 - memory refresh
Color.LightYellow, // 9 - display word
Color.LightPink, // 10 - cursor
Color.LightGoldenrodYellow, // 11 - display horizontal
Color.LightCoral, // 12 - display vertical
Color.LightSteelBlue, // 13 - parity
Color.Gray, // 14 - disk word
Color.LightGray, // 15 - unused
};
if (task == TaskType.Invalid)
{
return Color.White;
}
else
{
return taskColors[(int)task];
}
}
private struct SourceLine
{
public SourceLine(string sourceText)
{
//
// Mangle "<-" found in the source into the unicode arrow character, just to be neat.
//
sourceText = sourceText.Replace("<-", _arrowChar.ToString());
// See if line begins with something of the form "TNxxxxx>".
// If it does then we have extra metadata to parse out.
string[] tokens = sourceText.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
bool annotated = false;
// Make the compiler happy
Text = sourceText;
Address = String.Empty;
Task = TaskType.Invalid;
if (tokens.Length > 0 &&
tokens[0].Length == 8 &&
tokens[0].EndsWith(">"))
{
// Close enough. Look for the task tag and parse out the (octal) address
switch(tokens[0].Substring(0,2))
{
case "EM":
Task = TaskType.Emulator;
break;
case "SE":
Task = TaskType.DiskSector;
break;
case "EN":
Task = TaskType.Emulator;
break;
case "MR":
Task = TaskType.MemoryRefresh;
break;
case "DW":
Task = TaskType.DisplayWord;
break;
case "CU":
Task = TaskType.Cursor;
break;
case "DH":
Task = TaskType.DisplayHorizontal;
break;
case "DV":
Task = TaskType.DisplayVertical;
break;
case "PA":
Task = TaskType.Parity;
break;
case "KW":
Task = TaskType.DiskWord;
break;
default:
Task = TaskType.Invalid;
break;
}
if (Task != TaskType.Invalid)
{
try
{
// Belongs to a task, so we can grab the address out as well
Address = sourceText.Substring(2, 5);
}
catch
{
// That didn't work for whatever reason, just treat this as a normal source line.
annotated = false;
}
Text = sourceText.Substring(tokens[0].Length + 1, sourceText.Length - tokens[0].Length -1);
annotated = true;
}
else
{
// We will just display this as a non-source line
annotated = false;
}
}
if (!annotated)
{
Text = sourceText;
Address = String.Empty;
Task = TaskType.Invalid;
}
}
public string Text;
public string Address;
public TaskType Task;
}
private void Debugger_Load(object sender, EventArgs e)
{
}
private void OnStepButtonClicked(object sender, EventArgs e)
{
_system.SingleStep();
Refresh();
}
private AltoSystem _system;
// Unicode character for the Arrow used by Alto microcode
private const char _arrowChar = (char)0x2190;
}
}

159
Contralto/Debugger.resx Normal file
View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="T.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Addr.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Source.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="RegNum.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="R.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="S.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="TaskName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="TaskState.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="TaskPC.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Reg.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="RegValue.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>
</root>

View File

@ -10,7 +10,7 @@ namespace Contralto.Memory
{
public Memory()
{
_mem = new ushort[0xffff];
_mem = new ushort[0x10000];
}
public ushort Read(int address)

View File

@ -10,21 +10,46 @@ namespace Contralto.Memory
{
LoadAddress,
Read,
Load
Store
}
public static class MemoryBus
public class MemoryBus
{
static MemoryBus()
public MemoryBus()
{
_mem = new Memory();
Reset();
}
public void Reset()
{
_memoryCycle = 0;
_memoryAddress = 0;
_memoryData = 0;
_memoryOperationActive = false;
}
public static void Clock()
public ushort MAR
{
get { return _memoryAddress; }
}
public ushort MD
{
get { return _memoryData; }
}
public int Cycle
{
get { return _memoryCycle; }
}
public bool Active
{
get { return _memoryOperationActive; }
}
public void Clock()
{
_memoryCycle++;
if (_memoryOperationActive)
@ -50,7 +75,7 @@ namespace Contralto.Memory
}
}
public static bool Ready(MemoryOperation op)
public bool Ready(MemoryOperation op)
{
if (_memoryOperationActive)
{
@ -64,7 +89,7 @@ namespace Contralto.Memory
// Read operations take place on cycles 5 and 6
return _memoryCycle > 4;
case MemoryOperation.Load:
case MemoryOperation.Store:
// Write operations take place on cycles 3 and 4
return _memoryCycle > 2;
@ -79,7 +104,7 @@ namespace Contralto.Memory
}
}
public static void LoadMAR(ushort address)
public void LoadMAR(ushort address)
{
if (_memoryOperationActive)
{
@ -95,7 +120,7 @@ namespace Contralto.Memory
}
}
public static ushort ReadMD()
public ushort ReadMD()
{
if (_memoryOperationActive)
{
@ -141,7 +166,7 @@ namespace Contralto.Memory
}
}
public static void LoadMD(ushort data)
public void LoadMD(ushort data)
{
if (_memoryOperationActive)
{
@ -154,12 +179,14 @@ namespace Contralto.Memory
throw new InvalidOperationException("Unexpected microcode behavior -- LoadMD during incorrect memory cycle.");
case 3:
_memoryData = data; // Only really necessary to show in debugger
// Start of doubleword write:
WriteToBus(_memoryAddress, data);
_doubleWordStore = true;
break;
case 4:
case 4:
_memoryData = data; // Only really necessary to show in debugger
WriteToBus(_doubleWordStore ? (ushort)(_memoryAddress ^ 1) : _memoryAddress, data);
break;
}
@ -172,7 +199,7 @@ namespace Contralto.Memory
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
private static ushort ReadFromBus(ushort address)
private ushort ReadFromBus(ushort address)
{
// TODO: actually dispatch to I/O
return _mem.Read(address);
@ -184,22 +211,22 @@ namespace Contralto.Memory
/// <param name="address"></param>
/// <param name="data"></param>
/// <returns></returns>
private static void WriteToBus(ushort address, ushort data)
private void WriteToBus(ushort address, ushort data)
{
_mem.Load(address, data);
}
private static Memory _mem;
private static bool _memoryOperationActive;
private static int _memoryCycle;
private static ushort _memoryAddress;
private Memory _mem;
private bool _memoryOperationActive;
private int _memoryCycle;
private ushort _memoryAddress;
// Buffered read data (on cycles 3 and 4)
private static ushort _memoryData;
private static ushort _memoryData2;
private ushort _memoryData;
private ushort _memoryData2;
// Indicates a double-word store (started on cycle 3)
private static bool _doubleWordStore;
private bool _doubleWordStore;
}
}

View File

@ -12,5 +12,11 @@ namespace Contralto
{
return Convert.ToString(i, 8);
}
public static string ToOctal(int i, int digits)
{
string octalString = Convert.ToString(i, 8);
return new String('0', digits - octalString.Length) + octalString;
}
}
}

View File

@ -13,20 +13,13 @@ namespace Contralto
{
static void Main(string[] args)
{
AltoCPU cpu = new AltoCPU();
for(int i=0;i<2048;i++)
{
MicroInstruction inst = new MicroInstruction(UCodeMemory.UCodeROM[i]);
AltoSystem system = new AltoSystem();
Console.WriteLine("{0}: {1}", OctalHelpers.ToOctal(i), Disassembler.DisassembleInstruction(inst, TaskType.Emulator));
}
while(true)
{
MemoryBus.Clock();
cpu.ExecuteNext();
}
// for now everything is driven through the debugger
Debugger d = new Debugger(system);
d.LoadSourceCode("Disassembly\\altoIIcode3.mu");
d.ShowDialog();
}
}