From deb3859dffce1c82b858b31787adecabc29954df Mon Sep 17 00:00:00 2001 From: Ethan Lafrenais Date: Sun, 31 Dec 2017 18:25:46 -0500 Subject: [PATCH] Add PUSHF and POPF instructions --- .../net/simon987/server/assembly/CPU.java | 2 + .../net/simon987/server/assembly/Status.java | 16 +++++++ .../assembly/instruction/PopfInstruction.java | 46 +++++++++++++++++++ .../instruction/PushfInstruction.java | 42 +++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 Server/src/main/java/net/simon987/server/assembly/instruction/PopfInstruction.java create mode 100644 Server/src/main/java/net/simon987/server/assembly/instruction/PushfInstruction.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 50b49e4..a2e9966 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 PushfInstruction(this)); + instructionSet.add(new PopfInstruction(this)); status = new Status(); memory = new Memory(config.getInt("memory_size")); 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..f812e80 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/PopfInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/PopfInstruction.java new file mode 100644 index 0000000..2ec374b --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/PopfInstruction.java @@ -0,0 +1,46 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.CPU; +import net.simon987.server.assembly.Instruction; +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.Status; + +/** + * Pops a single word off the top of the stack and sets the CPU flags to it. + */ +public class PopfInstruction extends Instruction { + + /** + * Opcode of the instruction + */ + public static final int OPCODE = 44; + + private CPU cpu; + + public PopfInstruction(CPU cpu) { + super("popf", OPCODE); + + this.cpu = cpu; + } + + @Override + public Status execute(Status status) { + + Register sp = cpu.getRegisterSet().getRegister("SP"); + + // Get the word on the top of the stack + char flags = (char) cpu.getMemory().get(sp.getValue()); + + // Overwrite the CPU flags + status.fromByte(flags); + + // Increment SP + sp.setValue(sp.getValue() + 1); + + return status; + } + + public boolean noOperandsValid() { + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/PushfInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/PushfInstruction.java new file mode 100644 index 0000000..efa54ca --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/PushfInstruction.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.CPU; +import net.simon987.server.assembly.Instruction; +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.Status; + +/** + * Pushes the current CPU flags onto the stack. + */ +public class PushfInstruction extends Instruction { + + /** + * Opcode of the instruction + */ + public static final int OPCODE = 43; + + private CPU cpu; + + public PushfInstruction(CPU cpu) { + super("pushf", OPCODE); + + this.cpu = cpu; + } + + @Override + public Status execute(Status status) { + + // Decrement SP + Register sp = cpu.getRegisterSet().getRegister("SP"); + sp.setValue(sp.getValue() - 1); + + // Push the current flags + cpu.getMemory().set(sp.getValue(), status.toByte()); + + return status; + } + + public boolean noOperandsValid() { + return true; + } +}