Start a new simulator sketch with a better architecture + using a Uint8Array for memory
This commit is contained in:
parent
3eaced0e5d
commit
a17b7f4ba9
|
|
@ -0,0 +1,130 @@
|
||||||
|
// STATE
|
||||||
|
|
||||||
|
const CPU = {
|
||||||
|
running: false,
|
||||||
|
IP: 0,
|
||||||
|
CF: 0,
|
||||||
|
Acc: 0,
|
||||||
|
memory: null,
|
||||||
|
loadMemory: (data) => { // data: Uint8Array
|
||||||
|
// TODO: check length of data
|
||||||
|
CPU.memory = data;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTIONS THAT MODIFY STATE
|
||||||
|
|
||||||
|
const Instructions = {
|
||||||
|
end: () => {
|
||||||
|
console.log('END');
|
||||||
|
CPU.running = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
store_lit: (lit) => {
|
||||||
|
console.log('STO lit#');
|
||||||
|
CPU.memory[lit] = CPU.acc;
|
||||||
|
logTableTitled(CPU.memory, 'Current memory');
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
store_addr: (addr) => {
|
||||||
|
console.log('STO addr');
|
||||||
|
CPU.memory[CPU.memory[addr]] = CPU.acc;
|
||||||
|
logTableTitled(CPU.memory, 'Memory');
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
load_lit: (lit) => {
|
||||||
|
console.log('LDA lit#');
|
||||||
|
CPU.acc = lit;
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
load_addr: (addr) => {
|
||||||
|
console.log('LDA addr');
|
||||||
|
console.log('mem at addr: ', CPU.memory[addr]);
|
||||||
|
CPU.acc = CPU.memory[addr];
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const instructionLookupTable = {
|
||||||
|
0: (arg) => Instructions.end(arg),
|
||||||
|
1: (arg) => Instructions.store_lit(arg),
|
||||||
|
2: (arg) => Instructions.store_addr(arg),
|
||||||
|
3: (arg) => Instructions.load_lit(arg),
|
||||||
|
4: (arg) => Instructions.load_addr(arg),
|
||||||
|
};
|
||||||
|
|
||||||
|
function stepCPU() {
|
||||||
|
console.group("Step CPU");
|
||||||
|
let opcode = CPU.memory[CPU.IP];
|
||||||
|
let argument = CPU.memory[CPU.IP+1];
|
||||||
|
|
||||||
|
console.log(`OP: ${opcode} ARG: ${argument}`);
|
||||||
|
|
||||||
|
let instruction = instructionLookupTable[opcode];
|
||||||
|
instruction(argument);
|
||||||
|
|
||||||
|
logCPUState();
|
||||||
|
console.groupEnd("Step CPU");
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCPU() {
|
||||||
|
const initialMemory = JSON.parse(JSON.stringify(CPU.memory)); // Hack to make a copy-by-value -- https://stackoverflow.com/questions/18829099/copy-a-variables-value-into-another
|
||||||
|
console.log();
|
||||||
|
console.log("————————————————————————————————————————");
|
||||||
|
let time = new Date();
|
||||||
|
console.log( `Running at ${time.toLocaleTimeString('en-US')}` );
|
||||||
|
console.log("————————————————————————————————————————");
|
||||||
|
logCPUState();
|
||||||
|
|
||||||
|
CPU.running = true;
|
||||||
|
for (let i = 0; i < 255; i++) { // FIXME: temporary limit as a lazy way to halt infinite loops
|
||||||
|
if (!CPU.running) break;
|
||||||
|
if (CPU.IP >= CPU.memory.length) break;
|
||||||
|
stepCPU();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTIONS THAT PULL INFO FROM STATE TO DISPLAY
|
||||||
|
|
||||||
|
function logCPUState() {
|
||||||
|
console.log();
|
||||||
|
console.group('CPU state');
|
||||||
|
console.log( `Acc: ${CPU.acc} IP: ${CPU.IP} CF: ${CPU.CF} ${CPU.running ? "running" : "halted" }` );
|
||||||
|
console.log();
|
||||||
|
console.groupEnd('CPU state');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTIONS FOR DISPLAYING DATA
|
||||||
|
|
||||||
|
function num2hex(num) { num.toString(16) };
|
||||||
|
function hex2num(hex) { parseInt(hex, 16) };
|
||||||
|
|
||||||
|
logTableTitled = (memory, tableTitle) => {
|
||||||
|
console.log();
|
||||||
|
console.group(tableTitle);
|
||||||
|
console.table(memory);
|
||||||
|
console.groupEnd(tableTitle);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// RUN IT !
|
||||||
|
|
||||||
|
const test_lda_sto = new Uint8Array([
|
||||||
|
3, 17, // LDA lit ... acc = 17
|
||||||
|
1, 14, // STO lit ... @14 = acc = 17
|
||||||
|
3, 16, // LDA lit ... acc = 16
|
||||||
|
1, 15, // STO lit ... @15 = acc = 16
|
||||||
|
2, 15, // STO addr ... @[@15] = acc = 16 ... mem[mem[addr]] <- Acc
|
||||||
|
4, 0, // LDA addr ... acc = @00 = 03
|
||||||
|
0, 0, // END
|
||||||
|
0, 0, // DATA
|
||||||
|
]);
|
||||||
|
|
||||||
|
CPU.loadMemory(test_lda_sto);
|
||||||
|
runCPU();
|
||||||
Loading…
Reference in New Issue