From f7e211c2456331fba7a12aa5db232dfd4beeafc4 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 28 Sep 2018 20:39:14 -0400 Subject: [PATCH] Makes first attempt to put something vaguely like the Master System tile map on screen. --- Components/9918/9918.cpp | 30 +++++++++-- Components/9918/Implementation/9918Base.hpp | 58 ++++++++++++++------- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/Components/9918/9918.cpp b/Components/9918/9918.cpp index 4b353844d..157250239 100644 --- a/Components/9918/9918.cpp +++ b/Components/9918/9918.cpp @@ -211,6 +211,9 @@ void TMS9918::run_for(const HalfCycles cycles) { if(queued_access_ != MemoryAccess::None) { int time_until_access_slot = 0; switch(line_mode_) { + case LineMode::SMS: + time_until_access_slot = 0; // TODO. + break; case LineMode::Refresh: if(column_ < 53 || column_ >= 307) time_until_access_slot = column_&1; else time_until_access_slot = 3 - ((column_ - 53)&3); @@ -271,7 +274,7 @@ void TMS9918::run_for(const HalfCycles cycles) { case LineMode::Text: access_pointer_ = std::min(30, access_slot); if(access_pointer_ >= 30 && access_pointer_ < 150) { - const int row_base = pattern_name_address_ + static_cast(row_ >> 3) * 40; + const size_t row_base = pattern_name_address_ + static_cast(row_ >> 3) * 40; const int end = std::min(150, access_slot); // Pattern names are collected every third window starting from window 30. @@ -430,6 +433,20 @@ void TMS9918::run_for(const HalfCycles cycles) { switch(line_mode_) { default: break; + case LineMode::SMS: { + if(pixel_target_) { + const int pixels_left = pixels_end - output_column_; + int pixel_location = output_column_ - first_pixel_column_; + for(int c = 0; c < pixels_left; ++c) { + pixel_target_[c] = *(uint32_t *)master_system_.tile_graphics[pixel_location >> 8]; + } + pixel_target_ += pixels_left; + } + + output_column_ = pixels_end; + } + break; + case LineMode::Text: { if(pixel_target_) { const uint32_t colours[2] = { palette[background_colour_], palette[text_colour_] }; @@ -629,6 +646,9 @@ void TMS9918::run_for(const HalfCycles cycles) { break; case ScreenMode::SMSMode4: line_mode_ = LineMode::SMS; + master_system_.next_column = 0; + first_pixel_column_ = 63; + first_right_border_column_ = 319; break; default: line_mode_ = LineMode::Character; @@ -672,10 +692,14 @@ void TMS9918::set_register(int address, uint8_t value) { if(value & 0x80) { switch(personality_) { default: - value &= 7; + value &= 0x7; break; case TI::TMS::SMSVDP: - value &= 0x7f; + if(value & 0x40) { + // TODO: CRAM. + return; + } + value &= 0xf; break; } diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 79ed889d9..905289ff5 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -118,7 +118,14 @@ class Base { bool shift_sprites_8px_left = false; bool mode4_enable = false; - uint8_t colour_ram_[32]; + uint8_t colour_ram[32]; + + struct { + size_t offset; + uint8_t flags; + } names[32]; + uint8_t tile_graphics[32][4]; + size_t next_column = 0; } master_system_; enum class ScreenMode { @@ -208,23 +215,36 @@ class Base { - sprite n and n+1, y position */ -#define background_render_block(location) \ - slot(location): \ +#define fetch_tile_name(column) {\ + size_t address = pattern_address_base + ((column) << 1); \ + master_system_.names[column].flags = ram_[address+1]; \ + master_system_.names[column].offset = static_cast((master_system_.names[column].flags&1 | ram_[address]) << 5) + sub_row; \ + } + +#define fetch_tile(column) {\ + master_system_.tile_graphics[column][0] = ram_[master_system_.names[column].offset]; \ + master_system_.tile_graphics[column][1] = ram_[master_system_.names[column].offset+1]; \ + master_system_.tile_graphics[column][2] = ram_[master_system_.names[column].offset+2]; \ + master_system_.tile_graphics[column][3] = ram_[master_system_.names[column].offset+3]; \ + } + +#define background_render_block(location, column) \ + slot(location): fetch_tile_name(column) \ external_slot(location+1); \ slot(location+2): \ - slot(location+3): \ - slot(location+4): \ + slot(location+3): fetch_tile(column) \ + slot(location+4): fetch_tile_name(column+1) \ sprite_y_read(location+5); \ slot(location+6): \ - slot(location+7): \ - slot(location+8): \ + slot(location+7): fetch_tile(column+1) \ + slot(location+8): fetch_tile_name(column+2) \ sprite_y_read(location+9); \ slot(location+10): \ - slot(location+11): \ - slot(location+12): \ + slot(location+11): fetch_tile(column+2) \ + slot(location+12): fetch_tile_name(column+3) \ sprite_y_read(location+13); \ slot(location+14): \ - slot(location+15): + slot(location+15): fetch_tile(column+3) /* TODO: background_render_block should fetch: @@ -245,6 +265,8 @@ class Base { - column n+3, tile graphic first word - column n+3, tile graphic second word */ + const size_t pattern_address_base = (pattern_name_address_ | size_t(0x3ff)) & static_cast(((row_ & ~7) << 6) | 0x3800); + const size_t sub_row = static_cast((row_ & 7) << 2); switch(start) { default: @@ -267,14 +289,14 @@ class Base { sprite_y_read(36); sprite_y_read(37); sprite_y_read(38); - background_render_block(39); - background_render_block(55); - background_render_block(71); - background_render_block(87); - background_render_block(103); - background_render_block(119); - background_render_block(135); - background_render_block(151); + background_render_block(39, 0); + background_render_block(55, 4); + background_render_block(71, 8); + background_render_block(87, 12); + background_render_block(103, 16); + background_render_block(119, 20); + background_render_block(135, 24); + background_render_block(151, 28); external_slot(167); external_slot(168); external_slot(169);