--- nono/vm/mfp.cpp 2026/04/29 17:05:14 1.1.1.13 +++ nono/vm/mfp.cpp 2026/04/29 17:05:17 1.1.1.14 @@ -15,16 +15,10 @@ #include "scheduler.h" #include "x68kkbd.h" -// グローバル参照用 -MFPDevice *gMFP; - // コンストラクタ MFPDevice::MFPDevice() - : inherited("MFP") + : inherited(OBJ_MFP) { - devaddr = baseaddr; - devlen = 0x2000; - for (int ch = 0; ch < event.size(); ch++) { event[ch].dev = this; event[ch].func = ToEventCallback(&MFPDevice::TimerCallback); @@ -45,7 +39,20 @@ MFPDevice::MFPDevice() // デストラクタ MFPDevice::~MFPDevice() { - gMFP = NULL; +} + +// 初期化 +bool +MFPDevice::Init() +{ + if (inherited::Init() == false) { + return false; + } + + interrupt = GetInterruptDevice(); + keyboard = dynamic_cast(GetKeyboard()); + + return true; } // リセット @@ -71,9 +78,9 @@ MFPDevice::ResetHard(bool poweron) // All timers are stopped. for (auto& ev : event) { - gScheduler->StopEvent(ev); + scheduler->StopEvent(ev); } - gScheduler->StopEvent(key_event); + scheduler->StopEvent(key_event); // USART RX and TX are disabled. // SO line is placed in HighZ. @@ -95,7 +102,7 @@ MFPDevice::Read(uint32 offset) { uint8 data; - gMPU->AddCycle(24); // InsideOut p.135 + mpu->AddCycle(24); // InsideOut p.135 switch (offset) { case MFP::GPIP: @@ -182,7 +189,7 @@ MFPDevice::Read(uint32 offset) uint64 MFPDevice::Write(uint32 offset, uint32 data) { - gMPU->AddCycle(24); // InsideOut p.135 + mpu->AddCycle(24); // InsideOut p.135 switch (offset) { case MFP::GPIP: @@ -586,11 +593,11 @@ MFPDevice::SetTCR(int ch, uint32 data) // していたが、イベントを停止すると求められなくなるので、イベント // 停止前に求めておく。 uint64 period = prescale_ns[prev]; - uint64 now = gScheduler->GetVirtTime(); + uint64 now = scheduler->GetVirtTime(); mfp.tdr[ch] = ((event[ch].vtime - now) + period - 1) / period; // でイベント停止 - gScheduler->StopEvent(event[ch]); + scheduler->StopEvent(event[ch]); return; } else if (prev == 8) { // イベントカウントモードから停止しても何も起きないはず @@ -608,7 +615,7 @@ MFPDevice::SetTCR(int ch, uint32 data) uint64 period = prescale_ns[mfp.tcr[ch]]; uint count = mfp.tdr[ch] ?: 256; event[ch].time = period * count; - gScheduler->RestartEvent(event[ch]); + scheduler->RestartEvent(event[ch]); putlog(1, "Timer-%c Start Delay mode(%u x %u.%uusec)", ch + 'A', @@ -648,7 +655,7 @@ MFPDevice::GetTDR(int ch) const // プリスケーラと終了時刻から算出。 uint64 period = prescale_ns[tcr]; - uint64 now = gScheduler->GetVirtTime(); + uint64 now = scheduler->GetVirtTime(); return ((event[ch].vtime - now) + period - 1) / period; } else { @@ -700,7 +707,7 @@ MFPDevice::TimerCallback(Event& ev) // time が1タイムアウトパルス期間 uint64 period = prescale_ns[mfp.tcr[ch]]; ev.time = period * (mfp.tdr[ch] ?: 256); - gScheduler->RestartEvent(ev); + scheduler->RestartEvent(ev); } // HSync 入力 @@ -840,8 +847,7 @@ MFPDevice::ClearBF() // 実際のハードウェアでは、キーボードが本体 MFP が Ready になるのを待って // いるが、それに相当。 // システムポートの KEYCTRL はキーボード側で処理している。 - X68030Keyboard *x68kkbd = dynamic_cast(gKeyboard); - x68kkbd->Ready(); + keyboard->Ready(); } // UDR への書き込み @@ -849,7 +855,7 @@ void MFPDevice::SetUDR(uint32 data) { if ((mfp.tsr & MFP::TSR_TE)) { - gKeyboard->Command(data); + keyboard->Command(data); } } @@ -898,7 +904,7 @@ MFPDevice::Rx(uint32 data) // ので、まだ Buffer Full は立てない。 key_event.code = data; - gScheduler->RestartEvent(key_event); + scheduler->RestartEvent(key_event); } // キーボードからのデータが受信し終わった頃に呼ばれるイベント。 @@ -953,7 +959,7 @@ MFPDevice::ChangeInterrupt() // ペンディングの割り込みがあればアサートされる、 // IPR をクリアするか IMR をクリアすると /IRQ はネゲートされる。 bool irq = ((mfp.ipr.w & mfp.imr.w) != 0); - gInterrupt->ChangeINT(this, irq); + interrupt->ChangeINT(this, irq); } // 割り込みアクノリッジ