1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-11 04:28:58 +00:00

Merge pull request #900 from TomHarte/SpeccyTiming

Further tweaks Spectrum timing.
This commit is contained in:
Thomas Harte 2021-04-04 20:19:54 -04:00 committed by GitHub
commit c2fde2b147
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 26 deletions

View File

@ -53,14 +53,14 @@ template <VideoTiming timing> class Video {
// Number of lines comprising a whole frame. Will be 311 or 312.
int lines_per_frame;
// Number of cycles after first pixel fetch at which interrupt is first signalled.
int interrupt_time;
// Number of cycles before first pixel fetch that contention starts to be applied.
int contention_leadin;
// Period in a line for which contention is applied.
int contention_duration;
// Number of cycles after first pixel fetch at which interrupt is first signalled.
int interrupt_time;
// Contention to apply, in half-cycles, as a function of number of half cycles since
// contention began.
int delays[16];
@ -88,11 +88,15 @@ template <VideoTiming timing> class Video {
.cycles_per_line = 228 * 2,
.lines_per_frame = 311,
.interrupt_time = 56545 * 2,
.contention_leadin = 2 * 2, // TODO: is this 2? Or 4? Or... ?
// i.e. video fetching begins six 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 = 6 * 2,
.contention_duration = 129 * 2,
// i.e. interrupt is first signalled 14368 cycles before the first video fetch.
.interrupt_time = (228*311 - 14368) * 2,
.delays = {
2, 1,
0, 0,
@ -311,7 +315,9 @@ template <VideoTiming timing> class Video {
}
const int time_into_line = delay_time % timings.cycles_per_line;
if(time_into_line >= timings.contention_duration) return 0;
if(time_into_line >= timings.contention_duration) {
return 0;
}
return timings.delays[time_into_line & 15];
}

View File

@ -184,25 +184,30 @@ template<Model model> class ConcreteMachine:
forceinline HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
using PartialMachineCycle = CPU::Z80::PartialMachineCycle;
HalfCycles delay(0);
const uint16_t address = cycle.address ? *cycle.address : 0x0000;
// Apply contention if necessary.
if(
is_contended_[address >> 14] &&
cycle.operation >= PartialMachineCycle::ReadOpcodeStart &&
cycle.operation <= PartialMachineCycle::WriteStart) {
// Assumption here: the trigger for the ULA inserting a delay is the falling edge
// of MREQ, which is always half a cycle into a read or write.
//
// TODO: somehow provide that information in the PartialMachineCycle?
const HalfCycles delay = video_.last_valid()->access_delay(video_.time_since_flush() + HalfCycles(1));
advance(cycle.length + delay);
return delay;
}
// For all other machine cycles, model the action as happening at the end of the machine cycle;
// that means advancing time now.
advance(cycle.length);
switch(cycle.operation) {
default: break;
case PartialMachineCycle::ReadOpcodeStart:
case PartialMachineCycle::ReadStart:
case PartialMachineCycle::WriteStart:
// Apply contention if necessary.
//
// Assumption here: the trigger for the ULA inserting a delay is the falling edge
// of MREQ, which is always half a cycle into a read or write.
//
// TODO: somehow provide that information in the PartialMachineCycle?
if(is_contended_[address >> 14]) {
delay = video_.last_valid()->access_delay(video_.time_since_flush() + HalfCycles(1));
}
break;
case PartialMachineCycle::ReadOpcode:
// Fast loading: ROM version.
//
@ -224,7 +229,7 @@ template<Model model> class ConcreteMachine:
*cycle.value = read_pointers_[address >> 14][address];
if(is_contended_[address >> 14]) {
video_.last_valid()->set_last_contended_area_access(*cycle.value);
video_->set_last_contended_area_access(*cycle.value);
}
break;
@ -238,7 +243,7 @@ template<Model model> class ConcreteMachine:
// Fill the floating bus buffer if this write is within the contended area.
if(is_contended_[address >> 14]) {
video_.last_valid()->set_last_contended_area_access(*cycle.value);
video_->set_last_contended_area_access(*cycle.value);
}
break;
@ -356,8 +361,7 @@ template<Model model> class ConcreteMachine:
break;
}
advance(cycle.length + delay);
return delay;
return HalfCycles(0);
}
private: