1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-19 09:28:00 +00:00

Fixed bug in carry flag on SUB operations; SUBLZ X,X now works correctly. Alto now appears to boot successfully. Skeleton of Display hardware added.

This commit is contained in:
Josh Dersch 2015-11-09 17:36:26 -08:00
parent e9a13529c1
commit e1c90dbe01
13 changed files with 182 additions and 13 deletions

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Contralto.CPU;
using Contralto.IO;
using Contralto.Memory;
using Contralto.Display;
namespace Contralto
{
@ -23,6 +24,7 @@ namespace Contralto
_mem = new Memory.Memory();
_keyboard = new Keyboard();
_diskController = new DiskController(this);
_displayController = new DisplayController(this);
// Attach memory-mapped devices to the bus
_memBus.AddDevice(_mem);
@ -32,7 +34,8 @@ namespace Contralto
_clockableDevices = new List<IClockable>();
_clockableDevices.Add(_memBus);
_clockableDevices.Add(_diskController);
_clockableDevices.Add(_cpu);
_clockableDevices.Add(_displayController);
_clockableDevices.Add(_cpu);
Reset();
}
@ -45,6 +48,7 @@ namespace Contralto
ALU.Reset();
Shifter.Reset();
_diskController.Reset();
_displayController.Reset();
}
public void SingleStep()
@ -85,6 +89,7 @@ namespace Contralto
private Contralto.Memory.Memory _mem;
private Keyboard _keyboard;
private DiskController _diskController;
private DisplayController _displayController;
private List<IClockable> _clockableDevices;
}

View File

@ -72,7 +72,7 @@ namespace Contralto.CPU
// addition (1s complement), a carry out means borrow; thus,
// a carry is generated when there is no underflow and no carry
// is generated when there is underflow."
_carry = (r <= 0) ? 0 : 1;
_carry = (r < 0) ? 0 : 1;
break;
case AluFunction.BusPlusT:
@ -82,12 +82,12 @@ namespace Contralto.CPU
case AluFunction.BusMinusT:
r = bus - t;
_carry = (r <= 0) ? 0 : 1;
_carry = (r < 0) ? 0 : 1;
break;
case AluFunction.BusMinusTMinus1:
r = bus - t - 1;
_carry = (r <= 0) ? 0 : 1;
_carry = (r < 0) ? 0 : 1;
break;
case AluFunction.BusPlusTPlus1:

View File

@ -31,6 +31,7 @@ namespace Contralto.CPU
_tasks[(int)TaskType.Emulator] = new EmulatorTask(this);
_tasks[(int)TaskType.DiskSector] = new DiskTask(this, true);
_tasks[(int)TaskType.DiskWord] = new DiskTask(this, false);
_tasks[(int)TaskType.DisplayWord] = new DisplayWordTask(this);
Reset();
}

View File

@ -135,6 +135,22 @@ namespace Contralto.CPU
ReadKDATA = 4,
}
enum DisplayWordF2
{
LoadDDR = 8,
}
enum DisplayHorizontalF2
{
EVENFIELD = 8,
SETMODE = 9,
}
enum DisplayVerticalF2
{
EVENFIELD = 8,
}
public class MicroInstruction
{
public MicroInstruction(UInt32 code)

View File

@ -143,6 +143,11 @@ namespace Contralto.CPU
// "...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);
if (_count != 1)
{
throw new NotImplementedException("magic LCY 8 not implemented yet.");
}
}
else if (_dns)
{

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Contralto.Memory;
namespace Contralto.CPU
{
public partial class AltoCPU
{
/// <summary>
/// DisplayWordTask provides functionality for the DWT task
/// </summary>
private class DisplayHorizontalTask : Task
{
public DisplayHorizontalTask(AltoCPU cpu) : base(cpu)
{
_taskType = TaskType.DisplayHorizontal;
// The Wakeup signal is always true for the Emulator task.
_wakeup = false;
}
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
{
DisplayWordF2 ef2 = (DisplayWordF2)instruction.F2;
switch (ef2)
{
case DisplayWordF2.LoadDDR:
break;
default:
throw new InvalidOperationException(String.Format("Unhandled display word F2 {0}.", ef2));
break;
}
}
}
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Contralto.Memory;
namespace Contralto.CPU
{
public partial class AltoCPU
{
/// <summary>
/// DisplayWordTask provides functionality for the DWT task
/// </summary>
private class DisplayWordTask : Task
{
public DisplayWordTask(AltoCPU cpu) : base(cpu)
{
_taskType = TaskType.DisplayWord;
// The Wakeup signal is always true for the Emulator task.
_wakeup = false;
}
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
{
DisplayWordF2 ef2 = (DisplayWordF2)instruction.F2;
switch (ef2)
{
case DisplayWordF2.LoadDDR:
break;
default:
throw new InvalidOperationException(String.Format("Unhandled display word F2 {0}.", ef2));
break;
}
}
}
}
}

View File

@ -76,8 +76,9 @@ namespace Contralto.CPU
break;
case EmulatorF1.STARTF:
// Dispatch function to I/O based on contents of AC0... (TBD: what are these?)
throw new NotImplementedException();
// Dispatch function to Ethernet I/O based on contents of AC0... (TBD: what are these?)
// For now do nothing, since we have no Ethernet implemented
//throw new NotImplementedException();
break;
case EmulatorF1.SWMODE:

View File

@ -409,8 +409,16 @@ namespace Contralto.CPU
return nextTask;
}
protected abstract ushort GetBusSource(int bs);
protected abstract void ExecuteSpecialFunction1(MicroInstruction instruction);
protected virtual ushort GetBusSource(int bs)
{
// Nothing by default.
return 0;
}
protected virtual void ExecuteSpecialFunction1(MicroInstruction instruction)
{
// Nothing by default
}
/// <summary>
/// Used to allow Task-specific F2s that need to modify RSELECT to do so.
@ -421,7 +429,10 @@ namespace Contralto.CPU
// Nothing by default.
}
protected abstract void ExecuteSpecialFunction2(MicroInstruction instruction);
protected virtual void ExecuteSpecialFunction2(MicroInstruction instruction)
{
// Nothing by default.
}
protected virtual void ExecuteSpecialFunction2Late(MicroInstruction instruction)
{

View File

@ -48,6 +48,8 @@
<Compile Include="CPU\ConstantMemory.cs" />
<Compile Include="CPU\CPU.cs" />
<Compile Include="CPU\NovaDisassembler.cs" />
<Compile Include="CPU\Tasks\DisplayHorizontalTask.cs" />
<Compile Include="CPU\Tasks\DisplayWordTask.cs" />
<Compile Include="CPU\UCodeDisassembler.cs" />
<Compile Include="CPU\Tasks\DiskTask.cs" />
<Compile Include="CPU\Tasks\EmulatorTask.cs" />
@ -61,6 +63,7 @@
<Compile Include="Debugger.Designer.cs">
<DependentUpon>Debugger.cs</DependentUpon>
</Compile>
<Compile Include="Display\DisplayController.cs" />
<Compile Include="IClockable.cs" />
<Compile Include="IO\DiskController.cs" />
<Compile Include="IO\DiabloPack.cs" />

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Contralto.Logging;
namespace Contralto.Display
{
/// <summary>
/// DisplayController implements hardware controlling the virtual electron beam
/// as it scans across the screen. It implements the logic of the display's sync generator
/// and wakes up the DVT and DHT tasks as necessary during a display field.
/// </summary>
public class DisplayController : IClockable
{
public DisplayController(AltoSystem system)
{
_system = system;
Reset();
}
public void Reset()
{
_evenField = true;
}
public void Clock()
{
// TODO: Move the electron beam appropriately and wake up the display tasks
// as necessary.
}
bool _evenField;
private AltoSystem _system;
}
}

View File

@ -368,7 +368,7 @@ namespace Contralto.IO
// And figure out how long this will take.
_seekClocks = CalculateSeekTime();
_elapsedSeekTime = 0.0;
Log.Write(LogComponent.DiskController, "Seek to {0} from {1} commencing. Will take {2} clocks.", _destCylinder, _cylinder, _seekClocks);
}
}
@ -384,7 +384,7 @@ namespace Contralto.IO
//
double seekTimeMsec = 15.0 + 8.6 * Math.Sqrt(dt);
return seekTimeMsec / AltoSystem.ClockInterval;
return (seekTimeMsec / AltoSystem.ClockInterval) / 100; // div 100 to make things faster for now
}
/// <summary>

View File

@ -34,10 +34,11 @@ namespace Contralto.Memory
address += 0x10000 * GetBankNumber(task, extendedMemory);
ushort data = _mem[address];
/*
if (extendedMemory)
{
Log.Write(LogComponent.Memory, "extended memory read from {0} - {1}", Conversion.ToOctal(address), Conversion.ToOctal(data));
}
} */
return data;
}
@ -59,10 +60,11 @@ namespace Contralto.Memory
address += 0x10000 * GetBankNumber(task, extendedMemory);
_mem[address] = data;
/*
if (extendedMemory)
{
Log.Write(LogComponent.Memory, "extended memory write to {0} of {1}", Conversion.ToOctal(address), Conversion.ToOctal(data));
}
} */
}
}