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