From 1b18426c5cd5634a71c0ca96142107660c9e28ce Mon Sep 17 00:00:00 2001 From: Brent O'Neil Date: Sat, 30 Dec 2017 02:02:18 +1100 Subject: [PATCH] Added the Interupt (int ) and Return from Interupt (intr) command. Interupt pushes the flag register and the instruction pointer, then resets execution to 0x0200 + (imm)*2. Return from interupt pops the flags back and sets the ip. Returning execution to the interupting code. Implemented using a CPU hook that can be used to later implement interupts generated from hardware, or for errors like divide by 0. --- .../net/simon987/server/assembly/CPU.java | 14 ++++++-- .../net/simon987/server/assembly/Status.java | 16 +++++++++ .../assembly/instruction/IntInstruction.java | 35 +++++++++++++++++++ .../assembly/instruction/IntrInstruction.java | 26 ++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 Server/src/main/java/net/simon987/server/assembly/instruction/IntInstruction.java create mode 100644 Server/src/main/java/net/simon987/server/assembly/instruction/IntrInstruction.java diff --git a/Server/src/main/java/net/simon987/server/assembly/CPU.java b/Server/src/main/java/net/simon987/server/assembly/CPU.java index 0a8efe9..f8cfc3e 100755 --- a/Server/src/main/java/net/simon987/server/assembly/CPU.java +++ b/Server/src/main/java/net/simon987/server/assembly/CPU.java @@ -97,6 +97,8 @@ public class CPU implements JSONSerialisable { instructionSet.add(new JncInstruction(this)); instructionSet.add(new JnoInstruction(this)); instructionSet.add(new JoInstruction(this)); + instructionSet.add(new IntInstruction(this)); + instructionSet.add(new IntrInstruction(this)); status = new Status(); memory = new Memory(config.getInt("memory_size")); @@ -466,6 +468,14 @@ public class CPU implements JSONSerialisable { return attachedHardware.get(address); } - - + /** + * Sets the IP to 0x0200 + Offset and pushes flags then the old IP + * + */ + public void Interrupt(int hw, int offset, boolean retry) { + Instruction push = instructionSet.get("push"); + push.execute(status.toByte(), status); + push.execute(ip, status); + this.setIp((char)(0x0200 + offset*2 + 0x0080*hw)); + } } diff --git a/Server/src/main/java/net/simon987/server/assembly/Status.java b/Server/src/main/java/net/simon987/server/assembly/Status.java index 4b370a6..2bea560 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Status.java +++ b/Server/src/main/java/net/simon987/server/assembly/Status.java @@ -132,4 +132,20 @@ public class Status { public void setErrorFlag(boolean errorFlag) { this.errorFlag = errorFlag; } + + public char toByte() { + char stat = 0; + stat = (char) (stat | ((signFlag ? 1 : 0) << 3)); + stat = (char) (stat | ((zeroFlag ? 1 : 0) << 2)); + stat = (char) (stat | ((carryFlag ? 1 : 0) << 1)); + stat = (char) (stat | (overflowFlag ? 1 : 0)); + return stat; + } + + public void fromByte(char stat) { + setSignFlag((stat & (1 << 3)) != 0); + setZeroFlag((stat & (1 << 2)) != 0); + setCarryFlag((stat & (1 << 1)) != 0); + setOverflowFlag((stat & 1) != 0); + } } diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/IntInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/IntInstruction.java new file mode 100644 index 0000000..3a90690 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/IntInstruction.java @@ -0,0 +1,35 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.CPU; +import net.simon987.server.assembly.Instruction; +import net.simon987.server.assembly.Status; +/** + * Sets the PC to 0x0200 + Immediate operand + * + * + * + */ +public class IntInstruction extends Instruction{ + + public static final int OPCODE = 48; + private CPU cpu; + + public IntInstruction(CPU cpu) { + super("int", OPCODE); + this.cpu = cpu; + } + + @Override + public Status execute(int src, Status status) { + cpu.Interrupt(0, src, false); + return status; + } + + + public Status execute(Status status) { + cpu.Interrupt(0,0, false); + return status; + } + + +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/IntrInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/IntrInstruction.java new file mode 100644 index 0000000..feaf846 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/IntrInstruction.java @@ -0,0 +1,26 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.CPU; +import net.simon987.server.assembly.Instruction; +import net.simon987.server.assembly.Status; + +public class IntrInstruction extends Instruction{ + + public static final int OPCODE = 49; + private CPU cpu; + + public IntrInstruction(CPU cpu) { + super("intr", OPCODE); + this.cpu = cpu; + } + + public Status execute(Status status) { + cpu.setIp((char)cpu.getMemory().get(cpu.getRegisterSet().getRegister("SP").getValue())); + status.fromByte((char) cpu.getMemory().get(cpu.getRegisterSet().getRegister("SP").getValue() + 1)); + cpu.getRegisterSet().getRegister("SP").setValue(cpu.getRegisterSet().getRegister("SP").getValue() + 2); //Increment SP (stack grows towards smaller) + return status; + } + + +} +