diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 78728ec42..bfabfeea4 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -171,7 +171,7 @@ void TMS9918::run_for(const HalfCycles cycles) { if(write_cycles_pool) { // Determine how much writing to do. const int write_cycles = std::min( - this->clock_converter_.CyclesPerLine - this->write_pointer_.column, + Timing::CyclesPerLine - this->write_pointer_.column, write_cycles_pool ); const int end_column = this->write_pointer_.column + write_cycles; @@ -270,7 +270,7 @@ void TMS9918::run_for(const HalfCycles cycles) { this->write_pointer_.column = end_column; write_cycles_pool -= write_cycles; - if(this->write_pointer_.column == this->clock_converter_.CyclesPerLine) { + if(this->write_pointer_.column == Timing::CyclesPerLine) { this->write_pointer_.column = 0; this->write_pointer_.row = (this->write_pointer_.row + 1) % this->mode_timing_.total_lines; LineBuffer &next_line_buffer = this->line_buffers_[this->write_pointer_.row]; @@ -279,7 +279,7 @@ void TMS9918::run_for(const HalfCycles cycles) { this->set_current_screen_mode(); // Based on the output mode, pick a line mode. - next_line_buffer.first_pixel_output_column = 86; // TODO: these should be a function of ClockConverter::CyclesPerLine. + next_line_buffer.first_pixel_output_column = 86; // TODO: these should be a function of Timing next_line_buffer.next_border_column = 342; this->mode_timing_.maximum_visible_sprites = 4; switch(this->screen_mode_) { @@ -314,7 +314,7 @@ void TMS9918::run_for(const HalfCycles cycles) { if(read_cycles_pool) { // Determine how much time has passed in the remainder of this line, and proceed. const int target_read_cycles = std::min( - this->clock_converter_.CyclesPerLine - this->read_pointer_.column, + Timing::CyclesPerLine - this->read_pointer_.column, read_cycles_pool ); int read_cycles_performed = 0; @@ -448,7 +448,7 @@ void TMS9918::run_for(const HalfCycles cycles) { } read_cycles_pool -= target_read_cycles; - if(this->read_pointer_.column == this->clock_converter_.CyclesPerLine) { + if(this->read_pointer_.column == Timing::CyclesPerLine) { this->read_pointer_.column = 0; this->read_pointer_.row = (this->read_pointer_.row + 1) % this->mode_timing_.total_lines; } diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 8027931e7..2f14b0f9c 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -15,6 +15,8 @@ #include "../../../Numeric/BitReverse.hpp" #include "../../../Outputs/CRT/CRT.hpp" +#include "PersonalityTraits.hpp" + #include #include #include @@ -25,10 +27,7 @@ namespace TI { namespace TMS { -constexpr bool is_sega_vdp(Personality p) { - return p >= Personality::SMSVDP; -} - +// Additional properties that correlate with personality. constexpr size_t memory_size(Personality p) { switch(p) { case TI::TMS::TMS9918A: diff --git a/Components/9918/Implementation/ClockConverter.hpp b/Components/9918/Implementation/ClockConverter.hpp index c89f0bc14..a81db17f3 100644 --- a/Components/9918/Implementation/ClockConverter.hpp +++ b/Components/9918/Implementation/ClockConverter.hpp @@ -10,18 +10,28 @@ #define ClockConverter_hpp #include "../9918.hpp" +#include "PersonalityTraits.hpp" namespace TI { namespace TMS { -template constexpr int cycles_per_line() { - switch(personality) { - default: return 342; - case Personality::V9938: - case Personality::V9958: return 1368; - case Personality::MDVDP: return 3420; - } -} +// Timing constants. +template struct Timing {}; + +template +struct Timing> { + constexpr static int CyclesPerLine = 1368; +}; + +template +struct Timing> { + constexpr static int CyclesPerLine = 342; +}; + +template <> +struct Timing { + constexpr static int CyclesPerLine = 3420; +}; constexpr int TMSAccessWindowsPerLine = 171; @@ -133,9 +143,6 @@ template class ClockConverter { } } - /// The number of internal cycles in a single line. - constexpr static int CyclesPerLine = cycles_per_line(); - private: // Holds current residue in conversion from the external to // internal clock. diff --git a/Components/9918/Implementation/PersonalityTraits.hpp b/Components/9918/Implementation/PersonalityTraits.hpp new file mode 100644 index 000000000..18fae4319 --- /dev/null +++ b/Components/9918/Implementation/PersonalityTraits.hpp @@ -0,0 +1,36 @@ +// +// PersonalityTraits.hpp +// Clock Signal +// +// Created by Thomas Harte on 06/01/2023. +// Copyright © 2023 Thomas Harte. All rights reserved. +// + +#ifndef PersonalityTraits_hpp +#define PersonalityTraits_hpp + +namespace TI { +namespace TMS { + +// Genus determinants for the various personalityes. +constexpr bool is_sega_vdp(Personality p) { + return p >= Personality::SMSVDP; +} + +constexpr bool is_yamaha_vdp(Personality p) { + return p == Personality::V9938 || p == Personality::V9958; +} + +constexpr bool is_classic_vdp(Personality p) { + return + p == Personality::TMS9918A || + p == Personality::SMSVDP || + p == Personality::SMS2VDP || + p == Personality::GGVDP; +} + +} +} + + +#endif /* PersonalityTraits_hpp */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 1447f9c93..dcf95902c 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1246,6 +1246,7 @@ 4B228CDA24DA41880077EF25 /* ScanTarget.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = ScanTarget.metal; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.metal; }; 4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = ""; }; 4B2530F3244E6773007980BF /* fm.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = fm.json; sourceTree = ""; }; + 4B262BFF29691F55002EC0F7 /* PersonalityTraits.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PersonalityTraits.hpp; sourceTree = ""; }; 4B2A332C1DB86821002876E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/OricOptions.xib"; sourceTree = SOURCE_ROOT; }; 4B2A53901D117D36003C6002 /* CSAudioQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSAudioQueue.h; sourceTree = ""; }; 4B2A53911D117D36003C6002 /* CSAudioQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSAudioQueue.m; sourceTree = ""; }; @@ -4740,8 +4741,9 @@ 4B43983829620FB1006B0BFC /* 9918.cpp */, 4BD388411FE34E010042B588 /* 9918Base.hpp */, 4B43983C29621024006B0BFC /* ClockConverter.hpp */, - 4B43983E29628538006B0BFC /* Fetch.hpp */, 4B43983F2967459B006B0BFC /* Draw.hpp */, + 4B43983E29628538006B0BFC /* Fetch.hpp */, + 4B262BFF29691F55002EC0F7 /* PersonalityTraits.hpp */, ); path = Implementation; sourceTree = "";