.optimized memory footprint

.improved hardware initialization (fixes Ultimate Mortal Kombat Trilogy)
.improved soft-reset emulation
.fixed some menu bugs on Gamecube
This commit is contained in:
ekeeke31 2010-05-28 12:08:00 +00:00
parent 70ef2fc20b
commit 2c2f760f44
38 changed files with 1089 additions and 854 deletions

View File

@ -60,12 +60,13 @@ of samples per frame and keeping PSG & FM chips in sync.
[Gamecube/Wii]
---------------
* implemented new FONT engine (using internal IPL font & GX hardware rendering).
* implemented custom GUI engine (with PCM/OGG sound support, multithreading & using GX hardware for rendering)
* new interface design (incl. IR pointing, game snapshots, visual & sound effects, BGM...).
* improved audio/video back-end synchronization to ensure 100% smooth video & audio playback.
* implemented custom FONT engine (uses internal IPL font & GX hardware rendering).
* implemented custom GUI engine (uses GX hardware rendering & multithreading)
* implemented advanced interface (IR pointing, game snapshots, visual & sound effects, BGM...).
* improved audio/video synchronization to ensure 100% smooth video AND audio playback.
* improved reset button behavior, now works more like the real Genesis reset button.
* improved lightgun cursors layout.
* added automatic ROM loading feature
* fixed stability issues and memory leaks.
[Wii only]

View File

@ -62,62 +62,59 @@ static void special_regs_w(uint32 address, uint32 data);
static const T_CART_ENTRY rom_database[CART_CNT] =
{
/* Funny World & Balloon Boy */
{0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}},
{0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}},
/* Whac-a-Critter */
{0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}},
{0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}},
/* Earth Defense */
{0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}},
{0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}},
/* RADICA (Volume 1) (not byteswapped) */
{0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}},
{0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}},
/* RADICA (Volume 2) */
{0x4f10,0x0836,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}},
{0x4f10,0x0836,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}},
/* RADICA (Volume 1) */
{0xf424,0x9f82,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}},
{0xf424,0x9f82,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}},
/* Lion King 3 */
{0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}},
{0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}},
/* Super King Kong 99 */
{0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}},
{0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}},
/* Pokemon Stadium */
{0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}},
{0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}},
/* Lion King 2 */
{0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}},
{0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}},
/* Squirell King */
{0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}},
{0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}},
/* Supper Bubble Bobble */
{0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x400002,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x400002,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}},
/* Mahjong Lover */
{0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x401000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}},
/* Elf Wor */
{0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
/* Huan Le Tao Qi Shu - Smart Mouse */
{0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
/* Ya-Se Chuanshuo */
{0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
/* Soul Blade */
{0x0000,0x0c5b,0x40,0x40,{{0x00,0x98,0xc9,0xF0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0x0000,0x0c5b,0x40,0x40,{{0x00,0x98,0xc9,0xF0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
/* King of Fighter 98 */
{0x0000,0xd0a0,0x48,0x4f,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0x0000,0xd0a0,0x48,0x4f,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,NULL,NULL,default_regs_r,NULL}},
/* Lian Huan Pao - Barver Battle Saga */
{0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}},
{0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}},
/* Rockman X3 */
{0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0xa13000,0x400004,0x000000,0x000000},0,0,0,default_regs_r,NULL,default_regs_r,NULL}},
{0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0xa13000,0x400004,0x000000,0x000000},0,0,default_regs_r,NULL,default_regs_r,NULL}},
/* Super Mario 2 1998 */
{0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
{0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
/* Super Mario 2 1998 */
{0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
{0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
/* A Bug's Life */
{0x7f7f,0x2aad,0x00,0x00,{{0x28,0x1f,0x01,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
{0x7f7f,0x2aad,0x00,0x00,{{0x28,0x1f,0x01,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
/* King of Fighter 99 */
{0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
{0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
/* Pocket Monster */
{0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
{0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
/* Game no Kanzume Otokuyou */
{0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,seganet_mapper_w,NULL,NULL}}
{0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,seganet_mapper_w,NULL,NULL}}
};
/* temporary memory chunk */
static uint8 mem_chunk[0x10000];
/************************************************************
Cart Hardware initialization
@ -286,124 +283,15 @@ void cart_hw_init()
m68k_memory_map[0x3a].read16 = svp_read_cell_2;
}
/**********************************************
SPECIFIC CONTROLLER SETTINGS
***********************************************/
/* restore previous settings */
if (old_system[0] != -1)
input.system[0] = old_system[0];
if (old_system[1] != -1)
input.system[1] = old_system[1];
/* initialize default GUN settings */
input.x_offset = 0x00;
input.y_offset = 0x00;
/**********************************************
SEGA MENACER
***********************************************/
if (strstr(rominfo.international,"MENACER") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = NO_SYSTEM;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x52;
input.y_offset = 0x00;
}
else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x84;
input.y_offset = 0x08;
}
else if (strstr(rominfo.international,"BODY COUNT") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_MOUSE;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x44;
input.y_offset = 0x18;
}
/**********************************************
KONAMI JUSTIFIER
***********************************************/
else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_JUSTIFIER;
input.x_offset = 0x18;
input.y_offset = 0x00;
}
else if (strstr(rominfo.international,"LETHAL ENFORCERS") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_JUSTIFIER;
input.x_offset = 0x00;
input.y_offset = 0x00;
}
/**********************************************
J-CART
***********************************************/
cart.hw.jcart = 0;
if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */
((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */
((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */
((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/
(strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */
if (cart.jcart)
{
if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */
{
cart.hw.jcart = 1;
m68k_memory_map[0x38].read16 = jcart_read;
m68k_memory_map[0x38].write16 = jcart_write;
m68k_memory_map[0x3f].read16 = jcart_read;
m68k_memory_map[0x3f].write16 = jcart_write;
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
/* set default settings */
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_GAMEPAD;
}
m68k_memory_map[0x38].read16 = jcart_read;
m68k_memory_map[0x38].write16 = jcart_write;
m68k_memory_map[0x3f].read16 = jcart_read;
m68k_memory_map[0x3f].write16 = jcart_write;
}
/**********************************************
@ -427,51 +315,51 @@ void cart_hw_init()
break;
case TYPE_SK:
/* be sure we have enough place to store both ROMs */
if (cart.romsize < 0x700000)
{
/* load Sonic & Knuckles ROM (2 MBytes) */
FILE *f = fopen(SK_ROM,"r+b");
if (!f) break;
int done = 0;
while (done < 0x200000)
{
fread(cart.rom+0x700000+done,4096,1,f);
done += 4096;
}
fclose(f);
{
/* store S&K ROM above cartridge ROM + SRAM */
if (cart.romsize > 0x600000) break;
/* load Sonic 2 UPMEM ROM (256 KBytes) */
f = fopen(SK_UPMEM,"r+b");
if (!f) break;
done = 0;
while (done < 0x40000)
{
fread(cart.rom+0x900000+done,4096,1,f);
done += 4096;
}
fclose(f);
/* load Sonic & Knuckles ROM (2 MBytes) */
FILE *f = fopen(SK_ROM,"r+b");
if (!f) break;
int done = 0;
while (done < 0x200000)
{
fread(cart.rom + 0x600000 + done, 2048, 1, f);
done += 2048;
}
fclose(f);
/* load Sonic 2 UPMEM ROM (256 KBytes) */
f = fopen(SK_UPMEM,"r+b");
if (!f) break;
done = 0;
while (done < 0x40000)
{
fread(cart.rom + 0x800000 + done, 2048, 1, f);
done += 2048;
}
fclose(f);
#ifdef LSB_FIRST
/* Byteswap ROM */
int i;
uint8 temp;
for(i = 0; i < 0x240000; i += 2)
{
temp = cart.rom[i+0x700000];
cart.rom[i+0x700000] = cart.rom[i+1+0x700000];
cart.rom[i+1+0x700000] = temp;
}
/* Byteswap ROM */
int i;
uint8 temp;
for(i = 0; i < 0x240000; i += 2)
{
temp = cart.rom[i + 0x600000];
cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1];
cart.rom[i + 0x600000 + 1] = temp;
}
#endif
/*$000000-$1fffff is mapped to S&K ROM */
for (i=0x00; i<0x20; i++)
m68k_memory_map[i].base = (cart.rom + 0x700000) + (i<<16);
/*$000000-$1fffff is mapped to S&K ROM */
for (i=0x00; i<0x20; i++)
m68k_memory_map[i].base = (cart.rom + 0x600000) + (i<<16);
cart.lock_on = 1;
}
cart.lock_on = 1;
break;
}
default:
break;
@ -487,7 +375,7 @@ void cart_hw_init()
{
/* known cart found ! */
if ((rominfo.checksum == rom_database[i].chk_1) &&
(realchecksum == rom_database[i].chk_2))
(rominfo.realchecksum == rom_database[i].chk_2))
{
/* retrieve hardware information */
memcpy(&cart.hw, &(rom_database[i].cart_hw), sizeof(T_CART_HW));
@ -521,7 +409,7 @@ void cart_hw_init()
emulate_address_error = config.addr_error;
#endif
/* detect ROM files larger than 4MB */
/* detect special cartridges */
if (cart.romsize > 0x800000)
{
/* Ultimate MK3 (hack) */
@ -546,7 +434,6 @@ void cart_hw_init()
}
/* default write handler for !TIME signal */
/* TODO: handle Sonic & Knuckles + Sonic 2 case to prevent RAM activation */
if (!cart.hw.time_w)
cart.hw.time_w = default_time_w;
}
@ -567,10 +454,10 @@ void cart_hw_reset()
if (cart.hw.realtec & 1)
{
/* enable BOOTROM */
for (i=0x00; i<0x40; i++)
m68k_memory_map[i].base = mem_chunk;
for (i=0; i<8; i++)
memcpy(mem_chunk + i*0x2000, cart.rom + 0x7e000, 0x2000);
memcpy(cart.rom + 0x900000 + i*0x2000, cart.rom + 0x7e000, 0x2000);
for (i=0x00; i<0x40; i++)
m68k_memory_map[i].base = cart.rom + 0x900000;
cart.hw.realtec |= 2;
}
@ -657,7 +544,7 @@ static void sega_mapper_w(uint32 address, uint32 data)
{
/* enable UPMEM chip at $300000-$3fffff */
for (i=0x30; i<0x40; i++)
m68k_memory_map[i].base = (cart.rom + 0x900000) + ((i & 3)<<16);
m68k_memory_map[i].base = (cart.rom + 0x800000) + ((i & 3)<<16);
}
}
else
@ -708,9 +595,9 @@ static void multi_mapper_w(uint32 address, uint32 data)
static void special_mapper_w(uint32 address, uint32 data)
{
/* 1 x 32k bank */
m68k_memory_map[0].base = mem_chunk;
memcpy(mem_chunk,&cart.rom[(data & 0x7f) << 15],0x8000);
memcpy(mem_chunk+0x8000,cart.rom + 0x8000,0x8000);
memcpy(cart.rom + 0x900000, cart.rom + ((data & 0x7f) << 15), 0x8000);
memcpy(cart.rom + 0x908000, cart.rom + 0x8000, 0x8000);
m68k_memory_map[0].base = cart.rom + 0x900000;
}
/*

View File

@ -38,8 +38,7 @@ typedef struct
uint8 regs[4]; /* internal registers (R/W) */
uint32 mask[4]; /* registers address mask */
uint32 addr[4]; /* registers address */
uint32 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */
uint16 jcart; /* cartridge with JCART port */
uint16 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */
uint16 bankshift; /* cartridge with bankshift mecanism */
unsigned int (*time_r)(unsigned int address); /* !TIME signal ($a130xx) read handler */
void (*time_w)(unsigned int address, unsigned int data); /* !TIME signal ($a130xx) write handler */
@ -51,11 +50,12 @@ typedef struct
typedef struct
{
uint8 *rom; /* ROM data */
uint8 *base; /* ROM area (slot 0) */
uint32 mask; /* mask ROM */
uint32 lock_on; /* 1: Lock-On enabled */
uint8 *base; /* ROM base area (slot 0) */
uint32 romsize; /* ROM size */
T_CART_HW hw; /* Custom hardware */
uint32 mask; /* mask ROM */
uint16 lock_on; /* 1: Lock-On enabled */
uint16 jcart; /* 1: J-CART port enabled */
T_CART_HW hw; /* Extra hardware */
} T_CART;
/* global variables */

View File

@ -27,8 +27,8 @@
struct
{
uint8 enabled;
uint8 rom[0x20000];
uint8 ram[0x10000];
uint8 *rom;
uint8 *ram;
uint16 regs[13];
uint16 old[4];
uint16 data[4];
@ -49,6 +49,11 @@ void datel_init(void)
if (!f)
return;
/* store Action replay ROM + RAM above cartridge ROM + SRAM */
if (cart.romsize > 0x600000) return;
action_replay.rom = cart.rom + 0x600000;
action_replay.ram = cart.rom + 0x610000;
/* ROM size */
fseek(f, 0, SEEK_END);
int size = ftell(f);
@ -59,9 +64,6 @@ void datel_init(void)
case 0x8000: /* ACTION REPLAY (32K) */
{
action_replay.enabled = TYPE_AR;
/* $0000-$7fff mirrored into $8000-$ffff */
memcpy(action_replay.rom+0x8000,action_replay.rom,0x8000);
break;
}
@ -92,33 +94,32 @@ void datel_init(void)
}
default:
{
fclose(f);
return;
}
}
if (action_replay.enabled)
/* Load ROM */
fseek(f, 0, SEEK_SET);
int i = 0;
while (i < size)
{
/* Load ROM */
fseek(f, 0, SEEK_SET);
int i = 0;
while (i < size)
{
fread(action_replay.rom+i,0x1000,1,f);
i += 0x1000;
}
fread(action_replay.rom+i,0x1000,1,f);
i += 0x1000;
}
fclose(f);
#ifdef LSB_FIRST
/* Byteswap ROM */
uint8 temp;
for(i = 0; i < size; i += 2)
{
temp = action_replay.rom[i];
action_replay.rom[i] = action_replay.rom[i+1];
action_replay.rom[i+1] = temp;
}
#endif
/* Byteswap ROM */
uint8 temp;
for(i = 0; i < size; i += 2)
{
temp = action_replay.rom[i];
action_replay.rom[i] = action_replay.rom[i+1];
action_replay.rom[i+1] = temp;
}
fclose(f);
#endif
}
void datel_shutdown(void)
@ -178,7 +179,7 @@ void datel_reset(int hard_reset)
/* clear RAM on hard reset only */
if (hard_reset)
memset(action_replay.ram,0,sizeof(action_replay.ram));
memset(action_replay.ram,0,0x10000);
}
void datel_switch(int enable)

View File

@ -111,14 +111,12 @@ void eeprom_init()
}
/* Game not found in database but header seems to indicate it uses EEPROM */
if (!sram.custom)
if (sram.detected && !sram.custom)
{
if ((sram.end - sram.start) < 2)
{
sram.custom = 1;
sram.on = 1;
/* set SEGA mapper as default */
sram.custom = 1;
memcpy(&eeprom.type, &database[9].type, sizeof(T_EEPROM_TYPE));
}
}

View File

@ -27,7 +27,7 @@
static struct
{
uint8 enabled;
uint8 rom[0x10000];
uint8 *rom;
uint16 regs[0x20];
uint16 old[6];
uint16 data[6];
@ -47,6 +47,10 @@ void ggenie_init(void)
FILE *f = fopen(GG_ROM,"rb");
if (!f) return;
/* store Game Genie ROM above cartridge ROM + SRAM */
if (cart.romsize > 0x600000) return;
ggenie.rom = cart.rom + 0x600000;
/* Load ROM */
int i = 0;
while (i < 0x8000)

View File

@ -42,33 +42,41 @@ T_SRAM sram;
void sram_init()
{
memset (&sram, 0, sizeof (T_SRAM));
memset (&sram.sram[0], 0xFF, 0x10000);
sram.crc = crc32(0, &sram.sram[0], 0x10000);
/* store SRAM into cartridge area */
if (cart.romsize > 0x500000) return;
sram.sram = cart.rom + 0x500000;
/* initialize SRAM */
memset(sram.sram, 0xff, 0x10000);
sram.crc = crc32(0, sram.sram, 0x10000);
/* retrieve informations from header */
if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41))
{
/* retrieve informations from headezr */
sram.detected = 1;
sram.start = READ_WORD_LONG(cart.rom, 0x1b4);
sram.end = READ_WORD_LONG(cart.rom, 0x1b8);
/* fixe some bad header informations */
if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000))
sram.end = sram.start + 0xffff;
sram.end = sram.start + 0xffff;
sram.start &= 0xfffffffe;
sram.end |= 1;
/* enable SRAM */
sram.on = 1;
sram.detected = 1;
}
else
else
{
/* default SRAM region */
sram.start = 0x200000;
sram.end = 0x20ffff;
}
/* set SRAM ON by default when ROM is not mapped */
if (cart.romsize <= sram.start)
sram.on = 1;
/* enable SRAM only if ROM < 2MB */
if (cart.romsize <= sram.start)
sram.on = 1;
}
/* autodetect some games with bad header or specific configuration */
if (strstr(rominfo.product,"T-113016") != NULL)
@ -119,7 +127,8 @@ void sram_init()
sram.start = 0x200001;
sram.end = 0x203fff;
}
else if (((realchecksum == 0xaeaa) || (realchecksum == 0x8dba)) && (rominfo.checksum == 0x8104))
else if (((rominfo.realchecksum == 0xaeaa) || (rominfo.realchecksum == 0x8dba)) &&
(rominfo.checksum == 0x8104))
{
/* Xin Qigai Wangzi, aka Beggar Prince (no header, use uncommon area) */
sram.on = 1;

View File

@ -31,7 +31,7 @@ typedef struct
uint32 start;
uint32 end;
uint32 crc;
uint8 sram[0x10000];
uint8 *sram;
} T_SRAM;
/* Function prototypes */

View File

@ -24,6 +24,7 @@
#include "shared.h"
t_input input;
int old_system[2] = {-1,-1};
/************************************************************************************/
/* */
@ -70,7 +71,7 @@ static const uint8 hc_256[171] =
};
/*****************************************************************************
* LIGHTGUN specific functions
* LIGHTGUN support
*
*****************************************************************************/
static inline void lightgun_reset(int num)
@ -146,7 +147,7 @@ uint32 justifier_read(void)
}
/*****************************************************************************
* SEGA MOUSE specific functions
* SEGA MOUSE support
*
*****************************************************************************/
static struct mega_mouse
@ -268,7 +269,7 @@ uint32 mouse_read()
/*****************************************************************************
* GAMEPAD specific functions (2PLAYERS/4WAYPLAY)
* GAMEPAD support (2PLAYERS/4WAYPLAY)
*
*****************************************************************************/
static struct pad
@ -297,15 +298,15 @@ static inline void gamepad_update(uint32 i)
static inline uint32 gamepad_read(uint32 i)
{
int control;
/* bit7 is latched */
int retval = 0x7F;
control = (gamepad[i].State & 0x40) >> 6; /* current TH state */
/* current TH state */
int control = (gamepad[i].State & 0x40) >> 6;
/* TH transitions counter */
if (input.dev[i] == DEVICE_6BUTTON)
{
control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */
}
control += (gamepad[i].Counter & 3) << 1;
switch (control)
{
@ -376,7 +377,6 @@ static inline uint32 gamepad_read(uint32 i)
break;
}
/* bit7 is latched */
return retval;
}
@ -397,7 +397,7 @@ static inline void gamepad_write(uint32 i, uint32 data)
/*****************************************************************************
* TEAMPLAYER adapter
* TEAMPLAYER adapter support
*
*****************************************************************************/
static struct teamplayer
@ -536,7 +536,7 @@ static inline void teamplayer_write(uint32 port, uint32 data)
}
/*****************************************************************************
* 4WAYPLAY adapter
* 4-WAYPLAY adapter support
*
*****************************************************************************/
static inline void wayplay_write(uint32 port, uint32 data)
@ -619,7 +619,8 @@ void teamplayer_2_write (uint32 data)
uint32 jcart_read(uint32 address)
{
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 */
/* TH2 (output) fixed to 0 on read (fixes Micro Machines 2) */
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8));
}
void jcart_write(uint32 address, uint32 data)
@ -719,7 +720,7 @@ void input_init(void)
}
/* J-CART: add two gamepad inputs */
if (cart.hw.jcart)
if (cart.jcart)
{
input.dev[5] = config.input[2].padtype;
input.dev[6] = config.input[3].padtype;
@ -767,13 +768,15 @@ void input_update(void)
switch (input.system[0])
{
case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0);
if (input.dev[0] == DEVICE_6BUTTON)
gamepad_update(0);
break;
case SYSTEM_WAYPLAY:
for (i=0; i<4; i++)
{
if (input.dev[i] == DEVICE_6BUTTON) gamepad_update(i);
if (input.dev[i] == DEVICE_6BUTTON)
gamepad_update(i);
}
break;
}
@ -781,7 +784,8 @@ void input_update(void)
switch (input.system[1])
{
case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4);
if (input.dev[4] == DEVICE_6BUTTON)
gamepad_update(4);
break;
case SYSTEM_MENACER:
@ -789,8 +793,10 @@ void input_update(void)
break;
case SYSTEM_JUSTIFIER:
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0);
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1);
if ((io_reg[2] & 0x30) == 0x00)
lightgun_update(0);
if ((io_reg[2] & 0x30) == 0x20)
lightgun_update(1);
break;
}
}
@ -801,13 +807,15 @@ void input_raz(void)
switch (input.system[0])
{
case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0);
if (input.dev[0] == DEVICE_6BUTTON)
gamepad_raz(0);
break;
case SYSTEM_WAYPLAY:
for (i=0; i<4; i++)
{
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
if (input.dev[i] == DEVICE_6BUTTON)
gamepad_raz(i);
}
break;
}
@ -815,7 +823,123 @@ void input_raz(void)
switch (input.system[1])
{
case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4);
if (input.dev[4] == DEVICE_6BUTTON)
gamepad_raz(4);
break;
}
}
void input_autodetect(void)
{
/* restore previous settings */
if (old_system[0] != -1)
input.system[0] = old_system[0];
if (old_system[1] != -1)
input.system[1] = old_system[1];
/* initialize default GUN settings */
input.x_offset = 0x00;
input.y_offset = 0x00;
/**********************************************
SEGA MENACER
***********************************************/
if (strstr(rominfo.international,"MENACER") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = NO_SYSTEM;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x52;
input.y_offset = 0x00;
}
else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x84;
input.y_offset = 0x08;
}
else if (strstr(rominfo.international,"BODY COUNT") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_MOUSE;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x44;
input.y_offset = 0x18;
}
/**********************************************
KONAMI JUSTIFIER
***********************************************/
else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_JUSTIFIER;
input.x_offset = 0x18;
input.y_offset = 0x00;
}
else if (strstr(rominfo.international,"LETHAL ENFORCERS") != NULL)
{
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_JUSTIFIER;
input.x_offset = 0x00;
input.y_offset = 0x00;
}
/**********************************************
J-CART
***********************************************/
cart.jcart = 0;
if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */
((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */
((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */
((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/
(strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */
{
if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */
{
cart.jcart = 1;
/* save current setting */
if (old_system[0] == -1)
old_system[0] = input.system[0];
if (old_system[1] == -1)
old_system[1] = input.system[1];
/* set default settings */
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_GAMEPAD;
}
}
}

View File

@ -78,6 +78,7 @@ extern void input_init(void);
extern void input_reset(void);
extern void input_update(void);
extern void input_raz(void);
extern void input_autodetect(void);
/* Peripherals specific */
extern void mouse_write(uint32 data);

View File

@ -25,7 +25,6 @@
uint8 io_reg[0x10];
uint8 region_code = REGION_USA;
int old_system[2] = {-1,-1};
static struct port_t
{
@ -117,20 +116,24 @@ void io_init(void)
void io_reset(void)
{
/* I/O register default settings */
uint8 io_def[0x10] =
{
0xA0,
0x7F, 0x7F, 0x7F,
0x00, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFB, 0x00, 0x00,
};
/* Reset I/O registers */
memcpy (io_reg, io_def, 0x10);
io_reg[0x00] = region_code | 0x20 | (config.bios_enabled == 3);
io_reg[0x01] = 0x7F;
io_reg[0x02] = 0x7F;
io_reg[0x03] = 0x7F;
io_reg[0x04] = 0x00;
io_reg[0x05] = 0x00;
io_reg[0x06] = 0x00;
io_reg[0x07] = 0xFF;
io_reg[0x08] = 0x00;
io_reg[0x09] = 0x00;
io_reg[0x0A] = 0xFF;
io_reg[0x0B] = 0x00;
io_reg[0x0C] = 0x00;
io_reg[0x0D] = 0xFB;
io_reg[0x0E] = 0x00;
io_reg[0x0F] = 0x00;
/* Reset connected input devices */
input_reset();
}
@ -142,29 +145,16 @@ void io_write(uint32 offset, uint32 value)
case 0x01: /* Port A Data */
case 0x02: /* Port B Data */
case 0x03: /* Port C Data */
io_reg[offset] = ((value & 0x80) | (value & io_reg[offset+3]));
if(port[offset-1].data_w) port[offset-1].data_w(value);
io_reg[offset] = value & (0x80 | io_reg[offset+3]);
if(port[offset-1].data_w)
port[offset-1].data_w(value);
return;
case 0x05: /* Port B Ctrl */
if (((value & 0x7F) == 0x7F) &&
((input.system[0] == SYSTEM_TEAMPLAYER) ||
(input.system[1] == SYSTEM_TEAMPLAYER)))
{
/* autodetect 4-Way play ! */
input.system[0] = SYSTEM_WAYPLAY;
input.system[1] = SYSTEM_WAYPLAY;
port[0].data_w = wayplay_1_write;
port[0].data_r = wayplay_1_read;
port[1].data_w = wayplay_2_write;
port[1].data_r = wayplay_2_read;
input_reset();
}
case 0x04: /* Port A Ctrl */
case 0x05: /* Port B Ctrl */
case 0x06: /* Port C Ctrl */
io_reg[offset] = value & 0xFF;
io_reg[offset-3] = ((io_reg[offset-3] & 0x80) | (io_reg[offset-3] & io_reg[offset]));
io_reg[offset] = value;
io_reg[offset-3] &= (0x80 | value);
return;
case 0x07: /* Port A TxData */
@ -176,7 +166,10 @@ void io_write(uint32 offset, uint32 value)
case 0x09: /* Port A S-Ctrl */
case 0x0C: /* Port B S-Ctrl */
case 0x0F: /* Port C S-Ctrl */
io_reg[offset] = (value & 0xF8);
io_reg[offset] = value & 0xF8;
return;
default: /* Read-only ports */
return;
}
}
@ -185,23 +178,17 @@ uint32 io_read(uint32 offset)
{
switch(offset)
{
case 0x00: /* Version register */
{
uint8 has_scd = 0x20; /* No Sega CD unit attached */
uint8 gen_ver = (config.bios_enabled == 3) ? 0x01 : 0x00; /* hardware version */
return (region_code | has_scd | gen_ver);
}
case 0x01: /* Port A Data */
case 0x02: /* Port B Data */
case 0x03: /* Port C Data */
{
uint8 input = 0x7F; /* default input state */
if(port[offset-1].data_r) input = port[offset-1].data_r();
uint8 input = 0x7F;
if(port[offset-1].data_r)
input = port[offset-1].data_r();
return (io_reg[offset] | ((~io_reg[offset+3]) & input));
}
default:
default: /* return register value */
return (io_reg[offset]);
}
}

View File

@ -30,15 +30,10 @@ uint32 zirq; /* /IRQ to Z80 */
uint32 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
uint32 zbank; /* Z80 bank window address */
uint32 gen_running; /* 0: cpu are in locked state */
int32 resetline; /* soft reset is triggered on a random line (X-Men 2, Eternal Champions) */
/*--------------------------------------------------------------------------*/
/* Init, reset, shutdown functions */
/*--------------------------------------------------------------------------*/
void set_softreset(void)
{
resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0));
}
void gen_init(void)
{
@ -138,13 +133,17 @@ void gen_reset(uint32 hard_reset)
mcycles_68k = 0;
mcycles_z80 = 0;
}
else
{
/* VDP is not reseted so CPU could be anywhere in a frame */
mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX));
}
zstate = 0; /* Z80 is reset & has control of the bus */
zirq = 0; /* No interrupts occuring */
zbank = 0; /* Assume default bank is $000000-$007FFF */
/* Reset CPUs */
resetline = -1;
gen_running = 1;
fm_reset(0);
m68k_pulse_reset();

View File

@ -134,7 +134,7 @@ void config_default(void)
sprintf (config.sddir, "sd:%s/roms/", DEFAULT_PATH);
sprintf (config.usbdir, "usb:%s/roms/", DEFAULT_PATH);
#else
sprintf (config.sddir, "/%s/roms/", DEFAULT_PATH);
sprintf (config.sddir, "%s/roms/", DEFAULT_PATH);
#endif
/* restore from config file */

View File

@ -308,9 +308,16 @@ int DVD_LoadFile(u8 *buffer, u32 selection)
/* determine file type */
if (!IsZipFile ((char *) readbuffer))
{
char msg[50];
if (length > MAXROMSIZE)
{
GUI_WaitPrompt("Error","File size not supported !");
return 0;
}
char msg[64];
sprintf(msg,"Loading %d bytes...", length);
GUI_MsgBoxOpen("Information",msg,1);
/* How many 2k blocks to read */
int blocks = length / DVDCHUNK;
int readoffset = 0;
@ -373,7 +380,7 @@ int DVD_Open(void)
while(DI_GetStatus() & DVD_INIT) usleep(10);
if (!(DI_GetStatus() & DVD_READY))
{
char msg[50];
char msg[64];
sprintf(msg, "DI Status Error: 0x%08X !\n",DI_GetStatus());
GUI_WaitPrompt("Error",msg);
return 0;

View File

@ -55,7 +55,7 @@ int FAT_UpdateDirectory(bool go_up, char *dirname)
{
int size=0;
char *test;
char temp[1024];
char temp[MAXPATHLEN];
/* go up to parent directory */
if (strcmp(dirname,"..") == 0)
@ -185,11 +185,17 @@ int FAT_LoadFile(u8 *buffer, u32 selection)
/* Determine file type */
if (!IsZipFile ((char *) temp))
{
if (length > MAXROMSIZE)
{
GUI_WaitPrompt("Error","File size not supported !");
return 0;
}
/* re-open and read file */
sdfile = fopen(fname, "rb");
if (sdfile)
{
char msg[50];
char msg[64];
sprintf(msg,"Loading %d bytes ...", length);
GUI_MsgBoxOpen("Information",msg,1);
int done = 0;
@ -235,7 +241,7 @@ int FAT_Open(int type)
filelist[i].offset = 0;
filelist[i].length = 0;
filelist[i].flags = 0;
strncpy(filelist[i].filename, history.entries[i].filename, MAXJOLIET-1);
strncpy(filelist[i].filename,history.entries[i].filename, MAXJOLIET-1);
filelist[i].filename[MAXJOLIET-1] = '\0';
max++;
}

View File

@ -35,13 +35,6 @@
*/
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
/**
* DMA Transfer Area.
* Must be 32-byte aligned.
* 64k SRAM + 2k Icon
*/
static u8 savebuffer[STATE_SIZE] ATTRIBUTE_ALIGN (32);
/****************************************************************************
* CardMount
@ -139,9 +132,9 @@ void slot_autodetect(int slot, int device, t_slot *ptr)
{
/* Memory Card support */
if (slot > 0)
sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1);
sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else
sprintf(filename,"MD-%04X.srm", realchecksum);
sprintf(filename,"MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */
memset(&SysArea, 0, CARD_WORKAREA);
@ -201,9 +194,9 @@ int slot_delete(int slot, int device)
{
/* Memory Card support */
if (slot > 0)
sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1);
sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else
sprintf(filename,"MD-%04X.srm", realchecksum);
sprintf(filename,"MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */
memset(&SysArea, 0, CARD_WORKAREA);
@ -228,15 +221,23 @@ int slot_load(int slot, int device)
{
char filename[MAXPATHLEN];
int filesize, done = 0;
int offset = device ? 2112 : 0;
int offset = 0;
u8 *savebuffer;
if (slot > 0)
{
GUI_MsgBoxOpen("Information","Loading State ...",1);
}
else
GUI_MsgBoxOpen("Information","Loading SRAM ...",1);
{
if (!sram.on)
{
GUI_WaitPrompt("Error","SRAM is disabled !");
return 0;
}
/* clean buffer */
memset(savebuffer, 0, STATE_SIZE);
GUI_MsgBoxOpen("Information","Loading SRAM ...",1);
}
if (!device)
{
@ -248,42 +249,49 @@ int slot_load(int slot, int device)
/* Open file */
FILE *fp = fopen(filename, "rb");
if (fp)
{
/* Read size */
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET);
/* Read into buffer (2k blocks) */
while (filesize > FATCHUNK)
{
fread(savebuffer + done, FATCHUNK, 1, fp);
done += FATCHUNK;
filesize -= FATCHUNK;
}
/* Read remaining bytes */
fread(savebuffer + done, filesize, 1, fp);
done += filesize;
fclose(fp);
}
else
if (!fp)
{
GUI_WaitPrompt("Error","Unable to open file !");
return 0;
}
/* Read size */
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET);
/* allocate buffer */
savebuffer = (u8 *)memalign(32,filesize);
if (!savebuffer)
{
GUI_WaitPrompt("Error","Unable to allocate memory !");
fclose(fp);
return 0;
}
/* Read into buffer (2k blocks) */
while (filesize > FATCHUNK)
{
fread(savebuffer + done, FATCHUNK, 1, fp);
done += FATCHUNK;
filesize -= FATCHUNK;
}
/* Read remaining bytes */
fread(savebuffer + done, filesize, 1, fp);
done += filesize;
fclose(fp);
}
else
{
/* Memory Card support */
if (slot > 0)
sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1);
sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else
sprintf(filename, "MD-%04X.srm", realchecksum);
sprintf(filename, "MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */
char action[80];
char action[64];
memset(&SysArea, 0, CARD_WORKAREA);
CARD_Init("GENP", "00");
@ -291,53 +299,60 @@ int slot_load(int slot, int device)
device--;
/* Attempt to mount the card */
if (CardMount(device))
{
/* Retrieve the sector size */
u32 SectorSize = 0;
int CardError = CARD_GetSectorSize(device, &SectorSize);
if (SectorSize > 0)
{
/* Open file */
card_file CardFile;
CardError = CARD_Open(device, filename, &CardFile);
if (CardError)
{
sprintf(action, "Unable to open file (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
return 0;
}
/* Get file size */
filesize = CardFile.len;
if (filesize % SectorSize)
filesize = ((filesize / SectorSize) + 1) * SectorSize;
/* Read file sectors */
while (filesize > 0)
{
CARD_Read(&CardFile, &savebuffer[done], SectorSize, done);
done += SectorSize;
filesize -= SectorSize;
}
CARD_Close(&CardFile);
CARD_Unmount(device);
}
else
{
sprintf(action, "Invalid sector size (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
return 0;
}
}
else
if (!CardMount(device))
{
GUI_WaitPrompt("Error","Unable to mount memory card");
return 0;
}
/* Retrieve the sector size */
u32 SectorSize = 0;
int CardError = CARD_GetSectorSize(device, &SectorSize);
if (!SectorSize)
{
sprintf(action, "Invalid sector size (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
return 0;
}
/* Open file */
card_file CardFile;
CardError = CARD_Open(device, filename, &CardFile);
if (CardError)
{
sprintf(action, "Unable to open file (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
return 0;
}
/* Retrieve file size */
filesize = CardFile.len;
if (filesize % SectorSize)
filesize = ((filesize / SectorSize) + 1) * SectorSize;
/* Allocate buffer */
savebuffer = (u8 *)memalign(32,filesize);
if (!savebuffer)
{
GUI_WaitPrompt("Error","Unable to allocate memory !");
CARD_Close(&CardFile);
CARD_Unmount(device);
return 0;
}
/* Read file sectors */
while (filesize > 0)
{
CARD_Read(&CardFile, &savebuffer[done], SectorSize, done);
done += SectorSize;
filesize -= SectorSize;
}
CARD_Close(&CardFile);
CARD_Unmount(device);
offset = 2112;
}
if (slot > 0)
@ -345,7 +360,8 @@ int slot_load(int slot, int device)
/* Load state */
if (!state_load(&savebuffer[offset]))
{
GUI_WaitPrompt("Error","Version is not compatible !");
free(savebuffer);
GUI_WaitPrompt("Error","Unable to load state !");
return 0;
}
}
@ -353,9 +369,10 @@ int slot_load(int slot, int device)
{
/* Load SRAM & update CRC */
memcpy(sram.sram, &savebuffer[offset], 0x10000);
sram.crc = crc32(0, &sram.sram[0], 0x10000);
sram.crc = crc32(0, sram.sram, 0x10000);
}
free(savebuffer);
GUI_MsgBoxClose();
return 1;
}
@ -366,20 +383,40 @@ int slot_save(int slot, int device)
char filename[MAXPATHLEN];
int filesize, done = 0;
int offset = device ? 2112 : 0;
/* clean buffer */
memset(savebuffer, 0, STATE_SIZE);
u8 *savebuffer;
if (slot > 0)
{
/* allocate buffer */
savebuffer = (u8 *)memalign(32,STATE_SIZE);
if (!savebuffer)
{
GUI_WaitPrompt("Error","Unable to allocate memory !");
return 0;
}
GUI_MsgBoxOpen("Information","Saving State ...",1);
filesize = state_save(&savebuffer[offset]);
}
else
{
if (!sram.on)
{
GUI_WaitPrompt("Error","SRAM is disabled !");
return 0;
}
/* allocate buffer */
savebuffer = (u8 *)memalign(32,0x10000+offset);
if (!savebuffer)
{
GUI_WaitPrompt("Error","Unable to allocate memory !");
return 0;
}
GUI_MsgBoxOpen("Information","Saving SRAM ...",1);
memcpy(&savebuffer[offset], sram.sram, 0x10000);
sram.crc = crc32(0, &sram.sram[0], 0x10000);
sram.crc = crc32(0, sram.sram, 0x10000);
filesize = 0x10000;
}
@ -393,44 +430,36 @@ int slot_save(int slot, int device)
/* Open file */
FILE *fp = fopen(filename, "wb");
if (fp)
{
/* Read into buffer (2k blocks) */
while (filesize > FATCHUNK)
{
fwrite(savebuffer + done, FATCHUNK, 1, fp);
done += FATCHUNK;
filesize -= FATCHUNK;
}
/* Write remaining bytes */
fwrite(savebuffer + done, filesize, 1, fp);
done += filesize;
fclose(fp);
if (slot)
{
/* save screenshot */
sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1);
gxSaveScreenshot(filename);
}
}
else
if (!fp)
{
GUI_WaitPrompt("Error","Unable to open file !");
free(savebuffer);
return 0;
}
}
/* Read into buffer (2k blocks) */
while (filesize > FATCHUNK)
{
fwrite(savebuffer + done, FATCHUNK, 1, fp);
done += FATCHUNK;
filesize -= FATCHUNK;
}
/* Write remaining bytes */
fwrite(savebuffer + done, filesize, 1, fp);
done += filesize;
fclose(fp);
}
else
{
/* Memory Card support */
if (slot > 0)
sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1);
sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else
sprintf(filename, "MD-%04X.srm", realchecksum);
sprintf(filename, "MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */
char action[80];
char action[64];
memset(&SysArea, 0, CARD_WORKAREA);
CARD_Init("GENP", "00");
@ -438,102 +467,112 @@ int slot_save(int slot, int device)
device--;
/* Attempt to mount the card */
if (CardMount(device))
if (!CardMount(device))
{
/* Retrieve the sector size */
u32 SectorSize = 0;
int CardError = CARD_GetSectorSize(device, &SectorSize);
if (SectorSize)
GUI_WaitPrompt("Error","Unable to mount memory card");
free(savebuffer);
return 0;
}
/* Retrieve the sector size */
u32 SectorSize = 0;
int CardError = CARD_GetSectorSize(device, &SectorSize);
if (!SectorSize)
{
sprintf(action, "Invalid sector size (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
free(savebuffer);
return 0;
}
/* Build the output buffer */
char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} };
strcpy (comment[1], filename);
memcpy (&savebuffer[0], &icon, 2048);
memcpy (&savebuffer[2048], &comment[0], 64);
/* Adjust file size */
filesize += 2112;
if (filesize % SectorSize)
filesize = ((filesize / SectorSize) + 1) * SectorSize;
/* Check if file already exists */
card_file CardFile;
if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY)
{
int size = filesize - CardFile.len;
CARD_Close(&CardFile);
memset(&CardFile,0,sizeof(CardFile));
/* Check file new size */
if (size > 0)
{
/* Build the output buffer */
char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} };
strcpy (comment[1], filename);
memcpy (&savebuffer[0], &icon, 2048);
memcpy (&savebuffer[2048], &comment[0], 64);
/* Adjust file size */
filesize += 2112;
if (filesize % SectorSize)
filesize = ((filesize / SectorSize) + 1) * SectorSize;
/* Check if file already exists */
card_file CardFile;
if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY)
{
int size = filesize - CardFile.len;
CARD_Close(&CardFile);
memset(&CardFile,0,sizeof(CardFile));
if (size > 0)
{
/* new file is bigger: check if there is enough space left */
CardError = CARD_Create(device, "TEMP", size, &CardFile);
if (CardError)
{
sprintf(action, "Not enough memory space left (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
return 0;
}
CARD_Close(&CardFile);
memset(&CardFile,0,sizeof(CardFile));
CARD_Delete(device, "TEMP");
}
/* delete previously existing slot */
CARD_Delete(device, filename);
}
/* Create a new slot */
CardError = CARD_Create(device, filename, filesize, &CardFile);
CardError = CARD_Create(device, "TEMP", size, &CardFile);
if (CardError)
{
sprintf(action, "Unable to create file (%d)", CardError);
sprintf(action, "Unable to increase file size (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
free(savebuffer);
return 0;
}
/* Get current time */
time_t rawtime;
time(&rawtime);
/* Update file informations */
card_stat CardStatus;
CARD_GetStatus(device, CardFile.filenum, &CardStatus);
CardStatus.icon_addr = 0x0;
CardStatus.icon_fmt = 2;
CardStatus.icon_speed = 1;
CardStatus.comment_addr = 2048;
CardStatus.time = rawtime;
CARD_SetStatus(device, CardFile.filenum, &CardStatus);
/* Write file sectors */
while (filesize > 0)
{
CARD_Write(&CardFile, &savebuffer[done], SectorSize, done);
filesize -= SectorSize;
done += SectorSize;
}
/* Close file */
/* delete temporary file */
CARD_Close(&CardFile);
CARD_Unmount(device);
}
else
{
sprintf(action, "Invalid sector size (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
return 0;
memset(&CardFile,0,sizeof(CardFile));
CARD_Delete(device, "TEMP");
}
/* delete previously existing file */
CARD_Delete(device, filename);
}
else
/* Create a new file */
CardError = CARD_Create(device, filename, filesize, &CardFile);
if (CardError)
{
GUI_WaitPrompt("Error","Unable to mount memory card");
sprintf(action, "Unable to create file (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
free(savebuffer);
return 0;
}
/* Update file informations */
time_t rawtime;
time(&rawtime);
card_stat CardStatus;
CARD_GetStatus(device, CardFile.filenum, &CardStatus);
CardStatus.icon_addr = 0x0;
CardStatus.icon_fmt = 2;
CardStatus.icon_speed = 1;
CardStatus.comment_addr = 2048;
CardStatus.time = rawtime;
CARD_SetStatus(device, CardFile.filenum, &CardStatus);
/* Write file sectors */
while (filesize > 0)
{
CARD_Write(&CardFile, &savebuffer[done], SectorSize, done);
filesize -= SectorSize;
done += SectorSize;
}
/* Close file */
CARD_Close(&CardFile);
CARD_Unmount(device);
}
GUI_MsgBoxClose();
free(savebuffer);
/* Save screenshot */
if (slot && !device)
{
sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1);
gxSaveScreenshot(filename);
}
return 1;
}

View File

@ -108,7 +108,7 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
int bufferoffset = 0;
int have = 0;
char readbuffer[2048];
char msg[128];
char msg[64];
FILE *fatfile = NULL;
/*** FAT file support ***/
@ -133,6 +133,12 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
/*** Copy PKZip header to local, used as info ***/
memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER));
if (FLIP32 (pkzip.uncompressedSize) > MAXROMSIZE)
{
GUI_WaitPrompt("Error","File size not supported !");
return 0;
}
sprintf (msg, "Unzipping %d bytes ...", FLIP32 (pkzip.uncompressedSize));
GUI_MsgBoxOpen("Information",msg,1);

View File

@ -532,7 +532,11 @@ int FileSelector(unsigned char *buffer, bool useFAT)
else
size = DVD_LoadFile(buffer,selection);
/* Reload emulation */
/* Exit menu */
GUI_MsgBoxClose();
GUI_DeleteMenu(m);
/* Init emulation */
if (size)
{
if (config.s_auto & 2)
@ -544,9 +548,6 @@ int FileSelector(unsigned char *buffer, bool useFAT)
slot_autoload(config.s_default,config.s_device);
}
/* Exit */
GUI_MsgBoxClose();
GUI_DeleteMenu(m);
return size;
}
}

View File

@ -26,7 +26,7 @@
#define _FILESEL_H
#define MAXJOLIET 256
#define MAXFILES 1000
#define MAXFILES 500
/* Filelist structure */
typedef struct

View File

@ -36,7 +36,7 @@ typedef struct _yay0header {
unsigned int chunks_offset ATTRIBUTE_PACKED;
} yay0header;
int font_size[256];
u8 font_size[256];
int fheight;
static u8 *fontImage;
@ -265,7 +265,7 @@ int FONT_Init(void)
else
c = i - fontHeader->first_char;
font_size[i] = ((unsigned char*)fontHeader)[fontHeader->width_table + c];
font_size[i] = ((u8*)fontHeader)[fontHeader->width_table + c];
}
/* font height */
@ -403,7 +403,7 @@ void WriteCentre_HL( int y, char *string)
* Draw functions (FrameBuffer)
*
****************************************************************************/
void fntDrawHLine (int x1, int x2, int y, int color)
static void fntDrawHLine (int x1, int x2, int y, int color)
{
int i;
y = 320 * y;
@ -412,21 +412,6 @@ void fntDrawHLine (int x1, int x2, int y, int color)
for (i = x1; i <= x2; i++) xfb[whichfb][y + i] = color;
}
void fntDrawVLine (int x, int y1, int y2, int color)
{
int i;
x >>= 1;
for (i = y1; i <= y2; i++) xfb[whichfb][x + (640 * i) / 2] = color;
}
void fntDrawBox (int x1, int y1, int x2, int y2, int color)
{
fntDrawHLine (x1, x2, y1, color);
fntDrawHLine (x1, x2, y2, color);
fntDrawVLine (x1, y1, y2, color);
fntDrawVLine (x2, y1, y2, color);
}
void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color)
{
int h;

View File

@ -37,6 +37,6 @@ extern void write_font (int x, int y, char *string);
extern void WriteText(char *text, int size, int x, int y);
extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color);
extern int fheight;
extern int font_size[256];
extern u8 font_size[256];
#endif

View File

@ -1710,66 +1710,47 @@ void GUI_OptionBox2(gui_menu *parent, char *text_1, char *text_2, s16 *option_1,
/* Message Box displays a message until a specific action is completed */
/* Message Box LWP Thread */
static void *MsgBox_Thread(void *arg)
static void *MsgBox_Thread(gui_message *message_box)
{
while (1)
while (message_box->refresh)
{
if (message_box.refresh)
/* draw parent menu */
GUI_DrawMenu(message_box->parent);
/* draw window */
gxDrawTexture(message_box->window,166,160,message_box->window->width,message_box->window->height,230);
gxDrawTexture(message_box->top,166,160,message_box->top->width,message_box->top->height,255);
/* draw title */
if (message_box->title)
FONT_writeCenter(message_box->title,20,166,166+message_box->window->width,160+(message_box->top->height-20)/2+20,(GXColor)WHITE);
/* draw box message */
if (message_box->msg)
FONT_writeCenter(message_box->msg,18,166,166+message_box->window->width,248,(GXColor)WHITE);
/* draw throbber */
if (message_box->throbber)
gxDrawTextureRotate(message_box->throbber,166+(message_box->window->width-message_box->throbber->width)/2,160+message_box->window->height-message_box->throbber->height-20,message_box->throbber->width,message_box->throbber->height,(message_box->progress * 360.0) / 100.0, 255);
/* draw exit message */
if (message_box->buttonA)
{
/* draw parent menu */
GUI_DrawMenu(message_box.parent);
/* draw window */
gxDrawTexture(message_box.window,166,160,message_box.window->width,message_box.window->height,230);
gxDrawTexture(message_box.top,166,160,message_box.top->width,message_box.top->height,255);
/* draw title */
if (message_box.title)
FONT_writeCenter(message_box.title,20,166,166+message_box.window->width,160+(message_box.top->height-20)/2+20,(GXColor)WHITE);
/* draw box message */
if (message_box.msg)
FONT_writeCenter(message_box.msg,18,166,166+message_box.window->width,248,(GXColor)WHITE);
/* draw throbber */
if (message_box.throbber)
gxDrawTextureRotate(message_box.throbber,166+(message_box.window->width-message_box.throbber->width)/2,160+message_box.window->height-message_box.throbber->height-20,message_box.throbber->width,message_box.throbber->height,(message_box.progress * 360.0) / 100.0, 255);
/* draw exit message */
if (message_box.buttonA)
{
if (message_box.buttonB)
{
FONT_write("OK",18,220+message_box.buttonA->width+6,288,640,(GXColor)WHITE);
FONT_alignRight("CANCEL",18,166+message_box.window->width-(220-166),288,(GXColor)WHITE);
if (message_box.buttonA)
gxDrawTexture(message_box.buttonA, 220, 288-18+(18-message_box.buttonA->height)/2,message_box.buttonA->width, message_box.buttonA->height,255);
if (message_box.buttonB)
gxDrawTexture(message_box.buttonB, 328, 288-18+(18-message_box.buttonB->height)/2,message_box.buttonB->width, message_box.buttonB->height,255);
}
else
{
FONT_writeCenter("Press to continue.",18,166,166+message_box.window->width,248+22,(GXColor)WHITE);
if (message_box.buttonA)
gxDrawTexture(message_box.buttonA, 166+116, 248+4+(18-message_box.buttonA->height)/2,message_box.buttonA->width, message_box.buttonA->height,255);
}
}
/* update display */
gxSetScreen();
/* update progression */
message_box.progress++;
if (message_box.progress > 100)
message_box.progress = 0;
}
else
{
LWP_YieldThread();
FONT_writeCenter("Press to continue.",18,166,166+message_box->window->width,248+22,(GXColor)WHITE);
gxDrawTexture(message_box->buttonA, 166+116, 248+4+(18-message_box->buttonA->height)/2,message_box->buttonA->width, message_box->buttonA->height,255);
}
/* update display */
gxSetScreen();
/* update progression */
message_box->progress++;
if (message_box->progress > 100)
message_box->progress = 0;
usleep(10);
}
return NULL;
return 0;
}
/* update current Message Box */
@ -1787,12 +1768,7 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber)
if (SILENT)
return;
/* clear unused textures */
gxTextureClose(&message_box.buttonA);
gxTextureClose(&message_box.buttonB);
gxTextureClose(&message_box.throbber);
/* update message box */
/* update text */
GUI_MsgBoxUpdate(title,msg);
/* ensure we are not already running */
@ -1841,20 +1817,9 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber)
yoffset -= 60;
}
/* Final position */
GUI_DrawMenu(message_box.parent);
gxDrawTexture(message_box.window,xwindow,ywindow,message_box.window->width,message_box.window->height,230);
gxDrawTexture(message_box.top,xwindow,ywindow,message_box.top->width,message_box.top->height,255);
if (title)
FONT_writeCenter(title,20,xwindow,xwindow+message_box.window->width,ywindow+(message_box.top->height-20)/2+20,(GXColor)WHITE);
if (msg)
FONT_writeCenter(msg,18,xwindow,xwindow+message_box.window->width,ypos,(GXColor)WHITE);
gxSetScreen();
/* resume LWP thread for MessageBox refresh */
message_box.progress = 0;
/* create LWP thread for MessageBox refresh */
message_box.refresh = TRUE;
LWP_ResumeThread(msgboxthread);
LWP_CreateThread (&msgboxthread, (void *)MsgBox_Thread, &message_box, NULL, 0, 70);
}
}
@ -1865,7 +1830,7 @@ void GUI_MsgBoxClose(void)
{
/* suspend MessageBox refresh */
message_box.refresh = FALSE;
LWP_SuspendThread(msgboxthread);
LWP_JoinThread(msgboxthread, NULL);
/* window position */
int xwindow = 166;
@ -1912,7 +1877,6 @@ void GUI_MsgBoxClose(void)
gxTextureClose(&message_box.window);
gxTextureClose(&message_box.top);
gxTextureClose(&message_box.buttonA);
gxTextureClose(&message_box.buttonB);
gxTextureClose(&message_box.throbber);
}
}
@ -1922,7 +1886,10 @@ void GUI_WaitPrompt(char *title, char *msg)
if (SILENT)
return;
/* update message box */
/* clear unused texture */
gxTextureClose(&message_box.throbber);
/* open or update message box */
GUI_MsgBoxOpen(title, msg, 0);
/* allocate texture */
@ -1968,12 +1935,3 @@ void GUI_SetBgColor(u8 color)
}
}
/* Initialize GUI engine */
void GUI_Initialize(void)
{
/* create LWP thread for MessageBox refresh */
message_box.refresh = FALSE;
LWP_CreateThread (&msgboxthread, MsgBox_Thread, NULL, NULL, 0, 10);
LWP_SuspendThread(msgboxthread);
}

View File

@ -132,7 +132,6 @@ typedef struct
gx_texture *window; /* pointer to box texture */
gx_texture *top; /* pointer to box title texture */
gx_texture *buttonA; /* pointer to button A texture */
gx_texture *buttonB; /* pointer to button B texture */
gx_texture *throbber; /* pointer to throbber texture */
} gui_message;

View File

@ -1046,8 +1046,8 @@ static void systemmenu ()
if (cart.romsize)
{
/* force region & cpu mode */
set_region();
/* reset console region */
region_autodetect();
/* update framerate */
if (vdp_pal)
@ -1494,7 +1494,7 @@ static void ctrlmenu_raz(void)
m->buttons[i+2].data = &button_player_data;
m->buttons[i+2].state |= BUTTON_ACTIVE;
sprintf(m->items[i+2].text,"%d",max + 1);
if (cart.hw.jcart && (i > 4))
if (cart.jcart && (i > 4))
sprintf(m->items[i+2].comment,"Configure Player %d (J-CART) settings", max + 1);
else
sprintf(m->items[i+2].comment,"Configure Player %d settings", max + 1);
@ -1674,7 +1674,7 @@ static void ctrlmenu(void)
switch (m->selected)
{
case 0: /* update port 1 system */
if (cart.hw.jcart) break;
if (cart.jcart) break;
if (input.system[0] == SYSTEM_MOUSE)
input.system[0] +=3; /* lightguns are never used on Port 1 */
else
@ -1688,8 +1688,6 @@ static void ctrlmenu(void)
input.system[0] = NO_SYSTEM;
input.system[1] = SYSTEM_GAMEPAD;
}
old_system[0] = -1;
old_system[1] = -1;
io_init();
io_reset();
old_system[0] = input.system[0];
@ -1729,7 +1727,7 @@ static void ctrlmenu(void)
break;
case 1: /* update port 2 system */
if (cart.hw.jcart) break;
if (cart.jcart) break;
input.system[1] ++;
if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE))
input.system[1] ++;
@ -1740,8 +1738,6 @@ static void ctrlmenu(void)
input.system[1] = NO_SYSTEM;
input.system[0] = SYSTEM_GAMEPAD;
}
old_system[0] = -1;
old_system[1] = -1;
io_init();
io_reset();
old_system[0] = input.system[0];
@ -1861,7 +1857,7 @@ static void ctrlmenu(void)
GUI_DrawMenuFX(m, 20, 0);
/* update title */
if (cart.hw.jcart && (player > 1))
if (cart.jcart && (player > 1))
sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1);
else
sprintf(m->title,"Controller Settings (Player %d)",player+1);
@ -2112,7 +2108,7 @@ static void ctrlmenu(void)
}
/* remove duplicate assigned inputs before leaving */
for (i=0; i<8; i++)
for (i=0; i<MAX_INPUTS; i++)
{
if ((i!=player) && (config.input[i].device == config.input[player].device) && (config.input[i].port == config.input[player].port))
{
@ -2232,6 +2228,7 @@ static void optionmenu(void)
}
}
config_save();
GUI_DrawMenuFX(m,30,1);
GUI_DeleteMenu(m);
}
@ -2401,6 +2398,7 @@ static int savemenu(void)
case 6: /* set default slot */
{
config.s_default = slot;
config_save();
break;
}
@ -2613,44 +2611,45 @@ static void showrominfo (void)
/* fill ROM infos */
sprintf (items[0], "Console Type: %s", rominfo.consoletype);
sprintf (items[1], "Copyright: %s", rominfo.copyright);
sprintf (items[2], "Company Name: %s", companyinfo[getcompany ()].company);
sprintf (items[2], "Company Name: %s", get_company());
sprintf (items[3], "Domestic Name:");
sprintf (items[4], "%s",rominfo.domestic);
sprintf (items[5], "International Name:");
sprintf (items[6], "%s",rominfo.international);
sprintf (items[7], "Type: %s (%s)",rominfo.ROMType, strcmp(rominfo.ROMType, "AI") ? "Game" : "Educational");
sprintf (items[8], "Product ID: %s", rominfo.product);
sprintf (items[9], "Checksum: %04x (%04x) (%s)", rominfo.checksum, realchecksum, (rominfo.checksum == realchecksum) ? "GOOD" : "BAD");
sprintf (items[9], "Checksum: %04x (%04x) (%s)", rominfo.checksum, rominfo.realchecksum,
(rominfo.checksum == rominfo.realchecksum) ? "GOOD" : "BAD");
sprintf (items[10], "Supports: ");
if (peripherals & (1 << 1))
if (rominfo.peripherals & (1 << 1))
{
strcat(items[10],peripheralinfo[1].pName);
strcat(items[10],get_peripheral(1));
strcat(items[10],", ");
}
else if (peripherals & (1 << 0))
else if (rominfo.peripherals & (1 << 0))
{
strcat(items[10],peripheralinfo[0].pName);
strcat(items[10],get_peripheral(0));
strcat(items[10],", ");
}
if (peripherals & (1 << 7))
if (rominfo.peripherals & (1 << 7))
{
strcat(items[10],peripheralinfo[7].pName);
strcat(items[10],get_peripheral(7));
strcat(items[10],", ");
}
if (peripherals & (1 << 8))
if (rominfo.peripherals & (1 << 8))
{
strcat(items[10],peripheralinfo[8].pName);
strcat(items[10],get_peripheral(8));
strcat(items[10],", ");
}
if (peripherals & (1 << 11))
if (rominfo.peripherals & (1 << 11))
{
strcat(items[10],peripheralinfo[11].pName);
strcat(items[10],get_peripheral(11));
strcat(items[10],", ");
}
if (peripherals & (1 << 13))
if (rominfo.peripherals & (1 << 13))
{
strcat(items[10],peripheralinfo[13].pName);
strcat(items[10],get_peripheral(12));
strcat(items[10],", ");
}
if (strlen(items[10]) > 10)
@ -2699,7 +2698,8 @@ static void showcredits(void)
while (!p)
{
gxClearScreen ((GXColor)BLACK);
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
if (texture)
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
FONT_writeCenter("Genesis Plus Core", 24, 0, 640, 480 - offset, (GXColor)LIGHT_BLUE);
FONT_writeCenter("original 1.2a version by Charles MacDonald", 18, 0, 640, 516 - offset, (GXColor)WHITE);
@ -2876,7 +2876,9 @@ void MainMenu (void)
switch (GUI_OptionWindow(m, VERSION, items,3))
{
case 0: /* credits */
GUI_DeleteMenu(m);
showcredits();
GUI_InitMenu(m);
break;
case 1: /* return to loader */

View File

@ -85,7 +85,7 @@ static void pad_config(int chan, int max_keys)
{
int i;
u16 p,key;
char msg[30];
char msg[64];
/* reset VSYNC callback */
VIDEO_SetPostRetraceCallback(NULL);
@ -168,7 +168,9 @@ static void pad_update(s8 chan, u8 i)
else if ((p & PAD_TRIGGER_L) && (p & PAD_TRIGGER_Z))
{
/* Soft RESET */
set_softreset();
if (config.lock_on == TYPE_AR)
datel_reset(0);
gen_reset(0);
}
/* Retrieve current key mapping */
@ -344,7 +346,7 @@ static s8 WPAD_StickY(WPADData *data, u8 right)
static void wpad_config(u8 chan, u8 exp, u8 max_keys)
{
int i;
char msg[30];
char msg[64];
u32 key,p = 255;
/* remove inputs update callback */
@ -473,7 +475,9 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
((p & WPAD_CLASSIC_BUTTON_PLUS) && (p & WPAD_CLASSIC_BUTTON_MINUS)))
{
/* Soft RESET */
set_softreset();
if (config.lock_on == TYPE_AR)
datel_reset(0);
gen_reset(0);
}
/* Retrieve current key mapping */
@ -610,7 +614,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
if (system_hw != SYSTEM_PICO)
{
/* gamepad */
if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY))
if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY))
input.pad[i] |= INPUT_UP;
else if ((p & wpad_dirmap[exp][PAD_DOWN]) || (y < -ANALOG_SENSITIVITY))
input.pad[i] |= INPUT_DOWN;
@ -822,7 +826,9 @@ void gx_input_UpdateEmu(void)
if (SYS_ResetButtonDown())
{
/* Soft RESET */
set_softreset();
if (config.lock_on == TYPE_AR)
datel_reset(0);
gen_reset(0);
}
#endif

View File

@ -58,10 +58,10 @@ u8 *screenshot; /* Texture Data */
u32 gc_pal = 0;
/*** NTSC Filters ***/
sms_ntsc_t sms_ntsc;
md_ntsc_t md_ntsc;
static sms_ntsc_setup_t sms_setup;
static md_ntsc_setup_t md_setup;
sms_ntsc_t *sms_ntsc;
md_ntsc_t *md_ntsc;
static const sms_ntsc_setup_t *sms_setup;
static const md_ntsc_setup_t *md_setup;
/*** GX FIFO ***/
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
@ -1266,6 +1266,12 @@ void gxTextureClose(gx_texture **p_texture)
/* Emulation mode -> Menu mode */
void gx_video_Stop(void)
{
/* unallocate NTSC filters */
if (sms_ntsc)
free(sms_ntsc);
if (md_ntsc)
free(md_ntsc);
/* lightgun textures */
gxTextureClose(&crosshair[0]);
gxTextureClose(&crosshair[1]);
@ -1274,6 +1280,10 @@ void gx_video_Stop(void)
gxResetRendering(1);
gxResetMode(vmode);
/* display game snapshot */
gxClearScreen((GXColor)BLACK);
gxDrawScreenshot(0xff);
/* default VI settings */
VIDEO_SetPreRetraceCallback(NULL);
VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu);
@ -1282,14 +1292,12 @@ void gx_video_Stop(void)
VIDEO_SetGamma(VI_GM_1_0);
#endif
/* default TV mode */
/* adjust TV width */
vmode->viWidth = config.screen_w;
vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2;
VIDEO_Configure(vmode);
/* starts menu rendering */
gxClearScreen((GXColor)BLACK);
gxDrawScreenshot(0xff);
/* wait for VSYNC */
gxSetScreen();
}
@ -1344,27 +1352,35 @@ void gx_video_Start(void)
vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x);
vheight = bitmap.viewport.h + (2 * bitmap.viewport.y);
/* software NTSC filters */
if (config.ntsc == 1)
/* NTSC filter */
sms_ntsc = NULL;
md_ntsc = NULL;
if (config.ntsc)
{
sms_setup = sms_ntsc_composite;
md_setup = md_ntsc_composite;
sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup );
}
else if (config.ntsc == 2)
{
sms_setup = sms_ntsc_svideo;
md_setup = md_ntsc_svideo;
sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup );
}
else if (config.ntsc == 3)
{
sms_setup = sms_ntsc_rgb;
md_setup = md_ntsc_rgb;
sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup );
/* allocate filters */
sms_ntsc = (sms_ntsc_t *)memalign(32,sizeof(sms_ntsc_t));
md_ntsc = (md_ntsc_t *)memalign(32,sizeof(md_ntsc_t));
/* setup filters default configuration */
switch (config.ntsc)
{
case 1:
sms_setup = &sms_ntsc_composite;
md_setup = &md_ntsc_composite;
break;
case 2:
sms_setup = &sms_ntsc_svideo;
md_setup = &md_ntsc_svideo;
break;
case 3:
sms_setup = &sms_ntsc_rgb;
md_setup = &md_ntsc_rgb;
break;
}
/* initialize filters */
sms_ntsc_init(sms_ntsc, sms_setup);
md_ntsc_init(md_ntsc, md_setup);
}
/* lightgun textures */

View File

@ -155,6 +155,54 @@ static void init_machine(void)
bitmap.data = texturemem;
}
static void run_emulation(void)
{
/* main emulation loop */
while (1)
{
/* Main Menu request */
if (ConfigRequested)
{
/* stop video & audio */
gx_audio_Stop();
gx_video_Stop();
/* show menu */
MainMenu ();
ConfigRequested = 0;
/* start video & audio */
gx_audio_Start();
gx_video_Start();
frameticker = 1;
}
/* automatic frame skipping */
if (frameticker > 1)
{
/* skip frame */
frameticker = 0;
system_frame(1);
}
else
{
/* render frame */
frameticker = 0;
system_frame(0);
/* update video */
gx_video_Update();
}
/* update audio */
gx_audio_Update();
/* wait for next frame */
while (frameticker < 1)
usleep(1);
}
}
/**************************************************
Load a new rom and performs some initialization
***************************************************/
@ -325,62 +373,13 @@ int main (int argc, char *argv[])
SILENT = 0;
}
/* initialize GUI engine */
GUI_Initialize();
#ifdef HW_RVL
/* Power button callback */
SYS_SetPowerCallback(Power_Off);
#endif
/* main emulation loop */
int skip = 0;
while (1)
{
/* Main Menu request */
if (ConfigRequested)
{
/* stop video & audio */
gx_audio_Stop();
gx_video_Stop();
/* show menu */
MainMenu ();
ConfigRequested = 0;
/* start video & audio */
gx_audio_Start();
gx_video_Start();
skip = 0;
}
frameticker = 0;
if (skip)
{
/* skip frame */
system_frame(1);
skip = 0;
}
else
{
/* render frame */
system_frame(0);
/* update video */
gx_video_Update();
}
/* update audio */
gx_audio_Update();
/* wait for next frame */
while (frameticker < 1)
usleep(1);
/* automatic frame skipping */
if (frameticker > 1)
skip = 1;
}
run_emulation();
return 0;
}

View File

@ -57,8 +57,23 @@
#define PCDROM 4096
#define PMOUSE 8192
uint16 peripherals;
uint16 realchecksum;
#define MAXCOMPANY 64
#define MAXPERIPHERALS 14
typedef struct
{
char companyid[6];
char company[26];
} COMPANYINFO;
typedef struct
{
char pID[2];
char pName[14];
} PERIPHERALINFO;
ROMINFO rominfo;
char rom_filename[256];
@ -69,7 +84,7 @@ char rom_filename[256];
* Based on the document provided at
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
**************************************************************************/
COMPANYINFO companyinfo[MAXCOMPANY] = {
static COMPANYINFO companyinfo[MAXCOMPANY] = {
{"ACLD", "Ballistic"},
{"RSI", "Razorsoft"},
{"SEGA", "SEGA"},
@ -105,7 +120,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = {
{"50", "Electronic Arts"},
{"56", "Razorsoft"},
{"58", "Mentrix"},
{"60", "Victor Musical Industries"},
{"60", "Victor Musical Ind."},
{"69", "Arena"},
{"70", "Virgin"},
{"73", "Soft Vision"},
@ -142,7 +157,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = {
* Based on the document provided at
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
***************************************************************************/
PERIPHERALINFO peripheralinfo[14] = {
static PERIPHERALINFO peripheralinfo[MAXPERIPHERALS] = {
{"J", "3B Joypad"},
{"6", "6B Joypad"},
{"K", "Keyboard"},
@ -156,13 +171,14 @@ PERIPHERALINFO peripheralinfo[14] = {
{"T", "Tablet"},
{"V", "Paddle"},
{"C", "CD-ROM"},
{"M", "Mega Mouse"}
{"M", "Mega Mouse"},
};
/*
* softdev - New Checksum Calculation
eke-eke: fixed
*/
/***************************************************************************
* GetRealChecksum
*
* Compute ROM checksum.
***************************************************************************/
static uint16 GetRealChecksum (uint8 *rom, int length)
{
int i;
@ -217,31 +233,28 @@ static void getrominfo (char *romheader)
memcpy (&rominfo.ROMType, romheader + ROMTYPE, 2);
memcpy (&rominfo.product, romheader + ROMPRODUCT, 12);
memcpy (&rominfo.checksum, romheader + ROMCHECKSUM, 2);
memcpy (&rominfo.io_support, romheader + ROMIOSUPPORT, 16);
memcpy (&rominfo.romstart, romheader + ROMROMSTART, 4);
memcpy (&rominfo.romend, romheader + ROMROMEND, 4);
memcpy (&rominfo.RAMInfo, romheader + ROMRAMINFO, 12);
memcpy (&rominfo.ramstart, romheader + ROMRAMSTART, 4);
memcpy (&rominfo.ramend, romheader + ROMRAMEND, 4);
memcpy (&rominfo.modem, romheader + ROMMODEMINFO, 12);
memcpy (&rominfo.memo, romheader + ROMMEMO, 40);
memcpy (&rominfo.country, romheader + ROMCOUNTRY, 16);
realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200);
#ifdef LSB_FIRST
rominfo.checksum = (rominfo.checksum >> 8) | ((rominfo.checksum & 0xff) << 8);
#endif
rominfo.realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200);
peripherals = 0;
rominfo.peripherals = 0;
for (i = 0; i < 14; i++)
for (j=0; j < 14; j++)
if (rominfo.io_support[i] == peripheralinfo[j].pID[0])
peripherals |= (1 << j);
for (j=0; j < 14; j++)
if (romheader[ROMIOSUPPORT+i] == peripheralinfo[j].pID[0])
rominfo.peripherals |= (1 << j);
}
/* SMD (interleaved) rom support */
static void deinterleave_block (uint8 * src)
/***************************************************************************
* deinterleave_block
*
* Convert interleaved (.smd) ROM files.
***************************************************************************/
static void deinterleave_block(uint8 * src)
{
int i;
uint8 block[0x4000];
@ -253,6 +266,11 @@ static void deinterleave_block (uint8 * src)
}
}
/***************************************************************************
* load_rom
*
* Load a new ROM file.
***************************************************************************/
int load_rom(char *filename)
{
int i, size, offset = 0;
@ -274,12 +292,8 @@ int load_rom(char *filename)
{
size -= 512;
offset += 512;
for (i = 0; i < (size / 0x4000); i += 1)
{
deinterleave_block (cart.rom + offset + (i * 0x4000));
}
memcpy(cart.rom, cart.rom + offset, size);
}
@ -288,13 +302,16 @@ int load_rom(char *filename)
cart.romsize = size;
/* clear unused ROM space */
memset (cart.rom + size, 0xff, MAXROMSIZE - size);
memset(cart.rom + size, 0xff, MAXROMSIZE - size);
/* get infos from ROM header */
getrominfo((char *)cart.rom);
/* set system region */
set_region();
/* get specific input devices */
input_autodetect();
/* get default region */
region_autodetect();
#ifdef LSB_FIRST
/* Byteswap ROM */
@ -331,8 +348,13 @@ int load_rom(char *filename)
return(1);
}
/* 05/05/2006: new region detection routine (taken from GENS sourcecode) */
void set_region ()
/****************************************************************************
* region_autodetect
*
* Set console region upon ROM header
*
****************************************************************************/
void region_autodetect(void)
{
/* country codes used to differentiate region */
/* 0001 = japan ntsc (1) */
@ -379,7 +401,7 @@ void set_region ()
/* need PAL settings */
region_code = REGION_EUROPE;
}
else if ((realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
else if ((rominfo.realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
{
/* On Dal Jang Goon (Korea) needs JAP region code */
region_code = REGION_JAPAN_NTSC;
@ -410,7 +432,7 @@ void set_region ()
}
/****************************************************************************
* getcompany
* get_company
*
* Try to determine which company made this rom
*
@ -418,13 +440,14 @@ void set_region ()
* It seems that there can be pretty much anything you like following the
* copyright (C) symbol!
****************************************************************************/
int getcompany ()
char *get_company(void)
{
char *s;
int i;
char company[10];
for (i = 3; i < 8; i++) company[i - 3] = rominfo.copyright[i];
for (i = 3; i < 8; i++)
company[i - 3] = rominfo.copyright[i];
company[5] = 0;
/** OK, first look for a hyphen
@ -439,14 +462,31 @@ int getcompany ()
/** Strip any trailing spaces **/
for (i = strlen (company) - 1; i >= 0; i--)
if (company[i] == 32) company[i] = 0;
if (company[i] == 32)
company[i] = 0;
if (strlen (company) == 0) return MAXCOMPANY - 1;
if (strlen (company) == 0)
return companyinfo[MAXCOMPANY - 1].company;
for (i = 0; i < MAXCOMPANY - 1; i++)
{
if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) return i;
if (!(strncmp (company, companyinfo[i].companyid, strlen (company))))
return companyinfo[i].company;
}
return MAXCOMPANY - 1;
return companyinfo[MAXCOMPANY - 1].company;
}
/****************************************************************************
* get_peripheral
*
* Return peripheral name based on header code
*
****************************************************************************/
char *get_peripheral(int index)
{
if (index < MAXPERIPHERALS)
return peripheralinfo[index].pName;
return companyinfo[MAXCOMPANY - 1].company;
}

View File

@ -23,53 +23,34 @@
#ifndef _LOADROM_H_
#define _LOADROM_H_
#define MAXCOMPANY 64
#define MAXROMSIZE 10485760
typedef struct
{
char consoletype[18]; /* Genesis or Mega Drive */
char copyright[18]; /* Copyright message */
char domestic[50]; /* Domestic name of ROM */
char international[50]; /* International name of ROM */
char ROMType[4]; /* Educational or Game */
char product[14]; /* Product serial number */
unsigned short checksum; /* Checksum */
char io_support[18]; /* Actually 16 chars :) */
unsigned int romstart; /* ROM start address */
unsigned int romend; /* ROM end address */
char RAMInfo[14]; /* Backup RAM header */
unsigned int ramstart; /* RAM start address */
unsigned int ramend; /* RAM end address */
char modem[14]; /* Sega Modem support */
char memo[50]; /* Misc */
char country[18]; /* Country flag */
char consoletype[18]; /* Genesis or Mega Drive */
char copyright[18]; /* Copyright message */
char domestic[50]; /* Domestic name of ROM */
char international[50]; /* International name of ROM */
char ROMType[4]; /* Educational or Game */
char product[14]; /* Product serial number */
unsigned short checksum; /* ROM Checksum (header) */
unsigned short realchecksum; /* ROM Checksum (calculated) */
unsigned int romstart; /* ROM start address */
unsigned int romend; /* ROM end address */
char country[18]; /* Country flag */
uint16 peripherals; /* Supported peripherals */
} ROMINFO;
typedef struct
{
char companyid[6];
char company[30];
} COMPANYINFO;
typedef struct
{
char pID[2];
char pName[21];
} PERIPHERALINFO;
/* Global variables */
extern ROMINFO rominfo;
extern COMPANYINFO companyinfo[MAXCOMPANY];
extern PERIPHERALINFO peripheralinfo[14];
extern uint16 realchecksum;
extern uint16 peripherals;
extern char rom_filename[256];
/* Function prototypes */
extern int load_rom(char *filename);
extern int getcompany();
extern void set_region();
extern void region_autodetect(void);
extern char *get_company(void);
extern char *get_peripheral(int index);
#endif /* _LOADROM_H_ */

View File

@ -124,7 +124,7 @@ const uint m68ki_shift_32_table[65] =
/* Number of clock cycles to use for exception processing.
* I used 4 for any vectors that are undocumented for processing times.
*/
uint16 m68ki_exception_cycle_table[4][256] =
uint16 m68ki_exception_cycle_table[NUM_CPU_TYPES][256] =
{
{ /* 000 */
40, /* 0: Reset - Initial Stack Pointer */
@ -199,6 +199,8 @@ uint16 m68ki_exception_cycle_table[4][256] =
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
},
#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
{ /* 010 */
40, /* 0: Reset - Initial Stack Pointer */
4, /* 1: Reset - Initial Program Counter */
@ -418,6 +420,7 @@ uint16 m68ki_exception_cycle_table[4][256] =
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
}
#endif
};
#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
@ -694,6 +697,8 @@ void m68k_set_cpu_type(unsigned int cpu_type)
CYC_SHIFT = 2 * 7;
CYC_RESET = 132 * 7;
return;
#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
case M68K_CPU_TYPE_68008:
CPU_TYPE = CPU_TYPE_008;
CPU_ADDRESS_MASK = 0x003fffff;
@ -774,6 +779,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
CYC_SHIFT = 0;
CYC_RESET = 518;
return;
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,11 @@
/* ============================ OPCODE HANDLERS =========================== */
/* ======================================================================== */
#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
#define NUM_CPU_TYPES 4
#else
#define NUM_CPU_TYPES 1
#endif
/* Build the opcode handler table */
void m68ki_build_opcode_table(void);

View File

@ -64,8 +64,6 @@ extern void vdp_write_word(uint32 address, uint32 data);
extern uint32 pico_read_byte(uint32 address);
extern uint32 pico_read_word(uint32 address);
uint8 m68k_readmap[256];
uint8 m68k_writemap[256];
uint32 pico_current;
#endif /* _MEM68K_H_ */

View File

@ -26,8 +26,8 @@
#include "sms_ntsc.h"
/*** NTSC Filters ***/
extern md_ntsc_t md_ntsc;
extern sms_ntsc_t sms_ntsc;
extern md_ntsc_t *md_ntsc;
extern sms_ntsc_t *sms_ntsc;
/* Look-up pixel table information */
#define LUT_MAX (5)
@ -1836,9 +1836,9 @@ void remap_buffer(int line, int width)
if (config.ntsc)
{
if (reg[12]&1)
md_ntsc_blit(&md_ntsc, ( MD_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
md_ntsc_blit(md_ntsc, ( MD_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
else
sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
sms_ntsc_blit(sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
return;
}

View File

@ -22,8 +22,7 @@
#include "shared.h"
static unsigned char state[STATE_SIZE];
#define STATE_VERSION "GENPLUS-GX 1.4.x"
#define load_param(param, size) \
memcpy(param, &state[bufferptr], size); \
@ -38,6 +37,10 @@ int state_load(unsigned char *buffer)
/* buffer size */
int bufferptr = 0;
/* first allocate state buffer */
unsigned char *state = (unsigned char *)malloc(STATE_SIZE);
if (!state) return 0;
/* uncompress savestate */
unsigned long inbytes, outbytes;
memcpy(&inbytes, buffer, 4);
@ -49,7 +52,8 @@ int state_load(unsigned char *buffer)
load_param(version,16);
if (strncmp(version,STATE_VERSION,16))
{
return 0;
free(state);
return -1;
}
/* reset system */
@ -116,6 +120,7 @@ int state_load(unsigned char *buffer)
// Z80
load_param(&Z80, sizeof(Z80_Regs));
free(state);
return 1;
}
@ -124,6 +129,10 @@ int state_save(unsigned char *buffer)
/* buffer size */
int bufferptr = 0;
/* first allocate state buffer */
unsigned char *state = (unsigned char *)malloc(STATE_SIZE);
if (!state) return 0;
/* version string */
char version[16];
strncpy(version,STATE_VERSION,16);
@ -164,7 +173,7 @@ int state_save(unsigned char *buffer)
uint16 tmp16;
uint32 tmp32;
tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4);
@ -181,7 +190,7 @@ int state_save(unsigned char *buffer)
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4);
tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2);
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
// Z80
save_param(&Z80, sizeof(Z80_Regs));
@ -191,6 +200,7 @@ int state_save(unsigned char *buffer)
unsigned long outbytes = STATE_SIZE;
compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9);
memcpy(buffer, &outbytes, 4);
free(state);
/* return total size */
return (outbytes + 4);

View File

@ -24,7 +24,6 @@
#define _STATE_H_
#define STATE_SIZE 0x28000
#define STATE_VERSION "GENPLUS-GX 1.4.x"
/* Function prototypes */
extern int state_load(unsigned char *buffer);

View File

@ -278,16 +278,16 @@ void audio_shutdown(void)
****************************************************************/
void system_init (void)
{
/* Cartridge hardware */
cart_hw_init();
/* Genesis hardware */
gen_init();
io_init();
vdp_init();
render_init();
/* Sound Chips hardware */
/* Cartridge hardware */
cart_hw_init();
/* Sound hardware */
sound_init();
}
@ -305,10 +305,10 @@ void system_reset (void)
vdp_reset();
render_reset();
/* Sound chips */
/* Sound hardware */
sound_reset();
/* Audio System */
/* Audio system */
audio_reset();
}
@ -335,7 +335,6 @@ int system_frame (int do_skip)
/* update display settings */
int line;
int reset = resetline;
int vdp_height = bitmap.viewport.h;
int end_line = vdp_height + bitmap.viewport.y;
int start_line = lines_per_frame - bitmap.viewport.y;
@ -381,16 +380,6 @@ int system_frame (int do_skip)
/* 68k line cycle count */
hint_68k = mcycles_68k;
/* Soft Reset line */
if (line == reset)
{
/* Pro Action Replay (switch at "Trainer" position) */
if (config.lock_on == TYPE_AR)
datel_reset(0);
gen_reset(0);
}
/* update VDP DMA */
if (dma_length)
vdp_update_dma();

View File

@ -220,7 +220,7 @@ static Uint32 sdl_sync_timer_callback(Uint32 interval)
{
int fps = vdp_pal ? (sdl_video.frames_rendered / 3) : sdl_video.frames_rendered;
sdl_sync.ticks = sdl_video.frames_rendered = 0;
sprintf(caption, "Genesis Plus/SDL - %s (%s) - 0x%04X - %d fps", rominfo.international, region, realchecksum, fps);
sprintf(caption, "Genesis Plus/SDL - %s (%s) - 0x%04X - %d fps", rominfo.international, region, rominfo.realchecksum, fps);
SDL_WM_SetCaption(caption, NULL);
}
return interval;