mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-27 22:30:49 +00:00
Merge pull request #900 from TomHarte/SpeccyTiming
Further tweaks Spectrum timing.
This commit is contained in:
commit
c2fde2b147
@ -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];
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user