mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
Pull everything out of master_system_
struct.
Now that it's inherently collected in the relevant `Storage`.
This commit is contained in:
parent
4b7606894e
commit
392b0acb58
@ -178,9 +178,9 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
if(this->write_pointer_.column < 61 && end_column >= 61) {
|
||||
if(!this->write_pointer_.row) {
|
||||
this->master_system_.latched_vertical_scroll = this->master_system_.vertical_scroll;
|
||||
Storage<personality>::latched_vertical_scroll_ = Storage<personality>::vertical_scroll_;
|
||||
|
||||
if(this->master_system_.mode4_enable) {
|
||||
if(Storage<personality>::mode4_enable_) {
|
||||
this->mode_timing_.pixel_lines = 192;
|
||||
if(this->mode2_enable_ && this->mode1_enable_) this->mode_timing_.pixel_lines = 224;
|
||||
if(this->mode2_enable_ && this->mode3_enable_) this->mode_timing_.pixel_lines = 240;
|
||||
@ -191,7 +191,7 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
|
||||
this->mode_timing_.end_of_frame_interrupt_position.row = this->mode_timing_.pixel_lines + 1;
|
||||
}
|
||||
}
|
||||
line_buffer.latched_horizontal_scroll = this->master_system_.horizontal_scroll;
|
||||
line_buffer.latched_horizontal_scroll = Storage<personality>::horizontal_scroll_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,13 +230,13 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
|
||||
// It is otherwise decremented.
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
if(this->write_pointer_.row >= 0 && this->write_pointer_.row <= this->mode_timing_.pixel_lines) {
|
||||
--this->line_interrupt_counter;
|
||||
if(this->line_interrupt_counter == 0xff) {
|
||||
--this->line_interrupt_counter_;
|
||||
if(this->line_interrupt_counter_ == 0xff) {
|
||||
this->line_interrupt_pending_ = true;
|
||||
this->line_interrupt_counter = this->line_interrupt_target;
|
||||
this->line_interrupt_counter_ = this->line_interrupt_target_;
|
||||
}
|
||||
} else {
|
||||
this->line_interrupt_counter = this->line_interrupt_target;
|
||||
this->line_interrupt_counter_ = this->line_interrupt_target_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,12 +575,12 @@ void Base<personality>::write_register(uint8_t value) {
|
||||
switch(value) {
|
||||
case 0:
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
Storage<personality>::master_system_.vertical_scroll_lock = low_write_ & 0x80;
|
||||
Storage<personality>::master_system_.horizontal_scroll_lock = low_write_ & 0x40;
|
||||
Storage<personality>::master_system_.hide_left_column = low_write_ & 0x20;
|
||||
Storage<personality>::vertical_scroll_lock_ = low_write_ & 0x80;
|
||||
Storage<personality>::horizontal_scroll_lock_ = low_write_ & 0x40;
|
||||
Storage<personality>::hide_left_column_ = low_write_ & 0x20;
|
||||
enable_line_interrupts_ = low_write_ & 0x10;
|
||||
Storage<personality>::master_system_.shift_sprites_8px_left = low_write_ & 0x08;
|
||||
Storage<personality>::master_system_.mode4_enable = low_write_ & 0x04;
|
||||
Storage<personality>::shift_sprites_8px_left_ = low_write_ & 0x08;
|
||||
Storage<personality>::mode4_enable_ = low_write_ & 0x04;
|
||||
}
|
||||
mode2_enable_ = low_write_ & 0x02;
|
||||
break;
|
||||
@ -602,7 +602,7 @@ void Base<personality>::write_register(uint8_t value) {
|
||||
pattern_name_address_ = size_t((low_write_ & 0xf) << 10) | 0x3ff;
|
||||
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
Storage<personality>::master_system_.pattern_name_address = pattern_name_address_ | ((personality == TMS::SMSVDP) ? 0x000 : 0x400);
|
||||
Storage<personality>::pattern_name_address_ = pattern_name_address_ | ((personality == TMS::SMSVDP) ? 0x000 : 0x400);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -617,14 +617,14 @@ void Base<personality>::write_register(uint8_t value) {
|
||||
case 5:
|
||||
sprite_attribute_table_address_ = size_t((low_write_ & 0x7f) << 7) | 0x7f;
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
Storage<personality>::master_system_.sprite_attribute_table_address = sprite_attribute_table_address_ | ((personality == TMS::SMSVDP) ? 0x00 : 0x80);
|
||||
Storage<personality>::sprite_attribute_table_address_ = sprite_attribute_table_address_ | ((personality == TMS::SMSVDP) ? 0x00 : 0x80);
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
sprite_generator_table_address_ = size_t((low_write_ & 0x07) << 11) | 0x7ff;
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
Storage<personality>::master_system_.sprite_generator_table_address = sprite_generator_table_address_ | ((personality == TMS::SMSVDP) ? 0x0000 : 0x1800);
|
||||
Storage<personality>::sprite_generator_table_address_ = sprite_generator_table_address_ | ((personality == TMS::SMSVDP) ? 0x0000 : 0x1800);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -635,7 +635,7 @@ void Base<personality>::write_register(uint8_t value) {
|
||||
|
||||
case 8:
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
Storage<personality>::master_system_.horizontal_scroll = low_write_;
|
||||
Storage<personality>::horizontal_scroll_ = low_write_;
|
||||
} else {
|
||||
LOG("Unknown TMS write: " << int(low_write_) << " to " << int(value));
|
||||
}
|
||||
@ -643,7 +643,7 @@ void Base<personality>::write_register(uint8_t value) {
|
||||
|
||||
case 9:
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
Storage<personality>::master_system_.vertical_scroll = low_write_;
|
||||
Storage<personality>::vertical_scroll_ = low_write_;
|
||||
} else {
|
||||
LOG("Unknown TMS write: " << int(low_write_) << " to " << int(value));
|
||||
}
|
||||
@ -651,7 +651,7 @@ void Base<personality>::write_register(uint8_t value) {
|
||||
|
||||
case 10:
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
line_interrupt_target = low_write_;
|
||||
line_interrupt_target_ = low_write_;
|
||||
} else {
|
||||
LOG("Unknown TMS write: " << int(low_write_) << " to " << int(value));
|
||||
}
|
||||
@ -837,11 +837,11 @@ HalfCycles TMS9918<personality>::get_next_sequence_point() const {
|
||||
// If there is still time for a line interrupt this frame, that'll be it;
|
||||
// otherwise it'll be on the next frame, supposing there's ever time for
|
||||
// it at all.
|
||||
if(line_of_next_interrupt_threshold + this->line_interrupt_counter <= this->mode_timing_.pixel_lines) {
|
||||
next_line_interrupt_row = line_of_next_interrupt_threshold + this->line_interrupt_counter;
|
||||
if(line_of_next_interrupt_threshold + this->line_interrupt_counter_ <= this->mode_timing_.pixel_lines) {
|
||||
next_line_interrupt_row = line_of_next_interrupt_threshold + this->line_interrupt_counter_;
|
||||
} else {
|
||||
if(this->line_interrupt_target <= this->mode_timing_.pixel_lines)
|
||||
next_line_interrupt_row = this->mode_timing_.total_lines + this->line_interrupt_target;
|
||||
if(this->line_interrupt_target_ <= this->mode_timing_.pixel_lines)
|
||||
next_line_interrupt_row = this->mode_timing_.total_lines + this->line_interrupt_target_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,24 +147,25 @@ template <Personality personality> struct Storage<personality, std::enable_if_t<
|
||||
bool cram_is_selected_ = false;
|
||||
|
||||
// Fields below affect only the Master System output mode.
|
||||
struct {
|
||||
// Programmer-set flags.
|
||||
bool vertical_scroll_lock = false;
|
||||
bool horizontal_scroll_lock = false;
|
||||
bool hide_left_column = false;
|
||||
bool shift_sprites_8px_left = false;
|
||||
bool mode4_enable = false;
|
||||
uint8_t horizontal_scroll = 0;
|
||||
uint8_t vertical_scroll = 0;
|
||||
|
||||
// Holds the vertical scroll position for this frame; this is latched
|
||||
// once and cannot dynamically be changed until the next frame.
|
||||
uint8_t latched_vertical_scroll = 0;
|
||||
// Programmer-set flags.
|
||||
bool vertical_scroll_lock_ = false;
|
||||
bool horizontal_scroll_lock_ = false;
|
||||
bool hide_left_column_ = false;
|
||||
bool shift_sprites_8px_left_ = false;
|
||||
bool mode4_enable_ = false;
|
||||
uint8_t horizontal_scroll_ = 0;
|
||||
uint8_t vertical_scroll_ = 0;
|
||||
|
||||
size_t pattern_name_address;
|
||||
size_t sprite_attribute_table_address;
|
||||
size_t sprite_generator_table_address;
|
||||
} master_system_;
|
||||
// Holds the vertical scroll position for this frame; this is latched
|
||||
// once and cannot dynamically be changed until the next frame.
|
||||
uint8_t latched_vertical_scroll_ = 0;
|
||||
|
||||
// Various resource addresses with VDP-version-specific modifications
|
||||
// built int.
|
||||
size_t pattern_name_address_;
|
||||
size_t sprite_attribute_table_address_;
|
||||
size_t sprite_generator_table_address_;
|
||||
};
|
||||
|
||||
template <Personality personality> struct Base: public Storage<personality> {
|
||||
@ -285,8 +286,8 @@ template <Personality personality> struct Base: public Storage<personality> {
|
||||
uint8_t sprite_terminator = 0xd0;
|
||||
} mode_timing_;
|
||||
|
||||
uint8_t line_interrupt_target = 0xff;
|
||||
uint8_t line_interrupt_counter = 0;
|
||||
uint8_t line_interrupt_target_ = 0xff;
|
||||
uint8_t line_interrupt_counter_ = 0;
|
||||
bool enable_line_interrupts_ = false;
|
||||
bool line_interrupt_pending_ = false;
|
||||
|
||||
@ -317,7 +318,7 @@ template <Personality personality> struct Base: public Storage<personality> {
|
||||
}
|
||||
|
||||
if constexpr (is_sega_vdp(personality)) {
|
||||
if(Storage<personality>::master_system_.mode4_enable) {
|
||||
if(Storage<personality>::mode4_enable_) {
|
||||
return ScreenMode::SMSMode4;
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ void Base<personality>::draw_sms(int start, int end, uint32_t cram_dot) {
|
||||
*/
|
||||
int tile_start = start, tile_end = end;
|
||||
int tile_offset = start;
|
||||
if(read_pointer_.row >= 16 || !Storage<personality>::master_system_.horizontal_scroll_lock) {
|
||||
if(read_pointer_.row >= 16 || !Storage<personality>::horizontal_scroll_lock_) {
|
||||
for(int c = start; c < (line_buffer.latched_horizontal_scroll & 7); ++c) {
|
||||
colour_buffer[c] = 16 + background_colour_;
|
||||
++tile_offset;
|
||||
@ -276,7 +276,7 @@ void Base<personality>::draw_sms(int start, int end, uint32_t cram_dot) {
|
||||
// If the VDP is set to hide the left column and this is the final call that'll come
|
||||
// this line, hide it.
|
||||
if(end == 256) {
|
||||
if(Storage<personality>::master_system_.hide_left_column) {
|
||||
if(Storage<personality>::hide_left_column_) {
|
||||
pixel_origin_[0] = pixel_origin_[1] = pixel_origin_[2] = pixel_origin_[3] =
|
||||
pixel_origin_[4] = pixel_origin_[5] = pixel_origin_[6] = pixel_origin_[7] =
|
||||
Storage<personality>::colour_ram_[16 + background_colour_];
|
||||
|
@ -324,12 +324,12 @@ template<bool use_end> void Base<personality>::fetch_sms(int start, int end) {
|
||||
#define sprite_fetch(sprite) {\
|
||||
line_buffer.active_sprites[sprite].x = \
|
||||
ram_[\
|
||||
Storage<personality>::master_system_.sprite_attribute_table_address & size_t(0x3f80 | (line_buffer.active_sprites[sprite].index << 1))\
|
||||
] - (Storage<personality>::master_system_.shift_sprites_8px_left ? 8 : 0); \
|
||||
Storage<personality>::sprite_attribute_table_address_ & size_t(0x3f80 | (line_buffer.active_sprites[sprite].index << 1))\
|
||||
] - (Storage<personality>::shift_sprites_8px_left_ ? 8 : 0); \
|
||||
const uint8_t name = ram_[\
|
||||
Storage<personality>::master_system_.sprite_attribute_table_address & size_t(0x3f81 | (line_buffer.active_sprites[sprite].index << 1))\
|
||||
Storage<personality>::sprite_attribute_table_address_ & size_t(0x3f81 | (line_buffer.active_sprites[sprite].index << 1))\
|
||||
] & (sprites_16x16_ ? ~1 : ~0);\
|
||||
const size_t graphic_location = Storage<personality>::master_system_.sprite_generator_table_address & size_t(0x2000 | (name << 5) | (line_buffer.active_sprites[sprite].row << 2)); \
|
||||
const size_t graphic_location = Storage<personality>::sprite_generator_table_address_ & size_t(0x2000 | (name << 5) | (line_buffer.active_sprites[sprite].row << 2)); \
|
||||
line_buffer.active_sprites[sprite].image[0] = ram_[graphic_location]; \
|
||||
line_buffer.active_sprites[sprite].image[1] = ram_[graphic_location+1]; \
|
||||
line_buffer.active_sprites[sprite].image[2] = ram_[graphic_location+2]; \
|
||||
@ -348,8 +348,8 @@ template<bool use_end> void Base<personality>::fetch_sms(int start, int end) {
|
||||
|
||||
#define sprite_y_read(location, sprite) \
|
||||
slot(location): \
|
||||
posit_sprite(sprite_selection_buffer, sprite, ram_[Storage<personality>::master_system_.sprite_attribute_table_address & ((sprite) | 0x3f00)], write_pointer_.row); \
|
||||
posit_sprite(sprite_selection_buffer, sprite+1, ram_[Storage<personality>::master_system_.sprite_attribute_table_address & ((sprite + 1) | 0x3f00)], write_pointer_.row); \
|
||||
posit_sprite(sprite_selection_buffer, sprite, ram_[Storage<personality>::sprite_attribute_table_address_ & ((sprite) | 0x3f00)], write_pointer_.row); \
|
||||
posit_sprite(sprite_selection_buffer, sprite+1, ram_[Storage<personality>::sprite_attribute_table_address_ & ((sprite + 1) | 0x3f00)], write_pointer_.row); \
|
||||
|
||||
#define fetch_tile_name(column, row_info) {\
|
||||
const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\
|
||||
@ -393,16 +393,16 @@ template<bool use_end> void Base<personality>::fetch_sms(int start, int end) {
|
||||
// Determine the coarse horizontal scrolling offset; this isn't applied on the first two lines if the programmer has requested it.
|
||||
LineBuffer &line_buffer = line_buffers_[write_pointer_.row];
|
||||
LineBuffer &sprite_selection_buffer = line_buffers_[(write_pointer_.row + 1) % mode_timing_.total_lines];
|
||||
const int horizontal_offset = (write_pointer_.row >= 16 || !Storage<personality>::master_system_.horizontal_scroll_lock) ? (line_buffer.latched_horizontal_scroll >> 3) : 0;
|
||||
const int horizontal_offset = (write_pointer_.row >= 16 || !Storage<personality>::horizontal_scroll_lock_) ? (line_buffer.latched_horizontal_scroll >> 3) : 0;
|
||||
|
||||
// Limit address bits in use if this is a SMS2 mode.
|
||||
const bool is_tall_mode = mode_timing_.pixel_lines != 192;
|
||||
const size_t pattern_name_address = Storage<personality>::master_system_.pattern_name_address | (is_tall_mode ? 0x800 : 0);
|
||||
const size_t pattern_name_address = Storage<personality>::pattern_name_address_ | (is_tall_mode ? 0x800 : 0);
|
||||
const size_t pattern_name_offset = is_tall_mode ? 0x100 : 0;
|
||||
|
||||
// Determine row info for the screen both (i) if vertical scrolling is applied; and (ii) if it isn't.
|
||||
// The programmer can opt out of applying vertical scrolling to the right-hand portion of the display.
|
||||
const int scrolled_row = (write_pointer_.row + Storage<personality>::master_system_.latched_vertical_scroll) % (is_tall_mode ? 256 : 224);
|
||||
const int scrolled_row = (write_pointer_.row + Storage<personality>::latched_vertical_scroll_) % (is_tall_mode ? 256 : 224);
|
||||
struct RowInfo {
|
||||
size_t pattern_address_base;
|
||||
size_t sub_row[2];
|
||||
@ -412,7 +412,7 @@ template<bool use_end> void Base<personality>::fetch_sms(int start, int end) {
|
||||
{size_t((scrolled_row & 7) << 2), 28 ^ size_t((scrolled_row & 7) << 2)}
|
||||
};
|
||||
RowInfo row_info;
|
||||
if(Storage<personality>::master_system_.vertical_scroll_lock) {
|
||||
if(Storage<personality>::vertical_scroll_lock_) {
|
||||
row_info.pattern_address_base = (pattern_name_address & size_t(((write_pointer_.row & ~7) << 3) | 0x3800)) - pattern_name_offset;
|
||||
row_info.sub_row[0] = size_t((write_pointer_.row & 7) << 2);
|
||||
row_info.sub_row[1] = 28 ^ size_t((write_pointer_.row & 7) << 2);
|
||||
|
Loading…
Reference in New Issue
Block a user