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:
@@ -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 ®ion = regions[region_map[0]];
|
auto ®ion = 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 ®ion = regions[region_map[page]]; \
|
auto ®ion = 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[(®ion.write[address] - map.ram_base) % (128 * 1024) + map.shadow_offset] = *value; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user