1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Mildly reduce cost of 8-byte ROM overlay.

This commit is contained in:
Thomas Harte 2023-11-27 15:48:30 -05:00
parent 2a0375e9c2
commit 87eec47b79

View File

@ -100,8 +100,7 @@ class ConcreteMachine:
Memory::PackBigEndian16(roms.find(rom_name)->second, rom_); Memory::PackBigEndian16(roms.find(rom_name)->second, rom_);
// Set up basic memory map. // Set up basic memory map.
memory_map_[0] = BusDevice::MostlyRAM; int c = 0;
int c = 1;
for(; c < int(ram_.size() >> 16); ++c) memory_map_[c] = BusDevice::RAM; for(; c < int(ram_.size() >> 16); ++c) memory_map_[c] = BusDevice::RAM;
for(; c < 0x40; ++c) memory_map_[c] = BusDevice::Floating; for(; c < 0x40; ++c) memory_map_[c] = BusDevice::Floating;
for(; c < 0xff; ++c) memory_map_[c] = BusDevice::Unassigned; for(; c < 0xff; ++c) memory_map_[c] = BusDevice::Unassigned;
@ -118,6 +117,9 @@ class ConcreteMachine:
memory_map_[0xfa] = memory_map_[0xfb] = BusDevice::Cartridge; memory_map_[0xfa] = memory_map_[0xfb] = BusDevice::Cartridge;
memory_map_[0xff] = BusDevice::IO; memory_map_[0xff] = BusDevice::IO;
// Copy the first 8 bytes of ROM into RAM.
reinstall_rom_vector();
midi_acia_->set_interrupt_delegate(this); midi_acia_->set_interrupt_delegate(this);
keyboard_acia_->set_interrupt_delegate(this); keyboard_acia_->set_interrupt_delegate(this);
@ -249,18 +251,15 @@ class ConcreteMachine:
uint8_t *memory = nullptr; uint8_t *memory = nullptr;
switch(memory_map_[address >> 16]) { switch(memory_map_[address >> 16]) {
default: default:
case BusDevice::MostlyRAM:
if(address < 8) {
memory = rom_.data();
break;
}
[[fallthrough]];
case BusDevice::RAM: case BusDevice::RAM:
memory = ram_.data(); memory = ram_.data();
break; break;
case BusDevice::ROM: case BusDevice::ROM:
memory = rom_.data(); memory = rom_.data();
if(!(operation & Microcycle::Read)) {
return delay;
}
address -= rom_start_; address -= rom_start_;
break; break;
@ -408,6 +407,9 @@ class ConcreteMachine:
} }
// If control has fallen through to here, the access is either a read from ROM, or a read or write to RAM. // If control has fallen through to here, the access is either a read from ROM, or a read or write to RAM.
//
// In both write cases, immediately reinstall the first eight bytes of RAM from ROM, so that any write to
// that area is in effect a no-op. This is cheaper than the conditionality of actually checking.
switch(operation & (Microcycle::SelectWord | Microcycle::SelectByte | Microcycle::Read)) { switch(operation & (Microcycle::SelectWord | Microcycle::SelectByte | Microcycle::Read)) {
default: default:
break; break;
@ -422,17 +424,23 @@ class ConcreteMachine:
if(address >= video_range_.low_address && address < video_range_.high_address) if(address >= video_range_.low_address && address < video_range_.high_address)
video_.flush(); video_.flush();
*reinterpret_cast<uint16_t *>(&memory[address]) = cycle.value->w; *reinterpret_cast<uint16_t *>(&memory[address]) = cycle.value->w;
reinstall_rom_vector();
break; break;
case Microcycle::SelectByte: case Microcycle::SelectByte:
if(address >= video_range_.low_address && address < video_range_.high_address) if(address >= video_range_.low_address && address < video_range_.high_address)
video_.flush(); video_.flush();
memory[address] = cycle.value->b; memory[address] = cycle.value->b;
reinstall_rom_vector();
break; break;
} }
return HalfCycles(0); return HalfCycles(0);
} }
void reinstall_rom_vector() {
std::copy(rom_.begin(), rom_.begin() + 8, ram_.begin());
}
void flush_output(int outputs) final { void flush_output(int outputs) final {
dma_.flush(); dma_.flush();
mfp_.flush(); mfp_.flush();
@ -520,8 +528,6 @@ class ConcreteMachine:
uint32_t rom_start_ = 0; uint32_t rom_start_ = 0;
enum class BusDevice { enum class BusDevice {
/// A mostly RAM page is one that returns ROM for the first 8 bytes, RAM elsewhere.
MostlyRAM,
/// Allows reads and writes to ram_. /// Allows reads and writes to ram_.
RAM, RAM,
/// Nothing is mapped to this area, and it also doesn't trigger an exception upon access. /// Nothing is mapped to this area, and it also doesn't trigger an exception upon access.