dasm: better error matching, count cycles in scanlineIO view
This commit is contained in:
parent
d97b0eb1c5
commit
8af418fca4
|
@ -1521,8 +1521,8 @@ function _recordVideo() {
|
||||||
_resume();
|
_resume();
|
||||||
$("#videoPreviewModal").modal('show');
|
$("#videoPreviewModal").modal('show');
|
||||||
});
|
});
|
||||||
var intervalMsec = 33;
|
var intervalMsec = 20;
|
||||||
var maxFrames = 200;
|
var maxFrames = 300;
|
||||||
var nframes = 0;
|
var nframes = 0;
|
||||||
console.log("Recording video", canvas);
|
console.log("Recording video", canvas);
|
||||||
$("#emulator").css('backgroundColor', '#cc3333');
|
$("#emulator").css('backgroundColor', '#cc3333');
|
||||||
|
|
|
@ -977,9 +977,23 @@ abstract class ProbeViewBaseBase {
|
||||||
probe : ProbeRecorder;
|
probe : ProbeRecorder;
|
||||||
tooldiv : HTMLElement;
|
tooldiv : HTMLElement;
|
||||||
cumulativeData : boolean = false;
|
cumulativeData : boolean = false;
|
||||||
|
cyclesPerLine : number;
|
||||||
|
totalScanlines : number;
|
||||||
|
|
||||||
abstract tick() : void;
|
abstract tick() : void;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
var width = 160;
|
||||||
|
var height = 262; // TODO: PAL?
|
||||||
|
try {
|
||||||
|
width = Math.ceil(platform['machine']['cpuCyclesPerLine']) || width; // TODO
|
||||||
|
height = Math.ceil(platform['machine']['numTotalScanlines']) || height; // TODO
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
this.cyclesPerLine = width;
|
||||||
|
this.totalScanlines = height;
|
||||||
|
}
|
||||||
|
|
||||||
addr2symbol(addr : number) : string {
|
addr2symbol(addr : number) : string {
|
||||||
var _addr2sym = (platform.debugSymbols && platform.debugSymbols.addr2symbol) || {};
|
var _addr2sym = (platform.debugSymbols && platform.debugSymbols.addr2symbol) || {};
|
||||||
return _addr2sym[addr];
|
return _addr2sym[addr];
|
||||||
|
@ -1128,8 +1142,6 @@ 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;
|
||||||
|
@ -1137,14 +1149,7 @@ abstract class ProbeBitmapViewBase extends ProbeViewBase {
|
||||||
recreateOnResize = false;
|
recreateOnResize = false;
|
||||||
|
|
||||||
createDiv(parent : HTMLElement) {
|
createDiv(parent : HTMLElement) {
|
||||||
var width = 160;
|
return this.createCanvas(parent, this.cyclesPerLine, this.totalScanlines);
|
||||||
var height = 262;
|
|
||||||
try {
|
|
||||||
width = Math.ceil(platform['machine']['cpuCyclesPerLine']) || 256; // TODO
|
|
||||||
height = Math.ceil(platform['machine']['numTotalScanlines']) || 262; // TODO
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
return this.createCanvas(parent, width, height);
|
|
||||||
}
|
}
|
||||||
initCanvas() {
|
initCanvas() {
|
||||||
this.imageData = this.ctx.createImageData(this.canvas.width, this.canvas.height);
|
this.imageData = this.ctx.createImageData(this.canvas.width, this.canvas.height);
|
||||||
|
@ -1270,7 +1275,7 @@ export class ProbeLogView extends ProbeViewBaseBase {
|
||||||
|
|
||||||
createDiv(parent : HTMLElement) {
|
createDiv(parent : HTMLElement) {
|
||||||
this.vlist = new VirtualTextScroller(parent);
|
this.vlist = new VirtualTextScroller(parent);
|
||||||
this.vlist.create(parent, 160*262, this.getMemoryLineAt.bind(this));
|
this.vlist.create(parent, this.cyclesPerLine*this.totalScanlines, this.getMemoryLineAt.bind(this));
|
||||||
return this.vlist.maindiv;
|
return this.vlist.maindiv;
|
||||||
}
|
}
|
||||||
getMemoryLineAt(row : number) : VirtualTextLine {
|
getMemoryLineAt(row : number) : VirtualTextLine {
|
||||||
|
@ -1324,14 +1329,15 @@ export class ScanlineIOView extends ProbeViewBaseBase {
|
||||||
|
|
||||||
createDiv(parent : HTMLElement) {
|
createDiv(parent : HTMLElement) {
|
||||||
this.vlist = new VirtualTextScroller(parent);
|
this.vlist = new VirtualTextScroller(parent);
|
||||||
this.vlist.create(parent, 262, this.getMemoryLineAt.bind(this));
|
this.vlist.create(parent, this.totalScanlines, this.getMemoryLineAt.bind(this));
|
||||||
return this.vlist.maindiv;
|
return this.vlist.maindiv;
|
||||||
}
|
}
|
||||||
getMemoryLineAt(row : number) : VirtualTextLine {
|
getMemoryLineAt(row : number) : VirtualTextLine {
|
||||||
var s = lpad(row+"",3) + ' ';
|
var s = lpad(row+"",3) + ' ';
|
||||||
var c = 'seg_code';
|
var c = 'seg_code';
|
||||||
var line = (this.dumplines && this.dumplines[row]) || [];
|
var line = (this.dumplines && this.dumplines[row]) || [];
|
||||||
for (var i=0; i<76; i++) {
|
var hblankCycle = Math.round(this.cyclesPerLine/3.3);
|
||||||
|
for (var i=0; i<this.cyclesPerLine; i++) {
|
||||||
var opaddr = line[i];
|
var opaddr = line[i];
|
||||||
if (opaddr !== undefined) {
|
if (opaddr !== undefined) {
|
||||||
var addr = opaddr & 0xffff;
|
var addr = opaddr & 0xffff;
|
||||||
|
@ -1344,7 +1350,7 @@ export class ScanlineIOView extends ProbeViewBaseBase {
|
||||||
i += v.length - 1;
|
i += v.length - 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s += (i==23) ? '|' : '.';
|
s += (i==hblankCycle) ? '|' : '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (line[-1]) s += ' ' + line[-1]; // executing symbol
|
if (line[-1]) s += ' ' + line[-1]; // executing symbol
|
||||||
|
|
|
@ -717,23 +717,24 @@ function parseSourceLines(code:string, lineMatch, offsetMatch) {
|
||||||
|
|
||||||
function parseDASMListing(lstpath:string, lsttext:string, listings:CodeListingMap, errors:WorkerError[], unresolved:{}) {
|
function parseDASMListing(lstpath:string, lsttext:string, listings:CodeListingMap, errors:WorkerError[], unresolved:{}) {
|
||||||
// TODO: this gets very slow
|
// TODO: this gets very slow
|
||||||
|
// TODO: macros that are on adjacent lines don't get offset addresses
|
||||||
// 4 08ee a9 00 start lda #01workermain.js:23:5
|
// 4 08ee a9 00 start lda #01workermain.js:23:5
|
||||||
var lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([?0-9a-f][?0-9a-f ]+)?\s+(.+)?/i;
|
let lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([?0-9a-f][?0-9a-f ]+)?\s+(.+)?/i;
|
||||||
var equMatch = /\bequ\b/i;
|
let equMatch = /\bequ\b/i;
|
||||||
var macroMatch = /\bMAC\s+(\S+)?/i;
|
let macroMatch = /\bMAC\s+(\S+)?/i;
|
||||||
var lastline = 0;
|
let lastline = 0;
|
||||||
var macros = {};
|
let macros = {};
|
||||||
var lstline = 0;
|
let lstline = 0;
|
||||||
var lstlist = listings[lstpath];
|
let lstlist = listings[lstpath];
|
||||||
for (var line of lsttext.split(re_crlf)) {
|
for (let line of lsttext.split(re_crlf)) {
|
||||||
lstline++;
|
lstline++;
|
||||||
var linem = lineMatch.exec(line + " ");
|
let linem = lineMatch.exec(line + " ");
|
||||||
if (linem && linem[1] != null) {
|
if (linem && linem[1] != null) {
|
||||||
var linenum = parseInt(linem[1]);
|
let linenum = parseInt(linem[1]);
|
||||||
var filename = linem[2];
|
let filename = linem[2];
|
||||||
var offset = parseInt(linem[3], 16);
|
let offset = parseInt(linem[3], 16);
|
||||||
var insns = linem[4];
|
let insns = linem[4];
|
||||||
var restline = linem[5];
|
let restline = linem[5];
|
||||||
if (insns && insns.startsWith('?')) insns = null;
|
if (insns && insns.startsWith('?')) insns = null;
|
||||||
// don't use listing yet
|
// don't use listing yet
|
||||||
if (lstlist && lstlist.lines) {
|
if (lstlist && lstlist.lines) {
|
||||||
|
@ -745,11 +746,11 @@ function parseDASMListing(lstpath:string, lsttext:string, listings:CodeListingMa
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// inside of a file?
|
// inside of a file?
|
||||||
var lst = listings[filename];
|
let lst = listings[filename];
|
||||||
if (lst) {
|
if (lst) {
|
||||||
var lines = lst.lines;
|
var lines = lst.lines;
|
||||||
// look for MAC statement
|
// look for MAC statement
|
||||||
var macmatch = macroMatch.exec(restline);
|
let macmatch = macroMatch.exec(restline);
|
||||||
if (macmatch) {
|
if (macmatch) {
|
||||||
macros[macmatch[1]] = {line:parseInt(linem[1]), file:linem[2].toLowerCase()};
|
macros[macmatch[1]] = {line:parseInt(linem[1]), file:linem[2].toLowerCase()};
|
||||||
}
|
}
|
||||||
|
@ -764,7 +765,7 @@ function parseDASMListing(lstpath:string, lsttext:string, listings:CodeListingMa
|
||||||
lastline = linenum;
|
lastline = linenum;
|
||||||
} else {
|
} else {
|
||||||
// inside of macro?
|
// inside of macro?
|
||||||
var mac = macros[filename.toLowerCase()];
|
let mac = macros[filename.toLowerCase()];
|
||||||
// macro invocation in main file
|
// macro invocation in main file
|
||||||
if (mac && linenum == 0) {
|
if (mac && linenum == 0) {
|
||||||
lines.push({
|
lines.push({
|
||||||
|
@ -775,7 +776,7 @@ function parseDASMListing(lstpath:string, lsttext:string, listings:CodeListingMa
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (insns && mac) {
|
if (insns && mac) {
|
||||||
var maclst = listings[mac.file];
|
let maclst = listings[mac.file];
|
||||||
if (maclst && maclst.lines) {
|
if (maclst && maclst.lines) {
|
||||||
maclst.lines.push({
|
maclst.lines.push({
|
||||||
path:mac.file,
|
path:mac.file,
|
||||||
|
@ -799,11 +800,11 @@ function parseDASMListing(lstpath:string, lsttext:string, listings:CodeListingMa
|
||||||
}
|
}
|
||||||
// TODO: better symbol test (word boundaries)
|
// TODO: better symbol test (word boundaries)
|
||||||
// TODO: ignore IFCONST and IFNCONST usage
|
// TODO: ignore IFCONST and IFNCONST usage
|
||||||
for (var key in unresolved) {
|
for (let key in unresolved) {
|
||||||
var l = restline || line;
|
let l = restline || line;
|
||||||
var pos = l.indexOf(key);
|
let pos = l.indexOf(key);
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
var cmt = l.indexOf(';');
|
let cmt = l.indexOf(';');
|
||||||
if (cmt < 0 || cmt > pos) {
|
if (cmt < 0 || cmt > pos) {
|
||||||
// make sure identifier is flanked by non-word chars
|
// make sure identifier is flanked by non-word chars
|
||||||
if (/\w+/.test(key) && new RegExp("\\b"+key+"\\b").test(key)) {
|
if (/\w+/.test(key) && new RegExp("\\b"+key+"\\b").test(key)) {
|
||||||
|
@ -817,7 +818,7 @@ function parseDASMListing(lstpath:string, lsttext:string, listings:CodeListingMa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var errm = re_msvc.exec(line);
|
let errm = re_msvc.exec(line);
|
||||||
if (errm) {
|
if (errm) {
|
||||||
errors.push({
|
errors.push({
|
||||||
path:errm[1],
|
path:errm[1],
|
||||||
|
@ -834,7 +835,7 @@ function assembleDASM(step:BuildStep) {
|
||||||
var unresolved = {};
|
var unresolved = {};
|
||||||
var errors = [];
|
var errors = [];
|
||||||
var errorMatcher = msvcErrorMatcher(errors);
|
var errorMatcher = msvcErrorMatcher(errors);
|
||||||
function match_fn(s) {
|
function match_fn(s:string) {
|
||||||
// TODO: what if s is not string? (startsWith is not a function)
|
// TODO: what if s is not string? (startsWith is not a function)
|
||||||
var matches = re_usl.exec(s);
|
var matches = re_usl.exec(s);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
|
@ -846,6 +847,10 @@ function assembleDASM(step:BuildStep) {
|
||||||
errors.push({line:0, msg:s.substr(9)});
|
errors.push({line:0, msg:s.substr(9)});
|
||||||
} else if (s.startsWith("unable ")) {
|
} else if (s.startsWith("unable ")) {
|
||||||
errors.push({line:0, msg:s});
|
errors.push({line:0, msg:s});
|
||||||
|
} else if (s.startsWith("segment: ")) {
|
||||||
|
errors.push({line:0, msg:"Segment overflow: "+s.substring(9)});
|
||||||
|
} else if (s.toLowerCase().indexOf('error:') >= 0) {
|
||||||
|
errors.push({line:0, msg:s.trim()});
|
||||||
} else {
|
} else {
|
||||||
errorMatcher(s);
|
errorMatcher(s);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue