cardiograph-computer/simulator-sketch.js

189 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
},
add_lit: (lit) => {
console.log("ADD lit");
if ( (this.acc + lit) > 15 ) { this.carryFlag = 1; }
this.acc = (this.acc + lit % 15);
this.instructionPointer = this.instructionPointer += 1;
},
add_addr: (addr) => {
console.log("ADD addr");
if ( (this.acc + this.memory[addr]) > 15 ) { this.carryFlag = 1; }
this.acc = (this.acc + this.memory[addr] % 15);
this.instructionPointer = this.instructionPointer += 1;
},
sub_lit: (lit) => { // TODO: carry flag
console.log("SUB lit");
this.acc = this.acc - lit;
this.instructionPointer = this.instructionPointer += 1;
},
sub_addr: (addr) => { // TODO: carry flag
console.log("SUB addr");
this.acc = this.acc - this.memory[addr];
this.instructionPointer = this.instructionPointer += 1;
},
};
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;
case 5:
this.instructions.add_lit(arg);
break;
case 6:
this.instructions.add_addr(arg);
break;
case 7:
this.instructions.sub_lit(arg);
break;
case 8:
this.instructions.sub_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");
}
}
}
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');
};
};
// UNIMPLEMENTED
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 test_lda_sto = [
[3, 8], // LDA lit
[1, 5], // STO lit
[4, 5], // LDA addr
[2, 6], // STO addr
[0, 0], // END
];
// let comp = new CPU(test_lda_sto);
// comp.run_program();
let test_add_sub_nocarry = [
[5, 6], // ADD lit ... acc = 6
[7, 1], // SUB lit ... acc = 5
[1, 8], // STO lit ... mem[8] = 5
[6, 8], // ADD addr ... acc = 10
[8, 8], // SUB addr ... acc = 5
[0, 0], // END
]
let test_add_sub = [
[5, 26], // ADD lit
[0, 0], // END
]
let comp = new CPU(test_add_sub);
comp.run_program();