x1_012.cpp: restrict partial updates in the seta tilemap chip to caliber 50, it breaks too many other places due to unmasking some bad timing problems in the drivers. (#10654)

This commit is contained in:
David Haywood 2022-12-10 10:02:23 +00:00 committed by GitHub
parent df20290ed5
commit a8c82d8a86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 3 deletions

View File

@ -1822,7 +1822,7 @@ void downtown_state::calibr50_map(address_map &map)
map(0x500000, 0x500001).nopw(); // ?
map(0x600000, 0x600003).r(FUNC(downtown_state::seta_dsw_r)); // DSW
map(0x700000, 0x7003ff).ram().share("paletteram1"); // Palette
map(0x800000, 0x800005).w(m_layers[0], FUNC(x1_012_device::vctrl_w));// VRAM Ctrl
map(0x800000, 0x800005).w(FUNC(downtown_state::vram_layer0_vctrl_raster_trampoline_w));// VRAM Ctrl
map(0x900000, 0x903fff).ram().w(m_layers[0], FUNC(x1_012_device::vram_w)).share("layer1"); // VRAM
map(0x904000, 0x904fff).ram(); //
@ -8172,6 +8172,7 @@ void downtown_state::calibr50(machine_config &config)
screen.set_visarea(0*8, 48*8-1, 1*8, 31*8-1);
screen.set_screen_update(FUNC(downtown_state::screen_update_seta));
screen.set_palette(m_palette);
//screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
X1_012(config, m_layers[0], m_palette, gfx_downtown);
m_layers[0]->set_screen(m_screen);

View File

@ -165,6 +165,7 @@ protected:
void ipl1_ack_w(u16 data);
u16 ipl2_ack_r();
void ipl2_ack_w(u16 data);
void vram_layer0_vctrl_raster_trampoline_w(offs_t offset, u16 data, u16 mem_mask);
void uPD71054_update_timer(device_t *cpu, int no);
INTERRUPT_GEN_MEMBER(wrofaero_interrupt);
TIMER_CALLBACK_MEMBER(uPD71054_timer_callback);

View File

@ -624,3 +624,12 @@ u32 usclssic_state::screen_update_usclssic(screen_device &screen, bitmap_ind16 &
usclssic_set_pens();
return screen_update_seta_layers(screen, bitmap, cliprect);
}
void seta_state::vram_layer0_vctrl_raster_trampoline_w(offs_t offset, u16 data, u16 mem_mask)
{
// Used by calibr50 as VIDEO_UPDATE_SCANLINE is problematic due to devices/video/x1_001.cpp not being optimized
// for scanline drawing, so instead we use this trampoline on tilemap register writes. Also see notes in x1_012.cpp
// for why we can't just do this in vctrl_w.
m_screen->update_partial(m_screen->vpos());
m_layers[0]->vctrl_w(offset, data, mem_mask);
}

View File

@ -12,7 +12,6 @@
#include "emu.h"
#include "x1_012.h"
DEFINE_DEVICE_TYPE(X1_012, x1_012_device, "x1_012", "Seta X1-012 Tile Layer")
x1_012_device::x1_012_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@ -78,7 +77,26 @@ u16 x1_012_device::vctrl_r(offs_t offset, u16 mem_mask)
void x1_012_device::vctrl_w(offs_t offset, u16 data, u16 mem_mask)
{
m_screen->update_partial(m_screen->vpos()); // needed for calibr50 effect when entering underground area
// HACK:
// In reality all MAME drivers should work with VIDEO_UPDATE_SCANLINE, ie a partial update every single line.
// However timing problems in various drivers means that registers (both here for the tilemap chip, but also
// in the sprite chip) end up being written at the wrong time, causing corruption if partial updates are
// allowed at all. MAME's default behavior of only updating the entire screen at a single point masks this
// otherwise incorrect timing.
//
// This is especially noticeable in Zombie Raid, which even writes the horizontal scroll in the middle of the
// screen, meaning that we can't even cheat by only updating on that. Caliber 50 shows that the tilemap chip
// does read the scroll registers every scanline as it is needed for a raster effect when entering the
// underground area.
//
// In addition to Zombie Raid, Blandia (Athena stage) and Strike Gunner STG are also good cases to demonstrate
// the broken timing that comes to light once partial updates are allowed.
//
// For the time being, we simply use a trampoline in the seta.cpp driver for Caliber 50 _only_, rather than
// correctly reflecting current register values in all games.
// m_screen->update_partial(m_screen->vpos()); // causes breakage, see note above
// Select tilemap bank. Only one tilemap bank per layer is enabled.
if (offset == 2 && ACCESSING_BITS_0_7)