Files
homeclaw/web-ui/vendor/avr8js/utils/test-utils.js
T
kim 209f3a3aef v3.0.6: RP2040 에뮬레이터 개선 — USB CDC, vendor화, 부팅 감지
- USB CDC 경로 복원: #define Serial Serial1 우회 제거
- rp2040js/avr8js/codemirror/xterm/monaco-editor vendor화
- /vendor 정적 라우팅 추가 (Express 5 catch-all 우회)
- 부팅 완료 타임아웃 감지 (Serial 출력 없어도 8초 후 RAF 전환)
- 리셋 시 Simulator 재생성으로 주변 장치 상태 초기화
- 시리얼 패널의 내부 메시지를 console.log로 이동
2026-06-19 15:49:36 +09:00

52 lines
1.7 KiB
JavaScript

// SPDX-License-Identifier: MIT
// Copyright (c) Uri Shaked and contributors
import { avrInstruction } from '../cpu/instruction.js';
import { assemble } from './assembler.js';
const BREAK_OPCODE = 0x9598;
export function asmProgram(source) {
const { bytes, errors, lines, labels } = assemble(source);
if (errors.length) {
throw new Error('Assembly failed: ' + errors);
}
return { program: new Uint16Array(bytes.buffer), lines, instructionCount: lines.length, labels };
}
const defaultOnBreak = () => {
throw new Error('BREAK instruction encountered');
};
export class TestProgramRunner {
constructor(cpu, onBreak = defaultOnBreak) {
this.cpu = cpu;
this.onBreak = onBreak;
}
runInstructions(count) {
const { cpu, onBreak } = this;
for (let i = 0; i < count; i++) {
if (cpu.progMem[cpu.pc] === BREAK_OPCODE) {
onBreak === null || onBreak === void 0 ? void 0 : onBreak(cpu);
}
avrInstruction(cpu);
cpu.tick();
}
}
runUntil(predicate, maxIterations = 5000) {
const { cpu, onBreak } = this;
for (let i = 0; i < maxIterations; i++) {
if (cpu.progMem[cpu.pc] === BREAK_OPCODE) {
onBreak === null || onBreak === void 0 ? void 0 : onBreak(cpu);
}
if (predicate(cpu)) {
return;
}
avrInstruction(cpu);
cpu.tick();
}
throw new Error('Test program ran for too long, check your predicate');
}
runToBreak() {
this.runUntil((cpu) => cpu.progMem[cpu.pc] === BREAK_OPCODE);
}
runToAddress(byteAddr) {
this.runUntil((cpu) => cpu.pc * 2 === byteAddr);
}
}