diff --git a/Contralto/AltoSystem.cs b/Contralto/AltoSystem.cs
index f210436..6fb8c9d 100644
--- a/Contralto/AltoSystem.cs
+++ b/Contralto/AltoSystem.cs
@@ -125,9 +125,9 @@ namespace Contralto
DiabloPack newPack = new DiabloPack(type);
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
- {
+ {
newPack.Load(fs, path, false);
- fs.Close();
+ fs.Close();
}
_diskController.Drives[drive].LoadPack(newPack);
diff --git a/Contralto/CPU/CPU.cs b/Contralto/CPU/CPU.cs
index bee96de..16d5e09 100644
--- a/Contralto/CPU/CPU.cs
+++ b/Contralto/CPU/CPU.cs
@@ -135,6 +135,7 @@ namespace Contralto.CPU
// If we have a new task, switch to it now.
_currentTask = _nextTask;
_nextTask = null;
+ _currentTask.OnTaskSwitch();
}
break;
@@ -164,7 +165,10 @@ namespace Contralto.CPU
}
Log.Write(LogComponent.CPU, "Silent Boot; microcode banks initialized to {0}", Conversion.ToOctal(_rmr));
- UCodeMemory.LoadBanksFromRMR(_rmr);
+ UCodeMemory.LoadBanksFromRMR(_rmr);
+
+ // Reset RMR after reset.
+ _rmr = 0x0;
// Start in Emulator
_currentTask = _tasks[0];
@@ -175,7 +179,7 @@ namespace Contralto.CPU
// itself as soon as the Emulator task yields after the reset. (CopyDisk is broken otherwise due to the
// sector task stomping over the KBLK CopyDisk sets up after the reset. This is a race of sorts.)
// Unsure if there is a deeper issue here or if there are other reset semantics
- // in play here.
+ // in play that are not understood.
//
WakeupTask(CPU.TaskType.DiskSector);
}
diff --git a/Contralto/CPU/ConstantMemory.cs b/Contralto/CPU/ConstantMemory.cs
index 1b0e836..706e451 100644
--- a/Contralto/CPU/ConstantMemory.cs
+++ b/Contralto/CPU/ConstantMemory.cs
@@ -3,42 +3,28 @@ using System.IO;
namespace Contralto.CPU
{
+ ///
+ /// Maintains a set of Control ROM images dumped from real Alto hardware.
+ ///
static class ControlROM
{
static ControlROM()
{
- Init();
-
- /*
- LoadConstants(_constantRomsAltoI);
-
- ushort[] temp = new ushort[256];
-
- _constantRom.CopyTo(temp, 0);
-
- LoadConstants(_constantRomsAltoII);
-
- for(int i=0;i<256;i++)
- {
- if (temp[i] != _constantRom[i])
- {
- Console.WriteLine("Diff at {0:x} - {1:x} vs {2:x}", i, temp[i], _constantRom[i]);
- }
- } */
-
+ Init();
}
private static void Init()
{
if (Configuration.SystemType == SystemType.AltoI)
{
- LoadConstants(_constantRomsAltoI);
+ LoadConstants(_constantRomsAltoI, true);
+ LoadACSource(_acSourceRoms, true);
}
else
{
- LoadConstants(_constantRomsAltoI);
- }
- LoadACSource(_acSourceRoms);
+ LoadConstants(_constantRomsAltoII, false);
+ LoadACSource(_acSourceRoms, true);
+ }
}
public static ushort[] ConstantROM
@@ -51,7 +37,7 @@ namespace Contralto.CPU
get { return _acSourceRom; }
}
- private static void LoadConstants(RomFile[] romInfo)
+ private static void LoadConstants(RomFile[] romInfo, bool flip)
{
_constantRom = new ushort[256];
@@ -60,7 +46,7 @@ namespace Contralto.CPU
//
// Each file contains 256 bytes, each byte containing one nybble in the low 4 bits.
//
- using (FileStream fs = new FileStream(Path.Combine("ROM", file.Filename), FileMode.Open, FileAccess.Read))
+ using (FileStream fs = new FileStream(file.Filename, FileMode.Open, FileAccess.Read))
{
int length = (int)fs.Length;
if (length != 256)
@@ -74,7 +60,14 @@ namespace Contralto.CPU
// OR in the data
for (int i = 0; i < length; i++)
{
- _constantRom[file.StartingAddress + i] |= (ushort)((DataMapConstantRom(data[AddressMapConstantRom(i)]) & 0xf) << file.BitPosition);
+ if (flip)
+ {
+ _constantRom[file.StartingAddress + i] |= (ushort)((DataMapConstantRom(~data[AddressMapConstantRom(i)]) & 0xf) << file.BitPosition);
+ }
+ else
+ {
+ _constantRom[file.StartingAddress + i] |= (ushort)((DataMapConstantRom(data[AddressMapConstantRom(i)]) & 0xf) << file.BitPosition);
+ }
}
}
}
@@ -86,11 +79,11 @@ namespace Contralto.CPU
}
}
- private static void LoadACSource(RomFile romInfo)
+ private static void LoadACSource(RomFile romInfo, bool reverseBits)
{
_acSourceRom = new byte[256];
- using (FileStream fs = new FileStream(Path.Combine("ROM", romInfo.Filename), FileMode.Open, FileAccess.Read))
+ using (FileStream fs = new FileStream(romInfo.Filename, FileMode.Open, FileAccess.Read))
{
int length = (int)fs.Length;
if (length != 256)
@@ -103,7 +96,14 @@ namespace Contralto.CPU
// Copy in the data, modifying the address as required.
for (int i = 0; i < length; i++)
{
- _acSourceRom[i] = (byte)((~data[AddressMapACSourceRom(i)]) & 0xf);
+ if (reverseBits)
+ {
+ _acSourceRom[i] = (byte)((~DataMapConstantRom(data[AddressMapACSourceRom(i)])) & 0xf);
+ }
+ else
+ {
+ _acSourceRom[i] = (byte)((~data[AddressMapACSourceRom(i)]) & 0xf);
+ }
}
}
}
@@ -158,24 +158,24 @@ namespace Contralto.CPU
// And invert data lines
return (~mappedData) & 0xff;
}
-
- private static RomFile[] _constantRomsAltoII =
- {
- new RomFile("c0", 0x000, 12),
- new RomFile("c1", 0x000, 8),
- new RomFile("c2", 0x000, 4),
- new RomFile("c3", 0x000, 0),
- };
-
+
private static RomFile[] _constantRomsAltoI =
{
- new RomFile("c0.2", 0x000, 12),
- new RomFile("c1.2", 0x000, 8),
- new RomFile("c2.2", 0x000, 4),
- new RomFile("c3.2", 0x000, 0),
+ new RomFile(Configuration.GetAltoIRomPath("c0_23.BIN"), 0x000, 12),
+ new RomFile(Configuration.GetAltoIRomPath("c1_23.BIN"), 0x000, 8),
+ new RomFile(Configuration.GetAltoIRomPath("c2_23.BIN"), 0x000, 4),
+ new RomFile(Configuration.GetAltoIRomPath("c3_23.BIN"), 0x000, 0),
};
- private static RomFile _acSourceRoms = new RomFile("2kctl.u3", 0x000, 0);
+ private static RomFile[] _constantRomsAltoII =
+ {
+ new RomFile(Configuration.GetAltoIIRomPath("c0"), 0x000, 12),
+ new RomFile(Configuration.GetAltoIIRomPath("c1"), 0x000, 8),
+ new RomFile(Configuration.GetAltoIIRomPath("c2"), 0x000, 4),
+ new RomFile(Configuration.GetAltoIIRomPath("c3"), 0x000, 0),
+ };
+
+ private static RomFile _acSourceRoms = new RomFile(Configuration.GetRomPath("ACSOURCE.NEW"), 0x000, 0);
private static ushort[] _constantRom;
private static byte[] _acSourceRom;
diff --git a/Contralto/CPU/MicroInstruction.cs b/Contralto/CPU/MicroInstruction.cs
index beccf3f..c94b76f 100644
--- a/Contralto/CPU/MicroInstruction.cs
+++ b/Contralto/CPU/MicroInstruction.cs
@@ -177,6 +177,11 @@ namespace Contralto.CPU
EISFCT = 14,
}
+ ///
+ /// MicroInstruction encapsulates the decoding of a microinstruction word.
+ /// It also caches precomputed metadata related to the microinstruction that
+ /// help speed microcode execution.
+ ///
public class MicroInstruction
{
public MicroInstruction(UInt32 code)
@@ -228,14 +233,14 @@ namespace Contralto.CPU
// What kind of memory access this instruction performs, if any.
if (MemoryAccess)
{
- if (BS == BusSource.ReadMD)
- {
- MemoryOperation = MemoryOperation.Read;
- }
- else if (F1 == SpecialFunction1.LoadMAR)
+ if (F1 == SpecialFunction1.LoadMAR)
{
MemoryOperation = MemoryOperation.LoadAddress;
}
+ else if (BS == BusSource.ReadMD)
+ {
+ MemoryOperation = MemoryOperation.Read;
+ }
else
{
MemoryOperation = MemoryOperation.Store;
diff --git a/Contralto/CPU/Tasks/CursorTask.cs b/Contralto/CPU/Tasks/CursorTask.cs
index 4d73647..9e0bc01 100644
--- a/Contralto/CPU/Tasks/CursorTask.cs
+++ b/Contralto/CPU/Tasks/CursorTask.cs
@@ -5,7 +5,7 @@ namespace Contralto.CPU
public partial class AltoCPU
{
///
- /// CursorTask provides functionality for the Cursor-specific task functions
+ /// CursorTask provides the implementation of Cursor-specific task functions
///
private sealed class CursorTask : Task
{
@@ -15,12 +15,10 @@ namespace Contralto.CPU
_wakeup = false;
}
- protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
+ public override void OnTaskSwitch()
{
- // We put ourselves back to sleep immediately once we've started running
- _wakeup = false;
-
- return base.ExecuteInstruction(instruction);
+ // We put ourselves back to sleep immediately once we've started running.
+ _wakeup = false;
}
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
diff --git a/Contralto/CPU/Tasks/DiskTask.cs b/Contralto/CPU/Tasks/DiskTask.cs
index d5c4f53..0f000df 100644
--- a/Contralto/CPU/Tasks/DiskTask.cs
+++ b/Contralto/CPU/Tasks/DiskTask.cs
@@ -7,9 +7,9 @@ namespace Contralto.CPU
public partial class AltoCPU
{
///
- /// DiskTask provides implementation for disk-specific special functions
+ /// DiskTask provides implementations of disk-specific special functions
/// (for both Disk Sector and Disk Word tasks, since the special functions are
- /// identical between the two)
+ /// identical between the two).
///
private sealed class DiskTask : Task
{
@@ -19,12 +19,10 @@ namespace Contralto.CPU
_wakeup = false;
_diskController = _cpu._system.DiskController;
- }
-
- protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
- {
- InstructionCompletion completion = base.ExecuteInstruction(instruction);
+ }
+ public override void OnTaskSwitch()
+ {
// Deal with SECLATE semantics: If the Disk Sector task wakes up and runs before
// the Disk Controller hits the SECLATE trigger time, then SECLATE remains false.
// Otherwise, when the trigger time is hit SECLATE is raised until
@@ -32,10 +30,8 @@ namespace Contralto.CPU
if (_taskType == TaskType.DiskSector)
{
// Sector task is running; clear enable for seclate signal
- _diskController.DisableSeclate();
- }
-
- return completion;
+ _diskController.DisableSeclate();
+ }
}
protected override ushort GetBusSource(int bs)
diff --git a/Contralto/CPU/Tasks/DisplayHorizontalTask.cs b/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
index 4a7d16e..0501254 100644
--- a/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
+++ b/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
@@ -6,7 +6,7 @@ namespace Contralto.CPU
public partial class AltoCPU
{
///
- /// DisplayWordTask provides functionality for the DHT task
+ /// DisplayHorizontalTask provides implementations of the DHT task functions.
///
private sealed class DisplayHorizontalTask : Task
{
@@ -18,12 +18,10 @@ namespace Contralto.CPU
_displayController = _cpu._system.DisplayController;
}
- protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
+ public override void OnTaskSwitch()
{
- // We put ourselves back to sleep immediately once we've started running
+ // We put ourselves back to sleep immediately once we've started running.
_wakeup = false;
-
- return base.ExecuteInstruction(instruction);
}
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
diff --git a/Contralto/CPU/Tasks/DisplayVerticalTask.cs b/Contralto/CPU/Tasks/DisplayVerticalTask.cs
index 8228f4e..117886a 100644
--- a/Contralto/CPU/Tasks/DisplayVerticalTask.cs
+++ b/Contralto/CPU/Tasks/DisplayVerticalTask.cs
@@ -18,15 +18,10 @@ namespace Contralto.CPU
_displayController = _cpu._system.DisplayController;
}
- protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
+ public override void OnTaskSwitch()
{
- // We put ourselves back to sleep immediately once we've started running
- // TODO: for this and other similar patterns: rework this so we don't need to
- // override ExecuteInstruction just to do this (or similar polling). Virtual calls
- // are expensive, especially when millions of them are being made a second.
+ // We put ourselves back to sleep immediately once we've started running.
_wakeup = false;
-
- return base.ExecuteInstruction(instruction);
}
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
diff --git a/Contralto/CPU/Tasks/EmulatorTask.cs b/Contralto/CPU/Tasks/EmulatorTask.cs
index 727d39d..bd17898 100644
--- a/Contralto/CPU/Tasks/EmulatorTask.cs
+++ b/Contralto/CPU/Tasks/EmulatorTask.cs
@@ -22,8 +22,6 @@ namespace Contralto.CPU
{
base.Reset();
_wakeup = true;
-
- _systemType = Configuration.SystemType;
}
public override void BlockTask()
@@ -126,7 +124,7 @@ namespace Contralto.CPU
// Dispatch to the appropriate device.
// The Ethernet controller is the only common device that is documented
// to have used STARTF, so we'll just go there directly; if other
- // hardware is discovered to be worth emulating we'll put together a more flexible dispatch.
+ // hardware is determined to be worth emulating we'll put together a more flexible dispatch.
//
if (_busData < 4)
{
@@ -226,49 +224,18 @@ namespace Contralto.CPU
// elseif IR[4-7] = 16B 6
// else IR[4-7]
// NB: as always, Xerox labels bits in the opposite order from modern convention;
- // (bit 0 is the msb...)
- /*
- if (Configuration.SystemType == SystemType.AltoI && UCodeMemory.GetBank(TaskType.Emulator) == MicrocodeBank.RAM0)
+ // (bit 0 is the msb...)
+ //
+ // NOTE: The above table is accurate and functions correctly; using the PROM is faster.
+ //
+ if ((_cpu._ir & 0x8000) != 0)
{
- if ((_cpu._ir & 0x8000) != 0)
- {1
- _nextModifier = (ushort)(3 - ((_cpu._ir & 0xc0) >> 6));
- }
- else if ((_cpu._ir & 0x6000) == 0x0000)
- {
- _nextModifier = (ushort)((_cpu._ir & 0x3000) >> 12);
- }
- else if ((_cpu._ir & 0x6000) == 0x2000)
- {
- _nextModifier = 4;
- }
- else if ((_cpu._ir & 0x6000) == 0x4000)
- {
- _nextModifier = 5;
- }
- else if ((_cpu._ir & 0x6000) == 0x6000)
- {
- if ((_cpu._ir & 0x1f00) == 0x0e00)
- {
- _nextModifier = 6;
- }
- else
- {
- _nextModifier = 1;
- }
- }
+ _nextModifier = (ushort)(3 - ((_cpu._ir & 0xc0) >> 6));
}
- else */
+ else
{
- if ((_cpu._ir & 0x8000) != 0)
- {
- _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;
case EmulatorF2.ACSOURCE:
@@ -290,7 +257,8 @@ namespace Contralto.CPU
// else 16B ROMTRAP
//
- // NOTE: the above table from the Hardware Manual is incorrect (or at least incomplete / misleading).
+ // NOTE: the above table from the Hardware Manual is incorrect
+ // (or at least incomplete / out of date / misleading).
// There is considerably more that goes into determining the dispatch, which is controlled by a 256x8
// PROM. We just use the PROM rather than implementing the above logic (because it works.)
//
@@ -462,9 +430,7 @@ namespace Contralto.CPU
// BUS+SKIP(ALUF= 13B). IR<- clears SKIP."
//
// NB: _skip is in the encapsulating AltoCPU class to make it easier to reference since the ALU needs to know about it.
- private int _carry;
-
- private SystemType _systemType;
+ private int _carry;
}
}
}
diff --git a/Contralto/CPU/Tasks/MemoryRefreshTask.cs b/Contralto/CPU/Tasks/MemoryRefreshTask.cs
index 0b73a6a..f485be2 100644
--- a/Contralto/CPU/Tasks/MemoryRefreshTask.cs
+++ b/Contralto/CPU/Tasks/MemoryRefreshTask.cs
@@ -23,7 +23,7 @@
//
// "; This version assumes MRTACT is cleared by BLOCK, not MAR<- R37"
//
- if (Configuration.SystemType == SystemType.AltoI &&
+ if (_systemType == SystemType.AltoI &&
instruction.F1 == SpecialFunction1.LoadMAR &&
_rSelect == 31)
{
diff --git a/Contralto/CPU/Tasks/Task.cs b/Contralto/CPU/Tasks/Task.cs
index 3e5abb4..884d3e4 100644
--- a/Contralto/CPU/Tasks/Task.cs
+++ b/Contralto/CPU/Tasks/Task.cs
@@ -26,7 +26,9 @@ namespace Contralto.CPU
_wakeup = false;
_mpc = 0xffff; // invalid, for sanity checking
_taskType = TaskType.Invalid;
- _cpu = cpu;
+ _cpu = cpu;
+
+ _systemType = Configuration.SystemType;
}
public int Priority
@@ -84,16 +86,26 @@ namespace Contralto.CPU
_mpc = (ushort)_taskType;
}
+ ///
+ /// Removes the Wakeup signal for this task.
+ ///
public virtual void BlockTask()
{
_wakeup = false;
}
+ ///
+ /// Sets the Wakeup signal for this task.
+ ///
public virtual void WakeupTask()
{
_wakeup = true;
}
+ ///
+ /// Executes a single microinstruction.
+ ///
+ /// An InstructionCompletion indicating whether this instruction calls for a task switch or not.
public InstructionCompletion ExecuteNext()
{
MicroInstruction instruction = UCodeMemory.GetInstruction(_mpc, _taskType);
@@ -102,10 +114,10 @@ namespace Contralto.CPU
///
/// ExecuteInstruction causes the Task to execute the next instruction (the one
- /// _mpc is pointing to). The base implementation covers non-task specific logic; subclasses may
- /// provide their own overrides.
+ /// _mpc is pointing to). The base implementation covers non-task specific logic,
+ /// subclasses (specific task implementations) may provide their own implementations.
///
- /// True if a task switch has been requested by a TASK instruction, false otherwise.
+ /// An InstructionCompletion indicating whether this instruction calls for a task switch or not.
protected virtual InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
InstructionCompletion completion = InstructionCompletion.Normal;
@@ -281,7 +293,7 @@ namespace Contralto.CPU
_cpu._system.MemoryBus.LoadMAR(
aluData,
_taskType,
- Configuration.SystemType == SystemType.AltoI ? false : instruction.F2 == SpecialFunction2.StoreMD);
+ _systemType == SystemType.AltoI ? false : instruction.F2 == SpecialFunction2.StoreMD);
break;
case SpecialFunction1.Task:
@@ -364,9 +376,13 @@ namespace Contralto.CPU
break;
case SpecialFunction2.StoreMD:
- // Special case for XMAR; if F1 is a LoadMAR we do nothing here;
+ // Special case for XMAR on non-Alto I machines: if F1 is a LoadMAR we do nothing here;
// the handler for LoadMAR will load the correct bank.
- if (instruction.F1 != SpecialFunction1.LoadMAR)
+ if (_systemType == SystemType.AltoI)
+ {
+ _cpu._system.MemoryBus.LoadMD(_busData);
+ }
+ else if(instruction.F1 != SpecialFunction1.LoadMAR)
{
_cpu._system.MemoryBus.LoadMD(_busData);
}
@@ -510,24 +526,39 @@ namespace Contralto.CPU
return completion;
}
+ ///
+ /// Provides task-specific implementations the opportunity to handle task-specific bus sources.
+ ///
+ ///
+ ///
protected virtual ushort GetBusSource(int bs)
{
// Nothing by default.
return 0;
}
+ ///
+ /// Executes before the ALU runs but after bus sources have been selected.
+ ///
+ ///
protected virtual void ExecuteSpecialFunction1Early(MicroInstruction instruction)
{
// Nothing by default
}
+ ///
+ /// Executes after the ALU has run but before the shifter runs, provides task-specific implementations
+ /// the opportunity to handle task-specific F1s.
+ ///
+ ///
protected virtual void ExecuteSpecialFunction1(MicroInstruction instruction)
{
// Nothing by default
}
///
- /// Used to allow Task-specific F2s that need to modify RSELECT to do so.
+ /// Executes before bus sources are selected. Used to allow Task-specific F2s that need to
+ /// modify RSELECT to do so.
///
///
protected virtual void ExecuteSpecialFunction2Early(MicroInstruction instruction)
@@ -535,11 +566,20 @@ namespace Contralto.CPU
// Nothing by default.
}
+ ///
+ /// Executes after the ALU has run but before the shifter runs, provides task-specific implementations
+ /// the opportunity to handle task-specific F2s.
+ ///
protected virtual void ExecuteSpecialFunction2(MicroInstruction instruction)
{
// Nothing by default.
}
+ ///
+ /// Executes after the shifter has run, provides task-specific implementations the opportunity
+ /// to handle task-specific F2s late in the cycle.
+ ///
+ ///
protected virtual void ExecuteSpecialFunction2Late(MicroInstruction instruction)
{
// Nothing by default.
@@ -554,6 +594,20 @@ namespace Contralto.CPU
// Nothing by default
}
+ ///
+ /// Allows task-specific behavior when a new task begins execution.
+ /// (Generally this is used to remove wakeup immediately.)
+ ///
+ public virtual void OnTaskSwitch()
+ {
+ // Nothing by default
+ }
+
+ ///
+ /// Cache the system type.
+ ///
+ protected SystemType _systemType;
+
//
// Per uInstruction Task Data:
// Modified by both the base Task implementation and any subclasses
diff --git a/Contralto/CPU/UCodeDisassembler.cs b/Contralto/CPU/UCodeDisassembler.cs
index 1a77fa9..a78083f 100644
--- a/Contralto/CPU/UCodeDisassembler.cs
+++ b/Contralto/CPU/UCodeDisassembler.cs
@@ -3,6 +3,9 @@ using System.Text;
namespace Contralto.CPU
{
+ ///
+ /// Provides a facility for doing a (crude) disassembly of microcode.
+ ///
public static class UCodeDisassembler
{
diff --git a/Contralto/CPU/UCodeMemory.cs b/Contralto/CPU/UCodeMemory.cs
index 5c9193f..d8cedac 100644
--- a/Contralto/CPU/UCodeMemory.cs
+++ b/Contralto/CPU/UCodeMemory.cs
@@ -27,6 +27,10 @@ namespace Contralto.CPU
public int BitPosition;
}
+ ///
+ /// UCodeMemory maintains a set of Microcode ROM images and provides facilities
+ /// for accessing them.
+ ///
static class UCodeMemory
{
static UCodeMemory()
@@ -278,7 +282,7 @@ namespace Contralto.CPU
//
// Each file contains 1024 bytes, each byte containing one nybble in the low 4 bits.
//
- using(FileStream fs = new FileStream(Path.Combine("ROM", file.Filename), FileMode.Open, FileAccess.Read))
+ using(FileStream fs = new FileStream(file.Filename, FileMode.Open, FileAccess.Read))
{
int length = (int)fs.Length;
if (length != 1024)
@@ -312,7 +316,7 @@ namespace Contralto.CPU
//
// Each file contains 256 bytes, each byte containing one nybble in the low 4 bits.
//
- using (FileStream fs = new FileStream(Path.Combine("ROM", file.Filename), FileMode.Open, FileAccess.Read))
+ using (FileStream fs = new FileStream(file.Filename, FileMode.Open, FileAccess.Read))
{
int length = (int)fs.Length;
if (length != 256)
@@ -384,73 +388,74 @@ namespace Contralto.CPU
{
UInt32 instructionWord = _uCodeRam[address];
_decodeCache[2048 + address] = new MicroInstruction(instructionWord);
- }
-
- private static RomFile[] _uCodeRomsAltoII =
- {
- // first K
- new RomFile("u55", 0x000, 28),
- new RomFile("u64", 0x000, 24),
- new RomFile("u65", 0x000, 20),
- new RomFile("u63", 0x000, 16),
- new RomFile("u53", 0x000, 12),
- new RomFile("u60", 0x000, 8),
- new RomFile("u61", 0x000, 4),
- new RomFile("u62", 0x000, 0),
-
- // second K
- new RomFile("u54", 0x400, 28),
- new RomFile("u74", 0x400, 24),
- new RomFile("u75", 0x400, 20),
- new RomFile("u73", 0x400, 16),
- new RomFile("u52", 0x400, 12),
- new RomFile("u70", 0x400, 8),
- new RomFile("u71", 0x400, 4),
- new RomFile("u72", 0x400, 0)
- };
+ }
private static RomFile[] _uCodeRomsAltoI =
{
// 0 to 377
- new RomFile("0.2", 0x000, 28),
- new RomFile("1.2", 0x000, 24),
- new RomFile("2.2", 0x000, 20),
- new RomFile("3.2", 0x000, 16),
- new RomFile("4.2", 0x000, 12),
- new RomFile("5.2", 0x000, 8),
- new RomFile("6.2", 0x000, 4),
- new RomFile("7.2", 0x000, 0),
+ new RomFile(Configuration.GetAltoIRomPath("00_23.BIN"), 0x000, 28),
+ new RomFile(Configuration.GetAltoIRomPath("01_23.BIN"), 0x000, 24),
+ new RomFile(Configuration.GetAltoIRomPath("02_23.BIN"), 0x000, 20),
+ new RomFile(Configuration.GetAltoIRomPath("03_23.BIN"), 0x000, 16),
+ new RomFile(Configuration.GetAltoIRomPath("04_23.BIN"), 0x000, 12),
+ new RomFile(Configuration.GetAltoIRomPath("05_23.BIN"), 0x000, 8),
+ new RomFile(Configuration.GetAltoIRomPath("06_23.BIN"), 0x000, 4),
+ new RomFile(Configuration.GetAltoIRomPath("07_23.BIN"), 0x000, 0),
// 400 to 777
- new RomFile("10.2", 0x100, 28),
- new RomFile("11.2", 0x100, 24),
- new RomFile("12.2", 0x100, 20),
- new RomFile("13.2", 0x100, 16),
- new RomFile("14.2", 0x100, 12),
- new RomFile("15.2", 0x100, 8),
- new RomFile("16.2", 0x100, 4),
- new RomFile("17.2", 0x100, 0),
+ new RomFile(Configuration.GetAltoIRomPath("10_23.BIN"), 0x100, 28),
+ new RomFile(Configuration.GetAltoIRomPath("11_23.BIN"), 0x100, 24),
+ new RomFile(Configuration.GetAltoIRomPath("12_23.BIN"), 0x100, 20),
+ new RomFile(Configuration.GetAltoIRomPath("13_23.BIN"), 0x100, 16),
+ new RomFile(Configuration.GetAltoIRomPath("14_23.BIN"), 0x100, 12),
+ new RomFile(Configuration.GetAltoIRomPath("15_23.BIN"), 0x100, 8),
+ new RomFile(Configuration.GetAltoIRomPath("16_23.BIN"), 0x100, 4),
+ new RomFile(Configuration.GetAltoIRomPath("17_23.BIN"), 0x100, 0),
// 1000 to 1377
- new RomFile("20.2", 0x200, 28),
- new RomFile("21.2", 0x200, 24),
- new RomFile("22.2", 0x200, 20),
- new RomFile("23.2", 0x200, 16),
- new RomFile("24.2", 0x200, 12),
- new RomFile("25.2", 0x200, 8),
- new RomFile("26.2", 0x200, 4),
- new RomFile("27.2", 0x200, 0),
+ new RomFile(Configuration.GetAltoIRomPath("20_23.BIN"), 0x200, 28),
+ new RomFile(Configuration.GetAltoIRomPath("21_23.BIN"), 0x200, 24),
+ new RomFile(Configuration.GetAltoIRomPath("22_23.BIN"), 0x200, 20),
+ new RomFile(Configuration.GetAltoIRomPath("23_23.BIN"), 0x200, 16),
+ new RomFile(Configuration.GetAltoIRomPath("24_23.BIN"), 0x200, 12),
+ new RomFile(Configuration.GetAltoIRomPath("25_23.BIN"), 0x200, 8),
+ new RomFile(Configuration.GetAltoIRomPath("26_23.BIN"), 0x200, 4),
+ new RomFile(Configuration.GetAltoIRomPath("27_23.BIN"), 0x200, 0),
// 1400 to 1777
- new RomFile("30.2", 0x300, 28),
- new RomFile("31.2", 0x300, 24),
- new RomFile("32.2", 0x300, 20),
- new RomFile("33.2", 0x300, 16),
- new RomFile("34.2", 0x300, 12),
- new RomFile("35.2", 0x300, 8),
- new RomFile("36.2", 0x300, 4),
- new RomFile("37.2", 0x300, 0),
- };
+ new RomFile(Configuration.GetAltoIRomPath("30_23.BIN"), 0x300, 28),
+ new RomFile(Configuration.GetAltoIRomPath("31_23.BIN"), 0x300, 24),
+ new RomFile(Configuration.GetAltoIRomPath("32_23.BIN"), 0x300, 20),
+ new RomFile(Configuration.GetAltoIRomPath("33_23.BIN"), 0x300, 16),
+ new RomFile(Configuration.GetAltoIRomPath("34_23.BIN"), 0x300, 12),
+ new RomFile(Configuration.GetAltoIRomPath("35_23.BIN"), 0x300, 8),
+ new RomFile(Configuration.GetAltoIRomPath("36_23.BIN"), 0x300, 4),
+ new RomFile(Configuration.GetAltoIRomPath("37_23.BIN"), 0x300, 0),
+ };
+
+ private static RomFile[] _uCodeRomsAltoII =
+ {
+ // first K (standard uCode)
+ new RomFile(Configuration.GetAltoIIRomPath("u55"), 0x000, 28),
+ new RomFile(Configuration.GetAltoIIRomPath("u64"), 0x000, 24),
+ new RomFile(Configuration.GetAltoIIRomPath("u65"), 0x000, 20),
+ new RomFile(Configuration.GetAltoIIRomPath("u63"), 0x000, 16),
+ new RomFile(Configuration.GetAltoIIRomPath("u53"), 0x000, 12),
+ new RomFile(Configuration.GetAltoIIRomPath("u60"), 0x000, 8),
+ new RomFile(Configuration.GetAltoIIRomPath("u61"), 0x000, 4),
+ new RomFile(Configuration.GetAltoIIRomPath("u62"), 0x000, 0),
+
+ // second K (MESA 5.0)
+ new RomFile(Configuration.GetAltoIIRomPath("u54"), 0x400, 28),
+ new RomFile(Configuration.GetAltoIIRomPath("u74"), 0x400, 24),
+ new RomFile(Configuration.GetAltoIIRomPath("u75"), 0x400, 20),
+ new RomFile(Configuration.GetAltoIIRomPath("u73"), 0x400, 16),
+ new RomFile(Configuration.GetAltoIIRomPath("u52"), 0x400, 12),
+ new RomFile(Configuration.GetAltoIIRomPath("u70"), 0x400, 8),
+ new RomFile(Configuration.GetAltoIIRomPath("u71"), 0x400, 4),
+ new RomFile(Configuration.GetAltoIIRomPath("u72"), 0x400, 0)
+ };
+
private static UInt32[] _uCodeRom;
private static UInt32[] _uCodeRam;
diff --git a/Contralto/Configuration.cs b/Contralto/Configuration.cs
index 4319a41..ef4a3e2 100644
--- a/Contralto/Configuration.cs
+++ b/Contralto/Configuration.cs
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace Contralto
{
///
- /// The configuration of an Alto II to emulate
+ /// The configuration of the Alto to emulate
///
public enum SystemType
{
@@ -166,6 +166,21 @@ namespace Contralto
///
public static bool ThrottleSpeed;
+ public static string GetAltoIRomPath(string romFileName)
+ {
+ return Path.Combine("ROM", "AltoI", romFileName);
+ }
+
+ public static string GetAltoIIRomPath(string romFileName)
+ {
+ return Path.Combine("ROM", "AltoII", romFileName);
+ }
+
+ public static string GetRomPath(string romFileName)
+ {
+ return Path.Combine("ROM", romFileName);
+ }
+
///
/// Reads the current configuration file from disk.
///
diff --git a/Contralto/Contralto.csproj b/Contralto/Contralto.csproj
index fabe0da..c8398df 100644
--- a/Contralto/Contralto.csproj
+++ b/Contralto/Contralto.csproj
@@ -258,223 +258,178 @@
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
+
PreserveNewest
diff --git a/Contralto/Display/DisplayController.cs b/Contralto/Display/DisplayController.cs
index cfd56c4..988486f 100644
--- a/Contralto/Display/DisplayController.cs
+++ b/Contralto/Display/DisplayController.cs
@@ -91,6 +91,9 @@ namespace Contralto.Display
_system.Scheduler.Schedule(_verticalBlankScanlineWakeup);
}
+ ///
+ /// Begins the next display field.
+ ///
private void FieldStart()
{
// Start of Vertical Blanking (end of last field). This lasts for 34 scanline times or so.
@@ -117,6 +120,12 @@ namespace Contralto.Display
_system.Scheduler.Schedule(_verticalBlankScanlineWakeup);
}
+ ///
+ /// Callback for each scanline during vblank.
+ ///
+ ///
+ ///
+ ///
private void VerticalBlankScanlineCallback(ulong timeNsec, ulong skewNsec, object context)
{
// End of VBlank scanline.
@@ -157,6 +166,12 @@ namespace Contralto.Display
}
}
+ ///
+ /// Callback for the end of each horizontal blank period.
+ ///
+ ///
+ ///
+ ///
private void HorizontalBlankEndCallback(ulong timeNsec, ulong skewNsec, object context)
{
// Reset scanline word counter
@@ -182,6 +197,12 @@ namespace Contralto.Display
_system.Scheduler.Schedule(_wordWakeup);
}
+ ///
+ /// Callback for each word of visible display lines.
+ ///
+ ///
+ ///
+ ///
private void WordCallback(ulong timeNsec, ulong skewNsec, object context)
{
if (_display == null)
@@ -268,6 +289,10 @@ namespace Contralto.Display
}
}
+ ///
+ /// Check to see if a Display Word task wakeup should be generated based on the current
+ /// state of the FIFO and task wakeup bits.
+ ///
private void CheckWordWakeup()
{
if (FIFOFULL ||
@@ -290,6 +315,10 @@ namespace Contralto.Display
}
}
+ ///
+ /// Enqueues a display word on the display controller's FIFO.
+ ///
+ ///
public void LoadDDR(ushort word)
{
_dataBuffer.Enqueue(word);
@@ -303,6 +332,10 @@ namespace Contralto.Display
CheckWordWakeup();
}
+ ///
+ /// Loads the X position register for the cursor
+ ///
+ ///
public void LoadXPREG(ushort word)
{
if (!_cursorXLatch)
@@ -312,6 +345,10 @@ namespace Contralto.Display
}
}
+ ///
+ /// Loads the cursor register
+ ///
+ ///
public void LoadCSR(ushort word)
{
if (!_cursorRegLatch)
@@ -321,6 +358,10 @@ namespace Contralto.Display
}
}
+ ///
+ /// Sets the mode (low res and white on black bits)
+ ///
+ ///
public void SETMODE(ushort word)
{
// These take effect at the beginning of the next scanline.
@@ -358,7 +399,7 @@ namespace Contralto.Display
private ushort _cursorX;
private ushort _cursorXLatched;
- // Indicates whether the DWT or DHT blocked itself
+ // Indicates whether the DWT or DHT blocked themselves
// in which case they cannot be reawakened until the next field.
private bool _dwtBlocked;
private bool _dhtBlocked;
diff --git a/Contralto/Display/IAltoDisplay.cs b/Contralto/Display/IAltoDisplay.cs
index eb389b3..e3e3f0f 100644
--- a/Contralto/Display/IAltoDisplay.cs
+++ b/Contralto/Display/IAltoDisplay.cs
@@ -6,6 +6,10 @@ using System.Threading.Tasks;
namespace Contralto.Display
{
+ ///
+ /// IAltoDisplay defines the interface necessary for generating and rendering the Alto's
+ /// bitmapped display.
+ ///
public interface IAltoDisplay
{
///
@@ -18,7 +22,7 @@ namespace Contralto.Display
void DrawDisplayWord(int scanline, int wordOffset, ushort dataWord, bool lowRes);
///
- /// Renders the cursor word for the specified scanline
+ /// Renders the cursor word for the specified scanline.
///
///
///
@@ -27,7 +31,7 @@ namespace Contralto.Display
void DrawCursorWord(int scanline, int xOffset, bool whiteOnBlack, ushort cursorWord);
///
- /// Causes the display to be rendered
+ /// Indicates that an entire frame is ready for display and should be rendered.
///
void Render();
}
diff --git a/Contralto/IO/DiabloDrive.cs b/Contralto/IO/DiabloDrive.cs
index 13eda50..755443e 100644
--- a/Contralto/IO/DiabloDrive.cs
+++ b/Contralto/IO/DiabloDrive.cs
@@ -9,7 +9,9 @@ using System.Threading.Tasks;
namespace Contralto.IO
{
- // The data for the current sector
+ ///
+ /// Defines the "type" of data in the current sector timeslice.
+ ///
public enum CellType
{
Data,
@@ -17,6 +19,11 @@ namespace Contralto.IO
Sync,
}
+ ///
+ /// Represents the data (or lack thereof) in the current sector timeslice.
+ /// This may be actual data (header, label, or data), interrecord gaps, or
+ /// sync words.
+ ///
public struct DataCell
{
public DataCell(ushort data, CellType type)
diff --git a/Contralto/IO/DiabloPack.cs b/Contralto/IO/DiabloPack.cs
index 14e0b36..bd48304 100644
--- a/Contralto/IO/DiabloPack.cs
+++ b/Contralto/IO/DiabloPack.cs
@@ -4,6 +4,9 @@ using System.IO;
namespace Contralto.IO
{
+ ///
+ /// DiskGeometry encapsulates the geometry of a disk.
+ ///
public struct DiskGeometry
{
public DiskGeometry(int cylinders, int tracks, int sectors)
@@ -24,6 +27,10 @@ namespace Contralto.IO
Diablo44
}
+ ///
+ /// DiabloDiskSector encapsulates the records contained in a single Alto disk sector
+ /// on a Diablo disk. This includes the header, label, and data records.
+ ///
public class DiabloDiskSector
{
public DiabloDiskSector(byte[] header, byte[] label, byte[] data)
@@ -106,13 +113,14 @@ namespace Contralto.IO
// Bitsavers images have an extra word in the header for some reason.
// ignore it.
// TODO: should support different formats ("correct" raw, Alto CopyDisk format, etc.)
- //
+ //
imageStream.Seek(2, SeekOrigin.Current);
+
if (imageStream.Read(header, 0, header.Length) != header.Length)
{
throw new InvalidOperationException("Short read while reading sector header.");
- }
+ }
if (imageStream.Read(label, 0, label.Length) != label.Length)
{
diff --git a/Contralto/IO/DiskController.cs b/Contralto/IO/DiskController.cs
index e937e34..7c77d60 100644
--- a/Contralto/IO/DiskController.cs
+++ b/Contralto/IO/DiskController.cs
@@ -15,6 +15,10 @@ namespace Contralto.IO
public delegate void DiskActivity(DiskActivityType activity);
+ ///
+ /// DiskController provides an implementation for the logic in the standard Alto disk controller,
+ /// which talks to a Diablo model 31 or 44 removable pack drive.
+ ///
public class DiskController
{
public DiskController(AltoSystem system)
@@ -28,11 +32,7 @@ namespace Contralto.IO
Reset();
}
-
- ///
- /// According to docs, on a Write, eventually it appears on the Read side during an actual write to the disk
- /// but not right away.
- ///
+
public ushort KDATA
{
get
@@ -165,37 +165,7 @@ namespace Contralto.IO
public bool DataXfer
{
get { return _dataXfer; }
- }
-
- public int Cylinder
- {
- get { return SelectedDrive.Cylinder; }
- }
-
- public int SeekCylinder
- {
- get { return _destCylinder; }
- }
-
- public int Head
- {
- get { return SelectedDrive.Head; }
- }
-
- public int Sector
- {
- get { return SelectedDrive.Sector; }
- }
-
- public int Drive
- {
- get { return _disk; }
- }
-
- public double ClocksUntilNextSector
- {
- get { return 0; } // _sectorClocks - _elapsedSectorTime; }
- }
+ }
public bool Ready
{
@@ -292,6 +262,12 @@ namespace Contralto.IO
_seclateEnable = false;
}
+ ///
+ /// Called back 12 times per rotation of the disk to kick off a new disk sector.
+ ///
+ ///
+ ///
+ ///
private void SectorCallback(ulong timeNsec, ulong skewNsec, object context)
{
//
@@ -351,6 +327,12 @@ namespace Contralto.IO
}
}
+ ///
+ /// Called back for every word time in this sector.
+ ///
+ ///
+ ///
+ ///
private void WordCallback(ulong timeNsec, ulong skewNsec, object context)
{
SpinDisk();
@@ -369,6 +351,13 @@ namespace Contralto.IO
}
}
+ ///
+ /// Called back if the sector task doesn't start in time, providing SECLATE
+ /// semantics.
+ ///
+ ///
+ ///
+ ///
private void SeclateCallback(ulong timeNsec, ulong skewNsec, object context)
{
if (_seclateEnable)
@@ -405,6 +394,9 @@ namespace Contralto.IO
}
}
+ ///
+ /// Starts a seek operation.
+ ///
public void Strobe()
{
//
@@ -487,7 +479,7 @@ namespace Contralto.IO
// for lead-in or inter-record delays, but the slices are still used to
// keep things in line time-wise; the real hardware uses a crystal-controlled clock
// to generate these slices during these periods (and the clock comes from the
- // disk itself when actual data is present). For our purposes, the two clocks
+ // drive itself when actual data is present). For our purposes, the two clocks
// are one and the same.
//
diff --git a/Contralto/IO/EthernetController.cs b/Contralto/IO/EthernetController.cs
index db620fa..8cedec9 100644
--- a/Contralto/IO/EthernetController.cs
+++ b/Contralto/IO/EthernetController.cs
@@ -9,6 +9,9 @@ using System.Threading.Tasks;
namespace Contralto.IO
{
+ ///
+ /// EthernetController implements the logic for the Alto's 3Mbit Ethernet controller.
+ ///
public class EthernetController
{
public EthernetController(AltoSystem system)
@@ -345,7 +348,7 @@ namespace Contralto.IO
///
/// Invoked when the host ethernet interface receives a packet destined for us.
- /// NOTE: This runs on the PCap receiver thread (see HostEthernet), not the main emulator thread.
+ /// NOTE: This runs on the PCap or UDP receiver thread, not the main emulator thread.
/// Any access to emulator structures must be properly protected.
///
/// Due to the nature of the "ethernet" we're simulating, there will never be any collisions or corruption and
@@ -502,18 +505,7 @@ namespace Contralto.IO
// Schedule the next wakeup.
_inputPollEvent.TimestampNsec = _inputPollPeriod - skewNsec;
_system.Scheduler.Schedule(_inputPollEvent);
- }
-
- private void LogPacket(int length, MemoryStream packet)
- {
- Log.Write(LogComponent.EthernetPacket,
- " - Packet src {0}, dest {1}, length {2}",
- packet.ReadByte(), packet.ReadByte(), length);
-
-
- // Return to top of packet
- packet.Position = 2;
- }
+ }
private Queue _fifo;
@@ -555,11 +547,11 @@ namespace Contralto.IO
private const int _maxQueuedPackets = 32;
// The actual connection to a real network device of some sort on the host
- IPacketEncapsulation _hostInterface;
+ private IPacketEncapsulation _hostInterface;
// Buffer to hold outgoing data to the host ethernet
- ushort[] _outputData;
- int _outputIndex;
+ private ushort[] _outputData;
+ private int _outputIndex;
// Incoming data and locking
private MemoryStream _incomingPacket;
diff --git a/Contralto/IO/HostEthernetEncapsulation.cs b/Contralto/IO/HostEthernetEncapsulation.cs
index 1c9acb8..e95092e 100644
--- a/Contralto/IO/HostEthernetEncapsulation.cs
+++ b/Contralto/IO/HostEthernetEncapsulation.cs
@@ -15,7 +15,9 @@ using System.Threading;
namespace Contralto.IO
{
-
+ ///
+ /// Represents a host ethernet interface.
+ ///
public struct EthernetInterface
{
public EthernetInterface(string name, string description)
@@ -249,19 +251,8 @@ namespace Contralto.IO
}
else
{
- // Check addressing table for external (non emulator) addresses;
- // otherwise just address other emulators
- // TODO: implement table. Currently hardcoded address 1 to test IFS on dev machine
- //
- if (destinationHost == 1)
- {
- destinationMac = new MacAddress((UInt48)(_ifsTestMAC));
- }
- else
- {
- destinationMac = new MacAddress((UInt48)(_10mbitMACPrefix | destinationHost)); // emulator destination address
- }
-
+ // Build 10mbit address from 3mbit
+ destinationMac = new MacAddress((UInt48)(_10mbitMACPrefix | destinationHost)); // emulator destination address
}
return destinationMac;
@@ -285,9 +276,6 @@ namespace Contralto.IO
private UInt48 _10mbitMACPrefix = 0x0000aa010200; // 00-00-AA is the Xerox vendor code, used just to be cute.
private UInt48 _10mbitBroadcast = (UInt48)0xffffffffffff;
- private const int _3mbitBroadcast = 0;
-
- // Temporary; to be replaced with an external address mapping table
- private UInt48 _ifsTestMAC = (UInt48)0x001060b88e3e;
+ private const int _3mbitBroadcast = 0;
}
}
diff --git a/Contralto/IO/IPacketEncapsulation.cs b/Contralto/IO/IPacketEncapsulation.cs
index b702b2e..a8c34ec 100644
--- a/Contralto/IO/IPacketEncapsulation.cs
+++ b/Contralto/IO/IPacketEncapsulation.cs
@@ -5,6 +5,10 @@ namespace Contralto.IO
{
public delegate void ReceivePacketDelegate(MemoryStream data);
+ ///
+ /// Provides a generic interface for host network devices that can encapsulate
+ /// Alto ethernet packets.
+ ///
public interface IPacketEncapsulation
{
///
@@ -14,14 +18,14 @@ namespace Contralto.IO
void RegisterReceiveCallback(ReceivePacketDelegate callback);
///
- /// Sends the specified word array
+ /// Sends the specified word array over the device.
///
///
///
void Send(ushort[] packet, int length);
///
- /// Shuts down the encapsulation provider
+ /// Shuts down the encapsulation provider.
///
void Shutdown();
}
diff --git a/Contralto/IO/Keyboard.cs b/Contralto/IO/Keyboard.cs
index d9c25f5..82b89f4 100644
--- a/Contralto/IO/Keyboard.cs
+++ b/Contralto/IO/Keyboard.cs
@@ -5,7 +5,9 @@ using Contralto.CPU;
namespace Contralto.IO
{
-
+ ///
+ /// The keys on the Alto keyboard.
+ ///
public enum AltoKey
{
None = 0,
@@ -72,6 +74,9 @@ namespace Contralto.IO
BlankBottom,
}
+ ///
+ /// Specifies the word and bitmask for a given Alto keyboard key.
+ ///
public struct AltoKeyBit
{
public AltoKeyBit(int word, ushort mask)
diff --git a/Contralto/IO/Mouse.cs b/Contralto/IO/Mouse.cs
index 6adc200..3aa960a 100644
--- a/Contralto/IO/Mouse.cs
+++ b/Contralto/IO/Mouse.cs
@@ -17,6 +17,9 @@ namespace Contralto.IO
Left = 0x4,
}
+ ///
+ /// Implements the hardware for the standard Alto mouse.
+ ///
public class Mouse : IMemoryMappedDevice
{
public Mouse()
@@ -27,10 +30,7 @@ namespace Contralto.IO
public void Reset()
{
- // cheat for synchronization: this is approximately where the mouse is initialized to
- // at alto boot.
- _mouseY = 80;
- _mouseX = 0;
+
}
public ushort Read(int address, TaskType task, bool extendedMemoryReference)
diff --git a/Contralto/IO/UDPEncapsulation.cs b/Contralto/IO/UDPEncapsulation.cs
index 087e37a..a63367d 100644
--- a/Contralto/IO/UDPEncapsulation.cs
+++ b/Contralto/IO/UDPEncapsulation.cs
@@ -168,9 +168,6 @@ namespace Contralto.IO
private void ReceiveThread()
{
- // Just call ReceivePackets, that's it. This will never return.
- // (probably need to make this more elegant so we can tear down the thread
- // properly.)
Log.Write(LogComponent.HostNetworkInterface, "UDP Receiver thread started.");
IPEndPoint groupEndPoint = new IPEndPoint(IPAddress.Any, _udpPort);
diff --git a/Contralto/Memory/Memory.cs b/Contralto/Memory/Memory.cs
index f8eb165..913f5a5 100644
--- a/Contralto/Memory/Memory.cs
+++ b/Contralto/Memory/Memory.cs
@@ -3,6 +3,10 @@ using Contralto.Logging;
namespace Contralto.Memory
{
+ ///
+ /// Implements the Alto's main memory, up to 4 banks of 64KW in 16-bit words.
+ /// Provides implementation of the IIXM's memory mapping hardware.
+ ///
public class Memory : IMemoryMappedDevice
{
public Memory()
diff --git a/Contralto/Memory/MemoryBus.cs b/Contralto/Memory/MemoryBus.cs
index 6d7cfd2..27d892e 100644
--- a/Contralto/Memory/MemoryBus.cs
+++ b/Contralto/Memory/MemoryBus.cs
@@ -14,13 +14,14 @@ namespace Contralto.Memory
///
/// Implements the memory bus and memory timings for the Alto system.
- /// TODO: Currently only implements timings for Alto II systems.
+ /// This implements timings for both Alto I and Alto II systems.
///
- public class MemoryBus : IClockable
+ public sealed class MemoryBus : IClockable
{
public MemoryBus()
{
_bus = new Dictionary(65536);
+ _systemType = Configuration.SystemType;
Reset();
}
@@ -106,25 +107,59 @@ namespace Contralto.Memory
{
_memoryCycle++;
if (_memoryOperationActive)
- {
- switch (_memoryCycle)
+ {
+ if (_systemType == SystemType.AltoI)
{
- case 3:
- // Buffered read of single word
- _memoryData = ReadFromBus(_memoryAddress, _task, _extendedMemoryReference);
- break;
-
- case 4:
- // Buffered read of double-word
- _memoryData2 = ReadFromBus((ushort)(_memoryAddress ^ 1), _task, _extendedMemoryReference);
- break;
-
- case 5:
- // End of memory operation
- _memoryOperationActive = false;
- _doubleWordStore = false;
- break;
+ ClockAltoI();
}
+ else
+ {
+ ClockAltoII();
+ }
+ }
+ }
+
+ private void ClockAltoI()
+ {
+ switch (_memoryCycle)
+ {
+ case 4:
+ // Buffered read of single word
+ _memoryData = ReadFromBus(_memoryAddress, _task, _extendedMemoryReference);
+ break;
+
+ case 5:
+ // Buffered read of double-word
+ _memoryData2 = ReadFromBus((ushort)(_memoryAddress | 1), _task, _extendedMemoryReference);
+ break;
+
+ case 7:
+ // End of memory operation
+ _memoryOperationActive = false;
+ _doubleWordStore = false;
+ break;
+ }
+ }
+
+ private void ClockAltoII()
+ {
+ switch (_memoryCycle)
+ {
+ case 3:
+ // Buffered read of single word
+ _memoryData = ReadFromBus(_memoryAddress, _task, _extendedMemoryReference);
+ break;
+
+ case 4:
+ // Buffered read of double-word
+ _memoryData2 = ReadFromBus((ushort)(_memoryAddress ^ 1), _task, _extendedMemoryReference);
+ break;
+
+ case 5:
+ // End of memory operation
+ _memoryOperationActive = false;
+ _doubleWordStore = false;
+ break;
}
}
@@ -143,8 +178,16 @@ namespace Contralto.Memory
return _memoryCycle > 4;
case MemoryOperation.Store:
- // Write operations take place on cycles 3 and 4
- return _memoryCycle > 2;
+ if (_systemType == SystemType.AltoI)
+ {
+ // // Store operations take place on cycles 5 and 6
+ return _memoryCycle > 4;
+ }
+ else
+ {
+ // Store operations take place on cycles 3 and 4
+ return _memoryCycle > 2;
+ }
default:
throw new InvalidOperationException(String.Format("Unexpected memory operation {0}", op));
@@ -161,7 +204,8 @@ namespace Contralto.Memory
{
if (_memoryOperationActive)
{
- // This should not happen; CPU should check whether the operation is possible using Ready and stall if not.
+ // This should not happen; CPU implementation should check whether the operation is possible
+ // using Ready and stall if not.
throw new InvalidOperationException("Invalid LoadMAR request during active memory operation.");
}
else
@@ -177,31 +221,71 @@ namespace Contralto.Memory
}
public ushort ReadMD()
+ {
+ if (_systemType == SystemType.AltoI)
+ {
+ return ReadMDAltoI();
+ }
+ else
+ {
+ return ReadMDAltoII();
+ }
+ }
+
+ private ushort ReadMDAltoI()
{
if (_memoryOperationActive)
{
switch (_memoryCycle)
{
- case 1:
+ case 1:
+ case 2:
+
+ // TODO: good microcode should never do this
+ throw new InvalidOperationException("Unexpected microcode behavior -- ReadMD too soon after start of memory cycle.");
+ 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.");
+
+ case 5:
+ // Single word read
+ return _memoryData;
+
+ case 6:
+ // Double word read, return other half of double word.
+ return _memoryData2;
+
+ default:
+ // Invalid state.
+ throw new InvalidOperationException(string.Format("Unexpected memory cycle {0} in memory state machine.", _memoryCycle));
+ }
+ }
+ else
+ {
+ // The Alto I does not latch memory contents, an <-MD operation returns undefined results
+ return 0xffff;
+ }
+ }
+
+ private ushort ReadMDAltoII()
+ {
+ if (_memoryOperationActive)
+ {
+ switch (_memoryCycle)
+ {
+ case 1:
case 2:
// TODO: good microcode should never do this
throw new InvalidOperationException("Unexpected microcode behavior -- ReadMD too soon after start of memory cycle.");
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 ReadMR request during cycle 3 or 4 of memory operation.");
case 5:
- // Single word read
- //Log.Write(LogType.Verbose, LogComponent.Memory, "Single-word read of {0} from {1} (cycle 5)", Conversion.ToOctal(_memoryData), Conversion.ToOctal(_memoryAddress ^ 1));
-
- // debug
- /*
- if (_memoryAddress == 0xfc90 && _task != TaskType.Emulator) // 176220 -- status word for disk
- {
- Logging.Log.Write(Logging.LogComponent.Debug, "--> Task {0} read {1} from 176220.", _task, _memoryData);
- } */
- return _memoryData;
+ // Single word read
+ return _memoryData;
// ***
// NB: Handler for double-word read (cycle 6) is in the "else" clause below; this is kind of a hack.
@@ -219,104 +303,97 @@ namespace Contralto.Memory
// 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))
- {
-
- //Log.Write(LogType.Verbose, LogComponent.Memory, "Double-word read of {0} from {1} (cycle 6)", Conversion.ToOctal(_memoryData2), Conversion.ToOctal(_memoryAddress ^ 1));
- _doubleWordMixed = false;
- // debug
- /*
- if ((_memoryAddress ^ 1) == 0xfc90 && _task != TaskType.Emulator) // 176220 -- status word for disk
- {
- Logging.Log.Write(Logging.LogComponent.Debug, "--> Task {0} read {1} from 176220.", _task, _memoryData2);
- } */
+ {
+ _doubleWordMixed = false;
return _memoryData2;
}
else
{
- _doubleWordMixed = false;
- // debug
- /*
- if (_memoryAddress == 0xfc90 && _task != TaskType.Emulator) // 176220 -- status word for disk
- {
- Logging.Log.Write(Logging.LogComponent.Debug, "--> Task {0} read {1} from 176220.", _task, _memoryData);
- } */
- //Log.Write(LogType.Verbose, LogComponent.Memory, "Single-word read of {0} from {1} (post cycle 6)", Conversion.ToOctal(_memoryData), Conversion.ToOctal(_memoryAddress));
+ _doubleWordMixed = false;
return _memoryData;
}
- }
+ }
}
public void LoadMD(ushort data)
{
if (_memoryOperationActive)
{
- switch (_memoryCycle)
+ if (_systemType == SystemType.AltoI)
{
- 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 3:
-
- // debug
- /*
- if (_memoryAddress == 0xfc90 || _memoryAddress == 0xfc91 || _memoryAddress == 0x151) // 176220 -- status word for disk
- {
- Logging.Log.Write(Logging.LogComponent.Debug, "++> Task {0} wrote {1} to {3} (was {2}).", _task, Conversion.ToOctal(data), Conversion.ToOctal(DebugReadWord(_task, _memoryAddress)), Conversion.ToOctal(_memoryAddress));
- }*/
-
- _memoryData = data; // Only really necessary to show in debugger
- // Start of doubleword write:
- WriteToBus(_memoryAddress, data, _task, _extendedMemoryReference);
- _doubleWordStore = true;
- _doubleWordMixed = true;
-
-
-
- /*
- Log.Write(
- LogType.Verbose,
- LogComponent.Memory,
- "Single-word store of {0} to {1} (cycle 3)",
- Conversion.ToOctal(data),
- Conversion.ToOctal(_memoryAddress)); */
- break;
-
- case 4:
- _memoryData = data; // Only really necessary to show in debugger
-
- /*
- Log.Write(
- LogType.Verbose,
- LogComponent.Memory,
- _doubleWordStore ? "Double-word store of {0} to {1} (cycle 4)" : "Single-word store of {0} to {1} (cycle 4)",
- Conversion.ToOctal(data),
- _doubleWordStore ? Conversion.ToOctal(_memoryAddress ^ 1) : Conversion.ToOctal(_memoryAddress));
- */
- // debug
- ushort actualAddress = _doubleWordStore ? (ushort)(_memoryAddress ^ 1) : _memoryAddress;
-
- /*
- if (actualAddress == 0xfc90 || actualAddress == 0xfc91 || _memoryAddress == 0x151) // 176220 -- status word for disk
- {
- Logging.Log.Write(Logging.LogComponent.Debug, "--> Task {0} wrote {1} to {4} (was {2}). Extd {3}", _task, Conversion.ToOctal(data), Conversion.ToOctal(DebugReadWord(_task, actualAddress)), _extendedMemoryReference, Conversion.ToOctal(actualAddress));
- } */
-
- WriteToBus(actualAddress, data, _task, _extendedMemoryReference);
-
- /*
- if (actualAddress == 0xfc90 || actualAddress == 0xfc91 || _memoryAddress == 0x151) // 176220 -- status word for disk
- {
- Logging.Log.Write(Logging.LogComponent.Debug, "--> Now {0}.", Conversion.ToOctal(DebugReadWord(_task, actualAddress)));
- } */
- break;
- }
-
+ LoadMDAltoI(data);
+ }
+ else
+ {
+ LoadMDAltoII(data);
+ }
}
}
+ private void LoadMDAltoI(ushort data)
+ {
+ switch (_memoryCycle)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ // TODO: 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:
+ WriteToBus(_memoryAddress, data, _task, _extendedMemoryReference);
+ _doubleWordStore = true;
+ _doubleWordMixed = true;
+ break;
+
+ case 6:
+ if (!_doubleWordStore)
+ {
+ throw new InvalidOperationException("Unexpected microcode behavior -- LoadMD on cycle 6, no LoadMD on cycle 5.");
+ }
+
+ _memoryData = data; // Only really necessary to show in debugger
+ ushort actualAddress = (ushort)(_memoryAddress | 1);
+
+ WriteToBus(actualAddress, data, _task, _extendedMemoryReference);
+ break;
+ }
+
+ }
+
+ private void LoadMDAltoII(ushort data)
+ {
+ 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 3:
+
+ _memoryData = data; // Only really necessary to show in debugger
+ // Start of doubleword write:
+ WriteToBus(_memoryAddress, data, _task, _extendedMemoryReference);
+ _doubleWordStore = true;
+ _doubleWordMixed = true;
+ break;
+
+ case 4:
+ _memoryData = data; // Only really necessary to show in debugger
+ ushort actualAddress = _doubleWordStore ? (ushort)(_memoryAddress ^ 1) : _memoryAddress;
+
+ WriteToBus(actualAddress, data, _task, _extendedMemoryReference);
+ break;
+ }
+
+ }
+
///
/// Dispatches reads to memory mapped hardware (RAM, I/O)
///
@@ -340,8 +417,7 @@ namespace Contralto.Memory
return memoryMappedDevice.Read(address, task, extendedMemoryReference);
}
else
- {
- //throw new NotImplementedException(String.Format("Read from unimplemented memory-mapped I/O device at {0}.", OctalHelpers.ToOctal(address)));
+ {
return 0;
}
}
@@ -369,11 +445,7 @@ namespace Contralto.Memory
if (_bus.TryGetValue(address, out memoryMappedDevice))
{
memoryMappedDevice.Load(address, data, task, extendedMemoryReference);
- }
- else
- {
- // throw new NotImplementedException(String.Format("Write to unimplemented memory-mapped I/O device at {0}.", OctalHelpers.ToOctal(address)));
- }
+ }
}
}
@@ -382,6 +454,11 @@ namespace Contralto.Memory
///
private Dictionary _bus;
+ ///
+ /// Cache the system type since we rely on it
+ ///
+ private SystemType _systemType;
+
//
// Optimzation: keep reference to main memory; since 99.9999% of accesses go directly there,
// we can avoid the hashtable overhead using a simple address check.
diff --git a/Contralto/Program.cs b/Contralto/Program.cs
index 598d670..b3cf373 100644
--- a/Contralto/Program.cs
+++ b/Contralto/Program.cs
@@ -103,7 +103,6 @@ namespace Contralto
}
}
- private static AltoSystem _system;
- private static ManualResetEvent _closeEvent;
+ private static AltoSystem _system;
}
}
diff --git a/Contralto/ROM/0.2 b/Contralto/ROM/0.2
deleted file mode 100644
index a42e7eb..0000000
Binary files a/Contralto/ROM/0.2 and /dev/null differ
diff --git a/Contralto/ROM/1.2 b/Contralto/ROM/1.2
deleted file mode 100644
index b2cf4b8..0000000
Binary files a/Contralto/ROM/1.2 and /dev/null differ
diff --git a/Contralto/ROM/10.2 b/Contralto/ROM/10.2
deleted file mode 100644
index f4586cb..0000000
Binary files a/Contralto/ROM/10.2 and /dev/null differ
diff --git a/Contralto/ROM/11.2 b/Contralto/ROM/11.2
deleted file mode 100644
index 76fce7e..0000000
--- a/Contralto/ROM/11.2
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Contralto/ROM/12.2 b/Contralto/ROM/12.2
deleted file mode 100644
index 773887a..0000000
--- a/Contralto/ROM/12.2
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Contralto/ROM/13.2 b/Contralto/ROM/13.2
deleted file mode 100644
index 5b5e7a9..0000000
Binary files a/Contralto/ROM/13.2 and /dev/null differ
diff --git a/Contralto/ROM/14.2 b/Contralto/ROM/14.2
deleted file mode 100644
index 821d423..0000000
Binary files a/Contralto/ROM/14.2 and /dev/null differ
diff --git a/Contralto/ROM/16.2 b/Contralto/ROM/16.2
deleted file mode 100644
index c469133..0000000
Binary files a/Contralto/ROM/16.2 and /dev/null differ
diff --git a/Contralto/ROM/17.2 b/Contralto/ROM/17.2
deleted file mode 100644
index b625c88..0000000
Binary files a/Contralto/ROM/17.2 and /dev/null differ
diff --git a/Contralto/ROM/2.2 b/Contralto/ROM/2.2
deleted file mode 100644
index afa2d3c..0000000
Binary files a/Contralto/ROM/2.2 and /dev/null differ
diff --git a/Contralto/ROM/20.2 b/Contralto/ROM/20.2
deleted file mode 100644
index d863b7a..0000000
Binary files a/Contralto/ROM/20.2 and /dev/null differ
diff --git a/Contralto/ROM/21.2 b/Contralto/ROM/21.2
deleted file mode 100644
index 350c44e..0000000
--- a/Contralto/ROM/21.2
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/Contralto/ROM/23.2 b/Contralto/ROM/23.2
deleted file mode 100644
index 79cbafd..0000000
Binary files a/Contralto/ROM/23.2 and /dev/null differ
diff --git a/Contralto/ROM/24.2 b/Contralto/ROM/24.2
deleted file mode 100644
index 375adb6..0000000
Binary files a/Contralto/ROM/24.2 and /dev/null differ
diff --git a/Contralto/ROM/25.2 b/Contralto/ROM/25.2
deleted file mode 100644
index dd1405e..0000000
Binary files a/Contralto/ROM/25.2 and /dev/null differ
diff --git a/Contralto/ROM/26.2 b/Contralto/ROM/26.2
deleted file mode 100644
index 38eed62..0000000
Binary files a/Contralto/ROM/26.2 and /dev/null differ
diff --git a/Contralto/ROM/27.2 b/Contralto/ROM/27.2
deleted file mode 100644
index a67a321..0000000
Binary files a/Contralto/ROM/27.2 and /dev/null differ
diff --git a/Contralto/ROM/3.2 b/Contralto/ROM/3.2
deleted file mode 100644
index 7cb371a..0000000
Binary files a/Contralto/ROM/3.2 and /dev/null differ
diff --git a/Contralto/ROM/30.2 b/Contralto/ROM/30.2
deleted file mode 100644
index e0b5c95..0000000
Binary files a/Contralto/ROM/30.2 and /dev/null differ
diff --git a/Contralto/ROM/31.2 b/Contralto/ROM/31.2
deleted file mode 100644
index 56c950a..0000000
--- a/Contralto/ROM/31.2
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/Contralto/ROM/32.2 b/Contralto/ROM/32.2
deleted file mode 100644
index 0b4094e..0000000
--- a/Contralto/ROM/32.2
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Contralto/ROM/33.2 b/Contralto/ROM/33.2
deleted file mode 100644
index 8daf422..0000000
Binary files a/Contralto/ROM/33.2 and /dev/null differ
diff --git a/Contralto/ROM/34.2 b/Contralto/ROM/34.2
deleted file mode 100644
index 496034a..0000000
Binary files a/Contralto/ROM/34.2 and /dev/null differ
diff --git a/Contralto/ROM/35.2 b/Contralto/ROM/35.2
deleted file mode 100644
index abd0a6b..0000000
Binary files a/Contralto/ROM/35.2 and /dev/null differ
diff --git a/Contralto/ROM/36.2 b/Contralto/ROM/36.2
deleted file mode 100644
index 1363d07..0000000
Binary files a/Contralto/ROM/36.2 and /dev/null differ
diff --git a/Contralto/ROM/37.2 b/Contralto/ROM/37.2
deleted file mode 100644
index f21037c..0000000
Binary files a/Contralto/ROM/37.2 and /dev/null differ
diff --git a/Contralto/ROM/4.2 b/Contralto/ROM/4.2
deleted file mode 100644
index 60cf83f..0000000
Binary files a/Contralto/ROM/4.2 and /dev/null differ
diff --git a/Contralto/ROM/5.2 b/Contralto/ROM/5.2
deleted file mode 100644
index ef94e44..0000000
Binary files a/Contralto/ROM/5.2 and /dev/null differ
diff --git a/Contralto/ROM/6.2 b/Contralto/ROM/6.2
deleted file mode 100644
index eb9fb29..0000000
Binary files a/Contralto/ROM/6.2 and /dev/null differ
diff --git a/Contralto/ROM/7.2 b/Contralto/ROM/7.2
deleted file mode 100644
index bcb2e81..0000000
Binary files a/Contralto/ROM/7.2 and /dev/null differ
diff --git a/Contralto/ROM/ACSOURCE.NEW b/Contralto/ROM/ACSOURCE.NEW
new file mode 100644
index 0000000..a627611
Binary files /dev/null and b/Contralto/ROM/ACSOURCE.NEW differ
diff --git a/Contralto/ROM/2kctl.u3 b/Contralto/ROM/ACSOURCE.OLD
similarity index 100%
rename from Contralto/ROM/2kctl.u3
rename to Contralto/ROM/ACSOURCE.OLD
diff --git a/Contralto/ROM/AltoI/00_23.BIN b/Contralto/ROM/AltoI/00_23.BIN
new file mode 100644
index 0000000..f7c0985
Binary files /dev/null and b/Contralto/ROM/AltoI/00_23.BIN differ
diff --git a/Contralto/ROM/AltoI/01_23.BIN b/Contralto/ROM/AltoI/01_23.BIN
new file mode 100644
index 0000000..fce814c
--- /dev/null
+++ b/Contralto/ROM/AltoI/01_23.BIN
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Contralto/ROM/AltoI/02_23.BIN b/Contralto/ROM/AltoI/02_23.BIN
new file mode 100644
index 0000000..7a2877a
Binary files /dev/null and b/Contralto/ROM/AltoI/02_23.BIN differ
diff --git a/Contralto/ROM/AltoI/03_23.BIN b/Contralto/ROM/AltoI/03_23.BIN
new file mode 100644
index 0000000..1b2f987
Binary files /dev/null and b/Contralto/ROM/AltoI/03_23.BIN differ
diff --git a/Contralto/ROM/AltoI/04_23.BIN b/Contralto/ROM/AltoI/04_23.BIN
new file mode 100644
index 0000000..f951f39
Binary files /dev/null and b/Contralto/ROM/AltoI/04_23.BIN differ
diff --git a/Contralto/ROM/AltoI/05_23.BIN b/Contralto/ROM/AltoI/05_23.BIN
new file mode 100644
index 0000000..5467401
Binary files /dev/null and b/Contralto/ROM/AltoI/05_23.BIN differ
diff --git a/Contralto/ROM/AltoI/06_23.BIN b/Contralto/ROM/AltoI/06_23.BIN
new file mode 100644
index 0000000..294445f
Binary files /dev/null and b/Contralto/ROM/AltoI/06_23.BIN differ
diff --git a/Contralto/ROM/AltoI/07_23.BIN b/Contralto/ROM/AltoI/07_23.BIN
new file mode 100644
index 0000000..71ffb8c
Binary files /dev/null and b/Contralto/ROM/AltoI/07_23.BIN differ
diff --git a/Contralto/ROM/AltoI/10_23.BIN b/Contralto/ROM/AltoI/10_23.BIN
new file mode 100644
index 0000000..5a3bf2e
Binary files /dev/null and b/Contralto/ROM/AltoI/10_23.BIN differ
diff --git a/Contralto/ROM/AltoI/11_23.BIN b/Contralto/ROM/AltoI/11_23.BIN
new file mode 100644
index 0000000..0718659
--- /dev/null
+++ b/Contralto/ROM/AltoI/11_23.BIN
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Contralto/ROM/AltoI/12_23.BIN b/Contralto/ROM/AltoI/12_23.BIN
new file mode 100644
index 0000000..707bc88
--- /dev/null
+++ b/Contralto/ROM/AltoI/12_23.BIN
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Contralto/ROM/AltoI/13_23.BIN b/Contralto/ROM/AltoI/13_23.BIN
new file mode 100644
index 0000000..b79e532
Binary files /dev/null and b/Contralto/ROM/AltoI/13_23.BIN differ
diff --git a/Contralto/ROM/AltoI/14_23.BIN b/Contralto/ROM/AltoI/14_23.BIN
new file mode 100644
index 0000000..e92be1f
Binary files /dev/null and b/Contralto/ROM/AltoI/14_23.BIN differ
diff --git a/Contralto/ROM/15.2 b/Contralto/ROM/AltoI/15_23.BIN
similarity index 55%
rename from Contralto/ROM/15.2
rename to Contralto/ROM/AltoI/15_23.BIN
index ef36b00..a3955ef 100644
Binary files a/Contralto/ROM/15.2 and b/Contralto/ROM/AltoI/15_23.BIN differ
diff --git a/Contralto/ROM/AltoI/16_23.BIN b/Contralto/ROM/AltoI/16_23.BIN
new file mode 100644
index 0000000..0be5331
Binary files /dev/null and b/Contralto/ROM/AltoI/16_23.BIN differ
diff --git a/Contralto/ROM/AltoI/17_23.BIN b/Contralto/ROM/AltoI/17_23.BIN
new file mode 100644
index 0000000..960b1f7
Binary files /dev/null and b/Contralto/ROM/AltoI/17_23.BIN differ
diff --git a/Contralto/ROM/AltoI/20_23.BIN b/Contralto/ROM/AltoI/20_23.BIN
new file mode 100644
index 0000000..976c6a1
Binary files /dev/null and b/Contralto/ROM/AltoI/20_23.BIN differ
diff --git a/Contralto/ROM/AltoI/21_23.BIN b/Contralto/ROM/AltoI/21_23.BIN
new file mode 100644
index 0000000..cdc55dc
--- /dev/null
+++ b/Contralto/ROM/AltoI/21_23.BIN
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Contralto/ROM/22.2 b/Contralto/ROM/AltoI/22_23.BIN
similarity index 64%
rename from Contralto/ROM/22.2
rename to Contralto/ROM/AltoI/22_23.BIN
index f766736..72f43c5 100644
Binary files a/Contralto/ROM/22.2 and b/Contralto/ROM/AltoI/22_23.BIN differ
diff --git a/Contralto/ROM/AltoI/23_23.BIN b/Contralto/ROM/AltoI/23_23.BIN
new file mode 100644
index 0000000..ed00bcc
Binary files /dev/null and b/Contralto/ROM/AltoI/23_23.BIN differ
diff --git a/Contralto/ROM/AltoI/24_23.BIN b/Contralto/ROM/AltoI/24_23.BIN
new file mode 100644
index 0000000..bb5fa4c
Binary files /dev/null and b/Contralto/ROM/AltoI/24_23.BIN differ
diff --git a/Contralto/ROM/AltoI/25_23.BIN b/Contralto/ROM/AltoI/25_23.BIN
new file mode 100644
index 0000000..53c61c2
--- /dev/null
+++ b/Contralto/ROM/AltoI/25_23.BIN
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Contralto/ROM/AltoI/26_23.BIN b/Contralto/ROM/AltoI/26_23.BIN
new file mode 100644
index 0000000..d6fbbb5
Binary files /dev/null and b/Contralto/ROM/AltoI/26_23.BIN differ
diff --git a/Contralto/ROM/AltoI/27_23.BIN b/Contralto/ROM/AltoI/27_23.BIN
new file mode 100644
index 0000000..091ee0a
Binary files /dev/null and b/Contralto/ROM/AltoI/27_23.BIN differ
diff --git a/Contralto/ROM/AltoI/30_23.BIN b/Contralto/ROM/AltoI/30_23.BIN
new file mode 100644
index 0000000..f9e0b05
Binary files /dev/null and b/Contralto/ROM/AltoI/30_23.BIN differ
diff --git a/Contralto/ROM/AltoI/31_23.BIN b/Contralto/ROM/AltoI/31_23.BIN
new file mode 100644
index 0000000..cb2bbfb
--- /dev/null
+++ b/Contralto/ROM/AltoI/31_23.BIN
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Contralto/ROM/AltoI/32_23.BIN b/Contralto/ROM/AltoI/32_23.BIN
new file mode 100644
index 0000000..d067eb3
--- /dev/null
+++ b/Contralto/ROM/AltoI/32_23.BIN
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Contralto/ROM/AltoI/33_23.BIN b/Contralto/ROM/AltoI/33_23.BIN
new file mode 100644
index 0000000..5e452ef
Binary files /dev/null and b/Contralto/ROM/AltoI/33_23.BIN differ
diff --git a/Contralto/ROM/AltoI/34_23.BIN b/Contralto/ROM/AltoI/34_23.BIN
new file mode 100644
index 0000000..386286a
Binary files /dev/null and b/Contralto/ROM/AltoI/34_23.BIN differ
diff --git a/Contralto/ROM/AltoI/35_23.BIN b/Contralto/ROM/AltoI/35_23.BIN
new file mode 100644
index 0000000..1a47102
Binary files /dev/null and b/Contralto/ROM/AltoI/35_23.BIN differ
diff --git a/Contralto/ROM/AltoI/36_23.BIN b/Contralto/ROM/AltoI/36_23.BIN
new file mode 100644
index 0000000..555cd36
Binary files /dev/null and b/Contralto/ROM/AltoI/36_23.BIN differ
diff --git a/Contralto/ROM/AltoI/37_23.BIN b/Contralto/ROM/AltoI/37_23.BIN
new file mode 100644
index 0000000..8fced69
Binary files /dev/null and b/Contralto/ROM/AltoI/37_23.BIN differ
diff --git a/Contralto/ROM/AltoI/C0_23.BIN b/Contralto/ROM/AltoI/C0_23.BIN
new file mode 100644
index 0000000..302a6c1
Binary files /dev/null and b/Contralto/ROM/AltoI/C0_23.BIN differ
diff --git a/Contralto/ROM/AltoI/C1_23.BIN b/Contralto/ROM/AltoI/C1_23.BIN
new file mode 100644
index 0000000..1720ef5
Binary files /dev/null and b/Contralto/ROM/AltoI/C1_23.BIN differ
diff --git a/Contralto/ROM/AltoI/C2_23.BIN b/Contralto/ROM/AltoI/C2_23.BIN
new file mode 100644
index 0000000..7abb4fc
Binary files /dev/null and b/Contralto/ROM/AltoI/C2_23.BIN differ
diff --git a/Contralto/ROM/AltoI/C3_23.BIN b/Contralto/ROM/AltoI/C3_23.BIN
new file mode 100644
index 0000000..2914418
Binary files /dev/null and b/Contralto/ROM/AltoI/C3_23.BIN differ
diff --git a/Contralto/ROM/C0 b/Contralto/ROM/AltoII/C0
similarity index 100%
rename from Contralto/ROM/C0
rename to Contralto/ROM/AltoII/C0
diff --git a/Contralto/ROM/C1 b/Contralto/ROM/AltoII/C1
similarity index 100%
rename from Contralto/ROM/C1
rename to Contralto/ROM/AltoII/C1
diff --git a/Contralto/ROM/C2 b/Contralto/ROM/AltoII/C2
similarity index 100%
rename from Contralto/ROM/C2
rename to Contralto/ROM/AltoII/C2
diff --git a/Contralto/ROM/C3 b/Contralto/ROM/AltoII/C3
similarity index 100%
rename from Contralto/ROM/C3
rename to Contralto/ROM/AltoII/C3
diff --git a/Contralto/ROM/U52 b/Contralto/ROM/AltoII/U52
similarity index 100%
rename from Contralto/ROM/U52
rename to Contralto/ROM/AltoII/U52
diff --git a/Contralto/ROM/U53 b/Contralto/ROM/AltoII/U53
similarity index 100%
rename from Contralto/ROM/U53
rename to Contralto/ROM/AltoII/U53
diff --git a/Contralto/ROM/U54 b/Contralto/ROM/AltoII/U54
similarity index 100%
rename from Contralto/ROM/U54
rename to Contralto/ROM/AltoII/U54
diff --git a/Contralto/ROM/U55 b/Contralto/ROM/AltoII/U55
similarity index 100%
rename from Contralto/ROM/U55
rename to Contralto/ROM/AltoII/U55
diff --git a/Contralto/ROM/U60 b/Contralto/ROM/AltoII/U60
similarity index 100%
rename from Contralto/ROM/U60
rename to Contralto/ROM/AltoII/U60
diff --git a/Contralto/ROM/U61 b/Contralto/ROM/AltoII/U61
similarity index 100%
rename from Contralto/ROM/U61
rename to Contralto/ROM/AltoII/U61
diff --git a/Contralto/ROM/U62 b/Contralto/ROM/AltoII/U62
similarity index 100%
rename from Contralto/ROM/U62
rename to Contralto/ROM/AltoII/U62
diff --git a/Contralto/ROM/U63 b/Contralto/ROM/AltoII/U63
similarity index 100%
rename from Contralto/ROM/U63
rename to Contralto/ROM/AltoII/U63
diff --git a/Contralto/ROM/U64 b/Contralto/ROM/AltoII/U64
similarity index 100%
rename from Contralto/ROM/U64
rename to Contralto/ROM/AltoII/U64
diff --git a/Contralto/ROM/U65 b/Contralto/ROM/AltoII/U65
similarity index 100%
rename from Contralto/ROM/U65
rename to Contralto/ROM/AltoII/U65
diff --git a/Contralto/ROM/U70 b/Contralto/ROM/AltoII/U70
similarity index 100%
rename from Contralto/ROM/U70
rename to Contralto/ROM/AltoII/U70
diff --git a/Contralto/ROM/U71 b/Contralto/ROM/AltoII/U71
similarity index 100%
rename from Contralto/ROM/U71
rename to Contralto/ROM/AltoII/U71
diff --git a/Contralto/ROM/U72 b/Contralto/ROM/AltoII/U72
similarity index 100%
rename from Contralto/ROM/U72
rename to Contralto/ROM/AltoII/U72
diff --git a/Contralto/ROM/U73 b/Contralto/ROM/AltoII/U73
similarity index 100%
rename from Contralto/ROM/U73
rename to Contralto/ROM/AltoII/U73
diff --git a/Contralto/ROM/U74 b/Contralto/ROM/AltoII/U74
similarity index 100%
rename from Contralto/ROM/U74
rename to Contralto/ROM/AltoII/U74
diff --git a/Contralto/ROM/U75 b/Contralto/ROM/AltoII/U75
similarity index 100%
rename from Contralto/ROM/U75
rename to Contralto/ROM/AltoII/U75
diff --git a/Contralto/ROM/C0.2 b/Contralto/ROM/C0.2
deleted file mode 100644
index 5642219..0000000
Binary files a/Contralto/ROM/C0.2 and /dev/null differ
diff --git a/Contralto/ROM/C1.2 b/Contralto/ROM/C1.2
deleted file mode 100644
index 582bfdc..0000000
Binary files a/Contralto/ROM/C1.2 and /dev/null differ
diff --git a/Contralto/ROM/C2.2 b/Contralto/ROM/C2.2
deleted file mode 100644
index de596dd..0000000
Binary files a/Contralto/ROM/C2.2 and /dev/null differ
diff --git a/Contralto/ROM/C3.2 b/Contralto/ROM/C3.2
deleted file mode 100644
index 609e959..0000000
Binary files a/Contralto/ROM/C3.2 and /dev/null differ
diff --git a/Contralto/ROM/U52_2k b/Contralto/ROM/U52_2k
deleted file mode 100644
index 5e85cc1..0000000
Binary files a/Contralto/ROM/U52_2k and /dev/null differ
diff --git a/Contralto/ROM/U53_2k b/Contralto/ROM/U53_2k
deleted file mode 100644
index de31481..0000000
Binary files a/Contralto/ROM/U53_2k and /dev/null differ
diff --git a/Contralto/ROM/U54_2k b/Contralto/ROM/U54_2k
deleted file mode 100644
index 1800c8c..0000000
Binary files a/Contralto/ROM/U54_2k and /dev/null differ
diff --git a/Contralto/ROM/U55_2k b/Contralto/ROM/U55_2k
deleted file mode 100644
index 4064bc8..0000000
Binary files a/Contralto/ROM/U55_2k and /dev/null differ
diff --git a/Contralto/ROM/U60_2k b/Contralto/ROM/U60_2k
deleted file mode 100644
index b229aef..0000000
Binary files a/Contralto/ROM/U60_2k and /dev/null differ
diff --git a/Contralto/ROM/U61_2k b/Contralto/ROM/U61_2k
deleted file mode 100644
index d151140..0000000
Binary files a/Contralto/ROM/U61_2k and /dev/null differ
diff --git a/Contralto/ROM/U62_2k b/Contralto/ROM/U62_2k
deleted file mode 100644
index a283def..0000000
Binary files a/Contralto/ROM/U62_2k and /dev/null differ
diff --git a/Contralto/ROM/U63_2k b/Contralto/ROM/U63_2k
deleted file mode 100644
index eccc858..0000000
Binary files a/Contralto/ROM/U63_2k and /dev/null differ
diff --git a/Contralto/ROM/U64_2k b/Contralto/ROM/U64_2k
deleted file mode 100644
index 4ca9317..0000000
Binary files a/Contralto/ROM/U64_2k and /dev/null differ
diff --git a/Contralto/ROM/U65_2k b/Contralto/ROM/U65_2k
deleted file mode 100644
index 9b4b584..0000000
Binary files a/Contralto/ROM/U65_2k and /dev/null differ
diff --git a/Contralto/ROM/U70_2k b/Contralto/ROM/U70_2k
deleted file mode 100644
index c6f6188..0000000
Binary files a/Contralto/ROM/U70_2k and /dev/null differ
diff --git a/Contralto/ROM/U71_2k b/Contralto/ROM/U71_2k
deleted file mode 100644
index b4d5676..0000000
Binary files a/Contralto/ROM/U71_2k and /dev/null differ
diff --git a/Contralto/ROM/U72_2k b/Contralto/ROM/U72_2k
deleted file mode 100644
index e89dd81..0000000
Binary files a/Contralto/ROM/U72_2k and /dev/null differ
diff --git a/Contralto/ROM/U73_2k b/Contralto/ROM/U73_2k
deleted file mode 100644
index 3e3f017..0000000
Binary files a/Contralto/ROM/U73_2k and /dev/null differ
diff --git a/Contralto/ROM/U74_2k b/Contralto/ROM/U74_2k
deleted file mode 100644
index 808d30d..0000000
Binary files a/Contralto/ROM/U74_2k and /dev/null differ
diff --git a/Contralto/ROM/U75_2k b/Contralto/ROM/U75_2k
deleted file mode 100644
index 87eed96..0000000
Binary files a/Contralto/ROM/U75_2k and /dev/null differ
diff --git a/Contralto/Scheduler.cs b/Contralto/Scheduler.cs
index c62a5b0..7d52dbb 100644
--- a/Contralto/Scheduler.cs
+++ b/Contralto/Scheduler.cs
@@ -14,7 +14,7 @@ namespace Contralto
public delegate void SchedulerEventCallback(ulong timeNsec, ulong skewNsec, object context);
///
- ///
+ /// An Event represents a callback and associated context that is scheduled for a future timestamp.
///
public class Event
{
@@ -88,24 +88,20 @@ namespace Contralto
//
// See if we have any events waiting to fire at this timestep.
- //
- while (true)
- {
- if (_schedule.Top != null && _currentTimeNsec >= _schedule.Top.TimestampNsec)
- {
- // Pop the top event and fire the callback.
- Event e = _schedule.Pop();
- e.EventCallback(_currentTimeNsec, _currentTimeNsec - e.TimestampNsec, e.Context);
- }
- else
- {
- // All done.
- break;
- }
- }
+ //
+ while (_schedule.Top != null && _currentTimeNsec >= _schedule.Top.TimestampNsec)
+ {
+ // Pop the top event and fire the callback.
+ Event e = _schedule.Pop();
+ e.EventCallback(_currentTimeNsec, _currentTimeNsec - e.TimestampNsec, e.Context);
+ }
}
-
+ ///
+ /// Add a new event to the schedule.
+ ///
+ ///
+ ///
public Event Schedule(Event e)
{
e.TimestampNsec += _currentTimeNsec;
@@ -114,6 +110,10 @@ namespace Contralto
return e;
}
+ ///
+ /// Remove an event from the schedule.
+ ///
+ ///
public void CancelEvent(Event e)
{
_schedule.Remove(e);
diff --git a/Contralto/UI/AltoWindow.Designer.cs b/Contralto/UI/AltoWindow.Designer.cs
index 4d925f9..b7493a7 100644
--- a/Contralto/UI/AltoWindow.Designer.cs
+++ b/Contralto/UI/AltoWindow.Designer.cs
@@ -253,7 +253,7 @@
this.StatusLine.Size = new System.Drawing.Size(608, 25);
this.StatusLine.TabIndex = 3;
this.StatusLine.Text = "statusStrip1";
- this.StatusLine.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
+ this.StatusLine.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
//
// DiskStatusLabel
//