debugger: made debug views "sticky" but not listings or certain debug commands

This commit is contained in:
Steven Hugg 2022-08-09 13:29:06 -05:00
parent cc8ce51f05
commit 50cac5afd4
3 changed files with 48 additions and 27 deletions

View File

@ -52,7 +52,7 @@ export class SourceFile {
}
}
// TODO: smarter about looking for source lines between two addresses
findLineForOffset(PC:number, lookbehind:number) {
findLineForOffset(PC:number, lookbehind:number) : SourceLine {
if (this.offset2loc) {
for (var i=0; i<=lookbehind; i++) {
var loc = this.offset2loc[PC];

View File

@ -14,7 +14,7 @@ import { StateRecorderImpl } from "../common/recorder";
import { GHSession, GithubService, getRepos, parseGithubURL } from "./services";
import Split = require('split.js');
import { importPlatform } from "../platform/_index";
import { DisassemblerView, ListingView, SourceEditor } from "./views/editors";
import { DisassemblerView, ListingView, PC_LINE_LOOKAHEAD, SourceEditor } from "./views/editors";
import { AddressHeatMapView, BinaryFileView, MemoryMapView, MemoryView, ProbeLogView, ProbeSymbolView, RasterPCHeatMapView, ScanlineIOView, VRAMMemoryView } from "./views/debugviews";
import { AssetEditorView } from "./views/asseteditor";
import { isMobileDevice } from "./views/baseviews";
@ -80,11 +80,16 @@ var store : LocalForage; // persistent store
export var compparams; // received build params from worker
export var lastDebugState : EmuState; // last debug state (object)
type DebugCommandType = null
| 'toline' | 'step' | 'stepout' | 'stepover'
| 'tovsync' | 'stepback' | 'restart';
var lastDebugInfo; // last debug info (CPU text)
var debugCategory; // current debug category
var debugTickPaused = false;
var recorderActive = false;
var lastViewClicked = null;
var lastViewClicked : string = null;
var lastDebugCommand : DebugCommandType = null;
var errorWasRuntime = false;
var lastBreakExpr = "c.PC == 0x6000";
@ -1425,30 +1430,40 @@ function checkRunReady() {
}
function openRelevantListing(state: EmuState) {
// if we clicked on another window, retain it
if (lastViewClicked != null) return;
// if we clicked on a specific tool, don't switch windows
if (lastViewClicked && lastViewClicked.startsWith('#')) return;
// don't switch windows for specific debug commands
if (['toline','restart','tovsync','stepover'].includes(lastDebugCommand)) return;
// has to support disassembly, at least
if (!platform.disassemble) return;
// search through listings
var listings = current_project.getListings();
var bestid = "#disasm";
var bestscore = 32;
let listings = current_project.getListings();
let bestid = "#disasm";
let bestscore = 256;
if (listings) {
var pc = state.c ? (state.c.EPC || state.c.PC) : 0;
for (var lstfn in listings) {
var lst = listings[lstfn];
var file = lst.assemblyfile || lst.sourcefile;
let pc = state.c ? (state.c.EPC || state.c.PC) : 0;
for (let lstfn in listings) {
let lst = listings[lstfn];
let file = lst.assemblyfile || lst.sourcefile;
// pick either listing or source file
var wndid = current_project.filename2path[lstfn] || lstfn;
let wndid = current_project.filename2path[lstfn] || lstfn;
if (file == lst.sourcefile) wndid = projectWindows.findWindowWithFilePrefix(lstfn);
// does this window exist?
if (projectWindows.isWindow(wndid)) {
var res = file && file.findLineForOffset(pc, 32); // TODO: const
if (res && pc-res.offset < bestscore) {
bestid = wndid;
bestscore = pc-res.offset;
// find the source line at the PC or closely before it
let srcline1 = file && file.findLineForOffset(pc, PC_LINE_LOOKAHEAD);
if (srcline1) {
// try to find the next line and bound the PC
let srcline2 = file.lines[srcline1.line+1];
if (!srcline2 || pc < srcline2.offset) {
let score = pc - srcline1.offset;
if (score < bestscore) {
bestid = wndid;
bestscore = score;
}
}
//console.log(hex(pc,4), srcline1, srcline2, wndid, lstfn, bestid, bestscore);
}
//console.log(hex(pc,4), wndid, lstfn, bestid, bestscore);
}
}
}
@ -1464,15 +1479,18 @@ function uiDebugCallback(state: EmuState) {
debugTickPaused = true;
}
function setupDebugCallback(btnid? : string) {
if (platform.setupDebug) platform.setupDebug((state:EmuState, msg:string) => {
uiDebugCallback(state);
setDebugButtonState(btnid||"pause", "stopped");
msg && showErrorAlert([{msg:"STOPPED: " + msg, line:0}], true);
});
function setupDebugCallback(btnid? : DebugCommandType) {
if (platform.setupDebug) {
platform.setupDebug((state:EmuState, msg:string) => {
uiDebugCallback(state);
setDebugButtonState(btnid||"pause", "stopped");
msg && showErrorAlert([{msg:"STOPPED: " + msg, line:0}], true);
});
lastDebugCommand = btnid;
}
}
function setupBreakpoint(btnid? : string) {
function setupBreakpoint(btnid? : DebugCommandType) {
if (!checkRunReady()) return;
_disableRecording();
setupDebugCallback(btnid);

View File

@ -23,6 +23,9 @@ function createTextSpan(text:string, className:string) : HTMLElement {
/////
// look ahead this many bytes when finding source lines for a PC
export const PC_LINE_LOOKAHEAD = 64;
const MAX_ERRORS = 200;
const MODEDEFS = {
@ -384,7 +387,7 @@ export class SourceEditor implements ProjectView {
cpustate = platform.getCPUState();
if (cpustate) {
var EPC = (cpustate && (cpustate.EPC || cpustate.PC));
var res = this.sourcefile.findLineForOffset(EPC, 15);
var res = this.sourcefile.findLineForOffset(EPC, PC_LINE_LOOKAHEAD);
return res;
}
}
@ -598,7 +601,7 @@ export class ListingView extends DisassemblerView implements ProjectView {
var state = lastDebugState || platform.saveState();
var pc = state.c ? (state.c.EPC || state.c.PC) : 0;
if (pc >= 0 && this.assemblyfile) {
var res = this.assemblyfile.findLineForOffset(pc, 15);
var res = this.assemblyfile.findLineForOffset(pc, PC_LINE_LOOKAHEAD);
if (res) {
// set cursor while debugging
if (moveCursor) {