1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-26 09:29:45 +00:00

Rolls out JustInTime acting to the MSX and ColecoVision.

This commit is contained in:
Thomas Harte 2019-07-29 21:22:31 -04:00
parent 7dcad516bd
commit f3dd4b028d
2 changed files with 28 additions and 35 deletions

View File

@ -19,6 +19,7 @@
#include "../../Configurable/StandardOptions.hpp"
#include "../../ClockReceiver/ForceInline.hpp"
#include "../../ClockReceiver/JustInTime.hpp"
#include "../../Outputs/Speaker/Implementation/CompoundSource.hpp"
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
@ -169,7 +170,7 @@ class ConcreteMachine:
}
// ColecoVisions have composite output only.
vdp_.set_display_type(Outputs::Display::DisplayType::CompositeColour);
vdp_->set_display_type(Outputs::Display::DisplayType::CompositeColour);
}
~ConcreteMachine() {
@ -181,11 +182,11 @@ class ConcreteMachine:
}
void set_scan_target(Outputs::Display::ScanTarget *scan_target) override {
vdp_.set_scan_target(scan_target);
vdp_->set_scan_target(scan_target);
}
void set_display_type(Outputs::Display::DisplayType display_type) override {
vdp_.set_display_type(display_type);
vdp_->set_display_type(display_type);
}
Outputs::Speaker::Speaker *get_speaker() override {
@ -210,7 +211,7 @@ class ConcreteMachine:
}
const HalfCycles length = cycle.length + penalty;
time_since_vdp_update_ += length;
vdp_ += length;
time_since_sn76489_update_ += length;
// Act only if necessary.
@ -255,10 +256,9 @@ class ConcreteMachine:
case CPU::Z80::PartialMachineCycle::Input:
switch((address >> 5) & 7) {
case 5:
update_video();
*cycle.value = vdp_.get_register(address);
z80_.set_non_maskable_interrupt_line(vdp_.get_interrupt_line());
time_until_interrupt_ = vdp_.get_time_until_interrupt();
*cycle.value = vdp_->get_register(address);
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
case 7: {
@ -299,10 +299,9 @@ class ConcreteMachine:
break;
case 5:
update_video();
vdp_.set_register(address, *cycle.value);
z80_.set_non_maskable_interrupt_line(vdp_.get_interrupt_line());
time_until_interrupt_ = vdp_.get_time_until_interrupt();
vdp_->set_register(address, *cycle.value);
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
case 7:
@ -354,7 +353,7 @@ class ConcreteMachine:
}
void flush() {
update_video();
vdp_.flush();
update_audio();
audio_queue_.perform();
}
@ -396,12 +395,9 @@ class ConcreteMachine:
inline void update_audio() {
speaker_.run_for(audio_queue_, time_since_sn76489_update_.divide_cycles(Cycles(sn76489_divider)));
}
inline void update_video() {
vdp_.run_for(time_since_vdp_update_.flush<HalfCycles>());
}
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
TI::TMS::TMS9918 vdp_;
JustInTimeActor<TI::TMS::TMS9918, HalfCycles> vdp_;
Concurrency::DeferringAsyncTaskQueue audio_queue_;
TI::SN76489 sn76489_;
@ -424,7 +420,6 @@ class ConcreteMachine:
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
bool joysticks_in_keypad_mode_ = false;
HalfCycles time_since_vdp_update_;
HalfCycles time_since_sn76489_update_;
HalfCycles time_until_interrupt_;

View File

@ -45,6 +45,7 @@
#include "../../Configurable/StandardOptions.hpp"
#include "../../ClockReceiver/ForceInline.hpp"
#include "../../ClockReceiver/JustInTime.hpp"
#include "../../Analyser/Static/MSX/Target.hpp"
@ -187,7 +188,7 @@ class ConcreteMachine:
switch(target.region) {
case Target::Region::Japan:
required_roms.emplace_back(machine_name, "a Japanese MSX BIOS", "msx-japanese.rom", 32*1024, 0xee229390);
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
vdp_->set_tv_standard(TI::TMS::TVStandard::NTSC);
is_ntsc = true;
character_generator = 0;
@ -195,7 +196,7 @@ class ConcreteMachine:
break;
case Target::Region::USA:
required_roms.emplace_back(machine_name, "an American MSX BIOS", "msx-american.rom", 32*1024, 0);
vdp_.set_tv_standard(TI::TMS::TVStandard::NTSC);
vdp_->set_tv_standard(TI::TMS::TVStandard::NTSC);
is_ntsc = true;
character_generator = 1;
@ -203,7 +204,7 @@ class ConcreteMachine:
break;
case Target::Region::Europe:
required_roms.emplace_back(machine_name, "a European MSX BIOS", "msx-european.rom", 32*1024, 0);
vdp_.set_tv_standard(TI::TMS::TVStandard::PAL);
vdp_->set_tv_standard(TI::TMS::TVStandard::PAL);
is_ntsc = false;
character_generator = 1;
@ -278,11 +279,11 @@ class ConcreteMachine:
}
void set_scan_target(Outputs::Display::ScanTarget *scan_target) override {
vdp_.set_scan_target(scan_target);
vdp_->set_scan_target(scan_target);
}
void set_display_type(Outputs::Display::DisplayType display_type) override {
vdp_.set_display_type(display_type);
vdp_->set_display_type(display_type);
}
Outputs::Speaker::Speaker *get_speaker() override {
@ -411,7 +412,7 @@ class ConcreteMachine:
// but otherwise runs without pause.
const HalfCycles addition((cycle.operation == CPU::Z80::PartialMachineCycle::ReadOpcode) ? 2 : 0);
const HalfCycles total_length = addition + cycle.length;
time_since_vdp_update_ += total_length;
vdp_ += total_length;
time_since_ay_update_ += total_length;
memory_slots_[0].cycles_since_update += total_length;
memory_slots_[1].cycles_since_update += total_length;
@ -508,10 +509,9 @@ class ConcreteMachine:
case CPU::Z80::PartialMachineCycle::Input:
switch(address & 0xff) {
case 0x98: case 0x99:
vdp_.run_for(time_since_vdp_update_.flush<HalfCycles>());
*cycle.value = vdp_.get_register(address);
z80_.set_interrupt_line(vdp_.get_interrupt_line());
time_until_interrupt_ = vdp_.get_time_until_interrupt();
*cycle.value = vdp_->get_register(address);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
case 0xa2:
@ -536,10 +536,9 @@ class ConcreteMachine:
const int port = address & 0xff;
switch(port) {
case 0x98: case 0x99:
vdp_.run_for(time_since_vdp_update_.flush<HalfCycles>());
vdp_.set_register(address, *cycle.value);
z80_.set_interrupt_line(vdp_.get_interrupt_line());
time_until_interrupt_ = vdp_.get_time_until_interrupt();
vdp_->set_register(address, *cycle.value);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
case 0xa0: case 0xa1:
@ -612,7 +611,7 @@ class ConcreteMachine:
}
void flush() {
vdp_.run_for(time_since_vdp_update_.flush<HalfCycles>());
vdp_.flush();
update_audio();
audio_queue_.perform();
}
@ -753,7 +752,7 @@ class ConcreteMachine:
};
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
TI::TMS::TMS9918 vdp_;
JustInTimeActor<TI::TMS::TMS9918, HalfCycles> vdp_;
Intel::i8255::i8255<i8255PortHandler> i8255_;
Concurrency::DeferringAsyncTaskQueue audio_queue_;
@ -797,7 +796,6 @@ class ConcreteMachine:
uint8_t scratch_[8192];
uint8_t unpopulated_[8192];
HalfCycles time_since_vdp_update_;
HalfCycles time_since_ay_update_;
HalfCycles time_until_interrupt_;