UNPKG

@justnine/asm80

Version:

ASM80 stand-alone assembler (fork of asm80)

296 lines (260 loc) 7.31 kB
#!/usr/bin/env node /** * Multitarget assembler (C) 2013 Martin Maly, http://www.maly.cz, http://www.webscript.cz * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Parser is based on ndef.parser, by Raphael Graf(r@undefined.ch) * http://www.undefined.ch/mparser/index.html * * Ported to JavaScript and modified by Matthew Crumley (email@matthewcrumley.com, http://silentmatt.com/) * * You are free to use and modify this code in anyway you find useful. Please leave this comment in the code * to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, * but don't feel like you have to let me know or ask permission. */ /* eslint-disable no-console */ var __cwd = process.cwd(); var ASM = require("./asm.js"); var Monolith = require("./monolith.js"); var path = require("path"); var LFS = require("./lfsnode.js"); var hextools = require("./hextools.js"); var pjson = require("./package.json"); var corejson = require("./core.json"); var program = require("commander"); program .version(pjson.version + "-core" + corejson.version) .usage("[options] <file>") .option("-o, --output <file>", "Output file name") .option( "-t, --type <type>", "Output type [default: hex] - hex, srec, com (for CP/M), sna, tap (for ZX Spectrum), prg (for C64), bin" ) .option("-n, --nolist", "Suppress listing") .option("-m, --machine <type>", "Processor type (see below)") .on("--help", function () { console.log(" Machine types:"); console.log(""); if (Monolith) { for (var i in Monolith) { console.log(" - " + i); } } console.log(""); console.log("See https://maly.github.io/asm80-node/ for further docs"); }) .parse(process.argv); if (!program.args.length) { program.help(); } var asmType = function (fn) { var type = "unknown"; switch (path.extname(fn).toUpperCase()) { case ".A80": type = "I8080"; break; case ".A08": type = "I8008"; break; case ".A68": type = "M6800"; break; case ".A18": type = "CDP1802"; break; case ".A09": type = "M6809"; break; case ".A65": type = "C6502"; break; case ".816": type = "C65816"; break; case ".Z80": type = "Z80"; break; } return type; }; var fn = path.resolve(__cwd, program.args[program.args.length - 1]); var asmtype = asmType(fn); var data = LFS.load(program.args[program.args.length - 1]); if (program.machine) { asmtype = program.machine.toUpperCase(); } var vxx = [null, null]; var mpath = path.parse(fn); var root = mpath.dir; ASM.fileGet(function (fn, binary) { var nfn = path.resolve(root, fn); return LFS.load(nfn, binary); }); switch (asmtype) { case "I8080": vxx = ASM.compile(data, Monolith.I8080); break; case "I8008": vxx = ASM.compile(data, Monolith.I8008); break; case "C6502": vxx = ASM.compile(data, Monolith.C6502); break; case "C65816": vxx = ASM.compile(data, Monolith.C65816); break; case "Z80": vxx = ASM.compile(data, Monolith.Z80); break; case "M6800": vxx = ASM.compile(data, Monolith.M6800); break; case "CDP1802": vxx = ASM.compile(data, Monolith.CDP1802); break; case "M6809": vxx = ASM.compile(data, Monolith.H6309); if (ASM.PRAGMAS.indexOf("6309") < 0) { vxx = ASM.compile(data, Monolith.M6809); } break; default: console.log("Unrecognized ASM type"); process.exit(-1); } if (vxx[0]) { //error var err = vxx[0]; if (err.msg) { console.error("ERROR ", err.msg); console.error("at line ", err.s.numline); console.error(">>> ", err.s.line); } else console.log(vxx[0]); process.exit(-1); } var otype = "hex"; if (program.type) { switch (program.type.toUpperCase()) { case "SREC": otype = "srec"; break; case "HEX": otype = "hex"; break; case "PRG": otype = "prg"; break; case "COM": otype = "com"; break; case "SNA": otype = "sna"; break; case "TAP": otype = "tap"; break; case "BIN": otype = "bin"; break; default: console.log("Unknown output type"); process.exit(-1); } } var npath = path.parse(fn); npath.ext = "." + otype; delete npath.base; var vx = vxx[1]; var outdata; if (otype === "srec") { outdata = ASM.srec(vx[0]); } else { outdata = ASM.hex(vx[0]); } if (program.output) { npath.base = program.output; } if (ASM.PRAGMAS.indexOf("SEGMENT") >= 0) { LFS.save(path.format(npath), outdata); var mseg = ASM.hex(vx[0], "DSEG"); npath.ext = ".dseg.hex"; if (mseg.length > 11) LFS.save(path.format(npath), mseg); npath.ext = ".eseg.hex"; mseg = ASM.hex(vx[0], "ESEG"); if (mseg.length > 11) LFS.save(path.format(npath), mseg); npath.ext = ".hex"; } if (otype === "prg") { if (asmtype !== "C6502") { console.log( "Warning: PRG is for Commodore C64, it should be compiled for 6502 CPU" ); } if (!ASM.ENT) { console.log("Please specify the entry point (use .ENT directive)"); } outdata = hextools.hex2prg(outdata, ASM.ENT); } if (otype === "com") { if (asmtype !== "I8080" && asmtype !== "Z80") { console.log( "Warning: COM is for CP/M, it should be compiled for 8080/Z80 CPU" ); } outdata = hextools.hex2com(outdata, ASM.ENT); } if (otype === "sna") { if (asmtype !== "Z80") { console.log( "Warning: SNA is for ZX Spectrum, it should be compiled for Z80 CPU" ); } outdata = hextools.makeSNA(vx[0], ASM.ENT); } if (otype === "tap") { if (asmtype !== "Z80") { console.log( "Warning: TAP is for ZX Spectrum, it should be compiled for Z80 CPU" ); } outdata = hextools.makeTAP(vx[0], ASM.ENT); } if (otype === "bin") { var hex = ASM.hex(vx[0]); var mFrom = 0; var mTo = 65535; if (ASM.BINFROM) mFrom = ASM.BINFROM; if (ASM.BINTO) mTo = ASM.BINTO; outdata = hextools.hex2bin(hex, mFrom, mTo); } LFS.save(path.format(npath), outdata); if (!program.nolist) { var lpath = path.parse(path.format(npath)); lpath.ext = ".lst"; delete lpath.base; var lst = ASM.lst(vx[0], vx[1]); LFS.save(path.format(lpath), lst); }