mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
sinclair/tsconf.cpp Improved tiles decoding (#13145)
* sinclair/tsconf.cpp Improved tiles decoding * rm palette hack * replace math with bitswap * simplify * restore tile cache
This commit is contained in:
parent
6d3d9c03a8
commit
53d73e817f
@ -56,14 +56,13 @@ TILE_GET_INFO_MEMBER(tsconf_state::get_tile_info_txt)
|
||||
template <u8 Layer>
|
||||
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();
|
||||
|
@ -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<u8, 2> m_tiles_raw;
|
||||
memory_share_creator<u8> m_sprites_raw;
|
||||
|
||||
required_device<at_keyboard_device> m_keyboard;
|
||||
required_ioport_array<3> m_io_mouse;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user