2023-11-13 18:17:54 +00:00
|
|
|
import { CodeListing, CodeListingMap } from "../../common/workertypes";
|
|
|
|
import { BuildStep, BuildStepResult, emglobal, execMain, fixParamsWithDefines, gatherFiles, loadNative, makeErrorMatcher, moduleInstFn, msvcErrorMatcher, populateFiles, print_fn, putWorkFile, setupFS, staleFiles } from "../workermain";
|
|
|
|
import { EmscriptenModule } from "../workermain"
|
|
|
|
|
|
|
|
function parseACMESymbolTable(text: string) {
|
|
|
|
var symbolmap = {};
|
|
|
|
var lines = text.split("\n");
|
|
|
|
for (var i = 0; i < lines.length; ++i) {
|
|
|
|
var line = lines[i].trim();
|
|
|
|
// init_text = $81b ; ?
|
|
|
|
var m = line.match(/(\w+)\s*=\s*[$]([0-9a-f]+)/i);
|
|
|
|
if (m) {
|
|
|
|
symbolmap[m[1]] = parseInt(m[2], 16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return symbolmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseACMEReportFile(text: string) {
|
|
|
|
var listings : CodeListingMap = {};
|
|
|
|
var listing : CodeListing;
|
|
|
|
var lines = text.split("\n");
|
|
|
|
for (var i = 0; i < lines.length; ++i) {
|
|
|
|
var line = lines[i].trim();
|
|
|
|
// ; ******** Source: hello.acme
|
|
|
|
var m1 = line.match(/^;\s*[*]+\s*Source: (.+)$/);
|
|
|
|
if (m1) {
|
|
|
|
var file = m1[1];
|
|
|
|
listings[file] = listing = {
|
|
|
|
lines: [],
|
|
|
|
};
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// 15 0815 201b08 jsr init_text ; write line of text
|
|
|
|
var m2 = line.match(/^(\d+)\s+([0-9a-f]+)\s+([0-9a-f]+)/i);
|
|
|
|
if (m2) {
|
|
|
|
if (listing) {
|
|
|
|
listing.lines.push({
|
|
|
|
line: parseInt(m2[1]),
|
|
|
|
offset: parseInt(m2[2], 16),
|
|
|
|
insns: m2[3],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return listings;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function assembleACME(step: BuildStep): BuildStepResult {
|
|
|
|
loadNative("acme");
|
|
|
|
var errors = [];
|
|
|
|
gatherFiles(step, { mainFilePath: "main.acme" });
|
|
|
|
var binpath = step.prefix + ".bin";
|
|
|
|
var lstpath = step.prefix + ".lst";
|
|
|
|
var sympath = step.prefix + ".sym";
|
2023-11-28 03:30:16 +00:00
|
|
|
if (staleFiles(step, [binpath])) {
|
2023-11-13 18:17:54 +00:00
|
|
|
var binout, lstout, symout;
|
|
|
|
var ACME: EmscriptenModule = emglobal.acme({
|
|
|
|
instantiateWasm: moduleInstFn('acme'),
|
|
|
|
noInitialRun: true,
|
|
|
|
print: print_fn,
|
|
|
|
printErr: msvcErrorMatcher(errors),
|
|
|
|
//printErr: makeErrorMatcher(errors, /(Error|Warning) - File (.+?), line (\d+)[^:]+: (.+)/, 3, 4, step.path, 2),
|
|
|
|
});
|
|
|
|
var FS = ACME.FS;
|
|
|
|
populateFiles(step, FS);
|
|
|
|
fixParamsWithDefines(step.path, step.params);
|
|
|
|
var args = ['--msvc', '--initmem', '0', '-o', binpath, '-r', lstpath, '-l', sympath, step.path];
|
|
|
|
if (step.params?.acmeargs) {
|
|
|
|
args.unshift.apply(args, step.params.acmeargs);
|
|
|
|
} else {
|
|
|
|
args.unshift.apply(args, ['-f', 'plain']);
|
|
|
|
}
|
|
|
|
args.unshift.apply(args, ["-D__8BITWORKSHOP__=1"]);
|
|
|
|
if (step.mainfile) {
|
|
|
|
args.unshift.apply(args, ["-D__MAIN__=1"]);
|
|
|
|
}
|
|
|
|
execMain(step, ACME, args);
|
|
|
|
if (errors.length) {
|
|
|
|
let listings: CodeListingMap = {};
|
|
|
|
return { errors, listings };
|
|
|
|
}
|
|
|
|
binout = FS.readFile(binpath, { encoding: 'binary' });
|
|
|
|
lstout = FS.readFile(lstpath, { encoding: 'utf8' });
|
|
|
|
symout = FS.readFile(sympath, { encoding: 'utf8' });
|
|
|
|
putWorkFile(binpath, binout);
|
|
|
|
putWorkFile(lstpath, lstout);
|
|
|
|
putWorkFile(sympath, symout);
|
|
|
|
return {
|
|
|
|
output: binout,
|
|
|
|
listings: parseACMEReportFile(lstout),
|
|
|
|
errors: errors,
|
|
|
|
symbolmap: parseACMESymbolTable(symout),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|