Separate protection

This commit is contained in:
mahoneyt944 2024-07-19 04:22:00 -04:00 committed by GitHub
parent a2ca0fc5ef
commit 4af6b905b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 400 additions and 321 deletions

View File

@ -510,7 +510,7 @@ SOURCES_C += \
$(CORE_DIR)/drivers/sharrier.c $(CORE_DIR)/drivers/system18.c \
$(CORE_DIR)/drivers/system24.c $(CORE_DIR)/machine/system24_machine.c $(CORE_DIR)/vidhrdw/system24_vidhrdw.c \
$(CORE_DIR)/vidhrdw/segaic24.c $(CORE_DIR)/vidhrdw/segas18.c \
$(CORE_DIR)/drivers/segas32.c $(CORE_DIR)/vidhrdw/segas32.c \
$(CORE_DIR)/drivers/segas32.c $(CORE_DIR)/machine/segas32.c $(CORE_DIR)/vidhrdw/segas32.c \
$(CORE_DIR)/vidhrdw/segac2_vidhrdw.c $(CORE_DIR)/drivers/segac2.c \
$(CORE_DIR)/drivers/stv.c $(CORE_DIR)/drivers/stvhacks.c $(CORE_DIR)/machine/stvcd.c \
$(CORE_DIR)/machine/scudsp.c \

View File

@ -396,12 +396,12 @@ static UINT16 sound_bank;
static UINT8 misc_io_data[2][0x10];
static data16_t *segas32_protram;
static data16_t *system32_workram;
data16_t *system32_protram;
data16_t *system32_workram;
int system32_use_default_eeprom;
static void (*system32_prot_vblank)(void);
int system32_use_default_eeprom;
enum { EEPROM_SYS32_0=0, EEPROM_ALIEN3, EEPROM_RADM, EEPROM_RADR };
/* alien 3 with the gun calibrated, it doesn't prompt you if its not */
@ -601,194 +601,6 @@ static INTERRUPT_GEN( start_of_vblank_int )
}
static READ16_HANDLER(ga2_sprite_protection_r)
{
static unsigned int prot[16] =
{
0x0a, 0,
0xc5, 0,
0x11, 0,
0x11, 0,
0x18, 0,
0x18, 0,
0x1f, 0,
0xc6, 0,
};
return prot[offset];
}
static READ16_HANDLER(ga2_wakeup_protection_r)
{
static const char *prot =
"wake up! GOLDEN AXE The Revenge of Death-Adder! ";
return prot[offset];
}
/******************************************************************************
******************************************************************************
Sonic Arcade protection
******************************************************************************
******************************************************************************/
// This code duplicates the actions of the protection device used in SegaSonic
// arcade revision C, allowing the game to run correctly.
#define CLEARED_LEVELS 0xE5C4
#define CURRENT_LEVEL 0xF06E
#define CURRENT_LEVEL_STATUS 0xF0BC
#define LEVEL_ORDER_ARRAY 0x263A
static WRITE16_HANDLER(sonic_level_load_protection)
{
UINT16 level;
/*Perform write*/
COMBINE_DATA(&system32_workram[CLEARED_LEVELS / 2]);
/*Refresh current level*/
if (system32_workram[CLEARED_LEVELS / 2] == 0)
{
level = 0x0007;
}
else
{
const UINT8 *ROM = memory_region(REGION_CPU1);
level = *((ROM + LEVEL_ORDER_ARRAY) + (system32_workram[CLEARED_LEVELS / 2] * 2) - 1);
level |= *((ROM + LEVEL_ORDER_ARRAY) + (system32_workram[CLEARED_LEVELS / 2] * 2) - 2) << 8;
}
system32_workram[CURRENT_LEVEL / 2] = level;
/*Reset level status*/
system32_workram[CURRENT_LEVEL_STATUS / 2] = 0x0000;
system32_workram[(CURRENT_LEVEL_STATUS + 2) / 2] = 0x0000;
}
/******************************************************************************
******************************************************************************
The J.League 1994 (Japan)
******************************************************************************
******************************************************************************/
static WRITE16_HANDLER( jleague_protection_w )
{
COMBINE_DATA( &system32_workram[0xf700/2 + offset ] );
switch( offset )
{
/* Map team browser selection to opponent browser selection*/
/* using same lookup table that V60 uses for sound sample mapping.*/
case 0:
cpu_writemem24lew( 0x20f708, cpu_readmem24lew_word( 0x7bbc0 + data*2 ) );
break;
/* move on to team browser*/
case 4/2:
cpu_writemem24lew( 0x200016, data & 0xff );
break;
default:
break;
}
}
/* the protection board on many system32 games has full dma/bus access*/
/* and can write things into work RAM. we simulate that here for burning rival.*/
static READ16_HANDLER(brival_protection_r)
{
if (!mem_mask) /* only trap on word-wide reads*/
{
switch (offset)
{
case 0:
case 2:
case 3:
return 0;
}
}
return system32_workram[0xba00/2 + offset];
}
static WRITE16_HANDLER(brival_protboard_w)
{
static const int protAddress[6][2] =
{
{ 0x109517, 0x00/2 },
{ 0x109597, 0x10/2 },
{ 0x109597, 0x20/2 },
{ 0x109597, 0x30/2 },
{ 0x109597, 0x40/2 },
{ 0x109617, 0x50/2 },
};
char ret[32];
int curProtType;
UINT8 *ROM = memory_region(REGION_CPU1);
switch (offset)
{
case 0x800/2:
curProtType = 0;
break;
case 0x802/2:
curProtType = 1;
break;
case 0x804/2:
curProtType = 2;
break;
case 0x806/2:
curProtType = 3;
break;
case 0x808/2:
curProtType = 4;
break;
case 0x80a/2:
curProtType = 5;
break;
default:
if (offset >= 0xa00/2 && offset < 0xc00/2)
return;
log_cb(RETRO_LOG_DEBUG, LOGPRE "brival_protboard_w: UNKNOWN WRITE: offset %x value %x\n", offset, data);
return;
}
memcpy(ret, &ROM[protAddress[curProtType][0]], 16);
ret[16] = '\0';
memcpy(&segas32_protram[protAddress[curProtType][1]], ret, 16);
}
/* protection ram is 8-bits wide and only occupies every other address*/
static READ16_HANDLER(arabfgt_protboard_r)
{
int PC = activecpu_get_pc();
int cmpVal;
if (PC == 0xfe0325 || PC == 0xfe01e5 || PC == 0xfe035e || PC == 0xfe03cc)
{
cmpVal = activecpu_get_reg(1);
/* R0 always contains the value the protection is supposed to return (!)*/
return cmpVal;
}
else
{
usrintf_showmessage("UNKONWN ARF PROTECTION READ PC=%x\n", PC);
}
return 0;
}
static WRITE16_HANDLER(arabfgt_protboard_w)
{
}
static READ16_HANDLER(arf_wakeup_protection_r)
{
static const char *prot =
"wake up! ARF! ";
return prot[offset];
}
/*************************************
*
* IO Handling
@ -3688,7 +3500,7 @@ static DRIVER_INIT ( brival )
{
system32_use_default_eeprom = EEPROM_SYS32_0;
segas32_protram = auto_malloc (0x1000);
system32_protram = auto_malloc (0x1000);
install_mem_read16_handler (0, 0x20ba00, 0x20ba07, brival_protection_r);
install_mem_write16_handler(0, 0xa000000, 0xa00fff, brival_protboard_w);
}
@ -3702,7 +3514,6 @@ static DRIVER_INIT ( ga2 )
install_mem_read16_handler (0, 0xa00100, 0xa0015f, ga2_wakeup_protection_r);
}
/* comms board workaround */
static UINT16* dual_pcb_comms;
@ -3721,18 +3532,6 @@ static READ16_HANDLER( dual_pcb_masterslave )
return 0; /* 0/1 master/slave */
}
void f1lap_fd1149_vblank(void)
{
data8_t val;
cpu_writemem24lew(0x20F7C6, 0);
/* needed to start a game */
val = cpu_readmem24lew(0x20EE81);
if (val == 0xff) cpu_writemem24lew(0x20EE81,0);
}
static DRIVER_INIT ( f1sl )
{
system32_use_default_eeprom = EEPROM_SYS32_0;
@ -3817,42 +3616,6 @@ static READ16_HANDLER( arescue_81000f_r )
return 1; /* 0/1 2player/1player*/
}
static UINT16 arescue_dsp_io[6] = {0,0,0,0,0,0};
static READ16_HANDLER( arescue_dsp_r )
{
if( offset == 4/2 )
{
switch( arescue_dsp_io[0] )
{
case 0:
case 1:
case 2:
break;
case 3:
arescue_dsp_io[0] = 0x8000;
arescue_dsp_io[2/2] = 0x0001;
break;
case 6:
arescue_dsp_io[0] = 4 * arescue_dsp_io[2/2];
break;
default:
log_cb(RETRO_LOG_DEBUG, LOGPRE "Unhandled DSP cmd %04x (%04x).\n", arescue_dsp_io[0], arescue_dsp_io[1] );
break;
}
}
return arescue_dsp_io[offset];
}
static WRITE16_HANDLER( arescue_dsp_w )
{
COMBINE_DATA(&arescue_dsp_io[offset]);
}
static DRIVER_INIT( arescue )
{
system32_use_default_eeprom = EEPROM_SYS32_0;
@ -3870,73 +3633,6 @@ static DRIVER_INIT( arescue )
install_mem_read16_handler (0, 0x81000f, 0x81000f, arescue_81000f_r); /* 1player game*/
}
static UINT16 MemRead16_16(offs_t address)
{
if (!(address & 1))
return cpu_readmem24lew_word(address);
else
{
UINT16 result = cpu_readmem24lew(address);
return result | cpu_readmem24lew(address + 1) << 8;
}
}
static void MemWrite16_16(offs_t address, UINT16 data)
{
if (!(address & 1))
cpu_writemem24lew_word(address, data);
else
{
cpu_writemem24lew(address, data);
cpu_writemem24lew(address + 1, data >> 8);
}
}
#define program_read_byte cpu_readmem24lew
#define program_write_byte cpu_writemem24lew
#define program_read_word MemRead16_16
#define program_write_word MemWrite16_16
/******************************************************************************
******************************************************************************
Dark Edge
******************************************************************************
******************************************************************************/
/* V60 24lew for 8-16bit mem calls i think */
void darkedge_fd1149_vblank(void)
{
program_write_word(0x20f072, 0);
program_write_word(0x20f082, 0);
if( program_read_byte(0x20a12c) != 0 )
{
program_write_byte(0x20a12c, program_read_byte(0x20a12c)-1 );
if( program_read_byte(0x20a12c) == 0 )
program_write_byte(0x20a12e, 1);
}
}
WRITE16_HANDLER( darkedge_protection_w )
{
log_cb(RETRO_LOG_DEBUG, LOGPRE "%06x:darkedge_prot_w(%06X) = %04X & %04X\n",
activecpu_get_pc(), 0xa00000 + 2*offset, data, mem_mask ^ 0xffff);
}
READ16_HANDLER( darkedge_protection_r )
{
log_cb(RETRO_LOG_DEBUG, LOGPRE "%06x:darkedge_prot_r(%06X) & %04X\n",
activecpu_get_pc(), 0xa00000 + 2*offset, mem_mask ^ 0xffff);
return 0xffff;
}
static DRIVER_INIT( darkedge )
{
system32_use_default_eeprom = EEPROM_SYS32_0;
@ -3949,17 +3645,6 @@ static DRIVER_INIT( darkedge )
opaquey_hack = true;
}
WRITE16_HANDLER( dbzvrvs_protection_w )
{
program_write_word( 0x2080c8, program_read_word( 0x200044 ) );
}
READ16_HANDLER( dbzvrvs_protection_r )
{
return 0xffff;
}
static DRIVER_INIT( jleague )
{
system32_use_default_eeprom = EEPROM_SYS32_0;

View File

@ -5,6 +5,11 @@
***************************************************************************/
/*----------- defined in driver/segas32.c -----------*/
extern data16_t *system32_protram;
extern data16_t *system32_workram;
/*----------- defined in vidhrdw/segas32.c -----------*/
extern UINT16 *system32_videoram;
@ -22,7 +27,6 @@ WRITE16_HANDLER( system32_spriteram_w );
READ32_HANDLER( multi32_spriteram_r );
WRITE32_HANDLER( multi32_spriteram_w );
READ16_HANDLER( system32_videoram_r );
WRITE16_HANDLER( system32_videoram_w );
READ32_HANDLER( multi32_videoram_r );
@ -54,6 +58,39 @@ VIDEO_UPDATE( system32 );
VIDEO_UPDATE( multi32 );
/*************************************
*
* Protection - machine/segas32.c
*
*************************************/
READ16_HANDLER(ga2_sprite_protection_r);
READ16_HANDLER(ga2_wakeup_protection_r);
WRITE16_HANDLER(sonic_level_load_protection);
WRITE16_HANDLER( jleague_protection_w );
READ16_HANDLER(brival_protection_r);
WRITE16_HANDLER(brival_protboard_w);
READ16_HANDLER(arabfgt_protboard_r);
WRITE16_HANDLER(arabfgt_protboard_w);
READ16_HANDLER(arf_wakeup_protection_r);
void f1lap_fd1149_vblank(void);
READ16_HANDLER( arescue_dsp_r );
WRITE16_HANDLER( arescue_dsp_w );
void darkedge_fd1149_vblank(void);
WRITE16_HANDLER( darkedge_protection_w );
READ16_HANDLER( darkedge_protection_r );
WRITE16_HANDLER( dbzvrvs_protection_w );
READ16_HANDLER( dbzvrvs_protection_r );
/*************************************
*
* ROM definition(s)

357
src/machine/segas32.c Normal file
View File

@ -0,0 +1,357 @@
/* Sega System 32 Protection related functions */
#include "driver.h"
#include "includes/segas32.h"
/******************************************************************************
******************************************************************************
Memory helper prototypes
******************************************************************************
******************************************************************************/
static UINT16 MemRead16_16(offs_t address)
{
if (!(address & 1))
return cpu_readmem24lew_word(address);
else
{
UINT16 result = cpu_readmem24lew(address);
return result | cpu_readmem24lew(address + 1) << 8;
}
}
static void MemWrite16_16(offs_t address, UINT16 data)
{
if (!(address & 1))
cpu_writemem24lew_word(address, data);
else
{
cpu_writemem24lew(address, data);
cpu_writemem24lew(address + 1, data >> 8);
}
}
#define program_read_byte cpu_readmem24lew
#define program_write_byte cpu_writemem24lew
#define program_read_word MemRead16_16
#define program_write_word MemWrite16_16
/******************************************************************************
******************************************************************************
Golden Axe 2 (Revenge of Death Adder)
******************************************************************************
******************************************************************************/
READ16_HANDLER(ga2_sprite_protection_r)
{
static unsigned int prot[16] =
{
0x0a, 0,
0xc5, 0,
0x11, 0,
0x11, 0,
0x18, 0,
0x18, 0,
0x1f, 0,
0xc6, 0,
};
return prot[offset];
}
READ16_HANDLER(ga2_wakeup_protection_r)
{
static const char *prot =
"wake up! GOLDEN AXE The Revenge of Death-Adder! ";
return prot[offset];
}
/******************************************************************************
******************************************************************************
Sonic Arcade protection
******************************************************************************
******************************************************************************/
/* This code duplicates the actions of the protection device used in SegaSonic */
/* arcade revision C, allowing the game to run correctly. */
#define CLEARED_LEVELS 0xE5C4
#define CURRENT_LEVEL 0xF06E
#define CURRENT_LEVEL_STATUS 0xF0BC
#define LEVEL_ORDER_ARRAY 0x263A
WRITE16_HANDLER(sonic_level_load_protection)
{
UINT16 level;
/*Perform write*/
COMBINE_DATA(&system32_workram[CLEARED_LEVELS / 2]);
/*Refresh current level*/
if (system32_workram[CLEARED_LEVELS / 2] == 0)
{
level = 0x0007;
}
else
{
const UINT8 *ROM = memory_region(REGION_CPU1);
level = *((ROM + LEVEL_ORDER_ARRAY) + (system32_workram[CLEARED_LEVELS / 2] * 2) - 1);
level |= *((ROM + LEVEL_ORDER_ARRAY) + (system32_workram[CLEARED_LEVELS / 2] * 2) - 2) << 8;
}
system32_workram[CURRENT_LEVEL / 2] = level;
/*Reset level status*/
system32_workram[CURRENT_LEVEL_STATUS / 2] = 0x0000;
system32_workram[(CURRENT_LEVEL_STATUS + 2) / 2] = 0x0000;
}
/******************************************************************************
******************************************************************************
The J.League 1994 (Japan)
******************************************************************************
******************************************************************************/
WRITE16_HANDLER( jleague_protection_w )
{
COMBINE_DATA( &system32_workram[0xf700/2 + offset ] );
switch( offset )
{
/* Map team browser selection to opponent browser selection*/
/* using same lookup table that V60 uses for sound sample mapping.*/
case 0:
cpu_writemem24lew( 0x20f708, cpu_readmem24lew_word( 0x7bbc0 + data*2 ) );
break;
/* move on to team browser*/
case 4/2:
cpu_writemem24lew( 0x200016, data & 0xff );
break;
default:
break;
}
}
/******************************************************************************
******************************************************************************
Burning Rival
******************************************************************************
******************************************************************************/
READ16_HANDLER(brival_protection_r)
{
if (!mem_mask) /* only trap on word-wide reads*/
{
switch (offset)
{
case 0:
case 2:
case 3:
return 0;
}
}
return system32_workram[0xba00/2 + offset];
}
WRITE16_HANDLER(brival_protboard_w)
{
static const int protAddress[6][2] =
{
{ 0x109517, 0x00/2 },
{ 0x109597, 0x10/2 },
{ 0x109597, 0x20/2 },
{ 0x109597, 0x30/2 },
{ 0x109597, 0x40/2 },
{ 0x109617, 0x50/2 },
};
char ret[32];
int curProtType;
UINT8 *ROM = memory_region(REGION_CPU1);
switch (offset)
{
case 0x800/2:
curProtType = 0;
break;
case 0x802/2:
curProtType = 1;
break;
case 0x804/2:
curProtType = 2;
break;
case 0x806/2:
curProtType = 3;
break;
case 0x808/2:
curProtType = 4;
break;
case 0x80a/2:
curProtType = 5;
break;
default:
if (offset >= 0xa00/2 && offset < 0xc00/2)
return;
log_cb(RETRO_LOG_DEBUG, LOGPRE "brival_protboard_w: UNKNOWN WRITE: offset %x value %x\n", offset, data);
return;
}
memcpy(ret, &ROM[protAddress[curProtType][0]], 16);
ret[16] = '\0';
memcpy(&system32_protram[protAddress[curProtType][1]], ret, 16);
}
/******************************************************************************
******************************************************************************
Arabian Fight
******************************************************************************
******************************************************************************/
/* protection ram is 8-bits wide and only occupies every other address*/
READ16_HANDLER(arabfgt_protboard_r)
{
int PC = activecpu_get_pc();
int cmpVal;
if (PC == 0xfe0325 || PC == 0xfe01e5 || PC == 0xfe035e || PC == 0xfe03cc)
{
cmpVal = activecpu_get_reg(1);
/* R0 always contains the value the protection is supposed to return (!)*/
return cmpVal;
}
else
{
usrintf_showmessage("UNKONWN ARF PROTECTION READ PC=%x\n", PC);
}
return 0;
}
WRITE16_HANDLER(arabfgt_protboard_w)
{
}
READ16_HANDLER(arf_wakeup_protection_r)
{
static const char *prot =
"wake up! ARF! ";
return prot[offset];
}
/******************************************************************************
******************************************************************************
F1 Super Lap
******************************************************************************
******************************************************************************/
void f1lap_fd1149_vblank(void)
{
data8_t val;
cpu_writemem24lew(0x20F7C6, 0);
/* needed to start a game */
val = cpu_readmem24lew(0x20EE81);
if (val == 0xff) cpu_writemem24lew(0x20EE81,0);
}
/******************************************************************************
******************************************************************************
Air Rescue
******************************************************************************
******************************************************************************/
static UINT16 arescue_dsp_io[6] = {0,0,0,0,0,0};
READ16_HANDLER( arescue_dsp_r )
{
if( offset == 4/2 )
{
switch( arescue_dsp_io[0] )
{
case 0:
case 1:
case 2:
break;
case 3:
arescue_dsp_io[0] = 0x8000;
arescue_dsp_io[2/2] = 0x0001;
break;
case 6:
arescue_dsp_io[0] = 4 * arescue_dsp_io[2/2];
break;
default:
log_cb(RETRO_LOG_DEBUG, LOGPRE "Unhandled DSP cmd %04x (%04x).\n", arescue_dsp_io[0], arescue_dsp_io[1] );
break;
}
}
return arescue_dsp_io[offset];
}
WRITE16_HANDLER( arescue_dsp_w )
{
COMBINE_DATA(&arescue_dsp_io[offset]);
}
/******************************************************************************
******************************************************************************
Dark Edge
******************************************************************************
******************************************************************************/
void darkedge_fd1149_vblank(void)
{
program_write_word(0x20f072, 0);
program_write_word(0x20f082, 0);
if( program_read_byte(0x20a12c) != 0 )
{
program_write_byte(0x20a12c, program_read_byte(0x20a12c)-1 );
if( program_read_byte(0x20a12c) == 0 )
program_write_byte(0x20a12e, 1);
}
}
WRITE16_HANDLER( darkedge_protection_w )
{
log_cb(RETRO_LOG_DEBUG, LOGPRE "%06x:darkedge_prot_w(%06X) = %04X & %04X\n",
activecpu_get_pc(), 0xa00000 + 2*offset, data, mem_mask ^ 0xffff);
}
READ16_HANDLER( darkedge_protection_r )
{
log_cb(RETRO_LOG_DEBUG, LOGPRE "%06x:darkedge_prot_r(%06X) & %04X\n",
activecpu_get_pc(), 0xa00000 + 2*offset, mem_mask ^ 0xffff);
return 0xffff;
}
/******************************************************************************
******************************************************************************
DBZ VRVS
******************************************************************************
******************************************************************************/
WRITE16_HANDLER( dbzvrvs_protection_w )
{
program_write_word( 0x2080c8, program_read_word( 0x200044 ) );
}
READ16_HANDLER( dbzvrvs_protection_r )
{
return 0xffff;
}