diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index da5cbf94c..f23d1a968 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -115,7 +115,7 @@ public: // NTSC: 7159090? // i.e. colour subcarriers multiplied by two? - set_clock_rate(7159090); // TODO. + set_clock_rate(8867240); // TODO. const auto kernel = ROM::Name::Plus4KernelPALv5; const auto basic = ROM::Name::Plus4BASIC; @@ -141,8 +141,9 @@ public: const uint16_t address, uint8_t *const value ) { - // TODO: calculate length of this bus operation. - const auto length = Cycles(5); + // Determine from the TED video subsystem the length of this clock cycle as perceived by the 6502, + // relative to the master clock. + const auto length = video_.cycle_length(operation == CPU::MOS6502::BusOperation::Ready); // Update other subsystems. // TODO: timers decrement at a 894 KHz rate for NTSC television systems, 884 KHZ for PAL systems. @@ -179,6 +180,7 @@ public: case 0xff08: // TODO: keyboard. + // For now: all keys unpressed. *value = 0xff; break; @@ -255,6 +257,7 @@ private: } void page_rom() { + // TODO: allow other ROM selection. And no ROM? map_.page(basic_.data()); map_.page(kernel_.data()); } diff --git a/Machines/Commodore/Plus4/Video.hpp b/Machines/Commodore/Plus4/Video.hpp index 8efe2dbb0..c09c2262a 100644 --- a/Machines/Commodore/Plus4/Video.hpp +++ b/Machines/Commodore/Plus4/Video.hpp @@ -126,6 +126,18 @@ public: // printf("bitmap:%d c256:%d ntsc:%d 40col:%d; base:%04x\n", bitmap_mode_, characters_256_, is_ntsc_, columns_40_, screen_memory_address_); } + Cycles cycle_length([[maybe_unused]] bool is_ready) const { + // TODO: the complete test is more than this. + // TODO: if this is a RDY cycle, can reply with time until end-of-RDY. + const bool is_long_cycle = refresh_; + + if(is_ntsc_) { + return is_long_cycle ? Cycles(8) : Cycles(4); + } else { + return is_long_cycle ? Cycles(10) : Cycles(5); + } + } + // Outer clock is [NTSC or PAL] colour subcarrier * 2. // // 65 cycles = 64µs? @@ -212,13 +224,25 @@ public: case OutputState::Sync: crt_.output_sync(time_in_state_); break; case OutputState::Burst: crt_.output_default_colour_burst(time_in_state_); break; case OutputState::Border: crt_.output_level(time_in_state_, background_[4]); break; - case OutputState::Pixels: crt_.output_level(time_in_state_, background_[0]); break; + case OutputState::Pixels: crt_.output_data(time_in_state_, time_in_state_); break; } time_in_state_ = 0; + + output_state_ = state; + if(output_state_ == OutputState::Pixels) { + pixels_ = reinterpret_cast(crt_.begin_data(384, 2)); + } } - output_state_ = state; time_in_state_ += period; + // Output pixels. TODO: properly. + if(pixels_) { + for(int c = 0; c < period; c++) { + pixels_[c] = ((c + horizontal_counter_) & 1) ? 0x0000 : 0xffff; + } + pixels_ += period; + } + // // Advance for current period. // @@ -346,6 +370,7 @@ private: Pixels, } output_state_ = OutputState::Blank; int time_in_state_ = 0; + uint16_t *pixels_ = nullptr; std::array background_{}; std::array raw_background_{};