From 3976b3ec3c76e7c74ad81fad0714b2c11e3c71c8 Mon Sep 17 00:00:00 2001 From: jnosek Date: Fri, 3 Jul 2015 23:38:49 -0400 Subject: [PATCH] Added CS command The Clear And Subtract command --- AGC/AGC.csproj | 1 + AGC/Base/OnesCompliment.cs | 3 +- AGC/InstructionSet.cs | 1 + AGC/Instructions/ClearAndSubtract.cs | 40 ++++++++++++++++ AGC/Instructions/CountCompareAndSkip.cs | 6 +-- AGC/Processor.cs | 4 +- Tests/AGC.Tests/AGC.Tests.csproj | 1 + .../Instructions/ClearAndSubtract.cs | 48 +++++++++++++++++++ 8 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 AGC/Instructions/ClearAndSubtract.cs create mode 100644 Tests/AGC.Tests/Instructions/ClearAndSubtract.cs diff --git a/AGC/AGC.csproj b/AGC/AGC.csproj index 4228cb5..93fd596 100644 --- a/AGC/AGC.csproj +++ b/AGC/AGC.csproj @@ -44,6 +44,7 @@ + diff --git a/AGC/Base/OnesCompliment.cs b/AGC/Base/OnesCompliment.cs index 8f4335a..485c07c 100644 --- a/AGC/Base/OnesCompliment.cs +++ b/AGC/Base/OnesCompliment.cs @@ -44,7 +44,8 @@ public static ushort Add(this ushort left, ushort right) // if we have overflow, most likely from subtracting negative numbers if ((sum & 0x10000) > 0) { - // we need to Single Precision correct the negative number by adding 1 and taking the lower 16 bits + // we need to ones compliment correct the negative number by adding 1 and taking the lower 16 bits + // this process is called "end around carry" sum = sum + 1; sum = sum & 0xFFFF; } diff --git a/AGC/InstructionSet.cs b/AGC/InstructionSet.cs index ecaa2fe..7b222c9 100644 --- a/AGC/InstructionSet.cs +++ b/AGC/InstructionSet.cs @@ -21,6 +21,7 @@ public InstructionSet(Processor cpu) Add(new Add()); Add(new ClearAndAdd()); Add(new CountCompareAndSkip()); + Add(new ClearAndSubtract()); } public new IInstruction this[ushort code] diff --git a/AGC/Instructions/ClearAndSubtract.cs b/AGC/Instructions/ClearAndSubtract.cs new file mode 100644 index 0000000..4f570af --- /dev/null +++ b/AGC/Instructions/ClearAndSubtract.cs @@ -0,0 +1,40 @@ +using Apollo.Virtual.AGC.Base; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Apollo.Virtual.AGC.Instructions +{ + /// + /// CS - 0100 + /// + /// The "Clear and Subtract" instruction moves the 1's-complement (i.e., the negative) of a memory location into the accumulator. + /// + /// Also: + /// COM - 0100 0000 0000 0000 + /// The "Complement the Contents of A" bitwise complements the accumulator + /// Assembles as CS A + /// + class ClearAndSubtract : IInstruction + { + public ushort Code + { + get { return 0x4; } + } + + public Processor CPU { get; set; } + + public void Execute(ushort K) + { + var value = CPU.Memory[K]; + + // write the compliment to the accumulator + CPU.A.Write((ushort)~value); + + // if not the A register, re-write value to K + if (K != CPU.A.Address) + CPU.Memory[K] = value; + } + } +} diff --git a/AGC/Instructions/CountCompareAndSkip.cs b/AGC/Instructions/CountCompareAndSkip.cs index d64dd44..ee8fe24 100644 --- a/AGC/Instructions/CountCompareAndSkip.cs +++ b/AGC/Instructions/CountCompareAndSkip.cs @@ -27,12 +27,12 @@ public void Execute(ushort K) // 1) compute the Diminished ABSolute value found at K and set in A - // if negative, XOR 1's to get ABS + // if negative, NOT 1's to get ABS var isNegative = (value & 0x8000) > 0; - var abs = isNegative ? value ^ 0xFFFF : value; + var abs = (ushort)(isNegative ? ~value : value); if (abs > 1) - CPU.A.Write((ushort)(abs - 1)); + CPU.A.Write(abs.Add(OnesCompliment.NegativeOne)); else CPU.A.Write(0); diff --git a/AGC/Processor.cs b/AGC/Processor.cs index 25d6729..d01d97b 100644 --- a/AGC/Processor.cs +++ b/AGC/Processor.cs @@ -35,7 +35,7 @@ public class Processor /// The lower product after MP instructions /// also known as L /// - internal IWord LP; + internal IWord L; /// /// Remainder from the DV instruction, @@ -229,7 +229,7 @@ public Processor(MemoryMap memory) // main registers? A = memory.AddRegister(); - LP = memory.AddRegister(0x01); + L = memory.AddRegister(0x01); Q = memory.AddRegister(0x02); EB = memory.GetWord(0x3); FB = memory.GetWord(0x4); diff --git a/Tests/AGC.Tests/AGC.Tests.csproj b/Tests/AGC.Tests/AGC.Tests.csproj index 8e0330b..f46dbe7 100644 --- a/Tests/AGC.Tests/AGC.Tests.csproj +++ b/Tests/AGC.Tests/AGC.Tests.csproj @@ -57,6 +57,7 @@ + diff --git a/Tests/AGC.Tests/Instructions/ClearAndSubtract.cs b/Tests/AGC.Tests/Instructions/ClearAndSubtract.cs new file mode 100644 index 0000000..dda6b02 --- /dev/null +++ b/Tests/AGC.Tests/Instructions/ClearAndSubtract.cs @@ -0,0 +1,48 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AGC.Tests.Instructions +{ + [TestClass] + public class ClearAndSubtract : BaseTest + { + [TestMethod] + public void ClearAndSubtractAccumulator() + { + // arrange + Memory[0x0] = 0x0101; + + Memory.LoadFixedRom(new ushort[] { + 0x4000 + }); + + // act + CPU.Execute(); + + // assert + + Assert.AreEqual(0xFEFE, Memory[0x0]); + } + + [TestMethod] + public void ClearAndSubtractMemory() + { + // arrange + Memory[0x200] = 0xF0F0; + + Memory.LoadFixedRom(new ushort[] { + 0x4000 | 0x0200 + }); + + // act + CPU.Execute(); + + // assert + Assert.AreEqual(0x0F0F, Memory[0x0]); + } + } +}