diff --git a/Machines/Atari2600.cpp b/Machines/Atari2600.cpp
index 347bd8685..24fc65e63 100644
--- a/Machines/Atari2600.cpp
+++ b/Machines/Atari2600.cpp
@@ -23,6 +23,7 @@ Machine::Machine()
 	_crt = new Outputs::CRT(228, 262, 1, 4);
 	_piaTimerStatus = 0xff;
 	memset(_collisions, 0xff, sizeof(_collisions));
+	_rom = nullptr;
 
 	setup6502();
 	set_reset_line(true);
@@ -30,6 +31,7 @@ Machine::Machine()
 
 Machine::~Machine()
 {
+	delete[] _rom;
 	delete _crt;
 }
 
@@ -267,9 +269,30 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add
 
 	if(operation != CPU6502::BusOperation::Ready) {
 
-		// check for a ROM access
+		// check for a ROM or paging access
 		if ((address&0x1000) && isReadOperation(operation)) {
-			returnValue &= _rom[address&_romMask];
+
+			if(_rom_size > 4096 && ((address & 0x1f00) == 0x1f00)) {
+				uint8_t *base_ptr = _romPages[0];
+				uint8_t first_paging_register = 0xf8 - (_rom_size >> 14)*2;
+
+				const uint8_t paging_register = address&0xff;
+				if(paging_register >= first_paging_register) {
+					const uint16_t selected_page = paging_register - first_paging_register;
+					if(selected_page * 4096 < _rom_size) {
+						base_ptr = &_rom[selected_page * 4096];
+					}
+				}
+
+				if(base_ptr != _romPages[0]) {
+					_romPages[0] = base_ptr;
+					_romPages[1] = base_ptr + 1024;
+					_romPages[2] = base_ptr + 2048;
+					_romPages[3] = base_ptr + 3072;
+				}
+			}
+
+			returnValue &= _romPages[(address >> 10)&3][address&1023];
 		}
 
 		// check for a RAM access
@@ -458,7 +481,16 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add
 
 void Machine::set_rom(size_t length, const uint8_t *data)
 {
-	length = std::min((size_t)4096, length);
-	memcpy(_rom, data, length);
-	_romMask = length - 1;
+	_rom_size = 1024;
+	while(_rom_size < length && _rom_size < 32768) _rom_size <<= 1;
+
+	delete[] _rom;
+	_rom = new uint8_t[_rom_size];
+	memcpy(_rom, data, std::min(_rom_size, length));
+
+	size_t romMask = _rom_size - 1;
+	_romPages[0] = _rom;
+	_romPages[1] = &_rom[1024 & romMask];
+	_romPages[2] = &_rom[2048 & romMask];
+	_romPages[3] = &_rom[3072 & romMask];
 }
diff --git a/Machines/Atari2600.hpp b/Machines/Atari2600.hpp
index d8131d5f9..9a3d9dabb 100644
--- a/Machines/Atari2600.hpp
+++ b/Machines/Atari2600.hpp
@@ -30,8 +30,8 @@ class Machine: public CPU6502::Processor<Machine> {
 		Outputs::CRT *get_crt() { return _crt; }
 
 	private:
-		uint8_t _rom[4096], _ram[128];
-		uint16_t _romMask;
+		uint8_t *_rom, *_romPages[4], _ram[128];
+		size_t _rom_size;
 
 		uint64_t _timestamp;