diff --git a/AGC/AGC.csproj b/AGC/AGC.csproj
index 48a9dc7..eea698f 100644
--- a/AGC/AGC.csproj
+++ b/AGC/AGC.csproj
@@ -41,6 +41,12 @@
+
+
+
+
+
+
diff --git a/AGC/Base/IInstruction.cs b/AGC/Base/IInstruction.cs
new file mode 100644
index 0000000..5598f4e
--- /dev/null
+++ b/AGC/Base/IInstruction.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Apollo.Virtual.AGC.Base
+{
+ interface IInstruction
+ {
+ ushort Code { get; }
+
+ Processor CPU { get; set; }
+
+ void Execute(ushort K);
+ }
+}
diff --git a/AGC/Base/InstructionList.cs b/AGC/Base/InstructionList.cs
new file mode 100644
index 0000000..10029cd
--- /dev/null
+++ b/AGC/Base/InstructionList.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Apollo.Virtual.AGC.Base
+{
+ class InstructionList
+ {
+ private IInstruction[] array;
+
+ public InstructionList(int count)
+ {
+ array = new IInstruction[0];
+ }
+
+ public InstructionList()
+ : this(0)
+ {
+ }
+
+ public void Add(IInstruction instruction)
+ {
+ this[instruction.Code] = instruction;
+ }
+
+ public IInstruction this[ushort code]
+ {
+ get
+ {
+ if (code > array.Length - 1)
+ throw new IndexOutOfRangeException();
+
+ return array[code];
+ }
+ set
+ {
+ if(code > array.Length - 1)
+ Array.Resize(ref array, code + 1);
+
+ array[code] = value;
+ }
+ }
+
+ public void Clear()
+ {
+ array = new IInstruction[0];
+ }
+
+ public int Count
+ {
+ get { return array.Length; }
+ }
+ }
+}
diff --git a/AGC/InstructionSet.cs b/AGC/InstructionSet.cs
new file mode 100644
index 0000000..4494b34
--- /dev/null
+++ b/AGC/InstructionSet.cs
@@ -0,0 +1,32 @@
+using Apollo.Virtual.AGC.Base;
+using Apollo.Virtual.AGC.Instructions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Apollo.Virtual.AGC
+{
+ class InstructionSet
+ {
+ private Processor CPU;
+ private InstructionList instructions;
+
+ public InstructionSet(Processor cpu)
+ {
+ CPU = cpu;
+ instructions = new InstructionList(7);
+
+ instructions.Add(new QuarterCode { CPU = CPU });
+ instructions.Add(new Add { CPU = CPU });
+ }
+
+ public IInstruction this[ushort code]
+ {
+ get
+ {
+ return instructions[code];
+ }
+ }
+ }
+}
diff --git a/AGC/Instructions/Add.cs b/AGC/Instructions/Add.cs
new file mode 100644
index 0000000..adfee30
--- /dev/null
+++ b/AGC/Instructions/Add.cs
@@ -0,0 +1,29 @@
+using Apollo.Virtual.AGC.Base;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Apollo.Virtual.AGC.Instructions
+{
+ ///
+ /// AD - 0110
+ ///
+ /// Adds the value located in K to the accumulator
+ ///
+ class Add : IInstruction
+ {
+ public Processor CPU { get; set; }
+
+ public ushort Code { get { return 0x06; } }
+
+ public void Execute(ushort K)
+ {
+ var value = CPU.Memory[K];
+ CPU.A.Add(CPU.Memory[K]);
+
+ // value in K is re-written
+ CPU.Memory[K] = value;
+ }
+ }
+}
diff --git a/AGC/Instructions/AddToStorage.cs b/AGC/Instructions/AddToStorage.cs
new file mode 100644
index 0000000..978622b
--- /dev/null
+++ b/AGC/Instructions/AddToStorage.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
+{
+ ///
+ /// ADS - 0010 11
+ /// QuaterCode Instruction
+ ///
+ /// Adds the accumulator to an eraseable memory location and vice versa
+ ///
+ class AddToStorage : IInstruction
+ {
+ public ushort Code
+ {
+ get { return 0x02; }
+ }
+
+ public Processor CPU { get; set; }
+
+ public void Execute(ushort K)
+ {
+ var value = CPU.Memory[K];
+ CPU.A.Add(value);
+
+ CPU.Memory[K] = CPU.A.Read();
+ }
+ }
+}
diff --git a/AGC/Instructions/QuarterCode.cs b/AGC/Instructions/QuarterCode.cs
new file mode 100644
index 0000000..c4770df
--- /dev/null
+++ b/AGC/Instructions/QuarterCode.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
+{
+ ///
+ /// QC - 0010
+ ///
+ /// Operation on 10-bit address space operand restricted to eraseable memory
+ /// Followed by 2-bit quarter code for instruction
+ ///
+ class QuarterCode : IInstruction
+ {
+ private InstructionList instuctions;
+
+ public QuarterCode()
+ {
+ instuctions = new InstructionList(3);
+ instuctions.Add(new AddToStorage { CPU = this.CPU });
+ }
+
+ public ushort Code
+ {
+ get { return 0x02; }
+ }
+
+ public Processor CPU { get; set; }
+
+ public void Execute(ushort K)
+ {
+ var quarterCode = (ushort)(K >> 10);
+ K = (ushort)(K & 0x3FF);
+
+ instuctions[quarterCode].Execute(K);
+ }
+ }
+}
diff --git a/AGC/Processor.cs b/AGC/Processor.cs
index 65b2739..3136ad4 100644
--- a/AGC/Processor.cs
+++ b/AGC/Processor.cs
@@ -10,7 +10,9 @@ namespace Apollo.Virtual.AGC
public class Processor
{
- private MemoryMap memory;
+ internal MemoryMap Memory;
+
+ private InstructionSet instructions;
#region Register Definitions
@@ -209,7 +211,8 @@ public class Processor
public Processor(MemoryMap memory)
{
- this.memory = memory;
+ this.Memory = memory;
+ instructions = new InstructionSet(this);
// configure registers
@@ -262,67 +265,19 @@ public Processor(MemoryMap memory)
}
- // try some instructions
-
- ///
- /// AD - 0110
- ///
- /// Adds the value located in K to the accumulator
- ///
- public void Add(ushort K)
- {
- var value = memory[K];
- A.Add(memory[K]);
-
- // value in K is re-written
- memory[K] = value;
- }
-
- ///
- /// ADS - 0010 11
- /// Adds the accumulator to an eraseable memory location and vice versa
- ///
- ///
- public void AddToStorage(ushort K)
- {
- var value = memory[K];
- A.Add(value);
-
- memory[K] = A.Read();
- }
public void Execute()
{
// get address of instruction to run
- var address = memory.GetAddress(Z.Read());
+ var address = Memory.GetAddress(Z.Read());
// update Z
Z.Write((ushort)(Z.Read() + 1));
- var code = address.Read() >> 12;
- var operand = (ushort)(address.Read() & 0xFFF);
-
- switch (code)
- {
- // Add
- case 0x06:
- this.Add(operand);
- break;
-
- // Quarter Codes
- case 0x02:
- var quarterCode = operand >> 10;
- operand = (ushort)(operand & 0x3FF);
-
- switch (quarterCode)
- {
- case 0x02:
- this.AddToStorage(operand);
- break;
- }
-
- break;
- }
+ var code = (ushort)(address.Read() >> 12);
+ var K = (ushort)(address.Read() & 0xFFF);
+
+ instructions[code].Execute(K);
}
}
}