mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +00:00
Restores just-in-time processing of video.
This commit is contained in:
parent
ab14433151
commit
b4a3f66773
@ -137,13 +137,36 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
using Microcycle = CPU::MC68000::Microcycle;
|
using Microcycle = CPU::MC68000::Microcycle;
|
||||||
|
|
||||||
HalfCycles perform_bus_operation(const Microcycle &cycle, int is_supervisor) {
|
HalfCycles perform_bus_operation(const Microcycle &cycle, int is_supervisor) {
|
||||||
// time_since_video_update_ += cycle.length;
|
time_since_video_update_ += cycle.length;
|
||||||
iwm_.time_since_update += cycle.length;
|
iwm_.time_since_update += cycle.length;
|
||||||
|
|
||||||
// The VIA runs at one-tenth of the 68000's clock speed, in sync with the E clock.
|
// The VIA runs at one-tenth of the 68000's clock speed, in sync with the E clock.
|
||||||
// See: Guide to the Macintosh Hardware Family p149 (PDF p188).
|
// See: Guide to the Macintosh Hardware Family p149 (PDF p188). Some extra division
|
||||||
via_clock_ += cycle.length;
|
// may occur here in order to provide VSYNC at a proper moment.
|
||||||
via_.run_for(via_clock_.divide(HalfCycles(10)));
|
// Possibly route vsync.
|
||||||
|
if(time_until_video_event_ >= cycle.length) {
|
||||||
|
via_clock_ += cycle.length;
|
||||||
|
via_.run_for(via_clock_.divide(HalfCycles(10)));
|
||||||
|
time_until_video_event_ -= cycle.length;
|
||||||
|
} else {
|
||||||
|
auto cycles_to_progress = cycle.length;
|
||||||
|
while(time_until_video_event_ < cycles_to_progress) {
|
||||||
|
cycles_to_progress -= time_until_video_event_;
|
||||||
|
|
||||||
|
via_clock_ += time_until_video_event_;
|
||||||
|
via_.run_for(via_clock_.divide(HalfCycles(10)));
|
||||||
|
|
||||||
|
video_.run_for(time_until_video_event_);
|
||||||
|
time_since_video_update_ -= time_until_video_event_;
|
||||||
|
time_until_video_event_ = video_.get_next_sequence_point();
|
||||||
|
|
||||||
|
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !video_.vsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
via_clock_ += cycles_to_progress;
|
||||||
|
via_.run_for(via_clock_.divide(HalfCycles(10)));
|
||||||
|
time_until_video_event_ -= cycles_to_progress;
|
||||||
|
}
|
||||||
|
|
||||||
// The keyboard also has a clock, albeit a very slow one — 100,000 cycles/second.
|
// The keyboard also has a clock, albeit a very slow one — 100,000 cycles/second.
|
||||||
// Its clock and data lines are connected to the VIA.
|
// Its clock and data lines are connected to the VIA.
|
||||||
@ -177,10 +200,6 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::Two, false);
|
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::Two, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the video. TODO: only on demand.
|
|
||||||
video_.run_for(cycle.length);
|
|
||||||
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !video_.vsync());
|
|
||||||
|
|
||||||
// Update interrupt input. TODO: move this into a VIA/etc delegate callback?
|
// Update interrupt input. TODO: move this into a VIA/etc delegate callback?
|
||||||
// Double TODO: does this really cascade like this?
|
// Double TODO: does this really cascade like this?
|
||||||
if(scc_.get_interrupt_line()) {
|
if(scc_.get_interrupt_line()) {
|
||||||
@ -292,6 +311,7 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
) {
|
) {
|
||||||
memory_base = ram_;
|
memory_base = ram_;
|
||||||
word_address &= ram_mask_;
|
word_address &= ram_mask_;
|
||||||
|
update_video();
|
||||||
} else {
|
} else {
|
||||||
memory_base = rom_;
|
memory_base = rom_;
|
||||||
word_address &= rom_mask_;
|
word_address &= rom_mask_;
|
||||||
@ -371,7 +391,7 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
// video is responsible for providing part of the
|
// video is responsible for providing part of the
|
||||||
// audio signal, so the two aren't as distinct as in
|
// audio signal, so the two aren't as distinct as in
|
||||||
// most machines.
|
// most machines.
|
||||||
// video_.run_for(time_since_video_update_.flush());
|
update_video();
|
||||||
|
|
||||||
// As above: flush audio after video.
|
// As above: flush audio after video.
|
||||||
via_.flush();
|
via_.flush();
|
||||||
@ -385,6 +405,10 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
ROM_is_overlay_ = rom_is_overlay;
|
ROM_is_overlay_ = rom_is_overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool video_is_outputting() {
|
||||||
|
return video_.is_outputting(time_since_video_update_);
|
||||||
|
}
|
||||||
|
|
||||||
void set_use_alternate_buffers(bool use_alternate_screen_buffer, bool use_alternate_audio_buffer) {
|
void set_use_alternate_buffers(bool use_alternate_screen_buffer, bool use_alternate_audio_buffer) {
|
||||||
video_.set_use_alternate_buffers(use_alternate_screen_buffer, use_alternate_audio_buffer);
|
video_.set_use_alternate_buffers(use_alternate_screen_buffer, use_alternate_audio_buffer);
|
||||||
}
|
}
|
||||||
@ -414,6 +438,11 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
// TODO: clear all keys.
|
// TODO: clear all keys.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void update_video() {
|
||||||
|
video_.run_for(time_since_video_update_.flush());
|
||||||
|
time_until_video_event_ = video_.get_next_sequence_point();
|
||||||
|
}
|
||||||
|
|
||||||
Inputs::Mouse &get_mouse() override {
|
Inputs::Mouse &get_mouse() override {
|
||||||
return mouse_;
|
return mouse_;
|
||||||
}
|
}
|
||||||
@ -496,7 +525,7 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
((mouse_.get_channel(0) & 2) << 3) |
|
((mouse_.get_channel(0) & 2) << 3) |
|
||||||
((mouse_.get_channel(1) & 2) << 4) |
|
((mouse_.get_channel(1) & 2) << 4) |
|
||||||
(clock_.get_data() ? 0x02 : 0x00) |
|
(clock_.get_data() ? 0x02 : 0x00) |
|
||||||
(video_.is_outputting() ? 0x00 : 0x40)
|
(machine_.video_is_outputting() ? 0x00 : 0x40)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,8 +585,8 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
HalfCycles via_clock_;
|
HalfCycles via_clock_;
|
||||||
HalfCycles real_time_clock_;
|
HalfCycles real_time_clock_;
|
||||||
HalfCycles keyboard_clock_;
|
HalfCycles keyboard_clock_;
|
||||||
HalfCycles video_clock_;
|
HalfCycles time_since_video_update_;
|
||||||
// HalfCycles time_since_video_update_;
|
HalfCycles time_until_video_event_;
|
||||||
HalfCycles time_since_iwm_update_;
|
HalfCycles time_since_iwm_update_;
|
||||||
HalfCycles time_since_mouse_update_;
|
HalfCycles time_since_mouse_update_;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user