- USB CDC 경로 복원: #define Serial Serial1 우회 제거 - rp2040js/avr8js/codemirror/xterm/monaco-editor vendor화 - /vendor 정적 라우팅 추가 (Express 5 catch-all 우회) - 부팅 완료 타임아웃 감지 (Serial 출력 없어도 8초 후 RAF 전환) - 리셋 시 Simulator 재생성으로 주변 장치 상태 초기화 - 시리얼 패널의 내부 메시지를 console.log로 이동
52 lines
1.7 KiB
JavaScript
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);
|
|
}
|
|
}
|