Feature (CPU): Implement a simple single-stepping mode

This commit is contained in:
n loewen 2023-08-16 13:56:23 +01:00
parent 344257a322
commit dd0fdd3b06
7 changed files with 72 additions and 5 deletions

19
cpu.js
View File

@ -1,3 +1,5 @@
const readlineSync = require('readline-sync');
const { INITIAL_IP_ADDRESS, CYCLE_LIMIT } = require('./machine.config');
const { num2hex, num2bin_4bit } = require('./logging.js');
const display = require('./display.js');
@ -311,6 +313,23 @@ exports.runProgram = (code, debug = false, clockSpeed = 10) => {
}, clockSpeed);
}
/**
* @param {Uint8Array} code - Machine code to run
* @param {Boolean} [debug] - Enable/disable debugging printouts
**/
exports.singleStepProgram = (code, debug = false) => {
startCPU(code);
while (CPU.running) {
stepCPU(debug);
// FIXME: this prevents exiting with Ctrl+C:
let key = readlineSync.keyIn('S to step, Q to quit > ', {
limit: ['s', 'S', 'q', 'Q'],
});
if (key.toLowerCase() === 'q') { process.exit(); }
console.log();
}
}
// FUNCTIONS THAT PULL INFO FROM STATE TO DISPLAY

View File

@ -8,7 +8,7 @@
- [ ] Notes re: ROM and/or tape loader
- [ ] CPU updates
- [x] Rename to CPU
- [ ] Implement single-stepping
- [x] Implement single-stepping
- [ ] Implement keypad input
- [ ] Look at KIM-1 and VIP buttons for memory editing

11
package-lock.json generated
View File

@ -5,6 +5,9 @@
"packages": {
"": {
"name": "paper-computer",
"dependencies": {
"readline-sync": "^1.4.10"
},
"devDependencies": {
"jsdoc": "^4.0.2",
"jsdoc-to-markdown": "^8.0.0"
@ -720,6 +723,14 @@
"node": ">=0.10.0"
}
},
"node_modules/readline-sync": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
"integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==",
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/reduce-extract": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",

View File

@ -1,10 +1,13 @@
{
"name": "paper-computer",
"scripts": {
"jsdoc": "./node_modules/.bin/jsdoc"
"jsdoc": "./node_modules/.bin/jsdoc"
},
"devDependencies": {
"jsdoc": "^4.0.2",
"jsdoc-to-markdown": "^8.0.0"
},
"dependencies": {
"readline-sync": "^1.4.10"
}
}

View File

@ -25,6 +25,12 @@ With animated display of screen memory:
With verbose debugging output:
```./run-cpu debug source_code.asm```
With single stepping + pretty-printed display:
```./run-cpu step source_code.asm```
With single stepping + verbose debugging output:
```./run-cpu stepdebug source_code.asm```
## Instruction set
00 END

View File

@ -2,6 +2,8 @@
// Run: `./run-cpu.js run assembly.asm`
// Debug: `./run-cpu.js debug assembly.asm`
// Run with single-stepping: `./run-cpu.js step assembly.asm`
// Debug with single-stepping: `./run-cpu.js stepdebug assembly.asm`
// TODO: allow running pre-compiled machine code.
//
@ -22,12 +24,15 @@ const mode = process.argv[2];
const filename = process.argv[3];
const inputFile_str = fs.readFileSync(filename, 'utf8');
let machineCode;
let machineCode = assembler.assemble(inputFile_str);
if (mode === "debug") {
logRunningHeader();
machineCode = assembler.assemble(inputFile_str);
computer.runProgram(machineCode, true);
} else if (mode === "stepdebug") {
logRunningHeader();
computer.singleStepProgram(machineCode, true);
} else if (mode === "step") {
computer.singleStepProgram(machineCode, false);
} else {
machineCode = assembler.assemble(inputFile_str);
computer.runProgram(machineCode, false, 200);
}

23
sketches/stdin.js Normal file
View File

@ -0,0 +1,23 @@
const readlineSync = require('readline-sync');
let key = readlineSync.keyIn('? ')
console.log(key);
/* This works without external dependencies,
* but it's for a full line at a time
const readline = require('readline/promises');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
async function getInput(prompt) {
let input = await rl.question(prompt)
console.log(input);
console.log("Later");
rl.close();
}
getInput('?');
*/