diff --git a/Contralto/CPU/MicroInstruction.cs b/Contralto/CPU/MicroInstruction.cs
index bc3b178..bf42f62 100644
--- a/Contralto/CPU/MicroInstruction.cs
+++ b/Contralto/CPU/MicroInstruction.cs
@@ -220,14 +220,14 @@ namespace Contralto.CPU
F1 == SpecialFunction1.Constant ||
F2 == SpecialFunction2.Constant;
- BS4 = ((int)BS > 4);
+ BS4 = ((int)BS >= 4);
// Constant ROM access:
// "The constant memory is gated to the bus by F1=7, F2=7, or BS>4. The constant memory is addressed by the
// (8 bit) concatenation of RSELECT and BS. The intent in enabling constants with BS>4 is to provide a masking
// facility, particularly for the <-MOUSE and <-DISP bus sources. This works because the processor bus ANDs if
// more than one source is gated to it. Up to 32 such mask contans can be provided for each of the four bus sources
- // > 4."
+ // >= 4."
// NOTE also:
// "Note that the [emulator task F2] functions which replace the low bits of RSELECT with IR affect only the
// selection of R; they do not affect the address supplied to the constant ROM."
diff --git a/Contralto/CPU/NovaDisassembler.cs b/Contralto/CPU/NovaDisassembler.cs
index 5eb093a..efe07c7 100644
--- a/Contralto/CPU/NovaDisassembler.cs
+++ b/Contralto/CPU/NovaDisassembler.cs
@@ -51,6 +51,10 @@ namespace Contralto.CPU.Nova
_altoIOTable.Add(0x6214, "BITBLT");
_altoIOTable.Add(0x6215, "XMLDA");
_altoIOTable.Add(0x6216, "XMSTA");
+ _altoIOTable.Add(0x6200, "DIR");
+ _altoIOTable.Add(0x6201, "EIR");
+ _altoIOTable.Add(0x6202, "BRI");
+ _altoIOTable.Add(0x620b, "DIRS");
}
///
diff --git a/Contralto/CPU/Tasks/DiskTask.cs b/Contralto/CPU/Tasks/DiskTask.cs
index b35263b..9f585e2 100644
--- a/Contralto/CPU/Tasks/DiskTask.cs
+++ b/Contralto/CPU/Tasks/DiskTask.cs
@@ -51,9 +51,9 @@ namespace Contralto.CPU
}
}
- protected override ushort GetBusSource(int bs)
+ protected override ushort GetBusSource(MicroInstruction instruction)
{
- DiskBusSource dbs = (DiskBusSource)bs;
+ DiskBusSource dbs = (DiskBusSource)instruction.BS;
switch (dbs)
{
@@ -64,7 +64,7 @@ namespace Contralto.CPU
return _diskController.KDATA;
default:
- throw new InvalidOperationException(String.Format("Unhandled bus source {0}", bs));
+ throw new InvalidOperationException(String.Format("Unhandled bus source {0}", instruction.BS));
}
}
diff --git a/Contralto/CPU/Tasks/EmulatorTask.cs b/Contralto/CPU/Tasks/EmulatorTask.cs
index 30ecb2a..9871498 100644
--- a/Contralto/CPU/Tasks/EmulatorTask.cs
+++ b/Contralto/CPU/Tasks/EmulatorTask.cs
@@ -51,16 +51,16 @@ namespace Contralto.CPU
throw new InvalidOperationException("The emulator task is always in wakeup state.");
}
- protected override ushort GetBusSource(int bs)
+ protected override ushort GetBusSource(MicroInstruction instruction)
{
- EmulatorBusSource ebs = (EmulatorBusSource)bs;
+ EmulatorBusSource ebs = (EmulatorBusSource)instruction.BS;
switch (ebs)
{
case EmulatorBusSource.ReadSLocation:
- if (_srSelect != 0)
+ if (instruction.RSELECT != 0)
{
- return _cpu._s[_rb][_srSelect];
+ return _cpu._s[_rb][instruction.RSELECT];
}
else
{
@@ -77,7 +77,7 @@ namespace Contralto.CPU
return 0xffff; // Technically this is an "undefined value," we're defining it as -1.
default:
- throw new InvalidOperationException(String.Format("Unhandled bus source {0}", bs));
+ throw new InvalidOperationException(String.Format("Unhandled bus source {0}", instruction.BS));
}
}
@@ -220,7 +220,7 @@ namespace Contralto.CPU
// "IR<- also merges bus bits 0, 5, 6 and 7 into NEXT[6-9] which does a first level
// instruction dispatch."
- _nextModifier = (ushort)(((_busData & 0x8000) >> 12) | ((_busData & 0x0700) >> 8));
+ _nextModifier |= (ushort)(((_busData & 0x8000) >> 12) | ((_busData & 0x0700) >> 8));
// "IR<- clears SKIP"
_skip = 0;
@@ -247,11 +247,11 @@ namespace Contralto.CPU
//
if ((_cpu._ir & 0x8000) != 0)
{
- _nextModifier = (ushort)(3 - ((_cpu._ir & 0xc0) >> 6));
+ _nextModifier |= (ushort)(3 - ((_cpu._ir & 0xc0) >> 6));
}
else
{
- _nextModifier = ControlROM.ACSourceROM[((_cpu._ir & 0x7f00) >> 8) + 0x80];
+ _nextModifier |= ControlROM.ACSourceROM[((_cpu._ir & 0x7f00) >> 8) + 0x80];
}
break;
@@ -279,12 +279,12 @@ namespace Contralto.CPU
if ((_cpu._ir & 0x8000) != 0)
{
// 3-IR[8-9] (shift field of arithmetic instruction)
- _nextModifier = (ushort)(3 - ((_cpu._ir & 0xc0) >> 6));
+ _nextModifier |= (ushort)(3 - ((_cpu._ir & 0xc0) >> 6));
}
else
{
// Use the PROM.
- _nextModifier = ControlROM.ACSourceROM[((_cpu._ir & 0x7f00) >> 8)];
+ _nextModifier |= ControlROM.ACSourceROM[((_cpu._ir & 0x7f00) >> 8)];
}
break;
diff --git a/Contralto/CPU/Tasks/EthernetTask.cs b/Contralto/CPU/Tasks/EthernetTask.cs
index deb96eb..7100e69 100644
--- a/Contralto/CPU/Tasks/EthernetTask.cs
+++ b/Contralto/CPU/Tasks/EthernetTask.cs
@@ -50,9 +50,9 @@ namespace Contralto.CPU
return base.ExecuteInstruction(instruction);
}
- protected override ushort GetBusSource(int bs)
+ protected override ushort GetBusSource(MicroInstruction instruction)
{
- EthernetBusSource ebs = (EthernetBusSource)bs;
+ EthernetBusSource ebs = (EthernetBusSource)instruction.BS;
switch(ebs)
{
diff --git a/Contralto/CPU/Tasks/Task.cs b/Contralto/CPU/Tasks/Task.cs
index 1be4517..6de4d3a 100644
--- a/Contralto/CPU/Tasks/Task.cs
+++ b/Contralto/CPU/Tasks/Task.cs
@@ -19,6 +19,7 @@ using System;
using Contralto.Memory;
using Contralto.Logging;
+using System.IO;
namespace Contralto.CPU
{
@@ -143,8 +144,7 @@ namespace Contralto.CPU
ushort nextModifier;
_loadR = false;
_loadS = false;
- _rSelect = 0;
- _srSelect = 0;
+ _rSelect = 0;
_busData = 0;
_softReset = false;
@@ -158,16 +158,16 @@ namespace Contralto.CPU
{
if (!_cpu._system.MemoryBus.Ready(instruction.MemoryOperation))
{
- // Suspend operation for this cycle.
+ // Suspend operation for this cycle.
return InstructionCompletion.MemoryWait;
}
}
-
+
// If we have a modified next field from the last instruction, make sure it gets applied to this one.
nextModifier = _nextModifier;
_nextModifier = 0;
- _srSelect = _rSelect = instruction.RSELECT;
+ _rSelect = instruction.RSELECT;
// Give tasks the chance to modify parameters early on (like RSELECT)
ExecuteSpecialFunction2Early(instruction);
@@ -193,11 +193,11 @@ namespace Contralto.CPU
case BusSource.TaskSpecific1:
case BusSource.TaskSpecific2:
- _busData = GetBusSource((int)instruction.BS); // task specific -- call into specific implementation
+ _busData = GetBusSource(instruction); // task specific -- call into specific implementation
break;
case BusSource.ReadMD:
- _busData = _cpu._system.MemoryBus.ReadMD();
+ _busData = _cpu._system.MemoryBus.ReadMD();
break;
case BusSource.ReadMouse:
@@ -218,7 +218,7 @@ namespace Contralto.CPU
if ((_cpu._ir & 0x300) != 0)
{
// sign extend if necessary
- if ((_cpu._ir & 0x80) == 0x80)
+ if ((_cpu._ir & 0x80) != 0)
{
_busData |= (0xff00);
}
@@ -311,7 +311,7 @@ namespace Contralto.CPU
_cpu._system.MemoryBus.LoadMAR(
aluData,
_taskType,
- _systemType == SystemType.AltoI ? false : instruction.F2 == SpecialFunction2.StoreMD);
+ _systemType == SystemType.AltoI ? false : instruction.F2 == SpecialFunction2.StoreMD);
break;
case SpecialFunction1.Task:
@@ -366,7 +366,7 @@ namespace Contralto.CPU
case SpecialFunction2.BusEq0:
if (_busData == 0)
{
- _nextModifier = 1;
+ _nextModifier |= 1;
}
break;
@@ -380,14 +380,14 @@ namespace Contralto.CPU
case SpecialFunction2.Bus:
// Select bits 6-15 (bits 0-9 in modern parlance) of the bus
- _nextModifier = (ushort)(_busData & 0x3ff);
+ _nextModifier |= (ushort)(_busData & 0x3ff);
break;
case SpecialFunction2.ALUCY:
// ALUC0 is the carry produced by the ALU during the most recent microinstruction
// that loaded L. It is *not* the carry produced during the execution of the microinstruction
// that contains the ALUCY function.
- _nextModifier = _cpu._aluC0;
+ _nextModifier |= _cpu._aluC0;
break;
case SpecialFunction2.StoreMD:
@@ -446,7 +446,7 @@ namespace Contralto.CPU
//
if ((short)Shifter.Output < 0)
{
- _nextModifier = 1;
+ _nextModifier |= 1;
}
break;
@@ -454,7 +454,7 @@ namespace Contralto.CPU
// See note above.
if (Shifter.Output == 0)
{
- _nextModifier = 1;
+ _nextModifier |= 1;
}
break;
}
@@ -472,7 +472,7 @@ namespace Contralto.CPU
// Do writeback to selected S register from M
if (_loadS)
{
- _cpu._s[_rb][_srSelect] = _cpu._m;
+ _cpu._s[_rb][instruction.RSELECT] = _cpu._m;
}
// Load T
@@ -546,7 +546,7 @@ namespace Contralto.CPU
///
///
///
- protected virtual ushort GetBusSource(int bs)
+ protected virtual ushort GetBusSource(MicroInstruction instruction)
{
// Nothing by default.
return 0;
@@ -631,8 +631,7 @@ namespace Contralto.CPU
// these could be encapsulated in an object and passed to subclass implementations?
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 uint _rSelect; // RSELECT field from current instruction, potentially modified by task
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.
diff --git a/Contralto/Memory/MemoryBus.cs b/Contralto/Memory/MemoryBus.cs
index 3b21e23..43ed2e0 100644
--- a/Contralto/Memory/MemoryBus.cs
+++ b/Contralto/Memory/MemoryBus.cs
@@ -16,6 +16,7 @@
*/
using Contralto.CPU;
+using Contralto.Logging;
using System;
using System.Collections.Generic;
@@ -23,7 +24,7 @@ namespace Contralto.Memory
{
public enum MemoryOperation
{
- None,
+ None,
LoadAddress,
Read,
Store
@@ -76,9 +77,10 @@ namespace Contralto.Memory
{
_memoryCycle = 0;
_memoryAddress = 0;
- _memoryData = 0;
- _doubleWordStore = false;
- _doubleWordMixed = false;
+ _memoryDataLow = 0;
+ _memoryDataHigh = 0;
+ _firstWordStored = false;
+ _firstWordRead = false;
_memoryOperationActive = false;
_extendedMemoryReference = false;
}
@@ -88,9 +90,19 @@ namespace Contralto.Memory
get { return _memoryAddress; }
}
- public ushort MD
+ public ushort MDLow
{
- get { return _memoryData; }
+ get { return _memoryDataLow; }
+ }
+
+ public ushort MDHigh
+ {
+ get { return _memoryDataHigh; }
+ }
+
+ public ushort MDWrite
+ {
+ get { return _memoryDataWrite; }
}
public int Cycle
@@ -134,27 +146,26 @@ namespace Contralto.Memory
{
ClockAltoII();
}
- }
+ }
}
-
+
private void ClockAltoI()
{
switch (_memoryCycle)
{
case 4:
// Buffered read of single word
- _memoryData = ReadFromBus(_memoryAddress, _task, _extendedMemoryReference);
+ _memoryDataLow = ReadFromBus(_memoryAddress, _task, _extendedMemoryReference);
break;
case 5:
// Buffered read of double-word
- _memoryData2 = ReadFromBus((ushort)(_memoryAddress | 1), _task, _extendedMemoryReference);
+ _memoryDataHigh = ReadFromBus((ushort)(_memoryAddress | 1), _task, _extendedMemoryReference);
break;
case 7:
// End of memory operation
- _memoryOperationActive = false;
- _doubleWordStore = false;
+ _memoryOperationActive = false;
break;
}
}
@@ -165,18 +176,17 @@ namespace Contralto.Memory
{
case 3:
// Buffered read of single word
- _memoryData = ReadFromBus(_memoryAddress, _task, _extendedMemoryReference);
+ _memoryDataLow = ReadFromBus(_memoryAddress, _task, _extendedMemoryReference);
break;
case 4:
// Buffered read of double-word
- _memoryData2 = ReadFromBus((ushort)(_memoryAddress ^ 1), _task, _extendedMemoryReference);
+ _memoryDataHigh = ReadFromBus((ushort)(_memoryAddress ^ 1), _task, _extendedMemoryReference);
break;
- case 5:
+ case 6:
// End of memory operation
- _memoryOperationActive = false;
- _doubleWordStore = false;
+ _memoryOperationActive = false;
break;
}
}
@@ -198,7 +208,7 @@ namespace Contralto.Memory
case MemoryOperation.Store:
if (_systemType == SystemType.AltoI)
{
- // // Store operations take place on cycles 5 and 6
+ // Store operations take place on cycles 5 and 6
return _memoryCycle > 4;
}
else
@@ -220,6 +230,13 @@ namespace Contralto.Memory
public void LoadMAR(ushort address, TaskType task, bool extendedMemoryReference)
{
+ //
+ // This seems like as good a place as any to point out an oddity --
+ // The Hardware Reference (Section 2, page 7) notes:
+ // "MAR<- cannot be invoked in the same instruction as <-MD of a previous access."
+ // This rule is broken by the Butte microcode used by BravoX. It appears to expect that
+ // the MAR load takes place after MD has been read, which makes sense.
+ //
if (_memoryOperationActive)
{
// This should not happen; CPU implementation should check whether the operation is possible
@@ -229,13 +246,14 @@ namespace Contralto.Memory
else
{
_memoryOperationActive = true;
- _doubleWordStore = false;
- _doubleWordMixed = false;
+ _firstWordStored = false;
+ _firstWordRead = false;
_memoryAddress = address;
_extendedMemoryReference = extendedMemoryReference;
_task = task;
- _memoryCycle = 1;
- }
+ _memoryCycle = 1;
+ }
+
}
public ushort ReadMD()
@@ -264,15 +282,15 @@ namespace Contralto.Memory
case 3:
case 4:
// This should not happen; CPU should check whether the operation is possible using Ready and stall if not.
- throw new InvalidOperationException("Invalid ReadMR request during cycle 3 or 4 of memory operation.");
+ throw new InvalidOperationException("Invalid ReadMD request during cycle 3 or 4 of memory operation.");
case 5:
// Single word read
- return _memoryData;
+ return _memoryDataLow;
case 6:
// Double word read, return other half of double word.
- return _memoryData2;
+ return _memoryDataHigh;
default:
// Invalid state.
@@ -299,11 +317,16 @@ namespace Contralto.Memory
case 3:
case 4:
// This should not happen; CPU should check whether the operation is possible using Ready and stall if not.
- throw new InvalidOperationException("Invalid ReadMR request during cycle 3 or 4 of memory operation.");
+ throw new InvalidOperationException("Invalid ReadMD request during cycle 3 or 4 of memory operation.");
case 5:
- // Single word read
- return _memoryData;
+ // Single word read.
+ // If this is memory cycle 5 of a double-word *store* (started in cycle 3) then the second word can be *read* here.
+ // (An example of this is provided in the hardware ref, section 2, pg 8. and is done by the Ethernet microcode on
+ // the Alto II, see the code block starting at address 0224 -- EPLOC (600) is loaded with the interface status,
+ // EBLOC (601) is read and OR'd with NWW in the same memory op.)
+ _firstWordRead = true;
+ return _firstWordStored ? _memoryDataHigh : _memoryDataLow;
// ***
// NB: Handler for double-word read (cycle 6) is in the "else" clause below; this is kind of a hack.
@@ -315,21 +338,15 @@ namespace Contralto.Memory
}
}
else
- {
- // memory state machine not running, just return last latched contents.
+ {
+ //
+ // Memory state machine not running, just return last latched contents.
// ("Because the Alto II latches memory contents, it is possible to execute _MD anytime after
// cycle 5 of a reference and obtain the results of the read operation")
- // If this is memory cycle 6 we will return the last half of the doubleword to complete a double-word read.
- if (_memoryCycle == 6 || (_memoryCycle == 5 && _doubleWordMixed))
- {
- _doubleWordMixed = false;
- return _memoryData2;
- }
- else
- {
- _doubleWordMixed = false;
- return _memoryData;
- }
+ // We will return the last half of the doubleword to complete a double-word read.
+ // (If the first half hasn't yet been read, we return the first half instead...)
+ //
+ return _firstWordRead ? _memoryDataHigh : _memoryDataLow;
}
}
@@ -346,6 +363,17 @@ namespace Contralto.Memory
LoadMDAltoII(data);
}
}
+ else
+ {
+ //
+ // This is illegal behavior but we won't throw here;
+ // ST80 will cause this, for example, if you run it in a 1K CRAM configuration.
+ // Because it expects 3K CRAM, it jumps into the middle of ROM1 and weird things happen.
+ // We don't want to kill the emulator when this happens, but we will log the result.
+ //
+ Log.Write(LogType.Warning, LogComponent.Memory,
+ "Unexpected microcode behavior -- LoadMD while memory inactive (cycle {0}).", _memoryCycle);
+ }
}
private void LoadMDAltoI(ushort data)
@@ -356,25 +384,24 @@ namespace Contralto.Memory
case 2:
case 3:
case 4:
- // TODO: good microcode should never do this
+ // Good microcode should never do this
throw new InvalidOperationException("Unexpected microcode behavior -- LoadMD during incorrect memory cycle.");
case 5:
- _memoryData = data; // Only really necessary to show in debugger
- // Start of doubleword write:
+ _memoryDataWrite = data;
+ // Start of doubleword write:
WriteToBus(_memoryAddress, data, _task, _extendedMemoryReference);
- _doubleWordStore = true;
- _doubleWordMixed = true;
+ _firstWordStored = true;
break;
case 6:
- if (!_doubleWordStore)
+ if (!_firstWordStored)
{
throw new InvalidOperationException("Unexpected microcode behavior -- LoadMD on cycle 6, no LoadMD on cycle 5.");
}
- _memoryData = data; // Only really necessary to show in debugger
+ _memoryDataWrite = data;
ushort actualAddress = (ushort)(_memoryAddress | 1);
WriteToBus(actualAddress, data, _task, _extendedMemoryReference);
@@ -388,26 +415,36 @@ namespace Contralto.Memory
switch (_memoryCycle)
{
case 1:
- case 2:
- case 5:
- // TODO: good microcode should never do this
- throw new InvalidOperationException("Unexpected microcode behavior -- LoadMD during incorrect memory cycle.");
+ case 2:
+ // Good microcode should never do this
+ throw new InvalidOperationException(
+ String.Format("Unexpected microcode behavior -- LoadMD during incorrect memory cycle {0}.", _memoryCycle));
case 3:
-
- _memoryData = data; // Only really necessary to show in debugger
- // Start of doubleword write:
+ _memoryDataWrite = data;
+ // Start of doubleword write:
WriteToBus(_memoryAddress, data, _task, _extendedMemoryReference);
- _doubleWordStore = true;
- _doubleWordMixed = true;
+ _firstWordStored = true;
break;
case 4:
- _memoryData = data; // Only really necessary to show in debugger
- ushort actualAddress = _doubleWordStore ? (ushort)(_memoryAddress ^ 1) : _memoryAddress;
-
+ _memoryDataWrite = data;
+ ushort actualAddress = _firstWordStored ? (ushort)(_memoryAddress ^ 1) : _memoryAddress;
WriteToBus(actualAddress, data, _task, _extendedMemoryReference);
break;
+
+ case 5:
+ //
+ // This case is not documented in the HW ref. The ALU portion of MADTEST executes an instruction
+ // including an <-MD Bus Source (ANDed with Constant value) and an MD<- F2, which makes
+ // very little sense. Since the read can't be accomplished until cycle 5, the instruction
+ // is blocked until then. MADTEST doesn't seem to care what the result is, and I can't find
+ // any other code that uses microcode in this way.
+ // For now, this is a no-op.
+ //
+ Log.Write(LogType.Warning, LogComponent.Memory,
+ "Unexpected microcode behavior -- LoadMD during cycle 5.");
+ break;
}
}
@@ -490,13 +527,16 @@ namespace Contralto.Memory
private TaskType _task;
// Buffered read data (on cycles 3 and 4)
- private ushort _memoryData;
- private ushort _memoryData2;
+ private ushort _memoryDataLow;
+ private ushort _memoryDataHigh;
- // Indicates a double-word store (started on cycle 3)
- private bool _doubleWordStore;
+ // Write data (used for debugger UI only)
+ private ushort _memoryDataWrite;
- // Indicates a mixed double-word store/load (started in cycle 3)
- private bool _doubleWordMixed;
+ // Indicates that the first word of a double-word store has taken place (started on cycle 3)
+ private bool _firstWordStored;
+
+ // Indicates tghat the first word of a double-word read has taken place (started on cycle 5)
+ private bool _firstWordRead;
}
}
diff --git a/Contralto/Program.cs b/Contralto/Program.cs
index 784902f..fa34ce6 100644
--- a/Contralto/Program.cs
+++ b/Contralto/Program.cs
@@ -96,7 +96,7 @@ namespace Contralto
private static void PrintHerald()
{
- Console.WriteLine("ContrAlto v1.0 (c) 2015, 2016 Living Computer Museum.");
+ Console.WriteLine("ContrAlto v1.1 (c) 2015, 2016 Living Computer Museum.");
Console.WriteLine("Bug reports to joshd@livingcomputermuseum.org");
Console.WriteLine();
}
diff --git a/Contralto/Properties/AssemblyInfo.cs b/Contralto/Properties/AssemblyInfo.cs
index 0066d30..17b5f9d 100644
--- a/Contralto/Properties/AssemblyInfo.cs
+++ b/Contralto/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.1.*")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/Contralto/UI/AboutBox.Designer.cs b/Contralto/UI/AboutBox.Designer.cs
index 1b298d5..f57e88d 100644
--- a/Contralto/UI/AboutBox.Designer.cs
+++ b/Contralto/UI/AboutBox.Designer.cs
@@ -29,39 +29,40 @@
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox));
- this.label1 = new System.Windows.Forms.Label();
+ this.VersionLabel = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.OkButton = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
- this.linkLabel1 = new System.Windows.Forms.LinkLabel();
+ this.emailLink = new System.Windows.Forms.LinkLabel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
+ this.websiteLink = new System.Windows.Forms.LinkLabel();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
- // label1
+ // VersionLabel
//
- this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(88, 18);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(74, 13);
- this.label1.TabIndex = 0;
- this.label1.Text = "ContrAlto v1.0";
+ this.VersionLabel.Location = new System.Drawing.Point(12, 17);
+ this.VersionLabel.Name = "VersionLabel";
+ this.VersionLabel.Size = new System.Drawing.Size(224, 14);
+ this.VersionLabel.TabIndex = 0;
+ this.VersionLabel.Text = "ContrAlto v";
+ this.VersionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
this.label2.AutoSize = true;
- this.label2.Location = new System.Drawing.Point(41, 63);
+ this.label2.Location = new System.Drawing.Point(41, 59);
this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(168, 13);
+ this.label2.Size = new System.Drawing.Size(46, 13);
this.label2.TabIndex = 1;
- this.label2.Text = "(c) 2016 Living Computer Museum";
+ this.label2.Text = "(c) 2016";
this.label2.Click += new System.EventHandler(this.label2_Click);
//
// label3
//
this.label3.AutoSize = true;
- this.label3.Location = new System.Drawing.Point(69, 41);
+ this.label3.Location = new System.Drawing.Point(69, 38);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(109, 13);
this.label3.TabIndex = 2;
@@ -85,16 +86,16 @@
this.label4.TabIndex = 4;
this.label4.Text = "Bug reports, comments and miscellanea to";
//
- // linkLabel1
+ // emailLink
//
- this.linkLabel1.AutoSize = true;
- this.linkLabel1.Location = new System.Drawing.Point(41, 338);
- this.linkLabel1.Name = "linkLabel1";
- this.linkLabel1.Size = new System.Drawing.Size(168, 13);
- this.linkLabel1.TabIndex = 5;
- this.linkLabel1.TabStop = true;
- this.linkLabel1.Text = "joshd@livingcomputermuseum.org";
- this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
+ this.emailLink.AutoSize = true;
+ this.emailLink.Location = new System.Drawing.Point(41, 338);
+ this.emailLink.Name = "emailLink";
+ this.emailLink.Size = new System.Drawing.Size(168, 13);
+ this.emailLink.TabIndex = 5;
+ this.emailLink.TabStop = true;
+ this.emailLink.Text = "joshd@livingcomputermuseum.org";
+ this.emailLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
//
// pictureBox1
//
@@ -106,19 +107,31 @@
this.pictureBox1.TabIndex = 6;
this.pictureBox1.TabStop = false;
//
+ // websiteLink
+ //
+ this.websiteLink.AutoSize = true;
+ this.websiteLink.Location = new System.Drawing.Point(84, 60);
+ this.websiteLink.Name = "websiteLink";
+ this.websiteLink.Size = new System.Drawing.Size(126, 13);
+ this.websiteLink.TabIndex = 7;
+ this.websiteLink.TabStop = true;
+ this.websiteLink.Text = "Living Computer Museum";
+ this.websiteLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnSiteLinkClicked);
+ //
// AboutBox
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(248, 393);
this.ControlBox = false;
+ this.Controls.Add(this.websiteLink);
this.Controls.Add(this.pictureBox1);
- this.Controls.Add(this.linkLabel1);
+ this.Controls.Add(this.emailLink);
this.Controls.Add(this.label4);
this.Controls.Add(this.OkButton);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
- this.Controls.Add(this.label1);
+ this.Controls.Add(this.VersionLabel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
@@ -137,12 +150,13 @@
#endregion
- private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label VersionLabel;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button OkButton;
private System.Windows.Forms.Label label4;
- private System.Windows.Forms.LinkLabel linkLabel1;
+ private System.Windows.Forms.LinkLabel emailLink;
private System.Windows.Forms.PictureBox pictureBox1;
+ private System.Windows.Forms.LinkLabel websiteLink;
}
}
\ No newline at end of file
diff --git a/Contralto/UI/AboutBox.cs b/Contralto/UI/AboutBox.cs
index 1af79f1..e1587d9 100644
--- a/Contralto/UI/AboutBox.cs
+++ b/Contralto/UI/AboutBox.cs
@@ -16,6 +16,7 @@
*/
using System;
+using System.Reflection;
using System.Windows.Forms;
namespace Contralto
@@ -25,6 +26,8 @@ namespace Contralto
public AboutBox()
{
InitializeComponent();
+
+ VersionLabel.Text += typeof(Program).Assembly.GetName().Version;
}
private void OkButton_Click(object sender, EventArgs e)
@@ -41,5 +44,10 @@ namespace Contralto
{
System.Diagnostics.Process.Start("mailto:joshd@livingcomputermuseum.org");
}
+
+ private void OnSiteLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ System.Diagnostics.Process.Start("http://www.livingcomputermuseum.org");
+ }
}
}
diff --git a/Contralto/UI/Debugger.cs b/Contralto/UI/Debugger.cs
index 9f16aae..0d53c3b 100644
--- a/Contralto/UI/Debugger.cs
+++ b/Contralto/UI/Debugger.cs
@@ -125,12 +125,12 @@ namespace Contralto
_otherRegs.Rows[1].Cells[1].Value = Conversion.ToOctal(_system.CPU.T, 6);
_otherRegs.Rows[2].Cells[1].Value = Conversion.ToOctal(_system.CPU.M, 6);
_otherRegs.Rows[3].Cells[1].Value = Conversion.ToOctal(_system.CPU.IR, 6);
- _otherRegs.Rows[4].Cells[1].Value = Conversion.ToOctal(_system.CPU.ALUC0, 1);
- //_otherRegs.Rows[4].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.Carry, 1);
- //_otherRegs.Rows[4].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.Skip, 1);
+ _otherRegs.Rows[4].Cells[1].Value = Conversion.ToOctal(_system.CPU.ALUC0, 1);
_otherRegs.Rows[5].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.MAR, 6);
- _otherRegs.Rows[6].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.MD, 6);
- _otherRegs.Rows[7].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.Cycle & 0x3f, 2);
+ _otherRegs.Rows[6].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.MDLow, 6);
+ _otherRegs.Rows[7].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.MDHigh, 6);
+ _otherRegs.Rows[8].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.MDWrite, 6);
+ _otherRegs.Rows[9].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.Cycle & 0x3f, 2);
// Reserved memory locations
for (int i = 0; i < _reservedMemoryEntries.Length; i++)
@@ -247,11 +247,11 @@ namespace Contralto
_otherRegs.Rows.Add("T", "0");
_otherRegs.Rows.Add("M", "0");
_otherRegs.Rows.Add("IR", "0");
- _otherRegs.Rows.Add("ALUC0", "0");
- //_otherRegs.Rows.Add("CARRY", "0");
- //_otherRegs.Rows.Add("SKIP", "0");
+ _otherRegs.Rows.Add("ALUC0", "0");
_otherRegs.Rows.Add("MAR", "0");
- _otherRegs.Rows.Add("MD", "0");
+ _otherRegs.Rows.Add("←MDL", "0");
+ _otherRegs.Rows.Add("←MDH", "0");
+ _otherRegs.Rows.Add("MD←", "0");
_otherRegs.Rows.Add("MCycle", "0");
for (int i = 0; i < _reservedMemoryEntries.Length; i++)
diff --git a/Contralto/readme.txt b/Contralto/readme.txt
index 56625fb..4f19b0a 100644
--- a/Contralto/readme.txt
+++ b/Contralto/readme.txt
@@ -31,7 +31,7 @@ keyset input device.
================
ContrAlto will run on any Windows PC running Windows Vista or later, with version
-4.6 or later of the .NET Framework installed. .NET should be present by default
+4.5.3 or later of the .NET Framework installed. .NET should be present by default
on Windows Vista and later; if it is not installed on your computer it can be
obtained at https://www.microsoft.com/net.
@@ -475,3 +475,21 @@ Contributions are welcome!
ContrAlto would not have been possible without the amazing preservation work of
the Computer History Museum.
+
+10.0 Change History
+===================
+
+V1.1
+----
+- A few minor performance tweaks, adding to a 5% speed increase.
+- Switched back to targeting .NET 4.5.3 rather than 4.6; this works better under Mono
+ and avoids odd issues on Windows machines running pre-4.6 frameworks.
+- Microcode disassembly improved slightly, annotated microcode source updated.
+- Nova disassembler now handles BRI, DIR, EIR, DIRS instructions rather than treating
+ them all as TRAPs.
+- Fixed serious bugs in memory state machine, BravoX now runs.
+- Fixed minor bug in Constant ROM selection.
+
+V1.0
+----
+Initial release.
diff --git a/ContraltoSetup/Product.wxs b/ContraltoSetup/Product.wxs
index 0511177..55ca61b 100644
--- a/ContraltoSetup/Product.wxs
+++ b/ContraltoSetup/Product.wxs
@@ -17,10 +17,24 @@
-->
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+ SELFFOUND
+ NEWERFOUND
+