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:
parent
1d07b8238c
commit
ed766c74e6
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user