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:
parent
2e47104e53
commit
7704bca35d
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user