.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] [Gamecube/Wii]
--------------- ---------------
* implemented new FONT engine (using internal IPL font & GX hardware rendering). * implemented custom FONT engine (uses internal IPL font & GX hardware rendering).
* implemented custom GUI engine (with PCM/OGG sound support, multithreading & using GX hardware for rendering) * implemented custom GUI engine (uses GX hardware rendering & multithreading)
* new interface design (incl. IR pointing, game snapshots, visual & sound effects, BGM...). * implemented advanced interface (IR pointing, game snapshots, visual & sound effects, BGM...).
* improved audio/video back-end synchronization to ensure 100% smooth video & audio playback. * 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 reset button behavior, now works more like the real Genesis reset button.
* improved lightgun cursors layout. * improved lightgun cursors layout.
* added automatic ROM loading feature
* fixed stability issues and memory leaks. * fixed stability issues and memory leaks.
[Wii only] [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] = static const T_CART_ENTRY rom_database[CART_CNT] =
{ {
/* Funny World & Balloon Boy */ /* 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 */ /* 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 */ /* 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) */ /* 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) */ /* 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) */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 Cart Hardware initialization
@ -286,124 +283,15 @@ void cart_hw_init()
m68k_memory_map[0x3a].read16 = svp_read_cell_2; 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 J-CART
***********************************************/ ***********************************************/
cart.hw.jcart = 0; if (cart.jcart)
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) */ m68k_memory_map[0x38].read16 = jcart_read;
{ m68k_memory_map[0x38].write16 = jcart_write;
cart.hw.jcart = 1; m68k_memory_map[0x3f].read16 = jcart_read;
m68k_memory_map[0x38].read16 = jcart_read; m68k_memory_map[0x3f].write16 = jcart_write;
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;
}
} }
/********************************************** /**********************************************
@ -427,51 +315,51 @@ void cart_hw_init()
break; break;
case TYPE_SK: case TYPE_SK:
/* be sure we have enough place to store both ROMs */ {
if (cart.romsize < 0x700000) /* store S&K ROM above cartridge ROM + SRAM */
{ if (cart.romsize > 0x600000) break;
/* 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);
/* load Sonic 2 UPMEM ROM (256 KBytes) */ /* load Sonic & Knuckles ROM (2 MBytes) */
f = fopen(SK_UPMEM,"r+b"); FILE *f = fopen(SK_ROM,"r+b");
if (!f) break; if (!f) break;
done = 0; int done = 0;
while (done < 0x40000) while (done < 0x200000)
{ {
fread(cart.rom+0x900000+done,4096,1,f); fread(cart.rom + 0x600000 + done, 2048, 1, f);
done += 4096; done += 2048;
} }
fclose(f); 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 #ifdef LSB_FIRST
/* Byteswap ROM */ /* Byteswap ROM */
int i; int i;
uint8 temp; uint8 temp;
for(i = 0; i < 0x240000; i += 2) for(i = 0; i < 0x240000; i += 2)
{ {
temp = cart.rom[i+0x700000]; temp = cart.rom[i + 0x600000];
cart.rom[i+0x700000] = cart.rom[i+1+0x700000]; cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1];
cart.rom[i+1+0x700000] = temp; cart.rom[i + 0x600000 + 1] = temp;
} }
#endif #endif
/*$000000-$1fffff is mapped to S&K ROM */ /*$000000-$1fffff is mapped to S&K ROM */
for (i=0x00; i<0x20; i++) for (i=0x00; i<0x20; i++)
m68k_memory_map[i].base = (cart.rom + 0x700000) + (i<<16); m68k_memory_map[i].base = (cart.rom + 0x600000) + (i<<16);
cart.lock_on = 1; cart.lock_on = 1;
}
break; break;
}
default: default:
break; break;
@ -487,7 +375,7 @@ void cart_hw_init()
{ {
/* known cart found ! */ /* known cart found ! */
if ((rominfo.checksum == rom_database[i].chk_1) && if ((rominfo.checksum == rom_database[i].chk_1) &&
(realchecksum == rom_database[i].chk_2)) (rominfo.realchecksum == rom_database[i].chk_2))
{ {
/* retrieve hardware information */ /* retrieve hardware information */
memcpy(&cart.hw, &(rom_database[i].cart_hw), sizeof(T_CART_HW)); 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; emulate_address_error = config.addr_error;
#endif #endif
/* detect ROM files larger than 4MB */ /* detect special cartridges */
if (cart.romsize > 0x800000) if (cart.romsize > 0x800000)
{ {
/* Ultimate MK3 (hack) */ /* Ultimate MK3 (hack) */
@ -546,7 +434,6 @@ void cart_hw_init()
} }
/* default write handler for !TIME signal */ /* default write handler for !TIME signal */
/* TODO: handle Sonic & Knuckles + Sonic 2 case to prevent RAM activation */
if (!cart.hw.time_w) if (!cart.hw.time_w)
cart.hw.time_w = default_time_w; cart.hw.time_w = default_time_w;
} }
@ -567,10 +454,10 @@ void cart_hw_reset()
if (cart.hw.realtec & 1) if (cart.hw.realtec & 1)
{ {
/* enable BOOTROM */ /* enable BOOTROM */
for (i=0x00; i<0x40; i++)
m68k_memory_map[i].base = mem_chunk;
for (i=0; i<8; i++) 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; cart.hw.realtec |= 2;
} }
@ -657,7 +544,7 @@ static void sega_mapper_w(uint32 address, uint32 data)
{ {
/* enable UPMEM chip at $300000-$3fffff */ /* enable UPMEM chip at $300000-$3fffff */
for (i=0x30; i<0x40; i++) 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 else
@ -708,9 +595,9 @@ static void multi_mapper_w(uint32 address, uint32 data)
static void special_mapper_w(uint32 address, uint32 data) static void special_mapper_w(uint32 address, uint32 data)
{ {
/* 1 x 32k bank */ /* 1 x 32k bank */
m68k_memory_map[0].base = mem_chunk; memcpy(cart.rom + 0x900000, cart.rom + ((data & 0x7f) << 15), 0x8000);
memcpy(mem_chunk,&cart.rom[(data & 0x7f) << 15],0x8000); memcpy(cart.rom + 0x908000, cart.rom + 0x8000, 0x8000);
memcpy(mem_chunk+0x8000,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) */ uint8 regs[4]; /* internal registers (R/W) */
uint32 mask[4]; /* registers address mask */ uint32 mask[4]; /* registers address mask */
uint32 addr[4]; /* registers address */ uint32 addr[4]; /* registers address */
uint32 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */ uint16 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */
uint16 jcart; /* cartridge with JCART port */
uint16 bankshift; /* cartridge with bankshift mecanism */ uint16 bankshift; /* cartridge with bankshift mecanism */
unsigned int (*time_r)(unsigned int address); /* !TIME signal ($a130xx) read handler */ 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 */ void (*time_w)(unsigned int address, unsigned int data); /* !TIME signal ($a130xx) write handler */
@ -51,11 +50,12 @@ typedef struct
typedef struct typedef struct
{ {
uint8 *rom; /* ROM data */ uint8 *rom; /* ROM data */
uint8 *base; /* ROM area (slot 0) */ uint8 *base; /* ROM base area (slot 0) */
uint32 mask; /* mask ROM */
uint32 lock_on; /* 1: Lock-On enabled */
uint32 romsize; /* ROM size */ 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; } T_CART;
/* global variables */ /* global variables */

View File

@ -27,8 +27,8 @@
struct struct
{ {
uint8 enabled; uint8 enabled;
uint8 rom[0x20000]; uint8 *rom;
uint8 ram[0x10000]; uint8 *ram;
uint16 regs[13]; uint16 regs[13];
uint16 old[4]; uint16 old[4];
uint16 data[4]; uint16 data[4];
@ -49,6 +49,11 @@ void datel_init(void)
if (!f) if (!f)
return; 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 */ /* ROM size */
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
int size = ftell(f); int size = ftell(f);
@ -59,9 +64,6 @@ void datel_init(void)
case 0x8000: /* ACTION REPLAY (32K) */ case 0x8000: /* ACTION REPLAY (32K) */
{ {
action_replay.enabled = TYPE_AR; action_replay.enabled = TYPE_AR;
/* $0000-$7fff mirrored into $8000-$ffff */
memcpy(action_replay.rom+0x8000,action_replay.rom,0x8000);
break; break;
} }
@ -92,33 +94,32 @@ void datel_init(void)
} }
default: default:
{
fclose(f);
return; return;
}
} }
if (action_replay.enabled) /* Load ROM */
fseek(f, 0, SEEK_SET);
int i = 0;
while (i < size)
{ {
/* Load ROM */ fread(action_replay.rom+i,0x1000,1,f);
fseek(f, 0, SEEK_SET); i += 0x1000;
int i = 0; }
while (i < size) fclose(f);
{
fread(action_replay.rom+i,0x1000,1,f);
i += 0x1000;
}
#ifdef LSB_FIRST #ifdef LSB_FIRST
/* Byteswap ROM */ /* Byteswap ROM */
uint8 temp; uint8 temp;
for(i = 0; i < size; i += 2) for(i = 0; i < size; i += 2)
{ {
temp = action_replay.rom[i]; temp = action_replay.rom[i];
action_replay.rom[i] = action_replay.rom[i+1]; action_replay.rom[i] = action_replay.rom[i+1];
action_replay.rom[i+1] = temp; action_replay.rom[i+1] = temp;
}
#endif
} }
#endif
fclose(f);
} }
void datel_shutdown(void) void datel_shutdown(void)
@ -178,7 +179,7 @@ void datel_reset(int hard_reset)
/* clear RAM on hard reset only */ /* clear RAM on hard reset only */
if (hard_reset) if (hard_reset)
memset(action_replay.ram,0,sizeof(action_replay.ram)); memset(action_replay.ram,0,0x10000);
} }
void datel_switch(int enable) 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 */ /* 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) if ((sram.end - sram.start) < 2)
{ {
sram.custom = 1;
sram.on = 1;
/* set SEGA mapper as default */ /* set SEGA mapper as default */
sram.custom = 1;
memcpy(&eeprom.type, &database[9].type, sizeof(T_EEPROM_TYPE)); memcpy(&eeprom.type, &database[9].type, sizeof(T_EEPROM_TYPE));
} }
} }

View File

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

View File

@ -42,33 +42,41 @@ T_SRAM sram;
void sram_init() void sram_init()
{ {
memset (&sram, 0, sizeof (T_SRAM)); 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)) 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.start = READ_WORD_LONG(cart.rom, 0x1b4);
sram.end = READ_WORD_LONG(cart.rom, 0x1b8); sram.end = READ_WORD_LONG(cart.rom, 0x1b8);
/* fixe some bad header informations */ /* fixe some bad header informations */
if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000)) if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000))
sram.end = sram.start + 0xffff; sram.end = sram.start + 0xffff;
sram.start &= 0xfffffffe; sram.start &= 0xfffffffe;
sram.end |= 1; sram.end |= 1;
/* enable SRAM */
sram.on = 1; sram.on = 1;
sram.detected = 1;
} }
else else
{ {
/* default SRAM region */ /* default SRAM region */
sram.start = 0x200000; sram.start = 0x200000;
sram.end = 0x20ffff; sram.end = 0x20ffff;
}
/* set SRAM ON by default when ROM is not mapped */ /* enable SRAM only if ROM < 2MB */
if (cart.romsize <= sram.start) if (cart.romsize <= sram.start)
sram.on = 1; sram.on = 1;
}
/* autodetect some games with bad header or specific configuration */ /* autodetect some games with bad header or specific configuration */
if (strstr(rominfo.product,"T-113016") != NULL) if (strstr(rominfo.product,"T-113016") != NULL)
@ -119,7 +127,8 @@ void sram_init()
sram.start = 0x200001; sram.start = 0x200001;
sram.end = 0x203fff; 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) */ /* Xin Qigai Wangzi, aka Beggar Prince (no header, use uncommon area) */
sram.on = 1; sram.on = 1;

View File

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

View File

@ -24,6 +24,7 @@
#include "shared.h" #include "shared.h"
t_input input; 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) 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 static struct mega_mouse
@ -268,7 +269,7 @@ uint32 mouse_read()
/***************************************************************************** /*****************************************************************************
* GAMEPAD specific functions (2PLAYERS/4WAYPLAY) * GAMEPAD support (2PLAYERS/4WAYPLAY)
* *
*****************************************************************************/ *****************************************************************************/
static struct pad static struct pad
@ -297,15 +298,15 @@ static inline void gamepad_update(uint32 i)
static inline uint32 gamepad_read(uint32 i) static inline uint32 gamepad_read(uint32 i)
{ {
int control; /* bit7 is latched */
int retval = 0x7F; 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) if (input.dev[i] == DEVICE_6BUTTON)
{ control += (gamepad[i].Counter & 3) << 1;
control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */
}
switch (control) switch (control)
{ {
@ -376,7 +377,6 @@ static inline uint32 gamepad_read(uint32 i)
break; break;
} }
/* bit7 is latched */
return retval; return retval;
} }
@ -397,7 +397,7 @@ static inline void gamepad_write(uint32 i, uint32 data)
/***************************************************************************** /*****************************************************************************
* TEAMPLAYER adapter * TEAMPLAYER adapter support
* *
*****************************************************************************/ *****************************************************************************/
static struct teamplayer 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) static inline void wayplay_write(uint32 port, uint32 data)
@ -619,7 +619,8 @@ void teamplayer_2_write (uint32 data)
uint32 jcart_read(uint32 address) 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) void jcart_write(uint32 address, uint32 data)
@ -719,7 +720,7 @@ void input_init(void)
} }
/* J-CART: add two gamepad inputs */ /* J-CART: add two gamepad inputs */
if (cart.hw.jcart) if (cart.jcart)
{ {
input.dev[5] = config.input[2].padtype; input.dev[5] = config.input[2].padtype;
input.dev[6] = config.input[3].padtype; input.dev[6] = config.input[3].padtype;
@ -767,13 +768,15 @@ void input_update(void)
switch (input.system[0]) switch (input.system[0])
{ {
case SYSTEM_GAMEPAD: case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0); if (input.dev[0] == DEVICE_6BUTTON)
gamepad_update(0);
break; break;
case SYSTEM_WAYPLAY: case SYSTEM_WAYPLAY:
for (i=0; i<4; i++) 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; break;
} }
@ -781,7 +784,8 @@ void input_update(void)
switch (input.system[1]) switch (input.system[1])
{ {
case SYSTEM_GAMEPAD: case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4); if (input.dev[4] == DEVICE_6BUTTON)
gamepad_update(4);
break; break;
case SYSTEM_MENACER: case SYSTEM_MENACER:
@ -789,8 +793,10 @@ void input_update(void)
break; break;
case SYSTEM_JUSTIFIER: case SYSTEM_JUSTIFIER:
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0); if ((io_reg[2] & 0x30) == 0x00)
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1); lightgun_update(0);
if ((io_reg[2] & 0x30) == 0x20)
lightgun_update(1);
break; break;
} }
} }
@ -801,13 +807,15 @@ void input_raz(void)
switch (input.system[0]) switch (input.system[0])
{ {
case SYSTEM_GAMEPAD: case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0); if (input.dev[0] == DEVICE_6BUTTON)
gamepad_raz(0);
break; break;
case SYSTEM_WAYPLAY: case SYSTEM_WAYPLAY:
for (i=0; i<4; i++) 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; break;
} }
@ -815,7 +823,123 @@ void input_raz(void)
switch (input.system[1]) switch (input.system[1])
{ {
case SYSTEM_GAMEPAD: case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4); if (input.dev[4] == DEVICE_6BUTTON)
gamepad_raz(4);
break; 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_reset(void);
extern void input_update(void); extern void input_update(void);
extern void input_raz(void); extern void input_raz(void);
extern void input_autodetect(void);
/* Peripherals specific */ /* Peripherals specific */
extern void mouse_write(uint32 data); extern void mouse_write(uint32 data);

View File

@ -25,7 +25,6 @@
uint8 io_reg[0x10]; uint8 io_reg[0x10];
uint8 region_code = REGION_USA; uint8 region_code = REGION_USA;
int old_system[2] = {-1,-1};
static struct port_t static struct port_t
{ {
@ -117,20 +116,24 @@ void io_init(void)
void io_reset(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 */ /* 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 */ /* Reset connected input devices */
input_reset(); input_reset();
} }
@ -142,29 +145,16 @@ void io_write(uint32 offset, uint32 value)
case 0x01: /* Port A Data */ case 0x01: /* Port A Data */
case 0x02: /* Port B Data */ case 0x02: /* Port B Data */
case 0x03: /* Port C Data */ case 0x03: /* Port C Data */
io_reg[offset] = ((value & 0x80) | (value & io_reg[offset+3])); io_reg[offset] = value & (0x80 | io_reg[offset+3]);
if(port[offset-1].data_w) port[offset-1].data_w(value); if(port[offset-1].data_w)
port[offset-1].data_w(value);
return; 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 0x04: /* Port A Ctrl */
case 0x05: /* Port B Ctrl */
case 0x06: /* Port C Ctrl */ case 0x06: /* Port C Ctrl */
io_reg[offset] = value & 0xFF; io_reg[offset] = value;
io_reg[offset-3] = ((io_reg[offset-3] & 0x80) | (io_reg[offset-3] & io_reg[offset])); io_reg[offset-3] &= (0x80 | value);
return; return;
case 0x07: /* Port A TxData */ case 0x07: /* Port A TxData */
@ -176,7 +166,10 @@ void io_write(uint32 offset, uint32 value)
case 0x09: /* Port A S-Ctrl */ case 0x09: /* Port A S-Ctrl */
case 0x0C: /* Port B S-Ctrl */ case 0x0C: /* Port B S-Ctrl */
case 0x0F: /* Port C S-Ctrl */ case 0x0F: /* Port C S-Ctrl */
io_reg[offset] = (value & 0xF8); io_reg[offset] = value & 0xF8;
return;
default: /* Read-only ports */
return; return;
} }
} }
@ -185,23 +178,17 @@ uint32 io_read(uint32 offset)
{ {
switch(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 0x01: /* Port A Data */
case 0x02: /* Port B Data */ case 0x02: /* Port B Data */
case 0x03: /* Port C Data */ case 0x03: /* Port C Data */
{ {
uint8 input = 0x7F; /* default input state */ uint8 input = 0x7F;
if(port[offset-1].data_r) input = port[offset-1].data_r(); if(port[offset-1].data_r)
input = port[offset-1].data_r();
return (io_reg[offset] | ((~io_reg[offset+3]) & input)); return (io_reg[offset] | ((~io_reg[offset+3]) & input));
} }
default: default: /* return register value */
return (io_reg[offset]); 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 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
uint32 zbank; /* Z80 bank window address */ uint32 zbank; /* Z80 bank window address */
uint32 gen_running; /* 0: cpu are in locked state */ 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 */ /* Init, reset, shutdown functions */
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void set_softreset(void)
{
resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0));
}
void gen_init(void) void gen_init(void)
{ {
@ -138,13 +133,17 @@ void gen_reset(uint32 hard_reset)
mcycles_68k = 0; mcycles_68k = 0;
mcycles_z80 = 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 */ zstate = 0; /* Z80 is reset & has control of the bus */
zirq = 0; /* No interrupts occuring */ zirq = 0; /* No interrupts occuring */
zbank = 0; /* Assume default bank is $000000-$007FFF */ zbank = 0; /* Assume default bank is $000000-$007FFF */
/* Reset CPUs */ /* Reset CPUs */
resetline = -1;
gen_running = 1; gen_running = 1;
fm_reset(0); fm_reset(0);
m68k_pulse_reset(); m68k_pulse_reset();

View File

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

View File

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

View File

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

View File

@ -35,13 +35,6 @@
*/ */
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32); 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 * CardMount
@ -139,9 +132,9 @@ void slot_autodetect(int slot, int device, t_slot *ptr)
{ {
/* Memory Card support */ /* Memory Card support */
if (slot > 0) if (slot > 0)
sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1); sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else else
sprintf(filename,"MD-%04X.srm", realchecksum); sprintf(filename,"MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */ /* Initialise the CARD system */
memset(&SysArea, 0, CARD_WORKAREA); memset(&SysArea, 0, CARD_WORKAREA);
@ -201,9 +194,9 @@ int slot_delete(int slot, int device)
{ {
/* Memory Card support */ /* Memory Card support */
if (slot > 0) if (slot > 0)
sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1); sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else else
sprintf(filename,"MD-%04X.srm", realchecksum); sprintf(filename,"MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */ /* Initialise the CARD system */
memset(&SysArea, 0, CARD_WORKAREA); memset(&SysArea, 0, CARD_WORKAREA);
@ -228,15 +221,23 @@ int slot_load(int slot, int device)
{ {
char filename[MAXPATHLEN]; char filename[MAXPATHLEN];
int filesize, done = 0; int filesize, done = 0;
int offset = device ? 2112 : 0; int offset = 0;
u8 *savebuffer;
if (slot > 0) if (slot > 0)
{
GUI_MsgBoxOpen("Information","Loading State ...",1); GUI_MsgBoxOpen("Information","Loading State ...",1);
}
else else
GUI_MsgBoxOpen("Information","Loading SRAM ...",1); {
if (!sram.on)
{
GUI_WaitPrompt("Error","SRAM is disabled !");
return 0;
}
/* clean buffer */ GUI_MsgBoxOpen("Information","Loading SRAM ...",1);
memset(savebuffer, 0, STATE_SIZE); }
if (!device) if (!device)
{ {
@ -248,42 +249,49 @@ int slot_load(int slot, int device)
/* Open file */ /* Open file */
FILE *fp = fopen(filename, "rb"); FILE *fp = fopen(filename, "rb");
if (fp) 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
{ {
GUI_WaitPrompt("Error","Unable to open file !"); GUI_WaitPrompt("Error","Unable to open file !");
return 0; 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 else
{ {
/* Memory Card support */ /* Memory Card support */
if (slot > 0) if (slot > 0)
sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1); sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else else
sprintf(filename, "MD-%04X.srm", realchecksum); sprintf(filename, "MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */ /* Initialise the CARD system */
char action[80]; char action[64];
memset(&SysArea, 0, CARD_WORKAREA); memset(&SysArea, 0, CARD_WORKAREA);
CARD_Init("GENP", "00"); CARD_Init("GENP", "00");
@ -291,53 +299,60 @@ int slot_load(int slot, int device)
device--; device--;
/* Attempt to mount the card */ /* 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 > 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
{ {
GUI_WaitPrompt("Error","Unable to mount memory card"); GUI_WaitPrompt("Error","Unable to mount memory card");
return 0; 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) if (slot > 0)
@ -345,7 +360,8 @@ int slot_load(int slot, int device)
/* Load state */ /* Load state */
if (!state_load(&savebuffer[offset])) if (!state_load(&savebuffer[offset]))
{ {
GUI_WaitPrompt("Error","Version is not compatible !"); free(savebuffer);
GUI_WaitPrompt("Error","Unable to load state !");
return 0; return 0;
} }
} }
@ -353,9 +369,10 @@ int slot_load(int slot, int device)
{ {
/* Load SRAM & update CRC */ /* Load SRAM & update CRC */
memcpy(sram.sram, &savebuffer[offset], 0x10000); 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(); GUI_MsgBoxClose();
return 1; return 1;
} }
@ -366,20 +383,40 @@ int slot_save(int slot, int device)
char filename[MAXPATHLEN]; char filename[MAXPATHLEN];
int filesize, done = 0; int filesize, done = 0;
int offset = device ? 2112 : 0; int offset = device ? 2112 : 0;
u8 *savebuffer;
/* clean buffer */
memset(savebuffer, 0, STATE_SIZE);
if (slot > 0) 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); GUI_MsgBoxOpen("Information","Saving State ...",1);
filesize = state_save(&savebuffer[offset]); filesize = state_save(&savebuffer[offset]);
} }
else 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); GUI_MsgBoxOpen("Information","Saving SRAM ...",1);
memcpy(&savebuffer[offset], sram.sram, 0x10000); memcpy(&savebuffer[offset], sram.sram, 0x10000);
sram.crc = crc32(0, &sram.sram[0], 0x10000); sram.crc = crc32(0, sram.sram, 0x10000);
filesize = 0x10000; filesize = 0x10000;
} }
@ -393,44 +430,36 @@ int slot_save(int slot, int device)
/* Open file */ /* Open file */
FILE *fp = fopen(filename, "wb"); FILE *fp = fopen(filename, "wb");
if (fp) 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
{ {
GUI_WaitPrompt("Error","Unable to open file !"); GUI_WaitPrompt("Error","Unable to open file !");
free(savebuffer);
return 0; 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 else
{ {
/* Memory Card support */ /* Memory Card support */
if (slot > 0) if (slot > 0)
sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1); sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
else else
sprintf(filename, "MD-%04X.srm", realchecksum); sprintf(filename, "MD-%04X.srm", rominfo.realchecksum);
/* Initialise the CARD system */ /* Initialise the CARD system */
char action[80]; char action[64];
memset(&SysArea, 0, CARD_WORKAREA); memset(&SysArea, 0, CARD_WORKAREA);
CARD_Init("GENP", "00"); CARD_Init("GENP", "00");
@ -438,102 +467,112 @@ int slot_save(int slot, int device)
device--; device--;
/* Attempt to mount the card */ /* Attempt to mount the card */
if (CardMount(device)) if (!CardMount(device))
{ {
/* Retrieve the sector size */ GUI_WaitPrompt("Error","Unable to mount memory card");
u32 SectorSize = 0; free(savebuffer);
int CardError = CARD_GetSectorSize(device, &SectorSize); return 0;
if (SectorSize) }
/* 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 */ CardError = CARD_Create(device, "TEMP", size, &CardFile);
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);
if (CardError) if (CardError)
{ {
sprintf(action, "Unable to create file (%d)", CardError); sprintf(action, "Unable to increase file size (%d)", CardError);
GUI_WaitPrompt("Error",action); GUI_WaitPrompt("Error",action);
CARD_Unmount(device); CARD_Unmount(device);
free(savebuffer);
return 0; return 0;
} }
/* Get current time */ /* delete temporary file */
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 */
CARD_Close(&CardFile); CARD_Close(&CardFile);
CARD_Unmount(device); memset(&CardFile,0,sizeof(CardFile));
} CARD_Delete(device, "TEMP");
else
{
sprintf(action, "Invalid sector size (%d)", CardError);
GUI_WaitPrompt("Error",action);
CARD_Unmount(device);
return 0;
} }
/* 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; 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(); 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; return 1;
} }

View File

@ -108,7 +108,7 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
int bufferoffset = 0; int bufferoffset = 0;
int have = 0; int have = 0;
char readbuffer[2048]; char readbuffer[2048];
char msg[128]; char msg[64];
FILE *fatfile = NULL; FILE *fatfile = NULL;
/*** FAT file support ***/ /*** FAT file support ***/
@ -133,6 +133,12 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
/*** Copy PKZip header to local, used as info ***/ /*** Copy PKZip header to local, used as info ***/
memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER)); 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)); sprintf (msg, "Unzipping %d bytes ...", FLIP32 (pkzip.uncompressedSize));
GUI_MsgBoxOpen("Information",msg,1); GUI_MsgBoxOpen("Information",msg,1);

View File

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

View File

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

View File

@ -36,7 +36,7 @@ typedef struct _yay0header {
unsigned int chunks_offset ATTRIBUTE_PACKED; unsigned int chunks_offset ATTRIBUTE_PACKED;
} yay0header; } yay0header;
int font_size[256]; u8 font_size[256];
int fheight; int fheight;
static u8 *fontImage; static u8 *fontImage;
@ -265,7 +265,7 @@ int FONT_Init(void)
else else
c = i - fontHeader->first_char; 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 */ /* font height */
@ -403,7 +403,7 @@ void WriteCentre_HL( int y, char *string)
* Draw functions (FrameBuffer) * 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; int i;
y = 320 * y; 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; 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) void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color)
{ {
int h; 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 WriteText(char *text, int size, int x, int y);
extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color); extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color);
extern int fheight; extern int fheight;
extern int font_size[256]; extern u8 font_size[256];
#endif #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 displays a message until a specific action is completed */
/* Message Box LWP Thread */ /* 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 */ FONT_writeCenter("Press to continue.",18,166,166+message_box->window->width,248+22,(GXColor)WHITE);
GUI_DrawMenu(message_box.parent); gxDrawTexture(message_box->buttonA, 166+116, 248+4+(18-message_box->buttonA->height)/2,message_box->buttonA->width, message_box->buttonA->height,255);
/* 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();
} }
/* 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 */ /* update current Message Box */
@ -1787,12 +1768,7 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber)
if (SILENT) if (SILENT)
return; return;
/* clear unused textures */ /* update text */
gxTextureClose(&message_box.buttonA);
gxTextureClose(&message_box.buttonB);
gxTextureClose(&message_box.throbber);
/* update message box */
GUI_MsgBoxUpdate(title,msg); GUI_MsgBoxUpdate(title,msg);
/* ensure we are not already running */ /* ensure we are not already running */
@ -1841,20 +1817,9 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber)
yoffset -= 60; yoffset -= 60;
} }
/* Final position */ /* create LWP thread for MessageBox refresh */
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;
message_box.refresh = TRUE; 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 */ /* suspend MessageBox refresh */
message_box.refresh = FALSE; message_box.refresh = FALSE;
LWP_SuspendThread(msgboxthread); LWP_JoinThread(msgboxthread, NULL);
/* window position */ /* window position */
int xwindow = 166; int xwindow = 166;
@ -1912,7 +1877,6 @@ void GUI_MsgBoxClose(void)
gxTextureClose(&message_box.window); gxTextureClose(&message_box.window);
gxTextureClose(&message_box.top); gxTextureClose(&message_box.top);
gxTextureClose(&message_box.buttonA); gxTextureClose(&message_box.buttonA);
gxTextureClose(&message_box.buttonB);
gxTextureClose(&message_box.throbber); gxTextureClose(&message_box.throbber);
} }
} }
@ -1922,7 +1886,10 @@ void GUI_WaitPrompt(char *title, char *msg)
if (SILENT) if (SILENT)
return; return;
/* update message box */ /* clear unused texture */
gxTextureClose(&message_box.throbber);
/* open or update message box */
GUI_MsgBoxOpen(title, msg, 0); GUI_MsgBoxOpen(title, msg, 0);
/* allocate texture */ /* 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 *window; /* pointer to box texture */
gx_texture *top; /* pointer to box title texture */ gx_texture *top; /* pointer to box title texture */
gx_texture *buttonA; /* pointer to button A texture */ gx_texture *buttonA; /* pointer to button A texture */
gx_texture *buttonB; /* pointer to button B texture */
gx_texture *throbber; /* pointer to throbber texture */ gx_texture *throbber; /* pointer to throbber texture */
} gui_message; } gui_message;

View File

@ -1046,8 +1046,8 @@ static void systemmenu ()
if (cart.romsize) if (cart.romsize)
{ {
/* force region & cpu mode */ /* reset console region */
set_region(); region_autodetect();
/* update framerate */ /* update framerate */
if (vdp_pal) if (vdp_pal)
@ -1494,7 +1494,7 @@ static void ctrlmenu_raz(void)
m->buttons[i+2].data = &button_player_data; m->buttons[i+2].data = &button_player_data;
m->buttons[i+2].state |= BUTTON_ACTIVE; m->buttons[i+2].state |= BUTTON_ACTIVE;
sprintf(m->items[i+2].text,"%d",max + 1); 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); sprintf(m->items[i+2].comment,"Configure Player %d (J-CART) settings", max + 1);
else else
sprintf(m->items[i+2].comment,"Configure Player %d settings", max + 1); sprintf(m->items[i+2].comment,"Configure Player %d settings", max + 1);
@ -1674,7 +1674,7 @@ static void ctrlmenu(void)
switch (m->selected) switch (m->selected)
{ {
case 0: /* update port 1 system */ case 0: /* update port 1 system */
if (cart.hw.jcart) break; if (cart.jcart) break;
if (input.system[0] == SYSTEM_MOUSE) if (input.system[0] == SYSTEM_MOUSE)
input.system[0] +=3; /* lightguns are never used on Port 1 */ input.system[0] +=3; /* lightguns are never used on Port 1 */
else else
@ -1688,8 +1688,6 @@ static void ctrlmenu(void)
input.system[0] = NO_SYSTEM; input.system[0] = NO_SYSTEM;
input.system[1] = SYSTEM_GAMEPAD; input.system[1] = SYSTEM_GAMEPAD;
} }
old_system[0] = -1;
old_system[1] = -1;
io_init(); io_init();
io_reset(); io_reset();
old_system[0] = input.system[0]; old_system[0] = input.system[0];
@ -1729,7 +1727,7 @@ static void ctrlmenu(void)
break; break;
case 1: /* update port 2 system */ case 1: /* update port 2 system */
if (cart.hw.jcart) break; if (cart.jcart) break;
input.system[1] ++; input.system[1] ++;
if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE)) if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE))
input.system[1] ++; input.system[1] ++;
@ -1740,8 +1738,6 @@ static void ctrlmenu(void)
input.system[1] = NO_SYSTEM; input.system[1] = NO_SYSTEM;
input.system[0] = SYSTEM_GAMEPAD; input.system[0] = SYSTEM_GAMEPAD;
} }
old_system[0] = -1;
old_system[1] = -1;
io_init(); io_init();
io_reset(); io_reset();
old_system[0] = input.system[0]; old_system[0] = input.system[0];
@ -1861,7 +1857,7 @@ static void ctrlmenu(void)
GUI_DrawMenuFX(m, 20, 0); GUI_DrawMenuFX(m, 20, 0);
/* update title */ /* update title */
if (cart.hw.jcart && (player > 1)) if (cart.jcart && (player > 1))
sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1); sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1);
else else
sprintf(m->title,"Controller Settings (Player %d)",player+1); sprintf(m->title,"Controller Settings (Player %d)",player+1);
@ -2112,7 +2108,7 @@ static void ctrlmenu(void)
} }
/* remove duplicate assigned inputs before leaving */ /* 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)) 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_DrawMenuFX(m,30,1);
GUI_DeleteMenu(m); GUI_DeleteMenu(m);
} }
@ -2401,6 +2398,7 @@ static int savemenu(void)
case 6: /* set default slot */ case 6: /* set default slot */
{ {
config.s_default = slot; config.s_default = slot;
config_save();
break; break;
} }
@ -2613,44 +2611,45 @@ static void showrominfo (void)
/* fill ROM infos */ /* fill ROM infos */
sprintf (items[0], "Console Type: %s", rominfo.consoletype); sprintf (items[0], "Console Type: %s", rominfo.consoletype);
sprintf (items[1], "Copyright: %s", rominfo.copyright); 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[3], "Domestic Name:");
sprintf (items[4], "%s",rominfo.domestic); sprintf (items[4], "%s",rominfo.domestic);
sprintf (items[5], "International Name:"); sprintf (items[5], "International Name:");
sprintf (items[6], "%s",rominfo.international); sprintf (items[6], "%s",rominfo.international);
sprintf (items[7], "Type: %s (%s)",rominfo.ROMType, strcmp(rominfo.ROMType, "AI") ? "Game" : "Educational"); sprintf (items[7], "Type: %s (%s)",rominfo.ROMType, strcmp(rominfo.ROMType, "AI") ? "Game" : "Educational");
sprintf (items[8], "Product ID: %s", rominfo.product); 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: "); 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],", "); 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],", "); 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],", "); 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],", "); 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],", "); 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],", "); strcat(items[10],", ");
} }
if (strlen(items[10]) > 10) if (strlen(items[10]) > 10)
@ -2699,7 +2698,8 @@ static void showcredits(void)
while (!p) while (!p)
{ {
gxClearScreen ((GXColor)BLACK); 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("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); 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)) switch (GUI_OptionWindow(m, VERSION, items,3))
{ {
case 0: /* credits */ case 0: /* credits */
GUI_DeleteMenu(m);
showcredits(); showcredits();
GUI_InitMenu(m);
break; break;
case 1: /* return to loader */ case 1: /* return to loader */

View File

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

View File

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

View File

@ -155,6 +155,54 @@ static void init_machine(void)
bitmap.data = texturemem; 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 Load a new rom and performs some initialization
***************************************************/ ***************************************************/
@ -325,62 +373,13 @@ int main (int argc, char *argv[])
SILENT = 0; SILENT = 0;
} }
/* initialize GUI engine */
GUI_Initialize();
#ifdef HW_RVL #ifdef HW_RVL
/* Power button callback */ /* Power button callback */
SYS_SetPowerCallback(Power_Off); SYS_SetPowerCallback(Power_Off);
#endif #endif
/* main emulation loop */ /* main emulation loop */
int skip = 0; run_emulation();
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;
}
return 0; return 0;
} }

View File

@ -57,8 +57,23 @@
#define PCDROM 4096 #define PCDROM 4096
#define PMOUSE 8192 #define PMOUSE 8192
uint16 peripherals; #define MAXCOMPANY 64
uint16 realchecksum; #define MAXPERIPHERALS 14
typedef struct
{
char companyid[6];
char company[26];
} COMPANYINFO;
typedef struct
{
char pID[2];
char pName[14];
} PERIPHERALINFO;
ROMINFO rominfo; ROMINFO rominfo;
char rom_filename[256]; char rom_filename[256];
@ -69,7 +84,7 @@ char rom_filename[256];
* Based on the document provided at * Based on the document provided at
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt * http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
**************************************************************************/ **************************************************************************/
COMPANYINFO companyinfo[MAXCOMPANY] = { static COMPANYINFO companyinfo[MAXCOMPANY] = {
{"ACLD", "Ballistic"}, {"ACLD", "Ballistic"},
{"RSI", "Razorsoft"}, {"RSI", "Razorsoft"},
{"SEGA", "SEGA"}, {"SEGA", "SEGA"},
@ -105,7 +120,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = {
{"50", "Electronic Arts"}, {"50", "Electronic Arts"},
{"56", "Razorsoft"}, {"56", "Razorsoft"},
{"58", "Mentrix"}, {"58", "Mentrix"},
{"60", "Victor Musical Industries"}, {"60", "Victor Musical Ind."},
{"69", "Arena"}, {"69", "Arena"},
{"70", "Virgin"}, {"70", "Virgin"},
{"73", "Soft Vision"}, {"73", "Soft Vision"},
@ -142,7 +157,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = {
* Based on the document provided at * Based on the document provided at
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt * http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
***************************************************************************/ ***************************************************************************/
PERIPHERALINFO peripheralinfo[14] = { static PERIPHERALINFO peripheralinfo[MAXPERIPHERALS] = {
{"J", "3B Joypad"}, {"J", "3B Joypad"},
{"6", "6B Joypad"}, {"6", "6B Joypad"},
{"K", "Keyboard"}, {"K", "Keyboard"},
@ -156,13 +171,14 @@ PERIPHERALINFO peripheralinfo[14] = {
{"T", "Tablet"}, {"T", "Tablet"},
{"V", "Paddle"}, {"V", "Paddle"},
{"C", "CD-ROM"}, {"C", "CD-ROM"},
{"M", "Mega Mouse"} {"M", "Mega Mouse"},
}; };
/* /***************************************************************************
* softdev - New Checksum Calculation * GetRealChecksum
eke-eke: fixed *
*/ * Compute ROM checksum.
***************************************************************************/
static uint16 GetRealChecksum (uint8 *rom, int length) static uint16 GetRealChecksum (uint8 *rom, int length)
{ {
int i; int i;
@ -217,31 +233,28 @@ static void getrominfo (char *romheader)
memcpy (&rominfo.ROMType, romheader + ROMTYPE, 2); memcpy (&rominfo.ROMType, romheader + ROMTYPE, 2);
memcpy (&rominfo.product, romheader + ROMPRODUCT, 12); memcpy (&rominfo.product, romheader + ROMPRODUCT, 12);
memcpy (&rominfo.checksum, romheader + ROMCHECKSUM, 2); memcpy (&rominfo.checksum, romheader + ROMCHECKSUM, 2);
memcpy (&rominfo.io_support, romheader + ROMIOSUPPORT, 16);
memcpy (&rominfo.romstart, romheader + ROMROMSTART, 4); memcpy (&rominfo.romstart, romheader + ROMROMSTART, 4);
memcpy (&rominfo.romend, romheader + ROMROMEND, 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); memcpy (&rominfo.country, romheader + ROMCOUNTRY, 16);
realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200);
#ifdef LSB_FIRST #ifdef LSB_FIRST
rominfo.checksum = (rominfo.checksum >> 8) | ((rominfo.checksum & 0xff) << 8); rominfo.checksum = (rominfo.checksum >> 8) | ((rominfo.checksum & 0xff) << 8);
#endif #endif
rominfo.realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200);
peripherals = 0; rominfo.peripherals = 0;
for (i = 0; i < 14; i++) for (i = 0; i < 14; i++)
for (j=0; j < 14; j++) for (j=0; j < 14; j++)
if (rominfo.io_support[i] == peripheralinfo[j].pID[0]) if (romheader[ROMIOSUPPORT+i] == peripheralinfo[j].pID[0])
peripherals |= (1 << j); 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; int i;
uint8 block[0x4000]; 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 load_rom(char *filename)
{ {
int i, size, offset = 0; int i, size, offset = 0;
@ -274,12 +292,8 @@ int load_rom(char *filename)
{ {
size -= 512; size -= 512;
offset += 512; offset += 512;
for (i = 0; i < (size / 0x4000); i += 1) for (i = 0; i < (size / 0x4000); i += 1)
{
deinterleave_block (cart.rom + offset + (i * 0x4000)); deinterleave_block (cart.rom + offset + (i * 0x4000));
}
memcpy(cart.rom, cart.rom + offset, size); memcpy(cart.rom, cart.rom + offset, size);
} }
@ -288,13 +302,16 @@ int load_rom(char *filename)
cart.romsize = size; cart.romsize = size;
/* clear unused ROM space */ /* clear unused ROM space */
memset (cart.rom + size, 0xff, MAXROMSIZE - size); memset(cart.rom + size, 0xff, MAXROMSIZE - size);
/* get infos from ROM header */ /* get infos from ROM header */
getrominfo((char *)cart.rom); getrominfo((char *)cart.rom);
/* set system region */ /* get specific input devices */
set_region(); input_autodetect();
/* get default region */
region_autodetect();
#ifdef LSB_FIRST #ifdef LSB_FIRST
/* Byteswap ROM */ /* Byteswap ROM */
@ -331,8 +348,13 @@ int load_rom(char *filename)
return(1); 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 */ /* country codes used to differentiate region */
/* 0001 = japan ntsc (1) */ /* 0001 = japan ntsc (1) */
@ -379,7 +401,7 @@ void set_region ()
/* need PAL settings */ /* need PAL settings */
region_code = REGION_EUROPE; 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 */ /* On Dal Jang Goon (Korea) needs JAP region code */
region_code = REGION_JAPAN_NTSC; region_code = REGION_JAPAN_NTSC;
@ -410,7 +432,7 @@ void set_region ()
} }
/**************************************************************************** /****************************************************************************
* getcompany * get_company
* *
* Try to determine which company made this rom * 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 * It seems that there can be pretty much anything you like following the
* copyright (C) symbol! * copyright (C) symbol!
****************************************************************************/ ****************************************************************************/
int getcompany () char *get_company(void)
{ {
char *s; char *s;
int i; int i;
char company[10]; 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; company[5] = 0;
/** OK, first look for a hyphen /** OK, first look for a hyphen
@ -439,14 +462,31 @@ int getcompany ()
/** Strip any trailing spaces **/ /** Strip any trailing spaces **/
for (i = strlen (company) - 1; i >= 0; i--) 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++) 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_ #ifndef _LOADROM_H_
#define _LOADROM_H_ #define _LOADROM_H_
#define MAXCOMPANY 64
#define MAXROMSIZE 10485760 #define MAXROMSIZE 10485760
typedef struct typedef struct
{ {
char consoletype[18]; /* Genesis or Mega Drive */ char consoletype[18]; /* Genesis or Mega Drive */
char copyright[18]; /* Copyright message */ char copyright[18]; /* Copyright message */
char domestic[50]; /* Domestic name of ROM */ char domestic[50]; /* Domestic name of ROM */
char international[50]; /* International name of ROM */ char international[50]; /* International name of ROM */
char ROMType[4]; /* Educational or Game */ char ROMType[4]; /* Educational or Game */
char product[14]; /* Product serial number */ char product[14]; /* Product serial number */
unsigned short checksum; /* Checksum */ unsigned short checksum; /* ROM Checksum (header) */
char io_support[18]; /* Actually 16 chars :) */ unsigned short realchecksum; /* ROM Checksum (calculated) */
unsigned int romstart; /* ROM start address */ unsigned int romstart; /* ROM start address */
unsigned int romend; /* ROM end address */ unsigned int romend; /* ROM end address */
char RAMInfo[14]; /* Backup RAM header */ char country[18]; /* Country flag */
unsigned int ramstart; /* RAM start address */ uint16 peripherals; /* Supported peripherals */
unsigned int ramend; /* RAM end address */
char modem[14]; /* Sega Modem support */
char memo[50]; /* Misc */
char country[18]; /* Country flag */
} ROMINFO; } ROMINFO;
typedef struct
{
char companyid[6];
char company[30];
} COMPANYINFO;
typedef struct
{
char pID[2];
char pName[21];
} PERIPHERALINFO;
/* Global variables */ /* Global variables */
extern ROMINFO rominfo; extern ROMINFO rominfo;
extern COMPANYINFO companyinfo[MAXCOMPANY];
extern PERIPHERALINFO peripheralinfo[14];
extern uint16 realchecksum;
extern uint16 peripherals;
extern char rom_filename[256]; extern char rom_filename[256];
/* Function prototypes */ /* Function prototypes */
extern int load_rom(char *filename); extern int load_rom(char *filename);
extern int getcompany(); extern void region_autodetect(void);
extern void set_region(); extern char *get_company(void);
extern char *get_peripheral(int index);
#endif /* _LOADROM_H_ */ #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. /* Number of clock cycles to use for exception processing.
* I used 4 for any vectors that are undocumented for processing times. * 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 */ { /* 000 */
40, /* 0: Reset - Initial Stack Pointer */ 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,
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 */ { /* 010 */
40, /* 0: Reset - Initial Stack Pointer */ 40, /* 0: Reset - Initial Stack Pointer */
4, /* 1: Reset - Initial Program Counter */ 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,
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 #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_SHIFT = 2 * 7;
CYC_RESET = 132 * 7; CYC_RESET = 132 * 7;
return; return;
#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
case M68K_CPU_TYPE_68008: case M68K_CPU_TYPE_68008:
CPU_TYPE = CPU_TYPE_008; CPU_TYPE = CPU_TYPE_008;
CPU_ADDRESS_MASK = 0x003fffff; CPU_ADDRESS_MASK = 0x003fffff;
@ -774,6 +779,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
CYC_SHIFT = 0; CYC_SHIFT = 0;
CYC_RESET = 518; CYC_RESET = 518;
return; return;
#endif
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,11 @@
/* ============================ OPCODE HANDLERS =========================== */ /* ============================ 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 */ /* Build the opcode handler table */
void m68ki_build_opcode_table(void); 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_byte(uint32 address);
extern uint32 pico_read_word(uint32 address); extern uint32 pico_read_word(uint32 address);
uint8 m68k_readmap[256];
uint8 m68k_writemap[256];
uint32 pico_current; uint32 pico_current;
#endif /* _MEM68K_H_ */ #endif /* _MEM68K_H_ */

View File

@ -26,8 +26,8 @@
#include "sms_ntsc.h" #include "sms_ntsc.h"
/*** NTSC Filters ***/ /*** NTSC Filters ***/
extern md_ntsc_t md_ntsc; extern md_ntsc_t *md_ntsc;
extern sms_ntsc_t sms_ntsc; extern sms_ntsc_t *sms_ntsc;
/* Look-up pixel table information */ /* Look-up pixel table information */
#define LUT_MAX (5) #define LUT_MAX (5)
@ -1836,9 +1836,9 @@ void remap_buffer(int line, int width)
if (config.ntsc) if (config.ntsc)
{ {
if (reg[12]&1) 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 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; return;
} }

View File

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

View File

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

View File

@ -278,16 +278,16 @@ void audio_shutdown(void)
****************************************************************/ ****************************************************************/
void system_init (void) void system_init (void)
{ {
/* Cartridge hardware */
cart_hw_init();
/* Genesis hardware */ /* Genesis hardware */
gen_init(); gen_init();
io_init(); io_init();
vdp_init(); vdp_init();
render_init(); render_init();
/* Sound Chips hardware */ /* Cartridge hardware */
cart_hw_init();
/* Sound hardware */
sound_init(); sound_init();
} }
@ -305,10 +305,10 @@ void system_reset (void)
vdp_reset(); vdp_reset();
render_reset(); render_reset();
/* Sound chips */ /* Sound hardware */
sound_reset(); sound_reset();
/* Audio System */ /* Audio system */
audio_reset(); audio_reset();
} }
@ -335,7 +335,6 @@ int system_frame (int do_skip)
/* update display settings */ /* update display settings */
int line; int line;
int reset = resetline;
int vdp_height = bitmap.viewport.h; int vdp_height = bitmap.viewport.h;
int end_line = vdp_height + bitmap.viewport.y; int end_line = vdp_height + bitmap.viewport.y;
int start_line = lines_per_frame - 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 */ /* 68k line cycle count */
hint_68k = mcycles_68k; 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 */ /* update VDP DMA */
if (dma_length) if (dma_length)
vdp_update_dma(); 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; int fps = vdp_pal ? (sdl_video.frames_rendered / 3) : sdl_video.frames_rendered;
sdl_sync.ticks = sdl_video.frames_rendered = 0; 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); SDL_WM_SetCaption(caption, NULL);
} }
return interval; return interval;