1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Gets started on different video timings.

This commit is contained in:
Thomas Harte 2021-04-14 22:23:27 -04:00
parent 0af405aa46
commit f10ec80153
2 changed files with 131 additions and 44 deletions

View File

@ -69,6 +69,7 @@ template <VideoTiming timing> class Video {
};
static constexpr Timings get_timings() {
if constexpr (timing == VideoTiming::Plus3) {
// Amstrad gate array timings, classic statement:
//
// Contention begins 14361 cycles "after interrupt" and follows the pattern [1, 0, 7, 6 5 4, 3, 2].
@ -110,9 +111,71 @@ template <VideoTiming timing> class Video {
4, 3,
}
};
return result;
}
// TODO: fix 48kb and 128kb timings, below.
if constexpr (timing == VideoTiming::OneTwoEightK) {
constexpr Timings result = {
.cycles_per_line = 228 * 2,
.lines_per_frame = 311,
// i.e. video fetching begins five cycles after the start of the
// contended memory pattern below; that should put a clear two
// cycles between a Z80 access and the first video fetch.
.contention_leadin = 5 * 2,
.contention_duration = 128 * 2,
// i.e. interrupt is first signalled 14368 cycles before the first video fetch.
.interrupt_time = (228*311 - 14361) * 2,
.delays = {
12, 11,
10, 9,
8, 7,
6, 5,
4, 3,
2, 1,
0, 0,
0, 0,
}
};
return result;
}
if constexpr (timing == VideoTiming::FortyEightK) {
constexpr Timings result = {
.cycles_per_line = 224 * 2,
.lines_per_frame = 312,
// i.e. video fetching begins five cycles after the start of the
// contended memory pattern below; that should put a clear two
// cycles between a Z80 access and the first video fetch.
.contention_leadin = 5 * 2,
.contention_duration = 128 * 2,
// i.e. interrupt is first signalled 14368 cycles before the first video fetch.
.interrupt_time = (224*312 - 14361) * 2,
.delays = {
12, 11,
10, 9,
8, 7,
6, 5,
4, 3,
2, 1,
0, 0,
0, 0,
}
};
return result;
}
}
// TODO: how long is the interrupt line held for?
static constexpr int interrupt_duration = 48;
@ -238,9 +301,14 @@ template <VideoTiming timing> class Video {
if(offset >= burst_position && offset < burst_position+burst_length && end_offset > offset) {
const int burst_duration = std::min(burst_position + burst_length, end_offset) - offset;
if constexpr (timing >= VideoTiming::OneTwoEightK) {
crt_.output_colour_burst(burst_duration, 116, is_alternate_line_);
offset += burst_duration;
// The colour burst phase above is an empirical guess. I need to research further.
} else {
crt_.output_default_colour_burst(burst_duration);
}
offset += burst_duration;
}
if(offset >= burst_position+burst_length && end_offset > offset) {
@ -261,9 +329,21 @@ template <VideoTiming timing> class Video {
crt_.output_level(duration);
}
static constexpr int half_cycles_per_line() {
if constexpr (timing == VideoTiming::FortyEightK) {
// TODO: determine real figure here, if one exists.
// The source I'm looking at now suggests that the theoretical
// ideal of 224*2 ignores the real-life effects of separate
// crystals, so I've nudged this experimentally.
return 224*2 - 1;
} else {
return 227*2;
}
}
public:
Video() :
crt_(227 * 2, 2, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red2Green2Blue2)
crt_(half_cycles_per_line(), 2, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red2Green2Blue2)
{
// Show only the centre 80% of the TV frame.
crt_.set_display_type(Outputs::Display::DisplayType::RGB);

View File

@ -638,8 +638,15 @@ template<Model model> class ConcreteMachine:
}
// MARK: - Video.
static constexpr VideoTiming video_timing = VideoTiming::Plus3;
JustInTimeActor<Video<video_timing>> video_;
using VideoType =
std::conditional_t<
model <= Model::FortyEightK, Video<VideoTiming::FortyEightK>,
std::conditional_t<
model <= Model::Plus2, Video<VideoTiming::OneTwoEightK>,
Video<VideoTiming::Plus3>
>
>;
JustInTimeActor<VideoType> video_;
// MARK: - Keyboard.
Sinclair::ZX::Keyboard::Keyboard keyboard_;