5 Commits

Author SHA1 Message Date
clobber 17f423cfbd Bump version for sparkle updater 2020-08-28 15:10:36 -05:00
clobber 975a3e3266 Sync with upstream https://github.com/ekeeke/Genesis-Plus-GX/commit/f8a8046948aedc9d96ad81b3894c55d914dbef0f 2020-08-28 15:10:11 -05:00
clobber 17788c3ddd Bump version for sparkle updater 2020-08-19 14:47:23 -05:00
clobber 15af996d79 Sync with upstream https://github.com/ekeeke/Genesis-Plus-GX/commit/15722b16ab5a539b14dba024bb008b5c6f22c202 2020-08-19 14:46:59 -05:00
C.W. Betts 2c0279c0ac Update language resources.
This quiets warnings in newer Xcode releases.

Also update framework locations.
2020-01-08 01:15:51 -07:00
38 changed files with 2156 additions and 436 deletions
Binary file not shown.
+2
View File
@@ -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];
+7 -8
View File
@@ -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
View File
@@ -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>
+2
View File
@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */
+241 -18
View File
@@ -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;
+1 -1
View File
@@ -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/)
+34
View File
@@ -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 */
+10 -6
View File
@@ -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);
}
+1 -1
View File
@@ -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:
+2 -1
View File
@@ -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 */
+53 -27
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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 -2
View File
@@ -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);
+13 -28
View File
@@ -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 ;
+1 -1
View File
@@ -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:
+70 -79
View File
@@ -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)
+1 -1
View File
@@ -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:
+12 -4
View File
@@ -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;
+1 -1
View File
@@ -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:
+6 -3
View File
@@ -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;
+1 -1
View File
@@ -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:
+9 -8
View File
@@ -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
+12 -12
View File
@@ -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,
+22 -22
View File
@@ -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},
+1 -1
View File
@@ -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
}
+13 -13
View File
@@ -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,
+4 -1
View File
@@ -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.
+5 -3
View File
@@ -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_ */
+14 -4
View File
@@ -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 */
+1 -1
View File
@@ -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:
+3
View File
@@ -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
+215
View File
@@ -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
View File
@@ -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]);
+1 -1
View File
@@ -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:
+4 -2
View File
@@ -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);