diff --git a/Contralto/CPU/ALU.cs b/Contralto/CPU/ALU.cs
index 1ecfc03..3db19f1 100644
--- a/Contralto/CPU/ALU.cs
+++ b/Contralto/CPU/ALU.cs
@@ -7,10 +7,21 @@ using System.Threading.Tasks;
namespace Contralto.CPU
{
// From Alto Hardware Manual, Section 2.1
-
-
-
- class ALU
+ static class ALU
{
+ static ALU()
+ {
+ _lastCarry = 0;
+ }
+
+
+
+ public static ushort Execute(AluFunction fn, ushort a, ushort b)
+ {
+
+ return 0;
+ }
+
+ private static ushort _lastCarry;
}
}
diff --git a/Contralto/CPU/ConstantMemory.cs b/Contralto/CPU/ConstantMemory.cs
new file mode 100644
index 0000000..1de60cb
--- /dev/null
+++ b/Contralto/CPU/ConstantMemory.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contralto.CPU
+{
+
+
+ static class ConstantMemory
+ {
+ static ConstantMemory()
+ {
+ Init();
+ }
+
+ private static void Init()
+ {
+ LoadConstants(_constantRoms);
+ }
+
+ public static ushort[] ConstantROM
+ {
+ get { return _constantRom; }
+ }
+
+ private static void LoadConstants(RomFile[] romInfo)
+ {
+ _constantRom = new ushort[256];
+
+ foreach (RomFile file in romInfo)
+ {
+ //
+ // Each file contains 256 bytes, each byte containing one nybble in the low 4 bits.
+ //
+ using (FileStream fs = new FileStream(Path.Combine("ROM", file.Filename), FileMode.Open, FileAccess.Read))
+ {
+ int length = (int)fs.Length;
+ if (length != 256)
+ {
+ throw new InvalidOperationException("ROM file should be 256 bytes in length");
+ }
+
+ byte[] data = new byte[fs.Length];
+ fs.Read(data, 0, (int)fs.Length);
+
+ // OR in the data
+ for (int i = 0; i < length; i++)
+ {
+ _constantRom[file.StartingAddress + i] |= (ushort)((data[AddressMap(i)] & 0xf) << file.BitPosition);
+ }
+ }
+ }
+ }
+
+ private static int AddressMap(int address)
+ {
+ int mappedAddress = (~address) & 0xff;
+ return mappedAddress;
+ }
+
+ private static RomFile[] _constantRoms =
+ {
+ new RomFile("c0", 0x000, 12),
+ new RomFile("c1", 0x000, 8),
+ new RomFile("c2", 0x000, 4),
+ new RomFile("c3", 0x000, 0),
+ };
+
+ private static UInt16[] _constantRom;
+ }
+}
diff --git a/Contralto/CPU/Shifter.cs b/Contralto/CPU/Shifter.cs
new file mode 100644
index 0000000..7113226
--- /dev/null
+++ b/Contralto/CPU/Shifter.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contralto.CPU
+{
+ public enum ShifterOp
+ {
+ Invalid = 0,
+ None,
+ ShiftLeft,
+ ShiftRight,
+ RotateLeft,
+ RotateRight
+ }
+
+ public static class Shifter
+ {
+ static Shifter()
+ {
+ _op = ShifterOp.Invalid;
+ }
+
+ public static void SetOperation(ShifterOp op, int count)
+ {
+ _op = op;
+ }
+
+ public static ushort DoOperation(ushort input)
+ {
+ ushort output = 0;
+ switch(_op)
+ {
+ case ShifterOp.Invalid:
+ throw new InvalidOperationException("Shifter op has not been set.");
+
+ case ShifterOp.None:
+ output = input;
+ break;
+
+ case ShifterOp.ShiftLeft:
+ output = (ushort)(input << _count);
+ break;
+
+ case ShifterOp.ShiftRight:
+ output = (ushort)(input >> _count);
+ break;
+
+ case ShifterOp.RotateLeft:
+ // 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);
+ }
+ break;
+
+ default:
+ throw new InvalidOperationException(String.Format("Unhandled shift operation {0}", _op));
+ }
+
+ return output;
+ }
+
+ private static ShifterOp _op;
+ private static int _count;
+ }
+}
diff --git a/Contralto/CPU/UCodeMemory.cs b/Contralto/CPU/UCodeMemory.cs
index a9d4c9c..279bb94 100644
--- a/Contralto/CPU/UCodeMemory.cs
+++ b/Contralto/CPU/UCodeMemory.cs
@@ -32,7 +32,6 @@ namespace Contralto.CPU
{
_uCodeRam = new UInt32[1024];
LoadMicrocode(_uCodeRoms);
- //_constantRom = LoadMicrocode(_constantRoms);
}
public static UInt32[] UCodeROM
@@ -40,6 +39,11 @@ namespace Contralto.CPU
get { return _uCodeRom; }
}
+ public static UInt32[] UCodeRAM
+ {
+ get { return _uCodeRam; }
+ }
+
private static void LoadMicrocode(RomFile[] romInfo)
{
_uCodeRom = new UInt32[2048];
@@ -69,9 +73,8 @@ namespace Contralto.CPU
}
// Invert the requisite bits just to make things easier; the high bits of F1 and F2 and the Load L bit are inverted
- // normally; we leave those alone.
+ // already; we leave those alone.
const UInt32 invertedBitMask = 0xfff77bff;
-
for(int i=0;i<_uCodeRom.Length;i++)
{
@@ -82,24 +85,8 @@ namespace Contralto.CPU
}
private static int AddressMap(int address)
- {
- //
- // For reasons lost to time, the address bits on the ucode PROMs are flipped
- // (that is, address bit 9 on the PROM chip is connected to address bit 0 on the Alto's
- // microcode address lines, and so on). The address bits are also inverted, so that's fun too.
- // We need to translate the 10-bit address appropriately by swapping the bits around.
- //
- int mappedAddress = (~address) & 0x3ff;
- /*
- int mappedAddress = 0;
- for(int i=0;i<10;i++)
- {
- if ((address & (1 << i)) != 0)
- {
- mappedAddress |= (1 << (9 - i));
- }
- } */
-
+ {
+ int mappedAddress = (~address) & 0x3ff;
return mappedAddress;
}
@@ -124,16 +111,10 @@ namespace Contralto.CPU
new RomFile("u70", 0x400, 8),
new RomFile("u71", 0x400, 4),
new RomFile("u72", 0x400, 0)
- };
-
- private static RomFile[] _constantRoms =
- {
-
- };
+ };
private static UInt32[] _uCodeRom;
- private static UInt32[] _uCodeRam;
- private static UInt16[] _constantRom;
+ private static UInt32[] _uCodeRam;
}
diff --git a/Contralto/Contralto.csproj b/Contralto/Contralto.csproj
index edfb337..006ea30 100644
--- a/Contralto/Contralto.csproj
+++ b/Contralto/Contralto.csproj
@@ -42,14 +42,28 @@
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Contralto/ROM/C0 b/Contralto/ROM/C0
new file mode 100644
index 0000000..c376cf2
Binary files /dev/null and b/Contralto/ROM/C0 differ
diff --git a/Contralto/ROM/C1 b/Contralto/ROM/C1
new file mode 100644
index 0000000..0f785b2
Binary files /dev/null and b/Contralto/ROM/C1 differ
diff --git a/Contralto/ROM/C3 b/Contralto/ROM/C3
new file mode 100644
index 0000000..68e488e
Binary files /dev/null and b/Contralto/ROM/C3 differ
diff --git a/Contralto/ROM/C4 b/Contralto/ROM/C4
new file mode 100644
index 0000000..9c5cc18
Binary files /dev/null and b/Contralto/ROM/C4 differ