#include "../unzip/unzip_stream.h"\r
\r
\r
-static char *rom_exts[] = { "bin", "gen", "smd", "iso" };\r
+static const char *rom_exts[] = { "bin", "gen", "smd", "iso", "sms", "gg", "sg" };\r
\r
void (*PicoCartUnloadHook)(void) = NULL;\r
\r
void (*PicoCartLoadProgressCB)(int percent) = NULL;\r
-void (*PicoCDLoadProgressCB)(int percent) = NULL; // handled in Pico/cd/cd_file.c\r
+void (*PicoCDLoadProgressCB)(const char *fname, int percent) = NULL; // handled in Pico/cd/cd_file.c\r
\r
static void PicoCartDetect(void);\r
\r
return inflateEnd(&stream);\r
}\r
\r
+static const char *get_ext(const char *path)\r
+{\r
+ const char *ext;\r
+ if (strlen(path) < 4)\r
+ return ""; // no ext\r
+\r
+ // allow 2 or 3 char extensions for now\r
+ ext = path + strlen(path) - 2;\r
+ if (ext[-1] != '.') ext--;\r
+ if (ext[-1] != '.')\r
+ return "";\r
+ return ext;\r
+}\r
+\r
pm_file *pm_open(const char *path)\r
{\r
pm_file *file = NULL;\r
const char *ext;\r
FILE *f;\r
\r
- if (path == NULL) return NULL;\r
-\r
- if (strlen(path) < 5) ext = NULL; // no ext\r
- else ext = path + strlen(path) - 3;\r
+ if (path == NULL)\r
+ return NULL;\r
\r
- if (ext && strcasecmp(ext, "zip") == 0)\r
+ ext = get_ext(path);\r
+ if (strcasecmp(ext, "zip") == 0)\r
{\r
struct zipent *zipentry;\r
gzFile gzf = NULL;\r
int i;\r
\r
zipfile = openzip(path);\r
-\r
if (zipfile != NULL)\r
{\r
/* search for suitable file (right extension or large enough file) */\r
while ((zipentry = readzip(zipfile)) != NULL)\r
{\r
- if (zipentry->uncompressed_size >= 128*1024) goto found_rom_zip;\r
- if (strlen(zipentry->name) < 5) continue;\r
+ ext = get_ext(zipentry->name);\r
+\r
+ if (zipentry->uncompressed_size >= 32*1024)\r
+ goto found_rom_zip;\r
\r
- ext = zipentry->name+strlen(zipentry->name)-3;\r
for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)\r
- if (strcasecmp(ext, rom_exts[i]) == 0) goto found_rom_zip;\r
+ if (strcasecmp(ext, rom_exts[i]) == 0)\r
+ goto found_rom_zip;\r
}\r
\r
/* zipfile given, but nothing found suitable for us inside */\r
gzf = zip2gz(zipfile, zipentry);\r
if (gzf == NULL) goto zip_failed;\r
\r
- file = malloc(sizeof(*file));\r
+ file = calloc(1, sizeof(*file));\r
if (file == NULL) goto zip_failed;\r
file->file = zipfile;\r
file->param = gzf;\r
file->size = zipentry->uncompressed_size;\r
file->type = PMT_ZIP;\r
+ strncpy(file->ext, ext, sizeof(file->ext) - 1);\r
return file;\r
\r
zip_failed:\r
return NULL;\r
}\r
}\r
- else if (ext && strcasecmp(ext, "cso") == 0)\r
+ else if (strcasecmp(ext, "cso") == 0)\r
{\r
cso_struct *cso = NULL, *tmp = NULL;\r
int size;\r
cso->fpos_in = ftell(f);\r
cso->fpos_out = 0;\r
cso->block_in_buff = -1;\r
- file = malloc(sizeof(*file));\r
+ file = calloc(1, sizeof(*file));\r
if (file == NULL) goto cso_failed;\r
file->file = f;\r
file->param = cso;\r
f = fopen(path, "rb");\r
if (f == NULL) return NULL;\r
\r
- file = malloc(sizeof(*file));\r
+ file = calloc(1, sizeof(*file));\r
if (file == NULL) {\r
fclose(f);\r
return NULL;\r
file->param = NULL;\r
file->size = ftell(f);\r
file->type = PMT_UNCOMPRESSED;\r
+ strncpy(file->ext, ext, sizeof(file->ext) - 1);\r
fseek(f, 0, SEEK_SET);\r
\r
#ifndef __EPOC32__ // makes things worse on Symbian\r
return rom;\r
}\r
\r
-static unsigned char *PicoCartAlloc(int filesize)\r
+static unsigned char *PicoCartAlloc(int filesize, int is_sms)\r
{\r
int alloc_size;\r
unsigned char *rom;\r
\r
- if (PicoAHW & PAHW_MCD) return cd_realloc(NULL, filesize);\r
+ if (PicoAHW & PAHW_MCD)\r
+ return cd_realloc(NULL, filesize);\r
+\r
+ if (is_sms) {\r
+ // make size power of 2 for easier banking handling\r
+ int s = 0, tmp = filesize;\r
+ while ((tmp >>= 1) != 0)\r
+ s++;\r
+ if (filesize > (1 << s))\r
+ s++;\r
+ alloc_size = 1 << s;\r
+ }\r
+ else {\r
+ // align to 512K for memhandlers\r
+ alloc_size = (filesize + 0x7ffff) & ~0x7ffff;\r
+ }\r
\r
- alloc_size=filesize+0x7ffff;\r
- if((filesize&0x3fff)==0x200) alloc_size-=0x200;\r
- alloc_size&=~0x7ffff; // use alloc size of multiples of 512K, so that memhandlers could be set up more efficiently\r
- if((filesize&0x3fff)==0x200) alloc_size+=0x200;\r
- else if(alloc_size-filesize < 4) alloc_size+=4; // padding for out-of-bound exec protection\r
+ if (alloc_size - filesize < 4)\r
+ alloc_size += 4; // padding for out-of-bound exec protection\r
\r
// Allocate space for the rom plus padding\r
- rom=(unsigned char *)malloc(alloc_size);\r
- if(rom) memset(rom+alloc_size-0x80000,0,0x80000);\r
+ rom = calloc(alloc_size, 1);\r
return rom;\r
}\r
\r
-int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize)\r
+int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)\r
{\r
- unsigned char *rom=NULL; int size, bytes_read;\r
- if (f==NULL) return 1;\r
+ unsigned char *rom;\r
+ int size, bytes_read;\r
+\r
+ if (f == NULL)\r
+ return 1;\r
\r
- size=f->size;\r
+ size = f->size;\r
if (size <= 0) return 1;\r
- size=(size+3)&~3; // Round up to a multiple of 4\r
+ size = (size+3)&~3; // Round up to a multiple of 4\r
\r
// Allocate space for the rom plus padding\r
- rom=PicoCartAlloc(size);\r
- if (rom==NULL) {\r
+ rom = PicoCartAlloc(size, is_sms);\r
+ if (rom == NULL) {\r
elprintf(EL_STATUS, "out of memory (wanted %i)", size);\r
return 2;\r
}\r
return 3;\r
}\r
\r
- // maybe we are loading MegaCD BIOS?\r
- if (!(PicoAHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) ||\r
- !strncmp((char *)rom+0x128, "BOOT", 4))) {\r
- PicoAHW |= PAHW_MCD;\r
- rom = cd_realloc(rom, size);\r
- }\r
+ if (!is_sms)\r
+ {\r
+ // maybe we are loading MegaCD BIOS?\r
+ if (!(PicoAHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) ||\r
+ !strncmp((char *)rom+0x128, "BOOT", 4))) {\r
+ PicoAHW |= PAHW_MCD;\r
+ rom = cd_realloc(rom, size);\r
+ }\r
\r
- // Check for SMD:\r
- if (size >= 0x4200 && (size&0x3fff)==0x200 &&\r
- ((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) {\r
- DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD\r
+ // Check for SMD:\r
+ if (size >= 0x4200 && (size&0x3fff) == 0x200 &&\r
+ ((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) {\r
+ elprintf(EL_STATUS, "SMD format detected.");\r
+ DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD\r
+ }\r
+ else Byteswap(rom,size); // Just byteswap\r
+ }\r
+ else\r
+ {\r
+ if (size >= 0x4200 && (size&0x3fff) == 0x200) {\r
+ elprintf(EL_STATUS, "SMD format detected.");\r
+ // at least here it's not interleaved\r
+ size -= 0x200;\r
+ memmove(rom, rom + 0x200, size);\r
+ }\r
}\r
- else Byteswap(rom,size); // Just byteswap\r
\r
- if (prom) *prom=rom;\r
- if (psize) *psize=size;\r
+ if (prom) *prom = rom;\r
+ if (psize) *psize = size;\r
\r
return 0;\r
}\r
PicoCartUnloadHook = NULL;\r
}\r
\r
- PicoAHW &= PAHW_MCD;\r
+ PicoAHW &= PAHW_MCD|PAHW_SMS;\r
\r
PicoMemResetHooks();\r
PicoDmaHook = NULL;\r
\r
PicoMemReset();\r
\r
- if (!(PicoAHW & PAHW_MCD))\r
+ if (!(PicoAHW & (PAHW_MCD|PAHW_SMS)))\r
PicoCartDetect();\r
\r
// setup correct memory map for loaded ROM\r
case PAHW_SVP: PicoMemSetup(); break;\r
case PAHW_MCD: PicoMemSetupCD(); break;\r
case PAHW_PICO: PicoMemSetupPico(); break;\r
+ case PAHW_SMS: PicoMemSetupMS(); break;\r
}\r
PicoMemReset();\r
\r
- PicoPower();\r
+ if (PicoAHW & PAHW_SMS)\r
+ PicoPowerMS();\r
+ else\r
+ PicoPower();\r
+\r
return 0;\r
}\r
\r
void PicoCartUnload(void)\r
{\r
+ if (PicoCartUnloadHook != NULL) {\r
+ PicoCartUnloadHook();\r
+ PicoCartUnloadHook = NULL;\r
+ }\r
+\r
if (Pico.rom != NULL) {\r
SekFinishIdleDet();\r
free(Pico.rom);\r