Implement and test remaining instructions
This commit is contained in:
parent
a17b7f4ba9
commit
10ada984e6
|
|
@ -1,3 +1,8 @@
|
||||||
|
// NOTES:
|
||||||
|
//
|
||||||
|
// - instructions are two bytes long:
|
||||||
|
// one byte for the opcode, one for the argument
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
|
|
||||||
const CPU = {
|
const CPU = {
|
||||||
|
|
@ -23,30 +28,114 @@ const Instructions = {
|
||||||
|
|
||||||
store_lit: (lit) => {
|
store_lit: (lit) => {
|
||||||
console.log('STO lit#');
|
console.log('STO lit#');
|
||||||
CPU.memory[lit] = CPU.acc;
|
CPU.memory[lit] = CPU.Acc;
|
||||||
logTableTitled(CPU.memory, 'Current memory');
|
logTableTitled(CPU.memory, 'Current memory');
|
||||||
CPU.IP = CPU.IP += 2;
|
CPU.IP = CPU.IP += 2;
|
||||||
},
|
},
|
||||||
|
|
||||||
store_addr: (addr) => {
|
store_addr: (addr) => {
|
||||||
console.log('STO addr');
|
console.log('STO addr');
|
||||||
CPU.memory[CPU.memory[addr]] = CPU.acc;
|
CPU.memory[CPU.memory[addr]] = CPU.Acc;
|
||||||
logTableTitled(CPU.memory, 'Memory');
|
logTableTitled(CPU.memory, 'Memory');
|
||||||
CPU.IP = CPU.IP += 2;
|
CPU.IP = CPU.IP += 2;
|
||||||
},
|
},
|
||||||
|
|
||||||
load_lit: (lit) => {
|
load_lit: (lit) => {
|
||||||
console.log('LDA lit#');
|
console.log('LDA lit#');
|
||||||
CPU.acc = lit;
|
CPU.Acc = lit;
|
||||||
CPU.IP = CPU.IP += 2;
|
CPU.IP = CPU.IP += 2;
|
||||||
},
|
},
|
||||||
|
|
||||||
load_addr: (addr) => {
|
load_addr: (addr) => {
|
||||||
console.log('LDA addr');
|
console.log('LDA addr');
|
||||||
console.log('mem at addr: ', CPU.memory[addr]);
|
console.log('mem at addr: ', CPU.memory[addr]);
|
||||||
CPU.acc = CPU.memory[addr];
|
CPU.Acc = CPU.memory[addr];
|
||||||
CPU.IP = CPU.IP += 2;
|
CPU.IP = CPU.IP += 2;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
add_lit: (lit) => {
|
||||||
|
console.log("ADD lit");
|
||||||
|
let sum = CPU.Acc + lit;
|
||||||
|
if (sum > 15) {
|
||||||
|
CPU.CF = 1;
|
||||||
|
CPU.Acc = (sum % 15) - 1;
|
||||||
|
} else {
|
||||||
|
CPU.CF = 0;
|
||||||
|
CPU.Acc = sum;
|
||||||
|
}
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
add_addr: (addr) => {
|
||||||
|
console.log("ADD addr");
|
||||||
|
let sum = CPU.Acc + CPU.memory[addr];
|
||||||
|
if (sum > 15) {
|
||||||
|
CPU.CF = 1;
|
||||||
|
CPU.Acc = (sum % 15) - 1;
|
||||||
|
} else {
|
||||||
|
CPU.CF = 0;
|
||||||
|
CPU.Acc = sum;
|
||||||
|
}
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
sub_lit: (lit) => { // TODO: carry flag
|
||||||
|
console.log("SUB lit");
|
||||||
|
CPU.Acc = CPU.Acc - lit;
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
sub_addr: (addr) => { // TODO: carry flag
|
||||||
|
console.log("SUB addr");
|
||||||
|
CPU.Acc = CPU.Acc - CPU.memory[addr];
|
||||||
|
CPU.IP = CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
hop_lit: (lit) => {
|
||||||
|
console.log("HOP lit");
|
||||||
|
console.log(` ↳ Memory at IP+2 and +3: ${CPU.memory[CPU.IP+2]}, ${CPU.memory[CPU.IP+3]}`);
|
||||||
|
if (CPU.Acc === lit) {
|
||||||
|
CPU.IP += 4;
|
||||||
|
} else {
|
||||||
|
CPU.IP += 2;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hop_addr: (addr) => {
|
||||||
|
console.log("HOP addr");
|
||||||
|
if (CPU.Acc === CPU.memory[addr]) {
|
||||||
|
CPU.IP += 4;
|
||||||
|
} else {
|
||||||
|
CPU.IP += 2;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
jump_lit: (lit) => {
|
||||||
|
console.log("JMP lit");
|
||||||
|
CPU.IP = lit;
|
||||||
|
},
|
||||||
|
|
||||||
|
jump_addr: (addr) => {
|
||||||
|
console.log("JMP addr");
|
||||||
|
CPU.IP = CPU.memory[addr];
|
||||||
|
},
|
||||||
|
|
||||||
|
carry_clear: () => {
|
||||||
|
console.log("CFC");
|
||||||
|
CPU.CF = 0;
|
||||||
|
CPU.IP += 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
carry_hop: () => {
|
||||||
|
console.log("CHP");
|
||||||
|
console.log(` ↳ Memory at IP+2 and +3: ${CPU.memory[CPU.IP+2]}, ${CPU.memory[CPU.IP+3]}`);
|
||||||
|
console.table(CPU.memory);
|
||||||
|
if (CPU.CF != 0) {
|
||||||
|
CPU.IP += 4;
|
||||||
|
} else {
|
||||||
|
CPU.IP += 2;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const instructionLookupTable = {
|
const instructionLookupTable = {
|
||||||
|
|
@ -55,6 +144,16 @@ const instructionLookupTable = {
|
||||||
2: (arg) => Instructions.store_addr(arg),
|
2: (arg) => Instructions.store_addr(arg),
|
||||||
3: (arg) => Instructions.load_lit(arg),
|
3: (arg) => Instructions.load_lit(arg),
|
||||||
4: (arg) => Instructions.load_addr(arg),
|
4: (arg) => Instructions.load_addr(arg),
|
||||||
|
5: (arg) => Instructions.add_lit(arg),
|
||||||
|
6: (arg) => Instructions.add_addr(arg),
|
||||||
|
7: (arg) => Instructions.sub_lit(arg),
|
||||||
|
8: (arg) => Instructions.sub_addr(arg),
|
||||||
|
9: (arg) => Instructions.hop_lit(arg),
|
||||||
|
10: (arg) => Instructions.hop_addr(arg),
|
||||||
|
11: (arg) => Instructions.jump_lit(arg),
|
||||||
|
12: (arg) => Instructions.jump_addr(arg),
|
||||||
|
13: (arg) => Instructions.carry_clear(arg),
|
||||||
|
14: (arg) => Instructions.carry_hop(arg),
|
||||||
};
|
};
|
||||||
|
|
||||||
function stepCPU() {
|
function stepCPU() {
|
||||||
|
|
@ -94,7 +193,7 @@ function runCPU() {
|
||||||
function logCPUState() {
|
function logCPUState() {
|
||||||
console.log();
|
console.log();
|
||||||
console.group('CPU state');
|
console.group('CPU state');
|
||||||
console.log( `Acc: ${CPU.acc} IP: ${CPU.IP} CF: ${CPU.CF} ${CPU.running ? "running" : "halted" }` );
|
console.log( `Acc: ${CPU.Acc} IP: ${CPU.IP} CF: ${CPU.CF} ${CPU.running ? "running" : "halted" }` );
|
||||||
console.log();
|
console.log();
|
||||||
console.groupEnd('CPU state');
|
console.groupEnd('CPU state');
|
||||||
};
|
};
|
||||||
|
|
@ -116,15 +215,60 @@ logTableTitled = (memory, tableTitle) => {
|
||||||
// RUN IT !
|
// RUN IT !
|
||||||
|
|
||||||
const test_lda_sto = new Uint8Array([
|
const test_lda_sto = new Uint8Array([
|
||||||
3, 17, // LDA lit ... acc = 17
|
3, 17, // LDA lit ... Acc = 17
|
||||||
1, 14, // STO lit ... @14 = acc = 17
|
1, 14, // STO lit ... @14 = Acc = 17
|
||||||
3, 16, // LDA lit ... acc = 16
|
3, 16, // LDA lit ... Acc = 16
|
||||||
1, 15, // STO lit ... @15 = acc = 16
|
1, 15, // STO lit ... @15 = Acc = 16
|
||||||
2, 15, // STO addr ... @[@15] = acc = 16 ... mem[mem[addr]] <- Acc
|
2, 15, // STO addr ... @[@15] = Acc = 16 ... mem[mem[addr]] <- Acc
|
||||||
4, 0, // LDA addr ... acc = @00 = 03
|
4, 0, // LDA addr ... Acc = @00 = 03
|
||||||
0, 0, // END
|
0, 0, // END
|
||||||
0, 0, // DATA
|
0, 0, // DATA
|
||||||
]);
|
]);
|
||||||
|
|
||||||
CPU.loadMemory(test_lda_sto);
|
let test_add_sub_nocarry = new Uint8Array([
|
||||||
|
5, 6, // ADD lit ... acc = 6
|
||||||
|
7, 1, // SUB lit ... acc = 5
|
||||||
|
1, 15, // STO lit ... mem[15] = 5
|
||||||
|
6, 15, // ADD addr ... acc = 10
|
||||||
|
8, 15, // SUB addr ... acc = 5
|
||||||
|
0, 0, // END
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let test_hop = new Uint8Array([
|
||||||
|
5, 8, // ADD lit ... acc = 8
|
||||||
|
9, 8, // HOP lit ... hop over next op if acc = 8
|
||||||
|
0, 0, // END ... (hopped over)
|
||||||
|
7, 8, // SUB lit ... acc = 0
|
||||||
|
0, 0
|
||||||
|
]);
|
||||||
|
|
||||||
|
let test_jmp = new Uint8Array([
|
||||||
|
11, 8, // 0 ... JMP lit
|
||||||
|
0, 0, // 2 ... END ... JMP'd over
|
||||||
|
0, 0, // 4
|
||||||
|
0, 0, // 6
|
||||||
|
5, 8, // 8 ... ADD lit ... acc = 8
|
||||||
|
0, 0, // 10 ... END
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
const test_chp = new Uint8Array([
|
||||||
|
5, 8, // ADD lit ... Acc = 8
|
||||||
|
14, 0, // CHP ... shouldn't hop (CF = 0)
|
||||||
|
5, 1, // ADD lit ... Acc = 9
|
||||||
|
5, 8, // ADD lit ... Acc = 1 and CF = 1
|
||||||
|
14, 0, // CHP ... hop! (CF = 1)
|
||||||
|
0, 0, // END
|
||||||
|
7, 1, // SUB lit ... Acc = 0
|
||||||
|
13, 0, // CFC ... CF = 0
|
||||||
|
0, 0, // END
|
||||||
|
]);
|
||||||
|
|
||||||
|
//CPU.loadMemory(test_lda_sto);
|
||||||
|
//CPU.loadMemory(test_add_sub_nocarry);
|
||||||
|
//CPU.loadMemory(test_hop);
|
||||||
|
CPU.loadMemory(test_jmp);
|
||||||
|
//CPU.loadMemory(test_chp);
|
||||||
runCPU();
|
runCPU();
|
||||||
Loading…
Reference in New Issue