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 { INITIAL_IP_ADDRESS, CYCLE_LIMIT } = require('./machine.config');
const { num2hex, num2bin_4bit } = require('./logging.js'); const { num2hex, num2bin_4bit } = require('./logging.js');
const display = require('./display.js'); const display = require('./display.js');
@ -311,6 +313,23 @@ exports.runProgram = (code, debug = false, clockSpeed = 10) => {
}, clockSpeed); }, 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 // FUNCTIONS THAT PULL INFO FROM STATE TO DISPLAY

View File

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

11
package-lock.json generated
View File

@ -5,6 +5,9 @@
"packages": { "packages": {
"": { "": {
"name": "paper-computer", "name": "paper-computer",
"dependencies": {
"readline-sync": "^1.4.10"
},
"devDependencies": { "devDependencies": {
"jsdoc": "^4.0.2", "jsdoc": "^4.0.2",
"jsdoc-to-markdown": "^8.0.0" "jsdoc-to-markdown": "^8.0.0"
@ -720,6 +723,14 @@
"node": ">=0.10.0" "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": { "node_modules/reduce-extract": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",

View File

@ -1,10 +1,13 @@
{ {
"name": "paper-computer", "name": "paper-computer",
"scripts": { "scripts": {
"jsdoc": "./node_modules/.bin/jsdoc" "jsdoc": "./node_modules/.bin/jsdoc"
}, },
"devDependencies": { "devDependencies": {
"jsdoc": "^4.0.2", "jsdoc": "^4.0.2",
"jsdoc-to-markdown": "^8.0.0" "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: With verbose debugging output:
```./run-cpu debug source_code.asm``` ```./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 ## Instruction set
00 END 00 END

View File

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