diff --git a/Components/6560/6560.cpp b/Components/6560/6560.cpp index 73a06b3f4..4c6518f9d 100644 --- a/Components/6560/6560.cpp +++ b/Components/6560/6560.cpp @@ -10,7 +10,7 @@ #include -using namespace MOS; +using namespace MOS::MOS6560; AudioGenerator::AudioGenerator(Concurrency::DeferringAsyncTaskQueue &audio_queue) : audio_queue_(audio_queue) {} diff --git a/Components/6560/6560.hpp b/Components/6560/6560.hpp index d680ef2c9..de885615c 100644 --- a/Components/6560/6560.hpp +++ b/Components/6560/6560.hpp @@ -16,6 +16,7 @@ #include "../../Outputs/Speaker/Implementation/SampleSource.hpp" namespace MOS { +namespace MOS6560 { // audio state class AudioGenerator: public ::Outputs::Speaker::SampleSource { @@ -40,6 +41,17 @@ class AudioGenerator: public ::Outputs::Speaker::SampleSource { int16_t range_multiplier_ = 1; }; +struct BusHandler { + void perform_read(uint16_t address, uint8_t *pixel_data, uint8_t *colour_data) { + *pixel_data = 0xff; + *colour_data = 0xff; + } +}; + +enum class OutputMode { + PAL, NTSC +}; + /*! The 6560 Video Interface Chip ('VIC') is a video and audio output chip; it therefore vends both a @c CRT and a @c Speaker. @@ -48,9 +60,10 @@ class AudioGenerator: public ::Outputs::Speaker::SampleSource { @c set_register and @c get_register provide register access. */ -template class MOS6560 { +template class MOS6560 { public: - MOS6560() : + MOS6560(BusHandler &bus_handler) : + bus_handler_(bus_handler), crt_(new Outputs::CRT::CRT(65*4, 4, Outputs::CRT::DisplayType::NTSC60, 2)), audio_generator_(audio_queue_), speaker_(audio_generator_) @@ -88,10 +101,6 @@ template class MOS6560 { speaker_.set_high_frequency_cutoff(cutoff); } - enum OutputMode { - PAL, NTSC - }; - /*! Sets the output mode to either PAL or NTSC. */ @@ -248,7 +257,7 @@ template class MOS6560 { uint8_t pixel_data; uint8_t colour_data; - static_cast(this)->perform_read(fetch_address, &pixel_data, &colour_data); + bus_handler_.perform_read(fetch_address, &pixel_data, &colour_data); // TODO: there should be a further two-cycle delay on pixels being output; the reverse bit should // divide the byte it is set for 3:1 and then continue as usual. @@ -422,6 +431,7 @@ template class MOS6560 { } private: + BusHandler &bus_handler_; std::unique_ptr crt_; Concurrency::DeferringAsyncTaskQueue audio_queue_; @@ -511,6 +521,7 @@ template class MOS6560 { OutputMode output_mode_; }; +} } #endif /* _560_hpp */ diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 1c722d7d4..dcd200cba 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -240,10 +240,10 @@ class SerialPort : public ::Commodore::Serial::Port { /*! Provides the bus over which the Vic 6560 fetches memory in a Vic-20. */ -class Vic6560: public MOS::MOS6560 { +class Vic6560BusHandler { public: /// Performs a read on behalf of the 6560; in practice uses @c video_memory_map and @c colour_memory to find data. - inline void perform_read(uint16_t address, uint8_t *pixel_data, uint8_t *colour_data) { + forceinline void perform_read(uint16_t address, uint8_t *pixel_data, uint8_t *colour_data) { *pixel_data = video_memory_map[address >> 10] ? video_memory_map[address >> 10][address & 0x3ff] : 0xff; // TODO *colour_data = colour_memory[address & 0x03ff]; } @@ -433,7 +433,7 @@ class ConcreteMachine: void set_ntsc_6560() { set_clock_rate(1022727); if(mos6560_) { - mos6560_->set_output_mode(MOS::MOS6560::OutputMode::NTSC); + mos6560_->set_output_mode(MOS::MOS6560::OutputMode::NTSC); mos6560_->set_clock_rate(1022727); } } @@ -441,7 +441,7 @@ class ConcreteMachine: void set_pal_6560() { set_clock_rate(1108404); if(mos6560_) { - mos6560_->set_output_mode(MOS::MOS6560::OutputMode::PAL); + mos6560_->set_output_mode(MOS::MOS6560::OutputMode::PAL); mos6560_->set_clock_rate(1108404); } } @@ -459,7 +459,7 @@ class ConcreteMachine: // Initialise the memory maps as all pointing to nothing memset(processor_read_memory_map_, 0, sizeof(processor_read_memory_map_)); memset(processor_write_memory_map_, 0, sizeof(processor_write_memory_map_)); - memset(mos6560_->video_memory_map, 0, sizeof(mos6560_->video_memory_map)); + memset(mos6560_bus_handler_.video_memory_map, 0, sizeof(mos6560_bus_handler_.video_memory_map)); #define set_ram(baseaddr, length) \ write_to_map(processor_read_memory_map_, &ram_[baseaddr], baseaddr, length); \ @@ -503,11 +503,11 @@ class ConcreteMachine: for(auto addr = video_range.start; addr < video_range.end; addr += 0x400) { auto destination_address = (addr & 0x1fff) | (((addr & 0x8000) >> 2) ^ 0x2000); if(processor_read_memory_map_[addr >> 10]) { - write_to_map(mos6560_->video_memory_map, &ram_[addr], static_cast(destination_address), 0x400); + write_to_map(mos6560_bus_handler_.video_memory_map, &ram_[addr], static_cast(destination_address), 0x400); } } } - mos6560_->colour_memory = colour_ram_; + mos6560_bus_handler_.colour_memory = colour_ram_; // install the BASIC ROM write_to_map(processor_read_memory_map_, basic_rom_.data(), 0xc000, static_cast(basic_rom_.size())); @@ -539,7 +539,7 @@ class ConcreteMachine: } write_to_map(processor_read_memory_map_, roms_[character_rom].data(), 0x8000, static_cast(roms_[character_rom].size())); - write_to_map(mos6560_->video_memory_map, roms_[character_rom].data(), 0x0000, static_cast(roms_[character_rom].size())); + write_to_map(mos6560_bus_handler_.video_memory_map, roms_[character_rom].data(), 0x0000, static_cast(roms_[character_rom].size())); write_to_map(processor_read_memory_map_, roms_[kernel_rom].data(), 0xe000, static_cast(roms_[kernel_rom].size())); // install the inserted ROM if there is one @@ -679,7 +679,7 @@ class ConcreteMachine: } void setup_output(float aspect_ratio) override final { - mos6560_.reset(new Vic6560()); + mos6560_.reset(new MOS::MOS6560::MOS6560(mos6560_bus_handler_)); mos6560_->set_high_frequency_cutoff(1600); // There is a 1.6Khz low-pass filter in the Vic-20. // Make a guess: PAL. Without setting a clock rate the 6560 isn't fully set up so contractually something must be set. set_memory_map(commodore_target_.memory_model, commodore_target_.region); @@ -789,7 +789,8 @@ class ConcreteMachine: std::vector> joysticks_; Cycles cycles_since_mos6560_update_; - std::unique_ptr mos6560_; + Vic6560BusHandler mos6560_bus_handler_; + std::unique_ptr> mos6560_; std::shared_ptr user_port_via_port_handler_; std::shared_ptr keyboard_via_port_handler_; std::shared_ptr serial_port_;