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:
parent
86d709ae01
commit
20670bab2f
@ -781,7 +781,7 @@ template <bool has_fdc> class ConcreteMachine:
|
||||
ay_.ay().set_port_handler(&key_state_);
|
||||
|
||||
// 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;
|
||||
switch(target.model) {
|
||||
default:
|
||||
|
@ -347,26 +347,26 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
|
||||
// Pick the required ROMs.
|
||||
using Target = Analyser::Static::AppleII::Target;
|
||||
std::vector<std::string> rom_names;
|
||||
std::vector<ROMMachine::ROM> rom_names;
|
||||
size_t rom_size = 12*1024;
|
||||
switch(target.model) {
|
||||
default:
|
||||
rom_names.push_back("apple2-character.rom");
|
||||
rom_names.push_back("apple2o.rom");
|
||||
rom_names.emplace_back("apple2-character.rom");
|
||||
rom_names.emplace_back("apple2o.rom");
|
||||
break;
|
||||
case Target::Model::IIplus:
|
||||
rom_names.push_back("apple2-character.rom");
|
||||
rom_names.push_back("apple2.rom");
|
||||
rom_names.emplace_back("apple2-character.rom");
|
||||
rom_names.emplace_back("apple2.rom");
|
||||
break;
|
||||
case Target::Model::IIe:
|
||||
rom_size += 3840;
|
||||
rom_names.push_back("apple2eu-character.rom");
|
||||
rom_names.push_back("apple2eu.rom");
|
||||
rom_names.emplace_back("apple2eu-character.rom");
|
||||
rom_names.emplace_back("apple2eu.rom");
|
||||
break;
|
||||
case Target::Model::EnhancedIIe:
|
||||
rom_size += 3840;
|
||||
rom_names.push_back("apple2e-character.rom");
|
||||
rom_names.push_back("apple2e.rom");
|
||||
rom_names.emplace_back("apple2e-character.rom");
|
||||
rom_names.emplace_back("apple2e.rom");
|
||||
break;
|
||||
}
|
||||
const auto roms = rom_fetcher("AppleII", rom_names);
|
||||
|
@ -14,8 +14,8 @@ DiskIICard::DiskIICard(const ROMMachine::ROMFetcher &rom_fetcher, bool is_16_sec
|
||||
const auto roms = rom_fetcher(
|
||||
"DiskII",
|
||||
{
|
||||
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 ? "boot-16.rom" : "boot-13.rom"),
|
||||
ROMMachine::ROM(is_16_sector ? "state-machine-16.rom" : "state-machine-13.rom")
|
||||
});
|
||||
boot_ = std::move(*roms[0]);
|
||||
diskii_.set_state_machine(*roms[1]);
|
||||
|
@ -132,7 +132,7 @@ class ConcreteMachine:
|
||||
|
||||
const auto roms = rom_fetcher(
|
||||
"ColecoVision",
|
||||
{ "coleco.rom" });
|
||||
{ ROMMachine::ROM("coleco.rom") });
|
||||
|
||||
if(!roms[0]) {
|
||||
throw ROMMachine::Error::MissingROMs;
|
||||
|
@ -323,27 +323,27 @@ class ConcreteMachine:
|
||||
// install a joystick
|
||||
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) {
|
||||
default:
|
||||
rom_names.push_back("characters-english.bin");
|
||||
rom_names.push_back("kernel-pal.bin");
|
||||
rom_names.emplace_back("characters-english.bin");
|
||||
rom_names.emplace_back("kernel-pal.bin");
|
||||
break;
|
||||
case Analyser::Static::Commodore::Target::Region::American:
|
||||
rom_names.push_back("characters-english.bin");
|
||||
rom_names.push_back("kernel-ntsc.bin");
|
||||
rom_names.emplace_back("characters-english.bin");
|
||||
rom_names.emplace_back("kernel-ntsc.bin");
|
||||
break;
|
||||
case Analyser::Static::Commodore::Target::Region::Danish:
|
||||
rom_names.push_back("characters-danish.bin");
|
||||
rom_names.push_back("kernel-danish.bin");
|
||||
rom_names.emplace_back("characters-danish.bin");
|
||||
rom_names.emplace_back("kernel-danish.bin");
|
||||
break;
|
||||
case Analyser::Static::Commodore::Target::Region::Japanese:
|
||||
rom_names.push_back("characters-japanese.bin");
|
||||
rom_names.push_back("kernel-japanese.bin");
|
||||
rom_names.emplace_back("characters-japanese.bin");
|
||||
rom_names.emplace_back("kernel-japanese.bin");
|
||||
break;
|
||||
case Analyser::Static::Commodore::Target::Region::Swedish:
|
||||
rom_names.push_back("characters-swedish.bin");
|
||||
rom_names.push_back("kernel-japanese.bin");
|
||||
rom_names.emplace_back("characters-swedish.bin");
|
||||
rom_names.emplace_back("kernel-japanese.bin");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -64,14 +64,14 @@ class ConcreteMachine:
|
||||
speaker_.set_input_rate(2000000 / SoundGenerator::clock_rate_divider);
|
||||
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) {
|
||||
rom_names.push_back("ADFS-E00_1.rom");
|
||||
rom_names.push_back("ADFS-E00_2.rom");
|
||||
rom_names.emplace_back("ADFS-E00_1.rom");
|
||||
rom_names.emplace_back("ADFS-E00_2.rom");
|
||||
}
|
||||
const size_t dfs_rom_position = rom_names.size();
|
||||
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);
|
||||
|
||||
|
@ -173,7 +173,7 @@ class ConcreteMachine:
|
||||
mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f});
|
||||
|
||||
// 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;
|
||||
uint8_t character_generator = 1; /* 0 = Japan, 1 = USA, etc, 2 = USSR */
|
||||
@ -182,7 +182,7 @@ class ConcreteMachine:
|
||||
|
||||
switch(target.region) {
|
||||
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);
|
||||
|
||||
is_ntsc = true;
|
||||
@ -190,7 +190,7 @@ class ConcreteMachine:
|
||||
date_format = 0;
|
||||
break;
|
||||
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);
|
||||
|
||||
is_ntsc = true;
|
||||
@ -198,7 +198,7 @@ class ConcreteMachine:
|
||||
date_format = 1;
|
||||
break;
|
||||
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);
|
||||
|
||||
is_ntsc = false;
|
||||
@ -212,7 +212,7 @@ class ConcreteMachine:
|
||||
size_t disk_index = 0;
|
||||
if(target.has_disk_drive) {
|
||||
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);
|
||||
|
||||
|
@ -132,7 +132,7 @@ class ConcreteMachine:
|
||||
|
||||
// Load the BIOS if relevant.
|
||||
if(has_bios()) {
|
||||
const auto roms = rom_fetcher("MasterSystem", {"bios.sms"});
|
||||
const auto roms = rom_fetcher("MasterSystem", { ROMMachine::ROM("bios.sms") });
|
||||
if(!roms[0]) {
|
||||
// No BIOS found; attempt to boot as though it has already disabled itself.
|
||||
memory_control_ |= 0x08;
|
||||
|
@ -228,16 +228,16 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
||||
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) {
|
||||
case Analyser::Static::Oric::Target::ROM::BASIC10: rom_names.push_back("basic10.rom"); break;
|
||||
case Analyser::Static::Oric::Target::ROM::BASIC11: rom_names.push_back("basic11.rom"); break;
|
||||
case Analyser::Static::Oric::Target::ROM::Pravetz: rom_names.push_back("pravetz.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.emplace_back("basic11.rom"); break;
|
||||
case Analyser::Static::Oric::Target::ROM::Pravetz: rom_names.emplace_back("pravetz.rom"); break;
|
||||
}
|
||||
switch(disk_interface) {
|
||||
default: break;
|
||||
case Analyser::Static::Oric::Target::DiskInterface::Microdisc: rom_names.push_back("microdisc.rom"); break;
|
||||
case Analyser::Static::Oric::Target::DiskInterface::Pravetz: rom_names.push_back("8dos.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.emplace_back("8dos.rom"); break;
|
||||
}
|
||||
|
||||
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_.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]) {
|
||||
throw ROMMachine::Error::MissingROMs;
|
||||
}
|
||||
|
@ -16,6 +16,32 @@
|
||||
|
||||
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
|
||||
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
|
||||
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 {
|
||||
MissingROMs
|
||||
|
@ -76,7 +76,7 @@ template<bool is_zx81> class ConcreteMachine:
|
||||
clear_all_keys();
|
||||
|
||||
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;
|
||||
|
||||
rom_ = std::move(*roms[0]);
|
||||
|
@ -15,11 +15,14 @@
|
||||
#include <string>
|
||||
|
||||
ROMMachine::ROMFetcher CSROMFetcher() {
|
||||
return [] (const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<std::uint8_t>>> {
|
||||
NSString *subDirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:machine.c_str()]];
|
||||
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()]];
|
||||
std::vector<std::unique_ptr<std::vector<std::uint8_t>>> results;
|
||||
for(const auto &name: names) {
|
||||
NSData *fileData = [[NSBundle mainBundle] dataForResource:[NSString stringWithUTF8String:name.c_str()] withExtension:nil subdirectory:subDirectory];
|
||||
for(const auto &rom: roms) {
|
||||
NSData *fileData = [[NSBundle mainBundle]
|
||||
dataForResource:[NSString stringWithUTF8String:rom.file_name.c_str()]
|
||||
withExtension:nil
|
||||
subdirectory:subdirectory];
|
||||
|
||||
if(!fileData)
|
||||
results.emplace_back(nullptr);
|
||||
|
@ -365,11 +365,11 @@ int main(int argc, char *argv[]) {
|
||||
// /usr/local/share/CLK/[system];
|
||||
// /usr/share/CLK/[system]; or
|
||||
// [user-supplied path]/[system]
|
||||
std::vector<std::string> rom_names;
|
||||
std::vector<ROMMachine::ROM> requested_roms;
|
||||
std::string machine_name;
|
||||
ROMMachine::ROMFetcher rom_fetcher = [&rom_names, &machine_name, &arguments]
|
||||
(const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> {
|
||||
rom_names.insert(rom_names.end(), names.begin(), names.end());
|
||||
ROMMachine::ROMFetcher rom_fetcher = [&requested_roms, &machine_name, &arguments]
|
||||
(const std::string &machine, const std::vector<ROMMachine::ROM> &roms) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> {
|
||||
requested_roms.insert(requested_roms.end(), roms.begin(), roms.end());
|
||||
machine_name = machine;
|
||||
|
||||
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;
|
||||
for(const auto &name: names) {
|
||||
for(const auto &rom: roms) {
|
||||
FILE *file = nullptr;
|
||||
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");
|
||||
if(file) break;
|
||||
}
|
||||
@ -425,8 +425,8 @@ int main(int argc, char *argv[]) {
|
||||
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 << "One or more of the following was needed but not found:" << std::endl;
|
||||
for(const auto &name: rom_names) {
|
||||
std::cerr << machine_name << '/' << name << std::endl;
|
||||
for(const auto &rom: requested_roms) {
|
||||
std::cerr << machine_name << '/' << rom.file_name << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user