8bitworkshop/src/worker/tools/z80.ts

70 lines
2.4 KiB
TypeScript

import { CodeListingMap } from "../../common/workertypes";
import { BuildStep, BuildStepResult, gatherFiles, staleFiles, populateFiles, putWorkFile, anyTargetChanged } from "../builder";
import { makeErrorMatcher, parseListing } from "../listingutils";
import { EmscriptenModule, emglobal, execMain, loadNative, moduleInstFn, print_fn } from "../wasmutils";
export function assembleZMAC(step: BuildStep): BuildStepResult {
loadNative("zmac");
var hexout, lstout, binout;
var errors = [];
var params = step.params;
gatherFiles(step, { mainFilePath: "main.asm" });
var lstpath = step.prefix + ".lst";
var binpath = step.prefix + ".cim";
if (staleFiles(step, [binpath])) {
/*
error1.asm(4) : 'l18d4' Undeclared
JP L18D4
error1.asm(11): warning: 'foobar' treated as label (instruction typo?)
Add a colon or move to first column to stop this warning.
1 errors (see listing if no diagnostics appeared here)
*/
var ZMAC: EmscriptenModule = emglobal.zmac({
instantiateWasm: moduleInstFn('zmac'),
noInitialRun: true,
//logReadFiles:true,
print: print_fn,
printErr: makeErrorMatcher(errors, /([^( ]+)\s*[(](\d+)[)]\s*:\s*(.+)/, 2, 3, step.path),
});
var FS = ZMAC.FS;
populateFiles(step, FS);
// TODO: don't know why CIM (hexary) doesn't work
execMain(step, ZMAC, ['-z', '-c', '--oo', 'lst,cim', step.path]);
if (errors.length) {
return { errors: errors };
}
lstout = FS.readFile("zout/" + lstpath, { encoding: 'utf8' });
binout = FS.readFile("zout/" + binpath, { encoding: 'binary' });
putWorkFile(binpath, binout);
putWorkFile(lstpath, lstout);
if (!anyTargetChanged(step, [binpath, lstpath]))
return;
// 230: 1739+7+x 017A 1600 L017A: LD D,00h
var lines = parseListing(lstout, /\s*(\d+):\s*([0-9a-f]+)\s+([0-9a-f]+)\s+(.+)/i, 1, 2, 3);
var listings: CodeListingMap = {};
listings[lstpath] = { lines: lines };
// parse symbol table
var symbolmap = {};
var sympos = lstout.indexOf('Symbol Table:');
if (sympos > 0) {
var symout = lstout.slice(sympos + 14);
symout.split('\n').forEach(function (l) {
var m = l.match(/(\S+)\s+([= ]*)([0-9a-f]+)/i);
if (m) {
symbolmap[m[1]] = parseInt(m[3], 16);
}
});
}
return {
output: binout,
listings: listings,
errors: errors,
symbolmap: symbolmap
};
}
}