mirror of
https://github.com/libretro/mame2003-plus-libretro.git
synced 2026-11-07 04:16:07 -10:00
Save states: exact load for Ms. Pac-Man, SNK, Bubble Bobble, OPL, SCSP and Sega Model 2 (#2182)
- mspacman: the mapped ROM (decoded set or boot ROM) - snk.c: the sound command/busy register, the sprite blink parity, the tile cache marked dirty after a load - fmopl.c: the whole YM3812/YM3526/Y8950 state (channels, operators, envelopes, LFO, noise, timers, status, Delta-T ADPCM); replaces the register replay of #2045 (3812intf.c back to its earlier version) - scsp.c: chip registers, slots, LFOs, DSP, timers, MIDI FIFOs, DMA - model2: which CPU waits on the i960/copro FIFOs, the SCSP IRQ line - bublbobl: ROM bank, display enable, sound NMI, MCU port latches - m6800.c: the 6801/6803/63701 internal registers (ports, timer, TCSR, RAM control, WAI state) - mb86233.c: the stall flag Claude-Session: https://claude.ai/code/session_01N3fzdsnzkQVtgYtYzqepjX Co-authored-by: Claude <[email protected]>
This commit is contained in:
1 parent
0ad96d5104
commit
d7117cdcdc
12 files changed
+472
-55
No files matched your search
@@ -554,6 +554,24 @@ static void state_register(const char *type)
|
||||
state_save_register_UINT8 (type, cpu, "NMI_STATE", &m6800.nmi_state, 1);
|
||||
state_save_register_UINT8 (type, cpu, "IRQ_STATE", &m6800.irq_state[M6800_IRQ_LINE], 1);
|
||||
state_save_register_UINT8 (type, cpu, "TIN_STATE", &m6800.irq_state[M6800_TIN_LINE], 1);
|
||||
state_save_register_UINT16(type, cpu, "PPC", &m6800.ppc.w.l, 1);
|
||||
state_save_register_UINT8 (type, cpu, "WAI_STATE", &m6800.wai_state, 1);
|
||||
state_save_register_UINT8 (type, cpu, "IC_EDDGE", &m6800.ic_eddge, 1);
|
||||
state_save_register_int (type, cpu, "EXTRA_CYCLES", &m6800.extra_cycles);
|
||||
/* the internal registers of the 6801/6803/63701: ports, timer, RAM control */
|
||||
state_save_register_UINT8 (type, cpu, "PORT1_DDR", &m6800.port1_ddr, 1);
|
||||
state_save_register_UINT8 (type, cpu, "PORT2_DDR", &m6800.port2_ddr, 1);
|
||||
state_save_register_UINT8 (type, cpu, "PORT1_DATA", &m6800.port1_data, 1);
|
||||
state_save_register_UINT8 (type, cpu, "PORT2_DATA", &m6800.port2_data, 1);
|
||||
state_save_register_UINT8 (type, cpu, "TCSR", &m6800.tcsr, 1);
|
||||
state_save_register_UINT8 (type, cpu, "PENDING_TCSR", &m6800.pending_tcsr, 1);
|
||||
state_save_register_UINT8 (type, cpu, "IRQ2", &m6800.irq2, 1);
|
||||
state_save_register_UINT8 (type, cpu, "RAM_CTRL", &m6800.ram_ctrl, 1);
|
||||
state_save_register_UINT32(type, cpu, "COUNTER", &m6800.counter.d, 1);
|
||||
state_save_register_UINT32(type, cpu, "OUTPUT_COMPARE", &m6800.output_compare.d, 1);
|
||||
state_save_register_UINT16(type, cpu, "INPUT_CAPTURE", &m6800.input_capture, 1);
|
||||
state_save_register_UINT32(type, cpu, "TIMER_OVER", &m6800.timer_over.d, 1);
|
||||
state_save_register_UINT32(type, cpu, "TIMER_NEXT", &timer_next, 1);
|
||||
}
|
||||
|
||||
void m6800_init(void)
|
||||
|
||||
@@ -1160,6 +1160,8 @@ void mb86233_init( void )
|
||||
state_save_register_int( "mb86233", cpu, "gpio1", &mb.gpio[ 1 ] );
|
||||
state_save_register_int( "mb86233", cpu, "gpio2", &mb.gpio[ 2 ] );
|
||||
state_save_register_int( "mb86233", cpu, "gpio3", &mb.gpio[ 3 ] );
|
||||
/* a stalled FIFO access is retried when the CPU runs again */
|
||||
state_save_register_int( "mb86233", cpu, "stall", &mb.stall );
|
||||
}
|
||||
|
||||
void mb86233_reset( void *param )
|
||||
|
||||
+41
-1
@@ -138,6 +138,7 @@ CPU 3
|
||||
#include "driver.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "state.h"
|
||||
|
||||
static int ddr1, ddr2, ddr3, ddr4;
|
||||
static int port1_in, port2_in, port3_in, port4_in;
|
||||
@@ -170,6 +171,26 @@ WRITE_HANDLER( bublbobl_sh_nmi_disable_w );
|
||||
WRITE_HANDLER( bublbobl_sh_nmi_enable_w );
|
||||
|
||||
|
||||
void bublbobl_save_state(void);
|
||||
|
||||
/* save states: the M6801 ports here, the rest in machine/bublbobl_machine.c */
|
||||
static void bublbobl_register_state(void)
|
||||
{
|
||||
bublbobl_save_state();
|
||||
state_save_register_int("bublbobl", 0, "ddr1", &ddr1);
|
||||
state_save_register_int("bublbobl", 0, "ddr2", &ddr2);
|
||||
state_save_register_int("bublbobl", 0, "ddr3", &ddr3);
|
||||
state_save_register_int("bublbobl", 0, "ddr4", &ddr4);
|
||||
state_save_register_int("bublbobl", 0, "port1_in", &port1_in);
|
||||
state_save_register_int("bublbobl", 0, "port2_in", &port2_in);
|
||||
state_save_register_int("bublbobl", 0, "port3_in", &port3_in);
|
||||
state_save_register_int("bublbobl", 0, "port4_in", &port4_in);
|
||||
state_save_register_int("bublbobl", 0, "port1_out", &port1_out);
|
||||
state_save_register_int("bublbobl", 0, "port2_out", &port2_out);
|
||||
state_save_register_int("bublbobl", 0, "port3_out", &port3_out);
|
||||
state_save_register_int("bublbobl", 0, "port4_out", &port4_out);
|
||||
}
|
||||
|
||||
READ_HANDLER( bublbobl_mcu_ddr1_r )
|
||||
{
|
||||
return ddr1;
|
||||
@@ -302,6 +323,24 @@ static unsigned char portA_in,portA_out,ddrA;
|
||||
static unsigned char portB_in,portB_out,ddrB;
|
||||
static unsigned char portC_in,portC_out,ddrC;
|
||||
|
||||
static void tokio_register_state(void)
|
||||
{
|
||||
bublbobl_save_state();
|
||||
state_save_register_UINT8("tokio", 0, "from_main", &from_main, 1);
|
||||
state_save_register_UINT8("tokio", 0, "from_mcu", &from_mcu, 1);
|
||||
state_save_register_int ("tokio", 0, "mcu_sent", &mcu_sent);
|
||||
state_save_register_int ("tokio", 0, "main_sent", &main_sent);
|
||||
state_save_register_UINT8("tokio", 0, "portA_in", &portA_in, 1);
|
||||
state_save_register_UINT8("tokio", 0, "portA_out", &portA_out, 1);
|
||||
state_save_register_UINT8("tokio", 0, "ddrA", &ddrA, 1);
|
||||
state_save_register_UINT8("tokio", 0, "portB_in", &portB_in, 1);
|
||||
state_save_register_UINT8("tokio", 0, "portB_out", &portB_out, 1);
|
||||
state_save_register_UINT8("tokio", 0, "ddrB", &ddrB, 1);
|
||||
state_save_register_UINT8("tokio", 0, "portC_in", &portC_in, 1);
|
||||
state_save_register_UINT8("tokio", 0, "portC_out", &portC_out, 1);
|
||||
state_save_register_UINT8("tokio", 0, "ddrC", &ddrC, 1);
|
||||
}
|
||||
|
||||
READ_HANDLER( tokio_68705_portA_r )
|
||||
{
|
||||
return (portA_out & ddrA) | (portA_in & ~ddrA);
|
||||
@@ -1720,6 +1759,7 @@ static DRIVER_INIT( bublbobl )
|
||||
memcpy(ROM+0x08000,ROM+0x10000,0x4000);
|
||||
|
||||
bublbobl_video_enable = 1;
|
||||
bublbobl_register_state();
|
||||
}
|
||||
|
||||
static DRIVER_INIT( boblbobl )
|
||||
@@ -1745,7 +1785,7 @@ static DRIVER_INIT( tokio )
|
||||
|
||||
/* preemptively enable video, the bit is not mapped for this game and */
|
||||
/* I don't know if it even has it. */
|
||||
bublbobl_video_enable = 1;
|
||||
bublbobl_video_enable = 1; tokio_register_state();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1881,6 +1881,7 @@ static DRIVER_INIT( model2a )
|
||||
state_save_register_UINT8( "model2comm", 0, "zfg", &m2comm_zfg, 1 );
|
||||
state_save_register_UINT8( "model2", 0, "io_analog_channel", &io_analog_channel, 1 );
|
||||
state_save_register_UINT8( "model2", 0, "lightgun_mux", &m_lightgun_mux, 1 );
|
||||
state_save_register_int( "model2", 0, "scsp_last_line", &scsp_last_line );
|
||||
state_save_register_func_postload( model2_postload );
|
||||
}
|
||||
|
||||
|
||||
@@ -216,6 +216,7 @@ Credits (in alphabetical order)
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "snk.h"
|
||||
@@ -289,6 +290,14 @@ static int hard_flags;
|
||||
*/
|
||||
static int snk_sound_register;
|
||||
|
||||
/* the sound handshake register is part of the save state (the sound CPU
|
||||
went another way after loading a state in a new instance) */
|
||||
static MACHINE_INIT( snk )
|
||||
{
|
||||
snk_sound_register = 0;
|
||||
state_save_register_int("snk", 0, "sound_register", &snk_sound_register);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
static int snk_rot8( int which ){
|
||||
@@ -1058,6 +1067,7 @@ static MACHINE_DRIVER_START( tnk3 )
|
||||
|
||||
MDRV_PALETTE_INIT(aso)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(tnk3)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1094,6 +1104,7 @@ static MACHINE_DRIVER_START( athena )
|
||||
|
||||
MDRV_PALETTE_INIT(aso)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(tnk3)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1130,6 +1141,7 @@ static MACHINE_DRIVER_START( ikari )
|
||||
|
||||
MDRV_PALETTE_INIT(snk_3bpp_shadow)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(ikari)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1168,6 +1180,7 @@ static MACHINE_DRIVER_START( victroad )
|
||||
|
||||
MDRV_PALETTE_INIT(snk_3bpp_shadow)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(ikari)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1205,6 +1218,7 @@ static MACHINE_DRIVER_START( gwar )
|
||||
|
||||
MDRV_PALETTE_INIT(RRRR_GGGG_BBBB)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(gwar)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1243,6 +1257,7 @@ static MACHINE_DRIVER_START( bermudat )
|
||||
|
||||
MDRV_PALETTE_INIT(RRRR_GGGG_BBBB)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(gwar)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1280,6 +1295,7 @@ static MACHINE_DRIVER_START( psychos )
|
||||
|
||||
MDRV_PALETTE_INIT(RRRR_GGGG_BBBB)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(gwar)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1317,6 +1333,7 @@ static MACHINE_DRIVER_START( chopper1 )
|
||||
|
||||
MDRV_PALETTE_INIT(RRRR_GGGG_BBBB)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(gwar)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1354,6 +1371,7 @@ static MACHINE_DRIVER_START( tdfever )
|
||||
|
||||
MDRV_PALETTE_INIT(snk_4bpp_shadow)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(tdfever)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1391,6 +1409,7 @@ static MACHINE_DRIVER_START( tdfever2 )
|
||||
|
||||
MDRV_PALETTE_INIT(snk_4bpp_shadow)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(tdfever)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -1428,6 +1447,7 @@ static MACHINE_DRIVER_START( ftsoccer )
|
||||
|
||||
MDRV_PALETTE_INIT(snk_4bpp_shadow)
|
||||
MDRV_VIDEO_START(snk)
|
||||
MDRV_MACHINE_INIT(snk)
|
||||
MDRV_VIDEO_UPDATE(tdfever)
|
||||
|
||||
/* sound hardware */
|
||||
|
||||
@@ -10,12 +10,26 @@
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "state.h"
|
||||
|
||||
|
||||
|
||||
unsigned char *bublbobl_sharedram1,*bublbobl_sharedram2;
|
||||
extern int bublbobl_video_enable;
|
||||
|
||||
/* the ROM bank at 0x8000, -1 until the game selects one */
|
||||
static int bublbobl_bank = -1;
|
||||
|
||||
static void bublbobl_set_bank(void)
|
||||
{
|
||||
unsigned char *ROM = memory_region(REGION_CPU1);
|
||||
|
||||
if (bublbobl_bank >= 0)
|
||||
cpu_setbank(1,&ROM[0x10000 + 0x4000 * bublbobl_bank]);
|
||||
else
|
||||
cpu_setbank(1,&ROM[0x8000]);
|
||||
}
|
||||
|
||||
|
||||
READ_HANDLER( bublbobl_sharedram1_r )
|
||||
{
|
||||
@@ -41,7 +55,8 @@ WRITE_HANDLER( bublbobl_bankswitch_w )
|
||||
unsigned char *ROM = memory_region(REGION_CPU1);
|
||||
|
||||
/* bits 0-2 select ROM bank */
|
||||
cpu_setbank(1,&ROM[0x10000 + 0x4000 * ((data ^ 4) & 7)]);
|
||||
bublbobl_bank = (data ^ 4) & 7;
|
||||
cpu_setbank(1,&ROM[0x10000 + 0x4000 * bublbobl_bank]);
|
||||
|
||||
/* bit 3 n.c. */
|
||||
|
||||
@@ -65,7 +80,8 @@ WRITE_HANDLER( tokio_bankswitch_w )
|
||||
unsigned char *ROM = memory_region(REGION_CPU1);
|
||||
|
||||
/* bits 0-2 select ROM bank */
|
||||
cpu_setbank(1,&ROM[0x10000 + 0x4000 * (data & 7)]);
|
||||
bublbobl_bank = data & 7;
|
||||
cpu_setbank(1,&ROM[0x10000 + 0x4000 * bublbobl_bank]);
|
||||
|
||||
/* bits 3-7 unknown */
|
||||
}
|
||||
@@ -257,3 +273,24 @@ WRITE_HANDLER( bublbobl_68705_ddrB_w )
|
||||
{
|
||||
ddrB = data;
|
||||
}
|
||||
|
||||
|
||||
/* save states: the ROM bank, the display enable, the sound NMI and the
|
||||
68705 ports of Bubble Bobble and Tokio */
|
||||
void bublbobl_save_state(void)
|
||||
{
|
||||
bublbobl_bank = -1;
|
||||
state_save_register_int ("bublbobl", 0, "bank", &bublbobl_bank);
|
||||
state_save_register_int ("bublbobl", 0, "video_enable", &bublbobl_video_enable);
|
||||
state_save_register_int ("bublbobl", 0, "sound_nmi_enable", &sound_nmi_enable);
|
||||
state_save_register_int ("bublbobl", 0, "pending_nmi", &pending_nmi);
|
||||
state_save_register_UINT8("bublbobl", 0, "portA_in", &portA_in, 1);
|
||||
state_save_register_UINT8("bublbobl", 0, "portA_out", &portA_out, 1);
|
||||
state_save_register_UINT8("bublbobl", 0, "ddrA", &ddrA, 1);
|
||||
state_save_register_UINT8("bublbobl", 0, "portB_in", &portB_in, 1);
|
||||
state_save_register_UINT8("bublbobl", 0, "portB_out", &portB_out, 1);
|
||||
state_save_register_UINT8("bublbobl", 0, "ddrB", &ddrB, 1);
|
||||
state_save_register_int ("bublbobl", 0, "address", &address);
|
||||
state_save_register_int ("bublbobl", 0, "latch", &latch);
|
||||
state_save_register_func_postload(bublbobl_set_bank);
|
||||
}
|
||||
@@ -526,11 +526,27 @@ READ32_HANDLER( model2_copro_status_r )
|
||||
static UINT32 fifo_in_save[ FIFO_ALLOC ], fifo_out_save[ FIFO_ALLOC ];
|
||||
static int fifo_in_count, fifo_out_count;
|
||||
|
||||
static INT32 fifo_waits_save[ 4 ];
|
||||
|
||||
static void fifo_wait_load( struct m2_fifo *f, int reader_waits, int writer_waits )
|
||||
{
|
||||
f->reader_waits = reader_waits ? 1 : 0;
|
||||
f->writer_waits = writer_waits ? 1 : 0;
|
||||
if( f->reader_waits )
|
||||
cpunum_suspend( f->reader, SUSPEND_REASON_SPIN, 1 );
|
||||
if( f->writer_waits )
|
||||
cpunum_suspend( f->writer, SUSPEND_REASON_SPIN, 1 );
|
||||
}
|
||||
|
||||
static void copro_presave( void )
|
||||
{
|
||||
int i;
|
||||
fifo_in_count = fifo_in.count;
|
||||
fifo_out_count = fifo_out.count;
|
||||
fifo_waits_save[ 0 ] = fifo_in.reader_waits;
|
||||
fifo_waits_save[ 1 ] = fifo_in.writer_waits;
|
||||
fifo_waits_save[ 2 ] = fifo_out.reader_waits;
|
||||
fifo_waits_save[ 3 ] = fifo_out.writer_waits;
|
||||
for( i = 0; i < fifo_in.count; i++ )
|
||||
fifo_in_save[ i ] = fifo_in.data[ ( fifo_in.head + i ) % FIFO_ALLOC ];
|
||||
for( i = 0; i < fifo_out.count; i++ )
|
||||
@@ -548,6 +564,12 @@ static void copro_postload( void )
|
||||
fifo_out.data[ i ] = fifo_out_save[ i ];
|
||||
fifo_in.count = fifo_in_count;
|
||||
fifo_out.count = fifo_out_count;
|
||||
if( model2_copro_type == MODEL2_COPRO_SHARC )
|
||||
sharc_flags_update();
|
||||
/* the CPUs waiting on a FIFO at the save wait again, so that the
|
||||
access that ends the wait resumes them */
|
||||
fifo_wait_load( &fifo_in, fifo_waits_save[ 0 ], fifo_waits_save[ 1 ] );
|
||||
fifo_wait_load( &fifo_out, fifo_waits_save[ 2 ], fifo_waits_save[ 3 ] );
|
||||
if( tgp_booted )
|
||||
cpunum_resume( CPU_TGP, SUSPEND_REASON_HALT );
|
||||
else
|
||||
@@ -585,6 +607,7 @@ void model2_copro_init( void )
|
||||
state_save_register_UINT32( "model2tgp", 0, "fifo_out", fifo_out_save, FIFO_ALLOC );
|
||||
state_save_register_int( "model2tgp", 0, "fifo_in_count", &fifo_in_count );
|
||||
state_save_register_int( "model2tgp", 0, "fifo_out_count", &fifo_out_count );
|
||||
state_save_register_INT32( "model2tgp", 0, "fifo_waits", fifo_waits_save, 4 );
|
||||
state_save_register_func_presave( copro_presave );
|
||||
state_save_register_func_postload( copro_postload );
|
||||
}
|
||||
|
||||
+23
-5
@@ -1,6 +1,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "state.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -180,11 +181,26 @@ void mspacman_decode(void)
|
||||
}
|
||||
|
||||
|
||||
MACHINE_INIT( mspacman )
|
||||
/* the board boots from the original Pac-Man ROMs and switches to the
|
||||
decoded Ms. Pac-Man ROMs on a write to 0x5006; the switch is part of the
|
||||
save state, so that a state loaded in a new instance runs the same code */
|
||||
static UINT8 mspacman_rom_active;
|
||||
|
||||
static void mspacman_set_bank(void)
|
||||
{
|
||||
unsigned char *RAM = memory_region(REGION_CPU1);
|
||||
|
||||
cpu_setbank (1, &RAM[mspacman_rom_active ? 0x10000 : 0x00000]);
|
||||
}
|
||||
|
||||
MACHINE_INIT( mspacman )
|
||||
{
|
||||
mspacman_decode();
|
||||
cpu_setbank (1, &RAM[0x00000]);
|
||||
mspacman_rom_active = 0;
|
||||
mspacman_set_bank();
|
||||
|
||||
state_save_register_UINT8("mspacman", 0, "rom_active", &mspacman_rom_active, 1);
|
||||
state_save_register_func_postload(mspacman_set_bank);
|
||||
|
||||
machine_init_pacman();
|
||||
}
|
||||
@@ -192,7 +208,9 @@ MACHINE_INIT( mspacman )
|
||||
|
||||
WRITE_HANDLER( mspacman_activate_rom )
|
||||
{
|
||||
unsigned char *RAM = memory_region(REGION_CPU1);
|
||||
|
||||
if(data==1) cpu_setbank (1, &RAM[0x10000]);
|
||||
if (data == 1)
|
||||
{
|
||||
mspacman_rom_active = 1;
|
||||
mspacman_set_bank();
|
||||
}
|
||||
}
|
||||
+4
-47
@@ -18,7 +18,6 @@
|
||||
******************************************************************************/
|
||||
#include "driver.h"
|
||||
#include "3812intf.h"
|
||||
#include "state.h"
|
||||
#include "fm.h"
|
||||
#include "sound/fmopl.h"
|
||||
|
||||
@@ -28,42 +27,6 @@
|
||||
static int stream_3812[MAX_3812];
|
||||
static void *Timer_3812[MAX_3812*2];
|
||||
static const struct YM3812interface *intf_3812 = NULL;
|
||||
|
||||
/* The OPL core keeps no save state: the interface keeps a copy of every
|
||||
register written (and the address register), saves it, and writes it all
|
||||
back on load. That restores the channels and starts the timers again, which
|
||||
sound CPUs that wait on the timer flag or take its interrupt need. */
|
||||
static UINT8 regs_3812[MAX_3812][256];
|
||||
static UINT8 addr_3812[MAX_3812];
|
||||
|
||||
static void YM3812_postload(void)
|
||||
{
|
||||
int i, r;
|
||||
for (i = 0; i < intf_3812->num; i++)
|
||||
{
|
||||
YM3812ResetChip(i);
|
||||
for (r = 0x01; r < 0x100; r++)
|
||||
{
|
||||
if (r == 0x04)
|
||||
continue;
|
||||
YM3812Write(i, 0, r);
|
||||
YM3812Write(i, 1, regs_3812[i][r]);
|
||||
}
|
||||
/* the timers last: their load values are in place, start them (bit 7, the IRQ reset, is an action) */
|
||||
YM3812Write(i, 0, 0x04);
|
||||
YM3812Write(i, 1, regs_3812[i][0x04] & 0x63);
|
||||
YM3812Write(i, 0, addr_3812[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void YM3812_write_shadow(int n, int a, int data)
|
||||
{
|
||||
if (a == 0)
|
||||
addr_3812[n] = data;
|
||||
else
|
||||
regs_3812[n][addr_3812[n]] = data;
|
||||
YM3812Write(n, a, data);
|
||||
}
|
||||
static void IRQHandler_3812(int n,int irq)
|
||||
{
|
||||
if (intf_3812->handler[n]) (intf_3812->handler[n])(irq ? ASSERT_LINE : CLEAR_LINE);
|
||||
@@ -123,13 +86,7 @@ int YM3812_sh_start(const struct MachineSound *msound)
|
||||
|
||||
Timer_3812[i*2+0] = timer_alloc(timer_callback_3812);
|
||||
Timer_3812[i*2+1] = timer_alloc(timer_callback_3812);
|
||||
|
||||
memset(regs_3812[i], 0, sizeof(regs_3812[i]));
|
||||
addr_3812[i] = 0;
|
||||
state_save_register_UINT8("YM3812", i, "regs", regs_3812[i], 256);
|
||||
state_save_register_UINT8("YM3812", i, "address", &addr_3812[i], 1);
|
||||
}
|
||||
state_save_register_func_postload(YM3812_postload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -148,10 +105,10 @@ void YM3812_sh_reset(void)
|
||||
}
|
||||
|
||||
WRITE_HANDLER( YM3812_control_port_0_w ) {
|
||||
YM3812_write_shadow(0, 0, data);
|
||||
YM3812Write(0, 0, data);
|
||||
}
|
||||
WRITE_HANDLER( YM3812_write_port_0_w ) {
|
||||
YM3812_write_shadow(0, 1, data);
|
||||
YM3812Write(0, 1, data);
|
||||
}
|
||||
READ_HANDLER( YM3812_status_port_0_r ) {
|
||||
return YM3812Read(0, 0);
|
||||
@@ -162,10 +119,10 @@ READ_HANDLER( YM3812_read_port_0_r ) {
|
||||
|
||||
|
||||
WRITE_HANDLER( YM3812_control_port_1_w ) {
|
||||
YM3812_write_shadow(1, 0, data);
|
||||
YM3812Write(1, 0, data);
|
||||
}
|
||||
WRITE_HANDLER( YM3812_write_port_1_w ) {
|
||||
YM3812_write_shadow(1, 1, data);
|
||||
YM3812Write(1, 1, data);
|
||||
}
|
||||
READ_HANDLER( YM3812_status_port_1_r ) {
|
||||
return YM3812Read(1, 0);
|
||||
|
||||
@@ -73,6 +73,7 @@ Revision History:
|
||||
|
||||
#include "driver.h" /* use M.A.M.E. */
|
||||
|
||||
#include "state.h"
|
||||
#include "ymdeltat.h"
|
||||
|
||||
#include "fmopl.h"
|
||||
@@ -2006,6 +2007,157 @@ static int OPLTimerOver(FM_OPL *OPL,int c)
|
||||
#define MAX_OPL_CHIPS 2
|
||||
|
||||
|
||||
/* Save states: the whole chip state, so that a state loaded in a new
|
||||
instance (netplay, RunAhead with a second instance) goes on exactly as
|
||||
the running one. Only pointers are left out: connect1 is rebuilt from
|
||||
CON, and the Delta-T pan pointer is kept as its index. */
|
||||
static FM_OPL *OPL_saved[3 * MAX_OPL_CHIPS];
|
||||
static int OPL_saved_count;
|
||||
#if BUILD_Y8950
|
||||
static UINT8 OPL_deltat_pan[3 * MAX_OPL_CHIPS];
|
||||
#endif
|
||||
|
||||
static void OPL_save_presave(void)
|
||||
{
|
||||
#if BUILD_Y8950
|
||||
int i;
|
||||
for (i = 0; i < OPL_saved_count; i++)
|
||||
{
|
||||
YM_DELTAT *DELTAT = OPL_saved[i]->deltat;
|
||||
if (DELTAT && DELTAT->pan && DELTAT->output_pointer)
|
||||
OPL_deltat_pan[i] = DELTAT->pan - DELTAT->output_pointer;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void OPL_save_postload(void)
|
||||
{
|
||||
int i, ch;
|
||||
for (i = 0; i < OPL_saved_count; i++)
|
||||
{
|
||||
FM_OPL *OPL = OPL_saved[i];
|
||||
for (ch = 0; ch < 9; ch++)
|
||||
{
|
||||
OPL_SLOT *SLOT = &OPL->P_CH[ch].SLOT[SLOT1];
|
||||
SLOT->connect1 = SLOT->CON ? &output[0] : &phase_modulation;
|
||||
}
|
||||
#if BUILD_Y8950
|
||||
if (OPL->deltat && OPL->deltat->output_pointer)
|
||||
{
|
||||
OPL->deltat->pan = &OPL->deltat->output_pointer[OPL_deltat_pan[i] & 3];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void OPL_save_state(FM_OPL *OPL, const char *name, int num)
|
||||
{
|
||||
char buf[32];
|
||||
int ch, s;
|
||||
|
||||
if (OPL_saved_count >= 3 * MAX_OPL_CHIPS)
|
||||
return;
|
||||
OPL_saved[OPL_saved_count++] = OPL;
|
||||
|
||||
for (ch = 0; ch < 9; ch++)
|
||||
{
|
||||
OPL_CH *CH = &OPL->P_CH[ch];
|
||||
sprintf(buf, "%s.ch%d", name, ch);
|
||||
state_save_register_UINT32(buf, num, "block_fnum", &CH->block_fnum, 1);
|
||||
state_save_register_UINT32(buf, num, "fc", &CH->fc, 1);
|
||||
state_save_register_UINT32(buf, num, "ksl_base", &CH->ksl_base, 1);
|
||||
state_save_register_UINT8 (buf, num, "kcode", &CH->kcode, 1);
|
||||
for (s = 0; s < 2; s++)
|
||||
{
|
||||
OPL_SLOT *SLOT = &CH->SLOT[s];
|
||||
sprintf(buf, "%s.ch%d.slot%d", name, ch, s);
|
||||
state_save_register_UINT32(buf, num, "ar", &SLOT->ar, 1);
|
||||
state_save_register_UINT32(buf, num, "dr", &SLOT->dr, 1);
|
||||
state_save_register_UINT32(buf, num, "rr", &SLOT->rr, 1);
|
||||
state_save_register_UINT8 (buf, num, "KSR", &SLOT->KSR, 1);
|
||||
state_save_register_UINT8 (buf, num, "ksl", &SLOT->ksl, 1);
|
||||
state_save_register_UINT8 (buf, num, "ksr", &SLOT->ksr, 1);
|
||||
state_save_register_UINT8 (buf, num, "mul", &SLOT->mul, 1);
|
||||
state_save_register_UINT32(buf, num, "Cnt", &SLOT->Cnt, 1);
|
||||
state_save_register_UINT32(buf, num, "Incr", &SLOT->Incr, 1);
|
||||
state_save_register_UINT8 (buf, num, "FB", &SLOT->FB, 1);
|
||||
state_save_register_INT32 (buf, num, "op1_out", SLOT->op1_out, 2);
|
||||
state_save_register_UINT8 (buf, num, "CON", &SLOT->CON, 1);
|
||||
state_save_register_UINT8 (buf, num, "eg_type", &SLOT->eg_type, 1);
|
||||
state_save_register_UINT8 (buf, num, "state", &SLOT->state, 1);
|
||||
state_save_register_UINT32(buf, num, "TL", &SLOT->TL, 1);
|
||||
state_save_register_INT32 (buf, num, "TLL", &SLOT->TLL, 1);
|
||||
state_save_register_INT32 (buf, num, "volume", &SLOT->volume, 1);
|
||||
state_save_register_UINT32(buf, num, "sl", &SLOT->sl, 1);
|
||||
state_save_register_UINT8 (buf, num, "eg_sh_ar", &SLOT->eg_sh_ar, 1);
|
||||
state_save_register_UINT8 (buf, num, "eg_sel_ar", &SLOT->eg_sel_ar, 1);
|
||||
state_save_register_UINT8 (buf, num, "eg_sh_dr", &SLOT->eg_sh_dr, 1);
|
||||
state_save_register_UINT8 (buf, num, "eg_sel_dr", &SLOT->eg_sel_dr, 1);
|
||||
state_save_register_UINT8 (buf, num, "eg_sh_rr", &SLOT->eg_sh_rr, 1);
|
||||
state_save_register_UINT8 (buf, num, "eg_sel_rr", &SLOT->eg_sel_rr, 1);
|
||||
state_save_register_UINT32(buf, num, "key", &SLOT->key, 1);
|
||||
state_save_register_UINT32(buf, num, "AMmask", &SLOT->AMmask, 1);
|
||||
state_save_register_UINT8 (buf, num, "vib", &SLOT->vib, 1);
|
||||
state_save_register_UINT16(buf, num, "wavetable", &SLOT->wavetable, 1);
|
||||
}
|
||||
}
|
||||
state_save_register_UINT32(name, num, "eg_cnt", &OPL->eg_cnt, 1);
|
||||
state_save_register_UINT32(name, num, "eg_timer", &OPL->eg_timer, 1);
|
||||
state_save_register_UINT8 (name, num, "rhythm", &OPL->rhythm, 1);
|
||||
state_save_register_UINT8 (name, num, "lfo_am_depth", &OPL->lfo_am_depth, 1);
|
||||
state_save_register_UINT8 (name, num, "lfo_pm_depth_range", &OPL->lfo_pm_depth_range, 1);
|
||||
state_save_register_UINT32(name, num, "lfo_am_cnt", &OPL->lfo_am_cnt, 1);
|
||||
state_save_register_UINT32(name, num, "lfo_pm_cnt", &OPL->lfo_pm_cnt, 1);
|
||||
state_save_register_UINT32(name, num, "noise_rng", &OPL->noise_rng, 1);
|
||||
state_save_register_UINT32(name, num, "noise_p", &OPL->noise_p, 1);
|
||||
state_save_register_UINT8 (name, num, "wavesel", &OPL->wavesel, 1);
|
||||
state_save_register_UINT32(name, num, "T", OPL->T, 2);
|
||||
state_save_register_UINT8 (name, num, "st", OPL->st, 2);
|
||||
state_save_register_UINT8 (name, num, "address", &OPL->address, 1);
|
||||
state_save_register_UINT8 (name, num, "status", &OPL->status, 1);
|
||||
state_save_register_UINT8 (name, num, "statusmask", &OPL->statusmask, 1);
|
||||
state_save_register_UINT8 (name, num, "mode", &OPL->mode, 1);
|
||||
#if BUILD_Y8950
|
||||
if (OPL->deltat)
|
||||
{
|
||||
YM_DELTAT *DELTAT = OPL->deltat;
|
||||
state_save_register_UINT8 (name, num, "portDirection", &OPL->portDirection, 1);
|
||||
state_save_register_UINT8 (name, num, "portLatch", &OPL->portLatch, 1);
|
||||
sprintf(buf, "%s.deltat", name);
|
||||
state_save_register_UINT32(buf, num, "now_addr", &DELTAT->now_addr, 1);
|
||||
state_save_register_UINT32(buf, num, "now_step", &DELTAT->now_step, 1);
|
||||
state_save_register_UINT32(buf, num, "step", &DELTAT->step, 1);
|
||||
state_save_register_UINT32(buf, num, "start", &DELTAT->start, 1);
|
||||
state_save_register_UINT32(buf, num, "limit", &DELTAT->limit, 1);
|
||||
state_save_register_UINT32(buf, num, "end", &DELTAT->end, 1);
|
||||
state_save_register_UINT32(buf, num, "delta", &DELTAT->delta, 1);
|
||||
state_save_register_INT32 (buf, num, "volume", &DELTAT->volume, 1);
|
||||
state_save_register_INT32 (buf, num, "acc", &DELTAT->acc, 1);
|
||||
state_save_register_INT32 (buf, num, "adpcmd", &DELTAT->adpcmd, 1);
|
||||
state_save_register_INT32 (buf, num, "adpcml", &DELTAT->adpcml, 1);
|
||||
state_save_register_INT32 (buf, num, "prev_acc", &DELTAT->prev_acc, 1);
|
||||
state_save_register_UINT8 (buf, num, "now_data", &DELTAT->now_data, 1);
|
||||
state_save_register_UINT8 (buf, num, "CPU_data", &DELTAT->CPU_data, 1);
|
||||
state_save_register_UINT8 (buf, num, "portstate", &DELTAT->portstate, 1);
|
||||
state_save_register_UINT8 (buf, num, "control2", &DELTAT->control2, 1);
|
||||
state_save_register_UINT8 (buf, num, "portshift", &DELTAT->portshift, 1);
|
||||
state_save_register_UINT8 (buf, num, "DRAMportshift", &DELTAT->DRAMportshift, 1);
|
||||
state_save_register_UINT8 (buf, num, "memread", &DELTAT->memread, 1);
|
||||
state_save_register_UINT8 (buf, num, "PCM_BSY", &DELTAT->PCM_BSY, 1);
|
||||
state_save_register_UINT8 (buf, num, "reg", DELTAT->reg, 16);
|
||||
state_save_register_UINT8 (buf, num, "pan", &OPL_deltat_pan[OPL_saved_count - 1], 1);
|
||||
}
|
||||
#endif
|
||||
state_save_register_func_presave(OPL_save_presave);
|
||||
state_save_register_func_postload(OPL_save_postload);
|
||||
}
|
||||
|
||||
static void OPL_save_reset(void)
|
||||
{
|
||||
OPL_saved_count = 0;
|
||||
}
|
||||
|
||||
|
||||
#if (BUILD_YM3812)
|
||||
|
||||
static FM_OPL *OPL_YM3812[MAX_OPL_CHIPS]; /* array of pointers to the YM3812's */
|
||||
@@ -2032,6 +2184,7 @@ int YM3812Init(int num, int clock, int rate)
|
||||
}
|
||||
/* reset */
|
||||
YM3812ResetChip(i);
|
||||
OPL_save_state(OPL_YM3812[i], "YM3812", i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2041,6 +2194,8 @@ void YM3812Shutdown(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OPL_save_reset();
|
||||
|
||||
for (i = 0;i < YM3812NumChips; i++)
|
||||
{
|
||||
/* emulator shutdown */
|
||||
@@ -2183,6 +2338,7 @@ int YM3526Init(int num, int clock, int rate)
|
||||
}
|
||||
/* reset */
|
||||
YM3526ResetChip(i);
|
||||
OPL_save_state(OPL_YM3526[i], "YM3526", i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2192,6 +2348,8 @@ void YM3526Shutdown(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OPL_save_reset();
|
||||
|
||||
for (i = 0;i < YM3526NumChips; i++)
|
||||
{
|
||||
/* emulator shutdown */
|
||||
@@ -2352,6 +2510,7 @@ int Y8950Init(int num, int clock, int rate)
|
||||
/*OPL_Y8950[i]->deltat->read_time = 8.0 / clock;*/ /* a single byte read takes 8 cycles of main clock */
|
||||
/* reset */
|
||||
Y8950ResetChip(i);
|
||||
OPL_save_state(OPL_Y8950[i], "Y8950", i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2361,6 +2520,8 @@ void Y8950Shutdown(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OPL_save_reset();
|
||||
|
||||
for (i = 0;i < Y8950NumChips; i++)
|
||||
{
|
||||
/* emulator shutdown */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <string.h>
|
||||
#include "driver.h"
|
||||
#include "cpuintrf.h"
|
||||
#include "state.h"
|
||||
|
||||
static signed short *bufferl;
|
||||
static signed short *bufferr;
|
||||
@@ -1095,6 +1096,134 @@ static void SCSP_Update(int num, short **buf, int samples)
|
||||
SCSP_DoMasterSamples(num, samples);
|
||||
}
|
||||
|
||||
/* Save states: the chip registers, the slots (phase, envelope, LFOs),
|
||||
the effect DSP, the timers, the interrupts and the MIDI FIFOs, so that
|
||||
a state loaded in a new instance goes on exactly as the running one.
|
||||
The pointers (sample base, LFO tables) are kept as offsets. */
|
||||
static UINT32 SCSP_ss_base[MAX_SCSP][32];
|
||||
static UINT8 SCSP_ss_lfo[MAX_SCSP][32][4]; /* PLFO table, PLFO scale, ALFO table, ALFO scale */
|
||||
|
||||
static int SCSP_lfo_table_index(int *table, int alfo)
|
||||
{
|
||||
if (alfo)
|
||||
{
|
||||
if (table == ALFO_SQR) return 1;
|
||||
if (table == ALFO_TRI) return 2;
|
||||
if (table == ALFO_NOI) return 3;
|
||||
return 0;
|
||||
}
|
||||
if (table == PLFO_SQR) return 1;
|
||||
if (table == PLFO_TRI) return 2;
|
||||
if (table == PLFO_NOI) return 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int *SCSP_lfo_table(int index, int alfo)
|
||||
{
|
||||
static int *atab[4] = { ALFO_SAW, ALFO_SQR, ALFO_TRI, ALFO_NOI };
|
||||
static int *ptab[4] = { PLFO_SAW, PLFO_SQR, PLFO_TRI, PLFO_NOI };
|
||||
return alfo ? atab[index & 3] : ptab[index & 3];
|
||||
}
|
||||
|
||||
static void SCSP_presave(void)
|
||||
{
|
||||
int i, s;
|
||||
for (i = 0; i < MAX_SCSP; i++)
|
||||
for (s = 0; s < 32; s++)
|
||||
{
|
||||
struct _SLOT *slot = &SCSPs[i].Slots[s];
|
||||
SCSP_ss_base[i][s] = (slot->base && SCSPs[i].SCSPRAM) ? (UINT32)(slot->base - SCSPs[i].SCSPRAM) : 0;
|
||||
SCSP_ss_lfo[i][s][0] = slot->PLFO.table ? SCSP_lfo_table_index(slot->PLFO.table, 0) : 0;
|
||||
SCSP_ss_lfo[i][s][1] = slot->PLFO.scale ? (UINT8)((slot->PLFO.scale - PSCALES[0]) / 256) : 0;
|
||||
SCSP_ss_lfo[i][s][2] = slot->ALFO.table ? SCSP_lfo_table_index(slot->ALFO.table, 1) : 0;
|
||||
SCSP_ss_lfo[i][s][3] = slot->ALFO.scale ? (UINT8)((slot->ALFO.scale - ASCALES[0]) / 256) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void SCSP_postload(void)
|
||||
{
|
||||
int i, s;
|
||||
for (i = 0; i < MAX_SCSP; i++)
|
||||
for (s = 0; s < 32; s++)
|
||||
{
|
||||
struct _SLOT *slot = &SCSPs[i].Slots[s];
|
||||
slot->base = SCSPs[i].SCSPRAM ? SCSPs[i].SCSPRAM + SCSP_ss_base[i][s] : NULL;
|
||||
slot->PLFO.table = SCSP_lfo_table(SCSP_ss_lfo[i][s][0], 0);
|
||||
slot->PLFO.scale = PSCALES[SCSP_ss_lfo[i][s][1] & 7];
|
||||
slot->ALFO.table = SCSP_lfo_table(SCSP_ss_lfo[i][s][2], 1);
|
||||
slot->ALFO.scale = ASCALES[SCSP_ss_lfo[i][s][3] & 7];
|
||||
}
|
||||
}
|
||||
|
||||
static void SCSP_save_state(int num)
|
||||
{
|
||||
char buf[32];
|
||||
int i, s;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
struct _SCSP *chip = &SCSPs[i];
|
||||
struct _SCSPDSP *DSP = &chip->DSP;
|
||||
|
||||
state_save_register_UINT16("SCSP", i, "regs", chip->udata.data, 0x30/2);
|
||||
state_save_register_int ("SCSP", i, "MvolSet", &chip->MvolSet);
|
||||
for (s = 0; s < 32; s++)
|
||||
{
|
||||
struct _SLOT *slot = &chip->Slots[s];
|
||||
sprintf(buf, "SCSP.slot%d", s);
|
||||
state_save_register_UINT16(buf, i, "regs", slot->udata.data, 0x10);
|
||||
state_save_register_UINT8 (buf, i, "active", &slot->active, 1);
|
||||
state_save_register_UINT32(buf, i, "base", &SCSP_ss_base[i][s], 1);
|
||||
state_save_register_UINT32(buf, i, "cur_addr", &slot->cur_addr, 1);
|
||||
state_save_register_UINT32(buf, i, "step", &slot->step, 1);
|
||||
state_save_register_int (buf, i, "EG.volume", &slot->EG.volume);
|
||||
state_save_register_int (buf, i, "EG.state", (int *)&slot->EG.state);
|
||||
state_save_register_int (buf, i, "EG.step", &slot->EG.step);
|
||||
state_save_register_int (buf, i, "EG.AR", &slot->EG.AR);
|
||||
state_save_register_int (buf, i, "EG.D1R", &slot->EG.D1R);
|
||||
state_save_register_int (buf, i, "EG.D2R", &slot->EG.D2R);
|
||||
state_save_register_int (buf, i, "EG.RR", &slot->EG.RR);
|
||||
state_save_register_int (buf, i, "EG.DL", &slot->EG.DL);
|
||||
state_save_register_UINT8 (buf, i, "EG.EGHOLD", &slot->EG.EGHOLD, 1);
|
||||
state_save_register_UINT8 (buf, i, "EG.LPLINK", &slot->EG.LPLINK, 1);
|
||||
state_save_register_UINT16(buf, i, "PLFO.phase", &slot->PLFO.phase, 1);
|
||||
state_save_register_UINT32(buf, i, "PLFO.phase_step", &slot->PLFO.phase_step, 1);
|
||||
state_save_register_UINT16(buf, i, "ALFO.phase", &slot->ALFO.phase, 1);
|
||||
state_save_register_UINT32(buf, i, "ALFO.phase_step", &slot->ALFO.phase_step, 1);
|
||||
state_save_register_UINT8 (buf, i, "LFO.tables", SCSP_ss_lfo[i][s], 4);
|
||||
}
|
||||
state_save_register_UINT32("SCSP.DSP", i, "RBP", &DSP->RBP, 1);
|
||||
state_save_register_UINT32("SCSP.DSP", i, "RBL", &DSP->RBL, 1);
|
||||
state_save_register_INT16 ("SCSP.DSP", i, "COEF", DSP->COEF, 64);
|
||||
state_save_register_UINT16("SCSP.DSP", i, "MADRS", DSP->MADRS, 32);
|
||||
state_save_register_UINT16("SCSP.DSP", i, "MPRO", DSP->MPRO, 128*4);
|
||||
state_save_register_INT32 ("SCSP.DSP", i, "TEMP", DSP->TEMP, 128);
|
||||
state_save_register_INT32 ("SCSP.DSP", i, "MEMS", DSP->MEMS, 32);
|
||||
state_save_register_UINT32("SCSP.DSP", i, "DEC", &DSP->DEC, 1);
|
||||
state_save_register_INT32 ("SCSP.DSP", i, "MIXS", DSP->MIXS, 16);
|
||||
state_save_register_INT16 ("SCSP.DSP", i, "EXTS", DSP->EXTS, 2);
|
||||
state_save_register_INT16 ("SCSP.DSP", i, "EFREG", DSP->EFREG, 16);
|
||||
state_save_register_int ("SCSP.DSP", i, "Stopped", &DSP->Stopped);
|
||||
state_save_register_int ("SCSP.DSP", i, "LastStep", &DSP->LastStep);
|
||||
}
|
||||
state_save_register_UINT32("SCSP", 0, "IrqTimA", &IrqTimA, 1);
|
||||
state_save_register_UINT32("SCSP", 0, "IrqTimBC", &IrqTimBC, 1);
|
||||
state_save_register_UINT32("SCSP", 0, "IrqMidi", &IrqMidi, 1);
|
||||
state_save_register_UINT8 ("SCSP", 0, "MidiOutW", &MidiOutW, 1);
|
||||
state_save_register_UINT8 ("SCSP", 0, "MidiOutR", &MidiOutR, 1);
|
||||
state_save_register_UINT8 ("SCSP", 0, "MidiStack", MidiStack, 32);
|
||||
state_save_register_UINT8 ("SCSP", 0, "MidiOutStack", MidiOutStack, 16);
|
||||
state_save_register_UINT8 ("SCSP", 0, "MidiW", &MidiW, 1);
|
||||
state_save_register_UINT8 ("SCSP", 0, "MidiR", &MidiR, 1);
|
||||
state_save_register_INT32 ("SCSP", 0, "TimPris", (INT32 *)TimPris, 3);
|
||||
state_save_register_INT32 ("SCSP", 0, "TimCnt", (INT32 *)TimCnt, 3);
|
||||
state_save_register_UINT32("SCSP", 0, "dmea", &scsp_dmea, 1);
|
||||
state_save_register_UINT16("SCSP", 0, "drga", &scsp_drga, 1);
|
||||
state_save_register_UINT16("SCSP", 0, "dtlg", &scsp_dtlg, 1);
|
||||
state_save_register_func_presave(SCSP_presave);
|
||||
state_save_register_func_postload(SCSP_postload);
|
||||
}
|
||||
|
||||
int SCSP_sh_start(const struct MachineSound *msound)
|
||||
{
|
||||
char buf[2][40];
|
||||
@@ -1124,6 +1253,8 @@ int SCSP_sh_start(const struct MachineSound *msound)
|
||||
|
||||
SCSP = &SCSPs[0];
|
||||
|
||||
SCSP_save_state(intf->num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "snk.h"
|
||||
|
||||
@@ -71,9 +72,17 @@ PALETTE_INIT( snk_4bpp_shadow )
|
||||
gfx_drawmode_table[15] = DRAWMODE_NONE;
|
||||
}
|
||||
|
||||
/* after a state load the tile cache doesn't match the restored video RAM */
|
||||
static void snk_postload(void)
|
||||
{
|
||||
memset( dirtybuffer, 0xff, MAX_VRAM_SIZE );
|
||||
}
|
||||
|
||||
VIDEO_START( snk )
|
||||
{
|
||||
snk_blink_parity = 0;
|
||||
state_save_register_int("snk", 0, "blink_parity", &snk_blink_parity);
|
||||
state_save_register_func_postload(snk_postload);
|
||||
|
||||
dirtybuffer = auto_malloc( MAX_VRAM_SIZE );
|
||||
if(!dirtybuffer) return 1;
|
||||
|
||||
Reference in new issue
Block a user