1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-24 12:30:17 +00:00

Further clarify different usages of storage.

This commit is contained in:
Thomas Harte 2023-02-14 20:23:17 -05:00
parent bf0ed2813c
commit 35a0a1447e
3 changed files with 45 additions and 38 deletions

View File

@ -20,7 +20,7 @@ void Base<personality>::draw_tms_character(int start, int end) {
if(this->screen_mode_ == ScreenMode::MultiColour) { if(this->screen_mode_ == ScreenMode::MultiColour) {
for(int c = start; c < end; ++c) { for(int c = start; c < end; ++c) {
pixel_target_[c] = palette()[ pixel_target_[c] = palette()[
(line_buffer.patterns[c >> 3][0] >> (((c & 4)^4))) & 15 (line_buffer.tiles.patterns[c >> 3][0] >> (((c & 4)^4))) & 15
]; ];
} }
} else { } else {
@ -29,8 +29,8 @@ void Base<personality>::draw_tms_character(int start, int end) {
int length = std::min(pixels_left, 8 - shift); int length = std::min(pixels_left, 8 - shift);
int pattern = Numeric::bit_reverse(line_buffer.patterns[byte_column][0]) >> shift; int pattern = Numeric::bit_reverse(line_buffer.tiles.patterns[byte_column][0]) >> shift;
uint8_t colour = line_buffer.patterns[byte_column][1]; uint8_t colour = line_buffer.tiles.patterns[byte_column][1];
uint32_t colours[2] = { uint32_t colours[2] = {
palette()[(colour & 15) ? (colour & 15) : background_colour_], palette()[(colour & 15) ? (colour & 15) : background_colour_],
palette()[(colour >> 4) ? (colour >> 4) : background_colour_] palette()[(colour >> 4) ? (colour >> 4) : background_colour_]
@ -49,8 +49,8 @@ void Base<personality>::draw_tms_character(int start, int end) {
length = std::min(8, background_pixels_left); length = std::min(8, background_pixels_left);
byte_column++; byte_column++;
pattern = Numeric::bit_reverse(line_buffer.patterns[byte_column][0]); pattern = Numeric::bit_reverse(line_buffer.tiles.patterns[byte_column][0]);
colour = line_buffer.patterns[byte_column][1]; colour = line_buffer.tiles.patterns[byte_column][1];
colours[0] = palette()[(colour & 15) ? (colour & 15) : background_colour_]; colours[0] = palette()[(colour & 15) ? (colour & 15) : background_colour_];
colours[1] = palette()[(colour >> 4) ? (colour >> 4) : background_colour_]; colours[1] = palette()[(colour >> 4) ? (colour >> 4) : background_colour_];
} }
@ -111,7 +111,7 @@ void Base<personality>::draw_tms_text(int start, int end) {
const int shift = start % 6; const int shift = start % 6;
int byte_column = start / 6; int byte_column = start / 6;
int pattern = Numeric::bit_reverse(line_buffer.patterns[byte_column][0]) >> shift; int pattern = Numeric::bit_reverse(line_buffer.characters.shapes[byte_column]) >> shift;
int pixels_left = end - start; int pixels_left = end - start;
int length = std::min(pixels_left, 6 - shift); int length = std::min(pixels_left, 6 - shift);
while(true) { while(true) {
@ -125,7 +125,7 @@ void Base<personality>::draw_tms_text(int start, int end) {
if(!pixels_left) break; if(!pixels_left) break;
length = std::min(6, pixels_left); length = std::min(6, pixels_left);
byte_column++; byte_column++;
pattern = Numeric::bit_reverse(line_buffer.patterns[byte_column][0]); pattern = Numeric::bit_reverse(line_buffer.characters.shapes[byte_column]);
} }
} }
@ -169,15 +169,15 @@ void Base<personality>::draw_sms(int start, int end, uint32_t cram_dot) {
int pixels_left = tile_end - tile_start; int pixels_left = tile_end - tile_start;
int length = std::min(pixels_left, 8 - shift); int length = std::min(pixels_left, 8 - shift);
pattern = *reinterpret_cast<const uint32_t *>(line_buffer.patterns[byte_column]); pattern = *reinterpret_cast<const uint32_t *>(line_buffer.tiles.patterns[byte_column]);
if(line_buffer.flags[byte_column]&2) if(line_buffer.characters.flags[byte_column]&2)
pattern >>= shift; pattern >>= shift;
else else
pattern <<= shift; pattern <<= shift;
while(true) { while(true) {
const int palette_offset = (line_buffer.flags[byte_column]&0x18) << 1; const int palette_offset = (line_buffer.characters.flags[byte_column]&0x18) << 1;
if(line_buffer.flags[byte_column]&2) { if(line_buffer.characters.flags[byte_column]&2) {
for(int c = 0; c < length; ++c) { for(int c = 0; c < length; ++c) {
colour_buffer[tile_offset] = colour_buffer[tile_offset] =
((pattern_index[3] & 0x01) << 3) | ((pattern_index[3] & 0x01) << 3) |
@ -206,7 +206,7 @@ void Base<personality>::draw_sms(int start, int end, uint32_t cram_dot) {
length = std::min(8, pixels_left); length = std::min(8, pixels_left);
byte_column++; byte_column++;
pattern = *reinterpret_cast<const uint32_t *>(line_buffer.patterns[byte_column]); pattern = *reinterpret_cast<const uint32_t *>(line_buffer.tiles.patterns[byte_column]);
} }
} }
@ -323,7 +323,7 @@ void Base<personality>::draw_yamaha(LineBuffer &buffer, int start, int end) {
const int shift = start % 6; const int shift = start % 6;
int byte_column = start / 6; int byte_column = start / 6;
int pattern = Numeric::bit_reverse(buffer.patterns[byte_column >> 1][byte_column & 1]) >> shift; int pattern = Numeric::bit_reverse(buffer.characters.shapes[byte_column]) >> shift;
int pixels_left = end - start; int pixels_left = end - start;
int length = std::min(pixels_left, 6 - shift); int length = std::min(pixels_left, 6 - shift);
while(true) { while(true) {
@ -337,7 +337,7 @@ void Base<personality>::draw_yamaha(LineBuffer &buffer, int start, int end) {
if(!pixels_left) break; if(!pixels_left) break;
length = std::min(6, pixels_left); length = std::min(6, pixels_left);
byte_column++; byte_column++;
pattern = Numeric::bit_reverse(buffer.patterns[byte_column >> 1][byte_column & 1]); pattern = Numeric::bit_reverse(buffer.characters.shapes[byte_column]);
} }
} }
} }

View File

@ -140,9 +140,9 @@ struct TextFetcher {
constexpr int offset = cycle - 47; constexpr int offset = cycle - 47;
constexpr auto column = AddressT(offset / 3); constexpr auto column = AddressT(offset / 3);
switch(offset % 3) { switch(offset % 3) {
case 0: base->name_[0] = base->ram_[row_base + column]; break; // (1) fetch tile name. case 0: base->name_[0] = base->ram_[row_base + column]; break; // (1) fetch tile name.
case 1: base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow>(cycle)); break; // (2) external slot. case 1: base->do_external_slot(to_internal<personality, Clock::TMSMemoryWindow>(cycle)); break; // (2) external slot.
case 2: line_buffer.patterns[column][0] = base->ram_[row_offset + size_t(base->name_[0] << 3)]; break; // (3) fetch tile pattern. case 2: line_buffer.characters.shapes[column] = base->ram_[row_offset + size_t(base->name_[0] << 3)]; break; // (3) fetch tile pattern.
} }
} }
} }
@ -207,8 +207,8 @@ template<bool use_end> void Base<personality>::fetch_tms_character(LineBuffer &l
#define fetch_tile_name(column) tile_offset_ = ram_[(row_base + column) & 0x3fff]; #define fetch_tile_name(column) tile_offset_ = ram_[(row_base + column) & 0x3fff];
#define fetch_tile(column) {\ #define fetch_tile(column) {\
line_buffer.patterns[column][1] = ram_[(colour_base + size_t((tile_offset_ << 3) >> colour_name_shift)) & 0x3fff]; \ line_buffer.tiles.patterns[column][1] = ram_[(colour_base + size_t((tile_offset_ << 3) >> colour_name_shift)) & 0x3fff]; \
line_buffer.patterns[column][0] = ram_[(pattern_base + size_t(tile_offset_ << 3)) & 0x3fff]; \ line_buffer.tiles.patterns[column][0] = ram_[(pattern_base + size_t(tile_offset_ << 3)) & 0x3fff]; \
} }
#define background_fetch_block(location, column, sprite) \ #define background_fetch_block(location, column, sprite) \
@ -345,17 +345,17 @@ template<bool use_end> void Base<personality>::fetch_sms(LineBuffer &line_buffer
#define fetch_tile_name(column, row_info) {\ #define fetch_tile_name(column, row_info) {\
const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\ const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\
const size_t address = row_info.pattern_address_base + (scrolled_column << 1); \ const size_t address = row_info.pattern_address_base + (scrolled_column << 1); \
line_buffer.flags[column] = ram_[address+1]; \ line_buffer.tiles.flags[column] = ram_[address+1]; \
tile_offset_ = uint16_t( \ tile_offset_ = uint16_t( \
(((line_buffer.flags[column]&1) << 8) | ram_[address]) << 5 \ (((line_buffer.tiles.flags[column]&1) << 8) | ram_[address]) << 5 \
) + row_info.sub_row[(line_buffer.flags[column]&4) >> 2]; \ ) + row_info.sub_row[(line_buffer.tiles.flags[column]&4) >> 2]; \
} }
#define fetch_tile(column) \ #define fetch_tile(column) \
line_buffer.patterns[column][0] = ram_[tile_offset_]; \ line_buffer.tiles.patterns[column][0] = ram_[tile_offset_]; \
line_buffer.patterns[column][1] = ram_[tile_offset_+1]; \ line_buffer.tiles.patterns[column][1] = ram_[tile_offset_+1]; \
line_buffer.patterns[column][2] = ram_[tile_offset_+2]; \ line_buffer.tiles.patterns[column][2] = ram_[tile_offset_+2]; \
line_buffer.patterns[column][3] = ram_[tile_offset_+3]; line_buffer.tiles.patterns[column][3] = ram_[tile_offset_+3];
#define background_fetch_block(location, column, sprite, row_info) \ #define background_fetch_block(location, column, sprite, row_info) \
slot(location): fetch_tile_name(column, row_info) \ slot(location): fetch_tile_name(column, row_info) \
@ -516,19 +516,19 @@ template<ScreenMode mode> void Base<personality>::fetch_yamaha(LineBuffer &line_
Storage<personality>::data_block_ += 2; Storage<personality>::data_block_ += 2;
const AddressT start = pattern_generator_table_address_ & (0x1f800 | (y & 7)); const AddressT start = pattern_generator_table_address_ & (0x1f800 | (y & 7));
line_buffer.patterns[column + 0][0] = ram_[start + AddressT(name_[0] << 3)]; line_buffer.characters.shapes[column + 0] = ram_[start + AddressT(name_[0] << 3)];
line_buffer.patterns[column + 1][0] = ram_[start + AddressT(name_[1] << 3)]; line_buffer.characters.shapes[column + 1] = ram_[start + AddressT(name_[1] << 3)];
} break; } break;
case ScreenMode::YamahaText80: { case ScreenMode::YamahaText80: {
const auto column = AddressT(Storage<personality>::data_block_); const auto column = AddressT(Storage<personality>::data_block_);
Storage<personality>::data_block_ += 2; Storage<personality>::data_block_ += 4;
const AddressT start = pattern_generator_table_address_ & (0x1f800 | (y & 7)); const AddressT start = pattern_generator_table_address_ & (0x1f800 | (y & 7));
line_buffer.patterns[column + 0][0] = ram_[start + AddressT(name_[0] << 3)]; line_buffer.characters.shapes[column + 0] = ram_[start + AddressT(name_[0] << 3)];
line_buffer.patterns[column + 0][1] = ram_[start + AddressT(name_[1] << 3)]; line_buffer.characters.shapes[column + 1] = ram_[start + AddressT(name_[1] << 3)];
line_buffer.patterns[column + 1][0] = ram_[start + AddressT(name_[2] << 3)]; line_buffer.characters.shapes[column + 2] = ram_[start + AddressT(name_[2] << 3)];
line_buffer.patterns[column + 1][1] = ram_[start + AddressT(name_[3] << 3)]; line_buffer.characters.shapes[column + 3] = ram_[start + AddressT(name_[3] << 3)];
} break; } break;
default: break; default: break;

View File

@ -31,16 +31,23 @@ struct LineBuffer {
// The names array holds pattern names, as an offset into memory, and // The names array holds pattern names, as an offset into memory, and
// potentially flags also. // potentially flags also.
union { union {
// The TMS and Sega VDPs are close enough to always tile-based; // This struct captures maximal potential detail across the TMS9918
// this struct captures maximal potential detail there. // and Sega VDP for tiled modes (plus multicolour).
struct { struct {
uint8_t flags[40]{}; uint8_t flags[32]{};
// The patterns array holds tile patterns, corresponding 1:1 with names. // The patterns array holds tile patterns, corresponding 1:1 with names.
// Four bytes per pattern is the maximum required by any // Four bytes per pattern is the maximum required by any
// currently-implemented VDP. // currently-implemented VDP.
uint8_t patterns[40][4]{}; uint8_t patterns[32][4]{};
}; } tiles;
// The Yamaha and TMS both have text modes, with the former going up to
// 80 columns plus 10 bytes of colour-esque flags.
struct {
uint8_t shapes[80];
uint8_t flags[10];
} characters;
// The Yamaha VDP also has a variety of bitmap modes, // The Yamaha VDP also has a variety of bitmap modes,
// the widest of which is 512px @ 4bpp. // the widest of which is 512px @ 4bpp.