- annual code cleanup ;-)
- added port $3E emulation (SMS, GG) - added SMS & GG BIOS support - added an option to run BIOS without cartridge - added separate ROM browsers for SG-1000, Master System, Game Gear & Mega Drive / Genesis - changed Cheat menu icon - moved ROM device selection (SD,USB,DVD) to menu options - moved savestate compression/decompression out of emulator core - removed useless background images & background color option - prevented deletion of cheat files when no valid codes are found left - added IOS patch on startup to fix Homebrew Channel network bug when <no_ios_reload> option is used [GUI] -
@ -199,44 +199,39 @@ void md_cart_init(void)
|
||||
CARTRIDGE ROM MIRRORING
|
||||
***************************************************************************************************************
|
||||
|
||||
Cartridge area is mapped to $000000-$3fffff:
|
||||
MD Cartridge area is mapped to $000000-$3fffff:
|
||||
|
||||
-> when accessing ROM, 68k address lines A1 to A21 are used by the internal cartridge hardware to decode the
|
||||
-> when accessing ROM, 68k address lines A1 to A21 can be used by the internal cartridge hardware to decode
|
||||
full 4MB address range.
|
||||
-> depending on the ROM total size, some address lines might be ignored, resulting in ROM mirroring.
|
||||
|
||||
-> depending on ROM total size and additional decoding hardware, some address lines might be ignored,
|
||||
resulting in ROM mirroring.
|
||||
|
||||
Cartridges can use either 8-bits (x2) or 16-bits (x1, x2) Mask ROM chips, each chip size is a factor of 2 bytes:
|
||||
|
||||
-> two 8-bits chips are equivalent to one 16-bits chip, no specific address decoding is required, needed
|
||||
address lines are simply connected to each chip, upper address lines are ignored and data lines are
|
||||
connected appropriately to each chip (D0-D7 to one chip, D8-D15 to the other one).
|
||||
ROM is mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1+ROM2,ROM1+ROM2,...).
|
||||
ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1+ROM2,ROM1+ROM2,...)
|
||||
|
||||
-> one single 16-bits chip do not need specific address decoding, address lines are simply connected
|
||||
depending on the ROM size, upper address lines being ignored.
|
||||
ROM is mirrored each N bytes where N=2^k is the size of the ROM chip (ROM1,ROM1,ROM1,...).
|
||||
ROM is generally mirrored each N bytes where N=2^k is the size of the ROM chip (ROM1,ROM1,ROM1,...)
|
||||
|
||||
-> two 16-bits chips of the same size are equivalent to one chip of double size, address decoding generally
|
||||
is the same except that specific hardware is used (one address line is generally used for chip selection,
|
||||
lower ones being used to address the chips and upper ones being ignored).
|
||||
ROM is mirrored continuously each N bytes where N=2^(k+1) is the total ROM size (ROM1,ROM2,ROM1,ROM2,...).
|
||||
ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1,ROM2,ROM1,ROM2,...)
|
||||
|
||||
-> two 16-bits chips with different size are mapped differently. Address decoding is done the same way as
|
||||
above (one address line used for chip selection) but the ignored & required address lines differ from
|
||||
one chip to another, which makes ROM mirroring different.
|
||||
ROM2 size is generally half of ROM1 size and ROM are mirrored like that : ROM1,ROM2,ROM2,ROM1,ROM2,ROM2,...
|
||||
ROM2 size is generally half of ROM1 size and upper half ignored (ROM1,ROM2,XXXX,ROM1,ROM2,XXXX,...)
|
||||
|
||||
From the emulator point of view, we only need to distinguish 3 cases:
|
||||
From the emulator point of view, we only need to distinguish 2 cases:
|
||||
|
||||
1/ total ROM size is a factor of 2: ROM is mirrored each 2^k bytes.
|
||||
|
||||
2/ total ROM size is not a factor of 2 and cartridge uses one or two chips of the same size (Type A):
|
||||
ROM is padded up to 2^k and mirrored each 2^k bytes.
|
||||
|
||||
3/ total ROM size is not a factor of 2 and cartridge uses two chips of different sizes (Type B):
|
||||
ROM is not padded and the first 2^(k-1) bytes are mirrored each 2^k bytes while the next 2^(k-2) bytes are
|
||||
mirrored in the last 2^(k-2) bytes.
|
||||
2/ total ROM size is not a factor of 2: ROM is padded up to 2^k then mirrored each 2^k bytes.
|
||||
|
||||
******************************************************************************************************************/
|
||||
|
||||
@ -246,21 +241,12 @@ void md_cart_init(void)
|
||||
size <<= 1;
|
||||
|
||||
/* total ROM size is not a factor of 2 */
|
||||
/* TODO: handle more possible ROM configurations (using cartridge database ???) */
|
||||
/* TODO: handle all possible ROM configurations using cartridge database */
|
||||
if ((size < MAXROMSIZE) && (cart.romsize < size))
|
||||
{
|
||||
/* two chips with different size */
|
||||
if (config.romtype)
|
||||
{
|
||||
/* third ROM section is mirrored in the last section */
|
||||
memcpy(cart.rom + cart.romsize, cart.rom + 2*cart.romsize - size, size - cart.romsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ROM is padded up to 2^k bytes */
|
||||
memset(cart.rom + cart.romsize, 0xff, size - cart.romsize);
|
||||
}
|
||||
}
|
||||
|
||||
/* special case: Sonic & Knuckles */
|
||||
/* $200000-$3fffff is mapped to external cartridge */
|
||||
@ -521,38 +507,34 @@ void md_cart_init(void)
|
||||
|
||||
case TYPE_SK:
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
/* store S&K ROM above cartridge ROM + SRAM */
|
||||
if (cart.romsize > 0x600000) break;
|
||||
|
||||
/* load Sonic & Knuckles ROM (2 MBytes) */
|
||||
FILE *f = fopen(SK_ROM,"r+b");
|
||||
f = fopen(SK_ROM,"r+b");
|
||||
if (!f) break;
|
||||
int done = 0;
|
||||
while (done < 0x200000)
|
||||
for (i=0; i<0x200000; i+=0x1000)
|
||||
{
|
||||
fread(cart.rom + 0x600000 + done, 2048, 1, f);
|
||||
done += 2048;
|
||||
fread(cart.rom + 0x600000 + i, 0x1000, 1, f);
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
/* load Sonic 2 UPMEM ROM (256 KBytes) */
|
||||
f = fopen(SK_UPMEM,"r+b");
|
||||
if (!f) break;
|
||||
done = 0;
|
||||
while (done < 0x40000)
|
||||
for (i=0; i<0x40000; i+=0x1000)
|
||||
{
|
||||
fread(cart.rom + 0x800000 + done, 2048, 1, f);
|
||||
done += 2048;
|
||||
fread(cart.rom + 0x800000 + i, 0x1000, 1, f);
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* Byteswap ROM */
|
||||
int i;
|
||||
uint8 temp;
|
||||
for (i=0; i<0x240000; i+=2)
|
||||
{
|
||||
temp = cart.rom[i + 0x600000];
|
||||
/* Byteswap ROM */
|
||||
uint8 temp = cart.rom[i + 0x600000];
|
||||
cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1];
|
||||
cart.rom[i + 0x600000 + 1] = temp;
|
||||
}
|
||||
@ -561,7 +543,7 @@ void md_cart_init(void)
|
||||
/* $000000-$1FFFFF is mapped to S&K ROM */
|
||||
for (i=0x00; i<0x20; i++)
|
||||
{
|
||||
m68k_memory_map[i].base = (cart.rom + 0x600000) + (i<<16);
|
||||
m68k_memory_map[i].base = cart.rom + 0x600000 + (i << 16);
|
||||
}
|
||||
|
||||
cart.special |= HW_LOCK_ON;
|
||||
@ -586,11 +568,12 @@ void md_cart_init(void)
|
||||
if ((rominfo.checksum == rom_database[i].chk_1) &&
|
||||
(rominfo.realchecksum == rom_database[i].chk_2))
|
||||
{
|
||||
int j = rom_database[i].bank_start;
|
||||
|
||||
/* retrieve hardware information */
|
||||
memcpy(&cart.hw, &(rom_database[i].cart_hw), sizeof(T_CART_HW));
|
||||
|
||||
/* initialize memory handlers for $400000-$7FFFFF region */
|
||||
int j = rom_database[i].bank_start;
|
||||
while (j <= rom_database[i].bank_end)
|
||||
{
|
||||
if (cart.hw.regs_r)
|
||||
@ -739,9 +722,6 @@ void md_cart_reset(int hard_reset)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* save default cartridge slot mapping */
|
||||
cart.base = m68k_memory_map[0].base;
|
||||
}
|
||||
|
||||
int md_cart_context_save(uint8 *state)
|
||||
@ -880,17 +860,17 @@ static void mapper_sega_w(uint32 data)
|
||||
static void mapper_ssf2_w(uint32 address, uint32 data)
|
||||
{
|
||||
/* 8 x 512k banks */
|
||||
uint32 dst = (address << 2) & 0x38;
|
||||
address = (address << 2) & 0x38;
|
||||
|
||||
/* bank 0 remains unchanged */
|
||||
if (dst)
|
||||
if (address)
|
||||
{
|
||||
uint32 i;
|
||||
uint8 *src = cart.rom + (data << 19);
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
m68k_memory_map[dst++].base = src + (i<<16);
|
||||
m68k_memory_map[address++].base = src + (i<<16);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -946,17 +926,19 @@ static void mapper_realtec_w(uint32 address, uint32 data)
|
||||
/* 00000yy1 */
|
||||
cart.hw.regs[1] = data & 6;
|
||||
|
||||
/* mapped start address is 00yy xxx0 0000 0000 0000 0000 */
|
||||
uint32 base = (cart.hw.regs[0] << 1) | (cart.hw.regs[1] << 3);
|
||||
|
||||
/* ensure mapped size is not null */
|
||||
if (cart.hw.regs[2])
|
||||
{
|
||||
/* mapped start address is 00yy xxx0 0000 0000 0000 0000 */
|
||||
uint32 base = (cart.hw.regs[0] << 1) | (cart.hw.regs[1] << 3);
|
||||
|
||||
/* selected blocks are mirrored into the whole cartridge area */
|
||||
int i;
|
||||
for (i=0x00; i<0x40; i++)
|
||||
{
|
||||
m68k_memory_map[i].base = &cart.rom[(base + (i % cart.hw.regs[2])) << 16];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1144,6 +1126,8 @@ static void default_regs_w(uint32 address, uint32 data)
|
||||
/* custom register hardware (Top Fighter, Lion King III, Super Donkey Kong 99, Mulan, Pocket Monsters II, Pokemon Stadium) */
|
||||
static void custom_regs_w(uint32 address, uint32 data)
|
||||
{
|
||||
uint8 temp;
|
||||
|
||||
/* ROM bankswitch */
|
||||
if ((address >> 16) > 0x6f)
|
||||
{
|
||||
@ -1155,7 +1139,7 @@ static void custom_regs_w(uint32 address, uint32 data)
|
||||
default_regs_w(address, data);
|
||||
|
||||
/* bitswapping */
|
||||
uint32 temp = cart.hw.regs[0];
|
||||
temp = cart.hw.regs[0];
|
||||
switch (cart.hw.regs[1] & 3)
|
||||
{
|
||||
case 0:
|
||||
|
@ -42,8 +42,8 @@
|
||||
#include "cheats.h"
|
||||
#endif
|
||||
|
||||
#define MAPPER_TEREBI (0)
|
||||
#define MAPPER_NONE (1)
|
||||
#define MAPPER_NONE (0)
|
||||
#define MAPPER_TEREBI (1)
|
||||
#define MAPPER_SEGA (2)
|
||||
#define MAPPER_SEGA_X (3)
|
||||
#define MAPPER_CODIES (4)
|
||||
@ -64,11 +64,12 @@ typedef struct
|
||||
uint8 region;
|
||||
} rominfo_t;
|
||||
|
||||
static struct
|
||||
typedef struct
|
||||
{
|
||||
uint8 fcr[4];
|
||||
uint8 mapper;
|
||||
} slot;
|
||||
uint8 pages;
|
||||
} romhw_t;
|
||||
|
||||
static const rominfo_t game_list[GAME_DATABASE_CNT] =
|
||||
{
|
||||
@ -82,19 +83,19 @@ static const rominfo_t game_list[GAME_DATABASE_CNT] =
|
||||
{0x23BAC434, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA_X, SYSTEM_GG, REGION_USA}, /* Shining Force Gaiden - Final Conflict (JP) [T-Eng] */
|
||||
|
||||
/* games using Korean mappers */
|
||||
{0x17AB6883, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* FA Tetris (KR) */
|
||||
{0x61E8806F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Flash Point (KR) */
|
||||
{0x445525E2, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Penguin Adventure (KR) */
|
||||
{0x83F0EEDE, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Street Master (KR) */
|
||||
{0xA05258F5, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Won-Si-In (KR) */
|
||||
{0x06965ED9, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* F-1 Spirit - The way to Formula-1 (KR) */
|
||||
{0x77EFE84A, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Cyborg Z (KR) */
|
||||
{0xF89AF3CC, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Knightmare II - The Maze of Galious (KR) */
|
||||
{0x9195C34C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Super Boy 3 (KR) */
|
||||
{0x89B79E77, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Dodgeball King (KR) */
|
||||
{0x18FB98A3, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Jang Pung 3 (KR) */
|
||||
{0x97D03541, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Sangokushi 3 (KR) */
|
||||
{0x67C2F0FF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Super Boy 2 (KR) */
|
||||
{0x17AB6883, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* FA Tetris (KR) */
|
||||
{0x61E8806F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Flash Point (KR) */
|
||||
{0x445525E2, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Penguin Adventure (KR) */
|
||||
{0x83F0EEDE, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Street Master (KR) */
|
||||
{0xA05258F5, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Won-Si-In (KR) */
|
||||
{0x06965ED9, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* F-1 Spirit - The way to Formula-1 (KR) */
|
||||
{0x77EFE84A, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Cyborg Z (KR) */
|
||||
{0xF89AF3CC, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Knightmare II - The Maze of Galious (KR) */
|
||||
{0x9195C34C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Boy 3 (KR) */
|
||||
{0x89B79E77, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Dodgeball King (KR) */
|
||||
{0x18FB98A3, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Jang Pung 3 (KR) */
|
||||
{0x97D03541, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Sangokushi 3 (KR) */
|
||||
{0x67C2F0FF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Boy 2 (KR) */
|
||||
|
||||
/* games using Codemaster mapper */
|
||||
{0x29822980, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_SMS2, REGION_EUROPE}, /* Cosmic Spacehead */
|
||||
@ -124,10 +125,11 @@ static const rominfo_t game_list[GAME_DATABASE_CNT] =
|
||||
|
||||
/* games requiring JAPANESE region setting */
|
||||
{0x71DEBA5A, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GG, REGION_JAPAN_NTSC}, /* Pop Breaker */
|
||||
{0xC9DD4E5F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Woody Pop (Super Arkanoid) */
|
||||
{0xC9DD4E5F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Woody Pop (Super Arkanoid) */
|
||||
|
||||
/* games requiring Mark-III hardware (no Memory Control port) */
|
||||
{0xBD1CC7DF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_MARKIII, REGION_USA}, /* Super Tetris (K) */
|
||||
{0xBD1CC7DF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_MARKIII, REGION_JAPAN_NTSC}, /* Super Tetris (K) */
|
||||
{0x6D309AC5, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_MARKIII, REGION_JAPAN_NTSC}, /* Power Boggle Boggle (K) */
|
||||
|
||||
/* games requiring PAL timings */
|
||||
{0x72420F38, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Addams Familly */
|
||||
@ -163,7 +165,6 @@ static const rominfo_t game_list[GAME_DATABASE_CNT] =
|
||||
{0x45F058D6, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Prince of Persia [B][SMS-GG] */
|
||||
{0x56201996, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* R.C. Grand Prix [SMS-GG] */
|
||||
{0x10DBBEF4, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Super Kick Off [SMS-GG] */
|
||||
{0xBD1CC7DF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Super Tetris (KR) [SMS-GG] */
|
||||
{0x9942B69B, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Castle of Illusion - Starring Mickey Mouse (J) [SMS-GG] */
|
||||
{0x7BB81E3D, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Taito Chase H.Q (J) [SMS-GG] */
|
||||
{0x6F8E46CF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Alex Kidd in Miracle World (TW) [SMS-GG] */
|
||||
@ -179,8 +180,8 @@ static const rominfo_t game_list[GAME_DATABASE_CNT] =
|
||||
{0xA3EF13CB, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Zaxxon 3-D */
|
||||
{0xBBA74147, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Zaxxon 3-D [Proto] */
|
||||
{0xD6F43DDA, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Out Run 3-D */
|
||||
{0x871562b0, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Maze Walker */
|
||||
{0x156948f9, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Space Harrier 3-D (J) */
|
||||
{0x871562b0, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Maze Walker */
|
||||
{0x156948f9, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Space Harrier 3-D (J) */
|
||||
|
||||
/* games requiring 3-D Glasses & Sega Light Phaser */
|
||||
{0xFBE5CFBB, 1, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Missile Defense 3D */
|
||||
@ -203,10 +204,10 @@ static const rominfo_t game_list[GAME_DATABASE_CNT] =
|
||||
{0x0CA95637, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Laser Ghost */
|
||||
|
||||
/* games requiring Sega Paddle */
|
||||
{0xF9DBB533, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Alex Kidd BMX Trial */
|
||||
{0xA6FA42D0, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Galactic Protector */
|
||||
{0x29BC7FAD, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Megumi Rescue */
|
||||
{0x315917D4, 0, 0, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Woody Pop */
|
||||
{0xF9DBB533, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Alex Kidd BMX Trial */
|
||||
{0xA6FA42D0, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Galactic Protector */
|
||||
{0x29BC7FAD, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Megumi Rescue */
|
||||
{0x315917D4, 0, 0, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Woody Pop */
|
||||
|
||||
/* games requiring Sega Sport Pad */
|
||||
{0x0CB7E21F, 0, 0, SYSTEM_SPORTSPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Great Ice Hockey */
|
||||
@ -264,39 +265,50 @@ static const rominfo_t game_list[GAME_DATABASE_CNT] =
|
||||
{0x679E1676, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Wonder Boy III: The Dragon's Trap */
|
||||
{0x8CBEF0C1, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Wonder Boy in Monster Land */
|
||||
{0x2F2E3BC9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Zillion II - The Tri Formation */
|
||||
{0x48D44A13, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Master System Bios (J) */
|
||||
{0xD8C4165B, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Aleste */
|
||||
{0x4CC11DF9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Alien Syndrome (J) */
|
||||
{0xE421E466, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Chouon Senshi Borgman */
|
||||
{0x2BCDB8FA, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Doki Doki Penguin Land - Uchuu-Daibouken */
|
||||
{0x56BD2455, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Doki Doki Penguin Land - Uchuu-Daibouken [Proto] */
|
||||
{0xC722FB42, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Fantasy Zone II (J) */
|
||||
{0x7ABC70E9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Family Games (Party Games) */
|
||||
{0x6586BD1F, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Masters Golf */
|
||||
{0x4847BC91, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Masters Golf [Proto] */
|
||||
{0xB9FDF6D9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Haja no Fuuin */
|
||||
{0x955A009E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Hoshi wo Sagashite */
|
||||
{0x05EA5353, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Kenseiden (J) */
|
||||
{0xD11D32E4, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Kujakuou */
|
||||
{0xAA7D6F45, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Lord of Sword */
|
||||
{0xBF0411AD, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Maou Golvellius */
|
||||
{0x21A21352, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Maou Golvellius [Proto] */
|
||||
{0x5B5F9106, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Nekyuu Kousien */
|
||||
{0xBEA27D5C, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Opa Opa */
|
||||
{0x6605D36A, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Phantasy Star (J) */
|
||||
{0xE1FFF1BB, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Shinobi (J) */
|
||||
{0x11645549, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Solomon no Kagi - Oujo Rihita no Namida */
|
||||
{0x7E0EF8CB, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Super Racing */
|
||||
{0xB1DA6A30, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Super Wonder Boy Monster World */
|
||||
{0x8132AB2C, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Tensai Bakabon */
|
||||
{0xC0CE19B1, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_JAPAN_NTSC}, /* Thunder Blade (J) */
|
||||
{0x48D44A13, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* BIOS (J) */
|
||||
{0xD8C4165B, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Aleste */
|
||||
{0x4CC11DF9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Alien Syndrome (J) */
|
||||
{0xE421E466, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Chouon Senshi Borgman */
|
||||
{0x2BCDB8FA, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Doki Doki Penguin Land - Uchuu-Daibouken */
|
||||
{0x56BD2455, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Doki Doki Penguin Land - Uchuu-Daibouken [Proto] */
|
||||
{0xC722FB42, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Fantasy Zone II (J) */
|
||||
{0x7ABC70E9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Family Games (Party Games) */
|
||||
{0x6586BD1F, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Masters Golf */
|
||||
{0x4847BC91, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Masters Golf [Proto] */
|
||||
{0xB9FDF6D9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Haja no Fuuin */
|
||||
{0x955A009E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Hoshi wo Sagashite */
|
||||
{0x05EA5353, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Kenseiden (J) */
|
||||
{0xD11D32E4, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Kujakuou */
|
||||
{0xAA7D6F45, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Lord of Sword */
|
||||
{0xBF0411AD, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Maou Golvellius */
|
||||
{0x21A21352, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Maou Golvellius [Proto] */
|
||||
{0x5B5F9106, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Nekyuu Kousien */
|
||||
{0xBEA27D5C, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Opa Opa */
|
||||
{0x6605D36A, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Phantasy Star (J) */
|
||||
{0xE1FFF1BB, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Shinobi (J) */
|
||||
{0x11645549, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Solomon no Kagi - Oujo Rihita no Namida */
|
||||
{0x7E0EF8CB, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Racing */
|
||||
{0xB1DA6A30, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Wonder Boy Monster World */
|
||||
{0x8132AB2C, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Tensai Bakabon */
|
||||
{0xC0CE19B1, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Thunder Blade (J) */
|
||||
{0x07301F83, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_PBC, REGION_JAPAN_NTSC} /* Phantasy Star [Megadrive] (J) */
|
||||
};
|
||||
|
||||
/* 1K trash buffer */
|
||||
static uint8 dummy[0x400];
|
||||
/* Cartridge & BIOS ROM hardware */
|
||||
static romhw_t cart_rom;
|
||||
static romhw_t bios_rom;
|
||||
|
||||
/* Current slot */
|
||||
static struct
|
||||
{
|
||||
uint8 *rom;
|
||||
uint8 *fcr;
|
||||
uint8 mapper;
|
||||
uint8 pages;
|
||||
} slot;
|
||||
|
||||
/* Function prototypes */
|
||||
static void mapper_reset(void);
|
||||
static void mapper_8k_w(int offset, unsigned int data);
|
||||
static void mapper_16k_w(int offset, unsigned int data);
|
||||
static void write_mapper_none(unsigned int address, unsigned char data);
|
||||
@ -312,32 +324,45 @@ static unsigned char read_mapper_default(unsigned int address);
|
||||
|
||||
void sms_cart_init(void)
|
||||
{
|
||||
/* default mapper */
|
||||
slot.mapper = (cart.romsize > 0xC000) ? MAPPER_SEGA : MAPPER_NONE;
|
||||
int i;
|
||||
|
||||
/* game CRC */
|
||||
uint32 crc = crc32(0, cart.rom, cart.romsize);
|
||||
|
||||
/* use Master System controller by default */
|
||||
uint8 device = SYSTEM_MS_GAMEPAD;
|
||||
|
||||
/* unmapped memory return $FF on read (mapped to unused cartridge areas $510000-$5103FF & $510400-$5107FF) */
|
||||
memset(cart.rom + 0x510000, 0xFF, 0x800);
|
||||
|
||||
/* default cartridge ROM mapper */
|
||||
cart_rom.mapper = (cart.romsize > 0xC000) ? MAPPER_SEGA : MAPPER_NONE;
|
||||
|
||||
/* disable 3-D Glasses by default */
|
||||
cart.special = 0;
|
||||
|
||||
/* disable YM2413 chip disabled by default in AUTO mode */
|
||||
/* YM2413 chip in AUTO mode */
|
||||
if (config.ym2413 & 2)
|
||||
{
|
||||
if ((system_hw & SYSTEM_SMS) && (region_code == REGION_JAPAN_NTSC))
|
||||
{
|
||||
/* japanese Master System has built-in FM chip */
|
||||
config.ym2413 = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* by default, FM chip is disabled */
|
||||
config.ym2413 = 2;
|
||||
}
|
||||
|
||||
/* compute CRC */
|
||||
uint32 crc = crc32(0, cart.rom, cart.romsize);
|
||||
}
|
||||
|
||||
/* auto-detect game settings */
|
||||
int i;
|
||||
for (i=0; i<GAME_DATABASE_CNT; i++)
|
||||
{
|
||||
if (crc == game_list[i].crc)
|
||||
{
|
||||
/* auto-detect cartridge mapper */
|
||||
slot.mapper = game_list[i].mapper;
|
||||
cart_rom.mapper = game_list[i].mapper;
|
||||
|
||||
/* auto-detect required peripherals */
|
||||
device = game_list[i].peripheral;
|
||||
@ -362,45 +387,33 @@ void sms_cart_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize Z80 memory handlers */
|
||||
switch(slot.mapper)
|
||||
/* ROM paging */
|
||||
if (cart_rom.mapper == MAPPER_NONE)
|
||||
{
|
||||
case MAPPER_NONE:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_none;
|
||||
break;
|
||||
/* 1k ROM banks */
|
||||
cart_rom.pages = cart.romsize >> 10;
|
||||
}
|
||||
else if (cart_rom.mapper == MAPPER_MSX)
|
||||
{
|
||||
/* 8k ROM banks */
|
||||
cart_rom.pages = cart.romsize >> 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 16k ROM banks */
|
||||
cart_rom.pages = cart.romsize >> 14;
|
||||
}
|
||||
|
||||
case MAPPER_CODIES:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_codies;
|
||||
break;
|
||||
|
||||
case MAPPER_KOREA:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_korea;
|
||||
break;
|
||||
|
||||
case MAPPER_MSX:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_msx;
|
||||
break;
|
||||
|
||||
case MAPPER_93C46:
|
||||
/* initialize extra hardware */
|
||||
if (cart_rom.mapper == MAPPER_93C46)
|
||||
{
|
||||
/* 93C46 eeprom */
|
||||
gg_eeprom_init();
|
||||
z80_readmem = read_mapper_93c46;
|
||||
z80_writemem = write_mapper_93c46;
|
||||
break;
|
||||
|
||||
case MAPPER_TEREBI:
|
||||
}
|
||||
else if (cart_rom.mapper == MAPPER_TEREBI)
|
||||
{
|
||||
/* Terebi Oekaki tablet */
|
||||
cart.special |= HW_TEREBI_OEKAKI;
|
||||
z80_readmem = read_mapper_terebi;
|
||||
z80_writemem = write_mapper_terebi;
|
||||
break;
|
||||
|
||||
default:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_sega;
|
||||
break;
|
||||
}
|
||||
|
||||
/* initialize SRAM */
|
||||
@ -439,141 +452,277 @@ void sms_cart_init(void)
|
||||
{
|
||||
input.x_offset = 16;
|
||||
}
|
||||
|
||||
/* BIOS support */
|
||||
if (config.bios & 0x01)
|
||||
{
|
||||
/* verify that BIOS is not already loaded */
|
||||
if (!(config.bios & (system_hw & 0xF0)))
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
|
||||
/* reset BIOS size */
|
||||
int bios_size = 0;
|
||||
|
||||
/* mark both BIOS as unloaded */
|
||||
config.bios &= ~(SYSTEM_SMS | SYSTEM_GG);
|
||||
|
||||
/* open BIOS file */
|
||||
switch (system_hw)
|
||||
{
|
||||
case SYSTEM_GG:
|
||||
case SYSTEM_GGMS:
|
||||
fp = fopen(GG_BIOS, "rb");
|
||||
break;
|
||||
|
||||
case SYSTEM_SMS:
|
||||
case SYSTEM_SMS2:
|
||||
fp = fopen(MS_BIOS, "rb");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* try to load BIOS file */
|
||||
if (fp != NULL)
|
||||
{
|
||||
/* get file size */
|
||||
int size;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
/* BIOS ROM is stored above cartridge ROM area, into $400000-$4FFFFF (max. 1MB) */
|
||||
if ((size <= 0x100000) && (cart.romsize <= 0x400000))
|
||||
{
|
||||
/* BIOS ROM size */
|
||||
bios_size = size;
|
||||
|
||||
/* read bytes chunks */
|
||||
while (size > 2048)
|
||||
{
|
||||
fread(cart.rom + 0x400000 + bios_size - size, 2048, 1, fp);
|
||||
size -= 2048;
|
||||
}
|
||||
|
||||
/* read remaining bytes */
|
||||
fread(cart.rom + 0x400000 + bios_size - size, size, 1, fp);
|
||||
|
||||
/* mark BIOS ROM as loaded */
|
||||
config.bios |= (system_hw & 0xF0);
|
||||
}
|
||||
|
||||
/* close file */
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* BIOS ROM mapper */
|
||||
if (bios_size > 0xC000)
|
||||
{
|
||||
/* assume SEGA mapper if BIOS ROM is larger than 48k */
|
||||
bios_rom.mapper = MAPPER_SEGA;
|
||||
bios_rom.pages = bios_size >> 14;
|
||||
}
|
||||
else
|
||||
{
|
||||
bios_rom.mapper = MAPPER_NONE;
|
||||
bios_rom.pages = bios_size >> 10;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if BIOS has been correctly loaded */
|
||||
if (bios_rom.pages)
|
||||
{
|
||||
/* unload cartridge if required */
|
||||
if (!(config.bios & 2))
|
||||
{
|
||||
cart_rom.pages = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* BIOS support disabled */
|
||||
{
|
||||
/* unload BIOS */
|
||||
bios_rom.pages = 0;
|
||||
|
||||
/* mark both BIOS as unloaded */
|
||||
config.bios &= ~(SYSTEM_SMS | SYSTEM_GG);
|
||||
}
|
||||
}
|
||||
|
||||
void sms_cart_reset(void)
|
||||
{
|
||||
int i;
|
||||
/* reset BIOS ROM paging (SEGA mapper by default) */
|
||||
bios_rom.fcr[0] = 0;
|
||||
bios_rom.fcr[1] = 0;
|
||||
bios_rom.fcr[2] = 1;
|
||||
bios_rom.fcr[3] = 2;
|
||||
|
||||
/* Unmapped memory return $FF */
|
||||
memset(dummy, 0xFF, 0x400);
|
||||
|
||||
/* $0000-$7FFF mapped to Cartridge ROM (32K) */
|
||||
for(i = 0x00; i < 0x20; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[i << 10];
|
||||
z80_writemap[i] = dummy;
|
||||
}
|
||||
|
||||
/* $8000-$BFFF mapped to Cartridge ROM or RAM (16K) */
|
||||
if (cart.romsize > 0x8000)
|
||||
{
|
||||
for(i = 0x20; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[i << 10];
|
||||
z80_writemap[i] = dummy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0x20; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = z80_writemap[i] = &sram.sram[(i & 0x0F) << 10];
|
||||
}
|
||||
}
|
||||
|
||||
if (system_hw == SYSTEM_SG)
|
||||
{
|
||||
/* $C000-$FFFF mapped to internal RAM (2K mirrored) */
|
||||
for(i = 0x30; i < 0x40; i++)
|
||||
{
|
||||
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x01) << 10];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* $C000-$FFFF mapped to internal RAM (8K mirrored) */
|
||||
for(i = 0x30; i < 0x40; i++)
|
||||
{
|
||||
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10];
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset cartridge paging registers */
|
||||
switch(slot.mapper)
|
||||
/* reset cartridge ROM paging */
|
||||
switch (cart_rom.mapper)
|
||||
{
|
||||
case MAPPER_SEGA:
|
||||
case MAPPER_SEGA_X:
|
||||
{
|
||||
slot.fcr[0] = 0;
|
||||
slot.fcr[1] = 0;
|
||||
slot.fcr[2] = 1;
|
||||
slot.fcr[3] = 2;
|
||||
cart_rom.fcr[0] = 0;
|
||||
cart_rom.fcr[1] = 0;
|
||||
cart_rom.fcr[2] = 1;
|
||||
cart_rom.fcr[3] = 2;
|
||||
break;
|
||||
|
||||
case MAPPER_MSX:
|
||||
cart_rom.fcr[0] = 0;
|
||||
cart_rom.fcr[1] = 0;
|
||||
cart_rom.fcr[2] = 0;
|
||||
cart_rom.fcr[3] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
slot.fcr[0] = 0;
|
||||
slot.fcr[1] = 0;
|
||||
slot.fcr[2] = 1;
|
||||
slot.fcr[3] = 0;
|
||||
cart_rom.fcr[0] = 0;
|
||||
cart_rom.fcr[1] = 0;
|
||||
cart_rom.fcr[2] = 1;
|
||||
cart_rom.fcr[3] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set default memory map */
|
||||
if (slot.mapper == MAPPER_MSX)
|
||||
/* check if BIOS is larger than 1k */
|
||||
if (bios_rom.pages > 1)
|
||||
{
|
||||
mapper_8k_w(0,slot.fcr[0]);
|
||||
mapper_8k_w(1,slot.fcr[1]);
|
||||
mapper_8k_w(2,slot.fcr[2]);
|
||||
mapper_8k_w(3,slot.fcr[3]);
|
||||
/* enable BIOS ROM */
|
||||
slot.rom = cart.rom + 0x400000;
|
||||
slot.fcr = bios_rom.fcr;
|
||||
slot.mapper = bios_rom.mapper;
|
||||
slot.pages = bios_rom.pages;
|
||||
}
|
||||
else if (slot.mapper > MAPPER_NONE)
|
||||
else
|
||||
{
|
||||
mapper_16k_w(0,slot.fcr[0]);
|
||||
mapper_16k_w(1,slot.fcr[1]);
|
||||
mapper_16k_w(2,slot.fcr[2]);
|
||||
mapper_16k_w(3,slot.fcr[3]);
|
||||
/* enable cartridge ROM */
|
||||
slot.rom = cart.rom;
|
||||
slot.fcr = cart_rom.fcr;
|
||||
slot.mapper = cart_rom.mapper;
|
||||
slot.pages = cart_rom.pages;
|
||||
|
||||
/* force Memory Control register value in RAM (usually set by Master System BIOS) */
|
||||
if (system_hw & SYSTEM_SMS)
|
||||
{
|
||||
work_ram[0] = 0xA8;
|
||||
}
|
||||
}
|
||||
|
||||
void sms_cart_switch(int enabled)
|
||||
{
|
||||
int i;
|
||||
/* reset Memory Control register (RAM & I/O are enabled, either BIOS or Cartridge ROM are enabled) */
|
||||
io_reg[0x0E] = bios_rom.pages ? 0xE0 : 0xA8;
|
||||
|
||||
if (enabled)
|
||||
/* reset Z80 memory map */
|
||||
mapper_reset();
|
||||
|
||||
/* 1k BIOS special case (Majesco GG) */
|
||||
if (bios_rom.pages == 1)
|
||||
{
|
||||
/* Enable cartridge ROM at $0000-$BFFF */
|
||||
for(i = 0x00; i < 0x30; i++)
|
||||
/* BIOS ROM is mapped to $0000-$03FF */
|
||||
z80_readmap[0] = cart.rom + 0x400000;
|
||||
}
|
||||
}
|
||||
|
||||
void sms_cart_switch(uint8 mode)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(i & 0x1F) << 10];
|
||||
z80_writemap[i] = dummy;
|
||||
/* by default, disable cartridge & BIOS ROM */
|
||||
slot.pages = 0;
|
||||
|
||||
/* cartridge ROM enabled ? */
|
||||
if (mode & 0x40)
|
||||
{
|
||||
/* check if cartridge is loaded */
|
||||
if (cart_rom.pages)
|
||||
{
|
||||
/* map cartridge ROM */
|
||||
slot.rom = cart.rom;
|
||||
slot.fcr = cart_rom.fcr;
|
||||
slot.mapper = cart_rom.mapper;
|
||||
slot.pages = cart_rom.pages;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable cartridge ROM at $0000-$BFFF */
|
||||
for(i = 0x00; i < 0x30; i++)
|
||||
/* BIOS ROM enabled ? */
|
||||
if (mode & 0x08)
|
||||
{
|
||||
z80_readmap[i] = z80_writemap[i] = dummy;
|
||||
/* check if BIOS ROM is larger than 1K */
|
||||
if (bios_rom.pages > 1)
|
||||
{
|
||||
/* map BIOS ROM */
|
||||
slot.rom = cart.rom + 0x400000;
|
||||
slot.fcr = bios_rom.fcr;
|
||||
slot.mapper = bios_rom.mapper;
|
||||
slot.pages = bios_rom.pages;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* by default, map cartridge ROM */
|
||||
slot.rom = cart.rom;
|
||||
slot.fcr = cart_rom.fcr;
|
||||
slot.mapper = cart_rom.mapper;
|
||||
slot.pages = cart_rom.pages;
|
||||
}
|
||||
}
|
||||
|
||||
/* assume only BIOS would disable cartridge slot */
|
||||
if (!bios_rom.pages)
|
||||
{
|
||||
/* max. BIOS ROM size supported is 1MB */
|
||||
if (cart.romsize <= 0x100000)
|
||||
{
|
||||
/* copy to BIOS ROM */
|
||||
memcpy(cart.rom + 0x400000, cart.rom, cart.romsize);
|
||||
memcpy(bios_rom.fcr, cart_rom.fcr, 4);
|
||||
bios_rom.mapper = cart_rom.mapper;
|
||||
bios_rom.pages = cart_rom.pages;
|
||||
|
||||
/* unload cartridge */
|
||||
cart_rom.pages = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* reset Z80 memory map */
|
||||
mapper_reset();
|
||||
|
||||
/* 1k BIOS special case (Majesco GG) */
|
||||
if ((bios_rom.pages == 1) && ((mode & 0x48) == 0x08))
|
||||
{
|
||||
/* BIOS ROM is mapped to $0000-$03FF */
|
||||
z80_readmap[0] = cart.rom + 0x400000;
|
||||
}
|
||||
}
|
||||
|
||||
int sms_cart_region_detect(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* compute CRC */
|
||||
uint32 crc = crc32(0, cart.rom, cart.romsize);
|
||||
|
||||
/* detect game region */
|
||||
int i;
|
||||
for (i=0; i<GAME_DATABASE_CNT; i++)
|
||||
{
|
||||
if (crc == game_list[i].crc)
|
||||
{
|
||||
/* Turma da Mônica em: O Resgate & Wonder Boy III enable FM support on japanese hardware only */
|
||||
if (config.ym2413 && ((crc == 0x22CCA9BB) || (crc == 0x679E1676)))
|
||||
{
|
||||
return REGION_JAPAN_NTSC;
|
||||
}
|
||||
|
||||
/* game database */
|
||||
for (i=0; i<GAME_DATABASE_CNT; i++)
|
||||
{
|
||||
if (crc == game_list[i].crc)
|
||||
{
|
||||
return game_list[i].region;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark-III hardware */
|
||||
if (system_hw == SYSTEM_MARKIII)
|
||||
{
|
||||
/* Japan */
|
||||
return REGION_JAPAN_NTSC;
|
||||
}
|
||||
|
||||
/* default region */
|
||||
return REGION_USA;
|
||||
}
|
||||
@ -581,16 +730,94 @@ int sms_cart_region_detect(void)
|
||||
int sms_cart_context_save(uint8 *state)
|
||||
{
|
||||
int bufferptr = 0;
|
||||
save_param(slot.fcr, sizeof(slot.fcr));
|
||||
save_param(slot.fcr, 4);
|
||||
return bufferptr;
|
||||
}
|
||||
|
||||
int sms_cart_context_load(uint8 *state)
|
||||
{
|
||||
int bufferptr = 0;
|
||||
load_param(slot.fcr, sizeof(slot.fcr));
|
||||
load_param(slot.fcr, 4);
|
||||
return bufferptr;
|
||||
}
|
||||
|
||||
/* Set default memory map */
|
||||
static void mapper_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* reset internal RAM mapping */
|
||||
if (system_hw == SYSTEM_SG)
|
||||
{
|
||||
/* $C000-$FFFF mapped to 2k mirrored RAM */
|
||||
for (i = 0x30; i < 0x40; i++)
|
||||
{
|
||||
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x01) << 10];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* $C000-$FFFF mapped to 8k mirrored RAM */
|
||||
for (i = 0x30; i < 0x40; i++)
|
||||
{
|
||||
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10];
|
||||
}
|
||||
}
|
||||
|
||||
/* check if ROM is disabled */
|
||||
if (!slot.pages)
|
||||
{
|
||||
/* $0000-$BFFF mapped to unused cartridge areas */
|
||||
for(i = 0x00; i < 0x30; i++)
|
||||
{
|
||||
z80_writemap[i] = cart.rom + 0x510000;
|
||||
z80_readmap[i] = cart.rom + 0x510400;
|
||||
}
|
||||
|
||||
/* set default Z80 memory handlers */
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_none;
|
||||
return;
|
||||
}
|
||||
|
||||
/* $0000-$3FFF mapped to ROM (first 16k) by default */
|
||||
for (i = 0x00; i < 0x20; i++)
|
||||
{
|
||||
z80_readmap[i] = &slot.rom[i << 10];
|
||||
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
|
||||
}
|
||||
|
||||
/* reset default $4000-$BFFF mapping (32k) */
|
||||
if ((slot.mapper == MAPPER_NONE) || (slot.mapper == MAPPER_TEREBI))
|
||||
{
|
||||
/* $4000-$7FFF mapped to ROM (16k) */
|
||||
for (i = 0x00; i < 0x20; i++)
|
||||
{
|
||||
z80_readmap[i] = &slot.rom[i << 10];
|
||||
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
|
||||
}
|
||||
|
||||
/* enable 16k external RAM by default with 32k ROM (The Castle) */
|
||||
if (slot.pages > 0x20)
|
||||
{
|
||||
/* $8000-$BFFF mapped to ROM (16k) */
|
||||
for (i = 0x20; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = &slot.rom[i << 10];
|
||||
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* $8000-$BFFF mapped to external RAM (16k) */
|
||||
for (i = 0x20; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = z80_writemap[i] = &sram.sram[(i & 0x0F) << 10];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ROM paging */
|
||||
if (slot.mapper == MAPPER_MSX)
|
||||
{
|
||||
mapper_8k_w(0,slot.fcr[0]);
|
||||
@ -598,24 +825,61 @@ int sms_cart_context_load(uint8 *state)
|
||||
mapper_8k_w(2,slot.fcr[2]);
|
||||
mapper_8k_w(3,slot.fcr[3]);
|
||||
}
|
||||
else if (slot.mapper > MAPPER_NONE)
|
||||
else
|
||||
{
|
||||
mapper_16k_w(0,slot.fcr[0]);
|
||||
mapper_16k_w(1,slot.fcr[1]);
|
||||
mapper_16k_w(2,slot.fcr[2]);
|
||||
mapper_16k_w(3,slot.fcr[3]);
|
||||
}
|
||||
|
||||
return bufferptr;
|
||||
}
|
||||
|
||||
/* reset Z80 memory handlers */
|
||||
switch (slot.mapper)
|
||||
{
|
||||
case MAPPER_NONE:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_none;
|
||||
break;
|
||||
|
||||
void mapper_8k_w(int offset, unsigned int data)
|
||||
case MAPPER_CODIES:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_codies;
|
||||
break;
|
||||
|
||||
case MAPPER_KOREA:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_korea;
|
||||
break;
|
||||
|
||||
case MAPPER_MSX:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_msx;
|
||||
break;
|
||||
|
||||
case MAPPER_93C46:
|
||||
z80_readmem = read_mapper_93c46;
|
||||
z80_writemem = write_mapper_93c46;
|
||||
break;
|
||||
|
||||
case MAPPER_TEREBI:
|
||||
z80_readmem = read_mapper_terebi;
|
||||
z80_writemem = write_mapper_terebi;
|
||||
break;
|
||||
|
||||
default:
|
||||
z80_readmem = read_mapper_default;
|
||||
z80_writemem = write_mapper_sega;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mapper_8k_w(int offset, unsigned int data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* cartridge ROM page (8k) */
|
||||
uint8 page = data % (cart.romsize >> 13);
|
||||
uint8 page = data % slot.pages;
|
||||
|
||||
/* Save frame control register data */
|
||||
slot.fcr[offset] = data;
|
||||
@ -627,7 +891,7 @@ void mapper_8k_w(int offset, unsigned int data)
|
||||
{
|
||||
for (i = 0x20; i < 0x28; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -636,7 +900,7 @@ void mapper_8k_w(int offset, unsigned int data)
|
||||
{
|
||||
for (i = 0x28; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -645,7 +909,7 @@ void mapper_8k_w(int offset, unsigned int data)
|
||||
{
|
||||
for (i = 0x10; i < 0x18; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -654,7 +918,7 @@ void mapper_8k_w(int offset, unsigned int data)
|
||||
{
|
||||
for (i = 0x18; i < 0x20; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 13) | ((i & 0x07) << 10)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -666,17 +930,17 @@ void mapper_8k_w(int offset, unsigned int data)
|
||||
#endif
|
||||
}
|
||||
|
||||
void mapper_16k_w(int offset, unsigned int data)
|
||||
static void mapper_16k_w(int offset, unsigned int data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* cartridge ROM page (16k) */
|
||||
uint8 page = data % (cart.romsize >> 14);
|
||||
uint8 page = data % slot.pages;
|
||||
|
||||
/* page index increment (SEGA mapper) */
|
||||
/* page index increment (SEGA mapper only) */
|
||||
if ((slot.fcr[0] & 0x03) && (slot.mapper == MAPPER_SEGA))
|
||||
{
|
||||
page = (page + ((4 - (slot.fcr[0] & 0x03)) << 3)) % (cart.romsize >> 14);
|
||||
page = (page + ((4 - (slot.fcr[0] & 0x03)) << 3)) % slot.pages;
|
||||
}
|
||||
|
||||
/* save frame control register data */
|
||||
@ -684,7 +948,7 @@ void mapper_16k_w(int offset, unsigned int data)
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0: /* control register (SEGA mapper) */
|
||||
case 0: /* control register (SEGA mapper only) */
|
||||
{
|
||||
if (data & 0x08)
|
||||
{
|
||||
@ -697,19 +961,19 @@ void mapper_16k_w(int offset, unsigned int data)
|
||||
else
|
||||
{
|
||||
/* cartridge ROM page (16k) */
|
||||
page = slot.fcr[3] % (cart.romsize >> 14);
|
||||
page = slot.fcr[3] % slot.pages;
|
||||
|
||||
/* page index increment (SEGA mapper) */
|
||||
if ((data & 0x03) && (slot.mapper == MAPPER_SEGA))
|
||||
{
|
||||
page = (page + ((4 - (data & 0x03)) << 3)) % (cart.romsize >> 14);
|
||||
page = (page + ((4 - (data & 0x03)) << 3)) % slot.pages;
|
||||
}
|
||||
|
||||
/* cartridge ROM mapped at $8000-$BFFF */
|
||||
for (i = 0x20; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_writemap[i] = dummy;
|
||||
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,15 +998,15 @@ void mapper_16k_w(int offset, unsigned int data)
|
||||
|
||||
case 1: /* cartridge ROM bank (16k) at $0000-$3FFF */
|
||||
{
|
||||
/* first 1k is not fixed (CODEMASTER mapper) */
|
||||
/* first 1k is not fixed (CODEMASTER mapper only) */
|
||||
if (slot.mapper == MAPPER_CODIES)
|
||||
{
|
||||
z80_readmap[0] = &cart.rom[(page << 14)];
|
||||
z80_readmap[0] = &slot.rom[(page << 14)];
|
||||
}
|
||||
|
||||
for (i = 0x01; i < 0x10; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -751,10 +1015,10 @@ void mapper_16k_w(int offset, unsigned int data)
|
||||
{
|
||||
for (i = 0x10; i < 0x20; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
}
|
||||
|
||||
/* Ernie Elf's Golf external RAM switch */
|
||||
/* cartridge RAM switch (CODEMASTER mapper only, see Ernie Elf's Golf) */
|
||||
if (slot.mapper == MAPPER_CODIES)
|
||||
{
|
||||
if (data & 0x80)
|
||||
@ -768,13 +1032,13 @@ void mapper_16k_w(int offset, unsigned int data)
|
||||
else
|
||||
{
|
||||
/* cartridge ROM page (16k) */
|
||||
page = slot.fcr[3] % (cart.romsize >> 14);
|
||||
page = slot.fcr[3] % slot.pages;
|
||||
|
||||
/* cartridge ROM mapped at $A000-$BFFF */
|
||||
for (i = 0x28; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_writemap[i] = dummy;
|
||||
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -783,22 +1047,22 @@ void mapper_16k_w(int offset, unsigned int data)
|
||||
|
||||
case 3: /* cartridge ROM bank (16k) at $8000-$BFFF */
|
||||
{
|
||||
/* check that external RAM (16k) is not mapped at $8000-$BFFF (SEGA mapper) */
|
||||
/* check that external RAM (16k) is not mapped at $8000-$BFFF (SEGA mapper only) */
|
||||
if ((slot.fcr[0] & 0x08)) break;
|
||||
|
||||
/* first 8k */
|
||||
for (i = 0x20; i < 0x28; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
}
|
||||
|
||||
/* check that external RAM (8k) is not mapped at $A000-$BFFF (CODEMASTER mapper) */
|
||||
/* check that cartridge RAM (8k) is not mapped at $A000-$BFFF (CODEMASTER mapper only) */
|
||||
if ((slot.mapper == MAPPER_CODIES) && (slot.fcr[2] & 0x80)) break;
|
||||
|
||||
/* last 8k */
|
||||
for (i = 0x28; i < 0x30; i++)
|
||||
{
|
||||
z80_readmap[i] = &cart.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -39,13 +39,14 @@
|
||||
#ifndef _SMS_CART_H_
|
||||
#define _SMS_CART_H_
|
||||
|
||||
/* Special hardware (0x01 reserved for Master System 3-D glasses) */
|
||||
/* Special hardware */
|
||||
#define HW_3D_GLASSES 0x01
|
||||
#define HW_TEREBI_OEKAKI 0x02
|
||||
|
||||
/* Function prototypes */
|
||||
extern void sms_cart_init(void);
|
||||
extern void sms_cart_reset(void);
|
||||
extern void sms_cart_switch(int enabled);
|
||||
extern void sms_cart_switch(uint8 mode);
|
||||
extern int sms_cart_region_detect(void);
|
||||
extern int sms_cart_context_save(uint8 *state);
|
||||
extern int sms_cart_context_load(uint8 *state);
|
||||
|
@ -59,7 +59,7 @@ void sram_init()
|
||||
{
|
||||
memset (&sram, 0, sizeof (T_SRAM));
|
||||
|
||||
/* store SRAM into cartridge area */
|
||||
/* SRAM data is stored above cartridge ROM area, at $500000-$50FFFF (max. 64K) */
|
||||
if (cart.romsize > 0x500000) return;
|
||||
sram.sram = cart.rom + 0x500000;
|
||||
|
||||
@ -87,14 +87,15 @@ void sram_init()
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default SRAM region */
|
||||
/* by default, enable SRAM only for ROM <= 2MB */
|
||||
if (cart.romsize <= 0x200000)
|
||||
{
|
||||
/* SRAM mapped to $200000-$20ffff */
|
||||
sram.start = 0x200000;
|
||||
sram.end = 0x20ffff;
|
||||
|
||||
/* 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)
|
||||
|
@ -41,16 +41,15 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
uint8 tmss[4]; /* TMSS security register */
|
||||
uint8 bios_rom[0x800]; /* OS ROM */
|
||||
uint8 boot_rom[0x800]; /* Genesis BOOT ROM */
|
||||
uint8 work_ram[0x10000]; /* 68K RAM */
|
||||
uint8 zram[0x2000]; /* Z80 RAM */
|
||||
uint32 zbank; /* Z80 bank window address */
|
||||
uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
|
||||
uint8 pico_current; /* PICO current page */
|
||||
uint8 pico_page[7]; /* PICO page registers */
|
||||
|
||||
/* PICO data */
|
||||
uint8 pico_current;
|
||||
uint8 pico_page[7];
|
||||
static uint8 tmss[4]; /* TMSS security register */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown functions */
|
||||
@ -90,7 +89,7 @@ void gen_init(void)
|
||||
m68k_memory_map[i].read16 = NULL;
|
||||
m68k_memory_map[i].write8 = NULL;
|
||||
m68k_memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].read = zbank_unused_r;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
@ -153,13 +152,13 @@ void gen_init(void)
|
||||
|
||||
/* page registers */
|
||||
pico_current = 0x00;
|
||||
pico_page[0] = 0x00;
|
||||
pico_page[1] = 0x01;
|
||||
pico_page[2] = 0x03;
|
||||
pico_page[3] = 0x07;
|
||||
pico_page[4] = 0x0F;
|
||||
pico_page[5] = 0x1F;
|
||||
pico_page[6] = 0x3F;
|
||||
pico_regs[0] = 0x00;
|
||||
pico_regs[1] = 0x01;
|
||||
pico_regs[2] = 0x03;
|
||||
pico_regs[3] = 0x07;
|
||||
pico_regs[4] = 0x0F;
|
||||
pico_regs[5] = 0x1F;
|
||||
pico_regs[6] = 0x3F;
|
||||
|
||||
/* initialize cartridge hardware */
|
||||
md_cart_init();
|
||||
@ -219,7 +218,7 @@ void gen_reset(int hard_reset)
|
||||
/* System Reset */
|
||||
if (hard_reset)
|
||||
{
|
||||
/* clear RAM */
|
||||
/* clear RAM (TODO: use random bit patterns as on real hardware) */
|
||||
memset(work_ram, 0x00, sizeof (work_ram));
|
||||
memset(zram, 0x00, sizeof (zram));
|
||||
}
|
||||
@ -232,9 +231,10 @@ void gen_reset(int hard_reset)
|
||||
/* 68k & Z80 could restart anywhere in VDP frame (Bonkers, Eternal Champions, X-Men 2) */
|
||||
mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX));
|
||||
|
||||
/* Genesis / Master System modes */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
/* reset cartridge hardware */
|
||||
/* reset cartridge hardware & mapping */
|
||||
md_cart_reset(hard_reset);
|
||||
|
||||
/* Z80 bus is released & Z80 is reseted */
|
||||
@ -247,17 +247,18 @@ void gen_reset(int hard_reset)
|
||||
/* assume default bank is $000000-$007FFF */
|
||||
zbank = 0;
|
||||
|
||||
/* TMSS & OS ROM support */
|
||||
if (config.tmss & 1)
|
||||
/* TMSS support */
|
||||
if ((config.bios & 1) && (system_hw != SYSTEM_PICO))
|
||||
{
|
||||
/* on HW reset only */
|
||||
if (hard_reset)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* clear TMSS register */
|
||||
memset(tmss, 0x00, sizeof(tmss));
|
||||
|
||||
/* VDP access is locked by default */
|
||||
int i;
|
||||
for (i=0xc0; i<0xe0; i+=8)
|
||||
{
|
||||
m68k_memory_map[i].read8 = m68k_lockup_r_8;
|
||||
@ -268,10 +269,14 @@ void gen_reset(int hard_reset)
|
||||
zbank_memory_map[i].write = zbank_lockup_w;
|
||||
}
|
||||
|
||||
/* OS ROM is mapped at $000000-$0007FF */
|
||||
if (config.tmss & 2)
|
||||
/* check if BOOT ROM is loaded */
|
||||
if (config.bios & SYSTEM_MD)
|
||||
{
|
||||
m68k_memory_map[0].base = bios_rom;
|
||||
/* save default cartridge slot mapping */
|
||||
cart.base = m68k_memory_map[0].base;
|
||||
|
||||
/* BOOT ROM is mapped at $000000-$0007FF */
|
||||
m68k_memory_map[0].base = boot_rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -281,16 +286,13 @@ void gen_reset(int hard_reset)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Z80 cycles should a multiple of 15 to avoid rounding errors */
|
||||
/* Z80 cycles should be a multiple of 15 to avoid rounding errors */
|
||||
mcycles_z80 = (mcycles_z80 / 15) * 15;
|
||||
|
||||
/* reset cartridge hardware */
|
||||
sms_cart_reset();
|
||||
|
||||
/* Z80 is running */
|
||||
zstate = 1;
|
||||
|
||||
/* 68k is halted (/VRES is forced low) */
|
||||
/* halt 68k (/VRES is forced low) */
|
||||
m68k_pulse_halt();
|
||||
}
|
||||
|
||||
@ -310,11 +312,12 @@ void gen_shutdown(void)
|
||||
|
||||
void gen_tmss_w(unsigned int offset, unsigned int data)
|
||||
{
|
||||
/* write TMSS regisiter */
|
||||
int i;
|
||||
|
||||
/* write TMSS register */
|
||||
WRITE_WORD(tmss, offset, data);
|
||||
|
||||
/* VDP requires "SEGA" value to be written in TMSS register */
|
||||
int i;
|
||||
if (strncmp((char *)tmss, "SEGA", 4) == 0)
|
||||
{
|
||||
for (i=0xc0; i<0xe0; i+=8)
|
||||
@ -343,23 +346,15 @@ void gen_tmss_w(unsigned int offset, unsigned int data)
|
||||
|
||||
void gen_bankswitch_w(unsigned int data)
|
||||
{
|
||||
/* OS ROM has not been loaded yet */
|
||||
if (!(config.tmss & 2))
|
||||
{
|
||||
config.tmss |= 2;
|
||||
memcpy(bios_rom, cart.rom, 0x800);
|
||||
memset(cart.rom, 0xff, cart.romsize);
|
||||
}
|
||||
|
||||
if (data & 1)
|
||||
{
|
||||
/* enable CART */
|
||||
/* enable cartridge ROM */
|
||||
m68k_memory_map[0].base = cart.base;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* enable internal BIOS ROM */
|
||||
m68k_memory_map[0].base = bios_rom;
|
||||
/* enable internal BOOT ROM */
|
||||
m68k_memory_map[0].base = boot_rom;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,7 @@
|
||||
#define _GENESIS_H_
|
||||
|
||||
/* Global variables */
|
||||
extern uint8 tmss[4];
|
||||
extern uint8 bios_rom[0x800];
|
||||
extern uint8 boot_rom[0x800];
|
||||
extern uint8 work_ram[0x10000];
|
||||
extern uint8 zram[0x2000];
|
||||
extern uint32 zbank;
|
||||
|
@ -109,9 +109,8 @@ void config_default(void)
|
||||
config.region_detect = 0; /* AUTO */
|
||||
config.force_dtack = 0;
|
||||
config.addr_error = 1;
|
||||
config.tmss = 0;
|
||||
config.bios = 0;
|
||||
config.lock_on = 0;
|
||||
config.romtype = 0;
|
||||
config.hot_swap = 0;
|
||||
|
||||
/* video options */
|
||||
@ -154,29 +153,44 @@ void config_default(void)
|
||||
#endif
|
||||
config.s_default = 1;
|
||||
config.s_device = 0;
|
||||
config.bg_type = 0;
|
||||
config.bg_overlay = 1;
|
||||
config.l_device = 0;
|
||||
config.bg_overlay = 0;
|
||||
config.screen_w = 658;
|
||||
config.bgm_volume = 100.0;
|
||||
config.sfx_volume = 100.0;
|
||||
|
||||
/* default ROM directories */
|
||||
#ifdef HW_RVL
|
||||
sprintf (config.lastdir[TYPE_SD], "sd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[TYPE_USB], "usb:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[0][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[1][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[2][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[3][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[0][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[1][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[2][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[3][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[0][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[1][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[2][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[3][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
#else
|
||||
sprintf (config.lastdir[TYPE_SD], "%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[0][TYPE_SD], "%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[1][TYPE_SD], "%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[2][TYPE_SD], "%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[3][TYPE_SD], "%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[0][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[1][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[2][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
sprintf (config.lastdir[3][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||
#endif
|
||||
|
||||
/* try to restore settings from config file */
|
||||
if (!config_load()) GUI_WaitPrompt("Info","Default Settings restored");
|
||||
|
||||
/* hot swap requires at least a first initialization */
|
||||
config.hot_swap &= 1;
|
||||
|
||||
/* restore inputs */
|
||||
input_init();
|
||||
|
||||
/* restore menu settings */
|
||||
menu_configure();
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
#define CONFIG_VERSION "GENPLUS-GX 1.6.0"
|
||||
#define CONFIG_VERSION "GENPLUS-GX 1.6.1"
|
||||
|
||||
/****************************************************************************
|
||||
* Config Option
|
||||
@ -68,9 +68,9 @@ typedef struct
|
||||
uint8 force_dtack;
|
||||
uint8 addr_error;
|
||||
uint8 tmss;
|
||||
uint8 bios;
|
||||
uint8 lock_on;
|
||||
uint8 hot_swap;
|
||||
uint8 romtype;
|
||||
uint8 invert_mouse;
|
||||
uint8 gun_cursor[2];
|
||||
uint8 overscan;
|
||||
@ -97,16 +97,15 @@ typedef struct
|
||||
uint8 s_auto;
|
||||
uint8 s_default;
|
||||
uint8 s_device;
|
||||
uint8 autocheats;
|
||||
int8 bg_type;
|
||||
int8 bg_overlay;
|
||||
uint8 l_device;
|
||||
uint8 bg_overlay;
|
||||
int16 screen_w;
|
||||
float bgm_volume;
|
||||
float sfx_volume;
|
||||
#ifdef HW_RVL
|
||||
char lastdir[3][MAXPATHLEN];
|
||||
char lastdir[4][3][MAXPATHLEN];
|
||||
#else
|
||||
char lastdir[2][MAXPATHLEN];
|
||||
char lastdir[4][2][MAXPATHLEN];
|
||||
#endif
|
||||
} t_config;
|
||||
|
||||
|
@ -71,6 +71,9 @@ static char *fileDir;
|
||||
/* current device */
|
||||
static int deviceType = -1;
|
||||
|
||||
/* current file type */
|
||||
static int fileType = -1;
|
||||
|
||||
/* DVD status flag */
|
||||
static u8 dvd_mounted = 0;
|
||||
|
||||
@ -139,16 +142,6 @@ static int FileSortCallback(const void *f1, const void *f2)
|
||||
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* GetCurrentDirectory
|
||||
*
|
||||
* Return current browser directory
|
||||
***************************************************************************/
|
||||
char *GetCurrentDirectory(int selection)
|
||||
{
|
||||
return (deviceType == TYPE_RECENT) ? history.entries[selection].filepath : fileDir;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* UpdateDirectory
|
||||
*
|
||||
@ -248,10 +241,11 @@ int ParseDirectory(void)
|
||||
****************************************************************************/
|
||||
int LoadFile(int selection)
|
||||
{
|
||||
int filetype;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
/* file path */
|
||||
char *filepath = GetCurrentDirectory(selection);
|
||||
char *filepath = (deviceType == TYPE_RECENT) ? history.entries[selection].filepath : fileDir;
|
||||
|
||||
/* full filename */
|
||||
sprintf(filename, "%s%s", filepath, filelist[selection].filename);
|
||||
@ -273,37 +267,35 @@ int LoadFile(int selection)
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
/* add/move the file to the top of the history. */
|
||||
history_add_file(filepath, filelist[selection].filename);
|
||||
|
||||
/* recent file list has changed */
|
||||
if (deviceType == TYPE_RECENT) deviceType = -1;
|
||||
|
||||
/* auto-save previous game state */
|
||||
if (config.s_auto & 2)
|
||||
{
|
||||
slot_autosave(config.s_default,config.s_device);
|
||||
}
|
||||
|
||||
/* ROM pathname for screenshot, save & cheat files */
|
||||
/* update ROM pathname for screenshot, save & cheat files */
|
||||
if (!strnicmp(".sms", &filename[strlen(filename) - 4], 4))
|
||||
{
|
||||
/* Master System ROM file */
|
||||
filetype = 1;
|
||||
sprintf(rom_filename,"ms/%s",filelist[selection].filename);
|
||||
}
|
||||
else if (!strnicmp(".gg", &filename[strlen(filename) - 3], 3))
|
||||
{
|
||||
/* Game Gear ROM file */
|
||||
filetype = 2;
|
||||
sprintf(rom_filename,"gg/%s",filelist[selection].filename);
|
||||
}
|
||||
else if (!strnicmp(".sg", &filename[strlen(filename) - 3], 3))
|
||||
{
|
||||
/* SG-1000 ROM file */
|
||||
filetype = 3;
|
||||
sprintf(rom_filename,"sg/%s",filelist[selection].filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise, it's Genesis ROM file */
|
||||
/* by default, Genesis ROM file */
|
||||
filetype = 0;
|
||||
sprintf(rom_filename,"md/%s",filelist[selection].filename);
|
||||
}
|
||||
|
||||
@ -312,6 +304,12 @@ int LoadFile(int selection)
|
||||
while ((i > 0) && (rom_filename[i] != '.')) i--;
|
||||
if (i > 0) rom_filename[i] = 0;
|
||||
|
||||
/* add/move the file to the top of the history. */
|
||||
history_add_file(filepath, filelist[selection].filename, filetype);
|
||||
|
||||
/* recent file list may have changed */
|
||||
if (deviceType == TYPE_RECENT) deviceType = -1;
|
||||
|
||||
/* valid ROM has been loaded */
|
||||
return 1;
|
||||
}
|
||||
@ -324,7 +322,7 @@ int LoadFile(int selection)
|
||||
*
|
||||
* Function to open a directory and load ROM file list.
|
||||
****************************************************************************/
|
||||
int OpenDirectory(int device)
|
||||
int OpenDirectory(int device, int type)
|
||||
{
|
||||
int max = 0;
|
||||
|
||||
@ -368,7 +366,7 @@ int OpenDirectory(int device)
|
||||
}
|
||||
|
||||
/* parse last directory */
|
||||
fileDir = config.lastdir[device];
|
||||
fileDir = config.lastdir[type][device];
|
||||
max = ParseDirectory();
|
||||
if (max <= 0)
|
||||
{
|
||||
@ -390,11 +388,12 @@ int OpenDirectory(int device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if device type has changed */
|
||||
if (device != deviceType)
|
||||
/* check if device or file type has changed */
|
||||
if ((device != deviceType) || (type != fileType))
|
||||
{
|
||||
/* reset current device type */
|
||||
/* reset current types */
|
||||
deviceType = device;
|
||||
fileType = type;
|
||||
|
||||
/* reset File selector */
|
||||
ClearSelector(max);
|
||||
|
@ -52,8 +52,7 @@
|
||||
|
||||
#define CHUNKSIZE (2048)
|
||||
|
||||
extern int OpenDirectory(int device);
|
||||
extern char *GetCurrentDirectory(int selection);
|
||||
extern int OpenDirectory(int device, int type);
|
||||
extern int UpdateDirectory(bool go_up, char *filename);
|
||||
extern int ParseDirectory(void);
|
||||
extern int LoadFile(int selection);
|
||||
|
@ -51,7 +51,7 @@ t_history history;
|
||||
* already in the list then the existing entry is (in effect) moved to the
|
||||
* top instead.
|
||||
****************************************************************************/
|
||||
void history_add_file(char *filepath, char *filename)
|
||||
void history_add_file(char *filepath, char *filename, u8 filetype)
|
||||
{
|
||||
/* Create the new entry for this path. */
|
||||
t_history_entry newentry;
|
||||
@ -59,6 +59,7 @@ void history_add_file(char *filepath, char *filename)
|
||||
strncpy(newentry.filename, filename, MAXJOLIET - 1);
|
||||
newentry.filepath[MAXJOLIET - 1] = '\0';
|
||||
newentry.filename[MAXJOLIET - 1] = '\0';
|
||||
newentry.filetype = filetype;
|
||||
|
||||
t_history_entry oldentry; /* Old entry is the one being shuffled down a spot. */
|
||||
t_history_entry currentry; /* Curr entry is the one that just replaced old path. */
|
||||
@ -112,7 +113,13 @@ void history_load(void)
|
||||
if (fp)
|
||||
{
|
||||
/* read file */
|
||||
fread(&history, sizeof(history), 1, fp);
|
||||
if (fread(&history, sizeof(history), 1, fp) != 1)
|
||||
{
|
||||
/* an error ocurred, better clear hoistory */
|
||||
memset(&history, 0, sizeof(history));
|
||||
}
|
||||
|
||||
/* close file */
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ typedef struct
|
||||
{
|
||||
char filepath[MAXJOLIET];
|
||||
char filename[MAXJOLIET];
|
||||
u8 filetype;
|
||||
} t_history_entry;
|
||||
|
||||
typedef struct
|
||||
@ -60,7 +61,7 @@ typedef struct
|
||||
} t_history;
|
||||
|
||||
extern t_history history;
|
||||
extern void history_add_file(char *filepath, char *filename);
|
||||
extern void history_add_file(char *filepath, char *filename, u8 filetype);
|
||||
extern void history_save(void);
|
||||
extern void history_load(void);
|
||||
extern void history_default(void);
|
||||
|
@ -131,7 +131,7 @@ static gui_item action_select =
|
||||
/*****************************************************************************/
|
||||
static gui_image bg_cheats[7] =
|
||||
{
|
||||
{NULL,Bg_main_png,IMAGE_VISIBLE,374,140,284,288,255},
|
||||
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255},
|
||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255},
|
||||
@ -830,26 +830,6 @@ void CheatMenu(void)
|
||||
/* reset scrolling */
|
||||
string_offset = 0;
|
||||
|
||||
/* background type */
|
||||
if (config.bg_type > 0)
|
||||
{
|
||||
bg_cheats[0].state &= ~IMAGE_REPEAT;
|
||||
bg_cheats[0].data = (config.bg_type > 1) ? Bg_main_png : Bg_main_2_png;
|
||||
bg_cheats[0].x = 374;
|
||||
bg_cheats[0].y = 140;
|
||||
bg_cheats[0].w = 284;
|
||||
bg_cheats[0].h = 288;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_cheats[0].state |= IMAGE_REPEAT;
|
||||
bg_cheats[0].data = Bg_layer_png;
|
||||
bg_cheats[0].x = 0;
|
||||
bg_cheats[0].y = 0;
|
||||
bg_cheats[0].w = 640;
|
||||
bg_cheats[0].h = 480;
|
||||
}
|
||||
|
||||
/* background overlay */
|
||||
if (config.bg_overlay)
|
||||
{
|
||||
@ -1327,11 +1307,6 @@ void CheatMenu(void)
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* delete cheat file */
|
||||
remove(temp);
|
||||
}
|
||||
|
||||
/* unlock background elements */
|
||||
m->bg_images[2].state |= IMAGE_SLIDE_TOP;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "font.h"
|
||||
#include "gui.h"
|
||||
#include "file_load.h"
|
||||
#include "history.h"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <wiiuse/wpad.h>
|
||||
@ -54,7 +55,10 @@
|
||||
|
||||
extern const u8 Browser_dir_png[];
|
||||
extern const u8 Snap_empty_png[];
|
||||
extern const u8 Snap_frame_png[];
|
||||
extern const u8 Cart_md_png[];
|
||||
extern const u8 Cart_ms_png[];
|
||||
extern const u8 Cart_gg_png[];
|
||||
extern const u8 Cart_sg_png[];
|
||||
|
||||
FILEENTRIES filelist[MAXFILES];
|
||||
|
||||
@ -103,18 +107,37 @@ static gui_item action_select =
|
||||
/*****************************************************************************/
|
||||
/* GUI Background images */
|
||||
/*****************************************************************************/
|
||||
static gui_image bg_filesel[10] =
|
||||
static gui_image bg_filesel[13] =
|
||||
{
|
||||
{NULL,Bg_main_png,IMAGE_VISIBLE,374,140,284,288,255},
|
||||
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
|
||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
|
||||
{NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255},
|
||||
{NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,152},
|
||||
{NULL,Frame_s2_png,0,384,264,248,140,152},
|
||||
{NULL,Snap_empty_png,IMAGE_VISIBLE,422,114,164,116,255},
|
||||
{NULL,NULL,0,424,116,160,112,255},
|
||||
{NULL,Snap_frame_png,IMAGE_VISIBLE,388,112,236,148,255}
|
||||
{NULL,Snap_empty_png,IMAGE_VISIBLE,424,148,160,112,255},
|
||||
{NULL,NULL,0,424,148,160,112,255},
|
||||
{NULL,NULL,0,388,147,240,152,255},
|
||||
{NULL,NULL,0,392,118,232,148,255},
|
||||
{NULL,NULL,0,414,116,184,188,255},
|
||||
{NULL,NULL,0,416,144,180,228,255}
|
||||
};
|
||||
|
||||
static const u8 *Cart_png[4] =
|
||||
{
|
||||
Cart_md_png,
|
||||
Cart_ms_png,
|
||||
Cart_gg_png,
|
||||
Cart_sg_png
|
||||
};
|
||||
|
||||
static const char *Cart_dir[4] =
|
||||
{
|
||||
"md",
|
||||
"ms",
|
||||
"gg",
|
||||
"sg"
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -124,7 +147,7 @@ static gui_menu menu_selector =
|
||||
{
|
||||
"Game Selection",
|
||||
-1,-1,
|
||||
0,0,10,0,
|
||||
0,0,13,0,
|
||||
NULL,
|
||||
NULL,
|
||||
bg_filesel,
|
||||
@ -241,7 +264,7 @@ static void selector_cb(void)
|
||||
* return ROM size
|
||||
*
|
||||
****************************************************************************/
|
||||
int FileSelector(void)
|
||||
int FileSelector(int type)
|
||||
{
|
||||
short p;
|
||||
int i;
|
||||
@ -255,27 +278,7 @@ int FileSelector(void)
|
||||
gui_butn *button;
|
||||
#endif
|
||||
|
||||
/* background type */
|
||||
if (config.bg_type > 0)
|
||||
{
|
||||
bg_filesel[0].state &= ~IMAGE_REPEAT;
|
||||
bg_filesel[0].data = (config.bg_type > 1) ? Bg_main_png : Bg_main_2_png;
|
||||
bg_filesel[0].x = 374;
|
||||
bg_filesel[0].y = 140;
|
||||
bg_filesel[0].w = 284;
|
||||
bg_filesel[0].h = 288;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_filesel[0].state |= IMAGE_REPEAT;
|
||||
bg_filesel[0].data = Bg_layer_png;
|
||||
bg_filesel[0].x = 0;
|
||||
bg_filesel[0].y = 0;
|
||||
bg_filesel[0].w = 640;
|
||||
bg_filesel[0].h = 480;
|
||||
}
|
||||
|
||||
/* background overlay */
|
||||
/* Background overlay */
|
||||
if (config.bg_overlay)
|
||||
{
|
||||
bg_filesel[1].state |= IMAGE_VISIBLE;
|
||||
@ -285,6 +288,34 @@ int FileSelector(void)
|
||||
bg_filesel[1].state &= ~IMAGE_VISIBLE;
|
||||
}
|
||||
|
||||
/* Hide all cartridge labels */
|
||||
bg_filesel[9].state &= ~IMAGE_VISIBLE;
|
||||
bg_filesel[10].state &= ~IMAGE_VISIBLE;
|
||||
bg_filesel[11].state &= ~IMAGE_VISIBLE;
|
||||
bg_filesel[12].state &= ~IMAGE_VISIBLE;
|
||||
|
||||
/* Cartridge type */
|
||||
if (type < 0)
|
||||
{
|
||||
/* Recent game list -> select all cartridge type */
|
||||
bg_filesel[9].data = Cart_png[0];
|
||||
bg_filesel[10].data = Cart_png[1];
|
||||
bg_filesel[11].data = Cart_png[2];
|
||||
bg_filesel[12].data = Cart_png[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear all cartridges type */
|
||||
bg_filesel[9].data = NULL;
|
||||
bg_filesel[10].data = NULL;
|
||||
bg_filesel[11].data = NULL;
|
||||
bg_filesel[12].data = NULL;
|
||||
|
||||
/* Select cartridge type */
|
||||
bg_filesel[9 + type].data = Cart_png[type];
|
||||
bg_filesel[9 + type].state |= IMAGE_VISIBLE;
|
||||
}
|
||||
|
||||
/* Initialize Menu */
|
||||
GUI_InitMenu(m);
|
||||
string_offset = 0;
|
||||
@ -303,48 +334,33 @@ int FileSelector(void)
|
||||
|
||||
if (!filelist[selection].flags)
|
||||
{
|
||||
/* get compressed file name */
|
||||
sprintf(fname, "%s/%s", GetCurrentDirectory(selection), filelist[selection].filename);
|
||||
get_zipfilename(fname);
|
||||
/* recent game list -> variable game types */
|
||||
if (type < 0)
|
||||
{
|
||||
/* hide all cartridge labels */
|
||||
bg_filesel[9].state &= ~IMAGE_VISIBLE;
|
||||
bg_filesel[10].state &= ~IMAGE_VISIBLE;
|
||||
bg_filesel[11].state &= ~IMAGE_VISIBLE;
|
||||
bg_filesel[12].state &= ~IMAGE_VISIBLE;
|
||||
|
||||
/* auto-detect file type */
|
||||
if (!strnicmp(".sms", &fname[strlen(fname) - 4], 4))
|
||||
{
|
||||
/* Master System ROM file */
|
||||
sprintf(fname, "%s/snaps/ms/%s", DEFAULT_PATH, filelist[selection].filename);
|
||||
}
|
||||
else if (!strnicmp(".gg", &fname[strlen(fname) - 3], 3))
|
||||
{
|
||||
/* Game Gear ROM file */
|
||||
sprintf(fname, "%s/snaps/gg/%s", DEFAULT_PATH, filelist[selection].filename);
|
||||
}
|
||||
else if (!strnicmp(".sg", &fname[strlen(fname) - 3], 3))
|
||||
{
|
||||
/* SG-1000 ROM file */
|
||||
sprintf(fname, "%s/snaps/sg/%s", DEFAULT_PATH, filelist[selection].filename);
|
||||
}
|
||||
else if ((!strnicmp(".md", &fname[strlen(fname) - 3], 3)) ||
|
||||
(!strnicmp(".gen", &fname[strlen(fname) - 4], 4)) ||
|
||||
(!strnicmp(".bin", &fname[strlen(fname) - 4], 4)) ||
|
||||
(!strnicmp(".mdx", &fname[strlen(fname) - 4], 4)) ||
|
||||
(!strnicmp(".smd", &fname[strlen(fname) - 4], 4)))
|
||||
{
|
||||
/* Genesis ROM file */
|
||||
sprintf(fname, "%s/snaps/md/%s", DEFAULT_PATH, filelist[selection].filename);
|
||||
/* detect cartridge type (0-3) */
|
||||
type = history.entries[selection].filetype;
|
||||
|
||||
/* show selected cartridge label */
|
||||
bg_filesel[9 + type].state |= IMAGE_VISIBLE;
|
||||
|
||||
/* default screenshot file path */
|
||||
sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename);
|
||||
|
||||
/* restore recent type flag */
|
||||
type = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fname[0] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fname[0] = 0;
|
||||
/* default screenshot file path */
|
||||
sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename);
|
||||
}
|
||||
|
||||
/* Supported ROM file found ? */
|
||||
if (fname[0])
|
||||
{
|
||||
/* remove original file extension */
|
||||
i = strlen(fname) - 1;
|
||||
while ((i > 0) && (fname[i] != '.')) i--;
|
||||
@ -353,7 +369,7 @@ int FileSelector(void)
|
||||
/* add PNG file extension */
|
||||
strcat(fname, ".png");
|
||||
|
||||
/* try to load screenshot */
|
||||
/* try to load screenshot file */
|
||||
snap = fopen(fname, "rb");
|
||||
if (snap)
|
||||
{
|
||||
@ -563,7 +579,7 @@ int FileSelector(void)
|
||||
selection = offset = 0;
|
||||
old = -1;
|
||||
}
|
||||
else if (fname[0])
|
||||
else
|
||||
{
|
||||
/* load ROM file from device */
|
||||
int ret = LoadFile(selection);
|
||||
@ -574,11 +590,6 @@ int FileSelector(void)
|
||||
/* return ROM size (or zero if an error occured) */
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unsupported ROM file */
|
||||
GUI_WaitPrompt("Error","Unsupported ROM type !");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HW_RVL
|
||||
@ -605,7 +616,6 @@ int FileSelector(void)
|
||||
offset += 10;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ typedef struct
|
||||
}FILEENTRIES;
|
||||
|
||||
/* Globals */
|
||||
extern int FileSelector(void);
|
||||
extern int FileSelector(int type);
|
||||
extern void ClearSelector(u32 max);
|
||||
extern FILEENTRIES filelist[MAXFILES];
|
||||
|
||||
|
@ -51,31 +51,10 @@ u8 SILENT = 0;
|
||||
static gui_message message_box;
|
||||
static lwp_t msgboxthread;
|
||||
|
||||
/* background color */
|
||||
static GXColor bg_color;
|
||||
/* background color (black) */
|
||||
static const GXColor bg_color = {0x00,0x00,0x00,0xff};
|
||||
|
||||
/* various background colors */
|
||||
static GXColor bg_colors[BG_COLOR_MAX]=
|
||||
{
|
||||
{0x00,0x00,0x00,0xff}, /* black */
|
||||
{0xd4,0xd0,0xc8,0xff}, /* cream */
|
||||
{0xbb,0xb0,0x99,0xff}, /* gold */
|
||||
{0xd6,0xcb,0xba,0xff}, /* light gold */
|
||||
{0xcc,0xcc,0xcc,0xff}, /* light grey */
|
||||
{0x66,0x66,0x66,0xff}, /* faded grey */
|
||||
{0x50,0x51,0x5b,0xff}, /* grey blue */
|
||||
{0xb8,0xc7,0xda,0xff}, /* light blue */
|
||||
{0xc0,0xcf,0xe7,0xff}, /* sky blue */
|
||||
{0x98,0xb1,0xd8,0xff}, /* sea blue */
|
||||
{0x7b,0x8c,0xa6,0xff}, /* violet */
|
||||
{0xa9,0xc7,0xc6,0xff}, /* green blue */
|
||||
{0x7d,0xa4,0x9f,0xff}, /* darker green blue */
|
||||
{0x22,0x52,0x74,0xff}, /* dark blue */
|
||||
{0x33,0x33,0x33,0xff} /* dark grey */
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/* Generic GUI routines */
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -1987,22 +1966,3 @@ void GUI_FadeOut()
|
||||
alpha +=3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return background color */
|
||||
GXColor *GUI_GetBgColor(void)
|
||||
{
|
||||
return &bg_color;
|
||||
}
|
||||
|
||||
/* Select background color */
|
||||
void GUI_SetBgColor(u8 color)
|
||||
{
|
||||
if (color < BG_COLOR_MAX)
|
||||
{
|
||||
bg_color.r = bg_colors[color].r;
|
||||
bg_color.g = bg_colors[color].g;
|
||||
bg_color.b = bg_colors[color].b;
|
||||
bg_color.a = bg_colors[color].a;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,15 +170,10 @@ extern gx_texture *w_pointer;
|
||||
|
||||
/* Generic backgrounds */
|
||||
extern const u8 Bg_layer_png[];
|
||||
extern const u8 Bg_main_png[];
|
||||
extern const u8 Bg_main_2_png[];
|
||||
extern const u8 Bg_overlay_png[];
|
||||
extern const u8 Banner_main_png[];
|
||||
extern const u8 Banner_bottom_png[];
|
||||
extern const u8 Banner_top_png[];
|
||||
extern const u8 Banner_main_2_png[];
|
||||
extern const u8 Banner_bottom_2_png[];
|
||||
extern const u8 Banner_top_2_png[];
|
||||
extern const u8 Main_logo_png[];
|
||||
|
||||
/* Generic frames */
|
||||
|
@ -45,7 +45,6 @@ extern const u8 Bg_intro_c1_png[];
|
||||
extern const u8 Bg_intro_c2_png[];
|
||||
extern const u8 Bg_intro_c3_png[];
|
||||
extern const u8 Bg_intro_c4_png[];
|
||||
extern const u8 Bg_intro_c5_png[];
|
||||
|
||||
/*
|
||||
* This is the legal stuff - which must be shown at program startup
|
||||
@ -95,16 +94,12 @@ void legal ()
|
||||
#else
|
||||
gx_texture *button = gxTextureOpenPNG(Key_A_gcn_png,0);
|
||||
#endif
|
||||
|
||||
gx_texture *logo_left= gxTextureOpenPNG(Bg_intro_c5_png,0);
|
||||
gx_texture *logo_right = gxTextureOpenPNG(Bg_intro_c4_png,0);
|
||||
gx_texture *logo = gxTextureOpenPNG(Bg_intro_c4_png,0);
|
||||
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
show_disclaimer(56);
|
||||
gxDrawTexture(logo_left, (640-logo_left->width-logo_right->width -32)/2, 480-logo_left->height-24, logo_left->width, logo_left->height,255);
|
||||
gxDrawTexture(logo_right, (640-logo_left->width-logo_right->width -32)/2+logo_left->width+32, 480-logo_right->height-24, logo_right->width, logo_right->height,255);
|
||||
gxDrawTexture(logo, (640-logo->width)/2, 480-24-logo->height, logo->width, logo->height,255);
|
||||
gxSetScreen();
|
||||
|
||||
sleep(1);
|
||||
|
||||
while (!(m_input.keys & PAD_BUTTON_A) && (count > 0))
|
||||
@ -117,15 +112,13 @@ void legal ()
|
||||
FONT_writeCenter("Press button to continue.",24,0,640,366,(GXColor)SKY_BLUE);
|
||||
gxDrawTexture(button, 220, 366-24+(24-button->height)/2, button->width, button->height,255);
|
||||
}
|
||||
gxDrawTexture(logo_left, (640-logo_left->width-logo_right->width -32)/2, 480-logo_left->height-24, logo_left->width, logo_left->height,255);
|
||||
gxDrawTexture(logo_right, (640-logo_left->width-logo_right->width -32)/2+logo_left->width+32, 480-logo_right->height-24, logo_right->width, logo_right->height,255);
|
||||
gxDrawTexture(logo, (640-logo->width)/2, 480-24-logo->height, logo->width, logo->height,255);
|
||||
gxSetScreen();
|
||||
count--;
|
||||
}
|
||||
|
||||
gxTextureClose(&button);
|
||||
gxTextureClose(&logo_left);
|
||||
gxTextureClose(&logo_right);
|
||||
gxTextureClose(&logo);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ extern const u8 Main_options_png[];
|
||||
extern const u8 Main_quit_png[];
|
||||
extern const u8 Main_file_png[];
|
||||
extern const u8 Main_reset_png[];
|
||||
extern const u8 Main_ggenie_png[];
|
||||
extern const u8 Main_cheats_png[];
|
||||
extern const u8 Main_showinfo_png[];
|
||||
extern const u8 Main_takeshot_png[];
|
||||
#ifdef HW_RVL
|
||||
@ -80,11 +80,10 @@ extern const u8 Option_system_png[];
|
||||
|
||||
/* Load ROM menu */
|
||||
extern const u8 Load_recent_png[];
|
||||
extern const u8 Load_sd_png[];
|
||||
extern const u8 Load_dvd_png[];
|
||||
#ifdef HW_RVL
|
||||
extern const u8 Load_usb_png[];
|
||||
#endif
|
||||
extern const u8 Load_md_png[];
|
||||
extern const u8 Load_ms_png[];
|
||||
extern const u8 Load_gg_png[];
|
||||
extern const u8 Load_sg_png[];
|
||||
|
||||
/* Save Manager menu */
|
||||
extern const u8 Button_load_png[];
|
||||
@ -216,13 +215,12 @@ static gui_item action_select =
|
||||
NULL,Key_A_png,"","",602,422,28,28
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* GUI backgrounds images */
|
||||
/*****************************************************************************/
|
||||
static gui_image bg_main[4] =
|
||||
{
|
||||
{NULL,Bg_main_png,IMAGE_VISIBLE,178,74,284,288,255},
|
||||
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Banner_main_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,340,640,140,255},
|
||||
{NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,202,362,232,56,255}
|
||||
@ -230,7 +228,7 @@ static gui_image bg_main[4] =
|
||||
|
||||
static gui_image bg_misc[5] =
|
||||
{
|
||||
{NULL,Bg_main_png,IMAGE_VISIBLE,178,96,284,288,255},
|
||||
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255},
|
||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255},
|
||||
@ -239,7 +237,7 @@ static gui_image bg_misc[5] =
|
||||
|
||||
static gui_image bg_ctrls[8] =
|
||||
{
|
||||
{NULL,Bg_main_png,IMAGE_VISIBLE,374,140,284,288,255},
|
||||
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
|
||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
|
||||
@ -251,7 +249,7 @@ static gui_image bg_ctrls[8] =
|
||||
|
||||
static gui_image bg_list[6] =
|
||||
{
|
||||
{NULL,Bg_main_png,IMAGE_VISIBLE,374,140,284,288,255},
|
||||
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
|
||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
|
||||
@ -262,7 +260,7 @@ static gui_image bg_list[6] =
|
||||
static gui_image bg_saves[8] =
|
||||
{
|
||||
{NULL,NULL,0,0,0,0,0,255},
|
||||
{NULL,Bg_main_png,IMAGE_VISIBLE,374,140,284,288,255},
|
||||
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
||||
{NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255},
|
||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255},
|
||||
@ -283,7 +281,7 @@ static gui_item items_main[10] =
|
||||
{NULL,Main_quit_png ,"","",460,170,52,84},
|
||||
{NULL,Main_file_png ,"","",114,216,80,92},
|
||||
{NULL,Main_reset_png ,"","",282,224,76,84},
|
||||
{NULL,Main_ggenie_png ,"","",450,224,72,84},
|
||||
{NULL,Main_cheats_png ,"","",454,218,64,92},
|
||||
{NULL,NULL ,"","", 10,334,84,32},
|
||||
#ifdef HW_RVL
|
||||
{NULL,Main_play_wii_png,"","", 10,372,84,32},
|
||||
@ -313,18 +311,13 @@ static gui_item items_ctrls[13] =
|
||||
};
|
||||
|
||||
/* Load menu */
|
||||
static gui_item items_load[4] =
|
||||
static gui_item items_load[5] =
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
{NULL,Load_recent_png,"","Load recent ROM files" ,276,120,88,96},
|
||||
{NULL,Load_sd_png ,"","Load ROM files from SD card" ,110,266,88,96},
|
||||
{NULL,Load_usb_png ,"","Load ROM files from USB drive" ,276,266,88,96},
|
||||
{NULL,Load_dvd_png ,"","Load ROM files from DVD" ,442,266,88,96}
|
||||
#else
|
||||
{NULL,Load_recent_png,"","Load recent ROM files (USB/SD)" ,110,192,88,96},
|
||||
{NULL,Load_sd_png ,"","Load ROM files from SD card" ,276,192,88,96},
|
||||
{NULL,Load_dvd_png ,"","Load ROM files from DVD" ,442,192,88,96}
|
||||
#endif
|
||||
{NULL,Load_recent_png,"","Load recently played games", 200,144,72, 92},
|
||||
{NULL,Load_md_png, "","Load Mega Drive/Genesis games", 362,141,84, 92},
|
||||
{NULL,Load_ms_png, "","Load Master System games", 114,284,84, 96},
|
||||
{NULL,Load_gg_png, "","Load Game Gear games", 278,283,84,100},
|
||||
{NULL,Load_sg_png, "","Load SG-1000 games", 455,281,64, 96}
|
||||
};
|
||||
|
||||
/* Option menu */
|
||||
@ -360,9 +353,9 @@ static gui_item items_system[8] =
|
||||
{
|
||||
{NULL,NULL,"Console Hardware: AUTO", "Select system hardware model", 56,132,276,48},
|
||||
{NULL,NULL,"Console Region: AUTO", "Select system region", 56,132,276,48},
|
||||
{NULL,NULL,"System Lockups: OFF", "Enable/disable original system lock-ups", 56,132,276,48},
|
||||
{NULL,NULL,"68k Address Error: ON", "Enable/disable 68k Address Error", 56,132,276,48},
|
||||
{NULL,NULL,"System BIOS: OFF", "Enable/disable TMSS BIOS support", 56,132,276,48},
|
||||
{NULL,NULL,"System Boot: BIOS&CART", "Select system booting method", 56,132,276,48},
|
||||
{NULL,NULL,"System Lockups: ON", "Enable/disable original system lock-ups", 56,132,276,48},
|
||||
{NULL,NULL,"68k Address Error: ON", "Enable/disable 68k address error exceptions", 56,132,276,48},
|
||||
{NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 56,132,276,48},
|
||||
{NULL,NULL,"Cartridge Swap: OFF", "Enable/disable cartridge hot swap", 56,132,276,48},
|
||||
{NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 56,132,276,48}
|
||||
@ -395,10 +388,10 @@ static gui_item items_prefs[9] =
|
||||
{NULL,NULL,"Auto ROM Load: OFF","Enable/Disable automatic ROM loading on startup", 56,132,276,48},
|
||||
{NULL,NULL,"Auto Cheats: OFF", "Enable/Disable automatic cheats activation", 56,132,276,48},
|
||||
{NULL,NULL,"Auto Saves: OFF", "Enable/Disable automatic saves", 56,132,276,48},
|
||||
{NULL,NULL,"Saves Device: FAT", "Configure default device for saves", 56,132,276,48},
|
||||
{NULL,NULL,"ROM Device: SD", "Configure default device for ROM files", 56,132,276,48},
|
||||
{NULL,NULL,"Saves Device: FAT", "Configure default device for Save files", 56,132,276,48},
|
||||
{NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 56,132,276,48},
|
||||
{NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 56,132,276,48},
|
||||
{NULL,NULL,"BG Color: DEFAULT", "Select background color", 56,132,276,48},
|
||||
{NULL,NULL,"BG Overlay: ON", "Enable/disable background overlay", 56,132,276,48},
|
||||
{NULL,NULL,"Screen Width: 658", "Adjust menu screen width in pixels", 56,132,276,48},
|
||||
};
|
||||
@ -468,18 +461,13 @@ static gui_butn buttons_ctrls[13] =
|
||||
};
|
||||
|
||||
/* Load Game menu */
|
||||
static gui_butn buttons_load[4] =
|
||||
static gui_butn buttons_load[5] =
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,0,1},246,102,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,1,1}, 80,248,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0,1,1},246,248,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,0},412,248,148,132}
|
||||
#else
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,0,1}, 80,174,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,1,1},246,174,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,0},412,174,148,132}
|
||||
#endif
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,0,1},162,120,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,1,0},330,120,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0,0,1}, 80,264,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0,1,1},246,264,148,132},
|
||||
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,0},412,264,148,132}
|
||||
};
|
||||
|
||||
/* Options menu */
|
||||
@ -543,11 +531,7 @@ static gui_menu menu_load =
|
||||
{
|
||||
"Load Game",
|
||||
0,0,
|
||||
#ifdef HW_RVL
|
||||
4,4,5,0,
|
||||
#else
|
||||
3,3,5,0,
|
||||
#endif
|
||||
5,5,5,0,
|
||||
items_load,
|
||||
buttons_load,
|
||||
bg_misc,
|
||||
@ -575,7 +559,7 @@ static gui_menu menu_system =
|
||||
{
|
||||
"System Settings",
|
||||
0,0,
|
||||
7,4,7,0,
|
||||
8,4,6,0,
|
||||
items_system,
|
||||
buttons_list,
|
||||
bg_list,
|
||||
@ -670,13 +654,18 @@ static void prefmenu ()
|
||||
else if (config.s_auto == 2) sprintf (items[2].text, "Auto Saves: STATE ONLY");
|
||||
else if (config.s_auto == 1) sprintf (items[2].text, "Auto Saves: SRAM ONLY");
|
||||
else sprintf (items[2].text, "Auto Saves: NONE");
|
||||
if (config.s_device == 1) sprintf (items[3].text, "Saves Device: MCARD A");
|
||||
else if (config.s_device == 2) sprintf (items[3].text, "Saves Device: MCARD B");
|
||||
else sprintf (items[3].text, "Saves Device: FAT");
|
||||
sprintf (items[4].text, "SFX Volume: %1.1f", config.sfx_volume);
|
||||
sprintf (items[5].text, "BGM Volume: %1.1f", config.bgm_volume);
|
||||
if (config.bg_type) sprintf (items[6].text, "BG Type: COLOR %d", config.bg_type - 1);
|
||||
else sprintf (items[6].text, "BG Type: DEFAULT");
|
||||
#ifdef HW_RVL
|
||||
if (config.l_device == 1) sprintf (items[3].text, "Default ROM Device: USB");
|
||||
else if (config.l_device == 2) sprintf (items[3].text, "Default ROM Device: DVD");
|
||||
#else
|
||||
if (config.l_device == 1) sprintf (items[3].text, "Default ROM Device: DVD");
|
||||
#endif
|
||||
else sprintf (items[3].text, "Default ROM Device: SD");
|
||||
if (config.s_device == 1) sprintf (items[4].text, "Saves Device: MCARD A");
|
||||
else if (config.s_device == 2) sprintf (items[4].text, "Saves Device: MCARD B");
|
||||
else sprintf (items[4].text, "Saves Device: FAT");
|
||||
sprintf (items[5].text, "SFX Volume: %1.1f", config.sfx_volume);
|
||||
sprintf (items[6].text, "BGM Volume: %1.1f", config.bgm_volume);
|
||||
sprintf (items[7].text, "BG Overlay: %s", config.bg_overlay ? "ON":"OFF");
|
||||
sprintf (items[8].text, "Screen Width: %d", config.screen_w);
|
||||
|
||||
@ -707,39 +696,55 @@ static void prefmenu ()
|
||||
else sprintf (items[2].text, "Auto Saves: NONE");
|
||||
break;
|
||||
|
||||
case 3: /*** Default saves device ***/
|
||||
case 3: /*** Default ROM device ***/
|
||||
#ifdef HW_RVL
|
||||
config.l_device = (config.l_device + 1) % 3;
|
||||
if (config.l_device == 1) sprintf (items[3].text, "Default ROM Device: USB");
|
||||
else if (config.l_device == 2) sprintf (items[3].text, "Default ROM Device: DVD");
|
||||
#else
|
||||
config.l_device ^= 1;
|
||||
if (config.l_device == 1) sprintf (items[3].text, "Default ROM Device: DVD");
|
||||
#endif
|
||||
else sprintf (items[3].text, "Default ROM Device: SD");
|
||||
break;
|
||||
|
||||
case 4: /*** Default saves device ***/
|
||||
config.s_device = (config.s_device + 1) % 3;
|
||||
if (config.s_device == 1) sprintf (items[3].text, "Saves Device: MCARD A");
|
||||
else if (config.s_device == 2) sprintf (items[3].text, "Saves Device: MCARD B");
|
||||
else sprintf (items[3].text, "Saves Device: FAT");
|
||||
if (config.s_device == 1) sprintf (items[4].text, "Saves Device: MCARD A");
|
||||
else if (config.s_device == 2) sprintf (items[4].text, "Saves Device: MCARD B");
|
||||
else sprintf (items[4].text, "Saves Device: FAT");
|
||||
break;
|
||||
|
||||
case 4: /*** Sound effects volume ***/
|
||||
case 5: /*** Sound effects volume ***/
|
||||
GUI_OptionBox(m,0,"SFX Volume",(void *)&config.sfx_volume,10.0,0.0,100.0,0);
|
||||
sprintf (items[4].text, "SFX Volume: %1.1f", config.sfx_volume);
|
||||
sprintf (items[5].text, "SFX Volume: %1.1f", config.sfx_volume);
|
||||
break;
|
||||
|
||||
case 5: /*** Background music volume ***/
|
||||
case 6: /*** Background music volume ***/
|
||||
GUI_OptionBox(m,update_bgm,"BGM Volume",(void *)&config.bgm_volume,10.0,0.0,100.0,0);
|
||||
sprintf (items[5].text, "BGM Volume: %1.1f", config.bgm_volume);
|
||||
break;
|
||||
|
||||
case 6: /*** Background type ***/
|
||||
if (ret < 0) config.bg_type --;
|
||||
else config.bg_type++;
|
||||
if (config.bg_type < 0) config.bg_type = BG_COLOR_MAX;
|
||||
else if (config.bg_type > BG_COLOR_MAX) config.bg_type = 0;
|
||||
if (config.bg_type) sprintf (items[6].text, "BG Type: COLOR %d", config.bg_type - 1);
|
||||
else sprintf (items[6].text, "BG Type: DEFAULT");
|
||||
GUI_DeleteMenu(m);
|
||||
menu_configure();
|
||||
GUI_InitMenu(m);
|
||||
sprintf (items[6].text, "BGM Volume: %1.1f", config.bgm_volume);
|
||||
break;
|
||||
|
||||
case 7: /*** Background overlay ***/
|
||||
config.bg_overlay ^= 1;
|
||||
sprintf (items[7].text, "BG Overlay: %s", config.bg_overlay ? "ON":"OFF");
|
||||
menu_configure();
|
||||
if (config.bg_overlay)
|
||||
{
|
||||
bg_main[1].state |= IMAGE_VISIBLE;
|
||||
bg_misc[1].state |= IMAGE_VISIBLE;
|
||||
bg_ctrls[1].state |= IMAGE_VISIBLE;
|
||||
bg_list[1].state |= IMAGE_VISIBLE;
|
||||
bg_saves[2].state |= IMAGE_VISIBLE;
|
||||
sprintf (items[7].text, "BG Overlay: ON");
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_main[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_misc[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_ctrls[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_list[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_saves[2].state &= ~IMAGE_VISIBLE;
|
||||
sprintf (items[7].text, "BG Overlay: OFF");
|
||||
}
|
||||
break;
|
||||
|
||||
case 8: /*** Screen Width ***/
|
||||
@ -1085,9 +1090,9 @@ static void systemmenu ()
|
||||
else if (config.region_detect == 3)
|
||||
sprintf (items[1].text, "Console Region: JAPAN");
|
||||
|
||||
sprintf (items[2].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
sprintf (items[3].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
sprintf (items[4].text, "System TMSS: %s", (config.tmss & 1) ? "ON":"OFF");
|
||||
sprintf (items[2].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART" : "BIOS ONLY") : "CART");
|
||||
sprintf (items[3].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
sprintf (items[4].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
|
||||
if (config.lock_on == TYPE_GG)
|
||||
sprintf (items[5].text, "Lock-On: GAME GENIE");
|
||||
@ -1225,7 +1230,7 @@ static void systemmenu ()
|
||||
region_autodetect();
|
||||
if (system_hw == SYSTEM_MD)
|
||||
{
|
||||
io_reg[0x00] = 0x20 | region_code | (config.tmss & 1);
|
||||
io_reg[0x00] = 0x20 | region_code | (config.bios & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1271,14 +1276,36 @@ static void systemmenu ()
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: /*** force DTACK ***/
|
||||
case 2: /*** BIOS support ***/
|
||||
{
|
||||
config.force_dtack ^= 1;
|
||||
sprintf (items[2].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
uint8 temp = config.bios & 3;
|
||||
config.bios &= ~3;
|
||||
if (temp == 0) config.bios |= 3;
|
||||
else if (temp == 3) config.bios |= 1;
|
||||
sprintf (items[2].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART " : "BIOS ONLY") : "CART");
|
||||
if (cart.romsize && ((system_hw == SYSTEM_MD) || (system_hw & SYSTEM_GG) || (system_hw & SYSTEM_SMS)))
|
||||
{
|
||||
/* reset emulation */
|
||||
system_init();
|
||||
system_reset();
|
||||
|
||||
/* restore SRAM */
|
||||
if (config.s_auto & 1)
|
||||
{
|
||||
slot_autoload(0,config.s_device);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: /*** 68k Address Error ***/
|
||||
case 3: /*** force DTACK ***/
|
||||
{
|
||||
config.force_dtack ^= 1;
|
||||
sprintf (items[3].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: /*** 68k Address Error ***/
|
||||
{
|
||||
config.addr_error ^= 1;
|
||||
if (cart.romsize && ((system_hw & SYSTEM_PBC) == SYSTEM_MD))
|
||||
@ -1291,26 +1318,7 @@ static void systemmenu ()
|
||||
slot_autoload(0,config.s_device);
|
||||
}
|
||||
}
|
||||
sprintf (items[3].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: /*** BIOS support ***/
|
||||
{
|
||||
config.tmss ^= 1;
|
||||
sprintf (items[4].text, "System TMSS: %s", (config.tmss & 1) ? "ON":"OFF");
|
||||
if (cart.romsize && ((system_hw & SYSTEM_PBC) == SYSTEM_MD))
|
||||
{
|
||||
/* restart emulation */
|
||||
system_init();
|
||||
system_reset();
|
||||
|
||||
/* restore SRAM */
|
||||
if (config.s_auto & 1)
|
||||
{
|
||||
slot_autoload(0,config.s_device);
|
||||
}
|
||||
}
|
||||
sprintf (items[4].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3012,7 +3020,7 @@ static int savemenu(void)
|
||||
****************************************************************************/
|
||||
static int loadgamemenu ()
|
||||
{
|
||||
int ret;
|
||||
int ret, filetype;
|
||||
gui_menu *m = &menu_load;
|
||||
GUI_InitMenu(m);
|
||||
GUI_DrawMenuFX(m,30,0);
|
||||
@ -3032,19 +3040,23 @@ static int loadgamemenu ()
|
||||
/*** Load from selected device */
|
||||
default:
|
||||
{
|
||||
/* ROM File type */
|
||||
filetype = ret - 1;
|
||||
|
||||
/* Try to open current directory */
|
||||
if (ret > 0)
|
||||
{
|
||||
ret = OpenDirectory(ret - 1);
|
||||
ret = OpenDirectory(config.l_device, filetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = OpenDirectory(TYPE_RECENT);
|
||||
ret = OpenDirectory(TYPE_RECENT, filetype);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
GUI_DeleteMenu(m);
|
||||
if (FileSelector())
|
||||
if (FileSelector(filetype))
|
||||
{
|
||||
/* directly jump to game */
|
||||
return 1;
|
||||
@ -3320,7 +3332,7 @@ static void mainmenu_cb(void)
|
||||
}
|
||||
}
|
||||
|
||||
int menu_execute(void)
|
||||
void mainmenu(void)
|
||||
{
|
||||
char filename[MAXPATHLEN];
|
||||
int status, quit = 0;
|
||||
@ -3349,6 +3361,22 @@ int menu_execute(void)
|
||||
/* Update main menu */
|
||||
if (!m->screenshot && cart.romsize)
|
||||
{
|
||||
if (config.bg_overlay)
|
||||
{
|
||||
bg_main[1].state |= IMAGE_VISIBLE;
|
||||
bg_misc[1].state |= IMAGE_VISIBLE;
|
||||
bg_ctrls[1].state |= IMAGE_VISIBLE;
|
||||
bg_list[1].state |= IMAGE_VISIBLE;
|
||||
bg_saves[2].state |= IMAGE_VISIBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_main[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_misc[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_ctrls[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_list[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_saves[2].state &= ~IMAGE_VISIBLE;
|
||||
}
|
||||
m->screenshot = 128;
|
||||
m->bg_images[0].state &= ~IMAGE_VISIBLE;
|
||||
m->items[0].y -= 90;
|
||||
@ -3392,6 +3420,9 @@ int menu_execute(void)
|
||||
|
||||
if (loadgamemenu())
|
||||
{
|
||||
/* restart emulation */
|
||||
reloadrom();
|
||||
|
||||
/* check current controller configuration */
|
||||
if (!gx_input_FindDevices())
|
||||
{
|
||||
@ -3404,7 +3435,7 @@ int menu_execute(void)
|
||||
/* exit to game and reinitialize emulation */
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
gxSetScreen();
|
||||
quit = 2;
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3569,64 +3600,4 @@ int menu_execute(void)
|
||||
MOUSE_Deinit();
|
||||
}
|
||||
#endif
|
||||
|
||||
return (quit >> 1);
|
||||
}
|
||||
|
||||
void menu_configure(void)
|
||||
{
|
||||
/* background type */
|
||||
if (config.bg_type > 0)
|
||||
{
|
||||
GUI_SetBgColor((u8)(config.bg_type - 1));
|
||||
bg_main[0].state &= ~IMAGE_REPEAT;
|
||||
bg_misc[0].state &= ~IMAGE_REPEAT;
|
||||
bg_ctrls[0].state &= ~IMAGE_REPEAT;
|
||||
bg_list[0].state &= ~IMAGE_REPEAT;
|
||||
bg_saves[1].state &= ~IMAGE_REPEAT;
|
||||
if (config.bg_type > 1)
|
||||
{
|
||||
bg_main[0].data = bg_misc[0].data = bg_ctrls[0].data = bg_list[0].data = bg_saves[1].data = Bg_main_png;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_main[0].data = bg_misc[0].data = bg_ctrls[0].data = bg_list[0].data = bg_saves[1].data = Bg_main_2_png;
|
||||
}
|
||||
bg_main[0].x = bg_misc[0].x = bg_ctrls[0].x = bg_list[0].x = bg_saves[1].x = 374;
|
||||
bg_main[0].y = bg_misc[0].y = bg_ctrls[0].y = bg_list[0].y = bg_saves[1].y = 140;
|
||||
bg_main[0].w = bg_misc[0].w = bg_ctrls[0].w = bg_list[0].w = bg_saves[1].w = 284;
|
||||
bg_main[0].h = bg_misc[0].h = bg_ctrls[0].h = bg_list[0].h = bg_saves[1].h = 288;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI_SetBgColor(0);
|
||||
bg_main[0].state |= IMAGE_REPEAT;
|
||||
bg_misc[0].state |= IMAGE_REPEAT;
|
||||
bg_ctrls[0].state |= IMAGE_REPEAT;
|
||||
bg_list[0].state |= IMAGE_REPEAT;
|
||||
bg_saves[1].state |= IMAGE_REPEAT;
|
||||
bg_main[0].data = bg_misc[0].data = bg_ctrls[0].data = bg_list[0].data = bg_saves[1].data = Bg_layer_png;
|
||||
bg_main[0].x = bg_misc[0].x = bg_ctrls[0].x = bg_list[0].x = bg_saves[1].x = 0;
|
||||
bg_main[0].y = bg_misc[0].y = bg_ctrls[0].y = bg_list[0].y = bg_saves[1].y = 0;
|
||||
bg_main[0].w = bg_misc[0].w = bg_ctrls[0].w = bg_list[0].w = bg_saves[1].w = 640;
|
||||
bg_main[0].h = bg_misc[0].h = bg_ctrls[0].h = bg_list[0].h = bg_saves[1].h = 480;
|
||||
}
|
||||
|
||||
/* background overlay */
|
||||
if (config.bg_overlay)
|
||||
{
|
||||
bg_main[1].state |= IMAGE_VISIBLE;
|
||||
bg_misc[1].state |= IMAGE_VISIBLE;
|
||||
bg_ctrls[1].state |= IMAGE_VISIBLE;
|
||||
bg_list[1].state |= IMAGE_VISIBLE;
|
||||
bg_saves[2].state |= IMAGE_VISIBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_main[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_misc[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_ctrls[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_list[1].state &= ~IMAGE_VISIBLE;
|
||||
bg_saves[2].state &= ~IMAGE_VISIBLE;
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,7 @@
|
||||
#ifndef _MENU_H
|
||||
#define _MENU_H
|
||||
|
||||
extern int menu_execute(void);
|
||||
extern void menu_configure(void);
|
||||
|
||||
extern void mainmenu(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1400,7 +1400,7 @@ void gx_input_UpdateEmu(void)
|
||||
RAMCheatUpdate();
|
||||
}
|
||||
|
||||
/* Menu inputs update function (done by Video Interrupt callback) */
|
||||
/* Menu inputs update function */
|
||||
void gx_input_UpdateMenu(void)
|
||||
{
|
||||
/* Check if inputs update are disabled */
|
||||
|
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 72 KiB |
BIN
source/gx/images/Cart_gg.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
source/gx/images/Cart_md.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
source/gx/images/Cart_ms.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
source/gx/images/Cart_sg.png
Normal file
After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 12 KiB |
BIN
source/gx/images/Load_gg.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
source/gx/images/Load_md.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
source/gx/images/Load_ms.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 12 KiB |
BIN
source/gx/images/Load_sg.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 12 KiB |
BIN
source/gx/images/Main_cheats.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 22 KiB |
310
source/gx/main.c
@ -50,7 +50,6 @@
|
||||
#include <fat.h>
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <ogc/machine/processor.h>
|
||||
#endif
|
||||
|
||||
@ -66,6 +65,46 @@ u32 ConfigRequested = 1;
|
||||
u32 frameticker;
|
||||
|
||||
#ifdef HW_RVL
|
||||
|
||||
/****************************************************************************
|
||||
* Force AHBPROT flags when IOS is reloaded
|
||||
* Credits to DaveBaol for the original patch
|
||||
***************************************************************************/
|
||||
int Patch_IOS(void)
|
||||
{
|
||||
/* full hardware access is initially required */
|
||||
if (read32(0xd800064) == 0xffffffff)
|
||||
{
|
||||
/* disable MEM2 protection */
|
||||
write16(0xd8b420a, 0);
|
||||
|
||||
/* IOS area (top of MEM2, above IOS Heap area) */
|
||||
u8 *ptr_start = (u8*)*((u32*)0x80003134);
|
||||
u8 *ptr_end = (u8*)0x94000000;
|
||||
|
||||
/* Make sure start pointer is valid */
|
||||
if (((u32)ptr_start < 0x90000000) || (ptr_start >= ptr_end))
|
||||
{
|
||||
/* use libogc default value (longer but safer) */
|
||||
ptr_start = (u8*) SYS_GetArena2Hi();
|
||||
}
|
||||
|
||||
/* Search specific code pattern */
|
||||
const u8 es_set_ahbprot_pattern[] = { 0x68, 0x5B, 0x22, 0xEC, 0x00, 0x52, 0x18, 0x9B, 0x68, 0x1B, 0x46, 0x98, 0x07, 0xDB };
|
||||
while (ptr_start < (ptr_end - sizeof(es_set_ahbprot_pattern)))
|
||||
{
|
||||
if (!memcmp(ptr_start, es_set_ahbprot_pattern, sizeof(es_set_ahbprot_pattern)))
|
||||
{
|
||||
/* patch IOS (force AHBPROT bit to be set when launching titles) */
|
||||
ptr_start[25] = 0x01;
|
||||
DCFlushRange(ptr_start + 25, 1);
|
||||
}
|
||||
ptr_start++; /* could be optimized ? not sure if pattern coincides with instruction start */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Power Button callback
|
||||
***************************************************************************/
|
||||
@ -83,12 +122,12 @@ static void Reset_cb(void)
|
||||
{
|
||||
if (system_hw & SYSTEM_MD)
|
||||
{
|
||||
/* SOFT-RESET */
|
||||
/* Soft Reset */
|
||||
gen_reset(0);
|
||||
}
|
||||
else if (system_hw == SYSTEM_SMS)
|
||||
{
|
||||
/* assert RESET input */
|
||||
/* assert RESET input (Master System model 1 only) */
|
||||
io_reg[0x0D] &= ~IO_RESET_HI;
|
||||
}
|
||||
}
|
||||
@ -97,34 +136,30 @@ static void Reset_cb(void)
|
||||
* Genesis Plus Virtual Machine
|
||||
*
|
||||
***************************************************************************/
|
||||
static void load_bios(void)
|
||||
{
|
||||
/* clear BIOS detection flag */
|
||||
config.tmss &= ~2;
|
||||
|
||||
/* open BIOS file */
|
||||
FILE *fp = fopen(OS_ROM, "rb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* read file */
|
||||
fread(bios_rom, 1, 0x800, fp);
|
||||
fclose(fp);
|
||||
|
||||
/* check ROM file */
|
||||
if (!strncmp((char *)(bios_rom + 0x120),"GENESIS OS", 10))
|
||||
{
|
||||
/* valid BIOS detected */
|
||||
config.tmss |= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void init_machine(void)
|
||||
{
|
||||
/* allocate cart.rom here (10 MBytes) */
|
||||
/* allocate cartridge ROM here (10 MB) */
|
||||
cart.rom = memalign(32, MAXROMSIZE);
|
||||
|
||||
/* BIOS support */
|
||||
load_bios();
|
||||
/* mark all BIOS as unloaded */
|
||||
config.bios &= 0x03;
|
||||
|
||||
/* Genesis BOOT ROM support (2KB max) */
|
||||
memset(boot_rom, 0xFF, 0x800);
|
||||
FILE *fp = fopen(MD_BIOS, "rb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
/* read BOOT ROM */
|
||||
fread(boot_rom, 1, 0x800, fp);
|
||||
fclose(fp);
|
||||
|
||||
/* check BOOT ROM */
|
||||
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
|
||||
{
|
||||
/* mark Genesis BIOS as loaded */
|
||||
config.bios |= SYSTEM_MD;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate global work bitmap */
|
||||
memset(&bitmap, 0, sizeof (bitmap));
|
||||
@ -138,101 +173,29 @@ static void init_machine(void)
|
||||
bitmap.data = texturemem;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
Restart emulation when loading a new game
|
||||
********************************************/
|
||||
static void reload(void)
|
||||
{
|
||||
/* Cartridge Hot Swap (make sure system has already been inited once) */
|
||||
if (config.hot_swap && snd.enabled)
|
||||
{
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
md_cart_init();
|
||||
md_cart_reset(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sms_cart_init();
|
||||
sms_cart_reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize audio emulation */
|
||||
/* To prevent any sound skipping, sound chips must run at the exact same speed as the rest of emulation (see sound.c) */
|
||||
/* When TV output mode matches emulated video mode, we use video hardware interrupt (VSYNC) and exact framerates for perfect synchronization */
|
||||
/* In 60Hz TV modes, Wii & GC framerates have been measured to be 59.94 (interlaced or progressive) and ~59.825 fps (non-interlaced) */
|
||||
/* In 50Hz TV modes, Wii & GC framerates have been measured to be 50.00 (interlaced) and ~50.845 fps (non-interlaced) */
|
||||
/* When modes does not match, emulation is synchronized with audio hardware interrupt (DMA) and we use default framerates (50Hz for PAL, 60Hz for NTSC). */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 0) ? 50.0 : (config.render ? 50.00 : (1000000.0/19968.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 1) ? 60.0 : (config.render ? 59.94 : (1000000.0/16715.0)));
|
||||
}
|
||||
|
||||
/* Switch virtual system on */
|
||||
system_init();
|
||||
system_reset();
|
||||
}
|
||||
|
||||
/* Auto-Load SRAM file */
|
||||
if (config.s_auto & 1)
|
||||
{
|
||||
slot_autoload(0,config.s_device);
|
||||
}
|
||||
|
||||
/* Auto-Load State file */
|
||||
if (config.s_auto & 2)
|
||||
{
|
||||
slot_autoload(config.s_default,config.s_device);
|
||||
}
|
||||
|
||||
/* Load Cheat file */
|
||||
CheatLoad();
|
||||
}
|
||||
|
||||
static void run_emulation(void)
|
||||
{
|
||||
/* main emulation loop */
|
||||
while (1)
|
||||
{
|
||||
/* Main Menu request */
|
||||
if (ConfigRequested)
|
||||
/* emulated system */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
/* stop video & audio */
|
||||
gx_audio_Stop();
|
||||
gx_video_Stop();
|
||||
|
||||
/* show menu */
|
||||
ConfigRequested = 0;
|
||||
if (menu_execute())
|
||||
/* Mega Drive type hardware */
|
||||
while (!ConfigRequested)
|
||||
{
|
||||
/* new ROM has been loaded */
|
||||
reload();
|
||||
}
|
||||
|
||||
/* start video & audio */
|
||||
gx_video_Start();
|
||||
gx_audio_Start();
|
||||
frameticker = 1;
|
||||
}
|
||||
|
||||
/* automatic frame skipping (only necessary for Virtua Racing in Gamecube mode) */
|
||||
/* automatic frame skipping (only needed when running Virtua Racing on Gamecube) */
|
||||
if (frameticker > 1)
|
||||
{
|
||||
/* skip frame */
|
||||
system_frame(1);
|
||||
system_frame_gen(1);
|
||||
frameticker = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* render frame */
|
||||
frameticker = 0;
|
||||
system_frame(0);
|
||||
system_frame_gen(0);
|
||||
|
||||
/* update video */
|
||||
gx_video_Update();
|
||||
@ -269,6 +232,125 @@ static void run_emulation(void)
|
||||
while (frameticker < 1) usleep(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Master System type hardware */
|
||||
while (!ConfigRequested)
|
||||
{
|
||||
/* render frame (no frameskipping needed) */
|
||||
frameticker = 0;
|
||||
system_frame_sms(0);
|
||||
|
||||
/* update video */
|
||||
gx_video_Update();
|
||||
|
||||
/* update audio */
|
||||
gx_audio_Update();
|
||||
|
||||
/* check interlaced mode change */
|
||||
if (bitmap.viewport.changed & 4)
|
||||
{
|
||||
/* VSYNC "original" mode */
|
||||
if (!config.render && (gc_pal == vdp_pal))
|
||||
{
|
||||
/* framerate has changed, reinitialize audio timings */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, interlaced ? 50.00 : (1000000.0/19968.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, interlaced ? 59.94 : (1000000.0/16715.0));
|
||||
}
|
||||
|
||||
/* reinitialize sound chips */
|
||||
sound_restore();
|
||||
}
|
||||
|
||||
/* clear flag */
|
||||
bitmap.viewport.changed &= ~4;
|
||||
}
|
||||
|
||||
/* wait for next frame */
|
||||
while (frameticker < 1) usleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* stop video & audio */
|
||||
gx_audio_Stop();
|
||||
gx_video_Stop();
|
||||
|
||||
/* show menu */
|
||||
ConfigRequested = 0;
|
||||
mainmenu();
|
||||
|
||||
/* restart video & audio */
|
||||
gx_video_Start();
|
||||
gx_audio_Start();
|
||||
frameticker = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
Restart emulation when loading a new game
|
||||
********************************************/
|
||||
void reloadrom(void)
|
||||
{
|
||||
/* Cartridge Hot Swap (make sure system has already been inited once) */
|
||||
if (config.hot_swap == 3)
|
||||
{
|
||||
/* Initialize cartridge hardware only */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
md_cart_init();
|
||||
md_cart_reset(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sms_cart_init();
|
||||
sms_cart_reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize audio emulation */
|
||||
/* To prevent any sound skipping, sound chips must run at the exact same speed as the rest of emulation (see sound.c) */
|
||||
/* When TV output mode matches emulated video mode, we use video hardware interrupt (VSYNC) and exact framerates for perfect synchronization */
|
||||
/* In 60Hz TV modes, Wii & GC framerates have been measured to be 59.94 (interlaced or progressive) and ~59.825 fps (non-interlaced) */
|
||||
/* In 50Hz TV modes, Wii & GC framerates have been measured to be 50.00 (interlaced) and ~50.845 fps (non-interlaced) */
|
||||
/* When modes does not match, emulation is synchronized with audio hardware interrupt (DMA) and we use default framerates (50Hz for PAL, 60Hz for NTSC). */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 0) ? 50.0 : (config.render ? 50.00 : (1000000.0/19968.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 1) ? 60.0 : (config.render ? 59.94 : (1000000.0/16715.0)));
|
||||
}
|
||||
|
||||
/* Switch virtual system on */
|
||||
system_init();
|
||||
system_reset();
|
||||
|
||||
/* Allow hot swap */
|
||||
config.hot_swap |= 2;
|
||||
}
|
||||
|
||||
/* Auto-Load SRAM file */
|
||||
if (config.s_auto & 1)
|
||||
{
|
||||
slot_autoload(0,config.s_device);
|
||||
}
|
||||
|
||||
/* Auto-Load State file */
|
||||
if (config.s_auto & 2)
|
||||
{
|
||||
slot_autoload(config.s_default,config.s_device);
|
||||
}
|
||||
|
||||
/* Load Cheat file */
|
||||
CheatLoad();
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
Shutdown everything properly
|
||||
@ -302,6 +384,18 @@ void shutdown(void)
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
/* Temporary fix for HBC bug when using no_ios_reload with no connected network */
|
||||
/* Try to patch current IOS to force AHBPROT flags being set on reload */
|
||||
if (Patch_IOS())
|
||||
{
|
||||
/* reload IOS (full hardware access should now be preserved after reload) */
|
||||
IOS_ReloadIOS(IOS_GetVersion());
|
||||
|
||||
/* enable DVD video commands */
|
||||
write32(0xd800180, read32(0xd800180) & ~0x00200000);
|
||||
usleep(200000);
|
||||
}
|
||||
|
||||
/* enable 64-byte fetch mode for L2 cache */
|
||||
L2Enhance();
|
||||
|
||||
@ -422,11 +516,11 @@ int main (int argc, char *argv[])
|
||||
if (config.autoload)
|
||||
{
|
||||
SILENT = 1;
|
||||
if (OpenDirectory(TYPE_RECENT))
|
||||
if (OpenDirectory(TYPE_RECENT, -1))
|
||||
{
|
||||
if (LoadFile(0))
|
||||
{
|
||||
reload();
|
||||
reloadrom();
|
||||
gx_video_Start();
|
||||
gx_audio_Start();
|
||||
frameticker = 1;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <unistd.h>
|
||||
#include <asndlib.h>
|
||||
#include <oggplayer.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <di/di.h>
|
||||
@ -27,22 +28,23 @@
|
||||
#define DEFAULT_PATH "/genplus"
|
||||
#define GG_ROM "/genplus/ggenie.bin"
|
||||
#define AR_ROM "/genplus/areplay.bin"
|
||||
#define OS_ROM "/genplus/bios.bin"
|
||||
#define SK_ROM "/genplus/sk.bin"
|
||||
#define SK_UPMEM "/genplus/sk2chip.bin"
|
||||
#define MD_BIOS "/genplus/bios.bin"
|
||||
#define MS_BIOS "/genplus/bios.sms"
|
||||
#define GG_BIOS "/genplus/bios.gg"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#define VERSION "Genesis Plus GX 1.6.0 (WII)"
|
||||
#define VERSION "Genesis Plus GX 1.6.1 (WII)"
|
||||
#else
|
||||
#define VERSION "Genesis Plus GX 1.6.0 (GCN)"
|
||||
#define VERSION "Genesis Plus GX 1.6.1 (GCN)"
|
||||
#endif
|
||||
|
||||
#define osd_input_Update() gx_input_UpdateEmu()
|
||||
|
||||
/* globals */
|
||||
extern void error(char *format, ...);
|
||||
extern void legal(void);
|
||||
extern void reloadrom (char *name);
|
||||
extern void reloadrom(void);
|
||||
extern void shutdown(void);
|
||||
extern u32 frameticker;
|
||||
extern u32 Shutdown;
|
||||
|
@ -256,7 +256,7 @@ void io_reset(void)
|
||||
/* Reset I/O registers */
|
||||
if (system_hw == SYSTEM_MD)
|
||||
{
|
||||
io_reg[0x00] = 0x20 | region_code | (config.tmss & 1);
|
||||
io_reg[0x00] = region_code | 0x20 | (config.bios & 1);
|
||||
io_reg[0x01] = 0x00;
|
||||
io_reg[0x02] = 0x00;
|
||||
io_reg[0x03] = 0x00;
|
||||
@ -429,24 +429,11 @@ void io_z80_write(unsigned int offset, unsigned int data, unsigned int cycles)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Memory Control register */
|
||||
if (data & 0x40)
|
||||
{
|
||||
/* Assume only BIOS would disable Cartridge ROM */
|
||||
if (data & 0x08)
|
||||
{
|
||||
/* BIOS ROM disabled */
|
||||
sms_cart_switch(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* BIOS ROM enabled */
|
||||
sms_cart_switch(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update Memory Control register */
|
||||
io_reg[0x0E] = data;
|
||||
|
||||
/* Switch cartridge & BIOS ROM */
|
||||
sms_cart_switch(~data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "macros.h"
|
||||
|
@ -38,20 +38,9 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
int state_load(unsigned char *buffer)
|
||||
int state_load(unsigned char *state)
|
||||
{
|
||||
/* 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);
|
||||
outbytes = STATE_SIZE;
|
||||
uncompress ((Bytef *)state, &outbytes, (Bytef *)(buffer + 4), inbytes);
|
||||
int i, bufferptr = 0;
|
||||
|
||||
/* signature check (GENPLUS-GX x.x.x) */
|
||||
char version[17];
|
||||
@ -59,21 +48,30 @@ int state_load(unsigned char *buffer)
|
||||
version[16] = 0;
|
||||
if (strncmp(version,STATE_VERSION,11))
|
||||
{
|
||||
free(state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* version check (1.5.0 and above) */
|
||||
if ((version[11] < 0x31) || ((version[11] == 0x31) && (version[13] < 0x35)))
|
||||
/* version check (1.6.0 and above) */
|
||||
if ((version[11] < 0x31) || ((version[11] == 0x31) && (version[13] < 0x36)))
|
||||
{
|
||||
free(state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* reset system */
|
||||
system_reset();
|
||||
|
||||
// GENESIS
|
||||
/* enable VDP access for TMSS systems */
|
||||
for (i=0xc0; i<0xe0; i+=8)
|
||||
{
|
||||
m68k_memory_map[i].read8 = vdp_read_byte;
|
||||
m68k_memory_map[i].read16 = vdp_read_word;
|
||||
m68k_memory_map[i].write8 = vdp_write_byte;
|
||||
m68k_memory_map[i].write16 = vdp_write_word;
|
||||
zbank_memory_map[i].read = zbank_read_vdp;
|
||||
zbank_memory_map[i].write = zbank_write_vdp;
|
||||
}
|
||||
|
||||
/* GENESIS */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
load_param(work_ram, sizeof(work_ram));
|
||||
@ -100,28 +98,34 @@ int state_load(unsigned char *buffer)
|
||||
load_param(work_ram, 0x2000);
|
||||
}
|
||||
|
||||
/* extended state */
|
||||
/* CPU cycles */
|
||||
load_param(&mcycles_68k, sizeof(mcycles_68k));
|
||||
load_param(&mcycles_z80, sizeof(mcycles_z80));
|
||||
|
||||
// IO
|
||||
/* IO */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
load_param(io_reg, sizeof(io_reg));
|
||||
io_reg[0] = region_code | 0x20 | (config.tmss & 1);
|
||||
io_reg[0] = region_code | 0x20 | (config.bios & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 1.6.1 specific (keep support for previous state format) */
|
||||
if ((version[11] == 0x31) && (version[13] == 0x36) && (version[15] == 0x31))
|
||||
{
|
||||
load_param(&io_reg[0x0E], 1);
|
||||
}
|
||||
|
||||
load_param(&io_reg[0x0F], 1);
|
||||
}
|
||||
|
||||
// VDP
|
||||
bufferptr += vdp_context_load(&state[bufferptr], version);
|
||||
/* VDP */
|
||||
bufferptr += vdp_context_load(&state[bufferptr]);
|
||||
|
||||
// SOUND
|
||||
bufferptr += sound_context_load(&state[bufferptr], version);
|
||||
/* SOUND */
|
||||
bufferptr += sound_context_load(&state[bufferptr]);
|
||||
|
||||
// 68000
|
||||
/* 68000 */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
uint16 tmp16;
|
||||
@ -147,11 +151,11 @@ int state_load(unsigned char *buffer)
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
|
||||
}
|
||||
|
||||
// Z80
|
||||
/* Z80 */
|
||||
load_param(&Z80, sizeof(Z80_Regs));
|
||||
Z80.irq_callback = z80_irq_callback;
|
||||
|
||||
// Cartridge HW
|
||||
/* Cartridge HW */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
bufferptr += md_cart_context_load(&state[bufferptr]);
|
||||
@ -159,27 +163,28 @@ int state_load(unsigned char *buffer)
|
||||
else
|
||||
{
|
||||
bufferptr += sms_cart_context_load(&state[bufferptr]);
|
||||
|
||||
/* 1.6.1 specific (keep support for previous state format) */
|
||||
if ((version[11] == 0x31) && (version[13] == 0x36) && (version[15] == 0x31))
|
||||
{
|
||||
sms_cart_switch(~io_reg[0x0E]);
|
||||
}
|
||||
}
|
||||
|
||||
free(state);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int state_save(unsigned char *buffer)
|
||||
int state_save(unsigned char *state)
|
||||
{
|
||||
/* 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);
|
||||
save_param(version, 16);
|
||||
|
||||
// GENESIS
|
||||
/* GENESIS */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
save_param(work_ram, sizeof(work_ram));
|
||||
@ -191,26 +196,29 @@ int state_save(unsigned char *buffer)
|
||||
{
|
||||
save_param(work_ram, 0x2000);
|
||||
}
|
||||
|
||||
/* CPU cycles */
|
||||
save_param(&mcycles_68k, sizeof(mcycles_68k));
|
||||
save_param(&mcycles_z80, sizeof(mcycles_z80));
|
||||
|
||||
// IO
|
||||
/* IO */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
save_param(io_reg, sizeof(io_reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
save_param(&io_reg[0x0E], 1);
|
||||
save_param(&io_reg[0x0F], 1);
|
||||
}
|
||||
|
||||
// VDP
|
||||
/* VDP */
|
||||
bufferptr += vdp_context_save(&state[bufferptr]);
|
||||
|
||||
// SOUND
|
||||
/* SOUND */
|
||||
bufferptr += sound_context_save(&state[bufferptr]);
|
||||
|
||||
// 68000
|
||||
/* 68000 */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
uint16 tmp16;
|
||||
@ -236,10 +244,10 @@ int state_save(unsigned char *buffer)
|
||||
tmp32 = m68k_get_reg(M68K_REG_USP); save_param(&tmp32, 4);
|
||||
}
|
||||
|
||||
// Z80
|
||||
/* Z80 */
|
||||
save_param(&Z80, sizeof(Z80_Regs));
|
||||
|
||||
// Cartridge HW
|
||||
/* Cartridge HW */
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
bufferptr += md_cart_context_save(&state[bufferptr]);
|
||||
@ -249,13 +257,6 @@ int state_save(unsigned char *buffer)
|
||||
bufferptr += sms_cart_context_save(&state[bufferptr]);
|
||||
}
|
||||
|
||||
/* compress state file */
|
||||
unsigned long inbytes = bufferptr;
|
||||
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);
|
||||
return bufferptr;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@
|
||||
#define _STATE_H_
|
||||
|
||||
#define STATE_SIZE 0x48100
|
||||
#define STATE_VERSION "GENPLUS-GX 1.6.0"
|
||||
#define STATE_VERSION "GENPLUS-GX 1.6.1"
|
||||
|
||||
#define load_param(param, size) \
|
||||
memcpy(param, &state[bufferptr], size); \
|
||||
@ -51,7 +51,7 @@
|
||||
bufferptr+= size;
|
||||
|
||||
/* Function prototypes */
|
||||
extern int state_load(unsigned char *buffer);
|
||||
extern int state_save(unsigned char *buffer);
|
||||
extern int state_load(unsigned char *state);
|
||||
extern int state_save(unsigned char *state);
|
||||
|
||||
#endif
|
||||
|
@ -49,11 +49,9 @@ t_snd snd;
|
||||
uint32 mcycles_vdp;
|
||||
uint32 mcycles_z80;
|
||||
uint32 mcycles_68k;
|
||||
int16 SVP_cycles = 800;
|
||||
uint8 system_hw;
|
||||
void (*system_frame)(int do_skip);
|
||||
|
||||
static void system_frame_gen(int do_skip);
|
||||
static void system_frame_sms(int do_skip);
|
||||
static uint8 pause_b;
|
||||
static EQSTATE eq;
|
||||
static int32 llp,rrp;
|
||||
@ -77,11 +75,11 @@ int audio_init (int samplerate, float framerate)
|
||||
/* Calculate the sound buffer size (for one frame) */
|
||||
snd.buffer_size = (int)(samplerate / framerate) + 32;
|
||||
|
||||
/* SN76489 stream buffers */
|
||||
/* SN76489 stream buffer */
|
||||
snd.psg.buffer = (int16 *) malloc(snd.buffer_size * sizeof(int16));
|
||||
if (!snd.psg.buffer) return (-1);
|
||||
|
||||
/* YM2612 stream buffers */
|
||||
/* YM2612 stream buffer */
|
||||
snd.fm.buffer = (int32 *) malloc(snd.buffer_size * sizeof(int32) * 2);
|
||||
if (!snd.fm.buffer) return (-1);
|
||||
|
||||
@ -234,8 +232,8 @@ int audio_update (void)
|
||||
|
||||
/* update sound buffer */
|
||||
#ifndef NGC
|
||||
snd.buffer[0][i] = r;
|
||||
snd.buffer[1][i] = l;
|
||||
snd.buffer[0][i] = l;
|
||||
snd.buffer[1][i] = r;
|
||||
#else
|
||||
*sb++ = r;
|
||||
*sb++ = l;
|
||||
@ -267,22 +265,6 @@ void system_init(void)
|
||||
vdp_init();
|
||||
render_init();
|
||||
sound_init();
|
||||
|
||||
switch (system_hw)
|
||||
{
|
||||
case SYSTEM_MD:
|
||||
case SYSTEM_PICO:
|
||||
{
|
||||
system_frame = system_frame_gen;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
system_frame = system_frame_sms;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
@ -304,10 +286,10 @@ void system_shutdown (void)
|
||||
SN76489_Shutdown();
|
||||
}
|
||||
|
||||
static void system_frame_gen(int do_skip)
|
||||
void system_frame_gen(int do_skip)
|
||||
{
|
||||
/* line counter */
|
||||
int line = 0;
|
||||
/* line counters */
|
||||
int start, end, line = 0;
|
||||
|
||||
/* Z80 interrupt flag */
|
||||
int zirq = 1;
|
||||
@ -331,11 +313,10 @@ static void system_frame_gen(int do_skip)
|
||||
/* display changed during VBLANK */
|
||||
if (bitmap.viewport.changed & 2)
|
||||
{
|
||||
bitmap.viewport.changed &= ~2;
|
||||
|
||||
/* interlaced modes */
|
||||
int old_interlaced = interlaced;
|
||||
interlaced = (reg[12] & 0x02) >> 1;
|
||||
|
||||
if (old_interlaced != interlaced)
|
||||
{
|
||||
/* double resolution mode */
|
||||
@ -362,6 +343,11 @@ static void system_frame_gen(int do_skip)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clear flag */
|
||||
bitmap.viewport.changed &= ~2;
|
||||
}
|
||||
|
||||
/* active screen height */
|
||||
if (reg[1] & 0x04)
|
||||
@ -494,8 +480,8 @@ static void system_frame_gen(int do_skip)
|
||||
status |= 0x08;
|
||||
|
||||
/* overscan area */
|
||||
int start = lines_per_frame - bitmap.viewport.y;
|
||||
int end = bitmap.viewport.h + bitmap.viewport.y;
|
||||
start = lines_per_frame - bitmap.viewport.y;
|
||||
end = bitmap.viewport.h + bitmap.viewport.y;
|
||||
|
||||
/* check viewport changes */
|
||||
if ((bitmap.viewport.w != bitmap.viewport.ow) || (bitmap.viewport.h != bitmap.viewport.oh))
|
||||
@ -646,10 +632,10 @@ static void system_frame_gen(int do_skip)
|
||||
}
|
||||
|
||||
|
||||
static void system_frame_sms(int do_skip)
|
||||
void system_frame_sms(int do_skip)
|
||||
{
|
||||
/* line counter */
|
||||
int line = 0;
|
||||
int start, end, line = 0;
|
||||
|
||||
/* reload H Counter */
|
||||
int h_counter = reg[10];
|
||||
@ -774,7 +760,7 @@ static void system_frame_sms(int do_skip)
|
||||
}
|
||||
|
||||
/* 3-D glasses faking: skip rendering of left lens frame */
|
||||
do_skip |= (work_ram[0x1ffb] & cart.special);
|
||||
do_skip |= (work_ram[0x1ffb] & cart.special & HW_3D_GLASSES);
|
||||
|
||||
/* Mega Drive VDP specific */
|
||||
if (system_hw & SYSTEM_MD)
|
||||
@ -894,8 +880,8 @@ static void system_frame_sms(int do_skip)
|
||||
}
|
||||
|
||||
/* overscan area */
|
||||
int start = lines_per_frame - bitmap.viewport.y;
|
||||
int end = bitmap.viewport.h + bitmap.viewport.y;
|
||||
start = lines_per_frame - bitmap.viewport.y;
|
||||
end = bitmap.viewport.h + bitmap.viewport.y;
|
||||
|
||||
/* check viewport changes */
|
||||
if ((bitmap.viewport.w != bitmap.viewport.ow) || (bitmap.viewport.h != bitmap.viewport.oh))
|
||||
|
@ -104,6 +104,7 @@ extern t_snd snd;
|
||||
extern uint32 mcycles_z80;
|
||||
extern uint32 mcycles_68k;
|
||||
extern uint32 mcycles_vdp;
|
||||
extern int16 SVP_cycles;
|
||||
extern uint8 system_hw;
|
||||
|
||||
/* Function prototypes */
|
||||
@ -115,7 +116,8 @@ extern void audio_set_equalizer(void);
|
||||
extern void system_init(void);
|
||||
extern void system_reset(void);
|
||||
extern void system_shutdown(void);
|
||||
extern void (*system_frame)(int do_skip);
|
||||
extern void system_frame_gen(int do_skip);
|
||||
extern void system_frame_sms(int do_skip);
|
||||
|
||||
#endif /* _SYSTEM_H_ */
|
||||
|
||||
|
@ -29,9 +29,8 @@ void set_config_defaults(void)
|
||||
config.region_detect = 0; /* = AUTO (1 = USA, 2 = EUROPE, 3 = JAPAN/NTSC, 4 = JAPAN/PAL) */
|
||||
config.force_dtack = 0;
|
||||
config.addr_error = 1;
|
||||
config.tmss = 0;
|
||||
config.bios = 0;
|
||||
config.lock_on = 0; /* = OFF (can be TYPE_SK, TYPE_GG & TYPE_AR) */
|
||||
config.romtype = 0; /* ROM mirroring type (see md_cart_hw.c) */
|
||||
|
||||
/* display options */
|
||||
config.overscan = 3; /* = both ON (0 = no borders , 1 = vertical borders only, 2 = horizontal borders only) */
|
||||
|
@ -32,9 +32,9 @@ typedef struct
|
||||
uint8 force_dtack;
|
||||
uint8 addr_error;
|
||||
uint8 tmss;
|
||||
uint8 bios;
|
||||
uint8 lock_on;
|
||||
uint8 hot_swap;
|
||||
uint8 romtype;
|
||||
uint8 invert_mouse;
|
||||
uint8 gun_cursor[2];
|
||||
uint8 overscan;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "osd.h"
|
||||
|
||||
FILE *error_log;
|
||||
static FILE *error_log;
|
||||
|
||||
void error_init(void)
|
||||
{
|
||||
@ -16,15 +16,20 @@ void error_init(void)
|
||||
|
||||
void error_shutdown(void)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
if(error_log) fclose(error_log);
|
||||
#endif
|
||||
}
|
||||
|
||||
void error(char *format, ...)
|
||||
{
|
||||
if (!log_error) return;
|
||||
#ifdef LOGERROR
|
||||
if (log_error)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
if(error_log) vfprintf(error_log, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
|
||||
#ifndef _ERROR_H_
|
||||
#define _ERROR_H_
|
||||
|
||||
/* Global variables */
|
||||
FILE *error_log;
|
||||
|
||||
/* Function prototypes */
|
||||
void error_init(void);
|
||||
void error_shutdown(void);
|
||||
void error(char *format, ...);
|
||||
|
||||
#endif /* _ERROR_H_ */
|
||||
|
||||
|
@ -44,6 +44,9 @@
|
||||
#include <windows.h>
|
||||
#include <zlib.h>
|
||||
|
||||
static int check_zip(char *filename);
|
||||
static int gzsize(gzFile *gd);
|
||||
|
||||
int load_archive(char *filename)
|
||||
{
|
||||
int size = 0;
|
||||
@ -147,7 +150,7 @@ int load_archive(char *filename)
|
||||
Verifies if a file is a ZIP archive or not.
|
||||
Returns: 1= ZIP archive, 0= not a ZIP archive
|
||||
*/
|
||||
int check_zip(char *filename)
|
||||
static int check_zip(char *filename)
|
||||
{
|
||||
uint8 buf[2];
|
||||
FILE *fd = fopen(filename, "rb");
|
||||
@ -162,7 +165,7 @@ int check_zip(char *filename)
|
||||
/*
|
||||
Returns the size of a GZ compressed file.
|
||||
*/
|
||||
int gzsize(gzFile *gd)
|
||||
static int gzsize(gzFile *gd)
|
||||
{
|
||||
#define CHUNKSIZE (0x10000)
|
||||
int size = 0, length = 0;
|
||||
|
@ -43,8 +43,6 @@
|
||||
#define _FILEIO_H_
|
||||
|
||||
/* Function prototypes */
|
||||
int load_archive(char *filename);
|
||||
int check_zip(char *filename);
|
||||
int gzsize(gzFile *gd);
|
||||
extern int load_archive(char *filename);
|
||||
|
||||
#endif /* _FILEIO_H_ */
|
||||
|
@ -144,7 +144,14 @@ static int sdl_video_init()
|
||||
|
||||
static void sdl_video_update()
|
||||
{
|
||||
system_frame(0);
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
system_frame_gen(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
system_frame_sms(0);
|
||||
}
|
||||
|
||||
/* viewport size changed */
|
||||
if(bitmap.viewport.changed & 1)
|
||||
@ -240,8 +247,8 @@ struct {
|
||||
|
||||
static Uint32 sdl_sync_timer_callback(Uint32 interval)
|
||||
{
|
||||
SDL_SemPost(sdl_sync.sem_sync);
|
||||
char caption[100];
|
||||
SDL_SemPost(sdl_sync.sem_sync);
|
||||
sdl_sync.ticks++;
|
||||
if (sdl_sync.ticks == (vdp_pal ? 50 : 20))
|
||||
{
|
||||
@ -302,7 +309,10 @@ static int sdl_control_update(SDLKey keystate)
|
||||
|
||||
case SDLK_F3:
|
||||
{
|
||||
config.render ^=1;
|
||||
int temp = config.bios & 3;
|
||||
config.bios &= ~3;
|
||||
if (temp == 0) config.bios |= 3;
|
||||
else if (temp == 3) config.bios |= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -352,14 +362,11 @@ static int sdl_control_update(SDLKey keystate)
|
||||
|
||||
case SDLK_F9:
|
||||
{
|
||||
vdp_pal ^= 1;
|
||||
|
||||
/* reset region code */
|
||||
region_code &= ~0x40;
|
||||
region_code |= (vdp_pal << 6);
|
||||
config.region_detect = (config.region_detect + 1) % 5;
|
||||
region_autodetect();
|
||||
if (system_hw == SYSTEM_MD)
|
||||
{
|
||||
io_reg[0x00] = 0x20 | region_code | (config.tmss & 1);
|
||||
io_reg[0x00] = 0x20 | region_code | (config.bios & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -369,9 +376,6 @@ static int sdl_control_update(SDLKey keystate)
|
||||
/* reinitialize audio timings */
|
||||
audio_init(snd.sample_rate, snd.frame_rate);
|
||||
|
||||
/* reinitialize sound emulation */
|
||||
sound_restore();
|
||||
|
||||
/* reintialize VDP */
|
||||
vdp_init();
|
||||
|
||||
@ -395,8 +399,8 @@ static int sdl_control_update(SDLKey keystate)
|
||||
break;
|
||||
}
|
||||
|
||||
/* reinitialize display area */
|
||||
bitmap.viewport.changed = 3;
|
||||
/* reinitialize sound emulation */
|
||||
sound_restore();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -636,6 +640,7 @@ int sdl_input_update(void)
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
int running = 1;
|
||||
|
||||
/* Print help if no game specified */
|
||||
@ -662,23 +667,37 @@ int main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* load BIOS */
|
||||
memset(bios_rom, 0, sizeof(bios_rom));
|
||||
FILE *f = fopen(OS_ROM, "rb");
|
||||
if (f!=NULL)
|
||||
/* mark all BIOS as unloaded */
|
||||
config.bios &= 0x01;
|
||||
|
||||
/* Genesis BOOT ROM support (2KB max) */
|
||||
memset(boot_rom, 0xFF, 0x800);
|
||||
fp = fopen(MD_BIOS, "rb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
fread(&bios_rom, 0x800,1,f);
|
||||
fclose(f);
|
||||
int i;
|
||||
|
||||
/* read BOOT ROM */
|
||||
fread(boot_rom, 1, 0x800, fp);
|
||||
fclose(fp);
|
||||
|
||||
/* check BOOT ROM */
|
||||
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
|
||||
{
|
||||
/* mark Genesis BIOS as loaded */
|
||||
config.bios |= SYSTEM_MD;
|
||||
}
|
||||
|
||||
/* Byteswap ROM */
|
||||
for (i=0; i<0x800; i+=2)
|
||||
{
|
||||
uint8 temp = bios_rom[i];
|
||||
bios_rom[i] = bios_rom[i+1];
|
||||
bios_rom[i+1] = temp;
|
||||
uint8 temp = boot_rom[i];
|
||||
boot_rom[i] = boot_rom[i+1];
|
||||
boot_rom[i+1] = temp;
|
||||
}
|
||||
config.tmss |= 2;
|
||||
}
|
||||
|
||||
|
||||
/* initialize SDL */
|
||||
if(SDL_Init(0) < 0)
|
||||
{
|
||||
@ -714,11 +733,11 @@ int main (int argc, char **argv)
|
||||
system_init();
|
||||
|
||||
/* load SRAM */
|
||||
f = fopen("./game.srm", "rb");
|
||||
if (f!=NULL)
|
||||
fp = fopen("./game.srm", "rb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fread(sram.sram,0x10000,1, f);
|
||||
fclose(f);
|
||||
fread(sram.sram,0x10000,1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* reset emulation */
|
||||
@ -759,11 +778,11 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
/* save SRAM */
|
||||
f = fopen("./game.srm", "wb");
|
||||
if (f!=NULL)
|
||||
fp = fopen("./game.srm", "wb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fwrite(sram.sram,0x10000,1, f);
|
||||
fclose(f);
|
||||
fwrite(sram.sram,0x10000,1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
system_shutdown();
|
||||
|
@ -6,5 +6,6 @@
|
||||
|
||||
extern int debug_on;
|
||||
extern int log_error;
|
||||
extern int sdl_input_update(void);
|
||||
|
||||
#endif /* _MAIN_H_ */
|
||||
|
@ -22,8 +22,10 @@
|
||||
|
||||
#define GG_ROM "./ggenie.bin"
|
||||
#define AR_ROM "./areplay.bin"
|
||||
#define OS_ROM "./bios.bin"
|
||||
#define SK_ROM "./sk.bin"
|
||||
#define SK_UPMEM "./sk2chip.bin"
|
||||
#define MD_BIOS "./bios.bin"
|
||||
#define MS_BIOS "./bios.sms"
|
||||
#define GG_BIOS "./bios.gg"
|
||||
|
||||
#endif /* _OSD_H_ */
|
||||
|