mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-19 18:46:43 +00:00
INTO instruction #78
This commit is contained in:
parent
b1d7121b22
commit
2ff19f24eb
@ -6,6 +6,7 @@ import net.simon987.mar.server.assembly.exception.CancelledException;
|
|||||||
import net.simon987.mar.server.assembly.instruction.*;
|
import net.simon987.mar.server.assembly.instruction.*;
|
||||||
import net.simon987.mar.server.event.CpuInitialisationEvent;
|
import net.simon987.mar.server.event.CpuInitialisationEvent;
|
||||||
import net.simon987.mar.server.event.GameEvent;
|
import net.simon987.mar.server.event.GameEvent;
|
||||||
|
import net.simon987.mar.server.game.GameUniverse;
|
||||||
import net.simon987.mar.server.game.objects.ControllableUnit;
|
import net.simon987.mar.server.game.objects.ControllableUnit;
|
||||||
import net.simon987.mar.server.game.objects.HardwareHost;
|
import net.simon987.mar.server.game.objects.HardwareHost;
|
||||||
import net.simon987.mar.server.io.MongoSerializable;
|
import net.simon987.mar.server.io.MongoSerializable;
|
||||||
@ -47,7 +48,7 @@ public class CPU implements MongoSerializable {
|
|||||||
|
|
||||||
private int interruptVectorTableOffset;
|
private int interruptVectorTableOffset;
|
||||||
private final int graceInstructionCount;
|
private final int graceInstructionCount;
|
||||||
private int graceInstructionLeft;
|
private int graceInstructionsLeft;
|
||||||
private boolean isGracePeriod;
|
private boolean isGracePeriod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,6 +94,7 @@ public class CPU implements MongoSerializable {
|
|||||||
instructionSet.add(new JnaInstruction(this));
|
instructionSet.add(new JnaInstruction(this));
|
||||||
instructionSet.add(new JaInstruction(this));
|
instructionSet.add(new JaInstruction(this));
|
||||||
instructionSet.add(new IntInstruction(this));
|
instructionSet.add(new IntInstruction(this));
|
||||||
|
instructionSet.add(new IntoInstruction(this));
|
||||||
instructionSet.add(new IretInstruction(this));
|
instructionSet.add(new IretInstruction(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +142,7 @@ public class CPU implements MongoSerializable {
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
status.clear();
|
status.clear();
|
||||||
ip = codeSectionOffset;
|
ip = codeSectionOffset;
|
||||||
graceInstructionLeft = graceInstructionCount;
|
graceInstructionsLeft = graceInstructionCount;
|
||||||
isGracePeriod = false;
|
isGracePeriod = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,13 +159,13 @@ public class CPU implements MongoSerializable {
|
|||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
if (isGracePeriod) {
|
if (isGracePeriod) {
|
||||||
if (graceInstructionLeft-- == 0) {
|
if (graceInstructionsLeft-- == 0) {
|
||||||
writeExecutionStats(timeout, counter);
|
writeExecutionStats(timeout, counter);
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
} else if (counter % 10000 == 0) {
|
} else if (counter % 10000 == 0) {
|
||||||
if (System.currentTimeMillis() > (startTime + timeout)) {
|
if (System.currentTimeMillis() > (startTime + timeout)) {
|
||||||
interrupt(32);
|
interrupt(IntInstruction.INT_EXEC_LIMIT_REACHED);
|
||||||
isGracePeriod = true;
|
isGracePeriod = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,10 @@ public class IntInstruction extends Instruction {
|
|||||||
public static final int OPCODE = 48;
|
public static final int OPCODE = 48;
|
||||||
private final CPU cpu;
|
private final CPU cpu;
|
||||||
|
|
||||||
|
public static final int INT_DIVISION_BY_ZERO = 0;
|
||||||
|
public static final int INT_INTO_DETECTED_OVERFLOW = 4;
|
||||||
|
public static final int INT_EXEC_LIMIT_REACHED = 32;
|
||||||
|
|
||||||
public IntInstruction(CPU cpu) {
|
public IntInstruction(CPU cpu) {
|
||||||
super("int", OPCODE);
|
super("int", OPCODE);
|
||||||
this.cpu = cpu;
|
this.cpu = cpu;
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package net.simon987.mar.server.assembly.instruction;
|
||||||
|
|
||||||
|
import net.simon987.mar.server.assembly.*;
|
||||||
|
|
||||||
|
public class IntoInstruction extends Instruction {
|
||||||
|
|
||||||
|
public static final int OPCODE = 8;
|
||||||
|
private final CPU cpu;
|
||||||
|
|
||||||
|
|
||||||
|
public IntoInstruction(CPU cpu) {
|
||||||
|
super("into", OPCODE);
|
||||||
|
this.cpu = cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status execute(Status status) {
|
||||||
|
if (status.isOverflowFlag()) {
|
||||||
|
cpu.interrupt(IntInstruction.INT_INTO_DETECTED_OVERFLOW);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean noOperandsValid() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean operandsValid(Operand o1, Operand o2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean operandValid(Operand o1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
2
src/main/resources/static/js/editor.js
vendored
2
src/main/resources/static/js/editor.js
vendored
@ -275,7 +275,7 @@ function parseInstruction(line, result, currentLine) {
|
|||||||
|
|
||||||
if (new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|mul|push|pop|div|xor|hwi|hwq|nop|neg|' +
|
if (new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|mul|push|pop|div|xor|hwi|hwq|nop|neg|' +
|
||||||
'seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns|' +
|
'seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns|' +
|
||||||
'call|ret|jmp|jnz|jg|jl|jge|jle|int|jz|js|jns|brk|not|jc|jnc|ror|rol|sal|sar|jo|jno|inc|dec|rcl|xchg|rcr|pushf|popf|ja|jna)\\b').test(mnemonic.toLowerCase())) {
|
'call|ret|jmp|jnz|jg|jl|jge|jle|int|into|iret|jz|js|jns|brk|not|jc|jnc|ror|rol|sal|sar|jo|jno|inc|dec|rcl|xchg|rcr|pushf|popf|ja|jna)\\b').test(mnemonic.toLowerCase())) {
|
||||||
|
|
||||||
|
|
||||||
if (line.indexOf(",") !== -1) {
|
if (line.indexOf(",") !== -1) {
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package net.simon987.mar.server.assembly.instruction;
|
||||||
|
|
||||||
|
import net.simon987.mar.server.TestExecutionResult;
|
||||||
|
import net.simon987.mar.server.assembly.TestHelper;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class IntoInstructionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void intoSimple1() {
|
||||||
|
String code = "" +
|
||||||
|
"isr: \n" +
|
||||||
|
" MOV X, 0x1234 \n" +
|
||||||
|
" IRET \n" +
|
||||||
|
".text \n" +
|
||||||
|
"MOV [4], isr \n" +
|
||||||
|
"INTO \n" +
|
||||||
|
"MOV Y, 0x4567 \n" +
|
||||||
|
"brk \n";
|
||||||
|
|
||||||
|
TestExecutionResult res = TestHelper.executeCode(code);
|
||||||
|
|
||||||
|
assertEquals(0, res.regValue("X"));
|
||||||
|
assertEquals(0x4567, res.regValue("Y"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void intoSimple2() {
|
||||||
|
String code = "" +
|
||||||
|
"isr: \n" +
|
||||||
|
" MOV X, 0x1234 \n" +
|
||||||
|
" IRET \n" +
|
||||||
|
".text \n" +
|
||||||
|
"MOV [4], isr \n" +
|
||||||
|
"MOV A, 0x7FFF \n" +
|
||||||
|
"ADD A, 1 \n" +
|
||||||
|
"INTO \n" +
|
||||||
|
"MOV Y, 0x4567 \n" +
|
||||||
|
"brk \n";
|
||||||
|
|
||||||
|
TestExecutionResult res = TestHelper.executeCode(code);
|
||||||
|
|
||||||
|
assertEquals(0x1234, res.regValue("X"));
|
||||||
|
assertEquals(0x4567, res.regValue("Y"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user