--- nono/vm/mfp.cpp 2026/04/29 17:05:10 1.1.1.12 +++ nono/vm/mfp.cpp 2026/04/29 17:05:14 1.1.1.13 @@ -85,6 +85,9 @@ MFPDevice::ResetHard(bool poweron) // VR is initialized to $00 (not $0f). mfp.vr_vec = 0; mfp.vr_s = 0; + + // CIRQ | FMIRQ | EXPON | ALARM にしておく + mfp.gpip = 0x6b; } uint64 @@ -183,7 +186,7 @@ MFPDevice::Write(uint32 offset, uint32 d switch (offset) { case MFP::GPIP: - putlog(0, "GPIP <- $%02x 未実装書き込み", data); + putlog(0, "Write GPIP <- $%02x (NOT IMPLEMENTED)", data); mfp.gpip = data; break; case MFP::AER: @@ -192,7 +195,7 @@ MFPDevice::Write(uint32 offset, uint32 d break; case MFP::DDR: if (data != 0) { - putlog(0, "DDR <- $%02x 未実装書き込み", data); + putlog(0, "Write DDR <- $%02x (NOT IMPLEMENTED)", data); } mfp.ddr = data; break; @@ -267,7 +270,7 @@ MFPDevice::Write(uint32 offset, uint32 d SetTDR(3, data); break; case MFP::SCR: - putlog(0, "SCR <- $%02x 未実装書き込み", data); + putlog(0, "SCR <- $%02x (NOT IMPLEMENTED)", data); mfp.scr = data; break; case MFP::UCR: @@ -279,7 +282,10 @@ MFPDevice::Write(uint32 offset, uint32 d SetRSR(data); break; case MFP::TSR: - putlog(0, "TSR <- $%02x 未実装書き込み", data); + if ((data & 0x0e)) { + // SO 端子関係の B, H, L ビットは未実装 + putlog(0, "TSR <- $%02x (B,H,L bit NOT IMPLEMENTED)", data); + } mfp.tsr = (mfp.tsr & 0xf0) | (data & 0x0f); break; case MFP::UDR: @@ -392,8 +398,8 @@ MFPDevice::MonitorUpdate(Monitor *, Text // 0 1 2 3 4 5 6 // 01234567890123456789012345678901234567890123456789012345678901234567890 // $e88001(GPIP):$00 $e88007(IERA):$00 $e88019(TACR):$00 $e88027 - // IER IMR IPR ISR Mode TDR Cnt - // An:MPSC TxEmpty Enable Mask Pend Serv Timer-A Delay(50us) 255 255 + // IER IMR IPR ISR Mode TDR Cnt + // An:MPSC TxEmpty Enable Mask Pend Serv Timer-A Delay(50us) 255 255 #define A(x) (baseaddr + (x * 2) + 1) @@ -458,9 +464,9 @@ MFPDevice::MonitorUpdate(Monitor *, Text } // タイマー関連 - x = 39; + x = 40; y = 9; - screen.Print(x, y++, " Mode TDR Ini"); + screen.Print(x, y++, " Mode TDR Ini"); for (int ch = 0; ch < 4; ch++) { screen.Print(x, y, "Timer-%c", ch + 'A'); if (mfp.tcr[ch] == 0) { @@ -473,13 +479,13 @@ MFPDevice::MonitorUpdate(Monitor *, Text screen.Print(x + 8, y, "Delay(%s)", prescale_str[mfp.tcr[ch]]); } - screen.Print(x + 19, y, "%3d", GetTDR(ch)); - screen.Print(x + 23, y, "%3d", mfp.initial_tdr[ch]); + screen.Print(x + 20, y, "%3d", GetTDR(ch)); + screen.Print(x + 24, y, "%3d", mfp.initial_tdr[ch]); y++; } // GPIP 関連 - x = 39; + x = 40; y = 9 + 8; screen.Puts(x, y++, " GPIP AER DDR"); for (int i = 7; i >= 0; i--, y++) { @@ -573,7 +579,7 @@ MFPDevice::SetTCR(int ch, uint32 data) return; } else if (prev < 8) { // タイマー停止 - putlog(1, "Timer-%c 停止", ch + 'A'); + putlog(1, "Timer-%c Stop", ch + 'A'); // ここで TDR を確定させる。 // タイマー動作中の TDR の参照はイベント終了時刻から現在値を逆算 @@ -600,12 +606,13 @@ MFPDevice::SetTCR(int ch, uint32 data) mfp.tdr[ch] = mfp.initial_tdr[ch]; // タイマースタート uint64 period = prescale_ns[mfp.tcr[ch]]; - event[ch].time = period * (mfp.tdr[ch] ?: 256); + uint count = mfp.tdr[ch] ?: 256; + event[ch].time = period * count; gScheduler->RestartEvent(event[ch]); - putlog(1, "Timer-%c ディレイモード開始(%u x %u.%uusec)", + putlog(1, "Timer-%c Start Delay mode(%u x %u.%uusec)", ch + 'A', - mfp.initial_tdr[ch], + count, (uint)period / 1000, (uint)(period / 100) % 10); return; @@ -615,11 +622,11 @@ MFPDevice::SetTCR(int ch, uint32 data) // TDR をロードする mfp.initial_tdr[ch] = mfp.tdr[ch]; - putlog(1, "Timer-%c イベントカウントモード", ch + 'A'); + putlog(1, "Timer-%c Event count mode", ch + 'A'); return; } else { - putlog(0, "T%cCR パルス幅測定モード $%02x 未実装", + putlog(0, "T%cCR Pulse-Width Measurement Mode $%02x (NOT IMPLEMENTED)", ch + 'A', data); return; } @@ -669,7 +676,7 @@ MFPDevice::SetTDR(int ch, uint32 data) } else { // イベントモード、パルス幅測定モードは未対応 - putlog(0, "T%cDR サポートしてないモード中の書き込み $%02x", + putlog(0, "Write T%cDR $%02x during unsupported mode (NOT IMPLEMENTED)", ch + 'A', data); } } @@ -727,6 +734,20 @@ MFPDevice::SetVDisp(bool vdisp) SetGPIP(MFP::GPIP_VDISP, vdisp); } +// 電源ボタン状態入力 (PowerDevice から呼ばれる) +void +MFPDevice::SetPowSW(bool powsw) +{ + SetGPIP(MFP::GPIP_POWSW, powsw); +} + +// ALARM 信号入力 (RTC の ALARM_OUT 出力端子) +void +MFPDevice::SetAlarmOut(bool alarm) +{ + SetGPIP(MFP::GPIP_ALARM, alarm); +} + // GPIP への入力。 // num はビット番号(0..7)。 void @@ -746,7 +767,17 @@ MFPDevice::SetGPIP(int num, bool val) // 1 1 0 0 // 1 1 1 0 if ((old != val) && (aer == val)) { - // XXX ここで割り込みを上げる + // ここで割り込みを上げる + // XXX GPIP ビット番号と INTR の対応どうなってんの + int intr; + if (num < 4) { + intr = num; + } else if (num < 6) { + intr = num + 2; + } else { + intr = num - MFP::GPIP_CIRQ + MFP::INTR_CRTC_IRQ; + } + SetInterrupt(intr); } if (val) { @@ -763,13 +794,13 @@ MFPDevice::SetUCR(uint32 data) mfp.ucr = data; if ((mfp.ucr & MFP::UCR_CLK) == 0) { - putlog(0, "UCR CLK=0 未実装"); + putlog(0, "UCR CLK=0 (NOT IMPLEMENTED)"); } if (((mfp.ucr & MFP::UCR_WL) >> 5) != 0) { - putlog(0, "UCR WL=%d 未実装", (mfp.ucr >> 5) & 3); + putlog(0, "UCR WL=%d (NOT IMPLEMENTED)", (mfp.ucr >> 5) & 3); } if (((mfp.ucr & MFP::UCR_ST) >> 3) != 1) { - putlog(0, "UCR ST=%d 未実装", (mfp.ucr >> 3) & 3); + putlog(0, "UCR ST=%d (NOT IMPLEMENTED)", (mfp.ucr >> 3) & 3); } }