mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Switch to purposive name.
This commit is contained in:
parent
c75efb7dac
commit
40d5bd4e58
@ -24,8 +24,9 @@ enum class Clock {
|
||||
TMSMemoryWindow,
|
||||
/// A fixed 1368-cycle/line clock that is used to count output to the CRT.
|
||||
CRT,
|
||||
/// Provides the same clock rate as ::Internal but is relocated so that 0 is where Grauw put 0 (i.e. at the start of horizontal sync).
|
||||
Grauw,
|
||||
/// Provides the same clock rate as ::Internal but is relocated so that 0 is the start of horizontal sync — very not coincidentally,
|
||||
/// where Grauw puts 0 on his detailed TMS and Yamaha timing diagrams.
|
||||
FromStartOfSync,
|
||||
};
|
||||
|
||||
template <Personality personality, Clock clk> constexpr int clock_rate() {
|
||||
@ -40,7 +41,7 @@ template <Personality personality, Clock clk> constexpr int clock_rate() {
|
||||
case Clock::TMSMemoryWindow: return 171;
|
||||
case Clock::CRT: return 1368;
|
||||
case Clock::Internal:
|
||||
case Clock::Grauw:
|
||||
case Clock::FromStartOfSync:
|
||||
if constexpr (is_classic_vdp(personality)) {
|
||||
return 342;
|
||||
} else if constexpr (is_yamaha_vdp(personality)) {
|
||||
@ -53,8 +54,8 @@ template <Personality personality, Clock clk> constexpr int clock_rate() {
|
||||
|
||||
/// Statelessly converts @c length to the internal clock for @c personality; applies conversions per the list of clocks in left-to-right order.
|
||||
template <Personality personality, Clock head, Clock... tail> constexpr int to_internal(int length) {
|
||||
if constexpr (head == Clock::Grauw) {
|
||||
length = (length + LineLayout<personality>::LocationOfGrauwZero) % LineLayout<personality>::CyclesPerLine;
|
||||
if constexpr (head == Clock::FromStartOfSync) {
|
||||
length = (length + LineLayout<personality>::StartOfSync) % LineLayout<personality>::CyclesPerLine;
|
||||
} else {
|
||||
length = length * clock_rate<personality, Clock::Internal>() / clock_rate<personality, head>();
|
||||
}
|
||||
@ -68,8 +69,10 @@ template <Personality personality, Clock head, Clock... tail> constexpr int to_i
|
||||
|
||||
/// Statelessly converts @c length to @c clock from the the internal clock used by VDPs of @c personality throwing away any remainder.
|
||||
template <Personality personality, Clock head, Clock... tail> constexpr int from_internal(int length) {
|
||||
if constexpr (head == Clock::Grauw) {
|
||||
length = (length + LineLayout<personality>::CyclesPerLine - LineLayout<personality>::LocationOfGrauwZero) % LineLayout<personality>::CyclesPerLine;
|
||||
if constexpr (head == Clock::FromStartOfSync) {
|
||||
length =
|
||||
(length + LineLayout<personality>::CyclesPerLine - LineLayout<personality>::StartOfSync)
|
||||
% LineLayout<personality>::CyclesPerLine;
|
||||
} else {
|
||||
length = length * clock_rate<personality, head>() / clock_rate<personality, Clock::Internal>();
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ template<bool use_end, typename SequencerT> void Base<personality>::dispatch(Seq
|
||||
#define index(n) \
|
||||
if(use_end && end == n) return; \
|
||||
[[fallthrough]]; \
|
||||
case n: fetcher.template fetch<from_internal<personality, Clock::Grauw>(n)>();
|
||||
case n: fetcher.template fetch<from_internal<personality, Clock::FromStartOfSync>(n)>();
|
||||
|
||||
switch(start) {
|
||||
default: assert(false);
|
||||
@ -373,7 +373,7 @@ struct RefreshSequencer {
|
||||
|
||||
template <int cycle> void fetch() {
|
||||
if(cycle < 26 || (cycle & 1) || cycle >= 154) {
|
||||
base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ struct TextSequencer {
|
||||
template <int cycle> void fetch() {
|
||||
// The first 30 and the final 4 slots are external.
|
||||
if constexpr (cycle < 30 || cycle >= 150) {
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
return;
|
||||
} else {
|
||||
// For the 120 slots in between follow a three-step pattern of:
|
||||
@ -398,7 +398,7 @@ struct TextSequencer {
|
||||
fetcher.fetch_name(column);
|
||||
break;
|
||||
case 1: // (2) external slot.
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
break;
|
||||
case 2: // (3) fetch tile pattern.
|
||||
fetcher.fetch_pattern(column);
|
||||
@ -419,7 +419,7 @@ struct CharacterSequencer {
|
||||
|
||||
template <int cycle> void fetch() {
|
||||
if(cycle < 5) {
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
|
||||
if(cycle == 5) {
|
||||
@ -430,7 +430,7 @@ struct CharacterSequencer {
|
||||
}
|
||||
|
||||
if(cycle > 14 && cycle < 19) {
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
|
||||
// Fetch 8 new sprite Y coordinates, to begin selecting sprites for next line.
|
||||
@ -448,7 +448,7 @@ struct CharacterSequencer {
|
||||
case 0: character_fetcher.fetch_name(block); break;
|
||||
case 1:
|
||||
if(!(block & 3)) {
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
} else {
|
||||
constexpr int sprite = 8 + ((block >> 2) * 3) + ((block & 3) - 1);
|
||||
sprite_fetcher.fetch_y(sprite);
|
||||
@ -463,7 +463,7 @@ struct CharacterSequencer {
|
||||
}
|
||||
|
||||
if(cycle >= 155 && cycle < 157) {
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
character_fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
|
||||
if(cycle == 157) {
|
||||
@ -511,7 +511,7 @@ struct SMSSequencer {
|
||||
// window 0 to HSYNC low.
|
||||
template <int cycle> void fetch() {
|
||||
if(cycle < 3) {
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
|
||||
if(cycle == 3) {
|
||||
@ -522,7 +522,7 @@ struct SMSSequencer {
|
||||
}
|
||||
|
||||
if(cycle == 15 || cycle == 16) {
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
|
||||
if(cycle == 17) {
|
||||
@ -543,7 +543,7 @@ struct SMSSequencer {
|
||||
case 0: fetcher.fetch_tile_name(block); break;
|
||||
case 1:
|
||||
if(!(block & 3)) {
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
} else {
|
||||
constexpr int sprite = (8 + ((block >> 2) * 3) + ((block & 3) - 1)) << 1;
|
||||
fetcher.posit_sprite(sprite);
|
||||
@ -555,7 +555,7 @@ struct SMSSequencer {
|
||||
}
|
||||
|
||||
if(cycle >= 153 && cycle < 157) {
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
|
||||
if(cycle == 157) {
|
||||
@ -566,7 +566,7 @@ struct SMSSequencer {
|
||||
}
|
||||
|
||||
if(cycle >= 169) {
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::Grauw>(cycle));
|
||||
fetcher.base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow, Clock::FromStartOfSync>(cycle));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ template <Personality personality, typename Enable = void> struct LineLayout;
|
||||
// * text mode on all VDPs adjusts border width.
|
||||
|
||||
template <Personality personality> struct LineLayout<personality, std::enable_if_t<is_classic_vdp(personality)>> {
|
||||
constexpr static int StartOfSync = 0;
|
||||
constexpr static int EndOfSync = 26;
|
||||
constexpr static int StartOfColourBurst = 29;
|
||||
constexpr static int EndOfColourBurst = 43;
|
||||
@ -47,14 +48,13 @@ template <Personality personality> struct LineLayout<personality, std::enable_if
|
||||
// and falls into the collection gap between the final sprite
|
||||
// graphics and the initial tiles or pixels.
|
||||
|
||||
constexpr static int LocationOfGrauwZero = 0;
|
||||
|
||||
/// The number of internal cycles that must elapse between a request to read or write and
|
||||
/// it becoming a candidate for action.
|
||||
constexpr static int VRAMAccessDelay = 6;
|
||||
};
|
||||
|
||||
template <Personality personality> struct LineLayout<personality, std::enable_if_t<is_yamaha_vdp(personality)>> {
|
||||
constexpr static int StartOfSync = 0;
|
||||
constexpr static int EndOfSync = 100;
|
||||
constexpr static int StartOfColourBurst = 113;
|
||||
constexpr static int EndOfColourBurst = 167;
|
||||
@ -70,8 +70,6 @@ template <Personality personality> struct LineLayout<personality, std::enable_if
|
||||
|
||||
constexpr static int ModeLatchCycle = 144;
|
||||
|
||||
constexpr static int LocationOfGrauwZero = 0;
|
||||
|
||||
/// The number of internal cycles that must elapse between a request to read or write and
|
||||
/// it becoming a candidate for action.
|
||||
constexpr static int VRAMAccessDelay = 16;
|
||||
|
@ -85,9 +85,9 @@ struct YamahaFetcher {
|
||||
static constexpr std::array<Event, size> events() {
|
||||
std::array<Event, size> result{};
|
||||
size_t index = 0;
|
||||
for(int c = 0; c < 1368; c++) {
|
||||
for(int c = 0; c < 1368; c++) {
|
||||
// Specific personality doesn't matter here; both Yamahas use the same internal timing.
|
||||
const auto event = GeneratorT::event(from_internal<Personality::V9938, Clock::Grauw>(c));
|
||||
const auto event = GeneratorT::event(from_internal<Personality::V9938, Clock::FromStartOfSync>(c));
|
||||
if(!event) {
|
||||
continue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user