--- nono/vm/device.h 2026/04/29 17:04:55 1.1.1.10 +++ nono/vm/device.h 2026/04/29 17:05:10 1.1.1.12 @@ -4,10 +4,13 @@ // Licensed under nono-license.txt // +// +// デバイスの基本クラスなど +// + #pragma once #include "object.h" -#include #if BYTE_ORDER == LITTLE_ENDIAN #define HB(addr) ((addr) ^ 1) @@ -34,69 +37,74 @@ class Device : public Object // gConfig の内部変数の追加はここ(か2.の動的コンストラクション)で // 行うこと。この時点ですでに gConfig の設定内容の参照は可能だが、 // エラーが出るものはここではなく Init() で処理すること。 - // putlog() は使える。厳密には MPU コンストラクタ以降で使えるが - // MPU より前は BusErrDevice しかおらずこいつは putlog() しないので。 + // putmsg() は使えない。 // // 2. Create() ... 動的コンストラクション // 必要なら設定ファイルによって可変なオブジェクトのコンストラクトを行う。 - // 例えば SCSI ドライブなどが該当する。 - // ここでも gConfig の参照および内部変数の登録は可能。 + // 例えば SCSI ドライブなどが該当する。ここでも gConfig の参照および + // 内部変数の登録は可能、putmsg() は使えない。 // // 3. parse_logopt() ... -L オプションの処理 - // この時点で Object 由来のオブジェクトはすべて出揃っている必要がある。 + // この時点でログの割り当てを受ける Object 由来のオブジェクトはすべて + // 出揃っている必要がある。 // またここで --show-config も行うため、この時点で gConfig の内容は確定し // 以降 gConfig の変更は出来ない。 // - // 3.1. InitDriver() ... NetDriver を選択 - // NetDriver の選択はログが準備出来た後で行いたいが、スレッドの動く - // Init() よりは前で行いたいのでここで特別扱いしている。 - // - // 3.2. ParseMonitors() ... -M オプションの処理 + // (4.) ParseMonitors() ... -M オプションの処理 // (GUI 版のみ) この時点で Monitor がすべて登録されている必要がある。 // - // 4. Init() ... 初期化 - // ここでは ROM などのファイルの読み込み、またスレッドの起動などを行う。 - // Object 由来のオブジェクトはすべて揃っているため、相互にアクセス可能。 - // ただしその際の依存関係については、vm.cpp (や xiospace.cpp) 内の - // コンストラクタの順序で調整すること (循環参照不可)。 + // 5. Init() ... 初期化 + // この時点で Object 由来のオブジェクトはすべて出揃っており、ログレベル + // も確定しているのでこれ以降 putmsg() は使える。 + // gConfig の設定項目のうち内容によってエラー終了する可能性があるものは + // ここで処理する。 + // ここでは Object 同士を相互にアクセス可能。ただしその際の依存関係に + // ついては、vm.cpp (や xiospace.cpp) 内のコンストラクタの順序で調整 + // すること (循環参照不可)。 + // ホストデバイスの個別ドライバはここで起動する。本来 Create() で行いたい + // ところだが、ネットワークドライバの選択などは複雑なので putmsg() を + // 使いたい。そうするとここまで遅延せざるを得ない。そのため 3. を過ぎて + // からオブジェクトが増えることになるが、個別ドライバは新たなログ名を + // 増やさず、ホストドライバのログレベルを継承するため、ぎりぎり大丈夫。 + // スレッドはまだ起動していない。 // - // 5. Apply() ... 動的設定の適用 + // 6. StartThread() ... スレッド起動 + // + // 7. Apply() ... 動的設定の適用 // 実行中に変更可能なパラメータもここで一度適用する。 + // ここで適用するのは実行中に変更可能なパラメータのみ。 + // 適用内容を表示したい時は putlog(1) が妥当か。 // - // 6. PowerOn(), ResetHard() ... VM 起動 + // 8. ResetHard(true) ... 電源オン // 動的コンストラクション。 - // この時点で設定ファイルは読める。putlog() は使えない。 - // 成功すれば true を返す、 - // 失敗なら warn()/warnx() でエラーメッセージを表示して false を返すこと。 + // 成功すれば true を返す。失敗なら warn() 系、あるいは gConfig->Err() + // 系でエラーメッセージを表示して false を返すこと。 virtual bool Create(); // 初期化。 - // 起動時設定の適用、ファイルの読み込み、スレッド作成を行う。 - // Object 由来のオブジェクトはすべて揃っており、設定ファイルは読める。 - // putlog() も使える。 - // 成功すれば true を返すこと。 - // 失敗なら warn()/warnx()、あるいは ConfigItem::Err() 系 (実態は warnx) - // でエラーメッセージを表示して false を返すこと。 + // 成功すれば true を返す。失敗なら warn() 系、あるいは gConfig->Err() + // 系でエラーメッセージを表示して false を返すこと。 virtual bool Init(); // 現在の設定を VM に反映させる。 - // ここで適用するのは実行中に変更可能なパラメータのみ。 - // 適用内容を表示したい時は putlog(1) が妥当か。 - // 成功すれば true を返すこと。 - // 失敗なら warn()/warnx()、あるいは gConfig->Err() 系 (実態は warnx) で - // エラーメッセージを表示して false を返すこと。 + // 成功すれば true を返す。失敗なら warn() 系、あるいは gConfig->Err() + // 系でエラーメッセージを表示して false を返すこと。 // といっても false が返されたらどうするんだろうか。 virtual bool Apply(); - virtual bool PowerOn(); - virtual bool PowerOff(); - - // ResetHard() はこのデバイスのリセット。 + // 電源オンもしくはリセット。 + // true なら電源オン、false ならリセット。 // このデバイスがどのタイミングでリセットされるかは VM による。 // X68030 なら vm_x68k.cpp 内のコメント参照。 // LUNA は詳細不明。 - virtual void ResetHard(); + virtual void ResetHard(bool poweron); + + // 電源オフ + virtual void PowerOff(); + + // ログ出力 + void putlogn(const char *fmt, ...) const override __printflike(2, 3); }; class IODevice : public Device @@ -170,14 +178,12 @@ class NopIODevice : public IODevice class DMACDevice; class Human68k; class InterruptDevice; -class IODevice; class LunafbDevice; class MK48T02Device; class MPUDevice; class SCSIDevice; -class SCSIHD; +class SCSIDisk; class SCSITarget; -extern std::vector gDevices; -extern std::unique_ptr gBusErr; -extern std::unique_ptr gNopIO; +extern BusErrDevice *gBusErr; +extern NopIODevice *gNopIO;