mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-31 10:30:29 +00:00
better output listing parse
This commit is contained in:
parent
b1d05bde7c
commit
8f50fa9f25
16
src/emu.js
16
src/emu.js
@ -469,6 +469,12 @@ var Base6502Platform = function() {
|
||||
this.cpuStateToLongString = function(c) {
|
||||
return cpuStateToLongString_6502(c);
|
||||
}
|
||||
this.getToolForFilename = function(fn) {
|
||||
if (fn.endsWith(".pla")) return "plasm";
|
||||
if (fn.endsWith(".c")) return "cc65";
|
||||
if (fn.endsWith(".s")) return "ca65";
|
||||
return "dasm";
|
||||
}
|
||||
}
|
||||
|
||||
function dumpRAM(ram, ramofs, ramlen) {
|
||||
@ -619,4 +625,14 @@ var BaseZ80Platform = function() {
|
||||
this.cpuStateToLongString = function(c) {
|
||||
return cpuStateToLongString_Z80(c);
|
||||
}
|
||||
this.getToolForFilename = function(fn) {
|
||||
if (fn.endsWith(".c")) return "sdcc";
|
||||
return "z80asm";
|
||||
}
|
||||
}
|
||||
|
||||
function padBytes(data, len) {
|
||||
var r = new RAM(len);
|
||||
r.mem.set(data);
|
||||
return r.mem;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ var SpaceInvadersPlatform = function(mainElement) {
|
||||
}
|
||||
|
||||
this.loadROM = function(title, data) {
|
||||
rom = data;
|
||||
rom = padBytes(data, 0x2000);
|
||||
self.reset();
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,9 @@ var VCSPlatform = function() {
|
||||
var ram = self.getRAMForState(state);
|
||||
return "\n" + dumpRAM(ram, 0x80, 0x80);
|
||||
}
|
||||
this.getToolForFilename = function(fn) {
|
||||
return "dasm";
|
||||
}
|
||||
};
|
||||
|
||||
PLATFORMS['vcs'] = VCSPlatform;
|
||||
|
19
src/ui.js
19
src/ui.js
@ -202,7 +202,7 @@ function _shareFile(e) {
|
||||
$.post({
|
||||
url: 'share.php',
|
||||
data: {
|
||||
'platform':'vcs', /// TODO
|
||||
'platform':platform_id,
|
||||
'filename':current_preset_id.split('/').pop(),
|
||||
'text':text,
|
||||
},
|
||||
@ -275,16 +275,9 @@ function updateSelector() {
|
||||
});
|
||||
}
|
||||
|
||||
function getToolForFilename(fn) {
|
||||
if (fn.endsWith(".pla")) return "plasm";
|
||||
if (fn.endsWith(".c")) return "cc65";
|
||||
if (fn.endsWith(".s")) return "ca65";
|
||||
if (fn.endsWith(".asm")) return "z80asm";
|
||||
return "dasm";
|
||||
}
|
||||
|
||||
function setCode(text) {
|
||||
worker.postMessage({code:text, tool:getToolForFilename(current_preset_id)});
|
||||
worker.postMessage({code:text, platform:platform_id,
|
||||
tool:platform.getToolForFilename(current_preset_id)});
|
||||
}
|
||||
|
||||
function arrayCompare(a,b) {
|
||||
@ -301,10 +294,10 @@ function arrayCompare(a,b) {
|
||||
worker.onmessage = function(e) {
|
||||
// errors?
|
||||
var toolbar = $("#controls_top");
|
||||
if (e.data.listing.errors.length > 0) {
|
||||
if (e.data.errors.length > 0) {
|
||||
toolbar.addClass("has-errors");
|
||||
editor.clearGutter("gutter-info");
|
||||
for (info of e.data.listing.errors) {
|
||||
for (info of e.data.errors) {
|
||||
var div = document.createElement("div");
|
||||
div.setAttribute("class", "tooltipbox tooltiperror");
|
||||
div.style.color = '#ff3333'; // TODO
|
||||
@ -342,7 +335,7 @@ worker.onmessage = function(e) {
|
||||
editor.clearGutter("gutter-clock");
|
||||
offset2line = {};
|
||||
line2offset = {};
|
||||
for (var info of e.data.listing.lines) {
|
||||
for (var info of e.data.lines) {
|
||||
if (info.offset >= 0) {
|
||||
var textel = document.createTextNode(hex(info.offset,4));
|
||||
editor.setGutterMarker(info.line-1, "gutter-offset", textel);
|
||||
|
@ -72,14 +72,14 @@ var print_fn = function(s) {
|
||||
}
|
||||
|
||||
// test.c(6) : warning 85: in function main unreferenced local variable : 'x'
|
||||
var re_msvc = /(.*?)[(](\d+)[)]\s*:\s*(\w+)\s*(\d+):\s*(.*)/;
|
||||
var re_msvc = /(.*?)[(](\d+)[)]\s*:\s*(\w+)\s*(\d+):\s*(.*)/;
|
||||
var re_msvc2 = /\s*at\s+(\d+)\s*:\s*(.*)/;
|
||||
var msvc_errors;
|
||||
|
||||
function match_msvc(s) {
|
||||
var matches = re_msvc.exec(s);
|
||||
console.log(s, matches);
|
||||
var matches = re_msvc.exec(s) || re_msvc2.exec(s);
|
||||
if (matches) {
|
||||
errline = parseInt(matches[1]);
|
||||
var errline = parseInt(matches[1]);
|
||||
msvc_errors.push({
|
||||
line:errline,
|
||||
msg:matches[2]
|
||||
@ -87,22 +87,19 @@ function match_msvc(s) {
|
||||
}
|
||||
}
|
||||
|
||||
function parseListing(code, lineMatch) {
|
||||
function parseListing(code, lineMatch, iline, ioffset, iinsns) {
|
||||
var lines = [];
|
||||
for (var line of code.split(/\r?\n/)) {
|
||||
var linem = lineMatch.exec(line);
|
||||
if (linem && linem[1]) {
|
||||
var linenum = parseInt(linem[1]);
|
||||
var filename = linem[2];
|
||||
var offset = parseInt(linem[3], 16);
|
||||
var insns = linem[4];
|
||||
var restline = linem[5];
|
||||
var linenum = parseInt(linem[iline]);
|
||||
var offset = parseInt(linem[ioffset], 16);
|
||||
var insns = linem[iinsns];
|
||||
if (insns) {
|
||||
lines.push({
|
||||
line:linenum,
|
||||
offset:offset,
|
||||
insns:insns,
|
||||
iscode:restline[0] != '.'
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -193,7 +190,8 @@ function assembleDASM(code) {
|
||||
return {
|
||||
exitstatus:Module.EXITSTATUS,
|
||||
output:aout.slice(2),
|
||||
listing:listing,
|
||||
lines:listing.lines,
|
||||
errors:listing.errors,
|
||||
intermediate:{listing:alst},
|
||||
};
|
||||
}
|
||||
@ -224,16 +222,17 @@ function assembleACME(code) {
|
||||
// TODO: --msvc
|
||||
Module.callMain(["-o", "a.out", "-r", "a.rpt", "-l", "a.sym", "--setpc", "24576", "main.a"]);
|
||||
if (errors.length) {
|
||||
return {listing:{errors:errors}};
|
||||
return {errors:errors};
|
||||
}
|
||||
var aout = FS.readFile("a.out");
|
||||
var alst = FS.readFile("a.rpt", {'encoding':'utf8'});
|
||||
var asym = FS.readFile("a.sym", {'encoding':'utf8'});
|
||||
var listing = parseDASMListing(alst, {});
|
||||
var listing = parseDASMListing(alst, {}); // TODO
|
||||
return {
|
||||
exitstatus:Module.EXITSTATUS,
|
||||
output:aout,
|
||||
listing:listing,
|
||||
lines:listing.lines,
|
||||
errors:listing.errors,
|
||||
intermediate:{listing:alst, symbols:asym},
|
||||
};
|
||||
}
|
||||
@ -281,7 +280,7 @@ function compilePLASMA(code) {
|
||||
Module.callMain(["-A"]);
|
||||
outstr = "INTERP = $e044\n" + outstr; // TODO
|
||||
if (errors.length) {
|
||||
return {listing:{errors:errors}};
|
||||
return {errors:errors};
|
||||
}
|
||||
return assembleACME(outstr);
|
||||
}
|
||||
@ -317,8 +316,6 @@ function parseCA65Listing(code, mapfile) {
|
||||
function assemblelinkCA65(code, platform, warnings) {
|
||||
load("ca65");
|
||||
load("ld65");
|
||||
if (!platform)
|
||||
platform = 'apple2'; // TODO
|
||||
var objout, lstout;
|
||||
{
|
||||
var CA65 = ca65({
|
||||
@ -350,10 +347,12 @@ function assemblelinkCA65(code, platform, warnings) {
|
||||
'-t', platform, '-o', 'main', '-m', 'main.map', 'main.o', platform+'.lib']);
|
||||
var aout = FS.readFile("main", {encoding:'binary'});
|
||||
var mapout = FS.readFile("main.map", {encoding:'utf8'});
|
||||
var listing = parseCA65Listing(lstout, mapout);
|
||||
return {
|
||||
exitstatus:LD65.EXITSTATUS,
|
||||
output:aout.slice(4),
|
||||
listing:parseCA65Listing(lstout, mapout),
|
||||
lines:listing.lines,
|
||||
errors:listing.errors,
|
||||
intermediate:{listing:lstout, map:mapout},
|
||||
};
|
||||
}
|
||||
@ -361,8 +360,6 @@ function assemblelinkCA65(code, platform, warnings) {
|
||||
|
||||
function compileCC65(code, platform) {
|
||||
load("cc65");
|
||||
if (!platform)
|
||||
platform = 'apple2'; // TODO
|
||||
// stderr
|
||||
var re_err1 = /.*?(\d+).*?: (.+)/;
|
||||
var errors = [];
|
||||
@ -392,14 +389,12 @@ function compileCC65(code, platform) {
|
||||
var asmout = FS.readFile("main.s", {encoding:'utf8'});
|
||||
return assemblelinkCA65(asmout, platform, errors);
|
||||
} catch(e) {
|
||||
return {listing:{errors:errors}};
|
||||
return {errors:errors};
|
||||
}
|
||||
}
|
||||
|
||||
function assembleZ80ASM(code, platform) {
|
||||
function assembleZ80ASM(code, platform, ccompile) {
|
||||
load("z80asm");
|
||||
if (!platform)
|
||||
platform = 'apple2'; // TODO
|
||||
var Module = z80asm({
|
||||
noInitialRun:true,
|
||||
//logReadFiles:true,
|
||||
@ -412,15 +407,17 @@ function assembleZ80ASM(code, platform) {
|
||||
//setupFS(FS);
|
||||
// changes for dialect
|
||||
code = code.replace(".optsdcc -mz80","");
|
||||
code = code.replace(/^(\w+)\s*=/gim,"DEFC $1 =");
|
||||
code = code.replace(/\tXREF /gi,"\tEXTERN ");
|
||||
code = code.replace(/\tXDEF /gi,"\tPUBLIC ");
|
||||
//console.log(code.split("\n"));
|
||||
FS.writeFile("main.asm", code);
|
||||
try {
|
||||
Module.callMain(["-b", "-s", "-l", "-m", "main.asm"]);
|
||||
try {
|
||||
var aerr = FS.readFile("main.err", {'encoding':'utf8'}); // TODO
|
||||
if (aerr.length) {
|
||||
return {listing:{errors:extractErrors(aerr.split("\n"), /.+? line (\d+): (.+)/)}};
|
||||
return {errors:extractErrors(aerr.split("\n"), /.+? line (\d+): (.+)/)};
|
||||
}
|
||||
// Warning at file 'test.asm' line 9: 'XREF' is deprecated, use 'EXTERN' instead
|
||||
} catch (e) {
|
||||
@ -436,14 +433,13 @@ l_main00101 = 0003, L: test
|
||||
*/
|
||||
var amap = FS.readFile("main.map", {'encoding':'utf8'}); // TODO
|
||||
var aout = FS.readFile("main.bin", {'encoding':'binary'});
|
||||
var listing = parseDASMListing(alst, {}); // TODO
|
||||
var asmlines = parseListing(alst, /(\d+)(\s+)([0-9A-F]+)\s+([0-9A-F][0-9A-F ]*[0-9A-F])\s+([A-Z_.].+)/i, 1, 2, 3);
|
||||
var srclines = parseListing(alst, /(\d+)\s+([0-9A-F]+)\s+;[(]null[)]:(\d+)/i, 3, 2, 1);
|
||||
return {
|
||||
exitstatus:Module.EXITSTATUS,
|
||||
output:aout,
|
||||
listing:{
|
||||
errors:[],
|
||||
lines:parseListing(alst, /(\d+)(\s+)([0-9A-F]+)\s+([0-9A-F][0-9A-F ]*[0-9A-F])\s+([A-Z_.].+)/i)
|
||||
},
|
||||
errors:[],
|
||||
lines:ccompile ? srclines : asmlines,
|
||||
intermediate:{listing:alst, mapfile:amap},
|
||||
};
|
||||
} catch (e) {
|
||||
@ -470,14 +466,17 @@ function compileSDCC(code, platform) {
|
||||
'-mz80', '--asm=z80asm', '-o', 'test.asm']);
|
||||
try {
|
||||
var asmout = FS.readFile("test.asm", {encoding:'utf8'});
|
||||
return assembleZ80ASM(asmout, platform, msvc_errors);
|
||||
var result = assembleZ80ASM(asmout, platform, true);
|
||||
result.errors = result.errors.concat(msvc_errors);
|
||||
return result;
|
||||
} catch(e) {
|
||||
return {listing:{errors:msvc_errors}};
|
||||
return {errors:msvc_errors};
|
||||
}
|
||||
}
|
||||
|
||||
var tools = {
|
||||
var TOOLS = {
|
||||
'dasm': assembleDASM,
|
||||
'acme': assembleACME,
|
||||
'plasm': compilePLASMA,
|
||||
'cc65': compileCC65,
|
||||
'ca65': assemblelinkCA65,
|
||||
@ -488,7 +487,7 @@ var tools = {
|
||||
onmessage = function(e) {
|
||||
var code = e.data.code;
|
||||
var platform = e.data.platform;
|
||||
var toolfn = tools[e.data.tool];
|
||||
var toolfn = TOOLS[e.data.tool];
|
||||
if (!toolfn) throw "no tool named " + e.data.tool;
|
||||
var result = toolfn(code, platform);
|
||||
if (result) {
|
||||
|
@ -59,40 +59,46 @@ global.postMessage = null;
|
||||
|
||||
includeInThisContext("src/worker/workermain.js");
|
||||
|
||||
function compile(tool, code, callback, outlen, nlines, nerrors) {
|
||||
function compile(tool, code, platform, callback, outlen, nlines, nerrors) {
|
||||
global.postMessage = function(msg) {
|
||||
if (msg.listing.errors && msg.listing.errors.length) {
|
||||
console.log(msg.listing.errors);
|
||||
assert.equal(nerrors, msg.listing.errors.length, "errors");
|
||||
if (msg.errors && msg.errors.length) {
|
||||
console.log(msg.errors);
|
||||
assert.equal(nerrors, msg.errors.length, "errors");
|
||||
} else {
|
||||
assert.equal(nerrors||0, 0, "errors");
|
||||
assert.equal(msg.output.length, outlen, "output binary");
|
||||
assert.equal(msg.listing.lines.length, nlines, "listing lines");
|
||||
assert.equal(msg.lines.length, nlines, "listing lines");
|
||||
}
|
||||
callback(null, msg);
|
||||
};
|
||||
global.onmessage({
|
||||
data:{code:code, tool:tool}
|
||||
data:{code:code, platform:platform, tool:tool}
|
||||
});
|
||||
}
|
||||
|
||||
describe('Worker', function() {
|
||||
it('should assemble DASM', function(done) {
|
||||
compile('dasm', '\tprocessor 6502\n\torg $f000\nfoo lda #0\n', done, 2, 1);
|
||||
compile('dasm', '\tprocessor 6502\n\torg $f000\nfoo lda #0\n', 'vcs', done, 2, 1);
|
||||
});
|
||||
it('should assemble ACME', function(done) {
|
||||
compile('acme', 'foo: lda #0\n', 'vcs', done, 2, 0); // TODO
|
||||
});
|
||||
it('should compile PLASMA', function(done) {
|
||||
compile('plasm', 'word x = 0', done, 5, 0);
|
||||
compile('plasm', 'word x = 0', 'apple2', done, 5, 0);
|
||||
});
|
||||
it('should compile CC65', function(done) {
|
||||
compile('cc65', '#include <stdio.h>\nint main() {\nint x=1;\nprintf("%d",x);\nreturn x+2;\n}', done, 2947, 4);
|
||||
compile('cc65', '#include <stdio.h>\nint main() {\nint x=1;\nprintf("%d",x);\nreturn x+2;\n}', 'apple2', done, 2947, 4);
|
||||
});
|
||||
it('should NOT assemble Z80ASM', function(done) {
|
||||
compile('z80asm', 'ddwiuweq', done, 0, 0, 1);
|
||||
compile('z80asm', 'ddwiuweq', 'none', done, 0, 0, 1);
|
||||
});
|
||||
it('should assemble Z80ASM', function(done) {
|
||||
compile('z80asm', '\tMODULE test\n\tXREF _puts\n\tld hl,$0000\n\tret\n', done, 4, 2, 0);
|
||||
compile('z80asm', '\tMODULE test\n\tXREF _puts\n\tld hl,$0000\n\tret\n', 'none', done, 4, 2, 0);
|
||||
});
|
||||
it('should NOT compile SDCC', function(done) {
|
||||
compile('sdcc', 'foobar', 'none', done, 0, 0, 1);
|
||||
});
|
||||
it('should compile SDCC', function(done) {
|
||||
compile('sdcc', 'int main(int argc) {\nint x=1; int y=2;\nreturn x+y+argc;\n}', done, 16, 8, 0);
|
||||
compile('sdcc', 'int main(int argc) {\nint x=1; int y=2;\nreturn x+y+argc;\n}', 'none', done, 16, 2, 0);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user