--- nono/vm/vm.h 2026/04/29 17:04:50 1.1.1.6 +++ nono/vm/vm.h 2026/04/29 17:05:13 1.1.1.10 @@ -4,32 +4,25 @@ // Licensed under nono-license.txt // +// +// VM (基本クラス) +// + #pragma once #include "device.h" -// VM 種別 -enum vmtype_t { - VMTYPE_NONE = 0, - VMTYPE_X68030, - VMTYPE_LUNA1, - VMTYPE_RXZ, // Human68k .r .x .z console emulation - VMTYPE_LUNA88K, -}; -// VM 種別 (ビットマスク表現) -enum vmf_t { - VMF_NONE = 0, - VMF_X68030 = (1 << VMTYPE_X68030), - VMF_LUNA1 = (1 << VMTYPE_LUNA1), - VMF_RXZ = (1 << VMTYPE_RXZ), - VMF_LUNA88K = (1 << VMTYPE_LUNA88K), - - VMF_X68K = VMF_X68030 | VMF_RXZ, - VMF_LUNA = VMF_LUNA1 | VMF_LUNA88K, - VMF_M68K = VMF_X68K | VMF_LUNA1, - VMF_M88K = VMF_LUNA88K, - VMF_ALL = 0xffffffff, -}; +// ヘッダの依存関係を減らすための細工。 +// o pNAME はメンバ変数としてヘッダで宣言してあるが、vm*.h で各デバイスヘッダ +// を include したくないので、派生型ではなく Device* の unique_ptr にしたい。 +// o gNAME は各デバイスヘッダが持つ派生型のグローバルポインタ。 +// ベース型ではなく派生型で参照したい。また使いたい人が使いたいヘッダだけを +// include すれば済むよう、vm*.h とは切り離したい。 +#define NEWDV(NAME, NEW_CTOR) do { \ + __CONCAT(p,NAME).reset(NEW_CTOR); \ + __CONCAT(g,NAME) = \ + (decltype(__CONCAT(g,NAME)))(__CONCAT(p,NAME).get()); \ +} while (0) class VM { @@ -46,42 +39,36 @@ class VM // 初期化 virtual bool Init(); + // スレッド開始 + bool StartThread(); + // 設定の適用 bool Apply(); - // 電源ボタンを押す。 - // XXX この辺はもうちょっと検討したほうがいい - virtual void PowerButton() = 0; - - // 電源ボタンの状態を取得する。 - // モーメンタリスイッチの場合は常に false。 - virtual bool IsPowerButton() const { return false; } + // ブートページを ROM に切り替える + void SwitchBootPageToROM(Device *parent) { SwitchBootPage(parent, true); } + // ブートページを RAM に切り替える + void SwitchBootPageToRAM(Device *parent) { SwitchBootPage(parent, false); } - // VM の全デバイスの電源をオフ - bool DevicePowerOff(); - - // VM 電源オフ時のコールバックを設定する。(GUI から呼ばれる) - void SetPowerOffCallback(void (*callback)()); - - // 外部リセットボタンを押す。 - void ResetButton() { ResetHard(); } - - // ハードウェアリセット - void ResetHard(); - - // MPU の RESET 命令によるリセット - virtual void ResetByMPU() { } - - // BusErr デバイスを取得する - BusErrDevice *GetBusErrDevice() const { return buserr.get(); } + // MPU の RESET 命令によるリセット (機種ごとに異なるため) + virtual void ResetByMPU(); protected: - // VM の全デバイスの電源をオン - bool DevicePowerOn(); - - std::unique_ptr buserr {}; + // ブートページを切り替える (内部用) + virtual void SwitchBootPage(Device *parent, bool isrom); - void (*poweroff_callback)() {}; + std::unique_ptr pBusErr {}; + std::unique_ptr pDebugger {}; + std::unique_ptr pInterrupt {}; + std::unique_ptr pKeyboard {}; + std::unique_ptr pMPU {}; + std::unique_ptr pNMI {}; + std::unique_ptr pPower {}; + std::unique_ptr pRenderer {}; + std::unique_ptr pRAM {}; + std::unique_ptr pScheduler {}; + std::unique_ptr pSignalThread {}; + std::unique_ptr pSync {}; }; -extern std::unique_ptr gVM; +extern VM *gVM;