--- nono/lib/mainapp.cpp 2026/04/29 17:05:26 1.1.1.17 +++ nono/lib/mainapp.cpp 2026/04/29 17:05:39 1.1.1.20 @@ -88,6 +88,8 @@ MainApp::ShowHelp(bool all) const printf("usage: %s []\n", getprogname()); p("-c vm directory or configuration file"); p("-f fast mode (same as '-V fast-mode=1')"); + p("--fd[01] specify floppy image (same as '-V fdN-image=' except"); + p(" base directory)"); if (IsGUI()) p("--fontsize fontsize (same as '-V monitor-fontsize=')"); p("-h show brief help message"); @@ -107,6 +109,7 @@ MainApp::ShowHelp(bool all) const p(" set breakpoint. is either 'main'(default) or 'xp'"); p("--bi-exg set instruction breakpoint on 'exg sp,sp'"); p("-C output log to console"); + p("--console-log specify the console output log"); p("-d debugger prompt on startup"); p("-D same as '-V debugger-driver=stdio'"); p("-H human68k console emulation"); @@ -124,7 +127,10 @@ MainApp::ShowHelp(bool all) const enum { OPTstart = 0x80 - 1, OPT_bi_exg, + OPT_console_log, OPT_create_sram, + OPT_fd0, + OPT_fd1, OPT_fontsize, OPT_help, OPT_initrd, @@ -135,7 +141,10 @@ enum { }; static struct option longopts[] = { { "bi-exg", no_argument, NULL, OPT_bi_exg }, + { "console-log", required_argument, NULL, OPT_console_log }, { "create-sram", no_argument, NULL, OPT_create_sram }, + { "fd0", required_argument, NULL, OPT_fd0 }, + { "fd1", required_argument, NULL, OPT_fd1 }, { "fontsize", required_argument, NULL, OPT_fontsize }, { "help", no_argument, NULL, OPT_help }, { "initrd", required_argument, NULL, OPT_initrd }, @@ -327,13 +336,14 @@ MainApp::Init1a(int ac, char *av[]) PANIC("vmtype=%s not configured", vmstr.c_str()); } - // 2. 動的なコンストラクション - if (!pVM->Create()) { + // 2. 動的なコンストラクションその1 + // 3. ログ出力用の EarlyInit + if (!pVM->Create(VM::CreationPhase::First)) { pVM.reset(); return EXIT_FAILURE; } - // 3. 設定を確定。 + // 4. 設定を確定。 // (VM コンストラクタで変数の増減があるのでそれより後、 // Create() でも SCSI パラメータを減らすので、それより後) if (gConfig->Fix() == false) { @@ -354,21 +364,21 @@ MainApp::Init1a(int ac, char *av[]) int MainApp::Init1b() { - // 3.1 設定が確定したので --show-config なら設定内容を表示して終了。 + // 4.1 設定が確定したので --show-config なら設定内容を表示して終了。 if (show_config) { gConfig->Show(show_config - 1); pVM.reset(); return EXIT_SUCCESS; } - // 3.2 ログレベルを設定。コンストラクト後すぐに行う。 + // 4.2 ログレベルを設定。コンストラクト後すぐに行う。 // -L help もここで処理。 if (!ParseLogopt()) { pVM.reset(); return EXIT_FAILURE; } - // 3.3 -X のチェック。 + // 4.3 -X のチェック。 // -L help より後にしないとヘルプが表示できない。 const ConfigItem& itemexec = gConfig->Find("exec-file"); if (exec_file == NULL) { @@ -403,6 +413,13 @@ MainApp::Init1b() } } + // 5. 動的コンストラクションその2 + // ログ出力が出来る代わりにログクラスはもう増やせない。 + if (!pVM->Create(VM::CreationPhase::Second)) { + pVM.reset(); + return EXIT_FAILURE; + } + return PASS; } @@ -413,7 +430,7 @@ MainApp::Init1b() bool MainApp::Init2() { - // 5. VM 初期化。 + // 7. VM 初期化。 if (!pVM->Init()) { return false; } @@ -421,12 +438,12 @@ MainApp::Init2() // メインスレッド名を設定 PTHREAD_SETNAME("Main"); - // 6. スレッド開始 + // 8. スレッド開始 if (!pVM->StartThread()) { return false; } - // 7. 起動時設定の適用 + // 9. 起動時設定の適用 if (!pVM->Apply()) { return false; } @@ -480,6 +497,18 @@ MainApp::ParseOpt(int ac, char *av[]) config_options.emplace_back("fast-mode=1", "-f"); break; + case OPT_fd0: + case OPT_fd1: + { + int fd = c - OPT_fd0; + // 相対パスはカレントディレクトリを起点とする。 + std::string line = string_format("fd%u-image=%s", fd, + AbsPath(optarg).c_str()); + std::string from = string_format("--fd%u", fd); + config_options.emplace_back(line, from); + break; + } + case 'H': human_mode = true; break; @@ -509,10 +538,7 @@ MainApp::ParseOpt(int ac, char *av[]) case 'X': { // 相対パスはカレントディレクトリ起点とする。 - char cwd[PATH_MAX]; - getcwd(cwd, sizeof(cwd)); - std::string path = NormalizePath(optarg, std::string(cwd)); - std::string line = "exec-file=" + path; + std::string line = "exec-file=" + AbsPath(optarg); config_options.emplace_back(line, "-X"); // Human68k モードなら後続を引数にする。 @@ -544,6 +570,12 @@ MainApp::ParseOpt(int ac, char *av[]) debug_breakinst_exg = true; break; + case OPT_console_log: + // この時点ではコンソールを持つ VM かどうかが分からないので + // コンソールのない設定でもエラーを出さない(出せない)。 + console_logfile = optarg; + break; + case OPT_create_sram: create_sram = true; break; @@ -562,10 +594,7 @@ MainApp::ParseOpt(int ac, char *av[]) case OPT_initrd: { // 相対パスはカレントディレクトリを起点とする。 - char cwd[PATH_MAX]; - getcwd(cwd, sizeof(cwd)); - std::string path = NormalizePath(optarg, std::string(cwd)); - std::string line = "exec-initrd=" + path; + std::string line = "exec-initrd=" + AbsPath(optarg); config_options.emplace_back(line, "--initrd"); break; } @@ -657,6 +686,17 @@ MainApp::ParseOpt(int ac, char *av[]) return MainApp::PASS; } +// path を絶対パスにして返す。 +// 相対パスならカレントディレクトリからのパスとする。 +/*static*/ std::string +MainApp::AbsPath(const char *path) +{ + char cwd[PATH_MAX]; + + getcwd(cwd, sizeof(cwd)); + return NormalizePath(optarg, std::string(cwd)); +} + // CPU の機能とかをチェック。 bool MainApp::CheckCPU() @@ -1136,9 +1176,8 @@ MainApp::NormalizePath(const std::string // path を必要なら絶対パスに展開して返す。 // 相対パスは basedir を起点とする。 -std::string -MainApp::NormalizePath(const std::string& path, - const std::string& basedir) const +/*static*/ std::string +MainApp::NormalizePath(const std::string& path, const std::string& basedir) { // 絶対パスならそのまま返す。 if (path[0] == '/') {