genesis: big savestate rework. all old savestates are invalid. saveram is now stored in savestate. non-megaCD savestates should be significantly smaller than before; megaCD savestates should be slightly larger.
This commit is contained in:
parent
d81f2effb5
commit
343fbc7ae4
|
@ -108,8 +108,16 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
||||||
CoreComm.VsyncDen = fpsden;
|
CoreComm.VsyncDen = fpsden;
|
||||||
}
|
}
|
||||||
|
|
||||||
savebuff = new byte[LibGPGX.gpgx_state_size()];
|
// compute state size
|
||||||
savebuff2 = new byte[savebuff.Length + 13];
|
{
|
||||||
|
byte[] tmp = new byte[LibGPGX.gpgx_state_max_size()];
|
||||||
|
int size = LibGPGX.gpgx_state_size(tmp, tmp.Length);
|
||||||
|
if (size <= 0)
|
||||||
|
throw new Exception("Couldn't Determine GPGX internal state size!");
|
||||||
|
savebuff = new byte[size];
|
||||||
|
savebuff2 = new byte[savebuff.Length + 13];
|
||||||
|
Console.WriteLine("GPGX Internal State Size: {0}", size);
|
||||||
|
}
|
||||||
|
|
||||||
SetControllerDefinition();
|
SetControllerDefinition();
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
||||||
public static extern void gpgx_get_fps(ref int num, ref int den);
|
public static extern void gpgx_get_fps(ref int num, ref int den);
|
||||||
|
|
||||||
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern int gpgx_state_size();
|
public static extern int gpgx_state_max_size();
|
||||||
|
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gpgx_state_size(byte[] dest, int size);
|
||||||
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern bool gpgx_state_save(byte[] dest, int size);
|
public static extern bool gpgx_state_save(byte[] dest, int size);
|
||||||
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
|
|
@ -106,25 +106,36 @@ GPGX_EX void gpgx_get_fps(int *num, int *den)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GPGX_EX int gpgx_state_size(void)
|
GPGX_EX int gpgx_state_max_size(void)
|
||||||
{
|
{
|
||||||
return STATE_SIZE;
|
// original state size, plus 64K sram or 16K ebram, plus 8K ibram or seeprom control structures
|
||||||
|
return STATE_SIZE + (64 + 8) * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
GPGX_EX int gpgx_state_size(void *dest, int size)
|
||||||
|
{
|
||||||
|
int actual = 0;
|
||||||
|
if (size < gpgx_state_max_size())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
actual = state_save((unsigned char*) dest);
|
||||||
|
if (actual > size)
|
||||||
|
// fixme!
|
||||||
|
return -1;
|
||||||
|
return actual;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPGX_EX int gpgx_state_save(void *dest, int size)
|
GPGX_EX int gpgx_state_save(void *dest, int size)
|
||||||
{
|
{
|
||||||
if (size != STATE_SIZE)
|
return state_save((unsigned char*) dest) == size;
|
||||||
return 0;
|
|
||||||
|
|
||||||
return !!state_save((unsigned char*) dest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GPGX_EX int gpgx_state_load(void *src, int size)
|
GPGX_EX int gpgx_state_load(void *src, int size)
|
||||||
{
|
{
|
||||||
if (size != STATE_SIZE)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (state_load((unsigned char *) src))
|
if (state_load((unsigned char *) src) == size)
|
||||||
{
|
{
|
||||||
update_viewport();
|
update_viewport();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -200,28 +211,7 @@ GPGX_EX void gpgx_advance(void)
|
||||||
// internal: computes sram size (no brams)
|
// internal: computes sram size (no brams)
|
||||||
int saveramsize(void)
|
int saveramsize(void)
|
||||||
{
|
{
|
||||||
if (!sram.on)
|
return sram_get_actual_size();
|
||||||
return 0;
|
|
||||||
switch (sram.custom)
|
|
||||||
{
|
|
||||||
case 0: // plain bus access saveram
|
|
||||||
break;
|
|
||||||
case 1: // i2c
|
|
||||||
return eeprom_i2c.config.size_mask + 1;
|
|
||||||
case 2: // spi
|
|
||||||
return 0x10000; // it doesn't appear to mask anything internally
|
|
||||||
case 3: // 93c
|
|
||||||
return 0x10000; // SMS only and i don't have time to look into it
|
|
||||||
default:
|
|
||||||
return 0x10000; // who knows
|
|
||||||
}
|
|
||||||
// figure size for plain bus access saverams
|
|
||||||
{
|
|
||||||
int startaddr = sram.start / 8192;
|
|
||||||
int endaddr = sram.end / 8192 + 1;
|
|
||||||
int size = (endaddr - startaddr) * 8192;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GPGX_EX void gpgx_clear_sram(void)
|
GPGX_EX void gpgx_clear_sram(void)
|
||||||
|
|
|
@ -52,7 +52,7 @@ void eeprom_93c_init()
|
||||||
/* default eeprom state */
|
/* default eeprom state */
|
||||||
memset(&eeprom_93c, 0, sizeof(T_EEPROM_93C));
|
memset(&eeprom_93c, 0, sizeof(T_EEPROM_93C));
|
||||||
eeprom_93c.data = 1;
|
eeprom_93c.data = 1;
|
||||||
eeprom_93c.state = WAIT_START;
|
eeprom_93c.state = WAIT_START93;
|
||||||
sram.custom = 3;
|
sram.custom = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,19 +67,19 @@ void eeprom_93c_write(unsigned char data)
|
||||||
/* Current EEPROM state */
|
/* Current EEPROM state */
|
||||||
switch (eeprom_93c.state)
|
switch (eeprom_93c.state)
|
||||||
{
|
{
|
||||||
case WAIT_START:
|
case WAIT_START93:
|
||||||
{
|
{
|
||||||
/* Wait for START bit */
|
/* Wait for START bit */
|
||||||
if (data & (1 << BIT_DATA))
|
if (data & (1 << BIT_DATA))
|
||||||
{
|
{
|
||||||
eeprom_93c.opcode = 0;
|
eeprom_93c.opcode = 0;
|
||||||
eeprom_93c.cycles = 0;
|
eeprom_93c.cycles = 0;
|
||||||
eeprom_93c.state = GET_OPCODE;
|
eeprom_93c.state = GET_OPCODE93;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GET_OPCODE:
|
case GET_OPCODE93:
|
||||||
{
|
{
|
||||||
/* 8-bit buffer (opcode + address) */
|
/* 8-bit buffer (opcode + address) */
|
||||||
eeprom_93c.opcode |= ((data >> BIT_DATA) & 1) << (7 - eeprom_93c.cycles);
|
eeprom_93c.opcode |= ((data >> BIT_DATA) & 1) << (7 - eeprom_93c.cycles);
|
||||||
|
@ -95,7 +95,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
/* WRITE */
|
/* WRITE */
|
||||||
eeprom_93c.buffer = 0;
|
eeprom_93c.buffer = 0;
|
||||||
eeprom_93c.cycles = 0;
|
eeprom_93c.cycles = 0;
|
||||||
eeprom_93c.state = WRITE_WORD;
|
eeprom_93c.state = WRITE_WORD93;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
/* READ */
|
/* READ */
|
||||||
eeprom_93c.buffer = *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1));
|
eeprom_93c.buffer = *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1));
|
||||||
eeprom_93c.cycles = 0;
|
eeprom_93c.cycles = 0;
|
||||||
eeprom_93c.state = READ_WORD;
|
eeprom_93c.state = READ_WORD93;
|
||||||
|
|
||||||
/* Force DATA OUT */
|
/* Force DATA OUT */
|
||||||
eeprom_93c.data = 0;
|
eeprom_93c.data = 0;
|
||||||
|
@ -120,7 +120,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for next command */
|
/* wait for next command */
|
||||||
eeprom_93c.state = WAIT_STANDBY;
|
eeprom_93c.state = WAIT_STANDBY93;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
/* WRITE ALL */
|
/* WRITE ALL */
|
||||||
eeprom_93c.buffer = 0;
|
eeprom_93c.buffer = 0;
|
||||||
eeprom_93c.cycles = 0;
|
eeprom_93c.cycles = 0;
|
||||||
eeprom_93c.state = WRITE_WORD;
|
eeprom_93c.state = WRITE_WORD93;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for next command */
|
/* wait for next command */
|
||||||
eeprom_93c.state = WAIT_STANDBY;
|
eeprom_93c.state = WAIT_STANDBY93;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
eeprom_93c.we = (eeprom_93c.opcode >> 4) & 1;
|
eeprom_93c.we = (eeprom_93c.opcode >> 4) & 1;
|
||||||
|
|
||||||
/* wait for next command */
|
/* wait for next command */
|
||||||
eeprom_93c.state = WAIT_STANDBY;
|
eeprom_93c.state = WAIT_STANDBY93;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WRITE_WORD:
|
case WRITE_WORD93:
|
||||||
{
|
{
|
||||||
/* 16-bit data buffer */
|
/* 16-bit data buffer */
|
||||||
eeprom_93c.buffer |= ((data >> BIT_DATA) & 1) << (15 - eeprom_93c.cycles);
|
eeprom_93c.buffer |= ((data >> BIT_DATA) & 1) << (15 - eeprom_93c.cycles);
|
||||||
|
@ -197,12 +197,12 @@ void eeprom_93c_write(unsigned char data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for next command */
|
/* wait for next command */
|
||||||
eeprom_93c.state = WAIT_STANDBY;
|
eeprom_93c.state = WAIT_STANDBY93;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case READ_WORD:
|
case READ_WORD93:
|
||||||
{
|
{
|
||||||
/* set DATA OUT */
|
/* set DATA OUT */
|
||||||
eeprom_93c.data = ((eeprom_93c.buffer >> (15 - eeprom_93c.cycles)) & 1);
|
eeprom_93c.data = ((eeprom_93c.buffer >> (15 - eeprom_93c.cycles)) & 1);
|
||||||
|
@ -233,7 +233,7 @@ void eeprom_93c_write(unsigned char data)
|
||||||
{
|
{
|
||||||
/* standby mode */
|
/* standby mode */
|
||||||
eeprom_93c.data = 1;
|
eeprom_93c.data = 1;
|
||||||
eeprom_93c.state = WAIT_START;
|
eeprom_93c.state = WAIT_START93;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,11 @@
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
WAIT_STANDBY,
|
WAIT_STANDBY93,
|
||||||
WAIT_START,
|
WAIT_START93,
|
||||||
GET_OPCODE,
|
GET_OPCODE93,
|
||||||
WRITE_WORD,
|
WRITE_WORD93,
|
||||||
READ_WORD
|
READ_WORD93
|
||||||
} T_STATE_93C;
|
} T_STATE_93C;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
#include "eeprom_spi.h"
|
||||||
|
|
||||||
/* max supported size 64KB (25x512/95x512) */
|
/* max supported size 64KB (25x512/95x512) */
|
||||||
#define SIZE_MASK 0xffff
|
#define SIZE_MASK 0xffff
|
||||||
|
@ -48,28 +49,6 @@
|
||||||
#define BIT_HOLD (2)
|
#define BIT_HOLD (2)
|
||||||
#define BIT_CS (3)
|
#define BIT_CS (3)
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
STANDBY,
|
|
||||||
GET_OPCODE,
|
|
||||||
GET_ADDRESS,
|
|
||||||
WRITE_BYTE,
|
|
||||||
READ_BYTE
|
|
||||||
} T_STATE_SPI;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8 cs; /* !CS line state */
|
|
||||||
uint8 clk; /* SCLK line state */
|
|
||||||
uint8 out; /* SO line state */
|
|
||||||
uint8 status; /* status register */
|
|
||||||
uint8 opcode; /* 8-bit opcode */
|
|
||||||
uint8 buffer; /* 8-bit data buffer */
|
|
||||||
uint16 addr; /* 16-bit address */
|
|
||||||
uint32 cycles; /* current operation cycle */
|
|
||||||
T_STATE_SPI state; /* current operation state */
|
|
||||||
} T_EEPROM_SPI;
|
|
||||||
|
|
||||||
T_EEPROM_SPI spi_eeprom;
|
T_EEPROM_SPI spi_eeprom;
|
||||||
|
|
||||||
void eeprom_spi_init()
|
void eeprom_spi_init()
|
||||||
|
|
|
@ -39,6 +39,30 @@
|
||||||
#ifndef _EEPROM_SPI_H_
|
#ifndef _EEPROM_SPI_H_
|
||||||
#define _EEPROM_SPI_H_
|
#define _EEPROM_SPI_H_
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STANDBY,
|
||||||
|
GET_OPCODE,
|
||||||
|
GET_ADDRESS,
|
||||||
|
WRITE_BYTE,
|
||||||
|
READ_BYTE
|
||||||
|
} T_STATE_SPI;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8 cs; /* !CS line state */
|
||||||
|
uint8 clk; /* SCLK line state */
|
||||||
|
uint8 out; /* SO line state */
|
||||||
|
uint8 status; /* status register */
|
||||||
|
uint8 opcode; /* 8-bit opcode */
|
||||||
|
uint8 buffer; /* 8-bit data buffer */
|
||||||
|
uint16 addr; /* 16-bit address */
|
||||||
|
uint32 cycles; /* current operation cycle */
|
||||||
|
T_STATE_SPI state; /* current operation state */
|
||||||
|
} T_EEPROM_SPI;
|
||||||
|
|
||||||
|
extern T_EEPROM_SPI spi_eeprom;
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
extern void eeprom_spi_init();
|
extern void eeprom_spi_init();
|
||||||
extern void eeprom_spi_write(unsigned char data);
|
extern void eeprom_spi_write(unsigned char data);
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
#include "eeprom_i2c.h"
|
||||||
|
#include "eeprom_spi.h"
|
||||||
|
#include "eeprom_93c.h"
|
||||||
|
|
||||||
T_SRAM sram;
|
T_SRAM sram;
|
||||||
|
|
||||||
|
@ -69,7 +72,7 @@ void sram_init()
|
||||||
|
|
||||||
/* initialize Backup RAM */
|
/* initialize Backup RAM */
|
||||||
memset(sram.sram, 0xFF, 0x10000);
|
memset(sram.sram, 0xFF, 0x10000);
|
||||||
sram.crc = crc32(0, sram.sram, 0x10000);
|
//sram.crc = crc32(0, sram.sram, 0x10000);
|
||||||
|
|
||||||
/* retrieve informations from header */
|
/* retrieve informations from header */
|
||||||
if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41))
|
if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41))
|
||||||
|
@ -221,3 +224,74 @@ void sram_write_word(unsigned int address, unsigned int data)
|
||||||
sram.sram[address] = data >> 8;
|
sram.sram[address] = data >> 8;
|
||||||
sram.sram[address + 1] = data & 0xff;
|
sram.sram[address + 1] = data & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the variables in SRAM_T are all part of "configuration", so we don't have to save those.
|
||||||
|
// the only thing that needs to be saved is the SRAM itself and the SEEPROM struct (if applicable)
|
||||||
|
|
||||||
|
int sram_context_save(uint8 *state)
|
||||||
|
{
|
||||||
|
int bufferptr = 0;
|
||||||
|
if (!sram.on)
|
||||||
|
return 0;
|
||||||
|
save_param(sram.sram, sram_get_actual_size());
|
||||||
|
switch (sram.custom)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
save_param(&eeprom_i2c, sizeof(eeprom_i2c));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
save_param(&spi_eeprom, sizeof(spi_eeprom));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
save_param(&eeprom_93c, sizeof(eeprom_93c));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return bufferptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sram_context_load(uint8 *state)
|
||||||
|
{
|
||||||
|
int bufferptr = 0;
|
||||||
|
if (!sram.on)
|
||||||
|
return 0;
|
||||||
|
load_param(sram.sram, sram_get_actual_size());
|
||||||
|
switch (sram.custom)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
load_param(&eeprom_i2c, sizeof(eeprom_i2c));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
load_param(&spi_eeprom, sizeof(spi_eeprom));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
load_param(&eeprom_93c, sizeof(eeprom_93c));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return bufferptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sram_get_actual_size()
|
||||||
|
{
|
||||||
|
if (!sram.on)
|
||||||
|
return 0;
|
||||||
|
switch (sram.custom)
|
||||||
|
{
|
||||||
|
case 0: // plain bus access saveram
|
||||||
|
break;
|
||||||
|
case 1: // i2c
|
||||||
|
return eeprom_i2c.config.size_mask + 1;
|
||||||
|
case 2: // spi
|
||||||
|
return 0x10000; // it doesn't appear to mask anything internally
|
||||||
|
case 3: // 93c
|
||||||
|
return 0x10000; // SMS only and i don't have time to look into it
|
||||||
|
default:
|
||||||
|
return 0x10000; // who knows
|
||||||
|
}
|
||||||
|
// figure size for plain bus access saverams
|
||||||
|
{
|
||||||
|
int startaddr = sram.start / 8192;
|
||||||
|
int endaddr = sram.end / 8192 + 1;
|
||||||
|
int size = (endaddr - startaddr) * 8192;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ typedef struct
|
||||||
uint8 custom;
|
uint8 custom;
|
||||||
uint32 start;
|
uint32 start;
|
||||||
uint32 end;
|
uint32 end;
|
||||||
uint32 crc;
|
//uint32 crc;
|
||||||
uint8 *sram;
|
uint8 *sram;
|
||||||
} T_SRAM;
|
} T_SRAM;
|
||||||
|
|
||||||
|
@ -57,6 +57,10 @@ extern unsigned int sram_read_word(unsigned int address);
|
||||||
extern void sram_write_byte(unsigned int address, unsigned int data);
|
extern void sram_write_byte(unsigned int address, unsigned int data);
|
||||||
extern void sram_write_word(unsigned int address, unsigned int data);
|
extern void sram_write_word(unsigned int address, unsigned int data);
|
||||||
|
|
||||||
|
extern int sram_context_save(uint8 *state);
|
||||||
|
extern int sram_context_load(uint8 *state);
|
||||||
|
extern int sram_get_actual_size();
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
extern T_SRAM sram;
|
extern T_SRAM sram;
|
||||||
|
|
||||||
|
|
|
@ -1441,6 +1441,11 @@ int scd_context_save(uint8 *state)
|
||||||
bufferptr += md_cart_context_save(&state[bufferptr]);
|
bufferptr += md_cart_context_save(&state[bufferptr]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
save_param(scd.bram, 0x2000);
|
||||||
|
// we don't save scd.cartridge.id separately, so it must be non-changing!
|
||||||
|
if (scd.cartridge.id)
|
||||||
|
save_param(scd.cartridge.area, scd.cartridge.mask + 1);
|
||||||
|
|
||||||
return bufferptr;
|
return bufferptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1641,6 +1646,11 @@ int scd_context_load(uint8 *state)
|
||||||
bufferptr += md_cart_context_load(&state[bufferptr]);
|
bufferptr += md_cart_context_load(&state[bufferptr]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load_param(scd.bram, 0x2000);
|
||||||
|
// we don't save scd.cartridge.id separately, so it must be non-changing!
|
||||||
|
if (scd.cartridge.id)
|
||||||
|
load_param(scd.cartridge.area, scd.cartridge.mask + 1);
|
||||||
|
|
||||||
return bufferptr;
|
return bufferptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,8 @@ int state_load(unsigned char *state)
|
||||||
sms_cart_switch(~io_reg[0x0E]);
|
sms_cart_switch(~io_reg[0x0E]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bufferptr += sram_context_load(&state[bufferptr]);
|
||||||
|
|
||||||
load_param(&bitmap.viewport, sizeof(bitmap.viewport));
|
load_param(&bitmap.viewport, sizeof(bitmap.viewport));
|
||||||
|
|
||||||
return bufferptr;
|
return bufferptr;
|
||||||
|
@ -282,6 +284,8 @@ int state_save(unsigned char *state)
|
||||||
bufferptr += sms_cart_context_save(&state[bufferptr]);
|
bufferptr += sms_cart_context_save(&state[bufferptr]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bufferptr += sram_context_save(&state[bufferptr]);
|
||||||
|
|
||||||
save_param(&bitmap.viewport, sizeof(bitmap.viewport));
|
save_param(&bitmap.viewport, sizeof(bitmap.viewport));
|
||||||
|
|
||||||
/* return total size */
|
/* return total size */
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue