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