--- nono/vm/fdc.cpp 2026/04/29 17:05:29 1.1.1.13 +++ nono/vm/fdc.cpp 2026/04/29 17:05:38 1.1.1.15 @@ -75,11 +75,17 @@ // OP.SEL.x でドライブごとに有効になる信号 // EJECT, EJECT MASK, LED BLINK, DISK IN, ERR DISK +// ドライブセレクトイネーブルがネゲートされていて、 +// どのドライブも選択されていない状態になったとき、 +// 各入力信号はプルアップされているため、 +// 負論理の信号はすべてネゲート状態となる。 + #include "fdc.h" #include "bitops.h" #include "config.h" #include "dmac.h" #include "fdd.h" +#include "monitor.h" #include "pedec.h" #include "scheduler.h" @@ -96,9 +102,9 @@ FDCDevice::FDCDevice() : inherited(OBJ_FDC) { - monitor.func = ToMonitorCallback(&FDCDevice::MonitorUpdate); + monitor = gMonitorManager->Regist(ID_MONITOR_FDC, this); + monitor->func = ToMonitorCallback(&FDCDevice::MonitorUpdate); // サイズは Create() 時に確定する - monitor.Regist(ID_MONITOR_FDC); } // デストラクタ @@ -122,7 +128,7 @@ FDCDevice::Create() } // モニタサイズはここで決定。FDD は横に2台で、それ以上は縦に伸ばす。 - monitor.SetSize(80, 15 + (ndrive / 2) * 10); + monitor->SetSize(80, 15 + (ndrive / 2) * 10); // vector は面倒なので一旦 unique_ptr[] に確保して // 生ポインタの vector を作る。うーん。 @@ -144,10 +150,6 @@ FDCDevice::Create() bool FDCDevice::Init() { - if (inherited::Init() == false) { - return false; - } - dmac = GetDMACDevice(); pedec = GetPEDECDevice(); @@ -276,13 +278,15 @@ FDCDevice::WritePort(uint32 offset, uint // ドライブコントロールレジスタ putlog(1, "Drive Control <- $%02x", data); - // FDD 割り込みクリア(要実機確認) - pedec->NegateINT(fdd_vector[0]); - uint8 bit = 0x01; for (const auto f : fdd_vector) { + // ドライブセレクタのビットが %1 -> %0 になると動作する。 if (f && bit_falling(drivectrl, data, bit)) { f->SetDriveCtrl(data & 0xe0); + + // FDD 割り込みのクリアは詳細不明だが、とりあえず + // 同じタイミングで動作するようにしておく。 + pedec->NegateINT(f); } bit <<= 1; } @@ -1134,6 +1138,12 @@ FDCDevice::DriveSelect(uint8 drive) fdd = NULL; } + // ドライブセレクト信号線が変わったら READY が変わるかもしれないので + // ポーリングを再開する必要がある。 + if (initialized) { + StartPoll(); + } + // いまのところ LUNA のことは忘れる }