From dbd6e5e93ee78f419e6499075df4d5d90b13ecf9 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Thu, 13 Mar 2008 08:09:58 +0000 Subject: [PATCH] Fixed 68000 prefetching operation. Changed slapstic management to always install an opbase handler to more aggressively catch code executing in the slapstic region. Updated all drivers to separate the slapstic region of ROM into a different ROM section from the fixed ROM. --- src/emu/cpu/m68000/m68kcpu.h | 35 +++++++++++++++----------- src/mame/drivers/atarig1.c | 5 +++- src/mame/drivers/atarisy1.c | 48 ++++-------------------------------- src/mame/drivers/gauntlet.c | 4 ++- src/mame/drivers/rampart.c | 2 +- src/mame/drivers/xybots.c | 4 ++- src/mame/machine/atarigen.c | 34 +++++++++++++++++++++++++ src/mame/machine/slapstic.c | 32 ++++++++++++++++-------- src/mame/video/atarig1.c | 8 +++--- 9 files changed, 97 insertions(+), 75 deletions(-) diff --git a/src/emu/cpu/m68000/m68kcpu.h b/src/emu/cpu/m68000/m68kcpu.h index bc8ce7dea01..e8ea18f1b52 100644 --- a/src/emu/cpu/m68000/m68kcpu.h +++ b/src/emu/cpu/m68000/m68kcpu.h @@ -1059,13 +1059,19 @@ INLINE uint m68ki_read_imm_16(void) m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PREFETCH - if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) +{ + uint result; + if(REG_PC != CPU_PREF_ADDR) { - CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); - CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); } + result = MASK_OUT_ABOVE_16(CPU_PREF_DATA); REG_PC += 2; - return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3)); + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); + return result; +} #else REG_PC += 2; return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2)); @@ -1078,20 +1084,21 @@ INLINE uint m68ki_read_imm_32(void) m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ - if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + + if(REG_PC != CPU_PREF_ADDR) { - CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); - CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); } - temp_val = CPU_PREF_DATA; + temp_val = MASK_OUT_ABOVE_16(CPU_PREF_DATA); REG_PC += 2; - if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) - { - CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); - CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); - temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16)); - } + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); + + temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(CPU_PREF_DATA)); REG_PC += 2; + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); return temp_val; #else diff --git a/src/mame/drivers/atarig1.c b/src/mame/drivers/atarig1.c index 150bbdcf965..24b5e1e5f30 100644 --- a/src/mame/drivers/atarig1.c +++ b/src/mame/drivers/atarig1.c @@ -218,7 +218,10 @@ static void pitfighb_cheap_slapstic_init(void) *************************************/ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x000000, 0x07ffff) AM_ROM + AM_RANGE(0x000000, 0x037fff) AM_ROM + AM_RANGE(0x038000, 0x03ffff) AM_ROM /* pitfight slapstic goes here */ + AM_RANGE(0x040000, 0x077fff) AM_ROM + AM_RANGE(0x078000, 0x07ffff) AM_ROM /* hydra slapstic goes here */ AM_RANGE(0xf80000, 0xf80001) AM_WRITE(watchdog_reset16_w) AM_RANGE(0xf88000, 0xf8ffff) AM_WRITE(atarigen_eeprom_enable_w) AM_RANGE(0xf90000, 0xf90001) AM_WRITE(atarigen_sound_upper_w) diff --git a/src/mame/drivers/atarisy1.c b/src/mame/drivers/atarisy1.c index 578a4b20b63..54e1d0137a4 100644 --- a/src/mame/drivers/atarisy1.c +++ b/src/mame/drivers/atarisy1.c @@ -145,6 +145,9 @@ static UINT8 tms5220_in_data; static UINT8 tms5220_ctl; +static TIMER_CALLBACK( delayed_joystick_int ); + + /************************************* * @@ -174,8 +177,6 @@ static void update_interrupts(running_machine *machine) } -static TIMER_CALLBACK( delayed_joystick_int ); - static MACHINE_RESET( atarisy1 ) { /* initialize the system */ @@ -408,43 +409,6 @@ static WRITE8_HANDLER( led_w ) -/************************************* - * - * Opcode memory catcher. - * - *************************************/ - -static OPBASE_HANDLER( indytemp_setopbase ) -{ - int prevpc = activecpu_get_previouspc(); - /* - * This is a slightly ugly kludge for Indiana Jones & the Temple of Doom because it jumps - * directly to code in the slapstic. The general order of things is this: - * - * jump to $3A, which turns off interrupts and jumps to $00 (the reset address) - * look up the request in a table and jump there - * (under some circumstances, tweak the special addresses) - * return via an RTS at the real bankswitch address - * - * To simulate this, we tweak the slapstic reset address on entry into slapstic code; then - * we let the system tweak whatever other addresses it wishes. On exit, we tweak the - * address of the previous PC, which is the RTS instruction, thereby completing the - * bankswitch sequence. - * - * Fortunately for us, all 4 banks have exactly the same code at this point in their - * ROM, so it doesn't matter which version we're actually executing. - */ - - if (address & 0x80000) - atarigen_slapstic_r(machine,0,0); - else if (prevpc & 0x80000) - atarigen_slapstic_r(machine,(prevpc >> 1) & 0x3fff,0); - - return address; -} - - - /************************************* * * Main CPU memory handlers @@ -452,7 +416,8 @@ static OPBASE_HANDLER( indytemp_setopbase ) *************************************/ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x000000, 0x087fff) AM_ROM + AM_RANGE(0x000000, 0x07ffff) AM_ROM + AM_RANGE(0x080000, 0x087fff) AM_ROM /* slapstic maps here */ AM_RANGE(0x2e0000, 0x2e0001) AM_READ(atarisy1_int3state_r) AM_RANGE(0x400000, 0x401fff) AM_RAM AM_RANGE(0x800000, 0x800001) AM_WRITE(atarisy1_xscroll_w) AM_BASE(&atarigen_xscroll) @@ -2164,9 +2129,6 @@ static DRIVER_INIT( indytemp ) atarigen_eeprom_default = NULL; atarigen_slapstic_init(0, 0x080000, 0, 105); - /* special case for the Indiana Jones slapstic */ - memory_set_opbase_handler(0,indytemp_setopbase); - joystick_type = 1; /* digital */ trackball_type = 0; /* none */ } diff --git a/src/mame/drivers/gauntlet.c b/src/mame/drivers/gauntlet.c index 9f193071fd0..c3499260bd2 100644 --- a/src/mame/drivers/gauntlet.c +++ b/src/mame/drivers/gauntlet.c @@ -314,7 +314,9 @@ static WRITE8_HANDLER( mixer_w ) /* full map verified from schematics */ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x07ffff) AM_MIRROR(0x280000) AM_ROM + AM_RANGE(0x000000, 0x037fff) AM_MIRROR(0x280000) AM_ROM + AM_RANGE(0x038000, 0x03ffff) AM_MIRROR(0x280000) AM_ROM /* slapstic maps here */ + AM_RANGE(0x040000, 0x07ffff) AM_MIRROR(0x280000) AM_ROM /* MBUS */ AM_RANGE(0x800000, 0x801fff) AM_MIRROR(0x2fc000) AM_RAM diff --git a/src/mame/drivers/rampart.c b/src/mame/drivers/rampart.c index e56671196f8..f550d99b4f4 100644 --- a/src/mame/drivers/rampart.c +++ b/src/mame/drivers/rampart.c @@ -173,7 +173,7 @@ static WRITE16_HANDLER( latch_w ) static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_GLOBAL_MASK(0x7fffff) AM_RANGE(0x000000, 0x0fffff) AM_ROM - AM_RANGE(0x140000, 0x147fff) AM_MIRROR(0x438000) AM_ROM + AM_RANGE(0x140000, 0x147fff) AM_MIRROR(0x438000) AM_ROM /* slapstic goes here */ AM_RANGE(0x200000, 0x21ffff) AM_RAM AM_BASE(&rampart_bitmap) AM_RANGE(0x220000, 0x3bffff) AM_WRITENOP /* the code blasts right through this when initializing */ AM_RANGE(0x3c0000, 0x3c07ff) AM_MIRROR(0x019800) AM_READWRITE(SMH_RAM, atarigen_expanded_666_paletteram_w) AM_BASE(&paletteram16) diff --git a/src/mame/drivers/xybots.c b/src/mame/drivers/xybots.c index 94a7e36266f..e267b106fbc 100644 --- a/src/mame/drivers/xybots.c +++ b/src/mame/drivers/xybots.c @@ -84,7 +84,9 @@ static READ16_HANDLER( special_port1_r ) /* full map verified from schematics */ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x03ffff) AM_MIRROR(0x7c0000) AM_ROM + AM_RANGE(0x000000, 0x007fff) AM_MIRROR(0x7c0000) AM_ROM + AM_RANGE(0x008000, 0x00ffff) AM_MIRROR(0x7c0000) AM_ROM /* slapstic maps here */ + AM_RANGE(0x010000, 0x03ffff) AM_MIRROR(0x7c0000) AM_ROM AM_RANGE(0xff8000, 0xff8fff) AM_MIRROR(0x7f8000) AM_READWRITE(SMH_RAM, atarigen_alpha_w) AM_BASE(&atarigen_alpha) AM_RANGE(0xff9000, 0xffadff) AM_MIRROR(0x7f8000) AM_RAM AM_RANGE(0xffae00, 0xffafff) AM_MIRROR(0x7f8000) AM_READWRITE(SMH_RAM, atarimo_0_spriteram_w) AM_BASE(&atarimo_0_spriteram) diff --git a/src/mame/machine/atarigen.c b/src/mame/machine/atarigen.c index a240ed38304..1790c1fe9ee 100644 --- a/src/mame/machine/atarigen.c +++ b/src/mame/machine/atarigen.c @@ -73,6 +73,10 @@ static UINT8 atarigen_slapstic_num; static UINT16 * atarigen_slapstic; static UINT8 atarigen_slapstic_bank; static void * atarigen_slapstic_bank0; +static offs_t atarigen_slapstic_last_pc; +static offs_t atarigen_slapstic_last_address; +static offs_t atarigen_slapstic_base; +static offs_t atarigen_slapstic_mirror; static UINT8 sound_cpu_num; static UINT8 atarigen_cpu_to_sound; @@ -504,6 +508,29 @@ static void slapstic_postload(void) } +static OPBASE_HANDLER( atarigen_slapstic_setopbase ) +{ + /* if we jump to an address in the slapstic region, tweak the slapstic + at that address and return ~0; this will cause us to be called on + subsequent fetches as well */ + address &= ~atarigen_slapstic_mirror; + if (address >= atarigen_slapstic_base && address < atarigen_slapstic_base + 0x8000) + { + offs_t pc = activecpu_get_previouspc(); + if (pc != atarigen_slapstic_last_pc || address != atarigen_slapstic_last_address) + { + atarigen_slapstic_last_pc = pc; + atarigen_slapstic_last_address = address; + atarigen_slapstic_r(machine, (address >> 1) & 0x3fff, 0); + } + return ~0; + } + + return address; +} + + + /*--------------------------------------------------------------- atarigen_slapstic_init: Installs memory handlers for the slapstic and sets the chip number. @@ -530,6 +557,11 @@ void atarigen_slapstic_init(int cpunum, offs_t base, offs_t mirror, int chipnum) /* ensure we recopy memory for the bank */ atarigen_slapstic_bank = 0xff; + + /* install an opcode base handler if we are a 68000 or variant */ + atarigen_slapstic_base = base; + atarigen_slapstic_mirror = mirror; + memory_set_opbase_handler(cpunum, atarigen_slapstic_setopbase); } } @@ -1629,6 +1661,8 @@ void atarigen_init_save_state(void) state_save_register_global(atarigen_slapstic_num); state_save_register_global(atarigen_slapstic_bank); + state_save_register_global(atarigen_slapstic_last_pc); + state_save_register_global(atarigen_slapstic_last_address); state_save_register_global(sound_cpu_num); state_save_register_global(atarigen_cpu_to_sound); diff --git a/src/mame/machine/slapstic.c b/src/mame/machine/slapstic.c index 59440da6a41..af2722d7456 100644 --- a/src/mame/machine/slapstic.c +++ b/src/mame/machine/slapstic.c @@ -184,6 +184,16 @@ #include "cpu/m68000/m68000.h" +/************************************* + * + * Debugging + * + *************************************/ + +#define LOG_SLAPSTIC (0) + + + /************************************* * * Structure of slapstic params @@ -247,6 +257,7 @@ struct slapstic_data #define MATCHES_MASK_VALUE(val, maskval) (((val) & (maskval).mask) == (maskval).value) + /************************************* * * Constants @@ -268,8 +279,6 @@ enum ADDITIVE3 }; -#define LOG_SLAPSTIC 0 - /************************************* @@ -816,8 +825,8 @@ void slapstic_init(int chip) slapstic_reset(); /* see if we're 68k or 6502/6809 based */ - access_68k = (Machine->config->cpu[0].type != CPU_M6809 && - Machine->config->cpu[0].type != CPU_M6502); + access_68k = (Machine->config->cpu[0].type == CPU_M68000 || + Machine->config->cpu[0].type == CPU_M68010); /* save state */ state_save_register_item("slapstic", 0, state); @@ -861,16 +870,20 @@ int slapstic_bank(void) static int alt2_kludge(offs_t offset) { - /* 68k case is fairly complex: we need to look for special triplets */ + /* Of the 3 alternate addresses, only the middle one needs to actually hit + in the slapstic region; the first and third ones can be anywhere in the + address space. For this reason, the read/write handlers usually only + see the 2nd access. For the 68000-based games, we do the following + kludge to examine the opcode that is executing and look for the 1st + and 3rd accesses. */ + if (access_68k) { - UINT32 pc = activecpu_get_previouspc(); - /* first verify that the prefetched PC matches the first alternate */ - if (MATCHES_MASK_VALUE((pc + 2) >> 1, slapstic.alt1)) + if (MATCHES_MASK_VALUE(activecpu_get_pc() >> 1, slapstic.alt1)) { /* now look for a move.w (An),(An) or cmpm.w (An)+,(An)+ */ - UINT16 opcode = cpu_readop16(pc & 0xffffff); + UINT16 opcode = cpu_readop16(activecpu_get_previouspc() & 0xffffff); if ((opcode & 0xf1f8) == 0x3090 || (opcode & 0xf1f8) == 0xb148) { /* fetch the value of the register for the second operand, and see */ @@ -904,7 +917,6 @@ static int alt2_kludge(offs_t offset) int slapstic_tweak(offs_t offset) { -//logerror("PC=%04X touch=%04X state=%d\n", activecpu_get_pc(), offset, state); /* reset is universal */ if (offset == 0x0000) { diff --git a/src/mame/video/atarig1.c b/src/mame/video/atarig1.c index 1dbdcd076a8..137aa72a3c9 100644 --- a/src/mame/video/atarig1.c +++ b/src/mame/video/atarig1.c @@ -164,7 +164,7 @@ void atarig1_scanline_update(const device_config *screen, int scanline) /* keep in range */ if (base >= &atarigen_alpha[0x800]) return; - video_screen_update_partial(screen, scanline - 1); + video_screen_update_partial(screen, MAX(scanline - 1, 0)); /* update the playfield scrolls */ for (i = 0; i < 8; i++) @@ -178,7 +178,7 @@ void atarig1_scanline_update(const device_config *screen, int scanline) int newscroll = ((word >> 6) + pfscroll_xoffset) & 0x1ff; if (newscroll != playfield_xscroll) { - video_screen_update_partial(screen, scanline + i - 1); + video_screen_update_partial(screen, MAX(scanline + i - 1, 0)); tilemap_set_scrollx(atarigen_playfield_tilemap, 0, newscroll); playfield_xscroll = newscroll; } @@ -192,13 +192,13 @@ void atarig1_scanline_update(const device_config *screen, int scanline) int newbank = word & 7; if (newscroll != playfield_yscroll) { - video_screen_update_partial(screen, scanline + i - 1); + video_screen_update_partial(screen, MAX(scanline + i - 1, 0)); tilemap_set_scrolly(atarigen_playfield_tilemap, 0, newscroll); playfield_yscroll = newscroll; } if (newbank != playfield_tile_bank) { - video_screen_update_partial(screen, scanline + i - 1); + video_screen_update_partial(screen, MAX(scanline + i - 1, 0)); tilemap_mark_all_tiles_dirty(atarigen_playfield_tilemap); playfield_tile_bank = newbank; }