--- nono/vm/scsidev.h 2026/04/29 17:04:29 1.1.1.1 +++ nono/vm/scsidev.h 2026/04/29 17:04:39 1.1.1.4 @@ -1,12 +1,14 @@ // // nono -// Copyright (C) 2020 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // // SCSI デバイス共通部分 #pragma once +#include "mappedfile.h" #include "scsibus.h" // IODevice (SPCDevice の親になるため) @@ -31,7 +33,7 @@ class SCSIDevice : public IODevice { public: SCSIDevice(); - virtual ~SCSIDevice(); + ~SCSIDevice() override; // バスに接続 (SCSIBus::Attach から呼ばれる) void Attach(SCSIBus *bus_, int id) { @@ -114,18 +116,25 @@ class SCSIHostDevice : public SCSIDevice { public: SCSIHostDevice(); - virtual ~SCSIHostDevice(); + ~SCSIHostDevice() override; - virtual bool Create(); - virtual bool Init(); + bool Create() override; + bool Init() override; // 設定ファイル上のこのホストデバイスを示す接頭語を返す const char *GetConfigName() const { return config_name; } // バスフリーになった (全員に通知される) - virtual void BusFreeCB(int id); + void BusFreeCB(int id) override; + + // ターゲットデバイス取得 (ROM エミュレーション用) + SCSITarget *GetTarget(int id) const { return target[id].get(); } protected: + // 設定ファイルに使われるこのホストデバイスを示す接頭語を設定する + // (ここで設定項目を Add するので、継承クラスのコンストラクタから呼ぶこと) + void SetConfigName(const char *name); + // 設定ファイルに使われるこのホストデバイスを示す接頭語。 // ("spc0" とか) const char *config_name = NULL; @@ -164,11 +173,11 @@ class SCSIHostDevice : public SCSIDevice // class SCSITarget : public SCSIDevice { - typedef SCSIDevice inherited; + using inherited = SCSIDevice; friend class SCSICmdModeSelect6; public: SCSITarget(SCSIHostDevice *h, int id, std::vector& inq); - virtual ~SCSITarget(); + ~SCSITarget() override; // デバイス種別を返す (主にデバッグ表示用) SCSI::DevType GetDevType() const { return devtype; } @@ -179,19 +188,36 @@ class SCSITarget : public SCSIDevice // 現在のコマンド列を返す (モニタ用) std::vector GetCmdSeq() const { return cmdseq; } + // 論理ブロック長 + uint32 GetBlocksize() const { return blocksize; } + void SetBlocksize(uint32 val) { blocksize = val; } + + // センスキーと ASC/ASCQ + uint8 sensekey {}; + uint16 senseasc {}; + + // センスキーをクリア + void ClearSense() { + sensekey = 0; + senseasc = 0; + } + // SCSIBus コールバック + // バスリセットされた (全員に通知される) + void BusResetCB() override; + // セレクションで選択された (ターゲットのみ通知される) - virtual void SelectionCB(); + void SelectionCB() override; // 情報転送フェーズを開始する (ターゲットのみ通知される) - virtual void StartTransferCB(); + void StartTransferCB() override; // 情報転送フェーズで1バイト送受信が進んだ (ターゲットのみ通知される) - virtual void TransferCB(); + void TransferCB() override; // 情報転送フェーズ(マニュアル転送)で ACK を下げた (ターゲットのみ通知) - virtual void TransferAckCB(); + void TransferAckCB() override; protected: // デバイス種別 @@ -229,23 +255,31 @@ class SCSITarget : public SCSIDevice // class SCSIHD : public SCSITarget { - typedef SCSITarget inherited; + using inherited = SCSITarget; friend class SCSICmdRead6; friend class SCSICmdWrite6; friend class SCSICmdReadCapacity; friend class SCSICmdRead10; public: SCSIHD(SCSIHostDevice *h, int id); - virtual ~SCSIHD(); + ~SCSIHD() override; - virtual bool Init(); - virtual void DispatchCmd(); + bool Init() override; + void DispatchCmd() override; + + // このディスクをディスクイメージだと思うとして (いや実際そうだけど) + // 先頭から start バイト目から len バイト読み出して返す。 + // 単位はセクタではなくバイトなことに注意。 + // (エミュレータ特権アクセス) + bool PeekImage(void *buf, uint32 start, uint32 len) const; private: - int fd = 0; - uint8 *mem = NULL; - size_t memlen = 0; + MappedFile file {}; + uint8 *mem {}; bool writeprotect = false; + // ディスクイメージ長を取得。 + off_t GetSize() const { return file.GetMemSize(); } + static std::vector inquiry_data; };