mirror of
https://github.com/TomHarte/CLK.git
synced 2024-08-24 23:29:00 +00:00
Merge pull request #569 from TomHarte/224px
Adds 'full' support for 224- and 240-line SMS modes
This commit is contained in:
commit
cba8e6814f
@ -138,7 +138,7 @@ void Base::posit_sprite(LineBuffer &buffer, int sprite_number, int sprite_positi
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// A sprite Y of 208 means "don't scan the list any further".
|
// A sprite Y of 208 means "don't scan the list any further".
|
||||||
if(mode_timing_.allow_sprite_terminator && sprite_position == 208) {
|
if(mode_timing_.allow_sprite_terminator && sprite_position == mode_timing_.sprite_terminator) {
|
||||||
buffer.sprites_stopped = true;
|
buffer.sprites_stopped = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -191,11 +191,27 @@ void TMS9918::run_for(const HalfCycles cycles) {
|
|||||||
// ---------------------------------------
|
// ---------------------------------------
|
||||||
// Latch scrolling position, if necessary.
|
// Latch scrolling position, if necessary.
|
||||||
// ---------------------------------------
|
// ---------------------------------------
|
||||||
if(write_pointer_.column < 61 && end_column >= 61) {
|
if(is_sega_vdp(personality_)) {
|
||||||
if(!write_pointer_.row) {
|
if(write_pointer_.column < 61 && end_column >= 61) {
|
||||||
master_system_.latched_vertical_scroll = master_system_.vertical_scroll;
|
if(!write_pointer_.row) {
|
||||||
|
master_system_.latched_vertical_scroll = master_system_.vertical_scroll;
|
||||||
|
|
||||||
|
if(master_system_.mode4_enable) {
|
||||||
|
mode_timing_.pixel_lines = 192;
|
||||||
|
if(mode2_enable_ && mode1_enable_) mode_timing_.pixel_lines = 224;
|
||||||
|
if(mode2_enable_ && mode3_enable_) mode_timing_.pixel_lines = 240;
|
||||||
|
|
||||||
|
mode_timing_.sprite_terminator = 0xd0;
|
||||||
|
if(mode_timing_.pixel_lines != 192) {
|
||||||
|
mode_timing_.sprite_terminator = 0xf0;
|
||||||
|
}
|
||||||
|
mode_timing_.first_vsync_line = (mode_timing_.total_lines + mode_timing_.pixel_lines) >> 1;
|
||||||
|
|
||||||
|
mode_timing_.end_of_frame_interrupt_position.row = mode_timing_.pixel_lines + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line_buffer.latched_horizontal_scroll = master_system_.horizontal_scroll;
|
||||||
}
|
}
|
||||||
line_buffer.latched_horizontal_scroll = master_system_.horizontal_scroll;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,9 +155,10 @@ class Base {
|
|||||||
} end_of_frame_interrupt_position;
|
} end_of_frame_interrupt_position;
|
||||||
int line_interrupt_position = -1;
|
int line_interrupt_position = -1;
|
||||||
|
|
||||||
// Enables or disabled the recognition of 0xd0 as a sprite
|
// Enables or disabled the recognition of the sprite
|
||||||
// list terminator.
|
// list terminator, and sets the terminator value.
|
||||||
bool allow_sprite_terminator = true;
|
bool allow_sprite_terminator = true;
|
||||||
|
uint8_t sprite_terminator = 0xd0;
|
||||||
} mode_timing_;
|
} mode_timing_;
|
||||||
|
|
||||||
uint8_t line_interrupt_target = 0xff;
|
uint8_t line_interrupt_target = 0xff;
|
||||||
@ -279,9 +280,6 @@ class Base {
|
|||||||
|
|
||||||
if(is_sega_vdp(personality_) && master_system_.mode4_enable) {
|
if(is_sega_vdp(personality_) && master_system_.mode4_enable) {
|
||||||
screen_mode_ = ScreenMode::SMSMode4;
|
screen_mode_ = ScreenMode::SMSMode4;
|
||||||
mode_timing_.pixel_lines = 192;
|
|
||||||
if(mode2_enable_ && mode1_enable_) mode_timing_.pixel_lines = 224;
|
|
||||||
if(mode2_enable_ && mode3_enable_) mode_timing_.pixel_lines = 240;
|
|
||||||
mode_timing_.maximum_visible_sprites = 8;
|
mode_timing_.maximum_visible_sprites = 8;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -646,12 +644,12 @@ class Base {
|
|||||||
#define sprite_fetch(sprite) {\
|
#define sprite_fetch(sprite) {\
|
||||||
line_buffer.active_sprites[sprite].x = \
|
line_buffer.active_sprites[sprite].x = \
|
||||||
ram_[\
|
ram_[\
|
||||||
sprite_attribute_table_address_ & size_t(0x3f80 | (line_buffer.active_sprites[sprite].index << 1))\
|
sprite_attribute_table_address & size_t(0x3f80 | (line_buffer.active_sprites[sprite].index << 1))\
|
||||||
] - (master_system_.shift_sprites_8px_left ? 8 : 0); \
|
] - (master_system_.shift_sprites_8px_left ? 8 : 0); \
|
||||||
const uint8_t name = ram_[\
|
const uint8_t name = ram_[\
|
||||||
sprite_attribute_table_address_ & size_t(0x3f81 | (line_buffer.active_sprites[sprite].index << 1))\
|
sprite_attribute_table_address & size_t(0x3f81 | (line_buffer.active_sprites[sprite].index << 1))\
|
||||||
] & (sprites_16x16_ ? ~1 : ~0);\
|
] & (sprites_16x16_ ? ~1 : ~0);\
|
||||||
const size_t graphic_location = sprite_generator_table_address_ & size_t(0x2000 | (name << 5) | (line_buffer.active_sprites[sprite].row << 2)); \
|
const size_t graphic_location = 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[0] = ram_[graphic_location]; \
|
||||||
line_buffer.active_sprites[sprite].image[1] = ram_[graphic_location+1]; \
|
line_buffer.active_sprites[sprite].image[1] = ram_[graphic_location+1]; \
|
||||||
line_buffer.active_sprites[sprite].image[2] = ram_[graphic_location+2]; \
|
line_buffer.active_sprites[sprite].image[2] = ram_[graphic_location+2]; \
|
||||||
@ -670,8 +668,8 @@ class Base {
|
|||||||
|
|
||||||
#define sprite_y_read(location, sprite) \
|
#define sprite_y_read(location, sprite) \
|
||||||
slot(location): \
|
slot(location): \
|
||||||
posit_sprite(sprite_selection_buffer, sprite, ram_[sprite_attribute_table_address_ & ((sprite) | 0x3f00)], write_pointer_.row); \
|
posit_sprite(sprite_selection_buffer, sprite, ram_[sprite_attribute_table_address & ((sprite) | 0x3f00)], write_pointer_.row); \
|
||||||
posit_sprite(sprite_selection_buffer, sprite+1, ram_[sprite_attribute_table_address_ & ((sprite + 1) | 0x3f00)], write_pointer_.row); \
|
posit_sprite(sprite_selection_buffer, sprite+1, ram_[sprite_attribute_table_address & ((sprite + 1) | 0x3f00)], write_pointer_.row); \
|
||||||
|
|
||||||
#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;\
|
||||||
@ -717,20 +715,27 @@ class Base {
|
|||||||
LineBuffer &sprite_selection_buffer = line_buffers_[(write_pointer_.row + 1) % mode_timing_.total_lines];
|
LineBuffer &sprite_selection_buffer = line_buffers_[(write_pointer_.row + 1) % mode_timing_.total_lines];
|
||||||
const int horizontal_offset = (write_pointer_.row >= 16 || !master_system_.horizontal_scroll_lock) ? (line_buffer.latched_horizontal_scroll >> 3) : 0;
|
const int horizontal_offset = (write_pointer_.row >= 16 || !master_system_.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 = pattern_name_address_ | (is_tall_mode ? 0xc00 : 0);
|
||||||
|
const size_t pattern_name_offset = is_tall_mode ? 0x100 : 0;
|
||||||
|
const size_t sprite_attribute_table_address = sprite_attribute_table_address_ | (is_tall_mode ? 0x80 : 0);
|
||||||
|
const size_t sprite_generator_table_address = sprite_generator_table_address_ | (is_tall_mode ? 0x1800 : 0);
|
||||||
|
|
||||||
// Determine row info for the screen both (i) if vertical scrolling is applied; and (ii) if it isn't.
|
// 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.
|
// The programmer can opt out of applying vertical scrolling to the right-hand portion of the display.
|
||||||
const int scrolled_row = (write_pointer_.row + master_system_.latched_vertical_scroll) % 224;
|
const int scrolled_row = (write_pointer_.row + master_system_.latched_vertical_scroll) % (is_tall_mode ? 256 : 224);
|
||||||
struct RowInfo {
|
struct RowInfo {
|
||||||
size_t pattern_address_base;
|
size_t pattern_address_base;
|
||||||
size_t sub_row[2];
|
size_t sub_row[2];
|
||||||
};
|
};
|
||||||
const RowInfo scrolled_row_info = {
|
const RowInfo scrolled_row_info = {
|
||||||
pattern_name_address_ & static_cast<size_t>(((scrolled_row & ~7) << 3) | 0x3800),
|
pattern_name_address & size_t(((scrolled_row & ~7) << 3) | 0x3800) - pattern_name_offset,
|
||||||
{static_cast<size_t>((scrolled_row & 7) << 2), 28 ^ static_cast<size_t>((scrolled_row & 7) << 2)}
|
{static_cast<size_t>((scrolled_row & 7) << 2), 28 ^ static_cast<size_t>((scrolled_row & 7) << 2)}
|
||||||
};
|
};
|
||||||
RowInfo row_info;
|
RowInfo row_info;
|
||||||
if(master_system_.vertical_scroll_lock) {
|
if(master_system_.vertical_scroll_lock) {
|
||||||
row_info.pattern_address_base = pattern_name_address_ & static_cast<size_t>(((write_pointer_.row & ~7) << 3) | 0x3800);
|
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[0] = size_t((write_pointer_.row & 7) << 2);
|
||||||
row_info.sub_row[1] = 28 ^ size_t((write_pointer_.row & 7) << 2);
|
row_info.sub_row[1] = 28 ^ size_t((write_pointer_.row & 7) << 2);
|
||||||
} else row_info = scrolled_row_info;
|
} else row_info = scrolled_row_info;
|
||||||
|
Loading…
Reference in New Issue
Block a user