From d9016909edbd341a0c3dce7c97e94c62778bc11a Mon Sep 17 00:00:00 2001 From: Thomas Harte <thomas.harte@gmail.com> Date: Sun, 14 Aug 2016 13:33:20 -0400 Subject: [PATCH] Added some wiring for PAL/NTSC mode switching on the Vic, making an attempt to simplify the whole loop of having different clock rates. --- Machines/Atari2600/Atari2600.cpp | 11 ++++------- Machines/Atari2600/Atari2600.hpp | 1 - Machines/CRTMachine.hpp | 17 ++++++++++++++--- Machines/Commodore/Vic-20/Vic20.cpp | 20 +++++++++++++++++++- Machines/Commodore/Vic-20/Vic20.hpp | 10 +++++++++- Machines/Electron/Electron.cpp | 1 + Machines/Electron/Electron.hpp | 1 - 7 files changed, 47 insertions(+), 14 deletions(-) diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index 9260e22e5..6d76cdadb 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -13,6 +13,8 @@ using namespace Atari2600; namespace { static const unsigned int horizontalTimerPeriod = 228; + static const double NTSC_clock_rate = 1194720; + static const double PAL_clock_rate = 1182298; } Machine::Machine() : @@ -52,6 +54,7 @@ Machine::Machine() : _stateByExtendTime[vbextend][c] = state; } } + set_clock_rate(NTSC_clock_rate); } void Machine::setup_output(float aspect_ratio) @@ -94,8 +97,7 @@ void Machine::switch_region() _is_pal_region = true; _speaker->set_input_rate((float)(get_clock_rate() / 38.0)); - - if(delegate) delegate->machine_did_change_clock_rate(this); + set_clock_rate(PAL_clock_rate); } void Machine::close_output() @@ -109,11 +111,6 @@ Machine::~Machine() close_output(); } -double Machine::get_clock_rate() -{ - return _is_pal_region ? 1182298 : 1194720; -} - void Machine::update_timers(int mask) { unsigned int upcomingPointerPlus4 = (_upcomingEventsPointer + 4)%number_of_upcoming_events; diff --git a/Machines/Atari2600/Atari2600.hpp b/Machines/Atari2600/Atari2600.hpp index 4a1778b14..3b9fa0131 100644 --- a/Machines/Atari2600/Atari2600.hpp +++ b/Machines/Atari2600/Atari2600.hpp @@ -94,7 +94,6 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine { virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _crt; } virtual std::shared_ptr<Outputs::Speaker> get_speaker() { return _speaker; } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); } - virtual double get_clock_rate(); // TODO: different rate for PAL private: diff --git a/Machines/CRTMachine.hpp b/Machines/CRTMachine.hpp index c193199c4..6e00b482f 100644 --- a/Machines/CRTMachine.hpp +++ b/Machines/CRTMachine.hpp @@ -30,15 +30,26 @@ class Machine { virtual void run_for_cycles(int number_of_cycles) = 0; // TODO: sever the clock-rate stuff. - virtual double get_clock_rate() = 0; + double get_clock_rate() { + return clock_rate_; + } class Delegate { public: virtual void machine_did_change_clock_rate(Machine *machine) = 0; }; - void set_delegate(Delegate *delegate) { this->delegate = delegate; } + void set_delegate(Delegate *delegate) { this->delegate_ = delegate; } protected: - Delegate *delegate; + double clock_rate_; + void set_clock_rate(double clock_rate) { + if(clock_rate_ != clock_rate) { + clock_rate_ = clock_rate; + if(delegate_) delegate_->machine_did_change_clock_rate(this); + } + } + + private: + Delegate *delegate_; }; } diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 3050216e8..664277c44 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -37,6 +37,8 @@ Machine::Machine() : // establish the memory maps set_memory_size(MemorySize::Default); + // set the NTSC clock rate + set_region(NTSC); // _debugPort.reset(new ::Commodore::Serial::DebugPort); // _debugPort->set_serial_bus(_serialBus); // _serialBus->add_port(_debugPort); @@ -60,7 +62,6 @@ void Machine::set_memory_size(MemorySize size) break; } - // install the ROMs and VIC-visible memory write_to_map(_processorReadMemoryMap, _userBASICMemory, 0x0000, sizeof(_userBASICMemory)); write_to_map(_processorReadMemoryMap, _screenMemory, 0x1000, sizeof(_screenMemory)); @@ -161,9 +162,26 @@ void Machine::mos6522_did_change_interrupt_status(void *mos6522) #pragma mark - Setup +void Machine::set_region(Commodore::Vic20::Region region) +{ + _region = region; + switch(region) + { + case PAL: + set_clock_rate(1108404); + if(_mos6560) _mos6560->set_output_mode(MOS::MOS6560<Commodore::Vic20::Vic6560>::OutputMode::PAL); + break; + case NTSC: + set_clock_rate(1022727); + if(_mos6560) _mos6560->set_output_mode(MOS::MOS6560<Commodore::Vic20::Vic6560>::OutputMode::NTSC); + break; + } +} + void Machine::setup_output(float aspect_ratio) { _mos6560.reset(new Vic6560()); + set_region(_region); memset(_mos6560->_videoMemoryMap, 0, sizeof(_mos6560->_videoMemoryMap)); write_to_map(_mos6560->_videoMemoryMap, _characterROM, 0x0000, sizeof(_characterROM)); diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index e1b4b8a3c..e4fb58386 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -38,6 +38,11 @@ enum MemorySize { ThirtyTwoKB }; +enum Region { + NTSC, + PAL +}; + #define key(line, mask) (((mask) << 3) | (line)) enum Key: uint16_t { @@ -265,7 +270,9 @@ class Machine: _userPortVIA->set_joystick_state(input, isPressed); _keyboardVIA->set_joystick_state(input, isPressed); } + void set_memory_size(MemorySize size); + void set_region(Region region); inline void set_use_fast_tape_hack(bool activate) { _use_fast_tape_hack = activate; } inline void set_should_automatically_load_media(bool activate) { _should_automatically_load_media = activate; } @@ -280,7 +287,6 @@ class Machine: virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _mos6560->get_crt(); } virtual std::shared_ptr<Outputs::Speaker> get_speaker() { return _mos6560->get_speaker(); } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); } - virtual double get_clock_rate() { return 1022727; } // TODO: or 1108405 for PAL; see http://www.antimon.org/dl/c64/code/stable.txt // to satisfy MOS::MOS6522::Delegate @@ -313,6 +319,8 @@ class Machine: uint8_t *_processorWriteMemoryMap[64]; void write_to_map(uint8_t **map, uint8_t *area, uint16_t address, uint16_t length); + Region _region; + std::unique_ptr<Vic6560> _mos6560; std::shared_ptr<UserPortVIA> _userPortVIA; std::shared_ptr<KeyboardVIA> _keyboardVIA; diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index bf07f869d..30c9a0ad4 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -55,6 +55,7 @@ Machine::Machine() : memset(_roms[c], 0xff, 16384); _tape.set_delegate(this); + set_clock_rate(2000000); } void Machine::setup_output(float aspect_ratio) diff --git a/Machines/Electron/Electron.hpp b/Machines/Electron/Electron.hpp index d5f593e1a..6ec7b81a2 100644 --- a/Machines/Electron/Electron.hpp +++ b/Machines/Electron/Electron.hpp @@ -162,7 +162,6 @@ class Machine: virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _crt; } virtual std::shared_ptr<Outputs::Speaker> get_speaker() { return _speaker; } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); } - virtual double get_clock_rate() { return 2000000; } // to satisfy Tape::Delegate virtual void tape_did_change_interrupt_status(Tape *tape);