Add constants to assembler

This commit is contained in:
n loewen 2023-08-03 15:50:37 +01:00
parent 297daafc89
commit d3134aa9e6
3 changed files with 64 additions and 15 deletions

View File

@ -34,9 +34,10 @@ function decodeInstructions(str) {
machineCode[0] = POINTER_TO_START_OF_DISPLAY_MEM;
let labels = {};
let constants = {};
let IP = INITIAL_IP_ADDRESS;
for (let i = 0; i < lines.length; i++) {
dbg(1, '');
dbg(2, '');
dbgGroup(1, `Input line ${i}, IP ${num2hex(IP)}`);
dbg(3, `> ${lines[i]}`);
let line = stripWhitespaceFromEnds(stripComments(lines[i]));
@ -49,11 +50,14 @@ function decodeInstructions(str) {
continue;
}
// Handle labels -- anchors
// HANDLE OPS
// Handle label definitions
if (line.startsWith('@')) {
// TODO: validate label
// validateLabel(line);
label = line.substring(1); // strip '@'
let label = line.substring(1); // strip '@'
if (label in labels) {
labels[label].pointsToByte = IP;
@ -72,21 +76,36 @@ function decodeInstructions(str) {
let op_arg_array = line.split(" "); // split line into an array of [op, arg]
let opName = op_arg_array[0].toLowerCase();
let addressingMode = 'direct'; // Must be "direct" or "indirect"
let arg_str = op_arg_array[1];
let arg_num = null;
let addressingMode = 'direct'; // Must be "direct" or "indirect"
// Handle constant definitions
if (opName.startsWith('=')) {
// TODO: validate constant
let constantName = opName.substring(1); // strip '>'
let constantValue = arg_str;
constants[constantName] = constantValue;
dbg(2, `constants:`);
dbg(2, constants);
continue;
}
// Handle mnemonics without arguments (eg END) ...
if (typeof arg_str === 'undefined') {
// Handle mnemonics without arguments (eg END) ...
if (mnemonicsWithOptionalArgs.indexOf(opName) < 0) {
console.error(`Missing opcode: ${line}`);
throw new Error("Missing opcode");
}
arg_num = 0;
// HANDLE ARGUMENTS
// Handle references to labels
} else if (arg_str.startsWith('@')) {
// Handle mnemonics with pointers to labels
// TODO: validate label // validateLabel(line);
label = arg_str.substring(1); // strip '@'
let label = arg_str.substring(1); // strip '@'
arg_num = 0;
if (label in labels) {
@ -100,8 +119,24 @@ function decodeInstructions(str) {
}
dbg(2, `pointsToByte: ${labels[label].pointsToByte}`);
dbg(2, `bytesToReplace: ${labels[label].bytesToReplace}`);
// Handle references to constants
} else if (arg_str.startsWith('=')) {
arg_str = arg_str.substring(1) // strip '>'
dbg(2, `argument references '${arg_str}'`);
arg_str = constants[arg_str];
dbg(2, `arg_str from '${arg_str}`);
// Handle references to constants in indirect mode
} else if (arg_str.startsWith("(=")) {
addressingMode = "indirect";
arg_str = arg_str.replace("(=", "");
arg_str = arg_str.replace(")", "");
dbg(2, `INDY - argument references '${arg_str}'`);
arg_str = constants[arg_str];
// Handle indirect expressions
} else if (arg_str.startsWith("(")) {
// Handle indirect expressions
addressingMode = "indirect";
arg_str = arg_str.replace("(", "");
arg_str = arg_str.replace(")", "");
@ -119,7 +154,7 @@ function decodeInstructions(str) {
}
}
// Decode!
// DECODE!
op = mnemonics2opcodes[opName][addressingMode];
machineCode.push(op);
@ -130,11 +165,11 @@ function decodeInstructions(str) {
};
dbg(1, '');
dbgGroup(1, 'Memory before filling in label pointers');
dbgGroup(1, 'Memory before filling in label constants');
dbgExec(1, () => logMemory(machineCode));
dbgGroupEnd(1, 'Memory before filling in label pointers');
dbgGroupEnd(1, 'Memory before filling in label constants');
// Backfill label pointers
// Backfill label references
for (let k of Object.keys(labels)) {
dbgGroup(2, `@${k}`);
let label = labels[k];

View File

@ -10,12 +10,14 @@
### Features
- [ ] Make $0F a NOP
- [ ] Assembler: pad to 256 bytes, OR, to start, always add an END
- [x] Add constants to assembler
- [ ] Keypad
- [ ] Add single-stepping
- [x] Make $0F a NOP
- [ ] In assembler.js: validateLabel()
- [ ] In assemble.js: print better output to stdout
- [ ] Add a function for logging just a specific range of memory
- [ ] Add single-stepping
- [ ] Add variables to assembler
### Under-the-hood improvements
@ -104,5 +106,10 @@ Assemble and run, with debug output:
; the label will be replaced with
; the address of the label
=foo $FF ; define a constant
; (must be defined before it is referenced)
ADD =foo ; use a constant as an operand
- Hexadecimal numbers are preceded by a `$`
- Whitespace is ignored

View File

@ -0,0 +1,7 @@
;; Test constants
=foo $01
=bar $02
ADD =foo
STO =bar
STO (=bar)
END