--- nono/vm/fdd.cpp 2026/04/29 17:05:14 1.1.1.1 +++ nono/vm/fdd.cpp 2026/04/29 17:05:18 1.1.1.2 @@ -25,13 +25,34 @@ #define MFM_SECTOR_HEADER (12 + 3 + 1 + 4 + 2 + 22 + 12 + 3 + 1 + 2) #define MFM_TRACK_RAW_SIZE (10416) -// トラックデータ追加 +// +// フロッピーディスクの 1 トラック +// + +// トラックデータの記録開始 +void +FDTrack::Begin() +{ + markpos.push_back(buf.size()); +} + +// トラックデータの記録終了 +void +FDTrack::End() +{ + assert(buf.size() == MFM_TRACK_RAW_SIZE); + + markpos.push_back(buf.size()); +} + +// トラックデータに data を追加 void FDTrack::Append(uint8 data) { buf.push_back(data); } +// トラックデータに data を count 個追加 void FDTrack::Append(uint8 data, int count) { @@ -49,22 +70,6 @@ FDTrack::AppendMark(uint8 data) Append(data); } -// トラックデータの記録開始 -void -FDTrack::Begin() -{ - markpos.push_back(buf.size()); -} - -// トラックデータの記録終了 -void -FDTrack::End() -{ - assert(buf.size() == MFM_TRACK_RAW_SIZE); - - markpos.push_back(buf.size()); -} - void FDTrack::Clear() { @@ -73,20 +78,21 @@ FDTrack::Clear() } +// +// フロッピードライブ +// - +// コンストラクタ FDDDevice::FDDDevice(int unit_) - : inherited("FDD") + : inherited(OBJ_FDD(unit_)) { unit = unit_; - SetName(string_format("FDD%d", unit)); - ClearAlias(); - AddAlias(GetName()); event.func = ToEventCallback(&FDDDevice::EventCallback); event.Regist(GetName()); } +// デストラクタ FDDDevice::~FDDDevice() { } @@ -95,6 +101,13 @@ FDDDevice::~FDDDevice() bool FDDDevice::Init() { + if (inherited::Init() == false) { + return false; + } + + fdc = GetFDCDevice(); + pedec = GetPEDECDevice(); + const std::string keybody = string_format("fd%d-", unit); const std::string imgkey = keybody + "image"; const std::string wikey = keybody + "writeignore"; @@ -105,9 +118,9 @@ FDDDevice::Init() const std::string& filename = itemimg.AsString(); // UI からの通知を受け取るイベントを用意 - gScheduler->ConnectMessage(MessageID::FDD_LOAD(unit), this, + scheduler->ConnectMessage(MessageID::FDD_LOAD(unit), this, ToMessageCallback(&FDDDevice::LoadCallback)); - gScheduler->ConnectMessage(MessageID::FDD_UNLOAD(unit), this, + scheduler->ConnectMessage(MessageID::FDD_UNLOAD(unit), this, ToMessageCallback(&FDDDevice::UnloadCallback)); // オープン前に writeignore をチェック。 @@ -306,7 +319,7 @@ FDDDevice::EventCallback(Event& ev) switch (motor_state) { case READY: - gScheduler->StartEvent(ev); + scheduler->StartEvent(ev); break; case SPIN_UP: @@ -314,7 +327,7 @@ FDDDevice::EventCallback(Event& ev) if (event.time == 16_usec) { motor_state = READY; // READY になったので FDC に通知 - gFDC->ReadyChanged(unit, true); + fdc->ReadyChanged(unit, true); } else { if (event.time < 16_usec) { // オーバーシュート対応 @@ -324,7 +337,7 @@ FDDDevice::EventCallback(Event& ev) } putlog(4, "SPIN_UP next=%uusec", (uint)(event.time / 1_usec)); } - gScheduler->StartEvent(ev); + scheduler->StartEvent(ev); break; case SPIN_DOWN: @@ -334,7 +347,7 @@ FDDDevice::EventCallback(Event& ev) event.time = 0; } else { event.time *= 2; - gScheduler->StartEvent(ev); + scheduler->StartEvent(ev); putlog(4, "SPIN_DOWN next=%uusec", (uint)(event.time / 1_usec)); } break; @@ -397,7 +410,7 @@ FDDDevice::DoMotorOn() VMPANIC("DoMotorOn called on motor_state=%d", (int)motor_state); } - gScheduler->RestartEvent(event); + scheduler->RestartEvent(event); } void @@ -409,14 +422,14 @@ FDDDevice::DoMotorOff() // 物理的には多少モータは慣性回転するはずではあるが、ディスクは // もうないので。 motor_state = STOPPED; - gFDC->ReadyChanged(unit, false); + fdc->ReadyChanged(unit, false); } else if (motor_state == READY) { // 減速に転じる。 // 細かいことは気にせず増速と同様に倍々で減速していくので停止まで // 約 524msec かかる。細かいことは気にしない。 motor_state = SPIN_DOWN; // 定常回転 (READY) ではなくなった - gFDC->ReadyChanged(unit, false); + fdc->ReadyChanged(unit, false); } else if (motor_state == SPIN_UP) { // 細かいことは無視して、減速に転じる。 motor_state = SPIN_DOWN; @@ -424,7 +437,7 @@ FDDDevice::DoMotorOff() VMPANIC("DoMotorOff called on motor_state=%d", (int)motor_state); } - gScheduler->RestartEvent(event); + scheduler->RestartEvent(event); } // ドライブコントロールのセット @@ -456,7 +469,7 @@ FDDDevice::SetDriveCtrl(uint8 data) if (islog(is_blink == false)) { putlogn("LED Blink"); } - blink_start = gScheduler->GetVirtTime(); + blink_start = scheduler->GetVirtTime(); is_blink = true; } else { if (islog(is_blink == true)) { @@ -723,7 +736,7 @@ FDDDevice::LoadDisk(const std::string& p // 変化があれば if (ejected || medium_loaded) { ChangeStatus(); - gPEDEC->AssertINT(this); + pedec->AssertINT(this); // 通知 MediaChanged(); } @@ -754,7 +767,7 @@ FDDDevice::UnloadDisk_internal() return false; } - gPEDEC->AssertINT(this); + pedec->AssertINT(this); Clear(); @@ -792,7 +805,7 @@ void FDDDevice::LoadDiskUI(const std::string& pathname_) { new_pathname = pathname_; - gScheduler->SendMessage(MessageID::FDD_LOAD(unit)); + scheduler->SendMessage(MessageID::FDD_LOAD(unit)); } // メディアを排出する。 @@ -800,7 +813,7 @@ FDDDevice::LoadDiskUI(const std::string& void FDDDevice::UnloadDiskUI(bool force) { - gScheduler->SendMessage(MessageID::FDD_UNLOAD(unit), force); + scheduler->SendMessage(MessageID::FDD_UNLOAD(unit), force); } // メディア挿入メッセージコールバック @@ -830,7 +843,7 @@ FDDDevice::GetAccessLED() const // 点滅状態はここで作成。 // 点滅開始から 0.5秒は点灯、次の 0.5秒を消灯とする。 // XXX 間隔は適当 - uint64 time = gScheduler->GetVirtTime() - blink_start; + uint64 time = scheduler->GetVirtTime() - blink_start; time %= 1_sec; if (time < 500_msec) { return LED::GREEN;