const { num2hex, bool2bit } = require('./logging.js'); const CFG = require('./machine.config.js'); const CPU = require('./cpu.js'); const io = require('./io.js'); // TODO - replace with reading STDIN: const assembler = require('./assembler.js'); const fs = require('fs'); const filename = process.argv[2]; const inputFile_str = fs.readFileSync(filename, 'utf8'); let assemblerOutput = assembler.assemble(inputFile_str); let cpu = new CPU(CFG.initialIP, CFG.defaultCycleLimit); cpu.loadMemory(assemblerOutput.machineCode); cpu.loadSourceInfo(assemblerOutput.debugInfo); cpu.onCycleEnd(tick); cpu.onCycleEnd(logCPUState); cpu.start(); io.getKeypadInput(cpu); cpu.step(); async function tick() { const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) await sleep(100); cpu.step(); if (!cpu.running) { console.log('Halted'); process.exit(); } } function logCPUState() { let lineInfo = cpu.dbg.sourceInfo[cpu.dbg.previousIP]; console.group(`Step ${cpu.dbg.cycleCounter}`); console.log(); io.showDisplay(cpu.memory, true); // FIXME - display - allow printing hex as well as pretty-printing console.log(); if (lineInfo) { console.log(`Line ${lineInfo.lineNumber}: ${lineInfo.source}`); console.log(); } console.log('Mnemonic:', cpu.dbg.currentMnemonic); console.log(`Machine: $${num2hex(cpu.instruction.opcode)} $${num2hex(cpu.instruction.operand)}`); console.log(); console.log(`IP: $${num2hex(cpu.IP)} Acc: $${num2hex(cpu.acc)} ONZC ${bool2bit(cpu.flags.O)}${bool2bit(cpu.flags.N)}${bool2bit(cpu.flags.Z)}${bool2bit(cpu.flags.C)}`); console.log(`KEY: ${io.readKeyMem(cpu.memory)} ${cpu.running ? "running" : "halted" }`); console.log(); console.groupEnd(); }; /* (async function() { let input = await readPipedStdin(); console.log(input); })() */ async function readPipedStdin() { // https://wellingguzman.com/notes/node-pipe-input return new Promise(function (resolve, reject) { const stdin = process.stdin; stdin.setEncoding('utf8'); let data = ''; stdin.on('data', function (chunk) { data += chunk; }); stdin.on('end', function () { resolve(data); }); stdin.on('error', reject); }); }