mirror of
https://github.com/array-in-a-matrix/SAROO.git
synced 2025-04-02 10:31:43 -04:00
add save tools
This commit is contained in:
parent
756c19e422
commit
3fb1d9af9c
8 changed files with 1467 additions and 2 deletions
4
Firm_Saturn/.gitignore
vendored
4
Firm_Saturn/.gitignore
vendored
|
@ -1,6 +1,6 @@
|
|||
|
||||
/obj/*
|
||||
/ramimage.bin
|
||||
/ramimage.elf
|
||||
/ssfirm.bin
|
||||
/ssfirm.elf
|
||||
/dump.txt
|
||||
|
||||
|
|
3
tools/savetool/.gitignore
vendored
Normal file
3
tools/savetool/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
/*.exe
|
||||
|
7
tools/savetool/Makefile
Normal file
7
tools/savetool/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
|
||||
all:
|
||||
gcc -Wall -g -o sst main.c sr_bup.c ss_bup.c sr_mems.c
|
||||
|
||||
clean:
|
||||
rm -f *.exe
|
65
tools/savetool/bup.h
Normal file
65
tools/savetool/bup.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
#ifndef _BUP_H_
|
||||
#define _BUP_H_
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char file_name[12];
|
||||
char comment[11];
|
||||
char language;
|
||||
u32 date;
|
||||
u32 data_size;
|
||||
u8 *dbuf;
|
||||
}SAVEINFO;
|
||||
|
||||
extern u8 save_buf[0x100000];
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
u8 *load_file(char *name, int *size);
|
||||
int write_file(char *file, void *buf, int size);
|
||||
|
||||
u32 get_be32(void *p);
|
||||
u32 get_be16(void *p);
|
||||
void put_be32(void *p, u32 v);
|
||||
void put_be16(void *p, u32 v);
|
||||
|
||||
void set_bitmap(u8 *bmp, int index, int val);
|
||||
SAVEINFO *load_saveraw(char *save_name);
|
||||
void bup_flush(void);
|
||||
|
||||
int sr_bup_init(u8 *buf);
|
||||
int sr_bup_list(int slot_id);
|
||||
int sr_bup_export(int slot_id, int save_id);
|
||||
int sr_bup_import(int slot_id, int save_id, char *save_name);
|
||||
int sr_bup_delete(int slot_id, int save_id);
|
||||
int sr_bup_create(char *game_id);
|
||||
|
||||
int ss_bup_init(u8 *buf);
|
||||
int ss_bup_list(int slot_id);
|
||||
int ss_bup_export(int slot_id, int save_id);
|
||||
int ss_bup_import(int slot_id, int save_id, char *save_name);
|
||||
int ss_bup_delete(int slot_id, int save_id);
|
||||
int ss_bup_create(char *game_id);
|
||||
|
||||
int sr_mems_init(u8 *buf);
|
||||
int sr_mems_list(int slot_id);
|
||||
int sr_mems_export(int slot_id, int save_id);
|
||||
int sr_mems_import(int slot_id, int save_id, char *save_name);
|
||||
int sr_mems_delete(int slot_id, int save_id);
|
||||
int sr_mems_create(char *game_id);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
367
tools/savetool/main.c
Normal file
367
tools/savetool/main.c
Normal file
|
@ -0,0 +1,367 @@
|
|||
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "bup.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
u8 *load_file(char *name, int *size)
|
||||
{
|
||||
FILE *fp;
|
||||
u8 *buf;
|
||||
|
||||
fp = fopen(name, "rb");
|
||||
if(fp==NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
*size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
buf = (u8*)malloc((*size)*2);
|
||||
fread(buf, *size, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int write_file(char *file, void *buf, int size)
|
||||
{
|
||||
FILE *fp;
|
||||
int written;
|
||||
|
||||
fp = fopen(file, "wb");
|
||||
if(fp==NULL)
|
||||
return -1;
|
||||
written = fwrite(buf, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
|
||||
u32 get_be32(void *p)
|
||||
{
|
||||
u8 *d = (u8*)p;
|
||||
return (d[0]<<24) | (d[1]<<16) | (d[2]<<8) | d[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void put_be32(void *p, u32 v)
|
||||
{
|
||||
u8 *d = (u8*)p;
|
||||
|
||||
d[0] = v>>24;
|
||||
d[1] = v>>16;
|
||||
d[2] = v>>8;
|
||||
d[3] = v;
|
||||
}
|
||||
|
||||
|
||||
u32 get_be16(void *p)
|
||||
{
|
||||
u8 *d = (u8*)p;
|
||||
return (d[0]<<8) | d[1];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void put_be16(void *p, u32 v)
|
||||
{
|
||||
u8 *d = (u8*)p;
|
||||
|
||||
d[0] = v>>8;
|
||||
d[1] = v;
|
||||
}
|
||||
|
||||
|
||||
void set_bitmap(u8 *bmp, int index, int val)
|
||||
{
|
||||
int byte = index/8;
|
||||
int mask = 1<<(index&7);
|
||||
|
||||
if(val)
|
||||
bmp[byte] |= mask;
|
||||
else
|
||||
bmp[byte] &= ~mask;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
u8 save_buf[0x100000];
|
||||
static SAVEINFO saveinfo;
|
||||
|
||||
SAVEINFO *load_saveraw(char *save_name)
|
||||
{
|
||||
SAVEINFO *sinfo = &saveinfo;
|
||||
u8 *fbuf;
|
||||
int fsize;
|
||||
|
||||
fbuf = load_file(save_name, &fsize);
|
||||
if(fbuf==NULL){
|
||||
printf("Faield to load file %s!\n", save_name);
|
||||
return NULL;
|
||||
}
|
||||
if(strcmp((char*)fbuf, "SSAVERAW")){
|
||||
printf("%s: Not a SSAVERAW file!\n", save_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(sinfo, 0, sizeof(SAVEINFO));
|
||||
memcpy(sinfo->file_name, fbuf+0x10, 11);
|
||||
memcpy(sinfo->comment, fbuf+0x20, 10);
|
||||
memcpy(&sinfo->data_size, fbuf+0x1c, 4);
|
||||
memcpy(&sinfo->date, fbuf+0x2c, 4);
|
||||
sinfo->language = fbuf[0x2b];
|
||||
|
||||
memcpy(save_buf, fbuf+0x40, fsize-0x40);
|
||||
sinfo->dbuf = save_buf;
|
||||
return sinfo;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// 0: SAROO save file
|
||||
// 1: Saturn save file
|
||||
// 2: SAROO extend save
|
||||
|
||||
static int bup_type;
|
||||
static u8 *bup_buf;
|
||||
static int bup_size;
|
||||
static char *bup_name = NULL;
|
||||
|
||||
|
||||
void bup_flush(void)
|
||||
{
|
||||
write_file(bup_name, bup_buf, bup_size);
|
||||
}
|
||||
|
||||
|
||||
int bup_create(char *game_id)
|
||||
{
|
||||
int retv;
|
||||
|
||||
if(bup_type==0){
|
||||
retv = sr_bup_create(game_id);
|
||||
}else if(bup_type==1){
|
||||
retv = ss_bup_create(game_id);
|
||||
}else if(bup_type==2){
|
||||
retv = sr_mems_create(game_id);
|
||||
}
|
||||
if(retv>0){
|
||||
bup_size += retv;
|
||||
bup_flush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
int bup_import(int slot_id, int save_id, char *save_name)
|
||||
{
|
||||
int retv;
|
||||
|
||||
if(bup_type==0){
|
||||
retv = sr_bup_import(slot_id, save_id, save_name);
|
||||
}else if(bup_type==1){
|
||||
retv = ss_bup_import(slot_id, save_id, save_name);
|
||||
}else if(bup_type==2){
|
||||
retv = sr_mems_import(slot_id, save_id, save_name);
|
||||
}
|
||||
if(retv==0){
|
||||
bup_flush();
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
int bup_delete(int slot_id, int save_id)
|
||||
{
|
||||
int retv;
|
||||
|
||||
if(bup_type==0){
|
||||
retv = sr_bup_delete(slot_id, save_id);
|
||||
}else if(bup_type==1){
|
||||
retv = ss_bup_delete(slot_id, save_id);
|
||||
}else if(bup_type==2){
|
||||
retv = sr_mems_delete(slot_id, save_id);
|
||||
}
|
||||
if(retv==0){
|
||||
bup_flush();
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
int bup_export(int slot_id, int save_id)
|
||||
{
|
||||
if(bup_type==0){
|
||||
return sr_bup_export(slot_id, save_id);
|
||||
}else if(bup_type==1){
|
||||
return ss_bup_export(slot_id, save_id);
|
||||
}else if(bup_type==2){
|
||||
return sr_mems_export(slot_id, save_id);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int bup_list(int slot_id)
|
||||
{
|
||||
if(bup_type==0){
|
||||
return sr_bup_list(slot_id);
|
||||
}else if(bup_type==1){
|
||||
return ss_bup_list(slot_id);
|
||||
}else if(bup_type==2){
|
||||
return sr_mems_list(slot_id);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int bup_load(char *bup_name)
|
||||
{
|
||||
bup_buf = load_file(bup_name, &bup_size);
|
||||
if(bup_buf==NULL)
|
||||
return -1;
|
||||
|
||||
if(strcmp((char*)bup_buf, "Saroo Save File")==0){
|
||||
bup_type = 0;
|
||||
return sr_bup_init(bup_buf);
|
||||
}
|
||||
if(strncmp((char*)bup_buf, "BackUpRam Format", 16)==0){
|
||||
bup_type = 1;
|
||||
return ss_bup_init(bup_buf);
|
||||
}
|
||||
if(bup_buf[1]=='B' && bup_buf[3]=='a' && bup_buf[5]=='c' && bup_buf[7]=='k'){
|
||||
bup_type = 1;
|
||||
return ss_bup_init(bup_buf);
|
||||
}
|
||||
if(strncmp((char*)bup_buf, "SaroMems", 8)==0){
|
||||
bup_type = 2;
|
||||
return sr_mems_init(bup_buf);
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int slot_id = -1;
|
||||
int save_id = -1;
|
||||
int create = 0;
|
||||
int import = 0;
|
||||
int delete = 0;
|
||||
char *save_name = NULL;
|
||||
char *game_id = NULL;
|
||||
|
||||
int retv;
|
||||
int p = 1;
|
||||
|
||||
|
||||
if(argc==1){
|
||||
printf("Usage: sstool save_file [-c \"gameid\"][-t n] [-s n] [-i [file]]\n");
|
||||
printf(" -t n Select save slot(for SAROO save).\n");
|
||||
printf(" -c \"gameid\" New save slot(for SAROO save).\n");
|
||||
printf(" -s n Select and Export(without -i/-d) save.\n");
|
||||
printf(" -i [file] Import save.\n");
|
||||
printf(" -d Delete save.\n");
|
||||
printf(" List save.\n");
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
while(p<argc){
|
||||
if(argv[p][0]=='-'){
|
||||
switch(argv[p][1]){
|
||||
case 't':
|
||||
if(p+1==argc)
|
||||
goto _invalid_params;
|
||||
slot_id = atoi(argv[p+1]);
|
||||
p += 1;
|
||||
break;
|
||||
case 's':
|
||||
if(p+1==argc)
|
||||
goto _invalid_params;
|
||||
save_id = atoi(argv[p+1]);
|
||||
p += 1;
|
||||
break;
|
||||
case 'c':
|
||||
if(p+1==argc)
|
||||
goto _invalid_params;
|
||||
create = 1;
|
||||
game_id = argv[p+1];
|
||||
p += 1;
|
||||
break;
|
||||
case 'i':
|
||||
import = 1;
|
||||
if(p+1<argc){
|
||||
save_name = argv[p+1];
|
||||
p += 1;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
delete = 1;
|
||||
break;
|
||||
default:
|
||||
_invalid_params:
|
||||
printf("Invalid params: %s\n", argv[p]);
|
||||
return -1;
|
||||
}
|
||||
}else if(bup_name==NULL){
|
||||
bup_name = argv[p];
|
||||
}
|
||||
p += 1;
|
||||
}
|
||||
|
||||
if(bup_name==NULL){
|
||||
printf("Need a Save file!\n");
|
||||
return -1;
|
||||
}
|
||||
if(create){
|
||||
if(game_id==NULL){
|
||||
printf("Need a Game ID!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
retv = bup_load(bup_name);
|
||||
if(retv<0){
|
||||
printf("Faield to load save file!\n");
|
||||
return retv;
|
||||
}
|
||||
|
||||
if(create){
|
||||
retv = bup_create(game_id);
|
||||
}else if(import){
|
||||
retv = bup_import(slot_id, save_id, save_name);
|
||||
}else if(delete){
|
||||
retv = bup_delete(slot_id, save_id);
|
||||
}else if(save_id>=0){
|
||||
retv = bup_export(slot_id, save_id);
|
||||
}else{
|
||||
retv = bup_list(slot_id);
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
437
tools/savetool/sr_bup.c
Normal file
437
tools/savetool/sr_bup.c
Normal file
|
@ -0,0 +1,437 @@
|
|||
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "bup.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static u8 *bup_buf;
|
||||
static u8 *bup_mem;
|
||||
|
||||
#define BUP_NON (1)
|
||||
#define BUP_UNFORMAT (2)
|
||||
#define BUP_WRITE_PROTECT (3)
|
||||
#define BUP_NOT_ENOUGH_MEMORY (4)
|
||||
#define BUP_NOT_FOUND (5)
|
||||
#define BUP_FOUND (6)
|
||||
#define BUP_NO_MATCH (7)
|
||||
#define BUP_BROKEN (8)
|
||||
|
||||
|
||||
typedef struct {
|
||||
char file_name[12];
|
||||
char comment[11];
|
||||
char language;
|
||||
u32 date;
|
||||
u32 data_size;
|
||||
u16 block_size;
|
||||
}BUPDIR;
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
u32 magic0; // 00
|
||||
u32 magic1;
|
||||
u32 total_size;
|
||||
u16 block_size;
|
||||
u16 free_block;
|
||||
u8 unuse_10[16]; // 10
|
||||
u8 gameid[16]; // 20
|
||||
u8 unuse_30[14]; // 30
|
||||
u16 first_save; // 3e
|
||||
u8 bitmap[64]; // 40
|
||||
}BUPHEADER;
|
||||
|
||||
#define BUPMEM ((BUPHEADER*)(bup_mem))
|
||||
|
||||
static u16 block_size;
|
||||
static u16 free_block;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
static int get_free_block(int pos)
|
||||
{
|
||||
int i, byte, mask;
|
||||
|
||||
for(i=pos; i<512; i++){
|
||||
byte = i/8;
|
||||
mask = 1<<(i&7);
|
||||
if( (BUPMEM->bitmap[byte]&mask) == 0 ){
|
||||
BUPMEM->bitmap[byte] |= mask;
|
||||
free_block -= 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int get_next_block(u8 *bmp, int pos)
|
||||
{
|
||||
int byte, mask;
|
||||
|
||||
while(pos<512){
|
||||
byte = pos/8;
|
||||
mask = 1<<(pos&7);
|
||||
if(bmp[byte]&mask){
|
||||
return pos;
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static u8 *get_block_addr(int id)
|
||||
{
|
||||
return (u8*)(bup_mem + block_size*id);
|
||||
}
|
||||
|
||||
|
||||
static int access_data(int block, u8 *data, int type)
|
||||
{
|
||||
u8 *bp, *bmp;
|
||||
int dsize, asize, bsize;
|
||||
|
||||
bsize = block_size;
|
||||
|
||||
bp = get_block_addr(block);
|
||||
bmp = bp+0x40;
|
||||
dsize = get_be32(bp+0x0c);
|
||||
block = 0;
|
||||
|
||||
while(dsize>0){
|
||||
block = get_next_block(bmp, block);
|
||||
bp = get_block_addr(block);
|
||||
|
||||
asize = (dsize>bsize)? bsize : dsize;
|
||||
//printf("dsize=%04x block=%04x asize=%04x\n", dsize, block, asize);
|
||||
|
||||
if(type==0){
|
||||
// read
|
||||
memcpy(data, bp, asize);
|
||||
}else{
|
||||
// write
|
||||
memcpy(bp, data, asize);
|
||||
}
|
||||
data += asize;
|
||||
dsize -= asize;
|
||||
block += 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
static int sr_bup_format(u8 *gameid)
|
||||
{
|
||||
memset(bup_mem, 0, 0x10000);
|
||||
|
||||
// SaroSave
|
||||
put_be32(&BUPMEM->magic0, 0x5361726f);
|
||||
put_be32(&BUPMEM->magic1, 0x53617665);
|
||||
put_be32(&BUPMEM->total_size, 0x10000);
|
||||
put_be16(&BUPMEM->block_size, 0x80);
|
||||
put_be16(&BUPMEM->free_block, 512-1);
|
||||
memcpy(&BUPMEM->gameid, gameid, 16);
|
||||
put_be16(&BUPMEM->first_save, 0x0000);
|
||||
|
||||
memset(&BUPMEM->bitmap, 0, 0x40);
|
||||
BUPMEM->bitmap[0] = 0x01;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int sr_bup_select(int slot_id)
|
||||
{
|
||||
char sname[20];
|
||||
|
||||
if(slot_id<0 || *(u32*)(bup_buf+slot_id*16)==0)
|
||||
return -1;
|
||||
|
||||
memcpy(sname, bup_buf+slot_id*16, 16);
|
||||
sname[16] = 0;
|
||||
printf("[%s] :\n", sname);
|
||||
bup_mem = bup_buf+slot_id*0x10000;
|
||||
|
||||
// Check "SaroSave"
|
||||
if(get_be32(&BUPMEM->magic0)!=0x5361726f || get_be32(&BUPMEM->magic1)!=0x53617665){
|
||||
printf(" empty bup memory, need format.\n");
|
||||
sr_bup_format(bup_buf+slot_id*16);
|
||||
}
|
||||
|
||||
block_size = get_be16(&BUPMEM->block_size);
|
||||
free_block = get_be16(&BUPMEM->free_block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
int sr_bup_export(int slot_id, int save_id)
|
||||
{
|
||||
int block, i;
|
||||
u8 *bp;
|
||||
|
||||
if(sr_bup_select(slot_id)<0)
|
||||
return -1;
|
||||
|
||||
i = 0;
|
||||
block = get_be16(&BUPMEM->first_save);
|
||||
while(block){
|
||||
bp = get_block_addr(block);
|
||||
if(i == save_id){
|
||||
memset(save_buf, 0, 32768);
|
||||
|
||||
strcpy((char*)save_buf, "SSAVERAW");
|
||||
memcpy(save_buf+0x10, bp+0, 11); // Filename
|
||||
memcpy(save_buf+0x1c, bp+0x0c, 4); // Size
|
||||
memcpy(save_buf+0x20, bp+0x10, 10); // Comment
|
||||
save_buf[0x2b] = bp[0x1b]; // Language
|
||||
memcpy(save_buf+0x2c, bp+0x1c, 4); // Date
|
||||
|
||||
access_data(block, save_buf+0x40, 0);
|
||||
|
||||
char fname[16];
|
||||
int fsize = get_be32(save_buf+0x1c);
|
||||
sprintf(fname, "%s.bin", save_buf+0x10);
|
||||
write_file(fname, save_buf, fsize+0x40);
|
||||
|
||||
printf("Export Save_%d: %s\n", i, fname);
|
||||
return 0;
|
||||
}
|
||||
block = get_be16(bp+0x3e);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
printf("Save_%d not found!\n", save_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int sr_bup_import(int slot_id, int save_id, char *save_name)
|
||||
{
|
||||
SAVEINFO *save;
|
||||
int block, block_need, i, last, hdr;
|
||||
u8 *bp;
|
||||
|
||||
if(sr_bup_select(slot_id)<0)
|
||||
return -1;
|
||||
|
||||
i = 0;
|
||||
last = 0;
|
||||
block = get_be16(&BUPMEM->first_save);
|
||||
while(block){
|
||||
bp = get_block_addr(block);
|
||||
if(i == save_id){
|
||||
break;
|
||||
}
|
||||
last = block;
|
||||
block = get_be16(bp+0x3e);
|
||||
i += 1;
|
||||
}
|
||||
if(block){
|
||||
// overwrite
|
||||
char sname[20];
|
||||
if(save_name==NULL){
|
||||
sprintf(sname, "%s.bin", bp);
|
||||
save_name = sname;
|
||||
}
|
||||
save = load_saveraw(save_name);
|
||||
if(save==NULL)
|
||||
return -1;
|
||||
|
||||
*(u32*)(bp+0x1c) = save->date;
|
||||
access_data(block, save->dbuf, 2);
|
||||
printf("Import %s from %s.\n", bp, save_name);
|
||||
return 0;
|
||||
}
|
||||
if(save_id>=0){
|
||||
printf("Save_%d not found!\n", save_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// new save
|
||||
save = load_saveraw(save_name);
|
||||
if(save==NULL)
|
||||
return -1;
|
||||
|
||||
// 计算所需的块数量。起始块+块列表块+数据块
|
||||
int dsize = get_be32(&save->data_size);
|
||||
block_need = (dsize+block_size-1)/(block_size);
|
||||
printf("block_need=%d\n", block_need+1);
|
||||
if((block_need+1) > free_block){
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 分配起始块
|
||||
block = get_free_block(0);
|
||||
hdr = block;
|
||||
|
||||
bp = get_block_addr(hdr);
|
||||
printf("start at %d\n", hdr);
|
||||
|
||||
// 写开始块
|
||||
memset(bp, 0, 64*2);
|
||||
memcpy(bp+0x00, save->file_name, 11);
|
||||
*(u32*)(bp+0x0c) = save->data_size;
|
||||
memcpy(bp+0x10, save->comment, 10);
|
||||
bp[0x1b] = save->language;
|
||||
*(u32*)(bp+0x1c) = save->date;
|
||||
|
||||
// 分配块
|
||||
block = 0;
|
||||
for(i=0; i<block_need; i++){
|
||||
block = get_free_block(block);
|
||||
set_bitmap(bp+0x40, block, 1);
|
||||
block += 1;
|
||||
}
|
||||
|
||||
// 写数据
|
||||
access_data(hdr, save->dbuf, 2);
|
||||
|
||||
bp = get_block_addr(last);
|
||||
put_be16(bp+0x3e, hdr);
|
||||
put_be16(&BUPMEM->free_block, free_block);
|
||||
|
||||
printf("Import %s.\n", save->file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sr_bup_delete(int slot_id, int save_id)
|
||||
{
|
||||
int block, i, last;
|
||||
u8 *bp;
|
||||
|
||||
if(sr_bup_select(slot_id)<0)
|
||||
return -1;
|
||||
|
||||
i = 0;
|
||||
last = 0;
|
||||
block = get_be16(&BUPMEM->first_save);
|
||||
while(block){
|
||||
bp = get_block_addr(block);
|
||||
if(i == save_id){
|
||||
break;
|
||||
}
|
||||
last = block;
|
||||
block = get_be16(bp+0x3e);
|
||||
i += 1;
|
||||
}
|
||||
if(block==0){
|
||||
printf("Save_%d not found!\n", save_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 释放开始块
|
||||
set_bitmap((u8*)BUPMEM->bitmap, block, 0);
|
||||
free_block += 1;
|
||||
|
||||
// 释放数据块
|
||||
u8 *bmp = bp+0x40;
|
||||
block = 0;
|
||||
while(1){
|
||||
block = get_next_block(bmp, block);
|
||||
if(block==0)
|
||||
break;
|
||||
set_bitmap((u8*)BUPMEM->bitmap, block, 0);
|
||||
free_block += 1;
|
||||
block += 1;
|
||||
}
|
||||
|
||||
// 更新last指针
|
||||
u8 *last_bp = get_block_addr(last);
|
||||
*(u16*)(last_bp+0x3e) = *(u16*)(bp+0x3e);
|
||||
|
||||
put_be16(&BUPMEM->free_block, free_block);
|
||||
|
||||
printf("Delete Save_%d.\n", save_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sr_bup_create(char *game_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("sr_bup_create: [%s]\n", game_id);
|
||||
|
||||
for(i=1; i<4096; i++){
|
||||
if(*(u32*)(bup_buf+i*16)==0)
|
||||
break;
|
||||
if(strncmp((char*)bup_buf+i*16, game_id, 16)==0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(bup_buf+i*16, game_id, 16);
|
||||
|
||||
bup_mem = bup_buf+i*0x10000;
|
||||
sr_bup_format((u8*)game_id);
|
||||
|
||||
return 0x10000;
|
||||
}
|
||||
|
||||
|
||||
int sr_bup_list(int slot_id)
|
||||
{
|
||||
int block, i, dsize, bsize;
|
||||
u8 *bp;
|
||||
|
||||
if(slot_id==-1){
|
||||
// List all slot
|
||||
for(i=1; i<4096; i++){
|
||||
char sname[20];
|
||||
if(*(u32*)(bup_buf+i*16)==0)
|
||||
break;
|
||||
memcpy(sname, bup_buf+i*16, 16);
|
||||
sname[16] = 0;
|
||||
printf("Slot_%-2d: [%s]\n", i, sname);
|
||||
}
|
||||
}else{
|
||||
// List saves in slot
|
||||
if(sr_bup_select(slot_id)<0)
|
||||
return -1;
|
||||
|
||||
i = 0;
|
||||
block = get_be16(&BUPMEM->first_save);
|
||||
while(block){
|
||||
bp = get_block_addr(block);
|
||||
|
||||
dsize = get_be32(bp+0x0c);
|
||||
bsize = (dsize+block_size-1)/(block_size);
|
||||
bsize += 1;
|
||||
|
||||
printf(" Save_%-3d: %s size=%5x block=%d\n", i, bp, dsize, bsize);
|
||||
block = get_be16(bp+0x3e);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf(" Total block: %4d Free block: %d\n\n", 512, free_block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sr_bup_init(u8 *bbuf)
|
||||
{
|
||||
bup_buf = bbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
342
tools/savetool/sr_mems.c
Normal file
342
tools/savetool/sr_mems.c
Normal file
|
@ -0,0 +1,342 @@
|
|||
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "bup.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static u8 *mems_buf;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
u32 magic0;
|
||||
u32 magic1;
|
||||
u32 total_size;
|
||||
u16 free_block;
|
||||
u16 first_save;
|
||||
u8 bitmap[1024-16];
|
||||
}MEMSHEADER;
|
||||
|
||||
#define MEMS ((MEMSHEADER*)(mems_buf))
|
||||
|
||||
static u16 block_size = 1024;
|
||||
static u16 free_block;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
static int get_free_block(int pos)
|
||||
{
|
||||
int i, byte, mask;
|
||||
|
||||
for(i=pos; i<8064; i++){
|
||||
byte = i/8;
|
||||
mask = 1<<(i&7);
|
||||
if( (MEMS->bitmap[byte]&mask) == 0 ){
|
||||
MEMS->bitmap[byte] |= mask;
|
||||
free_block -= 1;
|
||||
//printf("get_free_block(%d): %d\n", pos, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static u8 *get_block_addr(int id)
|
||||
{
|
||||
return (u8*)(mems_buf + block_size*id);
|
||||
}
|
||||
|
||||
|
||||
static int access_data(int block, u8 *data, int type)
|
||||
{
|
||||
u8 *bp, *bmp;
|
||||
int dsize, asize;
|
||||
|
||||
bp = get_block_addr(block);
|
||||
dsize = get_be32(bp+0x0c);
|
||||
if(dsize<=(block_size-64)){
|
||||
if(type==0){ // read
|
||||
memcpy(data, bp+0x40, dsize);
|
||||
}else{ // write
|
||||
memcpy(bp+0x40, data, dsize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bmp = bp+0x40;
|
||||
while(dsize>0){
|
||||
block = get_be16(bmp);
|
||||
bmp += 2;
|
||||
bp = get_block_addr(block);
|
||||
|
||||
asize = (dsize>block_size)? block_size : dsize;
|
||||
//printf("dsize=%04x block=%04x asize=%04x\n", dsize, block, asize);
|
||||
|
||||
if(type==0){ // read
|
||||
memcpy(data, bp, asize);
|
||||
}else{ // write
|
||||
memcpy(bp, data, asize);
|
||||
}
|
||||
data += asize;
|
||||
dsize -= asize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
int sr_mems_export(int slot_id, int save_id)
|
||||
{
|
||||
int block, i, index;
|
||||
u8 *bp;
|
||||
|
||||
index = 0;
|
||||
for(i=0; i<448; i++){
|
||||
bp = (u8*)(mems_buf+1024+i*16);
|
||||
if(bp[0]==0)
|
||||
continue;
|
||||
if(index == save_id){
|
||||
block = get_be16(bp+0x0e);
|
||||
bp = get_block_addr(block);
|
||||
|
||||
memset(save_buf, 0, 0x100000);
|
||||
|
||||
strcpy((char*)save_buf, "SSAVERAW");
|
||||
memcpy(save_buf+0x10, bp+0, 11); // Filename
|
||||
memcpy(save_buf+0x1c, bp+0x0c, 4); // Size
|
||||
memcpy(save_buf+0x20, bp+0x10, 10); // Comment
|
||||
save_buf[0x2b] = bp[0x1b]; // Language
|
||||
memcpy(save_buf+0x2c, bp+0x1c, 4); // Date
|
||||
|
||||
access_data(block, save_buf+0x40, 0);
|
||||
|
||||
char fname[16];
|
||||
int fsize = get_be32(save_buf+0x1c);
|
||||
sprintf(fname, "%s.bin", save_buf+0x10);
|
||||
write_file(fname, save_buf, fsize+0x40);
|
||||
|
||||
printf("Export Save_%d: %s\n", index, fname);
|
||||
return 0;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
printf("Save_%d not found!\n", save_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int sr_mems_import(int slot_id, int save_id, char *save_name)
|
||||
{
|
||||
SAVEINFO *save;
|
||||
int block, block_need, i, index, last, hdr;
|
||||
u8 *bp;
|
||||
|
||||
index = 0;
|
||||
block = 0;
|
||||
last = -1;
|
||||
for(i=0; i<448; i++){
|
||||
bp = (u8*)(mems_buf+1024+i*16);
|
||||
if(bp[0]==0){
|
||||
if(last==-1){
|
||||
last = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(index == save_id){
|
||||
block = get_be16(bp+0x0e);
|
||||
break;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if(block){
|
||||
// overwrite
|
||||
char sname[20];
|
||||
if(save_name==NULL){
|
||||
sprintf(sname, "%s.bin", bp);
|
||||
save_name = sname;
|
||||
}
|
||||
save = load_saveraw(save_name);
|
||||
if(save==NULL)
|
||||
return -1;
|
||||
|
||||
*(u32*)(bp+0x1c) = save->date;
|
||||
access_data(block, save->dbuf, 2);
|
||||
printf("Import %s from %s.\n", bp, save_name);
|
||||
return 0;
|
||||
}
|
||||
if(save_id>=0){
|
||||
printf("Save_%d not found!\n", save_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// new save
|
||||
save = load_saveraw(save_name);
|
||||
if(save==NULL)
|
||||
return -1;
|
||||
|
||||
// 计算所需的块数量。起始块+数据块
|
||||
int dsize = get_be32(&save->data_size);
|
||||
if(dsize<=(block_size-64)){
|
||||
block_need = 0;
|
||||
}else{
|
||||
block_need = (dsize+block_size-1)/(block_size);
|
||||
if((block_need+1) > free_block){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
printf("block_need=%d\n", block_need+1);
|
||||
|
||||
// 分配起始块
|
||||
block = get_free_block(0);
|
||||
hdr = block;
|
||||
|
||||
bp = get_block_addr(hdr);
|
||||
printf("start at %d\n", hdr);
|
||||
|
||||
// 写开始块
|
||||
memset(bp, 0, 1024);
|
||||
memcpy(bp+0x00, save->file_name, 11);
|
||||
*(u32*)(bp+0x0c) = save->data_size;
|
||||
memcpy(bp+0x10, save->comment, 10);
|
||||
bp[0x1b] = save->language;
|
||||
*(u32*)(bp+0x1c) = save->date;
|
||||
|
||||
// 分配块
|
||||
block = 0;
|
||||
for(i=0; i<block_need; i++){
|
||||
block = get_free_block(block);
|
||||
put_be16(bp+0x40+i*2, block);
|
||||
block += 1;
|
||||
}
|
||||
put_be16(bp+0x40+i*2, 0);
|
||||
|
||||
// 写数据
|
||||
access_data(hdr, save->dbuf, 2);
|
||||
|
||||
// 更新目录
|
||||
memcpy((u8*)mems_buf+1024+last*16, save->file_name, 11);
|
||||
put_be16(mems_buf+1024+last*16+0x0e, hdr);
|
||||
|
||||
put_be16(&MEMS->free_block, free_block);
|
||||
|
||||
printf("Import %s.\n", save->file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sr_mems_delete(int slot_id, int save_id)
|
||||
{
|
||||
int block, i, index, last;
|
||||
u8 *bp;
|
||||
|
||||
index = 0;
|
||||
block = 0;
|
||||
last = -1;
|
||||
for(i=0; i<448; i++){
|
||||
bp = (u8*)(mems_buf+1024+i*16);
|
||||
if(bp[0]==0)
|
||||
continue;
|
||||
if(index == save_id){
|
||||
block = get_be16(bp+0x0e);
|
||||
last = i;
|
||||
break;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
if(block==0){
|
||||
printf("Save_%d not found!\n", save_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bp = get_block_addr(block);
|
||||
|
||||
// 释放开始块
|
||||
set_bitmap((u8*)MEMS->bitmap, block, 0);
|
||||
free_block += 1;
|
||||
|
||||
// 释放数据块
|
||||
int dsize = get_be32(bp+0x0c);
|
||||
if(dsize>960){
|
||||
u8 *bmp = bp+0x40;
|
||||
block = 0;
|
||||
while(1){
|
||||
block = get_be16(bmp);
|
||||
if(block==0)
|
||||
break;
|
||||
set_bitmap((u8*)MEMS->bitmap, block, 0);
|
||||
free_block += 1;
|
||||
bmp += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新last指针
|
||||
memset((u8*)mems_buf+1024+last*16, 0, 16);
|
||||
|
||||
put_be16(&MEMS->free_block, free_block);
|
||||
|
||||
printf("Delete Save_%d.\n", save_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sr_mems_create(char *game_id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int sr_mems_list(int slot_id)
|
||||
{
|
||||
int block, i, index, dsize, bsize;
|
||||
u8 *bp;
|
||||
|
||||
index = 0;
|
||||
for(i=0; i<448; i++){
|
||||
bp = (u8*)(mems_buf+1024+i*16);
|
||||
if(bp[0]==0)
|
||||
continue;
|
||||
|
||||
block = get_be16(bp+0x0e);
|
||||
bp = get_block_addr(block);
|
||||
|
||||
dsize = get_be32(bp+0x0c);
|
||||
bsize = 0;
|
||||
if(dsize>960){
|
||||
bsize = (dsize+block_size-1)/(block_size);
|
||||
}
|
||||
bsize += 1;
|
||||
|
||||
printf(" Save_%-3d: %s size=%5x block=%d\n", index, bp, dsize, bsize);
|
||||
|
||||
index += 1;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf(" Total block: %4d Free block: %d\n\n", 8064, free_block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sr_mems_init(u8 *bbuf)
|
||||
{
|
||||
mems_buf = bbuf;
|
||||
free_block = get_be16(&MEMS->free_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
244
tools/savetool/ss_bup.c
Normal file
244
tools/savetool/ss_bup.c
Normal file
|
@ -0,0 +1,244 @@
|
|||
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "bup.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static u8 bup_mem[32768];
|
||||
static int ss_bup_type;
|
||||
|
||||
typedef struct {
|
||||
u32 total_size;
|
||||
u32 total_block;
|
||||
u32 block_size;
|
||||
u8 block_map[64];
|
||||
|
||||
// 描述某个存档的信息
|
||||
int dsize; // 数据大小
|
||||
int bsize; // 一共有多少块
|
||||
u16 blist[512];
|
||||
int nbp; // blist中下一块的索引
|
||||
int dp; // 块中的数据指针
|
||||
}BUPINFO;
|
||||
|
||||
|
||||
static BUPINFO bup_info;
|
||||
#define GET_BUP_INFO() (&bup_info)
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
static u8 *get_block_addr(BUPINFO *binfo, int id)
|
||||
{
|
||||
return (u8*)(bup_mem + binfo->block_size*id);
|
||||
}
|
||||
|
||||
|
||||
static void load_blist(BUPINFO *binfo, int block)
|
||||
{
|
||||
int nbp, dp, i;
|
||||
u8 *bp;
|
||||
|
||||
binfo->blist[0] = block;
|
||||
binfo->bsize = 1;
|
||||
bp = get_block_addr(binfo, block);
|
||||
|
||||
binfo->dsize = get_be32(bp+0x1e);
|
||||
if(binfo->dsize<=0x1e){
|
||||
// 数据可以放在起始块内
|
||||
binfo->nbp = 1;
|
||||
binfo->dp = 0x22;
|
||||
return;
|
||||
}else{
|
||||
nbp = 1;
|
||||
dp = 0x22;
|
||||
i = 1;
|
||||
while(1){
|
||||
block = get_be16(bp+dp);
|
||||
if(block==0)
|
||||
break;
|
||||
|
||||
binfo->blist[i] = block;
|
||||
i += 1;
|
||||
dp += 2;
|
||||
if(dp==binfo->block_size){
|
||||
// 当前块用完了,取得块列表中下一块的地址。
|
||||
bp = get_block_addr(binfo, binfo->blist[nbp]);
|
||||
nbp += 1;
|
||||
dp = 4;
|
||||
}
|
||||
}
|
||||
dp += 2;
|
||||
if(dp==binfo->block_size){
|
||||
nbp += 1;
|
||||
dp = 4;
|
||||
}
|
||||
|
||||
binfo->bsize = i;
|
||||
binfo->nbp = nbp;
|
||||
binfo->dp = dp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int read_data(BUPINFO *binfo, u8 *data)
|
||||
{
|
||||
u8 *bp;
|
||||
int dp, nbp, dsize;
|
||||
|
||||
dsize = binfo->dsize;
|
||||
nbp = binfo->nbp;
|
||||
|
||||
bp = get_block_addr(binfo, binfo->blist[nbp-1]);
|
||||
dp = binfo->dp;
|
||||
//printf("read_data: %d %d\n", binfo->blist[nbp-1], dp);
|
||||
while(dsize>0){
|
||||
*(u16*)data = *(u16*)(bp+dp);
|
||||
dp += 2;
|
||||
data += 2;
|
||||
dsize -= 2;
|
||||
if(dp==binfo->block_size){
|
||||
// 当前块用完了,取得块列表中下一块的地址。
|
||||
bp = get_block_addr(binfo, binfo->blist[nbp]);
|
||||
//printf("next block: %d %08x dsize=%04x\n", binfo->blist[nbp], bp, dsize);
|
||||
nbp += 1;
|
||||
dp = 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void scan_save(BUPINFO *binfo)
|
||||
{
|
||||
int i;
|
||||
u8 *bp;
|
||||
|
||||
memset(binfo->block_map, 0, 64);
|
||||
binfo->block_map[0] = 0x03;
|
||||
|
||||
for(i=2; i<binfo->total_block; i++){
|
||||
bp = get_block_addr(binfo, i);
|
||||
if(get_be32(bp)==0x80000000){
|
||||
// 找到了save起始块
|
||||
load_blist(binfo, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
int ss_bup_export(int slot_id, int index)
|
||||
{
|
||||
BUPINFO *binfo = GET_BUP_INFO();
|
||||
int block, i;
|
||||
u8 *bp;
|
||||
|
||||
i = 0;
|
||||
for(block=2; block<binfo->total_block; block++){
|
||||
bp = get_block_addr(binfo, block);
|
||||
if(get_be32(bp)==0x80000000){
|
||||
// 找到了save起始块
|
||||
if(i == index){
|
||||
memset(save_buf, 0, 32768);
|
||||
strcpy((char*)save_buf, "SSAVERAW");
|
||||
memcpy(save_buf+0x10, bp+4, 11); // Filename
|
||||
memcpy(save_buf+0x1c, bp+0x1e, 4); // Size
|
||||
memcpy(save_buf+0x20, bp+0x10, 10); // Comment
|
||||
save_buf[0x2b] = bp[0x0f]; // Language
|
||||
memcpy(save_buf+0x2c, bp+0x1a, 4); // Date
|
||||
|
||||
load_blist(binfo, block);
|
||||
read_data(binfo, save_buf+0x40);
|
||||
|
||||
char fname[16];
|
||||
int fsize = get_be32(save_buf+0x1c);
|
||||
sprintf(fname, "%s.bin", save_buf+0x10);
|
||||
write_file(fname, save_buf, fsize+0x40);
|
||||
|
||||
printf("Export Save_%d: %s\n", index, fname);
|
||||
return 0;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int ss_bup_import(int slot_id, int save_id, char *save_name)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int ss_bup_delete(int slot_id, int save_id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int ss_bup_create(char *game_id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int ss_bup_list(int slot_id)
|
||||
{
|
||||
BUPINFO *binfo = GET_BUP_INFO();
|
||||
int i, snum;
|
||||
u8 *bp;
|
||||
|
||||
snum = 0;
|
||||
for(i=2; i<binfo->total_block; i++){
|
||||
bp = get_block_addr(binfo, i);
|
||||
if(get_be32(bp)==0x80000000){
|
||||
// 找到了save起始块
|
||||
printf("Save_%d: %s\n", snum, bp+4);
|
||||
snum += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ss_bup_init(u8 *bbuf)
|
||||
{
|
||||
BUPINFO *binfo = GET_BUP_INFO();
|
||||
int i;
|
||||
|
||||
if(bbuf[1]=='B' && bbuf[3]=='a' && bbuf[5]=='c' && bbuf[7]=='k'){
|
||||
ss_bup_type = 0;
|
||||
for(i=0; i<32768; i++){
|
||||
bup_mem[i] = bbuf[i*2+1];
|
||||
}
|
||||
}else if(strncmp((char*)bbuf, "BackUpRam Format", 16)==0){
|
||||
ss_bup_type = 1;
|
||||
memcpy(bup_mem, bbuf, 32768);
|
||||
}
|
||||
|
||||
memset(binfo, 0, sizeof(BUPINFO));
|
||||
|
||||
binfo->total_size = 0x8000;
|
||||
binfo->total_block = 512;
|
||||
binfo->block_size = 64;
|
||||
|
||||
scan_save(binfo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue