1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-20 10:17:05 +00:00

Comment and collapse a lot of the recent indirectness.

This commit is contained in:
Thomas Harte
2025-11-26 12:01:22 -05:00
parent f1e4de1670
commit c23791ba1d
+22 -19
View File
@@ -624,6 +624,7 @@ private:
std::array<uint8_t, 16 * 1024> host_fs_rom_;
const uint8_t min_ram_slot_;
/// @returns A pointer to the start of the RAM segment representing @c page if any; otherwise @c nullptr.
uint8_t *ram_segment(const uint8_t page) {
if(page < min_ram_slot_) return nullptr;
const auto ram_floor = (0x100 << 14) - ram_.size();
@@ -644,6 +645,8 @@ private:
}
};
/// @returns A pointer to the ROM segment representing @c page if any; otherwise an object that converts to bool @c false. The returned object
/// names both the start of the ROM and how many pages into it this page rests.
ROMPage rom_segment(const uint8_t page) {
const auto rom_segment = [&](const uint8_t base, auto &source) -> ROMPage {
if(page < base || page >= base + source.size() / 0x4000) {
@@ -665,22 +668,19 @@ private:
return { nullptr, 0 };
}
// Ephemeral, user-set state, representing the current memory map as viewed from the Z80.
const uint8_t *read_pointers_[4] = {nullptr, nullptr, nullptr, nullptr};
uint8_t *write_pointers_[4] = {nullptr, nullptr, nullptr, nullptr};
uint8_t pages_[4] = {0x80, 0x80, 0x80, 0x80};
template <size_t slot, typename RomT>
bool page_rom(const uint8_t offset, const uint8_t location, const RomT &source) {
if(offset < location || offset >= location + source.size() / 0x4000) {
return false;
}
page<slot>(&source[(offset - location) * 0x4000], nullptr);
is_video_[slot] = false;
return true;
}
/// Pages whatever is supposed to be at @c offset into memory at @c slot, whether ROM or RAM, and updates the
/// @c test_host_fs_traps_ and relevant @c is_video_ flags.
template <size_t slot> void page(const uint8_t offset) {
const auto apply = [&](const uint8_t *const read, uint8_t *const write) {
read_pointers_[slot] = read ? read - (slot * 0x4000) : nullptr;
write_pointers_[slot] = write ? write - (slot * 0x4000) : nullptr;
};
pages_[slot] = offset;
const auto rom = rom_segment(offset);
@@ -693,7 +693,7 @@ private:
}
if(rom) {
page<slot>(rom.rom + rom.page_offset * 0x4000, nullptr);
apply(rom.rom + rom.page_offset * 0x4000, nullptr);
is_video_[slot] = false;
return;
}
@@ -705,16 +705,11 @@ private:
if(offset >= min_ram_slot_) {
is_video_[slot] = offset >= 0xfc; // TODO: this hard-codes a 64kb video assumption.
auto pointer = ram_segment(offset);
page<slot>(pointer, pointer);
apply(pointer, pointer);
return;
}
page<slot>(nullptr, nullptr);
}
template <size_t slot> void page(const uint8_t *const read, uint8_t *const write) {
read_pointers_[slot] = read ? read - (slot * 0x4000) : nullptr;
write_pointers_[slot] = write ? write - (slot * 0x4000) : nullptr;
apply(nullptr, nullptr);
}
// MARK: - Memory Timing
@@ -851,6 +846,7 @@ private:
std::unordered_set<uint16_t> host_fs_traps_;
bool test_host_fs_traps_ = false;
/// Reads from mamory as currently laid out.
uint8_t hostfs_read(const uint16_t address) override {
if(read_pointers_[address >> 14]) {
return read_pointers_[address >> 14][address];
@@ -859,11 +855,14 @@ private:
}
}
/// @returns The page that should be used to access memory at @c address within the current user memory map.
/// This is purely an EXOS construct. It has no basis in hardware.
uint8_t user_page(const uint16_t address) {
const auto page_id = address >> 14;
return read_pointers_[0xbffc >> 14] ? read_pointers_[0xbffc >> 14][0xbffc + page_id] : 0xff;
}
/// @returns The byte of RAM at @c address in the user memory map, if RAM is paged there. @c nullptr otherwise.
uint8_t *user_ram(const uint8_t page, const uint16_t address) {
// "User" accesses go to to wherever the user last had paged;
// per 5.4 System Segment Usage those pages are stored in memory from
@@ -876,6 +875,7 @@ private:
return nullptr;
}
/// @returns The byte at @c address in the user memory map, whether ROM or RAM.
uint8_t hostfs_user_read(const uint16_t address) override {
const auto page = user_page(address);
@@ -888,11 +888,14 @@ private:
return 0xff;
}
/// Writes a byte to an address in the user memory map, if it's RAM. Otherwise acts as a no-op.
void hostfs_user_write(const uint16_t address, const uint8_t value) override {
const auto ram = user_ram(user_page(address), address);
if(ram) *ram = value;
}
/// Searches @c host_fs_rom_ for high-level hooks and records those addresses into @c host_fs_traps_ with the assumption that the rom will
/// be paged at 0xc000. Then covers up the hook with NOPs other than the first byte, which captures the hook code.
void find_host_fs_hooks() {
static constexpr uint8_t syscall[] = {
0xed, 0xfe, 0xfe