mirror of
https://github.com/holub/mame
synced 2025-04-26 18:23:08 +03:00
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:
parent
6454c32b9f
commit
dbd6e5e93e
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user