mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-10 14:26:45 +00:00
More work on debugger
This commit is contained in:
parent
3ae119072c
commit
60c763167d
@ -157,6 +157,11 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
if (getCpu().isPaused() || getCpu().isExecuting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentAction == Action.WALKING) {
|
||||
if (spendEnergy(100)) {
|
||||
if (!incrementLocation()) {
|
||||
|
@ -276,7 +276,7 @@ public class GameServer implements Runnable {
|
||||
int allocation = Math.min(user.getControlledUnit().getEnergy() * CPU.INSTRUCTION_COST, maxExecutionInstructions);
|
||||
cpu.setInstructionAlloction(allocation);
|
||||
|
||||
if (!cpu.isPaused()) {
|
||||
if (!cpu.isPaused() && !cpu.isExecuting()) {
|
||||
cpu.reset();
|
||||
executeUserCode(user);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ public class CPU implements MongoSerializable {
|
||||
private final Status status;
|
||||
|
||||
private boolean trapFlag = false;
|
||||
private boolean executing = false;
|
||||
|
||||
/**
|
||||
* Memory associated with the CPU, 64kb max
|
||||
@ -161,6 +162,7 @@ public class CPU implements MongoSerializable {
|
||||
|
||||
public int execute() {
|
||||
|
||||
executing = true;
|
||||
int counter = 0;
|
||||
status.clear();
|
||||
|
||||
@ -190,6 +192,7 @@ public class CPU implements MongoSerializable {
|
||||
|
||||
writeExecutionStats(counter);
|
||||
|
||||
executing = false;
|
||||
return counter / INSTRUCTION_COST;
|
||||
}
|
||||
|
||||
@ -507,6 +510,10 @@ public class CPU implements MongoSerializable {
|
||||
return trapFlag;
|
||||
}
|
||||
|
||||
public boolean isExecuting() {
|
||||
return executing;
|
||||
}
|
||||
|
||||
public void setTrapFlag(boolean trapFlag) {
|
||||
this.trapFlag = trapFlag;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.simon987.mar.server.assembly;
|
||||
|
||||
|
||||
import net.simon987.mar.server.io.JSONSerializable;
|
||||
import net.simon987.mar.server.io.MongoSerializable;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONArray;
|
||||
@ -12,7 +13,7 @@ import java.util.List;
|
||||
/**
|
||||
* A set of registers for a CPU
|
||||
*/
|
||||
public class RegisterSet implements Target, MongoSerializable, Cloneable {
|
||||
public class RegisterSet implements Target, MongoSerializable, Cloneable, JSONSerializable {
|
||||
|
||||
private int size = 0;
|
||||
|
||||
@ -210,4 +211,21 @@ public class RegisterSet implements Target, MongoSerializable, Cloneable {
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject jsonSerialise() {
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
for (int i = 1; i <= size; i++) {
|
||||
Register reg = getRegister(i);
|
||||
json.put(reg.getName(), (int)reg.getValue());
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject debugJsonSerialise() {
|
||||
return jsonSerialise();
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,10 @@ public class Util {
|
||||
return String.format("%04X ", a);
|
||||
}
|
||||
|
||||
public static String toHex16(int a) {
|
||||
return String.format("%04X", a & 0x0000FFFF);
|
||||
}
|
||||
|
||||
public static String toHex(byte[] byteArray) {
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
@ -41,6 +41,7 @@ public class CodeUploadHandler implements MessageHandler {
|
||||
cpu.setCodeSectionOffset(ar.getCodeSectionOffset());
|
||||
|
||||
cpu.reset();
|
||||
cpu.getRegisterSet().clear();
|
||||
//Clear keyboard buffer
|
||||
if (user.getUser().getControlledUnit() != null &&
|
||||
user.getUser().getControlledUnit().getKeyboardBuffer() != null) {
|
||||
|
@ -31,7 +31,7 @@ public class DebugStepHandler implements MessageHandler {
|
||||
|
||||
CPU cpu = user.getUser().getControlledUnit().getCpu();
|
||||
|
||||
if (!cpu.isPaused()) {
|
||||
if (!cpu.isPaused() || cpu.isExecuting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class StateRequestHandler implements MessageHandler {
|
||||
response.put("t", "state");
|
||||
response.put("memory", cpu.getMemory().toString());
|
||||
response.put("status", cpu.getStatus().toString());
|
||||
response.put("registers", cpu.getRegisterSet().toString());
|
||||
response.put("registers", cpu.getRegisterSet().jsonSerialise());
|
||||
Map<Integer, Integer> codeLineMap = user.getUser().getCodeLineMap();
|
||||
Integer line = codeLineMap == null ? null : codeLineMap.get(cpu.getIp());
|
||||
response.put("line", line == null ? 0 : line);
|
||||
|
@ -372,7 +372,7 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#disassembly-hl {
|
||||
.disassembly-hl {
|
||||
background: #ff000077;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
|
@ -158,40 +158,60 @@ class StateListener implements MessageListener {
|
||||
stateStatus.removeChild(stateStatus.firstChild);
|
||||
}
|
||||
|
||||
stateMemory.insertAdjacentHTML("beforeend", message.memory.replace(/(0000 )+/g, '<span class="_0">$&</span>'));
|
||||
// stateMemory.insertAdjacentHTML("beforeend", message.memory);
|
||||
stateRegisters.insertAdjacentHTML("beforeend", message.registers.replace(/(0000 )+/g, '<span class="_0">$&</span>'));
|
||||
// stateMemory.insertAdjacentHTML("beforeend", message.memory.replace(/(0000 )+/g, '<span class="_0">$&</span>'));
|
||||
stateMemory.insertAdjacentHTML("beforeend", message.memory);
|
||||
let registers = "";
|
||||
let regKeys = Object.keys(message.registers);
|
||||
for (let i = 0; i < regKeys.length; i++) {
|
||||
registers += regKeys[i] + "=" + message.registers[regKeys[i]].toString(16).padStart(4, "0").toUpperCase()
|
||||
if (i != regKeys.length - 1) {
|
||||
registers += " ";
|
||||
}
|
||||
}
|
||||
stateRegisters.insertAdjacentHTML("beforeend", registers.replace(/(0000)+/g, '<span class="_0">$&</span>'));
|
||||
|
||||
stateStatus.insertAdjacentHTML("beforeend", message.status.replace(/=0/g, '=<span class="_0">0</span>'));
|
||||
updateDisassemblyPane()
|
||||
}
|
||||
}
|
||||
|
||||
function hlDisassembly(lines) {
|
||||
let text = ""
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
text += "<span id='line-" + i + "'>" + lines[i]
|
||||
.replace(/^\s*([a-zA-Z_]\w*):/gm, '<span class="_l"> $1:</span>')
|
||||
.replace(/^.*INT 0003$/gm, '<span class="i3">$&</span>')
|
||||
.replace(/^[0-9A-F]{4}/gm, '<span class="_a">$&</span>')
|
||||
.replace(/ (MOV|ADD|SUB|AND|OR|TEST|CMP|SHL|SHR|MUL|PUSH|POP|DIV|XOR|DW|NOP|EQU|NEG|HWQ|NOT|ROR|ROL|SAL|SAR|INC|DEC|RCL|XCHG|RCR|PUSHF|POPF|INT|IRET|INTO|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)/g, '<span class="_k"> $1</span>')
|
||||
.replace(/ (CALL|RET|JMP|JNZ|JG|JL|JGE|JLE|HWI|JZ|JS|JNS|JC|JNC|JO|JNO|JA|JNA)/g, '<span class="_o"> $1 </span>')
|
||||
.replace(/ (BRK)$/gm, '<span class="_b"> $1</span>')
|
||||
+ "</span>\n";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
function updateDisassemblyPane() {
|
||||
|
||||
const line = mar.pausedLine;
|
||||
const lines = mar.disassembly.slice();
|
||||
if (mar.disassembly == undefined || line == -1 || !mar.isPaused) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stateDisassembly = document.getElementById("state-disassembly");
|
||||
|
||||
while (stateDisassembly.firstChild) {
|
||||
stateDisassembly.removeChild(stateDisassembly.firstChild);
|
||||
}
|
||||
if (!mar.disassemblyInitialized) {
|
||||
mar.disassemblyInitialized = true;
|
||||
while (stateDisassembly.firstChild) {
|
||||
stateDisassembly.removeChild(stateDisassembly.firstChild);
|
||||
}
|
||||
|
||||
if (line != -1 && mar.isPaused) {
|
||||
lines[line] = `<span id="disassembly-hl">${lines[line]}</span>`
|
||||
}
|
||||
|
||||
stateDisassembly.innerHTML = lines.join("\n")
|
||||
.replace(/^\s*([a-zA-Z_]\w*):/gm, '<span class="_l"> $1:</span>')
|
||||
.replace(/^.*INT 0003$/gm, '<span class="i3">$&</span>')
|
||||
.replace(/^[0-9A-F]{4}/gm, '<span class="_a">$&</span>')
|
||||
.replace(/ (MOV|ADD|SUB|AND|OR|TEST|CMP|SHL|SHR|MUL|PUSH|POP|DIV|XOR|DW|NOP|EQU|NEG|HWQ|NOT|ROR|ROL|SAL|SAR|INC|DEC|RCL|XCHG|RCR|PUSHF|POPF|INT|IRET|INTO|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)/g, '<span class="_k"> $1</span>')
|
||||
.replace(/ (CALL|RET|JMP|JNZ|JG|JL|JGE|JLE|HWI|JZ|JS|JNS|JC|JNC|JO|JNO|JA|JNA) /g, '<span class="_o"> $1 </span>')
|
||||
.replace(/ (BRK)$/gm, '<span class="_b"> $1</span>')
|
||||
|
||||
const hl = document.getElementById("disassembly-hl");
|
||||
if (hl != null) {
|
||||
hl.scrollIntoView({block: "center"});
|
||||
stateDisassembly.innerHTML = hlDisassembly(mar.disassembly)
|
||||
} else {
|
||||
[].forEach.call(document.getElementsByClassName("disassembly-hl"), el => el.setAttribute("class", null));
|
||||
}
|
||||
const lineElem = document.getElementById("line-" + line);
|
||||
lineElem.classList.add("disassembly-hl");
|
||||
lineElem.scrollIntoView({block: "center"});
|
||||
}
|
||||
|
||||
class DisassemblyListener implements MessageListener {
|
||||
|
@ -1,6 +1,7 @@
|
||||
class MarGame {
|
||||
|
||||
disassembly : string[];
|
||||
disassemblyInitialized = false
|
||||
pausedLine: number = -1;
|
||||
|
||||
_isPaused = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user