diff --git a/Analyser/Static/Enterprise/Target.hpp b/Analyser/Static/Enterprise/Target.hpp index d758e4d6d..2a0fe11d4 100644 --- a/Analyser/Static/Enterprise/Target.hpp +++ b/Analyser/Static/Enterprise/Target.hpp @@ -20,17 +20,21 @@ namespace Enterprise { struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Target> { ReflectableEnum(EXOSVersion, v10, v20, v21, v23, Any); ReflectableEnum(BASICVersion, v10, v11, v21, Any, None); + ReflectableEnum(DOS, EPDOS, EXDOS, None); EXOSVersion exos_version = EXOSVersion::Any; BASICVersion basic_version = BASICVersion::None; + DOS dos = DOS::None; Target() : Analyser::Static::Target(Machine::Enterprise) { if(needs_declare()) { AnnounceEnum(EXOSVersion); AnnounceEnum(BASICVersion); + AnnounceEnum(DOS); DeclareField(exos_version); DeclareField(basic_version); + DeclareField(dos); } } }; diff --git a/Machines/Enterprise/Enterprise.cpp b/Machines/Enterprise/Enterprise.cpp index cb62888fd..ac01c39e2 100644 --- a/Machines/Enterprise/Enterprise.cpp +++ b/Machines/Enterprise/Enterprise.cpp @@ -60,7 +60,7 @@ namespace Enterprise { */ -class ConcreteMachine: +template <bool has_disk_controller> class ConcreteMachine: public CPU::Z80::BusHandler, public Machine, public MachineTypes::MappedKeyboardMachine, @@ -122,6 +122,13 @@ class ConcreteMachine: default: break; } + // Possibly add in a DOS. + switch(target.dos) { + case Target::DOS::EPDOS: request = request && ROM::Request(ROM::Name::EnterpriseEPDOS); break; + case Target::DOS::EXDOS: request = request && ROM::Request(ROM::Name::EnterpriseEXDOS); break; + default: break; + } + // Get and validate ROMs. auto roms = rom_fetcher(request); if(!request.validate(roms)) { @@ -158,6 +165,16 @@ class ConcreteMachine: } } + // Extract the appropriate DOS ROM. + dos_.fill(0xff); + for(const auto rom_name: { ROM::Name::EnterpriseEPDOS, ROM::Name::EnterpriseEXDOS }) { + const auto dos = roms.find(rom_name); + if(dos != roms.end()) { + memcpy(dos_.data(), dos->second.data(), std::min(dos_.size(), dos->second.size())); + break; + } + } + // Seed key state. clear_all_keys(); @@ -291,6 +308,7 @@ class ConcreteMachine: std::array<uint8_t, 64 * 1024> ram_; std::array<uint8_t, 64 * 1024> exos_; std::array<uint8_t, 16 * 1024> basic_; + std::array<uint8_t, 32 * 1024> dos_; const uint8_t min_ram_slot_ = uint8_t(0x100 - (ram_.size() / 0x4000)); const uint8_t *read_pointers_[4] = {nullptr, nullptr, nullptr, nullptr}; @@ -310,6 +328,11 @@ class ConcreteMachine: return; } + if(offset >= 32 && offset < 32 + dos_.size() / 0x4000) { + page<slot>(&dos_[(offset - 32) * 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 @@ -392,7 +415,10 @@ Machine *Machine::Enterprise(const Analyser::Static::Target *target, const ROMMa using Target = Analyser::Static::Enterprise::Target; const Target *const enterprise_target = dynamic_cast<const Target *>(target); - return new Enterprise::ConcreteMachine(*enterprise_target, rom_fetcher); + if(enterprise_target->dos != Target::DOS::None) + return new Enterprise::ConcreteMachine<false>(*enterprise_target, rom_fetcher); + else + return new Enterprise::ConcreteMachine<true>(*enterprise_target, rom_fetcher); } Machine::~Machine() {} diff --git a/Machines/Utility/ROMCatalogue.cpp b/Machines/Utility/ROMCatalogue.cpp index d245e98bb..acabcc591 100644 --- a/Machines/Utility/ROMCatalogue.cpp +++ b/Machines/Utility/ROMCatalogue.cpp @@ -458,6 +458,15 @@ Description::Description(Name name) { *this = Description(name, "Enterprise", "the Enterprise BASIC ROM v2.1", filenames, 16 * 1024, crcs); } break; + case Name::EnterpriseEPDOS: { + const std::initializer_list<std::string> filenames = {"epdos.bin", "EPDOS v1.7 (19xx)(Haluska, Laszlo).bin"}; + *this = Description(name, "Enterprise", "the Enterprise EPDOS ROM", filenames, 32 * 1024, 0x201319ebu); + } break; + case Name::EnterpriseEXDOS: { + const std::initializer_list<std::string> filenames = {"exdos.bin", "EX-DOS EPROM (198x)(Enterprise).bin"}; + *this = Description(name, "Enterprise", "the Enterprise EXOS ROM", filenames, 16 * 1024, 0xe6daa0e9u); + } break; + case Name::Macintosh128k: *this = Description(name, "Macintosh", "the Macintosh 128k ROM", "mac128k.rom", 64*1024, 0x6d0c8a28u); break; case Name::Macintosh512k: *this = Description(name, "Macintosh", "the Macintosh 512k ROM", "mac512k.rom", 64*1024, 0xcf759e0d); break; case Name::MacintoshPlus: { diff --git a/Machines/Utility/ROMCatalogue.hpp b/Machines/Utility/ROMCatalogue.hpp index 56b4e2c07..4f481f2e2 100644 --- a/Machines/Utility/ROMCatalogue.hpp +++ b/Machines/Utility/ROMCatalogue.hpp @@ -84,6 +84,9 @@ enum Name { EnterpriseBASIC11Suffixed, EnterpriseBASIC21, + EnterpriseEPDOS, + EnterpriseEXDOS, + // Macintosh. Macintosh128k, Macintosh512k,