diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index e638a3806..277cacb64 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -130,11 +130,11 @@ public: ConcreteMachine(const Analyser::Static::Commodore::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : m6502_(*this) { - // PAL: 8'867'240 divided by 5 or 4? - // NTSC: 7'159'090? + // PAL: 8867240 divided by 5 or 4? + // NTSC: 7159090? // i.e. colour subcarriers multiplied by two? - set_clock_rate(8'867'240); // TODO. + set_clock_rate(7159090); // TODO. const auto kernel = ROM::Name::Plus4KernelPALv5; const auto basic = ROM::Name::Plus4BASIC; @@ -171,6 +171,8 @@ public: const auto timers_cycles = timers_subcycles_.divide(Cycles(5)); timers_.tick(timers_cycles.as()); + video_.run_for(length); + // Perform actual access. if(address < 0xfd00 || address >= 0xff40) { if(isReadOperation(operation)) { diff --git a/Machines/Commodore/Plus4/Video.hpp b/Machines/Commodore/Plus4/Video.hpp index 86b9f1f6f..b1260ed3d 100644 --- a/Machines/Commodore/Plus4/Video.hpp +++ b/Machines/Commodore/Plus4/Video.hpp @@ -25,7 +25,6 @@ public: ); }; - switch(address) { case 0xff06: extended_colour_mode_ = value & 0x40; @@ -58,6 +57,68 @@ public: } } + // Outer clock is [NTSC or PAL] colour subcarrier * 2. + // + // 65 cycles = 64µs? + // 65*262*60 = 1021800 + // + // In an NTSC television system. 262 raster lines are produced (0 to 261), 312 for PAL (0−311). + // + // An interrupt is generated 8 cycles before the character window. For a 25 row display, the visible + // raster lines are from 4 to 203. + // + // The horizontal position register counts 456 dots, 0 to 455. + void run_for(Cycles) { + // Timing: + // + // 456 cycles/line; + // if in PAL mode, divide input clock by 1.25 (?); + // see page 34 of plus4_tech.pdf for event times. + + // Horizontal events: + // + // 3: 38-column screen start + // 288: external fetch window end, refresh single clock start, increment character position end + // 290: latch character position to reload + // 296: character window end, character window single clock end, increment refresh start + // 304: video shift register end + // 307: 38-column screen stop + // 315: 40-column screen end + // 328: refresh single clock end + // 336: increment blink, increment refresh end + // 344: horizontal blanking start + // 358: horizontal sync start + // 376: increment vertical line + // 384: burst start, end of screen — clear vertical line, vertical sub and character reload registers + // 390: horizontal sync end + // 408: burst end + // 400: external fetch window start + // 416: horizontal blanking end + // 424: increment character position reload + // 432: character window start, character window single clock start, increment character position start + // 440: video shift register start + // 451: 40-column screen start + + // Vertical events: + // + // 0: attribute fetch start + // 4: vertical screen window start (25 lines) + // 8: vertical screen window start (24 lines) + // 203: attribute fetch end + // 200: vertical screen window stop (24 lines) + // 204: frame window stop, vertical screen window stop (25 lines) + // 226: NTSC vertical blank start + // 229: NTSC vsync start + // 232: NTSC vsync end + // 244: NTSC vertical blank end + // 251: PAL vertical blank start + // 254: PAL vsync start + // 257: PAL vsync end + // 261: end of screen NTSC + // 269: PAL vertical blank end + // 311: end of screen PAL + } + private: bool extended_colour_mode_ = false; bool bitmap_mode_ = false; @@ -76,6 +137,9 @@ private: uint16_t character_row_address_ = 0; uint16_t character_generator_address_ = 0; uint16_t screen_memory_address_ = 0; + + int horizontal_counter_ = 0; + int vertical_counter_ = 0; }; }