.fixed YM2413 context restore when changing options

.added YM2413 context to Master System savestates
.removed support for older savestates format (1.3.x, 1.4.x), use 1.5.0 to convert old savestates to new (1.5.x) format
This commit is contained in:
ekeeke31 2011-04-30 12:56:01 +00:00
parent d0eab7d8d9
commit 8af85558d0
18 changed files with 214 additions and 271 deletions

View File

@ -732,15 +732,12 @@ int md_cart_context_save(uint8 *state)
return bufferptr; return bufferptr;
} }
int md_cart_context_load(uint8 *state, char *version) int md_cart_context_load(uint8 *state)
{ {
int i; int i;
int bufferptr = 0; int bufferptr = 0;
uint8 offset; uint8 offset;
/* extended state (from 1.4.1 and above) */
if ((version[11] > 0x31) || (version[13] > 0x34) || (version[15] > 0x30))
{
/* cartridge mapping */ /* cartridge mapping */
for (i=0; i<0x40; i++) for (i=0; i<0x40; i++)
{ {
@ -769,7 +766,6 @@ int md_cart_context_load(uint8 *state, char *version)
load_param(svp->dram,sizeof(svp->dram)); load_param(svp->dram,sizeof(svp->dram));
load_param(&svp->ssp1601,sizeof(ssp1601_t)); load_param(&svp->ssp1601,sizeof(ssp1601_t));
} }
}
return bufferptr; return bufferptr;
} }

View File

@ -68,7 +68,7 @@ extern T_CART cart;
extern void md_cart_init(void); extern void md_cart_init(void);
extern void md_cart_reset(int hard_reset); extern void md_cart_reset(int hard_reset);
extern int md_cart_context_save(uint8 *state); extern int md_cart_context_save(uint8 *state);
extern int md_cart_context_load(uint8 *state, char *version); extern int md_cart_context_load(uint8 *state);
#endif #endif

View File

@ -355,7 +355,7 @@ int sms_cart_context_save(uint8 *state)
return bufferptr; return bufferptr;
} }
int sms_cart_context_load(uint8 *state, char *version) int sms_cart_context_load(uint8 *state)
{ {
int bufferptr = 0; int bufferptr = 0;
load_param(slot.fcr, sizeof(slot.fcr)); load_param(slot.fcr, sizeof(slot.fcr));

View File

@ -31,7 +31,7 @@ extern void sms_cart_reset(void);
extern void sms_cart_switch(int enabled); extern void sms_cart_switch(int enabled);
extern int sms_cart_region_detect(void); extern int sms_cart_region_detect(void);
extern int sms_cart_context_save(uint8 *state); extern int sms_cart_context_save(uint8 *state);
extern int sms_cart_context_load(uint8 *state, char *version); extern int sms_cart_context_load(uint8 *state);
#endif #endif

View File

@ -356,10 +356,10 @@ int slot_load(int slot, int device)
if (slot > 0) if (slot > 0)
{ {
/* Load state */ /* Load state */
if (!state_load(&savebuffer[offset])) if (state_load(&savebuffer[offset]) <= 0)
{ {
free(savebuffer); free(savebuffer);
GUI_WaitPrompt("Error","Unable to load state !"); GUI_WaitPrompt("Error","Invalid state file !");
return 0; return 0;
} }
} }

View File

@ -817,7 +817,7 @@ static int update_snd_items(void)
static void soundmenu () static void soundmenu ()
{ {
int ret, quit = 0; int ret, quit = 0;
u8 *temp; int reinit = 0;
gui_menu *m = &menu_audio; gui_menu *m = &menu_audio;
gui_item *items = m->items; gui_item *items = m->items;
float fm_volume = (float)config.fm_preamp/100.0; float fm_volume = (float)config.fm_preamp/100.0;
@ -826,7 +826,9 @@ static void soundmenu ()
float lg = (float)config.lg/100.0; float lg = (float)config.lg/100.0;
float mg = (float)config.mg/100.0; float mg = (float)config.mg/100.0;
float hg = (float)config.hg/100.0; float hg = (float)config.hg/100.0;
int offset = update_snd_items(); int offset = update_snd_items();
GUI_InitMenu(m); GUI_InitMenu(m);
GUI_SlideMenuTitle(m,strlen("Audio ")); GUI_SlideMenuTitle(m,strlen("Audio "));
@ -842,24 +844,8 @@ static void soundmenu ()
GUI_OptionBox(m,0,"FM Roll-off",(void *)&rolloff,0.1,95.0,99.9,0); GUI_OptionBox(m,0,"FM Roll-off",(void *)&rolloff,0.1,95.0,99.9,0);
sprintf (items[2].text, "FM Roll-off: %1.2f %%",rolloff); sprintf (items[2].text, "FM Roll-off: %1.2f %%",rolloff);
config.rolloff = rolloff / 100.0; config.rolloff = rolloff / 100.0;
reinit = 1;
ret = 255; ret = 255;
if (cart.romsize)
{
temp = memalign(32,YM2612GetContextSize());
if (temp)
{
/* save YM2612 context */
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
/* reinitialize audio timings */
audio_init(snd.sample_rate,snd.frame_rate);
sound_init();
/* restore YM2612 context */
YM2612Restore(temp);
free(temp);
}
}
} }
else if (ret > 2) else if (ret > 2)
{ {
@ -876,53 +862,16 @@ static void soundmenu ()
case 1: case 1:
config.hq_fm ^= 1; config.hq_fm ^= 1;
reinit = 1;
offset = update_snd_items(); offset = update_snd_items();
if (cart.romsize)
{
temp = memalign(32,YM2612GetContextSize());
if (temp)
{
/* save YM2612 context */
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
/* reinitialize audio timings */
audio_init(snd.sample_rate,snd.frame_rate);
sound_init();
/* restore YM2612 context */
YM2612Restore(temp);
free(temp);
}
}
break; break;
case 2: case 2:
config.dac_bits++; config.dac_bits++;
if (config.dac_bits > 14) if (config.dac_bits > 14) config.dac_bits = 7;
config.dac_bits = 7; else sprintf (items[offset].text, "FM Resolution: MAX");
if (config.dac_bits < 14) if (config.dac_bits < 14) sprintf (items[offset].text, "FM Resolution: %d bits", config.dac_bits);
sprintf (items[offset].text, "FM Resolution: %d bits", config.dac_bits); reinit = 1;
else
sprintf (items[offset].text, "FM Resolution: MAX");
if (cart.romsize)
{
temp = memalign(32,YM2612GetContextSize());
if (temp)
{
/* save YM2612 context */
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
/* reinitialize audio timings */
audio_init(snd.sample_rate,snd.frame_rate);
sound_init();
/* restore YM2612 context */
YM2612Restore(temp);
free(temp);
}
}
break; break;
case 3: case 3:
@ -1020,6 +969,12 @@ static void soundmenu ()
} }
} }
if (reinit && cart.romsize)
{
audio_init(snd.sample_rate,snd.frame_rate);
sound_restore();
}
GUI_DeleteMenu(m); GUI_DeleteMenu(m);
} }
@ -1039,7 +994,6 @@ static const uint16 vc_table[4][2] =
static void systemmenu () static void systemmenu ()
{ {
int ret, quit = 0; int ret, quit = 0;
u8 *temp;
gui_menu *m = &menu_system; gui_menu *m = &menu_system;
gui_item *items = m->items; gui_item *items = m->items;
@ -1102,13 +1056,6 @@ static void systemmenu ()
/* reset console region */ /* reset console region */
region_autodetect(); region_autodetect();
/* save YM2612 context */
temp = memalign(32,YM2612GetContextSize());
if (temp)
{
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
}
/* reinitialize audio timings */ /* reinitialize audio timings */
if (vdp_pal) if (vdp_pal)
{ {
@ -1120,20 +1067,9 @@ static void systemmenu ()
} }
/* reinitialize system emulation */ /* reinitialize system emulation */
system_init(); vdp_init();
io_init();
/* restore YM2612 context */ sound_restore();
if (temp)
{
YM2612Restore(temp);
free(temp);
}
/* restore SRAM */
if (config.s_auto & 1)
{
slot_autoload(0,config.s_device);
}
/* reinitialize VC max value */ /* reinitialize VC max value */
vc_max = vc_table[(reg[1] >> 2) & 3][vdp_pal]; vc_max = vc_table[(reg[1] >> 2) & 3][vdp_pal];
@ -1257,7 +1193,7 @@ static void videomenu ()
{ {
u16 state[2]; u16 state[2];
int ret, quit = 0; int ret, quit = 0;
u8 *temp; int reinit = 0;
gui_menu *m = &menu_video; gui_menu *m = &menu_video;
gui_item *items = m->items; gui_item *items = m->items;
@ -1346,85 +1282,26 @@ static void videomenu ()
} }
} }
if (!vdp_pal && cart.romsize)
{
/* save YM2612 context */
temp = memalign(32,YM2612GetContextSize());
if (temp)
{
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
}
/* reinitialize audio timings */
if (vdp_pal)
{
audio_init(snd.sample_rate, (config.tv_mode == 0) ? 50.0 : ((config.render || interlaced) ? 50.00 : (1000000.0/19968.0)));
}
else
{
audio_init(snd.sample_rate, (config.tv_mode == 1) ? 60.0 : ((config.render || interlaced) ? 59.94 : (1000000.0/16715.0)));
}
/* reinitialize sound chip emulation */
sound_init();
/* restore YM2612 context */
if (temp)
{
YM2612Restore(temp);
free(temp);
}
}
if (config.render == 1) if (config.render == 1)
sprintf (items[0].text,"Display: INTERLACED"); sprintf (items[0].text,"Display: INTERLACED");
else if (config.render == 2) else if (config.render == 2)
sprintf (items[0].text, "Display: PROGRESSIVE"); sprintf (items[0].text, "Display: PROGRESSIVE");
else else
sprintf (items[0].text, "Display: ORIGINAL"); sprintf (items[0].text, "Display: ORIGINAL");
reinit = 1;
break; break;
case 1: /*** tv mode ***/ case 1: /*** tv mode ***/
if (config.render != 2) if (config.render != 2)
{ {
config.tv_mode = (config.tv_mode + 1) % 3; config.tv_mode = (config.tv_mode + 1) % 3;
if (!vdp_pal && cart.romsize)
{
/* save YM2612 context */
temp = memalign(32,YM2612GetContextSize());
if (temp)
{
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
}
/* reinitialize audio timings */
if (vdp_pal)
{
audio_init(snd.sample_rate, (config.tv_mode == 0) ? 50.0 : ((config.render || interlaced) ? 50.00 : (1000000.0/19968.0)));
}
else
{
audio_init(snd.sample_rate, (config.tv_mode == 1) ? 60.0 : ((config.render || interlaced) ? 59.94 : (1000000.0/16715.0)));
}
/* reinitialize sound chip emulation */
sound_init();
/* restore YM2612 context */
if (temp)
{
YM2612Restore(temp);
free(temp);
}
}
if (config.tv_mode == 0) if (config.tv_mode == 0)
sprintf (items[1].text, "TV Mode: 60HZ"); sprintf (items[1].text, "TV Mode: 60HZ");
else if (config.tv_mode == 1) else if (config.tv_mode == 1)
sprintf (items[1].text, "TV Mode: 50HZ"); sprintf (items[1].text, "TV Mode: 50HZ");
else else
sprintf (items[1].text, "TV Mode: 50/60HZ"); sprintf (items[1].text, "TV Mode: 50/60HZ");
reinit = 1;
} }
else else
{ {
@ -1495,9 +1372,6 @@ static void videomenu ()
sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY"); sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY");
else else
sprintf (items[VI_OFFSET+1].text, "Borders: NONE"); sprintf (items[VI_OFFSET+1].text, "Borders: NONE");
/* update viewport */
bitmap.viewport.x = (config.overscan & 2) * 7;
break; break;
case VI_OFFSET+2: /*** aspect ratio ***/ case VI_OFFSET+2: /*** aspect ratio ***/
@ -1591,6 +1465,22 @@ static void videomenu ()
} }
} }
if (cart.romsize && reinit)
{
/* reinitialize audio timings */
if (vdp_pal)
{
audio_init(snd.sample_rate, (config.tv_mode == 0) ? 50.0 : ((config.render || interlaced) ? 50.00 : (1000000.0/19968.0)));
}
else
{
audio_init(snd.sample_rate, (config.tv_mode == 1) ? 60.0 : ((config.render || interlaced) ? 59.94 : (1000000.0/16715.0)));
}
/* reinitialize sound chips */
sound_restore();
}
GUI_DeleteMenu(m); GUI_DeleteMenu(m);
} }

View File

@ -1367,7 +1367,8 @@ void gx_video_Start(void)
tvmodes[2]->xfbMode = VI_XFBMODE_DF; tvmodes[2]->xfbMode = VI_XFBMODE_DF;
} }
/* force video update */ /* force viewport update */
bitmap.viewport.x = (config.overscan & 2) * 7;
bitmap.viewport.changed = 3; bitmap.viewport.changed = 3;
/* NTSC filter */ /* NTSC filter */

View File

@ -177,12 +177,6 @@ static void run_emulation(void)
/* VSYNC "original" mode */ /* VSYNC "original" mode */
if (!config.render && (gc_pal == vdp_pal)) if (!config.render && (gc_pal == vdp_pal))
{ {
u8 *temp = memalign(32,YM2612GetContextSize());
if (temp)
{
/* save YM2612 context */
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
/* framerate has changed, reinitialize audio timings */ /* framerate has changed, reinitialize audio timings */
if (vdp_pal) if (vdp_pal)
{ {
@ -193,13 +187,8 @@ static void run_emulation(void)
audio_init(SAMPLERATE_48KHZ, interlaced ? 59.94 : (1000000.0/16715.0)); audio_init(SAMPLERATE_48KHZ, interlaced ? 59.94 : (1000000.0/16715.0));
} }
/* reinitialize sound chip emulation */ /* reinitialize sound chips */
sound_init(); sound_restore();
/* restore YM2612 context */
YM2612Restore(temp);
free(temp);
}
} }
/* clear flag */ /* clear flag */

View File

@ -186,9 +186,59 @@ void sound_reset(void)
psg_cycles_count = 0; psg_cycles_count = 0;
} }
void sound_restore()
{
int size;
u8 *ptr, *temp;
/* save YM context */
if (system_hw != SYSTEM_PBC)
{
size = YM2612GetContextSize();
ptr = YM2612GetContextPtr();
}
else
{
size = YM2413GetContextSize();
ptr = YM2413GetContextPtr();
}
temp = malloc(size);
if (temp)
{
memcpy(temp, ptr, size);
}
/* reinitialize sound chips */
sound_init();
/* restore YM context */
if (temp)
{
if (system_hw != SYSTEM_PBC)
{
YM2612Restore(temp);
}
else
{
YM2413Restore(temp);
}
free(temp);
}
}
int sound_context_save(uint8 *state) int sound_context_save(uint8 *state)
{ {
int bufferptr = YM2612SaveContext(state); int bufferptr = 0;
if (system_hw != SYSTEM_PBC)
{
bufferptr = YM2612SaveContext(state);
}
else
{
save_param(YM2413GetContextPtr(),YM2413GetContextSize());
}
save_param(SN76489_GetContextPtr(),SN76489_GetContextSize()); save_param(SN76489_GetContextPtr(),SN76489_GetContextSize());
save_param(&fm_cycles_count,sizeof(fm_cycles_count)); save_param(&fm_cycles_count,sizeof(fm_cycles_count));
save_param(&psg_cycles_count,sizeof(psg_cycles_count)); save_param(&psg_cycles_count,sizeof(psg_cycles_count));
@ -198,16 +248,22 @@ int sound_context_save(uint8 *state)
int sound_context_load(uint8 *state, char *version) int sound_context_load(uint8 *state, char *version)
{ {
int bufferptr = YM2612LoadContext(state, version); int bufferptr = 0;
if ((system_hw != SYSTEM_PBC) || (version[15] == 0x30))
{
bufferptr = YM2612LoadContext(state);
}
else
{
load_param(YM2413GetContextPtr(),YM2413GetContextSize());
}
load_param(SN76489_GetContextPtr(),SN76489_GetContextSize()); load_param(SN76489_GetContextPtr(),SN76489_GetContextSize());
/* extended state (from 1.4.1 and above) */
if ((version[11] > 0x31) || (version[13] > 0x34) || (version[15] > 0x30))
{
load_param(&fm_cycles_count,sizeof(fm_cycles_count)); load_param(&fm_cycles_count,sizeof(fm_cycles_count));
load_param(&psg_cycles_count,sizeof(psg_cycles_count)); load_param(&psg_cycles_count,sizeof(psg_cycles_count));
fm_cycles_count = psg_cycles_count; fm_cycles_count = psg_cycles_count;
}
return bufferptr; return bufferptr;
} }

View File

@ -27,6 +27,7 @@
/* Function prototypes */ /* Function prototypes */
extern void sound_init(void); extern void sound_init(void);
extern void sound_reset(void); extern void sound_reset(void);
extern void sound_restore(void);
extern int sound_context_save(uint8 *state); extern int sound_context_save(uint8 *state);
extern int sound_context_load(uint8 *state, char *version); extern int sound_context_load(uint8 *state, char *version);
extern int sound_update(unsigned int cycles); extern int sound_update(unsigned int cycles);

View File

@ -1733,3 +1733,28 @@ void YM2413Update(long int *buffer, int length)
advance(); advance();
} }
} }
unsigned char *YM2413GetContextPtr(void)
{
return (unsigned char *)&ym2413;
}
unsigned int YM2413GetContextSize(void)
{
return sizeof(YM2413);
}
void YM2413Restore(unsigned char *buffer)
{
/* save current timings */
double clock = ym2413.clock;
int rate = ym2413.rate;
/* restore internal state */
memcpy(&ym2413, buffer, sizeof(YM2413));
/* keep current timings */
ym2413.clock = clock;
ym2413.rate = rate;
OPLL_initalize();
}

View File

@ -17,6 +17,9 @@ extern void YM2413ResetChip(void);
extern void YM2413Update(long int *buffer, int length); extern void YM2413Update(long int *buffer, int length);
extern void YM2413Write(unsigned int a, unsigned int v); extern void YM2413Write(unsigned int a, unsigned int v);
extern unsigned int YM2413Read(unsigned int a); extern unsigned int YM2413Read(unsigned int a);
extern unsigned char *YM2413GetContextPtr(void);
extern unsigned int YM2413GetContextSize(void);
extern void YM2413Restore(unsigned char *buffer);
#endif /*_H_YM2413_*/ #endif /*_H_YM2413_*/

View File

@ -2208,16 +2208,13 @@ void YM2612Restore(unsigned char *buffer)
init_tables(); init_tables();
} }
int YM2612LoadContext(unsigned char *state, char *version) int YM2612LoadContext(unsigned char *state)
{ {
int bufferptr = sizeof(YM2612); int bufferptr = sizeof(YM2612);
/* restore YM2612 context */ /* restore YM2612 context */
YM2612Restore(state); YM2612Restore(state);
/* extended state (from 1.5.0 and above) */
if ((version[11] > 0x31) || (version[13] > 0x34))
{
int c,s; int c,s;
uint8 index; uint8 index;
@ -2231,7 +2228,6 @@ int YM2612LoadContext(unsigned char *state, char *version)
ym2612.CH[c].SLOT[s].DT = ym2612.OPN.ST.dt_tab[index&7]; ym2612.CH[c].SLOT[s].DT = ym2612.OPN.ST.dt_tab[index&7];
} }
} }
}
return bufferptr; return bufferptr;
} }

View File

@ -24,7 +24,7 @@ extern unsigned int YM2612Read(void);
extern unsigned char *YM2612GetContextPtr(void); extern unsigned char *YM2612GetContextPtr(void);
extern unsigned int YM2612GetContextSize(void); extern unsigned int YM2612GetContextSize(void);
extern void YM2612Restore(unsigned char *buffer); extern void YM2612Restore(unsigned char *buffer);
extern int YM2612LoadContext(unsigned char *state, char *version); extern int YM2612LoadContext(unsigned char *state);
extern int YM2612SaveContext(unsigned char *state); extern int YM2612SaveContext(unsigned char *state);
#endif /* _YM2612_ */ #endif /* _YM2612_ */

View File

@ -47,8 +47,8 @@ int state_load(unsigned char *buffer)
return -1; return -1;
} }
/* version check (1.4.0 and above) */ /* version check (1.5.0 and above) */
if ((version[11] < 0x31) || ((version[11] == 0x31) && (version[13] < 0x34))) if ((version[11] < 0x31) || ((version[11] == 0x31) && (version[13] < 0x35)))
{ {
free(state); free(state);
return -1; return -1;
@ -84,13 +84,9 @@ int state_load(unsigned char *buffer)
} }
} }
/* 1.4.1 and above */
if ((version[11] > 0x31) || (version[13] > 0x34) || (version[15] > 0x30))
{
/* extended state */ /* extended state */
load_param(&mcycles_68k, sizeof(mcycles_68k)); load_param(&mcycles_68k, sizeof(mcycles_68k));
load_param(&mcycles_z80, sizeof(mcycles_z80)); load_param(&mcycles_z80, sizeof(mcycles_z80));
}
// IO // IO
if (system_hw == SYSTEM_PBC) if (system_hw == SYSTEM_PBC)
@ -104,7 +100,7 @@ int state_load(unsigned char *buffer)
} }
// VDP // VDP
bufferptr += vdp_context_load(&state[bufferptr], version); bufferptr += vdp_context_load(&state[bufferptr]);
// SOUND // SOUND
bufferptr += sound_context_load(&state[bufferptr], version); bufferptr += sound_context_load(&state[bufferptr], version);
@ -142,11 +138,11 @@ int state_load(unsigned char *buffer)
// Cartridge HW // Cartridge HW
if (system_hw == SYSTEM_PBC) if (system_hw == SYSTEM_PBC)
{ {
bufferptr += sms_cart_context_load(&state[bufferptr], version); bufferptr += sms_cart_context_load(&state[bufferptr]);
} }
else else
{ {
bufferptr += md_cart_context_load(&state[bufferptr], version); bufferptr += md_cart_context_load(&state[bufferptr]);
} }
free(state); free(state);

View File

@ -24,7 +24,7 @@
#define _STATE_H_ #define _STATE_H_
#define STATE_SIZE 0x48100 #define STATE_SIZE 0x48100
#define STATE_VERSION "GENPLUS-GX 1.5.0" #define STATE_VERSION "GENPLUS-GX 1.5.1"
#define load_param(param, size) \ #define load_param(param, size) \
memcpy(param, &state[bufferptr], size); \ memcpy(param, &state[bufferptr], size); \

View File

@ -167,6 +167,7 @@ void vdp_reset(void)
addr_latch = 0; addr_latch = 0;
code = 0; code = 0;
pending = 0; pending = 0;
border = 0;
hint_pending = 0; hint_pending = 0;
vint_pending = 0; vint_pending = 0;
m68k_irq_state = 0; m68k_irq_state = 0;
@ -234,6 +235,14 @@ void vdp_reset(void)
parse_satb = parse_satb_m4; parse_satb = parse_satb_m4;
update_bg_pattern_cache = update_bg_pattern_cache_m4; update_bg_pattern_cache = update_bg_pattern_cache_m4;
/* reset palette */
int i;
color_update(0x40, 0x00);
for(i = 0; i < 0x20; i ++)
{
color_update(i, 0x00);
}
/* default bus access mode */ /* default bus access mode */
vdp_68k_data_w = vdp_68k_data_w_m4; vdp_68k_data_w = vdp_68k_data_w_m4;
vdp_z80_data_w = vdp_z80_data_w_m4; vdp_z80_data_w = vdp_z80_data_w_m4;
@ -276,7 +285,7 @@ int vdp_context_save(uint8 *state)
return bufferptr; return bufferptr;
} }
int vdp_context_load(uint8 *state, char *version) int vdp_context_load(uint8 *state)
{ {
int i, bufferptr = 0; int i, bufferptr = 0;
uint8 temp_reg[0x20]; uint8 temp_reg[0x20];
@ -291,35 +300,13 @@ int vdp_context_load(uint8 *state, char *version)
load_param(&code, sizeof(code)); load_param(&code, sizeof(code));
load_param(&pending, sizeof(pending)); load_param(&pending, sizeof(pending));
load_param(&status, sizeof(status)); load_param(&status, sizeof(status));
/* different size parameter starting from 1.5.0 */
if ((version[11] > 0x31) || (version[13] > 0x34))
{
load_param(&dmafill, sizeof(dmafill)); load_param(&dmafill, sizeof(dmafill));
}
else
{
load_param(&dmafill, sizeof(uint8));
}
load_param(&hint_pending, sizeof(hint_pending)); load_param(&hint_pending, sizeof(hint_pending));
load_param(&vint_pending, sizeof(vint_pending)); load_param(&vint_pending, sizeof(vint_pending));
load_param(&m68k_irq_state, sizeof(m68k_irq_state)); load_param(&m68k_irq_state, sizeof(m68k_irq_state));
/* extended state (1.4.1 and above) */
if ((version[11] > 0x31) || (version[13] > 0x34) || (version[15] > 0x30))
{
load_param(&dma_length, sizeof(dma_length)); load_param(&dma_length, sizeof(dma_length));
load_param(&dma_type, sizeof(dma_type)); load_param(&dma_type, sizeof(dma_type));
if ((version[11] == 0x31) && (version[13] == 0x34) && (version[15] == 0x31)) /* 1.4.1 only */
{
uint16 temp;
load_param(&temp, sizeof(temp));
}
load_param(&cached_write, sizeof(cached_write)); load_param(&cached_write, sizeof(cached_write));
}
/* restore VDP registers */ /* restore VDP registers */
for (i=0;i<0x20;i++) for (i=0;i<0x20;i++)
@ -515,6 +502,7 @@ void vdp_dma_update(unsigned int cycles)
void vdp_68k_ctrl_w(unsigned int data) void vdp_68k_ctrl_w(unsigned int data)
{ {
/* Check pending flag */
if (pending == 0) if (pending == 0)
{ {
/* A single long word write instruction could have started DMA with the first word */ /* A single long word write instruction could have started DMA with the first word */
@ -531,6 +519,7 @@ void vdp_68k_ctrl_w(unsigned int data)
} }
} }
/* Check CD0-CD1 bits */
if ((data & 0xC000) == 0x8000) if ((data & 0xC000) == 0x8000)
{ {
/* VDP register write */ /* VDP register write */
@ -558,9 +547,10 @@ void vdp_68k_ctrl_w(unsigned int data)
addr = addr_latch | (addr & 0x3FFF); addr = addr_latch | (addr & 0x3FFF);
code = ((code & 0x03) | ((data >> 2) & 0x3C)); code = ((code & 0x03) | ((data >> 2) & 0x3C));
/* Detect DMA operation */ /* Detect DMA operation (CD5 bit set) */
if ((code & 0x20) && (reg[1] & 0x10)) if ((code & 0x20) && (reg[1] & 0x10))
{ {
/* DMA type */
switch (reg[23] >> 6) switch (reg[23] >> 6)
{ {
case 2: case 2:
@ -1622,7 +1612,7 @@ static void vdp_bus_w(unsigned int data)
break; break;
} }
#ifdef LOGVDP #ifdef LOGERROR
default: default:
{ {
error("[%d(%d)][%d(%d)] Unknown (%d) 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, code, addr, data, m68k_get_reg (NULL, M68K_REG_PC)); error("[%d(%d)][%d(%d)] Unknown (%d) 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, code, addr, data, m68k_get_reg (NULL, M68K_REG_PC));
@ -1821,7 +1811,7 @@ static unsigned int vdp_68k_data_r_m5(void)
default: default:
{ {
/* Invalid code value */ /* Invalid code value */
#ifdef LOGVDP #ifdef LOGERROR
error("[%d(%d)][%d(%d)] Invalid (%d) 0x%x read (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, code, addr, m68k_get_reg (NULL, M68K_REG_PC)); error("[%d(%d)][%d(%d)] Invalid (%d) 0x%x read (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, code, addr, m68k_get_reg (NULL, M68K_REG_PC));
#endif #endif
break; break;

View File

@ -74,7 +74,7 @@ extern unsigned int (*vdp_z80_data_r)(void);
extern void vdp_init(void); extern void vdp_init(void);
extern void vdp_reset(void); extern void vdp_reset(void);
extern int vdp_context_save(uint8 *state); extern int vdp_context_save(uint8 *state);
extern int vdp_context_load(uint8 *state, char *version); extern int vdp_context_load(uint8 *state);
extern void vdp_dma_update(unsigned int cycles); extern void vdp_dma_update(unsigned int cycles);
extern void vdp_68k_ctrl_w(unsigned int data); extern void vdp_68k_ctrl_w(unsigned int data);
extern void vdp_z80_ctrl_w(unsigned int data); extern void vdp_z80_ctrl_w(unsigned int data);