From 97d237eed038a2ff227a329bae62db6da7819417 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 15 Mar 2025 21:13:31 -0400 Subject: [PATCH] Support real IBM BIOS, either in odd/even or complete form. --- Machines/PCCompatible/PCCompatible.cpp | 63 ++++++++++++++++++++------ Machines/Utility/ROMCatalogue.cpp | 9 ++++ Machines/Utility/ROMCatalogue.hpp | 6 +++ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index 375089782..47c5537ce 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -592,19 +592,26 @@ public: // Fetch the BIOS. const auto font = Video::FontROM; - constexpr auto biosXT = ROM::Name::PCCompatibleGLaBIOS; - constexpr auto tickXT = ROM::Name::PCCompatibleGLaTICK; + constexpr auto bios_XT = ROM::Name::PCCompatibleGLaBIOS; + constexpr auto tick_XT = ROM::Name::PCCompatibleGLaTICK; - constexpr auto biosAT = ROM::Name::PCCompatiblePhoenix80286BIOS; + constexpr auto bios_AT = ROM::Name::PCCompatibleIBMATBIOS; + constexpr auto bios_AT_even = ROM::Name::PCCompatibleIBMATBIOSNov85U27; + constexpr auto bios_AT_odd = ROM::Name::PCCompatibleIBMATBIOSNov85U47; + constexpr auto bios_AT_Phoenix = ROM::Name::PCCompatiblePhoenix80286BIOS; ROM::Request request = ROM::Request(font); switch(pc_model) { default: - request = request && ROM::Request(biosXT) && ROM::Request(tickXT); - break; - case Analyser::Static::PCCompatible::Model::AT: - request = request && ROM::Request(biosAT); + request = request && ROM::Request(bios_XT) && ROM::Request(tick_XT); break; + case Analyser::Static::PCCompatible::Model::AT: { + auto at_even_odd = ROM::Request(bios_AT_odd) && ROM::Request(bios_AT_even); + auto at_full = ROM::Request(bios_AT); + auto phoenix_full = ROM::Request(bios_AT_Phoenix); + const auto at_any = at_even_odd || at_full || phoenix_full; + request = request && at_any; + } break; } auto roms = rom_fetcher(request); @@ -614,20 +621,50 @@ public: switch(pc_model) { default: { - const auto &bios_contents = roms.find(biosXT)->second; + const auto &bios_contents = roms.find(bios_XT)->second; context_.memory.install(0x10'0000 - bios_contents.size(), bios_contents.data(), bios_contents.size()); // If found, install GlaTICK at 0xd'0000. - auto tick_contents = roms.find(tickXT); + auto tick_contents = roms.find(tick_XT); if(tick_contents != roms.end()) { context_.memory.install(0xd'0000, tick_contents->second.data(), tick_contents->second.size()); } } break; - case Analyser::Static::PCCompatible::Model::AT: - const auto &bios_contents = roms.find(biosAT)->second; - context_.memory.install(0x10'0000 - bios_contents.size(), bios_contents.data(), bios_contents.size()); - break; + case Analyser::Static::PCCompatible::Model::AT: { + const auto install_at = [&] { + const auto bios_even = roms.find(bios_AT_even); + const auto bios_odd = roms.find(bios_AT_odd); + if(bios_even != roms.end() && bios_odd != roms.end()) { + std::vector bios(65536); + + for(size_t c = 0; c < bios.size(); c++) { + bios[c] = (c & 1) ? bios_odd->second[c >> 1] : bios_even->second[c >> 1]; + } + + context_.memory.install( + 0x10'0000 - bios.size(), + bios.data(), + bios.size() + ); + return; + } + + for(const auto name: {bios_AT, bios_AT_Phoenix}) { + const auto bios_contents = roms.find(name); + if(bios_contents != roms.end()) { + context_.memory.install( + 0x10'0000 - bios_contents->second.size(), + bios_contents->second.data(), + bios_contents->second.size() + ); + return; + } + } + }; + + install_at(); + } break; } // Give the video card something to read from. diff --git a/Machines/Utility/ROMCatalogue.cpp b/Machines/Utility/ROMCatalogue.cpp index 5eea65c7b..10ce1a076 100644 --- a/Machines/Utility/ROMCatalogue.cpp +++ b/Machines/Utility/ROMCatalogue.cpp @@ -588,6 +588,15 @@ Description::Description(Name name) { case Name::PCCompatiblePhoenix80286BIOS: *this = Description(name, "PCCompatible", "Phoenix 80286 BIOS 3.05", "Phoenix 80286 ROM BIOS Version 3.05.bin", 32 * 1024, 0x8d0d318au); break; + case Name::PCCompatibleIBMATBIOS: + *this = Description(name, "PCCompatible", "IBM PC AT BIOS v3", "at-bios.bin", 64 * 1024, 0x674426beu); + break; + case Name::PCCompatibleIBMATBIOSNov85U27: + *this = Description(name, "PCCompatible", "IBM PC AT BIOS; 15th Nov 1985; U27", "BIOS_5170_15NOV85_U27_61X9266_27256.BIN", 32 * 1024, 0x4995be7au); + break; + case Name::PCCompatibleIBMATBIOSNov85U47: + *this = Description(name, "PCCompatible", "IBM PC AT BIOS; 15th Nov 1985; U47", "BIOS_5170_15NOV85_U47_61X9265_27256.BIN", 32 * 1024, 0xc32713e4u); + break; case Name::PCCompatibleCGAFont: *this = Description(name, "PCCompatible", "IBM's CGA font", "CGA.F08", 8 * 256, 0xa362ffe6u); break; diff --git a/Machines/Utility/ROMCatalogue.hpp b/Machines/Utility/ROMCatalogue.hpp index d366e0d2e..a05693c3e 100644 --- a/Machines/Utility/ROMCatalogue.hpp +++ b/Machines/Utility/ROMCatalogue.hpp @@ -141,6 +141,10 @@ enum Name { PCCompatibleGLaTICK, PCCompatiblePhoenix80286BIOS, + PCCompatibleIBMATBIOS, + PCCompatibleIBMATBIOSNov85U27, + PCCompatibleIBMATBIOSNov85U47, + PCCompatibleMDAFont, PCCompatibleCGAFont, PCCompatibleEGABIOS, @@ -236,6 +240,8 @@ struct Request { Request(Name name, bool optional = false); Request() = default; + // TODO: the following is definitely not const correct. + /// Forms the request that would be satisfied by @c this plus the right-hand side. Request operator &&(const Request &);