1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Expands information included in ROM load requests.

This commit is contained in:
Thomas Harte 2019-07-19 22:35:22 -04:00
parent 86d709ae01
commit 20670bab2f
13 changed files with 84 additions and 55 deletions

View File

@ -781,7 +781,7 @@ template <bool has_fdc> class ConcreteMachine:
ay_.ay().set_port_handler(&key_state_); ay_.ay().set_port_handler(&key_state_);
// construct the list of necessary ROMs // construct the list of necessary ROMs
std::vector<std::string> required_roms = {"amsdos.rom"}; std::vector<ROMMachine::ROM> required_roms = { {"amsdos.rom"} };
std::string model_number; std::string model_number;
switch(target.model) { switch(target.model) {
default: default:

View File

@ -347,26 +347,26 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
// Pick the required ROMs. // Pick the required ROMs.
using Target = Analyser::Static::AppleII::Target; using Target = Analyser::Static::AppleII::Target;
std::vector<std::string> rom_names; std::vector<ROMMachine::ROM> rom_names;
size_t rom_size = 12*1024; size_t rom_size = 12*1024;
switch(target.model) { switch(target.model) {
default: default:
rom_names.push_back("apple2-character.rom"); rom_names.emplace_back("apple2-character.rom");
rom_names.push_back("apple2o.rom"); rom_names.emplace_back("apple2o.rom");
break; break;
case Target::Model::IIplus: case Target::Model::IIplus:
rom_names.push_back("apple2-character.rom"); rom_names.emplace_back("apple2-character.rom");
rom_names.push_back("apple2.rom"); rom_names.emplace_back("apple2.rom");
break; break;
case Target::Model::IIe: case Target::Model::IIe:
rom_size += 3840; rom_size += 3840;
rom_names.push_back("apple2eu-character.rom"); rom_names.emplace_back("apple2eu-character.rom");
rom_names.push_back("apple2eu.rom"); rom_names.emplace_back("apple2eu.rom");
break; break;
case Target::Model::EnhancedIIe: case Target::Model::EnhancedIIe:
rom_size += 3840; rom_size += 3840;
rom_names.push_back("apple2e-character.rom"); rom_names.emplace_back("apple2e-character.rom");
rom_names.push_back("apple2e.rom"); rom_names.emplace_back("apple2e.rom");
break; break;
} }
const auto roms = rom_fetcher("AppleII", rom_names); const auto roms = rom_fetcher("AppleII", rom_names);

View File

@ -14,8 +14,8 @@ DiskIICard::DiskIICard(const ROMMachine::ROMFetcher &rom_fetcher, bool is_16_sec
const auto roms = rom_fetcher( const auto roms = rom_fetcher(
"DiskII", "DiskII",
{ {
is_16_sector ? "boot-16.rom" : "boot-13.rom", ROMMachine::ROM(is_16_sector ? "boot-16.rom" : "boot-13.rom"),
is_16_sector ? "state-machine-16.rom" : "state-machine-13.rom" ROMMachine::ROM(is_16_sector ? "state-machine-16.rom" : "state-machine-13.rom")
}); });
boot_ = std::move(*roms[0]); boot_ = std::move(*roms[0]);
diskii_.set_state_machine(*roms[1]); diskii_.set_state_machine(*roms[1]);

View File

@ -132,7 +132,7 @@ class ConcreteMachine:
const auto roms = rom_fetcher( const auto roms = rom_fetcher(
"ColecoVision", "ColecoVision",
{ "coleco.rom" }); { ROMMachine::ROM("coleco.rom") });
if(!roms[0]) { if(!roms[0]) {
throw ROMMachine::Error::MissingROMs; throw ROMMachine::Error::MissingROMs;

View File

@ -323,27 +323,27 @@ class ConcreteMachine:
// install a joystick // install a joystick
joysticks_.emplace_back(new Joystick(*user_port_via_port_handler_, *keyboard_via_port_handler_)); joysticks_.emplace_back(new Joystick(*user_port_via_port_handler_, *keyboard_via_port_handler_));
std::vector<std::string> rom_names = { "basic.bin" }; std::vector<ROMMachine::ROM> rom_names = { ROMMachine::ROM("basic.bin") };
switch(target.region) { switch(target.region) {
default: default:
rom_names.push_back("characters-english.bin"); rom_names.emplace_back("characters-english.bin");
rom_names.push_back("kernel-pal.bin"); rom_names.emplace_back("kernel-pal.bin");
break; break;
case Analyser::Static::Commodore::Target::Region::American: case Analyser::Static::Commodore::Target::Region::American:
rom_names.push_back("characters-english.bin"); rom_names.emplace_back("characters-english.bin");
rom_names.push_back("kernel-ntsc.bin"); rom_names.emplace_back("kernel-ntsc.bin");
break; break;
case Analyser::Static::Commodore::Target::Region::Danish: case Analyser::Static::Commodore::Target::Region::Danish:
rom_names.push_back("characters-danish.bin"); rom_names.emplace_back("characters-danish.bin");
rom_names.push_back("kernel-danish.bin"); rom_names.emplace_back("kernel-danish.bin");
break; break;
case Analyser::Static::Commodore::Target::Region::Japanese: case Analyser::Static::Commodore::Target::Region::Japanese:
rom_names.push_back("characters-japanese.bin"); rom_names.emplace_back("characters-japanese.bin");
rom_names.push_back("kernel-japanese.bin"); rom_names.emplace_back("kernel-japanese.bin");
break; break;
case Analyser::Static::Commodore::Target::Region::Swedish: case Analyser::Static::Commodore::Target::Region::Swedish:
rom_names.push_back("characters-swedish.bin"); rom_names.emplace_back("characters-swedish.bin");
rom_names.push_back("kernel-japanese.bin"); rom_names.emplace_back("kernel-japanese.bin");
break; break;
} }

View File

@ -64,14 +64,14 @@ class ConcreteMachine:
speaker_.set_input_rate(2000000 / SoundGenerator::clock_rate_divider); speaker_.set_input_rate(2000000 / SoundGenerator::clock_rate_divider);
speaker_.set_high_frequency_cutoff(7000); speaker_.set_high_frequency_cutoff(7000);
std::vector<std::string> rom_names = {"basic.rom", "os.rom"}; std::vector<ROMMachine::ROM> rom_names = { {"basic.rom"}, {"os.rom"} };
if(target.has_adfs) { if(target.has_adfs) {
rom_names.push_back("ADFS-E00_1.rom"); rom_names.emplace_back("ADFS-E00_1.rom");
rom_names.push_back("ADFS-E00_2.rom"); rom_names.emplace_back("ADFS-E00_2.rom");
} }
const size_t dfs_rom_position = rom_names.size(); const size_t dfs_rom_position = rom_names.size();
if(target.has_dfs) { if(target.has_dfs) {
rom_names.push_back("DFS-1770-2.20.rom"); rom_names.emplace_back("DFS-1770-2.20.rom");
} }
const auto roms = rom_fetcher("Electron", rom_names); const auto roms = rom_fetcher("Electron", rom_names);

View File

@ -173,7 +173,7 @@ class ConcreteMachine:
mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f}); mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f});
// Install the proper TV standard and select an ideal BIOS name. // Install the proper TV standard and select an ideal BIOS name.
std::vector<std::string> rom_names = {"msx.rom"}; std::vector<ROMMachine::ROM> rom_names = { {"msx.rom"} };
bool is_ntsc = true; bool is_ntsc = true;
uint8_t character_generator = 1; /* 0 = Japan, 1 = USA, etc, 2 = USSR */ uint8_t character_generator = 1; /* 0 = Japan, 1 = USA, etc, 2 = USSR */
@ -182,7 +182,7 @@ class ConcreteMachine:
switch(target.region) { switch(target.region) {
case Target::Region::Japan: case Target::Region::Japan:
rom_names.push_back("msx-japanese.rom"); rom_names.emplace_back("msx-japanese.rom");
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC); vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
is_ntsc = true; is_ntsc = true;
@ -190,7 +190,7 @@ class ConcreteMachine:
date_format = 0; date_format = 0;
break; break;
case Target::Region::USA: case Target::Region::USA:
rom_names.push_back("msx-american.rom"); rom_names.emplace_back("msx-american.rom");
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC); vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
is_ntsc = true; is_ntsc = true;
@ -198,7 +198,7 @@ class ConcreteMachine:
date_format = 1; date_format = 1;
break; break;
case Target::Region::Europe: case Target::Region::Europe:
rom_names.push_back("msx-european.rom"); rom_names.emplace_back("msx-european.rom");
vdp_.set_tv_standard(TI::TMS::TVStandard::PAL); vdp_.set_tv_standard(TI::TMS::TVStandard::PAL);
is_ntsc = false; is_ntsc = false;
@ -212,7 +212,7 @@ class ConcreteMachine:
size_t disk_index = 0; size_t disk_index = 0;
if(target.has_disk_drive) { if(target.has_disk_drive) {
disk_index = rom_names.size(); disk_index = rom_names.size();
rom_names.push_back("disk.rom"); rom_names.emplace_back("disk.rom");
} }
const auto roms = rom_fetcher("MSX", rom_names); const auto roms = rom_fetcher("MSX", rom_names);

View File

@ -132,7 +132,7 @@ class ConcreteMachine:
// Load the BIOS if relevant. // Load the BIOS if relevant.
if(has_bios()) { if(has_bios()) {
const auto roms = rom_fetcher("MasterSystem", {"bios.sms"}); const auto roms = rom_fetcher("MasterSystem", { ROMMachine::ROM("bios.sms") });
if(!roms[0]) { if(!roms[0]) {
// No BIOS found; attempt to boot as though it has already disabled itself. // No BIOS found; attempt to boot as though it has already disabled itself.
memory_control_ |= 0x08; memory_control_ |= 0x08;

View File

@ -228,16 +228,16 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
diskii_.set_clocking_hint_observer(this); diskii_.set_clocking_hint_observer(this);
} }
std::vector<std::string> rom_names = {"colour.rom"}; std::vector<ROMMachine::ROM> rom_names = { {"colour.rom"} };
switch(target.rom) { switch(target.rom) {
case Analyser::Static::Oric::Target::ROM::BASIC10: rom_names.push_back("basic10.rom"); break; case Analyser::Static::Oric::Target::ROM::BASIC10: rom_names.emplace_back("basic10.rom"); break;
case Analyser::Static::Oric::Target::ROM::BASIC11: rom_names.push_back("basic11.rom"); break; case Analyser::Static::Oric::Target::ROM::BASIC11: rom_names.emplace_back("basic11.rom"); break;
case Analyser::Static::Oric::Target::ROM::Pravetz: rom_names.push_back("pravetz.rom"); break; case Analyser::Static::Oric::Target::ROM::Pravetz: rom_names.emplace_back("pravetz.rom"); break;
} }
switch(disk_interface) { switch(disk_interface) {
default: break; default: break;
case Analyser::Static::Oric::Target::DiskInterface::Microdisc: rom_names.push_back("microdisc.rom"); break; case Analyser::Static::Oric::Target::DiskInterface::Microdisc: rom_names.emplace_back("microdisc.rom"); break;
case Analyser::Static::Oric::Target::DiskInterface::Pravetz: rom_names.push_back("8dos.rom"); break; case Analyser::Static::Oric::Target::DiskInterface::Pravetz: rom_names.emplace_back("8dos.rom"); break;
} }
const auto roms = rom_fetcher("Oric", rom_names); const auto roms = rom_fetcher("Oric", rom_names);
@ -261,7 +261,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
pravetz_rom_ = std::move(*roms[2]); pravetz_rom_ = std::move(*roms[2]);
pravetz_rom_.resize(512); pravetz_rom_.resize(512);
auto state_machine_rom = rom_fetcher("DiskII", {"state-machine-16.rom"}); auto state_machine_rom = rom_fetcher("DiskII", { ROMMachine::ROM("state-machine-16.rom") });
if(!state_machine_rom[0]) { if(!state_machine_rom[0]) {
throw ROMMachine::Error::MissingROMs; throw ROMMachine::Error::MissingROMs;
} }

View File

@ -16,6 +16,32 @@
namespace ROMMachine { namespace ROMMachine {
/*!
Describes a ROM image; this term is used in this emulator strictly in the sense of firmware
system software that is an inherent part of a machine.
*/
struct ROM {
/// A descriptive name for this ROM, e.g. "Electron MOS 1.0".
std::string descriptive_name;
/// An idiomatic file name for this ROM, e.g. "os10.rom".
std::string file_name;
/// The expected size of this ROM in bytes, e.g. 32768.
size_t size = 0;
/// CRC32s for all known acceptable copies of this ROM; intended to allow a host platform
/// to test user-provided ROMs of unknown provenance. **Not** intended to be used
/// to exclude ROMs where the user's intent is otherwise clear.
std::vector<uint32_t> crc32s;
/// This is a temporary constructor provided for transitional purposes.
ROM(std::string file_name) :
file_name(file_name) {}
ROM(std::string descriptive_name, std::string file_name, size_t size, uint32_t crc32) :
descriptive_name(descriptive_name), file_name(file_name), size(size), crc32s({crc32}) {}
ROM(std::string descriptive_name, std::string file_name, size_t size, std::vector<uint32_t> &crc32s) :
descriptive_name(descriptive_name), file_name(file_name), size(size), crc32s(std::move(crc32s)) {}
};
/*! /*!
Defines the signature for a function that must be supplied by the host environment in order to give machines Defines the signature for a function that must be supplied by the host environment in order to give machines
a route for fetching any system ROMs they might need. a route for fetching any system ROMs they might need.
@ -24,7 +50,7 @@ namespace ROMMachine {
to be present. The recevier should return a vector of unique_ptrs that either contain the contents of the to be present. The recevier should return a vector of unique_ptrs that either contain the contents of the
ROM from @c names that corresponds by index, or else are the nullptr ROM from @c names that corresponds by index, or else are the nullptr
*/ */
typedef std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> ROMFetcher; typedef std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<ROM> &roms)> ROMFetcher;
enum class Error { enum class Error {
MissingROMs MissingROMs

View File

@ -76,7 +76,7 @@ template<bool is_zx81> class ConcreteMachine:
clear_all_keys(); clear_all_keys();
const bool use_zx81_rom = target.is_ZX81 || target.ZX80_uses_ZX81_ROM; const bool use_zx81_rom = target.is_ZX81 || target.ZX80_uses_ZX81_ROM;
const auto roms = rom_fetcher("ZX8081", { use_zx81_rom ? "zx81.rom" : "zx80.rom" }); const auto roms = rom_fetcher("ZX8081", { ROMMachine::ROM(use_zx81_rom ? "zx81.rom" : "zx80.rom") } );
if(!roms[0]) throw ROMMachine::Error::MissingROMs; if(!roms[0]) throw ROMMachine::Error::MissingROMs;
rom_ = std::move(*roms[0]); rom_ = std::move(*roms[0]);

View File

@ -15,11 +15,14 @@
#include <string> #include <string>
ROMMachine::ROMFetcher CSROMFetcher() { ROMMachine::ROMFetcher CSROMFetcher() {
return [] (const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<std::uint8_t>>> { return [] (const std::string &machine, const std::vector<ROMMachine::ROM> &roms) -> std::vector<std::unique_ptr<std::vector<std::uint8_t>>> {
NSString *subDirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:machine.c_str()]]; NSString *subdirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:machine.c_str()]];
std::vector<std::unique_ptr<std::vector<std::uint8_t>>> results; std::vector<std::unique_ptr<std::vector<std::uint8_t>>> results;
for(const auto &name: names) { for(const auto &rom: roms) {
NSData *fileData = [[NSBundle mainBundle] dataForResource:[NSString stringWithUTF8String:name.c_str()] withExtension:nil subdirectory:subDirectory]; NSData *fileData = [[NSBundle mainBundle]
dataForResource:[NSString stringWithUTF8String:rom.file_name.c_str()]
withExtension:nil
subdirectory:subdirectory];
if(!fileData) if(!fileData)
results.emplace_back(nullptr); results.emplace_back(nullptr);

View File

@ -365,11 +365,11 @@ int main(int argc, char *argv[]) {
// /usr/local/share/CLK/[system]; // /usr/local/share/CLK/[system];
// /usr/share/CLK/[system]; or // /usr/share/CLK/[system]; or
// [user-supplied path]/[system] // [user-supplied path]/[system]
std::vector<std::string> rom_names; std::vector<ROMMachine::ROM> requested_roms;
std::string machine_name; std::string machine_name;
ROMMachine::ROMFetcher rom_fetcher = [&rom_names, &machine_name, &arguments] ROMMachine::ROMFetcher rom_fetcher = [&requested_roms, &machine_name, &arguments]
(const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> { (const std::string &machine, const std::vector<ROMMachine::ROM> &roms) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> {
rom_names.insert(rom_names.end(), names.begin(), names.end()); requested_roms.insert(requested_roms.end(), roms.begin(), roms.end());
machine_name = machine; machine_name = machine;
std::vector<std::string> paths = { std::vector<std::string> paths = {
@ -386,10 +386,10 @@ int main(int argc, char *argv[]) {
} }
std::vector<std::unique_ptr<std::vector<uint8_t>>> results; std::vector<std::unique_ptr<std::vector<uint8_t>>> results;
for(const auto &name: names) { for(const auto &rom: roms) {
FILE *file = nullptr; FILE *file = nullptr;
for(const auto &path: paths) { for(const auto &path: paths) {
std::string local_path = path + machine + "/" + name; std::string local_path = path + machine + "/" + rom.file_name;
file = std::fopen(local_path.c_str(), "rb"); file = std::fopen(local_path.c_str(), "rb");
if(file) break; if(file) break;
} }
@ -425,8 +425,8 @@ int main(int argc, char *argv[]) {
case ::Machine::Error::MissingROM: case ::Machine::Error::MissingROM:
std::cerr << "Could not find system ROMs; please install to /usr/local/share/CLK/ or /usr/share/CLK/, or provide a --rompath." << std::endl; std::cerr << "Could not find system ROMs; please install to /usr/local/share/CLK/ or /usr/share/CLK/, or provide a --rompath." << std::endl;
std::cerr << "One or more of the following was needed but not found:" << std::endl; std::cerr << "One or more of the following was needed but not found:" << std::endl;
for(const auto &name: rom_names) { for(const auto &rom: requested_roms) {
std::cerr << machine_name << '/' << name << std::endl; std::cerr << machine_name << '/' << rom.file_name << std::endl;
} }
break; break;
} }