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

Fixed two microcode bugs related to task switching behavior. Dance, StarWars and *SMALLTALK* work!

This commit is contained in:
Josh Dersch 2016-03-09 16:05:45 -08:00
parent b6e43080f2
commit 4cbb74c033
19 changed files with 80 additions and 47 deletions

View File

@ -47,7 +47,7 @@ namespace Contralto
t.AutoReset = true;
t.Interval = 1000;
t.Elapsed += T_Elapsed;
//t.Start();
t.Start();
}
public void Reset()

View File

@ -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;
}
}
/// <summary>

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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.
/// </summary>
/// <returns>True if a task switch has been requested by a TASK instruction, false otherwise.</returns>
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)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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);
}

View File

@ -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;
/// <summary>
/// Temporary, for debugging floating point ucode issues
/// </summary>
@ -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 ******");
}
}