131 lines
3.2 KiB
JavaScript
131 lines
3.2 KiB
JavaScript
function CPU(mem) {
|
||
this.memory = mem;
|
||
this.running = false;
|
||
this.instructionPointer = 0;
|
||
this.carryFlag = 0;
|
||
this.acc = 0;
|
||
|
||
this.instructions = {
|
||
end: () => {
|
||
console.log('END');
|
||
this.running = false
|
||
},
|
||
store_lit: (lit) => {
|
||
console.log('STO lit#');
|
||
this.memory[lit] = this.acc;
|
||
log_memory();
|
||
this.instructionPointer = this.instructionPointer += 1;
|
||
},
|
||
store_addr: (addr) => {
|
||
console.log('STO addr');
|
||
this.memory[this.memory[addr]] = this.acc;
|
||
log_memory();
|
||
this.instructionPointer = this.instructionPointer += 1;
|
||
},
|
||
load_lit: (lit) => {
|
||
console.log('LDA lit#');
|
||
this.acc = lit;
|
||
this.instructionPointer = this.instructionPointer += 1;
|
||
},
|
||
load_addr: (addr) => {
|
||
console.log('LDA addr');
|
||
console.log('mem at addr: ', this.memory[addr]);
|
||
this.acc = this.memory[addr];
|
||
this.instructionPointer = this.instructionPointer += 1;
|
||
},
|
||
};
|
||
|
||
log_debug_state = () => {
|
||
console.log();
|
||
console.group('CPU state');
|
||
console.log( `IP: ${this.instructionPointer} Acc: ${this.acc} CF: ${this.carryFlag} ${this.running ? "running" : "halted" }` );
|
||
console.log();
|
||
console.groupEnd('CPU state');
|
||
};
|
||
|
||
log_memory = () => {
|
||
console.log();
|
||
console.group('Memory');
|
||
console.table(this.memory);
|
||
console.groupEnd('Memory');
|
||
}
|
||
|
||
this.perform_operation = (opcode, arg) => {
|
||
switch (opcode) {
|
||
case 0:
|
||
this.instructions.end(arg);
|
||
break;
|
||
|
||
case 1:
|
||
this.instructions.store_lit(arg);
|
||
break;
|
||
|
||
case 2:
|
||
this.instructions.store_addr(arg);
|
||
break;
|
||
|
||
case 3:
|
||
this.instructions.load_lit(arg);
|
||
break;
|
||
|
||
case 4:
|
||
this.instructions.load_addr(arg);
|
||
break;
|
||
|
||
default:
|
||
console.error( `Invalid opcode: ${opcode} with argument ${arg}` );
|
||
}
|
||
};
|
||
|
||
this.run_program = () => {
|
||
console.log();
|
||
console.log( "Running program..." );
|
||
log_debug_state();
|
||
|
||
this.running = true;
|
||
|
||
for (let i = 1; i < 16; i++) {
|
||
if ( this.running &&
|
||
(this.instructionPointer < this.memory.length) ) {
|
||
let op_arg_tuple = this.memory[this.instructionPointer];
|
||
console.group("Proccessing instruction");
|
||
console.log( op_arg_tuple );
|
||
// console.log( `processing opcode ${op_arg_tuple[0]} with arg ${op_arg_tuple[1]}` );
|
||
this.perform_operation(op_arg_tuple[0], op_arg_tuple[1]);
|
||
log_debug_state();
|
||
console.groupEnd("Processing instruction");
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// UNIMPLEMENTED
|
||
let add_lit = function(lit) { return; }
|
||
let add_addr = function(addr) { return; }
|
||
let subtract_lit = function(lit) { return; }
|
||
let subtract_addr = function(addr) { return; }
|
||
let hop_lit = function(lit) { return; }
|
||
let hop_addr = function(addr) { return; }
|
||
let jump_lit = function(lit) { return; }
|
||
let jump_addr = function(addr) { return; }
|
||
let carry_toggle = function() { return; }
|
||
let carry_hop = function() { return; }
|
||
|
||
|
||
// TEST
|
||
|
||
let halt_and_catch_fire = [
|
||
[0, 0],
|
||
[1, 0],
|
||
];
|
||
|
||
let basic_test = [
|
||
[3, 8], // LDA lit
|
||
[1, 5], // STO lit
|
||
[4, 5], // LDA addr
|
||
[2, 6], // STO addr
|
||
[0, 0], // END
|
||
];
|
||
|
||
let comp = new CPU(basic_test);
|
||
comp.run_program(); |