- USB CDC 경로 복원: #define Serial Serial1 우회 제거 - rp2040js/avr8js/codemirror/xterm/monaco-editor vendor화 - /vendor 정적 라우팅 추가 (Express 5 catch-all 우회) - 부팅 완료 타임아웃 감지 (Serial 출력 없어도 8초 후 RAF 전환) - 리셋 시 Simulator 재생성으로 주변 장치 상태 초기화 - 시리얼 패널의 내부 메시지를 console.log로 이동
55 lines
2.0 KiB
JavaScript
55 lines
2.0 KiB
JavaScript
// SPDX-License-Identifier: MIT
|
|
// Copyright (c) Uri Shaked and contributors
|
|
const CLKPCE = 128;
|
|
export const clockConfig = {
|
|
CLKPR: 0x61,
|
|
};
|
|
const prescalers = [
|
|
1, 2, 4, 8, 16, 32, 64, 128, 256,
|
|
// The following values are "reserved" according to the datasheet, so we measured
|
|
// with a scope to figure them out (on ATmega328p)
|
|
2, 4, 8, 16, 32, 64, 128,
|
|
];
|
|
export class AVRClock {
|
|
constructor(cpu, baseFreqHz, config = clockConfig) {
|
|
this.cpu = cpu;
|
|
this.baseFreqHz = baseFreqHz;
|
|
this.config = config;
|
|
this.clockEnabledCycles = 0;
|
|
this.prescalerValue = 1;
|
|
this.cyclesDelta = 0;
|
|
this.cpu.writeHooks[this.config.CLKPR] = (clkpr) => {
|
|
if ((!this.clockEnabledCycles || this.clockEnabledCycles < cpu.cycles) && clkpr === CLKPCE) {
|
|
this.clockEnabledCycles = this.cpu.cycles + 4;
|
|
}
|
|
else if (this.clockEnabledCycles && this.clockEnabledCycles >= cpu.cycles) {
|
|
this.clockEnabledCycles = 0;
|
|
const index = clkpr & 0xf;
|
|
const oldPrescaler = this.prescalerValue;
|
|
this.prescalerValue = prescalers[index];
|
|
this.cpu.data[this.config.CLKPR] = index;
|
|
if (oldPrescaler !== this.prescalerValue) {
|
|
this.cyclesDelta =
|
|
(cpu.cycles + this.cyclesDelta) * (oldPrescaler / this.prescalerValue) - cpu.cycles;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
}
|
|
get frequency() {
|
|
return this.baseFreqHz / this.prescalerValue;
|
|
}
|
|
get prescaler() {
|
|
return this.prescalerValue;
|
|
}
|
|
get timeNanos() {
|
|
return ((this.cpu.cycles + this.cyclesDelta) / this.frequency) * 1e9;
|
|
}
|
|
get timeMicros() {
|
|
return ((this.cpu.cycles + this.cyclesDelta) / this.frequency) * 1e6;
|
|
}
|
|
get timeMillis() {
|
|
return ((this.cpu.cycles + this.cyclesDelta) / this.frequency) * 1e3;
|
|
}
|
|
}
|