mirror of
https://github.com/livingcomputermuseum/ContrAlto.git
synced 2026-01-22 10:31:01 +00:00
Fixed S register addressing (many things now working!), tweaked display (mouse displays correctly in lowres mode). Added support for committing disk changes back to disk images (done automatically when switching disks or exiting). Repaired BravoX image.
This commit is contained in:
parent
3c8a64bac8
commit
0cce77c842
@ -28,6 +28,8 @@ namespace Contralto
|
||||
_mouse = new Mouse();
|
||||
_ethernetController = new EthernetController(this);
|
||||
|
||||
|
||||
|
||||
_cpu = new AltoCPU(this);
|
||||
|
||||
// Attach memory-mapped devices to the bus
|
||||
@ -177,7 +179,7 @@ namespace Contralto
|
||||
|
||||
private AltoCPU _cpu;
|
||||
private MemoryBus _memBus;
|
||||
private Contralto.Memory.Memory _mem;
|
||||
private Memory.Memory _mem;
|
||||
private Keyboard _keyboard;
|
||||
private Mouse _mouse;
|
||||
private DiskController _diskController;
|
||||
|
||||
39
Contralto/AltoWindow.Designer.cs
generated
39
Contralto/AltoWindow.Designer.cs
generated
@ -39,17 +39,17 @@
|
||||
this.drive0ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.loadToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.unloadToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.Drive0ImageName = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.drive1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.loadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.unloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.Drive1ImageName = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SystemShowDebuggerMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.StatusLine = new System.Windows.Forms.StatusStrip();
|
||||
this.CaptureStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.Drive0ImageName = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.Drive1ImageName = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SystemStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.DiskStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DisplayBox)).BeginInit();
|
||||
@ -92,7 +92,7 @@
|
||||
// exitToolStripMenuItem
|
||||
//
|
||||
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
|
||||
this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.exitToolStripMenuItem.Size = new System.Drawing.Size(92, 22);
|
||||
this.exitToolStripMenuItem.Text = "Exit";
|
||||
this.exitToolStripMenuItem.Click += new System.EventHandler(this.OnFileExitClick);
|
||||
//
|
||||
@ -154,6 +154,13 @@
|
||||
this.unloadToolStripMenuItem1.Text = "Unload...";
|
||||
this.unloadToolStripMenuItem1.Click += new System.EventHandler(this.OnSystemDrive0UnloadClick);
|
||||
//
|
||||
// Drive0ImageName
|
||||
//
|
||||
this.Drive0ImageName.Enabled = false;
|
||||
this.Drive0ImageName.Name = "Drive0ImageName";
|
||||
this.Drive0ImageName.Size = new System.Drawing.Size(167, 22);
|
||||
this.Drive0ImageName.Text = "Image Name";
|
||||
//
|
||||
// drive1ToolStripMenuItem
|
||||
//
|
||||
this.drive1ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
@ -167,17 +174,24 @@
|
||||
// loadToolStripMenuItem
|
||||
//
|
||||
this.loadToolStripMenuItem.Name = "loadToolStripMenuItem";
|
||||
this.loadToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.loadToolStripMenuItem.Size = new System.Drawing.Size(134, 22);
|
||||
this.loadToolStripMenuItem.Text = "Load...";
|
||||
this.loadToolStripMenuItem.Click += new System.EventHandler(this.OnSystemDrive1LoadClick);
|
||||
//
|
||||
// unloadToolStripMenuItem
|
||||
//
|
||||
this.unloadToolStripMenuItem.Name = "unloadToolStripMenuItem";
|
||||
this.unloadToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.unloadToolStripMenuItem.Size = new System.Drawing.Size(134, 22);
|
||||
this.unloadToolStripMenuItem.Text = "Unload...";
|
||||
this.unloadToolStripMenuItem.Click += new System.EventHandler(this.OnSystemDrive1UnloadClick);
|
||||
//
|
||||
// Drive1ImageName
|
||||
//
|
||||
this.Drive1ImageName.Enabled = false;
|
||||
this.Drive1ImageName.Name = "Drive1ImageName";
|
||||
this.Drive1ImageName.Size = new System.Drawing.Size(134, 22);
|
||||
this.Drive1ImageName.Text = "Image Name";
|
||||
//
|
||||
// optionsToolStripMenuItem
|
||||
//
|
||||
this.optionsToolStripMenuItem.Enabled = false;
|
||||
@ -228,20 +242,6 @@
|
||||
this.CaptureStatusLabel.Size = new System.Drawing.Size(102, 17);
|
||||
this.CaptureStatusLabel.Text = "CaptureStatusLabel";
|
||||
//
|
||||
// Drive0ImageName
|
||||
//
|
||||
this.Drive0ImageName.Enabled = false;
|
||||
this.Drive0ImageName.Name = "Drive0ImageName";
|
||||
this.Drive0ImageName.Size = new System.Drawing.Size(167, 22);
|
||||
this.Drive0ImageName.Text = "Image Name";
|
||||
//
|
||||
// Drive1ImageName
|
||||
//
|
||||
this.Drive1ImageName.Enabled = false;
|
||||
this.Drive1ImageName.Name = "Drive1ImageName";
|
||||
this.Drive1ImageName.Size = new System.Drawing.Size(152, 22);
|
||||
this.Drive1ImageName.Text = "Image Name";
|
||||
//
|
||||
// SystemStatusLabel
|
||||
//
|
||||
this.SystemStatusLabel.Name = "SystemStatusLabel";
|
||||
@ -271,6 +271,7 @@
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.Text = "ContrAlto";
|
||||
this.Deactivate += new System.EventHandler(this.OnWindowDeactivate);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnAltoWindowClosed);
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
|
||||
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnKeyUp);
|
||||
this.Leave += new System.EventHandler(this.OnWindowLeave);
|
||||
|
||||
@ -97,8 +97,7 @@ namespace Contralto.CPU
|
||||
_l = 0;
|
||||
_m = 0;
|
||||
_ir = 0;
|
||||
_aluC0 = 0;
|
||||
_rb = 0;
|
||||
_aluC0 = 0;
|
||||
_rmr = 0xffff; // Start all tasks in ROM0
|
||||
|
||||
// Reset tasks.
|
||||
@ -233,8 +232,7 @@ namespace Contralto.CPU
|
||||
|
||||
// R and S register files and bank select
|
||||
private ushort[] _r;
|
||||
private ushort[][] _s;
|
||||
private ushort _rb; // S register bank select
|
||||
private ushort[][] _s;
|
||||
|
||||
// Stores the last carry from the ALU on a Load L
|
||||
private ushort _aluC0;
|
||||
|
||||
@ -167,10 +167,17 @@ namespace Contralto.CPU
|
||||
break;
|
||||
|
||||
case DiskF2.NFER:
|
||||
// "NEXT <- NEXT OR (IF fatal error in latches THEN 0 ELSE 1)"
|
||||
// We assume success for now...
|
||||
// "NEXT <- NEXT OR (IF fatal error in latches THEN 0 ELSE 1)"
|
||||
_nextModifier |= GetInitModifier(instruction);
|
||||
_nextModifier |= 0x1;
|
||||
|
||||
if (true) //!_diskController.FatalError)
|
||||
{
|
||||
_nextModifier |= 0x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("fatal disk error");
|
||||
}
|
||||
break;
|
||||
|
||||
case DiskF2.STROBON:
|
||||
|
||||
@ -34,9 +34,9 @@ namespace Contralto.CPU
|
||||
switch (ebs)
|
||||
{
|
||||
case EmulatorBusSource.ReadSLocation:
|
||||
if (_rSelect != 0)
|
||||
if (_srSelect != 0)
|
||||
{
|
||||
return _cpu._s[_cpu._rb][_rSelect];
|
||||
return _cpu._s[_rb][_srSelect];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -47,8 +47,10 @@ namespace Contralto.CPU
|
||||
}
|
||||
|
||||
case EmulatorBusSource.LoadSLocation:
|
||||
// "When an S register is being loaded from M, the processor bus receives an
|
||||
// undefined value rather than being set to zero."
|
||||
_loadS = true;
|
||||
return 0; // TODO: technically this is an "undefined value," not zero.
|
||||
return 0xffff; // TODO: technically this is an "undefined value.".
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException(String.Format("Unhandled bus source {0}", bs));
|
||||
@ -136,6 +138,14 @@ namespace Contralto.CPU
|
||||
_wrtRam = true;
|
||||
break;
|
||||
|
||||
case EmulatorF1.LoadESRB:
|
||||
// For now, this is always 0; we do not yet support the 3K RAM system with 8 banks of S registers.
|
||||
_rb = 0;
|
||||
Logging.Log.Write(Logging.LogType.Warning, Logging.LogComponent.EmulatorTask, "ESRB<- ({0}) not fully implemented.",
|
||||
Conversion.ToOctal((_busData & 0xe) >> 1));
|
||||
//_rb = (ushort)((_busData & 0xe) >> 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException(String.Format("Unhandled emulator F1 {0}.", ef1));
|
||||
}
|
||||
@ -165,6 +175,9 @@ namespace Contralto.CPU
|
||||
//
|
||||
// "...DNS also addresses R from (3-IR[3 - 4])..."
|
||||
//
|
||||
|
||||
// TODO: is S reg select impacted by this?
|
||||
//_srSelect =
|
||||
_rSelect = (_rSelect & 0xfffc) | ((((uint)_cpu._ir & 0x1800) >> 11) ^ 3);
|
||||
break;
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@ namespace Contralto.CPU
|
||||
//
|
||||
_mpc = (ushort)_taskType;
|
||||
_rdRam = false;
|
||||
_rb = 0;
|
||||
}
|
||||
|
||||
public virtual void BlockTask()
|
||||
@ -95,6 +96,7 @@ namespace Contralto.CPU
|
||||
_loadR = false;
|
||||
_loadS = false;
|
||||
_rSelect = 0;
|
||||
_srSelect = 0;
|
||||
_busData = 0;
|
||||
|
||||
|
||||
@ -118,7 +120,7 @@ namespace Contralto.CPU
|
||||
nextModifier = _nextModifier;
|
||||
_nextModifier = 0;
|
||||
|
||||
_rSelect = instruction.RSELECT;
|
||||
_srSelect = _rSelect = instruction.RSELECT;
|
||||
|
||||
// Give tasks the chance to modify parameters early on (like RSELECT)
|
||||
ExecuteSpecialFunction2Early(instruction);
|
||||
@ -220,7 +222,8 @@ namespace Contralto.CPU
|
||||
|
||||
//
|
||||
// If there was a WRTRAM operation last cycle, we write the uCode RAM here
|
||||
// using the results of this instruction's ALU operation.
|
||||
// using the results of this instruction's ALU operation and the M register
|
||||
// from the last instruction.
|
||||
//
|
||||
if (_wrtRam)
|
||||
{
|
||||
@ -371,10 +374,10 @@ namespace Contralto.CPU
|
||||
_cpu._r[_rSelect] = Shifter.Output;
|
||||
}
|
||||
|
||||
// Do writeback to selected R register from M
|
||||
// Do writeback to selected S register from M
|
||||
if (_loadS)
|
||||
{
|
||||
_cpu._s[_cpu._rb][_rSelect] = _cpu._m;
|
||||
_cpu._s[_rb][_srSelect] = _cpu._m;
|
||||
}
|
||||
|
||||
// Load T
|
||||
@ -485,6 +488,7 @@ namespace Contralto.CPU
|
||||
protected ushort _busData; // Data placed onto the bus (ANDed from multiple sources)
|
||||
protected ushort _nextModifier; // Bits ORed onto the NEXT field of the current instruction
|
||||
protected uint _rSelect; // RSELECT field from current instruction, potentially modified by task
|
||||
protected uint _srSelect; // RSELECT field as used by S register access (not modified in the same way as normal _rSelect).
|
||||
protected bool _loadS; // Whether to load S from M at and of cycle
|
||||
protected bool _loadR; // Whether to load R from shifter at end of cycle.
|
||||
protected bool _rdRam; // Whether to load uCode RAM onto the bus during the next cycle.
|
||||
@ -497,6 +501,7 @@ namespace Contralto.CPU
|
||||
//
|
||||
protected AltoCPU _cpu;
|
||||
protected ushort _mpc;
|
||||
protected ushort _rb; // S register bank select
|
||||
protected TaskType _taskType;
|
||||
protected bool _wakeup;
|
||||
|
||||
|
||||
@ -104,7 +104,13 @@ namespace Contralto.CPU
|
||||
_ramBank = (address & 0x3000) >> 12;
|
||||
_ramSelect = (address & 0x0800) == 0;
|
||||
_lowHalfsel = (address & 0x0400) == 0;
|
||||
_ramAddr = (address & 0x3ff);
|
||||
_ramAddr = (address & 0x3ff);
|
||||
|
||||
if (_ramBank != 0)
|
||||
{
|
||||
//throw new NotImplementedException(String.Format("Unexpected RAM BANK select of {0}", _ramBank));
|
||||
_ramBank = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -117,7 +123,8 @@ namespace Contralto.CPU
|
||||
{
|
||||
Logging.Log.Write(Logging.LogComponent.Microcode, "SWMODE: Current Bank {0}", _microcodeBank[(int)task]);
|
||||
|
||||
// 2K ROM
|
||||
// 2K ROM
|
||||
/*
|
||||
switch(_microcodeBank[(int)task])
|
||||
{
|
||||
case MicrocodeBank.ROM0:
|
||||
@ -131,10 +138,10 @@ namespace Contralto.CPU
|
||||
case MicrocodeBank.RAM0:
|
||||
_microcodeBank[(int)task] = (nextAddress & 0x100) == 0 ? MicrocodeBank.ROM0 : MicrocodeBank.ROM1;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
// for 1K ROM
|
||||
//_microcodeBank[(int)task] = _microcodeBank[(int)task] == MicrocodeBank.ROM0 ? MicrocodeBank.RAM0 : MicrocodeBank.ROM0;
|
||||
_microcodeBank[(int)task] = _microcodeBank[(int)task] == MicrocodeBank.ROM0 ? MicrocodeBank.RAM0 : MicrocodeBank.ROM0;
|
||||
|
||||
Logging.Log.Write(Logging.LogComponent.Microcode, "SWMODE: New Bank {0} for Task {1}", _microcodeBank[(int)task], task);
|
||||
}
|
||||
@ -144,13 +151,7 @@ namespace Contralto.CPU
|
||||
if (!_ramSelect)
|
||||
{
|
||||
throw new NotImplementedException("Read from microcode ROM not implemented.");
|
||||
}
|
||||
|
||||
if (_ramBank > 0)
|
||||
{
|
||||
//throw new InvalidOperationException("RAM bank > 0, unexpected.");
|
||||
_ramBank = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// pretend no ram for the moment
|
||||
Logging.Log.Write(Logging.LogComponent.Microcode, "CRAM address for read: Bank {0}, RAM {1}, lowhalf {2} addr {3}",
|
||||
@ -178,13 +179,7 @@ namespace Contralto.CPU
|
||||
{
|
||||
// No-op, can't write to ROM.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_ramBank > 0)
|
||||
{
|
||||
//throw new InvalidOperationException("RAM bank > 0, unexpected.");
|
||||
_ramBank = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Log.Write(Logging.LogComponent.Microcode, "CRAM address for write: Bank {0}, addr {1}",
|
||||
_ramBank,
|
||||
|
||||
135
Contralto/Debugger.Designer.cs
generated
135
Contralto/Debugger.Designer.cs
generated
@ -53,6 +53,8 @@
|
||||
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.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Debugger));
|
||||
this.Microcode = new System.Windows.Forms.GroupBox();
|
||||
this.SourceTabs = new System.Windows.Forms.TabControl();
|
||||
@ -109,6 +111,13 @@
|
||||
this.ResetButton = new System.Windows.Forms.Button();
|
||||
this.RunToNextTaskButton = new System.Windows.Forms.Button();
|
||||
this.NovaStep = new System.Windows.Forms.Button();
|
||||
this.groupBox6 = new System.Windows.Forms.GroupBox();
|
||||
this._reservedMemory = new System.Windows.Forms.DataGridView();
|
||||
this.dataGridViewTextBoxColumn9 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.dataGridViewTextBoxColumn10 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.dataGridViewTextBoxColumn11 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.MemoryJumpToAddress = new System.Windows.Forms.TextBox();
|
||||
this.Microcode.SuspendLayout();
|
||||
this.SourceTabs.SuspendLayout();
|
||||
this.Rom0Page.SuspendLayout();
|
||||
@ -127,6 +136,8 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this._memoryData)).BeginInit();
|
||||
this.groupBox5.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._diskData)).BeginInit();
|
||||
this.groupBox6.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._reservedMemory)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// Microcode
|
||||
@ -149,7 +160,7 @@
|
||||
this.SourceTabs.Location = new System.Drawing.Point(6, 19);
|
||||
this.SourceTabs.Name = "SourceTabs";
|
||||
this.SourceTabs.SelectedIndex = 0;
|
||||
this.SourceTabs.Size = new System.Drawing.Size(590, 571);
|
||||
this.SourceTabs.Size = new System.Drawing.Size(590, 580);
|
||||
this.SourceTabs.TabIndex = 14;
|
||||
this.SourceTabs.SelectedIndexChanged += new System.EventHandler(this.OnTabChanged);
|
||||
//
|
||||
@ -159,7 +170,7 @@
|
||||
this.Rom0Page.Location = new System.Drawing.Point(4, 22);
|
||||
this.Rom0Page.Name = "Rom0Page";
|
||||
this.Rom0Page.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.Rom0Page.Size = new System.Drawing.Size(582, 545);
|
||||
this.Rom0Page.Size = new System.Drawing.Size(582, 554);
|
||||
this.Rom0Page.TabIndex = 0;
|
||||
this.Rom0Page.Text = "ROM0";
|
||||
this.Rom0Page.UseVisualStyleBackColor = true;
|
||||
@ -199,7 +210,7 @@
|
||||
this._rom0SourceViewer.ShowCellErrors = false;
|
||||
this._rom0SourceViewer.ShowEditingIcon = false;
|
||||
this._rom0SourceViewer.ShowRowErrors = false;
|
||||
this._rom0SourceViewer.Size = new System.Drawing.Size(582, 545);
|
||||
this._rom0SourceViewer.Size = new System.Drawing.Size(582, 554);
|
||||
this._rom0SourceViewer.TabIndex = 1;
|
||||
this._rom0SourceViewer.TabStop = false;
|
||||
this._rom0SourceViewer.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.SourceViewCellClick);
|
||||
@ -454,7 +465,7 @@
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(11, 599);
|
||||
this.label2.Location = new System.Drawing.Point(11, 602);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(47, 13);
|
||||
this.label2.TabIndex = 13;
|
||||
@ -462,7 +473,7 @@
|
||||
//
|
||||
// JumpToAddress
|
||||
//
|
||||
this.JumpToAddress.Location = new System.Drawing.Point(59, 596);
|
||||
this.JumpToAddress.Location = new System.Drawing.Point(64, 599);
|
||||
this.JumpToAddress.Name = "JumpToAddress";
|
||||
this.JumpToAddress.Size = new System.Drawing.Size(48, 20);
|
||||
this.JumpToAddress.TabIndex = 12;
|
||||
@ -670,7 +681,7 @@
|
||||
this.groupBox3.Size = new System.Drawing.Size(137, 344);
|
||||
this.groupBox3.TabIndex = 8;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "Other Registers";
|
||||
this.groupBox3.Text = "CPU Registers";
|
||||
//
|
||||
// _otherRegs
|
||||
//
|
||||
@ -729,6 +740,8 @@
|
||||
//
|
||||
// groupBox4
|
||||
//
|
||||
this.groupBox4.Controls.Add(this.MemoryJumpToAddress);
|
||||
this.groupBox4.Controls.Add(this.label3);
|
||||
this.groupBox4.Controls.Add(this._memoryData);
|
||||
this.groupBox4.Location = new System.Drawing.Point(172, 634);
|
||||
this.groupBox4.Name = "groupBox4";
|
||||
@ -773,7 +786,7 @@
|
||||
this._memoryData.ShowCellToolTips = false;
|
||||
this._memoryData.ShowEditingIcon = false;
|
||||
this._memoryData.ShowRowErrors = false;
|
||||
this._memoryData.Size = new System.Drawing.Size(279, 273);
|
||||
this._memoryData.Size = new System.Drawing.Size(279, 257);
|
||||
this._memoryData.TabIndex = 0;
|
||||
this._memoryData.TabStop = false;
|
||||
this._memoryData.VirtualMode = true;
|
||||
@ -936,11 +949,107 @@
|
||||
this.NovaStep.UseVisualStyleBackColor = true;
|
||||
this.NovaStep.Click += new System.EventHandler(this.NovaStep_Click);
|
||||
//
|
||||
// groupBox6
|
||||
//
|
||||
this.groupBox6.Controls.Add(this._reservedMemory);
|
||||
this.groupBox6.Location = new System.Drawing.Point(757, 3);
|
||||
this.groupBox6.Name = "groupBox6";
|
||||
this.groupBox6.Size = new System.Drawing.Size(180, 975);
|
||||
this.groupBox6.TabIndex = 3;
|
||||
this.groupBox6.TabStop = false;
|
||||
this.groupBox6.Text = "Reserved Memory";
|
||||
//
|
||||
// _reservedMemory
|
||||
//
|
||||
this._reservedMemory.AllowUserToAddRows = false;
|
||||
this._reservedMemory.AllowUserToDeleteRows = false;
|
||||
this._reservedMemory.AllowUserToResizeColumns = false;
|
||||
this._reservedMemory.AllowUserToResizeRows = false;
|
||||
dataGridViewCellStyle26.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
|
||||
this._reservedMemory.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle26;
|
||||
this._reservedMemory.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
this._reservedMemory.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.dataGridViewTextBoxColumn9,
|
||||
this.dataGridViewTextBoxColumn10,
|
||||
this.dataGridViewTextBoxColumn11});
|
||||
dataGridViewCellStyle27.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||
dataGridViewCellStyle27.BackColor = System.Drawing.SystemColors.Window;
|
||||
dataGridViewCellStyle27.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
dataGridViewCellStyle27.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
dataGridViewCellStyle27.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle27.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle27.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this._reservedMemory.DefaultCellStyle = dataGridViewCellStyle27;
|
||||
this._reservedMemory.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
|
||||
this._reservedMemory.Location = new System.Drawing.Point(7, 19);
|
||||
this._reservedMemory.MultiSelect = false;
|
||||
this._reservedMemory.Name = "_reservedMemory";
|
||||
this._reservedMemory.ReadOnly = true;
|
||||
this._reservedMemory.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
|
||||
this._reservedMemory.RowHeadersVisible = false;
|
||||
this._reservedMemory.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
|
||||
this._reservedMemory.RowTemplate.Height = 18;
|
||||
this._reservedMemory.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
|
||||
this._reservedMemory.ShowCellErrors = false;
|
||||
this._reservedMemory.ShowCellToolTips = false;
|
||||
this._reservedMemory.ShowEditingIcon = false;
|
||||
this._reservedMemory.ShowRowErrors = false;
|
||||
this._reservedMemory.Size = new System.Drawing.Size(167, 950);
|
||||
this._reservedMemory.TabIndex = 0;
|
||||
this._reservedMemory.TabStop = false;
|
||||
//
|
||||
// dataGridViewTextBoxColumn9
|
||||
//
|
||||
this.dataGridViewTextBoxColumn9.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
|
||||
this.dataGridViewTextBoxColumn9.HeaderText = "Addr";
|
||||
this.dataGridViewTextBoxColumn9.Name = "dataGridViewTextBoxColumn9";
|
||||
this.dataGridViewTextBoxColumn9.ReadOnly = true;
|
||||
this.dataGridViewTextBoxColumn9.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
|
||||
this.dataGridViewTextBoxColumn9.Width = 35;
|
||||
//
|
||||
// dataGridViewTextBoxColumn10
|
||||
//
|
||||
this.dataGridViewTextBoxColumn10.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
|
||||
this.dataGridViewTextBoxColumn10.HeaderText = "Name";
|
||||
this.dataGridViewTextBoxColumn10.Name = "dataGridViewTextBoxColumn10";
|
||||
this.dataGridViewTextBoxColumn10.ReadOnly = true;
|
||||
this.dataGridViewTextBoxColumn10.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.dataGridViewTextBoxColumn10.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
|
||||
this.dataGridViewTextBoxColumn10.Width = 41;
|
||||
//
|
||||
// dataGridViewTextBoxColumn11
|
||||
//
|
||||
this.dataGridViewTextBoxColumn11.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||
this.dataGridViewTextBoxColumn11.HeaderText = "Value";
|
||||
this.dataGridViewTextBoxColumn11.Name = "dataGridViewTextBoxColumn11";
|
||||
this.dataGridViewTextBoxColumn11.ReadOnly = true;
|
||||
this.dataGridViewTextBoxColumn11.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.dataGridViewTextBoxColumn11.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(6, 279);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(47, 13);
|
||||
this.label3.TabIndex = 14;
|
||||
this.label3.Text = "Jump to:";
|
||||
//
|
||||
// MemoryJumpToAddress
|
||||
//
|
||||
this.MemoryJumpToAddress.Location = new System.Drawing.Point(53, 276);
|
||||
this.MemoryJumpToAddress.Name = "MemoryJumpToAddress";
|
||||
this.MemoryJumpToAddress.Size = new System.Drawing.Size(48, 20);
|
||||
this.MemoryJumpToAddress.TabIndex = 15;
|
||||
this.MemoryJumpToAddress.TabStop = false;
|
||||
this.MemoryJumpToAddress.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnMemoryJumpAddressKeyDown);
|
||||
//
|
||||
// Debugger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(750, 997);
|
||||
this.ClientSize = new System.Drawing.Size(949, 997);
|
||||
this.Controls.Add(this.groupBox6);
|
||||
this.Controls.Add(this.NovaStep);
|
||||
this.Controls.Add(this.RunToNextTaskButton);
|
||||
this.Controls.Add(this.ResetButton);
|
||||
@ -981,9 +1090,12 @@
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this._otherRegs)).EndInit();
|
||||
this.groupBox4.ResumeLayout(false);
|
||||
this.groupBox4.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this._memoryData)).EndInit();
|
||||
this.groupBox5.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this._diskData)).EndInit();
|
||||
this.groupBox6.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this._reservedMemory)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@ -1046,5 +1158,12 @@
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5;
|
||||
private System.Windows.Forms.GroupBox groupBox6;
|
||||
private System.Windows.Forms.DataGridView _reservedMemory;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn9;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn10;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn11;
|
||||
private System.Windows.Forms.TextBox MemoryJumpToAddress;
|
||||
private System.Windows.Forms.Label label3;
|
||||
}
|
||||
}
|
||||
@ -134,6 +134,13 @@ namespace Contralto
|
||||
_diskData.Rows[8].Cells[1].Value = Conversion.ToOctal(_system.DiskController.KSTAT, 6);
|
||||
_diskData.Rows[9].Cells[1].Value = _system.DiskController.RECNO.ToString();
|
||||
|
||||
// Reserved memory locations
|
||||
for (int i = 0; i < _reservedMemoryEntries.Length; i++)
|
||||
{
|
||||
_reservedMemory.Rows[i].Cells[2].Value =
|
||||
Conversion.ToOctal(_system.MemoryBus.DebugReadWord(_reservedMemoryEntries[i].Address), 6);
|
||||
}
|
||||
|
||||
//
|
||||
// Select active tab based on current UCode bank
|
||||
switch (UCodeMemory.Bank)
|
||||
@ -248,7 +255,15 @@ 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");
|
||||
|
||||
for(int i=0;i< _reservedMemoryEntries.Length;i++)
|
||||
{
|
||||
_reservedMemory.Rows.Add(
|
||||
Conversion.ToOctal(_reservedMemoryEntries[i].Address, 3),
|
||||
_reservedMemoryEntries[i].Name,
|
||||
Conversion.ToOctal(0, 6));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -641,6 +656,25 @@ namespace Contralto
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMemoryJumpAddressKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Return ||
|
||||
e.KeyCode == Keys.Enter)
|
||||
{
|
||||
try
|
||||
{
|
||||
UInt16 address = Convert.ToUInt16(MemoryJumpToAddress.Text, 8);
|
||||
|
||||
// find the source address that matches this, if any.
|
||||
HighlightNovaSourceLine(address);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// eh, just do nothing for now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStepButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
_execType = ExecutionType.Step;
|
||||
@ -790,6 +824,80 @@ namespace Contralto
|
||||
InternalError,
|
||||
}
|
||||
|
||||
private struct ReservedMemoryEntry
|
||||
{
|
||||
public ReservedMemoryEntry(ushort address, string name)
|
||||
{
|
||||
Address = address;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public ushort Address;
|
||||
public string Name;
|
||||
}
|
||||
|
||||
private ReservedMemoryEntry[] _reservedMemoryEntries =
|
||||
{
|
||||
new ReservedMemoryEntry(0x110, "DASTART"),
|
||||
new ReservedMemoryEntry(0x111, "V.INT"),
|
||||
new ReservedMemoryEntry(0x112, "ITQUAN"),
|
||||
new ReservedMemoryEntry(0x113, "ITBITS"),
|
||||
new ReservedMemoryEntry(0x114, "MOUSEX"),
|
||||
new ReservedMemoryEntry(0x115, "MOUSEY"),
|
||||
new ReservedMemoryEntry(0x116, "CURSORX"),
|
||||
new ReservedMemoryEntry(0x117, "CURSORY"),
|
||||
new ReservedMemoryEntry(0x118, "RTC"),
|
||||
new ReservedMemoryEntry(0x119, "CURMAP0"),
|
||||
new ReservedMemoryEntry(0x11a, "CURMAP1"),
|
||||
new ReservedMemoryEntry(0x11b, "CURMAP2"),
|
||||
new ReservedMemoryEntry(0x11c, "CURMAP3"),
|
||||
new ReservedMemoryEntry(0x11d, "CURMAP4"),
|
||||
new ReservedMemoryEntry(0x11e, "CURMAP5"),
|
||||
new ReservedMemoryEntry(0x11f, "CURMAP6"),
|
||||
new ReservedMemoryEntry(0x120, "CURMAP7"),
|
||||
new ReservedMemoryEntry(0x121, "CURMAP8"),
|
||||
new ReservedMemoryEntry(0x122, "CURMAP9"),
|
||||
new ReservedMemoryEntry(0x123, "CURMAP10"),
|
||||
new ReservedMemoryEntry(0x124, "CURMAP11"),
|
||||
new ReservedMemoryEntry(0x125, "CURMAP12"),
|
||||
new ReservedMemoryEntry(0x126, "CURMAP13"),
|
||||
new ReservedMemoryEntry(0x127, "CURMAP14"),
|
||||
new ReservedMemoryEntry(0x128, "CURMAP15"),
|
||||
new ReservedMemoryEntry(0x12a, "WW"),
|
||||
new ReservedMemoryEntry(0x12b, "ACTIVE"),
|
||||
new ReservedMemoryEntry(0x140, "PCLOC"),
|
||||
new ReservedMemoryEntry(0x141, "INTVEC0"),
|
||||
new ReservedMemoryEntry(0x142, "INTVEC1"),
|
||||
new ReservedMemoryEntry(0x143, "INTVEC2"),
|
||||
new ReservedMemoryEntry(0x144, "INTVEC3"),
|
||||
new ReservedMemoryEntry(0x145, "INTVEC4"),
|
||||
new ReservedMemoryEntry(0x146, "INTVEC5"),
|
||||
new ReservedMemoryEntry(0x147, "INTVEC6"),
|
||||
new ReservedMemoryEntry(0x148, "INTVEC7"),
|
||||
new ReservedMemoryEntry(0x149, "INTVEC8"),
|
||||
new ReservedMemoryEntry(0x14a, "INTVEC9"),
|
||||
new ReservedMemoryEntry(0x14b, "INTVEC10"),
|
||||
new ReservedMemoryEntry(0x14c, "INTVEC11"),
|
||||
new ReservedMemoryEntry(0x14d, "INTVEC12"),
|
||||
new ReservedMemoryEntry(0x14e, "INTVEC13"),
|
||||
new ReservedMemoryEntry(0x14f, "INTVEC14"),
|
||||
new ReservedMemoryEntry(0x151, "KBLK"),
|
||||
new ReservedMemoryEntry(0x152, "KSTAT"),
|
||||
new ReservedMemoryEntry(0x153, "KADDR"),
|
||||
new ReservedMemoryEntry(0x154, "S.INTBM"),
|
||||
new ReservedMemoryEntry(0x155, "ITTIM"),
|
||||
new ReservedMemoryEntry(0x156, "TRAPPC"),
|
||||
new ReservedMemoryEntry(0x180, "EPLOC"),
|
||||
new ReservedMemoryEntry(0x181, "EBLOC"),
|
||||
new ReservedMemoryEntry(0x182, "EELOC"),
|
||||
new ReservedMemoryEntry(0x183, "ELLOC"),
|
||||
new ReservedMemoryEntry(0x184, "EICLOC"),
|
||||
new ReservedMemoryEntry(0x185, "EIPLOC"),
|
||||
new ReservedMemoryEntry(0x186, "EOCLOC"),
|
||||
new ReservedMemoryEntry(0x187, "EOPLOC"),
|
||||
new ReservedMemoryEntry(0x188, "EHLOC"),
|
||||
};
|
||||
|
||||
private AltoSystem _system;
|
||||
private ExecutionController _controller;
|
||||
|
||||
@ -811,5 +919,6 @@ namespace Contralto
|
||||
// Nova Debugger breakpoints; same as above
|
||||
private bool[] _novaBreakpointEnabled;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +195,15 @@
|
||||
<metadata name="dataGridViewTextBoxColumn2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn9.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn10.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn11.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -167,45 +167,25 @@ namespace Contralto.Display
|
||||
displayWord = _whiteOnBlack ? _dataBuffer.Dequeue() : (ushort)~_dataBuffer.Dequeue();
|
||||
}
|
||||
|
||||
_display.DrawDisplayWord(_scanline, _word, displayWord, _lowRes);
|
||||
|
||||
// Merge in cursor word:
|
||||
// Calculate X offset of current word
|
||||
int xOffset = _word * (_lowRes ? 32 : 16);
|
||||
|
||||
// Is cursor within this range? (Note cursor is always 16 bits wide regardless of
|
||||
// display mode, but may span two 16-bit display words.)
|
||||
if ((_cursorXLatched >= xOffset && _cursorXLatched < xOffset + 16) ||
|
||||
(_cursorXLatched + 16 >= xOffset & _cursorXLatched + 16 < xOffset + 16))
|
||||
{
|
||||
// Yes. Merge bits in the appropriate place.
|
||||
int shift = (_cursorXLatched - xOffset);
|
||||
|
||||
// Which half of the 32-bit word the cursor will appear in are we in?
|
||||
if (shift > 0)
|
||||
{
|
||||
// Take the cursor word shifted by the current offset
|
||||
displayWord ^= (ushort)((_cursorRegLatched) >> shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take the cursor word shifted left
|
||||
displayWord ^= (ushort)((_cursorRegLatched) << (-shift));
|
||||
}
|
||||
}
|
||||
|
||||
_display.DrawDisplayWord(_scanline, _word, displayWord, _lowRes);
|
||||
|
||||
_word++;
|
||||
|
||||
if (_word == (_lowRes ? _scanlineWords / 4 : _scanlineWords / 2))
|
||||
{
|
||||
// Run MRT
|
||||
//_system.CPU.WakeupTask(TaskType.MemoryRefresh);
|
||||
}
|
||||
|
||||
if (_word >= (_lowRes ? _scanlineWords / 2 : _scanlineWords))
|
||||
{
|
||||
// End of scanline.
|
||||
// Move to next.
|
||||
// Move to next.
|
||||
|
||||
// Draw cursor for this scanline first
|
||||
if (_cursorXLatched < 606)
|
||||
{
|
||||
_display.DrawCursorWord(_scanline, _cursorXLatched, _cursorRegLatched);
|
||||
}
|
||||
|
||||
_scanline += 2;
|
||||
|
||||
if (_scanline > 807)
|
||||
@ -274,21 +254,17 @@ namespace Contralto.Display
|
||||
}
|
||||
|
||||
public void LoadDDR(ushort word)
|
||||
{
|
||||
|
||||
if (_dataBuffer.Count < 20)
|
||||
{
|
||||
_dataBuffer.Enqueue(word);
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
_dataBuffer.Enqueue(word);
|
||||
|
||||
|
||||
// Sanity check: data length should never exceed 16 words.
|
||||
if (_dataBuffer.Count >= 16)
|
||||
{
|
||||
|
||||
//_dataBuffer.Dequeue();
|
||||
//_system.CPU.BlockTask(TaskType.DisplayWord);
|
||||
} */
|
||||
// TODO: we're allowing up to 18 before we start discarding things.
|
||||
// This indicates that our timing is messed up somewhere...
|
||||
if (_dataBuffer.Count > 18)
|
||||
{
|
||||
_dataBuffer.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadXPREG(ushort word)
|
||||
@ -296,32 +272,17 @@ namespace Contralto.Display
|
||||
if (!_cursorXLatch)
|
||||
{
|
||||
_cursorXLatch = true;
|
||||
_cursorX = (ushort)(~word);
|
||||
|
||||
//System.Console.WriteLine("XPREG {0}, scanline {1} word {2}", word, _scanline, _word);
|
||||
_cursorX = (ushort)(~word);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadCSR(ushort word)
|
||||
{
|
||||
/*
|
||||
if (_cursorReg != 0 && word == 0)
|
||||
{
|
||||
System.Console.WriteLine("csr disabled, scanline {0}", _scanline);
|
||||
} */
|
||||
|
||||
{
|
||||
if (!_cursorRegLatch)
|
||||
{
|
||||
_cursorRegLatch = true;
|
||||
_cursorReg = (ushort)word;
|
||||
|
||||
if (word != 0)
|
||||
{
|
||||
//System.Console.WriteLine("csr {0} scanline {1}, word {2}", Conversion.ToOctal(word), _scanline, _word);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_cursorReg = (ushort)word;
|
||||
}
|
||||
}
|
||||
|
||||
public void SETMODE(ushort word)
|
||||
|
||||
@ -89,7 +89,7 @@
|
||||
_display.DrawDisplayWord(scanline, wordOffset, (ushort)(dcb.whiteOnBlack ? 0x0 : 0xffff), false);
|
||||
}
|
||||
|
||||
_display.Render();
|
||||
//_display.Render();
|
||||
|
||||
// decrement scan line counter for this DCB, if < 0, grab next DCB.
|
||||
dcb.scanlineCount--;
|
||||
|
||||
@ -17,6 +17,15 @@ namespace Contralto.Display
|
||||
/// <param name="lowRes"></param>
|
||||
void DrawDisplayWord(int scanline, int wordOffset, ushort dataWord, bool lowRes);
|
||||
|
||||
/// <summary>
|
||||
/// Renders the cursor word for the specified scanline
|
||||
/// </summary>
|
||||
/// <param name="scanline"></param>
|
||||
/// <param name="wordOffset"></param>
|
||||
/// <param name="dataWord"></param>
|
||||
/// <param name="lowRes"></param>
|
||||
void DrawCursorWord(int scanline, int xOffset, ushort cursorWord);
|
||||
|
||||
/// <summary>
|
||||
/// Causes the display to be rendered
|
||||
/// </summary>
|
||||
|
||||
@ -18,7 +18,8 @@ namespace Contralto
|
||||
{
|
||||
_system = system;
|
||||
|
||||
_execAbort = false;
|
||||
_execAbort = false;
|
||||
_userAbort = false;
|
||||
|
||||
}
|
||||
|
||||
@ -29,7 +30,7 @@ namespace Contralto
|
||||
|
||||
public void StopExecution()
|
||||
{
|
||||
_execAbort = true;
|
||||
_userAbort = true;
|
||||
|
||||
if (_execThread != null)
|
||||
{
|
||||
@ -80,6 +81,7 @@ namespace Contralto
|
||||
}
|
||||
|
||||
_execAbort = false;
|
||||
_userAbort = false;
|
||||
|
||||
_execThread = new Thread(new System.Threading.ThreadStart(ExecuteProc));
|
||||
_execThread.Start();
|
||||
@ -108,7 +110,7 @@ namespace Contralto
|
||||
_execAbort = _stepCallback();
|
||||
}
|
||||
|
||||
if (_execAbort)
|
||||
if (_execAbort || _userAbort)
|
||||
{
|
||||
// Halt execution
|
||||
break;
|
||||
@ -119,6 +121,7 @@ namespace Contralto
|
||||
// Execution thread and state
|
||||
private Thread _execThread;
|
||||
private bool _execAbort;
|
||||
private bool _userAbort;
|
||||
|
||||
private StepCallbackDelegate _stepCallback;
|
||||
private ErrorCallbackDelegate _errorCallback;
|
||||
|
||||
@ -142,11 +142,51 @@ namespace Contralto.IO
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(Stream imageStream)
|
||||
{
|
||||
for (int cylinder = 0; cylinder < _geometry.Cylinders; cylinder++)
|
||||
{
|
||||
for (int track = 0; track < _geometry.Tracks; track++)
|
||||
{
|
||||
for (int sector = 0; sector < _geometry.Sectors; sector++)
|
||||
{
|
||||
byte[] header = new byte[4]; // 2 words
|
||||
byte[] label = new byte[16]; // 8 words
|
||||
byte[] data = new byte[512]; // 256 words
|
||||
|
||||
//
|
||||
// Bitsavers images have an extra word in the header for some reason.
|
||||
// We will follow this 'standard' when writing out.
|
||||
// TODO: should support different formats ("correct" raw, Alto CopyDisk format, etc.)
|
||||
//
|
||||
byte[] dummy = new byte[2];
|
||||
imageStream.Write(dummy, 0, 2);
|
||||
|
||||
DiabloDiskSector s = _sectors[cylinder, track, sector];
|
||||
|
||||
WriteWordBuffer(imageStream, s.Header);
|
||||
WriteWordBuffer(imageStream, s.Label);
|
||||
WriteWordBuffer(imageStream, s.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DiabloDiskSector GetSector(int cylinder, int track, int sector)
|
||||
{
|
||||
return _sectors[cylinder, track, sector];
|
||||
}
|
||||
|
||||
private void WriteWordBuffer(Stream imageStream, ushort[] buffer)
|
||||
{
|
||||
// TODO: this is beyond inefficient
|
||||
for(int i=0;i<buffer.Length;i++)
|
||||
{
|
||||
imageStream.WriteByte((byte)buffer[i]);
|
||||
imageStream.WriteByte((byte)(buffer[i] >> 8));
|
||||
}
|
||||
}
|
||||
|
||||
private void SwapBytes(byte[] data)
|
||||
{
|
||||
for(int i=0;i<data.Length;i+=2)
|
||||
|
||||
@ -71,12 +71,7 @@ namespace Contralto.IO
|
||||
(_kDataWrite & 0xf000) >> 12,
|
||||
(_kDataWrite & 0x2) >> 1,
|
||||
(_kDataWrite & 0x1));
|
||||
|
||||
//if ((_kAdr & 0x1) != 0)
|
||||
{
|
||||
//_disk = ((_kDataWrite & 0x2) >> 1);
|
||||
}
|
||||
|
||||
|
||||
Log.Write(LogComponent.DiskController, " -Selected disk is {0}", _disk);
|
||||
|
||||
if ((_kDataWrite & 0x1) != 0)
|
||||
@ -113,7 +108,20 @@ namespace Contralto.IO
|
||||
if (_sendAdr & (_kDataWrite & 0x2) != 0)
|
||||
{
|
||||
// Select disk if _sendAdr is true
|
||||
_disk = (_kAdr & 0x1);
|
||||
_disk = (_kAdr & 0x1);
|
||||
_seeking = false;
|
||||
|
||||
/*
|
||||
|
||||
// Clear the NOTREADY flag depending on whether the drive is loaded or not
|
||||
if (_drives[_disk].IsLoaded)
|
||||
{
|
||||
_kStat &= (ushort)~NOTREADY;
|
||||
}
|
||||
else
|
||||
{
|
||||
_kStat |= NOTREADY;
|
||||
} */
|
||||
}
|
||||
|
||||
}
|
||||
@ -186,8 +194,30 @@ namespace Contralto.IO
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: verify what generates this signal
|
||||
return true;
|
||||
// This is the SRWREADY signal, generated by the drive itself.
|
||||
// This is true if the drive is:
|
||||
// - powered on, loaded with a disk, spun up
|
||||
// - not actively seeking
|
||||
return _drives[0].IsLoaded;
|
||||
}
|
||||
}
|
||||
|
||||
public bool FatalError
|
||||
{
|
||||
get
|
||||
{
|
||||
//
|
||||
// A fatal error is signaled when any of:
|
||||
// - SECLATE
|
||||
// - A seek error
|
||||
// - Drive not ready
|
||||
// Is true.
|
||||
// (In reality the logic is a bit more complicated,
|
||||
// but this is sufficient.)
|
||||
//
|
||||
return (_kStat & SECLATE) != 0 ||
|
||||
(_kStat & SEEKFAIL) != 0 ||
|
||||
(_kStat & NOTREADY) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,6 +237,7 @@ namespace Contralto.IO
|
||||
_kDataWrite = 0;
|
||||
_kDataWriteLatch = false;
|
||||
_sendAdr = false;
|
||||
_seeking = false;
|
||||
|
||||
_wdInhib = true;
|
||||
_xferOff = true;
|
||||
@ -261,7 +292,7 @@ namespace Contralto.IO
|
||||
SelectedDrive.Sector = _sector;
|
||||
|
||||
// Only wake up if not actively seeking.
|
||||
if ((_kStat & 0x0040) == 0)
|
||||
if ((_kStat & STROBE) == 0)
|
||||
{
|
||||
Log.Write(LogType.Verbose, LogComponent.DiskController, "Waking up sector task for C/H/S {0}/{1}/{2}", SelectedDrive.Cylinder, SelectedDrive.Head, _sector);
|
||||
_system.CPU.WakeupTask(CPU.TaskType.DiskSector);
|
||||
@ -269,7 +300,7 @@ namespace Contralto.IO
|
||||
// Reset SECLATE
|
||||
_seclate = false;
|
||||
_seclateEnable = true;
|
||||
_kStat &= 0xffef;
|
||||
_kStat &= (ushort)~SECLATE;
|
||||
|
||||
// Schedule a disk word wakeup to spin the disk
|
||||
_wordEvent.TimestampNsec = _wordDuration;
|
||||
@ -306,11 +337,11 @@ namespace Contralto.IO
|
||||
}
|
||||
|
||||
private void SeclateCallback(ulong timeNsec, ulong skewNsec, object context)
|
||||
{
|
||||
{
|
||||
if (_seclateEnable)
|
||||
{
|
||||
_seclate = true;
|
||||
_kStat |= 0x0010; // TODO: move to constant field!
|
||||
_seclate = true;
|
||||
_kStat |= SECLATE; // TODO: move to constant field!
|
||||
Log.Write(LogComponent.DiskSectorTask, "SECLATE for sector {0}.", _sector);
|
||||
}
|
||||
}
|
||||
@ -318,7 +349,7 @@ namespace Contralto.IO
|
||||
public void ClearStatus()
|
||||
{
|
||||
// "...clears KSTAT[13]." (chksum error flag)
|
||||
_kStat &= 0xfffb;
|
||||
_kStat &= 0xff4b;
|
||||
}
|
||||
|
||||
public void IncrementRecord()
|
||||
@ -367,9 +398,10 @@ namespace Contralto.IO
|
||||
// TODO: handle Model-44 cylinder count (and packs, for that matter)
|
||||
if (destCylinder > 202)
|
||||
{
|
||||
_kStat |= 0x0080;
|
||||
_kStat |= SEEKFAIL;
|
||||
|
||||
Log.Write(LogComponent.DiskController, "Seek failed, specified cylinder {0} is out of range.", destCylinder);
|
||||
_seeking = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -377,10 +409,11 @@ namespace Contralto.IO
|
||||
_destCylinder = destCylinder;
|
||||
|
||||
// Clear the fail bit.
|
||||
_kStat &= 0xff7f;
|
||||
_kStat &= (ushort)~SEEKFAIL;
|
||||
|
||||
// Set seek bit
|
||||
_kStat |= 0x0040;
|
||||
_kStat |= STROBE;
|
||||
_seeking = true;
|
||||
|
||||
// And figure out how long this will take.
|
||||
_seekDuration = (ulong)(CalculateSeekTime() / (ulong)(Math.Abs(_destCylinder - SelectedDrive.Cylinder) + 1));
|
||||
@ -518,7 +551,7 @@ namespace Contralto.IO
|
||||
if (bWakeup)
|
||||
{
|
||||
Log.Write(LogType.Verbose, LogComponent.DiskWordTask, "Word task awoken for word {0}.", _sectorWordIndex);
|
||||
_system.CPU.WakeupTask(TaskType.DiskWord);
|
||||
_system.CPU.WakeupTask(TaskType.DiskWord);
|
||||
}
|
||||
|
||||
// Last, move to the next word.
|
||||
@ -548,7 +581,8 @@ namespace Contralto.IO
|
||||
if (SelectedDrive.Cylinder == _destCylinder)
|
||||
{
|
||||
// clear Seek bit
|
||||
_kStat &= 0xffbf;
|
||||
_kStat &= (ushort)~STROBE;
|
||||
_seeking = false;
|
||||
|
||||
Log.Write(LogComponent.DiskController, "Seek to {0} completed.", SelectedDrive.Cylinder);
|
||||
}
|
||||
@ -612,6 +646,7 @@ namespace Contralto.IO
|
||||
private int _destCylinder;
|
||||
private ulong _seekDuration;
|
||||
private Event _seekEvent;
|
||||
private bool _seeking;
|
||||
|
||||
// Selected disk
|
||||
private int _disk;
|
||||
@ -652,7 +687,7 @@ namespace Contralto.IO
|
||||
// 8.5uS for seclate delay (approx. 50 clocks)
|
||||
private static ulong _seclateDuration = (ulong)(85.0 * Conversion.UsecToNsec * _scale);
|
||||
private bool _seclateEnable;
|
||||
private bool _seclate;
|
||||
private bool _seclate;
|
||||
private Event _seclateEvent;
|
||||
|
||||
// Attached drives
|
||||
@ -661,5 +696,12 @@ namespace Contralto.IO
|
||||
private AltoSystem _system;
|
||||
|
||||
private bool _debugRead;
|
||||
|
||||
// KSTAT bitfields
|
||||
private readonly ushort SECLATE = 0x10;
|
||||
private readonly ushort NOTREADY = 0x20;
|
||||
private readonly ushort STROBE = 0x40;
|
||||
private readonly ushort SEEKFAIL = 0x80;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,3 +80,12 @@ Project is on backburner while working on SUPDUP; notes for myself on current st
|
||||
unsure if this is intentional... (i.e. marks a non-bootable pack)
|
||||
|
||||
|
||||
Never mind -- pack was corrupted
|
||||
|
||||
|
||||
12/18/2015:
|
||||
|
||||
Remaining disk controller signals:
|
||||
|
||||
NFER -- look at -KFER signal to determine what a "fatal error" is
|
||||
SWRNRDY -- llok at -SRWRDY signal to see what "ready" means
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user