(hex: string, options: RunOptions)
| 50 | } |
| 51 | |
| 52 | async function executeProgram(hex: string, options: RunOptions): Promise<number> { |
| 53 | const runner = new AVRRunner(hex); |
| 54 | let output = ""; |
| 55 | const startTime = Date.now(); |
| 56 | |
| 57 | // Hook to PORTB register for LED output |
| 58 | runner.portB.addListener(value => { |
| 59 | const time = formatTime(runner.cpu.cycles / runner.MHZ); |
| 60 | if (options.verbose) { |
| 61 | console.log(`[${time}] PORTB: 0x${value.toString(16).padStart(2, '0')}`); |
| 62 | } |
| 63 | }); |
| 64 | |
| 65 | // Serial port output support |
| 66 | runner.usart.onByteTransmit = (value: number) => { |
| 67 | const char = String.fromCharCode(value); |
| 68 | output += char; |
| 69 | process.stdout.write(char); |
| 70 | }; |
| 71 | |
| 72 | // Execute with periodic checks |
| 73 | try { |
| 74 | await runner.execute(cpu => { |
| 75 | const simTime = cpu.cycles / runner.MHZ; |
| 76 | if (simTime > (options.timeout || 30)) { |
| 77 | if (options.verbose) { |
| 78 | const time = formatTime(cpu.cycles / runner.MHZ); |
| 79 | console.error(`\n[${time}] Timeout reached after ${options.timeout}s simulated time`); |
| 80 | } |
| 81 | runner.stop(); |
| 82 | } |
| 83 | }); |
| 84 | } catch (err) { |
| 85 | console.error(`\nExecution error: ${err}`); |
| 86 | return 1; |
| 87 | } |
| 88 | |
| 89 | const executionTime = (Date.now() - startTime) / 1000; |
| 90 | const simTime = runner.cpu.cycles / runner.MHZ; |
| 91 | const cyclesPerSec = runner.cpu.cycles / executionTime; |
| 92 | const perfPercent = (cyclesPerSec / runner.MHZ * 100).toFixed(1); |
| 93 | |
| 94 | if (options.verbose) { |
| 95 | console.log(`\n--- Execution Complete ---`); |
| 96 | console.log(`Wall time: ${executionTime.toFixed(3)}s`); |
| 97 | console.log(`Simulated time: ${formatTime(simTime)}`); |
| 98 | console.log(`CPU cycles: ${runner.cpu.cycles}`); |
| 99 | console.log(`Performance: ${(cyclesPerSec / 1e6).toFixed(2)}M cycles/sec (${perfPercent}% of 16MHz)`); |
| 100 | } |
| 101 | |
| 102 | // Check for required test output |
| 103 | if (!output.includes("Test loop")) { |
| 104 | console.error('\nERROR: "Test loop" not found in output'); |
| 105 | console.error('This likely indicates the test did not execute properly'); |
| 106 | return 1; |
| 107 | } |
| 108 | |
| 109 | return 0; |
no test coverage detected