From 53d73e817f4031e274680a5ba92544df78744d4d Mon Sep 17 00:00:00 2001 From: holub Date: Sat, 11 Jan 2025 05:21:45 -0500 Subject: sinclair/tsconf.cpp Improved tiles decoding (#13145) * sinclair/tsconf.cpp Improved tiles decoding * rm palette hack * replace math with bitswap * simplify * restore tile cache --- src/mame/sinclair/tsconf.cpp | 36 ++++++++++-------------- src/mame/sinclair/tsconf.h | 6 +++- src/mame/sinclair/tsconf_m.cpp | 63 +++++++++++++++++++++++++++--------------- 3 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/mame/sinclair/tsconf.cpp b/src/mame/sinclair/tsconf.cpp index 2c914c2a445..5df2573f830 100644 --- a/src/mame/sinclair/tsconf.cpp +++ b/src/mame/sinclair/tsconf.cpp @@ -56,14 +56,13 @@ TILE_GET_INFO_MEMBER(tsconf_state::get_tile_info_txt) template TILE_GET_INFO_MEMBER(tsconf_state::get_tile_info_16c) { - u8 col_offset = (tile_index % tilemap.cols() + Layer * 64) << 1; - u16 row_offset = (tile_index / tilemap.cols() * 64 * 2) << 1; + const u8 col_offset = (tile_index & 0x03f) << 1; + const u16 row_offset = (tile_index & 0xfc0) << 2; - u8 *tile_info_addr = &m_ram->pointer()[(m_regs[T_MAP_PAGE] << 14) + row_offset + col_offset]; + u8 *tile_info_addr = &m_ram->pointer()[(m_regs[T_MAP_PAGE] << 14) | row_offset | (Layer ? 0x80 : 0x00) | col_offset]; u8 hi = tile_info_addr[1]; - u32 /*u16*/ tile = ((u16(hi) & 0x0f) << 8) | tile_info_addr[0]; - tile = tile / tilemap.cols() * 64 * 8 + (tile % tilemap.cols()); // same as: tmp_tile_oversized_to_code() + u16 tile = ((u16(hi) & 0x0f) << 8) | tile_info_addr[0]; u8 pal = (BIT(m_regs[PAL_SEL], 4 + Layer * 2, 2) << 2) | BIT(hi, 4, 2); tileinfo.set(TM_TILES0 + Layer, tile, pal, TILE_FLIPYX(BIT(hi, 6, 2))); tileinfo.category = tile == 0 ? 2 : 1; @@ -139,23 +138,11 @@ static const gfx_layout tsconf_charlayout = 8 * 8 }; -static const gfx_layout tsconf_tile_16cpp_layout = -{ - 8, - 8, - 64 * 64 * 8, - 4, - {STEP4(0, 1)}, - {STEP8(0, 4)}, - {STEP8(0, 256 * 8)}, // Much more tiles when needed. Because tiles are in RAW format but we don't know region properties. - 8 * 4 -}; - static GFXDECODE_START(gfx_tsconf) GFXDECODE_ENTRY("maincpu", 0, tsconf_charlayout, 0xf7, 1) // TM_TS_CHAR : TXT - GFXDECODE_ENTRY("maincpu", 0, tsconf_tile_16cpp_layout, 0, 16) // TM_TILES0 : T0 16cpp - GFXDECODE_ENTRY("maincpu", 0, tsconf_tile_16cpp_layout, 0, 16) // TM_TILES1 : T1 16cpp - GFXDECODE_ENTRY("maincpu", 0, tsconf_tile_16cpp_layout, 0, 16) // TM_SPRITES : Sprites 16cpp + GFXDECODE_RAM("tiles0_raw", 0, gfx_8x8x8_raw, 0, 16) // TM_TILES0 : T0 16cpp + GFXDECODE_RAM("tiles1_raw", 0, gfx_8x8x8_raw, 0, 16) // TM_TILES1 : T1 16cpp + GFXDECODE_RAM("sprites_raw", 0, gfx_8x8x8_raw, 0, 16) // TM_SPRITES : Sprites 16cpp GFXDECODE_ENTRY("maincpu", 0x1fd00, spectrum_charlayout, 0xf7, 1) // TM_ZX_CHAR GFXDECODE_END @@ -168,9 +155,13 @@ void tsconf_state::video_start() m_ts_tilemap[TM_TILES0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_16c<0>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_ts_tilemap[TM_TILES0]->set_transparent_pen(0); + m_gfxdecode->gfx(TM_TILES0)->set_granularity(16); m_ts_tilemap[TM_TILES1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_16c<1>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_ts_tilemap[TM_TILES1]->set_transparent_pen(0); + m_gfxdecode->gfx(TM_TILES1)->set_granularity(16); + + m_gfxdecode->gfx(TM_SPRITES)->set_granularity(16); m_frame_irq_timer = timer_alloc(FUNC(tsconf_state::irq_frame), this); m_scanline_irq_timer = timer_alloc(FUNC(tsconf_state::irq_scanline), this); @@ -247,6 +238,9 @@ void tsconf_state::device_post_load() { spectrum_128_state::device_post_load(); m_sprites_cache.clear(); + copy_tiles_to_raw(m_ram->pointer() + ((m_regs[SG_PAGE] & 0xf8) << 14), m_sprites_raw.target()); + copy_tiles_to_raw(m_ram->pointer() + ((m_regs[T0_G_PAGE] & 0xf8) << 14), m_sprites_raw.target()); + copy_tiles_to_raw(m_ram->pointer() + ((m_regs[T1_G_PAGE] & 0xf8) << 14), m_sprites_raw.target()); } INPUT_PORTS_START( tsconf ) @@ -323,7 +317,7 @@ void tsconf_state::tsconf(machine_config &config) DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "mono", 0.75);; - PALETTE(config, "palette", FUNC(tsconf_state::tsconf_palette), 256); + PALETTE(config, "palette", palette_device::BLACK, 256); m_screen->set_raw(14_MHz_XTAL / 2, 448, with_hblank(0), 448, 320, with_vblank(0), 320); m_screen->set_screen_update(FUNC(tsconf_state::screen_update)); m_screen->set_no_palette(); diff --git a/src/mame/sinclair/tsconf.h b/src/mame/sinclair/tsconf.h index 37dfe65b808..46d627574f2 100644 --- a/src/mame/sinclair/tsconf.h +++ b/src/mame/sinclair/tsconf.h @@ -29,6 +29,8 @@ public: tsconf_state(const machine_config &mconfig, device_type type, const char *tag) : spectrum_128_state(mconfig, type, tag) , m_bank0_rom(*this, "bank0_rom") + , m_tiles_raw(*this, "tiles%u_raw", 0U, 64U * 64 * 8 * 8, ENDIANNESS_LITTLE) + , m_sprites_raw(*this, "sprites_raw", 64U * 64 * 8 * 8, ENDIANNESS_LITTLE) , m_keyboard(*this, "pc_keyboard") , m_io_mouse(*this, "mouse_input%u", 1U) , m_beta(*this, BETA_DISK_TAG) @@ -170,8 +172,8 @@ private: void tsconf_draw_txt(bitmap_rgb32 &bitmap, const rectangle &cliprect); void tsconf_draw_gfx(bitmap_rgb32 &bitmap, const rectangle &cliprect); void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void tsconf_palette(palette_device &palette) const; void tsconf_update_video_mode(); + void copy_tiles_to_raw(const u8 *tiles_src, u8 *raw_target); u8 tsconf_port_xx1f_r(offs_t offset); void tsconf_port_7ffd_w(u8 data); @@ -214,6 +216,8 @@ private: memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program; memory_view m_bank0_rom; + memory_share_array_creator m_tiles_raw; + memory_share_creator m_sprites_raw; required_device m_keyboard; required_ioport_array<3> m_io_mouse; diff --git a/src/mame/sinclair/tsconf_m.cpp b/src/mame/sinclair/tsconf_m.cpp index 92f9678fd17..43ee709668f 100644 --- a/src/mame/sinclair/tsconf_m.cpp +++ b/src/mame/sinclair/tsconf_m.cpp @@ -29,11 +29,6 @@ enum v_mode : u8 VM_TXT }; -static constexpr u32 tmp_tile_oversized_to_code(u16 code) -{ - return code / 64 * 64 * 8 + (code % 64); -} - // https://github.com/tslabs/zx-evo/blob/master/pentevo/vdac/vdac1/cpld/top.v static constexpr u8 pwm_to_rgb[32] = { 0, 10, 21, 31, 42, 53, 63, 74, @@ -54,12 +49,6 @@ rectangle tsconf_state::get_screen_area() return info; } -void tsconf_state::tsconf_palette(palette_device &palette) const -{ - rgb_t colors[256] = {0}; - palette.set_pen_colors(0, colors); -} - void tsconf_state::tsconf_update_bank0() { u8 page0 = m_regs[PAGE0]; @@ -364,7 +353,7 @@ void tsconf_state::draw_sprites(screen_device &screen_d, bitmap_rgb32 &bitmap, c for (auto spr = m_sprites_cache.rbegin(); spr != m_sprites_cache.rend(); ++spr) { m_gfxdecode->gfx(TM_SPRITES)->prio_transpen(bitmap, cliprect, - tmp_tile_oversized_to_code(spr->code), spr->color, spr->flipx, spr->flipy, spr->destx, spr->desty, + spr->code, spr->color, spr->flipx, spr->flipy, spr->destx, spr->desty, screen_d.priority(), spr->pmask, 0); } @@ -395,6 +384,11 @@ void tsconf_state::ram_bank_write(u8 bank, offs_t offset, u8 data) ram_page_write(m_regs[PAGE0 + bank], offset, data); } +static int tiles_offset_to_raw(int t_offset) +{ + return bitswap<17>(t_offset, 16, 15, 14, 13, 12, 11, 7, 6, 5, 4, 3, 2, 10, 9, 8, 1, 0) << 1; +} + void tsconf_state::ram_page_write(u8 page, offs_t offset, u8 data) { u32 ram_addr = PAGE4K(page) + offset; @@ -405,15 +399,21 @@ void tsconf_state::ram_page_write(u8 page, offs_t offset, u8 data) } else { - if (ram_addr >= PAGE4K(m_regs[T0_G_PAGE] & 0xf8) && ram_addr < PAGE4K((m_regs[T0_G_PAGE] & 0xf8) + 8)) + const int t0_offset = ram_addr - PAGE4K(m_regs[T0_G_PAGE] & 0xf8); + if ((t0_offset >= 0) && (t0_offset < PAGE4K(8))) { - m_gfxdecode->gfx(TM_TILES0)->mark_all_dirty(); + const int raw_offset = tiles_offset_to_raw(t0_offset); + m_tiles_raw[0][raw_offset] = data >> 4; + m_tiles_raw[0][raw_offset + 1] = data & 0x0f; m_ts_tilemap[TM_TILES0]->mark_all_dirty(); } - if (ram_addr >= PAGE4K(m_regs[T1_G_PAGE] & 0xf8) && ram_addr < PAGE4K((m_regs[T1_G_PAGE] & 0xf8) + 8)) + const int t1_offset = ram_addr - PAGE4K(m_regs[T1_G_PAGE] & 0xf8); + if ((t1_offset >= 0) && (t1_offset < PAGE4K(8))) { - m_gfxdecode->gfx(TM_TILES1)->mark_all_dirty(); + const int raw_offset = tiles_offset_to_raw(t1_offset); + m_tiles_raw[1][raw_offset] = data >> 4; + m_tiles_raw[1][raw_offset + 1] = data & 0x0f; m_ts_tilemap[TM_TILES1]->mark_all_dirty(); } } @@ -424,8 +424,13 @@ void tsconf_state::ram_page_write(u8 page, offs_t offset, u8 data) if (ram_addr >= PAGE4K(m_regs[m_regs[V_PAGE] ^ 0x01]) && ram_addr < PAGE4K(m_regs[m_regs[V_PAGE] ^ 0x01] + 1)) m_gfxdecode->gfx(TM_TS_CHAR)->mark_all_dirty(); - if (ram_addr >= PAGE4K(m_regs[SG_PAGE] & 0xf8) && ram_addr < PAGE4K((m_regs[SG_PAGE] & 0xf8) + 8)) - m_gfxdecode->gfx(TM_SPRITES)->mark_all_dirty(); + const int spr_offset = ram_addr - PAGE4K(m_regs[SG_PAGE] & 0xf8); + if ((spr_offset >= 0) && (spr_offset < PAGE4K(8))) + { + const int raw_offset = tiles_offset_to_raw(spr_offset); + m_sprites_raw[raw_offset] = data >> 4; + m_sprites_raw[raw_offset + 1] = data & 0x0f; + } m_ram->pointer()[ram_addr] = data; } @@ -438,7 +443,7 @@ u16 tsconf_state::ram_read16(offs_t offset) void tsconf_state::ram_write16(offs_t offset, u16 data) { ram_page_write(0, offset & ~offs_t(1), data >> 8); - m_ram->pointer()[offset | 1] = data & 0xff; + ram_page_write(0, offset | 1, data & 0xff); } u16 tsconf_state::spi_read16() @@ -534,6 +539,20 @@ u8 tsconf_state::tsconf_port_xxaf_r(offs_t port) return data; } +void tsconf_state::copy_tiles_to_raw(const u8 *tiles_src, u8 *raw_target) +{ + for(u32 ln = 0; ln < PAGE4K(8); ln += 4) + { + int targ = tiles_offset_to_raw(ln); + for (u8 x = 0; x < 4; ++x) + { + const u8 data = tiles_src[ln + x]; + raw_target[targ + (x << 1)] = data >> 4; + raw_target[targ + (x << 1) + 1] = data & 0x0f; + } + } +} + void tsconf_state::tsconf_port_xxaf_w(offs_t port, u8 data) { u8 nreg = port >> 8; @@ -666,7 +685,7 @@ void tsconf_state::tsconf_port_xxaf_w(offs_t port, u8 data) break; case SG_PAGE: - m_gfxdecode->gfx(TM_SPRITES)->set_source(m_ram->pointer() + PAGE4K(data & 0xf8)); + copy_tiles_to_raw(m_ram->pointer() + PAGE4K(data & 0xf8), m_sprites_raw.target()); break; case SYS_CONFIG: @@ -916,12 +935,12 @@ TIMER_CALLBACK_MEMBER(tsconf_state::irq_scanline) break; case T0_G_PAGE: - m_gfxdecode->gfx(TM_TILES0)->set_source(m_ram->pointer() + PAGE4K(val & 0xf8)); + copy_tiles_to_raw(m_ram->pointer() + PAGE4K(val & 0xf8), m_tiles_raw[0].target()); m_ts_tilemap[TM_TILES0]->mark_all_dirty(); break; case T1_G_PAGE: - m_gfxdecode->gfx(TM_TILES1)->set_source(m_ram->pointer() + PAGE4K(val & 0xf8)); + copy_tiles_to_raw(m_ram->pointer() + PAGE4K(val & 0xf8), m_tiles_raw[1].target()); m_ts_tilemap[TM_TILES1]->mark_all_dirty(); break; -- cgit v1.2.3