1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Breaks apart the CPC's 6845 bus handler to obey phase 1 and phase 2, and now back-dates interrupts when appropriate.

This commit is contained in:
Thomas Harte 2017-08-26 14:07:51 -04:00
parent 28550c0227
commit e7ad79c79a

View File

@ -172,10 +172,10 @@ class CRTCBusHandler {
} }
/*! /*!
The CRTC entry function; takes the current bus state and determines what output The CRTC entry function for the main part of each clock cycle; takes the current
to produce based on the current palette and mode. bus state and determines what output to produce based on the current palette and mode.
*/ */
forceinline void perform_bus_cycle(const Motorola::CRTC::BusState &state) { forceinline void perform_bus_cycle_phase1(const Motorola::CRTC::BusState &state) {
// The gate array waits 2µs to react to the CRTC's vsync signal, and then // The gate array waits 2µs to react to the CRTC's vsync signal, and then
// caps output at 4µs. Since the clock rate is 1Mhz, that's 2 and 4 cycles, // caps output at 4µs. Since the clock rate is 1Mhz, that's 2 and 4 cycles,
// respectively. // respectively.
@ -268,7 +268,13 @@ class CRTCBusHandler {
} }
} }
} }
}
/*!
The CRTC entry function for phase 2 of each bus cycle in which the next sync line state becomes
visible early. The CPC uses changes in sync to clock the interrupt timer.
*/
void perform_bus_cycle_phase2(const Motorola::CRTC::BusState &state) {
// check for a trailing CRTC hsync; if one occurred then that's the trigger potentially to change // check for a trailing CRTC hsync; if one occurred then that's the trigger potentially to change
// modes, and should also be sent on to the interrupt timer // modes, and should also be sent on to the interrupt timer
if(was_hsync_ && !state.hsync) { if(was_hsync_ && !state.hsync) {
@ -700,7 +706,10 @@ class ConcreteMachine:
crtc_counter_ += cycle.length; crtc_counter_ += cycle.length;
Cycles crtc_cycles = crtc_counter_.divide_cycles(Cycles(4)); Cycles crtc_cycles = crtc_counter_.divide_cycles(Cycles(4));
if(crtc_cycles > Cycles(0)) crtc_.run_for(crtc_cycles); if(crtc_cycles > Cycles(0)) crtc_.run_for(crtc_cycles);
if(interrupt_timer_.request_has_changed()) z80_.set_interrupt_line(interrupt_timer_.get_request());
// Check whether that prompted a change in the interrupt line. If so then date
// it to whenever the cycle was triggered.
if(interrupt_timer_.request_has_changed()) z80_.set_interrupt_line(interrupt_timer_.get_request(), -crtc_counter_);
// TODO (in the player, not here): adapt it to accept an input clock rate and // TODO (in the player, not here): adapt it to accept an input clock rate and
// run_for as HalfCycles // run_for as HalfCycles