mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-11 04:28:58 +00:00
Merge pull request #627 from TomHarte/ExtraROMDetails
Extends system ROM details; provides for manual import on the Mac
This commit is contained in:
commit
90f6ca4635
@ -781,27 +781,37 @@ 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"};
|
const std::string machine_name = "AmstradCPC";
|
||||||
|
std::vector<ROMMachine::ROM> required_roms = {
|
||||||
|
ROMMachine::ROM(machine_name, "the Amstrad Disk Operating System", "amsdos.rom", 16*1024, 0x1fe22ecd)
|
||||||
|
};
|
||||||
std::string model_number;
|
std::string model_number;
|
||||||
|
uint32_t crcs[2];
|
||||||
switch(target.model) {
|
switch(target.model) {
|
||||||
default:
|
default:
|
||||||
model_number = "6128";
|
model_number = "6128";
|
||||||
has_128k_ = true;
|
has_128k_ = true;
|
||||||
|
crcs[0] = 0x0219bb74;
|
||||||
|
crcs[1] = 0xca6af63d;
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::AmstradCPC::Target::Model::CPC464:
|
case Analyser::Static::AmstradCPC::Target::Model::CPC464:
|
||||||
model_number = "464";
|
model_number = "464";
|
||||||
has_128k_ = false;
|
has_128k_ = false;
|
||||||
|
crcs[0] = 0x815752df;
|
||||||
|
crcs[1] = 0x7d9a3bac;
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::AmstradCPC::Target::Model::CPC664:
|
case Analyser::Static::AmstradCPC::Target::Model::CPC664:
|
||||||
model_number = "664";
|
model_number = "664";
|
||||||
has_128k_ = false;
|
has_128k_ = false;
|
||||||
|
crcs[0] = 0x3f5a6dc4;
|
||||||
|
crcs[1] = 0x32fee492;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
required_roms.push_back("os" + model_number + ".rom");
|
required_roms.emplace_back(machine_name, "the CPC " + model_number + " firmware", "os" + model_number + ".rom", 16*1024, crcs[0]);
|
||||||
required_roms.push_back("basic" + model_number + ".rom");
|
required_roms.emplace_back(machine_name, "the CPC " + model_number + " BASIC ROM", "basic" + model_number + ".rom", 16*1024, crcs[1]);
|
||||||
|
|
||||||
// fetch and verify the ROMs
|
// fetch and verify the ROMs
|
||||||
const auto roms = rom_fetcher("AmstradCPC", required_roms);
|
const auto roms = rom_fetcher(required_roms);
|
||||||
|
|
||||||
for(std::size_t index = 0; index < roms.size(); ++index) {
|
for(std::size_t index = 0; index < roms.size(); ++index) {
|
||||||
auto &data = roms[index];
|
auto &data = roms[index];
|
||||||
|
@ -347,30 +347,39 @@ 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;
|
const std::string machine_name = "AppleII";
|
||||||
|
std::vector<ROMMachine::ROM> rom_descriptions;
|
||||||
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_descriptions.emplace_back(machine_name, "the basic Apple II character ROM", "apple2-character.rom", 2*1024, 0x64f415c6);
|
||||||
rom_names.push_back("apple2o.rom");
|
rom_descriptions.emplace_back(machine_name, "the original Apple II ROM", "apple2o.rom", 12*1024, 0xba210588);
|
||||||
break;
|
break;
|
||||||
case Target::Model::IIplus:
|
case Target::Model::IIplus:
|
||||||
rom_names.push_back("apple2-character.rom");
|
rom_descriptions.emplace_back(machine_name, "the basic Apple II character ROM", "apple2-character.rom", 2*1024, 0x64f415c6);
|
||||||
rom_names.push_back("apple2.rom");
|
rom_descriptions.emplace_back(machine_name, "the Apple II+ ROM", "apple2.rom", 12*1024, 0xf66f9c26);
|
||||||
break;
|
break;
|
||||||
case Target::Model::IIe:
|
case Target::Model::IIe:
|
||||||
rom_size += 3840;
|
rom_size += 3840;
|
||||||
rom_names.push_back("apple2eu-character.rom");
|
rom_descriptions.emplace_back(machine_name, "the Apple IIe character ROM", "apple2eu-character.rom", 4*1024, 0x816a86f1);
|
||||||
rom_names.push_back("apple2eu.rom");
|
rom_descriptions.emplace_back(machine_name, "the Apple IIe ROM", "apple2eu.rom", 32*1024, 0xe12be18d);
|
||||||
break;
|
break;
|
||||||
case Target::Model::EnhancedIIe:
|
case Target::Model::EnhancedIIe:
|
||||||
rom_size += 3840;
|
rom_size += 3840;
|
||||||
rom_names.push_back("apple2e-character.rom");
|
rom_descriptions.emplace_back(machine_name, "the Enhanced Apple IIe character ROM", "apple2e-character.rom", 4*1024, 0x2651014d);
|
||||||
rom_names.push_back("apple2e.rom");
|
rom_descriptions.emplace_back(machine_name, "the Enhanced Apple IIe ROM", "apple2e.rom", 32*1024, 0x65989942);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const auto roms = rom_fetcher("AppleII", rom_names);
|
const auto roms = rom_fetcher(rom_descriptions);
|
||||||
|
|
||||||
|
// Try to install a Disk II card now, before checking the ROM list,
|
||||||
|
// to make sure that Disk II dependencies have been communicated.
|
||||||
|
if(target.disk_controller != Target::DiskController::None) {
|
||||||
|
// Apple recommended slot 6 for the (first) Disk II.
|
||||||
|
install_card(6, new Apple::II::DiskIICard(rom_fetcher, target.disk_controller == Target::DiskController::SixteenSector));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, check and move the ROMs.
|
||||||
if(!roms[0] || !roms[1]) {
|
if(!roms[0] || !roms[1]) {
|
||||||
throw ROMMachine::Error::MissingROMs;
|
throw ROMMachine::Error::MissingROMs;
|
||||||
}
|
}
|
||||||
@ -382,11 +391,6 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
|||||||
|
|
||||||
video_.set_character_rom(*roms[0]);
|
video_.set_character_rom(*roms[0]);
|
||||||
|
|
||||||
if(target.disk_controller != Target::DiskController::None) {
|
|
||||||
// Apple recommended slot 6 for the (first) Disk II.
|
|
||||||
install_card(6, new Apple::II::DiskIICard(rom_fetcher, target.disk_controller == Target::DiskController::SixteenSector));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the default memory blocks. On a II or II+ these values will never change.
|
// Set up the default memory blocks. On a II or II+ these values will never change.
|
||||||
// On a IIe they'll be affected by selection of auxiliary RAM.
|
// On a IIe they'll be affected by selection of auxiliary RAM.
|
||||||
set_main_paging();
|
set_main_paging();
|
||||||
|
@ -11,12 +11,22 @@
|
|||||||
using namespace Apple::II;
|
using namespace Apple::II;
|
||||||
|
|
||||||
DiskIICard::DiskIICard(const ROMMachine::ROMFetcher &rom_fetcher, bool is_16_sector) : diskii_(2045454) {
|
DiskIICard::DiskIICard(const ROMMachine::ROMFetcher &rom_fetcher, bool is_16_sector) : diskii_(2045454) {
|
||||||
const auto roms = rom_fetcher(
|
std::vector<std::unique_ptr<std::vector<uint8_t>>> roms;
|
||||||
"DiskII",
|
if(is_16_sector) {
|
||||||
{
|
roms = rom_fetcher({
|
||||||
is_16_sector ? "boot-16.rom" : "boot-13.rom",
|
{"DiskII", "the Disk II 16-sector boot ROM", "boot-16.rom", 256, 0xce7144f6},
|
||||||
is_16_sector ? "state-machine-16.rom" : "state-machine-13.rom"
|
{"DiskII", "the Disk II 16-sector state machine ROM", "state-machine-16.rom", 256, { 0x9796a238, 0xb72a2c70 } }
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
roms = rom_fetcher({
|
||||||
|
{"DiskII", "the Disk II 13-sector boot ROM", "boot-13.rom", 256, 0xd34eb2ff},
|
||||||
|
{"DiskII", "the Disk II 13-sector state machine ROM", "state-machine-13.rom", 256, 0x62e22620 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(!roms[0] || !roms[1]) {
|
||||||
|
throw ROMMachine::Error::MissingROMs;
|
||||||
|
}
|
||||||
|
|
||||||
boot_ = std::move(*roms[0]);
|
boot_ = std::move(*roms[0]);
|
||||||
diskii_.set_state_machine(*roms[1]);
|
diskii_.set_state_machine(*roms[1]);
|
||||||
set_select_constraints(None);
|
set_select_constraints(None);
|
||||||
|
@ -70,33 +70,35 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
// Select a ROM name and determine the proper ROM and RAM sizes
|
// Select a ROM name and determine the proper ROM and RAM sizes
|
||||||
// based on the machine model.
|
// based on the machine model.
|
||||||
using Model = Analyser::Static::Macintosh::Target::Model;
|
using Model = Analyser::Static::Macintosh::Target::Model;
|
||||||
std::string rom_name;
|
const std::string machine_name = "Macintosh";
|
||||||
uint32_t ram_size, rom_size;
|
uint32_t ram_size, rom_size;
|
||||||
|
std::vector<ROMMachine::ROM> rom_descriptions;
|
||||||
switch(model) {
|
switch(model) {
|
||||||
default:
|
default:
|
||||||
case Model::Mac128k:
|
case Model::Mac128k:
|
||||||
ram_size = 128*1024;
|
ram_size = 128*1024;
|
||||||
rom_size = 64*1024;
|
rom_size = 64*1024;
|
||||||
rom_name = "mac128k.rom";
|
rom_descriptions.emplace_back(machine_name, "the Macintosh 128k ROM", "mac128k.rom", 64*1024, 0x6d0c8a28);
|
||||||
break;
|
break;
|
||||||
case Model::Mac512k:
|
case Model::Mac512k:
|
||||||
ram_size = 512*1024;
|
ram_size = 512*1024;
|
||||||
rom_size = 64*1024;
|
rom_size = 64*1024;
|
||||||
rom_name = "mac512k.rom";
|
rom_descriptions.emplace_back(machine_name, "the Macintosh 512k ROM", "mac512k.rom", 64*1024, 0xcf759e0d);
|
||||||
break;
|
break;
|
||||||
case Model::Mac512ke:
|
case Model::Mac512ke:
|
||||||
case Model::MacPlus:
|
case Model::MacPlus: {
|
||||||
ram_size = 512*1024;
|
ram_size = 512*1024;
|
||||||
rom_size = 128*1024;
|
rom_size = 128*1024;
|
||||||
rom_name = "macplus.rom";
|
const std::initializer_list<uint32_t> crc32s = { 0x4fa5b399, 0x7cacd18f, 0xb2102e8e };
|
||||||
break;
|
rom_descriptions.emplace_back(machine_name, "the Macintosh Plus ROM", "macplus.rom", 128*1024, crc32s);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
ram_mask_ = (ram_size >> 1) - 1;
|
ram_mask_ = (ram_size >> 1) - 1;
|
||||||
rom_mask_ = (rom_size >> 1) - 1;
|
rom_mask_ = (rom_size >> 1) - 1;
|
||||||
video_.set_ram_mask(ram_mask_);
|
video_.set_ram_mask(ram_mask_);
|
||||||
|
|
||||||
// Grab a copy of the ROM and convert it into big-endian data.
|
// Grab a copy of the ROM and convert it into big-endian data.
|
||||||
const auto roms = rom_fetcher("Macintosh", { rom_name });
|
const auto roms = rom_fetcher(rom_descriptions);
|
||||||
if(!roms[0]) {
|
if(!roms[0]) {
|
||||||
throw ROMMachine::Error::MissingROMs;
|
throw ROMMachine::Error::MissingROMs;
|
||||||
}
|
}
|
||||||
|
@ -131,8 +131,7 @@ class ConcreteMachine:
|
|||||||
joysticks_.emplace_back(new Joystick);
|
joysticks_.emplace_back(new Joystick);
|
||||||
|
|
||||||
const auto roms = rom_fetcher(
|
const auto roms = rom_fetcher(
|
||||||
"ColecoVision",
|
{ {"ColecoVision", "the ColecoVision BIOS", "coleco.rom", 8*1024, 0x3aa93ef3} });
|
||||||
{ "coleco.rom" });
|
|
||||||
|
|
||||||
if(!roms[0]) {
|
if(!roms[0]) {
|
||||||
throw ROMMachine::Error::MissingROMs;
|
throw ROMMachine::Error::MissingROMs;
|
||||||
|
@ -39,13 +39,20 @@ MachineBase::MachineBase(Personality personality, const ROMMachine::ROMFetcher &
|
|||||||
// attach the only drive there is
|
// attach the only drive there is
|
||||||
set_drive(drive_);
|
set_drive(drive_);
|
||||||
|
|
||||||
std::string rom_name;
|
std::string device_name;
|
||||||
|
uint32_t crc = 0;
|
||||||
switch(personality) {
|
switch(personality) {
|
||||||
case Personality::C1540: rom_name = "1540.bin"; break;
|
case Personality::C1540:
|
||||||
case Personality::C1541: rom_name = "1541.bin"; break;
|
device_name = "1540";
|
||||||
|
crc = 0x718d42b1;
|
||||||
|
break;
|
||||||
|
case Personality::C1541:
|
||||||
|
device_name = "1541";
|
||||||
|
crc = 0xfb760019;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto roms = rom_fetcher("Commodore1540", {rom_name});
|
auto roms = rom_fetcher({ {"Commodore1540", "the " + device_name + " ROM", device_name + ".bin", 16*1024, crc} });
|
||||||
if(!roms[0]) {
|
if(!roms[0]) {
|
||||||
throw ROMMachine::Error::MissingROMs;
|
throw ROMMachine::Error::MissingROMs;
|
||||||
}
|
}
|
||||||
|
@ -323,31 +323,34 @@ 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" };
|
const std::string machine_name = "Vic20";
|
||||||
|
std::vector<ROMMachine::ROM> rom_names = {
|
||||||
|
{machine_name, "the VIC-20 BASIC ROM", "basic.bin", 8*1024, 0xdb4c43c1}
|
||||||
|
};
|
||||||
switch(target.region) {
|
switch(target.region) {
|
||||||
default:
|
default:
|
||||||
rom_names.push_back("characters-english.bin");
|
rom_names.emplace_back(machine_name, "the English-language VIC-20 character ROM", "characters-english.bin", 4*1024, 0x83e032a6);
|
||||||
rom_names.push_back("kernel-pal.bin");
|
rom_names.emplace_back(machine_name, "the English-language PAL VIC-20 kernel ROM", "kernel-pal.bin", 8*1024, 0x4be07cb4);
|
||||||
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(machine_name, "the English-language VIC-20 character ROM", "characters-english.bin", 4*1024, 0x83e032a6);
|
||||||
rom_names.push_back("kernel-ntsc.bin");
|
rom_names.emplace_back(machine_name, "the English-language NTSC VIC-20 kernel ROM", "kernel-ntsc.bin", 8*1024, 0xe5e7c174);
|
||||||
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(machine_name, "the Danish VIC-20 character ROM", "characters-danish.bin", 4*1024, 0x7fc11454);
|
||||||
rom_names.push_back("kernel-danish.bin");
|
rom_names.emplace_back(machine_name, "the Danish VIC-20 kernel ROM", "kernel-danish.bin", 8*1024, 0x02adaf16);
|
||||||
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(machine_name, "the Japanese VIC-20 character ROM", "characters-japanese.bin", 4*1024, 0xfcfd8a4b);
|
||||||
rom_names.push_back("kernel-japanese.bin");
|
rom_names.emplace_back(machine_name, "the Japanese VIC-20 kernel ROM", "kernel-japanese.bin", 8*1024, 0x336900d7);
|
||||||
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(machine_name, "the Swedish VIC-20 character ROM", "characters-swedish.bin", 4*1024, 0xd808551d);
|
||||||
rom_names.push_back("kernel-japanese.bin");
|
rom_names.emplace_back(machine_name, "the Swedish VIC-20 kernel ROM", "kernel-swedish.bin", 8*1024, 0xb2a60662);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto roms = rom_fetcher("Vic20", rom_names);
|
const auto roms = rom_fetcher(rom_names);
|
||||||
|
|
||||||
for(const auto &rom: roms) {
|
for(const auto &rom: roms) {
|
||||||
if(!rom) {
|
if(!rom) {
|
||||||
|
@ -64,16 +64,20 @@ 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"};
|
const std::string machine_name = "Electron";
|
||||||
|
std::vector<ROMMachine::ROM> required_roms = {
|
||||||
|
{machine_name, "the Acorn BASIC II ROM", "basic.rom", 16*1024, 0x79434781},
|
||||||
|
{machine_name, "the Electron MOS ROM", "os.rom", 16*1024, 0xbf63fb1f}
|
||||||
|
};
|
||||||
if(target.has_adfs) {
|
if(target.has_adfs) {
|
||||||
rom_names.push_back("ADFS-E00_1.rom");
|
required_roms.emplace_back(machine_name, "the E00 ADFS ROM, first slot", "ADFS-E00_1.rom", 16*1024, 0x51523993);
|
||||||
rom_names.push_back("ADFS-E00_2.rom");
|
required_roms.emplace_back(machine_name, "the E00 ADFS ROM, second slot", "ADFS-E00_2.rom", 16*1024, 0x8d17de0e);
|
||||||
}
|
}
|
||||||
const size_t dfs_rom_position = rom_names.size();
|
const size_t dfs_rom_position = required_roms.size();
|
||||||
if(target.has_dfs) {
|
if(target.has_dfs) {
|
||||||
rom_names.push_back("DFS-1770-2.20.rom");
|
required_roms.emplace_back(machine_name, "the 1770 DFS ROM", "DFS-1770-2.20.rom", 16*1024, 0xf3dc9bc5);
|
||||||
}
|
}
|
||||||
const auto roms = rom_fetcher("Electron", rom_names);
|
const auto roms = rom_fetcher(required_roms);
|
||||||
|
|
||||||
for(const auto &rom: roms) {
|
for(const auto &rom: roms) {
|
||||||
if(!rom) {
|
if(!rom) {
|
||||||
|
@ -173,16 +173,20 @@ 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"};
|
const std::string machine_name = "MSX";
|
||||||
|
std::vector<ROMMachine::ROM> required_roms = {
|
||||||
|
{machine_name, "any MSX BIOS", "msx.rom", 32*1024, 0x94ee12f3}
|
||||||
|
};
|
||||||
|
|
||||||
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 */
|
||||||
uint8_t date_format = 1; /* 0 = Y/M/D, 1 = M/D/Y, 2 = D/M/Y */
|
uint8_t date_format = 1; /* 0 = Y/M/D, 1 = M/D/Y, 2 = D/M/Y */
|
||||||
uint8_t keyboard = 1; /* 0 = Japan, 1 = USA, 2 = France, 3 = UK, 4 = Germany, 5 = USSR, 6 = Spain */
|
uint8_t keyboard = 1; /* 0 = Japan, 1 = USA, 2 = France, 3 = UK, 4 = Germany, 5 = USSR, 6 = Spain */
|
||||||
|
|
||||||
|
// TODO: CRCs below are incomplete, at best.
|
||||||
switch(target.region) {
|
switch(target.region) {
|
||||||
case Target::Region::Japan:
|
case Target::Region::Japan:
|
||||||
rom_names.push_back("msx-japanese.rom");
|
required_roms.emplace_back(machine_name, "a Japanese MSX BIOS", "msx-japanese.rom", 32*1024, 0xee229390);
|
||||||
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
|
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
|
||||||
|
|
||||||
is_ntsc = true;
|
is_ntsc = true;
|
||||||
@ -190,7 +194,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");
|
required_roms.emplace_back(machine_name, "an American MSX BIOS", "msx-american.rom", 32*1024, 0);
|
||||||
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
|
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
|
||||||
|
|
||||||
is_ntsc = true;
|
is_ntsc = true;
|
||||||
@ -198,7 +202,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");
|
required_roms.emplace_back(machine_name, "a European MSX BIOS", "msx-european.rom", 32*1024, 0);
|
||||||
vdp_.set_tv_standard(TI::TMS::TVStandard::PAL);
|
vdp_.set_tv_standard(TI::TMS::TVStandard::PAL);
|
||||||
|
|
||||||
is_ntsc = false;
|
is_ntsc = false;
|
||||||
@ -211,10 +215,10 @@ class ConcreteMachine:
|
|||||||
// but failing that fall back on patching the main one.
|
// but failing that fall back on patching the main one.
|
||||||
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 = required_roms.size();
|
||||||
rom_names.push_back("disk.rom");
|
required_roms.emplace_back(machine_name, "the MSX-DOS ROM", "disk.rom", 16*1024, 0x721f61df);
|
||||||
}
|
}
|
||||||
const auto roms = rom_fetcher("MSX", rom_names);
|
const auto roms = rom_fetcher(required_roms);
|
||||||
|
|
||||||
if((!roms[0] && !roms[1]) || (target.has_disk_drive && !roms[2])) {
|
if((!roms[0] && !roms[1]) || (target.has_disk_drive && !roms[2])) {
|
||||||
throw ROMMachine::Error::MissingROMs;
|
throw ROMMachine::Error::MissingROMs;
|
||||||
|
@ -132,7 +132,12 @@ 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"});
|
// TODO: there's probably a million other versions of the Master System BIOS; try to build a
|
||||||
|
// CRC32 catalogue of those. So far:
|
||||||
|
//
|
||||||
|
// 0072ed54 = US/European BIOS 1.3
|
||||||
|
// 48d44a13 = Japanese BIOS 2.1
|
||||||
|
const auto roms = rom_fetcher({ {"MasterSystem", "the Master System BIOS", "bios.sms", 8*1024, { 0x0072ed54, 0x48d44a13 } } });
|
||||||
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;
|
||||||
|
@ -228,19 +228,34 @@ 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"};
|
const std::string machine_name = "Oric";
|
||||||
|
std::vector<ROMMachine::ROM> rom_names = { {machine_name, "the Oric colour ROM", "colour.rom", 128, 0xd50fca65} };
|
||||||
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:
|
||||||
case Analyser::Static::Oric::Target::ROM::BASIC11: rom_names.push_back("basic11.rom"); break;
|
rom_names.emplace_back(machine_name, "Oric BASIC 1.0", "basic10.rom", 16*1024, 0xf18710b4);
|
||||||
case Analyser::Static::Oric::Target::ROM::Pravetz: rom_names.push_back("pravetz.rom"); break;
|
break;
|
||||||
|
case Analyser::Static::Oric::Target::ROM::BASIC11:
|
||||||
|
rom_names.emplace_back(machine_name, "Oric BASIC 1.1", "basic11.rom", 16*1024, 0xc3a92bef);
|
||||||
|
break;
|
||||||
|
case Analyser::Static::Oric::Target::ROM::Pravetz:
|
||||||
|
rom_names.emplace_back(machine_name, "Pravetz BASIC", "pravetz.rom", 16*1024, 0x58079502);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
size_t diskii_state_machine_index = 0;
|
||||||
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:
|
||||||
case Analyser::Static::Oric::Target::DiskInterface::Pravetz: rom_names.push_back("8dos.rom"); break;
|
rom_names.emplace_back(machine_name, "the ORIC Microdisc ROM", "microdisc.rom", 8*1024, 0xa9664a9c);
|
||||||
|
break;
|
||||||
|
case Analyser::Static::Oric::Target::DiskInterface::Pravetz:
|
||||||
|
rom_names.emplace_back(machine_name, "the 8DOS boot ROM", "8dos.rom", 512, 0x49a74c06);
|
||||||
|
// These ROM details are coupled with those in the DiskIICard.
|
||||||
|
diskii_state_machine_index = rom_names.size();
|
||||||
|
rom_names.push_back({"DiskII", "the Disk II 16-sector state machine ROM", "state-machine-16.rom", 256, { 0x9796a238, 0xb72a2c70 }});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto roms = rom_fetcher("Oric", rom_names);
|
const auto roms = rom_fetcher(rom_names);
|
||||||
|
|
||||||
for(std::size_t index = 0; index < roms.size(); ++index) {
|
for(std::size_t index = 0; index < roms.size(); ++index) {
|
||||||
if(!roms[index]) {
|
if(!roms[index]) {
|
||||||
@ -261,11 +276,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"});
|
diskii_.set_state_machine(*roms[diskii_state_machine_index]);
|
||||||
if(!state_machine_rom[0]) {
|
|
||||||
throw ROMMachine::Error::MissingROMs;
|
|
||||||
}
|
|
||||||
diskii_.set_state_machine(*state_machine_rom[0]);
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,15 +16,41 @@
|
|||||||
|
|
||||||
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 {
|
||||||
|
/// The machine with which this ROM is associated, in a form that is safe for using as
|
||||||
|
/// part of a file name.
|
||||||
|
std::string machine_name;
|
||||||
|
/// A descriptive name for this ROM, suitable for use in a bullet-point list, a bracket
|
||||||
|
/// clause, etc, e.g. "the 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;
|
||||||
|
|
||||||
|
ROM(std::string machine_name, std::string descriptive_name, std::string file_name, size_t size, uint32_t crc32) :
|
||||||
|
machine_name(machine_name), descriptive_name(descriptive_name), file_name(file_name), size(size), crc32s({crc32}) {}
|
||||||
|
ROM(std::string machine_name, std::string descriptive_name, std::string file_name, size_t size, std::initializer_list<uint32_t> crc32s) :
|
||||||
|
machine_name(machine_name), descriptive_name(descriptive_name), file_name(file_name), size(size), crc32s(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.
|
||||||
|
|
||||||
The caller will supply the idiomatic name of the machine plus a vector of the names of ROM files that it expects
|
The caller will supply a vector of the names of ROM files that it would like to inspect. The recevier should
|
||||||
to be present. The recevier should return a vector of unique_ptrs that either contain the contents of the
|
return a vector of unique_ptrs that either contain the contents of the ROM from @c names that corresponds by
|
||||||
ROM from @c names that corresponds by index, or else are the nullptr
|
index, or else are @c 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::vector<ROM> &roms)> ROMFetcher;
|
||||||
|
|
||||||
enum class Error {
|
enum class Error {
|
||||||
MissingROMs
|
MissingROMs
|
||||||
|
@ -76,7 +76,11 @@ 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 =
|
||||||
|
use_zx81_rom ?
|
||||||
|
rom_fetcher({ {"ZX8081", "the ZX81 BASIC ROM", "zx81.rom", 8 * 1024, 0x4b1dd6eb} }) :
|
||||||
|
rom_fetcher({ {"ZX8081", "the ZX80 BASIC ROM", "zx80.rom", 4 * 1024, 0x4c7fc597} });
|
||||||
|
|
||||||
if(!roms[0]) throw ROMMachine::Error::MissingROMs;
|
if(!roms[0]) throw ROMMachine::Error::MissingROMs;
|
||||||
|
|
||||||
rom_ = std::move(*roms[0]);
|
rom_ = std::move(*roms[0]);
|
||||||
|
@ -145,7 +145,6 @@
|
|||||||
4B1EDB451E39A0AC009D6819 /* chip.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B1EDB431E39A0AC009D6819 /* chip.png */; };
|
4B1EDB451E39A0AC009D6819 /* chip.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B1EDB431E39A0AC009D6819 /* chip.png */; };
|
||||||
4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2A332B1DB86821002876E3 /* OricOptions.xib */; };
|
4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2A332B1DB86821002876E3 /* OricOptions.xib */; };
|
||||||
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; };
|
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; };
|
||||||
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53961D117D36003C6002 /* CSMachine.mm */; };
|
|
||||||
4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; };
|
4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; };
|
||||||
4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */; };
|
4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */; };
|
||||||
4B2BFC5F1D613E0200BA3AA9 /* TapePRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */; };
|
4B2BFC5F1D613E0200BA3AA9 /* TapePRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */; };
|
||||||
@ -633,7 +632,6 @@
|
|||||||
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
|
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
|
||||||
4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; };
|
4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; };
|
||||||
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */; };
|
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */; };
|
||||||
4BC9DF451D044FCA00F44158 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; };
|
|
||||||
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
|
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
|
||||||
4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */; };
|
4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */; };
|
||||||
4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCA6CC61D9DD9F000C2D7B2 /* CommodoreROM.cpp */; };
|
4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCA6CC61D9DD9F000C2D7B2 /* CommodoreROM.cpp */; };
|
||||||
@ -666,6 +664,11 @@
|
|||||||
4BD67DCC209BE4D700AB2146 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCA209BE4D600AB2146 /* StaticAnalyser.cpp */; };
|
4BD67DCC209BE4D700AB2146 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCA209BE4D600AB2146 /* StaticAnalyser.cpp */; };
|
||||||
4BD67DD0209BF27B00AB2146 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCE209BF27B00AB2146 /* Encoder.cpp */; };
|
4BD67DD0209BF27B00AB2146 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCE209BF27B00AB2146 /* Encoder.cpp */; };
|
||||||
4BD67DD1209BF27B00AB2146 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCE209BF27B00AB2146 /* Encoder.cpp */; };
|
4BD67DD1209BF27B00AB2146 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCE209BF27B00AB2146 /* Encoder.cpp */; };
|
||||||
|
4BDA00DA22E60EE300AC3CD0 /* ROMRequester.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BDA00D922E60EE300AC3CD0 /* ROMRequester.xib */; };
|
||||||
|
4BDA00DD22E622C200AC3CD0 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; };
|
||||||
|
4BDA00E022E644AF00AC3CD0 /* CSROMReceiverView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDA00DF22E644AF00AC3CD0 /* CSROMReceiverView.m */; };
|
||||||
|
4BDA00E422E663B900AC3CD0 /* NSData+CRC32.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDA00E222E663B900AC3CD0 /* NSData+CRC32.m */; };
|
||||||
|
4BDA00E622E699B000AC3CD0 /* CSMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53961D117D36003C6002 /* CSMachine.mm */; };
|
||||||
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539A1D117D36003C6002 /* CSAtari2600.mm */; };
|
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539A1D117D36003C6002 /* CSAtari2600.mm */; };
|
||||||
4BDB61EC203285AE0048AF91 /* Atari2600OptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */; };
|
4BDB61EC203285AE0048AF91 /* Atari2600OptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */; };
|
||||||
4BDDBA991EF3451200347E61 /* Z80MachineCycleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */; };
|
4BDDBA991EF3451200347E61 /* Z80MachineCycleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */; };
|
||||||
@ -1473,6 +1476,11 @@
|
|||||||
4BD67DCE209BF27B00AB2146 /* Encoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Encoder.cpp; sourceTree = "<group>"; };
|
4BD67DCE209BF27B00AB2146 /* Encoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Encoder.cpp; sourceTree = "<group>"; };
|
||||||
4BD67DCF209BF27B00AB2146 /* Encoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Encoder.hpp; sourceTree = "<group>"; };
|
4BD67DCF209BF27B00AB2146 /* Encoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Encoder.hpp; sourceTree = "<group>"; };
|
||||||
4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = "<group>"; };
|
4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = "<group>"; };
|
||||||
|
4BDA00D922E60EE300AC3CD0 /* ROMRequester.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ROMRequester.xib; sourceTree = "<group>"; };
|
||||||
|
4BDA00DE22E644AF00AC3CD0 /* CSROMReceiverView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSROMReceiverView.h; sourceTree = "<group>"; };
|
||||||
|
4BDA00DF22E644AF00AC3CD0 /* CSROMReceiverView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSROMReceiverView.m; sourceTree = "<group>"; };
|
||||||
|
4BDA00E222E663B900AC3CD0 /* NSData+CRC32.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+CRC32.m"; sourceTree = "<group>"; };
|
||||||
|
4BDA00E322E663B900AC3CD0 /* NSData+CRC32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+CRC32.h"; sourceTree = "<group>"; };
|
||||||
4BDB3D8522833321002D3CEE /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = "<group>"; };
|
4BDB3D8522833321002D3CEE /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = "<group>"; };
|
||||||
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
|
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
|
||||||
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
|
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
|
||||||
@ -1736,13 +1744,15 @@
|
|||||||
4BBC34241D2208B100FFC9DF /* CSFastLoading.h */,
|
4BBC34241D2208B100FFC9DF /* CSFastLoading.h */,
|
||||||
4B2A53951D117D36003C6002 /* CSMachine.h */,
|
4B2A53951D117D36003C6002 /* CSMachine.h */,
|
||||||
4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */,
|
4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */,
|
||||||
4B98A05C1FFAD3F600ADF63B /* CSROMFetcher.hpp */,
|
|
||||||
4B2A53971D117D36003C6002 /* KeyCodes.h */,
|
4B2A53971D117D36003C6002 /* KeyCodes.h */,
|
||||||
4B8FE2251DA1DE2D0090D3CE /* NSBundle+DataResource.h */,
|
4B8FE2251DA1DE2D0090D3CE /* NSBundle+DataResource.h */,
|
||||||
|
4BDA00E322E663B900AC3CD0 /* NSData+CRC32.h */,
|
||||||
4BA61EAE1D91515900B3C876 /* NSData+StdVector.h */,
|
4BA61EAE1D91515900B3C876 /* NSData+StdVector.h */,
|
||||||
4B98A05D1FFAD3F600ADF63B /* CSROMFetcher.mm */,
|
4B98A05C1FFAD3F600ADF63B /* CSROMFetcher.hpp */,
|
||||||
4B8FE2261DA1DE2D0090D3CE /* NSBundle+DataResource.m */,
|
4B8FE2261DA1DE2D0090D3CE /* NSBundle+DataResource.m */,
|
||||||
|
4BDA00E222E663B900AC3CD0 /* NSData+CRC32.m */,
|
||||||
4B2A53961D117D36003C6002 /* CSMachine.mm */,
|
4B2A53961D117D36003C6002 /* CSMachine.mm */,
|
||||||
|
4B98A05D1FFAD3F600ADF63B /* CSROMFetcher.mm */,
|
||||||
4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */,
|
4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */,
|
||||||
4B643F3B1D77AD6D00D431D6 /* StaticAnalyser */,
|
4B643F3B1D77AD6D00D431D6 /* StaticAnalyser */,
|
||||||
4B2A53981D117D36003C6002 /* Wrappers */,
|
4B2A53981D117D36003C6002 /* Wrappers */,
|
||||||
@ -2944,6 +2954,7 @@
|
|||||||
4BE5F85A1C3E1C2500C43F01 /* Resources */,
|
4BE5F85A1C3E1C2500C43F01 /* Resources */,
|
||||||
4BD5F1961D1352A000631CD1 /* Updater */,
|
4BD5F1961D1352A000631CD1 /* Updater */,
|
||||||
4B55CE5A1C3B7D6F0093A61B /* Views */,
|
4B55CE5A1C3B7D6F0093A61B /* Views */,
|
||||||
|
4BDA00DB22E60EE900AC3CD0 /* ROMRequester */,
|
||||||
);
|
);
|
||||||
path = "Clock Signal";
|
path = "Clock Signal";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -3297,6 +3308,16 @@
|
|||||||
name = 8255;
|
name = 8255;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4BDA00DB22E60EE900AC3CD0 /* ROMRequester */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4BDA00D922E60EE300AC3CD0 /* ROMRequester.xib */,
|
||||||
|
4BDA00DE22E644AF00AC3CD0 /* CSROMReceiverView.h */,
|
||||||
|
4BDA00DF22E644AF00AC3CD0 /* CSROMReceiverView.m */,
|
||||||
|
);
|
||||||
|
path = ROMRequester;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4BE5F85A1C3E1C2500C43F01 /* Resources */ = {
|
4BE5F85A1C3E1C2500C43F01 /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -3544,6 +3565,7 @@
|
|||||||
4BB73EA91B587A5100552FC2 /* Assets.xcassets in Resources */,
|
4BB73EA91B587A5100552FC2 /* Assets.xcassets in Resources */,
|
||||||
4B79E4451E3AF38600141F11 /* floppy35.png in Resources */,
|
4B79E4451E3AF38600141F11 /* floppy35.png in Resources */,
|
||||||
4B55DD8420DF06680043F2E5 /* MachinePicker.xib in Resources */,
|
4B55DD8420DF06680043F2E5 /* MachinePicker.xib in Resources */,
|
||||||
|
4BDA00DA22E60EE300AC3CD0 /* ROMRequester.xib in Resources */,
|
||||||
4BC5FC3020CDDDEF00410AA0 /* AppleIIOptions.xib in Resources */,
|
4BC5FC3020CDDDEF00410AA0 /* AppleIIOptions.xib in Resources */,
|
||||||
4B1EDB451E39A0AC009D6819 /* chip.png in Resources */,
|
4B1EDB451E39A0AC009D6819 /* chip.png in Resources */,
|
||||||
4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */,
|
4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */,
|
||||||
@ -3555,7 +3577,6 @@
|
|||||||
4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */,
|
4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */,
|
||||||
4B8FE21D1DA19D5F0090D3CE /* QuickLoadCompositeOptions.xib in Resources */,
|
4B8FE21D1DA19D5F0090D3CE /* QuickLoadCompositeOptions.xib in Resources */,
|
||||||
4B79E4461E3AF38600141F11 /* floppy525.png in Resources */,
|
4B79E4461E3AF38600141F11 /* floppy525.png in Resources */,
|
||||||
4BC9DF451D044FCA00F44158 /* ROMImages in Resources */,
|
|
||||||
4BEEE6BD20DC72EB003723BF /* CompositeOptions.xib in Resources */,
|
4BEEE6BD20DC72EB003723BF /* CompositeOptions.xib in Resources */,
|
||||||
4B1497981EE4B97F00CE2596 /* ZX8081Options.xib in Resources */,
|
4B1497981EE4B97F00CE2596 /* ZX8081Options.xib in Resources */,
|
||||||
);
|
);
|
||||||
@ -3610,6 +3631,7 @@
|
|||||||
4BB299B91B587D8400A49093 /* rorz in Resources */,
|
4BB299B91B587D8400A49093 /* rorz in Resources */,
|
||||||
4BB299F61B587D8400A49093 /* tsxn in Resources */,
|
4BB299F61B587D8400A49093 /* tsxn in Resources */,
|
||||||
4BB298F11B587D8400A49093 /* start in Resources */,
|
4BB298F11B587D8400A49093 /* start in Resources */,
|
||||||
|
4BDA00DD22E622C200AC3CD0 /* ROMImages in Resources */,
|
||||||
4BB299061B587D8400A49093 /* asla in Resources */,
|
4BB299061B587D8400A49093 /* asla in Resources */,
|
||||||
4BB299901B587D8400A49093 /* lsrn in Resources */,
|
4BB299901B587D8400A49093 /* lsrn in Resources */,
|
||||||
4BB298FE1B587D8400A49093 /* anday in Resources */,
|
4BB298FE1B587D8400A49093 /* anday in Resources */,
|
||||||
@ -4067,6 +4089,7 @@
|
|||||||
4B595FAD2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */,
|
4B595FAD2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */,
|
||||||
4B1497921EE4B5A800CE2596 /* ZX8081.cpp in Sources */,
|
4B1497921EE4B5A800CE2596 /* ZX8081.cpp in Sources */,
|
||||||
4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */,
|
4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */,
|
||||||
|
4BDA00E422E663B900AC3CD0 /* NSData+CRC32.m in Sources */,
|
||||||
4BB4BFB022A42F290069048D /* MacintoshIMG.cpp in Sources */,
|
4BB4BFB022A42F290069048D /* MacintoshIMG.cpp in Sources */,
|
||||||
4B05401E219D1618001BF69C /* ScanTarget.cpp in Sources */,
|
4B05401E219D1618001BF69C /* ScanTarget.cpp in Sources */,
|
||||||
4B4518861F75E91A00926311 /* MFMDiskController.cpp in Sources */,
|
4B4518861F75E91A00926311 /* MFMDiskController.cpp in Sources */,
|
||||||
@ -4099,6 +4122,7 @@
|
|||||||
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */,
|
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */,
|
||||||
4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */,
|
4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */,
|
||||||
4B7913CC1DFCD80E00175A82 /* Video.cpp in Sources */,
|
4B7913CC1DFCD80E00175A82 /* Video.cpp in Sources */,
|
||||||
|
4BDA00E622E699B000AC3CD0 /* CSMachine.mm in Sources */,
|
||||||
4B4518831F75E91A00926311 /* PCMTrack.cpp in Sources */,
|
4B4518831F75E91A00926311 /* PCMTrack.cpp in Sources */,
|
||||||
4B45189F1F75FD1C00926311 /* AcornADF.cpp in Sources */,
|
4B45189F1F75FD1C00926311 /* AcornADF.cpp in Sources */,
|
||||||
4B7136911F789C93008B8ED9 /* SegmentParser.cpp in Sources */,
|
4B7136911F789C93008B8ED9 /* SegmentParser.cpp in Sources */,
|
||||||
@ -4120,6 +4144,7 @@
|
|||||||
4B4518851F75E91A00926311 /* DiskController.cpp in Sources */,
|
4B4518851F75E91A00926311 /* DiskController.cpp in Sources */,
|
||||||
4B8334841F5DA0360097E338 /* Z80Storage.cpp in Sources */,
|
4B8334841F5DA0360097E338 /* Z80Storage.cpp in Sources */,
|
||||||
4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */,
|
4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */,
|
||||||
|
4BDA00E022E644AF00AC3CD0 /* CSROMReceiverView.m in Sources */,
|
||||||
4BD191F42191180E0042E144 /* ScanTarget.cpp in Sources */,
|
4BD191F42191180E0042E144 /* ScanTarget.cpp in Sources */,
|
||||||
4BCD634922D6756400F567F1 /* MacintoshDoubleDensityDrive.cpp in Sources */,
|
4BCD634922D6756400F567F1 /* MacintoshDoubleDensityDrive.cpp in Sources */,
|
||||||
4B0F94FE208C1A1600FE41D9 /* NIB.cpp in Sources */,
|
4B0F94FE208C1A1600FE41D9 /* NIB.cpp in Sources */,
|
||||||
@ -4193,7 +4218,6 @@
|
|||||||
4BF437EE209D0F7E008CBD6B /* SegmentParser.cpp in Sources */,
|
4BF437EE209D0F7E008CBD6B /* SegmentParser.cpp in Sources */,
|
||||||
4B8334861F5DA3780097E338 /* 6502Storage.cpp in Sources */,
|
4B8334861F5DA3780097E338 /* 6502Storage.cpp in Sources */,
|
||||||
4B8FE2271DA1DE2D0090D3CE /* NSBundle+DataResource.m in Sources */,
|
4B8FE2271DA1DE2D0090D3CE /* NSBundle+DataResource.m in Sources */,
|
||||||
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,
|
|
||||||
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */,
|
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */,
|
||||||
4B55DD8320DF06680043F2E5 /* MachinePicker.swift in Sources */,
|
4B55DD8320DF06680043F2E5 /* MachinePicker.swift in Sources */,
|
||||||
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
|
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
|
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="450"/>
|
<rect key="frame" x="0.0" y="0.0" width="600" height="450"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<openGLView hidden="YES" useAuxiliaryDepthBufferStencil="NO" allowOffline="YES" wantsBestResolutionOpenGLSurface="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DEG-fq-cjd" customClass="CSOpenGLView">
|
<openGLView hidden="YES" wantsLayer="YES" useAuxiliaryDepthBufferStencil="NO" allowOffline="YES" wantsBestResolutionOpenGLSurface="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DEG-fq-cjd" customClass="CSOpenGLView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="450"/>
|
<rect key="frame" x="0.0" y="0.0" width="600" height="450"/>
|
||||||
</openGLView>
|
</openGLView>
|
||||||
</subviews>
|
</subviews>
|
||||||
@ -36,6 +36,11 @@
|
|||||||
<constraint firstItem="DEG-fq-cjd" firstAttribute="width" secondItem="gIp-Ho-8D9" secondAttribute="width" id="mYS-bH-DST"/>
|
<constraint firstItem="DEG-fq-cjd" firstAttribute="width" secondItem="gIp-Ho-8D9" secondAttribute="width" id="mYS-bH-DST"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
<userDefinedRuntimeAttributes>
|
||||||
|
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
|
||||||
|
<color key="value" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</userDefinedRuntimeAttribute>
|
||||||
|
</userDefinedRuntimeAttributes>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="delegate" destination="-2" id="0bl-1N-x8E"/>
|
<outlet property="delegate" destination="-2" id="0bl-1N-x8E"/>
|
||||||
<outlet property="initialFirstResponder" destination="DEG-fq-cjd" id="9RI-Kx-QeN"/>
|
<outlet property="initialFirstResponder" destination="DEG-fq-cjd" id="9RI-Kx-QeN"/>
|
||||||
|
@ -10,10 +10,13 @@
|
|||||||
|
|
||||||
#import "CSStaticAnalyser.h"
|
#import "CSStaticAnalyser.h"
|
||||||
|
|
||||||
#import "CSOpenGLView.h"
|
|
||||||
#import "CSAudioQueue.h"
|
#import "CSAudioQueue.h"
|
||||||
|
#import "CSOpenGLView.h"
|
||||||
|
#import "CSROMReceiverView.h"
|
||||||
|
|
||||||
#import "CSBestEffortUpdater.h"
|
#import "CSBestEffortUpdater.h"
|
||||||
#import "CSJoystickManager.h"
|
#import "CSJoystickManager.h"
|
||||||
|
|
||||||
|
#import "NSData+CRC32.h"
|
||||||
|
|
||||||
#include "KeyCodes.h"
|
#include "KeyCodes.h"
|
||||||
|
@ -16,7 +16,8 @@ class MachineDocument:
|
|||||||
CSOpenGLViewDelegate,
|
CSOpenGLViewDelegate,
|
||||||
CSOpenGLViewResponderDelegate,
|
CSOpenGLViewResponderDelegate,
|
||||||
CSBestEffortUpdaterDelegate,
|
CSBestEffortUpdaterDelegate,
|
||||||
CSAudioQueueDelegate
|
CSAudioQueueDelegate,
|
||||||
|
CSROMReciverViewDelegate
|
||||||
{
|
{
|
||||||
fileprivate let actionLock = NSLock()
|
fileprivate let actionLock = NSLock()
|
||||||
fileprivate let drawLock = NSLock()
|
fileprivate let drawLock = NSLock()
|
||||||
@ -152,12 +153,27 @@ class MachineDocument:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: configuring
|
// MARK: configuring
|
||||||
|
fileprivate var missingROMs: [CSMissingROM] = []
|
||||||
|
fileprivate var selectedMachine: CSStaticAnalyser?
|
||||||
|
|
||||||
func configureAs(_ analysis: CSStaticAnalyser) {
|
func configureAs(_ analysis: CSStaticAnalyser) {
|
||||||
if let machine = CSMachine(analyser: analysis) {
|
let missingROMs = NSMutableArray()
|
||||||
|
if let machine = CSMachine(analyser: analysis, missingROMs: missingROMs) {
|
||||||
|
self.selectedMachine = nil
|
||||||
self.machine = machine
|
self.machine = machine
|
||||||
self.optionsPanelNibName = analysis.optionsPanelNibName
|
self.optionsPanelNibName = analysis.optionsPanelNibName
|
||||||
setupMachineOutput()
|
setupMachineOutput()
|
||||||
setupActivityDisplay()
|
setupActivityDisplay()
|
||||||
|
} else {
|
||||||
|
// Store the selected machine and list of missing ROMs, and
|
||||||
|
// show the missing ROMs dialogue.
|
||||||
|
self.missingROMs = []
|
||||||
|
for untypedMissingROM in missingROMs {
|
||||||
|
self.missingROMs.append(untypedMissingROM as! CSMissingROM)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.selectedMachine = analysis
|
||||||
|
requestRoms()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,19 +319,173 @@ class MachineDocument:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: New machine creation
|
// MARK: New machine creation.
|
||||||
@IBOutlet var machinePicker: MachinePicker?
|
@IBOutlet var machinePicker: MachinePicker?
|
||||||
@IBOutlet var machinePickerPanel: NSWindow?
|
@IBOutlet var machinePickerPanel: NSWindow?
|
||||||
@IBAction func createMachine(_ sender: NSButton?) {
|
@IBAction func createMachine(_ sender: NSButton?) {
|
||||||
self.configureAs(machinePicker!.selectedMachine())
|
let selectedMachine = machinePicker!.selectedMachine()
|
||||||
machinePicker = nil
|
|
||||||
self.windowControllers[0].window?.endSheet(self.machinePickerPanel!)
|
self.windowControllers[0].window?.endSheet(self.machinePickerPanel!)
|
||||||
|
machinePicker = nil
|
||||||
|
self.configureAs(selectedMachine)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func cancelCreateMachine(_ sender: NSButton?) {
|
@IBAction func cancelCreateMachine(_ sender: NSButton?) {
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: User ROM provision.
|
||||||
|
@IBOutlet var romRequesterPanel: NSWindow?
|
||||||
|
@IBOutlet var romRequesterText: NSTextField?
|
||||||
|
@IBOutlet var romReceiverErrorField: NSTextField?
|
||||||
|
@IBOutlet var romReceiverView: CSROMReceiverView?
|
||||||
|
private var romRequestBaseText = ""
|
||||||
|
func requestRoms() {
|
||||||
|
// Load the ROM requester dialogue.
|
||||||
|
Bundle.main.loadNibNamed("ROMRequester", owner: self, topLevelObjects: nil)
|
||||||
|
self.romReceiverView!.delegate = self
|
||||||
|
self.romRequestBaseText = romRequesterText!.stringValue
|
||||||
|
romReceiverErrorField?.alphaValue = 0.0
|
||||||
|
|
||||||
|
// Populate the current absentee list.
|
||||||
|
populateMissingRomList()
|
||||||
|
|
||||||
|
// Show the thing.
|
||||||
|
self.windowControllers[0].window?.beginSheet(self.romRequesterPanel!, completionHandler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func cancelRequestROMs(_ sender: NSButton?) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func populateMissingRomList() {
|
||||||
|
// Fill in the missing details; first build a list of all the individual
|
||||||
|
// line items.
|
||||||
|
var requestLines: [String] = []
|
||||||
|
for missingROM in self.missingROMs {
|
||||||
|
if let descriptiveName = missingROM.descriptiveName {
|
||||||
|
requestLines.append("• " + descriptiveName)
|
||||||
|
} else {
|
||||||
|
requestLines.append("• " + missingROM.fileName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Suffix everything up to the penultimate line with a semicolon;
|
||||||
|
// the penultimate line with a semicolon and a conjunctive; the final
|
||||||
|
// line with a full stop.
|
||||||
|
for x in 0 ..< requestLines.count {
|
||||||
|
if x < requestLines.count - 2 {
|
||||||
|
requestLines[x].append(";")
|
||||||
|
} else if x < requestLines.count - 1 {
|
||||||
|
requestLines[x].append("; and")
|
||||||
|
} else {
|
||||||
|
requestLines[x].append(".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
romRequesterText!.stringValue = self.romRequestBaseText + requestLines.joined(separator: "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func romReceiverView(_ view: CSROMReceiverView, didReceiveFileAt URL: URL) {
|
||||||
|
// Test whether the file identified matches any of the currently missing ROMs.
|
||||||
|
// If so then remove that ROM from the missing list and update the request screen.
|
||||||
|
// If no ROMs are still missing, start the machine.
|
||||||
|
do {
|
||||||
|
let fileData = try Data(contentsOf: URL)
|
||||||
|
var didInstallRom = false
|
||||||
|
|
||||||
|
// Try to match by size first, CRC second. Accept that some ROMs may have
|
||||||
|
// some additional appended data. Arbitrarily allow them to be up to 10kb
|
||||||
|
// too large.
|
||||||
|
var index = 0
|
||||||
|
for missingROM in self.missingROMs {
|
||||||
|
if fileData.count >= missingROM.size && fileData.count < missingROM.size + 10*1024 {
|
||||||
|
// Trim to size.
|
||||||
|
let trimmedData = fileData[0 ..< missingROM.size]
|
||||||
|
|
||||||
|
// Get CRC.
|
||||||
|
if missingROM.crc32s.contains( (trimmedData as NSData).crc32 ) {
|
||||||
|
// This ROM matches; copy it into the application library,
|
||||||
|
// strike it from the missing ROM list and decide how to
|
||||||
|
// proceed.
|
||||||
|
let fileManager = FileManager.default
|
||||||
|
let targetPath = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
|
||||||
|
.appendingPathComponent("ROMImages")
|
||||||
|
.appendingPathComponent(missingROM.machineName)
|
||||||
|
let targetFile = targetPath
|
||||||
|
.appendingPathComponent(missingROM.fileName)
|
||||||
|
|
||||||
|
do {
|
||||||
|
try fileManager.createDirectory(atPath: targetPath.path, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
try trimmedData.write(to: targetFile)
|
||||||
|
} catch let error {
|
||||||
|
showRomReceiverError(error: "Couldn't write to application support directory: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.missingROMs.remove(at: index)
|
||||||
|
didInstallRom = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index = index + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if didInstallRom {
|
||||||
|
if self.missingROMs.count == 0 {
|
||||||
|
self.windowControllers[0].window?.endSheet(self.romRequesterPanel!)
|
||||||
|
configureAs(self.selectedMachine!)
|
||||||
|
} else {
|
||||||
|
populateMissingRomList()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showRomReceiverError(error: "Didn't recognise contents of \(URL.lastPathComponent)")
|
||||||
|
}
|
||||||
|
} catch let error {
|
||||||
|
showRomReceiverError(error: "Couldn't read file at \(URL.absoluteString): \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yucky ugliness follows; my experience as an iOS developer intersects poorly with
|
||||||
|
// NSAnimationContext hence the various stateful diplications below. isShowingError
|
||||||
|
// should be essentially a duplicate of the current alphaValue, and animationCount
|
||||||
|
// is to resolve my inability to figure out how to cancel scheduled animations.
|
||||||
|
private var errorText = ""
|
||||||
|
private var isShowingError = false
|
||||||
|
private var animationCount = 0
|
||||||
|
private func showRomReceiverError(error: String) {
|
||||||
|
// Set or append the new error.
|
||||||
|
if self.errorText.count > 0 {
|
||||||
|
self.errorText = self.errorText + "\n" + error
|
||||||
|
} else {
|
||||||
|
self.errorText = error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the new complete text.
|
||||||
|
romReceiverErrorField!.stringValue = self.errorText
|
||||||
|
|
||||||
|
if !isShowingError {
|
||||||
|
// Schedule the box's appearance.
|
||||||
|
NSAnimationContext.beginGrouping()
|
||||||
|
NSAnimationContext.current.duration = 0.1
|
||||||
|
romReceiverErrorField?.animator().alphaValue = 1.0
|
||||||
|
NSAnimationContext.endGrouping()
|
||||||
|
isShowingError = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule the box to disappear.
|
||||||
|
self.animationCount = self.animationCount + 1
|
||||||
|
let capturedAnimationCount = animationCount
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(2)) {
|
||||||
|
if self.animationCount == capturedAnimationCount {
|
||||||
|
NSAnimationContext.beginGrouping()
|
||||||
|
NSAnimationContext.current.duration = 1.0
|
||||||
|
self.romReceiverErrorField?.animator().alphaValue = 0.0
|
||||||
|
NSAnimationContext.endGrouping()
|
||||||
|
self.isShowingError = false
|
||||||
|
self.errorText = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Joystick-via-the-keyboard selection
|
// MARK: Joystick-via-the-keyboard selection
|
||||||
@IBAction func useKeyboardAsKeyboard(_ sender: NSMenuItem?) {
|
@IBAction func useKeyboardAsKeyboard(_ sender: NSMenuItem?) {
|
||||||
machine.inputMode = .keyboard
|
machine.inputMode = .keyboard
|
||||||
|
@ -509,6 +509,10 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>CFBundleTypeIconFile</key>
|
<key>CFBundleTypeIconFile</key>
|
||||||
<string>floppy35</string>
|
<string>floppy35</string>
|
||||||
|
<key>CFBundleTypeMIMETypes</key>
|
||||||
|
<array>
|
||||||
|
<string>application/x-apple-diskimage</string>
|
||||||
|
</array>
|
||||||
<key>CFBundleTypeName</key>
|
<key>CFBundleTypeName</key>
|
||||||
<string>DiskCopy 4.2 Disk Image</string>
|
<string>DiskCopy 4.2 Disk Image</string>
|
||||||
<key>CFBundleTypeOSTypes</key>
|
<key>CFBundleTypeOSTypes</key>
|
||||||
|
@ -33,6 +33,14 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) {
|
|||||||
CSMachineKeyboardInputModeJoystick
|
CSMachineKeyboardInputModeJoystick
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@interface CSMissingROM: NSObject
|
||||||
|
@property (nonatomic, readonly, nonnull) NSString *machineName;
|
||||||
|
@property (nonatomic, readonly, nonnull) NSString *fileName;
|
||||||
|
@property (nonatomic, readonly, nullable) NSString *descriptiveName;
|
||||||
|
@property (nonatomic, readonly) NSUInteger size;
|
||||||
|
@property (nonatomic, readonly, nonnull) NSArray<NSNumber *> *crc32s;
|
||||||
|
@end
|
||||||
|
|
||||||
// Deliberately low; to ensure CSMachine has been declared as an @class already.
|
// Deliberately low; to ensure CSMachine has been declared as an @class already.
|
||||||
#import "CSAtari2600.h"
|
#import "CSAtari2600.h"
|
||||||
#import "CSZX8081.h"
|
#import "CSZX8081.h"
|
||||||
@ -45,8 +53,10 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) {
|
|||||||
Initialises an instance of CSMachine.
|
Initialises an instance of CSMachine.
|
||||||
|
|
||||||
@param result The CSStaticAnalyser result that describes the machine needed.
|
@param result The CSStaticAnalyser result that describes the machine needed.
|
||||||
|
@param missingROMs An array that is filled with a list of ROMs that the machine requested but which
|
||||||
|
were not found; populated only if this `init` has failed.
|
||||||
*/
|
*/
|
||||||
- (nullable instancetype)initWithAnalyser:(nonnull CSStaticAnalyser *)result NS_DESIGNATED_INITIALIZER;
|
- (nullable instancetype)initWithAnalyser:(nonnull CSStaticAnalyser *)result missingROMs:(nullable inout NSMutableArray<CSMissingROM *> *)missingROMs NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
- (void)runForInterval:(NSTimeInterval)interval;
|
- (void)runForInterval:(NSTimeInterval)interval;
|
||||||
|
|
||||||
|
@ -74,6 +74,68 @@ struct ActivityObserver: public Activity::Observer {
|
|||||||
__unsafe_unretained CSMachine *machine;
|
__unsafe_unretained CSMachine *machine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@interface CSMissingROM (Mutability)
|
||||||
|
@property (nonatomic, nonnull, copy) NSString *machineName;
|
||||||
|
@property (nonatomic, nonnull, copy) NSString *fileName;
|
||||||
|
@property (nonatomic, nullable, copy) NSString *descriptiveName;
|
||||||
|
@property (nonatomic, readwrite) NSUInteger size;
|
||||||
|
@property (nonatomic, copy) NSArray<NSNumber *> *crc32s;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation CSMissingROM {
|
||||||
|
NSString *_machineName;
|
||||||
|
NSString *_fileName;
|
||||||
|
NSString *_descriptiveName;
|
||||||
|
NSUInteger _size;
|
||||||
|
NSArray<NSNumber *> *_crc32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)machineName {
|
||||||
|
return _machineName;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setMachineName:(NSString *)machineName {
|
||||||
|
_machineName = [machineName copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)fileName {
|
||||||
|
return _fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFileName:(NSString *)fileName {
|
||||||
|
_fileName = [fileName copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)descriptiveName {
|
||||||
|
return _descriptiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDescriptiveName:(NSString *)descriptiveName {
|
||||||
|
_descriptiveName = [descriptiveName copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)size {
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setSize:(NSUInteger)size {
|
||||||
|
_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray<NSNumber *> *)crc32s {
|
||||||
|
return _crc32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setCrc32s:(NSArray<NSNumber *> *)crc32s {
|
||||||
|
_crc32s = [crc32s copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)description {
|
||||||
|
return [NSString stringWithFormat:@"%@/%@, %@ bytes, CRCs: %@", _fileName, _descriptiveName, @(_size), _crc32s];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation CSMachine {
|
@implementation CSMachine {
|
||||||
SpeakerDelegate _speakerDelegate;
|
SpeakerDelegate _speakerDelegate;
|
||||||
ActivityObserver _activityObserver;
|
ActivityObserver _activityObserver;
|
||||||
@ -90,14 +152,37 @@ struct ActivityObserver: public Activity::Observer {
|
|||||||
std::unique_ptr<Outputs::Display::OpenGL::ScanTarget> _scanTarget;
|
std::unique_ptr<Outputs::Display::OpenGL::ScanTarget> _scanTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result {
|
- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result missingROMs:(inout NSMutableArray<CSMissingROM *> *)missingROMs {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
_analyser = result;
|
_analyser = result;
|
||||||
|
|
||||||
Machine::Error error;
|
Machine::Error error;
|
||||||
_machine.reset(Machine::MachineForTargets(_analyser.targets, CSROMFetcher(), error));
|
std::vector<ROMMachine::ROM> missing_roms;
|
||||||
if(!_machine) return nil;
|
_machine.reset(Machine::MachineForTargets(_analyser.targets, CSROMFetcher(&missing_roms), error));
|
||||||
|
if(!_machine) {
|
||||||
|
for(const auto &missing_rom : missing_roms) {
|
||||||
|
CSMissingROM *rom = [[CSMissingROM alloc] init];
|
||||||
|
|
||||||
|
// Copy/convert the primitive fields.
|
||||||
|
rom.machineName = [NSString stringWithUTF8String:missing_rom.machine_name.c_str()];
|
||||||
|
rom.fileName = [NSString stringWithUTF8String:missing_rom.file_name.c_str()];
|
||||||
|
rom.descriptiveName = missing_rom.descriptive_name.empty() ? nil : [NSString stringWithUTF8String:missing_rom.descriptive_name.c_str()];
|
||||||
|
rom.size = missing_rom.size;
|
||||||
|
|
||||||
|
// Convert the CRC list.
|
||||||
|
NSMutableArray<NSNumber *> *crc32s = [[NSMutableArray alloc] init];
|
||||||
|
for(const auto &crc : missing_rom.crc32s) {
|
||||||
|
[crc32s addObject:@(crc)];
|
||||||
|
}
|
||||||
|
rom.crc32s = [crc32s copy];
|
||||||
|
|
||||||
|
// Add to the missing list.
|
||||||
|
[missingROMs addObject:rom];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
_inputMode =
|
_inputMode =
|
||||||
(_machine->keyboard_machine() && _machine->keyboard_machine()->get_keyboard().is_exclusive())
|
(_machine->keyboard_machine() && _machine->keyboard_machine()->get_keyboard().is_exclusive())
|
||||||
|
@ -8,4 +8,4 @@
|
|||||||
|
|
||||||
#include "ROMMachine.hpp"
|
#include "ROMMachine.hpp"
|
||||||
|
|
||||||
ROMMachine::ROMFetcher CSROMFetcher();
|
ROMMachine::ROMFetcher CSROMFetcher(std::vector<ROMMachine::ROM> *missing_roms = nullptr);
|
||||||
|
@ -14,15 +14,39 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
ROMMachine::ROMFetcher CSROMFetcher() {
|
ROMMachine::ROMFetcher CSROMFetcher(std::vector<ROMMachine::ROM> *missing_roms) {
|
||||||
return [] (const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<std::uint8_t>>> {
|
return [missing_roms] (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()]];
|
NSArray<NSURL *> *const supportURLs = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
|
||||||
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];
|
|
||||||
|
|
||||||
if(!fileData)
|
std::vector<std::unique_ptr<std::vector<std::uint8_t>>> results;
|
||||||
|
for(const auto &rom: roms) {
|
||||||
|
NSData *fileData;
|
||||||
|
NSString *const subdirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:rom.machine_name.c_str()]];
|
||||||
|
|
||||||
|
// Check for this file first within the application support directories.
|
||||||
|
for(NSURL *supportURL in supportURLs) {
|
||||||
|
NSURL *const fullURL = [[supportURL URLByAppendingPathComponent:subdirectory]
|
||||||
|
URLByAppendingPathComponent:[NSString stringWithUTF8String:rom.file_name.c_str()]];
|
||||||
|
fileData = [NSData dataWithContentsOfURL:fullURL];
|
||||||
|
if(fileData) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failing that, check inside the application bundle.
|
||||||
|
if(!fileData) {
|
||||||
|
fileData = [[NSBundle mainBundle]
|
||||||
|
dataForResource:[NSString stringWithUTF8String:rom.file_name.c_str()]
|
||||||
|
withExtension:nil
|
||||||
|
subdirectory:subdirectory];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store an appropriate result, accumulating a list of the missing if requested.
|
||||||
|
if(!fileData) {
|
||||||
results.emplace_back(nullptr);
|
results.emplace_back(nullptr);
|
||||||
|
|
||||||
|
if(missing_roms) {
|
||||||
|
missing_roms->push_back(rom);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
std::unique_ptr<std::vector<std::uint8_t>> data(new std::vector<std::uint8_t>);
|
std::unique_ptr<std::vector<std::uint8_t>> data(new std::vector<std::uint8_t>);
|
||||||
*data = fileData.stdVector8;
|
*data = fileData.stdVector8;
|
||||||
|
17
OSBindings/Mac/Clock Signal/Machine/NSData+CRC32.h
Normal file
17
OSBindings/Mac/Clock Signal/Machine/NSData+CRC32.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// NSData+CRC32.m
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 22/07/2019.
|
||||||
|
// Copyright 2019 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@interface NSData (CRC32)
|
||||||
|
|
||||||
|
@property(nonnull, nonatomic, readonly) NSNumber *crc32;
|
||||||
|
|
||||||
|
@end
|
19
OSBindings/Mac/Clock Signal/Machine/NSData+CRC32.m
Normal file
19
OSBindings/Mac/Clock Signal/Machine/NSData+CRC32.m
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// NSData+CRC32.m
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 22/07/2019.
|
||||||
|
// Copyright 2019 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "NSData+CRC32.h"
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
@implementation NSData (StdVector)
|
||||||
|
|
||||||
|
- (NSNumber *)crc32 {
|
||||||
|
return @(crc32(crc32(0, Z_NULL, 0), self.bytes, (uInt)self.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -64,7 +64,7 @@ Gw
|
|||||||
<tabViewItems>
|
<tabViewItems>
|
||||||
<tabViewItem label="Apple II" identifier="appleii" id="P59-QG-LOa">
|
<tabViewItem label="Apple II" identifier="appleii" id="P59-QG-LOa">
|
||||||
<view key="view" id="dHz-Yv-GNq">
|
<view key="view" id="dHz-Yv-GNq">
|
||||||
<rect key="frame" x="10" y="33" width="554" height="94"/>
|
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5Z-dX-Ns4">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5Z-dX-Ns4">
|
||||||
@ -168,7 +168,7 @@ Gw
|
|||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Electron" identifier="electron" id="muc-z9-Vqc">
|
<tabViewItem label="Electron" identifier="electron" id="muc-z9-Vqc">
|
||||||
<view key="view" id="SRc-2D-95G">
|
<view key="view" id="SRc-2D-95G">
|
||||||
<rect key="frame" x="10" y="33" width="654" height="94"/>
|
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JqM-IK-FMP">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JqM-IK-FMP">
|
||||||
@ -199,13 +199,29 @@ Gw
|
|||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Macintosh" identifier="mac" id="lmR-z3-xSm">
|
<tabViewItem label="Macintosh" identifier="mac" id="lmR-z3-xSm">
|
||||||
<view key="view" id="7Yf-vi-Q0W">
|
<view key="view" id="7Yf-vi-Q0W">
|
||||||
<rect key="frame" x="10" y="33" width="654" height="94"/>
|
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="F6e-UC-25u">
|
||||||
|
<rect key="frame" x="15" y="74" width="574" height="17"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" title="At present Clock Signal emulates only the Macintosh 512ke." id="IGV-Yp-6Af">
|
||||||
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="F6e-UC-25u" secondAttribute="trailing" constant="17" id="42z-hS-aPq"/>
|
||||||
|
<constraint firstItem="F6e-UC-25u" firstAttribute="leading" secondItem="7Yf-vi-Q0W" secondAttribute="leading" constant="17" id="bIg-C3-xdz"/>
|
||||||
|
<constraint firstItem="F6e-UC-25u" firstAttribute="top" secondItem="7Yf-vi-Q0W" secondAttribute="top" constant="3" id="cxs-OP-oH5"/>
|
||||||
|
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="F6e-UC-25u" secondAttribute="bottom" constant="17" id="vpF-ER-pmD"/>
|
||||||
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="MSX" identifier="msx" id="6SR-DY-zdI">
|
<tabViewItem label="MSX" identifier="msx" id="6SR-DY-zdI">
|
||||||
<view key="view" id="mWD-An-tR7">
|
<view key="view" id="mWD-An-tR7">
|
||||||
<rect key="frame" x="10" y="33" width="654" height="94"/>
|
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8xT-Pr-8SE">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8xT-Pr-8SE">
|
||||||
@ -253,7 +269,7 @@ Gw
|
|||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Oric" identifier="oric" id="NSx-DC-p4M">
|
<tabViewItem label="Oric" identifier="oric" id="NSx-DC-p4M">
|
||||||
<view key="view" id="sOR-e0-8iZ">
|
<view key="view" id="sOR-e0-8iZ">
|
||||||
<rect key="frame" x="10" y="33" width="654" height="94"/>
|
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0ct-tf-uRH">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0ct-tf-uRH">
|
||||||
@ -318,7 +334,7 @@ Gw
|
|||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Vic-20" identifier="vic20" id="cyO-PU-hSU">
|
<tabViewItem label="Vic-20" identifier="vic20" id="cyO-PU-hSU">
|
||||||
<view key="view" id="fLI-XB-QCr">
|
<view key="view" id="fLI-XB-QCr">
|
||||||
<rect key="frame" x="10" y="33" width="554" height="94"/>
|
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ueK-gq-gaF">
|
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ueK-gq-gaF">
|
||||||
@ -497,7 +513,7 @@ Gw
|
|||||||
<constraint firstItem="VUb-QG-x7c" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="zT3-Ea-QQJ"/>
|
<constraint firstItem="VUb-QG-x7c" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="zT3-Ea-QQJ"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<point key="canvasLocation" x="34" y="89"/>
|
<point key="canvasLocation" x="34" y="88.5"/>
|
||||||
</window>
|
</window>
|
||||||
<customObject id="192-Eb-Rpg" customClass="MachinePicker" customModule="Clock_Signal" customModuleProvider="target">
|
<customObject id="192-Eb-Rpg" customClass="MachinePicker" customModule="Clock_Signal" customModuleProvider="target">
|
||||||
<connections>
|
<connections>
|
||||||
|
27
OSBindings/Mac/Clock Signal/ROMRequester/CSROMReceiverView.h
Normal file
27
OSBindings/Mac/Clock Signal/ROMRequester/CSROMReceiverView.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// CSROMReceiverView.h
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 22/07/2019.
|
||||||
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@class CSROMReceiverView;
|
||||||
|
|
||||||
|
@protocol CSROMReciverViewDelegate
|
||||||
|
/*!
|
||||||
|
Announces receipt of a file by drag and drop to the delegate.
|
||||||
|
@param view The view making the request.
|
||||||
|
@param URL The file URL of the received file.
|
||||||
|
*/
|
||||||
|
- (void)romReceiverView:(nonnull CSROMReceiverView *)view didReceiveFileAtURL:(nonnull NSURL *)URL;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface CSROMReceiverView : NSView
|
||||||
|
|
||||||
|
@property(nonatomic, weak, nullable) id <CSROMReciverViewDelegate> delegate;
|
||||||
|
|
||||||
|
@end
|
40
OSBindings/Mac/Clock Signal/ROMRequester/CSROMReceiverView.m
Normal file
40
OSBindings/Mac/Clock Signal/ROMRequester/CSROMReceiverView.m
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// CSROMReceiverView.m
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 22/07/2019.
|
||||||
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "CSROMReceiverView.h"
|
||||||
|
|
||||||
|
@interface CSROMReceiverView () <NSDraggingDestination>
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation CSROMReceiverView
|
||||||
|
|
||||||
|
- (void)awakeFromNib {
|
||||||
|
[super awakeFromNib];
|
||||||
|
|
||||||
|
// Accept file URLs by drag and drop.
|
||||||
|
[self registerForDraggedTypes:@[(__bridge NSString *)kUTTypeFileURL]];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSDraggingDestination
|
||||||
|
|
||||||
|
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
|
||||||
|
// Just forward the URLs.
|
||||||
|
for(NSPasteboardItem *item in [[sender draggingPasteboard] pasteboardItems]) {
|
||||||
|
NSURL *URL = [NSURL URLWithString:[item stringForType:(__bridge NSString *)kUTTypeFileURL]];
|
||||||
|
[self.delegate romReceiverView:self didReceiveFileAtURL:URL];
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender {
|
||||||
|
// The emulator will take a copy of any deposited ROM files.
|
||||||
|
return NSDragOperationCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
75
OSBindings/Mac/Clock Signal/ROMRequester/ROMRequester.xib
Normal file
75
OSBindings/Mac/Clock Signal/ROMRequester/ROMRequester.xib
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="MachineDocument" customModule="Clock_Signal" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="romReceiverErrorField" destination="Bia-0m-GxK" id="wnH-Kz-uXD"/>
|
||||||
|
<outlet property="romReceiverView" destination="EiT-Mj-1SZ" id="Y2M-Qd-i7y"/>
|
||||||
|
<outlet property="romRequesterPanel" destination="QvC-M9-y7g" id="saI-YH-9NP"/>
|
||||||
|
<outlet property="romRequesterText" destination="5qG-I3-Qav" id="J9M-T8-Xyy"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titleVisibility="hidden" id="QvC-M9-y7g">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES"/>
|
||||||
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
|
||||||
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ" customClass="CSROMReceiverView">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5qG-I3-Qav">
|
||||||
|
<rect key="frame" x="18" y="148" width="444" height="102"/>
|
||||||
|
<textFieldCell key="cell" enabled="NO" allowsUndo="NO" id="itJ-2T-0ia">
|
||||||
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
|
<string key="title">Clock Signal requires you to provide images of the system ROMs for this machine. They will be stored permanently; you need do this only once.
Please drag and drop the following over this view:
|
||||||
|
|
||||||
|
</string>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nvl-dm-8bK">
|
||||||
|
<rect key="frame" x="384" y="13" width="82" height="32"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="oS1-Pk-LsO">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<string key="keyEquivalent" base64-UTF8="YES">
|
||||||
|
DQ
|
||||||
|
</string>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="cancelRequestROMs:" target="-2" id="58q-yi-dlv"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bia-0m-GxK">
|
||||||
|
<rect key="frame" x="20" y="61" width="442" height="17"/>
|
||||||
|
<textFieldCell key="cell" allowsUndo="NO" alignment="center" title="Multiline Label" drawsBackground="YES" id="8jl-xs-LjP">
|
||||||
|
<font key="font" metaFont="message"/>
|
||||||
|
<color key="textColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="tertiaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="Bia-0m-GxK" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="9Lj-3p-7Vr"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="5qG-I3-Qav" secondAttribute="trailing" constant="20" id="AwT-WO-Nyf"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="nvl-dm-8bK" secondAttribute="bottom" constant="20" id="BU0-5T-YRH"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="Bia-0m-GxK" secondAttribute="bottom" constant="61" id="ENn-7a-NGa"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="Bia-0m-GxK" secondAttribute="trailing" constant="18" id="UUy-bf-87w"/>
|
||||||
|
<constraint firstItem="5qG-I3-Qav" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="bRM-z1-cRf"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="nvl-dm-8bK" secondAttribute="trailing" constant="20" id="eQI-Nj-ane"/>
|
||||||
|
<constraint firstItem="nvl-dm-8bK" firstAttribute="top" relation="greaterThanOrEqual" secondItem="5qG-I3-Qav" secondAttribute="bottom" constant="17" id="plB-x4-He5"/>
|
||||||
|
<constraint firstItem="5qG-I3-Qav" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="qeC-Rh-hmr"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</window>
|
||||||
|
</objects>
|
||||||
|
</document>
|
@ -9,6 +9,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -339,21 +340,21 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a sanity check on arguments.
|
// Perform a sanity check on arguments.
|
||||||
if(arguments.file_name.empty()) {
|
if(arguments.file_name.empty()) {
|
||||||
std::cerr << "Usage: " << final_path_component(argv[0]) << usage_suffix << std::endl;
|
std::cerr << "Usage: " << final_path_component(argv[0]) << usage_suffix << std::endl;
|
||||||
std::cerr << "Use --help to learn more about available options." << std::endl;
|
std::cerr << "Use --help to learn more about available options." << std::endl;
|
||||||
return -1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the machine for the supplied file.
|
// Determine the machine for the supplied file.
|
||||||
Analyser::Static::TargetList targets = Analyser::Static::GetTargets(arguments.file_name);
|
Analyser::Static::TargetList targets = Analyser::Static::GetTargets(arguments.file_name);
|
||||||
if(targets.empty()) {
|
if(targets.empty()) {
|
||||||
std::cerr << "Cannot open " << arguments.file_name << "; no target machine found" << std::endl;
|
std::cerr << "Cannot open " << arguments.file_name << "; no target machine found" << std::endl;
|
||||||
return -1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Concurrency::BestEffortUpdater updater;
|
Concurrency::BestEffortUpdater updater;
|
||||||
@ -365,12 +366,10 @@ 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;
|
ROMMachine::ROMFetcher rom_fetcher = [&requested_roms, &arguments]
|
||||||
ROMMachine::ROMFetcher rom_fetcher = [&rom_names, &machine_name, &arguments]
|
(const std::vector<ROMMachine::ROM> &roms) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> {
|
||||||
(const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<uint8_t>>> {
|
requested_roms.insert(requested_roms.end(), roms.begin(), roms.end());
|
||||||
rom_names.insert(rom_names.end(), names.begin(), names.end());
|
|
||||||
machine_name = machine;
|
|
||||||
|
|
||||||
std::vector<std::string> paths = {
|
std::vector<std::string> paths = {
|
||||||
"/usr/local/share/CLK/",
|
"/usr/local/share/CLK/",
|
||||||
@ -386,10 +385,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 + rom.machine_name + "/" + 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,13 +424,17 @@ 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 << rom.machine_name << '/' << rom.file_name;
|
||||||
|
if(!rom.descriptive_name.empty()) {
|
||||||
|
std::cerr << " (" << rom.descriptive_name << ")";
|
||||||
|
}
|
||||||
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
best_effort_updater_delegate.machine = machine.get();
|
best_effort_updater_delegate.machine = machine.get();
|
||||||
@ -441,7 +444,7 @@ int main(int argc, char *argv[]) {
|
|||||||
// Attempt to set up video and audio.
|
// Attempt to set up video and audio.
|
||||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
||||||
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
|
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
|
||||||
return -1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask for no depth buffer, a core profile and vsync-aligned rendering.
|
// Ask for no depth buffer, a core profile and vsync-aligned rendering.
|
||||||
@ -463,7 +466,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if(!window || !gl_context) {
|
if(!window || !gl_context) {
|
||||||
std::cerr << "Could not create " << (window ? "OpenGL context" : "window");
|
std::cerr << "Could not create " << (window ? "OpenGL context" : "window");
|
||||||
std::cerr << "; reported error: \"" << SDL_GetError() << "\"" << std::endl;
|
std::cerr << "; reported error: \"" << SDL_GetError() << "\"" << std::endl;
|
||||||
return -1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GL_MakeCurrent(window, gl_context);
|
SDL_GL_MakeCurrent(window, gl_context);
|
||||||
@ -816,5 +819,5 @@ int main(int argc, char *argv[]) {
|
|||||||
SDL_DestroyWindow( window );
|
SDL_DestroyWindow( window );
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user