--- nono/lib/config.cpp 2026/04/29 17:05:15 1.1.1.12 +++ nono/lib/config.cpp 2026/04/29 17:05:22 1.1.1.14 @@ -45,7 +45,15 @@ Config::Config() Add("dipsw-serial", "", VMCap::LUNA | VMCap::NEWS); // MAC アドレス - Add("ethernet-macaddr", "auto", VMCap::LUNA | VMCap::NEWS); + Add("ethernet0-macaddr", "auto"); + Add("ethernet1-macaddr", "auto", VMCap::X68030); + AddAlias("ethernet-macaddr", "ethernet0-macaddr"); + + // 実行ファイル(-X) + Add("exec-file"); + Add("exec-arg", "", VMCap::LUNA | VMCap::X68030); + // RAMDISK (--initrd) + Add("exec-initrd", "", VMCap::VIRT68K); // X68030 の拡張メモリサイズ Add("extram-size", "0", VMCap::X68030); @@ -65,27 +73,43 @@ Config::Config() // 高速モード。 Add("fast-mode", "0"); + // ホスト CPU アクセラレーション。 + Add("host-avx2", "auto"); + // シリアルポートのホスト側設定 Add("hostcom-driver", "none"); Add("hostcom-fallback", 0); Add("hostcom-tcp-port", 9998); // キーボードの入力モード - Add("hostkbd-input", "char"); + Add("hostkbd-input", "char", VMCap::LUNA | VMCap::X68030); // ネットワークのホスト側設定。 - Add("hostnet-driver", "auto"); - Add("hostnet-fallback", 0); - Add("hostnet-afpacket-ifname", "auto"); - Add("hostnet-bpf-ifname", "auto"); - Add("hostnet-tap-devpath", "auto"); + // (0 と 1 で -driver の初期値が違う) + Add("hostnet0-driver", "auto"); + Add("hostnet0-fallback", 0); + Add("hostnet0-afpacket-ifname", "auto"); + Add("hostnet0-bpf-ifname", "auto"); + Add("hostnet0-tap-devpath", "auto"); + + Add("hostnet1-driver", "none", VMCap::X68030); + Add("hostnet1-fallback", 0, VMCap::X68030); + Add("hostnet1-afpacket-ifname", "auto", VMCap::X68030); + Add("hostnet1-bpf-ifname", "auto", VMCap::X68030); + Add("hostnet1-tap-devpath", "auto", VMCap::X68030); + + AddAlias("hostnet-driver", "hostnet0-driver"); + AddAlias("hostnet-fallback", "hostnet0-fallback"); + AddAlias("hostnet-afpacket-ifname", "hostnet0-afpacket-ifname"); + AddAlias("hostnet-bpf-ifname", "hostnet0-bpf-ifname"); + AddAlias("hostnet-tap-devpath", "hostnet0-tap-devpath"); // IPLROM1/2 ファイルパス。なければ内蔵 ROM。 Add("iplrom1-image", "", VMCap::X68030); Add("iplrom2-image", "", VMCap::X68030); // キーボードの接続 - Add("keyboard-connect", 1); + Add("keyboard-connect", 1, VMCap::LUNA | VMCap::X68030); // LUNA の RTC(MK48T02) がうるう年でない 1970 をエポックとして // 設定しているので、そちらに合わせてうるう年を補正する @@ -118,10 +142,23 @@ Config::Config() // M88100 で疑似 STOP 状態をサポートする Add("mpu-pseudo-stop", 1, VMCap::M88K); + // Nereid + Add("nereid0-enable", 0, VMCap::X68030); + Add("nereid1-enable", 0, VMCap::X68030); + + // Nereid イーサネット + Add("nereid0-net", 1, VMCap::X68030); + Add("nereid1-net", 1, VMCap::X68030); + + // Nereid バンクメモリ容量 (0, 4, 16 もしくは -4, -16) + Add("nereid0-ram-size", 16, VMCap::X68030); + Add("nereid1-ram-size", 16, VMCap::X68030); + // NEWS の DIPSW (1 がオン、0 がオフ)。 Add("news-dipsw", "00001000", VMCap::NEWS); // NEWS の SIC を無視する。(暫定) + // これは新旧で処置が変わるのでエイリアスにしていない。 Add("xxx-news-sic-ignore", "0", VMCap::NEWS); Add("xxx-news-sci-ignore", "", VMCap::NEWS); @@ -149,19 +186,35 @@ Config::Config() // SCSI 設定。 for (int id = 0; id < 8; id++) { + auto scsicap = VMCap::LUNA | VMCap::X68030; // 種別とイメージパス - Add(string_format("spc0-id%d-image", id)); + Add(string_format("spc0-id%d-image", id), scsicap); // エミュレータ的に書き込みを禁止するか - Add(string_format("spc0-id%d-writeignore", id), 0); + Add(string_format("spc0-id%d-writeignore", id), 0, scsicap); // エミュレータ的に書き込みを禁止するか // (後方互換、十分不要になった頃に削除する) - Add(string_format("spc0-id%d-writeprotect", id), 0); + Add(string_format("spc0-id%d-writeprotect", id), 0, scsicap); // シークタイム [msec] - Add(string_format("spc0-id%d-seektime", id), 0); + Add(string_format("spc0-id%d-seektime", id), 0, scsicap); } // SRAM の RAM 容量を同期するか。 Add("sram-sync-ramsize", 1, VMCap::X68030); + + // virtio 設定。 + for (int id = 0; id < 8; id++) { + auto viocap = VMCap::VIRT68K; + // イメージパス + Add(string_format("virtio-block%d-image", id), viocap); + // エミュレータ的に書き込みを禁止するか + Add(string_format("virtio-block%d-writeignore", id), 0, viocap); + } + + // Windrv パス。 + Add("windrv-path", "", VMCap::X68030); + + // X68030 で FC2 ピンを切るか。 + Add("x68k-cut-fc2", 1, VMCap::X68030); } // デストラクタ @@ -195,6 +248,21 @@ Config::Add(const std::string& key, cons return true; } +// エイリアスを追加 +bool +Config::AddAlias(const std::string& alias, const std::string& key) +{ + // すでに同名のエイリアスがあれば、プログラムミス + for (const auto& p : aliases) { + if (alias == p.first) { + PANIC("aliases already has %s !", alias.c_str()); + } + } + + aliases.emplace_back(alias, key); + return true; +} + // 項目を削除 // key が見付からなくても何もしない。key は複数登録されていることはないはず。 void @@ -221,7 +289,7 @@ Config::Update(const ConfigFile& file) int lineno = pair.second; auto where = string_format("%s:%d", file.filepath.c_str(), lineno); - if (UpdateLine(line, ConfigItem::FromConfig, where) == false) { + if (UpdateLine(line, file.from, where) == false) { return false; } } @@ -255,17 +323,32 @@ Config::UpdateLine(const std::string& li return false; } + // キーが別名なら正規名に置換 + key = GetCanonKey(key); + // キーで検索 ConfigItem *itemptr = FindItem(key); if (itemptr == NULL) { - // コマンドラインからの場合はエラーにする - if (from == ConfigItem::FromOption) { + switch (from) { + default: + case ConfigItem::FromHome: + // 共通設定ファイルなら黙って無視する。 + // このファイルには他機種向けの設定も並んでいる可能性があるため + // 無視してくれないと困る。 + return true; + + case ConfigItem::FromConfig: + // VM 設定ファイルなら警告のみで無視する。 + // このファイルに他機種向けの設定があるのはおかしいが + // 止めるほどではない。 + ConfigItem::PrintErr(from, where, key, val, "Unknown key, ignored"); + return true; + + case ConfigItem::FromOption: + // コマンドラインからの場合はエラーにする。 ConfigItem::PrintErr(from, where, key, val, "Unknown key"); return false; } - // コマンドライン以外の場合は警告のみで無視する - ConfigItem::PrintErr(from, where, key, val, "Unknown key, ignored"); - return true; } // 見付かったので更新 @@ -301,6 +384,23 @@ Config::SplitKeyVal(std::string *keyp, s return true; } +// キーがエイリアスなら正規名を返す。 +// エイリアスでなければキーをそのまま返す。 +const std::string& +Config::GetCanonKey(const std::string& key) const +{ + for (const auto& p : aliases) { + const auto& alias = p.first; + const auto& canon = p.second; + + if (key == alias) { + return canon; + } + } + + return key; +} + // 内容を表示する。 // all なら隠し設定も含めて表示。 void @@ -333,6 +433,7 @@ Config::Show(bool all) const case ConfigItem::FromInitial: fromstr = "initial value"; break; + case ConfigItem::FromHome: case ConfigItem::FromConfig: fromstr = item.where; break; @@ -340,7 +441,8 @@ Config::Show(bool all) const fromstr = "option " + item.where; break; default: - fromstr = string_format("corrupted item.from=%d", (int)item.from); + fromstr = string_format("corrupted item.from=%d for key=%s", + (int)item.from, item.key.c_str()); break; } @@ -409,11 +511,14 @@ Config::Fix() VMCap vmcap = item.GetVMCap(); if (gMainApp.Has(vmcap) == false) { // この機種用ではない - - if (item.from != ConfigItem::FromInitial) { - // 更新されていればエラー + switch (item.from) { + case ConfigItem::FromConfig: + case ConfigItem::FromOption: + // 明示的に更新されていればエラー item.Err("Not supported in this vmtype"); return false; + default: + break; } it = list.erase(it); @@ -520,12 +625,13 @@ ConfigItem::PrintErr(ConfigItem::from_t fromstr = "initial value: " + key + "=" + value; break; + case FromHome: case FromConfig: // 設定ファイルでのエラー。where はファイル名と行番号。 fromstr = where + ": "; if (key.empty() == false) { fromstr += key; - fromstr + "="; + fromstr += "="; } fromstr += value; break; @@ -536,7 +642,7 @@ ConfigItem::PrintErr(ConfigItem::from_t // "-V" なら (key =) value を追加し、 // それ以外なら value のみ追加がいいか。 fromstr = "option " + where + " "; - if (where == "-V") { + if (where.find("-V") != std::string::npos) { if (key.empty() == false) { fromstr += key; fromstr += "="; @@ -546,7 +652,8 @@ ConfigItem::PrintErr(ConfigItem::from_t break; default: - fromstr = string_format("corrupted item.from=%d", (int)from); + fromstr = string_format("corrupted item.from=%d for key=%s", + (int)from, key.c_str()); break; } @@ -559,9 +666,10 @@ ConfigItem::PrintErr(ConfigItem::from_t // // コンストラクタ -ConfigFile::ConfigFile(const std::string& filepath_) +ConfigFile::ConfigFile(const std::string& filepath_, ConfigItem::from_t from_) { filepath = filepath_; + from = from_; } // デストラクタ