Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 17f423cfbd | |||
| 975a3e3266 | |||
| 17788c3ddd | |||
| 15af996d79 | |||
| 2c0279c0ac |
Binary file not shown.
@@ -47,6 +47,8 @@
|
||||
static const double pal_fps = 53203424.0 / (3420.0 * 313.0);
|
||||
static const double ntsc_fps = 53693175.0 / (3420.0 * 262.0);
|
||||
|
||||
t_config config;
|
||||
|
||||
char GG_ROM[256];
|
||||
char AR_ROM[256];
|
||||
char SK_ROM[256];
|
||||
|
||||
@@ -126,10 +126,10 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
|
||||
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
089C167EFE841241C02AAC07 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
82287C08101E9C2C0072172D /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
|
||||
82287C33101E9DB40072172D /* GenPlusGameCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenPlusGameCore.h; sourceTree = "<group>"; };
|
||||
82287C34101E9DB40072172D /* GenPlusGameCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GenPlusGameCore.m; sourceTree = "<group>"; };
|
||||
@@ -258,7 +258,7 @@
|
||||
94ED8A8714CF933700FF8901 /* z80.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = z80.h; sourceTree = "<group>"; };
|
||||
C6B948191365164700A425F0 /* OEGenesisSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEGenesisSystemResponderClient.h; path = ../OpenEmu/Genesis/OEGenesisSystemResponderClient.h; sourceTree = "<group>"; };
|
||||
C6D120F1171130E700E868A8 /* OpenEmuBase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OpenEmuBase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -575,10 +575,9 @@
|
||||
};
|
||||
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "GenesisPlus" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = 089C166AFE841209C02AAC07 /* GenesisPlus */;
|
||||
@@ -715,7 +714,7 @@
|
||||
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
089C167EFE841241C02AAC07 /* English */,
|
||||
089C167EFE841241C02AAC07 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.7.4.11</string>
|
||||
<string>1.7.4.13</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>OEGameCoreController</string>
|
||||
<key>OEGameCoreClass</key>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* Mega Drive cartridge hardware support
|
||||
*
|
||||
* Copyright (C) 2007-2019 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Many cartridge protections were initially documented by Haze
|
||||
* (http://haze.mameworld.info/)
|
||||
@@ -74,7 +74,11 @@ static void mapper_seganet_w(uint32 address, uint32 data);
|
||||
static void mapper_32k_w(uint32 data);
|
||||
static void mapper_64k_w(uint32 data);
|
||||
static void mapper_64k_multi_w(uint32 address);
|
||||
static uint32 mapper_radica_r(uint32 address);
|
||||
static uint32 mapper_128k_multi_r(uint32 address);
|
||||
static void mapper_256k_multi_w(uint32 address, uint32 data);
|
||||
static void mapper_wd1601_w(uint32 address, uint32 data);
|
||||
static uint32 mapper_64k_radica_r(uint32 address);
|
||||
static uint32 mapper_128k_radica_r(uint32 address);
|
||||
static void default_time_w(uint32 address, uint32 data);
|
||||
static void default_regs_w(uint32 address, uint32 data);
|
||||
static uint32 default_regs_r(uint32 address);
|
||||
@@ -102,13 +106,26 @@ static const md_entry_t rom_database[] =
|
||||
/* Tom Clown */
|
||||
{0x0000,0xc0cd,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}},
|
||||
|
||||
/* 1800-in-1 */
|
||||
{0x3296,0x2370,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,mapper_128k_multi_r,m68k_unused_8_w,NULL,NULL}},
|
||||
|
||||
/* Golden Mega 250-in-1 */
|
||||
{0xe43c,0x886f,0x08,0x08,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,NULL,m68k_unused_8_w,NULL,mapper_256k_multi_w}},
|
||||
|
||||
/* RADICA (Volume 1) (bad dump ?) */
|
||||
{0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,mapper_radica_r,NULL,NULL,NULL}},
|
||||
{0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,mapper_64k_radica_r,m68k_unused_8_w,NULL,NULL}},
|
||||
/* RADICA (Volume 1) */
|
||||
{0x24f4,0xfc84,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}},
|
||||
{0x24f4,0xfc84,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_64k_radica_r,m68k_unused_8_w,NULL,NULL}},
|
||||
/* RADICA (Volume 2) */
|
||||
{0x104f,0x32e9,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}},
|
||||
{0xd951,0x78d0,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_64k_radica_r,m68k_unused_8_w,NULL,NULL}},
|
||||
/* RADICA (Volume 3 - Super Sonic Gold edition) */
|
||||
{0x0000,0x1f25,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_64k_radica_r,m68k_unused_8_w,NULL,NULL}},
|
||||
/* RADICA (Street Fighter II CE edition) */
|
||||
{0x1add,0xa838,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_64k_radica_r,m68k_unused_8_w,NULL,NULL}},
|
||||
/* RADICA (Street Fighter II CE edition) (PAL) */
|
||||
{0x104f,0x32e9,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_64k_radica_r,m68k_unused_8_w,NULL,NULL}},
|
||||
/* RADICA (Sensible Soccer Plus edition) (PAL) */
|
||||
{0x0000,0x1f7f,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_128k_radica_r,m68k_unused_8_w,NULL,NULL}},
|
||||
|
||||
|
||||
/* Tenchi wo Kurau III: Sangokushi Gaiden - Chinese Fighter */
|
||||
@@ -391,11 +408,12 @@ void md_cart_init(void)
|
||||
zbank_memory_map[sram.start >> 16].write = sram_write_byte;
|
||||
}
|
||||
|
||||
/* support for Triple Play 96 & Triple Play - Gold Edition (available ROM dumps include dumped SRAM data) */
|
||||
/* support for Triple Play 96 & Triple Play - Gold Edition mapping */
|
||||
else if ((strstr(rominfo.product,"T-172026") != NULL) || (strstr(rominfo.product,"T-172116") != NULL))
|
||||
{
|
||||
/* $000000-$1fffff and $300000-$3fffff: cartridge ROM (2MB + 1MB) */
|
||||
/* $200000-$2fffff: SRAM (32 KB mirrored) */
|
||||
/* $000000-$1fffff: cartridge ROM (lower 2MB) */
|
||||
/* $200000-$2fffff: SRAM (32KB mirrored) */
|
||||
/* NB: existing 4MB ROM dumps include SRAM data at ROM offsets 0x200000-0x2fffff */
|
||||
for (i=0x20; i<0x30; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = sram.sram;
|
||||
@@ -406,6 +424,16 @@ void md_cart_init(void)
|
||||
zbank_memory_map[i].read = sram_read_byte;
|
||||
zbank_memory_map[i].write = sram_write_byte;
|
||||
}
|
||||
|
||||
/* $300000-$3fffff: cartridge ROM (upper 1MB) */
|
||||
/* NB: only real (3MB) Mask ROM dumps need ROM offsets 0x200000-0x2fffff to be remapped to this area */
|
||||
if (READ_BYTE(cart.rom, 0x200000) != 0xFF)
|
||||
{
|
||||
for (i=0x30; i<0x40; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = cart.rom + ((i - 0x10) << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,7 +449,7 @@ void md_cart_init(void)
|
||||
/**********************************************
|
||||
LOCK-ON
|
||||
***********************************************/
|
||||
|
||||
|
||||
/* clear existing patches */
|
||||
ggenie_shutdown();
|
||||
areplay_shutdown();
|
||||
@@ -454,7 +482,7 @@ void md_cart_init(void)
|
||||
{
|
||||
/* try to load Sonic 2 & Knuckles UPMEM ROM (256 KB) */
|
||||
if (load_archive(SK_UPMEM, cart.rom + 0x900000, 0x40000, NULL) == 0x40000)
|
||||
{
|
||||
{
|
||||
/* $000000-$1FFFFF is mapped to S&K ROM */
|
||||
for (i=0x00; i<0x20; i++)
|
||||
{
|
||||
@@ -469,7 +497,7 @@ void md_cart_init(void)
|
||||
cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1];
|
||||
cart.rom[i + 0x600000 + 1] = temp;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<0x40000; i+=2)
|
||||
{
|
||||
/* Byteswap ROM */
|
||||
@@ -657,6 +685,20 @@ void md_cart_init(void)
|
||||
m68k.memory_map[0x00].write16 = mapper_flashkit_w;
|
||||
zbank_memory_map[0x00].write = mapper_flashkit_w;
|
||||
}
|
||||
else if ((cart.romsize == 0x400000) &&
|
||||
(READ_BYTE(cart.rom, 0x200150) == 'C') &&
|
||||
(READ_BYTE(cart.rom, 0x200151) == 'A') &&
|
||||
(READ_BYTE(cart.rom, 0x200152) == 'N') &&
|
||||
(READ_BYTE(cart.rom, 0x200153) == 'O') &&
|
||||
(READ_BYTE(cart.rom, 0x200154) == 'N'))
|
||||
{
|
||||
/* Canon - Legend of the new Gods (4MB dump) */
|
||||
cart.hw.time_w = mapper_wd1601_w;
|
||||
cart.hw.bankshift = 1;
|
||||
sram.on = 1;
|
||||
sram.start = 0x200000;
|
||||
sram.end = 0x201fff;
|
||||
}
|
||||
else if ((*(uint16 *)(cart.rom + 0x08) == 0x6000) && (*(uint16 *)(cart.rom + 0x0a) == 0x01f6) && (rominfo.realchecksum == 0xf894))
|
||||
{
|
||||
/* Super Mario World 64 (unlicensed) mapper */
|
||||
@@ -1646,27 +1688,208 @@ static void mapper_64k_multi_w(uint32 address)
|
||||
/* 64 x 64k banks */
|
||||
for (i=0; i<64; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = &cart.rom[((address++) & 0x3f) << 16];
|
||||
m68k.memory_map[i].base = &cart.rom[((address + i) & 0x3f) << 16];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Custom ROM Bankswitch used in pirate "1800-in-1" cartridge
|
||||
*/
|
||||
static uint32 mapper_128k_multi_r(uint32 address)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* 16 x 128k banks (2MB ROM) */
|
||||
/* Bank index (B3 B2 B1 B0) is encoded in address lower byte = {0 X B0 B1 X B2 B3 0} */
|
||||
/* Note: {0 B0 X B1 X B2 B3 0} also works, see below for the 9 unique values being used for all menu entries
|
||||
read16 00A13000 (0002FBEE) => 0x000000-0x03ffff (2x128KB)
|
||||
read16 00A13018 (00FF2056) => 0x040000-0x07ffff (2x128KB)
|
||||
read16 00A13004 (00FF2120) => 0x080000-0x0bffff (2x128KB)
|
||||
read16 00A1301C (00FF20A6) => 0x0c0000-0x0fffff (2x128KB)
|
||||
read16 00A1300A (00FF20BA) => 0x100000-0x13ffff (2x128KB)
|
||||
read16 00A1301A (00FF20CE) => 0x140000-0x17ffff (2x128KB)
|
||||
read16 00A1300E (00FF20F4) => 0x180000-0x1bffff (2x128KB)
|
||||
read16 00A1301E (00FF2136) => 0x1c0000-0x1dffff (1x128KB)
|
||||
read16 00A1307E (00FF2142) => 0x1e0000-0x1fffff (1x128KB)
|
||||
*/
|
||||
int bank = ((address & 0x02) << 2) | (address & 0x04) | ((address & 0x10) >> 3) | ((address & 0x20) >> 5);
|
||||
|
||||
/* remap cartridge area (64 x 64k banks) */
|
||||
address = bank << 1;
|
||||
for (i=0x00; i<0x40; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = &cart.rom[((address + i) & 0x3f) << 16];
|
||||
}
|
||||
|
||||
/* returned value changes the menu title and number of entries in the 'game' list (the number of distinct games does not change though) */
|
||||
/* 0x00 => 9-in-1 */
|
||||
/* 0x01 => 190-in-1 */
|
||||
/* 0x02 => 888-in-1 */
|
||||
/* 0x03 => 1800-in-1 */
|
||||
/* real cartridge board has switches to select between the four different menus but here we force the largest menu selection (each other menus being a subset of the next larger menu) */
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
/*
|
||||
Custom ROM Bankswitch used in pirate "Golden Mega 250-in-1" cartridge
|
||||
*/
|
||||
static void mapper_256k_multi_w(uint32 address, uint32 data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* 8 x 256k banks (2MB ROM) */
|
||||
/* Bank index (B2 B1 B0) is encoded in data lower byte = {B1 B0 X X 0 0 0 B2} */
|
||||
/* Note: {X B0 B1 B2 0 0 0 X}, {B1 B0 X B2 0 0 0 X} or {X B0 B1 X 0 0 0 B2} also work, see below for the 4 unique values being used for all menu entries
|
||||
write16 00089000 = 0000 (00FF0006) => 0x000000-0x03ffff (1x256KB)
|
||||
write16 00089000 = 0040 (00FF0006) => 0x040000-0x07ffff (1x256KB)
|
||||
write16 00089000 = 00A0 (00FF0006) => 0x080000-0x0fffff (2x256KB)
|
||||
write16 00089000 = 0011 (00FF0006) => 0x100000-0x1fffff (4x256KB)
|
||||
*/
|
||||
int bank = ((data & 0x01) << 2) | ((data & 0xc0) >> 6);
|
||||
|
||||
/* remap cartridge area (64 x 64k banks) */
|
||||
address = bank << 2;
|
||||
for (i=0x00; i<0x40; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = &cart.rom[((address + i) & 0x3f) << 16];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Custom ROM Bankswitch used in "Canon - Legend of the New Gods"
|
||||
(uses WD1601 QFPL V1.01 board also used in chinese X-in-1 pirates sold by mindkids)
|
||||
*/
|
||||
static void mapper_wd1601_w(uint32 address, uint32 data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* !TIME write16 0xA13002 = 0x3002 (00FFFE0C) */
|
||||
/* The board probably allows up to 256MB Flash ROM remapping but this game only has 4MB ROM chip */
|
||||
if ((address & 0xfe) == 0x02)
|
||||
{
|
||||
/* upper 2MB ROM mapped to $000000-$1fffff */
|
||||
for (i=0; i<0x20; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = &cart.rom[(0x20 + i) << 16];
|
||||
}
|
||||
|
||||
/* backup RAM (8KB) mapped to $2000000-$3fffff */
|
||||
for (i=0x20; i<0x40; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = sram.sram;
|
||||
m68k.memory_map[i].read8 = sram_read_byte;
|
||||
m68k.memory_map[i].read16 = sram_read_word;
|
||||
m68k.memory_map[i].write8 = sram_write_byte;
|
||||
m68k.memory_map[i].write16 = sram_write_word;
|
||||
zbank_memory_map[i].read = sram_read_byte;
|
||||
zbank_memory_map[i].write = sram_write_byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Custom ROM Bankswitch used in RADICA cartridges
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++
|
||||
Two different boards seem to exist (one with support for 64KB banks mapping and another one supporting 128KB banks + battery-RAM).
|
||||
Radica Volume 1 requires 64KB banks mapping as the menu is located at a 64KB boundary.
|
||||
Sensible Soccer Plus edition requires 128KB banks mapping with only VA6-VA2 being used to select bank index (VA1 is ignored).
|
||||
Sensible Soccer Plus edition also requires 8KB backup RAM to be mapped in higher 2MB range.
|
||||
Other games support both 64KB or 128KB mapping so it's not clear what exact board they are using but none require SRAM so we use 64KB mapper by default.
|
||||
Note that Radica Volume 3 uses similar ROM mapping as Sensible Soccer Plus edition so it might be using same 128KB board, without any SRAM chip connected.
|
||||
*/
|
||||
static uint32 mapper_radica_r(uint32 address)
|
||||
static uint32 mapper_64k_radica_r(uint32 address)
|
||||
{
|
||||
int i = 0;
|
||||
address = (address >> 1);
|
||||
|
||||
|
||||
/* 64 x 64k banks */
|
||||
for (i = 0; i < 64; i++)
|
||||
/*
|
||||
Volume 1
|
||||
--------
|
||||
000000h-0fffffh: Kid Chameleon : !TIME read16 0xA13000 (00FF103A)
|
||||
100000h-1fffffh: Dr Robotnik's Mean Bean Machine : !TIME read16 0xA13020 (00FF101E)
|
||||
200000h-27ffffh: Sonic The Hedgehog : !TIME read16 0xA13040 (00FF101E)
|
||||
280000h-2fffffh: Golden Axe : !TIME read16 0xA13050 (00FF101E)
|
||||
300000h-37ffffh: Altered Beast : !TIME read16 0xA13060 (00FF101E)
|
||||
380000h-39ffffh: Flicky : !TIME read16 0xA13070 (00FF101E)
|
||||
3a0000h-3effffh: N/A : N/A
|
||||
3f0000h-3fffffh: Radica Menu (64 KB) : !TIME read16 0xA1307E (00FF1006)
|
||||
|
||||
Volume 2
|
||||
--------
|
||||
000000h-0fffffh: Sonic The Hedgehog 2 : !TIME read16 0xA13000 (00FF103A)
|
||||
100000h-1fffffh: The Ooze : !TIME read16 0xA13020 (00FF101E)
|
||||
200000h-2fffffh: Ecco The Dolphin : !TIME read16 0xA13040 (00FF101E)
|
||||
300000h-37ffffh: Gain Ground : !TIME read16 0xA13060 (00FF101E)
|
||||
380000h-3bffffh: Alex Kidd in Enchanted Castle : !TIME read16 0xA13070 (00FF101E)
|
||||
3c0000h-3dffffh: Columns : !TIME read16 0xA13078 (00FF101E)
|
||||
3e0000h-3fffffh: Radica Menu (128 KB) : !TIME read16 0xA1307C (00FF1006)
|
||||
|
||||
Volume 3 - Super Sonic Gold edition
|
||||
-----------------------------------
|
||||
000000h-01ffffh: Radica Menu (128 KB) : N/A
|
||||
020000h-07ffffh: N/A : N/A
|
||||
080000h-0fffffh: Sonic The Hedgehog : !TIME read16 0xA13010 (00FF1012)
|
||||
100000h-1fffffh: Sonic The Hedgehog 2 : !TIME read16 0xA13020 (00FF1012)
|
||||
200000h-2fffffh: Sonic Spinball : !TIME read16 0xA13040 (00FF1012)
|
||||
300000h-3fffffh: Dr Robotnik's Mean Bean Machine : !TIME read16 0xA13060 (00FF1012)
|
||||
|
||||
Street Fighter 2 CE edition
|
||||
---------------------------
|
||||
000000h-2fffffh: Street Fighter 2 CE : !TIME read16 0xA13000 (00FF103A)
|
||||
300000h-3bffffh: Ghouls'n Ghosts : !TIME read16 0xA13060 (00FF101E)
|
||||
3c0000h-3dffffh: Radica Menu (128 KB) : !TIME read16 0xA13078 (00FF1006)
|
||||
3e0000h-3fffffh: N/A : N/A
|
||||
*/
|
||||
int index = (address >> 1) & 0x3F;
|
||||
|
||||
/* $000000-$3fffff area is mapped to selected banks (OR gates between VA21-VA16 and selected index) */
|
||||
for (i = 0x00; i < 0x40; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = &cart.rom[((address++)& 0x3f)<< 16];
|
||||
m68k.memory_map[i].base = &cart.rom[(index | i) << 16];
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
static uint32 mapper_128k_radica_r(uint32 address)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* 32 x 128k banks */
|
||||
/*
|
||||
Sensible Soccer Plus edition
|
||||
----------------------------
|
||||
000000h-01ffffh: Radica Menu (128 KB) : N/A
|
||||
020000h-07ffffh: N/A : N/A
|
||||
080000h-0fffffh: Sensible Soccer : !TIME read16 0xA13010 (00FF1012)
|
||||
100000h-1fffffh: Mega-Lo-Mania : !TIME read16 0xA13022 (00FF1012)
|
||||
200000h-37ffffh: Cannon Fodder : !TIME read16 0xA13042 (00FF1012)
|
||||
380000h-3fffffh: N/A : N/A
|
||||
|
||||
Note: address bit 1 is ignored for bank selection but might be used to enable/disable SRAM mapping ?
|
||||
*/
|
||||
int index = (address >> 1) & 0x3E;
|
||||
|
||||
/* $000000-$1fffff area is mapped to selected banks (OR gates between VA20-VA17 and selected index) */
|
||||
for (i = 0x00; i < 0x20; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = &cart.rom[(index | i) << 16];
|
||||
}
|
||||
|
||||
/* $200000-$3fffff area is mapped to 8KB SRAM (mirrored) */
|
||||
for (i = 0x20; i < 0x40; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = sram.sram;
|
||||
m68k.memory_map[i].read8 = sram_read_byte;
|
||||
m68k.memory_map[i].read16 = sram_read_word;
|
||||
m68k.memory_map[i].write8 = sram_write_byte;
|
||||
m68k.memory_map[i].write16 = sram_write_word;
|
||||
zbank_memory_map[i].read = sram_read_byte;
|
||||
zbank_memory_map[i].write = sram_write_byte;
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
default !TIME signal handler
|
||||
@@ -1675,7 +1898,7 @@ static uint32 mapper_radica_r(uint32 address)
|
||||
static void default_time_w(uint32 address, uint32 data)
|
||||
{
|
||||
/* enable multi-game cartridge mapper by default */
|
||||
if (address < 0xa13040)
|
||||
if (address < 0xa13060)
|
||||
{
|
||||
mapper_64k_multi_w(address);
|
||||
return;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* Mega Drive cartridge hardware support
|
||||
*
|
||||
* Copyright (C) 2007-2019 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Most cartridge protections were initially documented by Haze
|
||||
* (http://haze.mameworld.info/)
|
||||
|
||||
@@ -777,11 +777,45 @@ int sms_cart_context_load(uint8 *state)
|
||||
{
|
||||
/* load Boot ROM mapper settings */
|
||||
load_param(bios_rom.fcr, 4);
|
||||
|
||||
/* set default cartridge ROM paging */
|
||||
switch (cart_rom.mapper)
|
||||
{
|
||||
case MAPPER_SEGA:
|
||||
case MAPPER_SEGA_X:
|
||||
cart_rom.fcr[0] = 0;
|
||||
cart_rom.fcr[1] = 0;
|
||||
cart_rom.fcr[2] = 1;
|
||||
cart_rom.fcr[3] = 2;
|
||||
break;
|
||||
|
||||
case MAPPER_KOREA_8K:
|
||||
case MAPPER_MSX:
|
||||
case MAPPER_MSX_NEMESIS:
|
||||
cart_rom.fcr[0] = 0;
|
||||
cart_rom.fcr[1] = 0;
|
||||
cart_rom.fcr[2] = 0;
|
||||
cart_rom.fcr[3] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
cart_rom.fcr[0] = 0;
|
||||
cart_rom.fcr[1] = 0;
|
||||
cart_rom.fcr[2] = 1;
|
||||
cart_rom.fcr[3] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* load cartridge mapper settings */
|
||||
load_param(cart_rom.fcr, 4);
|
||||
|
||||
/* set default 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;
|
||||
}
|
||||
|
||||
/* support for SG-1000 games with extra RAM */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* Backup RAM support
|
||||
*
|
||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -147,6 +147,13 @@ void sram_init()
|
||||
sram.start = 0x400001;
|
||||
sram.end = 0x40ffff;
|
||||
}
|
||||
else if ((rominfo.checksum == 0x0000) && (rominfo.realchecksum == 0x1f7f) && (READ_BYTE(cart.rom + 0x80000,0x1b0) == 0x52) && (READ_BYTE(cart.rom + 0x80000,0x1b1) == 0x41))
|
||||
{
|
||||
/* Radica - Sensible Soccer Plus edition (use bankswitching) */
|
||||
sram.on = 1;
|
||||
sram.start = 0x200001;
|
||||
sram.end = 0x203fff;
|
||||
}
|
||||
else if ((strstr(rominfo.ROMType,"SF") != NULL) && (strstr(rominfo.product,"001") != NULL))
|
||||
{
|
||||
/* SF-001 */
|
||||
@@ -214,8 +221,7 @@ unsigned int sram_read_byte(unsigned int address)
|
||||
|
||||
unsigned int sram_read_word(unsigned int address)
|
||||
{
|
||||
address &= 0xfffe;
|
||||
return (sram.sram[address + 1] | (sram.sram[address] << 8));
|
||||
return READ_WORD(sram.sram, address & 0xfffe);
|
||||
}
|
||||
|
||||
void sram_write_byte(unsigned int address, unsigned int data)
|
||||
@@ -225,7 +231,5 @@ void sram_write_byte(unsigned int address, unsigned int data)
|
||||
|
||||
void sram_write_word(unsigned int address, unsigned int data)
|
||||
{
|
||||
address &= 0xfffe;
|
||||
sram.sram[address] = data >> 8;
|
||||
sram.sram[address + 1] = data & 0xff;
|
||||
WRITE_WORD(sram.sram, address & 0xfffe, data);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* Backup RAM support
|
||||
*
|
||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
/* CD compatible ROM/RAM cartridge */
|
||||
typedef struct
|
||||
{
|
||||
uint8 area[0x840080]; /* cartridge ROM/RAM area (max. 8MB ROM + 64KB backup memory + Pro Action Replay 128KB ROM / 64KB RAM + cartridge infos) */
|
||||
uint8 reserved[0x80]; /* reserved for ROM cartridge infos (see md_cart.h) */
|
||||
uint8 area[0x840000]; /* cartridge ROM/RAM area (max. 8MB ROM + 64KB backup memory + Pro Action Replay 128KB ROM / 64KB RAM) */
|
||||
uint8 boot; /* cartridge boot mode (0x00: boot from CD with ROM/RAM cartridge enabled, 0x40: boot from ROM cartridge with CD enabled) */
|
||||
uint8 id; /* RAM cartridge ID (related to RAM size, 0 if disabled) */
|
||||
uint8 prot; /* RAM cartridge write protection */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************************
|
||||
* Genesis Plus
|
||||
* CD data controller (LC89510 compatible)
|
||||
* CD data controller (LC8951x compatible)
|
||||
*
|
||||
* Copyright (C) 2012-2015 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -51,7 +51,6 @@
|
||||
|
||||
/* CTRL0 register bitmasks */
|
||||
#define BIT_DECEN 0x80
|
||||
#define BIT_E01RQ 0x20
|
||||
#define BIT_AUTORQ 0x10
|
||||
#define BIT_WRRQ 0x04
|
||||
|
||||
@@ -60,7 +59,7 @@
|
||||
#define BIT_FORMRQ 0x04
|
||||
#define BIT_SHDREN 0x01
|
||||
|
||||
/* CTRL2 register bitmask */
|
||||
/* STAT3 register bitmask */
|
||||
#define BIT_VALST 0x80
|
||||
|
||||
/* TODO: figure exact DMA transfer rate */
|
||||
@@ -248,7 +247,7 @@ void cdc_decoder_update(uint32 header)
|
||||
/* data decoding enabled ? */
|
||||
if (cdc.ctrl[0] & BIT_DECEN)
|
||||
{
|
||||
/* update HEAD registers */
|
||||
/* update HEADx registers with current block header */
|
||||
*(uint32 *)(cdc.head[0]) = header;
|
||||
|
||||
/* set !VALST */
|
||||
@@ -285,18 +284,50 @@ void cdc_decoder_update(uint32 header)
|
||||
/* CDC buffer address */
|
||||
offset = cdc.pt.w & 0x3fff;
|
||||
|
||||
/* write CDD block header (4 bytes) */
|
||||
/* write current block header to RAM buffer (4 bytes) */
|
||||
*(uint32 *)(cdc.ram + offset) = header;
|
||||
offset += 4;
|
||||
|
||||
/* write CDD block data (2048 bytes) */
|
||||
cdd_read_data(cdc.ram + 4 + offset);
|
||||
/* check decoded block mode */
|
||||
if (cdc.head[0][3] == 0x01)
|
||||
{
|
||||
/* write Mode 1 user data to RAM buffer (2048 bytes) */
|
||||
cdd_read_data(cdc.ram + offset, NULL);
|
||||
offset += 2048;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check if CD-ROM Mode 2 decoding is enabled */
|
||||
if (cdc.ctrl[1] & BIT_MODRQ)
|
||||
{
|
||||
/* update HEADx registers with current block sub-header & write Mode 2 user data to RAM buffer (max 2328 bytes) */
|
||||
cdd_read_data(cdc.ram + offset + 8, cdc.head[1]);
|
||||
|
||||
/* write current block sub-header to RAM buffer (4 bytes x 2) */
|
||||
*(uint32 *)(cdc.ram + offset) = *(uint32 *)(cdc.head[1]);
|
||||
*(uint32 *)(cdc.ram + offset + 4) = *(uint32 *)(cdc.head[1]);
|
||||
offset += 2336;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* update HEADx registers with current block sub-header & write Mode 2 user data to RAM buffer (max 2328 bytes) */
|
||||
/* NB: when Mode 2 decoding is disabled, sub-header is apparently not written to RAM buffer (required by Wonder Library) */
|
||||
cdd_read_data(cdc.ram + offset, cdc.head[1]);
|
||||
offset += 2328;
|
||||
}
|
||||
|
||||
/* set STAT2 register FORM bit according to sub-header FORM bit when CTRL0 register AUTORQ bit is set */
|
||||
if (cdc.ctrl[0] & BIT_AUTORQ)
|
||||
{
|
||||
cdc.stat[2] = (cdc.ctrl[1] & BIT_MODRQ) | ((cdc.head[1][2] & 0x20) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* take care of buffer overrun */
|
||||
offset = offset + 2048 + 4 - 0x4000;
|
||||
if (offset > 0)
|
||||
if (offset > 0x4000)
|
||||
{
|
||||
/* data should be written at the start of buffer */
|
||||
memcpy(cdc.ram, cdc.ram + 0x4000, offset);
|
||||
memcpy(cdc.ram, cdc.ram + 0x4000, offset - 0x4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -484,15 +515,15 @@ void cdc_reg_w(unsigned char data)
|
||||
/* set CRCOK bit only if decoding is enabled */
|
||||
cdc.stat[0] = data & BIT_DECEN;
|
||||
|
||||
/* update decoding mode */
|
||||
/* update STAT2 register */
|
||||
if (data & BIT_AUTORQ)
|
||||
{
|
||||
/* set MODE bit according to CTRL1 register & clear FORM bit */
|
||||
cdc.stat[2] = cdc.ctrl[1] & BIT_MODRQ;
|
||||
/* set MODE bit according to CTRL1 register MODRQ bit & set FORM bit according to sub-header FORM bit*/
|
||||
cdc.stat[2] = (cdc.ctrl[1] & BIT_MODRQ) | ((cdc.head[1][2] & 0x20) >> 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set MODE & FORM bits according to CTRL1 register */
|
||||
/* set MODE & FORM bits according to CTRL1 register MODRQ & FORMRQ bits */
|
||||
cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ);
|
||||
}
|
||||
|
||||
@@ -503,15 +534,15 @@ void cdc_reg_w(unsigned char data)
|
||||
|
||||
case 0x0b: /* CTRL1 */
|
||||
{
|
||||
/* update decoding mode */
|
||||
/* update STAT2 register */
|
||||
if (cdc.ctrl[0] & BIT_AUTORQ)
|
||||
{
|
||||
/* set MODE bit according to CTRL1 register & clear FORM bit */
|
||||
cdc.stat[2] = data & BIT_MODRQ;
|
||||
/* set MODE bit according to CTRL1 register MODRQ bit & set FORM bit according to sub-header FORM bit*/
|
||||
cdc.stat[2] = (data & BIT_MODRQ) | ((cdc.head[1][2] & 0x20) >> 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set MODE & FORM bits according to CTRL1 register */
|
||||
/* set MODE & FORM bits according to CTRL1 register MODRQ & FORMRQ bits */
|
||||
cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ);
|
||||
}
|
||||
|
||||
@@ -612,7 +643,7 @@ unsigned char cdc_reg_r(void)
|
||||
|
||||
/* clear pending decoder interrupt */
|
||||
cdc.ifstat |= BIT_DECI;
|
||||
|
||||
|
||||
#if 0
|
||||
/* no pending data transfer end interrupt */
|
||||
if ((cdc.ifstat | BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN))
|
||||
@@ -639,13 +670,8 @@ unsigned short cdc_host_r(void)
|
||||
/* check if data is available */
|
||||
if (scd.regs[0x04>>1].byte.h & 0x40)
|
||||
{
|
||||
/* read data word from CDC RAM buffer */
|
||||
uint16 data = *(uint16 *)(cdc.ram + (cdc.dac.w & 0x3ffe));
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* source data is stored in big endian format */
|
||||
data = ((data >> 8) | (data << 8)) & 0xffff;
|
||||
#endif
|
||||
/* read 16-bit word from CDC RAM buffer (big-endian format) */
|
||||
uint16 data = READ_WORD(cdc.ram, cdc.dac.w & 0x3ffe);
|
||||
|
||||
#ifdef LOG_CDC
|
||||
error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac.w, data, cdc.dbc.w, s68k.pc);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************************
|
||||
* Genesis Plus
|
||||
* CD data controller (LC89510 compatible)
|
||||
* CD data controller (LC8951x compatible)
|
||||
*
|
||||
* Copyright (C) 2012-2015 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
+190
-170
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* CD drive processor & CD-DA fader
|
||||
*
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -47,7 +47,9 @@
|
||||
#define CD_SCAN_SPEED 30
|
||||
|
||||
/* CD tracks type (CD-DA by default) */
|
||||
#define TYPE_CDROM 0x01
|
||||
#define TYPE_AUDIO 0x00
|
||||
#define TYPE_MODE1 0x01
|
||||
#define TYPE_MODE2 0x02
|
||||
|
||||
/* BCD conversion lookup tables */
|
||||
static const uint8 lut_BCD_8[100] =
|
||||
@@ -122,14 +124,8 @@ static const uint32 toc_ffightj[29] =
|
||||
14553, 9834, 10542, 1699, 1792, 1781, 3783, 3052
|
||||
};
|
||||
|
||||
/* supported WAVE file header (16-bit stereo samples @44.1kHz) */
|
||||
static const unsigned char waveHeader[28] =
|
||||
{
|
||||
0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,0x10,0x00,0x00,0x00,0x01,0x00,
|
||||
0x02,0x00,0x44,0xac,0x00,0x00,0x10,0xb1,0x02,0x00,0x04,0x00,0x10,0x00
|
||||
};
|
||||
|
||||
/* supported WAVE file extensions */
|
||||
/* supported audio file extensions */
|
||||
static const char extensions[SUPPORTED_EXT][16] =
|
||||
{
|
||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||
@@ -322,7 +318,7 @@ int cdd_load(char *filename, char *header)
|
||||
return (-1);
|
||||
|
||||
#if defined(USE_LIBCHDR)
|
||||
if (!memcmp(".chd", &filename[strlen(filename) - 4], 4) || !memcmp(".CHD", &filename[strlen(filename) - 4], 4))
|
||||
if (!memcmp("chd", &filename[strlen(filename) - 3], 3) || !memcmp("CHD", &filename[strlen(filename) - 3], 3))
|
||||
{
|
||||
int sectors = 0;
|
||||
char metadata[256];
|
||||
@@ -400,19 +396,31 @@ int cdd_load(char *filename, char *header)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* COOKED format (2048 bytes data blocks) */
|
||||
if (!strcmp(type, "MODE1"))
|
||||
cdd.sectorSize = 2048;
|
||||
|
||||
/* RAW format (2352 bytes data blocks) */
|
||||
else if (!strcmp(type, "MODE1_RAW"))
|
||||
if (!strcmp(type, "MODE1_RAW"))
|
||||
{
|
||||
/* Mode 1 RAW format (2352 bytes data blocks) */
|
||||
cdd.sectorSize = 2352;
|
||||
|
||||
/* unsupported track format */
|
||||
cdd.toc.tracks[0].type = TYPE_MODE1;
|
||||
}
|
||||
else if (!strcmp(type, "MODE1"))
|
||||
{
|
||||
/* Mode 1 COOKED format (2048 bytes data blocks) */
|
||||
cdd.sectorSize = 2048;
|
||||
cdd.toc.tracks[0].type = TYPE_MODE1;
|
||||
}
|
||||
else if (!strcmp(type, "MODE2_RAW"))
|
||||
{
|
||||
/* Mode 2 RAW format (2352 bytes data blocks) */
|
||||
cdd.sectorSize = 2352;
|
||||
cdd.toc.tracks[0].type = TYPE_MODE2;
|
||||
}
|
||||
else if (strcmp(type, "AUDIO"))
|
||||
{
|
||||
/* unsupported track format */
|
||||
break;
|
||||
|
||||
/* Data track start LBA (2s pause assumed by default) */
|
||||
}
|
||||
|
||||
/* First track start LBA (2s pause assumed by default) */
|
||||
cdd.toc.tracks[0].start = 0;
|
||||
}
|
||||
|
||||
@@ -448,9 +456,6 @@ int cdd_load(char *filename, char *header)
|
||||
|
||||
/* copy CD image header + security code (skip RAW sector 16-byte header) */
|
||||
memcpy(header, cdd.chd.hunk + (cdd.toc.tracks[0].offset % cdd.chd.hunkbytes) + ((cdd.sectorSize == 2048) ? 0 : 16), 0x210);
|
||||
|
||||
/* there is a valid DATA track */
|
||||
cdd.toc.tracks[0].type = TYPE_CDROM;
|
||||
}
|
||||
|
||||
/* valid CD image ? */
|
||||
@@ -475,44 +480,47 @@ int cdd_load(char *filename, char *header)
|
||||
strncpy(fname, filename, 256);
|
||||
|
||||
/* check loaded file extension */
|
||||
if (memcmp(".cue", &filename[strlen(filename) - 4], 4) && memcmp(".CUE", &filename[strlen(filename) - 4], 4))
|
||||
if (memcmp("cue", &filename[strlen(filename) - 3], 3) && memcmp("CUE", &filename[strlen(filename) - 3], 3))
|
||||
{
|
||||
int len;
|
||||
|
||||
static const uint8 sync[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00};
|
||||
|
||||
/* read first 16 bytes */
|
||||
cdStreamRead(header, 0x10, 1, fd);
|
||||
|
||||
/* look for valid CD image identifier */
|
||||
/* auto-detect valid Sega CD image */
|
||||
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
||||
{
|
||||
/* COOKED format (2048 bytes data blocks) */
|
||||
cdd.sectorSize = 2048;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read next 16 bytes */
|
||||
cdStreamRead(header, 0x10, 1, fd);
|
||||
|
||||
/* look for valid CD image identifier */
|
||||
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
||||
{
|
||||
/* RAW format (2352 bytes data blocks) */
|
||||
cdd.sectorSize = 2352;
|
||||
}
|
||||
}
|
||||
|
||||
/* valid CD image file ? */
|
||||
if (cdd.sectorSize)
|
||||
{
|
||||
/* read CD image header + security code */
|
||||
/* COOKED CD-ROM image (2048 bytes data blocks) */
|
||||
cdd.sectorSize = 2048;
|
||||
|
||||
/* CD-ROM Mode 1 by default */
|
||||
cdd.toc.tracks[0].type = TYPE_MODE1;
|
||||
}
|
||||
|
||||
/* auto-detect CD-ROM synchro pattern */
|
||||
else if (!memcmp(sync, header, 12))
|
||||
{
|
||||
/* RAW CD-ROM image (2352 bytes data blocks) */
|
||||
cdd.sectorSize = 2352;
|
||||
|
||||
/* auto-detect CD-ROM mode from block header (byte 15) */
|
||||
cdd.toc.tracks[0].type = header[15];
|
||||
|
||||
/* read next 16 bytes (start of user data) */
|
||||
cdStreamRead(header, 0x10, 1, fd);
|
||||
}
|
||||
|
||||
/* supported CD-ROM image file ? */
|
||||
if ((cdd.toc.tracks[0].type == TYPE_MODE1) || (cdd.toc.tracks[0].type == TYPE_MODE2))
|
||||
{
|
||||
/* read Sega CD image header + security code */
|
||||
cdStreamRead(header + 0x10, 0x200, 1, fd);
|
||||
|
||||
/* initialize first track file descriptor */
|
||||
cdd.toc.tracks[0].fd = fd;
|
||||
|
||||
/* this is a valid DATA track */
|
||||
cdd.toc.tracks[0].type = TYPE_CDROM;
|
||||
|
||||
/* DATA track end LBA (based on DATA file length) */
|
||||
cdStreamSeek(fd, 0, SEEK_END);
|
||||
cdd.toc.tracks[0].end = cdStreamTell(fd) / cdd.sectorSize;
|
||||
@@ -533,7 +541,7 @@ int cdd_load(char *filename, char *header)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is not a CD image file */
|
||||
/* this is not a supported CD-ROM image file */
|
||||
isCDfile = 0;
|
||||
|
||||
/* close file */
|
||||
@@ -618,26 +626,26 @@ int cdd_load(char *filename, char *header)
|
||||
if (!strstr(lptr,"BINARY") && !strstr(lptr,"MOTOROLA"))
|
||||
{
|
||||
/* read file header */
|
||||
unsigned char head[28];
|
||||
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 8, SEEK_SET);
|
||||
cdStreamRead(head, 28, 1, cdd.toc.tracks[cdd.toc.last].fd);
|
||||
unsigned char head[12];
|
||||
cdStreamRead(head, 12, 1, cdd.toc.tracks[cdd.toc.last].fd);
|
||||
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
||||
|
||||
/* autodetect WAVE file header (44.1KHz 16-bit stereo format only) */
|
||||
if (!memcmp(head, waveHeader, 28))
|
||||
|
||||
/* autodetect WAVE file */
|
||||
if (!memcmp(head, "RIFF", 4) && !memcmp(head + 8, "WAVE", 4))
|
||||
{
|
||||
/* look for 'data' chunk id */
|
||||
int dataOffset = 0;
|
||||
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 36, SEEK_SET);
|
||||
while (cdStreamRead(head, 4, 1, cdd.toc.tracks[cdd.toc.last].fd))
|
||||
/* look for 'data' chunk */
|
||||
int chunkSize, dataOffset = 0;
|
||||
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 12, SEEK_SET);
|
||||
while (cdStreamRead(head, 8, 1, cdd.toc.tracks[cdd.toc.last].fd))
|
||||
{
|
||||
if (!memcmp(head, "data", 4))
|
||||
{
|
||||
dataOffset = cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) + 4;
|
||||
dataOffset = cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd);
|
||||
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
||||
break;
|
||||
}
|
||||
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, -2, SEEK_CUR);
|
||||
chunkSize = head[4] + (head[5] << 8) + (head[6] << 16) + (head[7] << 24);
|
||||
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, chunkSize, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* check if 'data' chunk has not been found */
|
||||
@@ -679,42 +687,35 @@ int cdd_load(char *filename, char *header)
|
||||
/* decode TRACK commands */
|
||||
else if ((sscanf(lptr, "TRACK %02d %*s", &bb)) || (sscanf(lptr, "TRACK %d %*s", &bb)))
|
||||
{
|
||||
/* check track number */
|
||||
if (bb != (cdd.toc.last + 1))
|
||||
{
|
||||
/* close any opened file */
|
||||
if (cdd.toc.tracks[cdd.toc.last].fd)
|
||||
{
|
||||
cdStreamClose(cdd.toc.tracks[cdd.toc.last].fd);
|
||||
cdd.toc.tracks[cdd.toc.last].fd = 0;
|
||||
}
|
||||
|
||||
/* missing tracks */
|
||||
break;
|
||||
}
|
||||
|
||||
/* autodetect DATA track (first track only) */
|
||||
/* autodetect DATA track type (first track only) */
|
||||
if (!cdd.toc.last)
|
||||
{
|
||||
/* CD-ROM Mode 1 support only */
|
||||
if (strstr(lptr,"MODE1/2048"))
|
||||
{
|
||||
/* COOKED format (2048 bytes / block) */
|
||||
/* Mode 1 COOKED format (2048 bytes / block) */
|
||||
cdd.sectorSize = 2048;
|
||||
cdd.toc.tracks[0].type = TYPE_MODE1;
|
||||
}
|
||||
else if (strstr(lptr,"MODE1/2352"))
|
||||
{
|
||||
/* RAW format (2352 bytes / block) */
|
||||
/* Mode 1 RAW format (2352 bytes / block) */
|
||||
cdd.sectorSize = 2352;
|
||||
|
||||
/* skip 16-byte header */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, 0x10, SEEK_SET);
|
||||
cdd.toc.tracks[0].type = TYPE_MODE1;
|
||||
}
|
||||
else if (strstr(lptr,"MODE2/2352"))
|
||||
{
|
||||
/* Mode 2 RAW format (2352 bytes / block) */
|
||||
cdd.sectorSize = 2352;
|
||||
cdd.toc.tracks[0].type = TYPE_MODE2;
|
||||
}
|
||||
|
||||
if (cdd.sectorSize)
|
||||
{
|
||||
/* this is a valid DATA track */
|
||||
cdd.toc.tracks[0].type = TYPE_CDROM;
|
||||
if (cdd.sectorSize == 2352)
|
||||
{
|
||||
/* skip 16-byte header */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, 0x10, SEEK_SET);
|
||||
}
|
||||
|
||||
/* read CD image header + security code */
|
||||
cdStreamRead(header, 0x210, 1, cdd.toc.tracks[0].fd);
|
||||
@@ -757,16 +758,16 @@ int cdd_load(char *filename, char *header)
|
||||
cdd.toc.tracks[cdd.toc.last].offset += pregap * 2352;
|
||||
|
||||
/* check if a single file is used for consecutive tracks */
|
||||
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
||||
if (!cdd.toc.tracks[cdd.toc.last].fd && cdd.toc.last)
|
||||
{
|
||||
/* use common file descriptor */
|
||||
cdd.toc.tracks[cdd.toc.last].fd = cdd.toc.tracks[0].fd;
|
||||
cdd.toc.tracks[cdd.toc.last].fd = cdd.toc.tracks[cdd.toc.last - 1].fd;
|
||||
|
||||
/* current track start time (based on current file absolute time + PREGAP length) */
|
||||
cdd.toc.tracks[cdd.toc.last].start = bb + ss*75 + mm*60*75 + pregap;
|
||||
|
||||
/* check if previous track end time needs to be set */
|
||||
if (cdd.toc.last && !cdd.toc.tracks[cdd.toc.last - 1].end)
|
||||
if (!cdd.toc.tracks[cdd.toc.last - 1].end)
|
||||
{
|
||||
/* set previous track end time (based on current track start time, ignoring any "PREGAP"-type pause if no INDEX00) */
|
||||
cdd.toc.tracks[cdd.toc.last - 1].end = cdd.toc.tracks[cdd.toc.last].start;
|
||||
@@ -863,7 +864,7 @@ int cdd_load(char *filename, char *header)
|
||||
/* close CUE file */
|
||||
cdStreamClose(fd);
|
||||
}
|
||||
else
|
||||
else if (cdd.toc.last)
|
||||
{
|
||||
int i, offset = 1;
|
||||
|
||||
@@ -890,26 +891,27 @@ int cdd_load(char *filename, char *header)
|
||||
/* repeat until no more valid track files can be found */
|
||||
while (fd)
|
||||
{
|
||||
/* read file HEADER */
|
||||
unsigned char head[28];
|
||||
cdStreamSeek(fd, 8, SEEK_SET);
|
||||
cdStreamRead(head, 28, 1, fd);
|
||||
/* read file header */
|
||||
unsigned char head[12];
|
||||
cdStreamRead(head, 12, 1, fd);
|
||||
cdStreamSeek(fd, 0, SEEK_SET);
|
||||
|
||||
/* check if this is a valid WAVE file (44.1KHz 16-bit stereo format only) */
|
||||
if (!memcmp(head, waveHeader, 28))
|
||||
|
||||
/* autodetect WAVE file */
|
||||
if (!memcmp(head, "RIFF", 4) && !memcmp(head + 8, "WAVE", 4))
|
||||
{
|
||||
/* look for 'data' chunk id */
|
||||
int dataOffset = 0;
|
||||
cdStreamSeek(fd, 36, SEEK_SET);
|
||||
while (cdStreamRead(head, 4, 1, fd))
|
||||
/* look for 'data' chunk */
|
||||
int chunkSize, dataOffset = 0;
|
||||
cdStreamSeek(fd, 12, SEEK_SET);
|
||||
while (cdStreamRead(head, 8, 1, fd))
|
||||
{
|
||||
if (!memcmp(head, "data", 4))
|
||||
{
|
||||
dataOffset = cdStreamTell(fd) + 4;
|
||||
dataOffset = cdStreamTell(fd);
|
||||
cdStreamSeek(fd, 0, SEEK_SET);
|
||||
break;
|
||||
}
|
||||
cdStreamSeek(fd, -2, SEEK_CUR);
|
||||
chunkSize = head[4] + (head[5] << 8) + (head[6] << 16) + (head[7] << 24);
|
||||
cdStreamSeek(fd, chunkSize, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* check if 'data' chunk has not been found */
|
||||
@@ -1033,19 +1035,9 @@ int cdd_load(char *filename, char *header)
|
||||
sprintf(ptr, extensions[i], cdd.toc.last + offset);
|
||||
fd = cdStreamOpen(fname);
|
||||
}
|
||||
}
|
||||
|
||||
/* CD tracks found ? */
|
||||
if (cdd.toc.last)
|
||||
{
|
||||
/* Lead-out */
|
||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
||||
|
||||
/* CD mounted */
|
||||
cdd.loaded = 1;
|
||||
|
||||
/* Valid DATA track found ? */
|
||||
if (cdd.toc.tracks[0].type)
|
||||
/* Valid CD-ROM Mode 1 track found ? */
|
||||
if (cdd.toc.tracks[0].type == TYPE_MODE1)
|
||||
{
|
||||
/* simulate audio tracks if none found */
|
||||
if (cdd.toc.last == 1)
|
||||
@@ -1129,6 +1121,11 @@ int cdd_load(char *filename, char *header)
|
||||
}
|
||||
while (cdd.toc.last < 29);
|
||||
}
|
||||
else if (strstr(header + 0x180,"T-06201-01") != NULL)
|
||||
{
|
||||
/* Sewer Shark (USA) (REV1) */
|
||||
/* no audio track */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default TOC (99 tracks & 2s per audio tracks) */
|
||||
@@ -1144,6 +1141,17 @@ int cdd_load(char *filename, char *header)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* CD tracks found ? */
|
||||
if (cdd.toc.last)
|
||||
{
|
||||
/* Lead-out */
|
||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
||||
|
||||
/* CD mounted */
|
||||
cdd.loaded = 1;
|
||||
|
||||
/* Automatically try to open associated subcode data file */
|
||||
memcpy(&fname[strlen(fname) - 4], ".sub", 4);
|
||||
cdd.toc.sub = cdStreamOpen(fname);
|
||||
@@ -1215,7 +1223,7 @@ void cdd_unload(void)
|
||||
cdd.sectorSize = 0;
|
||||
}
|
||||
|
||||
void cdd_read_data(uint8 *dst)
|
||||
void cdd_read_data(uint8 *dst, uint8 *subheader)
|
||||
{
|
||||
/* only allow reading (first) CD-ROM track sectors */
|
||||
if (cdd.toc.tracks[cdd.index].type && (cdd.lba >= 0))
|
||||
@@ -1236,36 +1244,60 @@ void cdd_read_data(uint8 *dst)
|
||||
cdd.chd.hunknum = hunknum;
|
||||
}
|
||||
|
||||
/* copy Mode 1 sector data (2048 bytes only) */
|
||||
/* check sector size */
|
||||
if (cdd.sectorSize == 2048)
|
||||
{
|
||||
/* Mode 1 COOKED data (ISO) */
|
||||
/* read Mode 1 user data (2048 bytes) */
|
||||
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes), 2048);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mode 1 RAW data (skip 16-byte header) */
|
||||
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 16, 2048);
|
||||
/* check if sub-header is required (Mode 2 sector only) */
|
||||
if (!subheader)
|
||||
{
|
||||
/* read Mode 1 user data (2048 bytes), skipping block sync pattern (12 bytes) + block header (4 bytes)*/
|
||||
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 12 + 4, 2048);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read Mode 2 sub-header (first 4 bytes), skipping block sync pattern (12 bytes) + block header (4 bytes)*/
|
||||
memcpy(subheader, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 12 + 4, 4);
|
||||
|
||||
/* read Mode 2 user data (max 2328 bytes), skipping Mode 2 sub-header (8 bytes) */
|
||||
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 12 + 4 + 8, 2328);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* seek current track sector */
|
||||
/* check sector size */
|
||||
if (cdd.sectorSize == 2048)
|
||||
{
|
||||
/* Mode 1 COOKED data (ISO) */
|
||||
/* read Mode 1 user data (2048 bytes) */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * 2048, SEEK_SET);
|
||||
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mode 1 RAW data (skip 16-byte header) */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * 2352 + 16, SEEK_SET);
|
||||
}
|
||||
/* check if sub-header is required (Mode 2 sector only) */
|
||||
if (!subheader)
|
||||
{
|
||||
/* skip block sync pattern (12 bytes) + block header (4 bytes) then read Mode 1 user data (2048 bytes) */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, (cdd.lba * 2352) + 12 + 4, SEEK_SET);
|
||||
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* skip block sync pattern (12 bytes) + block header (4 bytes) + Mode 2 sub-header (first 4 bytes) then read Mode 2 sub-header (last 4 bytes) */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, (cdd.lba * 2352) + 12 + 4 + 4, SEEK_SET);
|
||||
cdStreamRead(subheader, 4, 1, cdd.toc.tracks[0].fd);
|
||||
|
||||
/* read Mode 1 sector data (2048 bytes only) */
|
||||
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd);
|
||||
/* read Mode 2 user data (max 2328 bytes) */
|
||||
cdStreamRead(dst, 2328, 1, cdd.toc.tracks[0].fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1545,30 +1577,16 @@ void cdd_update(void)
|
||||
error("LBA = %d (track %d)(latency=%d)\n", cdd.lba, cdd.index, cdd.latency);
|
||||
#endif
|
||||
|
||||
/* seeking disc */
|
||||
if (cdd.status == CD_SEEK)
|
||||
/* drive latency */
|
||||
if (cdd.latency > 0)
|
||||
{
|
||||
/* drive latency */
|
||||
if (cdd.latency > 0)
|
||||
{
|
||||
cdd.latency--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* drive is ready */
|
||||
cdd.status = CD_PAUSE;
|
||||
cdd.latency--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* reading disc */
|
||||
else if (cdd.status == CD_PLAY)
|
||||
if (cdd.status == CD_PLAY)
|
||||
{
|
||||
/* drive latency */
|
||||
if (cdd.latency > 0)
|
||||
{
|
||||
cdd.latency--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of disc detection */
|
||||
if (cdd.index >= cdd.toc.last)
|
||||
{
|
||||
@@ -1585,13 +1603,13 @@ void cdd_update(void)
|
||||
/* track type */
|
||||
if (cdd.toc.tracks[cdd.index].type)
|
||||
{
|
||||
/* CD-ROM (Mode 1) sector header */
|
||||
/* CD-ROM sector header */
|
||||
uint8 header[4];
|
||||
uint32 msf = cdd.lba + 150;
|
||||
header[0] = lut_BCD_8[(msf / 75) / 60];
|
||||
header[1] = lut_BCD_8[(msf / 75) % 60];
|
||||
header[2] = lut_BCD_8[(msf % 75)];
|
||||
header[3] = 0x01;
|
||||
header[3] = cdd.toc.tracks[cdd.index].type;
|
||||
|
||||
/* decode CD-ROM track sector */
|
||||
cdc_decoder_update(*(uint32 *)(header));
|
||||
@@ -1725,7 +1743,7 @@ void cdd_update(void)
|
||||
}
|
||||
|
||||
/* AUDIO track playing ? */
|
||||
scd.regs[0x36>>1].byte.h = cdd.toc.tracks[cdd.index].type;
|
||||
scd.regs[0x36>>1].byte.h = cdd.toc.tracks[cdd.index].type ? 0x01 : 0x00;
|
||||
|
||||
/* seek to current subcode position */
|
||||
if (cdd.toc.sub)
|
||||
@@ -1775,18 +1793,20 @@ void cdd_process(void)
|
||||
/* Process CDD command */
|
||||
switch (scd.regs[0x42>>1].byte.h & 0x0f)
|
||||
{
|
||||
case 0x00: /* Report Drive Status */
|
||||
case 0x00: /* Get Drive Status */
|
||||
{
|
||||
/* RS1-RS8 normally unchanged */
|
||||
scd.regs[0x38>>1].byte.h = cdd.status;
|
||||
|
||||
/* unless RS1 indicated invalid track infos */
|
||||
if (scd.regs[0x38>>1].byte.l == 0x0f)
|
||||
/* RS0-RS8 are normally unchanged unless reported drive status needs to be updated (i.e previous drive command has been processed) */
|
||||
/* Note: this function is called one 75hz frame ahead of CDD update so latency counter is always one step ahead of upcoming status */
|
||||
/* Radical Rex and Annet Futatabi both need at least respectively 2 and 3 interrupts with 'playing' status returned before sectors start getting incremented */
|
||||
if (cdd.latency <= 3)
|
||||
{
|
||||
/* and drive is now ready */
|
||||
if (!cdd.latency)
|
||||
/* update reported drive status */
|
||||
scd.regs[0x38>>1].byte.h = cdd.status;
|
||||
|
||||
/* check if RS1 indicated invalid track infos (during seeking) */
|
||||
if (scd.regs[0x38>>1].byte.l == 0x0f)
|
||||
{
|
||||
/* then return valid track infos, e.g current track number in RS2-RS3 (fixes Lunar - The Silver Star) */
|
||||
/* seeking has ended so we return valid track infos, e.g current track number in RS2-RS3 (fixes Lunar - The Silver Star) */
|
||||
scd.regs[0x38>>1].byte.l = 0x02;
|
||||
scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A;
|
||||
}
|
||||
@@ -1824,7 +1844,7 @@ void cdd_process(void)
|
||||
scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60];
|
||||
scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60];
|
||||
scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)];
|
||||
scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type << 2; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
|
||||
scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type ? 0x04 : 0x00; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1835,7 +1855,7 @@ void cdd_process(void)
|
||||
scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60];
|
||||
scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60];
|
||||
scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)];
|
||||
scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type << 2; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
|
||||
scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type ? 0x04 : 0x00; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1878,7 +1898,7 @@ void cdd_process(void)
|
||||
scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60];
|
||||
scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60];
|
||||
scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)];
|
||||
scd.regs[0x3e>>1].byte.h |= (cdd.toc.tracks[track-1].type << 3); /* RS6 bit 3 is set for CD-ROM track */
|
||||
scd.regs[0x3e>>1].byte.h |= cdd.toc.tracks[track-1].type ? 0x08 : 0x00; /* RS6 bit 3 is set for CD-ROM track */
|
||||
scd.regs[0x40>>1].byte.h = track % 10; /* Track Number (low digit) */
|
||||
break;
|
||||
}
|
||||
@@ -1918,8 +1938,7 @@ void cdd_process(void)
|
||||
if (!cdd.latency)
|
||||
{
|
||||
/* Fixes a few games hanging because they expect data to be read with some delay */
|
||||
/* Radical Rex needs at least one interrupt delay */
|
||||
/* Wolf Team games (Anet Futatabi, Aisle Lord, Cobra Command, Earnest Evans, Road Avenger & Time Gal) need at least 11 interrupts delay */
|
||||
/* Wolf Team games (Annet Futatabi, Aisle Lord, Cobra Command, Earnest Evans, Road Avenger & Time Gal) need at least 11 interrupts delay */
|
||||
/* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 11 is OK) */
|
||||
cdd.latency = 11;
|
||||
}
|
||||
@@ -1978,14 +1997,14 @@ void cdd_process(void)
|
||||
if (cdd.chd.file)
|
||||
{
|
||||
/* CHD file offset */
|
||||
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (lba * CD_FRAME_SIZE);
|
||||
cdd.chd.hunkofs = cdd.toc.tracks[index].offset + (lba * CD_FRAME_SIZE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (cdd.toc.tracks[index].type)
|
||||
{
|
||||
/* DATA track */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||
cdStreamSeek(cdd.toc.tracks[index].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||
}
|
||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||
else if (cdd.toc.tracks[index].vf.seekable)
|
||||
@@ -2009,15 +2028,16 @@ void cdd_process(void)
|
||||
/* no audio track playing (yet) */
|
||||
scd.regs[0x36>>1].byte.h = 0x01;
|
||||
|
||||
/* update status */
|
||||
/* update status (reported to host once seeking has ended) */
|
||||
cdd.status = CD_PLAY;
|
||||
|
||||
/* RS0 should indicates seeking until drive is ready (fixes audio delay in Bari Arm) */
|
||||
/* RS1=0xf to invalidate track infos in RS2-RS8 until drive is ready (fixes Snatcher Act 2 start cutscene) */
|
||||
scd.regs[0x38>>1].w = (CD_PLAY << 8) | 0x0f;
|
||||
scd.regs[0x38>>1].w = (CD_SEEK << 8) | 0x0f;
|
||||
scd.regs[0x3a>>1].w = 0x0000;
|
||||
scd.regs[0x3c>>1].w = 0x0000;
|
||||
scd.regs[0x3e>>1].w = 0x0000;
|
||||
scd.regs[0x40>>1].w = ~(CD_PLAY + 0xf) & 0x0f;
|
||||
scd.regs[0x40>>1].w = ~(CD_SEEK + 0xf) & 0x0f;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2084,14 +2104,14 @@ void cdd_process(void)
|
||||
if (cdd.chd.file)
|
||||
{
|
||||
/* CHD file offset */
|
||||
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (lba * CD_FRAME_SIZE);
|
||||
cdd.chd.hunkofs = cdd.toc.tracks[index].offset + (lba * CD_FRAME_SIZE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (cdd.toc.tracks[index].type)
|
||||
{
|
||||
/* DATA track */
|
||||
cdStreamSeek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||
cdStreamSeek(cdd.toc.tracks[index].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||
}
|
||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||
else if (cdd.toc.tracks[index].vf.seekable)
|
||||
@@ -2115,8 +2135,8 @@ void cdd_process(void)
|
||||
/* no audio track playing */
|
||||
scd.regs[0x36>>1].byte.h = 0x01;
|
||||
|
||||
/* update status */
|
||||
cdd.status = CD_SEEK;
|
||||
/* update status (reported to host once seeking has ended) */
|
||||
cdd.status = CD_PAUSE;
|
||||
|
||||
/* RS1=0xf to invalidate track infos in RS2-RS8 while seeking (fixes Final Fight CD intro when seek time is emulated) */
|
||||
scd.regs[0x38>>1].w = (CD_SEEK << 8) | 0x0f;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* CD drive processor & CD-DA fader
|
||||
*
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -136,7 +136,7 @@ extern int cdd_context_save(uint8 *state);
|
||||
extern int cdd_context_load(uint8 *state);
|
||||
extern int cdd_load(char *filename, char *header);
|
||||
extern void cdd_unload(void);
|
||||
extern void cdd_read_data(uint8 *dst);
|
||||
extern void cdd_read_data(uint8 *dst, uint8 *subheader);
|
||||
extern void cdd_read_audio(unsigned int samples);
|
||||
extern void cdd_update(void);
|
||||
extern void cdd_process(void);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* CD graphics processor
|
||||
*
|
||||
* Copyright (C) 2012 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -47,10 +47,10 @@ void word_ram_0_dma_w(unsigned int words)
|
||||
|
||||
/* CDC buffer source address */
|
||||
uint16 src_index = cdc.dac.w & 0x3ffe;
|
||||
|
||||
|
||||
/* WORD-RAM destination address*/
|
||||
uint32 dst_index = (scd.regs[0x0a>>1].w << 3) & 0x1fffe;
|
||||
|
||||
|
||||
/* update DMA destination address */
|
||||
scd.regs[0x0a>>1].w += (words >> 2);
|
||||
|
||||
@@ -60,13 +60,8 @@ void word_ram_0_dma_w(unsigned int words)
|
||||
/* DMA transfer */
|
||||
while (words--)
|
||||
{
|
||||
/* read 16-bit word from CDC buffer */
|
||||
data = *(uint16 *)(cdc.ram + src_index);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* source data is stored in big endian format */
|
||||
data = ((data >> 8) | (data << 8)) & 0xffff;
|
||||
#endif
|
||||
/* read 16-bit word from CDC RAM buffer (big-endian format) */
|
||||
data = READ_WORD(cdc.ram, src_index);
|
||||
|
||||
/* write 16-bit word to WORD-RAM */
|
||||
*(uint16 *)(scd.word_ram[0] + dst_index) = data ;
|
||||
@@ -85,10 +80,10 @@ void word_ram_1_dma_w(unsigned int words)
|
||||
|
||||
/* CDC buffer source address */
|
||||
uint16 src_index = cdc.dac.w & 0x3ffe;
|
||||
|
||||
|
||||
/* WORD-RAM destination address*/
|
||||
uint32 dst_index = ((scd.regs[0x0a>>1].w << 3) & 0x1fffe);
|
||||
|
||||
|
||||
/* update DMA destination address */
|
||||
scd.regs[0x0a>>1].w += (words >> 2);
|
||||
|
||||
@@ -98,13 +93,8 @@ void word_ram_1_dma_w(unsigned int words)
|
||||
/* DMA transfer */
|
||||
while (words--)
|
||||
{
|
||||
/* read 16-bit word from CDC buffer */
|
||||
data = *(uint16 *)(cdc.ram + src_index);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* source data is stored in big endian format */
|
||||
data = ((data >> 8) | (data << 8)) & 0xffff;
|
||||
#endif
|
||||
/* read 16-bit word from CDC RAM buffer (big-endian format) */
|
||||
data = READ_WORD(cdc.ram, src_index);
|
||||
|
||||
/* write 16-bit word to WORD-RAM */
|
||||
*(uint16 *)(scd.word_ram[1] + dst_index) = data ;
|
||||
@@ -123,10 +113,10 @@ void word_ram_2M_dma_w(unsigned int words)
|
||||
|
||||
/* CDC buffer source address */
|
||||
uint16 src_index = cdc.dac.w & 0x3ffe;
|
||||
|
||||
|
||||
/* WORD-RAM destination address*/
|
||||
uint32 dst_index = (scd.regs[0x0a>>1].w << 3) & 0x3fffe;
|
||||
|
||||
|
||||
/* update DMA destination address */
|
||||
scd.regs[0x0a>>1].w += (words >> 2);
|
||||
|
||||
@@ -136,13 +126,8 @@ void word_ram_2M_dma_w(unsigned int words)
|
||||
/* DMA transfer */
|
||||
while (words--)
|
||||
{
|
||||
/* read 16-bit word from CDC buffer */
|
||||
data = *(uint16 *)(cdc.ram + src_index);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* source data is stored in big endian format */
|
||||
data = ((data >> 8) | (data << 8)) & 0xffff;
|
||||
#endif
|
||||
/* read 16-bit word from CDC RAM buffer (big-endian format) */
|
||||
data = READ_WORD(cdc.ram, src_index);
|
||||
|
||||
/* write 16-bit word to WORD-RAM */
|
||||
*(uint16 *)(scd.word_ram_2M + dst_index) = data ;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* CD graphics processor
|
||||
*
|
||||
* Copyright (C) 2012 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* Mega CD / Sega CD hardware
|
||||
*
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -101,13 +101,8 @@ void prg_ram_dma_w(unsigned int words)
|
||||
/* DMA transfer */
|
||||
while (words--)
|
||||
{
|
||||
/* read 16-bit word from CDC buffer */
|
||||
data = *(uint16 *)(cdc.ram + src_index);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* source data is stored in big endian format */
|
||||
data = ((data >> 8) | (data << 8)) & 0xffff;
|
||||
#endif
|
||||
/* read 16-bit word from CDC RAM buffer (big-endian format) */
|
||||
data = READ_WORD(cdc.ram, src_index);
|
||||
|
||||
/* write 16-bit word to PRG-RAM */
|
||||
*(uint16 *)(scd.prg_ram + dst_index) = data ;
|
||||
@@ -997,28 +992,6 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x37: /* CDD control (controlled by BIOS, byte access only ?) */
|
||||
{
|
||||
/* CDD communication started ? */
|
||||
if ((data & 0x04) && !(scd.regs[0x37>>1].byte.l & 0x04))
|
||||
{
|
||||
/* reset CDD cycle counter */
|
||||
cdd.cycles = (scd.cycles - s68k.cycles) * 3;
|
||||
|
||||
/* set pending interrupt level 4 */
|
||||
scd.pending |= (1 << 4);
|
||||
|
||||
/* update IRQ level if interrupt is enabled */
|
||||
if (scd.regs[0x32>>1].byte.l & 0x10)
|
||||
{
|
||||
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
scd.regs[0x37>>1].byte.l = data;
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* SUB-CPU communication words */
|
||||
@@ -1673,6 +1646,10 @@ void scd_reset(int hard)
|
||||
|
||||
void scd_update(unsigned int cycles)
|
||||
{
|
||||
int m68k_end_cycles;
|
||||
int s68k_run_cycles;
|
||||
int s68k_end_cycles = scd.cycles + SCYCLES_PER_LINE;
|
||||
|
||||
/* update CDC DMA transfer */
|
||||
if (cdc.dma_w)
|
||||
{
|
||||
@@ -1682,63 +1659,77 @@ void scd_update(unsigned int cycles)
|
||||
/* run both CPU in sync until end of line */
|
||||
do
|
||||
{
|
||||
m68k_run(cycles);
|
||||
s68k_run(scd.cycles + SCYCLES_PER_LINE);
|
||||
}
|
||||
while ((m68k.cycles < cycles) || (s68k.cycles < (scd.cycles + SCYCLES_PER_LINE)));
|
||||
/* CD hardware remaining cycles until end of line */
|
||||
s68k_run_cycles = s68k_end_cycles - scd.cycles;
|
||||
|
||||
/* increment CD hardware cycle counter */
|
||||
scd.cycles += SCYCLES_PER_LINE;
|
||||
|
||||
/* CDD processing at 75Hz (one clock = 12500000/75 = 500000/3 CPU clocks) */
|
||||
cdd.cycles += (SCYCLES_PER_LINE * 3);
|
||||
if (cdd.cycles >= (500000 * 4))
|
||||
{
|
||||
/* reload CDD cycle counter */
|
||||
cdd.cycles -= (500000 * 4);
|
||||
|
||||
/* update CDD sector */
|
||||
cdd_update();
|
||||
|
||||
/* check if a new CDD command has been processed */
|
||||
if (!(scd.regs[0x4a>>1].byte.l & 0xf0))
|
||||
/* check Timer interrupt occurence */
|
||||
if ((scd.timer > 0) && (scd.timer < s68k_run_cycles))
|
||||
{
|
||||
/* reset CDD command wait flag */
|
||||
scd.regs[0x4a>>1].byte.l = 0xf0;
|
||||
/* adjust Sub-CPU and Main-CPU end cycle counters up to Timer interrupt occurence */
|
||||
s68k_run_cycles = scd.timer;
|
||||
m68k_end_cycles = mcycles_vdp + ((s68k_run_cycles * MCYCLES_PER_LINE) / SCYCLES_PER_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default Main-CPU end cycle counter (end of line) */
|
||||
m68k_end_cycles = cycles;
|
||||
}
|
||||
|
||||
/* pending level 4 interrupt */
|
||||
scd.pending |= (1 << 4);
|
||||
/* run both CPU in sync until required cycle counters */
|
||||
m68k_run(m68k_end_cycles);
|
||||
s68k_run(scd.cycles + s68k_run_cycles);
|
||||
|
||||
/* level 4 interrupt enabled */
|
||||
if (scd.regs[0x32>>1].byte.l & 0x10)
|
||||
/* increment CD hardware cycle counter */
|
||||
scd.cycles += s68k_run_cycles;
|
||||
|
||||
/* CDD processing at 75Hz (one clock = 12500000/75 = 500000/3 CPU clocks) */
|
||||
cdd.cycles += (s68k_run_cycles * 3);
|
||||
if (cdd.cycles >= (500000 * 4))
|
||||
{
|
||||
/* reload CDD cycle counter */
|
||||
cdd.cycles -= (500000 * 4);
|
||||
|
||||
/* update CDD sector */
|
||||
cdd_update();
|
||||
|
||||
/* check if CDD communication is enabled */
|
||||
if (scd.regs[0x37>>1].byte.l & 0x04)
|
||||
{
|
||||
/* update IRQ level */
|
||||
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Timer */
|
||||
if (scd.timer)
|
||||
{
|
||||
/* decrement timer */
|
||||
scd.timer -= SCYCLES_PER_LINE;
|
||||
if (scd.timer <= 0)
|
||||
{
|
||||
/* reload timer (one timer clock = 384 CPU cycles) */
|
||||
scd.timer += (scd.regs[0x30>>1].byte.l * TIMERS_SCYCLES_RATIO);
|
||||
|
||||
/* level 3 interrupt enabled ? */
|
||||
if (scd.regs[0x32>>1].byte.l & 0x08)
|
||||
{
|
||||
/* trigger level 3 interrupt */
|
||||
scd.pending |= (1 << 3);
|
||||
|
||||
/* update IRQ level */
|
||||
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||
/* pending level 4 interrupt */
|
||||
scd.pending |= (1 << 4);
|
||||
|
||||
/* level 4 interrupt enabled */
|
||||
if (scd.regs[0x32>>1].byte.l & 0x10)
|
||||
{
|
||||
/* update IRQ level */
|
||||
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Timer */
|
||||
if (scd.timer)
|
||||
{
|
||||
/* decrement timer */
|
||||
scd.timer -= s68k_run_cycles;
|
||||
if (scd.timer <= 0)
|
||||
{
|
||||
/* reload timer (one timer clock = 384 CPU cycles) */
|
||||
scd.timer += (scd.regs[0x30>>1].byte.l * TIMERS_SCYCLES_RATIO);
|
||||
|
||||
/* level 3 interrupt enabled ? */
|
||||
if (scd.regs[0x32>>1].byte.l & 0x08)
|
||||
{
|
||||
/* trigger level 3 interrupt */
|
||||
scd.pending |= (1 << 3);
|
||||
|
||||
/* update IRQ level */
|
||||
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((m68k.cycles < cycles) || (s68k.cycles < s68k_end_cycles));
|
||||
|
||||
/* GFX processing */
|
||||
if (scd.regs[0x58>>1].byte.h & 0x80)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Genesis Plus
|
||||
* Mega CD / Sega CD hardware
|
||||
*
|
||||
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2012-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Support for SG-1000, Mark-III, Master System, Game Gear, Mega Drive & Mega CD hardware
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -279,10 +279,18 @@ void gen_reset(int hard_reset)
|
||||
/* reset CD hardware */
|
||||
scd_reset(1);
|
||||
}
|
||||
|
||||
/* reset MD cartridge hardware (only when booting from cartridge) */
|
||||
if (scd.cartridge.boot)
|
||||
{
|
||||
md_cart_reset(hard_reset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reset MD cartridge hardware */
|
||||
md_cart_reset(hard_reset);
|
||||
}
|
||||
|
||||
/* reset MD cartridge hardware */
|
||||
md_cart_reset(hard_reset);
|
||||
|
||||
/* Z80 bus is released & Z80 is reseted */
|
||||
m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Support for SG-1000, Mark-III, Master System, Game Gear, Mega Drive & Mega CD hardware
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* ROM Loading Support
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -647,7 +647,9 @@ int load_rom(char *filename)
|
||||
|
||||
/* auto-detect byte-swapped dumps */
|
||||
if (!memcmp((char *)(cart.rom + 0x100),"ESAGM GE ARDVI E", 16) ||
|
||||
!memcmp((char *)(cart.rom + 0x100),"ESAGG NESESI", 12))
|
||||
!memcmp((char *)(cart.rom + 0x100),"ESAGG NESESI", 12) ||
|
||||
!memcmp((char *)(cart.rom + 0x80000 + 0x100),"ESAGM GE ARDVI E", 16) ||
|
||||
!memcmp((char *)(cart.rom + 0x80000 + 0x100),"ESAGG NESESI", 12))
|
||||
{
|
||||
for(i = 0; i < size; i += 2)
|
||||
{
|
||||
@@ -1076,7 +1078,8 @@ void get_region(char *romheader)
|
||||
(strstr(rominfo.product,"T-69046-50") != NULL) || /* Back to the Future III (Europe) */
|
||||
(strstr(rominfo.product,"T-120106-00") != NULL) || /* Brian Lara Cricket (Europe) */
|
||||
(strstr(rominfo.product,"T-97126 -50") != NULL) || /* Williams Arcade's Greatest Hits (Europe) */
|
||||
(strstr(rominfo.product,"T-70096 -00") != NULL)) /* Muhammad Ali Heavyweight Boxing (Europe) */
|
||||
(strstr(rominfo.product,"T-70096 -00") != NULL) || /* Muhammad Ali Heavyweight Boxing (Europe) */
|
||||
((rominfo.checksum == 0x0000) && (rominfo.realchecksum == 0x1f7f))) /* Radica - Sensible Soccer Plus edition */
|
||||
{
|
||||
/* need PAL settings */
|
||||
region_code = REGION_EUROPE;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* ROM Loading Support
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
@@ -188,7 +188,8 @@ void m68k_set_fc_callback(void (*callback)(unsigned int new_fc))
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOGVDP
|
||||
#ifdef LOGERROR
|
||||
|
||||
extern void error(char *format, ...);
|
||||
extern uint16 v_counter;
|
||||
#endif
|
||||
@@ -202,8 +203,8 @@ void m68k_update_irq(unsigned int mask)
|
||||
/* Update IRQ level */
|
||||
CPU_INT_LEVEL |= (mask << 8);
|
||||
|
||||
#ifdef LOGVDP
|
||||
error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#ifdef LOGERROR
|
||||
error("[%d(%d)][%d(%d)] m68k IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -212,8 +213,8 @@ void m68k_set_irq(unsigned int int_level)
|
||||
/* Set IRQ level */
|
||||
CPU_INT_LEVEL = int_level << 8;
|
||||
|
||||
#ifdef LOGVDP
|
||||
error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#ifdef LOGERROR
|
||||
error("[%d(%d)][%d(%d)] m68k IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -245,8 +246,8 @@ void m68k_set_irq_delay(unsigned int int_level)
|
||||
CPU_INT_LEVEL = int_level << 8;
|
||||
}
|
||||
|
||||
#ifdef LOGVDP
|
||||
error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#ifdef LOGERROR
|
||||
error("[%d(%d)][%d(%d)] m68k IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
|
||||
/* Check interrupt mask to process IRQ */
|
||||
@@ -277,7 +278,7 @@ void m68k_run(unsigned int cycles)
|
||||
/* Return point for when we have an address error (TODO: use goto) */
|
||||
m68ki_set_address_error_trap() /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
#ifdef LOGVDP
|
||||
#ifdef LOGERROR
|
||||
error("[%d][%d] m68k run to %d cycles (%x), irq mask = %x (%x)\n", v_counter, m68k.cycles, cycles, m68k.pc,FLAG_INT_MASK, CPU_INT_LEVEL);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7,
|
||||
22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 20*7, 0*7, 0*7, 0*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7,
|
||||
30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7,
|
||||
34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 32*7, 36*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1197,9 +1197,9 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7,
|
||||
20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7,
|
||||
24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 0*7, 0*7, 4*7, 0*7, 0*7, 0*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7,
|
||||
16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7,
|
||||
20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 0*7, 0*7, 4*7, 0*7, 0*7, 0*7,
|
||||
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1284,7 +1284,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1316,7 +1316,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1348,7 +1348,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1380,7 +1380,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1412,7 +1412,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1444,7 +1444,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1476,7 +1476,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
@@ -1508,7 +1508,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7,
|
||||
4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
|
||||
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7,
|
||||
14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
|
||||
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
|
||||
|
||||
@@ -8117,7 +8117,7 @@ static void m68k_op_divu_16_d(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8148,7 +8148,7 @@ static void m68k_op_divu_16_ai(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8179,7 +8179,7 @@ static void m68k_op_divu_16_pi(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 *10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8210,7 +8210,7 @@ static void m68k_op_divu_16_pd(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8241,7 +8241,7 @@ static void m68k_op_divu_16_di(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8272,7 +8272,7 @@ static void m68k_op_divu_16_ix(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8303,7 +8303,7 @@ static void m68k_op_divu_16_aw(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8334,7 +8334,7 @@ static void m68k_op_divu_16_al(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8365,7 +8365,7 @@ static void m68k_op_divu_16_pcdi(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8396,7 +8396,7 @@ static void m68k_op_divu_16_pcix(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -8427,7 +8427,7 @@ static void m68k_op_divu_16_i(void)
|
||||
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
|
||||
return;
|
||||
}
|
||||
USE_CYCLES(7 * 10);
|
||||
USE_CYCLES(MUL * 10);
|
||||
FLAG_V = VFLAG_SET;
|
||||
FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
@@ -23888,7 +23888,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
|
||||
{m68k_op_addq_8_di , 0xf1f8, 0x5028, 16},
|
||||
{m68k_op_addq_8_ix , 0xf1f8, 0x5030, 18},
|
||||
{m68k_op_addq_16_d , 0xf1f8, 0x5040, 4},
|
||||
{m68k_op_addq_16_a , 0xf1f8, 0x5048, 4},
|
||||
{m68k_op_addq_16_a , 0xf1f8, 0x5048, 8}, /* see Yacht.txt */
|
||||
{m68k_op_addq_16_ai , 0xf1f8, 0x5050, 12},
|
||||
{m68k_op_addq_16_pi , 0xf1f8, 0x5058, 12},
|
||||
{m68k_op_addq_16_pd , 0xf1f8, 0x5060, 14},
|
||||
@@ -24598,7 +24598,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
|
||||
{m68k_op_andi_16_pd , 0xfff8, 0x0260, 18},
|
||||
{m68k_op_andi_16_di , 0xfff8, 0x0268, 20},
|
||||
{m68k_op_andi_16_ix , 0xfff8, 0x0270, 22},
|
||||
{m68k_op_andi_32_d , 0xfff8, 0x0280, 14},
|
||||
{m68k_op_andi_32_d , 0xfff8, 0x0280, 16}, /* see Yacht.txt */
|
||||
{m68k_op_andi_32_ai , 0xfff8, 0x0290, 28},
|
||||
{m68k_op_andi_32_pi , 0xfff8, 0x0298, 28},
|
||||
{m68k_op_andi_32_pd , 0xfff8, 0x02a0, 30},
|
||||
@@ -24881,11 +24881,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
|
||||
{m68k_op_tst_32_di , 0xfff8, 0x4aa8, 16},
|
||||
{m68k_op_tst_32_ix , 0xfff8, 0x4ab0, 18},
|
||||
{m68k_op_tas_8_d , 0xfff8, 0x4ac0, 4},
|
||||
{m68k_op_tas_8_ai , 0xfff8, 0x4ad0, 18},
|
||||
{m68k_op_tas_8_pi , 0xfff8, 0x4ad8, 18},
|
||||
{m68k_op_tas_8_pd , 0xfff8, 0x4ae0, 20},
|
||||
{m68k_op_tas_8_di , 0xfff8, 0x4ae8, 22},
|
||||
{m68k_op_tas_8_ix , 0xfff8, 0x4af0, 24},
|
||||
{m68k_op_tas_8_ai , 0xfff8, 0x4ad0, 14}, /* see Yacht.txt */
|
||||
{m68k_op_tas_8_pi , 0xfff8, 0x4ad8, 14}, /* see Yacht.txt */
|
||||
{m68k_op_tas_8_pd , 0xfff8, 0x4ae0, 16}, /* see Yacht.txt */
|
||||
{m68k_op_tas_8_di , 0xfff8, 0x4ae8, 18}, /* see Yacht.txt */
|
||||
{m68k_op_tas_8_ix , 0xfff8, 0x4af0, 20}, /* see Yacht.txt */
|
||||
{m68k_op_movem_16_er_ai , 0xfff8, 0x4c90, 12},
|
||||
{m68k_op_movem_16_er_pi , 0xfff8, 0x4c98, 12},
|
||||
{m68k_op_movem_16_er_di , 0xfff8, 0x4ca8, 16},
|
||||
@@ -25245,10 +25245,10 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
|
||||
{m68k_op_tst_16_al , 0xffff, 0x4a79, 16},
|
||||
{m68k_op_tst_32_aw , 0xffff, 0x4ab8, 16},
|
||||
{m68k_op_tst_32_al , 0xffff, 0x4ab9, 20},
|
||||
{m68k_op_tas_8_pi7 , 0xffff, 0x4adf, 18},
|
||||
{m68k_op_tas_8_pd7 , 0xffff, 0x4ae7, 20},
|
||||
{m68k_op_tas_8_aw , 0xffff, 0x4af8, 22},
|
||||
{m68k_op_tas_8_al , 0xffff, 0x4af9, 26},
|
||||
{m68k_op_tas_8_pi7 , 0xffff, 0x4adf, 14}, /* see Yacht.txt */
|
||||
{m68k_op_tas_8_pd7 , 0xffff, 0x4ae7, 16}, /* see Yacht.txt */
|
||||
{m68k_op_tas_8_aw , 0xffff, 0x4af8, 18}, /* see Yacht.txt */
|
||||
{m68k_op_tas_8_al , 0xffff, 0x4af9, 22}, /* see Yacht.txt */
|
||||
{m68k_op_illegal , 0xffff, 0x4afc, 4},
|
||||
{m68k_op_movem_16_er_aw , 0xffff, 0x4cb8, 16},
|
||||
{m68k_op_movem_16_er_al , 0xffff, 0x4cb9, 20},
|
||||
|
||||
@@ -213,7 +213,7 @@ void s68k_update_irq(unsigned int mask)
|
||||
CPU_INT_LEVEL = mask << 8;
|
||||
|
||||
#ifdef LOG_SCD
|
||||
error("[%d][%d] IRQ Level = %d(0x%02x) (%x)\n", v_counter, s68k.cycles, CPU_INT_LEVEL>>8,FLAG_INT_MASK,s68k.pc);
|
||||
error("[%d][%d] s68k IRQ Level = %d(0x%02x) (%x)\n", v_counter, s68k.cycles, CPU_INT_LEVEL>>8,FLAG_INT_MASK,s68k.pc);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4,
|
||||
22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 20*4, 0*4, 0*4, 0*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4,
|
||||
30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4,
|
||||
34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 32*4, 36*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -243,7 +243,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 10*4, 0*4, 0*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 10*4, 0*4, 0*4, 0*4,
|
||||
8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
@@ -1197,9 +1197,9 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4,
|
||||
20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4,
|
||||
24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 0*4, 0*4, 4*4, 0*4, 0*4, 0*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4,
|
||||
16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4,
|
||||
20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 0*4, 0*4, 4*4, 0*4, 0*4, 0*4,
|
||||
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1284,7 +1284,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1316,7 +1316,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1348,7 +1348,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1380,7 +1380,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1412,7 +1412,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1444,7 +1444,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1476,7 +1476,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
@@ -1508,7 +1508,7 @@ static const unsigned char m68ki_cycles[0x10000] =
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
|
||||
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
|
||||
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
|
||||
14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4,
|
||||
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Z80 bank access to 68k bus
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -39,6 +39,9 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
||||
t_zbank_memory_map zbank_memory_map[256];
|
||||
|
||||
/*
|
||||
Handlers for access to unused addresses and those which make the
|
||||
machine lock up.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Z80 bank access to 68k bus
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -49,10 +49,12 @@ extern void zbank_write_ctrl_io(unsigned int address, unsigned int data);
|
||||
extern unsigned int zbank_read_vdp(unsigned int address);
|
||||
extern void zbank_write_vdp(unsigned int address, unsigned int data);
|
||||
|
||||
struct _zbank_memory_map
|
||||
typedef struct
|
||||
{
|
||||
unsigned int (*read)(unsigned int address);
|
||||
void (*write)(unsigned int address, unsigned int data);
|
||||
} zbank_memory_map[256];
|
||||
} t_zbank_memory_map;
|
||||
|
||||
extern t_zbank_memory_map zbank_memory_map[256];
|
||||
|
||||
#endif /* _MEMBNK_H_ */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Support for SG-1000, Mark-III, Master System, Game Gear & Mega Drive ports access
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -111,6 +111,8 @@ unsigned char z80_memory_r(unsigned int address)
|
||||
{
|
||||
if ((address >> 8) == 0x7F)
|
||||
{
|
||||
/* average Z80 wait-states when accessing 68k area */
|
||||
Z80.cycles += 3 * 15;
|
||||
return (*zbank_memory_map[0xc0].read)(address);
|
||||
}
|
||||
return z80_unused_r(address);
|
||||
@@ -118,6 +120,9 @@ unsigned char z80_memory_r(unsigned int address)
|
||||
|
||||
default: /* $8000-$FFFF: 68k bank (32K) */
|
||||
{
|
||||
/* average Z80 wait-states when accessing 68k area */
|
||||
Z80.cycles += 3 * 15;
|
||||
|
||||
address = zbank | (address & 0x7FFF);
|
||||
if (zbank_memory_map[address >> 16].read)
|
||||
{
|
||||
@@ -158,6 +163,8 @@ void z80_memory_w(unsigned int address, unsigned char data)
|
||||
|
||||
case 0x7F: /* $7F00-$7FFF: VDP */
|
||||
{
|
||||
/* average Z80 wait-states when accessing 68k area */
|
||||
Z80.cycles += 3 * 15;
|
||||
(*zbank_memory_map[0xc0].write)(address, data);
|
||||
return;
|
||||
}
|
||||
@@ -172,6 +179,9 @@ void z80_memory_w(unsigned int address, unsigned char data)
|
||||
|
||||
default: /* $8000-$FFFF: 68k bank (32K) */
|
||||
{
|
||||
/* average Z80 wait-states when accessing 68k area */
|
||||
Z80.cycles += 3 * 15;
|
||||
|
||||
address = zbank | (address & 0x7FFF);
|
||||
if (zbank_memory_map[address >> 16].write)
|
||||
{
|
||||
@@ -300,7 +310,7 @@ unsigned char z80_md_port_r(unsigned int port)
|
||||
/* read FM chip if enabled */
|
||||
if ((port >= 0xF0) && (config.ym2413 & 1))
|
||||
{
|
||||
return YM2413Read();
|
||||
return fm_read(Z80.cycles, port);
|
||||
}
|
||||
|
||||
return z80_unused_port_r(port);
|
||||
@@ -578,7 +588,7 @@ unsigned char z80_ms_port_r(unsigned int port)
|
||||
/* read FM board if enabled */
|
||||
if (!(port & 4) && (config.ym2413 & 1))
|
||||
{
|
||||
data = YM2413Read();
|
||||
data = fm_read(Z80.cycles, port);
|
||||
}
|
||||
|
||||
/* read I/O ports if enabled */
|
||||
@@ -678,7 +688,7 @@ unsigned char z80_m3_port_r(unsigned int port)
|
||||
if (!(port & 4) && (config.ym2413 & 1))
|
||||
{
|
||||
/* I/O ports are automatically disabled by hardware */
|
||||
return YM2413Read();
|
||||
return fm_read(Z80.cycles, port);
|
||||
}
|
||||
|
||||
/* read I/O ports */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Support for SG-1000, Mark-III, Master System, Game Gear & Mega Drive ports access
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
#include "ym3438.h"
|
||||
#endif
|
||||
#ifdef HAVE_OPLL_CORE
|
||||
#include "opll.h"
|
||||
#endif
|
||||
#include "sram.h"
|
||||
#include "ggenie.h"
|
||||
#include "areplay.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Nuke.YKT
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions may not be sold, nor may they be used in a commercial
|
||||
* product or activity.
|
||||
*
|
||||
* - Redistributions that are modified from the original source must include the
|
||||
* complete source code, including the source code for all components used by a
|
||||
* binary built from the modified sources. However, as a special exception, the
|
||||
* source code distributed need not include anything that is normally distributed
|
||||
* (in either source or binary form) with the major components (compiler, kernel,
|
||||
* and so on) of the operating system on which the executable runs, unless that
|
||||
* component itself accompanies the executable.
|
||||
*
|
||||
* - Redistributions must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Yamaha YM2413 emulator
|
||||
* Thanks:
|
||||
* siliconpr0n.org(digshadow, John McMaster):
|
||||
* VRC VII decap and die shot.
|
||||
*
|
||||
* version: 1.0
|
||||
*/
|
||||
|
||||
#ifndef OPLL_H
|
||||
#define OPLL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
opll_type_ym2413 = 0x00, /* Yamaha YM2413 */
|
||||
opll_type_ds1001, /* Konami VRC VII */
|
||||
opll_type_ym2413b /* Yamaha YM2413B */
|
||||
};
|
||||
|
||||
enum {
|
||||
opll_patch_1 = 0x00,
|
||||
opll_patch_2,
|
||||
opll_patch_3,
|
||||
opll_patch_4,
|
||||
opll_patch_5,
|
||||
opll_patch_6,
|
||||
opll_patch_7,
|
||||
opll_patch_8,
|
||||
opll_patch_9,
|
||||
opll_patch_10,
|
||||
opll_patch_11,
|
||||
opll_patch_12,
|
||||
opll_patch_13,
|
||||
opll_patch_14,
|
||||
opll_patch_15,
|
||||
opll_patch_drum_0,
|
||||
opll_patch_drum_1,
|
||||
opll_patch_drum_2,
|
||||
opll_patch_drum_3,
|
||||
opll_patch_drum_4,
|
||||
opll_patch_drum_5,
|
||||
opll_patch_max
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t tl;
|
||||
uint8_t dc;
|
||||
uint8_t dm;
|
||||
uint8_t fb;
|
||||
uint8_t am[2];
|
||||
uint8_t vib[2];
|
||||
uint8_t et[2];
|
||||
uint8_t ksr[2];
|
||||
uint8_t multi[2];
|
||||
uint8_t ksl[2];
|
||||
uint8_t ar[2];
|
||||
uint8_t dr[2];
|
||||
uint8_t sl[2];
|
||||
uint8_t rr[2];
|
||||
} opll_patch_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t chip_type;
|
||||
uint32_t cycles;
|
||||
uint32_t slot;
|
||||
const opll_patch_t *patchrom;
|
||||
/* IO */
|
||||
uint8_t write_data;
|
||||
uint8_t write_a;
|
||||
uint8_t write_d;
|
||||
uint8_t write_a_en;
|
||||
uint8_t write_d_en;
|
||||
uint8_t write_fm_address;
|
||||
uint8_t write_fm_data;
|
||||
uint8_t write_mode_address;
|
||||
uint8_t address;
|
||||
uint8_t data;
|
||||
/* Envelope generator */
|
||||
uint8_t eg_counter_state;
|
||||
uint8_t eg_counter_state_prev;
|
||||
uint32_t eg_timer;
|
||||
uint8_t eg_timer_low_lock;
|
||||
uint8_t eg_timer_carry;
|
||||
uint8_t eg_timer_shift;
|
||||
uint8_t eg_timer_shift_lock;
|
||||
uint8_t eg_timer_shift_stop;
|
||||
uint8_t eg_state[18];
|
||||
uint8_t eg_level[18];
|
||||
uint8_t eg_kon;
|
||||
uint32_t eg_dokon;
|
||||
uint8_t eg_off;
|
||||
uint8_t eg_rate;
|
||||
uint8_t eg_maxrate;
|
||||
uint8_t eg_zerorate;
|
||||
uint8_t eg_inc_lo;
|
||||
uint8_t eg_inc_hi;
|
||||
uint8_t eg_rate_hi;
|
||||
uint16_t eg_sl;
|
||||
uint16_t eg_ksltl;
|
||||
uint8_t eg_out;
|
||||
uint8_t eg_silent;
|
||||
/* Phase generator */
|
||||
uint16_t pg_fnum;
|
||||
uint8_t pg_block;
|
||||
uint16_t pg_out;
|
||||
uint32_t pg_inc;
|
||||
uint32_t pg_phase[18];
|
||||
uint32_t pg_phase_next;
|
||||
/* Operator */
|
||||
int16_t op_fb1[9];
|
||||
int16_t op_fb2[9];
|
||||
int16_t op_fbsum;
|
||||
int16_t op_mod;
|
||||
uint8_t op_neg;
|
||||
uint16_t op_logsin;
|
||||
uint16_t op_exp_m;
|
||||
uint16_t op_exp_s;
|
||||
/* Channel */
|
||||
int16_t ch_out;
|
||||
int16_t ch_out_hh;
|
||||
int16_t ch_out_tm;
|
||||
int16_t ch_out_bd;
|
||||
int16_t ch_out_sd;
|
||||
int16_t ch_out_tc;
|
||||
/* LFO */
|
||||
uint16_t lfo_counter;
|
||||
uint8_t lfo_vib_counter;
|
||||
uint16_t lfo_am_counter;
|
||||
uint8_t lfo_am_step;
|
||||
uint8_t lfo_am_dir;
|
||||
uint8_t lfo_am_car;
|
||||
uint8_t lfo_am_out;
|
||||
/* Register set */
|
||||
uint16_t fnum[9];
|
||||
uint8_t block[9];
|
||||
uint8_t kon[9];
|
||||
uint8_t son[9];
|
||||
uint8_t vol[9];
|
||||
uint8_t inst[9];
|
||||
uint8_t rhythm;
|
||||
uint8_t testmode;
|
||||
opll_patch_t patch;
|
||||
uint8_t c_instr;
|
||||
uint8_t c_op;
|
||||
uint8_t c_tl;
|
||||
uint8_t c_dc;
|
||||
uint8_t c_dm;
|
||||
uint8_t c_fb;
|
||||
uint8_t c_am;
|
||||
uint8_t c_vib;
|
||||
uint8_t c_et;
|
||||
uint8_t c_ksr;
|
||||
uint8_t c_ksr_freq;
|
||||
uint8_t c_ksl_freq;
|
||||
uint8_t c_ksl_block;
|
||||
uint8_t c_multi;
|
||||
uint8_t c_ksl;
|
||||
uint8_t c_adrr[3];
|
||||
uint8_t c_sl;
|
||||
uint16_t c_fnum;
|
||||
uint16_t c_block;
|
||||
/* Rhythm mode */
|
||||
int8_t rm_enable;
|
||||
uint32_t rm_noise;
|
||||
uint32_t rm_select;
|
||||
uint8_t rm_hh_bit2;
|
||||
uint8_t rm_hh_bit3;
|
||||
uint8_t rm_hh_bit7;
|
||||
uint8_t rm_hh_bit8;
|
||||
uint8_t rm_tc_bit3;
|
||||
uint8_t rm_tc_bit5;
|
||||
|
||||
int16_t output_m;
|
||||
int16_t output_r;
|
||||
|
||||
} opll_t;
|
||||
|
||||
void OPLL_Reset(opll_t *chip, uint32_t chip_type);
|
||||
void OPLL_Clock(opll_t *chip, int32_t *buffer);
|
||||
void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data);
|
||||
#endif
|
||||
+128
-13
@@ -3,7 +3,7 @@
|
||||
* Sound Hardware
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@@ -44,7 +44,7 @@
|
||||
#define YM2612_CLOCK_RATIO (7*6)
|
||||
|
||||
/* FM output buffer (large enough to hold a whole frame at original chips rate) */
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
#if defined(HAVE_YM3438_CORE) || defined(HAVE_OPLL_CORE)
|
||||
static int fm_buffer[1080 * 2 * 24];
|
||||
#else
|
||||
static int fm_buffer[1080 * 2];
|
||||
@@ -72,6 +72,14 @@ static int ym3438_sample[2];
|
||||
static int ym3438_cycles;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPLL_CORE
|
||||
static opll_t opll;
|
||||
static int opll_accm[18][2];
|
||||
static int opll_sample;
|
||||
static int opll_cycles;
|
||||
static int opll_status;
|
||||
#endif
|
||||
|
||||
/* Run FM chip until required M-cycles */
|
||||
INLINE void fm_update(int cycles)
|
||||
{
|
||||
@@ -126,7 +134,7 @@ static unsigned int YM2612_Read(unsigned int cycles, unsigned int a)
|
||||
if ((a == 0) || (config.ym2612 > YM2612_DISCRETE))
|
||||
{
|
||||
/* synchronize FM chip with CPU */
|
||||
fm_update(cycles - fm_cycles_ratio + 1);
|
||||
fm_update(cycles);
|
||||
|
||||
/* read FM status */
|
||||
if (cycles >= fm_cycles_busy)
|
||||
@@ -167,6 +175,11 @@ static void YM2413_Write(unsigned int cycles, unsigned int a, unsigned int v)
|
||||
YM2413Write(a, v);
|
||||
}
|
||||
|
||||
static unsigned int YM2413_Read(unsigned int cycles, unsigned int a)
|
||||
{
|
||||
return YM2413Read();
|
||||
}
|
||||
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
static void YM3438_Update(int *buffer, int length)
|
||||
{
|
||||
@@ -211,13 +224,66 @@ static void YM3438_Write(unsigned int cycles, unsigned int a, unsigned int v)
|
||||
static unsigned int YM3438_Read(unsigned int cycles, unsigned int a)
|
||||
{
|
||||
/* synchronize FM chip with CPU */
|
||||
fm_update(cycles - fm_cycles_ratio + 1);
|
||||
fm_update(cycles);
|
||||
|
||||
/* read FM status */
|
||||
return OPN2_Read(&ym3438, a);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPLL_CORE
|
||||
static void OPLL2413_Update(int* buffer, int length)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
OPLL_Clock(&opll, opll_accm[opll_cycles]);
|
||||
opll_cycles = (opll_cycles + 1) % 18;
|
||||
if (opll_cycles == 0)
|
||||
{
|
||||
opll_sample = 0;
|
||||
for (j = 0; j < 18; j++)
|
||||
{
|
||||
opll_sample += opll_accm[j][0] + opll_accm[j][1];
|
||||
}
|
||||
}
|
||||
*buffer++ = opll_sample * 16 * opll_status;
|
||||
*buffer++ = opll_sample * 16 * opll_status;
|
||||
}
|
||||
}
|
||||
|
||||
static void OPLL2413_Reset(unsigned int cycles)
|
||||
{
|
||||
/* synchronize FM chip with CPU */
|
||||
fm_update(cycles);
|
||||
|
||||
/* reset FM chip */
|
||||
OPLL_Reset(&opll, opll_type_ym2413);
|
||||
}
|
||||
|
||||
static void OPLL2413_Write(unsigned int cycles, unsigned int a, unsigned int v)
|
||||
{
|
||||
if (!(a&2))
|
||||
{
|
||||
/* synchronize FM chip with CPU */
|
||||
fm_update(cycles);
|
||||
|
||||
/* write FM register */
|
||||
OPLL_Write(&opll, a, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
opll_status = v&1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int OPLL2413_Read(unsigned int cycles, unsigned int a)
|
||||
{
|
||||
return 0xf8 | opll_status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void sound_init( void )
|
||||
{
|
||||
/* Initialize FM chip */
|
||||
@@ -257,14 +323,34 @@ void sound_init( void )
|
||||
else
|
||||
{
|
||||
/* YM2413 */
|
||||
YM2413Init();
|
||||
YM_Update = (config.ym2413 & 1) ? YM2413Update : NULL;
|
||||
fm_reset = YM2413_Reset;
|
||||
fm_write = YM2413_Write;
|
||||
fm_read = NULL;
|
||||
#ifdef HAVE_OPLL_CORE
|
||||
if (config.opll)
|
||||
{
|
||||
/* Nuked OPLL */
|
||||
memset(&opll, 0, sizeof(opll));
|
||||
memset(&opll_accm, 0, sizeof(opll_accm));
|
||||
opll_sample = 0;
|
||||
opll_status = 0;
|
||||
YM_Update = (config.ym2413 & 1) ? OPLL2413_Update : NULL;
|
||||
fm_reset = OPLL2413_Reset;
|
||||
fm_write = OPLL2413_Write;
|
||||
fm_read = OPLL2413_Read;
|
||||
|
||||
/* chip is running at ZCLK / 72 = MCLK / 15 / 72 */
|
||||
fm_cycles_ratio = 72 * 15;
|
||||
/* chip is running at internal clock */
|
||||
fm_cycles_ratio = 4 * 15;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
YM2413Init();
|
||||
YM_Update = (config.ym2413 & 1) ? YM2413Update : NULL;
|
||||
fm_reset = YM2413_Reset;
|
||||
fm_write = YM2413_Write;
|
||||
fm_read = YM2413_Read;
|
||||
|
||||
/* chip is running at ZCLK / 72 = MCLK / 15 / 72 */
|
||||
fm_cycles_ratio = 72 * 15;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize PSG chip */
|
||||
@@ -401,7 +487,21 @@ int sound_context_save(uint8 *state)
|
||||
}
|
||||
else
|
||||
{
|
||||
save_param(YM2413GetContextPtr(),YM2413GetContextSize());
|
||||
#ifdef HAVE_OPLL_CORE
|
||||
save_param(&config.opll, sizeof(config.opll));
|
||||
if (config.opll)
|
||||
{
|
||||
save_param(&opll, sizeof(opll));
|
||||
save_param(&opll_accm, sizeof(opll_accm));
|
||||
save_param(&opll_sample, sizeof(opll_sample));
|
||||
save_param(&opll_cycles, sizeof(opll_cycles));
|
||||
save_param(&opll_status, sizeof(opll_status));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
save_param(YM2413GetContextPtr(),YM2413GetContextSize());
|
||||
}
|
||||
}
|
||||
|
||||
bufferptr += psg_context_save(&state[bufferptr]);
|
||||
@@ -437,7 +537,22 @@ int sound_context_load(uint8 *state)
|
||||
}
|
||||
else
|
||||
{
|
||||
load_param(YM2413GetContextPtr(),YM2413GetContextSize());
|
||||
#ifdef HAVE_OPLL_CORE
|
||||
uint8 config_opll;
|
||||
load_param(&config_opll, sizeof(config_opll));
|
||||
if (config_opll)
|
||||
{
|
||||
load_param(&opll, sizeof(opll));
|
||||
load_param(&opll_accm, sizeof(opll_accm));
|
||||
load_param(&opll_sample, sizeof(opll_sample));
|
||||
load_param(&opll_cycles, sizeof(opll_cycles));
|
||||
load_param(&opll_status, sizeof(opll_status));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
load_param(YM2413GetContextPtr(),YM2413GetContextSize());
|
||||
}
|
||||
}
|
||||
|
||||
bufferptr += psg_context_load(&state[bufferptr]);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Sound Hardware
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
||||
@@ -28,7 +28,7 @@ typedef struct
|
||||
uint8 padtype;
|
||||
} t_input_config;
|
||||
|
||||
struct
|
||||
typedef struct
|
||||
{
|
||||
char version[16];
|
||||
uint8 hq_fm;
|
||||
@@ -62,7 +62,7 @@ struct
|
||||
uint8 lcd;
|
||||
uint8 render;
|
||||
t_input_config input[MAX_INPUTS];
|
||||
} config;
|
||||
} t_config;
|
||||
|
||||
extern char GG_ROM[256];
|
||||
extern char AR_ROM[256];
|
||||
@@ -76,6 +76,8 @@ extern char MS_BIOS_US[256];
|
||||
extern char MS_BIOS_EU[256];
|
||||
extern char MS_BIOS_JP[256];
|
||||
|
||||
extern t_config config;
|
||||
|
||||
void osd_input_update(void);
|
||||
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
|
||||
extern void ROMCheatUpdate(void);
|
||||
|
||||
Reference in New Issue
Block a user