diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 9b1343081..5ecf72853 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -67,7 +67,12 @@ enum class MemoryAccess { }; // Temporary buffers collect a representation of each line prior to pixel serialisation. +// +// TODO: either template on personality, to avoid having to be the union of all potential footprints, +// or just stop keeping so many of these in the 9918. struct LineBuffer { + LineBuffer() {} + // The line mode describes the proper timing diagram for this line. LineMode line_mode = LineMode::Text; @@ -77,15 +82,25 @@ struct LineBuffer { // The names array holds pattern names, as an offset into memory, and // potentially flags also. - struct { - size_t offset = 0; - uint8_t flags = 0; - } names[40]; + union { + // The TMS and Sega VDPs are close enough to always tile-based; + // this struct captures maximal potential detail there. + struct { + struct { + size_t offset = 0; + uint8_t flags = 0; + } names[40]; - // The patterns array holds tile patterns, corresponding 1:1 with names. - // Four bytes per pattern is the maximum required by any - // currently-implemented VDP. - uint8_t patterns[40][4]; + // The patterns array holds tile patterns, corresponding 1:1 with names. + // Four bytes per pattern is the maximum required by any + // currently-implemented VDP. + uint8_t patterns[40][4]; + }; + + // The Yamaha VDP also has a variety of bitmap modes, the widest of which is + // 512px @ 4bpp. + uint8_t bitmap[256]; + }; /* Horizontal layout (on a 342-cycle clock): diff --git a/Components/9918/Implementation/Fetch.hpp b/Components/9918/Implementation/Fetch.hpp index 537fc492b..f8efc0034 100644 --- a/Components/9918/Implementation/Fetch.hpp +++ b/Components/9918/Implementation/Fetch.hpp @@ -480,6 +480,25 @@ template void Base::fetch_yamaha_refresh(int start, i template template void Base::fetch_yamaha(int start, int end) { + /* + Per http://map.grauw.nl/articles/vdp-vram-timing/vdp-timing.html : + + The major change compared to the previous mode is that now the VDP needs to fetch extra data + for the bitmap rendering. These fetches happen in 32 blocks of 4 bytes (screen 5/6) or + 8 bytes (screen 7/8). The fetches within one block happen in burst mode. This means that + one block takes 18 cycles (screen 5/6) or 20 cycles (screen 7/8). Though later we'll see + that the two spare cycles for screen 5/6 are not used for anything else, so for simplicity + we can say that in all bitmap modes a bitmap-fetch-block takes 20 cycles. This is even + clearer if you look at the RAS signal: this signal follows the exact same pattern in all + (bitmap) screen modes, so in screen 5/6 it remains active for two cycles longer than + strictly necessary. + + Actually before these 32 blocks there's one extra dummy block. This block has the same timing + as the other blocks, but it always reads address 0x1FFFF. From an emulator point of view, + these dummy reads don't matter, it only matters that at those moments no other VRAM accesses + can occur. + */ + (void)start; (void)end; }