1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-10-25 09:27:01 +00:00

Attempts to get at least as far as picking visible sprite indices.

This commit is contained in:
Thomas Harte
2018-10-06 19:27:19 -04:00
parent 76f3b9f6ba
commit e6510dc87b
2 changed files with 55 additions and 46 deletions

View File

@@ -16,7 +16,7 @@ using namespace TI::TMS;
namespace { namespace {
const uint8_t StatusInterrupt = 0x80; const uint8_t StatusInterrupt = 0x80;
const uint8_t StatusFifthSprite = 0x40; const uint8_t StatusSpriteOverflow = 0x40;
const int StatusSpriteCollisionShift = 5; const int StatusSpriteCollisionShift = 5;
const uint8_t StatusSpriteCollision = 0x20; const uint8_t StatusSpriteCollision = 0x20;
@@ -91,33 +91,38 @@ Outputs::CRT::CRT *TMS9918::get_crt() {
return crt_.get(); return crt_.get();
} }
void Base::test_sprite(int sprite_number, int screen_row) { void Base::reset_sprite_collection() {
/* if(!(status_ & StatusFifthSprite)) { sprite_set_.sprites_stopped = false;
sprite_set_.fetched_sprite_slot = sprite_set_.active_sprite_slot;
sprite_set_.active_sprite_slot = 0;
}
void Base::posit_sprite(int sprite_number, int sprite_position, int screen_row) {
if(!(status_ & StatusSpriteOverflow)) {
status_ = static_cast<uint8_t>((status_ & ~31) | sprite_number); status_ = static_cast<uint8_t>((status_ & ~31) | sprite_number);
} }
if(sprites_stopped_) if(sprite_set_.sprites_stopped)
return; return;
const int sprite_position = ram_[sprite_attribute_table_address_ + static_cast<size_t>(sprite_number << 2)]; // const int sprite_position = ram_[sprite_attribute_table_address_ + static_cast<size_t>(sprite_number << 2)];
// 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(sprite_position == 208) { if(mode_timing_.allow_sprite_terminator && sprite_position == 208) {
sprites_stopped_ = true; sprite_set_.sprites_stopped = true;
return; return;
} }
const int sprite_row = (screen_row - sprite_position)&255; const int sprite_row = (screen_row - sprite_position)&255;
if(sprite_row < 0 || sprite_row >= sprite_height_) return; if(sprite_row < 0 || sprite_row >= sprite_height_) return;
const int active_sprite_slot = sprite_sets_[active_sprite_set_].active_sprite_slot; if(sprite_set_.active_sprite_slot == mode_timing_.maximum_visible_sprites) {
if(active_sprite_slot == 4) { status_ |= StatusSpriteOverflow;
status_ |= StatusFifthSprite;
return; return;
} }
SpriteSet::ActiveSprite &sprite = sprite_sets_[active_sprite_set_].active_sprites[active_sprite_slot]; SpriteSet::ActiveSprite &sprite = sprite_set_.active_sprites[sprite_set_.active_sprite_slot];
sprite.index = sprite_number; sprite.index = sprite_number;
sprite.row = sprite_row >> (sprites_magnified_ ? 1 : 0); sprite.row = sprite_row >> (sprites_magnified_ ? 1 : 0);
sprite_sets_[active_sprite_set_].active_sprite_slot++;*/ ++sprite_set_.active_sprite_slot;
} }
void Base::get_sprite_contents(int field, int cycles_left, int screen_row) { void Base::get_sprite_contents(int field, int cycles_left, int screen_row) {
@@ -254,7 +259,7 @@ void TMS9918::run_for(const HalfCycles cycles) {
// Left border. // Left border.
intersect(73, mode_timing_.first_pixel_output_column, output_border(end - start)); intersect(73, mode_timing_.first_pixel_output_column, output_border(end - start));
// In pixel area: // Pixel region.
intersect( intersect(
mode_timing_.first_pixel_output_column, mode_timing_.first_pixel_output_column,
mode_timing_.next_border_column, mode_timing_.next_border_column,
@@ -629,7 +634,7 @@ uint8_t TMS9918::get_register(int address) {
// Reads from address 1 get the status register. // Reads from address 1 get the status register.
uint8_t result = status_; uint8_t result = status_;
status_ &= ~(StatusInterrupt | StatusFifthSprite | StatusSpriteCollision); status_ &= ~(StatusInterrupt | StatusSpriteOverflow | StatusSpriteCollision);
line_interrupt_pending_ = false; line_interrupt_pending_ = false;
return result; return result;
} }

View File

@@ -157,6 +157,8 @@ class Base {
// //
int end_of_frame_interrupt_position = 342; int end_of_frame_interrupt_position = 342;
int line_interrupt_position = -1; int line_interrupt_position = -1;
bool allow_sprite_terminator = true;
} mode_timing_; } mode_timing_;
uint8_t line_interrupt_target = 0; uint8_t line_interrupt_target = 0;
@@ -218,10 +220,12 @@ class Base {
} active_sprites[8]; } active_sprites[8];
int active_sprite_slot = 0; int active_sprite_slot = 0;
bool sprites_stopped_ = false; int fetched_sprite_slot = 0;
bool sprites_stopped = false;
} sprite_set_; } sprite_set_;
inline void test_sprite(int sprite_number, int screen_row); inline void reset_sprite_collection();
inline void posit_sprite(int sprite_number, int sprite_y, int screen_row);
inline void get_sprite_contents(int start, int cycles, int screen_row); inline void get_sprite_contents(int start, int cycles, int screen_row);
enum class ScreenMode { enum class ScreenMode {
@@ -273,7 +277,7 @@ class Base {
} }
void external_slot() { void do_external_slot() {
// TODO: write or read a value if one is queued and ready to read/write. // TODO: write or read a value if one is queued and ready to read/write.
// (and, later: update the command engine, if this is an MSX2). // (and, later: update the command engine, if this is an MSX2).
switch(queued_access_) { switch(queued_access_) {
@@ -303,7 +307,7 @@ class Base {
case n case n
#define external_slot(n) \ #define external_slot(n) \
slot(n): external_slot(); slot(n): do_external_slot();
#define external_slots_2(n) \ #define external_slots_2(n) \
external_slot(n); \ external_slot(n); \
@@ -596,13 +600,10 @@ class Base {
- sprite n+1, tile graphic second word - sprite n+1, tile graphic second word
*/ */
#define sprite_y_read(location) \ #define sprite_y_read(location, sprite) \
slot(location): slot(location): \
posit_sprite(sprite, ram_[sprite_attribute_table_address_ + sprite], row_); \
/* posit_sprite(sprite, ram_[sprite_attribute_table_address_ + sprite + 1], row_); \
TODO: sprite_y_read should fetch:
- sprite n and n+1, y position
*/
#define fetch_tile_name(column) {\ #define fetch_tile_name(column) {\
const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\ const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\
@@ -620,21 +621,21 @@ class Base {
master_system_.tile_graphics[column][3] = ram_[master_system_.names[column].offset+3]; \ master_system_.tile_graphics[column][3] = ram_[master_system_.names[column].offset+3]; \
} }
#define background_render_block(location, column) \ #define background_render_block(location, column, sprite) \
slot(location): fetch_tile_name(column) \ slot(location): fetch_tile_name(column) \
external_slot(location+1); \ external_slot(location+1); \
slot(location+2): \ slot(location+2): \
slot(location+3): fetch_tile(column) \ slot(location+3): fetch_tile(column) \
slot(location+4): fetch_tile_name(column+1) \ slot(location+4): fetch_tile_name(column+1) \
sprite_y_read(location+5); \ sprite_y_read(location+5, sprite); \
slot(location+6): \ slot(location+6): \
slot(location+7): fetch_tile(column+1) \ slot(location+7): fetch_tile(column+1) \
slot(location+8): fetch_tile_name(column+2) \ slot(location+8): fetch_tile_name(column+2) \
sprite_y_read(location+9); \ sprite_y_read(location+9, sprite+2); \
slot(location+10): \ slot(location+10): \
slot(location+11): fetch_tile(column+2) \ slot(location+11): fetch_tile(column+2) \
slot(location+12): fetch_tile_name(column+3) \ slot(location+12): fetch_tile_name(column+3) \
sprite_y_read(location+13); \ sprite_y_read(location+13, sprite+4); \
slot(location+14): \ slot(location+14): \
slot(location+15): fetch_tile(column+3) slot(location+15): fetch_tile(column+3)
@@ -664,25 +665,28 @@ class Base {
sprite_fetch_block(21, 4); sprite_fetch_block(21, 4);
sprite_fetch_block(27, 6); sprite_fetch_block(27, 6);
external_slots_2(33); slot(33):
reset_sprite_collection();
do_external_slot();
external_slot(34);
sprite_y_read(35); sprite_y_read(35, 0);
sprite_y_read(36); sprite_y_read(36, 2);
sprite_y_read(37); sprite_y_read(37, 4);
sprite_y_read(38); sprite_y_read(38, 6);
sprite_y_read(39); sprite_y_read(39, 8);
sprite_y_read(40); sprite_y_read(40, 10);
sprite_y_read(41); sprite_y_read(41, 12);
sprite_y_read(42); sprite_y_read(42, 14);
background_render_block(43, 0); background_render_block(43, 0, 16);
background_render_block(59, 4); background_render_block(59, 4, 22);
background_render_block(75, 8); background_render_block(75, 8, 28);
background_render_block(91, 12); background_render_block(91, 12, 34);
background_render_block(107, 16); background_render_block(107, 16, 40);
background_render_block(123, 20); background_render_block(123, 20, 46);
background_render_block(139, 24); // TODO: this and the next one should ignore master_system_.vertical_scroll. background_render_block(139, 24, 52); // TODO: this and the next one should ignore master_system_.vertical_scroll.
background_render_block(156, 28); background_render_block(156, 28, 58);
return; return;
} }