1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-01 20:41:36 +00:00

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 // TODO: smarter about looking for source lines between two addresses
findLineForOffset(PC:number, lookbehind:number) { findLineForOffset(PC:number, lookbehind:number) : SourceLine {
if (this.offset2loc) { if (this.offset2loc) {
for (var i=0; i<=lookbehind; i++) { for (var i=0; i<=lookbehind; i++) {
var loc = this.offset2loc[PC]; var loc = this.offset2loc[PC];

View File

@ -14,7 +14,7 @@ import { StateRecorderImpl } from "../common/recorder";
import { GHSession, GithubService, getRepos, parseGithubURL } from "./services"; import { GHSession, GithubService, getRepos, parseGithubURL } from "./services";
import Split = require('split.js'); import Split = require('split.js');
import { importPlatform } from "../platform/_index"; 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 { AddressHeatMapView, BinaryFileView, MemoryMapView, MemoryView, ProbeLogView, ProbeSymbolView, RasterPCHeatMapView, ScanlineIOView, VRAMMemoryView } from "./views/debugviews";
import { AssetEditorView } from "./views/asseteditor"; import { AssetEditorView } from "./views/asseteditor";
import { isMobileDevice } from "./views/baseviews"; import { isMobileDevice } from "./views/baseviews";
@ -80,11 +80,16 @@ var store : LocalForage; // persistent store
export var compparams; // received build params from worker export var compparams; // received build params from worker
export var lastDebugState : EmuState; // last debug state (object) 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 lastDebugInfo; // last debug info (CPU text)
var debugCategory; // current debug category var debugCategory; // current debug category
var debugTickPaused = false; var debugTickPaused = false;
var recorderActive = false; var recorderActive = false;
var lastViewClicked = null; var lastViewClicked : string = null;
var lastDebugCommand : DebugCommandType = null;
var errorWasRuntime = false; var errorWasRuntime = false;
var lastBreakExpr = "c.PC == 0x6000"; var lastBreakExpr = "c.PC == 0x6000";
@ -1425,30 +1430,40 @@ function checkRunReady() {
} }
function openRelevantListing(state: EmuState) { function openRelevantListing(state: EmuState) {
// if we clicked on another window, retain it // if we clicked on a specific tool, don't switch windows
if (lastViewClicked != null) return; 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 // has to support disassembly, at least
if (!platform.disassemble) return; if (!platform.disassemble) return;
// search through listings // search through listings
var listings = current_project.getListings(); let listings = current_project.getListings();
var bestid = "#disasm"; let bestid = "#disasm";
var bestscore = 32; let bestscore = 256;
if (listings) { if (listings) {
var pc = state.c ? (state.c.EPC || state.c.PC) : 0; let pc = state.c ? (state.c.EPC || state.c.PC) : 0;
for (var lstfn in listings) { for (let lstfn in listings) {
var lst = listings[lstfn]; let lst = listings[lstfn];
var file = lst.assemblyfile || lst.sourcefile; let file = lst.assemblyfile || lst.sourcefile;
// pick either listing or source file // 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); if (file == lst.sourcefile) wndid = projectWindows.findWindowWithFilePrefix(lstfn);
// does this window exist? // does this window exist?
if (projectWindows.isWindow(wndid)) { if (projectWindows.isWindow(wndid)) {
var res = file && file.findLineForOffset(pc, 32); // TODO: const // find the source line at the PC or closely before it
if (res && pc-res.offset < bestscore) { let srcline1 = file && file.findLineForOffset(pc, PC_LINE_LOOKAHEAD);
bestid = wndid; if (srcline1) {
bestscore = pc-res.offset; // 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; debugTickPaused = true;
} }
function setupDebugCallback(btnid? : string) { function setupDebugCallback(btnid? : DebugCommandType) {
if (platform.setupDebug) platform.setupDebug((state:EmuState, msg:string) => { if (platform.setupDebug) {
uiDebugCallback(state); platform.setupDebug((state:EmuState, msg:string) => {
setDebugButtonState(btnid||"pause", "stopped"); uiDebugCallback(state);
msg && showErrorAlert([{msg:"STOPPED: " + msg, line:0}], true); 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; if (!checkRunReady()) return;
_disableRecording(); _disableRecording();
setupDebugCallback(btnid); 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 MAX_ERRORS = 200;
const MODEDEFS = { const MODEDEFS = {
@ -384,7 +387,7 @@ export class SourceEditor implements ProjectView {
cpustate = platform.getCPUState(); cpustate = platform.getCPUState();
if (cpustate) { if (cpustate) {
var EPC = (cpustate && (cpustate.EPC || cpustate.PC)); 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; return res;
} }
} }
@ -598,7 +601,7 @@ export class ListingView extends DisassemblerView implements ProjectView {
var state = lastDebugState || platform.saveState(); var state = lastDebugState || platform.saveState();
var pc = state.c ? (state.c.EPC || state.c.PC) : 0; var pc = state.c ? (state.c.EPC || state.c.PC) : 0;
if (pc >= 0 && this.assemblyfile) { if (pc >= 0 && this.assemblyfile) {
var res = this.assemblyfile.findLineForOffset(pc, 15); var res = this.assemblyfile.findLineForOffset(pc, PC_LINE_LOOKAHEAD);
if (res) { if (res) {
// set cursor while debugging // set cursor while debugging
if (moveCursor) { if (moveCursor) {