diff --git a/app/windows/CPUWindow.js b/app/windows/CPUWindow.js index fa08ca1..4535cc7 100644 --- a/app/windows/CPUWindow.js +++ b/app/windows/CPUWindow.js @@ -130,7 +130,6 @@ overflow: "hidden" }); this.proWrap.element.setAttribute("name", "wrap-program-registers"); - this.proWrap.element.style.flexGrow = "1"; // Main element this.proRegs = this.proWrap.add(this.newPanel({ @@ -237,6 +236,8 @@ // Retrieved all register values getRegisters(msg) { + + // Update controls this.sysRegs.registers[CPUWindow.PC ] .setValue(msg.pc, msg.pcFrom, msg.pcTo); this.sysRegs.registers[CPUWindow.PSW ].setValue(msg.psw ); @@ -302,6 +303,7 @@ case "seek" : this.refreshDasm(address, line); } + } // Modified a register value @@ -352,6 +354,20 @@ // Control is pressed 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": let addr = prompt(this.application.translate("{app.goto_}")); if (addr === null) @@ -361,6 +377,7 @@ Math.floor(this.lines(true) / 3) ); break; + default: return; } @@ -546,6 +563,14 @@ CPUWindow.Row = class Row extends Toolkit.Panel { ///////////////////////////// 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 setWidths(columns) { 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); for (let x = 0; x < bytes.length; 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.mnemonic.setText(line.mnemonic); this.operands.setText(line.operands); - 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); + this.measure(columns); } }; diff --git a/app/windows/Disassembler.js b/app/windows/Disassembler.js index 472aa51..fb1a295 100644 --- a/app/windows/Disassembler.js +++ b/app/windows/Disassembler.js @@ -124,7 +124,7 @@ /**************************** Static Methods *****************************/ // 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; // Two bytes before PC to ensure PC isn't skipped @@ -136,39 +136,39 @@ hIndex = 0; } - // Locate the instruction containing the target address + // Locate the line containing the target address for (;;) { // Emergency error checking - if (offset >= buffer.length) + if (doffset >= buffer.length) 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 || - 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) break; - // Record the current instruction in the history + // Record the current line in the history if (line > 0) { let item = history[hIndex] = history[hIndex] || {}; hIndex = hIndex < history.length - 1 ? hIndex + 1 : 0; item.address = address; - item.offset = offset; + item.doffset = doffset; } - // Advance to the next instruction - offset += size; - address = (address + size & 0xFFFFFFFF) >>> 0; + // Advance to the next line + doffset += size; + address = (address + size & 0xFFFFFFFF) >>> 0; } // The target address is before the first line of output for (; line < 0; line++) { let size = address == prePC || - this.OPDEFS[buffer[offset + 1] >>> 2].format < 4 ? 2 : 4; - offset += size; + this.OPDEFS[buffer[doffset + 1] >>> 2].format < 4 ? 2 : 4; + doffset += size; address = (address + size & 0xFFFFFFFF) >>> 0; } @@ -181,16 +181,16 @@ throw "Error: First output not in disassembly history"; // Inherit the address of the first history item - address = item.address; - offset = item.offset; + address = item.address; + doffset = item.doffset; } - // Decode the instructions of the output + // Decode the lines of the output let ret = new Array(lines); 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; - offset += size; + doffset += size; address = (address + size & 0xFFFFFFFF) >>> 0; } @@ -201,7 +201,7 @@ /**************************** Private Methods ****************************/ - // Retrieve bits for a 16-bit instruction + // Retrieve the bits for an instruction static bits(inst) { return inst.size == 2 ? inst.bytes[1] << 8 | inst.bytes[0] : ( @@ -211,24 +211,25 @@ ; } - // Decode one instruction - static decode(buffer, offset, address) { - let opcode = buffer[offset + 1] >>> 2; + // Decode one line of output + static decode(buffer, doffset, address) { + let opcode = buffer[doffset + 1] >>> 2; let opdef = this.OPDEFS[opcode]; let size = opdef.format < 4 ? 2 : 4; // Emergency error checking - if (offset + size > buffer.length) + if (doffset + size > buffer.length) throw "Error: Insufficient disassembly data"; // Produce output line object let inst = { address : address, - bytes : new Uint8Array(buffer.buffer.slice(offset, offset+size)), mnemonic: opdef.mnemonic, opcode : opcode, operands: null, - size : size + size : size, + bytes : new Uint8Array( + buffer.buffer.slice(doffset, doffset + size)) }; // Processing by instruction format diff --git a/app/windows/MemoryWindow.js b/app/windows/MemoryWindow.js index 03ce5ef..31cfaa7 100644 --- a/app/windows/MemoryWindow.js +++ b/app/windows/MemoryWindow.js @@ -132,6 +132,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window { case "seek" : this.refresh((address + line * 16 & 0xFFFFFFF0) >>> 0); } + } diff --git a/makefile b/makefile index d832e1a..d98aaad 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ .PHONY: help help: @echo - @echo "Virtual Boy Emulator - September 5, 2021" + @echo "Virtual Boy Emulator - September 10, 2021" @echo @echo "Target build environment is any Debian with the following packages:" @echo " emscripten"