mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Clarify and simplify half_cycles_before_internal_cycles.
This commit is contained in:
parent
fd14829992
commit
f1f16d1f9a
@ -96,31 +96,9 @@ template <Personality personality> struct StandardTiming {
|
|||||||
template <Personality personality> struct Timing: public StandardTiming<personality> {};
|
template <Personality personality> struct Timing: public StandardTiming<personality> {};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This implementation of the TMS, etc mediates between three clocks:
|
Provides a [potentially-]stateful conversion between the external and internal clocks.
|
||||||
|
Unlike the other clock conversions, this one may be non-integral, requiring that
|
||||||
1) the external clock, which is whatever the rest of the system(s)
|
an error term be tracked.
|
||||||
it plugs into run at;
|
|
||||||
|
|
||||||
2) the internal clock, which is used to time and place syncs, borders,
|
|
||||||
pixel regions, etc; and
|
|
||||||
|
|
||||||
3) a memory acccess clock, which correlates to the number of windows
|
|
||||||
available for memory accesses.
|
|
||||||
|
|
||||||
E.g. for both a regular TMS9918 and the Sega Master System, the external
|
|
||||||
clock is 3.58Mhz, the internal clock is 5.37Mhz and the memory access
|
|
||||||
clock is 2.69Mhz.
|
|
||||||
|
|
||||||
Or, put another way, for both a TMS9918 and Master System:
|
|
||||||
|
|
||||||
* 228 external cycles;
|
|
||||||
* is 342 internal cycles;
|
|
||||||
* which exactly covers 228 NTSC colour clocks; and
|
|
||||||
* contains 171 memory access windows.
|
|
||||||
|
|
||||||
Both the Yamaha extensions and the Mega Drive VDP are a bit smarter about
|
|
||||||
paged mode memory accesses, obviating any advantage to treating (3) as a
|
|
||||||
separate clock.
|
|
||||||
*/
|
*/
|
||||||
template <Personality personality> class ClockConverter {
|
template <Personality personality> class ClockConverter {
|
||||||
public:
|
public:
|
||||||
@ -161,26 +139,32 @@ template <Personality personality> class ClockConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Provides the number of complete external cycles that lie between now and
|
Provides the number of external cycles that need to begin from now in order to
|
||||||
@c internal_cycles into the future. Any trailing fractional external cycle
|
get at least @c internal_cycles into the future.
|
||||||
is discarded.
|
|
||||||
*/
|
*/
|
||||||
HalfCycles half_cycles_before_internal_cycles(int internal_cycles) const {
|
HalfCycles half_cycles_before_internal_cycles(int internal_cycles) const {
|
||||||
// Logic here correlates with multipliers as per @c to_internal.
|
// Logic here correlates with multipliers as per @c to_internal.
|
||||||
switch(personality) {
|
switch(personality) {
|
||||||
default:
|
default:
|
||||||
return HalfCycles(
|
// Relative to the external clock multiplied by 3, it will definitely take this
|
||||||
((internal_cycles << 2) + (2 - cycles_error_)) / 3
|
// many cycles to complete a further (internal_cycles - 1) after the current one.
|
||||||
);
|
internal_cycles = (internal_cycles - 1) << 2;
|
||||||
|
|
||||||
|
// It will also be necessary to complete the current one.
|
||||||
|
internal_cycles += 4 - cycles_error_;
|
||||||
|
|
||||||
|
// Round up to get the first external cycle after
|
||||||
|
// the number of internal_cycles has elapsed.
|
||||||
|
return HalfCycles((internal_cycles + 2) / 3);
|
||||||
|
|
||||||
case Personality::V9938:
|
case Personality::V9938:
|
||||||
case Personality::V9958:
|
case Personality::V9958:
|
||||||
return HalfCycles((internal_cycles + 2) / 3);
|
return HalfCycles((internal_cycles + 2) / 3);
|
||||||
|
|
||||||
case Personality::MDVDP:
|
case Personality::MDVDP:
|
||||||
return HalfCycles(
|
internal_cycles = (internal_cycles - 1) << 1;
|
||||||
((internal_cycles << 1) + (1 - cycles_error_)) / 7
|
internal_cycles += 2 - cycles_error_;
|
||||||
);
|
return HalfCycles((internal_cycles + 6) / 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user