mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-10 14:26:45 +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.event.CpuInitialisationEvent;
|
||||
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.HardwareHost;
|
||||
import net.simon987.mar.server.io.MongoSerializable;
|
||||
@ -47,7 +48,7 @@ public class CPU implements MongoSerializable {
|
||||
|
||||
private int interruptVectorTableOffset;
|
||||
private final int graceInstructionCount;
|
||||
private int graceInstructionLeft;
|
||||
private int graceInstructionsLeft;
|
||||
private boolean isGracePeriod;
|
||||
|
||||
/**
|
||||
@ -93,6 +94,7 @@ public class CPU implements MongoSerializable {
|
||||
instructionSet.add(new JnaInstruction(this));
|
||||
instructionSet.add(new JaInstruction(this));
|
||||
instructionSet.add(new IntInstruction(this));
|
||||
instructionSet.add(new IntoInstruction(this));
|
||||
instructionSet.add(new IretInstruction(this));
|
||||
}
|
||||
|
||||
@ -140,7 +142,7 @@ public class CPU implements MongoSerializable {
|
||||
public void reset() {
|
||||
status.clear();
|
||||
ip = codeSectionOffset;
|
||||
graceInstructionLeft = graceInstructionCount;
|
||||
graceInstructionsLeft = graceInstructionCount;
|
||||
isGracePeriod = false;
|
||||
}
|
||||
|
||||
@ -157,13 +159,13 @@ public class CPU implements MongoSerializable {
|
||||
counter++;
|
||||
|
||||
if (isGracePeriod) {
|
||||
if (graceInstructionLeft-- == 0) {
|
||||
if (graceInstructionsLeft-- == 0) {
|
||||
writeExecutionStats(timeout, counter);
|
||||
return timeout;
|
||||
}
|
||||
} else if (counter % 10000 == 0) {
|
||||
if (System.currentTimeMillis() > (startTime + timeout)) {
|
||||
interrupt(32);
|
||||
interrupt(IntInstruction.INT_EXEC_LIMIT_REACHED);
|
||||
isGracePeriod = true;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ public class IntInstruction extends Instruction {
|
||||
public static final int OPCODE = 48;
|
||||
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) {
|
||||
super("int", OPCODE);
|
||||
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|' +
|
||||
'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) {
|
||||
|
@ -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