mirror of
https://github.com/libretro/mame2003-plus-libretro.git
synced 2026-11-07 04:16:07 -10:00
Taito G-NET: the 39 games of current MAME (PC card games in flash, Zoom sound)
New: Intel/Sharp 16-bit flash memories (intelfsh.c), the RF5C296 PC card controller with the ATA flash card and the three Taito locked cards (ataflash.c), the G-NET board in zn.c (flash bank, control registers, COM_DELAY, ZN-2 SPU toggle, the MCU protocol for analog and trackball inputs, mahjong panel, Mawasunda handles), the Zoom board in flash mode (samples read from the flashes), CHD metadata (CIS, IDNT, KEY), and a PC hook in the PSX CPU for the IRQ hack of Space Invaders Anniversary and Kollon. JP1 "Auto" for the mod BIOS and Compact Flash games. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MEgow1uRCv8pxMErKhmoHZ
This commit is contained in:
17 files changed
+3000
-1
No files matched your search
@@ -79,6 +79,8 @@ SOURCES_C += \
|
||||
$(CORE_DIR)/machine/8255ppi.c \
|
||||
$(CORE_DIR)/machine/eeprom.c \
|
||||
$(CORE_DIR)/machine/idectrl.c \
|
||||
$(CORE_DIR)/machine/intelfsh.c \
|
||||
$(CORE_DIR)/machine/ataflash.c \
|
||||
$(CORE_DIR)/machine/mathbox.c \
|
||||
$(CORE_DIR)/machine/mb87078.c \
|
||||
$(CORE_DIR)/machine/random.c \
|
||||
|
||||
@@ -223,6 +223,9 @@ extern void psxcpu_ram_written(const void *host, UINT32 bytes);
|
||||
per machine. */
|
||||
extern int psxcpu_jit_available(void);
|
||||
extern void psxcpu_set_jit(int enable);
|
||||
/* fn is called before the instruction at pc runs (NULL: none); set at */
|
||||
/* machine init, cleared at the CPU init */
|
||||
extern void psxcpu_set_pc_hook(UINT32 pc, void (*fn)(void));
|
||||
|
||||
#ifdef MAME_DEBUG
|
||||
extern unsigned DasmMIPS(char *buff, unsigned _pc);
|
||||
|
||||
@@ -348,6 +348,12 @@ static INLINE void psx_write32( offs_t address, data32_t data )
|
||||
cpu_writemem32ledw_dword( address, data );
|
||||
}
|
||||
|
||||
/* a driver hook called before the instruction at one address runs (the */
|
||||
/* hacks MAME does with a debugger breakpoint or a read tap on the code) */
|
||||
#define PC_HOOK_NONE 1 /* never an instruction address */
|
||||
static UINT32 pc_hook_pc = PC_HOOK_NONE;
|
||||
static void ( *pc_hook_fn )( void );
|
||||
|
||||
static void loop_arrive( UINT32 l, UINT32 from );
|
||||
static int loop_kind( UINT32 l );
|
||||
static int loop_pure_armed;
|
||||
@@ -539,6 +545,8 @@ void mips_init( void )
|
||||
fastram_count = 0;
|
||||
fastram_last = &fastram[ 0 ];
|
||||
psxcpu_set_jit( 0 );
|
||||
pc_hook_pc = PC_HOOK_NONE;
|
||||
pc_hook_fn = NULL;
|
||||
|
||||
state_save_register_UINT32( "psxcpu", cpu, "op", &mipscpu.op, 1 );
|
||||
state_save_register_UINT32( "psxcpu", cpu, "pc", &mipscpu.pc, 1 );
|
||||
@@ -565,6 +573,16 @@ void mips_reset( void *param )
|
||||
void mips_exit( void )
|
||||
{
|
||||
psxcpu_set_jit( 0 );
|
||||
pc_hook_pc = PC_HOOK_NONE;
|
||||
pc_hook_fn = NULL;
|
||||
}
|
||||
|
||||
void psxcpu_set_pc_hook( UINT32 pc, void ( *fn )( void ) )
|
||||
{
|
||||
pc_hook_pc = fn != NULL && ( pc & 3 ) == 0 ? pc : PC_HOOK_NONE;
|
||||
pc_hook_fn = fn;
|
||||
/* the recompiler leaves that instruction to the interpreter */
|
||||
jit_reset_flush();
|
||||
}
|
||||
|
||||
/* one instruction at mipscpu.pc (opcode in mipscpu.op), without the cycle */
|
||||
@@ -1789,6 +1807,10 @@ int mips_execute( int cycles )
|
||||
}
|
||||
{
|
||||
UINT32 from = mipscpu.pc;
|
||||
if( from == pc_hook_pc )
|
||||
{
|
||||
pc_hook_fn();
|
||||
}
|
||||
mipscpu.op = cpu_readop32( from );
|
||||
mips_step();
|
||||
mips_ICount--;
|
||||
|
||||
@@ -1377,6 +1377,11 @@ static void jit_compile( struct jit_block *block, UINT32 pc )
|
||||
{
|
||||
maxcount = JIT_MAX_BLOCK;
|
||||
}
|
||||
/* the hooked instruction runs in the interpreter: the block stops before it */
|
||||
if( pc_hook_pc != PC_HOOK_NONE && pc_hook_pc >= pc && ( pc_hook_pc - pc ) / 4 < maxcount )
|
||||
{
|
||||
maxcount = ( pc_hook_pc - pc ) / 4;
|
||||
}
|
||||
for( i = 0; i < maxcount; i++ )
|
||||
{
|
||||
ops[ i ] = *(const UINT32 *)( host + i * 4 );
|
||||
|
||||
@@ -2784,6 +2784,45 @@ V-V TP-027
|
||||
DRIVER( raystormo ) /* RayStorm (Ver 2.05O) */
|
||||
DRIVER( raystormu ) /* RayStorm (Ver 2.05A) */
|
||||
DRIVER( raystormj ) /* RayStorm (Ver 2.05J) */
|
||||
DRIVER( chaoshea ) /* Chaos Heat (V2.09O 1998/10/02 17:00) */
|
||||
DRIVER( chaosheaj ) /* Chaos Heat (V2.08J 1998/09/25 17:00) */
|
||||
DRIVER( raycris ) /* RayCrisis (V2.03O 1998/11/15 15:43) */
|
||||
DRIVER( raycrisj ) /* RayCrisis (V2.03J 1998/11/15 15:43) */
|
||||
DRIVER( spuzbobl ) /* Super Puzzle Bobble (V2.05O 1999/2/24 18:00) */
|
||||
DRIVER( spuzboblj ) /* Super Puzzle Bobble (V2.04J 1999/2/17 02:10) */
|
||||
DRIVER( gobyrc ) /* Go By RC (V2.03O 1999/05/25 13:31) */
|
||||
DRIVER( rcdego ) /* RC De Go (V2.03J 1999/05/22 19:29) */
|
||||
DRIVER( flipmaze ) /* Flip Maze (V2.04J 1999/09/02 20:00) */
|
||||
DRIVER( mawasunda ) /* Mawasunda!! (V2.08J 2000/02/01 11:02:54) */
|
||||
DRIVER( shikigam ) /* Shikigami no Shiro (V2.03J 2001/08/07 18:11) */
|
||||
DRIVER( shikigama ) /* Shikigami no Shiro - internal build (V1.02J 2001/09/27 18:45) */
|
||||
DRIVER( sianniv ) /* Space Invaders Anniversary (V2.02J 2003/09/12 20:00) */
|
||||
DRIVER( kollon ) /* Kollon (V2.04JA 2003/11/01 12:00) */
|
||||
DRIVER( kollonc ) /* Kollon (V2.04JC 2003/11/01 12:00) */
|
||||
DRIVER( otenamih ) /* Otenami Haiken (V2.04J 1999/02/01 18:00:00) */
|
||||
DRIVER( psyvaria ) /* Psyvariar -Medium Unit- (V2.02O 2000/02/22 13:00) */
|
||||
DRIVER( psyvarij ) /* Psyvariar -Medium Unit- (V2.04J 2000/02/15 11:00) */
|
||||
DRIVER( psyvarrv ) /* Psyvariar -Revision- (V2.04J 2000/08/11 22:00) */
|
||||
DRIVER( zokuoten ) /* Zoku Otenamihaiken (V2.05J 2003/05/12 18:00) */
|
||||
DRIVER( zokuotena ) /* Zoku Otenamihaiken (V2.03J 2001/02/16 16:00) */
|
||||
DRIVER( zooo ) /* Zooo (V2.01JA 2004/04/13 12:00) */
|
||||
DRIVER( otenamhf ) /* Otenami Haiken Final (V2.07JC 2005/04/20 15:36) */
|
||||
DRIVER( mahjngoh ) /* Mahjong Oh (V2.06J 1999/11/23 08:52:22) */
|
||||
DRIVER( shanghss ) /* Shanghai Shoryu Sairin (V2.03J 2000/05/26 12:45:28) */
|
||||
DRIVER( soutenry ) /* Soutenryu (V2.07J 2000/12/14 11:13:02) */
|
||||
DRIVER( usagi ) /* Usagi (V2.02J 2001/10/02 12:41:19) */
|
||||
DRIVER( shangtou ) /* Shanghai Sangokuhai Tougi (Ver 2.01J 2002/01/18 18:26:58) */
|
||||
DRIVER( nightrai ) /* Night Raid (V2.03J 2001/02/26 17:00) */
|
||||
DRIVER( otenki ) /* Otenki Kororin (V2.01J 2001/07/02 10:00) */
|
||||
DRIVER( xiistag ) /* XII Stag (V2.01J 2002/6/26 22:27) */
|
||||
DRIVER( aerofgtsg ) /* Aero Fighters Special (VER 1.00G) */
|
||||
DRIVER( brvbladeg ) /* Brave Blade (VER 1.40G) */
|
||||
DRIVER( flamegung ) /* Flame Gunner (VER 1.40G) */
|
||||
DRIVER( ftimpactg ) /* Fighters' Impact (VER 2.10G) */
|
||||
DRIVER( gdariusg ) /* G-Darius (VER 2.70G) */
|
||||
DRIVER( raystormg ) /* RayStorm (VER 2.60G) */
|
||||
DRIVER( shngmtkbg ) /* Shanghai Matekibuyuu (VER 1.20G) */
|
||||
DRIVER( tblkkuzug ) /* The Block Kuzushi (VER 1.10G) */
|
||||
DRIVER( ftimpcta ) /* Fighters' Impact A (Ver 2.00J) */
|
||||
DRIVER( ftimpact ) /* Fighters' Impact (Ver 2.02O) */
|
||||
DRIVER( ftimpactu ) /* Fighters' Impact (Ver 2.02A) */
|
||||
|
||||
+1290
File diff suppressed because it is too large.
Load diff
@@ -687,6 +687,20 @@ struct hard_disk_info *hard_disk_get_info(struct hard_disk_file *file)
|
||||
}
|
||||
|
||||
|
||||
/* reads the first metadata entry with this tag (as 'C','I','S',' ' -> */
|
||||
/* CHD_MAKE_TAG); returns its length (what fits in buffer is copied), */
|
||||
/* or -1 if the CHD has none */
|
||||
int hard_disk_get_metadata(struct hard_disk_file *file, UINT32 tag, void *buffer, UINT32 buflen)
|
||||
{
|
||||
UINT32 metalength, metatag;
|
||||
UINT8 metaflags;
|
||||
|
||||
if (chd_get_metadata(file->chd, tag, 0, buffer, buflen, &metalength, &metatag, &metaflags) != CHDERR_NONE)
|
||||
return -1;
|
||||
return metalength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
|
||||
@@ -48,6 +48,10 @@ void hard_disk_close_all(void);
|
||||
void hard_disk_get_hashes(struct hard_disk_file *file, char *datahash, char *imagehash);
|
||||
struct hard_disk_info *hard_disk_get_info(struct hard_disk_file *file);
|
||||
|
||||
/* the first metadata entry of the CHD with this tag: its length, -1 if none; */
|
||||
/* what fits in buffer is copied */
|
||||
int hard_disk_get_metadata(struct hard_disk_file *file, UINT32 tag, void *buffer, UINT32 buflen);
|
||||
|
||||
UINT32 hard_disk_read(struct hard_disk_file *file, UINT32 lbasector, UINT32 numsectors, void *buffer);
|
||||
UINT32 hard_disk_write(struct hard_disk_file *file, UINT32 lbasector, UINT32 numsectors, const void *buffer);
|
||||
|
||||
|
||||
@@ -899,6 +899,8 @@ void print_mame_xml()
|
||||
PRINT_RESOURCE(coh3002c);
|
||||
PRINT_RESOURCE(coh1002m);
|
||||
PRINT_RESOURCE(coh1000t);
|
||||
PRINT_RESOURCE(coh3002t);
|
||||
PRINT_RESOURCE(coh1002t);
|
||||
PRINT_RESOURCE(coh1000a);
|
||||
PRINT_RESOURCE(coh1000w);
|
||||
PRINT_RESOURCE(coh1001l);
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,39 @@
|
||||
/***************************************************************************
|
||||
|
||||
ATA flash PC card behind a Ricoh RF5C296 PC Card controller (Taito G-NET)
|
||||
|
||||
Backported from current MAME src/devices/bus/pccard/ataflash.cpp,
|
||||
src/devices/machine/rf5c296.cpp and the ATA mass storage device
|
||||
(atahle.cpp, atastorage.cpp; Aaron Giles, smf, Ville Linde and others).
|
||||
|
||||
One card. The disk is a CHD: its CIS ('CIS ' metadata), IDENTIFY data
|
||||
('IDNT') and Taito unlock key ('KEY ') come from the CHD, as in MAME.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef ATAFLASH_H
|
||||
#define ATAFLASH_H
|
||||
|
||||
#include "driver.h"
|
||||
#include "harddisk.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ATAFLASH_GENERIC = 0, /* ATA flash PC card */
|
||||
ATAFLASH_TAITO_PCCARD1, /* Taito, unlocked by the key in attribute memory */
|
||||
ATAFLASH_TAITO_PCCARD2, /* Taito, unlocked by two ATA commands */
|
||||
ATAFLASH_TAITO_CF /* Taito Compact Flash, unlocked by an ATA command */
|
||||
};
|
||||
|
||||
/* driver init; disk can be NULL (no card) */
|
||||
void ataflash_init( int type, struct hard_disk_file *disk );
|
||||
void ataflash_reset( void ); /* machine init */
|
||||
|
||||
/* the RF5C296, on a 16-bit bus: offsets in words, masks with the */
|
||||
/* bits that are accessed set (as current MAME) */
|
||||
UINT16 rf5c296_io_r( offs_t offset, UINT16 mem_mask ); /* I/O space: the ATA registers */
|
||||
void rf5c296_io_w( offs_t offset, UINT16 data, UINT16 mem_mask );
|
||||
UINT16 rf5c296_mem_r( offs_t offset, UINT16 mem_mask ); /* attribute memory: CIS, card registers */
|
||||
void rf5c296_mem_w( offs_t offset, UINT16 data, UINT16 mem_mask );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,324 @@
|
||||
/***************************************************************************
|
||||
|
||||
Intel / Sharp 16-bit flash memories, the Intel command set
|
||||
|
||||
Backported from current MAME src/devices/machine/intelfsh.cpp. A block
|
||||
erase takes the time of MAME (1 second for a 64KB block, 300 / 600 ms
|
||||
for the E28F400B boot blocks); the status reads busy until then.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "intelfsh.h"
|
||||
|
||||
enum
|
||||
{
|
||||
FM_NORMAL = 0, /* read array */
|
||||
FM_READID,
|
||||
FM_READSTATUS,
|
||||
FM_WRITEPART1, /* next write: the word to program */
|
||||
FM_CLEARPART1, /* next write: the erase confirm */
|
||||
FM_SETMASTER /* next write: the master lock confirm */
|
||||
};
|
||||
|
||||
struct intelfsh_chip
|
||||
{
|
||||
int type;
|
||||
UINT16 *data;
|
||||
UINT32 words;
|
||||
UINT8 maker_id;
|
||||
UINT16 device_id;
|
||||
UINT8 mode;
|
||||
UINT8 status;
|
||||
UINT8 master_lock;
|
||||
mame_timer *timer;
|
||||
double timer_left; /* time left on the timer, for save states (-1: none) */
|
||||
};
|
||||
|
||||
static struct intelfsh_chip chips[ INTELFSH_CHIPS_MAX ];
|
||||
|
||||
static void intelfsh_delay( int chip )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
|
||||
/* the erase is done */
|
||||
if( c->mode == FM_READSTATUS )
|
||||
c->status = 0x80;
|
||||
}
|
||||
|
||||
/* 0.78 does not save its timers: an erase goes on with the time it had left */
|
||||
static void intelfsh_presave( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < INTELFSH_CHIPS_MAX; i++ )
|
||||
{
|
||||
if( chips[ i ].data != NULL )
|
||||
{
|
||||
chips[ i ].timer_left = ( chips[ i ].status & 0x80 ) ? -1 : timer_timeleft( chips[ i ].timer );
|
||||
/* a timer due in this timeslice can be a little past its time */
|
||||
if( !( chips[ i ].status & 0x80 ) && chips[ i ].timer_left < 0 )
|
||||
chips[ i ].timer_left = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void intelfsh_postload( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < INTELFSH_CHIPS_MAX; i++ )
|
||||
{
|
||||
if( chips[ i ].data != NULL )
|
||||
{
|
||||
if( chips[ i ].timer_left >= 0 )
|
||||
timer_adjust( chips[ i ].timer, chips[ i ].timer_left, i, 0 );
|
||||
else
|
||||
timer_adjust( chips[ i ].timer, TIME_NEVER, 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void intelfsh_init( int chip, int type, UINT16 *data )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
UINT32 bytes;
|
||||
|
||||
/* chip 0 comes first: forget the chips of the game before */
|
||||
if( chip == 0 )
|
||||
memset( chips, 0, sizeof( chips ) );
|
||||
memset( c, 0, sizeof( *c ) );
|
||||
c->type = type;
|
||||
switch( type )
|
||||
{
|
||||
case INTELFSH_INTEL_E28F400B:
|
||||
bytes = 0x80000;
|
||||
c->maker_id = 0x89; /* Intel */
|
||||
c->device_id = 0x4471;
|
||||
break;
|
||||
|
||||
default:
|
||||
case INTELFSH_INTEL_TE28F160:
|
||||
bytes = 0x200000;
|
||||
c->maker_id = 0xb0; /* Sharp */
|
||||
c->device_id = 0xd0;
|
||||
break;
|
||||
}
|
||||
c->words = bytes / 2;
|
||||
c->data = data != NULL ? data : auto_malloc( bytes );
|
||||
memset( c->data, 0xff, bytes );
|
||||
c->mode = FM_NORMAL;
|
||||
c->status = 0x80;
|
||||
c->timer = timer_alloc( intelfsh_delay );
|
||||
c->timer_left = -1;
|
||||
|
||||
state_save_register_UINT16( "intelfsh", chip, "data", c->data, c->words );
|
||||
state_save_register_UINT8( "intelfsh", chip, "mode", &c->mode, 1 );
|
||||
state_save_register_UINT8( "intelfsh", chip, "status", &c->status, 1 );
|
||||
state_save_register_UINT8( "intelfsh", chip, "master_lock", &c->master_lock, 1 );
|
||||
state_save_register_double( "intelfsh", chip, "timer_left", &c->timer_left, 1 );
|
||||
if( chip == 0 )
|
||||
{
|
||||
state_save_register_func_presave( intelfsh_presave );
|
||||
state_save_register_func_postload( intelfsh_postload );
|
||||
}
|
||||
}
|
||||
|
||||
UINT16 *intelfsh_data( int chip )
|
||||
{
|
||||
return chips[ chip ].data;
|
||||
}
|
||||
|
||||
UINT32 intelfsh_size( int chip )
|
||||
{
|
||||
return chips[ chip ].words * 2;
|
||||
}
|
||||
|
||||
void intelfsh_reset( int chip )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
|
||||
/* a hardware reset ends any operation and goes back to read array */
|
||||
c->mode = FM_NORMAL;
|
||||
c->status = 0x80;
|
||||
timer_adjust( c->timer, TIME_NEVER, 0, 0 );
|
||||
}
|
||||
|
||||
UINT16 intelfsh_read( int chip, UINT32 offset )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
|
||||
switch( c->mode )
|
||||
{
|
||||
default:
|
||||
case FM_NORMAL:
|
||||
return c->data[ offset % c->words ];
|
||||
|
||||
case FM_READSTATUS:
|
||||
return c->status;
|
||||
|
||||
case FM_READID:
|
||||
switch( offset & 0xff )
|
||||
{
|
||||
case 0: return c->maker_id;
|
||||
case 1: return c->device_id;
|
||||
case 2: return 0; /* block lock config */
|
||||
case 3: return c->master_lock;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void intelfsh_erase( int chip, UINT32 offset )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
UINT32 base, size;
|
||||
double duration;
|
||||
|
||||
if( c->type == INTELFSH_INTEL_E28F400B )
|
||||
{
|
||||
/* 16KB, 2 x 8KB, 96KB, then 128KB blocks */
|
||||
base = ( offset & 0x3ffff ) * 2;
|
||||
if( base < 0x4000 )
|
||||
{
|
||||
base = 0;
|
||||
size = 0x4000;
|
||||
duration = TIME_IN_MSEC( 300 );
|
||||
}
|
||||
else if( base < 0x8000 )
|
||||
{
|
||||
base &= 0x6000;
|
||||
size = 0x2000;
|
||||
duration = TIME_IN_MSEC( 300 );
|
||||
}
|
||||
else if( base < 0x20000 )
|
||||
{
|
||||
base = 0x8000;
|
||||
size = 0x18000;
|
||||
duration = TIME_IN_MSEC( 600 );
|
||||
}
|
||||
else
|
||||
{
|
||||
base &= 0x60000;
|
||||
size = 0x20000;
|
||||
duration = TIME_IN_MSEC( 600 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base = ( ( offset % c->words ) * 2 ) & ~0xffff;
|
||||
size = 0x10000;
|
||||
duration = TIME_IN_SEC( 1 );
|
||||
}
|
||||
memset( c->data + base / 2, 0xff, size );
|
||||
timer_adjust( c->timer, duration, chip, 0 );
|
||||
}
|
||||
|
||||
void intelfsh_write( int chip, UINT32 offset, UINT16 data )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
|
||||
switch( c->mode )
|
||||
{
|
||||
case FM_NORMAL:
|
||||
case FM_READSTATUS:
|
||||
case FM_READID:
|
||||
switch( data & 0xff )
|
||||
{
|
||||
case 0xf0:
|
||||
case 0xff: /* read array */
|
||||
c->mode = FM_NORMAL;
|
||||
break;
|
||||
case 0x90: /* read ID */
|
||||
c->mode = FM_READID;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x10: /* program */
|
||||
c->mode = FM_WRITEPART1;
|
||||
break;
|
||||
case 0x50: /* clear status */
|
||||
c->status = 0x80;
|
||||
c->mode = FM_READSTATUS;
|
||||
break;
|
||||
case 0x20: /* block erase */
|
||||
c->mode = FM_CLEARPART1;
|
||||
break;
|
||||
case 0x60: /* set master lock */
|
||||
c->mode = FM_SETMASTER;
|
||||
break;
|
||||
case 0x70: /* read status */
|
||||
c->mode = FM_READSTATUS;
|
||||
break;
|
||||
default:
|
||||
logerror( "intelfsh %d: unknown command %02x\n", chip, data & 0xff );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FM_WRITEPART1:
|
||||
c->data[ offset % c->words ] &= data;
|
||||
c->status = 0x80;
|
||||
c->mode = FM_READSTATUS;
|
||||
break;
|
||||
|
||||
case FM_CLEARPART1:
|
||||
if( ( data & 0xff ) == 0xd0 )
|
||||
{
|
||||
intelfsh_erase( chip, offset );
|
||||
c->status = 0x00;
|
||||
c->mode = FM_READSTATUS;
|
||||
}
|
||||
else
|
||||
logerror( "intelfsh %d: unexpected %02x in block erase\n", chip, data & 0xff );
|
||||
break;
|
||||
|
||||
case FM_SETMASTER:
|
||||
switch( data & 0xff )
|
||||
{
|
||||
case 0xf1:
|
||||
c->master_lock = 1;
|
||||
break;
|
||||
case 0xd0:
|
||||
c->master_lock = 0;
|
||||
break;
|
||||
default:
|
||||
logerror( "intelfsh %d: unexpected %02x in set master lock\n", chip, data & 0xff );
|
||||
break;
|
||||
}
|
||||
c->mode = FM_READSTATUS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void intelfsh_nvram_load( int chip, mame_file *file )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
UINT8 buffer[ 0x1000 ];
|
||||
UINT32 i, j;
|
||||
|
||||
for( i = 0; i < c->words; i += sizeof( buffer ) / 2 )
|
||||
{
|
||||
mame_fread( file, buffer, sizeof( buffer ) );
|
||||
for( j = 0; j < sizeof( buffer ) / 2; j++ )
|
||||
c->data[ i + j ] = buffer[ j * 2 ] | ( buffer[ j * 2 + 1 ] << 8 );
|
||||
}
|
||||
}
|
||||
|
||||
void intelfsh_nvram_save( int chip, mame_file *file )
|
||||
{
|
||||
struct intelfsh_chip *c = &chips[ chip ];
|
||||
UINT8 buffer[ 0x1000 ];
|
||||
UINT32 i, j;
|
||||
|
||||
for( i = 0; i < c->words; i += sizeof( buffer ) / 2 )
|
||||
{
|
||||
for( j = 0; j < sizeof( buffer ) / 2; j++ )
|
||||
{
|
||||
buffer[ j * 2 ] = c->data[ i + j ] & 0xff;
|
||||
buffer[ j * 2 + 1 ] = c->data[ i + j ] >> 8;
|
||||
}
|
||||
mame_fwrite( file, buffer, sizeof( buffer ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/***************************************************************************
|
||||
|
||||
Intel / Sharp 16-bit flash memories, the Intel command set
|
||||
|
||||
Backported from current MAME src/devices/machine/intelfsh.cpp (R. Belmont
|
||||
and others), the parts the 16-bit Intel chips use: read array, read ID,
|
||||
read / clear status, word program, block erase (with its time), master
|
||||
lock. The contents are host order 16-bit words, so a driver can point a
|
||||
CPU or a sound chip straight at them.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef INTELFSH_H
|
||||
#define INTELFSH_H
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
#define INTELFSH_CHIPS_MAX ( 8 )
|
||||
|
||||
enum
|
||||
{
|
||||
INTELFSH_INTEL_E28F400B = 0, /* 512KB, Intel 0x89 / 0x4471, bottom boot blocks */
|
||||
INTELFSH_INTEL_TE28F160 /* 2MB, Sharp 0xb0 / 0xd0, 64KB blocks */
|
||||
};
|
||||
|
||||
/* data: the contents (size bytes, host order words), NULL to allocate them; */
|
||||
/* they start erased. Chip 0 is the first one a driver sets up */
|
||||
void intelfsh_init( int chip, int type, UINT16 *data );
|
||||
UINT16 *intelfsh_data( int chip );
|
||||
UINT32 intelfsh_size( int chip ); /* in bytes */
|
||||
|
||||
UINT16 intelfsh_read( int chip, UINT32 offset ); /* word offset */
|
||||
void intelfsh_write( int chip, UINT32 offset, UINT16 data );
|
||||
void intelfsh_reset( int chip ); /* the reset pin: back to read array mode */
|
||||
|
||||
/* the contents in the NVRAM file, as little endian words */
|
||||
void intelfsh_nvram_load( int chip, mame_file *file );
|
||||
void intelfsh_nvram_save( int chip, mame_file *file );
|
||||
|
||||
#endif
|
||||
+26
-1
@@ -168,6 +168,14 @@ MEMORY_READ16_START( taitozoom_mn_readmem )
|
||||
{ 0xe00000, 0xe000ff, zoom_shared16_r },
|
||||
MEMORY_END
|
||||
|
||||
/* G-NET: the samples in the flashes */
|
||||
static UINT32 (*zoom_flash_samples_r)( UINT32 offset );
|
||||
|
||||
void taitozoom_set_flash( UINT32 (*samples_r)( UINT32 offset ) )
|
||||
{
|
||||
zoom_flash_samples_r = samples_r;
|
||||
}
|
||||
|
||||
MEMORY_WRITE16_START( taitozoom_mn_writemem )
|
||||
{ 0x080000, 0x0fffff, MWA16_ROM },
|
||||
{ 0x400000, 0x41ffff, zoom_ram_w },
|
||||
@@ -264,7 +272,14 @@ static int zoom_sh_start( const struct MachineSound *msound )
|
||||
vols[ 0 ] = MIXER( 100, MIXER_PAN_LEFT );
|
||||
vols[ 1 ] = MIXER( 100, MIXER_PAN_RIGHT );
|
||||
|
||||
zsg2_init( memory_region( REGION_SOUND1 ), memory_region_length( REGION_SOUND1 ) );
|
||||
if( zoom_flash_samples_r != NULL )
|
||||
{
|
||||
/* G-NET: 6MB of samples in the three flashes */
|
||||
zsg2_init( NULL, 0x600000 );
|
||||
zsg2_set_ext_read( zoom_flash_samples_r );
|
||||
}
|
||||
else
|
||||
zsg2_init( memory_region( REGION_SOUND1 ), memory_region_length( REGION_SOUND1 ) );
|
||||
zsg2_reset();
|
||||
tms57002dsp_init();
|
||||
tms57002dsp_set_empty_callback( zoom_tms_empty );
|
||||
@@ -305,6 +320,7 @@ static void taitozoom_postload( void )
|
||||
|
||||
void taitozoom_init( void )
|
||||
{
|
||||
zoom_flash_samples_r = NULL;
|
||||
mn10200_set_port_handlers( zoom_port_r, zoom_port_w );
|
||||
memset( zoom_shared, 0, sizeof( zoom_shared ) );
|
||||
|
||||
@@ -320,6 +336,15 @@ void taitozoom_init( void )
|
||||
state_save_register_func_postload( taitozoom_postload );
|
||||
}
|
||||
|
||||
void taitozoom_device_reset( void )
|
||||
{
|
||||
if( zoom_stream >= 0 )
|
||||
stream_update( zoom_stream, 0 );
|
||||
zoom_reg_address = 0;
|
||||
zsg2_reset();
|
||||
tms57002dsp_reset();
|
||||
}
|
||||
|
||||
void taitozoom_reset( void )
|
||||
{
|
||||
zoom_tms_line = -1;
|
||||
|
||||
@@ -22,6 +22,12 @@ WRITE32_HANDLER( taitozoom_shared_w );
|
||||
extern const struct Memory_ReadAddress16 taitozoom_mn_readmem[];
|
||||
extern const struct Memory_WriteAddress16 taitozoom_mn_writemem[];
|
||||
|
||||
/* Taito G-NET: the ZSG-2 samples read by the driver (in flashes), as the */
|
||||
/* use_flash mode of MAME; the MN10200 program is in REGION_CPU2 as on the */
|
||||
/* FX-1B (the driver keeps its flash there). Set before the sound starts */
|
||||
void taitozoom_set_flash( UINT32 (*samples_r)( UINT32 offset ) );
|
||||
void taitozoom_device_reset( void ); /* the reset of the board (MAME device_reset) */
|
||||
|
||||
extern struct CustomSound_interface taitozoom_custom_interface;
|
||||
|
||||
void taitozoom_init( void ); /* driver init */
|
||||
|
||||
@@ -70,11 +70,15 @@ static UINT32 read_address;
|
||||
static UINT32 *mem_copy;
|
||||
static INT16 *full_samples;
|
||||
|
||||
static UINT32 (*ext_read)(UINT32 offset);
|
||||
|
||||
static UINT32 read_memory(UINT32 offset)
|
||||
{
|
||||
const UINT8 *p;
|
||||
if (offset >= mem_blocks)
|
||||
return 0;
|
||||
if (ext_read)
|
||||
return ext_read(offset);
|
||||
p = mem_base + offset * 4;
|
||||
return p[0] | (p[1] << 8) | (p[2] << 16) | ((UINT32)p[3] << 24);
|
||||
}
|
||||
@@ -461,6 +465,7 @@ void zsg2_init(const UINT8 *rom, UINT32 rom_bytes)
|
||||
memset(zsg2_reg, 0, sizeof(zsg2_reg));
|
||||
mem_base = rom;
|
||||
mem_blocks = rom_bytes / 4;
|
||||
ext_read = NULL;
|
||||
mem_copy = auto_malloc(mem_blocks * sizeof(UINT32));
|
||||
full_samples = auto_malloc((mem_blocks * 4 + 4) * sizeof(INT16));
|
||||
memset(mem_copy, 0, mem_blocks * sizeof(UINT32));
|
||||
@@ -475,6 +480,11 @@ void zsg2_init(const UINT8 *rom, UINT32 rom_bytes)
|
||||
gain_tab[0] = 0;
|
||||
}
|
||||
|
||||
void zsg2_set_ext_read(UINT32 (*read)(UINT32 offset))
|
||||
{
|
||||
ext_read = read;
|
||||
}
|
||||
|
||||
void zsg2_reset(void)
|
||||
{
|
||||
int ch, reg;
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
/* the sample ROM, little-endian 32-bit words (any host) */
|
||||
void zsg2_init(const UINT8 *rom, UINT32 rom_bytes);
|
||||
/* instead of the ROM (after zsg2_init): the 32-bit word at a word offset */
|
||||
void zsg2_set_ext_read(UINT32 (*read)(UINT32 offset));
|
||||
void zsg2_reset(void);
|
||||
/* offset in 16-bit words, 0x000-0x3ff */
|
||||
UINT16 zsg2_read(offs_t offset);
|
||||
|
||||
Reference in new issue
Block a user