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,