pvbemu/app/app/Debugger.js

188 lines
5.9 KiB
JavaScript

import { Disassembler } from /**/"./Disassembler.js";
import { Memory } from /**/"./Memory.js";
import { RegisterList } from /**/"./RegisterList.js";
class Debugger {
///////////////////////// Initialization Methods //////////////////////////
constructor(app, index, sim) {
// Configure instance fields
this.app = app;
this.index = index;
this.sim = sim;
// Configure components
this.disassembler = new Disassembler(this);
this.memory = new Memory (this);
this.programRegisters = new RegisterList(this, false);
this.systemRegisters = new RegisterList(this, true );
// Configure windows
this.initCPUWindow ();
this.initMemoryWindow();
}
// Set up the CPU window
initCPUWindow() {
let app = this.app;
// Produce the window
let wnd = this.cpuWindow = new app.Toolkit.Window(app, {
width : 400,
height : 300,
className : "tk tk-window tk-cpu" + (this.index==0?"":" two"),
closeToolTip: "common.close",
title : "cpu._",
visible : false
});
wnd.setSubstitution("sim", this.index == 1 ? " 2" : "");
wnd.addEventListener("close", ()=>wnd.setVisible(false));
app.desktop.add(wnd);
// Visibility override
let that = this;
let setVisible = wnd.setVisible;
wnd.setVisible = function(visible) {
that.disassembler .setSubscribed(visible);
that.systemRegisters .setSubscribed(visible);
that.programRegisters.setSubscribed(visible);
setVisible.apply(wnd, arguments);
};
// Auto-seek the initial view
let onSeek = ()=>this.disassembler.seek(this.disassembler.pc, true);
Toolkit.addResizeListener(this.disassembler.element, onSeek);
wnd.addEventListener("firstshow", ()=>{
app.desktop.center(wnd);
Toolkit.removeResizeListener(this.disassembler.element, onSeek);
});
// Window splitters
let sptMain = new Toolkit.SplitPane(this.app, {
className: "tk tk-splitpane tk-main",
edge : Toolkit.SplitPane.RIGHT
});
let sptRegs = new Toolkit.SplitPane(this.app, {
className: "tk tk-splitpane tk-registers",
edge : Toolkit.SplitPane.TOP
});
// Configure window splitter initial size
let resize = new ResizeObserver(()=>{
// Measure register lists
let sys = this.systemRegisters .getPreferredSize();
let pro = this.programRegisters.getPreferredSize();
let height = Math.ceil(Math.max(sys.height, pro.height));
let width = Math.ceil(Math.max(sys.width , pro.width )) +
this.systemRegisters.vertical.getBounds().width;
// Configure splitters
if (sptMain.getValue() != width)
sptMain.setValue(width);
if (sptRegs.getValue() != height)
sptRegs.setValue(height);
});
resize.observe(this.programRegisters.view.element);
resize.observe(this.systemRegisters .view.element);
// Stop monitoring splitter size when something receives focus
let onFocus = e=>{
resize.disconnect();
wnd.removeEventListener("focus", onFocus, true);
};
sptMain.addEventListener("focus", onFocus, true);
// Configure window layout
sptMain.setView(0, this.disassembler);
sptMain.setView(1, sptRegs);
sptRegs.setView(0, this.systemRegisters);
sptRegs.setView(1, this.programRegisters);
wnd.append(sptMain);
}
// Set up the Memory window
initMemoryWindow() {
let app = this.app;
// Produce the window
let wnd = this.memoryWindow = new app.Toolkit.Window(app, {
width : 400,
height : 300,
className : "tk tk-window" + (this.index == 0 ? "" : " two"),
closeToolTip: "common.close",
title : "memory._",
visible : false
});
wnd.setSubstitution("sim", this.index == 1 ? " 2" : "");
wnd.addEventListener("close" , ()=>wnd.setVisible(false));
wnd.addEventListener("firstshow", ()=>app.desktop.center(wnd));
app.desktop.add(wnd);
// Visibility override
let that = this;
let setVisible = wnd.setVisible;
wnd.setVisible = function(visible) {
that.memory.setSubscribed(visible);
setVisible.apply(wnd, arguments);
};
// Configure window layout
wnd.append(this.memory);
}
///////////////////////////// Package Methods /////////////////////////////
// Retrieve the disassembler configuraiton
getDasmConfig() {
return this.disassembler.getConfig();
}
// Attempt to run until the next instruction
runNext() {
this.app.runNext(this.index);
}
// Update the disassembler configuration
setDasmConfig(config) {
this.disassembler .setConfig(config);
this.memory .dasmChanged();
this.programRegisters.dasmChanged();
this.systemRegisters .dasmChanged();
}
// Specify whether dual sims mode is active
setDualSims(dualSims) {
// Update substitutions for sim 1
if (this.index == 0) {
let sub = dualSims ? " 1" : "";
this.cpuWindow .setSubstitution("sim", sub);
this.memoryWindow.setSubstitution("sim", sub);
}
// Hide windows for sim 2
else if (!dualSims) {
this.cpuWindow .close(false);
this.memoryWindow.close(false);
}
}
// Execute one instruction
singleStep() {
this.app.singleStep(this.index);
}
}
export { Debugger };