--- nono/vm/mfp.cpp 2026/04/29 17:04:39 1.1.1.5 +++ nono/vm/mfp.cpp 2026/04/29 17:04:42 1.1.1.6 @@ -40,28 +40,60 @@ MFPDevice::~MFPDevice() { } +// 本体リセットスイッチによるリセット +void +MFPDevice::ResetHard() +{ + Reset(); +} + // MPU の RESET 命令によるリセット void MFPDevice::ResetSoft() { - // TxDR, UDR, TSR はクリアされない - - // ? - mfp.tsr = 0x80; + Reset(); +} - // それ以外のすべてのレジスタはクリア? - mfp.vr = 0; +// リセット(共通) +void +MFPDevice::Reset() +{ + // All internal registers are cleared expect the TxDR, UDR, and TSR. + mfp.aer = 0; + mfp.ddr = 0; + mfp.ier.w = 0; + mfp.ipr.w = 0; + mfp.isr.w = 0; + mfp.imr.w = 0; + for (int i = 0; i < countof(mfp.tcr); i++) { + mfp.tcr[i] = 0; + mfp.timer_start[i] = 0; + } + mfp.scr = 0; + mfp.ucr = 0; + mfp.rsr = 0; + // XXX TSR は変化しないがたぶんバッファはクリアされるので BE は立つ + // ということかな。 + mfp.tsr = MFP::TSR_BE; - // タイマーはすべてストップなのでイベントを削除 + // All timers are stopped. for (int ch = 0; ch < countof(event); ch++) { event[ch].Stop(); } key_event.Stop(); + // USART RX and TX are disabled. + // SO line is placed in HighZ. + // The interrupt channels are disabled, and + // any pending interrupts are cleared. + // GPIO lines are placed in HighZ. + // timer outputs are driven low. + // External signals are nagated. + // VR is initialized to $00 (not $0f). + mfp.vr = 0; + // 信号線 rr = false; - - // ペンディング割り込みクリア } uint64 @@ -69,6 +101,8 @@ MFPDevice::Read(uint32 addr) { uint8 data; + gMPU->AddCycle(24); // InsideOut p.135 + switch (addr) { case MFP::GPIP: data = mfp.gpip; @@ -152,6 +186,8 @@ MFPDevice::Read(uint32 addr) uint64 MFPDevice::Write(uint32 addr, uint32 data) { + gMPU->AddCycle(24); // InsideOut p.135 + switch (addr) { case MFP::GPIP: putlog(0, "GPIP <- $%02x 未実装書き込み", data); @@ -685,9 +721,9 @@ MFPDevice::SetTDR(int ch, uint32 data) // イベントコールバック void -MFPDevice::TimerCallback(int arg) +MFPDevice::TimerCallback(Event& ev) { - int ch = arg; + int& ch = ev.code; int prevtdr; uint64 ellapsed; uint64 scale; @@ -717,8 +753,8 @@ MFPDevice::TimerCallback(int arg) // 1タイマー期間を新しい TDR で再計算 period = prescale_ns[mfp.tcr[ch]] * mfp.initial_tdr[ch]; // イベント再設定 - event[ch].time = period; - event[ch].Start(); + ev.time = period; + ev.Start(); // 割り込みを上げる gMPU680x0->Interrupt(this, 6, mfp.vr + timer_vector[ch]); @@ -860,12 +896,12 @@ MFPDevice::Rx(uint32 data) // キーボードからのデータが受信し終わった頃に呼ばれるイベント。 void -MFPDevice::KeyCallback(int code) +MFPDevice::KeyCallback(Event& ev) { // Ready を元に戻す rr = true; - mfp.udr = code; + mfp.udr = ev.code; mfp.rsr |= MFP::RSR_BF; // XXX この辺要再考察