diff --git a/Machines/MSX/DiskROM.cpp b/Machines/MSX/DiskROM.cpp
index 97d7a57aa..1311d99f0 100644
--- a/Machines/MSX/DiskROM.cpp
+++ b/Machines/MSX/DiskROM.cpp
@@ -10,7 +10,7 @@
 
 using namespace MSX;
 
-DiskROM::DiskROM(const MSX::MemorySlot &slot) :
+DiskROM::DiskROM(MSX::MemorySlot &slot) :
 	WD1770(P1793),
 	rom_(slot.source()) {
 	emplace_drives(2, 8000000, 300, 2);
diff --git a/Machines/MSX/DiskROM.hpp b/Machines/MSX/DiskROM.hpp
index 931668eb4..7d776b83f 100644
--- a/Machines/MSX/DiskROM.hpp
+++ b/Machines/MSX/DiskROM.hpp
@@ -23,7 +23,7 @@ namespace MSX {
 
 class DiskROM: public MemorySlotHandler, public WD::WD1770 {
 	public:
-		DiskROM(const MSX::MemorySlot &slot);
+		DiskROM(MSX::MemorySlot &slot);
 
 		void write(uint16_t address, uint8_t value, bool pc_is_outside_bios) final;
 		uint8_t read(uint16_t address) final;
diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp
index 7f71610be..aeeb2b517 100644
--- a/Machines/MSX/MSX.cpp
+++ b/Machines/MSX/MSX.cpp
@@ -143,6 +143,11 @@ class ConcreteMachine:
 	public Configurable::Device,
 	public ClockingHint::Observer,
 	public Activity::Source {
+	private:
+		static constexpr int RAMMemorySlot = 3;
+		static constexpr int RAMMemorySubSlot = 0;
+
+
 	public:
 		ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher):
 			z80_(*this),
@@ -156,7 +161,6 @@ class ConcreteMachine:
 			i8255_port_handler_(*this, audio_toggle_, tape_player_),
 			ay_port_handler_(tape_player_) {
 			set_clock_rate(3579545);
-			std::memset(unpopulated_, 0xff, sizeof(unpopulated_));
 			clear_all_keys();
 
 			ay_.set_port_handler(&ay_port_handler_);
@@ -234,11 +238,17 @@ class ConcreteMachine:
 
 			// Figure out which BIOS to use, either a specific one or the generic
 			// one appropriately patched.
-			const auto regional_bios = roms.find(regional_bios_name);
-			if(regional_bios != roms.end()) {
-				regional_bios->second.resize(32768);
-				memory_slots_[0].set_source(regional_bios->second);
-			} else {
+			bool has_bios = false;
+			if constexpr (model == Target::Model::MSX1) {
+				const auto regional_bios = roms.find(regional_bios_name);
+				if(regional_bios != roms.end()) {
+					regional_bios->second.resize(32768);
+					memory_slots_[0].set_source(regional_bios->second);
+					has_bios = true;
+				}
+			}
+
+			if(!has_bios) {
 				std::vector<uint8_t> &bios = roms.find(bios_name)->second;
 
 				bios.resize(32768);
@@ -255,7 +265,9 @@ class ConcreteMachine:
 			}
 
 			memory_slots_[0].map(0, 0, 0, 32768);
-			memory_slots_[3].template map<MemorySlot::AccessType::ReadWrite>(0, 0, 0, 65536);
+
+			memory_slots_[RAMMemorySlot].resize_source(65536);
+			memory_slots_[RAMMemorySlot].template map<MemorySlot::AccessType::ReadWrite>(RAMMemorySubSlot, 0, 0, 65536);
 
 			// Add a disk cartridge if any disks were supplied.
 			if(target.has_disk_drive) {
@@ -447,8 +459,8 @@ class ConcreteMachine:
 								using Parser = Storage::Tape::MSX::Parser;
 								std::unique_ptr<Parser::FileSpeed> new_speed = Parser::find_header(tape_player_);
 								if(new_speed) {
-									ram_[0xfca4] = new_speed->minimum_start_bit_duration;
-									ram_[0xfca5] = new_speed->low_high_disrimination_duration;
+									ram()[0xfca4] = new_speed->minimum_start_bit_duration;
+									ram()[0xfca5] = new_speed->low_high_disrimination_duration;
 									z80_.set_value_of_register(CPU::Z80::Register::Flags, 0);
 								} else {
 									z80_.set_value_of_register(CPU::Z80::Register::Flags, 1);
@@ -465,8 +477,8 @@ class ConcreteMachine:
 								// Grab the current values of LOWLIM and WINWID.
 								using Parser = Storage::Tape::MSX::Parser;
 								Parser::FileSpeed tape_speed;
-								tape_speed.minimum_start_bit_duration = ram_[0xfca4];
-								tape_speed.low_high_disrimination_duration = ram_[0xfca5];
+								tape_speed.minimum_start_bit_duration = ram()[0xfca4];
+								tape_speed.low_high_disrimination_duration = ram()[0xfca5];
 
 								// Ask the tape parser to grab a byte.
 								int next_byte = Parser::get_byte(tape_speed, tape_player_);
@@ -489,9 +501,12 @@ class ConcreteMachine:
 						if(!address) {
 							pc_zero_accesses_++;
 						}
-						if(read_pointers_[address >> 13] == unpopulated_) {
-							performed_unmapped_access_ = true;
-						}
+
+						// TODO: below relates to confidence measurements. Reinstate, somehow.
+//						if(is_unpopulated_[address >> 13] == unpopulated_) {
+//							performed_unmapped_access_ = true;
+//						}
+
 						pc_address_ = address;	// This is retained so as to be able to name the source of an access to cartridge handlers.
 						[[fallthrough]];
 
@@ -587,8 +602,8 @@ class ConcreteMachine:
 							const int buffer_size = 40;
 
 							// Also from the Red Book: GETPNT is at F3FAH and PUTPNT is at F3F8H.
-							int read_address = ram_[0xf3fa] | (ram_[0xf3fb] << 8);
-							int write_address = ram_[0xf3f8] | (ram_[0xf3f9] << 8);
+							int read_address = ram()[0xf3fa] | (ram()[0xf3fb] << 8);
+							int write_address = ram()[0xf3f8] | (ram()[0xf3f9] << 8);
 
 							// Write until either the string is exhausted or the write_pointer is immediately
 							// behind the read pointer; temporarily map write_address and read_address into
@@ -599,7 +614,7 @@ class ConcreteMachine:
 							while(characters_written < input_text_.size()) {
 								const int next_write_address = (write_address + 1) % buffer_size;
 								if(next_write_address == read_address) break;
-								ram_[write_address + buffer_start] = uint8_t(input_text_[characters_written]);
+								ram()[write_address + buffer_start] = uint8_t(input_text_[characters_written]);
 								++characters_written;
 								write_address = next_write_address;
 							}
@@ -607,8 +622,8 @@ class ConcreteMachine:
 
 							// Map the write address back into absolute terms and write it out again as PUTPNT.
 							write_address += buffer_start;
-							ram_[0xf3f8] = uint8_t(write_address);
-							ram_[0xf3f9] = uint8_t(write_address >> 8);
+							ram()[0xf3f8] = uint8_t(write_address);
+							ram()[0xf3f9] = uint8_t(write_address >> 8);
 						}
 					break;
 
@@ -690,6 +705,9 @@ class ConcreteMachine:
 		}
 
 	private:
+		uint8_t *ram() {
+			return memory_slots_[RAMMemorySlot].source().data();
+		}
 		DiskROM *get_disk_rom() {
 			return dynamic_cast<DiskROM *>(memory_slots_[2].handler.get());
 		}
@@ -795,15 +813,6 @@ class ConcreteMachine:
 		MemorySlot memory_slots_[4];
 		MemorySlot *final_slot_ = nullptr;
 
-		/// Base RAM.
-		uint8_t ram_[65536];
-
-		/// A never-read area that writes for unmapped regions can be diverted to.
-		uint8_t scratch_[8192];
-
-		/// A never-written area that reads for unmapped regions can be sourced from.
-		uint8_t unpopulated_[8192];
-
 		HalfCycles time_since_ay_update_;
 
 		uint8_t key_states_[16];
diff --git a/Machines/MSX/MemorySlotHandler.cpp b/Machines/MSX/MemorySlotHandler.cpp
index 5c039c8f1..28f160af1 100644
--- a/Machines/MSX/MemorySlotHandler.cpp
+++ b/Machines/MSX/MemorySlotHandler.cpp
@@ -39,16 +39,18 @@ uint8_t *MemorySlot::write_pointer(int segment) const {
 	return write_pointers_[subslot][segment];
 }
 
-void MemorySlot::apply_mapping(uint8_t port, uint8_t value) {
-	// TODO.
-	(void)port;
-	(void)value;
-}
-
 void MemorySlot::set_source(const std::vector<uint8_t> &source) {
 	source_ = source;
 }
 
+void MemorySlot::resize_source(std::size_t size) {
+	source_.resize(size);
+}
+
+std::vector<uint8_t> &MemorySlot::source() {
+	return source_;
+}
+
 const std::vector<uint8_t> &MemorySlot::source() const {
 	return source_;
 }
@@ -71,7 +73,6 @@ void MemorySlot::map(int subslot, std::size_t source_address, uint16_t destinati
 		source_address += 8192;
 	}
 
-	// TODO: allow write_pointers_ to be set.
 	// TODO: need to indicate that mapping changed.
 }
 
diff --git a/Machines/MSX/MemorySlotHandler.hpp b/Machines/MSX/MemorySlotHandler.hpp
index 3a1eefa8f..d20cba8a9 100644
--- a/Machines/MSX/MemorySlotHandler.hpp
+++ b/Machines/MSX/MemorySlotHandler.hpp
@@ -50,14 +50,14 @@ class MemorySlot {
 		/// @returns A pointer to the area of memory currently underneath @c address.
 		uint8_t *write_pointer(int segment) const;
 
-		/// Sets the value most-recently written to one of the standard
-		/// memory mapping ports, FC–FF.
-		void apply_mapping(uint8_t port, uint8_t value);
-
 		/// Copies an underlying source buffer.
 		void set_source(const std::vector<uint8_t> &source);
 
+		/// Sets the size of the underlying source buffer.
+		void resize_source(std::size_t);
+
 		/// Provides a reference to the internal source storage.
+		std::vector<uint8_t> &source();
 		const std::vector<uint8_t> &source() const;
 
 		enum AccessType {
@@ -107,6 +107,10 @@ class MemorySlotHandler {
 		/*! Seeks the result of a read at @c address; this is used only if the area is unmapped. */
 		virtual uint8_t read([[maybe_unused]] uint16_t address) { return 0xff; }
 
+		/// Sets the value most-recently written to one of the standard
+		/// memory mapping ports, FC–FF.
+		virtual void apply_mapping([[maybe_unused]] uint8_t port, [[maybe_unused]] uint8_t value) {}
+
 		/*! @returns The probability that this handler is correct for the data it owns. */
 		float get_confidence() {
 			return confidence_counter_.get_confidence();