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.
This commit is contained in:
Aaron Giles 2008-03-13 08:09:58 +00:00
parent 6454c32b9f
commit dbd6e5e93e
9 changed files with 97 additions and 75 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 */
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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;
}