diff --git a/app/src/main/java/hatelace/Computer.java b/app/src/main/java/hatelace/Computer.java index 9898561..50d762c 100644 --- a/app/src/main/java/hatelace/Computer.java +++ b/app/src/main/java/hatelace/Computer.java @@ -14,7 +14,7 @@ public class Computer { public void run() { // Note that the instructions themselves are responsible for incrementing the PC - for(ProgramCounter PC = new ProgramCounter(); PC.getPC() < this.program.size(); ) { + for(ProgramCounter PC = new ProgramCounter(); PC.getPC() < this.program.size() && !PC.halted() && PC.getSysTicks() < 100; ) { program.getInstructions()[PC.getPC()].execute(this.memory, PC); } } diff --git a/app/src/main/java/hatelace/IntMemory.java b/app/src/main/java/hatelace/IntMemory.java index 3be2faa..07f46c0 100644 --- a/app/src/main/java/hatelace/IntMemory.java +++ b/app/src/main/java/hatelace/IntMemory.java @@ -11,8 +11,8 @@ public class IntMemory extends Memory { this.memory = new int[size]; } - public int read(int address) { - return this.memory[address]; + public Word read(Address address) { + return new IntWord(this.memory[address.getAddress()]); } public int size() { diff --git a/app/src/main/java/hatelace/IntWord.java b/app/src/main/java/hatelace/IntWord.java index 2381cc2..4db7f87 100644 --- a/app/src/main/java/hatelace/IntWord.java +++ b/app/src/main/java/hatelace/IntWord.java @@ -31,4 +31,8 @@ public class IntWord extends Word { public String toString() { return value.toString(); } + + public boolean equals(Object other) { + return value.equals(((IntWord) other).getValue()); + } } diff --git a/app/src/main/java/hatelace/Main.java b/app/src/main/java/hatelace/Main.java index 85b8503..f06c53e 100644 --- a/app/src/main/java/hatelace/Main.java +++ b/app/src/main/java/hatelace/Main.java @@ -8,10 +8,18 @@ public class Main { Memory memory = new IntMemory(64); // 64 words of memory Computer computer = new Computer(memory); + + Address n = new Address(0), fac = new Address(1); + Program program = new Program(new Instruction[] { - new Add(new IntWord(1), new IntWord(1), new Address(0)), // Store 1 + 1 in address 0 - new Mul(new IntWord(2), new IntWord(2), new Address(1)), // Store 2 * 2 in address 1 - new Copy(new IntWord(3), new Address(2)) // Store 3 in address 2 + new Copy(new IntWord(5), n), + new Copy(new IntWord(1), fac), + new JumpEq(6, n, new IntWord(1)), + new Mul(fac, n, fac), + new Add(n, new IntWord(-1), n), + new Jump(2), + new Print(fac), + new Halt() }); computer.load(program); computer.run(); diff --git a/app/src/main/java/hatelace/Memory.java b/app/src/main/java/hatelace/Memory.java index 541a0d8..7a606c2 100644 --- a/app/src/main/java/hatelace/Memory.java +++ b/app/src/main/java/hatelace/Memory.java @@ -1,7 +1,7 @@ package hatelace; public abstract class Memory { - public abstract int read(int address); + public abstract Word read(Address address); public abstract int size(); public abstract void write(Address address, Word data); diff --git a/app/src/main/java/hatelace/ProgramCounter.java b/app/src/main/java/hatelace/ProgramCounter.java index 38dba7b..3089970 100644 --- a/app/src/main/java/hatelace/ProgramCounter.java +++ b/app/src/main/java/hatelace/ProgramCounter.java @@ -3,6 +3,9 @@ package hatelace; /** Simple class to represent the Program Counter */ public class ProgramCounter { private int PC; + private int SysTick; + + private boolean haltFlag; public ProgramCounter() { this.PC = 0; @@ -15,9 +18,28 @@ public class ProgramCounter { public int getPC() { return this.PC; } + + public int getSysTicks() { + return this.SysTick; + } public int incPC() { this.PC = this.PC + 1 <= 0 ? 0 : this.PC + 1; + this.SysTick += 1; return this.PC; } + + public int setPC(int PC) { + this.PC = PC; + this.SysTick += 1; + return this.PC; + } + + public boolean halted() { + return this.haltFlag; + } + + public void halt() { + this.haltFlag = true; + } } diff --git a/app/src/main/java/hatelace/Word.java b/app/src/main/java/hatelace/Word.java index f611c61..6ee37e8 100644 --- a/app/src/main/java/hatelace/Word.java +++ b/app/src/main/java/hatelace/Word.java @@ -7,4 +7,5 @@ public abstract class Word { public abstract Word multiply(Word other); public abstract Word divide(Word other); public abstract String toString(); + public abstract boolean equals(Object other); } diff --git a/app/src/main/java/hatelace/instructions/Add.java b/app/src/main/java/hatelace/instructions/Add.java index e17c023..84d4d46 100644 --- a/app/src/main/java/hatelace/instructions/Add.java +++ b/app/src/main/java/hatelace/instructions/Add.java @@ -7,18 +7,18 @@ import hatelace.Word; import hatelace.Address; public class Add extends Instruction { - private Word op1; + private Address op1; private Word op2; private Address dest; - public Add(Word op1, Word op2, Address dest) { + public Add(Address op1, Word op2, Address dest) { this.op1 = op1; this.op2 = op2; this.dest = dest; } public void execute(Memory memory, ProgramCounter PC) { - memory.write(this.dest, op1.add(op2)); + memory.write(this.dest, memory.read(this.op1).add(this.op2)); PC.incPC(); } diff --git a/app/src/main/java/hatelace/instructions/Halt.java b/app/src/main/java/hatelace/instructions/Halt.java new file mode 100644 index 0000000..20804d9 --- /dev/null +++ b/app/src/main/java/hatelace/instructions/Halt.java @@ -0,0 +1,23 @@ +package hatelace.instructions; + +import hatelace.*; + +public class Halt extends Instruction { + public Halt(){}; + + public void execute(Memory memory, ProgramCounter PC) { + PC.halt(); + } + + public String toString() { + return "HALT"; + } + + protected String opcode() { + return "halt"; + } + + protected Object[] operands() { + return new Object[] {}; + } +} diff --git a/app/src/main/java/hatelace/instructions/Jump.java b/app/src/main/java/hatelace/instructions/Jump.java new file mode 100644 index 0000000..4cd3b92 --- /dev/null +++ b/app/src/main/java/hatelace/instructions/Jump.java @@ -0,0 +1,23 @@ +package hatelace.instructions; + +import hatelace.*; + +public class Jump extends Instruction { + private int index; + + public Jump(int index) { + this.index = index; + } + + public void execute(Memory memory, ProgramCounter PC) { + PC.setPC(this.index); + } + + protected String opcode() { + return "jump"; + } + + protected Object[] operands() { + return new Object[] {this.index}; + } +} diff --git a/app/src/main/java/hatelace/instructions/JumpEq.java b/app/src/main/java/hatelace/instructions/JumpEq.java new file mode 100644 index 0000000..2491248 --- /dev/null +++ b/app/src/main/java/hatelace/instructions/JumpEq.java @@ -0,0 +1,31 @@ +package hatelace.instructions; + +import hatelace.*; + +public class JumpEq extends Instruction { + private int index; + private Address address; + private Word value; + + public JumpEq(int index, Address address, Word value) { + this.index = index; + this.address = address; + this.value = value; + } + + public void execute(Memory memory, ProgramCounter PC) { + if (this.value.equals(memory.read(this.address))) { + PC.setPC(this.index); + } else { + PC.incPC(); + } + } + + protected String opcode() { + return "jumpeq"; + } + + protected Object[] operands() { + return new Object[] {this.index, this.address, this.value}; + } +} diff --git a/app/src/main/java/hatelace/instructions/Mul.java b/app/src/main/java/hatelace/instructions/Mul.java index 6c587ed..0a265d2 100644 --- a/app/src/main/java/hatelace/instructions/Mul.java +++ b/app/src/main/java/hatelace/instructions/Mul.java @@ -1,24 +1,23 @@ package hatelace.instructions; import hatelace.Address; -import hatelace.Word; import hatelace.Instruction; import hatelace.Memory; import hatelace.ProgramCounter; public class Mul extends Instruction { - private Word op1; - private Word op2; + private Address op1; + private Address op2; private Address dest; - public Mul(Word op1, Word op2, Address dest) { + public Mul(Address op1, Address op2, Address dest) { this.op1 = op1; this.op2 = op2; this.dest = dest; } public void execute(Memory memory, ProgramCounter PC) { - memory.write(this.dest, op1.multiply(op2)); + memory.write(this.dest, memory.read(this.op1).multiply(memory.read(this.op2))); PC.incPC(); } diff --git a/app/src/main/java/hatelace/instructions/Print.java b/app/src/main/java/hatelace/instructions/Print.java new file mode 100644 index 0000000..6aa3cec --- /dev/null +++ b/app/src/main/java/hatelace/instructions/Print.java @@ -0,0 +1,24 @@ +package hatelace.instructions; + +import hatelace.*; + +public class Print extends Instruction { + private Address address; + + public Print(Address address) { + this.address = address; + } + + public void execute(Memory memory, ProgramCounter PC) { + System.out.println(memory.read(this.address)); + PC.incPC(); + } + + protected String opcode() { + return "print"; + } + + protected Object[] operands() { + return new Object[] {this.address}; + } +}