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); } } }