--- nono/vm/scsibus.h 2026/04/29 17:04:53 1.1.1.5 +++ nono/vm/scsibus.h 2026/04/29 17:05:33 1.1.1.10 @@ -4,13 +4,9 @@ // Licensed under nono-license.txt // +// // SCSI バス - -#pragma once - -#include "device.h" -#include "scheduler.h" -#include "scsi.h" +// // フェーズ遷移についてのメモ。 // @@ -96,21 +92,44 @@ // TransferReqCB <-〜〜〜 Event 〜〜〜〜〜〜〜〜〜〜〜〜+ // +#pragma once + +#include "event.h" +#include "scsi.h" + +class SCSIDevice; +class SCSIDisk; +class SCSIHostDevice; +class SCSITarget; // // SCSI バス // class SCSIBus : public Device { + using inherited = Device; + + public: + // (1<& GetConnectedDevices() const { + return connected_devices; + } + + // ターゲットデバイス取得 (ROM エミュレーション/UI用) + SCSITarget *GetTarget(int id) const { return target[id].get(); } + // 現在選択中のターゲットを返す、なければ NULL を返す。(モニタ用) - SCSIDevice *GetConnectedTarget() const { + SCSITarget *GetSelectedTarget() const { if (0 <= target_id && target_id < 8) { - return device[target_id]; + return target[target_id].get(); } return NULL; } @@ -166,7 +199,12 @@ class SCSIBus : public Device void SetOneshotReqWait(uint64 nsec) { req_wait += nsec; } private: - void BusFree(int id); + DECLARE_MONITOR_CALLBACK(MonitorUpdate); + + // connected_devices を更新する。 + void MakeConnectedDevices(); + + void BusFree(uint id); void SelectionStart(Event& ev); void Selected(Event& ev); void SelectionAck(Event& ev); @@ -196,26 +234,30 @@ class SCSIBus : public Device // 次の REQ アサートに入れるウェイト [nsec] uint64 req_wait {}; + // 設定ファイルに使われるこのホストデバイスを示す接頭語。 + // ("spc0" とか) + const char *config_name {}; + // 実際のバスではそんなことはないが、ここではバスがイニシエータと // ターゲットの ID を把握している。どちらも非選択状態なら -1。 int init_id {}; int target_id {}; - // SCSI デバイス(イニシエータも含む)。非接続なら NULL + // SCSI ターゲット (所有)。イニシエータは含まない。 + std::unique_ptr target[8] /*{}*/; + + // SCSI デバイス(イニシエータも含む)。非接続なら NULL。 // 所有権を持たない。 SCSIDevice *device[8] {}; + // 接続中のデバイス(イニシエータ含む)を ID 順に並べたリスト。 + std::vector connected_devices {}; + + // 親(イニシエータ) + SCSIHostDevice *parent {}; + // イベント - Event event {}; -}; + Event event { this }; -// (1<