diff --git a/AGC/AGC.csproj b/AGC/AGC.csproj
index b3912b5..e16bef8 100644
--- a/AGC/AGC.csproj
+++ b/AGC/AGC.csproj
@@ -40,6 +40,8 @@
+
+
diff --git a/AGC/Base/FixedMemory.cs b/AGC/Base/FixedMemory.cs
index 7ccbde0..bf88b9c 100644
--- a/AGC/Base/FixedMemory.cs
+++ b/AGC/Base/FixedMemory.cs
@@ -16,7 +16,7 @@ public FixedMemory(MemoryAddress memory)
public void Write(ushort value)
{
- throw new InvalidOperationException("Cannot write to a fixed memory location");
+ //throw new InvalidOperationException("Cannot write to a fixed memory location");
}
public ushort Address
diff --git a/AGC/ExtraCodeInstructionSet.cs b/AGC/ExtraCodeInstructionSet.cs
index df5f226..3acf8ef 100644
--- a/AGC/ExtraCodeInstructionSet.cs
+++ b/AGC/ExtraCodeInstructionSet.cs
@@ -18,6 +18,7 @@ public ExtraCodeInstructionSet(Processor cpu)
Add(new BranchZeroToFixed { CPU = CPU });
Add(new ExtraQuarterCode(CPU));
+ Add(new BranchZeroOrMinusToFixed { CPU = CPU });
}
public new IInstruction this[ushort code]
diff --git a/AGC/InstructionSet.cs b/AGC/InstructionSet.cs
index dabd553..559d108 100644
--- a/AGC/InstructionSet.cs
+++ b/AGC/InstructionSet.cs
@@ -17,7 +17,8 @@ public InstructionSet(Processor cpu)
CPU = cpu;
Add(new TransferControl { CPU = CPU });
- Add(new QuarterCode { CPU = CPU });
+ Add(new QuarterCode(CPU));
+ Add(new ClearAndAdd { CPU = CPU });
Add(new Add { CPU = CPU });
}
diff --git a/AGC/Instructions/BranchZeroOrMinusToFixed.cs b/AGC/Instructions/BranchZeroOrMinusToFixed.cs
new file mode 100644
index 0000000..367f806
--- /dev/null
+++ b/AGC/Instructions/BranchZeroOrMinusToFixed.cs
@@ -0,0 +1,32 @@
+using Apollo.Virtual.AGC.Base;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Apollo.Virtual.AGC.Instructions
+{
+ ///
+ /// BZMF - EX 0110
+ ///
+ /// Jumps to a fixed memory location if the accumulator is 0 or negative
+ ///
+ class BranchZeroOrMinusToFixed : IInstruction
+ {
+ public ushort Code
+ {
+ get { return 0x06; }
+ }
+
+ public Processor CPU { get; set; }
+
+ public void Execute(ushort K)
+ {
+ var value = CPU.A.Read();
+
+ // if +0 or negative, jump
+ if (value == 0 || (value & 0x8000) > 0)
+ CPU.Z.Write(K);
+ }
+ }
+}
diff --git a/AGC/Instructions/BranchZeroToFixed.cs b/AGC/Instructions/BranchZeroToFixed.cs
index 73e8787..665d650 100644
--- a/AGC/Instructions/BranchZeroToFixed.cs
+++ b/AGC/Instructions/BranchZeroToFixed.cs
@@ -9,7 +9,7 @@ namespace Apollo.Virtual.AGC.Instructions
///
/// BZF - EX 0001
///
- /// Jumps to a memory location in the fixed bank if the accumulator is 0
+ /// Jumps to a fixed memory location if the accumulator is 0
///
class BranchZeroToFixed : IInstruction
{
@@ -22,7 +22,14 @@ public ushort Code
public void Execute(ushort K)
{
- if (CPU.A.Read() == 0)
+ // if in overflow, no jump
+ if(CPU.A.IsOverflow)
+ return;
+
+ var value = CPU.A.Read();
+
+ // if +0 or -0, then jump
+ if (value == 0 || value == SinglePrecision.NegativeZero)
CPU.Z.Write(K);
}
}
diff --git a/AGC/Instructions/ClearAndAdd.cs b/AGC/Instructions/ClearAndAdd.cs
new file mode 100644
index 0000000..bb560ad
--- /dev/null
+++ b/AGC/Instructions/ClearAndAdd.cs
@@ -0,0 +1,34 @@
+using Apollo.Virtual.AGC.Base;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Apollo.Virtual.AGC.Instructions
+{
+ ///
+ /// CA - 0011
+ ///
+ /// Moves the contents of memory at location K into the accumulator
+ ///
+ class ClearAndAdd : IInstruction
+ {
+ public ushort Code
+ {
+ get { return 0x3; }
+ }
+
+ public Processor CPU { get; set; }
+
+ public void Execute(ushort K)
+ {
+ var value = CPU.Memory[K];
+
+ // set value in accumulator
+ CPU.A.Write(value);
+
+ // value in K is re-written
+ CPU.Memory[K] = value;
+ }
+ }
+}
diff --git a/AGC/Instructions/QuarterCode.cs b/AGC/Instructions/QuarterCode.cs
index b94006d..f169133 100644
--- a/AGC/Instructions/QuarterCode.cs
+++ b/AGC/Instructions/QuarterCode.cs
@@ -14,8 +14,10 @@ namespace Apollo.Virtual.AGC.Instructions
///
class QuarterCode : InstructionList, IInstruction
{
- public QuarterCode() : base(3)
+ public QuarterCode(Processor CPU) : base(3)
{
+ this.CPU = CPU;
+
Add(new AddToStorage { CPU = this.CPU });
}
diff --git a/AGC/Registers/FullRegister.cs b/AGC/Registers/FullRegister.cs
index e43ea60..8043219 100644
--- a/AGC/Registers/FullRegister.cs
+++ b/AGC/Registers/FullRegister.cs
@@ -28,6 +28,17 @@ public ushort Read()
return memory.Read();
}
+ public bool IsOverflow
+ {
+ get
+ {
+ // look at bits 16 and 15 to see if they are different
+ var value = (ushort)(Read() & 0xC000);
+
+ return value == 0x8000 || value == 0x4000;
+ }
+ }
+
MemoryAddress IRegister.Memory
{
set { this.memory = value; }
diff --git a/Tests/AGC.Tests/AGC.Tests.csproj b/Tests/AGC.Tests/AGC.Tests.csproj
index 2c5144e..c399a66 100644
--- a/Tests/AGC.Tests/AGC.Tests.csproj
+++ b/Tests/AGC.Tests/AGC.Tests.csproj
@@ -52,7 +52,11 @@
+
+
+
+
diff --git a/Tests/AGC.Tests/Instructions/Add.cs b/Tests/AGC.Tests/Instructions/Add.cs
index a5fabd2..97323cb 100644
--- a/Tests/AGC.Tests/Instructions/Add.cs
+++ b/Tests/AGC.Tests/Instructions/Add.cs
@@ -18,13 +18,13 @@ public void AddTwoPositiveNumbers()
Memory[0x200] = 10;
Memory[0x201] = 15;
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -39,13 +39,13 @@ public void AddTwoNegativeNumbers()
Memory[0x200] = SinglePrecision.To(-10);
Memory[0x201] = SinglePrecision.To(-15);
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -60,13 +60,13 @@ public void AddPostive1AndNegative1()
Memory[0x200] = SinglePrecision.To(-10);
Memory[0x201] = 15;
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -81,13 +81,13 @@ public void AddTwoNumbersThatEqualNegativeZero()
Memory[0x200] = 0xC000; // most negative number 15 bit number
Memory[0x201] = SinglePrecision.To(-1);
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -105,13 +105,13 @@ public void AddTwoNumbersThatEqualPositiveZero()
Memory[0x200] = 0x3FFF; // most positive number 15 bit number
Memory[0x201] = 1;
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -129,13 +129,13 @@ public void AddTwoNegativeNumbersThatCauseUnderflow()
Memory[0x200] = 0xC000; // most negative number 15 bit number
Memory[0x201] = SinglePrecision.To(-3);
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -153,13 +153,13 @@ public void AddTwoPositiveNumbersThatCauseOverflow()
Memory[0x200] = 0x3FFF; // most positive number 15 bit number
Memory[0x201] = 3;
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -177,13 +177,13 @@ public void AddNegativeZeroAndPositiveNumber()
Memory[0x200] = SinglePrecision.NegativeZero;
Memory[0x201] = 4;
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -201,13 +201,13 @@ public void AddNegativeZeroAndNegativeNumber()
Memory[0x200] = SinglePrecision.NegativeZero;
Memory[0x201] = SinglePrecision.To(-4);
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x06000 | 0x200,
0x06000 | 0x201
});
- // act - run the additions
+ // act - run the instructions
CPU.Execute();
CPU.Execute();
@@ -217,5 +217,29 @@ public void AddNegativeZeroAndNegativeNumber()
// assert
Assert.AreEqual(SinglePrecision.To(-4), Memory[0x202]);
}
+
+ [TestMethod]
+ public void Add1AndNegative1EqualsNegative0()
+ {
+ // arrange
+ Memory[0x200] = 0x01;
+ Memory[0x201] = SinglePrecision.To(-1);
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x06000 | 0x200,
+ 0x06000 | 0x201
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ //save acumulator value to a place in memory so we can view the overflow corrected value, for now
+ Memory[0x202] = Memory[0x0];
+
+ // assert
+ Assert.AreEqual(SinglePrecision.NegativeZero, Memory[0x202]);
+ }
}
}
diff --git a/Tests/AGC.Tests/Instructions/AddToStorage.cs b/Tests/AGC.Tests/Instructions/AddToStorage.cs
new file mode 100644
index 0000000..f1811f2
--- /dev/null
+++ b/Tests/AGC.Tests/Instructions/AddToStorage.cs
@@ -0,0 +1,56 @@
+using Apollo.Virtual.AGC.Base;
+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 AddToStorage : BaseTest
+ {
+ [TestMethod]
+ public void AddToStorageTwoPositiveNumbers()
+ {
+ // arrange
+ Memory[0x000] = 10;
+ Memory[0x201] = 15;
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x02C00 | 0x201
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+ Assert.AreEqual(25, Memory[0x0]);
+ Assert.AreEqual(25, Memory[0x201]);
+ }
+
+ [TestMethod]
+ public void AddToStorageTwoNegativeNumbers()
+ {
+ // arrange
+ Memory[0x000] = SinglePrecision.To(-10);
+ Memory[0x201] = SinglePrecision.To(-15);
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x02C00 | 0x201
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+ Assert.AreEqual(SinglePrecision.To(-25), Memory[0x0]);
+ Assert.AreEqual(SinglePrecision.To(-25), Memory[0x201]);
+ }
+ }
+}
diff --git a/Tests/AGC.Tests/Instructions/Augment.cs b/Tests/AGC.Tests/Instructions/Augment.cs
index 2357539..2e72620 100644
--- a/Tests/AGC.Tests/Instructions/Augment.cs
+++ b/Tests/AGC.Tests/Instructions/Augment.cs
@@ -17,7 +17,7 @@ public void AugmentPositiveNumber()
// arrange
Memory[0x200] = 10;
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x00006, // EXTEND instruction
0x02800 | 0x200
@@ -37,7 +37,7 @@ public void AugmentNegativeNumber()
// arrange
Memory[0x200] = SinglePrecision.To(-10);
- // insert add instructions
+ // insert instructions
Memory.LoadFixedRom(new ushort[] {
0x00006, // EXTEND instruction
0x02800 | 0x200
diff --git a/Tests/AGC.Tests/Instructions/BranchZeroOrMinusToFixed.cs b/Tests/AGC.Tests/Instructions/BranchZeroOrMinusToFixed.cs
new file mode 100644
index 0000000..8b06c53
--- /dev/null
+++ b/Tests/AGC.Tests/Instructions/BranchZeroOrMinusToFixed.cs
@@ -0,0 +1,102 @@
+using Apollo.Virtual.AGC.Base;
+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 BranchZeroOrMinusToFixed : BaseTest
+ {
+ [TestMethod]
+ public void BranchZeroOrMinusToFixedPositiveZero()
+ {
+ // arrange
+ Memory[0x0] = 0;
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x00006, // EXTEND instruction
+ 0x06000 | 0x400 // instruction and address in fixed memory
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+
+ // check for address to jump to in Z register
+ Assert.AreEqual(0x400, Memory[0x005]);
+ }
+
+ [TestMethod]
+ public void BranchZeroOrMinusToFixedNegativeZero()
+ {
+ // arrange
+ Memory[0x0] = SinglePrecision.NegativeZero;
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x00006, // EXTEND instruction
+ 0x06000 | 0x500 // instruction and address in fixed memory
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+
+ // check for address to jump to in Z register
+ Assert.AreEqual(0x500, Memory[0x005]);
+ }
+
+ [TestMethod]
+ public void BranchZeroOrMinusToFixedNegative()
+ {
+ // arrange
+ Memory[0x0] = SinglePrecision.To(-5);
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x00006, // EXTEND instruction
+ 0x06000 | 0x500 // instruction and address in fixed memory
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+
+ // check for address to jump to in Z register
+ Assert.AreEqual(0x500, Memory[0x005]);
+ }
+
+ [TestMethod]
+ public void BranchZeroOrMinusToFixedNoJump()
+ {
+ // arrange
+ Memory[0x0] = 5;
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x00006, // EXTEND instruction
+ 0x06000 | 0x500 // instruction and address in fixed memory
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+
+ // check for address to jump to in Z register
+ Assert.AreEqual(0x802, Memory[0x005]);
+ }
+ }
+}
diff --git a/Tests/AGC.Tests/Instructions/BranchZeroToFixed.cs b/Tests/AGC.Tests/Instructions/BranchZeroToFixed.cs
new file mode 100644
index 0000000..9ec5bd3
--- /dev/null
+++ b/Tests/AGC.Tests/Instructions/BranchZeroToFixed.cs
@@ -0,0 +1,80 @@
+using Apollo.Virtual.AGC.Base;
+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 BranchZeroToFixed : BaseTest
+ {
+ [TestMethod]
+ public void BranchZeroToFixedPositiveZero()
+ {
+ // arrange
+ Memory[0x0] = 0;
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x00006, // EXTEND instruction
+ 0x01000 | 0x400 // instruction and address in fixed memory
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+
+ // check for address to jump to in Z register
+ Assert.AreEqual(0x400, Memory[0x005]);
+ }
+
+ [TestMethod]
+ public void BranchZeroToFixedNegativeZero()
+ {
+ // arrange
+ Memory[0x0] = SinglePrecision.NegativeZero;
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x00006, // EXTEND instruction
+ 0x01000 | 0x500 // instruction and address in fixed memory
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+
+ // check for address to jump to in Z register
+ Assert.AreEqual(0x500, Memory[0x005]);
+ }
+
+ [TestMethod]
+ public void BranchZeroToFixedNoJump()
+ {
+ // arrange
+ Memory[0x0] = 5;
+
+ // insert instructions
+ Memory.LoadFixedRom(new ushort[] {
+ 0x00006, // EXTEND instruction
+ 0x01000 | 0x500 // instruction and address in fixed memory
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+ CPU.Execute();
+
+ // assert
+
+ // check for address to jump to in Z register
+ Assert.AreEqual(0x802, Memory[0x005]);
+ }
+ }
+}
diff --git a/Tests/AGC.Tests/Instructions/UnitTest1.cs b/Tests/AGC.Tests/Instructions/UnitTest1.cs
new file mode 100644
index 0000000..bfe791b
--- /dev/null
+++ b/Tests/AGC.Tests/Instructions/UnitTest1.cs
@@ -0,0 +1,49 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace AGC.Tests.Instructions
+{
+ [TestClass]
+ public class ClearAndAdd : BaseTest
+ {
+ [TestMethod]
+ public void ClearAndAddFixedMemory()
+ {
+ // arrange
+
+ // insert instructions and test data
+ Memory.LoadFixedRom(new ushort[] {
+ 0x03000 | 0x801, // CA instruction and address
+ 10 //value
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+
+ // assert
+
+ // check for value in the accumulator
+ Assert.AreEqual(10, Memory[0x0]);
+ }
+
+ [TestMethod]
+ public void ClearAndAddEraseableMemory()
+ {
+ // arrange
+ Memory[0x200] = 10;
+
+ // insert instructions and test data
+ Memory.LoadFixedRom(new ushort[] {
+ 0x03000 | 0x200 // CA instruction and address
+ });
+
+ // act - run the instructions
+ CPU.Execute();
+
+ // assert
+
+ // check for value in the accumulator
+ Assert.AreEqual(10, Memory[0x0]);
+ }
+ }
+}