Tweaks from concurrent project
This commit is contained in:
parent
85cc0f5754
commit
70f0f2a318
|
@ -130,7 +130,6 @@
|
||||||
overflow: "hidden"
|
overflow: "hidden"
|
||||||
});
|
});
|
||||||
this.proWrap.element.setAttribute("name", "wrap-program-registers");
|
this.proWrap.element.setAttribute("name", "wrap-program-registers");
|
||||||
this.proWrap.element.style.flexGrow = "1";
|
|
||||||
|
|
||||||
// Main element
|
// Main element
|
||||||
this.proRegs = this.proWrap.add(this.newPanel({
|
this.proRegs = this.proWrap.add(this.newPanel({
|
||||||
|
@ -237,6 +236,8 @@
|
||||||
|
|
||||||
// Retrieved all register values
|
// Retrieved all register values
|
||||||
getRegisters(msg) {
|
getRegisters(msg) {
|
||||||
|
|
||||||
|
// Update controls
|
||||||
this.sysRegs.registers[CPUWindow.PC ]
|
this.sysRegs.registers[CPUWindow.PC ]
|
||||||
.setValue(msg.pc, msg.pcFrom, msg.pcTo);
|
.setValue(msg.pc, msg.pcFrom, msg.pcTo);
|
||||||
this.sysRegs.registers[CPUWindow.PSW ].setValue(msg.psw );
|
this.sysRegs.registers[CPUWindow.PSW ].setValue(msg.psw );
|
||||||
|
@ -302,6 +303,7 @@
|
||||||
case "seek" :
|
case "seek" :
|
||||||
this.refreshDasm(address, line);
|
this.refreshDasm(address, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modified a register value
|
// Modified a register value
|
||||||
|
@ -352,6 +354,20 @@
|
||||||
|
|
||||||
// Control is pressed
|
// Control is pressed
|
||||||
if (e.ctrlKey) switch (e.key) {
|
if (e.ctrlKey) switch (e.key) {
|
||||||
|
|
||||||
|
// Auto-fit
|
||||||
|
case "f": case "F":
|
||||||
|
for (let x = 0; x < this.columns.length; x++)
|
||||||
|
this.columns[x] = 0;
|
||||||
|
for (let row of this.rows)
|
||||||
|
row.setWidths(this.columns);
|
||||||
|
for (let row of this.rows)
|
||||||
|
row.measure(this.columns);
|
||||||
|
for (let row of this.rows)
|
||||||
|
row.setWidths(this.columns);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Goto
|
||||||
case "g": case "G":
|
case "g": case "G":
|
||||||
let addr = prompt(this.application.translate("{app.goto_}"));
|
let addr = prompt(this.application.translate("{app.goto_}"));
|
||||||
if (addr === null)
|
if (addr === null)
|
||||||
|
@ -361,6 +377,7 @@
|
||||||
Math.floor(this.lines(true) / 3)
|
Math.floor(this.lines(true) / 3)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,6 +563,14 @@ CPUWindow.Row = class Row extends Toolkit.Panel {
|
||||||
|
|
||||||
///////////////////////////// Package Methods /////////////////////////////
|
///////////////////////////// Package Methods /////////////////////////////
|
||||||
|
|
||||||
|
// Measure the content widths of each column of output
|
||||||
|
measure(columns) {
|
||||||
|
columns[0] = Math.max(columns[0], this.address .getBounds().width);
|
||||||
|
columns[1] = Math.max(columns[1], this.bytes .getBounds().width);
|
||||||
|
columns[2] = Math.max(columns[2], this.mnemonic.getBounds().width);
|
||||||
|
columns[3] = Math.max(columns[3], this.operands.getBounds().width);
|
||||||
|
}
|
||||||
|
|
||||||
// Specify the column widths
|
// Specify the column widths
|
||||||
setWidths(columns) {
|
setWidths(columns) {
|
||||||
this.address .element.style.minWidth = columns[0] + "px";
|
this.address .element.style.minWidth = columns[0] + "px";
|
||||||
|
@ -562,16 +587,13 @@ CPUWindow.Row = class Row extends Toolkit.Panel {
|
||||||
let bytes = new Array(line.bytes.length);
|
let bytes = new Array(line.bytes.length);
|
||||||
for (let x = 0; x < bytes.length; x++)
|
for (let x = 0; x < bytes.length; x++)
|
||||||
bytes[x] =
|
bytes[x] =
|
||||||
("0"+line.bytes[x].toString(16).toUpperCase()).slice(-2);
|
("0" + line.bytes[x].toString(16).toUpperCase()).slice(-2);
|
||||||
this.bytes.setText(bytes.join(" "));
|
this.bytes.setText(bytes.join(" "));
|
||||||
|
|
||||||
this.mnemonic.setText(line.mnemonic);
|
this.mnemonic.setText(line.mnemonic);
|
||||||
this.operands.setText(line.operands);
|
this.operands.setText(line.operands);
|
||||||
|
|
||||||
columns[0] = Math.max(columns[0], this.address .getBounds().width);
|
this.measure(columns);
|
||||||
columns[1] = Math.max(columns[1], this.bytes .getBounds().width);
|
|
||||||
columns[2] = Math.max(columns[2], this.mnemonic.getBounds().width);
|
|
||||||
columns[3] = Math.max(columns[3], this.operands.getBounds().width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -124,7 +124,7 @@
|
||||||
/**************************** Static Methods *****************************/
|
/**************************** Static Methods *****************************/
|
||||||
|
|
||||||
// Disassemble instructions as lines of text
|
// Disassemble instructions as lines of text
|
||||||
static disassemble(buffer, offset, address, target, pc, line, lines) {
|
static disassemble(buffer, doffset, address, target, pc, line, lines) {
|
||||||
let history, hIndex;
|
let history, hIndex;
|
||||||
|
|
||||||
// Two bytes before PC to ensure PC isn't skipped
|
// Two bytes before PC to ensure PC isn't skipped
|
||||||
|
@ -136,39 +136,39 @@
|
||||||
hIndex = 0;
|
hIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locate the instruction containing the target address
|
// Locate the line containing the target address
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
// Emergency error checking
|
// Emergency error checking
|
||||||
if (offset >= buffer.length)
|
if (doffset >= buffer.length)
|
||||||
throw "Error: Target address not in disassembly buffer";
|
throw "Error: Target address not in disassembly buffer";
|
||||||
|
|
||||||
// Determine the size of the current instruction
|
// Determine the size of the current line of output
|
||||||
let size = address == prePC ||
|
let size = address == prePC ||
|
||||||
this.OPDEFS[buffer[offset + 1] >>> 2].format < 4 ? 2 : 4;
|
this.OPDEFS[buffer[doffset + 1] >>> 2].format < 4 ? 2 : 4;
|
||||||
|
|
||||||
// The instruction contianis the target address
|
// The line contians the target address
|
||||||
if ((target - address & 0xFFFFFFFF) >>> 0 < size)
|
if ((target - address & 0xFFFFFFFF) >>> 0 < size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Record the current instruction in the history
|
// Record the current line in the history
|
||||||
if (line > 0) {
|
if (line > 0) {
|
||||||
let item = history[hIndex] = history[hIndex] || {};
|
let item = history[hIndex] = history[hIndex] || {};
|
||||||
hIndex = hIndex < history.length - 1 ? hIndex + 1 : 0;
|
hIndex = hIndex < history.length - 1 ? hIndex + 1 : 0;
|
||||||
item.address = address;
|
item.address = address;
|
||||||
item.offset = offset;
|
item.doffset = doffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance to the next instruction
|
// Advance to the next line
|
||||||
offset += size;
|
doffset += size;
|
||||||
address = (address + size & 0xFFFFFFFF) >>> 0;
|
address = (address + size & 0xFFFFFFFF) >>> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The target address is before the first line of output
|
// The target address is before the first line of output
|
||||||
for (; line < 0; line++) {
|
for (; line < 0; line++) {
|
||||||
let size = address == prePC ||
|
let size = address == prePC ||
|
||||||
this.OPDEFS[buffer[offset + 1] >>> 2].format < 4 ? 2 : 4;
|
this.OPDEFS[buffer[doffset + 1] >>> 2].format < 4 ? 2 : 4;
|
||||||
offset += size;
|
doffset += size;
|
||||||
address = (address + size & 0xFFFFFFFF) >>> 0;
|
address = (address + size & 0xFFFFFFFF) >>> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,16 +181,16 @@
|
||||||
throw "Error: First output not in disassembly history";
|
throw "Error: First output not in disassembly history";
|
||||||
|
|
||||||
// Inherit the address of the first history item
|
// Inherit the address of the first history item
|
||||||
address = item.address;
|
address = item.address;
|
||||||
offset = item.offset;
|
doffset = item.doffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the instructions of the output
|
// Decode the lines of the output
|
||||||
let ret = new Array(lines);
|
let ret = new Array(lines);
|
||||||
for (let x = 0; x < lines; x++) {
|
for (let x = 0; x < lines; x++) {
|
||||||
let inst = ret[x] = this.decode(buffer, offset, address);
|
let inst = ret[x] = this.decode(buffer, doffset, address);
|
||||||
let size = address == prePC ? 2 : inst.size;
|
let size = address == prePC ? 2 : inst.size;
|
||||||
offset += size;
|
doffset += size;
|
||||||
address = (address + size & 0xFFFFFFFF) >>> 0;
|
address = (address + size & 0xFFFFFFFF) >>> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@
|
||||||
|
|
||||||
/**************************** Private Methods ****************************/
|
/**************************** Private Methods ****************************/
|
||||||
|
|
||||||
// Retrieve bits for a 16-bit instruction
|
// Retrieve the bits for an instruction
|
||||||
static bits(inst) {
|
static bits(inst) {
|
||||||
return inst.size == 2 ?
|
return inst.size == 2 ?
|
||||||
inst.bytes[1] << 8 | inst.bytes[0] : (
|
inst.bytes[1] << 8 | inst.bytes[0] : (
|
||||||
|
@ -211,24 +211,25 @@
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode one instruction
|
// Decode one line of output
|
||||||
static decode(buffer, offset, address) {
|
static decode(buffer, doffset, address) {
|
||||||
let opcode = buffer[offset + 1] >>> 2;
|
let opcode = buffer[doffset + 1] >>> 2;
|
||||||
let opdef = this.OPDEFS[opcode];
|
let opdef = this.OPDEFS[opcode];
|
||||||
let size = opdef.format < 4 ? 2 : 4;
|
let size = opdef.format < 4 ? 2 : 4;
|
||||||
|
|
||||||
// Emergency error checking
|
// Emergency error checking
|
||||||
if (offset + size > buffer.length)
|
if (doffset + size > buffer.length)
|
||||||
throw "Error: Insufficient disassembly data";
|
throw "Error: Insufficient disassembly data";
|
||||||
|
|
||||||
// Produce output line object
|
// Produce output line object
|
||||||
let inst = {
|
let inst = {
|
||||||
address : address,
|
address : address,
|
||||||
bytes : new Uint8Array(buffer.buffer.slice(offset, offset+size)),
|
|
||||||
mnemonic: opdef.mnemonic,
|
mnemonic: opdef.mnemonic,
|
||||||
opcode : opcode,
|
opcode : opcode,
|
||||||
operands: null,
|
operands: null,
|
||||||
size : size
|
size : size,
|
||||||
|
bytes : new Uint8Array(
|
||||||
|
buffer.buffer.slice(doffset, doffset + size))
|
||||||
};
|
};
|
||||||
|
|
||||||
// Processing by instruction format
|
// Processing by instruction format
|
||||||
|
|
|
@ -132,6 +132,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window {
|
||||||
case "seek" :
|
case "seek" :
|
||||||
this.refresh((address + line * 16 & 0xFFFFFFF0) >>> 0);
|
this.refresh((address + line * 16 & 0xFFFFFFF0) >>> 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
2
makefile
2
makefile
|
@ -1,7 +1,7 @@
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help:
|
help:
|
||||||
@echo
|
@echo
|
||||||
@echo "Virtual Boy Emulator - September 5, 2021"
|
@echo "Virtual Boy Emulator - September 10, 2021"
|
||||||
@echo
|
@echo
|
||||||
@echo "Target build environment is any Debian with the following packages:"
|
@echo "Target build environment is any Debian with the following packages:"
|
||||||
@echo " emscripten"
|
@echo " emscripten"
|
||||||
|
|
Loading…
Reference in New Issue