mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-20 11:06:46 +00:00
Added the Interupt (int <imm>) 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.
This commit is contained in:
parent
dab5cab602
commit
1b18426c5c
@ -97,6 +97,8 @@ public class CPU implements JSONSerialisable {
|
|||||||
instructionSet.add(new JncInstruction(this));
|
instructionSet.add(new JncInstruction(this));
|
||||||
instructionSet.add(new JnoInstruction(this));
|
instructionSet.add(new JnoInstruction(this));
|
||||||
instructionSet.add(new JoInstruction(this));
|
instructionSet.add(new JoInstruction(this));
|
||||||
|
instructionSet.add(new IntInstruction(this));
|
||||||
|
instructionSet.add(new IntrInstruction(this));
|
||||||
|
|
||||||
status = new Status();
|
status = new Status();
|
||||||
memory = new Memory(config.getInt("memory_size"));
|
memory = new Memory(config.getInt("memory_size"));
|
||||||
@ -466,6 +468,14 @@ public class CPU implements JSONSerialisable {
|
|||||||
return attachedHardware.get(address);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,4 +132,20 @@ public class Status {
|
|||||||
public void setErrorFlag(boolean errorFlag) {
|
public void setErrorFlag(boolean errorFlag) {
|
||||||
this.errorFlag = 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user