diff --git a/Components/9918/Implementation/Storage.hpp b/Components/9918/Implementation/Storage.hpp index 9a5189c9a..401caa82f 100644 --- a/Components/9918/Implementation/Storage.hpp +++ b/Components/9918/Implementation/Storage.hpp @@ -1,4 +1,5 @@ // +// // Storage.hpp // Clock Signal // @@ -12,6 +13,8 @@ #include "LineBuffer.hpp" #include "YamahaCommands.hpp" +#include + namespace TI { namespace TMS { @@ -53,7 +56,8 @@ template struct Storage struct Storage struct Storage struct Storage static constexpr size_t events_size() { + size_t size = 0; + for(int c = 0; c < 1368; c++) { + const auto event_type = GeneratorT::event(internal_to_grauw(c)); + size += event_type.has_value(); + } + return size + 1; + } - Event(164), Event(172), Event(180), Event(188), Event(196), Event(204), - Event(212), Event(220), Event(228), Event(236), Event(244), Event(252), - Event(260), Event(268), Event(276), /* Refresh. */ Event(292), Event(300), - Event(308), Event(316), Event(324), Event(332), Event(340), Event(348), - Event(356), Event(364), Event(372), Event(380), Event(388), Event(396), - Event(404), /* Refresh. */ Event(420), Event(428), Event(436), Event(444), - Event(452), Event(460), Event(468), Event(476), Event(484), Event(492), - Event(500), Event(508), Event(516), Event(524), Event(532), /* Refresh. */ - Event(548), Event(556), Event(564), Event(570), Event(580), Event(588), - Event(596), Event(604), Event(612), Event(620), Event(628), Event(636), - Event(644), Event(652), Event(660), /* Refresh. */ Event(676), Event(684), - Event(692), Event(700), Event(708), Event(716), Event(724), Event(732), - Event(740), Event(748), Event(756), Event(764), Event(772), Event(780), - Event(788), /* Refresh. */ Event(804), Event(812), Event(820), Event(828), - Event(836), Event(844), Event(852), Event(860), Event(868), Event(876), - Event(884), Event(892), Event(900), Event(908), Event(916), /* Refresh. */ - Event(932), Event(940), Event(948), Event(956), Event(964), Event(972), - Event(980), Event(988), Event(996), Event(1004), Event(1012), Event(1020), - Event(1028), Event(1036), Event(1044), /* Refresh. */ Event(1060), Event(1068), - Event(1076), Event(1084), Event(1092), Event(1100), Event(1108), Event(1116), - Event(1124), Event(1132), Event(1140), Event(1148), Event(1156), Event(1164), - Event(1172), /* Refresh. */ Event(1188), Event(1196), Event(1204), Event(1212), - Event(1220), Event(1228), + template ()> + static constexpr std::array events() { + std::array result{}; + size_t index = 0; + for(int c = 0; c < 1368; c++) { + const auto event_type = GeneratorT::event(internal_to_grauw(c)); + if(!event_type) { + continue; + } + // TODO: once all lists are using generators, remove implicit grauw_to_internal + // from Event constructor and just supply c here. + result[index] = Event(internal_to_grauw(c), *event_type); + ++index; + } + result[index] = Event(); + return result; + } - Event(1268), Event(1276), + struct RefreshGenerator { + static constexpr std::optional event(int grauw_index) { + // From 0 to 126: CPU/CMD slots at every cycle divisible by 8. + if(grauw_index < 126) { + if(grauw_index & 7) return std::nullopt; + return Event::Type::External; + } - Event() + // From 164 to 1234: eight-cycle windows, the first 15 of each 16 being + // CPU/CMD and the final being refresh. + if(grauw_index >= 164 && grauw_index < 1234) { + const int offset = grauw_index - 164; + if(offset & 7) return std::nullopt; + if(((offset >> 3) & 15) == 15) return std::nullopt; + return Event::Type::External; + } + + // From 1268 to 1330: CPU/CMD slots at every cycle divisible by 8. + if(grauw_index >= 1268 && grauw_index < 1330) { + const int offset = grauw_index - 1268; + if(offset & 7) return std::nullopt; + return Event::Type::External; + } + + // A CPU/CMD at 1334. + if(grauw_index == 1334) { + return Event::Type::External; + } + + // From 1344 to 1366: CPU/CMD slots every cycle divisible by 8. + if(grauw_index >= 1344 && grauw_index < 1366) { + const int offset = grauw_index - 1344; + if(offset & 7) return std::nullopt; + return Event::Type::External; + } + + // Otherwise: nothing. + return std::nullopt; + } }; + static constexpr auto refresh_events = events(); + static constexpr Event no_sprites_events[] = { Event(1282), Event(1290), Event(1298), Event(1306), Event(1314), Event(1322), Event(1332), Event(1342),