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

Make a close-enough guess at chrominances.

This commit is contained in:
Thomas Harte 2024-12-13 22:25:23 -05:00
parent 700b848f26
commit f41b54de21
2 changed files with 41 additions and 27 deletions

View File

@ -185,10 +185,16 @@ public:
case 0xff09: *value = interrupts_.status(); break;
case 0xff0a: *value = interrupts_.mask(); break;
case 0xff06: *value = video_.read<0xff06>(); break;
case 0xff07: *value = video_.read<0xff07>(); break;
case 0xff0b: *value = video_.read<0xff0b>(); break;
case 0xff1c: *value = video_.read<0xff1c>(); break;
case 0xff1d: *value = video_.read<0xff1d>(); break;
case 0xff12: *value = ff12_; break;
case 0xff13: *value = ff13_ | (rom_is_paged_ ? 1 : 0); break;
case 0xff14: *value = video_.read<0xff14>(); break;
case 0xff15: *value = video_.read<0xff15>(); break;
case 0xff16: *value = video_.read<0xff16>(); break;
case 0xff17: *value = video_.read<0xff17>(); break;
@ -207,7 +213,7 @@ public:
case 0xff04: timers_.write<4>(*value); break;
case 0xff05: timers_.write<5>(*value); break;
case 0xff08: {
case 0xff08:
keyboard_latch_ = ~(
((*value & 0x01) ? 0x00 : key_states_[0]) |
((*value & 0x02) ? 0x00 : key_states_[1]) |
@ -218,7 +224,7 @@ public:
((*value & 0x40) ? 0x00 : key_states_[6]) |
((*value & 0x80) ? 0x00 : key_states_[7])
);
} break;
break;
case 0xff09:
interrupts_.set_status(*value);
@ -233,8 +239,14 @@ public:
case 0xff07: video_.write<0xff07>(*value); break;
case 0xff0c: video_.write<0xff0c>(*value); break;
case 0xff0d: video_.write<0xff0d>(*value); break;
case 0xff12: video_.write<0xff12>(*value); break;
case 0xff13: video_.write<0xff13>(*value); break;
case 0xff12:
ff12_ = *value & 0x3f;
video_.write<0xff12>(*value);
break;
case 0xff13:
ff13_ = *value & 0xfe;
video_.write<0xff13>(*value);
break;
case 0xff14: video_.write<0xff14>(*value); break;
case 0xff1a: video_.write<0xff1a>(*value); break;
case 0xff1b: video_.write<0xff1b>(*value); break;
@ -270,10 +282,13 @@ private:
// TODO: allow other ROM selection. And no ROM?
map_.page<PagerSide::Read, 0x8000, 16384>(basic_.data());
map_.page<PagerSide::Read, 0xc000, 16384>(kernel_.data());
rom_is_paged_ = true;
}
void page_ram() {
map_.page<PagerSide::Read, 0x8000, 32768>(&ram_[0x8000]);
rom_is_paged_ = false;
}
bool rom_is_paged_ = false;
void set_scan_target(Outputs::Display::ScanTarget *const target) final {
video_.set_scan_target(target);
@ -295,6 +310,7 @@ private:
std::array<uint8_t, 65536> ram_;
std::vector<uint8_t> kernel_;
std::vector<uint8_t> basic_;
uint8_t ff12_, ff13_;
Interrupts interrupts_;
Cycles timers_subcycles_;

View File

@ -32,9 +32,12 @@ public:
template <uint16_t address>
uint8_t read() const {
switch(address) {
case 0xff06: return ff06_;
case 0xff07: return ff07_;
case 0xff0b: return uint8_t(raster_interrupt_);
case 0xff1c: return uint8_t(vertical_counter_ >> 8);
case 0xff1d: return uint8_t(vertical_counter_);
case 0xff14: return uint8_t((screen_memory_address_ >> 8) & 0xf8);
case 0xff15: case 0xff16: case 0xff17: case 0xff18: case 0xff19:
return raw_background_[size_t(address - 0xff15)];
@ -58,6 +61,7 @@ public:
switch(address) {
case 0xff06:
ff06_ = value;
extended_colour_mode_ = value & 0x40;
bitmap_mode_ = value & 0x20;
display_enable_ = value & 0x10;
@ -66,6 +70,7 @@ public:
break;
case 0xff07:
ff07_ = value;
characters_256_ = value & 0x80;
is_ntsc_ = value & 0x40;
ted_off_ = value & 0x20;
@ -79,6 +84,7 @@ public:
break;
case 0xff13:
character_generator_address_ = uint16_t((value & 0xfc) << 8);
single_clock_ = value & 0x02;
break;
case 0xff14:
screen_memory_address_ = uint16_t((value & 0xf8) << 8);
@ -102,37 +108,17 @@ public:
const uint8_t luminance = (value & 0x0f) ? uint8_t(
((value & 0x70) << 1) | ((value & 0x70) >> 2) | ((value & 0x70) >> 5)
) : 0;
const auto chrominance = uint8_t([&] {
switch(value & 0x0f) {
default:
printf("Unmapped colour: %d\n", value & 0x0f);
[[fallthrough]];
case 0:
case 1: return 0xff;
// The following have been eyeballed.
// case 5: return 3;
// case 7: return 3;
// case 11: return 3;
case 14: return 5;
}
}());
background_[size_t(address - 0xff15)] = uint16_t(
luminance | (chrominance << 8)
luminance | (chrominances[value & 0x0f] << 8)
);
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_);
}
Cycles cycle_length([[maybe_unused]] bool is_ready) const {
// TODO: the complete test is more than this.
// TODO: if this is a RDY cycle, can reply with time until end-of-RDY.
const bool is_long_cycle = refresh_;
const bool is_long_cycle = single_clock_ || refresh_;
if(is_ntsc_) {
return is_long_cycle ? Cycles(8) : Cycles(4);
@ -227,7 +213,7 @@ public:
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_data(time_in_state_, time_in_state_); break;
case OutputState::Pixels: crt_.output_data(time_in_state_, size_t(time_in_state_)); break;
}
time_in_state_ = 0;
@ -366,12 +352,15 @@ private:
bool horizontal_blank_ = false;
bool horizontal_sync_ = false;
bool horizontal_burst_ = false;
uint8_t ff06_;
uint16_t character_address_ = 0;
uint16_t line_character_address_ = 0;
bool fetch_characters_;
bool output_pixels_;
bool refresh_ = false;
bool single_clock_ = false;
uint8_t ff07_;
enum class OutputState {
Blank,
@ -388,6 +377,15 @@ private:
const Commodore::Plus4::Pager &pager_;
Interrupts &interrupts_;
// The following aren't accurate; they're eyeballed to be close enough for now in PAL.
static constexpr uint8_t chrominances[] = {
0xff, 0xff,
90, 23, 105, 59,
14, 69, 83, 78,
50, 96, 32, 9,
5, 41,
};
};
}