rk86 2.0.15 → 2.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/rk86.js +392 -96
package/package.json
CHANGED
package/rk86.js
CHANGED
|
@@ -1589,6 +1589,22 @@ var init_catalog_data = __esm(() => {
|
|
|
1589
1589
|
});
|
|
1590
1590
|
|
|
1591
1591
|
// node_modules/asm8080/dist/asm8.js
|
|
1592
|
+
class AsmError extends Error {
|
|
1593
|
+
line;
|
|
1594
|
+
column;
|
|
1595
|
+
source;
|
|
1596
|
+
constructor(message, line, source, column = 1) {
|
|
1597
|
+
super(message);
|
|
1598
|
+
this.name = "AsmError";
|
|
1599
|
+
this.line = line;
|
|
1600
|
+
this.source = source;
|
|
1601
|
+
this.column = column;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
function firstNonSpaceCol(s) {
|
|
1605
|
+
const m = s.match(/\S/);
|
|
1606
|
+
return m ? (m.index ?? 0) + 1 : 1;
|
|
1607
|
+
}
|
|
1592
1608
|
var REG8 = {
|
|
1593
1609
|
B: 0,
|
|
1594
1610
|
C: 1,
|
|
@@ -1682,6 +1698,81 @@ var ADDR16 = {
|
|
|
1682
1698
|
LHLD: 42,
|
|
1683
1699
|
SHLD: 34
|
|
1684
1700
|
};
|
|
1701
|
+
var ALL_MNEMONICS = new Set([
|
|
1702
|
+
...Object.keys(IMPLIED),
|
|
1703
|
+
...Object.keys(ALU_REG),
|
|
1704
|
+
...Object.keys(ALU_IMM),
|
|
1705
|
+
...Object.keys(ADDR16),
|
|
1706
|
+
"MOV",
|
|
1707
|
+
"MVI",
|
|
1708
|
+
"INR",
|
|
1709
|
+
"DCR",
|
|
1710
|
+
"LXI",
|
|
1711
|
+
"DAD",
|
|
1712
|
+
"INX",
|
|
1713
|
+
"DCX",
|
|
1714
|
+
"PUSH",
|
|
1715
|
+
"POP",
|
|
1716
|
+
"LDAX",
|
|
1717
|
+
"STAX",
|
|
1718
|
+
"IN",
|
|
1719
|
+
"OUT",
|
|
1720
|
+
"RST",
|
|
1721
|
+
"DB",
|
|
1722
|
+
"DW",
|
|
1723
|
+
"DS",
|
|
1724
|
+
"ORG",
|
|
1725
|
+
"SECTION",
|
|
1726
|
+
"END",
|
|
1727
|
+
"EQU"
|
|
1728
|
+
]);
|
|
1729
|
+
var MAX_STATEMENTS_PER_LINE = 10;
|
|
1730
|
+
function splitStatements(line) {
|
|
1731
|
+
const src = stripComment(line);
|
|
1732
|
+
const out = [];
|
|
1733
|
+
let start = 0;
|
|
1734
|
+
let inQ = false;
|
|
1735
|
+
let qc = "";
|
|
1736
|
+
for (let i = 0;i + 2 < src.length; i++) {
|
|
1737
|
+
const c = src[i];
|
|
1738
|
+
if (inQ) {
|
|
1739
|
+
if (c === qc)
|
|
1740
|
+
inQ = false;
|
|
1741
|
+
continue;
|
|
1742
|
+
}
|
|
1743
|
+
if (c === '"' || c === "'") {
|
|
1744
|
+
inQ = true;
|
|
1745
|
+
qc = c;
|
|
1746
|
+
continue;
|
|
1747
|
+
}
|
|
1748
|
+
if (c !== " " || src[i + 1] !== "/" || src[i + 2] !== " ")
|
|
1749
|
+
continue;
|
|
1750
|
+
let j = i + 3;
|
|
1751
|
+
while (j < src.length && src[j] === " ")
|
|
1752
|
+
j++;
|
|
1753
|
+
let tokStart = j;
|
|
1754
|
+
if (src[j] === ".")
|
|
1755
|
+
j++;
|
|
1756
|
+
let tokEnd = j;
|
|
1757
|
+
while (tokEnd < src.length && /\w/.test(src[tokEnd]))
|
|
1758
|
+
tokEnd++;
|
|
1759
|
+
if (tokEnd === j)
|
|
1760
|
+
continue;
|
|
1761
|
+
let tok = src.slice(tokStart, tokEnd).toUpperCase();
|
|
1762
|
+
if (tok.startsWith("."))
|
|
1763
|
+
tok = tok.slice(1);
|
|
1764
|
+
if (!ALL_MNEMONICS.has(tok))
|
|
1765
|
+
continue;
|
|
1766
|
+
out.push(src.slice(start, i));
|
|
1767
|
+
start = i + 2;
|
|
1768
|
+
i += 2;
|
|
1769
|
+
}
|
|
1770
|
+
out.push(src.slice(start));
|
|
1771
|
+
if (out.length > MAX_STATEMENTS_PER_LINE) {
|
|
1772
|
+
throw new Error(`too many statements on one line (max ${MAX_STATEMENTS_PER_LINE})`);
|
|
1773
|
+
}
|
|
1774
|
+
return out;
|
|
1775
|
+
}
|
|
1685
1776
|
function instrSize(m) {
|
|
1686
1777
|
if (m in IMPLIED)
|
|
1687
1778
|
return 1;
|
|
@@ -1749,6 +1840,13 @@ function splitOperands(s) {
|
|
|
1749
1840
|
r.push(current.trim());
|
|
1750
1841
|
return r;
|
|
1751
1842
|
}
|
|
1843
|
+
var DIRECTIVES = new Set(["ORG", "SECTION", "END", "DB", "DW", "DS", "EQU"]);
|
|
1844
|
+
function stripDirectiveDot(s) {
|
|
1845
|
+
if (s.startsWith(".") && DIRECTIVES.has(s.slice(1).toUpperCase())) {
|
|
1846
|
+
return s.slice(1);
|
|
1847
|
+
}
|
|
1848
|
+
return s;
|
|
1849
|
+
}
|
|
1752
1850
|
function parseLine(line) {
|
|
1753
1851
|
let s = stripComment(line).trim();
|
|
1754
1852
|
if (!s)
|
|
@@ -1766,7 +1864,7 @@ function parseLine(line) {
|
|
|
1766
1864
|
const rest = si < 0 ? "" : s.slice(si).trim();
|
|
1767
1865
|
if (!label && rest) {
|
|
1768
1866
|
const parts = rest.split(/\s+/);
|
|
1769
|
-
if (parts[0].toUpperCase() === "EQU") {
|
|
1867
|
+
if (stripDirectiveDot(parts[0]).toUpperCase() === "EQU") {
|
|
1770
1868
|
return {
|
|
1771
1869
|
label: first,
|
|
1772
1870
|
mnemonic: "EQU",
|
|
@@ -1775,43 +1873,189 @@ function parseLine(line) {
|
|
|
1775
1873
|
};
|
|
1776
1874
|
}
|
|
1777
1875
|
}
|
|
1778
|
-
return {
|
|
1876
|
+
return {
|
|
1877
|
+
label,
|
|
1878
|
+
mnemonic: stripDirectiveDot(first),
|
|
1879
|
+
operands: rest ? splitOperands(rest) : []
|
|
1880
|
+
};
|
|
1779
1881
|
}
|
|
1780
|
-
function
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1882
|
+
function tokenizeExpr(expr) {
|
|
1883
|
+
const tokens = [];
|
|
1884
|
+
let i = 0;
|
|
1885
|
+
while (i < expr.length) {
|
|
1886
|
+
let c = expr[i];
|
|
1887
|
+
if (/\s/.test(c)) {
|
|
1888
|
+
i++;
|
|
1889
|
+
continue;
|
|
1890
|
+
}
|
|
1891
|
+
if (c === "'" && i + 2 < expr.length && expr[i + 2] === "'") {
|
|
1892
|
+
tokens.push({ kind: "num", val: expr.charCodeAt(i + 1) });
|
|
1893
|
+
i += 3;
|
|
1894
|
+
continue;
|
|
1895
|
+
}
|
|
1896
|
+
if (/[0-9]/.test(c)) {
|
|
1897
|
+
let j = i;
|
|
1898
|
+
while (j < expr.length && /[0-9A-Fa-f]/.test(expr[j]))
|
|
1899
|
+
j++;
|
|
1900
|
+
if (j < expr.length && /[hH]/.test(expr[j])) {
|
|
1901
|
+
tokens.push({ kind: "num", val: parseInt(expr.slice(i, j), 16) });
|
|
1902
|
+
j++;
|
|
1903
|
+
} else {
|
|
1904
|
+
tokens.push({ kind: "num", val: parseInt(expr.slice(i, j), 10) });
|
|
1905
|
+
}
|
|
1906
|
+
i = j;
|
|
1907
|
+
continue;
|
|
1908
|
+
}
|
|
1909
|
+
if (/[A-Za-z_]/.test(c)) {
|
|
1910
|
+
let j = i;
|
|
1911
|
+
while (j < expr.length && /\w/.test(expr[j]))
|
|
1912
|
+
j++;
|
|
1913
|
+
tokens.push({ kind: "id", val: expr.slice(i, j) });
|
|
1914
|
+
i = j;
|
|
1915
|
+
continue;
|
|
1916
|
+
}
|
|
1917
|
+
if (c === "<" && expr[i + 1] === "<") {
|
|
1918
|
+
tokens.push({ kind: "op", val: "<<" });
|
|
1919
|
+
i += 2;
|
|
1920
|
+
continue;
|
|
1921
|
+
}
|
|
1922
|
+
if (c === ">" && expr[i + 1] === ">") {
|
|
1923
|
+
tokens.push({ kind: "op", val: ">>" });
|
|
1924
|
+
i += 2;
|
|
1925
|
+
continue;
|
|
1926
|
+
}
|
|
1927
|
+
if ("+-*/%&|^~()".includes(c)) {
|
|
1928
|
+
tokens.push({ kind: "op", val: c });
|
|
1929
|
+
i++;
|
|
1930
|
+
continue;
|
|
1931
|
+
}
|
|
1932
|
+
throw new Error(`unexpected character in expression: '${c}'`);
|
|
1933
|
+
}
|
|
1934
|
+
return tokens;
|
|
1792
1935
|
}
|
|
1793
1936
|
function evalExpr(expr, symbols) {
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1937
|
+
const tokens = tokenizeExpr(expr);
|
|
1938
|
+
let pos = 0;
|
|
1939
|
+
function peek() {
|
|
1940
|
+
return tokens[pos];
|
|
1941
|
+
}
|
|
1942
|
+
function next() {
|
|
1943
|
+
return tokens[pos++];
|
|
1944
|
+
}
|
|
1945
|
+
function isOp(val) {
|
|
1946
|
+
const t = peek();
|
|
1947
|
+
return t !== undefined && t.kind === "op" && t.val === val;
|
|
1948
|
+
}
|
|
1949
|
+
function atom() {
|
|
1950
|
+
const t = peek();
|
|
1951
|
+
if (!t)
|
|
1952
|
+
throw new Error("unexpected end of expression");
|
|
1953
|
+
if (t.kind === "num") {
|
|
1954
|
+
next();
|
|
1955
|
+
return t.val;
|
|
1956
|
+
}
|
|
1957
|
+
if (t.kind === "id") {
|
|
1958
|
+
next();
|
|
1959
|
+
const k = t.val.toUpperCase();
|
|
1960
|
+
if (k === "LOW" || k === "HIGH") {
|
|
1961
|
+
if (!isOp("("))
|
|
1962
|
+
throw new Error(`${k} requires parentheses`);
|
|
1963
|
+
next();
|
|
1964
|
+
const v = parseOr();
|
|
1965
|
+
if (!isOp(")"))
|
|
1966
|
+
throw new Error("expected ')'");
|
|
1967
|
+
next();
|
|
1968
|
+
return k === "LOW" ? v & 255 : v >> 8 & 255;
|
|
1969
|
+
}
|
|
1970
|
+
if (symbols.has(k))
|
|
1971
|
+
return symbols.get(k);
|
|
1972
|
+
throw new Error(`unknown symbol: ${t.val}`);
|
|
1973
|
+
}
|
|
1974
|
+
if (t.kind === "op" && t.val === "(") {
|
|
1975
|
+
next();
|
|
1976
|
+
const v = parseOr();
|
|
1977
|
+
if (!isOp(")"))
|
|
1978
|
+
throw new Error("expected ')'");
|
|
1979
|
+
next();
|
|
1980
|
+
return v;
|
|
1805
1981
|
}
|
|
1982
|
+
throw new Error(`unexpected token: ${t.val}`);
|
|
1806
1983
|
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1984
|
+
function unary() {
|
|
1985
|
+
if (isOp("-")) {
|
|
1986
|
+
next();
|
|
1987
|
+
return -unary() & 65535;
|
|
1988
|
+
}
|
|
1989
|
+
if (isOp("+")) {
|
|
1990
|
+
next();
|
|
1991
|
+
return unary();
|
|
1992
|
+
}
|
|
1993
|
+
if (isOp("~")) {
|
|
1994
|
+
next();
|
|
1995
|
+
return ~unary() & 65535;
|
|
1996
|
+
}
|
|
1997
|
+
return atom();
|
|
1998
|
+
}
|
|
1999
|
+
function multiplicative() {
|
|
2000
|
+
let v = unary();
|
|
2001
|
+
while (isOp("*") || isOp("/") || isOp("%")) {
|
|
2002
|
+
const op = next().val;
|
|
2003
|
+
let r = unary();
|
|
2004
|
+
if (op === "*")
|
|
2005
|
+
v = v * r & 65535;
|
|
2006
|
+
else if (op === "/")
|
|
2007
|
+
v = Math.trunc(v / r) & 65535;
|
|
2008
|
+
else
|
|
2009
|
+
v = v % r & 65535;
|
|
2010
|
+
}
|
|
2011
|
+
return v;
|
|
2012
|
+
}
|
|
2013
|
+
function additive() {
|
|
2014
|
+
let v = multiplicative();
|
|
2015
|
+
while (isOp("+") || isOp("-")) {
|
|
2016
|
+
const op = next().val;
|
|
2017
|
+
let r = multiplicative();
|
|
2018
|
+
v = op === "+" ? v + r & 65535 : v - r & 65535;
|
|
2019
|
+
}
|
|
2020
|
+
return v;
|
|
2021
|
+
}
|
|
2022
|
+
function shift() {
|
|
2023
|
+
let v = additive();
|
|
2024
|
+
while (isOp("<<") || isOp(">>")) {
|
|
2025
|
+
const op = next().val;
|
|
2026
|
+
let r = additive();
|
|
2027
|
+
v = op === "<<" ? v << r & 65535 : v >>> r & 65535;
|
|
2028
|
+
}
|
|
2029
|
+
return v;
|
|
2030
|
+
}
|
|
2031
|
+
function parseAnd() {
|
|
2032
|
+
let v = shift();
|
|
2033
|
+
while (isOp("&")) {
|
|
2034
|
+
next();
|
|
2035
|
+
v = v & shift();
|
|
2036
|
+
}
|
|
2037
|
+
return v;
|
|
2038
|
+
}
|
|
2039
|
+
function parseXor() {
|
|
2040
|
+
let v = parseAnd();
|
|
2041
|
+
while (isOp("^")) {
|
|
2042
|
+
next();
|
|
2043
|
+
v = (v ^ parseAnd()) & 65535;
|
|
2044
|
+
}
|
|
2045
|
+
return v;
|
|
2046
|
+
}
|
|
2047
|
+
function parseOr() {
|
|
2048
|
+
let v = parseXor();
|
|
2049
|
+
while (isOp("|")) {
|
|
2050
|
+
next();
|
|
2051
|
+
v = (v | parseXor()) & 65535;
|
|
2052
|
+
}
|
|
2053
|
+
return v;
|
|
1813
2054
|
}
|
|
1814
|
-
|
|
2055
|
+
const result = parseOr();
|
|
2056
|
+
if (pos < tokens.length)
|
|
2057
|
+
throw new Error(`unexpected token: ${tokens[pos].val}`);
|
|
2058
|
+
return result;
|
|
1815
2059
|
}
|
|
1816
2060
|
function encode(m, ops, symbols) {
|
|
1817
2061
|
if (m in IMPLIED)
|
|
@@ -1825,7 +2069,9 @@ function encode(m, ops, symbols) {
|
|
|
1825
2069
|
return [ADDR16[m], v & 255, v >> 8 & 255];
|
|
1826
2070
|
}
|
|
1827
2071
|
if (m === "MOV")
|
|
1828
|
-
return [
|
|
2072
|
+
return [
|
|
2073
|
+
64 | REG8[ops[0].toUpperCase()] << 3 | REG8[ops[1].toUpperCase()]
|
|
2074
|
+
];
|
|
1829
2075
|
if (m === "MVI") {
|
|
1830
2076
|
const v = evalExpr(ops[1], symbols);
|
|
1831
2077
|
return [6 | REG8[ops[0].toUpperCase()] << 3, v & 255];
|
|
@@ -1836,7 +2082,11 @@ function encode(m, ops, symbols) {
|
|
|
1836
2082
|
return [5 | REG8[ops[0].toUpperCase()] << 3];
|
|
1837
2083
|
if (m === "LXI") {
|
|
1838
2084
|
const v = evalExpr(ops[1], symbols);
|
|
1839
|
-
return [
|
|
2085
|
+
return [
|
|
2086
|
+
1 | REG_PAIR[ops[0].toUpperCase()] << 4,
|
|
2087
|
+
v & 255,
|
|
2088
|
+
v >> 8 & 255
|
|
2089
|
+
];
|
|
1840
2090
|
}
|
|
1841
2091
|
if (m === "DAD")
|
|
1842
2092
|
return [9 | REG_PAIR[ops[0].toUpperCase()] << 4];
|
|
@@ -1882,6 +2132,24 @@ function dwBytes(operands, symbols) {
|
|
|
1882
2132
|
}
|
|
1883
2133
|
return out;
|
|
1884
2134
|
}
|
|
2135
|
+
function parseDs(operands) {
|
|
2136
|
+
if (operands.length !== 1)
|
|
2137
|
+
throw new Error("DS takes one operand: count [(fill)]");
|
|
2138
|
+
const m = operands[0].match(/^(.+?)\s+\((.+)\)\s*$/);
|
|
2139
|
+
if (m)
|
|
2140
|
+
return { count: m[1], fill: m[2] };
|
|
2141
|
+
return { count: operands[0], fill: "0" };
|
|
2142
|
+
}
|
|
2143
|
+
function dsBytes(operands, symbols) {
|
|
2144
|
+
const { count, fill } = parseDs(operands);
|
|
2145
|
+
const n = evalExpr(count, symbols);
|
|
2146
|
+
const f = evalExpr(fill, symbols) & 255;
|
|
2147
|
+
return new Array(n).fill(f);
|
|
2148
|
+
}
|
|
2149
|
+
function countDs(operands, symbols) {
|
|
2150
|
+
const { count } = parseDs(operands);
|
|
2151
|
+
return evalExpr(count, symbols);
|
|
2152
|
+
}
|
|
1885
2153
|
function countDb(operands) {
|
|
1886
2154
|
let n = 0;
|
|
1887
2155
|
for (const op of operands) {
|
|
@@ -1897,75 +2165,103 @@ function asm(source) {
|
|
|
1897
2165
|
`);
|
|
1898
2166
|
const symbols = new Map;
|
|
1899
2167
|
let pc = 0;
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
2168
|
+
let ended = false;
|
|
2169
|
+
for (let idx = 0;idx < lines.length && !ended; idx++) {
|
|
2170
|
+
const line = lines[idx];
|
|
2171
|
+
try {
|
|
2172
|
+
for (const stmt of splitStatements(line)) {
|
|
2173
|
+
const parts = parseLine(stmt);
|
|
2174
|
+
if (parts.label) {
|
|
2175
|
+
if (parts.isEqu) {
|
|
2176
|
+
symbols.set(parts.label.toUpperCase(), evalExpr(parts.operands[0], symbols));
|
|
2177
|
+
continue;
|
|
2178
|
+
}
|
|
2179
|
+
symbols.set(parts.label.toUpperCase(), pc);
|
|
2180
|
+
}
|
|
2181
|
+
if (!parts.mnemonic)
|
|
2182
|
+
continue;
|
|
2183
|
+
const m = parts.mnemonic.toUpperCase();
|
|
2184
|
+
if (m === "EQU")
|
|
2185
|
+
continue;
|
|
2186
|
+
if (m === "ORG") {
|
|
2187
|
+
pc = evalExpr(parts.operands[0], symbols);
|
|
2188
|
+
continue;
|
|
2189
|
+
}
|
|
2190
|
+
if (m === "SECTION")
|
|
2191
|
+
continue;
|
|
2192
|
+
if (m === "END") {
|
|
2193
|
+
ended = true;
|
|
2194
|
+
break;
|
|
2195
|
+
}
|
|
2196
|
+
if (m === "DB") {
|
|
2197
|
+
pc += countDb(parts.operands);
|
|
2198
|
+
continue;
|
|
2199
|
+
}
|
|
2200
|
+
if (m === "DW") {
|
|
2201
|
+
pc += parts.operands.length * 2;
|
|
2202
|
+
continue;
|
|
2203
|
+
}
|
|
2204
|
+
if (m === "DS") {
|
|
2205
|
+
pc += countDs(parts.operands, symbols);
|
|
2206
|
+
continue;
|
|
2207
|
+
}
|
|
2208
|
+
pc += instrSize(m);
|
|
1906
2209
|
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
const m = parts.mnemonic.toUpperCase();
|
|
1912
|
-
if (m === "EQU")
|
|
1913
|
-
continue;
|
|
1914
|
-
if (m === "ORG") {
|
|
1915
|
-
pc = evalExpr(parts.operands[0], symbols);
|
|
1916
|
-
continue;
|
|
1917
|
-
}
|
|
1918
|
-
if (m === "SECTION")
|
|
1919
|
-
continue;
|
|
1920
|
-
if (m === "END")
|
|
1921
|
-
break;
|
|
1922
|
-
if (m === "DB") {
|
|
1923
|
-
pc += countDb(parts.operands);
|
|
1924
|
-
continue;
|
|
1925
|
-
}
|
|
1926
|
-
if (m === "DW") {
|
|
1927
|
-
pc += parts.operands.length * 2;
|
|
1928
|
-
continue;
|
|
2210
|
+
} catch (e) {
|
|
2211
|
+
if (e instanceof AsmError)
|
|
2212
|
+
throw e;
|
|
2213
|
+
throw new AsmError(e.message, idx + 1, line, firstNonSpaceCol(line));
|
|
1929
2214
|
}
|
|
1930
|
-
pc += instrSize(m);
|
|
1931
2215
|
}
|
|
1932
2216
|
const sections = [];
|
|
1933
2217
|
let current = null;
|
|
1934
2218
|
const sectionNames = new Set;
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
2219
|
+
let endedPass2 = false;
|
|
2220
|
+
for (let idx = 0;idx < lines.length && !endedPass2; idx++) {
|
|
2221
|
+
const line = lines[idx];
|
|
2222
|
+
try {
|
|
2223
|
+
for (const stmt of splitStatements(line)) {
|
|
2224
|
+
const parts = parseLine(stmt);
|
|
2225
|
+
if (parts.isEqu || !parts.mnemonic)
|
|
2226
|
+
continue;
|
|
2227
|
+
const m = parts.mnemonic.toUpperCase();
|
|
2228
|
+
if (m === "EQU")
|
|
2229
|
+
continue;
|
|
2230
|
+
if (m === "ORG") {
|
|
2231
|
+
if (current && current.data.length) {
|
|
2232
|
+
current.end = current.start + current.data.length - 1;
|
|
2233
|
+
sections.push(current);
|
|
2234
|
+
}
|
|
2235
|
+
const addr = evalExpr(parts.operands[0], symbols);
|
|
2236
|
+
current = { start: addr, end: addr, data: [] };
|
|
2237
|
+
continue;
|
|
2238
|
+
}
|
|
2239
|
+
if (m === "SECTION") {
|
|
2240
|
+
if (!current)
|
|
2241
|
+
throw new Error("SECTION before ORG");
|
|
2242
|
+
const name = parts.operands[0];
|
|
2243
|
+
if (!name)
|
|
2244
|
+
throw new Error("SECTION requires a name");
|
|
2245
|
+
if (sectionNames.has(name.toUpperCase()))
|
|
2246
|
+
throw new Error(`duplicate section name: ${name}`);
|
|
2247
|
+
sectionNames.add(name.toUpperCase());
|
|
2248
|
+
current.name = name;
|
|
2249
|
+
continue;
|
|
2250
|
+
}
|
|
2251
|
+
if (m === "END") {
|
|
2252
|
+
endedPass2 = true;
|
|
2253
|
+
break;
|
|
2254
|
+
}
|
|
2255
|
+
if (!current)
|
|
2256
|
+
throw new Error("code before ORG");
|
|
2257
|
+
const bytes = m === "DB" ? dbBytes(parts.operands, symbols) : m === "DW" ? dwBytes(parts.operands, symbols) : m === "DS" ? dsBytes(parts.operands, symbols) : encode(m, parts.operands, symbols);
|
|
2258
|
+
current.data.push(...bytes);
|
|
1946
2259
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
if (m === "SECTION") {
|
|
1952
|
-
if (!current)
|
|
1953
|
-
throw new Error("SECTION before ORG");
|
|
1954
|
-
const name = parts.operands[0];
|
|
1955
|
-
if (!name)
|
|
1956
|
-
throw new Error("SECTION requires a name");
|
|
1957
|
-
if (sectionNames.has(name.toUpperCase()))
|
|
1958
|
-
throw new Error(`duplicate section name: ${name}`);
|
|
1959
|
-
sectionNames.add(name.toUpperCase());
|
|
1960
|
-
current.name = name;
|
|
1961
|
-
continue;
|
|
2260
|
+
} catch (e) {
|
|
2261
|
+
if (e instanceof AsmError)
|
|
2262
|
+
throw e;
|
|
2263
|
+
throw new AsmError(e.message, idx + 1, line, firstNonSpaceCol(line));
|
|
1962
2264
|
}
|
|
1963
|
-
if (m === "END")
|
|
1964
|
-
break;
|
|
1965
|
-
if (!current)
|
|
1966
|
-
throw new Error("code before ORG");
|
|
1967
|
-
const bytes = m === "DB" ? dbBytes(parts.operands, symbols) : m === "DW" ? dwBytes(parts.operands, symbols) : encode(m, parts.operands, symbols);
|
|
1968
|
-
current.data.push(...bytes);
|
|
1969
2265
|
}
|
|
1970
2266
|
if (current && current.data.length) {
|
|
1971
2267
|
current.end = current.start + current.data.length - 1;
|
|
@@ -1981,7 +2277,7 @@ import { readFile } from "fs/promises";
|
|
|
1981
2277
|
// packages/rk86/package.json
|
|
1982
2278
|
var package_default = {
|
|
1983
2279
|
name: "rk86",
|
|
1984
|
-
version: "2.0.
|
|
2280
|
+
version: "2.0.15",
|
|
1985
2281
|
description: "\u042D\u043C\u0443\u043B\u044F\u0442\u043E\u0440 \u0420\u0430\u0434\u0438\u043E-86\u0420\u041A (Intel 8080) \u0434\u043B\u044F \u0442\u0435\u0440\u043C\u0438\u043D\u0430\u043B\u0430",
|
|
1986
2282
|
bin: {
|
|
1987
2283
|
rk86: "rk86.js"
|