Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9x 9x 8x 8x 9x 9x 1x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 9x 4x 4x 4x 6x 6x 9x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 9x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9x 9x 9x 11x 10x 11x 11x 9x 11x 9x 9x 7x 8x 8x 8x 6x 7x 4x 4x 4x 4x 4x 4x 4x 9x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | // this is a main file, you know...
import {lst, html} from "./listing.js"
import { pass1 } from "./pass1.js";
import {pass2} from "./pass2.js";
import {objCode, linkModules} from "./objcode.js"
import * as Parser from "./parser.js";
//import all CPUs
import {I8080} from "./cpu/i8080.js";
import {M6800} from "./cpu/m6800.js";
import { C6502 } from "./cpu/c6502.js";
import { Z80 } from "./cpu/z80.js";
import { I8008 } from "./cpu/i8008.js";
import { CDP1802 } from "./cpu/cdp1802.js";
import { M6809 } from "./cpu/m6809.js";
const cpus = [I8080, M6800, C6502, Z80, I8008, CDP1802, M6809];
/**
* Compiles assembly source code into machine code
* @param {string} source - Assembly source code
* @param {Object} fileSystem - File system interface with readFile method
* @param {Object} opts - Compilation options
* @param {string} opts.assembler - Assembler name or object
* @param {string} filename - Source filename for error reporting
* @returns {Object} Compilation result with dump, vars, xref, and opts
* @throws {Object} Error object with compilation details
*/
export const compile = async (source, fileSystem, opts = {assembler:null}, filename="noname") => {
if (typeof opts.assembler == "string") {
opts.assembler = cpus.find(x=>x.cpu.toUpperCase()==opts.assembler.toUpperCase());
}
if (!opts.assembler || typeof opts.assembler != "object") {
throw {msg:"No assembler specified", s:"Assembler error"};
}
opts = {...opts, readFile: fileSystem.readFile, endian:false,
ENT:null,
BINFROM:null,
BINTO:null,
ENGINE:null,
PRAGMAS:[],
includedFiles:{},
endian:opts.assembler.endian,
xfre: {},
xref: {},
}
try {
// parse source code into internal representation
let parsedSource = await Parser.parse(source, opts);
// pass 1: prepare instruction codes and try to evaluate expressions
let metacode = await pass1(parsedSource, null, opts)
// metacode is passed again and again until all expressions are evaluated
metacode = await pass1(metacode[0], metacode[1], opts);
metacode = await pass1(metacode[0], metacode[1], opts);
metacode = await pass1(metacode[0], metacode[1], opts);
metacode = await pass1(metacode[0], metacode[1], opts);
metacode[1]["__PRAGMAS"] = opts.PRAGMAS;
// pass 2: assign addresses to labels and evaluate expressions
// (this pass is not repeated)
// It should be all resolved aftrer the 2nd pass
metacode = pass2(metacode, opts);
//new output, broke backward compatibility
let out = {
dump: metacode[0],
vars: metacode[1],
xref: opts.xref,
opts: opts,
}
// is it a module?
let vars = metacode[1];
if (vars && typeof vars.__PRAGMAS !== "undefined" && vars.__PRAGMAS.indexOf("MODULE") != -1) {
let obj = objCode(metacode[0],metacode[1],opts,filename)
out.obj = obj;
}
return out
} catch (e) {
// Some error occured
//console.log(e)
let s = e.s || "Internal error";
//no message, so we use the general one
//FALLBACK - should be removed in future version
if (!e.msg) {
throw {
error:
{
msg: `Cannot evaluate line ${opts.WLINE.numline}, there is some unspecified error (e.g. reserved world as label etc.)`,
wline: opts.WLINE
}
}
}
if (!e.s) e.s = s;
throw {
error: {
msg: e.msg,
s: e.s,
//wline: opts.WLINE
}
};
}
}
/**
* Extracts filename from full path
* @param {string} fullpath - Full file path
* @returns {string} Filename without path
*/
const getfn = (fullpath) => {
let parts = fullpath.split("/");
return parts[parts.length-1];
}
/**
* Compiles assembly code from a file
* @param {string} filePath - Path to assembly source file
* @param {Object} fileSystem - File system interface with readFile method
* @param {Object} opts - Compilation options
* @returns {Object} Compilation result
*/
export const compileFromFile = async (filePath, fileSystem, opts = {assembler:null}) => {
let source = await fileSystem.readFile(filePath);
return compile(source, fileSystem, opts, getfn(filePath));
}
//----------------------------------------
// linker
/**
* Links multiple object modules into a single executable
* @param {Object} linkList - Link list configuration
* @param {Array} linkList.modules - Array of module names to link
* @param {Array} linkList.library - Array of library names to link
* @param {Object} fileSystem - File system interface with readFile method
* @param {string} name - Output name for the linked executable
* @returns {Object} Linked executable data
* @throws {Object} Error if modules have incompatible CPU or endian settings
*/
const link = async (linkList, fileSystem, name="noname") => {
let cpu = null
let endian = null
let modules = await Promise.all(linkList.modules.map(async m => {
let f = JSON.parse(await fileSystem.readFile(m+".obj"))
//checker
if (!cpu) cpu = f.cpu;
if (cpu != f.cpu) throw {msg:"Different CPU in module "+m, s:"Linker error"};
if (!endian) endian = f.endian;
if (endian != f.endian) throw {msg:"Different endian in module "+m, s:"Linker error"};
return f
}))
let library = await Promise.all(linkList.library.map(async m => {
let f = JSON.parse(await fileSystem.readFile(m+".obj"))
if (cpu != f.cpu) throw {msg:"Different CPU in library file "+m, s:"Linker error"};
if (endian != f.endian) throw {msg:"Different endian in library file "+m, s:"Linker error"};
return f
}))
linkList.endian = endian
let out = linkModules(linkList,modules, library)
return out
//fs.writeFileSync("./test/suite/"+name+".combined",JSON.stringify(out))
}
/**
* Main assembler interface object
*/
export const asm = {
lst,
html,
compile,
compileFromFile,
link,
cpus
} |