mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-09-10 16:53:15 +02:00
.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:
parent
70ef2fc20b
commit
2c2f760f44
@ -60,12 +60,13 @@ of samples per frame and keeping PSG & FM chips in sync.
|
||||
|
||||
[Gamecube/Wii]
|
||||
---------------
|
||||
* implemented new FONT engine (using internal IPL font & GX hardware rendering).
|
||||
* implemented custom GUI engine (with PCM/OGG sound support, multithreading & using GX hardware for rendering)
|
||||
* new interface design (incl. IR pointing, game snapshots, visual & sound effects, BGM...).
|
||||
* improved audio/video back-end synchronization to ensure 100% smooth video & audio playback.
|
||||
* implemented custom FONT engine (uses internal IPL font & GX hardware rendering).
|
||||
* implemented custom GUI engine (uses GX hardware rendering & multithreading)
|
||||
* implemented advanced interface (IR pointing, game snapshots, visual & sound effects, BGM...).
|
||||
* improved audio/video synchronization to ensure 100% smooth video AND audio playback.
|
||||
* improved reset button behavior, now works more like the real Genesis reset button.
|
||||
* improved lightgun cursors layout.
|
||||
* added automatic ROM loading feature
|
||||
* fixed stability issues and memory leaks.
|
||||
|
||||
[Wii only]
|
||||
|
@ -62,62 +62,59 @@ static void special_regs_w(uint32 address, uint32 data);
|
||||
static const T_CART_ENTRY rom_database[CART_CNT] =
|
||||
{
|
||||
/* Funny World & Balloon Boy */
|
||||
{0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}},
|
||||
{0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}},
|
||||
/* Whac-a-Critter */
|
||||
{0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}},
|
||||
{0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}},
|
||||
/* Earth Defense */
|
||||
{0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}},
|
||||
{0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}},
|
||||
/* RADICA (Volume 1) (not byteswapped) */
|
||||
{0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}},
|
||||
{0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}},
|
||||
/* RADICA (Volume 2) */
|
||||
{0x4f10,0x0836,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}},
|
||||
{0x4f10,0x0836,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}},
|
||||
/* RADICA (Volume 1) */
|
||||
{0xf424,0x9f82,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}},
|
||||
{0xf424,0x9f82,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}},
|
||||
/* Lion King 3 */
|
||||
{0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}},
|
||||
{0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}},
|
||||
/* Super King Kong 99 */
|
||||
{0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}},
|
||||
{0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}},
|
||||
/* Pokemon Stadium */
|
||||
{0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}},
|
||||
{0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}},
|
||||
/* Lion King 2 */
|
||||
{0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}},
|
||||
{0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}},
|
||||
/* Squirell King */
|
||||
{0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}},
|
||||
{0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}},
|
||||
/* Supper Bubble Bobble */
|
||||
{0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x400002,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x400002,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* Mahjong Lover */
|
||||
{0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x401000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* Elf Wor */
|
||||
{0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* Huan Le Tao Qi Shu - Smart Mouse */
|
||||
{0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* Ya-Se Chuanshuo */
|
||||
{0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* Soul Blade */
|
||||
{0x0000,0x0c5b,0x40,0x40,{{0x00,0x98,0xc9,0xF0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0x0000,0x0c5b,0x40,0x40,{{0x00,0x98,0xc9,0xF0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* King of Fighter 98 */
|
||||
{0x0000,0xd0a0,0x48,0x4f,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0x0000,0xd0a0,0x48,0x4f,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* Lian Huan Pao - Barver Battle Saga */
|
||||
{0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
{0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}},
|
||||
/* Rockman X3 */
|
||||
{0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0xa13000,0x400004,0x000000,0x000000},0,0,0,default_regs_r,NULL,default_regs_r,NULL}},
|
||||
{0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0xa13000,0x400004,0x000000,0x000000},0,0,default_regs_r,NULL,default_regs_r,NULL}},
|
||||
/* Super Mario 2 1998 */
|
||||
{0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
{0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
/* Super Mario 2 1998 */
|
||||
{0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
{0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
/* A Bug's Life */
|
||||
{0x7f7f,0x2aad,0x00,0x00,{{0x28,0x1f,0x01,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
{0x7f7f,0x2aad,0x00,0x00,{{0x28,0x1f,0x01,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
/* King of Fighter 99 */
|
||||
{0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
{0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
/* Pocket Monster */
|
||||
{0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
{0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}},
|
||||
/* Game no Kanzume Otokuyou */
|
||||
{0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,seganet_mapper_w,NULL,NULL}}
|
||||
{0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,seganet_mapper_w,NULL,NULL}}
|
||||
};
|
||||
|
||||
/* temporary memory chunk */
|
||||
static uint8 mem_chunk[0x10000];
|
||||
|
||||
|
||||
/************************************************************
|
||||
Cart Hardware initialization
|
||||
@ -286,124 +283,15 @@ void cart_hw_init()
|
||||
m68k_memory_map[0x3a].read16 = svp_read_cell_2;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
SPECIFIC CONTROLLER SETTINGS
|
||||
***********************************************/
|
||||
|
||||
/* restore previous settings */
|
||||
if (old_system[0] != -1)
|
||||
input.system[0] = old_system[0];
|
||||
if (old_system[1] != -1)
|
||||
input.system[1] = old_system[1];
|
||||
|
||||
/* initialize default GUN settings */
|
||||
input.x_offset = 0x00;
|
||||
input.y_offset = 0x00;
|
||||
|
||||
/**********************************************
|
||||
SEGA MENACER
|
||||
***********************************************/
|
||||
if (strstr(rominfo.international,"MENACER") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = NO_SYSTEM;
|
||||
input.system[1] = SYSTEM_MENACER;
|
||||
input.x_offset = 0x52;
|
||||
input.y_offset = 0x00;
|
||||
}
|
||||
else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_MENACER;
|
||||
input.x_offset = 0x84;
|
||||
input.y_offset = 0x08;
|
||||
}
|
||||
else if (strstr(rominfo.international,"BODY COUNT") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_MOUSE;
|
||||
input.system[1] = SYSTEM_MENACER;
|
||||
input.x_offset = 0x44;
|
||||
input.y_offset = 0x18;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
KONAMI JUSTIFIER
|
||||
***********************************************/
|
||||
else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_JUSTIFIER;
|
||||
input.x_offset = 0x18;
|
||||
input.y_offset = 0x00;
|
||||
}
|
||||
else if (strstr(rominfo.international,"LETHAL ENFORCERS") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_JUSTIFIER;
|
||||
input.x_offset = 0x00;
|
||||
input.y_offset = 0x00;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
J-CART
|
||||
***********************************************/
|
||||
cart.hw.jcart = 0;
|
||||
if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/
|
||||
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */
|
||||
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */
|
||||
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */
|
||||
((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */
|
||||
((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */
|
||||
((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/
|
||||
(strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */
|
||||
if (cart.jcart)
|
||||
{
|
||||
if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */
|
||||
{
|
||||
cart.hw.jcart = 1;
|
||||
m68k_memory_map[0x38].read16 = jcart_read;
|
||||
m68k_memory_map[0x38].write16 = jcart_write;
|
||||
m68k_memory_map[0x3f].read16 = jcart_read;
|
||||
m68k_memory_map[0x3f].write16 = jcart_write;
|
||||
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
/* set default settings */
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_GAMEPAD;
|
||||
}
|
||||
m68k_memory_map[0x38].read16 = jcart_read;
|
||||
m68k_memory_map[0x38].write16 = jcart_write;
|
||||
m68k_memory_map[0x3f].read16 = jcart_read;
|
||||
m68k_memory_map[0x3f].write16 = jcart_write;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
@ -427,51 +315,51 @@ void cart_hw_init()
|
||||
break;
|
||||
|
||||
case TYPE_SK:
|
||||
/* be sure we have enough place to store both ROMs */
|
||||
if (cart.romsize < 0x700000)
|
||||
{
|
||||
/* load Sonic & Knuckles ROM (2 MBytes) */
|
||||
FILE *f = fopen(SK_ROM,"r+b");
|
||||
if (!f) break;
|
||||
int done = 0;
|
||||
while (done < 0x200000)
|
||||
{
|
||||
fread(cart.rom+0x700000+done,4096,1,f);
|
||||
done += 4096;
|
||||
}
|
||||
fclose(f);
|
||||
{
|
||||
/* store S&K ROM above cartridge ROM + SRAM */
|
||||
if (cart.romsize > 0x600000) break;
|
||||
|
||||
/* load Sonic 2 UPMEM ROM (256 KBytes) */
|
||||
f = fopen(SK_UPMEM,"r+b");
|
||||
if (!f) break;
|
||||
done = 0;
|
||||
while (done < 0x40000)
|
||||
{
|
||||
fread(cart.rom+0x900000+done,4096,1,f);
|
||||
done += 4096;
|
||||
}
|
||||
fclose(f);
|
||||
/* load Sonic & Knuckles ROM (2 MBytes) */
|
||||
FILE *f = fopen(SK_ROM,"r+b");
|
||||
if (!f) break;
|
||||
int done = 0;
|
||||
while (done < 0x200000)
|
||||
{
|
||||
fread(cart.rom + 0x600000 + done, 2048, 1, f);
|
||||
done += 2048;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
/* load Sonic 2 UPMEM ROM (256 KBytes) */
|
||||
f = fopen(SK_UPMEM,"r+b");
|
||||
if (!f) break;
|
||||
done = 0;
|
||||
while (done < 0x40000)
|
||||
{
|
||||
fread(cart.rom + 0x800000 + done, 2048, 1, f);
|
||||
done += 2048;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* Byteswap ROM */
|
||||
int i;
|
||||
uint8 temp;
|
||||
for(i = 0; i < 0x240000; i += 2)
|
||||
{
|
||||
temp = cart.rom[i+0x700000];
|
||||
cart.rom[i+0x700000] = cart.rom[i+1+0x700000];
|
||||
cart.rom[i+1+0x700000] = temp;
|
||||
}
|
||||
/* Byteswap ROM */
|
||||
int i;
|
||||
uint8 temp;
|
||||
for(i = 0; i < 0x240000; i += 2)
|
||||
{
|
||||
temp = cart.rom[i + 0x600000];
|
||||
cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1];
|
||||
cart.rom[i + 0x600000 + 1] = temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$000000-$1fffff is mapped to S&K ROM */
|
||||
for (i=0x00; i<0x20; i++)
|
||||
m68k_memory_map[i].base = (cart.rom + 0x700000) + (i<<16);
|
||||
/*$000000-$1fffff is mapped to S&K ROM */
|
||||
for (i=0x00; i<0x20; i++)
|
||||
m68k_memory_map[i].base = (cart.rom + 0x600000) + (i<<16);
|
||||
|
||||
cart.lock_on = 1;
|
||||
|
||||
}
|
||||
cart.lock_on = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -487,7 +375,7 @@ void cart_hw_init()
|
||||
{
|
||||
/* known cart found ! */
|
||||
if ((rominfo.checksum == rom_database[i].chk_1) &&
|
||||
(realchecksum == rom_database[i].chk_2))
|
||||
(rominfo.realchecksum == rom_database[i].chk_2))
|
||||
{
|
||||
/* retrieve hardware information */
|
||||
memcpy(&cart.hw, &(rom_database[i].cart_hw), sizeof(T_CART_HW));
|
||||
@ -521,7 +409,7 @@ void cart_hw_init()
|
||||
emulate_address_error = config.addr_error;
|
||||
#endif
|
||||
|
||||
/* detect ROM files larger than 4MB */
|
||||
/* detect special cartridges */
|
||||
if (cart.romsize > 0x800000)
|
||||
{
|
||||
/* Ultimate MK3 (hack) */
|
||||
@ -546,7 +434,6 @@ void cart_hw_init()
|
||||
}
|
||||
|
||||
/* default write handler for !TIME signal */
|
||||
/* TODO: handle Sonic & Knuckles + Sonic 2 case to prevent RAM activation */
|
||||
if (!cart.hw.time_w)
|
||||
cart.hw.time_w = default_time_w;
|
||||
}
|
||||
@ -567,10 +454,10 @@ void cart_hw_reset()
|
||||
if (cart.hw.realtec & 1)
|
||||
{
|
||||
/* enable BOOTROM */
|
||||
for (i=0x00; i<0x40; i++)
|
||||
m68k_memory_map[i].base = mem_chunk;
|
||||
for (i=0; i<8; i++)
|
||||
memcpy(mem_chunk + i*0x2000, cart.rom + 0x7e000, 0x2000);
|
||||
memcpy(cart.rom + 0x900000 + i*0x2000, cart.rom + 0x7e000, 0x2000);
|
||||
for (i=0x00; i<0x40; i++)
|
||||
m68k_memory_map[i].base = cart.rom + 0x900000;
|
||||
cart.hw.realtec |= 2;
|
||||
}
|
||||
|
||||
@ -657,7 +544,7 @@ static void sega_mapper_w(uint32 address, uint32 data)
|
||||
{
|
||||
/* enable UPMEM chip at $300000-$3fffff */
|
||||
for (i=0x30; i<0x40; i++)
|
||||
m68k_memory_map[i].base = (cart.rom + 0x900000) + ((i & 3)<<16);
|
||||
m68k_memory_map[i].base = (cart.rom + 0x800000) + ((i & 3)<<16);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -708,9 +595,9 @@ static void multi_mapper_w(uint32 address, uint32 data)
|
||||
static void special_mapper_w(uint32 address, uint32 data)
|
||||
{
|
||||
/* 1 x 32k bank */
|
||||
m68k_memory_map[0].base = mem_chunk;
|
||||
memcpy(mem_chunk,&cart.rom[(data & 0x7f) << 15],0x8000);
|
||||
memcpy(mem_chunk+0x8000,cart.rom + 0x8000,0x8000);
|
||||
memcpy(cart.rom + 0x900000, cart.rom + ((data & 0x7f) << 15), 0x8000);
|
||||
memcpy(cart.rom + 0x908000, cart.rom + 0x8000, 0x8000);
|
||||
m68k_memory_map[0].base = cart.rom + 0x900000;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -38,8 +38,7 @@ typedef struct
|
||||
uint8 regs[4]; /* internal registers (R/W) */
|
||||
uint32 mask[4]; /* registers address mask */
|
||||
uint32 addr[4]; /* registers address */
|
||||
uint32 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */
|
||||
uint16 jcart; /* cartridge with JCART port */
|
||||
uint16 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */
|
||||
uint16 bankshift; /* cartridge with bankshift mecanism */
|
||||
unsigned int (*time_r)(unsigned int address); /* !TIME signal ($a130xx) read handler */
|
||||
void (*time_w)(unsigned int address, unsigned int data); /* !TIME signal ($a130xx) write handler */
|
||||
@ -51,11 +50,12 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint8 *rom; /* ROM data */
|
||||
uint8 *base; /* ROM area (slot 0) */
|
||||
uint32 mask; /* mask ROM */
|
||||
uint32 lock_on; /* 1: Lock-On enabled */
|
||||
uint8 *base; /* ROM base area (slot 0) */
|
||||
uint32 romsize; /* ROM size */
|
||||
T_CART_HW hw; /* Custom hardware */
|
||||
uint32 mask; /* mask ROM */
|
||||
uint16 lock_on; /* 1: Lock-On enabled */
|
||||
uint16 jcart; /* 1: J-CART port enabled */
|
||||
T_CART_HW hw; /* Extra hardware */
|
||||
} T_CART;
|
||||
|
||||
/* global variables */
|
||||
|
@ -27,8 +27,8 @@
|
||||
struct
|
||||
{
|
||||
uint8 enabled;
|
||||
uint8 rom[0x20000];
|
||||
uint8 ram[0x10000];
|
||||
uint8 *rom;
|
||||
uint8 *ram;
|
||||
uint16 regs[13];
|
||||
uint16 old[4];
|
||||
uint16 data[4];
|
||||
@ -49,6 +49,11 @@ void datel_init(void)
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
/* store Action replay ROM + RAM above cartridge ROM + SRAM */
|
||||
if (cart.romsize > 0x600000) return;
|
||||
action_replay.rom = cart.rom + 0x600000;
|
||||
action_replay.ram = cart.rom + 0x610000;
|
||||
|
||||
/* ROM size */
|
||||
fseek(f, 0, SEEK_END);
|
||||
int size = ftell(f);
|
||||
@ -59,9 +64,6 @@ void datel_init(void)
|
||||
case 0x8000: /* ACTION REPLAY (32K) */
|
||||
{
|
||||
action_replay.enabled = TYPE_AR;
|
||||
|
||||
/* $0000-$7fff mirrored into $8000-$ffff */
|
||||
memcpy(action_replay.rom+0x8000,action_replay.rom,0x8000);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -92,33 +94,32 @@ void datel_init(void)
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (action_replay.enabled)
|
||||
/* Load ROM */
|
||||
fseek(f, 0, SEEK_SET);
|
||||
int i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
/* Load ROM */
|
||||
fseek(f, 0, SEEK_SET);
|
||||
int i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
fread(action_replay.rom+i,0x1000,1,f);
|
||||
i += 0x1000;
|
||||
}
|
||||
fread(action_replay.rom+i,0x1000,1,f);
|
||||
i += 0x1000;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* Byteswap ROM */
|
||||
uint8 temp;
|
||||
for(i = 0; i < size; i += 2)
|
||||
{
|
||||
temp = action_replay.rom[i];
|
||||
action_replay.rom[i] = action_replay.rom[i+1];
|
||||
action_replay.rom[i+1] = temp;
|
||||
}
|
||||
#endif
|
||||
/* Byteswap ROM */
|
||||
uint8 temp;
|
||||
for(i = 0; i < size; i += 2)
|
||||
{
|
||||
temp = action_replay.rom[i];
|
||||
action_replay.rom[i] = action_replay.rom[i+1];
|
||||
action_replay.rom[i+1] = temp;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
void datel_shutdown(void)
|
||||
@ -178,7 +179,7 @@ void datel_reset(int hard_reset)
|
||||
|
||||
/* clear RAM on hard reset only */
|
||||
if (hard_reset)
|
||||
memset(action_replay.ram,0,sizeof(action_replay.ram));
|
||||
memset(action_replay.ram,0,0x10000);
|
||||
}
|
||||
|
||||
void datel_switch(int enable)
|
||||
|
@ -111,14 +111,12 @@ void eeprom_init()
|
||||
}
|
||||
|
||||
/* Game not found in database but header seems to indicate it uses EEPROM */
|
||||
if (!sram.custom)
|
||||
if (sram.detected && !sram.custom)
|
||||
{
|
||||
if ((sram.end - sram.start) < 2)
|
||||
{
|
||||
sram.custom = 1;
|
||||
sram.on = 1;
|
||||
|
||||
/* set SEGA mapper as default */
|
||||
sram.custom = 1;
|
||||
memcpy(&eeprom.type, &database[9].type, sizeof(T_EEPROM_TYPE));
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
static struct
|
||||
{
|
||||
uint8 enabled;
|
||||
uint8 rom[0x10000];
|
||||
uint8 *rom;
|
||||
uint16 regs[0x20];
|
||||
uint16 old[6];
|
||||
uint16 data[6];
|
||||
@ -47,6 +47,10 @@ void ggenie_init(void)
|
||||
FILE *f = fopen(GG_ROM,"rb");
|
||||
if (!f) return;
|
||||
|
||||
/* store Game Genie ROM above cartridge ROM + SRAM */
|
||||
if (cart.romsize > 0x600000) return;
|
||||
ggenie.rom = cart.rom + 0x600000;
|
||||
|
||||
/* Load ROM */
|
||||
int i = 0;
|
||||
while (i < 0x8000)
|
||||
|
@ -42,33 +42,41 @@ T_SRAM sram;
|
||||
void sram_init()
|
||||
{
|
||||
memset (&sram, 0, sizeof (T_SRAM));
|
||||
memset (&sram.sram[0], 0xFF, 0x10000);
|
||||
sram.crc = crc32(0, &sram.sram[0], 0x10000);
|
||||
|
||||
/* store SRAM into cartridge area */
|
||||
if (cart.romsize > 0x500000) return;
|
||||
sram.sram = cart.rom + 0x500000;
|
||||
|
||||
/* initialize SRAM */
|
||||
memset(sram.sram, 0xff, 0x10000);
|
||||
sram.crc = crc32(0, sram.sram, 0x10000);
|
||||
|
||||
/* retrieve informations from header */
|
||||
if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41))
|
||||
{
|
||||
/* retrieve informations from headezr */
|
||||
sram.detected = 1;
|
||||
sram.start = READ_WORD_LONG(cart.rom, 0x1b4);
|
||||
sram.end = READ_WORD_LONG(cart.rom, 0x1b8);
|
||||
|
||||
/* fixe some bad header informations */
|
||||
if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000))
|
||||
sram.end = sram.start + 0xffff;
|
||||
sram.end = sram.start + 0xffff;
|
||||
sram.start &= 0xfffffffe;
|
||||
sram.end |= 1;
|
||||
|
||||
/* enable SRAM */
|
||||
sram.on = 1;
|
||||
sram.detected = 1;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* default SRAM region */
|
||||
sram.start = 0x200000;
|
||||
sram.end = 0x20ffff;
|
||||
}
|
||||
|
||||
/* set SRAM ON by default when ROM is not mapped */
|
||||
if (cart.romsize <= sram.start)
|
||||
sram.on = 1;
|
||||
/* enable SRAM only if ROM < 2MB */
|
||||
if (cart.romsize <= sram.start)
|
||||
sram.on = 1;
|
||||
}
|
||||
|
||||
/* autodetect some games with bad header or specific configuration */
|
||||
if (strstr(rominfo.product,"T-113016") != NULL)
|
||||
@ -119,7 +127,8 @@ void sram_init()
|
||||
sram.start = 0x200001;
|
||||
sram.end = 0x203fff;
|
||||
}
|
||||
else if (((realchecksum == 0xaeaa) || (realchecksum == 0x8dba)) && (rominfo.checksum == 0x8104))
|
||||
else if (((rominfo.realchecksum == 0xaeaa) || (rominfo.realchecksum == 0x8dba)) &&
|
||||
(rominfo.checksum == 0x8104))
|
||||
{
|
||||
/* Xin Qigai Wangzi, aka Beggar Prince (no header, use uncommon area) */
|
||||
sram.on = 1;
|
||||
|
@ -31,7 +31,7 @@ typedef struct
|
||||
uint32 start;
|
||||
uint32 end;
|
||||
uint32 crc;
|
||||
uint8 sram[0x10000];
|
||||
uint8 *sram;
|
||||
} T_SRAM;
|
||||
|
||||
/* Function prototypes */
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "shared.h"
|
||||
|
||||
t_input input;
|
||||
int old_system[2] = {-1,-1};
|
||||
|
||||
/************************************************************************************/
|
||||
/* */
|
||||
@ -70,7 +71,7 @@ static const uint8 hc_256[171] =
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LIGHTGUN specific functions
|
||||
* LIGHTGUN support
|
||||
*
|
||||
*****************************************************************************/
|
||||
static inline void lightgun_reset(int num)
|
||||
@ -146,7 +147,7 @@ uint32 justifier_read(void)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* SEGA MOUSE specific functions
|
||||
* SEGA MOUSE support
|
||||
*
|
||||
*****************************************************************************/
|
||||
static struct mega_mouse
|
||||
@ -268,7 +269,7 @@ uint32 mouse_read()
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* GAMEPAD specific functions (2PLAYERS/4WAYPLAY)
|
||||
* GAMEPAD support (2PLAYERS/4WAYPLAY)
|
||||
*
|
||||
*****************************************************************************/
|
||||
static struct pad
|
||||
@ -297,15 +298,15 @@ static inline void gamepad_update(uint32 i)
|
||||
|
||||
static inline uint32 gamepad_read(uint32 i)
|
||||
{
|
||||
int control;
|
||||
/* bit7 is latched */
|
||||
int retval = 0x7F;
|
||||
|
||||
control = (gamepad[i].State & 0x40) >> 6; /* current TH state */
|
||||
/* current TH state */
|
||||
int control = (gamepad[i].State & 0x40) >> 6;
|
||||
|
||||
/* TH transitions counter */
|
||||
if (input.dev[i] == DEVICE_6BUTTON)
|
||||
{
|
||||
control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */
|
||||
}
|
||||
control += (gamepad[i].Counter & 3) << 1;
|
||||
|
||||
switch (control)
|
||||
{
|
||||
@ -376,7 +377,6 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
break;
|
||||
}
|
||||
|
||||
/* bit7 is latched */
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -397,7 +397,7 @@ static inline void gamepad_write(uint32 i, uint32 data)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* TEAMPLAYER adapter
|
||||
* TEAMPLAYER adapter support
|
||||
*
|
||||
*****************************************************************************/
|
||||
static struct teamplayer
|
||||
@ -536,7 +536,7 @@ static inline void teamplayer_write(uint32 port, uint32 data)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* 4WAYPLAY adapter
|
||||
* 4-WAYPLAY adapter support
|
||||
*
|
||||
*****************************************************************************/
|
||||
static inline void wayplay_write(uint32 port, uint32 data)
|
||||
@ -619,7 +619,8 @@ void teamplayer_2_write (uint32 data)
|
||||
|
||||
uint32 jcart_read(uint32 address)
|
||||
{
|
||||
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 */
|
||||
/* TH2 (output) fixed to 0 on read (fixes Micro Machines 2) */
|
||||
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8));
|
||||
}
|
||||
|
||||
void jcart_write(uint32 address, uint32 data)
|
||||
@ -719,7 +720,7 @@ void input_init(void)
|
||||
}
|
||||
|
||||
/* J-CART: add two gamepad inputs */
|
||||
if (cart.hw.jcart)
|
||||
if (cart.jcart)
|
||||
{
|
||||
input.dev[5] = config.input[2].padtype;
|
||||
input.dev[6] = config.input[3].padtype;
|
||||
@ -767,13 +768,15 @@ void input_update(void)
|
||||
switch (input.system[0])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0);
|
||||
if (input.dev[0] == DEVICE_6BUTTON)
|
||||
gamepad_update(0);
|
||||
break;
|
||||
|
||||
case SYSTEM_WAYPLAY:
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_update(i);
|
||||
if (input.dev[i] == DEVICE_6BUTTON)
|
||||
gamepad_update(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -781,7 +784,8 @@ void input_update(void)
|
||||
switch (input.system[1])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4);
|
||||
if (input.dev[4] == DEVICE_6BUTTON)
|
||||
gamepad_update(4);
|
||||
break;
|
||||
|
||||
case SYSTEM_MENACER:
|
||||
@ -789,8 +793,10 @@ void input_update(void)
|
||||
break;
|
||||
|
||||
case SYSTEM_JUSTIFIER:
|
||||
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0);
|
||||
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1);
|
||||
if ((io_reg[2] & 0x30) == 0x00)
|
||||
lightgun_update(0);
|
||||
if ((io_reg[2] & 0x30) == 0x20)
|
||||
lightgun_update(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -801,13 +807,15 @@ void input_raz(void)
|
||||
switch (input.system[0])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0);
|
||||
if (input.dev[0] == DEVICE_6BUTTON)
|
||||
gamepad_raz(0);
|
||||
break;
|
||||
|
||||
case SYSTEM_WAYPLAY:
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
|
||||
if (input.dev[i] == DEVICE_6BUTTON)
|
||||
gamepad_raz(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -815,7 +823,123 @@ void input_raz(void)
|
||||
switch (input.system[1])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4);
|
||||
if (input.dev[4] == DEVICE_6BUTTON)
|
||||
gamepad_raz(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void input_autodetect(void)
|
||||
{
|
||||
/* restore previous settings */
|
||||
if (old_system[0] != -1)
|
||||
input.system[0] = old_system[0];
|
||||
if (old_system[1] != -1)
|
||||
input.system[1] = old_system[1];
|
||||
|
||||
/* initialize default GUN settings */
|
||||
input.x_offset = 0x00;
|
||||
input.y_offset = 0x00;
|
||||
|
||||
/**********************************************
|
||||
SEGA MENACER
|
||||
***********************************************/
|
||||
if (strstr(rominfo.international,"MENACER") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = NO_SYSTEM;
|
||||
input.system[1] = SYSTEM_MENACER;
|
||||
input.x_offset = 0x52;
|
||||
input.y_offset = 0x00;
|
||||
}
|
||||
else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_MENACER;
|
||||
input.x_offset = 0x84;
|
||||
input.y_offset = 0x08;
|
||||
}
|
||||
else if (strstr(rominfo.international,"BODY COUNT") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_MOUSE;
|
||||
input.system[1] = SYSTEM_MENACER;
|
||||
input.x_offset = 0x44;
|
||||
input.y_offset = 0x18;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
KONAMI JUSTIFIER
|
||||
***********************************************/
|
||||
else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_JUSTIFIER;
|
||||
input.x_offset = 0x18;
|
||||
input.y_offset = 0x00;
|
||||
}
|
||||
else if (strstr(rominfo.international,"LETHAL ENFORCERS") != NULL)
|
||||
{
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_JUSTIFIER;
|
||||
input.x_offset = 0x00;
|
||||
input.y_offset = 0x00;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
J-CART
|
||||
***********************************************/
|
||||
cart.jcart = 0;
|
||||
if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/
|
||||
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */
|
||||
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */
|
||||
((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */
|
||||
((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */
|
||||
((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */
|
||||
((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/
|
||||
(strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */
|
||||
{
|
||||
if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */
|
||||
{
|
||||
cart.jcart = 1;
|
||||
|
||||
/* save current setting */
|
||||
if (old_system[0] == -1)
|
||||
old_system[0] = input.system[0];
|
||||
if (old_system[1] == -1)
|
||||
old_system[1] = input.system[1];
|
||||
|
||||
/* set default settings */
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
input.system[1] = SYSTEM_GAMEPAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ extern void input_init(void);
|
||||
extern void input_reset(void);
|
||||
extern void input_update(void);
|
||||
extern void input_raz(void);
|
||||
extern void input_autodetect(void);
|
||||
|
||||
/* Peripherals specific */
|
||||
extern void mouse_write(uint32 data);
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
uint8 io_reg[0x10];
|
||||
uint8 region_code = REGION_USA;
|
||||
int old_system[2] = {-1,-1};
|
||||
|
||||
static struct port_t
|
||||
{
|
||||
@ -117,20 +116,24 @@ void io_init(void)
|
||||
|
||||
void io_reset(void)
|
||||
{
|
||||
/* I/O register default settings */
|
||||
uint8 io_def[0x10] =
|
||||
{
|
||||
0xA0,
|
||||
0x7F, 0x7F, 0x7F,
|
||||
0x00, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00,
|
||||
0xFB, 0x00, 0x00,
|
||||
};
|
||||
|
||||
/* Reset I/O registers */
|
||||
memcpy (io_reg, io_def, 0x10);
|
||||
|
||||
io_reg[0x00] = region_code | 0x20 | (config.bios_enabled == 3);
|
||||
io_reg[0x01] = 0x7F;
|
||||
io_reg[0x02] = 0x7F;
|
||||
io_reg[0x03] = 0x7F;
|
||||
io_reg[0x04] = 0x00;
|
||||
io_reg[0x05] = 0x00;
|
||||
io_reg[0x06] = 0x00;
|
||||
io_reg[0x07] = 0xFF;
|
||||
io_reg[0x08] = 0x00;
|
||||
io_reg[0x09] = 0x00;
|
||||
io_reg[0x0A] = 0xFF;
|
||||
io_reg[0x0B] = 0x00;
|
||||
io_reg[0x0C] = 0x00;
|
||||
io_reg[0x0D] = 0xFB;
|
||||
io_reg[0x0E] = 0x00;
|
||||
io_reg[0x0F] = 0x00;
|
||||
|
||||
/* Reset connected input devices */
|
||||
input_reset();
|
||||
}
|
||||
@ -142,29 +145,16 @@ void io_write(uint32 offset, uint32 value)
|
||||
case 0x01: /* Port A Data */
|
||||
case 0x02: /* Port B Data */
|
||||
case 0x03: /* Port C Data */
|
||||
io_reg[offset] = ((value & 0x80) | (value & io_reg[offset+3]));
|
||||
if(port[offset-1].data_w) port[offset-1].data_w(value);
|
||||
io_reg[offset] = value & (0x80 | io_reg[offset+3]);
|
||||
if(port[offset-1].data_w)
|
||||
port[offset-1].data_w(value);
|
||||
return;
|
||||
|
||||
case 0x05: /* Port B Ctrl */
|
||||
if (((value & 0x7F) == 0x7F) &&
|
||||
((input.system[0] == SYSTEM_TEAMPLAYER) ||
|
||||
(input.system[1] == SYSTEM_TEAMPLAYER)))
|
||||
{
|
||||
/* autodetect 4-Way play ! */
|
||||
input.system[0] = SYSTEM_WAYPLAY;
|
||||
input.system[1] = SYSTEM_WAYPLAY;
|
||||
port[0].data_w = wayplay_1_write;
|
||||
port[0].data_r = wayplay_1_read;
|
||||
port[1].data_w = wayplay_2_write;
|
||||
port[1].data_r = wayplay_2_read;
|
||||
input_reset();
|
||||
}
|
||||
|
||||
case 0x04: /* Port A Ctrl */
|
||||
case 0x05: /* Port B Ctrl */
|
||||
case 0x06: /* Port C Ctrl */
|
||||
io_reg[offset] = value & 0xFF;
|
||||
io_reg[offset-3] = ((io_reg[offset-3] & 0x80) | (io_reg[offset-3] & io_reg[offset]));
|
||||
io_reg[offset] = value;
|
||||
io_reg[offset-3] &= (0x80 | value);
|
||||
return;
|
||||
|
||||
case 0x07: /* Port A TxData */
|
||||
@ -176,7 +166,10 @@ void io_write(uint32 offset, uint32 value)
|
||||
case 0x09: /* Port A S-Ctrl */
|
||||
case 0x0C: /* Port B S-Ctrl */
|
||||
case 0x0F: /* Port C S-Ctrl */
|
||||
io_reg[offset] = (value & 0xF8);
|
||||
io_reg[offset] = value & 0xF8;
|
||||
return;
|
||||
|
||||
default: /* Read-only ports */
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -185,23 +178,17 @@ uint32 io_read(uint32 offset)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 0x00: /* Version register */
|
||||
{
|
||||
uint8 has_scd = 0x20; /* No Sega CD unit attached */
|
||||
uint8 gen_ver = (config.bios_enabled == 3) ? 0x01 : 0x00; /* hardware version */
|
||||
return (region_code | has_scd | gen_ver);
|
||||
}
|
||||
|
||||
case 0x01: /* Port A Data */
|
||||
case 0x02: /* Port B Data */
|
||||
case 0x03: /* Port C Data */
|
||||
{
|
||||
uint8 input = 0x7F; /* default input state */
|
||||
if(port[offset-1].data_r) input = port[offset-1].data_r();
|
||||
uint8 input = 0x7F;
|
||||
if(port[offset-1].data_r)
|
||||
input = port[offset-1].data_r();
|
||||
return (io_reg[offset] | ((~io_reg[offset+3]) & input));
|
||||
}
|
||||
|
||||
default:
|
||||
default: /* return register value */
|
||||
return (io_reg[offset]);
|
||||
}
|
||||
}
|
||||
|
@ -30,15 +30,10 @@ uint32 zirq; /* /IRQ to Z80 */
|
||||
uint32 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
|
||||
uint32 zbank; /* Z80 bank window address */
|
||||
uint32 gen_running; /* 0: cpu are in locked state */
|
||||
int32 resetline; /* soft reset is triggered on a random line (X-Men 2, Eternal Champions) */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void set_softreset(void)
|
||||
{
|
||||
resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
|
||||
void gen_init(void)
|
||||
{
|
||||
@ -138,13 +133,17 @@ void gen_reset(uint32 hard_reset)
|
||||
mcycles_68k = 0;
|
||||
mcycles_z80 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* VDP is not reseted so CPU could be anywhere in a frame */
|
||||
mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX));
|
||||
}
|
||||
|
||||
zstate = 0; /* Z80 is reset & has control of the bus */
|
||||
zirq = 0; /* No interrupts occuring */
|
||||
zbank = 0; /* Assume default bank is $000000-$007FFF */
|
||||
|
||||
/* Reset CPUs */
|
||||
resetline = -1;
|
||||
gen_running = 1;
|
||||
fm_reset(0);
|
||||
m68k_pulse_reset();
|
||||
|
@ -134,7 +134,7 @@ void config_default(void)
|
||||
sprintf (config.sddir, "sd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.usbdir, "usb:%s/roms/", DEFAULT_PATH);
|
||||
#else
|
||||
sprintf (config.sddir, "/%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.sddir, "%s/roms/", DEFAULT_PATH);
|
||||
#endif
|
||||
|
||||
/* restore from config file */
|
||||
|
@ -308,9 +308,16 @@ int DVD_LoadFile(u8 *buffer, u32 selection)
|
||||
/* determine file type */
|
||||
if (!IsZipFile ((char *) readbuffer))
|
||||
{
|
||||
char msg[50];
|
||||
if (length > MAXROMSIZE)
|
||||
{
|
||||
GUI_WaitPrompt("Error","File size not supported !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char msg[64];
|
||||
sprintf(msg,"Loading %d bytes...", length);
|
||||
GUI_MsgBoxOpen("Information",msg,1);
|
||||
|
||||
/* How many 2k blocks to read */
|
||||
int blocks = length / DVDCHUNK;
|
||||
int readoffset = 0;
|
||||
@ -373,7 +380,7 @@ int DVD_Open(void)
|
||||
while(DI_GetStatus() & DVD_INIT) usleep(10);
|
||||
if (!(DI_GetStatus() & DVD_READY))
|
||||
{
|
||||
char msg[50];
|
||||
char msg[64];
|
||||
sprintf(msg, "DI Status Error: 0x%08X !\n",DI_GetStatus());
|
||||
GUI_WaitPrompt("Error",msg);
|
||||
return 0;
|
||||
|
@ -55,7 +55,7 @@ int FAT_UpdateDirectory(bool go_up, char *dirname)
|
||||
{
|
||||
int size=0;
|
||||
char *test;
|
||||
char temp[1024];
|
||||
char temp[MAXPATHLEN];
|
||||
|
||||
/* go up to parent directory */
|
||||
if (strcmp(dirname,"..") == 0)
|
||||
@ -185,11 +185,17 @@ int FAT_LoadFile(u8 *buffer, u32 selection)
|
||||
/* Determine file type */
|
||||
if (!IsZipFile ((char *) temp))
|
||||
{
|
||||
if (length > MAXROMSIZE)
|
||||
{
|
||||
GUI_WaitPrompt("Error","File size not supported !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* re-open and read file */
|
||||
sdfile = fopen(fname, "rb");
|
||||
if (sdfile)
|
||||
{
|
||||
char msg[50];
|
||||
char msg[64];
|
||||
sprintf(msg,"Loading %d bytes ...", length);
|
||||
GUI_MsgBoxOpen("Information",msg,1);
|
||||
int done = 0;
|
||||
@ -235,7 +241,7 @@ int FAT_Open(int type)
|
||||
filelist[i].offset = 0;
|
||||
filelist[i].length = 0;
|
||||
filelist[i].flags = 0;
|
||||
strncpy(filelist[i].filename, history.entries[i].filename, MAXJOLIET-1);
|
||||
strncpy(filelist[i].filename,history.entries[i].filename, MAXJOLIET-1);
|
||||
filelist[i].filename[MAXJOLIET-1] = '\0';
|
||||
max++;
|
||||
}
|
||||
|
@ -35,13 +35,6 @@
|
||||
*/
|
||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
/**
|
||||
* DMA Transfer Area.
|
||||
* Must be 32-byte aligned.
|
||||
* 64k SRAM + 2k Icon
|
||||
*/
|
||||
static u8 savebuffer[STATE_SIZE] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* CardMount
|
||||
@ -139,9 +132,9 @@ void slot_autodetect(int slot, int device, t_slot *ptr)
|
||||
{
|
||||
/* Memory Card support */
|
||||
if (slot > 0)
|
||||
sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1);
|
||||
sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
|
||||
else
|
||||
sprintf(filename,"MD-%04X.srm", realchecksum);
|
||||
sprintf(filename,"MD-%04X.srm", rominfo.realchecksum);
|
||||
|
||||
/* Initialise the CARD system */
|
||||
memset(&SysArea, 0, CARD_WORKAREA);
|
||||
@ -201,9 +194,9 @@ int slot_delete(int slot, int device)
|
||||
{
|
||||
/* Memory Card support */
|
||||
if (slot > 0)
|
||||
sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1);
|
||||
sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
|
||||
else
|
||||
sprintf(filename,"MD-%04X.srm", realchecksum);
|
||||
sprintf(filename,"MD-%04X.srm", rominfo.realchecksum);
|
||||
|
||||
/* Initialise the CARD system */
|
||||
memset(&SysArea, 0, CARD_WORKAREA);
|
||||
@ -228,15 +221,23 @@ int slot_load(int slot, int device)
|
||||
{
|
||||
char filename[MAXPATHLEN];
|
||||
int filesize, done = 0;
|
||||
int offset = device ? 2112 : 0;
|
||||
int offset = 0;
|
||||
u8 *savebuffer;
|
||||
|
||||
if (slot > 0)
|
||||
{
|
||||
GUI_MsgBoxOpen("Information","Loading State ...",1);
|
||||
}
|
||||
else
|
||||
GUI_MsgBoxOpen("Information","Loading SRAM ...",1);
|
||||
{
|
||||
if (!sram.on)
|
||||
{
|
||||
GUI_WaitPrompt("Error","SRAM is disabled !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clean buffer */
|
||||
memset(savebuffer, 0, STATE_SIZE);
|
||||
GUI_MsgBoxOpen("Information","Loading SRAM ...",1);
|
||||
}
|
||||
|
||||
if (!device)
|
||||
{
|
||||
@ -248,42 +249,49 @@ int slot_load(int slot, int device)
|
||||
|
||||
/* Open file */
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (fp)
|
||||
{
|
||||
/* Read size */
|
||||
fseek(fp, 0, SEEK_END);
|
||||
filesize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
/* Read into buffer (2k blocks) */
|
||||
while (filesize > FATCHUNK)
|
||||
{
|
||||
fread(savebuffer + done, FATCHUNK, 1, fp);
|
||||
done += FATCHUNK;
|
||||
filesize -= FATCHUNK;
|
||||
}
|
||||
|
||||
/* Read remaining bytes */
|
||||
fread(savebuffer + done, filesize, 1, fp);
|
||||
done += filesize;
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
if (!fp)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to open file !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read size */
|
||||
fseek(fp, 0, SEEK_END);
|
||||
filesize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
/* allocate buffer */
|
||||
savebuffer = (u8 *)memalign(32,filesize);
|
||||
if (!savebuffer)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to allocate memory !");
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read into buffer (2k blocks) */
|
||||
while (filesize > FATCHUNK)
|
||||
{
|
||||
fread(savebuffer + done, FATCHUNK, 1, fp);
|
||||
done += FATCHUNK;
|
||||
filesize -= FATCHUNK;
|
||||
}
|
||||
|
||||
/* Read remaining bytes */
|
||||
fread(savebuffer + done, filesize, 1, fp);
|
||||
done += filesize;
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Memory Card support */
|
||||
if (slot > 0)
|
||||
sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1);
|
||||
sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
|
||||
else
|
||||
sprintf(filename, "MD-%04X.srm", realchecksum);
|
||||
sprintf(filename, "MD-%04X.srm", rominfo.realchecksum);
|
||||
|
||||
/* Initialise the CARD system */
|
||||
char action[80];
|
||||
char action[64];
|
||||
memset(&SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init("GENP", "00");
|
||||
|
||||
@ -291,53 +299,60 @@ int slot_load(int slot, int device)
|
||||
device--;
|
||||
|
||||
/* Attempt to mount the card */
|
||||
if (CardMount(device))
|
||||
{
|
||||
/* Retrieve the sector size */
|
||||
u32 SectorSize = 0;
|
||||
int CardError = CARD_GetSectorSize(device, &SectorSize);
|
||||
if (SectorSize > 0)
|
||||
{
|
||||
/* Open file */
|
||||
card_file CardFile;
|
||||
CardError = CARD_Open(device, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf(action, "Unable to open file (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get file size */
|
||||
filesize = CardFile.len;
|
||||
if (filesize % SectorSize)
|
||||
filesize = ((filesize / SectorSize) + 1) * SectorSize;
|
||||
|
||||
/* Read file sectors */
|
||||
while (filesize > 0)
|
||||
{
|
||||
CARD_Read(&CardFile, &savebuffer[done], SectorSize, done);
|
||||
done += SectorSize;
|
||||
filesize -= SectorSize;
|
||||
}
|
||||
|
||||
CARD_Close(&CardFile);
|
||||
CARD_Unmount(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(action, "Invalid sector size (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!CardMount(device))
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to mount memory card");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve the sector size */
|
||||
u32 SectorSize = 0;
|
||||
int CardError = CARD_GetSectorSize(device, &SectorSize);
|
||||
if (!SectorSize)
|
||||
{
|
||||
sprintf(action, "Invalid sector size (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Open file */
|
||||
card_file CardFile;
|
||||
CardError = CARD_Open(device, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf(action, "Unable to open file (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve file size */
|
||||
filesize = CardFile.len;
|
||||
if (filesize % SectorSize)
|
||||
filesize = ((filesize / SectorSize) + 1) * SectorSize;
|
||||
|
||||
/* Allocate buffer */
|
||||
savebuffer = (u8 *)memalign(32,filesize);
|
||||
if (!savebuffer)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to allocate memory !");
|
||||
CARD_Close(&CardFile);
|
||||
CARD_Unmount(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read file sectors */
|
||||
while (filesize > 0)
|
||||
{
|
||||
CARD_Read(&CardFile, &savebuffer[done], SectorSize, done);
|
||||
done += SectorSize;
|
||||
filesize -= SectorSize;
|
||||
}
|
||||
|
||||
CARD_Close(&CardFile);
|
||||
CARD_Unmount(device);
|
||||
offset = 2112;
|
||||
}
|
||||
|
||||
if (slot > 0)
|
||||
@ -345,7 +360,8 @@ int slot_load(int slot, int device)
|
||||
/* Load state */
|
||||
if (!state_load(&savebuffer[offset]))
|
||||
{
|
||||
GUI_WaitPrompt("Error","Version is not compatible !");
|
||||
free(savebuffer);
|
||||
GUI_WaitPrompt("Error","Unable to load state !");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -353,9 +369,10 @@ int slot_load(int slot, int device)
|
||||
{
|
||||
/* Load SRAM & update CRC */
|
||||
memcpy(sram.sram, &savebuffer[offset], 0x10000);
|
||||
sram.crc = crc32(0, &sram.sram[0], 0x10000);
|
||||
sram.crc = crc32(0, sram.sram, 0x10000);
|
||||
}
|
||||
|
||||
free(savebuffer);
|
||||
GUI_MsgBoxClose();
|
||||
return 1;
|
||||
}
|
||||
@ -366,20 +383,40 @@ int slot_save(int slot, int device)
|
||||
char filename[MAXPATHLEN];
|
||||
int filesize, done = 0;
|
||||
int offset = device ? 2112 : 0;
|
||||
|
||||
/* clean buffer */
|
||||
memset(savebuffer, 0, STATE_SIZE);
|
||||
u8 *savebuffer;
|
||||
|
||||
if (slot > 0)
|
||||
{
|
||||
/* allocate buffer */
|
||||
savebuffer = (u8 *)memalign(32,STATE_SIZE);
|
||||
if (!savebuffer)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to allocate memory !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GUI_MsgBoxOpen("Information","Saving State ...",1);
|
||||
filesize = state_save(&savebuffer[offset]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sram.on)
|
||||
{
|
||||
GUI_WaitPrompt("Error","SRAM is disabled !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate buffer */
|
||||
savebuffer = (u8 *)memalign(32,0x10000+offset);
|
||||
if (!savebuffer)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to allocate memory !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GUI_MsgBoxOpen("Information","Saving SRAM ...",1);
|
||||
memcpy(&savebuffer[offset], sram.sram, 0x10000);
|
||||
sram.crc = crc32(0, &sram.sram[0], 0x10000);
|
||||
sram.crc = crc32(0, sram.sram, 0x10000);
|
||||
filesize = 0x10000;
|
||||
}
|
||||
|
||||
@ -393,44 +430,36 @@ int slot_save(int slot, int device)
|
||||
|
||||
/* Open file */
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (fp)
|
||||
{
|
||||
/* Read into buffer (2k blocks) */
|
||||
while (filesize > FATCHUNK)
|
||||
{
|
||||
fwrite(savebuffer + done, FATCHUNK, 1, fp);
|
||||
done += FATCHUNK;
|
||||
filesize -= FATCHUNK;
|
||||
}
|
||||
|
||||
/* Write remaining bytes */
|
||||
fwrite(savebuffer + done, filesize, 1, fp);
|
||||
done += filesize;
|
||||
fclose(fp);
|
||||
|
||||
if (slot)
|
||||
{
|
||||
/* save screenshot */
|
||||
sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1);
|
||||
gxSaveScreenshot(filename);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!fp)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to open file !");
|
||||
free(savebuffer);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read into buffer (2k blocks) */
|
||||
while (filesize > FATCHUNK)
|
||||
{
|
||||
fwrite(savebuffer + done, FATCHUNK, 1, fp);
|
||||
done += FATCHUNK;
|
||||
filesize -= FATCHUNK;
|
||||
}
|
||||
|
||||
/* Write remaining bytes */
|
||||
fwrite(savebuffer + done, filesize, 1, fp);
|
||||
done += filesize;
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Memory Card support */
|
||||
if (slot > 0)
|
||||
sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1);
|
||||
sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1);
|
||||
else
|
||||
sprintf(filename, "MD-%04X.srm", realchecksum);
|
||||
sprintf(filename, "MD-%04X.srm", rominfo.realchecksum);
|
||||
|
||||
/* Initialise the CARD system */
|
||||
char action[80];
|
||||
char action[64];
|
||||
memset(&SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init("GENP", "00");
|
||||
|
||||
@ -438,102 +467,112 @@ int slot_save(int slot, int device)
|
||||
device--;
|
||||
|
||||
/* Attempt to mount the card */
|
||||
if (CardMount(device))
|
||||
if (!CardMount(device))
|
||||
{
|
||||
/* Retrieve the sector size */
|
||||
u32 SectorSize = 0;
|
||||
int CardError = CARD_GetSectorSize(device, &SectorSize);
|
||||
if (SectorSize)
|
||||
GUI_WaitPrompt("Error","Unable to mount memory card");
|
||||
free(savebuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve the sector size */
|
||||
u32 SectorSize = 0;
|
||||
int CardError = CARD_GetSectorSize(device, &SectorSize);
|
||||
if (!SectorSize)
|
||||
{
|
||||
sprintf(action, "Invalid sector size (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
free(savebuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Build the output buffer */
|
||||
char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} };
|
||||
strcpy (comment[1], filename);
|
||||
memcpy (&savebuffer[0], &icon, 2048);
|
||||
memcpy (&savebuffer[2048], &comment[0], 64);
|
||||
|
||||
/* Adjust file size */
|
||||
filesize += 2112;
|
||||
if (filesize % SectorSize)
|
||||
filesize = ((filesize / SectorSize) + 1) * SectorSize;
|
||||
|
||||
/* Check if file already exists */
|
||||
card_file CardFile;
|
||||
if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY)
|
||||
{
|
||||
int size = filesize - CardFile.len;
|
||||
CARD_Close(&CardFile);
|
||||
memset(&CardFile,0,sizeof(CardFile));
|
||||
|
||||
/* Check file new size */
|
||||
if (size > 0)
|
||||
{
|
||||
/* Build the output buffer */
|
||||
char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} };
|
||||
strcpy (comment[1], filename);
|
||||
memcpy (&savebuffer[0], &icon, 2048);
|
||||
memcpy (&savebuffer[2048], &comment[0], 64);
|
||||
|
||||
/* Adjust file size */
|
||||
filesize += 2112;
|
||||
if (filesize % SectorSize)
|
||||
filesize = ((filesize / SectorSize) + 1) * SectorSize;
|
||||
|
||||
/* Check if file already exists */
|
||||
card_file CardFile;
|
||||
if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY)
|
||||
{
|
||||
int size = filesize - CardFile.len;
|
||||
CARD_Close(&CardFile);
|
||||
memset(&CardFile,0,sizeof(CardFile));
|
||||
if (size > 0)
|
||||
{
|
||||
/* new file is bigger: check if there is enough space left */
|
||||
CardError = CARD_Create(device, "TEMP", size, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf(action, "Not enough memory space left (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
return 0;
|
||||
}
|
||||
CARD_Close(&CardFile);
|
||||
memset(&CardFile,0,sizeof(CardFile));
|
||||
CARD_Delete(device, "TEMP");
|
||||
}
|
||||
|
||||
/* delete previously existing slot */
|
||||
CARD_Delete(device, filename);
|
||||
}
|
||||
|
||||
/* Create a new slot */
|
||||
CardError = CARD_Create(device, filename, filesize, &CardFile);
|
||||
CardError = CARD_Create(device, "TEMP", size, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf(action, "Unable to create file (%d)", CardError);
|
||||
sprintf(action, "Unable to increase file size (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
free(savebuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get current time */
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
|
||||
/* Update file informations */
|
||||
card_stat CardStatus;
|
||||
CARD_GetStatus(device, CardFile.filenum, &CardStatus);
|
||||
CardStatus.icon_addr = 0x0;
|
||||
CardStatus.icon_fmt = 2;
|
||||
CardStatus.icon_speed = 1;
|
||||
CardStatus.comment_addr = 2048;
|
||||
CardStatus.time = rawtime;
|
||||
CARD_SetStatus(device, CardFile.filenum, &CardStatus);
|
||||
|
||||
/* Write file sectors */
|
||||
while (filesize > 0)
|
||||
{
|
||||
CARD_Write(&CardFile, &savebuffer[done], SectorSize, done);
|
||||
filesize -= SectorSize;
|
||||
done += SectorSize;
|
||||
}
|
||||
|
||||
/* Close file */
|
||||
/* delete temporary file */
|
||||
CARD_Close(&CardFile);
|
||||
CARD_Unmount(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(action, "Invalid sector size (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
return 0;
|
||||
memset(&CardFile,0,sizeof(CardFile));
|
||||
CARD_Delete(device, "TEMP");
|
||||
}
|
||||
|
||||
/* delete previously existing file */
|
||||
CARD_Delete(device, filename);
|
||||
}
|
||||
else
|
||||
|
||||
/* Create a new file */
|
||||
CardError = CARD_Create(device, filename, filesize, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to mount memory card");
|
||||
sprintf(action, "Unable to create file (%d)", CardError);
|
||||
GUI_WaitPrompt("Error",action);
|
||||
CARD_Unmount(device);
|
||||
free(savebuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update file informations */
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
card_stat CardStatus;
|
||||
CARD_GetStatus(device, CardFile.filenum, &CardStatus);
|
||||
CardStatus.icon_addr = 0x0;
|
||||
CardStatus.icon_fmt = 2;
|
||||
CardStatus.icon_speed = 1;
|
||||
CardStatus.comment_addr = 2048;
|
||||
CardStatus.time = rawtime;
|
||||
CARD_SetStatus(device, CardFile.filenum, &CardStatus);
|
||||
|
||||
/* Write file sectors */
|
||||
while (filesize > 0)
|
||||
{
|
||||
CARD_Write(&CardFile, &savebuffer[done], SectorSize, done);
|
||||
filesize -= SectorSize;
|
||||
done += SectorSize;
|
||||
}
|
||||
|
||||
/* Close file */
|
||||
CARD_Close(&CardFile);
|
||||
CARD_Unmount(device);
|
||||
}
|
||||
|
||||
GUI_MsgBoxClose();
|
||||
free(savebuffer);
|
||||
|
||||
/* Save screenshot */
|
||||
if (slot && !device)
|
||||
{
|
||||
sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1);
|
||||
gxSaveScreenshot(filename);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
||||
int bufferoffset = 0;
|
||||
int have = 0;
|
||||
char readbuffer[2048];
|
||||
char msg[128];
|
||||
char msg[64];
|
||||
FILE *fatfile = NULL;
|
||||
|
||||
/*** FAT file support ***/
|
||||
@ -133,6 +133,12 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
||||
/*** Copy PKZip header to local, used as info ***/
|
||||
memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER));
|
||||
|
||||
if (FLIP32 (pkzip.uncompressedSize) > MAXROMSIZE)
|
||||
{
|
||||
GUI_WaitPrompt("Error","File size not supported !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sprintf (msg, "Unzipping %d bytes ...", FLIP32 (pkzip.uncompressedSize));
|
||||
GUI_MsgBoxOpen("Information",msg,1);
|
||||
|
||||
|
@ -532,7 +532,11 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
||||
else
|
||||
size = DVD_LoadFile(buffer,selection);
|
||||
|
||||
/* Reload emulation */
|
||||
/* Exit menu */
|
||||
GUI_MsgBoxClose();
|
||||
GUI_DeleteMenu(m);
|
||||
|
||||
/* Init emulation */
|
||||
if (size)
|
||||
{
|
||||
if (config.s_auto & 2)
|
||||
@ -544,9 +548,6 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
||||
slot_autoload(config.s_default,config.s_device);
|
||||
}
|
||||
|
||||
/* Exit */
|
||||
GUI_MsgBoxClose();
|
||||
GUI_DeleteMenu(m);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#define _FILESEL_H
|
||||
|
||||
#define MAXJOLIET 256
|
||||
#define MAXFILES 1000
|
||||
#define MAXFILES 500
|
||||
|
||||
/* Filelist structure */
|
||||
typedef struct
|
||||
|
@ -36,7 +36,7 @@ typedef struct _yay0header {
|
||||
unsigned int chunks_offset ATTRIBUTE_PACKED;
|
||||
} yay0header;
|
||||
|
||||
int font_size[256];
|
||||
u8 font_size[256];
|
||||
int fheight;
|
||||
|
||||
static u8 *fontImage;
|
||||
@ -265,7 +265,7 @@ int FONT_Init(void)
|
||||
else
|
||||
c = i - fontHeader->first_char;
|
||||
|
||||
font_size[i] = ((unsigned char*)fontHeader)[fontHeader->width_table + c];
|
||||
font_size[i] = ((u8*)fontHeader)[fontHeader->width_table + c];
|
||||
}
|
||||
|
||||
/* font height */
|
||||
@ -403,7 +403,7 @@ void WriteCentre_HL( int y, char *string)
|
||||
* Draw functions (FrameBuffer)
|
||||
*
|
||||
****************************************************************************/
|
||||
void fntDrawHLine (int x1, int x2, int y, int color)
|
||||
static void fntDrawHLine (int x1, int x2, int y, int color)
|
||||
{
|
||||
int i;
|
||||
y = 320 * y;
|
||||
@ -412,21 +412,6 @@ void fntDrawHLine (int x1, int x2, int y, int color)
|
||||
for (i = x1; i <= x2; i++) xfb[whichfb][y + i] = color;
|
||||
}
|
||||
|
||||
void fntDrawVLine (int x, int y1, int y2, int color)
|
||||
{
|
||||
int i;
|
||||
x >>= 1;
|
||||
for (i = y1; i <= y2; i++) xfb[whichfb][x + (640 * i) / 2] = color;
|
||||
}
|
||||
|
||||
void fntDrawBox (int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
fntDrawHLine (x1, x2, y1, color);
|
||||
fntDrawHLine (x1, x2, y2, color);
|
||||
fntDrawVLine (x1, y1, y2, color);
|
||||
fntDrawVLine (x2, y1, y2, color);
|
||||
}
|
||||
|
||||
void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
int h;
|
||||
|
@ -37,6 +37,6 @@ extern void write_font (int x, int y, char *string);
|
||||
extern void WriteText(char *text, int size, int x, int y);
|
||||
extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color);
|
||||
extern int fheight;
|
||||
extern int font_size[256];
|
||||
extern u8 font_size[256];
|
||||
|
||||
#endif
|
||||
|
@ -1710,66 +1710,47 @@ void GUI_OptionBox2(gui_menu *parent, char *text_1, char *text_2, s16 *option_1,
|
||||
/* Message Box displays a message until a specific action is completed */
|
||||
|
||||
/* Message Box LWP Thread */
|
||||
static void *MsgBox_Thread(void *arg)
|
||||
static void *MsgBox_Thread(gui_message *message_box)
|
||||
{
|
||||
while (1)
|
||||
while (message_box->refresh)
|
||||
{
|
||||
if (message_box.refresh)
|
||||
/* draw parent menu */
|
||||
GUI_DrawMenu(message_box->parent);
|
||||
|
||||
/* draw window */
|
||||
gxDrawTexture(message_box->window,166,160,message_box->window->width,message_box->window->height,230);
|
||||
gxDrawTexture(message_box->top,166,160,message_box->top->width,message_box->top->height,255);
|
||||
|
||||
/* draw title */
|
||||
if (message_box->title)
|
||||
FONT_writeCenter(message_box->title,20,166,166+message_box->window->width,160+(message_box->top->height-20)/2+20,(GXColor)WHITE);
|
||||
|
||||
/* draw box message */
|
||||
if (message_box->msg)
|
||||
FONT_writeCenter(message_box->msg,18,166,166+message_box->window->width,248,(GXColor)WHITE);
|
||||
|
||||
/* draw throbber */
|
||||
if (message_box->throbber)
|
||||
gxDrawTextureRotate(message_box->throbber,166+(message_box->window->width-message_box->throbber->width)/2,160+message_box->window->height-message_box->throbber->height-20,message_box->throbber->width,message_box->throbber->height,(message_box->progress * 360.0) / 100.0, 255);
|
||||
|
||||
/* draw exit message */
|
||||
if (message_box->buttonA)
|
||||
{
|
||||
/* draw parent menu */
|
||||
GUI_DrawMenu(message_box.parent);
|
||||
|
||||
/* draw window */
|
||||
gxDrawTexture(message_box.window,166,160,message_box.window->width,message_box.window->height,230);
|
||||
gxDrawTexture(message_box.top,166,160,message_box.top->width,message_box.top->height,255);
|
||||
|
||||
/* draw title */
|
||||
if (message_box.title)
|
||||
FONT_writeCenter(message_box.title,20,166,166+message_box.window->width,160+(message_box.top->height-20)/2+20,(GXColor)WHITE);
|
||||
|
||||
/* draw box message */
|
||||
if (message_box.msg)
|
||||
FONT_writeCenter(message_box.msg,18,166,166+message_box.window->width,248,(GXColor)WHITE);
|
||||
|
||||
/* draw throbber */
|
||||
if (message_box.throbber)
|
||||
gxDrawTextureRotate(message_box.throbber,166+(message_box.window->width-message_box.throbber->width)/2,160+message_box.window->height-message_box.throbber->height-20,message_box.throbber->width,message_box.throbber->height,(message_box.progress * 360.0) / 100.0, 255);
|
||||
|
||||
/* draw exit message */
|
||||
if (message_box.buttonA)
|
||||
{
|
||||
if (message_box.buttonB)
|
||||
{
|
||||
FONT_write("OK",18,220+message_box.buttonA->width+6,288,640,(GXColor)WHITE);
|
||||
FONT_alignRight("CANCEL",18,166+message_box.window->width-(220-166),288,(GXColor)WHITE);
|
||||
if (message_box.buttonA)
|
||||
gxDrawTexture(message_box.buttonA, 220, 288-18+(18-message_box.buttonA->height)/2,message_box.buttonA->width, message_box.buttonA->height,255);
|
||||
if (message_box.buttonB)
|
||||
gxDrawTexture(message_box.buttonB, 328, 288-18+(18-message_box.buttonB->height)/2,message_box.buttonB->width, message_box.buttonB->height,255);
|
||||
}
|
||||
else
|
||||
{
|
||||
FONT_writeCenter("Press to continue.",18,166,166+message_box.window->width,248+22,(GXColor)WHITE);
|
||||
if (message_box.buttonA)
|
||||
gxDrawTexture(message_box.buttonA, 166+116, 248+4+(18-message_box.buttonA->height)/2,message_box.buttonA->width, message_box.buttonA->height,255);
|
||||
}
|
||||
}
|
||||
|
||||
/* update display */
|
||||
gxSetScreen();
|
||||
|
||||
/* update progression */
|
||||
message_box.progress++;
|
||||
if (message_box.progress > 100)
|
||||
message_box.progress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LWP_YieldThread();
|
||||
FONT_writeCenter("Press to continue.",18,166,166+message_box->window->width,248+22,(GXColor)WHITE);
|
||||
gxDrawTexture(message_box->buttonA, 166+116, 248+4+(18-message_box->buttonA->height)/2,message_box->buttonA->width, message_box->buttonA->height,255);
|
||||
}
|
||||
|
||||
/* update display */
|
||||
gxSetScreen();
|
||||
|
||||
/* update progression */
|
||||
message_box->progress++;
|
||||
if (message_box->progress > 100)
|
||||
message_box->progress = 0;
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* update current Message Box */
|
||||
@ -1787,12 +1768,7 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber)
|
||||
if (SILENT)
|
||||
return;
|
||||
|
||||
/* clear unused textures */
|
||||
gxTextureClose(&message_box.buttonA);
|
||||
gxTextureClose(&message_box.buttonB);
|
||||
gxTextureClose(&message_box.throbber);
|
||||
|
||||
/* update message box */
|
||||
/* update text */
|
||||
GUI_MsgBoxUpdate(title,msg);
|
||||
|
||||
/* ensure we are not already running */
|
||||
@ -1841,20 +1817,9 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber)
|
||||
yoffset -= 60;
|
||||
}
|
||||
|
||||
/* Final position */
|
||||
GUI_DrawMenu(message_box.parent);
|
||||
gxDrawTexture(message_box.window,xwindow,ywindow,message_box.window->width,message_box.window->height,230);
|
||||
gxDrawTexture(message_box.top,xwindow,ywindow,message_box.top->width,message_box.top->height,255);
|
||||
if (title)
|
||||
FONT_writeCenter(title,20,xwindow,xwindow+message_box.window->width,ywindow+(message_box.top->height-20)/2+20,(GXColor)WHITE);
|
||||
if (msg)
|
||||
FONT_writeCenter(msg,18,xwindow,xwindow+message_box.window->width,ypos,(GXColor)WHITE);
|
||||
gxSetScreen();
|
||||
|
||||
/* resume LWP thread for MessageBox refresh */
|
||||
message_box.progress = 0;
|
||||
/* create LWP thread for MessageBox refresh */
|
||||
message_box.refresh = TRUE;
|
||||
LWP_ResumeThread(msgboxthread);
|
||||
LWP_CreateThread (&msgboxthread, (void *)MsgBox_Thread, &message_box, NULL, 0, 70);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1865,7 +1830,7 @@ void GUI_MsgBoxClose(void)
|
||||
{
|
||||
/* suspend MessageBox refresh */
|
||||
message_box.refresh = FALSE;
|
||||
LWP_SuspendThread(msgboxthread);
|
||||
LWP_JoinThread(msgboxthread, NULL);
|
||||
|
||||
/* window position */
|
||||
int xwindow = 166;
|
||||
@ -1912,7 +1877,6 @@ void GUI_MsgBoxClose(void)
|
||||
gxTextureClose(&message_box.window);
|
||||
gxTextureClose(&message_box.top);
|
||||
gxTextureClose(&message_box.buttonA);
|
||||
gxTextureClose(&message_box.buttonB);
|
||||
gxTextureClose(&message_box.throbber);
|
||||
}
|
||||
}
|
||||
@ -1922,7 +1886,10 @@ void GUI_WaitPrompt(char *title, char *msg)
|
||||
if (SILENT)
|
||||
return;
|
||||
|
||||
/* update message box */
|
||||
/* clear unused texture */
|
||||
gxTextureClose(&message_box.throbber);
|
||||
|
||||
/* open or update message box */
|
||||
GUI_MsgBoxOpen(title, msg, 0);
|
||||
|
||||
/* allocate texture */
|
||||
@ -1968,12 +1935,3 @@ void GUI_SetBgColor(u8 color)
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize GUI engine */
|
||||
void GUI_Initialize(void)
|
||||
{
|
||||
/* create LWP thread for MessageBox refresh */
|
||||
message_box.refresh = FALSE;
|
||||
LWP_CreateThread (&msgboxthread, MsgBox_Thread, NULL, NULL, 0, 10);
|
||||
LWP_SuspendThread(msgboxthread);
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,6 @@ typedef struct
|
||||
gx_texture *window; /* pointer to box texture */
|
||||
gx_texture *top; /* pointer to box title texture */
|
||||
gx_texture *buttonA; /* pointer to button A texture */
|
||||
gx_texture *buttonB; /* pointer to button B texture */
|
||||
gx_texture *throbber; /* pointer to throbber texture */
|
||||
} gui_message;
|
||||
|
||||
|
@ -1046,8 +1046,8 @@ static void systemmenu ()
|
||||
|
||||
if (cart.romsize)
|
||||
{
|
||||
/* force region & cpu mode */
|
||||
set_region();
|
||||
/* reset console region */
|
||||
region_autodetect();
|
||||
|
||||
/* update framerate */
|
||||
if (vdp_pal)
|
||||
@ -1494,7 +1494,7 @@ static void ctrlmenu_raz(void)
|
||||
m->buttons[i+2].data = &button_player_data;
|
||||
m->buttons[i+2].state |= BUTTON_ACTIVE;
|
||||
sprintf(m->items[i+2].text,"%d",max + 1);
|
||||
if (cart.hw.jcart && (i > 4))
|
||||
if (cart.jcart && (i > 4))
|
||||
sprintf(m->items[i+2].comment,"Configure Player %d (J-CART) settings", max + 1);
|
||||
else
|
||||
sprintf(m->items[i+2].comment,"Configure Player %d settings", max + 1);
|
||||
@ -1674,7 +1674,7 @@ static void ctrlmenu(void)
|
||||
switch (m->selected)
|
||||
{
|
||||
case 0: /* update port 1 system */
|
||||
if (cart.hw.jcart) break;
|
||||
if (cart.jcart) break;
|
||||
if (input.system[0] == SYSTEM_MOUSE)
|
||||
input.system[0] +=3; /* lightguns are never used on Port 1 */
|
||||
else
|
||||
@ -1688,8 +1688,6 @@ static void ctrlmenu(void)
|
||||
input.system[0] = NO_SYSTEM;
|
||||
input.system[1] = SYSTEM_GAMEPAD;
|
||||
}
|
||||
old_system[0] = -1;
|
||||
old_system[1] = -1;
|
||||
io_init();
|
||||
io_reset();
|
||||
old_system[0] = input.system[0];
|
||||
@ -1729,7 +1727,7 @@ static void ctrlmenu(void)
|
||||
break;
|
||||
|
||||
case 1: /* update port 2 system */
|
||||
if (cart.hw.jcart) break;
|
||||
if (cart.jcart) break;
|
||||
input.system[1] ++;
|
||||
if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE))
|
||||
input.system[1] ++;
|
||||
@ -1740,8 +1738,6 @@ static void ctrlmenu(void)
|
||||
input.system[1] = NO_SYSTEM;
|
||||
input.system[0] = SYSTEM_GAMEPAD;
|
||||
}
|
||||
old_system[0] = -1;
|
||||
old_system[1] = -1;
|
||||
io_init();
|
||||
io_reset();
|
||||
old_system[0] = input.system[0];
|
||||
@ -1861,7 +1857,7 @@ static void ctrlmenu(void)
|
||||
GUI_DrawMenuFX(m, 20, 0);
|
||||
|
||||
/* update title */
|
||||
if (cart.hw.jcart && (player > 1))
|
||||
if (cart.jcart && (player > 1))
|
||||
sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1);
|
||||
else
|
||||
sprintf(m->title,"Controller Settings (Player %d)",player+1);
|
||||
@ -2112,7 +2108,7 @@ static void ctrlmenu(void)
|
||||
}
|
||||
|
||||
/* remove duplicate assigned inputs before leaving */
|
||||
for (i=0; i<8; i++)
|
||||
for (i=0; i<MAX_INPUTS; i++)
|
||||
{
|
||||
if ((i!=player) && (config.input[i].device == config.input[player].device) && (config.input[i].port == config.input[player].port))
|
||||
{
|
||||
@ -2232,6 +2228,7 @@ static void optionmenu(void)
|
||||
}
|
||||
}
|
||||
|
||||
config_save();
|
||||
GUI_DrawMenuFX(m,30,1);
|
||||
GUI_DeleteMenu(m);
|
||||
}
|
||||
@ -2401,6 +2398,7 @@ static int savemenu(void)
|
||||
case 6: /* set default slot */
|
||||
{
|
||||
config.s_default = slot;
|
||||
config_save();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2613,44 +2611,45 @@ static void showrominfo (void)
|
||||
/* fill ROM infos */
|
||||
sprintf (items[0], "Console Type: %s", rominfo.consoletype);
|
||||
sprintf (items[1], "Copyright: %s", rominfo.copyright);
|
||||
sprintf (items[2], "Company Name: %s", companyinfo[getcompany ()].company);
|
||||
sprintf (items[2], "Company Name: %s", get_company());
|
||||
sprintf (items[3], "Domestic Name:");
|
||||
sprintf (items[4], "%s",rominfo.domestic);
|
||||
sprintf (items[5], "International Name:");
|
||||
sprintf (items[6], "%s",rominfo.international);
|
||||
sprintf (items[7], "Type: %s (%s)",rominfo.ROMType, strcmp(rominfo.ROMType, "AI") ? "Game" : "Educational");
|
||||
sprintf (items[8], "Product ID: %s", rominfo.product);
|
||||
sprintf (items[9], "Checksum: %04x (%04x) (%s)", rominfo.checksum, realchecksum, (rominfo.checksum == realchecksum) ? "GOOD" : "BAD");
|
||||
sprintf (items[9], "Checksum: %04x (%04x) (%s)", rominfo.checksum, rominfo.realchecksum,
|
||||
(rominfo.checksum == rominfo.realchecksum) ? "GOOD" : "BAD");
|
||||
|
||||
sprintf (items[10], "Supports: ");
|
||||
if (peripherals & (1 << 1))
|
||||
if (rominfo.peripherals & (1 << 1))
|
||||
{
|
||||
strcat(items[10],peripheralinfo[1].pName);
|
||||
strcat(items[10],get_peripheral(1));
|
||||
strcat(items[10],", ");
|
||||
}
|
||||
else if (peripherals & (1 << 0))
|
||||
else if (rominfo.peripherals & (1 << 0))
|
||||
{
|
||||
strcat(items[10],peripheralinfo[0].pName);
|
||||
strcat(items[10],get_peripheral(0));
|
||||
strcat(items[10],", ");
|
||||
}
|
||||
if (peripherals & (1 << 7))
|
||||
if (rominfo.peripherals & (1 << 7))
|
||||
{
|
||||
strcat(items[10],peripheralinfo[7].pName);
|
||||
strcat(items[10],get_peripheral(7));
|
||||
strcat(items[10],", ");
|
||||
}
|
||||
if (peripherals & (1 << 8))
|
||||
if (rominfo.peripherals & (1 << 8))
|
||||
{
|
||||
strcat(items[10],peripheralinfo[8].pName);
|
||||
strcat(items[10],get_peripheral(8));
|
||||
strcat(items[10],", ");
|
||||
}
|
||||
if (peripherals & (1 << 11))
|
||||
if (rominfo.peripherals & (1 << 11))
|
||||
{
|
||||
strcat(items[10],peripheralinfo[11].pName);
|
||||
strcat(items[10],get_peripheral(11));
|
||||
strcat(items[10],", ");
|
||||
}
|
||||
if (peripherals & (1 << 13))
|
||||
if (rominfo.peripherals & (1 << 13))
|
||||
{
|
||||
strcat(items[10],peripheralinfo[13].pName);
|
||||
strcat(items[10],get_peripheral(12));
|
||||
strcat(items[10],", ");
|
||||
}
|
||||
if (strlen(items[10]) > 10)
|
||||
@ -2699,7 +2698,8 @@ static void showcredits(void)
|
||||
while (!p)
|
||||
{
|
||||
gxClearScreen ((GXColor)BLACK);
|
||||
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
|
||||
if (texture)
|
||||
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
|
||||
|
||||
FONT_writeCenter("Genesis Plus Core", 24, 0, 640, 480 - offset, (GXColor)LIGHT_BLUE);
|
||||
FONT_writeCenter("original 1.2a version by Charles MacDonald", 18, 0, 640, 516 - offset, (GXColor)WHITE);
|
||||
@ -2876,7 +2876,9 @@ void MainMenu (void)
|
||||
switch (GUI_OptionWindow(m, VERSION, items,3))
|
||||
{
|
||||
case 0: /* credits */
|
||||
GUI_DeleteMenu(m);
|
||||
showcredits();
|
||||
GUI_InitMenu(m);
|
||||
break;
|
||||
|
||||
case 1: /* return to loader */
|
||||
|
@ -85,7 +85,7 @@ static void pad_config(int chan, int max_keys)
|
||||
{
|
||||
int i;
|
||||
u16 p,key;
|
||||
char msg[30];
|
||||
char msg[64];
|
||||
|
||||
/* reset VSYNC callback */
|
||||
VIDEO_SetPostRetraceCallback(NULL);
|
||||
@ -168,7 +168,9 @@ static void pad_update(s8 chan, u8 i)
|
||||
else if ((p & PAD_TRIGGER_L) && (p & PAD_TRIGGER_Z))
|
||||
{
|
||||
/* Soft RESET */
|
||||
set_softreset();
|
||||
if (config.lock_on == TYPE_AR)
|
||||
datel_reset(0);
|
||||
gen_reset(0);
|
||||
}
|
||||
|
||||
/* Retrieve current key mapping */
|
||||
@ -344,7 +346,7 @@ static s8 WPAD_StickY(WPADData *data, u8 right)
|
||||
static void wpad_config(u8 chan, u8 exp, u8 max_keys)
|
||||
{
|
||||
int i;
|
||||
char msg[30];
|
||||
char msg[64];
|
||||
u32 key,p = 255;
|
||||
|
||||
/* remove inputs update callback */
|
||||
@ -473,7 +475,9 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
((p & WPAD_CLASSIC_BUTTON_PLUS) && (p & WPAD_CLASSIC_BUTTON_MINUS)))
|
||||
{
|
||||
/* Soft RESET */
|
||||
set_softreset();
|
||||
if (config.lock_on == TYPE_AR)
|
||||
datel_reset(0);
|
||||
gen_reset(0);
|
||||
}
|
||||
|
||||
/* Retrieve current key mapping */
|
||||
@ -610,7 +614,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
if (system_hw != SYSTEM_PICO)
|
||||
{
|
||||
/* gamepad */
|
||||
if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY))
|
||||
if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY))
|
||||
input.pad[i] |= INPUT_UP;
|
||||
else if ((p & wpad_dirmap[exp][PAD_DOWN]) || (y < -ANALOG_SENSITIVITY))
|
||||
input.pad[i] |= INPUT_DOWN;
|
||||
@ -822,7 +826,9 @@ void gx_input_UpdateEmu(void)
|
||||
if (SYS_ResetButtonDown())
|
||||
{
|
||||
/* Soft RESET */
|
||||
set_softreset();
|
||||
if (config.lock_on == TYPE_AR)
|
||||
datel_reset(0);
|
||||
gen_reset(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -58,10 +58,10 @@ u8 *screenshot; /* Texture Data */
|
||||
u32 gc_pal = 0;
|
||||
|
||||
/*** NTSC Filters ***/
|
||||
sms_ntsc_t sms_ntsc;
|
||||
md_ntsc_t md_ntsc;
|
||||
static sms_ntsc_setup_t sms_setup;
|
||||
static md_ntsc_setup_t md_setup;
|
||||
sms_ntsc_t *sms_ntsc;
|
||||
md_ntsc_t *md_ntsc;
|
||||
static const sms_ntsc_setup_t *sms_setup;
|
||||
static const md_ntsc_setup_t *md_setup;
|
||||
|
||||
/*** GX FIFO ***/
|
||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
||||
@ -1266,6 +1266,12 @@ void gxTextureClose(gx_texture **p_texture)
|
||||
/* Emulation mode -> Menu mode */
|
||||
void gx_video_Stop(void)
|
||||
{
|
||||
/* unallocate NTSC filters */
|
||||
if (sms_ntsc)
|
||||
free(sms_ntsc);
|
||||
if (md_ntsc)
|
||||
free(md_ntsc);
|
||||
|
||||
/* lightgun textures */
|
||||
gxTextureClose(&crosshair[0]);
|
||||
gxTextureClose(&crosshair[1]);
|
||||
@ -1274,6 +1280,10 @@ void gx_video_Stop(void)
|
||||
gxResetRendering(1);
|
||||
gxResetMode(vmode);
|
||||
|
||||
/* display game snapshot */
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
gxDrawScreenshot(0xff);
|
||||
|
||||
/* default VI settings */
|
||||
VIDEO_SetPreRetraceCallback(NULL);
|
||||
VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu);
|
||||
@ -1282,14 +1292,12 @@ void gx_video_Stop(void)
|
||||
VIDEO_SetGamma(VI_GM_1_0);
|
||||
#endif
|
||||
|
||||
/* default TV mode */
|
||||
/* adjust TV width */
|
||||
vmode->viWidth = config.screen_w;
|
||||
vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2;
|
||||
VIDEO_Configure(vmode);
|
||||
|
||||
/* starts menu rendering */
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
gxDrawScreenshot(0xff);
|
||||
/* wait for VSYNC */
|
||||
gxSetScreen();
|
||||
}
|
||||
|
||||
@ -1344,27 +1352,35 @@ void gx_video_Start(void)
|
||||
vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x);
|
||||
vheight = bitmap.viewport.h + (2 * bitmap.viewport.y);
|
||||
|
||||
/* software NTSC filters */
|
||||
if (config.ntsc == 1)
|
||||
/* NTSC filter */
|
||||
sms_ntsc = NULL;
|
||||
md_ntsc = NULL;
|
||||
if (config.ntsc)
|
||||
{
|
||||
sms_setup = sms_ntsc_composite;
|
||||
md_setup = md_ntsc_composite;
|
||||
sms_ntsc_init( &sms_ntsc, &sms_setup );
|
||||
md_ntsc_init( &md_ntsc, &md_setup );
|
||||
}
|
||||
else if (config.ntsc == 2)
|
||||
{
|
||||
sms_setup = sms_ntsc_svideo;
|
||||
md_setup = md_ntsc_svideo;
|
||||
sms_ntsc_init( &sms_ntsc, &sms_setup );
|
||||
md_ntsc_init( &md_ntsc, &md_setup );
|
||||
}
|
||||
else if (config.ntsc == 3)
|
||||
{
|
||||
sms_setup = sms_ntsc_rgb;
|
||||
md_setup = md_ntsc_rgb;
|
||||
sms_ntsc_init( &sms_ntsc, &sms_setup );
|
||||
md_ntsc_init( &md_ntsc, &md_setup );
|
||||
/* allocate filters */
|
||||
sms_ntsc = (sms_ntsc_t *)memalign(32,sizeof(sms_ntsc_t));
|
||||
md_ntsc = (md_ntsc_t *)memalign(32,sizeof(md_ntsc_t));
|
||||
|
||||
/* setup filters default configuration */
|
||||
switch (config.ntsc)
|
||||
{
|
||||
case 1:
|
||||
sms_setup = &sms_ntsc_composite;
|
||||
md_setup = &md_ntsc_composite;
|
||||
break;
|
||||
case 2:
|
||||
sms_setup = &sms_ntsc_svideo;
|
||||
md_setup = &md_ntsc_svideo;
|
||||
break;
|
||||
case 3:
|
||||
sms_setup = &sms_ntsc_rgb;
|
||||
md_setup = &md_ntsc_rgb;
|
||||
break;
|
||||
}
|
||||
|
||||
/* initialize filters */
|
||||
sms_ntsc_init(sms_ntsc, sms_setup);
|
||||
md_ntsc_init(md_ntsc, md_setup);
|
||||
}
|
||||
|
||||
/* lightgun textures */
|
||||
|
@ -155,6 +155,54 @@ static void init_machine(void)
|
||||
bitmap.data = texturemem;
|
||||
}
|
||||
|
||||
static void run_emulation(void)
|
||||
{
|
||||
/* main emulation loop */
|
||||
while (1)
|
||||
{
|
||||
/* Main Menu request */
|
||||
if (ConfigRequested)
|
||||
{
|
||||
/* stop video & audio */
|
||||
gx_audio_Stop();
|
||||
gx_video_Stop();
|
||||
|
||||
/* show menu */
|
||||
MainMenu ();
|
||||
ConfigRequested = 0;
|
||||
|
||||
/* start video & audio */
|
||||
gx_audio_Start();
|
||||
gx_video_Start();
|
||||
frameticker = 1;
|
||||
}
|
||||
|
||||
/* automatic frame skipping */
|
||||
if (frameticker > 1)
|
||||
{
|
||||
/* skip frame */
|
||||
frameticker = 0;
|
||||
system_frame(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* render frame */
|
||||
frameticker = 0;
|
||||
system_frame(0);
|
||||
|
||||
/* update video */
|
||||
gx_video_Update();
|
||||
}
|
||||
|
||||
/* update audio */
|
||||
gx_audio_Update();
|
||||
|
||||
/* wait for next frame */
|
||||
while (frameticker < 1)
|
||||
usleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
Load a new rom and performs some initialization
|
||||
***************************************************/
|
||||
@ -325,62 +373,13 @@ int main (int argc, char *argv[])
|
||||
SILENT = 0;
|
||||
}
|
||||
|
||||
/* initialize GUI engine */
|
||||
GUI_Initialize();
|
||||
|
||||
#ifdef HW_RVL
|
||||
/* Power button callback */
|
||||
SYS_SetPowerCallback(Power_Off);
|
||||
#endif
|
||||
|
||||
/* main emulation loop */
|
||||
int skip = 0;
|
||||
while (1)
|
||||
{
|
||||
/* Main Menu request */
|
||||
if (ConfigRequested)
|
||||
{
|
||||
/* stop video & audio */
|
||||
gx_audio_Stop();
|
||||
gx_video_Stop();
|
||||
|
||||
/* show menu */
|
||||
MainMenu ();
|
||||
ConfigRequested = 0;
|
||||
|
||||
/* start video & audio */
|
||||
gx_audio_Start();
|
||||
gx_video_Start();
|
||||
skip = 0;
|
||||
}
|
||||
|
||||
frameticker = 0;
|
||||
if (skip)
|
||||
{
|
||||
/* skip frame */
|
||||
system_frame(1);
|
||||
skip = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* render frame */
|
||||
system_frame(0);
|
||||
|
||||
/* update video */
|
||||
gx_video_Update();
|
||||
}
|
||||
|
||||
/* update audio */
|
||||
gx_audio_Update();
|
||||
|
||||
/* wait for next frame */
|
||||
while (frameticker < 1)
|
||||
usleep(1);
|
||||
|
||||
/* automatic frame skipping */
|
||||
if (frameticker > 1)
|
||||
skip = 1;
|
||||
}
|
||||
run_emulation();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
122
source/loadrom.c
122
source/loadrom.c
@ -57,8 +57,23 @@
|
||||
#define PCDROM 4096
|
||||
#define PMOUSE 8192
|
||||
|
||||
uint16 peripherals;
|
||||
uint16 realchecksum;
|
||||
#define MAXCOMPANY 64
|
||||
#define MAXPERIPHERALS 14
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char companyid[6];
|
||||
char company[26];
|
||||
} COMPANYINFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char pID[2];
|
||||
char pName[14];
|
||||
} PERIPHERALINFO;
|
||||
|
||||
|
||||
ROMINFO rominfo;
|
||||
char rom_filename[256];
|
||||
|
||||
@ -69,7 +84,7 @@ char rom_filename[256];
|
||||
* Based on the document provided at
|
||||
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
|
||||
**************************************************************************/
|
||||
COMPANYINFO companyinfo[MAXCOMPANY] = {
|
||||
static COMPANYINFO companyinfo[MAXCOMPANY] = {
|
||||
{"ACLD", "Ballistic"},
|
||||
{"RSI", "Razorsoft"},
|
||||
{"SEGA", "SEGA"},
|
||||
@ -105,7 +120,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = {
|
||||
{"50", "Electronic Arts"},
|
||||
{"56", "Razorsoft"},
|
||||
{"58", "Mentrix"},
|
||||
{"60", "Victor Musical Industries"},
|
||||
{"60", "Victor Musical Ind."},
|
||||
{"69", "Arena"},
|
||||
{"70", "Virgin"},
|
||||
{"73", "Soft Vision"},
|
||||
@ -142,7 +157,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = {
|
||||
* Based on the document provided at
|
||||
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
|
||||
***************************************************************************/
|
||||
PERIPHERALINFO peripheralinfo[14] = {
|
||||
static PERIPHERALINFO peripheralinfo[MAXPERIPHERALS] = {
|
||||
{"J", "3B Joypad"},
|
||||
{"6", "6B Joypad"},
|
||||
{"K", "Keyboard"},
|
||||
@ -156,13 +171,14 @@ PERIPHERALINFO peripheralinfo[14] = {
|
||||
{"T", "Tablet"},
|
||||
{"V", "Paddle"},
|
||||
{"C", "CD-ROM"},
|
||||
{"M", "Mega Mouse"}
|
||||
{"M", "Mega Mouse"},
|
||||
};
|
||||
|
||||
/*
|
||||
* softdev - New Checksum Calculation
|
||||
eke-eke: fixed
|
||||
*/
|
||||
/***************************************************************************
|
||||
* GetRealChecksum
|
||||
*
|
||||
* Compute ROM checksum.
|
||||
***************************************************************************/
|
||||
static uint16 GetRealChecksum (uint8 *rom, int length)
|
||||
{
|
||||
int i;
|
||||
@ -217,31 +233,28 @@ static void getrominfo (char *romheader)
|
||||
memcpy (&rominfo.ROMType, romheader + ROMTYPE, 2);
|
||||
memcpy (&rominfo.product, romheader + ROMPRODUCT, 12);
|
||||
memcpy (&rominfo.checksum, romheader + ROMCHECKSUM, 2);
|
||||
memcpy (&rominfo.io_support, romheader + ROMIOSUPPORT, 16);
|
||||
memcpy (&rominfo.romstart, romheader + ROMROMSTART, 4);
|
||||
memcpy (&rominfo.romend, romheader + ROMROMEND, 4);
|
||||
memcpy (&rominfo.RAMInfo, romheader + ROMRAMINFO, 12);
|
||||
memcpy (&rominfo.ramstart, romheader + ROMRAMSTART, 4);
|
||||
memcpy (&rominfo.ramend, romheader + ROMRAMEND, 4);
|
||||
memcpy (&rominfo.modem, romheader + ROMMODEMINFO, 12);
|
||||
memcpy (&rominfo.memo, romheader + ROMMEMO, 40);
|
||||
memcpy (&rominfo.country, romheader + ROMCOUNTRY, 16);
|
||||
|
||||
realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200);
|
||||
#ifdef LSB_FIRST
|
||||
rominfo.checksum = (rominfo.checksum >> 8) | ((rominfo.checksum & 0xff) << 8);
|
||||
#endif
|
||||
rominfo.realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200);
|
||||
|
||||
peripherals = 0;
|
||||
|
||||
rominfo.peripherals = 0;
|
||||
for (i = 0; i < 14; i++)
|
||||
for (j=0; j < 14; j++)
|
||||
if (rominfo.io_support[i] == peripheralinfo[j].pID[0])
|
||||
peripherals |= (1 << j);
|
||||
for (j=0; j < 14; j++)
|
||||
if (romheader[ROMIOSUPPORT+i] == peripheralinfo[j].pID[0])
|
||||
rominfo.peripherals |= (1 << j);
|
||||
}
|
||||
|
||||
/* SMD (interleaved) rom support */
|
||||
static void deinterleave_block (uint8 * src)
|
||||
/***************************************************************************
|
||||
* deinterleave_block
|
||||
*
|
||||
* Convert interleaved (.smd) ROM files.
|
||||
***************************************************************************/
|
||||
static void deinterleave_block(uint8 * src)
|
||||
{
|
||||
int i;
|
||||
uint8 block[0x4000];
|
||||
@ -253,6 +266,11 @@ static void deinterleave_block (uint8 * src)
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* load_rom
|
||||
*
|
||||
* Load a new ROM file.
|
||||
***************************************************************************/
|
||||
int load_rom(char *filename)
|
||||
{
|
||||
int i, size, offset = 0;
|
||||
@ -274,12 +292,8 @@ int load_rom(char *filename)
|
||||
{
|
||||
size -= 512;
|
||||
offset += 512;
|
||||
|
||||
for (i = 0; i < (size / 0x4000); i += 1)
|
||||
{
|
||||
deinterleave_block (cart.rom + offset + (i * 0x4000));
|
||||
}
|
||||
|
||||
memcpy(cart.rom, cart.rom + offset, size);
|
||||
}
|
||||
|
||||
@ -288,13 +302,16 @@ int load_rom(char *filename)
|
||||
cart.romsize = size;
|
||||
|
||||
/* clear unused ROM space */
|
||||
memset (cart.rom + size, 0xff, MAXROMSIZE - size);
|
||||
memset(cart.rom + size, 0xff, MAXROMSIZE - size);
|
||||
|
||||
/* get infos from ROM header */
|
||||
getrominfo((char *)cart.rom);
|
||||
|
||||
/* set system region */
|
||||
set_region();
|
||||
/* get specific input devices */
|
||||
input_autodetect();
|
||||
|
||||
/* get default region */
|
||||
region_autodetect();
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* Byteswap ROM */
|
||||
@ -331,8 +348,13 @@ int load_rom(char *filename)
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* 05/05/2006: new region detection routine (taken from GENS sourcecode) */
|
||||
void set_region ()
|
||||
/****************************************************************************
|
||||
* region_autodetect
|
||||
*
|
||||
* Set console region upon ROM header
|
||||
*
|
||||
****************************************************************************/
|
||||
void region_autodetect(void)
|
||||
{
|
||||
/* country codes used to differentiate region */
|
||||
/* 0001 = japan ntsc (1) */
|
||||
@ -379,7 +401,7 @@ void set_region ()
|
||||
/* need PAL settings */
|
||||
region_code = REGION_EUROPE;
|
||||
}
|
||||
else if ((realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
|
||||
else if ((rominfo.realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
|
||||
{
|
||||
/* On Dal Jang Goon (Korea) needs JAP region code */
|
||||
region_code = REGION_JAPAN_NTSC;
|
||||
@ -410,7 +432,7 @@ void set_region ()
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* getcompany
|
||||
* get_company
|
||||
*
|
||||
* Try to determine which company made this rom
|
||||
*
|
||||
@ -418,13 +440,14 @@ void set_region ()
|
||||
* It seems that there can be pretty much anything you like following the
|
||||
* copyright (C) symbol!
|
||||
****************************************************************************/
|
||||
int getcompany ()
|
||||
char *get_company(void)
|
||||
{
|
||||
char *s;
|
||||
int i;
|
||||
char company[10];
|
||||
|
||||
for (i = 3; i < 8; i++) company[i - 3] = rominfo.copyright[i];
|
||||
for (i = 3; i < 8; i++)
|
||||
company[i - 3] = rominfo.copyright[i];
|
||||
company[5] = 0;
|
||||
|
||||
/** OK, first look for a hyphen
|
||||
@ -439,14 +462,31 @@ int getcompany ()
|
||||
|
||||
/** Strip any trailing spaces **/
|
||||
for (i = strlen (company) - 1; i >= 0; i--)
|
||||
if (company[i] == 32) company[i] = 0;
|
||||
if (company[i] == 32)
|
||||
company[i] = 0;
|
||||
|
||||
if (strlen (company) == 0) return MAXCOMPANY - 1;
|
||||
if (strlen (company) == 0)
|
||||
return companyinfo[MAXCOMPANY - 1].company;
|
||||
|
||||
for (i = 0; i < MAXCOMPANY - 1; i++)
|
||||
{
|
||||
if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) return i;
|
||||
if (!(strncmp (company, companyinfo[i].companyid, strlen (company))))
|
||||
return companyinfo[i].company;
|
||||
}
|
||||
|
||||
return MAXCOMPANY - 1;
|
||||
return companyinfo[MAXCOMPANY - 1].company;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* get_peripheral
|
||||
*
|
||||
* Return peripheral name based on header code
|
||||
*
|
||||
****************************************************************************/
|
||||
char *get_peripheral(int index)
|
||||
{
|
||||
if (index < MAXPERIPHERALS)
|
||||
return peripheralinfo[index].pName;
|
||||
return companyinfo[MAXCOMPANY - 1].company;
|
||||
}
|
||||
|
||||
|
@ -23,53 +23,34 @@
|
||||
#ifndef _LOADROM_H_
|
||||
#define _LOADROM_H_
|
||||
|
||||
#define MAXCOMPANY 64
|
||||
#define MAXROMSIZE 10485760
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char consoletype[18]; /* Genesis or Mega Drive */
|
||||
char copyright[18]; /* Copyright message */
|
||||
char domestic[50]; /* Domestic name of ROM */
|
||||
char international[50]; /* International name of ROM */
|
||||
char ROMType[4]; /* Educational or Game */
|
||||
char product[14]; /* Product serial number */
|
||||
unsigned short checksum; /* Checksum */
|
||||
char io_support[18]; /* Actually 16 chars :) */
|
||||
unsigned int romstart; /* ROM start address */
|
||||
unsigned int romend; /* ROM end address */
|
||||
char RAMInfo[14]; /* Backup RAM header */
|
||||
unsigned int ramstart; /* RAM start address */
|
||||
unsigned int ramend; /* RAM end address */
|
||||
char modem[14]; /* Sega Modem support */
|
||||
char memo[50]; /* Misc */
|
||||
char country[18]; /* Country flag */
|
||||
char consoletype[18]; /* Genesis or Mega Drive */
|
||||
char copyright[18]; /* Copyright message */
|
||||
char domestic[50]; /* Domestic name of ROM */
|
||||
char international[50]; /* International name of ROM */
|
||||
char ROMType[4]; /* Educational or Game */
|
||||
char product[14]; /* Product serial number */
|
||||
unsigned short checksum; /* ROM Checksum (header) */
|
||||
unsigned short realchecksum; /* ROM Checksum (calculated) */
|
||||
unsigned int romstart; /* ROM start address */
|
||||
unsigned int romend; /* ROM end address */
|
||||
char country[18]; /* Country flag */
|
||||
uint16 peripherals; /* Supported peripherals */
|
||||
} ROMINFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char companyid[6];
|
||||
char company[30];
|
||||
} COMPANYINFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char pID[2];
|
||||
char pName[21];
|
||||
} PERIPHERALINFO;
|
||||
|
||||
/* Global variables */
|
||||
extern ROMINFO rominfo;
|
||||
extern COMPANYINFO companyinfo[MAXCOMPANY];
|
||||
extern PERIPHERALINFO peripheralinfo[14];
|
||||
extern uint16 realchecksum;
|
||||
extern uint16 peripherals;
|
||||
extern char rom_filename[256];
|
||||
|
||||
/* Function prototypes */
|
||||
extern int load_rom(char *filename);
|
||||
extern int getcompany();
|
||||
extern void set_region();
|
||||
extern void region_autodetect(void);
|
||||
extern char *get_company(void);
|
||||
extern char *get_peripheral(int index);
|
||||
|
||||
#endif /* _LOADROM_H_ */
|
||||
|
||||
|
@ -124,7 +124,7 @@ const uint m68ki_shift_32_table[65] =
|
||||
/* Number of clock cycles to use for exception processing.
|
||||
* I used 4 for any vectors that are undocumented for processing times.
|
||||
*/
|
||||
uint16 m68ki_exception_cycle_table[4][256] =
|
||||
uint16 m68ki_exception_cycle_table[NUM_CPU_TYPES][256] =
|
||||
{
|
||||
{ /* 000 */
|
||||
40, /* 0: Reset - Initial Stack Pointer */
|
||||
@ -199,6 +199,8 @@ uint16 m68ki_exception_cycle_table[4][256] =
|
||||
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
|
||||
},
|
||||
|
||||
#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
|
||||
{ /* 010 */
|
||||
40, /* 0: Reset - Initial Stack Pointer */
|
||||
4, /* 1: Reset - Initial Program Counter */
|
||||
@ -418,6 +420,7 @@ uint16 m68ki_exception_cycle_table[4][256] =
|
||||
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
|
||||
@ -694,6 +697,8 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
||||
CYC_SHIFT = 2 * 7;
|
||||
CYC_RESET = 132 * 7;
|
||||
return;
|
||||
|
||||
#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
|
||||
case M68K_CPU_TYPE_68008:
|
||||
CPU_TYPE = CPU_TYPE_008;
|
||||
CPU_ADDRESS_MASK = 0x003fffff;
|
||||
@ -774,6 +779,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
||||
CYC_SHIFT = 0;
|
||||
CYC_RESET = 518;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,11 @@
|
||||
/* ============================ OPCODE HANDLERS =========================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040
|
||||
#define NUM_CPU_TYPES 4
|
||||
#else
|
||||
#define NUM_CPU_TYPES 1
|
||||
#endif
|
||||
|
||||
/* Build the opcode handler table */
|
||||
void m68ki_build_opcode_table(void);
|
||||
|
@ -64,8 +64,6 @@ extern void vdp_write_word(uint32 address, uint32 data);
|
||||
extern uint32 pico_read_byte(uint32 address);
|
||||
extern uint32 pico_read_word(uint32 address);
|
||||
|
||||
uint8 m68k_readmap[256];
|
||||
uint8 m68k_writemap[256];
|
||||
uint32 pico_current;
|
||||
|
||||
#endif /* _MEM68K_H_ */
|
||||
|
@ -26,8 +26,8 @@
|
||||
#include "sms_ntsc.h"
|
||||
|
||||
/*** NTSC Filters ***/
|
||||
extern md_ntsc_t md_ntsc;
|
||||
extern sms_ntsc_t sms_ntsc;
|
||||
extern md_ntsc_t *md_ntsc;
|
||||
extern sms_ntsc_t *sms_ntsc;
|
||||
|
||||
/* Look-up pixel table information */
|
||||
#define LUT_MAX (5)
|
||||
@ -1836,9 +1836,9 @@ void remap_buffer(int line, int width)
|
||||
if (config.ntsc)
|
||||
{
|
||||
if (reg[12]&1)
|
||||
md_ntsc_blit(&md_ntsc, ( MD_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
|
||||
md_ntsc_blit(md_ntsc, ( MD_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
|
||||
else
|
||||
sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
|
||||
sms_ntsc_blit(sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,7 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
||||
static unsigned char state[STATE_SIZE];
|
||||
#define STATE_VERSION "GENPLUS-GX 1.4.x"
|
||||
|
||||
#define load_param(param, size) \
|
||||
memcpy(param, &state[bufferptr], size); \
|
||||
@ -38,6 +37,10 @@ int state_load(unsigned char *buffer)
|
||||
/* buffer size */
|
||||
int bufferptr = 0;
|
||||
|
||||
/* first allocate state buffer */
|
||||
unsigned char *state = (unsigned char *)malloc(STATE_SIZE);
|
||||
if (!state) return 0;
|
||||
|
||||
/* uncompress savestate */
|
||||
unsigned long inbytes, outbytes;
|
||||
memcpy(&inbytes, buffer, 4);
|
||||
@ -49,7 +52,8 @@ int state_load(unsigned char *buffer)
|
||||
load_param(version,16);
|
||||
if (strncmp(version,STATE_VERSION,16))
|
||||
{
|
||||
return 0;
|
||||
free(state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* reset system */
|
||||
@ -116,6 +120,7 @@ int state_load(unsigned char *buffer)
|
||||
// Z80
|
||||
load_param(&Z80, sizeof(Z80_Regs));
|
||||
|
||||
free(state);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -124,6 +129,10 @@ int state_save(unsigned char *buffer)
|
||||
/* buffer size */
|
||||
int bufferptr = 0;
|
||||
|
||||
/* first allocate state buffer */
|
||||
unsigned char *state = (unsigned char *)malloc(STATE_SIZE);
|
||||
if (!state) return 0;
|
||||
|
||||
/* version string */
|
||||
char version[16];
|
||||
strncpy(version,STATE_VERSION,16);
|
||||
@ -164,7 +173,7 @@ int state_save(unsigned char *buffer)
|
||||
uint16 tmp16;
|
||||
uint32 tmp32;
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4);
|
||||
@ -181,7 +190,7 @@ int state_save(unsigned char *buffer)
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4);
|
||||
tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
|
||||
|
||||
// Z80
|
||||
save_param(&Z80, sizeof(Z80_Regs));
|
||||
@ -191,6 +200,7 @@ int state_save(unsigned char *buffer)
|
||||
unsigned long outbytes = STATE_SIZE;
|
||||
compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9);
|
||||
memcpy(buffer, &outbytes, 4);
|
||||
free(state);
|
||||
|
||||
/* return total size */
|
||||
return (outbytes + 4);
|
||||
|
@ -24,7 +24,6 @@
|
||||
#define _STATE_H_
|
||||
|
||||
#define STATE_SIZE 0x28000
|
||||
#define STATE_VERSION "GENPLUS-GX 1.4.x"
|
||||
|
||||
/* Function prototypes */
|
||||
extern int state_load(unsigned char *buffer);
|
||||
|
@ -278,16 +278,16 @@ void audio_shutdown(void)
|
||||
****************************************************************/
|
||||
void system_init (void)
|
||||
{
|
||||
/* Cartridge hardware */
|
||||
cart_hw_init();
|
||||
|
||||
/* Genesis hardware */
|
||||
gen_init();
|
||||
io_init();
|
||||
vdp_init();
|
||||
render_init();
|
||||
|
||||
/* Sound Chips hardware */
|
||||
/* Cartridge hardware */
|
||||
cart_hw_init();
|
||||
|
||||
/* Sound hardware */
|
||||
sound_init();
|
||||
}
|
||||
|
||||
@ -305,10 +305,10 @@ void system_reset (void)
|
||||
vdp_reset();
|
||||
render_reset();
|
||||
|
||||
/* Sound chips */
|
||||
/* Sound hardware */
|
||||
sound_reset();
|
||||
|
||||
/* Audio System */
|
||||
/* Audio system */
|
||||
audio_reset();
|
||||
}
|
||||
|
||||
@ -335,7 +335,6 @@ int system_frame (int do_skip)
|
||||
|
||||
/* update display settings */
|
||||
int line;
|
||||
int reset = resetline;
|
||||
int vdp_height = bitmap.viewport.h;
|
||||
int end_line = vdp_height + bitmap.viewport.y;
|
||||
int start_line = lines_per_frame - bitmap.viewport.y;
|
||||
@ -381,16 +380,6 @@ int system_frame (int do_skip)
|
||||
/* 68k line cycle count */
|
||||
hint_68k = mcycles_68k;
|
||||
|
||||
/* Soft Reset line */
|
||||
if (line == reset)
|
||||
{
|
||||
/* Pro Action Replay (switch at "Trainer" position) */
|
||||
if (config.lock_on == TYPE_AR)
|
||||
datel_reset(0);
|
||||
|
||||
gen_reset(0);
|
||||
}
|
||||
|
||||
/* update VDP DMA */
|
||||
if (dma_length)
|
||||
vdp_update_dma();
|
||||
|
@ -220,7 +220,7 @@ static Uint32 sdl_sync_timer_callback(Uint32 interval)
|
||||
{
|
||||
int fps = vdp_pal ? (sdl_video.frames_rendered / 3) : sdl_video.frames_rendered;
|
||||
sdl_sync.ticks = sdl_video.frames_rendered = 0;
|
||||
sprintf(caption, "Genesis Plus/SDL - %s (%s) - 0x%04X - %d fps", rominfo.international, region, realchecksum, fps);
|
||||
sprintf(caption, "Genesis Plus/SDL - %s (%s) - 0x%04X - %d fps", rominfo.international, region, rominfo.realchecksum, fps);
|
||||
SDL_WM_SetCaption(caption, NULL);
|
||||
}
|
||||
return interval;
|
||||
|
Loading…
Reference in New Issue
Block a user