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:
parent
700b848f26
commit
f41b54de21
@ -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_;
|
||||
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user