1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-05-28 08:41:30 +00:00

vcs: scanline view, fixed analysis with jsr

This commit is contained in:
Steven Hugg 2021-04-05 12:11:38 -05:00
parent c5ccd4ff48
commit 8afad5571b
8 changed files with 98 additions and 20 deletions

View File

@ -198,6 +198,7 @@ TODO:
- show current tool for file - show current tool for file
- download non-text incbin source file - download non-text incbin source file
- show hidden header files that only exist in Emscripten FS - show hidden header files that only exist in Emscripten FS
can't modify/delete an include file if project doesn't compile
Probing Probing
- probe log doesn't start @ reset - probe log doesn't start @ reset

View File

@ -143,6 +143,8 @@ abstract class CodeAnalyzer6502 implements CodeAnalyzer {
break; break;
case 0x20: // JSR case 0x20: // JSR
// TODO: handle bare RTS case // TODO: handle bare RTS case
minclocks += meta.minCycles;
maxclocks += meta.maxCycles;
this.traceInstructions(addr, minclocks, maxclocks, addr, constraints); this.traceInstructions(addr, minclocks, maxclocks, addr, constraints);
var result = this.jsrresult[addr]; var result = this.jsrresult[addr];
if (result) { if (result) {
@ -150,7 +152,8 @@ abstract class CodeAnalyzer6502 implements CodeAnalyzer {
maxclocks = result.maxclocks; maxclocks = result.maxclocks;
} else { } else {
console.log("No JSR result!", hex(pc), hex(addr)); console.log("No JSR result!", hex(pc), hex(addr));
return; minclocks = maxclocks;
//return;
} }
break; break;
case 0x4c: // JMP case 0x4c: // JMP
@ -160,7 +163,7 @@ abstract class CodeAnalyzer6502 implements CodeAnalyzer {
abort = true; abort = true;
break; break;
case 0x60: // RTS case 0x60: // RTS
if (subaddr) { // TODO: 0 doesn't work if (subaddr) { // TODO: 0 doesn't work
// TODO: combine with previous result // TODO: combine with previous result
var result = this.jsrresult[subaddr]; var result = this.jsrresult[subaddr];
if (!result) { if (!result) {

View File

@ -347,13 +347,15 @@ export class CodeProject {
} }
// returns first listing in format [prefix].lst (TODO: could be better) // returns first listing in format [prefix].lst (TODO: could be better)
getListingForFile(path) : CodeListing { getListingForFile(path: string) : CodeListing {
// ignore include files (TODO) // ignore include files (TODO)
if (path.toLowerCase().endsWith('.h') || path.toLowerCase().endsWith('.inc')) if (path.toLowerCase().endsWith('.h') || path.toLowerCase().endsWith('.inc'))
return; return;
var fnprefix = getFilenamePrefix(this.stripLocalPath(path)); var fnprefix = getFilenamePrefix(this.stripLocalPath(path));
var listings = this.getListings(); var listings = this.getListings();
var onlyfile = null;
for (var lstfn in listings) { for (var lstfn in listings) {
onlyfile = lstfn;
if (getFilenamePrefix(lstfn) == fnprefix) { if (getFilenamePrefix(lstfn) == fnprefix) {
return listings[lstfn]; return listings[lstfn];
} }

View File

@ -303,6 +303,9 @@ function refreshWindowList() {
addWindowItem("#probelog", "Probe Log", () => { addWindowItem("#probelog", "Probe Log", () => {
return new Views.ProbeLogView(); return new Views.ProbeLogView();
}); });
addWindowItem("#scanlineio", "Scanline I/O", () => {
return new Views.ScanlineIOView();
});
addWindowItem("#symbolprobe", "Symbol Profiler", () => { addWindowItem("#symbolprobe", "Symbol Profiler", () => {
return new Views.ProbeSymbolView(); return new Views.ProbeSymbolView();
}); });

View File

@ -1128,6 +1128,8 @@ abstract class ProbeViewBase extends ProbeViewBaseBase {
} }
} }
// TODO: remove all 160/262 constants (in case of PAL)
abstract class ProbeBitmapViewBase extends ProbeViewBase { abstract class ProbeBitmapViewBase extends ProbeViewBase {
imageData : ImageData; imageData : ImageData;
@ -1314,6 +1316,70 @@ export class ProbeLogView extends ProbeViewBaseBase {
} }
} }
export class ScanlineIOView extends ProbeViewBaseBase {
vlist : VirtualTextScroller;
maindiv : HTMLElement;
recreateOnResize = true;
dumplines;
createDiv(parent : HTMLElement) {
this.vlist = new VirtualTextScroller(parent);
this.vlist.create(parent, 262, this.getMemoryLineAt.bind(this));
return this.vlist.maindiv;
}
getMemoryLineAt(row : number) : VirtualTextLine {
var s = lpad(row+"",3) + ' ';
var c = 'seg_code';
var line = (this.dumplines && this.dumplines[row]) || [];
for (var i=0; i<76; i++) {
var opaddr = line[i];
if (opaddr !== undefined) {
var addr = opaddr & 0xffff;
var op = op & 0xff000000;
if (op == ProbeFlags.EXECUTE) {
s += ',';
} else {
var v = hex(addr);
s += v;
i += v.length - 1;
}
} else {
s += (i==23) ? '|' : '.';
}
}
if (line[-1]) s += ' ' + line[-1]; // executing symbol
return {text:s, clas:c};
}
refresh() {
this.tick();
}
tick() {
const isz80 = platform instanceof BaseZ80MachinePlatform || platform instanceof BaseZ80Platform; // TODO?
// cache each line in frame
this.dumplines = {};
this.redraw((op,addr,col,row,clk,value) => {
var line = this.dumplines[row];
if (line == null) {
this.dumplines[row] = line = [];
}
switch (op) {
case ProbeFlags.EXECUTE:
var sym = platform.debugSymbols.addr2symbol[addr];
if (sym) line[-1] = sym;
break;
case ProbeFlags.MEM_WRITE:
case ProbeFlags.IO_READ:
case ProbeFlags.IO_WRITE:
case ProbeFlags.VRAM_READ:
case ProbeFlags.VRAM_WRITE:
line[col] = op | addr;
break;
}
});
this.vlist.refresh();
}
}
/// ///
export class ProbeSymbolView extends ProbeViewBaseBase { export class ProbeSymbolView extends ProbeViewBaseBase {

View File

@ -126,13 +126,13 @@ class VCSPlatform extends BasePlatform {
return Javatari.getOpcodeMetadata(opcode, offset); return Javatari.getOpcodeMetadata(opcode, offset);
} }
getRasterPosition() : {x:number,y:number} { getRasterPosition() : {x:number,y:number,clk:number} {
var clkfs = Javatari.room.console.getClocksFromFrameStart() - 1; var clkfs = Javatari.room.console.getClocksFromFrameStart() - 1;
var row = Math.floor(clkfs/76); var row = Math.floor(clkfs/76);
var col = clkfs - row*76; var col = clkfs - row*76;
var xpos = col*3-68; var xpos = col*3-68;
var ypos = row-39; var ypos = row-39;
return {x:xpos, y:ypos}; return {x:xpos, y:ypos, clk:clkfs%76};
} }
getRasterScanline() : number { getRasterScanline() : number {
return this.getRasterPosition().y; return this.getRasterPosition().y;
@ -292,7 +292,7 @@ class VCSPlatform extends BasePlatform {
tiaStateToLongString(t) { tiaStateToLongString(t) {
var pos = this.getRasterPosition(); var pos = this.getRasterPosition();
var s = ''; var s = '';
s += "H" + lpad(pos.x.toString(),5) + " V" + lpad(pos.y.toString(),5) + " "; s += "H" + lpad(pos.x.toString(),5) + " (clk " + lpad(pos.clk.toString(),3) + ") V" + lpad(pos.y.toString(),5) + " ";
s += (t.vs?"VSYNC ":"- ") + (t.vb?"VBLANK ":"- ") + "\n"; s += (t.vs?"VSYNC ":"- ") + (t.vb?"VBLANK ":"- ") + "\n";
s += "\n"; s += "\n";
s += "Playfield " + t.f + "\n"; s += "Playfield " + t.f + "\n";

View File

@ -10,7 +10,7 @@ MEMORY {
SEGMENTS { SEGMENTS {
RODATA: load=ROM, type=ro, align=$100; RODATA: load=ROM, type=ro, align=$100;
CODE: load=ROM, type=ro, align=$100, define=yes; CODE: load=ROM, type=ro, define=yes;
DATA: load=ROM, run=RAM, type=rw, define=yes; DATA: load=ROM, run=RAM, type=rw, define=yes;
BSS: load=RAM, type=bss, define=yes; BSS: load=RAM, type=bss, define=yes;
VECTORS: load=ROM, type=ro, start=$FFFA; VECTORS: load=ROM, type=ro, start=$FFFA;

View File

@ -721,7 +721,6 @@ function parseDASMListing(code:string, listings:CodeListingMap, errors:WorkerErr
var lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([?0-9a-f][?0-9a-f ]+)?\s+(.+)?/i; var lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([?0-9a-f][?0-9a-f ]+)?\s+(.+)?/i;
var equMatch = /\bequ\b/i; var equMatch = /\bequ\b/i;
var macroMatch = /\bMAC\s+(.+)?/i; var macroMatch = /\bMAC\s+(.+)?/i;
var macrolines = [];
var lastline = 0; var lastline = 0;
var macros = {}; var macros = {};
for (var line of code.split(re_crlf)) { for (var line of code.split(re_crlf)) {
@ -752,23 +751,28 @@ function parseDASMListing(code:string, listings:CodeListingMap, errors:WorkerErr
} }
lastline = linenum; lastline = linenum;
} else { } else {
// inside of macro or include file
if (insns && linem[3] && lastline>0) {
lines.push({
line:lastline+1,
offset:offset,
insns:null
});
}
// inside of macro? // inside of macro?
var mac = macros[filename.toLowerCase()]; var mac = macros[filename.toLowerCase()];
if (insns && mac) { if (insns && mac) {
macrolines.push({ /*
filename:mac.file, lines.push({
path:mac.file,
line:mac.line+linenum, line:mac.line+linenum,
offset:offset, offset:offset,
insns:insns insns:insns,
iscode:true
}); });
*/
// TODO: a listing file can't include other files
} else {
// inside of macro or include file
if (insns && linem[3] && lastline>0) {
lines.push({
line:lastline+1,
offset:offset,
insns:null
});
}
} }
} }
// TODO: better symbol test (word boundaries) // TODO: better symbol test (word boundaries)
@ -800,7 +804,6 @@ function parseDASMListing(code:string, listings:CodeListingMap, errors:WorkerErr
}) })
} }
} }
// TODO: use macrolines
} }
function assembleDASM(step:BuildStep) { function assembleDASM(step:BuildStep) {