1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-09 20:25:19 +00:00

Contorts somewhat in pursuit of branchless shadowing regardless of page and without extra storage.

This commit is contained in:
Thomas Harte
2020-10-27 21:37:39 -04:00
parent bdda84dfde
commit 20631a157b

View File

@@ -27,7 +27,7 @@ class MemoryMap {
void set_storage(std::vector<uint8_t> &ram, std::vector<uint8_t> &rom) { void set_storage(std::vector<uint8_t> &ram, std::vector<uint8_t> &rom) {
// Keep a pointer for later; also note the proper RAM offset. // Keep a pointer for later; also note the proper RAM offset.
ram_ = ram.data(); ram_base = ram.data();
shadow_offset = ram.size() - (128*1024); shadow_offset = ram.size() - (128*1024);
// Establish bank mapping. // Establish bank mapping.
@@ -209,7 +209,6 @@ class MemoryMap {
Apple::II::LanguageCardSwitches<MemoryMap> language_card_; Apple::II::LanguageCardSwitches<MemoryMap> language_card_;
friend Apple::II::AuxiliaryMemorySwitches<MemoryMap>; friend Apple::II::AuxiliaryMemorySwitches<MemoryMap>;
friend Apple::II::LanguageCardSwitches<MemoryMap>; friend Apple::II::LanguageCardSwitches<MemoryMap>;
uint8_t *ram_ = nullptr;
uint8_t shadow_register_ = 0x08; uint8_t shadow_register_ = 0x08;
uint8_t speed_register_ = 0x00; uint8_t speed_register_ = 0x00;
@@ -245,20 +244,20 @@ class MemoryMap {
}; };
auto set_no_card = [this](uint32_t bank_base) { auto set_no_card = [this](uint32_t bank_base) {
auto &d0_region = regions[region_map[bank_base | 0xd0]]; auto &d0_region = regions[region_map[bank_base | 0xd0]];
d0_region.read = ram_; d0_region.read = ram_base;
d0_region.write = ram_; d0_region.write = ram_base;
auto &e0_region = regions[region_map[bank_base | 0xe0]]; auto &e0_region = regions[region_map[bank_base | 0xe0]];
e0_region.read = ram_; e0_region.read = ram_base;
e0_region.write = ram_; e0_region.write = ram_base;
}; };
if(inhibit_banks0001) { if(inhibit_banks0001) {
set_no_card(0x0000); set_no_card(0x0000);
set_no_card(0x0100); set_no_card(0x0100);
} else { } else {
apply(0x0000, zero_state ? &ram_[0x10000] : ram_); apply(0x0000, zero_state ? &ram_base[0x10000] : ram_base);
apply(0x0100, ram_); apply(0x0100, ram_base);
} }
uint8_t *const e0_ram = regions[region_map[0xe000]].write; uint8_t *const e0_ram = regions[region_map[0xe000]].write;
@@ -309,12 +308,12 @@ class MemoryMap {
// regular RAM (or possibly auxiliary). // regular RAM (or possibly auxiliary).
const auto auxiliary_state = auxiliary_switches_.main_state(); const auto auxiliary_state = auxiliary_switches_.main_state();
for(uint8_t region = region_map[0x00c0]; region < region_map[0x00d0]; region++) { for(uint8_t region = region_map[0x00c0]; region < region_map[0x00d0]; region++) {
regions[region].read = auxiliary_state.base.read ? &ram_[0x10000] : ram_; regions[region].read = auxiliary_state.base.read ? &ram_base[0x10000] : ram_base;
regions[region].write = auxiliary_state.base.write ? &ram_[0x10000] : ram_; regions[region].write = auxiliary_state.base.write ? &ram_base[0x10000] : ram_base;
regions[region].flags &= ~Region::IsIO; regions[region].flags &= ~Region::IsIO;
} }
for(uint8_t region = region_map[0x01c0]; region < region_map[0x01d0]; region++) { for(uint8_t region = region_map[0x01c0]; region < region_map[0x01d0]; region++) {
regions[region].read = regions[region].write = ram_; regions[region].read = regions[region].write = ram_base;
regions[region].flags &= ~Region::IsIO; regions[region].flags &= ~Region::IsIO;
} }
} else { } else {
@@ -331,7 +330,7 @@ class MemoryMap {
void set_zero_page_paging() { void set_zero_page_paging() {
// Affects bank $00 only, and should be a single region. // Affects bank $00 only, and should be a single region.
auto &region = regions[region_map[0]]; auto &region = regions[region_map[0]];
region.read = region.write = auxiliary_switches_.zero_state() ? &ram_[0x10000] : ram_; region.read = region.write = auxiliary_switches_.zero_state() ? &ram_base[0x10000] : ram_base;
// Switching to or from auxiliary RAM potentially affects the language // Switching to or from auxiliary RAM potentially affects the language
// and regular card areas. // and regular card areas.
@@ -373,7 +372,6 @@ class MemoryMap {
// TODO: does inhibiting Super Hi-Res also affect the regular hi-res pages? // TODO: does inhibiting Super Hi-Res also affect the regular hi-res pages?
#undef apply #undef apply
} }
void set_main_paging() { void set_main_paging() {
@@ -381,8 +379,8 @@ class MemoryMap {
#define set(page, flags) {\ #define set(page, flags) {\
auto &region = regions[region_map[page]]; \ auto &region = regions[region_map[page]]; \
region.read = flags.read ? &ram_[0x10000] : ram_; \ region.read = flags.read ? &ram_base[0x10000] : ram_base; \
region.write = flags.write ? &ram_[0x10000] : ram_; \ region.write = flags.write ? &ram_base[0x10000] : ram_base; \
} }
set(0x02, state.base); set(0x02, state.base);
@@ -407,6 +405,7 @@ class MemoryMap {
// Pointers are eight bytes at the time of writing, so the extra level of indirection // Pointers are eight bytes at the time of writing, so the extra level of indirection
// reduces what would otherwise be a 1.25mb table down to not a great deal more than 64kb. // reduces what would otherwise be a 1.25mb table down to not a great deal more than 64kb.
std::array<uint8_t, 65536> region_map; std::array<uint8_t, 65536> region_map;
uint8_t *ram_base = nullptr;
size_t shadow_offset; size_t shadow_offset;
struct Region { struct Region {
@@ -432,7 +431,7 @@ class MemoryMap {
if(region.write) { \ if(region.write) { \
region.write[address] = *value; \ region.write[address] = *value; \
if(region.flags & MemoryMap::Region::IsShadowed) { \ if(region.flags & MemoryMap::Region::IsShadowed) { \
region.write[address + map.shadow_offset] = *value; \ map.ram_base[(&region.write[address] - map.ram_base) % (128 * 1024) + map.shadow_offset] = *value; \
} \ } \
} }