mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-03 22:33:29 +00:00
Attempts to support the panoply of EXOS and BASIC versions.
This commit is contained in:
parent
42a98e1676
commit
0e1e8c7faa
@ -18,9 +18,21 @@ namespace Static {
|
||||
namespace Enterprise {
|
||||
|
||||
struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Target> {
|
||||
Target() : Analyser::Static::Target(Machine::Enterprise) {}
|
||||
ReflectableEnum(EXOSVersion, v10, v20, v21, v23, Any);
|
||||
ReflectableEnum(BASICVersion, v10, v11, v21, Any, None);
|
||||
|
||||
// TODO: I assume there'll be relevant fields to add here.
|
||||
EXOSVersion exos_version = EXOSVersion::Any;
|
||||
BASICVersion basic_version = BASICVersion::None;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::Enterprise) {
|
||||
if(needs_declare()) {
|
||||
AnnounceEnum(EXOSVersion);
|
||||
AnnounceEnum(BASICVersion);
|
||||
|
||||
DeclareField(exos_version);
|
||||
DeclareField(basic_version);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -70,17 +70,92 @@ class ConcreteMachine:
|
||||
// Request a clock of 4Mhz; this'll be mapped upwards for Nick and Dave elsewhere.
|
||||
set_clock_rate(4'000'000);
|
||||
|
||||
constexpr ROM::Name exos_name = ROM::Name::EnterpriseEXOS;
|
||||
const auto request = ROM::Request(exos_name);
|
||||
ROM::Request request;
|
||||
using Target = Analyser::Static::Enterprise::Target;
|
||||
|
||||
// Pick one or more EXOS ROMs.
|
||||
switch(target.exos_version) {
|
||||
case Target::EXOSVersion::v10: request = request && ROM::Request(ROM::Name::EnterpriseEXOS10); break;
|
||||
case Target::EXOSVersion::v20: request = request && ROM::Request(ROM::Name::EnterpriseEXOS20); break;
|
||||
case Target::EXOSVersion::v21: request = request && ROM::Request(ROM::Name::EnterpriseEXOS21); break;
|
||||
case Target::EXOSVersion::v23: request = request && ROM::Request(ROM::Name::EnterpriseEXOS23); break;
|
||||
case Target::EXOSVersion::Any:
|
||||
request =
|
||||
request && (
|
||||
ROM::Request(ROM::Name::EnterpriseEXOS10) || ROM::Request(ROM::Name::EnterpriseEXOS20) ||
|
||||
ROM::Request(ROM::Name::EnterpriseEXOS21) || ROM::Request(ROM::Name::EnterpriseEXOS23)
|
||||
);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Similarly pick one or more BASIC ROMs.
|
||||
switch(target.basic_version) {
|
||||
case Target::BASICVersion::v10:
|
||||
request = request && (
|
||||
ROM::Request(ROM::Name::EnterpriseBASIC10) ||
|
||||
(ROM::Request(ROM::Name::EnterpriseBASIC10Part1) && ROM::Request(ROM::Name::EnterpriseBASIC10Part2))
|
||||
);
|
||||
break;
|
||||
case Target::BASICVersion::v11:
|
||||
request = request && (
|
||||
ROM::Request(ROM::Name::EnterpriseBASIC11) ||
|
||||
ROM::Request(ROM::Name::EnterpriseBASIC11Suffixed)
|
||||
);
|
||||
case Target::BASICVersion::v21:
|
||||
request = request && ROM::Request(ROM::Name::EnterpriseBASIC21);
|
||||
break;
|
||||
case Target::BASICVersion::Any:
|
||||
request =
|
||||
request && (
|
||||
ROM::Request(ROM::Name::EnterpriseBASIC10) ||
|
||||
(ROM::Request(ROM::Name::EnterpriseBASIC10Part1) && ROM::Request(ROM::Name::EnterpriseBASIC10Part2)) ||
|
||||
ROM::Request(ROM::Name::EnterpriseBASIC11) ||
|
||||
ROM::Request(ROM::Name::EnterpriseBASIC21)
|
||||
);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Get and validate ROMs.
|
||||
auto roms = rom_fetcher(request);
|
||||
if(!request.validate(roms)) {
|
||||
throw ROMMachine::Error::MissingROMs;
|
||||
}
|
||||
|
||||
const auto &exos = roms.find(exos_name)->second;
|
||||
// Extract the appropriate EXOS ROM.
|
||||
exos_.fill(0xff);
|
||||
memcpy(exos_.data(), exos.data(), std::min(exos_.size(), exos.size()));
|
||||
for(const auto rom_name: { ROM::Name::EnterpriseEXOS10, ROM::Name::EnterpriseEXOS20, ROM::Name::EnterpriseEXOS21, ROM::Name::EnterpriseEXOS23 }) {
|
||||
const auto exos = roms.find(rom_name);
|
||||
if(exos != roms.end()) {
|
||||
memcpy(exos_.data(), exos->second.data(), std::min(exos_.size(), exos->second.size()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the appropriate BASIC ROM[s] (if any).
|
||||
basic_.fill(0xff);
|
||||
bool has_basic = false;
|
||||
for(const auto rom_name: { ROM::Name::EnterpriseBASIC10, ROM::Name::EnterpriseBASIC11, ROM::Name::EnterpriseBASIC11Suffixed, ROM::Name::EnterpriseBASIC21 }) {
|
||||
const auto basic = roms.find(rom_name);
|
||||
if(basic != roms.end()) {
|
||||
memcpy(basic_.data(), basic->second.data(), std::min(basic_.size(), basic->second.size()));
|
||||
has_basic = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!has_basic) {
|
||||
const auto basic1 = roms.find(ROM::Name::EnterpriseBASIC10Part1);
|
||||
const auto basic2 = roms.find(ROM::Name::EnterpriseBASIC10Part2);
|
||||
if(basic1 != roms.end() && basic2 != roms.end()) {
|
||||
memcpy(&basic_[0x0000], basic1->second.data(), std::min(size_t(8192), basic1->second.size()));
|
||||
memcpy(&basic_[0x2000], basic2->second.data(), std::min(size_t(8192), basic2->second.size()));
|
||||
}
|
||||
}
|
||||
|
||||
// Seed key state.
|
||||
clear_all_keys();
|
||||
|
||||
// Take a reasonable guess at the initial memory configuration:
|
||||
@ -212,6 +287,7 @@ class ConcreteMachine:
|
||||
// MARK: - Memory layout
|
||||
std::array<uint8_t, 64 * 1024> ram_;
|
||||
std::array<uint8_t, 64 * 1024> exos_;
|
||||
std::array<uint8_t, 16 * 1024> basic_;
|
||||
const uint8_t min_ram_slot_ = uint8_t(0x100 - (ram_.size() / 0x4000));
|
||||
|
||||
const uint8_t *read_pointers_[4] = {nullptr, nullptr, nullptr, nullptr};
|
||||
@ -226,6 +302,11 @@ class ConcreteMachine:
|
||||
return;
|
||||
}
|
||||
|
||||
if(offset >= 16 && offset < 16 + basic_.size() / 0x4000) {
|
||||
page<slot>(&basic_[(offset - 16) * 0x4000], nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Of whatever size of RAM I've declared above, use only the final portion.
|
||||
// This correlated with Nick always having been handed the final 64kb and,
|
||||
// at least while the RAM is the first thing declared above, does a little
|
||||
@ -280,9 +361,6 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
// MARK: - Interrupts
|
||||
|
||||
// TODO: include an error.
|
||||
|
||||
enum class Interrupt: uint8_t {
|
||||
Nick = 0x20
|
||||
};
|
||||
|
@ -411,9 +411,51 @@ Description::Description(Name name) {
|
||||
*this = Description(name, "DiskII", "the Disk II 13-sector state machine ROM", "state-machine-13.rom", 256, 0x62e22620u);
|
||||
break;
|
||||
|
||||
case Name::EnterpriseEXOS: {
|
||||
const std::initializer_list<std::string> filenames = {"exos.bin", "Exos (198x)(Enterprise).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise EXOS ROM", filenames, 32 * 1024, 0x30b26387u);
|
||||
case Name::EnterpriseEXOS10: {
|
||||
const std::initializer_list<std::string> filenames = {"exos10.bin", "Exos (198x)(Enterprise).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise EXOS ROM v1.0", filenames, 32 * 1024, 0x30b26387u);
|
||||
} break;
|
||||
case Name::EnterpriseEXOS20: {
|
||||
const std::initializer_list<std::string> filenames = {"exos20.bin", "Expandible OS v2.0 (1984)(Intelligent Software).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise EXOS ROM v2.0", filenames, 32 * 1024, 0xd421795fu);
|
||||
} break;
|
||||
case Name::EnterpriseEXOS21: {
|
||||
const std::initializer_list<std::string> filenames = {"exos21.bin", "Expandible OS v2.1 (1985)(Intelligent Software).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise EXOS ROM v2.1", filenames, 32 * 1024, 0x982a3b44u);
|
||||
} break;
|
||||
case Name::EnterpriseEXOS23: {
|
||||
const std::initializer_list<std::string> filenames = {"exos23.bin", "Expandible OS v2.3 (1987)(Intelligent Software).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise EXOS ROM v2.1", filenames, 64 * 1024, 0x24838410u);
|
||||
} break;
|
||||
|
||||
case Name::EnterpriseBASIC10: {
|
||||
const std::initializer_list<std::string> filenames = {"basic10.bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise BASIC ROM v1.0", filenames, 16 * 1024, 0xd62e4fb7u);
|
||||
} break;
|
||||
case Name::EnterpriseBASIC10Part1: {
|
||||
const std::initializer_list<std::string> filenames = {"BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise BASIC ROM v1.0, Part 1", filenames, 8193, 0x37bf48e1u);
|
||||
} break;
|
||||
case Name::EnterpriseBASIC10Part2: {
|
||||
const std::initializer_list<std::string> filenames = {"BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise BASIC ROM v1.0, Part 2", filenames, 8193, 0xc5298c79u);
|
||||
} break;
|
||||
case Name::EnterpriseBASIC11: {
|
||||
const std::initializer_list<std::string> filenames = {"basic11.bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise BASIC ROM v1.1", filenames, 16 * 1024, 0x683cf455u);
|
||||
} break;
|
||||
case Name::EnterpriseBASIC11Suffixed: {
|
||||
const std::initializer_list<std::string> filenames = {"BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin"};
|
||||
*this = Description(name, "Enterprise", "the Enterprise BASIC ROM v1.1, with trailing byte", filenames, 16385, 0xc96b7602u);
|
||||
} break;
|
||||
case Name::EnterpriseBASIC21: {
|
||||
const std::initializer_list<std::string> filenames = {
|
||||
"basic21.bin",
|
||||
"BASIC Interpreter v2.1 (1985)(Intelligent Software).bin",
|
||||
"BASIC Interpreter v2.1 (1985)(Intelligent Software)[a].bin"
|
||||
};
|
||||
const std::initializer_list<uint32_t> crcs = { 0x55f96251, 0x683cf455 };
|
||||
*this = Description(name, "Enterprise", "the Enterprise BASIC ROM v2.1", filenames, 16 * 1024, crcs);
|
||||
} break;
|
||||
|
||||
case Name::Macintosh128k: *this = Description(name, "Macintosh", "the Macintosh 128k ROM", "mac128k.rom", 64*1024, 0x6d0c8a28u); break;
|
||||
|
@ -72,7 +72,17 @@ enum Name {
|
||||
DiskIIBoot13Sector,
|
||||
|
||||
// Enterprise.
|
||||
EnterpriseEXOS,
|
||||
EnterpriseEXOS10,
|
||||
EnterpriseEXOS20,
|
||||
EnterpriseEXOS21,
|
||||
EnterpriseEXOS23,
|
||||
|
||||
EnterpriseBASIC10,
|
||||
EnterpriseBASIC10Part1,
|
||||
EnterpriseBASIC10Part2,
|
||||
EnterpriseBASIC11,
|
||||
EnterpriseBASIC11Suffixed,
|
||||
EnterpriseBASIC21,
|
||||
|
||||
// Macintosh.
|
||||
Macintosh128k,
|
||||
|
Loading…
x
Reference in New Issue
Block a user