diff --git a/Contralto/App.config b/Contralto/App.config
index d226eef..2c94bf2 100644
--- a/Contralto/App.config
+++ b/Contralto/App.config
@@ -6,10 +6,10 @@
-
+
-
+
@@ -17,16 +17,16 @@
2
-
+
-
+
34
-
+
0
diff --git a/Contralto/CPU/CPU.cs b/Contralto/CPU/CPU.cs
index dd0a6e4..f8e949f 100644
--- a/Contralto/CPU/CPU.cs
+++ b/Contralto/CPU/CPU.cs
@@ -130,10 +130,10 @@ namespace Contralto.CPU
}
// Execute the initial task switch.
+ _currentTask = null;
TaskSwitch();
- _currentTask = _nextTask;
- _nextTask = null;
+ _currentTask = _nextTask;
}
public void Clock()
@@ -146,14 +146,14 @@ namespace Contralto.CPU
TaskSwitch();
break;
- case InstructionCompletion.Normal:
- if (_nextTask != null)
+ case InstructionCompletion.Normal:
+ // If we have a new task, switch to it now.
+ if (_currentTask != _nextTask)
{
- // If we have a new task, switch to it now.
_currentTask = _nextTask;
- _nextTask = null;
- _currentTask.OnTaskSwitch();
- }
+ _currentTask.FirstInstructionAfterSwitch = true;
+ _currentTask.OnTaskSwitch();
+ }
break;
case InstructionCompletion.MemoryWait:
@@ -180,7 +180,7 @@ namespace Contralto.CPU
_tasks[i].SoftReset();
}
}
-
+
Log.Write(LogComponent.CPU, "Silent Boot; microcode banks initialized to {0}", Conversion.ToOctal(_rmr));
UCodeMemory.LoadBanksFromRMR(_rmr);
@@ -251,14 +251,13 @@ namespace Contralto.CPU
}
private void TaskSwitch()
- {
+ {
// Select the highest-priority eligible task
for (int i = _tasks.Length - 1; i >= 0; i--)
{
if (_tasks[i] != null && _tasks[i].Wakeup)
{
- _nextTask = _tasks[i];
- _nextTask.FirstInstructionAfterSwitch = true;
+ _nextTask = _tasks[i];
/*
if (_nextTask != _currentTask && _currentTask != null)
@@ -286,7 +285,7 @@ namespace Contralto.CPU
private ushort _aluC0;
// RMR (Reset Mode Register)
- ushort _rmr;
+ ushort _rmr;
// Task data
private Task _nextTask; // The task to switch two after the next microinstruction
diff --git a/Contralto/CPU/Shifter.cs b/Contralto/CPU/Shifter.cs
index 293bd5e..323d52d 100644
--- a/Contralto/CPU/Shifter.cs
+++ b/Contralto/CPU/Shifter.cs
@@ -24,8 +24,14 @@ namespace Contralto.CPU
None,
ShiftLeft,
ShiftRight,
- RotateLeft,
- RotateRight,
+ RotateLeft,
+ }
+
+ public enum ShifterModifier
+ {
+ None,
+ Magic,
+ DNS,
}
// NOTE: FOR NOVA (NOVEL) SHIFTS (from aug '76 manual):
@@ -43,11 +49,9 @@ namespace Contralto.CPU
public static void Reset()
{
- _op = ShifterOp.None;
- _count = 0;
+ _op = ShifterOp.None;
_output = 0;
- _magic = false;
- _dns = false;
+ _modifier = ShifterModifier.None;
_dnsCarry = 0;
}
@@ -66,50 +70,39 @@ namespace Contralto.CPU
}
///
- /// Returns the last DNS-style Carry bit from the last operation (via DoOperation).
+ /// Returns the last DNS-style Carry bit from the last operation (via DoOperation),
+ /// or sets the carry-in for the next DNS-style shift.
///
public static int DNSCarry
{
get { return _dnsCarry; }
- }
-
- public static void SetOperation(ShifterOp op, int count)
- {
- _op = op;
- _count = count;
- }
-
- ///
- /// TODO: this is kind of clumsy.
- ///
- ///
- public static void SetMagic(bool magic)
- {
- _magic = magic;
- }
-
- ///
- /// TODO: this is still kind of clumsy.
- ///
- ///
- public static void SetDNS(bool dns, int carry)
- {
- // Sanity check
- if (carry != 0 && carry != 1)
+ set
{
- throw new InvalidOperationException("carry can only be 0 or 1.");
+ // Sanity check
+ if (value != 0 && value != 1)
+ {
+ throw new InvalidOperationException("Invalid DNSCarry value.");
+ }
+ _dnsCarry = value;
}
-
- _dns = dns;
- _dnsCarry = carry;
}
+ public static void SetOperation(ShifterOp op)
+ {
+ _op = op;
+ }
+
+ public static void SetModifier(ShifterModifier mod)
+ {
+ _modifier = mod;
+ }
+
///
- /// Does the last specified operation to the specified inputs; the result
+ /// Does the last specified operation to the specified inputs; the result
/// can be read from Output.
///
/// Normal input to be shifted
- /// CPU t register, for MAGIC shifts only
+ /// CPU t register, used for MAGIC shifts only
public static ushort DoOperation(ushort input, ushort t)
{
switch(_op)
@@ -119,98 +112,65 @@ namespace Contralto.CPU
break;
case ShifterOp.ShiftLeft:
- _output = (ushort)(input << _count);
+ _output = (ushort)(input << 1);
- if (_magic)
+ switch (_modifier)
{
- // "MAGIC places the high order bit of T into the low order bit of the
- // shifter output on left shifts..."
- _output |= (ushort)((t & 0x8000) >> 15);
+ case ShifterModifier.Magic:
+ // "MAGIC places the high order bit of T into the low order bit of the
+ // shifter output on left shifts..."
+ _output |= (ushort)((t & 0x8000) >> 15);
+ break;
- if (_count != 1)
- {
- throw new NotImplementedException("magic LCY 8 not implemented yet.");
- }
- }
- else if (_dns)
- {
- //
- // "Rotate the 17 input bits left by one bit. This has the effect of rotating
- // bit 0 left into the carry position and the carry bit into bit 15."
- //
-
- // Put input carry into bit 15.
- _output = (ushort)(_output | _dnsCarry);
-
- // update carry
- _dnsCarry = ((input & 0x8000) >> 15);
+ case ShifterModifier.DNS:
+ //
+ // "Rotate the 17 input bits left by one bit. This has the effect of rotating
+ // bit 0 left into the carry position and the carry bit into bit 15."
+ //
+
+ // Put input carry into bit 15.
+ _output |= (ushort)(_dnsCarry);
+
+ // update carry
+ _dnsCarry = ((input & 0x8000) >> 15);
+ break;
}
+
break;
case ShifterOp.ShiftRight:
- _output = (ushort)(input >> _count);
+ _output = (ushort)(input >> 1);
- if (_magic)
+ switch (_modifier)
{
- // "...and places the low order bit of T into the high order bit position
- // of the shifter output on right shifts."
- _output |= (ushort)((t & 0x1) << 15);
+ case ShifterModifier.Magic:
+ _output |= (ushort)((t & 0x1) << 15);
+ break;
- if (_count != 1)
- {
- throw new NotImplementedException("magic LCY 8 not implemented yet.");
- }
- }
- else if (_dns)
- {
- //
- // "Rotate the 17 bits right by one bit. Bit 15 is rotated into the carry position
- // and the carry bit into bit 0."
- //
+ case ShifterModifier.DNS:
+ //
+ // "Rotate the 17 bits right by one bit. Bit 15 is rotated into the carry position
+ // and the carry bit into bit 0."
+ //
- // Put input carry into bit 0.
- _output |= (ushort)(_output | (_dnsCarry << 15));
+ // Put input carry into bit 0.
+ _output |= (ushort)(_dnsCarry << 15);
- // update carry
- _dnsCarry = input & 0x1;
+ // update carry
+ _dnsCarry = input & 0x1;
+ break;
}
break;
- case ShifterOp.RotateLeft:
- if (_dns)
- {
- //
- // "Swap the 8-bit halves of the 16-bit result. The carry is not affected."
- //
- _output = (ushort)(((input & 0xff00) >> 8) | ((input & 0x00ff) << 8));
- }
- else
- {
- // TODO: optimize, this is stupid
- _output = input;
- for (int i = 0; i < _count; i++)
- {
- int c = (_output & 0x8000) >> 15;
- _output = (ushort)((_output << 1) | c);
- }
- }
- break;
-
- case ShifterOp.RotateRight:
- // TODO: optimize, this is still stupid
- _output = input;
- for (int i = 0; i < _count; i++)
- {
- int c = (_output & 0x1) << 15;
- _output = (ushort)((_output >> 1) | c);
- }
-
- if (_dns)
- {
- // Should never happen
- throw new InvalidOperationException("DNS on Rotate Right, not possible.");
- }
- break;
+ case ShifterOp.RotateLeft:
+ //
+ // "Swap the 8-bit halves of the 16-bit result. The carry is not affected."
+ // NOTE: The hardware reference (Section 2) seems to indicate that L LCY 8 is modified by MAGIC and/or DNS,
+ // but this does not appear to actually be the case. Nothing in the documentation elsewhere, the microcode,
+ // or the schematics indicates that L LCY 8 ever does anything other than a simple swap.
+ //
+ _output = (ushort)(((input & 0xff00) >> 8) | ((input & 0x00ff) << 8));
+ break;
default:
throw new InvalidOperationException(String.Format("Unhandled shift operation {0}", _op));
@@ -220,10 +180,8 @@ namespace Contralto.CPU
}
private static ShifterOp _op;
- private static ushort _output;
- private static int _count;
- private static bool _magic;
- private static bool _dns;
+ private static ushort _output;
+ private static ShifterModifier _modifier;
private static int _dnsCarry;
}
}
diff --git a/Contralto/CPU/Tasks/EmulatorTask.cs b/Contralto/CPU/Tasks/EmulatorTask.cs
index 826035b..67866fc 100644
--- a/Contralto/CPU/Tasks/EmulatorTask.cs
+++ b/Contralto/CPU/Tasks/EmulatorTask.cs
@@ -302,7 +302,7 @@ namespace Contralto.CPU
break;
case EmulatorF2.MAGIC:
- Shifter.SetMagic(true);
+ Shifter.SetModifier(ShifterModifier.Magic);
break;
case EmulatorF2.LoadDNS:
@@ -361,11 +361,12 @@ namespace Contralto.CPU
carry = (~carry) & 0x1;
}
break;
- }
+ }
// Tell the Shifter to do a Nova-style shift with the
// given carry bit.
- Shifter.SetDNS(true, carry);
+ Shifter.SetModifier(ShifterModifier.DNS);
+ Shifter.DNSCarry = carry;
break;
diff --git a/Contralto/CPU/Tasks/Task.cs b/Contralto/CPU/Tasks/Task.cs
index e72b41b..0b520c5 100644
--- a/Contralto/CPU/Tasks/Task.cs
+++ b/Contralto/CPU/Tasks/Task.cs
@@ -202,7 +202,9 @@ namespace Contralto.CPU
break;
case BusSource.ReadMouse:
- _busData = _cpu._system.Mouse.PollMouseBits();
+ // "BUS[12-15]<-MOUSE; BUS[0-13]<- -1"
+ // (Note -- BUS[0-13] appears to be a typo, and should likely be BUS[0-11]).
+ _busData = (ushort)(_cpu._system.Mouse.PollMouseBits() | 0xfff0);
break;
case BusSource.ReadDisp:
@@ -338,15 +340,15 @@ namespace Contralto.CPU
break;
case SpecialFunction1.LLSH1:
- Shifter.SetOperation(ShifterOp.ShiftLeft, 1);
+ Shifter.SetOperation(ShifterOp.ShiftLeft);
break;
case SpecialFunction1.LRSH1:
- Shifter.SetOperation(ShifterOp.ShiftRight, 1);
+ Shifter.SetOperation(ShifterOp.ShiftRight);
break;
case SpecialFunction1.LLCY8:
- Shifter.SetOperation(ShifterOp.RotateLeft, 8);
+ Shifter.SetOperation(ShifterOp.RotateLeft);
break;
case SpecialFunction1.Constant:
@@ -518,7 +520,7 @@ namespace Contralto.CPU
//
if (swMode)
{
- //Log.Write(LogType.Verbose, LogComponent.Microcode, "SWMODE: uPC {0}, next uPC {1} (NEXT is {2})", Conversion.ToOctal(_mpc), Conversion.ToOctal(instruction.NEXT | nextModifier), Conversion.ToOctal(instruction.NEXT));
+ Log.Write(LogType.Verbose, LogComponent.Microcode, "SWMODE: uPC {0}, next uPC {1} (NEXT is {2})", Conversion.ToOctal(_mpc), Conversion.ToOctal(instruction.NEXT | nextModifier), Conversion.ToOctal(instruction.NEXT));
UCodeMemory.SwitchMode((ushort)(instruction.NEXT | nextModifier), _taskType);
}
diff --git a/Contralto/Contralto.csproj b/Contralto/Contralto.csproj
index 220f110..845ffea 100644
--- a/Contralto/Contralto.csproj
+++ b/Contralto/Contralto.csproj
@@ -9,7 +9,7 @@
Properties
Contralto
Contralto
- v4.6
+ v4.5.2
512
publish\
true
@@ -208,7 +208,9 @@
-
+
+ Designer
+
PreserveNewest
diff --git a/Contralto/Logging/Log.cs b/Contralto/Logging/Log.cs
index c5df200..a931bd6 100644
--- a/Contralto/Logging/Log.cs
+++ b/Contralto/Logging/Log.cs
@@ -74,7 +74,7 @@ namespace Contralto.Logging
{
// TODO: make configurable
_components = LogComponent.None; // LogComponent.HostNetworkInterface | LogComponent.EthernetPacket; // | LogComponent.HostEthernet | LogComponent.EthernetController; // LogComponent.DiskController | LogComponent.DiskSectorTask | LogComponent.Debug | LogComponent.CPU; // LogComponent.EthernetController; // | LogComponent.Microcode | LogComponent.Memory | LogComponent.CPU;
- _type = LogType.None; // LogType.Normal | LogType.Warning | LogType.Error | LogType.Verbose;
+ _type = LogType.Normal | LogType.Warning | LogType.Error | LogType.Verbose;
//_logStream = new StreamWriter("log.txt");
}