mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-19 18:46:43 +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
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
|
|
||||||
|
if (getCpu().isPaused() || getCpu().isExecuting()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentAction == Action.WALKING) {
|
if (currentAction == Action.WALKING) {
|
||||||
if (spendEnergy(100)) {
|
if (spendEnergy(100)) {
|
||||||
if (!incrementLocation()) {
|
if (!incrementLocation()) {
|
||||||
|
@ -276,7 +276,7 @@ public class GameServer implements Runnable {
|
|||||||
int allocation = Math.min(user.getControlledUnit().getEnergy() * CPU.INSTRUCTION_COST, maxExecutionInstructions);
|
int allocation = Math.min(user.getControlledUnit().getEnergy() * CPU.INSTRUCTION_COST, maxExecutionInstructions);
|
||||||
cpu.setInstructionAlloction(allocation);
|
cpu.setInstructionAlloction(allocation);
|
||||||
|
|
||||||
if (!cpu.isPaused()) {
|
if (!cpu.isPaused() && !cpu.isExecuting()) {
|
||||||
cpu.reset();
|
cpu.reset();
|
||||||
executeUserCode(user);
|
executeUserCode(user);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ public class CPU implements MongoSerializable {
|
|||||||
private final Status status;
|
private final Status status;
|
||||||
|
|
||||||
private boolean trapFlag = false;
|
private boolean trapFlag = false;
|
||||||
|
private boolean executing = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory associated with the CPU, 64kb max
|
* Memory associated with the CPU, 64kb max
|
||||||
@ -161,6 +162,7 @@ public class CPU implements MongoSerializable {
|
|||||||
|
|
||||||
public int execute() {
|
public int execute() {
|
||||||
|
|
||||||
|
executing = true;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
status.clear();
|
status.clear();
|
||||||
|
|
||||||
@ -190,6 +192,7 @@ public class CPU implements MongoSerializable {
|
|||||||
|
|
||||||
writeExecutionStats(counter);
|
writeExecutionStats(counter);
|
||||||
|
|
||||||
|
executing = false;
|
||||||
return counter / INSTRUCTION_COST;
|
return counter / INSTRUCTION_COST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,6 +510,10 @@ public class CPU implements MongoSerializable {
|
|||||||
return trapFlag;
|
return trapFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isExecuting() {
|
||||||
|
return executing;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTrapFlag(boolean trapFlag) {
|
public void setTrapFlag(boolean trapFlag) {
|
||||||
this.trapFlag = trapFlag;
|
this.trapFlag = trapFlag;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.simon987.mar.server.assembly;
|
package net.simon987.mar.server.assembly;
|
||||||
|
|
||||||
|
|
||||||
|
import net.simon987.mar.server.io.JSONSerializable;
|
||||||
import net.simon987.mar.server.io.MongoSerializable;
|
import net.simon987.mar.server.io.MongoSerializable;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.json.simple.JSONArray;
|
import org.json.simple.JSONArray;
|
||||||
@ -12,7 +13,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* A set of registers for a CPU
|
* 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;
|
private int size = 0;
|
||||||
|
|
||||||
@ -210,4 +211,21 @@ public class RegisterSet implements Target, MongoSerializable, Cloneable {
|
|||||||
}
|
}
|
||||||
return rs;
|
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);
|
return String.format("%04X ", a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toHex16(int a) {
|
||||||
|
return String.format("%04X", a & 0x0000FFFF);
|
||||||
|
}
|
||||||
|
|
||||||
public static String toHex(byte[] byteArray) {
|
public static String toHex(byte[] byteArray) {
|
||||||
|
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
|
@ -41,6 +41,7 @@ public class CodeUploadHandler implements MessageHandler {
|
|||||||
cpu.setCodeSectionOffset(ar.getCodeSectionOffset());
|
cpu.setCodeSectionOffset(ar.getCodeSectionOffset());
|
||||||
|
|
||||||
cpu.reset();
|
cpu.reset();
|
||||||
|
cpu.getRegisterSet().clear();
|
||||||
//Clear keyboard buffer
|
//Clear keyboard buffer
|
||||||
if (user.getUser().getControlledUnit() != null &&
|
if (user.getUser().getControlledUnit() != null &&
|
||||||
user.getUser().getControlledUnit().getKeyboardBuffer() != null) {
|
user.getUser().getControlledUnit().getKeyboardBuffer() != null) {
|
||||||
|
@ -31,7 +31,7 @@ public class DebugStepHandler implements MessageHandler {
|
|||||||
|
|
||||||
CPU cpu = user.getUser().getControlledUnit().getCpu();
|
CPU cpu = user.getUser().getControlledUnit().getCpu();
|
||||||
|
|
||||||
if (!cpu.isPaused()) {
|
if (!cpu.isPaused() || cpu.isExecuting()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ public class StateRequestHandler implements MessageHandler {
|
|||||||
response.put("t", "state");
|
response.put("t", "state");
|
||||||
response.put("memory", cpu.getMemory().toString());
|
response.put("memory", cpu.getMemory().toString());
|
||||||
response.put("status", cpu.getStatus().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();
|
Map<Integer, Integer> codeLineMap = user.getUser().getCodeLineMap();
|
||||||
Integer line = codeLineMap == null ? null : codeLineMap.get(cpu.getIp());
|
Integer line = codeLineMap == null ? null : codeLineMap.get(cpu.getIp());
|
||||||
response.put("line", line == null ? 0 : line);
|
response.put("line", line == null ? 0 : line);
|
||||||
|
@ -372,7 +372,7 @@
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#disassembly-hl {
|
.disassembly-hl {
|
||||||
background: #ff000077;
|
background: #ff000077;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -158,40 +158,60 @@ class StateListener implements MessageListener {
|
|||||||
stateStatus.removeChild(stateStatus.firstChild);
|
stateStatus.removeChild(stateStatus.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
stateMemory.insertAdjacentHTML("beforeend", message.memory.replace(/(0000 )+/g, '<span class="_0">$&</span>'));
|
// stateMemory.insertAdjacentHTML("beforeend", message.memory.replace(/(0000 )+/g, '<span class="_0">$&</span>'));
|
||||||
// stateMemory.insertAdjacentHTML("beforeend", message.memory);
|
stateMemory.insertAdjacentHTML("beforeend", message.memory);
|
||||||
stateRegisters.insertAdjacentHTML("beforeend", message.registers.replace(/(0000 )+/g, '<span class="_0">$&</span>'));
|
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>'));
|
stateStatus.insertAdjacentHTML("beforeend", message.status.replace(/=0/g, '=<span class="_0">0</span>'));
|
||||||
updateDisassemblyPane()
|
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() {
|
function updateDisassemblyPane() {
|
||||||
|
|
||||||
const line = mar.pausedLine;
|
const line = mar.pausedLine;
|
||||||
const lines = mar.disassembly.slice();
|
if (mar.disassembly == undefined || line == -1 || !mar.isPaused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const stateDisassembly = document.getElementById("state-disassembly");
|
const stateDisassembly = document.getElementById("state-disassembly");
|
||||||
|
|
||||||
while (stateDisassembly.firstChild) {
|
if (!mar.disassemblyInitialized) {
|
||||||
stateDisassembly.removeChild(stateDisassembly.firstChild);
|
mar.disassemblyInitialized = true;
|
||||||
}
|
while (stateDisassembly.firstChild) {
|
||||||
|
stateDisassembly.removeChild(stateDisassembly.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
if (line != -1 && mar.isPaused) {
|
stateDisassembly.innerHTML = hlDisassembly(mar.disassembly)
|
||||||
lines[line] = `<span id="disassembly-hl">${lines[line]}</span>`
|
} else {
|
||||||
}
|
[].forEach.call(document.getElementsByClassName("disassembly-hl"), el => el.setAttribute("class", null));
|
||||||
|
|
||||||
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"});
|
|
||||||
}
|
}
|
||||||
|
const lineElem = document.getElementById("line-" + line);
|
||||||
|
lineElem.classList.add("disassembly-hl");
|
||||||
|
lineElem.scrollIntoView({block: "center"});
|
||||||
}
|
}
|
||||||
|
|
||||||
class DisassemblyListener implements MessageListener {
|
class DisassemblyListener implements MessageListener {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
class MarGame {
|
class MarGame {
|
||||||
|
|
||||||
disassembly : string[];
|
disassembly : string[];
|
||||||
|
disassemblyInitialized = false
|
||||||
pausedLine: number = -1;
|
pausedLine: number = -1;
|
||||||
|
|
||||||
_isPaused = false
|
_isPaused = false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user