1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-21 02:07:30 +00:00

Cleanup of ugly Shifter code, a few tweaks to task-switch logic (now only calls OnTaskSwitch if a switch actually occurred), and moved back to .NET framework 4.5.2 (from 4.6) which works better on Mono.

This commit is contained in:
Josh Dersch 2016-09-06 12:48:33 -07:00
parent 2e47104e53
commit 7704bca35d
7 changed files with 110 additions and 148 deletions

View File

@ -6,10 +6,10 @@
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup>
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
<add key="EnableWindowsFormsHighDpiAutoResizing" value="false"/>
</appSettings>
<userSettings>
<Contralto.Properties.Settings>
@ -17,16 +17,16 @@
<value>2</value>
</setting>
<setting name="Drive0Image" serializeAs="String">
<value />
<value/>
</setting>
<setting name="Drive1Image" serializeAs="String">
<value />
<value/>
</setting>
<setting name="HostAddress" serializeAs="String">
<value>34</value>
</setting>
<setting name="HostPacketInterfaceName" serializeAs="String">
<value />
<value/>
</setting>
<setting name="HostPacketInterfaceType" serializeAs="String">
<value>0</value>

View File

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

View File

@ -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
}
/// <summary>
/// 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.
/// </summary>
public static int DNSCarry
{
get { return _dnsCarry; }
}
public static void SetOperation(ShifterOp op, int count)
{
_op = op;
_count = count;
}
/// <summary>
/// TODO: this is kind of clumsy.
/// </summary>
/// <param name="magic"></param>
public static void SetMagic(bool magic)
{
_magic = magic;
}
/// <summary>
/// TODO: this is still kind of clumsy.
/// </summary>
/// <param name="dns"></param>
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;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="input">Normal input to be shifted</param>
/// <param name="t">CPU t register, for MAGIC shifts only</param>
/// <param name="t">CPU t register, used for MAGIC shifts only</param>
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;
}
}

View File

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

View File

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

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Contralto</RootNamespace>
<AssemblyName>Contralto</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
@ -208,7 +208,9 @@
<ItemGroup>
<None Include="app.manifest" />
<None Include="Disassembly\altocode24.mu" />
<None Include="App.config" />
<None Include="App.config">
<SubType>Designer</SubType>
</None>
<None Include="Disassembly\altoIIcode3.mu">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

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