--- nono/vm/mfp.h 2026/04/29 17:04:36 1.1.1.3 +++ nono/vm/mfp.h 2026/04/29 17:04:45 1.1.1.6 @@ -81,32 +81,29 @@ struct MFP ir16 ipr; ir16 isr; ir16 imr; - uint8 vr; // V7 V6 V5 V4 S --- --- --- + + // + // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | + // VR | V7 | V6 | V5 | V4 | S | --- | --- | --- | + // | | | | +------------ In-Service Register Enable + // +-----+-----+-----+------------------ Vector Number + uint8 vr_vec; // ベクタの上位4ビット + uint8 vr_s; // %1:ソフトウェアEOI(ISR有効)、%0:自動EOI(ISR無効) + uint8 GetVR() const { return vr_vec | vr_s; } // TDR のカウンタをメインカウンタと呼び、このメインカウンタを // 1減らすためのカウンタをプリスケーラカウンタと呼ぶ。 // 実際のハードウェアは 4MHz のクロック入力ごとにプリスケーラカウンタを // カウントしていき指定回数カウントすればメインカウンタを1減らすのだが、 - // この実装ではどちらのカウンタも持たず、タイマー開始時刻と現在時刻で - // 管理する。そのため、メインカウンタもプリスケーラカウンタも必要なら - // この時間差から求める。 - // - // X680x0 の MFP は 4MHz なので、1クロックは 0.25 usec。 - // TxCR = 1 の時プリスケール回数は 10 なので、入力クロック10回 - // (2.5usec) ごとにメインカウンタを 1 減らす。 - // TxDR = 5 から開始すれば 50 カウント (12.5 usec) 後にタイムアップする。 - // そのためタイマー開始時から現在 3 usec 経過していれば 3 / 0.25 = 12 で - // 総入力クロックは12回、メインカウンタは 1 減っており、プリスケール - // カウントは10回中残り 8回を指していることになる。 + // この実装ではどちらのカウンタも持たず、タイマー終了時刻と現在時刻で + // 管理する。そのためメインカウンタの値はこの時間差から求める。 + // tcr は書き込み値、現在のモードを保持する。 uint8 tcr[4]; // --- --- --- RST AC3 AC2 AC1 AC0 : TACR // --- --- --- RST BC3 BC2 BC1 BC0 : TBCR // --- CC2 CC1 CC0 --- DC2 DC1 DC0 : TCDCR - // tdr はカウンタの設定値。 - // タイマー停止中に TxDR に書き込まれると、initial_tdr に即反映される。 - // タイマー動作中に TxDR に書き込まれると、initial_tdr に反映されるのは - // 次のリロードタイミング。 + // tdr はカウンタの現在値。 uint8 tdr[4]; // initial_tdr はカウントダウン開始時点での TxDR の値。 @@ -115,8 +112,6 @@ struct MFP // initial_tdr は 1..256 の値をとる。 uint initial_tdr[4]; - uint64 timer_start[4]; // タイマー開始時の仮想時刻 - uint8 scr; // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | @@ -189,10 +184,14 @@ class MFPDevice public: MFPDevice(); - ~MFPDevice() override; + virtual ~MFPDevice() override; + void ResetHard() override; void ResetSoft() override; - bool MonitorUpdate() override; + void MonitorUpdate(TextScreen&) override; + + // 割り込みアクノリッジ + int InterruptAcknowledge(); // VDisp 入力 void SetVDisp(bool vdisp); @@ -214,7 +213,7 @@ class MFPDevice uint64 Peek(uint32 addr); private: - bool IsTimerIntrEnable(uint ch) const; + void Reset(); void SetTCR(int ch, uint32 data); uint8 GetTDR(int ch) const; void SetTDR(int ch, uint32 data); @@ -227,8 +226,14 @@ class MFPDevice void SetUDR(uint32 data); // イベントコールバック - void TimerCallback(int arg); - void KeyCallback(int arg); + void TimerCallback(Event& ev); + void KeyCallback(Event& ev); + + // 必要なら割り込みを上げる + void SetInterrupt(uint ch); + + // 割り込み信号線の状態を変える + void ChangeInterrupt(); struct MFP mfp {}; Event event[4] {};