mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 18:30:21 +00:00
Adds a Master System class, so that SMSs can end up somewhere.
This commit is contained in:
parent
0d01346ad4
commit
e511261b04
@ -7,3 +7,112 @@
|
||||
//
|
||||
|
||||
#include "MasterSystem.hpp"
|
||||
|
||||
#include "../../Processors/Z80/Z80.hpp"
|
||||
|
||||
#include "../../Components/9918/9918.hpp"
|
||||
#include "../../Components/SN76489/SN76489.hpp"
|
||||
|
||||
#include "../CRTMachine.hpp"
|
||||
#include "../JoystickMachine.hpp"
|
||||
|
||||
#include "../../ClockReceiver/ForceInline.hpp"
|
||||
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
|
||||
namespace {
|
||||
const int sn76489_divider = 2;
|
||||
}
|
||||
|
||||
namespace Sega {
|
||||
namespace MasterSystem {
|
||||
|
||||
class ConcreteMachine:
|
||||
public Machine,
|
||||
public CPU::Z80::BusHandler,
|
||||
public CRTMachine::Machine {
|
||||
|
||||
public:
|
||||
ConcreteMachine(const Analyser::Static::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
|
||||
z80_(*this),
|
||||
sn76489_(TI::SN76489::Personality::SN76489, audio_queue_, sn76489_divider),
|
||||
speaker_(sn76489_) {
|
||||
speaker_.set_input_rate(3579545.0f / static_cast<float>(sn76489_divider));
|
||||
set_clock_rate(3579545);
|
||||
}
|
||||
|
||||
~ConcreteMachine() {
|
||||
audio_queue_.flush();
|
||||
}
|
||||
|
||||
void setup_output(float aspect_ratio) override {
|
||||
vdp_.reset(new TI::TMS::TMS9918(TI::TMS::TMS9918A));
|
||||
get_crt()->set_video_signal(Outputs::CRT::VideoSignal::Composite);
|
||||
}
|
||||
|
||||
void close_output() override {
|
||||
vdp_.reset();
|
||||
}
|
||||
|
||||
Outputs::CRT::CRT *get_crt() override {
|
||||
return vdp_->get_crt();
|
||||
}
|
||||
|
||||
Outputs::Speaker::Speaker *get_speaker() override {
|
||||
return &speaker_;
|
||||
}
|
||||
|
||||
void run_for(const Cycles cycles) override {
|
||||
z80_.run_for(cycles);
|
||||
}
|
||||
|
||||
forceinline HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
|
||||
time_since_vdp_update_ += cycle.length;
|
||||
time_since_sn76489_update_ += cycle.length;
|
||||
|
||||
if(time_until_interrupt_ > 0) {
|
||||
time_until_interrupt_ -= cycle.length;
|
||||
if(time_until_interrupt_ <= HalfCycles(0)) {
|
||||
z80_.set_non_maskable_interrupt_line(true, time_until_interrupt_);
|
||||
}
|
||||
}
|
||||
|
||||
return HalfCycles(0);
|
||||
}
|
||||
|
||||
void flush() {
|
||||
update_video();
|
||||
update_audio();
|
||||
audio_queue_.perform();
|
||||
}
|
||||
|
||||
private:
|
||||
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());
|
||||
}
|
||||
|
||||
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
||||
std::unique_ptr<TI::TMS::TMS9918> vdp_;
|
||||
|
||||
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
||||
TI::SN76489 sn76489_;
|
||||
Outputs::Speaker::LowpassSpeaker<TI::SN76489> speaker_;
|
||||
|
||||
HalfCycles time_since_vdp_update_;
|
||||
HalfCycles time_since_sn76489_update_;
|
||||
HalfCycles time_until_interrupt_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Sega::MasterSystem;
|
||||
|
||||
Machine *Machine::MasterSystem(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
||||
return new ConcreteMachine(*target, rom_fetcher);
|
||||
}
|
||||
|
||||
Machine::~Machine() {}
|
||||
|
@ -9,6 +9,19 @@
|
||||
#ifndef MasterSystem_hpp
|
||||
#define MasterSystem_hpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../../Analyser/Static/StaticAnalyser.hpp"
|
||||
#include "../ROMMachine.hpp"
|
||||
|
||||
namespace Sega {
|
||||
namespace MasterSystem {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine();
|
||||
static Machine *MasterSystem(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MasterSystem_hpp */
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../ColecoVision/ColecoVision.hpp"
|
||||
#include "../Commodore/Vic-20/Vic20.hpp"
|
||||
#include "../Electron/Electron.hpp"
|
||||
#include "../MasterSystem/MasterSystem.hpp"
|
||||
#include "../MSX/MSX.hpp"
|
||||
#include "../Oric/Oric.hpp"
|
||||
#include "../ZX8081/ZX8081.hpp"
|
||||
@ -36,6 +37,7 @@ namespace {
|
||||
Bind(Atari2600)
|
||||
BindD(Coleco::Vision, ColecoVision)
|
||||
Bind(Electron)
|
||||
BindD(Sega::MasterSystem, MasterSystem)
|
||||
Bind(MSX)
|
||||
Bind(Oric)
|
||||
BindD(Commodore::Vic20, Vic20)
|
||||
|
Loading…
Reference in New Issue
Block a user