1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-10 16:30:07 +00:00

Add some paging.

This commit is contained in:
Thomas Harte 2024-12-12 21:17:28 -05:00
parent 1d07b8238c
commit ed766c74e6
3 changed files with 49 additions and 13 deletions

View File

@ -8,6 +8,12 @@
#pragma once
enum PagerSide {
Read = 1,
Write = 2,
ReadWrite = Read | Write,
};
template <typename AddressT, typename DataT, int NumPages>
class Pager {
public:
@ -18,10 +24,16 @@ public:
return write_[address >> Shift][address];
}
template <int slot>
void page(const uint8_t *read, uint8_t *write) {
write_[slot] = write - (slot << Shift);
read_[slot] = read - (slot << Shift);
template <int side, size_t start, size_t length>
void page(uint8_t *data) {
static_assert(!(start % PageSize), "Start address must be a multiple of the page size");
static_assert(!(length % PageSize), "Data length must be a multiple of the page size");
for(size_t slot = start >> Shift; slot < (start + length) >> Shift; slot++) {
if constexpr (side & PagerSide::Write) write_[slot] = data - (slot << Shift);
if constexpr (side & PagerSide::Read) read_[slot] = data - (slot << Shift);
data += PageSize;
}
}
private:

View File

@ -115,10 +115,8 @@ public:
kernel_ = roms.find(kernel)->second;
basic_ = roms.find(basic)->second;
map_.page<0>(ram_.data(), ram_.data());
map_.page<1>(ram_.data() + 16*1024, ram_.data() + 16*1024);
map_.page<2>(basic_.data(), ram_.data() + 32*1024);
map_.page<3>(kernel_.data(), ram_.data() + 48*1024);
map_.page<PagerSide::ReadWrite, 0, 65536>(ram_.data());
page_rom();
insert_media(target.media);
}
@ -185,6 +183,9 @@ public:
case 0xff1a: video_.write<0xff1a>(*value); break;
case 0xff1b: video_.write<0xff1b>(*value); break;
case 0xff3e: page_rom(); break;
case 0xff3f: page_ram(); break;
default:
printf("TODO: TED write at %04x\n", address);
}
@ -197,6 +198,14 @@ public:
private:
CPU::MOS6502::Processor<CPU::MOS6502::Personality::P6502, ConcreteMachine, true> m6502_;
void page_rom() {
map_.page<PagerSide::Read, 0x8000, 16384>(basic_.data());
map_.page<PagerSide::Read, 0xc000, 16384>(kernel_.data());
}
void page_ram() {
map_.page<PagerSide::Read, 0x8000, 32768>(&ram_[0x8000]);
}
void set_scan_target(Outputs::Display::ScanTarget *const target) final {
video_.set_scan_target(target);
}

View File

@ -13,6 +13,8 @@
#include "../../../Numeric/UpperBound.hpp"
#include "../../../Outputs/CRT/CRT.hpp"
#include <array>
namespace Commodore::Plus4 {
struct Video {
@ -67,6 +69,17 @@ public:
case 0xff0d: load_low8(cursor_address_); break;
case 0xff1a: load_high10(character_row_address_); break;
case 0xff1b: load_low8(character_row_address_); break;
case 0xff15: case 0xff16: case 0xff17: case 0xff18: case 0xff19: {
const uint8_t luminance = uint8_t(
((value & 0x70) << 1) | ((value & 0x70) >> 2) | ((value & 0x70) >> 5)
);
background_[value - 0xff15] = uint16_t(
luminance
);
printf("%02x -> %04x\n", value, address);
} break;
}
// printf("bitmap:%d c256:%d ntsc:%d 40col:%d; base:%04x\n", bitmap_mode_, characters_256_, is_ntsc_, columns_40_, screen_memory_address_);
@ -151,11 +164,11 @@ public:
if(state != output_state_) {
switch(output_state_) {
case OutputState::Blank: crt_.output_blank(time_in_state_); break;
case OutputState::Sync: crt_.output_sync(time_in_state_); break;
case OutputState::Burst: crt_.output_default_colour_burst(time_in_state_); break;
case OutputState::Border: crt_.output_level<uint16_t>(time_in_state_, 0x8080); break;
case OutputState::Pixels: crt_.output_level<uint16_t>(time_in_state_, 0xff80); break;
case OutputState::Blank: crt_.output_blank(time_in_state_); break;
case OutputState::Sync: crt_.output_sync(time_in_state_); break;
case OutputState::Burst: crt_.output_default_colour_burst(time_in_state_); break;
case OutputState::Border: crt_.output_level<uint16_t>(time_in_state_, background_[4]); break;
case OutputState::Pixels: crt_.output_level<uint16_t>(time_in_state_, background_[0]); break;
}
time_in_state_ = 0;
}
@ -288,6 +301,8 @@ private:
} output_state_ = OutputState::Blank;
int time_in_state_ = 0;
std::array<uint16_t, 5> background_{};
const Commodore::Plus4::Pager &pager_;
};