diff --git a/Contralto/AltoSystem.cs b/Contralto/AltoSystem.cs
index c262144..d2f6418 100644
--- a/Contralto/AltoSystem.cs
+++ b/Contralto/AltoSystem.cs
@@ -47,7 +47,7 @@ namespace Contralto
t.AutoReset = true;
t.Interval = 1000;
t.Elapsed += T_Elapsed;
- //t.Start();
+ t.Start();
}
public void Reset()
diff --git a/Contralto/CPU/CPU.cs b/Contralto/CPU/CPU.cs
index 80b5898..5e71484 100644
--- a/Contralto/CPU/CPU.cs
+++ b/Contralto/CPU/CPU.cs
@@ -121,18 +121,28 @@ namespace Contralto.CPU
public void Clock()
{
- if (_currentTask.ExecuteNext())
+ switch (_currentTask.ExecuteNext())
{
- // Invoke the task switch, this will take effect after
- // the NEXT instruction, not this one.
- TaskSwitch();
+ case InstructionCompletion.TaskSwitch:
+ // Invoke the task switch, this will take effect after
+ // the NEXT instruction completes, not this one.
+ TaskSwitch();
+ break;
+
+ case InstructionCompletion.Normal:
+ if (_nextTask != null)
+ {
+ // If we have a new task, switch to it now.
+ _currentTask = _nextTask;
+ _nextTask = null;
+ }
+ break;
+
+ case InstructionCompletion.MemoryWait:
+ // We were waiting for memory on this cycle, we do nothing
+ // (no task switch even if one is pending) in this case.
+ break;
}
- else if (_nextTask != null)
- {
- // If we have a new task, switch to it now.
- _currentTask = _nextTask;
- _nextTask = null;
- }
}
///
diff --git a/Contralto/CPU/Tasks/CursorTask.cs b/Contralto/CPU/Tasks/CursorTask.cs
index d3748a1..4d73647 100644
--- a/Contralto/CPU/Tasks/CursorTask.cs
+++ b/Contralto/CPU/Tasks/CursorTask.cs
@@ -15,7 +15,7 @@ namespace Contralto.CPU
_wakeup = false;
}
- protected override bool ExecuteInstruction(MicroInstruction instruction)
+ protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
// We put ourselves back to sleep immediately once we've started running
_wakeup = false;
diff --git a/Contralto/CPU/Tasks/DiskTask.cs b/Contralto/CPU/Tasks/DiskTask.cs
index 9b1eb8b..ecb2b61 100644
--- a/Contralto/CPU/Tasks/DiskTask.cs
+++ b/Contralto/CPU/Tasks/DiskTask.cs
@@ -21,11 +21,11 @@ namespace Contralto.CPU
_diskController = _cpu._system.DiskController;
}
- protected override bool ExecuteInstruction(MicroInstruction instruction)
+ protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
// Log.Write(LogComponent.Debug, "{0}: {1}", Conversion.ToOctal(_mpc), UCodeDisassembler.DisassembleInstruction(instruction, _taskType));
- bool task = base.ExecuteInstruction(instruction);
+ InstructionCompletion completion = base.ExecuteInstruction(instruction);
// 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.
@@ -37,7 +37,7 @@ namespace Contralto.CPU
_diskController.DisableSeclate();
}
- return task;
+ return completion;
}
protected override ushort GetBusSource(int bs)
diff --git a/Contralto/CPU/Tasks/DisplayHorizontalTask.cs b/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
index 790f9ac..bc39f0a 100644
--- a/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
+++ b/Contralto/CPU/Tasks/DisplayHorizontalTask.cs
@@ -18,7 +18,7 @@ namespace Contralto.CPU
_displayController = _cpu._system.DisplayController;
}
- protected override bool ExecuteInstruction(MicroInstruction instruction)
+ protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
// We put ourselves back to sleep immediately once we've started running
_wakeup = false;
diff --git a/Contralto/CPU/Tasks/DisplayVerticalTask.cs b/Contralto/CPU/Tasks/DisplayVerticalTask.cs
index b4d73f4..6047fa5 100644
--- a/Contralto/CPU/Tasks/DisplayVerticalTask.cs
+++ b/Contralto/CPU/Tasks/DisplayVerticalTask.cs
@@ -18,7 +18,7 @@ namespace Contralto.CPU
_displayController = _cpu._system.DisplayController;
}
- protected override bool ExecuteInstruction(MicroInstruction instruction)
+ protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
// We put ourselves back to sleep immediately once we've started running
_wakeup = false;
diff --git a/Contralto/CPU/Tasks/DisplayWordTask.cs b/Contralto/CPU/Tasks/DisplayWordTask.cs
index 89b7163..42095e0 100644
--- a/Contralto/CPU/Tasks/DisplayWordTask.cs
+++ b/Contralto/CPU/Tasks/DisplayWordTask.cs
@@ -19,7 +19,7 @@ namespace Contralto.CPU
_displayController = _cpu._system.DisplayController;
}
- protected override bool ExecuteInstruction(MicroInstruction instruction)
+ protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
// We remove our wakeup only if there isn't a wakeup being generated for us by the
// display controller.
diff --git a/Contralto/CPU/Tasks/EthernetTask.cs b/Contralto/CPU/Tasks/EthernetTask.cs
index 4dcd34c..6c0cd55 100644
--- a/Contralto/CPU/Tasks/EthernetTask.cs
+++ b/Contralto/CPU/Tasks/EthernetTask.cs
@@ -19,7 +19,7 @@ namespace Contralto.CPU
_ethernetController = _cpu._system.EthernetController;
}
- protected override bool ExecuteInstruction(MicroInstruction instruction)
+ protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
// The Ethernet task only remains awake if there are pending data wakeups
if (_ethernetController.CountdownWakeup)
diff --git a/Contralto/CPU/Tasks/MemoryRefreshTask.cs b/Contralto/CPU/Tasks/MemoryRefreshTask.cs
index d00348b..d4e7968 100644
--- a/Contralto/CPU/Tasks/MemoryRefreshTask.cs
+++ b/Contralto/CPU/Tasks/MemoryRefreshTask.cs
@@ -14,7 +14,7 @@
_wakeup = false;
}
- protected override bool ExecuteInstruction(MicroInstruction instruction)
+ protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
//
// Based on readings of the MRT microcode, the MRT keeps its wakeup
diff --git a/Contralto/CPU/Tasks/Task.cs b/Contralto/CPU/Tasks/Task.cs
index 2e3e395..53beb52 100644
--- a/Contralto/CPU/Tasks/Task.cs
+++ b/Contralto/CPU/Tasks/Task.cs
@@ -7,6 +7,13 @@ namespace Contralto.CPU
{
public partial class AltoCPU
{
+ public enum InstructionCompletion
+ {
+ Normal,
+ TaskSwitch,
+ MemoryWait,
+ }
+
// Task:
// Base task class: provides implementation for non-task-specific microcode execution and
// state. Task subclasses implement and execute Task-specific behavior and are called into
@@ -92,7 +99,7 @@ namespace Contralto.CPU
_wakeup = true;
}
- public bool ExecuteNext()
+ public InstructionCompletion ExecuteNext()
{
MicroInstruction instruction = UCodeMemory.GetInstruction(_mpc, _taskType);
@@ -108,9 +115,9 @@ namespace Contralto.CPU
/// provide their own overrides.
///
/// True if a task switch has been requested by a TASK instruction, false otherwise.
- protected virtual bool ExecuteInstruction(MicroInstruction instruction)
+ protected virtual InstructionCompletion ExecuteInstruction(MicroInstruction instruction)
{
- bool nextTask = false;
+ InstructionCompletion completion = InstructionCompletion.Normal;
bool swMode = false;
bool block = false;
ushort aluData;
@@ -135,7 +142,7 @@ namespace Contralto.CPU
if (!_cpu._system.MemoryBus.Ready(instruction.MemoryOperation))
{
// Suspend operation for this cycle.
- return false;
+ return InstructionCompletion.MemoryWait;
}
}
@@ -290,7 +297,8 @@ namespace Contralto.CPU
//
//if (!_firstInstructionAfterSwitch)
{
- nextTask = true; // Yield to other more important tasks
+ // Yield to other more important tasks
+ completion = InstructionCompletion.TaskSwitch;
}
break;
@@ -430,7 +438,12 @@ namespace Contralto.CPU
if (instruction.LoadL)
{
_cpu._l = aluData;
- _cpu._m = aluData;
+
+ // Only RAM-related tasks can modify M. (Currently only the Emulator.)
+ if (_taskType == TaskType.Emulator)
+ {
+ _cpu._m = aluData;
+ }
// Save ALUC0 for use in the next ALUCY special function.
_cpu._aluC0 = (ushort)ALU.Carry;
@@ -470,7 +483,7 @@ namespace Contralto.CPU
}
_firstInstructionAfterSwitch = false;
- return nextTask;
+ return completion;
}
protected virtual ushort GetBusSource(int bs)
diff --git a/Contralto/Disk/Josh.dsk b/Contralto/Disk/Josh.dsk
index 9ab1408..791a29d 100644
Binary files a/Contralto/Disk/Josh.dsk and b/Contralto/Disk/Josh.dsk differ
diff --git a/Contralto/Disk/allgames.dsk b/Contralto/Disk/allgames.dsk
index 7aabfb6..6e412a8 100644
Binary files a/Contralto/Disk/allgames.dsk and b/Contralto/Disk/allgames.dsk differ
diff --git a/Contralto/Disk/bravox.dsk b/Contralto/Disk/bravox.dsk
index b723972..4c390ac 100644
Binary files a/Contralto/Disk/bravox.dsk and b/Contralto/Disk/bravox.dsk differ
diff --git a/Contralto/Disk/diag.dsk b/Contralto/Disk/diag.dsk
index 1736cd9..f88bce1 100644
Binary files a/Contralto/Disk/diag.dsk and b/Contralto/Disk/diag.dsk differ
diff --git a/Contralto/Disk/st76boot.dsk b/Contralto/Disk/st76boot.dsk
index a87c2f5..ef56fbd 100644
Binary files a/Contralto/Disk/st76boot.dsk and b/Contralto/Disk/st76boot.dsk differ
diff --git a/Contralto/Disk/st76new.dsk b/Contralto/Disk/st76new.dsk
index a47b8cc..e386c02 100644
Binary files a/Contralto/Disk/st76new.dsk and b/Contralto/Disk/st76new.dsk differ
diff --git a/Contralto/Disk/xmsmall.dsk b/Contralto/Disk/xmsmall.dsk
index 6333a39..0e644fa 100644
Binary files a/Contralto/Disk/xmsmall.dsk and b/Contralto/Disk/xmsmall.dsk differ
diff --git a/Contralto/IO/DiskController.cs b/Contralto/IO/DiskController.cs
index 4b0eb26..6c5245e 100644
--- a/Contralto/IO/DiskController.cs
+++ b/Contralto/IO/DiskController.cs
@@ -609,7 +609,8 @@ namespace Contralto.IO
// From the Hardware Manual, pg 43:
// "Seek time (approx.): 15 + 8.6 * sqrt(dt) (msec)
//
- double seekTimeMsec = 15.0 + 8.6 * Math.Sqrt(dt);
+ //double seekTimeMsec = 15.0 + 8.6 * Math.Sqrt(dt);
+ double seekTimeMsec = 1.0; // why not just have this be fast for now.
return (ulong)(seekTimeMsec * Conversion.MsecToNsec);
}
diff --git a/Contralto/UI/Debugger.cs b/Contralto/UI/Debugger.cs
index f46bfd6..42c2227 100644
--- a/Contralto/UI/Debugger.cs
+++ b/Contralto/UI/Debugger.cs
@@ -808,6 +808,7 @@ namespace Contralto
case ExecutionType.NextNovaInstruction:
// For debugging floating point microcode:
+#if FLOAT_DEBUG
if (_system.CPU.CurrentTask.MPC == 0x10) // MPC is 20(octal) meaning a new Nova instruction.
{
if (_lastFPInstruction == 0)
@@ -823,7 +824,8 @@ namespace Contralto
// And see if this new one is also a floating point instruction...
FloatDebugPre(_system.MemoryBus.DebugReadWord(TaskType.Emulator, _system.CPU.R[6]));
}
- }
+ }
+#endif
// See if we need to stop here
if (_execAbort || // The Stop button was hit
@@ -855,6 +857,7 @@ namespace Contralto
return false;
}
+#if FLOAT_DEBUG
// vars for float debug
ushort _lastFPInstruction;
ushort _ac0;
@@ -864,6 +867,8 @@ namespace Contralto
ushort _fpRegAddr;
ushort _fpRegCount;
+ int _fpInstructionCount;
+
///
/// Temporary, for debugging floating point ucode issues
///
@@ -874,6 +879,8 @@ namespace Contralto
// Float instructions are from 70001-70022 octal
if (instruction >= 0x7000 && instruction <= 0x7012)
{
+ _fpInstructionCount++;
+
// Save instruction
_lastFPInstruction = instruction;
@@ -883,7 +890,7 @@ namespace Contralto
_ac2 = _system.CPU.R[1];
_ac3 = _system.CPU.R[0];
- Console.Write("FP: ");
+ Console.Write("{0}:FP: ", _fpInstructionCount);
switch (instruction)
{
case 0x7000:
@@ -967,7 +974,7 @@ namespace Contralto
case 0x7012:
Console.WriteLine("FEXP {0},{1} ({2})", _ac0, _ac1, GetFloat(_ac0));
break;
- }
+ }
/*
Console.WriteLine(" AC0={0} AC1={1} AC2={2} AC3={3}",
@@ -979,9 +986,9 @@ namespace Contralto
}
private void FloatDebugPost()
- {
+ {
- Console.Write("Post: ");
+ Console.Write("{0}:Post: ", _fpInstructionCount);
switch (_lastFPInstruction)
{
case 0x7000:
@@ -1142,23 +1149,24 @@ namespace Contralto
uint mantissa =
(uint)(_system.MemoryBus.DebugReadWord(TaskType.Emulator, (ushort)(addr + 2)) << 16) |
(uint)(_system.MemoryBus.DebugReadWord(TaskType.Emulator, (ushort)(addr + 3)));
-
- double val = 0.0;
+
+ double valMantissa = 0.0;
for (int i = 0; i < 32; i++)
{
double bit = (mantissa & (0x80000000 >> i)) != 0 ? 1.0 : 0.0;
- val += (bit * (1.0 / Math.Pow(2.0, (double)i)));
+ valMantissa += (bit * (1.0 / Math.Pow(2.0, (double)i)));
}
- val = sign * (val) * Math.Pow(2.0, exponent - 1);
+ double val = sign * (valMantissa) * Math.Pow(2.0, exponent - 1);
- if (double.IsInfinity(val) || double.IsNaN(val))
+ //if (double.IsInfinity(val) || double.IsNaN(val))
{
- Console.WriteLine(" ERROR: sign {0} exp {1} mantissa {2:x} value {3}",
+ Console.WriteLine(" Vec: sign {0} exp {1} mantissa {2:x} ({3}) value {4}",
sign,
exponent,
mantissa,
+ valMantissa,
val);
}
@@ -1199,28 +1207,29 @@ namespace Contralto
(uint)(_system.MemoryBus.DebugReadWord(TaskType.Emulator, (ushort)(reg + 2 * _fpRegCount)) << 16) |
(uint)(_system.MemoryBus.DebugReadWord(TaskType.Emulator, (ushort)(reg + 3 * _fpRegCount)));
- double val = 0.0;
+ double valMantissa = 0.0;
for (int i = 0; i < 32; i++)
{
double bit = (mantissa & (0x80000000 >> i)) != 0 ? 1.0 : 0.0;
- val += (bit * (1.0 / Math.Pow(2.0, (double)i)));
+ valMantissa += (bit * (1.0 / Math.Pow(2.0, (double)i)));
}
- val = sign * (val) * Math.Pow(2.0, exponent - 1);
+ double val = sign * (valMantissa) * Math.Pow(2.0, exponent - 1);
- if (double.IsInfinity(val) || double.IsNaN(val))
+ //if (double.IsInfinity(val) || double.IsNaN(val))
{
- Console.WriteLine(" ERROR: sign {0} exp {1} mantissa {2:x} value {3}",
+ Console.WriteLine(" UCode: sign {0} exp {1} mantissa {2:x} ({3}) value {4}",
sign,
exponent,
mantissa,
+ valMantissa,
val);
}
return val;
}
-
+#endif
private void SetExecutionState(ExecutionState state)
{
_execState = state;
@@ -1343,8 +1352,8 @@ namespace Contralto
private bool[] _novaBreakpointEnabled;
private void HackButton_Click(object sender, EventArgs e)
- {
- Logging.Log.LogComponents |= Logging.LogComponent.TaskSwitch;
+ {
+ //_system.CPU.HAX = true;
Log.Write(Logging.LogComponent.Debug, "***** HACK HIT ******");
}
}