--- nono/lib/mainapp.cpp 2026/04/29 17:05:39 1.1.1.20 +++ nono/lib/mainapp.cpp 2026/04/29 17:05:47 1.1.1.22 @@ -16,12 +16,11 @@ #include "monitor.h" #include "mystring.h" #include "mythread.h" -#include "sram.h" +#include "uimessage.h" #include "vm_luna.h" #include "vm_news.h" #include "vm_virt68k.h" #include "vm_x68k.h" -#include #include #include #include @@ -105,9 +104,13 @@ MainApp::ShowHelp(bool all) const if (all) { printf("\n(options for developers)\n"); - p("-b [,][,]"); + p("--b [,][,] (or -b)"); p(" set breakpoint. is either 'main'(default) or 'xp'"); + p("--bi [,][:][,]"); + p(" set instruction breakpoint."); p("--bi-exg set instruction breakpoint on 'exg sp,sp'"); + p("--bv [,][-][,]"); + p(" set vector breakpoint."); p("-C output log to console"); p("--console-log specify the console output log"); p("-d debugger prompt on startup"); @@ -126,9 +129,10 @@ MainApp::ShowHelp(bool all) const // 0x80 から始めておく。 enum { OPTstart = 0x80 - 1, + OPT_bi, OPT_bi_exg, + OPT_bv, OPT_console_log, - OPT_create_sram, OPT_fd0, OPT_fd1, OPT_fontsize, @@ -140,9 +144,11 @@ enum { OPT_show_hostnet, }; static struct option longopts[] = { + { "b", required_argument, NULL, 'b' }, + { "bi", required_argument, NULL, OPT_bi }, { "bi-exg", no_argument, NULL, OPT_bi_exg }, + { "bv", required_argument, NULL, OPT_bv }, { "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 }, @@ -163,13 +169,13 @@ static struct option longopts[] = { // MainApp::PASS .. 実行を継続(通常パス) // EXIT_SUCCESS / EXIT_FAILURE .. この終了コードでアプリケーションを終了 int -MainApp::Init1(bool is_cli_, int ac, char *av[]) +MainApp::Init1(int ac, char *av[], std::string (*conv)(const std::string&)) { int rv; - is_cli = is_cli_; + is_cli = (conv == NULL); - rv = Init1a(ac, av); + rv = Init1a(ac, av, conv); if (rv != MainApp::PASS) { return rv; } @@ -181,7 +187,7 @@ MainApp::Init1(bool is_cli_, int ac, cha // VM の初期化、ステージ1 の前半。 // Config.Fix まで。 int -MainApp::Init1a(int ac, char *av[]) +MainApp::Init1a(int ac, char *av[], std::string (*conv)(const std::string&)) { int rv; @@ -196,15 +202,24 @@ MainApp::Init1a(int ac, char *av[]) return rv; } - // ログ機構は引数処理後なるはや + // モニタマネージャ (VM 作成より前、もしかしたら Config より前?) + pMonitorManager.reset(new MonitorManager()); + gMonitorManager = pMonitorManager.get(); + + // ログ機構は引数処理後なるはや…にしたいがモニタマネージャは必要。 // CLI ならログは常に標準出力へ(も)出力。 // GUI なら -C で指定。 logger.reset(new Logger()); - logger->UseStdout(IsCLI() ? true : log_to_console); + if (IsCLI()) { + logger->UseStdout(true); + } else { + logger->UseStdout(log_to_console); + logger->SetConverter(conv); + } + logger->StartThread(); - // モニタマネージャ (VM 作成より前、もしかしたら Config より前?) - pMonitorManager.reset(new MonitorManager()); - gMonitorManager = pMonitorManager.get(); + // UIMessage は VM 起動前ならどこでもいいはず。 + uimessage.reset(new UIMessage()); // 設定を作成。 // c0. コンストラクタで初期値を用意。 @@ -263,7 +278,9 @@ MainApp::Init1a(int ac, char *av[]) gConfig->Update("ram-size=16", "-S"); gConfig->Update("luna-video-plane=1", "-S"); // ホスト側には干渉しない。 - gConfig->Update("hostcom-driver=none", "-S"); + gConfig->Update("hostcom0-driver=none", "-S"); + gConfig->Update("hostcom1-driver=none", "-S"); + gConfig->Update("hostcom2-driver=none", "-S"); gConfig->Update("hostnet-driver=none", "-S"); } @@ -300,16 +317,6 @@ MainApp::Init1a(int ac, char *av[]) return EXIT_FAILURE; } - // 0.5. VM が確定したところで SRAM 作成。 - if (create_sram) { - if (vmtype == VMType::X68030) { - return CreateSRAM(); - } else { - warnx("--create-sram is only for X68030 mode"); - return EXIT_FAILURE; - } - } - // 1. VM 作成 switch (vmtype) { case VMType::X68030: @@ -443,11 +450,6 @@ MainApp::Init2() return false; } - // 9. 起動時設定の適用 - if (!pVM->Apply()) { - return false; - } - return true; } @@ -566,20 +568,24 @@ MainApp::ParseOpt(int ac, char *av[]) config_options.emplace_back(optarg, "-V"); break; + case OPT_bi: + debug_breakinst.push_back(optarg); + break; + case OPT_bi_exg: debug_breakinst_exg = true; break; + case OPT_bv: + debug_breakvec.push_back(optarg); + break; + case OPT_console_log: // この時点ではコンソールを持つ VM かどうかが分からないので // コンソールのない設定でもエラーを出さない(出せない)。 console_logfile = optarg; break; - case OPT_create_sram: - create_sram = true; - break; - case OPT_fontsize: { auto line = string_format("monitor-fontsize=%s", optarg); @@ -990,33 +996,22 @@ MainApp::SetLogopt1(const std::string& i } return true; } - // "fdd" なら "fdd*" 全部にする - if (name == "fdd") { - for (auto obj : gMainApp.GetObjects()) { - if (strncasecmp(obj->GetName().c_str(), "fdd", 3) == 0) { - obj->SetLogLevel(level); - } - } - return true; - } - // "bankram" も "bankram[01]" 両方にする - if (name == "bankram") { - for (auto obj : gMainApp.GetObjects()) { - if (strncasecmp(obj->GetName().c_str(), "bankram", 7) == 0) { - obj->SetLogLevel(level); - } - } - return true; - } - // "gfpic" も "gfpic*" 全部にする - if (name == "gfpic") { - for (auto obj : gMainApp.GetObjects()) { - if (strncasecmp(obj->GetName().c_str(), "gfpic", 5) == 0) { - obj->SetLogLevel(level); - } - } - return true; - } + + // "" なら "*" 全部に展開する。 +#define EXPAND(key) do { \ + if (name == key) { \ + for (auto obj : gMainApp.GetObjects()) { \ + if (strncasecmp(obj->GetName().c_str(), key, strlen(key)) == 0) \ + obj->SetLogLevel(level); \ + } \ + return true; \ + } \ +} while (0) + EXPAND("bankram"); + EXPAND("fdd"); + EXPAND("gfpic"); + EXPAND("hostcom"); + EXPAND("hostnet"); // エイリアスリストを作る using aliaslist_t = std::vector>; @@ -1208,48 +1203,6 @@ MainApp::NormalizePath(const std::string return newpath; } -// 初回起動時用に SRAM.DAT を作成する。 -// 戻り値は EXIT_SUCCESS / EXIT_FAILURE。 -int -MainApp::CreateSRAM() -{ - char buf[16 * 1024]; - std::string filename; - autofd fd; - int r; - - filename = GetVMDir() + "SRAM.DAT"; - - // 存在確認のため一旦読み込み専用で開いてみる。 - // オープン出来たら何もしない。 - fd = open(filename.c_str(), O_RDONLY); - if (fd >= 0) { - warnx("%s: Already exists", filename.c_str()); - return EXIT_FAILURE; - } - - fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) { - warn("%s: open failed", filename.c_str()); - return EXIT_FAILURE; - } - - memset(&buf[0], 0, sizeof(buf)); - for (int i = 0; i < SRAMDevice::InitialData.size(); i++) { - buf[i] = SRAMDevice::InitialData[i]; - } - - r = write(fd, buf, sizeof(buf)); - if (r < 0) { - warn("%s: write failed", filename.c_str()); - return EXIT_FAILURE; - } - - fd.Close(); - warnx("created %s", filename.c_str()); - return EXIT_SUCCESS; -} - // 現在の VM が指定のケーパビリティを持っているか? bool MainApp::Has(VMCap cap) const