Run the words
Your CPU from How computers work read text. A real one reads numbers. Decode each word by shifting and masking its fields, then execute — with registers kept to 8 bits and a SYS instruction that traps to the operating system (you'll need that on Day 4).
Decoding with masks
function decode(word) {
return { op: word >> 12, r: (word >> 10) & 3, s: (word >> 8) & 3, n: word & 255 };
}
function newMachine() {
return { pc: 0, regs: [0, 0, 0, 0], out: [], steps: 0, halted: false };
}
// Runs one instruction. Returns { sys: n } for a SYS instruction, otherwise null.
function step(m, words) {
const { op, r, s, n } = decode(words[m.pc]);
m.pc++;
m.steps++;
const R = m.regs;
switch (op) {
case 0: m.halted = true; m.pc--; break;
case 1: R[r] = n; break;
case 2: R[r] = (R[r] + R[s]) & 255; break;
case 3: R[r] = (R[r] - R[s] + 256) & 255; break;
case 4: m.pc = n; break;
case 5: if (R[r] === 0) m.pc = n; break;
case 6: if (R[r] !== 0) m.pc = n; break;
case 7: m.out.push(R[r]); break;
case 8: R[r] = (R[r] + 255) & 255; break;
case 9: R[r] = (R[r] + 1) & 255; break;
case 10: return { sys: n };
}
return null;
}
function execute(words, maxSteps = 10000) {
const m = newMachine();
while (!m.halted && m.pc < words.length) {
if (m.steps >= maxSteps) throw new Error("Too many steps");
step(m, words);
}
return { out: m.out, regs: m.regs, steps: m.steps };
}