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 };