Files
homeclaw/web-ui/vendor/rp2040js/clock/simulation-clock.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

93 lines
2.5 KiB
JavaScript

export class ClockAlarm {
constructor(clock, callback) {
this.clock = clock;
this.callback = callback;
this.next = null;
this.nanos = 0;
this.scheduled = false;
}
schedule(deltaNanos) {
if (this.scheduled) {
this.cancel();
}
this.clock.linkAlarm(deltaNanos, this);
}
cancel() {
this.clock.unlinkAlarm(this);
this.scheduled = false;
}
}
export class SimulationClock {
constructor(frequency = 125e6) {
this.frequency = frequency;
this.nextAlarm = null;
this.nanosCounter = 0;
}
get nanos() {
return this.nanosCounter;
}
get micros() {
return this.nanos / 1000;
}
createAlarm(callback) {
return new ClockAlarm(this, callback);
}
linkAlarm(nanos, alarm) {
alarm.nanos = this.nanos + nanos;
let alarmListItem = this.nextAlarm;
let lastItem = null;
while (alarmListItem && alarmListItem.nanos < alarm.nanos) {
lastItem = alarmListItem;
alarmListItem = alarmListItem.next;
}
if (lastItem) {
lastItem.next = alarm;
alarm.next = alarmListItem;
}
else {
this.nextAlarm = alarm;
alarm.next = alarmListItem;
}
alarm.scheduled = true;
return alarm;
}
unlinkAlarm(alarm) {
let alarmListItem = this.nextAlarm;
if (!alarmListItem) {
return false;
}
let lastItem = null;
while (alarmListItem) {
if (alarmListItem === alarm) {
if (lastItem) {
lastItem.next = alarmListItem.next;
}
else {
this.nextAlarm = alarmListItem.next;
}
return true;
}
lastItem = alarmListItem;
alarmListItem = alarmListItem.next;
}
return false;
}
tick(deltaNanos) {
const targetNanos = this.nanosCounter + deltaNanos;
let alarm = this.nextAlarm;
while (alarm && alarm.nanos <= targetNanos) {
this.nextAlarm = alarm.next;
this.nanosCounter = alarm.nanos;
alarm.callback();
alarm = this.nextAlarm;
}
this.nanosCounter = targetNanos;
}
get nanosToNextAlarm() {
if (this.nextAlarm) {
return this.nextAlarm.nanos - this.nanos;
}
return 0;
}
}