import { buildHex } from './compile'; import { AVRRunner } from './execute'; import { formatTime } from './format-time'; import './index.css'; import { LED } from './led'; import { CPUPerformance } from './cpu-performance'; let editor: any; const BLINK_CODE = ` // Green LED connected to LED_BUILTIN, // Red LED connected to pin 12. Enjoy! void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); } void loop() { Serial.println("Blink"); digitalWrite(LED_BUILTIN, HIGH); delay(500); digitalWrite(LED_BUILTIN, LOW); delay(500); }`.trim(); // Load Editor declare var window: any; declare var monaco: any; window.require.config({ paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.18.0/min/vs' } }); window.require(['vs/editor/editor.main'], () => { editor = monaco.editor.create(document.querySelector('.code-editor'), { value: BLINK_CODE, language: 'cpp', minimap: { enabled: false } }); }); // Set up LEDs const leds = document.querySelector('.leds'); const led13 = new LED({ color: 'green', lightColor: '#80ff80' }); const led12 = new LED({ color: 'red', lightColor: '#ff8080' }); leds.appendChild(led13.el); leds.appendChild(led12.el); // Set up toolbar let runner: AVRRunner; const runButton = document.querySelector('#run-button'); runButton.addEventListener('click', compileAndRun); const stopButton = document.querySelector('#stop-button'); stopButton.addEventListener('click', stopCode); const statusLabel = document.querySelector('#status-label'); const compilerOutputText = document.querySelector('#compiler-output-text'); const serialOutputText = document.querySelector('#serial-output-text'); function executeProgram(hex: string) { runner = new AVRRunner(hex); const MHZ = 16000000; // Hook to PORTB register runner.portB.addListener((value) => { const D12bit = 1 << 4; const D13bit = 1 << 5; led12.value = value & D12bit ? true : false; led13.value = value & D13bit ? true : false; }); runner.usart.onByteTransmit = (value) => { serialOutputText.textContent += String.fromCharCode(value); }; const cpuPerf = new CPUPerformance(runner.cpu, MHZ); runner.execute((cpu) => { const time = formatTime(cpu.cycles / MHZ); const speed = (cpuPerf.update() * 100).toFixed(0); statusLabel.textContent = `Simulation time: ${time} (${speed}%)`; }); } async function compileAndRun() { led12.value = false; led13.value = false; runButton.setAttribute('disabled', '1'); serialOutputText.textContent = ''; try { statusLabel.textContent = 'Compiling...'; const result = await buildHex(editor.getModel().getValue()); compilerOutputText.textContent = result.stderr || result.stdout; if (result.hex) { compilerOutputText.textContent += '\nProgram running...'; stopButton.removeAttribute('disabled'); executeProgram(result.hex); } else { runButton.removeAttribute('disabled'); } } catch (err) { runButton.removeAttribute('disabled'); alert('Failed: ' + err); } finally { statusLabel.textContent = ''; } } function stopCode() { stopButton.setAttribute('disabled', '1'); runButton.removeAttribute('disabled'); if (runner) { runner.stop(); runner = null; } }