68kcounter
Version:
68000 ASM source code cycle counter
71 lines (66 loc) • 1.56 kB
text/typescript
import evaluate, { Variables } from "../parse/evaluate";
import { DirectiveStatement, Node, StringNode } from "../parse/nodes";
import { Directives, Qualifier, Qualifiers } from "../syntax";
/**
* Get byte size of directive statement
*/
export default function directiveSize(
{ opcode: { op, qualifier }, operands }: DirectiveStatement,
vars: Variables
): number {
// DC:
if (op.name === Directives.DC && qualifier) {
if (qualifier.name === Qualifiers.B) {
return operandBytes(operands);
} else {
return operands.length * qualifierBytes[qualifier.name];
}
}
if (op.name === Directives.DB) {
return operandBytes(operands);
}
if (op.name === Directives.DW) {
return operands.length * 2;
}
if (op.name === Directives.DL) {
return operands.length * 4;
}
// DCB / DS:
if (
(op.name === Directives.DCB || op.name === Directives.DS) &&
qualifier &&
operands[0]
) {
const n = evaluate(operands[0].text, vars);
if (n) {
const bytes = qualifierBytes[qualifier.name];
return bytes * n;
}
}
return 0;
}
const qualifierBytes: Record<Qualifier, number> = {
B: 1,
W: 2,
L: 4,
S: 4,
D: 8,
Q: 8,
X: 12,
};
/**
* Get byte count for a list of operands on dc.b / db
*
* Handles quoted strings as well as individual byte values.
*/
function operandBytes(operands: Node[]): number {
let count = 0;
for (const arg of operands) {
if (arg instanceof StringNode) {
count += arg.value.length;
} else {
count++;
}
}
return count;
}