diff --git a/src/mame/machine/midwunit.c b/src/mame/machine/midwunit.c index 4cb9362565f..5a506062a2c 100644 --- a/src/mame/machine/midwunit.c +++ b/src/mame/machine/midwunit.c @@ -400,6 +400,33 @@ static void init_wunit_generic(void) /********************** Mortal Kombat 3 **********************/ +static UINT16 *umk3_palette; + +static WRITE16_HANDLER( umk3_palette_hack_w ) +{ + /* + UMK3 uses a circular buffer to hold pending palette changes; the buffer holds 17 entries + total, and the buffer is processed/cleared during the video interrupt. Most of the time, + 17 entries is enough. However, when characters are unlocked, or a number of characters are + being displayed, the circular buffer sometimes wraps, losing the first 17 palette changes. + + This bug manifests itself on a real PCB, but only rarely; whereas in MAME, it manifests + itself very frequently. This is due to the fact that the instruction timing for the TMS34010 + is optimistic and assumes that the instruction cache is always fully populated. Without + full cache level emulation of the chip, there is no hope of fixing this issue without a + hack. + + Thus, the hack. To slow down the CPU when it is adding palette entries to the list, we + install this write handler on the memory locations where the start/end circular buffer + pointers live. Each time they are written to, we penalize the main CPU a number of cycles. + Although not realistic, this is sufficient to reduce the frequency of incorrect colors + without significantly impacting the rest of the system. + */ + COMBINE_DATA(&umk3_palette[offset]); + activecpu_adjust_icount(-100); +/* printf("in=%04X%04X out=%04X%04X\n", umk3_palette[3], umk3_palette[2], umk3_palette[1], umk3_palette[0]); */ +} + static void init_mk3_common(void) { /* common init */ @@ -427,11 +454,13 @@ DRIVER_INIT( mk3r10 ) DRIVER_INIT( umk3 ) { init_mk3_common(); + umk3_palette = memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, 0x0106a060, 0x0106a09f, 0, 0, umk3_palette_hack_w); } DRIVER_INIT( umk3r11 ) { init_mk3_common(); + umk3_palette = memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, 0x0106a060, 0x0106a09f, 0, 0, umk3_palette_hack_w); }