|
|
nono 1.7.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// CLI/GUI 共通のメイン部分
//
#pragma once
#include "header.h"
#include <vector>
class Config;
class Logger;
class MonitorManager;
class Object;
class ThreadManager;
class UIMessage;
class VM;
// VM 種別
enum class VMType {
NONE = 0,
X68030,
LUNA1,
LUNA88K,
NEWS,
VIRT68K,
};
// VM ケーパビリティ (ビットマスク表現)
enum class VMCap : uint32 {
NONE = 0,
X68030 = (1U << (int)VMType::X68030),
LUNA1 = (1U << (int)VMType::LUNA1),
LUNA88K = (1U << (int)VMType::LUNA88K),
NEWS = (1U << (int)VMType::NEWS),
VIRT68K = (1U << (int)VMType::VIRT68K),
LUNA = VMCap::LUNA1 | VMCap::LUNA88K,
M68K = VMCap::X68030 | VMCap::LUNA1 | VMCap::NEWS | VMCap::VIRT68K,
M88K = VMCap::LUNA88K,
ALL = 0xffffffff,
};
inline VMCap operator|(VMCap a, VMCap b) {
return static_cast<VMCap>(static_cast<uint32>(a) | static_cast<uint32>(b));
}
class MainApp
{
public:
// Init() の戻り値
static const int PASS = -1; // 実行を継続
// CPU のバインド方法。
// o Neutral は何もしない。
// o Binding は、Heavy スレッドを高性能コアにバインドする。
// Light スレッドは
// 高性能コアが 3個以上あれば、バインドしない (OS に任せる)。
// 高性能コアが 2個以下なら、低性能コアにバインドする
enum class AffinityPolicy {
Neutral,
Binding,
};
public:
MainApp();
~MainApp();
void Dispose();
// 初期化 (ステージ1)
int Init1(int ac, char *av[], std::string (*conv)(const std::string&));
// 初期化 (ステージ2)
bool Init2();
// VM 種別を返す。
// (Config が持っているのは文字列)
VMType GetVMType() const { return vmtype; }
// VM 種別を文字列で返す。"luna" とか。
const std::string& GetVMTypeStr() const { return vmstr; }
// たいていは、この機種か?で調べたいことが多いので。
bool IsX68030() const { return (GetVMType() == VMType::X68030); }
bool IsLUNA1() const { return (GetVMType() == VMType::LUNA1); }
bool IsLUNA88K() const { return (GetVMType() == VMType::LUNA88K); }
bool IsNEWS() const { return (GetVMType() == VMType::NEWS); }
bool IsVIRT68K() const { return (GetVMType() == VMType::VIRT68K); }
// 現在の VM が指定のケーパビリティを持っているか?
bool Has(VMCap cap) const;
// VM 機種名を返す。こっちが "LUNA-I" とかで表示用。
const char *GetVMName() const;
// VM ディレクトリを返す
const std::string& GetVMDir() const { return vmdir; }
// ファイル名から適切なフルパスを検索。
std::string SearchFile(const std::string& name) const;
// 指定の path を正規化(展開)して返す。
// path が絶対パスならそのまま返す。
// path が '~' から始まっていればホームディレクトリからの相対パス、
// それ以外なら VM ディレクトリからの相対パスとみなして展開する。
std::string NormalizePath(const std::string& path) const;
// オブジェクト登録
void RegistObject(Object *obj);
// オブジェクト削除
void UnregistObject(Object *obj);
// オブジェクトのリストを返す
const std::vector<Object *>& GetObjects() const { return objects; }
// 指定のオブジェクトを返す。こっちは、なければ NULL を返す。
Object *FindObject(uint id) const;
// 指定のオブジェクトを返す。こっちは、なければ assert する。
Object *GetObject(uint id) const;
// 指定のオブジェクトを型 T* にキャストして返す。
// オブジェクトがないかキャストできなければ NULL を返す。
template <typename T>
T *FindObject(uint id) const {
return dynamic_cast<T *>(FindObject(id));
}
// 指定のオブジェクトを型 T* にキャストして返す。
// オブジェクトがないかキャストできなければ assert する。
template <typename T>
T *GetObject(uint id) const {
auto dev = FindObject<T>(id);
assert(dev);
return dev;
}
// ログレベルを設定する。
static bool SetLogopt(const std::vector<std::string>&, std::string *errmsg);
// ログ名の一覧を表示する
static std::vector<std::string> GetLogNames();
// list を一覧表示をする
static void ShowHelpList(FILE*, const std::vector<std::string>& list);
// Logger を返す
Logger *GetLogger() const { return logger.get(); }
// ThreadManager を返す
ThreadManager *GetThreadManager() const { return threadmanager.get(); }
// UIMessage を返す
UIMessage *GetUIMessage() const { return uimessage.get(); }
public:
// CLI/GUI 区別
bool IsCLI() const { return is_cli; }
bool IsGUI() const { return !is_cli; }
// -b(--b): ブレークポイント "[<cpu>,]<addr>[,<skip>]"
std::vector<std::string> debug_breakaddr {};
// --bi: 命令ブレークポイント "[<cpu>,]<inst>[:<mask>][,<skip>]"
std::vector<std::string> debug_breakinst {};
// --bv: ベクタブレークポイント "[<cpu>,]<vec1>[-<vec2>][,<skip>]"
std::vector<std::string> debug_breakvec {};
// --bi-exg (とりあえず)
bool debug_breakinst_exg {};
// --console-log: コンソールデバイスの出力ログ。
const char *console_logfile {};
// -d: 起動時にデバッガで停止
bool debug_on_start {};
// -H: 内蔵 Human68k 風を組み込む。-X による実行ファイル名が必要。
bool human_mode {};
// -M: モニタ名
std::string monitor_opt {};
// -M: 内蔵 MSX-DOS 風を組み込む。-X による実行ファイル名が必要。
bool msxdos_mode {};
// -X: ホスト実行ファイル名とその引数
const char *exec_file {};
std::string exec_arg {};
// AVX2 を使うかどうか。ホスト CPU 調査と設定ファイル反映後の値。
bool enable_avx2 {};
// AVX2 をホストがサポートしているかどうか。(こっちは情報表示用)
bool detect_avx2 {};
// NEON を使うかどうか。ホスト CPU 調査の設定ファイル反映後の値。
bool enable_neon {};
// NEON をホストがサポートしているかどうか。(こっちは情報表示用)
bool detect_neon {};
// CPU のバインド方法。
AffinityPolicy affinity_policy {};
// 要素数がコア数。高性能コアのところが true。
std::vector<bool> fastcore {};
// ログ表示用
std::unique_ptr<Object> hostcpu /*{}*/;
private:
// 初期化ステージ1 の下請け。
int Init1a(int, char *[], std::string (*conv)(const std::string&));
int Init1b();
// path を絶対パスにして返す。
// 相対パスならカレントディレクトリからのパスとする。
static std::string AbsPath(const char *path);
// path を正規化して返す (下請け)。
// path が相対パスなら basedir を起点とする。
static std::string NormalizePath(const std::string& path,
const std::string& basedir);
// ヘルプメッセージを表示する
void ShowHelp(bool all) const;
// バージョンを表示する
void ShowVersion() const;
// 引数を処理する
int ParseOpt(int ac, char *av[]);
// CPU の機能をチェックする。
bool CheckCPU();
// CPU のアフィニティを調べる。
bool CheckCPUAffinity();
// CPU 番号リスト文字列を処理する。
std::string ParseCPUList(const std::string& input);
// opt を logopt に追加する (-L オプション用)
void AddLogopt(const char *opt);
// -L オプションを処理する
bool ParseLogopt();
// 早期版
void ParseLogoptEarly();
// ログレベル1つを設定する。
static bool SetLogopt1(const std::string&, std::string *errmsg);
// コンパイルされている host netdriver の一覧を表示
void ShowHostnet() const;
// CLI/GUI 区別
bool is_cli {};
// ログ
std::unique_ptr<Logger> logger /*{}*/;
// UIMessage
std::unique_ptr<UIMessage> uimessage /*{}*/;
// 全オブジェクトへのポインタのリスト (所有はしていない)
std::vector<Object*> objects {};
// VM
std::unique_ptr<VM> pVM /*{}*/;
// 設定項目
std::unique_ptr<Config> pConfig /*{}*/;
// VM 種別
VMType vmtype {};
std::string vmstr {};
// スレッドマネージャ
std::unique_ptr<ThreadManager> threadmanager /*{}*/;
// モニタマネージャ
std::unique_ptr<MonitorManager> pMonitorManager /*{}*/;
// -c: VM ディレクトリ or 設定ファイル
std::string vmdir {};
std::string vmfile {};
// -C: ログをコンソールに出力
bool log_to_console {};
// -L: ログ指定文字列
std::string logopt {};
// --perf: パフォーマンス測定モード
bool opt_perf {};
// --show-config: 設定内容を表示 (1なら通常、2ならall)
int show_config {};
// -V: パラメータ指定
std::vector<std::pair<std::string, std::string>> config_options {};
};
// グローバルインスタンス
extern MainApp gMainApp;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.