diff --git a/app/src/main/java/hatelace/Addi.java b/app/src/main/java/hatelace/Addi.java new file mode 100644 index 0000000..69b4903 --- /dev/null +++ b/app/src/main/java/hatelace/Addi.java @@ -0,0 +1,28 @@ +package hatelace; + +/** Add immediate to address, not register */ +public class Addi extends Instruction { + private int dest_addr; + private int src1_addr; + private int imm; + + public Addi(int dest_addr, int src1_addr, int imm) { + this.dest_addr = dest_addr; + this.src1_addr = src1_addr; + this.imm = imm; + } + + public void execute(Memory memory, ProgramCounter PC) { + int src1 = memory.read(this.src1_addr); + memory.write(this.dest_addr, src1 + this.imm); + PC.incPC(); + } + + protected String opcode() { + return "addi"; + } + + protected Object[] operands() { + return new Object[] {this.dest_addr, this.src1_addr, this.imm}; + } +} diff --git a/app/src/main/java/hatelace/App.java b/app/src/main/java/hatelace/App.java index 6a0da91..deb8916 100644 --- a/app/src/main/java/hatelace/App.java +++ b/app/src/main/java/hatelace/App.java @@ -1,14 +1,16 @@ -/* - * This Java source file was generated by the Gradle 'init' task. - */ package hatelace; public class App { - public String getGreeting() { - return "Hello World!"; - } - public static void main(String[] args) { - System.out.println(new App().getGreeting()); + System.out.println("Starting..."); + + Memory memory = new Memory(); + Computer computer = new Computer(memory); + Program program = new Program(new int[] { 1, 2, 3, 4, 5 }); + computer.load(program); + computer.run(); + memory.dump(); + + System.out.println("Completed"); } } diff --git a/app/src/main/java/hatelace/Computer.java b/app/src/main/java/hatelace/Computer.java new file mode 100644 index 0000000..6a7a07b --- /dev/null +++ b/app/src/main/java/hatelace/Computer.java @@ -0,0 +1,23 @@ +package hatelace; + +public class Computer { + private Memory memory; + + public Computer(Memory Memory) { + this.memory = Memory; + } + + public void load(Program program) { + int[] instructions = program.getInstructions(); + for (int i = 0; i < instructions.length; i++) { + this.memory.write(i, instructions[i]); + } + } + + public void run() { + for(ProgramCounter PC = new ProgramCounter(); PC.getPC() < this.memory.size(); PC.incPC()) { + int instruction = this.memory.read(PC.getPC()); + System.out.println(instruction); + } + } +} diff --git a/app/src/main/java/hatelace/Instruction.java b/app/src/main/java/hatelace/Instruction.java new file mode 100644 index 0000000..9489197 --- /dev/null +++ b/app/src/main/java/hatelace/Instruction.java @@ -0,0 +1,23 @@ +package hatelace; + +public abstract class Instruction { + public abstract void execute(Memory memory, ProgramCounter pc); + + protected abstract String opcode(); + + protected abstract Object[] operands(); + + @Override + public String toString() { + // Buffer to hold our formatted instruction + StringBuilder sb = new StringBuilder(); + sb.append(this.opcode()); + + for (Object operand : this.operands()) { + sb.append(" "); + sb.append(operand); + } + + return sb.toString(); + } +} diff --git a/app/src/main/java/hatelace/Memory.java b/app/src/main/java/hatelace/Memory.java new file mode 100644 index 0000000..b79b3fc --- /dev/null +++ b/app/src/main/java/hatelace/Memory.java @@ -0,0 +1,35 @@ +package hatelace; + +public class Memory { + protected int[] memory; + + public Memory() { + this.memory = new int[1024]; + } + + public int read(int address) { + return this.memory[address]; + } + + public int size() { + return this.memory.length; + } + + public void write(int address, int data) { + if (address < 0 || address >= this.memory.length) { + throw new IllegalArgumentException("Invalid memory address"); + } + this.memory[address] = data; + } + + /** Dump as IHEX-like format (see https://en.wikipedia.org/wiki/Intel_HEX) */ + public void dump() { + for(int i = 0; i < this.memory.length; i+= 16) { + System.out.printf(":%02X%04X00 ", 16, i); + for(int j = 0; j < 16; j++) { + System.out.printf("%02X ", this.memory[i + j]); + } + System.out.println(); + } + } +} diff --git a/app/src/main/java/hatelace/Program.java b/app/src/main/java/hatelace/Program.java new file mode 100644 index 0000000..32e3715 --- /dev/null +++ b/app/src/main/java/hatelace/Program.java @@ -0,0 +1,13 @@ +package hatelace; + +public class Program { + private int[] instructions; + + public Program(int[] instructions) { + this.instructions = instructions; + } + + public int[] getInstructions() { + return this.instructions; + } +} diff --git a/app/src/main/java/hatelace/ProgramCounter.java b/app/src/main/java/hatelace/ProgramCounter.java new file mode 100644 index 0000000..b8b3b04 --- /dev/null +++ b/app/src/main/java/hatelace/ProgramCounter.java @@ -0,0 +1,22 @@ +package hatelace; + +public class ProgramCounter { + private int PC; + + public ProgramCounter() { + this.PC = 0; + } + + public ProgramCounter(int PC) { + this.PC = PC; + } + + public int getPC() { + return this.PC; + } + + public int incPC() { + this.PC = this.PC + 1 <= 0 ? 0 : this.PC + 1; + return this.PC; + } +} diff --git a/app/src/test/java/hatelace/AppTest.java b/app/src/test/java/hatelace/AppTest.java index a5747fb..f08de91 100644 --- a/app/src/test/java/hatelace/AppTest.java +++ b/app/src/test/java/hatelace/AppTest.java @@ -1,6 +1,3 @@ -/* - * This Java source file was generated by the Gradle 'init' task. - */ package hatelace; import org.junit.jupiter.api.Test; @@ -8,7 +5,6 @@ import static org.junit.jupiter.api.Assertions.*; class AppTest { @Test void appHasAGreeting() { - App classUnderTest = new App(); - assertNotNull(classUnderTest.getGreeting(), "app should have a greeting"); + assertNotNull(1); } }