27 Commits

Author SHA1 Message Date
clobber 1d652d0593 Bump version for sparkle updater 2023-10-16 21:56:24 -06:00
clobber 8956640b80 Sync with upstream https://github.com/ekeeke/Genesis-Plus-GX/commit/a2931d161f017a0614426bb01ce33a4d2f250260 2023-10-16 21:56:04 -06:00
clobber 8e4ee19963 Bump version 2023-06-21 22:28:36 -06:00
clobber fc7c85f773 Sync with upstream https://github.com/ekeeke/Genesis-Plus-GX/commit/4bb149ba0b798294fbfc51de31a97af08c018542 2023-06-20 21:29:58 -06:00
clobber 171f2425a5 Merge pull request #9 from ShutOstrich/master
Sync with upstream ekeeke/Genesis-Plus-GX@1db51e2
2023-04-29 20:42:37 -06:00
ShutOstrich d7d25b7b60 Sync with upstream https://github.com/ekeeke/Genesis-Plus-GX/commit/1db51e2c5fb29fb1305683705e8f007a18341d97 2023-04-30 00:32:22 +02:00
clobber 86a6ea8f0e Update Multitaps and Six Button Controller override database 2022-12-28 01:16:37 -07:00
clobber d661a9fb57 SG/MD/SCD/MCD: Fix EA 4-Way Play 2022-12-28 01:15:20 -07:00
clobber 01cfb4aa37 Cleanup 2022-12-28 01:12:53 -07:00
clobber 0c30f64676 Fix -ringBufferAtIndex: deprecation warning. 2022-12-24 17:10:51 -07:00
clobber 692374aa07 Bump version for sparkle updater 2022-12-23 10:52:24 -07:00
clobber 36de3d745f Fix comparison warning.
warning: bitwise comparison always evaluates to false [-Wtautological-compare]
2022-12-22 22:23:39 -07:00
clobber 3f33e549a5 Fix some problems with Genesis cheat support. 2022-12-22 22:02:02 -07:00
clobber fd3846df6e Fix indentation. 2022-12-21 21:18:45 -07:00
clobber 188663033a Sync with the latest cheat code support. 2022-12-21 19:39:22 -07:00
clobber c1a7cda4fb Sync with upstream https://github.com/ekeeke/Genesis-Plus-GX/commit/350be7731ccb8767b9abdb5ba567a899bc66e05f 2022-12-19 16:19:10 -07:00
clobber 3ebf7e57eb Bump version for sparkle updater 2021-09-17 00:27:33 -06:00
clobber 576e14d64c Sync with upstream https://github.com/ekeeke/Genesis-Plus-GX/commit/35ed78cc71f6b2c69b1377c9520416d0253b6633 2021-09-17 00:24:44 -06:00
C.W. Betts 95b9099b3e Change crc32 to be/take unsigned int instead of unsigned long.
This'll make crc_table smaller.
2020-10-19 17:05:00 -06:00
C.W. Betts 90c519eb1e Poke the plists: get the development language from Xcode build. 2020-10-01 01:51:37 -06:00
C.W. Betts 779baa7fca Fix locations of the system plugin headers.
Minor Xcode maintenance.
2020-10-01 01:26:41 -06:00
C.W. Betts 4f13fea4e2 Fix Xcode 12 build failure. 2020-09-22 14:13:55 -06:00
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
83 changed files with 6930 additions and 2064 deletions
Binary file not shown.
+291 -212
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2018, OpenEmu Team
Copyright (c) 2022, OpenEmu Team
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -34,7 +34,6 @@
#import <OpenGL/gl.h>
#include "shared.h"
#include "scrc32.h"
#define OptionDefault(_NAME_, _PREFKEY_) @{ OEGameCoreDisplayModeNameKey : _NAME_, OEGameCoreDisplayModePrefKeyNameKey : _PREFKEY_, OEGameCoreDisplayModeStateKey : @YES, }
#define Option(_NAME_, _PREFKEY_) @{ OEGameCoreDisplayModeNameKey : _NAME_, OEGameCoreDisplayModePrefKeyNameKey : _PREFKEY_, OEGameCoreDisplayModeStateKey : @NO, }
@@ -47,10 +46,13 @@
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];
char SK_UPMEM[256];
char MD_BIOS[256];
char GG_BIOS[256];
char MS_BIOS_EU[256];
char MS_BIOS_JP[256];
@@ -223,7 +225,7 @@ static __weak GenPlusGameCore *_current;
system_frame_sms(0);
int samples = audio_update(_soundBuffer);
[[self ringBufferAtIndex:0] write:_soundBuffer maxLength:samples << 2];
[[self audioBufferAtIndex:0] write:_soundBuffer maxLength:samples << 2];
}
- (void)resetEmulation
@@ -465,10 +467,10 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
{
if (_multiTapType == GamepadPort1TeamPlayerPort2 || cart.special & HW_J_CART)
{
int offset = (player == 1) ? 0 : player + 2;
NSUInteger offset = (player == 1) ? 0 : player + 2;
input.pad[offset] |= GenesisMap[button];
}
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2)
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2 || _multiTapType == EA4WayPlay)
{
input.pad[player-1] |= GenesisMap[button];
}
@@ -482,10 +484,10 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
{
if (_multiTapType == GamepadPort1TeamPlayerPort2 || cart.special & HW_J_CART)
{
int offset = (player == 1) ? 0 : player + 2;
NSUInteger offset = (player == 1) ? 0 : player + 2;
input.pad[offset] &= ~GenesisMap[button];
}
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2)
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2 || _multiTapType == EA4WayPlay)
{
input.pad[player-1] &= ~GenesisMap[button];
}
@@ -497,10 +499,10 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
{
if (_multiTapType == GamepadPort1TeamPlayerPort2)
{
int offset = (player == 1) ? 0 : player + 2;
NSUInteger offset = (player == 1) ? 0 : player + 2;
input.pad[offset] |= GenesisMap[button];
}
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2)
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2 || _multiTapType == EA4WayPlay)
{
input.pad[player-1] |= GenesisMap[button];
}
@@ -512,10 +514,10 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
{
if (_multiTapType == GamepadPort1TeamPlayerPort2)
{
int offset = (player == 1) ? 0 : player + 2;
NSUInteger offset = (player == 1) ? 0 : player + 2;
input.pad[offset] &= ~GenesisMap[button];
}
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2)
else if (_multiTapType == TeamPlayerPort1 || _multiTapType == TeamPlayerPort1TeamPlayerPort2 || _multiTapType == EA4WayPlay)
{
input.pad[player-1] &= ~GenesisMap[button];
}
@@ -773,6 +775,9 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
/* interpret code and give it an index */
decode_cheat((char *)code.UTF8String, maxcheats);
// Enable the cheat by default
cheatlist[maxcheats].enable = 1;
/* increment cheat count */
maxcheats++;
@@ -785,8 +790,9 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
/* clear existing ROM patches */
clear_cheats();
/* remove cheats from the list */
remove_cheats();
/* delete all cheats */
maxcheats = maxROMcheats = maxRAMcheats = 0;
memset(cheatlist, 0, sizeof(cheatlist));
}
- (void)configureOptions
@@ -794,12 +800,14 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
/* sound options */
config.psg_preamp = 150;
config.fm_preamp = 100;
config.cdda_volume = 100;
config.pcm_volume = 100;
config.hq_fm = 1; /* high-quality FM resampling (slower) */
config.hq_psg = 1; /* high-quality PSG resampling (slower) */
config.filter = 0; /* no filter */
config.lp_range = 0x7fff; /* 0.5 in 0.16 fixed point */
config.low_freq = 880;
config.high_freq = 5000;
config.filter = 1; /* single-pole low-pass filter (6 dB/octave) */
config.lp_range = 0x9999; /* 0.6 in 0.16 fixed point */
config.low_freq = 880; // 200
config.high_freq = 5000; // 8000
config.lg = 100;
config.mg = 100;
config.hg = 100;
@@ -809,6 +817,9 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
#ifdef HAVE_YM3438_CORE
config.ym3438 = 0;
#endif
#ifdef HAVE_OPLL_CORE
config.opll = 0;
#endif
/* system options */
config.system = 0; /* AUTO */
@@ -818,7 +829,9 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
config.force_dtack = 0;
config.addr_error = 1;
config.bios = 0;
config.lock_on = 0;
config.lock_on = 0;
config.add_on = 0; /* = HW_ADDON_AUTO (or HW_ADDON_MEGACD, HW_ADDON_MEGASD & HW_ADDON_NONE) */
config.cd_latency = 1;
/* video options */
config.overscan = 0; /* 3 == FULL */
@@ -831,13 +844,15 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
if (isLCDFilterEnabled)
[self changeDisplayWithMode:@"LCD Ghosting"];
else
config.lcd = 0;
config.lcd = 0; /* 0.8 fixed point */
}
else
config.lcd = 0;
config.render = 0;
config.render = 0; /* 1 = double resolution output (only when interlaced mode 2 is enabled) */
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
/* initialize bitmap */
memset(&bitmap, 0, sizeof(bitmap));
@@ -867,7 +882,8 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
@"6ba9e256579f0cbfa18abb96acc5b24d", // Greatest Heavyweights (Europe)
@"8662fc03ecb681fb5a463a2e9bb2ae41", // Greatest Heavyweights (Japan)
@"a2319592a31d22d9ec4501ce4c188152", // Greatest Heavyweights (USA)
@"a8dcb5476855a83702e2f49ebd4e2d57", // Lost Vikings, The (USA)
@"a8dcb5476855a83702e2f49ebd4e2d57", // Lost Vikings, The (USA) (November, 1993)
@"8335ca918a503047fc9cde6a0b082308", // Lost Vikings, The (USA) (October, 1995)
@"7914adf64ff1156c767ae550334c44b5", // Marsupilami (Europe) (En,Fr,De,Es,It)
@"9cf141681e68407d1e5279f7a35d6d53", // Marsupilami (USA) (En,Fr,De,Es,It)
@"a1dd8a3e4b8c98dee49d5e90d6b87903", // Mortal Kombat (World)
@@ -904,13 +920,14 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
@"840f9f6fd4f22686b89cfd9a9ade105a" : @(TeamPlayerPort1), // Gauntlet IV (USA, Europe) (En,Ja)
@"1f8e7897522b6e645f4b8123bff23654" : @(TeamPlayerPort1), // J. League Pro Striker Final Stage (Japan)
@"44752b050421c4e51d1bee96b3fed44e" : @(TeamPlayerPort1), // Lost Vikings, The (Europe)
@"a8dcb5476855a83702e2f49ebd4e2d57" : @(TeamPlayerPort1), // Lost Vikings, The (USA)
@"5a94b1e8792bb3572db92c2019d99377" : @(TeamPlayerPort1), // Mega Bomberman (Europe)
@"a8dcb5476855a83702e2f49ebd4e2d57" : @(TeamPlayerPort1), // Lost Vikings, The (USA) (November, 1993)
@"8335ca918a503047fc9cde6a0b082308" : @(TeamPlayerPort1), // Lost Vikings, The (USA) (October, 1995)
@"5a94b1e8792bb3572db92c2019d99377" : @(TeamPlayerPort1), // Mega Bomberman (Europe, Korea) (En)
@"514f6cad98f5f632d680983a050fffc4" : @(TeamPlayerPort1), // Mega Bomberman (USA)
@"f9a4e85931dcaaceded19c0c2a7aace1" : @(TeamPlayerPort1), // NBA Hang Time (Europe)
@"a2dddb13539df45f45ff4061cd6caacd" : @(TeamPlayerPort1), // NBA Hang Time (USA)
@"d72f13bc94ad76c90deef86d5a138ff6" : @(TeamPlayerPort1), // NBA Jam (Japan)
@"234bf02f7f7b6fdad65890424d3a8a8f" : @(TeamPlayerPort1), // NBA Jam (USA, Europe) (v1.1)
@"234bf02f7f7b6fdad65890424d3a8a8f" : @(TeamPlayerPort1), // NBA Jam (USA, Europe) (Rev 1)
@"338b8ed45e02d96f1ed31eaab59eaf43" : @(TeamPlayerPort1), // NBA Jam (USA, Europe)
@"edeb01f0aa8aed3868db1179670db22f" : @(TeamPlayerPort1), // NBA Jam - Tournament Edition (World)
//@"b465081da2e268a1c045c1b0615bed75" : @(TeamPlayerPort1), // NBA Pro Basketball '94 (Japan)
@@ -921,6 +938,7 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
@"0faab2309047b85de82a62e0230ec9f4" : @(TeamPlayerPort1), // Pele II - World Tournament Soccer (USA, Europe)
@"15a8114b96afcabcb2bd08acbc7a11c0" : @(TeamPlayerPort1), // Prime Time NFL Starring Deion Sanders (USA)
@"a0003ccd281f9cc74aa2ef97fe23c2fc" : @(TeamPlayerPort1), // Puzzle & Action - Ichidanto-R (Japan)
@"15ee1db49894b798155ae60eaa2dd961" : @(TeamPlayerPort1), // Puzzle & Action - Ichidanto-R (World) (Ja) (Sega Ages)
@"16b0f48a07baf1fa0df27453b7f008d4" : @(TeamPlayerPort1), // Puzzle & Action - Tanto-R (Japan)
//@"4abb0405b270695261494720a2af0783" : @(TeamPlayerPort1), // Shi Jie Zhi Bang Zheng Ba Zhan - World Pro Baseball 94 (Taiwan) (Unl)
@"abddd42b2548e9b708991f689d726c9a" : @(TeamPlayerPort1), // Tiny Toon Adventures - Acme All-Stars (Europe)
@@ -964,7 +982,7 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
@"8bc39c10ed8d26d53a0f24f5daca81c8" : @(TeamPlayerPort1TeamPlayerPort2), // Hyper Dunk (Europe)
@"008bcd6a3fc35015df0851e996ce80b4" : @(TeamPlayerPort1TeamPlayerPort2), // Hyper Dunk - The Playoff Edition (Japan)
@"494d00e7c0a3ee5448e6b82fa091bac8" : @(TeamPlayerPort1TeamPlayerPort2), // International Superstar Soccer Deluxe (Europe)
@"f2f41f4b8e400ef33a72033ae851eee5" : @(TeamPlayerPort1TeamPlayerPort2), // Mega Bomberman 8 Player Demo
@"e4392bd5e77321e8ec6e76a142e9536b" : @(TeamPlayerPort1TeamPlayerPort2), // Mega Bomberman - Special 8-Player-Demo (Europe) (Proto)
@"3426fc8802e1a385dc227b9dde59cbe4" : @(TeamPlayerPort1TeamPlayerPort2), // Ultimate Soccer (Europe) (En,Fr,De,Es,It)
// 1-4 Players EA 4-Way Play
@@ -1001,6 +1019,7 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
@"3817138d9054d91675f7378684744a4d" : @(EA4WayPlay), // NBA Live 98 (USA)
@"9c3aeaa26c74dfae329602ee27d0c1f9" : @(EA4WayPlay), // NBA Showdown '94 (USA, Europe)
@"8356b3f0d091b9cc441e2ff8721ad063" : @(EA4WayPlay), // NHL '94 (USA, Europe)
@"a1dd079f6b1ae80e90dc08839de4d3d4" : @(EA4WayPlay), // NHL '94 (USA, Europe) (Re-release)
@"94d3518a8e592563c78cf4da84d163c8" : @(EA4WayPlay), // NHL 95 (USA, Europe)
@"89e7e0fbe8db82b1f2dd7beafcc4e7fb" : @(EA4WayPlay), // NHL 96 (USA, Europe)
@"4ddc912038388de3818623c046890606" : @(EA4WayPlay), // NHL 97 (USA, Europe)
@@ -1042,6 +1061,7 @@ const int MasterSystemMap[] = {INPUT_UP, INPUT_DOWN, INPUT_LEFT, INPUT_RIGHT, IN
int port = 1; // Port 2
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_TEAMPLAYER;
config.input[0].padtype = pad;
for (int i = 0; i < 4; i++)
{
config.input[port*4 + i].padtype = pad;
@@ -1336,201 +1356,234 @@ static uint32_t decode_cheat(char *string, int index)
uint16_t data = 0;
uint8_t ref = 0;
/* 16-bit Game Genie code (ABCD-EFGH) */
if ((strlen(string) >= 9) && (string[4] == '-'))
{
/* 16-bit system only */
if ((system_hw & SYSTEM_PBC) != SYSTEM_MD)
{
return 0;
}
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD){
/*If system is Genesis-based*/
for (i = 0; i < 8; i++)
/*Game-Genie*/
if ((strlen(string) >= 9) && (string[4] == '-'))
{
if (i == 4) string++;
p = strchr (ggvalidchars, *string++);
if (p == NULL) return 0;
n = p - ggvalidchars;
switch (i)
for (i = 0; i < 8; i++)
{
case 0:
data |= n << 3;
break;
case 1:
data |= n >> 2;
address |= (n & 3) << 14;
break;
case 2:
address |= n << 9;
break;
case 3:
address |= (n & 0xF) << 20 | (n >> 4) << 8;
break;
case 4:
data |= (n & 1) << 12;
address |= (n >> 1) << 16;
break;
case 5:
data |= (n & 1) << 15 | (n >> 1) << 8;
break;
case 6:
data |= (n >> 3) << 13;
address |= (n & 7) << 5;
break;
case 7:
address |= n;
break;
if (i == 4) string++;
p = strchr (ggvalidchars, *string++);
if (!p)
return 0;
n = p - ggvalidchars;
switch (i)
{
case 0:
data |= n << 3;
break;
case 1:
data |= n >> 2;
address |= (n & 3) << 14;
break;
case 2:
address |= n << 9;
break;
case 3:
address |= (n & 0xF) << 20 | (n >> 4) << 8;
break;
case 4:
data |= (n & 1) << 12;
address |= (n >> 1) << 16;
break;
case 5:
data |= (n & 1) << 15 | (n >> 1) << 8;
break;
case 6:
data |= (n >> 3) << 13;
address |= (n & 7) << 5;
break;
case 7:
address |= n;
break;
}
}
/* code length */
len = 9;
}
/* code length */
len = 9;
}
/* 8-bit Game Genie code (DDA-AAA-XXX) */
else if ((strlen(string) >= 11) && (string[3] == '-') && (string[7] == '-'))
{
/* 8-bit system only */
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
/*Patch and PAR*/
else if ((strlen(string) >=9) && (string[6] == ':'))
{
return 0;
}
/* decode 8-bit data */
for (i=0; i<2; i++)
{
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
n = (p - arvalidchars) & 0xF;
data |= (n << ((1 - i) * 4));
}
/* decode 16-bit address (low 12-bits) */
for (i=0; i<3; i++)
{
if (i==1) string++; /* skip separator */
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
n = (p - arvalidchars) & 0xF;
address |= (n << ((2 - i) * 4));
}
/* decode 16-bit address (high 4-bits) */
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
n = (p - arvalidchars) & 0xF;
n ^= 0xF; /* bits inversion */
address |= (n << 12);
/* RAM address are also supported */
if (address >= 0xC000)
{
/* convert to 24-bit Work RAM address */
address = 0xFF0000 | (address & 0x1FFF);
}
/* decode reference 8-bit data */
for (i=0; i<2; i++)
{
string++; /* skip separator and 2nd digit */
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
n = (p - arvalidchars) & 0xF;
ref |= (n << ((1 - i) * 4));
}
ref = (ref >> 2) | ((ref & 0x03) << 6); /* 2-bit right rotation */
ref ^= 0xBA; /* XOR */
/* update old data value */
cheatlist[index].old = ref;
/* code length */
len = 11;
}
/* Action Replay code */
else if (string[6] == ':')
{
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{
/* 16-bit code (AAAAAA:DDDD) */
if (strlen(string) < 11) return 0;
/* decode 24-bit address */
for (i=0; i<6; i++)
{
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
address |= (n << ((5 - i) * 4));
}
/* decode 16-bit data */
string++;
for (i=0; i<4; i++)
{
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
if (!p)
break;
n = (p - arvalidchars) & 0xF;
data |= (n << ((3 - i) * 4));
}
/* code length */
len = 11;
}
else
{
/* 8-bit code (xxAAAA:DD) */
if (strlen(string) < 9) return 0;
} else {
/*If System is Master-based*/
/* decode 16-bit address */
/*Game Genie*/
if ((strlen(string) >=7) && (string[3] == '-'))
{
/* decode 8-bit data */
for (i=0; i<2; i++)
{
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
data |= (n << ((1 - i) * 4));
}
/* decode 16-bit address (low 12-bits) */
for (i=0; i<3; i++)
{
if (i==1) string++; /* skip separator */
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
address |= (n << ((2 - i) * 4));
}
/* decode 16-bit address (high 4-bits) */
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
n ^= 0xF; /* bits inversion */
address |= (n << 12);
/* Optional: decode reference 8-bit data */
if (*string=='-')
{
for (i=0; i<2; i++)
{
string++; /* skip separator and 2nd digit */
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
ref |= (n << ((1 - i) * 4));
}
ref = (ref >> 2) | ((ref & 0x03) << 6); /* 2-bit right rotation */
ref ^= 0xBA; /* XOR */
/* code length */
len = 11;
}
else
{
/* code length */
len = 7;
}
}
/*Action Replay*/
else if ((strlen(string) >=9) && (string[4] == '-')){
string+=2;
/* decode 16-bit address */
for (i=0; i<4; i++)
{
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
address |= (n << ((3 - i) * 4));
if (i==1) string++;
}
/* decode 8-bit data */
for (i=0; i<2; i++)
{
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
data |= (n << ((1 - i) * 4));
}
/* code length */
len = 9;
}
/*Fusion RAM*/
else if ((strlen(string) >=7) && (string[4] == ':'))
{
/* decode 16-bit address */
for (i=0; i<4; i++)
{
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
address |= (n << ((3 - i) * 4));
}
/* ROM addresses are not supported */
if (address < 0xC000) return 0;
/* convert to 24-bit Work RAM address */
address = 0xFF0000 | (address & 0x1FFF);
/* decode 8-bit data */
string++;
for (i=0; i<2; i++)
{
p = strchr (arvalidchars, *string++);
if (p == NULL) return 0;
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
data |= (n << ((1 - i) * 4));
data |= (n << ((1 - i) * 4));
}
/* code length */
len = 7;
}
/*Fusion ROM*/
else if ((strlen(string) >=9) && (string[6] == ':'))
{
/* decode reference 8-bit data */
for (i=0; i<2; i++)
{
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
ref |= (n << ((1 - i) * 4));
}
/* decode 16-bit address */
for (i=0; i<4; i++)
{
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
address |= (n << ((3 - i) * 4));
}
/* decode 8-bit data */
string++;
for (i=0; i<2; i++)
{
p = strchr (arvalidchars, *string++);
if (!p)
return 0;
n = (p - arvalidchars) & 0xF;
data |= (n << ((1 - i) * 4));
}
/* code length */
len = 9;
}
/* convert to 24-bit Work RAM address */
if (address >= 0xC000)
address = 0xFF0000 | (address & 0x1FFF);
}
/* Valid code found ? */
if (len)
{
/* update cheat address & data values */
cheatlist[index].address = address;
cheatlist[index].data = data;
cheatlist[index].enable = 1; // Enable the cheat by default
cheatlist[index].old = ref;
}
/* return code length (0 = invalid) */
return len;
}
@@ -1538,16 +1591,41 @@ static uint32_t decode_cheat(char *string, int index)
static void apply_cheats(void)
{
uint8_t *ptr;
int i;
/* clear ROM&RAM patches counter */
maxROMcheats = maxRAMcheats = 0;
int i;
for (i = 0; i < maxcheats; i++)
{
if (cheatlist[i].enable)
{
if (cheatlist[i].address < cart.romsize)
/* detect Work RAM patch */
if (cheatlist[i].address >= 0xFF0000)
{
/* add RAM patch */
cheatIndexes[maxRAMcheats++] = i;
}
/* check if Mega-CD game is running */
else if ((system_hw == SYSTEM_MCD) && !scd.cartridge.boot)
{
/* detect PRG-RAM patch (Sub-CPU side) */
if (cheatlist[i].address < 0x80000)
{
/* add RAM patch */
cheatIndexes[maxRAMcheats++] = i;
}
/* detect Word-RAM patch (Main-CPU side)*/
else if ((cheatlist[i].address >= 0x200000) && (cheatlist[i].address < 0x240000))
{
/* add RAM patch */
cheatIndexes[maxRAMcheats++] = i;
}
}
/* detect cartridge ROM patch */
else if (cheatlist[i].address < cart.romsize)
{
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{
@@ -1560,16 +1638,13 @@ static void apply_cheats(void)
/* add ROM patch */
maxROMcheats++;
cheatIndexes[MAX_CHEATS - maxROMcheats] = i;
/* get current banked ROM address */
ptr = &z80_readmap[(cheatlist[i].address) >> 10][cheatlist[i].address & 0x03FF];
/* check if reference matches original ROM data */
if (((uint8_t)cheatlist[i].old) == *ptr)
{
/* patch data */
*ptr = cheatlist[i].data;
/* save patched ROM address */
cheatlist[i].prev = ptr;
}
@@ -1580,20 +1655,20 @@ static void apply_cheats(void)
}
}
}
else if (cheatlist[i].address >= 0xFF0000)
{
/* add RAM patch */
cheatIndexes[maxRAMcheats++] = i;
}
}
}
}
static void clear_cheats(void)
{
int i = maxcheats;
int i;
/* disable cheats in reversed order in case the same address is used by multiple patches */
/* no ROM patches with Mega-CD games */
if ((system_hw == SYSTEM_MCD) && !scd.cartridge.boot)
return;
/* disable cheats in reversed order in case the same address is used by multiple ROM patches */
i = maxcheats;
while (i > 0)
{
if (cheatlist[i-1].enable)
@@ -1612,34 +1687,12 @@ static void clear_cheats(void)
{
/* restore original data */
*cheatlist[i-1].prev = cheatlist[i-1].old;
/* no more patched ROM address */
cheatlist[i-1].prev = NULL;
}
}
}
}
i--;
}
}
static void remove_cheats(void)
{
int i = maxcheats;
while (i > 0)
{
if (cheatlist[i-1].enable)
{
cheatlist[i-1].text[0] = 0;
cheatlist[i-1].code[0] = 0;
cheatlist[i-1].address = 0;
cheatlist[i-1].data = 0;
cheatlist[i-1].enable = 0;
maxcheats--;
}
i--;
}
}
@@ -1650,8 +1703,10 @@ static void remove_cheats(void)
* Apply RAM patches (this should be called once per frame)
*
****************************************************************************/
void RAMCheatUpdate(void)
static void RAMCheatUpdate(void)
{
uint8_t *base;
uint32_t mask;
int index, cnt = maxRAMcheats;
while (cnt)
@@ -1659,20 +1714,44 @@ void RAMCheatUpdate(void)
/* get cheat index */
index = cheatIndexes[--cnt];
/* detect destination RAM */
switch ((cheatlist[index].address >> 20) & 0xf)
{
case 0x0: /* Mega-CD PRG-RAM (512 KB) */
base = scd.prg_ram;
mask = 0x7fffe;
break;
case 0x2: /* Mega-CD 2M Word-RAM (256 KB) */
base = scd.word_ram_2M;
mask = 0x3fffe;
break;
default: /* Work-RAM (64 KB) */
base = work_ram;
mask = 0xfffe;
break;
}
/* apply RAM patch */
// TODO: Investigate. Some PAR cheats for Genesis don't work otherwise.
// e.g. Sonic The Hedgehog 2 (World) (Rev A).md (MD5 9feeb724052c39982d432a7851c98d3e) using Invincibility (Sonic only) code FFB02B:0002
// Fixes possible endianness issue, also does not invoke pointer typecasting UB
bool isSega16bit = ((system_hw & SYSTEM_PBC) == SYSTEM_MD) || (system_hw == SYSTEM_MCD);
//if (cheatlist[index].data & 0xFF00)
//if (cheatlist[index].data & 0x00FF) // For LSB?
BOOL isSega8bit = [_current.systemIdentifier isEqualToString:@"openemu.system.gg"] || [_current.systemIdentifier isEqualToString:@"openemu.system.sms"] || [_current.systemIdentifier isEqualToString:@"openemu.system.sg1000"];
// TODO: Figure out why this is. Some PAR cheats for Genesis don't work otherwise.
if (isSega8bit ? cheatlist[index].data & 0xFF00 : cheatlist[index].data & 0x00FF)
if (isSega16bit ? cheatlist[index].data & 0x00FF : cheatlist[index].data & 0xFF00)
{
/* word patch */
*(uint16_t *)(work_ram + (cheatlist[index].address & 0xFFFE)) = cheatlist[index].data;
unsigned addr = cheatlist[index].address & mask;
base[addr] = cheatlist[index].data & 0xFF;
base[addr + 1] = (cheatlist[index].data & 0xFF00) >> 8;
//*(uint16_t *)(base + (cheatlist[index].address & mask)) = cheatlist[index].data;
}
else
{
/* byte patch */
work_ram[cheatlist[index].address & 0xFFFF] = cheatlist[index].data;
mask |= 1;
base[cheatlist[index].address & mask] = cheatlist[index].data;
}
}
}
@@ -1706,8 +1785,8 @@ void ROMCheatUpdate(void)
/* get current banked ROM address */
ptr = &z80_readmap[(cheatlist[index].address) >> 10][cheatlist[index].address & 0x03FF];
/* check if reference matches original ROM data */
if (((uint8_t)cheatlist[index].old) == *ptr)
/* check if reference exists and matches original ROM data */
if (!cheatlist[index].old || ((uint8_t)cheatlist[index].old) == *ptr)
{
/* patch data */
*ptr = cheatlist[index].data;
+23 -15
View File
@@ -36,6 +36,7 @@
/* Begin PBXBuildFile section */
82287C39101E9DB40072172D /* GenPlusGameCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 82287C34101E9DB40072172D /* GenPlusGameCore.m */; };
87709EF32950DA090084AEE0 /* megasd.c in Sources */ = {isa = PBXBuildFile; fileRef = 87709EF22950DA090084AEE0 /* megasd.c */; };
879243AE1C0D044B0064C515 /* xe_1ap.c in Sources */ = {isa = PBXBuildFile; fileRef = 879243AC1C0D044B0064C515 /* xe_1ap.c */; };
879243B11C0D05120064C515 /* graphic_board.c in Sources */ = {isa = PBXBuildFile; fileRef = 879243AF1C0D05120064C515 /* graphic_board.c */; };
87E0514D1B18092700E870E1 /* scrc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 87E0514B1B18092700E870E1 /* scrc32.c */; };
@@ -126,21 +127,23 @@
/* 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>"; };
825C7E44101FAB7F0072187B /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
87709EF12950DA080084AEE0 /* megasd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = megasd.h; sourceTree = "<group>"; };
87709EF22950DA090084AEE0 /* megasd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = megasd.c; sourceTree = "<group>"; };
879243AC1C0D044B0064C515 /* xe_1ap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xe_1ap.c; sourceTree = "<group>"; };
879243AD1C0D044B0064C515 /* xe_1ap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xe_1ap.h; sourceTree = "<group>"; };
879243AF1C0D05120064C515 /* graphic_board.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = graphic_board.c; sourceTree = "<group>"; };
879243B01C0D05120064C515 /* graphic_board.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphic_board.h; sourceTree = "<group>"; };
87D7BFC01F9841EE000B38DE /* OESMSSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OESMSSystemResponderClient.h; path = ../OpenEmu/SegaMasterSystem/OESMSSystemResponderClient.h; sourceTree = "<group>"; };
87D7BFC11F9841F8000B38DE /* OEGGSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEGGSystemResponderClient.h; path = ../OpenEmu/GameGear/OEGGSystemResponderClient.h; sourceTree = "<group>"; };
87D7BFC21F984206000B38DE /* OESG1000SystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OESG1000SystemResponderClient.h; path = "../OpenEmu/SG-1000/OESG1000SystemResponderClient.h"; sourceTree = "<group>"; };
87D7BFC01F9841EE000B38DE /* OESMSSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OESMSSystemResponderClient.h; path = ../OpenEmu/SystemPlugins/SegaMasterSystem/OESMSSystemResponderClient.h; sourceTree = "<group>"; };
87D7BFC11F9841F8000B38DE /* OEGGSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEGGSystemResponderClient.h; path = ../OpenEmu/SystemPlugins/GameGear/OEGGSystemResponderClient.h; sourceTree = "<group>"; };
87D7BFC21F984206000B38DE /* OESG1000SystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OESG1000SystemResponderClient.h; path = "../OpenEmu/SystemPlugins/SG-1000/OESG1000SystemResponderClient.h"; sourceTree = "<group>"; };
87E0514A1B18092700E870E1 /* osd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osd.h; sourceTree = "<group>"; };
87E0514B1B18092700E870E1 /* scrc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scrc32.c; sourceTree = "<group>"; };
87E0514C1B18092700E870E1 /* scrc32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scrc32.h; sourceTree = "<group>"; };
@@ -156,7 +159,7 @@
941FF4F8162A4BAE005A9427 /* eeprom_spi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eeprom_spi.h; sourceTree = "<group>"; };
941FF4FC162A4BE1005A9427 /* blip_buf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blip_buf.c; sourceTree = "<group>"; };
941FF4FD162A4BE1005A9427 /* blip_buf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blip_buf.h; sourceTree = "<group>"; };
946C18AE17148D5200C64BF9 /* OESegaCDSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OESegaCDSystemResponderClient.h; path = "../OpenEmu/Sega CD/OESegaCDSystemResponderClient.h"; sourceTree = "<group>"; };
946C18AE17148D5200C64BF9 /* OESegaCDSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OESegaCDSystemResponderClient.h; path = "../OpenEmu/SystemPlugins/Sega CD/OESegaCDSystemResponderClient.h"; sourceTree = "<group>"; };
948DA2A115AB906400C0EA78 /* cd_cart.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cd_cart.c; sourceTree = "<group>"; };
948DA2A215AB906400C0EA78 /* cd_cart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cd_cart.h; sourceTree = "<group>"; };
948DA2A315AB906400C0EA78 /* cdc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cdc.c; sourceTree = "<group>"; };
@@ -256,9 +259,9 @@
94ED8A8514CF933700FF8901 /* osd_cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osd_cpu.h; sourceTree = "<group>"; };
94ED8A8614CF933700FF8901 /* z80.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = z80.c; sourceTree = "<group>"; };
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>"; };
C6B948191365164700A425F0 /* OEGenesisSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEGenesisSystemResponderClient.h; path = ../OpenEmu/SystemPlugins/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 */
@@ -431,6 +434,8 @@
94ED896F14CF933600FF8901 /* ggenie.h */,
94ED897014CF933600FF8901 /* md_cart.c */,
94ED897114CF933600FF8901 /* md_cart.h */,
87709EF22950DA090084AEE0 /* megasd.c */,
87709EF12950DA080084AEE0 /* megasd.h */,
94ED897214CF933600FF8901 /* sms_cart.c */,
94ED897314CF933600FF8901 /* sms_cart.h */,
94ED897414CF933600FF8901 /* sram.c */,
@@ -570,15 +575,13 @@
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 0700;
};
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "GenesisPlus" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 1;
knownRegions = (
English,
en,
);
mainGroup = 089C166AFE841209C02AAC07 /* GenesisPlus */;
@@ -634,7 +637,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = /usr/bin/openemu_rb_automation.rb;
shellScript = "/usr/bin/openemu_rb_automation.rb\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -675,6 +678,7 @@
94ED8B2914CF933800FF8901 /* membnk.c in Sources */,
94ED8B2A14CF933800FF8901 /* memz80.c in Sources */,
94ED8B3714CF933800FF8901 /* state.c in Sources */,
87709EF32950DA090084AEE0 /* megasd.c in Sources */,
94ED8B3814CF933800FF8901 /* system.c in Sources */,
87E0514D1B18092700E870E1 /* scrc32.c in Sources */,
94ED8B4D14CF933800FF8901 /* vdp_ctrl.c in Sources */,
@@ -715,7 +719,7 @@
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
089C167EFE841241C02AAC07 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
@@ -735,6 +739,8 @@
OTHER_CFLAGS = (
"-DLSB_FIRST",
"-DUSE_32BPP_RENDERING",
"-DMAXROMSIZE=33554432",
"-DENABLE_SUB_68K_ADDRESS_ERROR_EXCEPTIONS",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.openemu.${PRODUCT_NAME:identifier}";
PRODUCT_NAME = GenesisPlus;
@@ -755,6 +761,8 @@
OTHER_CFLAGS = (
"-DLSB_FIRST",
"-DUSE_32BPP_RENDERING",
"-DMAXROMSIZE=33554432",
"-DENABLE_SUB_68K_ADDRESS_ERROR_EXCEPTIONS",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.openemu.${PRODUCT_NAME:identifier}";
PRODUCT_NAME = GenesisPlus;
+3 -3
View File
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
@@ -19,7 +19,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.7.4.11</string>
<string>1.7.5.1</string>
<key>NSPrincipalClass</key>
<string>OEGameCoreController</string>
<key>OEGameCoreClass</key>
@@ -122,7 +122,7 @@
<key>OEGameCorePlayerCount</key>
<string>8</string>
<key>OEProjectURL</key>
<string>http://code.google.com/p/genplus-gx</string>
<string>https://github.com/ekeeke/Genesis-Plus-GX</string>
<key>OESystemIdentifiers</key>
<array>
<string>openemu.system.sg1000</string>
+2
View File
@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */
+38 -58
View File
@@ -1,8 +1,8 @@
/****************************************************************************
* Genesis Plus
* Action Replay / Pro Action Replay emulation
* Action Replay / Pro Action Replay hardware support
*
* Copyright (C) 2009-2014 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2009-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -45,8 +45,7 @@ static struct
{
uint8 enabled;
uint8 status;
uint8 *rom;
uint8 *ram;
uint8 ram[0x10000];
uint16 regs[13];
uint16 old[4];
uint16 data[4];
@@ -54,64 +53,52 @@ static struct
} action_replay;
static void ar_write_regs(uint32 address, uint32 data);
static void ar_write_regs_2(uint32 address, uint32 data);
static void ar2_write_reg(uint32 address, uint32 data);
static void ar_write_ram_8(uint32 address, uint32 data);
void areplay_init(void)
{
int size;
memset(&action_replay,0,sizeof(action_replay));
action_replay.enabled = action_replay.status = 0;
/* store Action replay ROM (max. 128k) & RAM (64k) above cartridge ROM + SRAM area */
if (cart.romsize > 0x810000) return;
action_replay.rom = cart.rom + 0x810000;
action_replay.ram = cart.rom + 0x830000;
/* try to load Action Replay ROM file */
size = load_archive(AR_ROM, action_replay.rom, 0x20000, NULL);
/* detect Action Replay board type */
switch (size)
/* try to load Action Replay ROM file (max. 64KB) */
if (load_archive(AR_ROM, cart.lockrom, 0x10000, NULL) > 0)
{
case 0x8000:
/* detect Action Replay board type */
if (!memcmp(cart.lockrom + 0x120, "ACTION REPLAY ", 16))
{
if (!memcmp(action_replay.rom + 0x120, "ACTION REPLAY ", 16))
{
/* normal Action Replay (32K) */
action_replay.enabled = TYPE_AR;
/* internal registers mapped at $010000-$01ffff */
m68k.memory_map[0x01].write16 = ar_write_regs;
break;
}
}
/* normal Action Replay (32KB ROM) */
action_replay.enabled = TYPE_AR;
case 0x10000:
case 0x20000:
/* $0000-$7fff mirrored into $8000-$ffff */
memcpy(cart.lockrom + 0x8000, cart.lockrom, 0x8000);
/* internal registers mapped at $010000-$01ffff */
m68k.memory_map[0x01].write16 = ar_write_regs;
}
else
{
/* Read stack pointer MSB */
uint8 sp = READ_BYTE(action_replay.rom, 0x01);
uint8 sp = cart.lockrom[0x01];
/* Detect board version */
if ((sp == 0x42) && !memcmp(action_replay.rom + 0x120, "ACTION REPLAY 2 ", 16))
if ((sp == 0x42) && !memcmp(cart.lockrom + 0x120, "ACTION REPLAY 2 ", 16))
{
/* PRO Action Replay 1 (64/128K) */
/* PRO Action Replay (2x32KB ROM) */
action_replay.enabled = TYPE_PRO1;
/* internal registers mapped at $010000-$01ffff */
m68k.memory_map[0x01].write16 = ar_write_regs;
}
else if ((sp == 0x60) && !memcmp(action_replay.rom + 0x3c6, "ACTION REPLAY II", 16))
else if ((sp == 0x60) && !memcmp(cart.lockrom + 0x3c6, "ACTION REPLAY II", 16))
{
/* PRO Action Replay 2 (64K) */
/* PRO Action Replay 2 (2x32KB ROM) */
action_replay.enabled = TYPE_PRO2;
/* internal registers mapped at $100000-$10ffff */
m68k.memory_map[0x10].write16 = ar_write_regs_2;
/* internal register mapped at $100000-$10ffff */
m68k.memory_map[0x10].write16 = ar2_write_reg;
}
/* internal RAM (64k), mapped at $420000-$42ffff or $600000-$60ffff */
/* internal RAM (64KB), mapped at $420000-$42ffff or $600000-$60ffff */
if (action_replay.enabled)
{
m68k.memory_map[sp].base = action_replay.ram;
@@ -120,28 +107,22 @@ void areplay_init(void)
m68k.memory_map[sp].write8 = ar_write_ram_8;
m68k.memory_map[sp].write16 = NULL;
}
break;
}
default:
{
break;
}
}
#ifdef LSB_FIRST
if (action_replay.enabled)
{
int i;
for (i= 0; i<size; i+=2)
if (action_replay.enabled)
{
/* Byteswap ROM */
uint8 temp = action_replay.rom[i];
action_replay.rom[i] = action_replay.rom[i+1];
action_replay.rom[i+1] = temp;
int i;
for (i= 0; i<0x10000; i+=2)
{
/* Byteswap ROM */
uint8 temp = cart.lockrom[i];
cart.lockrom[i] = cart.lockrom[i+1];
cart.lockrom[i+1] = temp;
}
}
}
#endif
}
}
void areplay_shutdown(void)
@@ -166,7 +147,7 @@ void areplay_reset(int hard)
memset(action_replay.addr, 0, sizeof(action_replay.addr));
/* by default, internal ROM is mapped at $000000-$00FFFF */
m68k.memory_map[0].base = action_replay.rom;
m68k.memory_map[0].base = cart.lockrom;
/* reset internal RAM on power-on */
if (hard)
@@ -287,7 +268,7 @@ static void ar_write_regs(uint32 address, uint32 data)
}
}
static void ar_write_regs_2(uint32 address, uint32 data)
static void ar2_write_reg(uint32 address, uint32 data)
{
/* enable Cartridge ROM */
if (((address & 0xff) == 0x78) && (data == 0xffff))
@@ -301,4 +282,3 @@ static void ar_write_ram_8(uint32 address, uint32 data)
/* byte writes are handled as word writes, with LSB duplicated in MSB (/LWR is not used) */
*(uint16 *)(action_replay.ram + (address & 0xfffe)) = (data | (data << 8));
}
+2 -2
View File
@@ -1,8 +1,8 @@
/****************************************************************************
* Genesis Plus
* DATEL Action Replay / Pro Action Replay emulation
* Action Replay / Pro Action Replay hardware support
*
* Copyright (C) 2009-2014 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2009-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
+1 -1
View File
@@ -47,7 +47,7 @@
T_EEPROM_93C eeprom_93c;
void eeprom_93c_init()
void eeprom_93c_init(void)
{
/* default eeprom state */
memset(&eeprom_93c, 0, sizeof(T_EEPROM_93C));
+1 -1
View File
@@ -65,7 +65,7 @@ typedef struct
extern T_EEPROM_93C eeprom_93c;
/* Function prototypes */
extern void eeprom_93c_init();
extern void eeprom_93c_init(void);
extern void eeprom_93c_write(unsigned char data);
extern unsigned char eeprom_93c_read(void);
+3 -3
View File
@@ -179,7 +179,7 @@ static struct
/* I2C EEPROM mapper initialization */
/********************************************************************/
void eeprom_i2c_init()
void eeprom_i2c_init(void)
{
int i = sizeof(i2c_database) / sizeof(T_I2C_GAME) - 1;
@@ -246,7 +246,7 @@ void eeprom_i2c_init()
/* I2C EEPROM internal */
/********************************************************************/
INLINE void Detect_START()
INLINE void Detect_START(void)
{
/* detect SDA HIGH to LOW transition while SCL is held HIGH */
if (eeprom_i2c.old_scl && eeprom_i2c.scl)
@@ -273,7 +273,7 @@ INLINE void Detect_START()
}
}
INLINE void Detect_STOP()
INLINE void Detect_STOP(void)
{
/* detect SDA LOW to HIGH transition while SCL is held HIGH */
if (eeprom_i2c.old_scl && eeprom_i2c.scl)
+1 -1
View File
@@ -40,6 +40,6 @@
#define _EEPROM_I2C_H_
/* Function prototypes */
extern void eeprom_i2c_init();
extern void eeprom_i2c_init(void);
#endif
+1 -1
View File
@@ -72,7 +72,7 @@ typedef struct
static T_EEPROM_SPI spi_eeprom;
void eeprom_spi_init()
void eeprom_spi_init(void)
{
/* reset eeprom state */
memset(&spi_eeprom, 0, sizeof(T_EEPROM_SPI));
+1 -1
View File
@@ -40,7 +40,7 @@
#define _EEPROM_SPI_H_
/* Function prototypes */
extern void eeprom_spi_init();
extern void eeprom_spi_init(void);
extern void eeprom_spi_write(unsigned char data);
extern unsigned int eeprom_spi_read(unsigned int address);
+12 -17
View File
@@ -1,8 +1,8 @@
/****************************************************************************
* Genesis Plus
* Game Genie Hardware emulation
* Game Genie hardware support
*
* Copyright (C) 2009-2014 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2009-2021 Eke-Eke (Genesis Plus GX)
*
* Based on documentation from Charles McDonald
* (http://cgfm2.emuviews.com/txt/genie.txt)
@@ -44,7 +44,6 @@
static struct
{
uint8 enabled;
uint8 *rom;
uint16 regs[0x20];
uint16 old[6];
uint16 data[6];
@@ -58,29 +57,25 @@ static void ggenie_write_word(unsigned int address, unsigned int data);
static void ggenie_write_regs(unsigned int offset, unsigned int data);
void ggenie_init(void)
{
memset(&ggenie,0,sizeof(ggenie));
{
ggenie.enabled = 0;
/* Store Game Genie ROM (32k) above cartridge ROM + SRAM area */
if (cart.romsize > 0x810000) return;
ggenie.rom = cart.rom + 0x810000;
/* Try to load Game Genie ROM file */
if (load_archive(GG_ROM, ggenie.rom, 0x8000, NULL) > 0)
/* Try to load Game Genie ROM file (32KB) */
if (load_archive(GG_ROM, cart.lockrom, 0x8000, NULL) > 0)
{
#ifdef LSB_FIRST
int i;
for (i=0; i<0x8000; i+=2)
{
/* Byteswap ROM */
uint8 temp = ggenie.rom[i];
ggenie.rom[i] = ggenie.rom[i+1];
ggenie.rom[i+1] = temp;
uint8 temp = cart.lockrom[i];
cart.lockrom[i] = cart.lockrom[i+1];
cart.lockrom[i+1] = temp;
}
#endif
/* $0000-$7fff mirrored into $8000-$ffff */
memcpy(ggenie.rom + 0x8000, ggenie.rom, 0x8000);
memcpy(cart.lockrom + 0x8000, cart.lockrom, 0x8000);
/* Game Genie hardware is enabled */
ggenie.enabled = 1;
@@ -113,7 +108,7 @@ void ggenie_reset(int hard)
}
/* Game Genie ROM is mapped at $000000-$007fff */
m68k.memory_map[0].base = ggenie.rom;
m68k.memory_map[0].base = cart.lockrom;
/* Internal registers are mapped at $000000-$00001f */
m68k.memory_map[0].write8 = ggenie_write_byte;
@@ -214,7 +209,7 @@ static void ggenie_write_regs(unsigned int offset, unsigned int data)
else
{
/* $0000-$7ffff reads mapped to Game Genie ROM */
m68k.memory_map[0].base = ggenie.rom;
m68k.memory_map[0].base = cart.lockrom;
m68k.memory_map[0].read8 = NULL;
m68k.memory_map[0].read16 = NULL;
+2 -2
View File
@@ -1,8 +1,8 @@
/****************************************************************************
* Genesis Plus
* Game Genie Hardware emulation
* Game Genie hardware support
*
* Copyright (C) 2009-2014 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2009-2021 Eke-Eke (Genesis Plus GX)
*
* Based on documentation from Charles McDonald
* (http://cgfm2.emuviews.com/txt/genie.txt)
File diff suppressed because it is too large Load Diff
+10 -3
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-2023 Eke-Eke (Genesis Plus GX)
*
* Most cartridge protections were initially documented by Haze
* (http://haze.mameworld.info/)
@@ -55,9 +55,16 @@
#define TYPE_AR 0x02 /* (Pro) Action Replay */
#define TYPE_SK 0x03 /* Sonic & Knuckles */
/* CD hardware add-on (MD mode) */
#define HW_ADDON_AUTO 0x00
#define HW_ADDON_MEGACD 0x01
#define HW_ADDON_MEGASD 0x02
#define HW_ADDON_NONE 0x03
/* Special hardware (0x01 & 0x02 reserved for Master System 3-D glasses & Terebi Oekaki) */
#define HW_J_CART 0x04
#define HW_LOCK_ON 0x08
#define HW_MEGASD 0x10
/* Cartridge extra hardware */
typedef struct
@@ -81,10 +88,10 @@ typedef struct
uint32 mask; /* ROM mask */
uint8 special; /* custom external hardware (Lock-On, J-Cart, 3-D glasses, Terebi Oekaki,...) */
cart_hw_t hw; /* cartridge internal hardware */
uint8 rom[MAXROMSIZE]; /* ROM area */
uint8 lockrom[0x10000]; /* Game Genie / (Pro) Action Replay Lock-On ROM area (max 64KB) */
uint8 rom[MAXROMSIZE]; /* cartridge ROM area */
} md_cart_t;
/* Function prototypes */
extern void md_cart_init(void);
extern void md_cart_reset(int hard_reset);
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
/****************************************************************************
* Genesis Plus
* MegaSD flashcart CD hardware interface overlay & enhanced ROM mappers
*
* Copyright (C) 2020-2022 Eke-Eke (Genesis Plus GX)
*
* 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.
*
****************************************************************************************/
#ifndef _MEGASD_H_
#define _MEGASD_H_
#include "shared.h"
extern void megasd_reset(void);
extern void megasd_rom_mapper_w(unsigned int address, unsigned int data);
extern void megasd_enhanced_ssf2_mapper_w(unsigned int address, unsigned int data);
extern void megasd_update_cdda(unsigned int samples);
extern int megasd_context_save(uint8 *state);
extern int megasd_context_load(uint8 *state);
#endif
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* SG-1000, Master System & Game Gear cartridge hardware support
*
* Copyright (C) 2007-2019 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2023 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,6 +47,7 @@
extern void sms_cart_init(void);
extern void sms_cart_reset(void);
extern void sms_cart_switch(uint8 mode);
extern int sms_cart_ram_size(void);
extern int sms_cart_region_detect(void);
extern int sms_cart_context_save(uint8 *state);
extern int sms_cart_context_load(uint8 *state);
+13 -12
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* Backup RAM support
*
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -59,13 +59,10 @@ T_SRAM sram;
*
* Assuming max. 64k backup RAM throughout
****************************************************************************/
void sram_init()
void sram_init(void)
{
memset(&sram, 0, sizeof (T_SRAM));
/* backup RAM data is stored above cartridge ROM area, at $800000-$80FFFF (max. 64K) */
if (cart.romsize > 0x800000) return;
sram.sram = cart.rom + 0x800000;
/* disable Backup RAM by default */
sram.detected = sram.on = sram.custom = sram.start = sram.end = 0;
/* initialize Backup RAM */
if (strstr(rominfo.international,"Sonic 1 Remastered"))
@@ -147,6 +144,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 +218,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 +228,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);
}
+3 -3
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* Backup RAM support
*
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2021 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,11 +47,11 @@ typedef struct
uint32 start;
uint32 end;
uint32 crc;
uint8 *sram;
uint8 sram[0x10000];
} T_SRAM;
/* Function prototypes */
extern void sram_init();
extern void sram_init(void);
extern unsigned int sram_read_byte(unsigned int address);
extern unsigned int sram_read_word(unsigned int address);
extern void sram_write_byte(unsigned int address, unsigned int data);
+1 -2
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* CD compatible ROM/RAM cartridge support
*
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2012-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -38,7 +38,6 @@
#include "shared.h"
/*--------------------------------------------------------------------------*/
/* backup RAM cartridge (max. 512KB) */
/*--------------------------------------------------------------------------*/
+3 -2
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* CD compatible ROM/RAM cartridge support
*
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2012-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -40,7 +40,8 @@
/* CD compatible ROM/RAM cartridge */
typedef struct
{
uint8 area[0x840080]; /* cartridge ROM/RAM area (max. 8MB ROM + 64KB backup memory + Pro Action Replay 128KB ROM / 64KB RAM + cartridge infos) */
uint8 reserved[0x80]; /* reserved for ROM cartridge infos (see md_cart.h) */
uint8 area[0x810000]; /* cartridge ROM/RAM area (max. 8MB ROM + Pro Action Replay 64KB ROM) */
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:
File diff suppressed because it is too large Load Diff
+7 -3
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-2023 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -86,6 +86,8 @@ typedef struct
int start;
int end;
int type;
int loopEnabled;
int loopOffset;
} track_t;
/* CD TOC */
@@ -133,11 +135,13 @@ typedef struct
extern void cdd_init(int samplerate);
extern void cdd_reset(void);
extern int cdd_context_save(uint8 *state);
extern int cdd_context_load(uint8 *state);
extern int cdd_context_load(uint8 *state, char *version);
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_seek_audio(int index, int lba);
extern void cdd_read_audio(unsigned int samples);
extern void cdd_update_audio(unsigned int samples);
extern void cdd_update(void);
extern void cdd_process(void);
+135 -133
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* CD graphics processor
*
* Copyright (C) 2012 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2012-2022 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 ;
@@ -475,6 +460,9 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
uint16 stamp_data;
uint32 stamp_index;
/* bits [1:0] of 32x32 pixels stamp index are masked (see Chuck Rock II - Son of Chuck) */
uint32 stamp_mask = (scd.regs[0x58>>1].byte.l & 0x02) ? 0x7fc : 0x7ff;
/* pixel map start position for current line (13.3 format converted to 13.11) */
uint32 xpos = *gfx.tracePtr++ << 8;
uint32 ypos = *gfx.tracePtr++ << 8;
@@ -517,7 +505,7 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
/* c = cell offset (0-3 for 16x16, 0-15 for 32x32) */
/* yyy = line offset (0-7) */
/* xxx = pixel offset (0-7) */
stamp_index = (stamp_data & 0x7ff) << 8;
stamp_index = (stamp_data & stamp_mask) << 8;
if (stamp_index)
{
@@ -598,132 +586,146 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
void gfx_start(unsigned int base, int cycles)
{
/* make sure 2M mode is enabled */
if (!(scd.regs[0x02>>1].byte.l & 0x04))
uint32 mask;
/* trace vector pointer */
gfx.tracePtr = (uint16 *)(scd.word_ram_2M + ((base << 2) & 0x3fff8));
/* stamps & stamp map size */
switch ((scd.regs[0x58>>1].byte.l >> 1) & 0x03)
{
uint32 mask;
/* trace vector pointer */
gfx.tracePtr = (uint16 *)(scd.word_ram_2M + ((base << 2) & 0x3fff8));
case 0:
gfx.dotMask = 0x07ffff; /* 256x256 dots/map */
gfx.stampShift = 11 + 4; /* 16x16 dots/stamps */
gfx.mapShift = 4; /* 16x16 stamps/map */
mask = 0x3fe00; /* 512 bytes/table */
break;
/* stamps & stamp map size */
switch ((scd.regs[0x58>>1].byte.l >> 1) & 0x03)
{
case 0:
gfx.dotMask = 0x07ffff; /* 256x256 dots/map */
gfx.stampShift = 11 + 4; /* 16x16 dots/stamps */
gfx.mapShift = 4; /* 16x16 stamps/map */
mask = 0x3fe00; /* 512 bytes/table */
break;
case 1:
gfx.dotMask = 0x07ffff; /* 256x256 dots/map */
gfx.stampShift = 11 + 5; /* 32x32 dots/stamps */
gfx.mapShift = 3; /* 8x8 stamps/map */
mask = 0x3ff80; /* 128 bytes/table */
break;
case 1:
gfx.dotMask = 0x07ffff; /* 256x256 dots/map */
gfx.stampShift = 11 + 5; /* 32x32 dots/stamps */
gfx.mapShift = 3; /* 8x8 stamps/map */
mask = 0x3ff80; /* 128 bytes/table */
break;
case 2:
gfx.dotMask = 0x7fffff; /* 4096*4096 dots/map */
gfx.stampShift = 11 + 4; /* 16x16 dots/stamps */
gfx.mapShift = 8; /* 256x256 stamps/map */
mask = 0x20000; /* 131072 bytes/table */
break;
case 2:
gfx.dotMask = 0x7fffff; /* 4096*4096 dots/map */
gfx.stampShift = 11 + 4; /* 16x16 dots/stamps */
gfx.mapShift = 8; /* 256x256 stamps/map */
mask = 0x20000; /* 131072 bytes/table */
break;
case 3:
gfx.dotMask = 0x7fffff; /* 4096*4096 dots/map */
gfx.stampShift = 11 + 5; /* 32x32 dots/stamps */
gfx.mapShift = 7; /* 128x128 stamps/map */
mask = 0x38000; /* 32768 bytes/table */
break;
}
/* stamp map table base address */
gfx.mapPtr = (uint16 *)(scd.word_ram_2M + ((scd.regs[0x5a>>1].w << 2) & mask));
/* image buffer column offset (64 pixels/cell, minus 7 pixels to restart at cell beginning) */
gfx.bufferOffset = (((scd.regs[0x5c>>1].byte.l & 0x1f) + 1) << 6) - 7;
/* image buffer start index in dot units (2 pixels/byte) */
gfx.bufferStart = (scd.regs[0x5e>>1].w << 3) & 0x7ffc0;
/* add image buffer horizontal dot offset */
gfx.bufferStart += (scd.regs[0x60>>1].byte.l & 0x3f);
/* reset GFX chip cycle counter */
gfx.cycles = cycles;
/* update GFX chip timings (see AC3:Thunderhawk / Thunderstrike) */
gfx.cyclesPerLine = 4 * 5 * scd.regs[0x62>>1].w;
/* start graphics operation */
scd.regs[0x58>>1].byte.h = 0x80;
case 3:
gfx.dotMask = 0x7fffff; /* 4096*4096 dots/map */
gfx.stampShift = 11 + 5; /* 32x32 dots/stamps */
gfx.mapShift = 7; /* 128x128 stamps/map */
mask = 0x38000; /* 32768 bytes/table */
break;
}
/* stamp map table base address */
gfx.mapPtr = (uint16 *)(scd.word_ram_2M + ((scd.regs[0x5a>>1].w << 2) & mask));
/* image buffer column offset (64 pixels/cell, minus 7 pixels to restart at cell beginning) */
gfx.bufferOffset = (((scd.regs[0x5c>>1].byte.l & 0x1f) + 1) << 6) - 7;
/* image buffer start index in dot units (2 pixels/byte) */
gfx.bufferStart = (scd.regs[0x5e>>1].w << 3) & 0x7ffc0;
/* add image buffer horizontal dot offset */
gfx.bufferStart += (scd.regs[0x60>>1].byte.l & 0x3f);
/* reset GFX chip cycle counter */
gfx.cycles = cycles;
/* update GFX chip timings (see AC3:Thunderhawk / Thunderstrike, Night Striker) */
/* number of Word-RAM accesses per image buffer rendered line: */
/* . 4 initial read accesses (Xposition, Yposition, Xoffset and Yoffset) */
/* . 2 read accesses per rendered pixels (stamp map + stamp pixel data) */
/* . 1 read-modify-write access per group of 4 rendered pixels */
/* each access (read or read-modify-write) takes 3 SUB-CPU cycles by default */
/* each access can be delayed by 1 to 3 CPU cycles in case of refresh or SUB-CPU access occuring on the same Word-RAM bank (not emulated) */
/* reference: https://github.com/MiSTer-devel/MegaCD_MiSTer/blob/master/docs/mcd%20logs/graphics_operations_and_68k_wordram_access.jpg */
/* TODO: figure what happen exactly when pixel offset is different from 0 */
/* for the moment, one additional read-modify-write access is assumed at the start if pixel offset is not aligned to 4 pixels */
gfx.cyclesPerLine = 4 * 3 * (4 + 2 * scd.regs[0x62>>1].w + ((scd.regs[0x62>>1].w + (scd.regs[0x60>>1].byte.l & 0x03) + 3) >> 2));
/* start graphics operation */
scd.regs[0x58>>1].byte.h = 0x80;
}
void gfx_update(int cycles)
{
/* synchronize GFX chip with SUB-CPU */
cycles -= gfx.cycles;
/* make sure SUB-CPU is ahead */
if (cycles > 0)
/* make sure Word-RAM is assigned to SUB-CPU in 2M mode */
if ((scd.regs[0x02>>1].byte.l & 0x05) != 0x01)
{
/* number of lines to process */
unsigned int lines = (cycles + gfx.cyclesPerLine - 1) / gfx.cyclesPerLine;
/* synchronize GFX processing with SUB-CPU */
cycles -= gfx.cycles;
/* check against remaining lines */
if (lines < scd.regs[0x64>>1].byte.l)
/* make sure SUB-CPU is ahead */
if (cycles > 0)
{
/* update Vdot remaining size */
scd.regs[0x64>>1].byte.l -= lines;
/* number of lines to process */
unsigned int lines = (cycles + gfx.cyclesPerLine - 1) / gfx.cyclesPerLine;
/* increment cycle counter */
gfx.cycles += lines * gfx.cyclesPerLine;
}
else
{
/* process remaining lines */
lines = scd.regs[0x64>>1].byte.l;
/* clear Vdot remaining size */
scd.regs[0x64>>1].byte.l = 0;
/* end of graphics operation */
scd.regs[0x58>>1].byte.h = 0;
/* SUB-CPU idle on register $58 polling ? */
if (s68k.stopped & (1<<0x08))
/* check against remaining lines */
if (lines < scd.regs[0x64>>1].byte.l)
{
/* sync SUB-CPU with GFX chip */
s68k.cycles = scd.cycles;
/* update Vdot remaining size */
scd.regs[0x64>>1].byte.l -= lines;
/* restart SUB-CPU */
s68k.stopped = 0;
/* increment cycle counter */
gfx.cycles += lines * gfx.cyclesPerLine;
}
else
{
/* process remaining lines */
lines = scd.regs[0x64>>1].byte.l;
/* clear Vdot remaining size */
scd.regs[0x64>>1].byte.l = 0;
/* end of graphics operation */
scd.regs[0x58>>1].byte.h = 0;
/* SUB-CPU idle on register $58 polling ? */
if (s68k.stopped & (1<<0x08))
{
/* sync SUB-CPU with GFX chip */
s68k.cycles = scd.cycles;
/* restart SUB-CPU */
s68k.stopped = 0;
#ifdef LOG_SCD
error("s68k started from %d cycles\n", s68k.cycles);
error("s68k started from %d cycles\n", s68k.cycles);
#endif
}
/* level 1 interrupt enabled ? */
if (scd.regs[0x32>>1].byte.l & 0x02)
{
/* trigger level 1 interrupt */
scd.pending |= (1 << 1);
/* update IRQ level */
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
}
}
/* level 1 interrupt enabled ? */
if (scd.regs[0x32>>1].byte.l & 0x02)
/* render lines */
while (lines--)
{
/* trigger level 1 interrupt */
scd.pending |= (1 << 1);
/* process dots to image buffer */
gfx_render(gfx.bufferStart, scd.regs[0x62>>1].w);
/* update IRQ level */
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
/* increment image buffer start index for next line (8 pixels/line) */
gfx.bufferStart += 8;
}
}
/* render lines */
while (lines--)
{
/* process dots to image buffer */
gfx_render(gfx.bufferStart, scd.regs[0x62>>1].w);
/* increment image buffer start index for next line (8 pixels/line) */
gfx.bufferStart += 8;
}
}
else
{
/* GFX processing is halted */
gfx.cycles = cycles;
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* CD graphics processor
*
* Copyright (C) 2012 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2012-2022 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,7 +39,7 @@
#include <stdlib.h>
#include <string.h>
#if defined(_MSC_VER) && !defined(_XBOX)
#if defined(_MSC_VER) && !defined(_XBOX) && _MSC_VER > 1310
# include <intrin.h> /* for __cpuid() and _xgetbv() */
#endif
@@ -49,11 +49,6 @@
#ifdef DEBUG
#include <stdio.h>
#define dfprintf fprintf
#else
/* This is bad practice, it should be a static void empty function */
#define dfprintf(file, format, ...)
#endif
@@ -138,21 +133,23 @@ ia32_cpu_info (FLAC__CPUInfo *info)
info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 ) ? true : false;
}
dfprintf(stderr, "CPU info (IA-32):\n");
dfprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
dfprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
dfprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
dfprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
dfprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
dfprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
dfprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
dfprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
#ifdef DEBUG
fprintf(stderr, "CPU info (IA-32):\n");
fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
dfprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
dfprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
dfprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
}
#endif
/*
* now have to check for OS support of AVX instructions
@@ -164,9 +161,10 @@ ia32_cpu_info (FLAC__CPUInfo *info)
info->ia32.fma = false;
}
if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
dfprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n');
}
#ifdef DEBUG
if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED)
fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n');
#endif
#else
info->use_asm = false;
#endif
@@ -199,17 +197,20 @@ x86_64_cpu_info (FLAC__CPUInfo *info)
info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 ) ? true : false;
}
dfprintf(stderr, "CPU info (x86-64):\n");
dfprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n');
dfprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
dfprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
dfprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
#ifdef DEBUG
fprintf(stderr, "CPU info (x86-64):\n");
fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
if (FLAC__AVX_SUPPORTED) {
dfprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n');
dfprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n');
dfprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n');
if (FLAC__AVX_SUPPORTED)
{
fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n');
fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n');
fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n');
}
#endif
/*
* now have to check for OS support of AVX instructions
@@ -221,9 +222,10 @@ x86_64_cpu_info (FLAC__CPUInfo *info)
info->x86.fma = false;
}
if (FLAC__AVX_SUPPORTED) {
dfprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
}
#ifdef DEBUG
if (FLAC__AVX_SUPPORTED)
fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
#endif
#else
/* Silence compiler warnings. */
(void) info;
@@ -38,7 +38,7 @@
#include "share/compat.h"
#if defined(_MSC_VER) && !defined(_XBOX)
#if defined(_MSC_VER) && !defined(_XBOX) && _MSC_VER > 1310
#include <intrin.h> /* for _BitScanReverse* */
#endif
@@ -49,7 +49,7 @@
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
#include <sys/types.h> /* for off_t */
#define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */
#if !defined __MINGW32__
#if !defined __MINGW32__ && _MSC_VER && _MSC_VER > 1310
#define fseeko _fseeki64
#define ftello _ftelli64
#else /* MinGW */
+46 -17
View File
@@ -201,6 +201,7 @@ typedef struct _zlib_allocator zlib_allocator;
struct _zlib_allocator
{
UINT32 * allocptr[MAX_ZLIB_ALLOCS];
UINT32 * allocptr2[MAX_ZLIB_ALLOCS];
};
typedef struct _zlib_codec_data zlib_codec_data;
@@ -220,10 +221,11 @@ struct _lzma_allocator
void (*Free)(void *p, void *address); /* address can be 0 */
void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
uint32_t* allocptr[MAX_LZMA_ALLOCS];
uint32_t* allocptr2[MAX_LZMA_ALLOCS];
};
typedef struct _lzma_codec_data lzma_codec_data;
struct _lzma_codec_data
struct _lzma_codec_data
{
CLzmaDec decoder;
lzma_allocator allocator;
@@ -375,6 +377,7 @@ void lzma_allocator_init(void* p)
/* reset pointer list */
memset(codec->allocptr, 0, sizeof(codec->allocptr));
memset(codec->allocptr2, 0, sizeof(codec->allocptr2));
codec->Alloc = lzma_fast_alloc;
codec->Free = lzma_fast_free;
}
@@ -403,11 +406,16 @@ void lzma_allocator_free(void* p )
*-------------------------------------------------
*/
/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
#define LZMA_MIN_ALIGNMENT_BITS 512
#define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8)
void *lzma_fast_alloc(void *p, size_t size)
{
int scan;
uint32_t *addr;
uint32_t *addr = NULL;
lzma_allocator *codec = (lzma_allocator *)(p);
uintptr_t vaddr = 0;
/* compute the size, rounding to the nearest 1k */
size = (size + 0x3ff) & ~0x3ff;
@@ -420,28 +428,37 @@ void *lzma_fast_alloc(void *p, size_t size)
{
/* set the low bit of the size so we don't match next time */
*ptr |= 1;
return ptr + 1;
/* return aligned address of the block */
return codec->allocptr2[scan];
}
}
/* alloc a new one and put it into the list */
addr = (uint32_t *)malloc(sizeof(uint8_t) * (size + sizeof(uint32_t)));
addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
if (addr==NULL)
return NULL;
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
{
if (codec->allocptr[scan] == NULL)
{
/* store block address */
codec->allocptr[scan] = addr;
/* compute aligned address, store it */
vaddr = (uintptr_t)addr;
vaddr = (vaddr + sizeof(uint32_t) + (LZMA_MIN_ALIGNMENT_BYTES-1)) & (~(LZMA_MIN_ALIGNMENT_BYTES-1));
codec->allocptr2[scan] = (uint32_t*)vaddr;
break;
}
}
/* set the low bit of the size so we don't match next time */
*addr = size | 1;
return addr + 1;
}
/* return aligned address */
return (void*)vaddr;
}
/*-------------------------------------------------
* lzma_fast_free - fast free for lzma, which
@@ -452,21 +469,22 @@ void *lzma_fast_alloc(void *p, size_t size)
void lzma_fast_free(void *p, void *address)
{
int scan;
uint32_t *ptr;
lzma_allocator *codec;
uint32_t *ptr = NULL;
lzma_allocator *codec = NULL;
if (address == NULL)
return;
codec = (lzma_allocator *)(p);
/* find the hunk */
ptr = (uint32_t *)(address) - 1;
ptr = (uint32_t *)address;
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
{
if (ptr == codec->allocptr[scan])
if (ptr == codec->allocptr2[scan])
{
/* clear the low bit of the size to allow matches */
*ptr &= ~1;
*codec->allocptr[scan] &= ~1;
return;
}
}
@@ -2458,9 +2476,14 @@ static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t
allocates and frees memory frequently
-------------------------------------------------*/
/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
#define ZLIB_MIN_ALIGNMENT_BITS 512
#define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
{
zlib_allocator *alloc = (zlib_allocator *)opaque;
uintptr_t paddr = 0;
UINT32 *ptr;
int i;
@@ -2475,12 +2498,14 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
{
/* set the low bit of the size so we don't match next time */
*ptr |= 1;
return ptr + 1;
/* return aligned block address */
return (voidpf)(alloc->allocptr2[i]);
}
}
/* alloc a new one */
ptr = (UINT32 *)malloc(size + sizeof(UINT32));
ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
if (!ptr)
return NULL;
@@ -2489,12 +2514,16 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
if (!alloc->allocptr[i])
{
alloc->allocptr[i] = ptr;
paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1));
alloc->allocptr2[i] = (uint32_t*)paddr;
break;
}
/* set the low bit of the size so we don't match next time */
*ptr = size | 1;
return ptr + 1;
/* return aligned block address */
return (voidpf)paddr;
}
@@ -2506,15 +2535,15 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
static void zlib_fast_free(voidpf opaque, voidpf address)
{
zlib_allocator *alloc = (zlib_allocator *)opaque;
UINT32 *ptr = (UINT32 *)address - 1;
UINT32 *ptr = (UINT32 *)address;
int i;
/* find the hunk */
for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
if (ptr == alloc->allocptr[i])
if (ptr == alloc->allocptr2[i])
{
/* clear the low bit of the size to allow matches */
*ptr &= ~1;
*(alloc->allocptr[i]) &= ~1;
return;
}
}
+11 -7
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* PCM sound chip (315-5476A) (RF5C164 compatible)
*
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2012-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -183,7 +183,11 @@ void pcm_run(unsigned int length)
if (r < -32768) r = -32768;
else if (r > 32767) r = 32767;
/* update Blip Buffer */
/* PCM output mixing level (0-100%) */
l = (l * config.pcm_volume) / 100;
r = (r * config.pcm_volume) / 100;
/* update blip buffer */
blip_add_delta_fast(snd.blips[1], i, l-prev_l, r-prev_r);
prev_l = l;
prev_r = r;
@@ -226,10 +230,10 @@ void pcm_update(unsigned int samples)
pcm.cycles = 0;
}
void pcm_write(unsigned int address, unsigned char data)
void pcm_write(unsigned int address, unsigned char data, unsigned int cycles)
{
/* synchronize PCM chip with SUB-CPU */
int clocks = s68k.cycles - pcm.cycles;
/* synchronize PCM chip with CPU */
int clocks = cycles - pcm.cycles;
if (clocks > 0)
{
/* number of internal clocks (samples) to run */
@@ -350,10 +354,10 @@ void pcm_write(unsigned int address, unsigned char data)
}
}
unsigned char pcm_read(unsigned int address)
unsigned char pcm_read(unsigned int address, unsigned int cycles)
{
/* synchronize PCM chip with SUB-CPU */
int clocks = s68k.cycles - pcm.cycles;
int clocks = cycles - pcm.cycles;
if (clocks > 0)
{
/* number of internal clocks (samples) to run */
+3 -3
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* PCM sound chip (315-5476A) (RF5C164 compatible)
*
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2012-2021 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,8 +70,8 @@ extern void pcm_reset(void);
extern int pcm_context_save(uint8 *state);
extern int pcm_context_load(uint8 *state);
extern void pcm_update(unsigned int samples);
extern void pcm_write(unsigned int address, unsigned char data);
extern unsigned char pcm_read(unsigned int address);
extern void pcm_write(unsigned int address, unsigned char data, unsigned int cycles);
extern unsigned char pcm_read(unsigned int address, unsigned int cycles);
extern void pcm_ram_dma_w(unsigned int words);
#endif
+111 -89
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-2022 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 ;
@@ -487,7 +482,7 @@ static unsigned int scd_read_byte(unsigned int address)
/* get /LDS only */
if (address & 1)
{
return pcm_read((address >> 1) & 0x1fff);
return pcm_read((address >> 1) & 0x1fff, s68k.cycles);
}
return s68k_read_bus_8(address);
@@ -553,7 +548,7 @@ static unsigned int scd_read_byte(unsigned int address)
}
/* Font data */
if ((address >= 0x50) && (address <= 0x56))
if ((address >= 0x50) && (address <= 0x57))
{
/* shifted 4-bit input (xxxx00) */
uint8 bits = (scd.regs[0x4e>>1].w >> (((address & 6) ^ 6) << 1)) << 2;
@@ -606,7 +601,7 @@ static unsigned int scd_read_word(unsigned int address)
if (!(address & 0x8000))
{
/* get /LDS only */
return pcm_read((address >> 1) & 0x1fff);
return pcm_read((address >> 1) & 0x1fff, s68k.cycles);
}
#ifdef LOG_SCD
@@ -769,7 +764,7 @@ static void scd_write_byte(unsigned int address, unsigned int data)
/* get /LDS only */
if (address & 1)
{
pcm_write((address >> 1) & 0x1fff, data);
pcm_write((address >> 1) & 0x1fff, data, s68k.cycles);
return;
}
@@ -803,6 +798,7 @@ static void scd_write_byte(unsigned int address, unsigned int data)
}
case 0x03: /* Memory Mode */
case 0x02: /* !LDS and !UDS are ignored (verified on real hardware, cf. Krikzz's mcd-verificator) */
{
s68k_poll_sync(1<<0x03);
@@ -936,6 +932,13 @@ static void scd_write_byte(unsigned int address, unsigned int data)
/* RET bit set in 2M mode */
if (data & 0x01)
{
/* check if graphics operation is running */
if (scd.regs[0x58>>1].byte.h & 0x80)
{
/* synchronize GFX processing with SUB-CPU */
gfx_update(s68k.cycles);
}
/* Word-RAM is returned to MAIN-CPU */
scd.dmna = 0;
@@ -957,8 +960,8 @@ static void scd_write_byte(unsigned int address, unsigned int data)
return;
}
case 0x0e: /* SUB-CPU communication flags */
case 0x0f: /* !LWR is ignored (Space Ace, Dragon's Lair) */
case 0x0f: /* SUB-CPU communication flags */
case 0x0e: /* !LDS and !UDS are ignored (verified on real hardware, cf. Krikzz's mcd-verificator, Space Ace, Dragon's Lair) */
{
s68k_poll_sync(1<<0x0f);
scd.regs[0x0f>>1].byte.l = data;
@@ -966,6 +969,7 @@ static void scd_write_byte(unsigned int address, unsigned int data)
}
case 0x31: /* Timer */
case 0x30: /* !LDS and !UDS are ignored (verified on real hardware, cf. Krikzz's mcd-verificator) */
{
/* reload timer (one timer clock = 384 CPU cycles) */
scd.timer = data * TIMERS_SCYCLES_RATIO;
@@ -997,26 +1001,11 @@ static void scd_write_byte(unsigned int address, unsigned int data)
return;
}
case 0x37: /* CDD control (controlled by BIOS, byte access only ?) */
case 0x4d: /* Font Color */
case 0x4c: /* !LDS and !UDS are ignored (verified on real hardware, cf. Krikzz's mcd-verificator) */
{
/* 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;
scd.regs[0x4c>>1].byte.l = data;
break;
}
default:
@@ -1055,7 +1044,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
if (!(address & 0x8000))
{
/* get /LDS only */
pcm_write((address >> 1) & 0x1fff, data);
pcm_write((address >> 1) & 0x1fff, data & 0xff, s68k.cycles);
return;
}
@@ -1214,6 +1203,13 @@ static void scd_write_word(unsigned int address, unsigned int data)
/* RET bit set in 2M mode */
if (data & 0x01)
{
/* check if graphics operation is running */
if (scd.regs[0x58>>1].byte.h & 0x80)
{
/* synchronize GFX processing with SUB-CPU */
gfx_update(s68k.cycles);
}
/* Word-RAM is returned to MAIN-CPU */
scd.dmna = 0;
@@ -1333,6 +1329,13 @@ static void scd_write_word(unsigned int address, unsigned int data)
return;
}
case 0x36: /* CDD control */
{
/* only bit 2 is writable (bits [1:0] forced to 0 by default) */
scd.regs[0x37>>1].byte.l = data & 0x04;
return;
}
case 0x4a: /* CDD command 9 (controlled by BIOS, word access only ?) */
{
scd.regs[0x4a>>1].w = 0;
@@ -1584,7 +1587,6 @@ void scd_init(void)
void scd_reset(int hard)
{
/* TODO: figure what exactly is resetted when RESET bit is cleared by SUB-CPU */
if (hard)
{
/* Clear all ASIC registers by default */
@@ -1594,7 +1596,6 @@ void scd_reset(int hard)
scd.dmna = 0;
/* H-INT default vector */
*(uint16 *)(m68k.memory_map[scd.cartridge.boot].base + 0x70) = 0x00FF;
*(uint16 *)(m68k.memory_map[scd.cartridge.boot].base + 0x72) = 0xFFFF;
/* Power ON initial values (MAIN-CPU side) */
@@ -1632,8 +1633,11 @@ void scd_reset(int hard)
}
else
{
/* Clear only SUB-CPU side registers */
memset(&scd.regs[0x04>>1], 0, sizeof(scd.regs) - 4);
/* TODO: figure what exactly is reset when RESET bit is cleared by SUB-CPU */
/* Clear only SUB-CPU side registers (communication registers are not cleared, see msu-md-sample.bin) */
scd.regs[0x04>>1].w = 0x0000;
scd.regs[0x0c>>1].w = 0x0000;
memset(&scd.regs[0x30>>1], 0, sizeof(scd.regs) - 0x30);
}
/* SUB-CPU side default values */
@@ -1673,6 +1677,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 +1690,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)
@@ -1851,7 +1873,7 @@ int scd_context_save(uint8 *state)
return bufferptr;
}
int scd_context_load(uint8 *state)
int scd_context_load(uint8 *state, char *version)
{
int i;
uint16 tmp16;
@@ -1873,7 +1895,7 @@ int scd_context_load(uint8 *state)
bufferptr += cdc_context_load(&state[bufferptr]);
/* CD Drive processor */
bufferptr += cdd_context_load(&state[bufferptr]);
bufferptr += cdd_context_load(&state[bufferptr], version);
/* PCM chip */
bufferptr += pcm_context_load(&state[bufferptr]);
+2 -2
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-2022 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -87,7 +87,7 @@ extern void scd_init(void);
extern void scd_reset(int hard);
extern void scd_update(unsigned int cycles);
extern void scd_end_frame(unsigned int cycles);
extern int scd_context_load(uint8 *state);
extern int scd_context_load(uint8 *state, char *version);
extern int scd_context_save(uint8 *state);
extern int scd_68k_irq_ack(int level);
extern void prg_ram_dma_w(unsigned int words);
+15 -5
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-2022 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -50,7 +50,7 @@ uint8 boot_rom[0x800]; /* Genesis BOOT ROM */
uint8 work_ram[0x10000]; /* 68K RAM */
uint8 zram[0x2000]; /* Z80 RAM */
uint32 zbank; /* Z80 bank window address */
uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
uint8 zstate; /* Z80 bus state (d0 = /RESET, d1 = BUSACK) */
uint8 pico_current; /* PICO current page */
static uint8 tmss[4]; /* TMSS security register */
@@ -161,6 +161,7 @@ void gen_init(void)
{
/* initialize SUB-CPU */
s68k_init();
s68k.aerr_enabled = config.addr_error;
/* initialize CD hardware */
scd_init();
@@ -220,6 +221,7 @@ void gen_init(void)
/* SG-1000 hardware */
case SYSTEM_SG:
case SYSTEM_SGII:
case SYSTEM_SGII_RAM_EXT:
{
z80_writeport = z80_sg_port_w;
z80_readport = z80_sg_port_r;
@@ -279,10 +281,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-2022 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
+1 -1
View File
@@ -56,7 +56,7 @@ void mouse_reset(int port)
mouse.Port = port;
}
unsigned char mouse_read()
unsigned char mouse_read(void)
{
unsigned int temp = 0x00;
int x = input.analog[mouse.Port][0];
+2 -2
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* XE-1AP analog controller support
*
* Copyright (C) 2011-2015 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2011-2023 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -96,7 +96,7 @@ INLINE unsigned char xe_1ap_read(int index)
case 9: /* CH3 low (Throttle vertical or horizontal direction) */
data = input.analog[port+1][0] & 0x0F;
break;
case 10: /* A B A' B' buttons status (active low) */
case 11: /* A B A' B' buttons status (active low) */
data = (~input.pad[port] >> 6) & 0x0F;
break;
default: /* N/A */
+1 -1
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* XE-1AP analog controller support
*
* Copyright (C) 2011-2015 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2011-2022 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
+84 -71
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-2022 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -58,20 +58,21 @@
#define ROMMEMO 456
#define ROMCOUNTRY 496
#define P3BUTTONS 1
#define P6BUTTONS 2
#define PKEYBOARD 4
#define PPRINTER 8
#define PBALL 16
#define PFLOPPY 32
#define PACTIVATOR 64
#define PTEAMPLAYER 128
#define PMSYSTEMPAD 256
#define PSERIAL 512
#define PTABLET 1024
#define PPADDLE 2048
#define PCDROM 4096
#define PMOUSE 8192
#define P3BUTTONS 0x0001
#define P6BUTTONS 0x0002
#define PKEYBOARD 0x0004
#define PPRINTER 0x0008
#define PBALL 0x0010
#define PFLOPPY 0x0020
#define PACTIVATOR 0x0040
#define PTEAMPLAYER 0x0080
#define PMSYSTEMPAD 0x0100
#define PSERIAL 0x0200
#define PTABLET 0x0400
#define PPADDLE 0x0800
#define PCDROM 0x1000
#define PMOUSE 0x2000
#define PMENACER 0x4000
#define MAXCOMPANY 64
#define MAXPERIPHERALS 15
@@ -288,7 +289,7 @@ void getrominfo(char *romheader)
/* Supported peripherals */
rominfo.peripherals = 0;
for (i = 0; i < 14; i++)
for (j=0; j < 14; j++)
for (j=0; j < MAXPERIPHERALS; j++)
if (romheader[ROMIOSUPPORT+i] == peripheralinfo[j].pID[0])
rominfo.peripherals |= (1 << j);
}
@@ -581,9 +582,6 @@ int load_rom(char *filename)
{
/* enable CD hardware */
system_hw = SYSTEM_MCD;
/* boot from CD hardware */
scd.cartridge.boot = 0x00;
}
else
{
@@ -647,7 +645,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)
{
@@ -708,10 +708,10 @@ int load_rom(char *filename)
/* Save auto-detected system hardware */
romtype = system_hw;
/* CD image file */
if (system_hw == SYSTEM_MCD)
{
{
/* try to load CD BOOTROM for selected region */
if (!load_bios(SYSTEM_MCD))
{
@@ -721,65 +721,52 @@ int load_rom(char *filename)
/* error booting from CD */
return (0);
}
}
/* CD BOOTROM */
else if (strstr(rominfo.ROMType, "BR") != NULL)
{
/* enable CD hardware */
system_hw = SYSTEM_MCD;
/* boot from CD hardware */
scd.cartridge.boot = 0x00;
/* copy ROM to BOOTROM area */
memcpy(scd.bootrom, cart.rom, sizeof(scd.bootrom));
/* mark CD BIOS as being loaded */
system_bios = system_bios | 0x10;
/* loaded CD BIOS region */
system_bios = (system_bios & 0xf0) | (region_code >> 4);
}
/* ROM cartridge (max. 8MB) with CD loaded */
else if ((cart.romsize <= 0x800000) && cdd.loaded)
/* 16-bit ROM cartridge (max. 8MB) with optional CD hardware add-on support enabled */
else if ((system_hw == SYSTEM_MD) && (cart.romsize <= 0x800000) && (config.add_on != HW_ADDON_NONE))
{
/* try to load CD BOOTROM */
if (load_bios(SYSTEM_MCD))
{
/* enable CD hardware */
system_hw = SYSTEM_MCD;
int len;
char fname[256];
/* boot from cartridge */
scd.cartridge.boot = 0x40;
#if defined(USE_LIBCHDR)
/* automatically try to load associated .chd file if no .cue file CD image loaded yet */
if (!cdd.loaded)
{
len = strlen(filename);
while ((len && (filename[len] != '.')) || (len > 251)) len--;
strncpy(fname, filename, len);
strcpy(&fname[len], ".chd");
fname[len+4] = 0;
cdd_load(fname, (char *)cdc.ram);
}
else
#endif
/* automatically enable CD hardware emulation (Mode 1) in case : */
/* - loaded ROM has known CD hardware support */
/* or */
/* - CD hardware emulation is forced on */
/* or */
/* - MegaSD add-on emulation is disabled and normal CD image file is loaded */
if ((rominfo.peripherals & PCDROM) || (strstr(rominfo.domestic,"FLUX") != NULL) ||
(config.add_on == HW_ADDON_MEGACD) || ((config.add_on | cdd.loaded) == HW_ADDON_MEGACD))
{
/* unmount CD image */
cdd_unload();
}
}
/* ROM cartridge with CD support */
else if ((strstr(rominfo.domestic,"FLUX") != NULL) ||
(strstr(rominfo.domestic,"WONDER LIBRARY") != NULL) ||
(strstr(rominfo.product,"T-5740") != NULL))
{
/* check if console hardware is set to AUTO */
if (!config.system)
{
/* try to load CD BOOTROM */
/* try to load CD BOOTROM for selected region */
if (load_bios(SYSTEM_MCD))
{
char fname[256];
int len = strlen(filename);
/* automatically try to load associated .iso file */
while ((len && (filename[len] != '.')) || (len > 251)) len--;
strncpy(fname, filename, len);
strcpy(&fname[len], ".iso");
cdd_load(fname, (char *)cdc.ram);
/* automatically try to load associated .iso file if no CD image loaded yet */
if (!cdd.loaded)
{
len = strlen(filename);
while ((len && (filename[len] != '.')) || (len > 251)) len--;
strncpy(fname, filename, len);
strcpy(&fname[len], ".iso");
fname[len+4] = 0;
cdd_load(fname, (char *)cdc.ram);
}
/* enable CD hardware */
system_hw = SYSTEM_MCD;
@@ -787,6 +774,30 @@ int load_rom(char *filename)
/* boot from cartridge */
scd.cartridge.boot = 0x40;
}
else
{
/* unmount any loaded CD image */
cdd_unload();
}
}
/* CD BOOTROM */
else if (strstr(rominfo.ROMType, "BR") != NULL)
{
/* enable CD hardware */
system_hw = SYSTEM_MCD;
/* boot from CD hardware */
scd.cartridge.boot = 0x00;
/* copy ROM to BOOTROM area */
memcpy(scd.bootrom, cart.rom, sizeof(scd.bootrom));
/* mark CD BIOS as being loaded */
system_bios = system_bios | 0x10;
/* loaded CD BIOS region */
system_bios = (system_bios & 0xf0) | (region_code >> 4);
}
}
@@ -1076,7 +1087,9 @@ 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-113026-50") != NULL) || /* Wiz'n'Liz - The Frantic Wabbit Wescue (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-2022 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
+3 -3
View File
@@ -596,12 +596,12 @@ static const uint16 m68ki_exception_cycle_table[256] =
50*MUL, /* 3: Address Error (unemulated) */
34*MUL, /* 4: Illegal Instruction */
38*MUL, /* 5: Divide by Zero -- ASG: changed from 42 */
40*MUL, /* 6: CHK -- ASG: chanaged from 44 */
38*MUL, /* 6: CHK -- ASG: changed from 44 */
34*MUL, /* 7: TRAPV */
34*MUL, /* 8: Privilege Violation */
34*MUL, /* 9: Trace */
4*MUL, /* 10: 1010 */
4*MUL, /* 11: 1111 */
34*MUL, /* 10: 1010 */
34*MUL, /* 11: 1111 */
4*MUL, /* 12: RESERVED */
4*MUL, /* 13: Coprocessor Protocol Violation (unemulated) */
4*MUL, /* 14: Format Error */
+107 -107
View File
@@ -20,15 +20,15 @@ static const unsigned char m68ki_cycles[0x10000] =
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -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,
@@ -52,15 +52,15 @@ static const unsigned char m68ki_cycles[0x10000] =
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -84,15 +84,15 @@ static const unsigned char m68ki_cycles[0x10000] =
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -116,15 +116,15 @@ static const unsigned char m68ki_cycles[0x10000] =
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -132,31 +132,31 @@ 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, 16*7, 18*7, 0*7, 0*7, 0*7, 0*7,
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*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, 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, 0*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 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, 0*7, 0*7, 0*7, 0*7,
12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*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, 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, 0*7, 0*7, 0*7, 0*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 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, 0*7, 0*7, 0*7, 0*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -180,15 +180,15 @@ static const unsigned char m68ki_cycles[0x10000] =
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -212,15 +212,15 @@ static const unsigned char m68ki_cycles[0x10000] =
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -244,15 +244,15 @@ static const unsigned char m68ki_cycles[0x10000] =
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*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, 12*7, 16*7, 12*7, 14*7, 10*7, 0*7, 0*7, 0*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*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,
8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*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,
@@ -1048,10 +1048,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
@@ -1080,10 +1080,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
@@ -1112,10 +1112,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
@@ -1144,10 +1144,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
@@ -1176,10 +1176,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
@@ -1197,25 +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,
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, 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, 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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*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, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*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,
@@ -1225,37 +1209,53 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
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,
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,
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*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,
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,
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,
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*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, 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, 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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*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, 8*7, 12*7, 8*7, 12*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, 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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*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, 8*7, 12*7, 8*7, 12*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, 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, 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,
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,
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,
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*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,
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,
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,
18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*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, 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, 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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*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, 8*7, 12*7, 8*7, 12*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, 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,
16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*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,
0*7, 4*7, 4*7, 20*7, 0*7, 16*7, 4*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7,
0*7, 4*7, 4*7, 20*7, 0*7, 16*7, 0*7, 20*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,
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,
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,
@@ -1272,10 +1272,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*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, 18*7, 20*7, 14*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,
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,
6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7,
10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*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,
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,
0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*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,
+138 -52
View File
@@ -4661,6 +4661,11 @@ static void m68k_op_bchg_32_r_d(void)
uint* r_dst = &DY;
uint mask = 1 << (DX & 0x1f);
if (mask & 0xffff0000)
{
USE_CYCLES(2 * MUL);
}
FLAG_Z = *r_dst & mask;
*r_dst ^= mask;
}
@@ -4770,6 +4775,11 @@ static void m68k_op_bchg_32_s_d(void)
uint* r_dst = &DY;
uint mask = 1 << (OPER_I_8() & 0x1f);
if (mask & 0xffff0000)
{
USE_CYCLES(2 * MUL);
}
FLAG_Z = *r_dst & mask;
*r_dst ^= mask;
}
@@ -4879,6 +4889,11 @@ static void m68k_op_bclr_32_r_d(void)
uint* r_dst = &DY;
uint mask = 1 << (DX & 0x1f);
if (mask & 0xffff0000)
{
USE_CYCLES(2 * MUL);
}
FLAG_Z = *r_dst & mask;
*r_dst &= ~mask;
}
@@ -4988,6 +5003,11 @@ static void m68k_op_bclr_32_s_d(void)
uint* r_dst = &DY;
uint mask = 1 << (OPER_I_8() & 0x1f);
if (mask & 0xffff0000)
{
USE_CYCLES(2 * MUL);
}
FLAG_Z = *r_dst & mask;
*r_dst &= ~mask;
}
@@ -5117,6 +5137,11 @@ static void m68k_op_bset_32_r_d(void)
uint* r_dst = &DY;
uint mask = 1 << (DX & 0x1f);
if (mask & 0xffff0000)
{
USE_CYCLES(2 * MUL);
}
FLAG_Z = *r_dst & mask;
*r_dst |= mask;
}
@@ -5226,6 +5251,11 @@ static void m68k_op_bset_32_s_d(void)
uint* r_dst = &DY;
uint mask = 1 << (OPER_I_8() & 0x1f);
if (mask & 0xffff0000)
{
USE_CYCLES(2 * MUL);
}
FLAG_Z = *r_dst & mask;
*r_dst |= mask;
}
@@ -5536,9 +5566,14 @@ static void m68k_op_chk_16_d(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5554,9 +5589,14 @@ static void m68k_op_chk_16_ai(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5572,9 +5612,14 @@ static void m68k_op_chk_16_pi(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5590,9 +5635,14 @@ static void m68k_op_chk_16_pd(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5608,9 +5658,14 @@ static void m68k_op_chk_16_di(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5626,9 +5681,14 @@ static void m68k_op_chk_16_ix(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5644,9 +5704,14 @@ static void m68k_op_chk_16_aw(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5662,9 +5727,14 @@ static void m68k_op_chk_16_al(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5680,9 +5750,14 @@ static void m68k_op_chk_16_pcdi(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5698,9 +5773,14 @@ static void m68k_op_chk_16_pcix(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -5716,9 +5796,14 @@ static void m68k_op_chk_16_i(void)
if(src >= 0 && src <= bound)
{
USE_CYCLES(10 * MUL);
return;
}
FLAG_N = (src < 0)<<7;
if(src < 0)
{
FLAG_N = 1<<7;
USE_CYCLES(2 * MUL);
}
m68ki_exception_trap(EXCEPTION_CHK);
}
@@ -8117,7 +8202,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 +8233,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 +8264,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 +8295,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 +8326,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 +8357,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 +8388,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 +8419,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 +8450,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 +8481,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 +8512,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;
@@ -23358,6 +23443,7 @@ static void m68k_op_trapv(void)
{
if(COND_VC())
{
USE_CYCLES (4 * MUL);
return;
}
m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */
@@ -23717,21 +23803,21 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
{m68k_op_btst_8_r_pd , 0xf1f8, 0x0120, 10},
{m68k_op_btst_8_r_di , 0xf1f8, 0x0128, 12},
{m68k_op_btst_8_r_ix , 0xf1f8, 0x0130, 14},
{m68k_op_bchg_32_r_d , 0xf1f8, 0x0140, 8},
{m68k_op_bchg_32_r_d , 0xf1f8, 0x0140, 6},
{m68k_op_movep_32_er , 0xf1f8, 0x0148, 24},
{m68k_op_bchg_8_r_ai , 0xf1f8, 0x0150, 12},
{m68k_op_bchg_8_r_pi , 0xf1f8, 0x0158, 12},
{m68k_op_bchg_8_r_pd , 0xf1f8, 0x0160, 14},
{m68k_op_bchg_8_r_di , 0xf1f8, 0x0168, 16},
{m68k_op_bchg_8_r_ix , 0xf1f8, 0x0170, 18},
{m68k_op_bclr_32_r_d , 0xf1f8, 0x0180, 10},
{m68k_op_bclr_32_r_d , 0xf1f8, 0x0180, 8},
{m68k_op_movep_16_re , 0xf1f8, 0x0188, 16},
{m68k_op_bclr_8_r_ai , 0xf1f8, 0x0190, 12},
{m68k_op_bclr_8_r_pi , 0xf1f8, 0x0198, 12},
{m68k_op_bclr_8_r_pd , 0xf1f8, 0x01a0, 14},
{m68k_op_bclr_8_r_di , 0xf1f8, 0x01a8, 16},
{m68k_op_bclr_8_r_ix , 0xf1f8, 0x01b0, 18},
{m68k_op_bset_32_r_d , 0xf1f8, 0x01c0, 8},
{m68k_op_bset_32_r_d , 0xf1f8, 0x01c0, 6},
{m68k_op_movep_32_re , 0xf1f8, 0x01c8, 24},
{m68k_op_bset_8_r_ai , 0xf1f8, 0x01d0, 12},
{m68k_op_bset_8_r_pi , 0xf1f8, 0x01d8, 12},
@@ -23872,12 +23958,12 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
{m68k_op_move_16_ix_pd , 0xf1f8, 0x31a0, 20},
{m68k_op_move_16_ix_di , 0xf1f8, 0x31a8, 22},
{m68k_op_move_16_ix_ix , 0xf1f8, 0x31b0, 24},
{m68k_op_chk_16_d , 0xf1f8, 0x4180, 10},
{m68k_op_chk_16_ai , 0xf1f8, 0x4190, 14},
{m68k_op_chk_16_pi , 0xf1f8, 0x4198, 14},
{m68k_op_chk_16_pd , 0xf1f8, 0x41a0, 16},
{m68k_op_chk_16_di , 0xf1f8, 0x41a8, 18},
{m68k_op_chk_16_ix , 0xf1f8, 0x41b0, 20},
{m68k_op_chk_16_d , 0xf1f8, 0x4180, 0},
{m68k_op_chk_16_ai , 0xf1f8, 0x4190, 4},
{m68k_op_chk_16_pi , 0xf1f8, 0x4198, 4},
{m68k_op_chk_16_pd , 0xf1f8, 0x41a0, 6},
{m68k_op_chk_16_di , 0xf1f8, 0x41a8, 8},
{m68k_op_chk_16_ix , 0xf1f8, 0x41b0, 10},
{m68k_op_lea_32_ai , 0xf1f8, 0x41d0, 4},
{m68k_op_lea_32_di , 0xf1f8, 0x41e8, 8},
{m68k_op_lea_32_ix , 0xf1f8, 0x41f0, 12},
@@ -23888,7 +23974,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},
@@ -24231,7 +24317,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
{m68k_op_lsl_32_r , 0xf1f8, 0xe1a8, 8},
{m68k_op_roxl_32_r , 0xf1f8, 0xe1b0, 8},
{m68k_op_rol_32_r , 0xf1f8, 0xe1b8, 8},
{m68k_op_trap , 0xfff0, 0x4e40, 4},
{m68k_op_trap , 0xfff0, 0x4e40, 0},
{m68k_op_btst_8_r_pi7 , 0xf1ff, 0x011f, 8},
{m68k_op_btst_8_r_pd7 , 0xf1ff, 0x0127, 10},
{m68k_op_btst_8_r_aw , 0xf1ff, 0x0138, 12},
@@ -24363,11 +24449,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
{m68k_op_move_16_ix_pcdi , 0xf1ff, 0x31ba, 22},
{m68k_op_move_16_ix_pcix , 0xf1ff, 0x31bb, 24},
{m68k_op_move_16_ix_i , 0xf1ff, 0x31bc, 18},
{m68k_op_chk_16_aw , 0xf1ff, 0x41b8, 18},
{m68k_op_chk_16_al , 0xf1ff, 0x41b9, 22},
{m68k_op_chk_16_pcdi , 0xf1ff, 0x41ba, 18},
{m68k_op_chk_16_pcix , 0xf1ff, 0x41bb, 20},
{m68k_op_chk_16_i , 0xf1ff, 0x41bc, 14},
{m68k_op_chk_16_aw , 0xf1ff, 0x41b8, 8},
{m68k_op_chk_16_al , 0xf1ff, 0x41b9, 12},
{m68k_op_chk_16_pcdi , 0xf1ff, 0x41ba, 8},
{m68k_op_chk_16_pcix , 0xf1ff, 0x41bb, 10},
{m68k_op_chk_16_i , 0xf1ff, 0x41bc, 4},
{m68k_op_lea_32_aw , 0xf1ff, 0x41f8, 8},
{m68k_op_lea_32_al , 0xf1ff, 0x41f9, 12},
{m68k_op_lea_32_pcdi , 0xf1ff, 0x41fa, 8},
@@ -24598,7 +24684,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},
@@ -24646,19 +24732,19 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
{m68k_op_btst_8_s_pd , 0xfff8, 0x0820, 14},
{m68k_op_btst_8_s_di , 0xfff8, 0x0828, 16},
{m68k_op_btst_8_s_ix , 0xfff8, 0x0830, 18},
{m68k_op_bchg_32_s_d , 0xfff8, 0x0840, 12},
{m68k_op_bchg_32_s_d , 0xfff8, 0x0840, 10},
{m68k_op_bchg_8_s_ai , 0xfff8, 0x0850, 16},
{m68k_op_bchg_8_s_pi , 0xfff8, 0x0858, 16},
{m68k_op_bchg_8_s_pd , 0xfff8, 0x0860, 18},
{m68k_op_bchg_8_s_di , 0xfff8, 0x0868, 20},
{m68k_op_bchg_8_s_ix , 0xfff8, 0x0870, 22},
{m68k_op_bclr_32_s_d , 0xfff8, 0x0880, 14},
{m68k_op_bclr_32_s_d , 0xfff8, 0x0880, 12},
{m68k_op_bclr_8_s_ai , 0xfff8, 0x0890, 16},
{m68k_op_bclr_8_s_pi , 0xfff8, 0x0898, 16},
{m68k_op_bclr_8_s_pd , 0xfff8, 0x08a0, 18},
{m68k_op_bclr_8_s_di , 0xfff8, 0x08a8, 20},
{m68k_op_bclr_8_s_ix , 0xfff8, 0x08b0, 22},
{m68k_op_bset_32_s_d , 0xfff8, 0x08c0, 12},
{m68k_op_bset_32_s_d , 0xfff8, 0x08c0, 10},
{m68k_op_bset_8_s_ai , 0xfff8, 0x08d0, 16},
{m68k_op_bset_8_s_pi , 0xfff8, 0x08d8, 16},
{m68k_op_bset_8_s_pd , 0xfff8, 0x08e0, 18},
@@ -24881,11 +24967,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 +25331,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},
@@ -25265,7 +25351,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] =
{m68k_op_stop , 0xffff, 0x4e72, 4},
{m68k_op_rte_32 , 0xffff, 0x4e73, 20},
{m68k_op_rts_32 , 0xffff, 0x4e75, 16},
{m68k_op_trapv , 0xffff, 0x4e76, 4},
{m68k_op_trapv , 0xffff, 0x4e76, 0},
{m68k_op_rtr_32 , 0xffff, 0x4e77, 20},
{m68k_op_jsr_32_aw , 0xffff, 0x4eb8, 18},
{m68k_op_jsr_32_al , 0xffff, 0x4eb9, 20},
+4
View File
@@ -62,7 +62,11 @@
* access a word or longword at an odd address.
* NOTE: This is only emulated properly for 68000 mode.
*/
#ifdef ENABLE_SUB_68K_ADDRESS_ERROR_EXCEPTIONS
#define M68K_EMULATE_ADDRESS_ERROR OPT_ON
#else
#define M68K_EMULATE_ADDRESS_ERROR OPT_OFF
#endif
/* If ON and previous option is also ON, address error exceptions will
also be checked when fetching instructions. Disabling this can help
+2 -2
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
}
@@ -348,7 +348,7 @@ void s68k_pulse_halt(void)
CPU_STOPPED |= STOP_LEVEL_HALT;
}
void s68k_clear_halt()
void s68k_clear_halt(void)
{
/* Clear the HALT line on the CPU */
CPU_STOPPED &= ~STOP_LEVEL_HALT;
+108 -108
View File
@@ -20,15 +20,15 @@ static const unsigned char m68ki_cycles[0x10000] =
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, 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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -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,
@@ -52,15 +52,15 @@ static const unsigned char m68ki_cycles[0x10000] =
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, 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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -84,15 +84,15 @@ static const unsigned char m68ki_cycles[0x10000] =
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, 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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -116,15 +116,15 @@ static const unsigned char m68ki_cycles[0x10000] =
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, 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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -132,31 +132,31 @@ 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, 16*4, 18*4, 0*4, 0*4, 0*4, 0*4,
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*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, 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, 0*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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 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, 0*4, 0*4, 0*4, 0*4,
12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*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, 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, 0*4, 0*4, 0*4, 0*4,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 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, 0*4, 0*4, 0*4, 0*4,
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, 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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -180,15 +180,15 @@ static const unsigned char m68ki_cycles[0x10000] =
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, 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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -212,15 +212,15 @@ static const unsigned char m68ki_cycles[0x10000] =
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, 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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -243,16 +243,16 @@ 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,
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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*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,
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,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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,
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,
@@ -1048,10 +1048,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
@@ -1080,10 +1080,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
@@ -1112,10 +1112,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
@@ -1144,10 +1144,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
@@ -1176,10 +1176,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4,
@@ -1197,25 +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,
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, 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, 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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*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,
@@ -1225,37 +1209,53 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
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,
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,
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*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,
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,
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,
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*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, 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, 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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 8*4, 12*4, 8*4, 12*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, 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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 8*4, 12*4, 8*4, 12*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, 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, 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,
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,
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,
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*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,
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,
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,
18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*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, 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, 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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 8*4, 12*4, 8*4, 12*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, 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,
16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
0*4, 4*4, 4*4, 20*4, 0*4, 16*4, 4*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4,
0*4, 4*4, 4*4, 20*4, 0*4, 16*4, 0*4, 20*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,
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,
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,
@@ -1272,10 +1272,10 @@ static const unsigned char m68ki_cycles[0x10000] =
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,
10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*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, 18*4, 20*4, 14*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,
4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4,
6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*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, 8*4, 12*4, 8*4, 10*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,
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,
0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*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,
+71 -27
View File
@@ -3,7 +3,7 @@
* Main 68k bus handlers
*
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2019 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2023 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -696,29 +696,40 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
/* RESET bit */
if (data & 0x01)
{
/* trigger reset on 0->1 transition */
/* SUB-CPU reset is triggered on /RESET input 0->1 transition */
if (!(scd.regs[0x00].byte.l & 0x01))
{
/* reset SUB-CPU */
s68k_pulse_reset();
}
/* BUSREQ bit */
if (data & 0x02)
{
/* SUB-CPU bus requested */
/* SUB-CPU is halted (/HALT input is asserted) */
s68k_pulse_halt();
}
else
{
/* SUB-CPU bus released */
/* SUB-CPU is running (/HALT input is released) */
s68k_clear_halt();
}
/* update BUSREQ and RESET bits */
scd.regs[0x00].byte.l = data & 0x03;
}
else
{
/* SUB-CPU is halted while !RESET is asserted */
/* SUB-CPU is halted (/HALT and /RESET inputs are asserted) */
s68k_pulse_halt();
/* RESET bit is cleared and BUSREQ bit is set to 1 (verified on real hardware) */
scd.regs[0x00].byte.l = 0x02;
}
/* BUSREQ bit remains set to 0 if SUB-CPU is halted while stopped (verified on real hardware) */
if (s68k.stopped & 0x01)
{
scd.regs[0x00].byte.l &= ~0x02;
}
/* check if SUB-CPU halt status has changed */
@@ -727,8 +738,8 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
/* PRG-RAM (128KB bank) is normally mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */
unsigned int base = scd.cartridge.boot + 0x02;
/* PRG-RAM can only be accessed from MAIN 68K & Z80 when SUB-CPU is halted (Dungeon Explorer USA version) */
if ((data & 0x03) != 0x01)
/* PRG-RAM can only be accessed from MAIN-CPU & Z80 when BUSREQ bit is set (Dungeon Explorer USA version) */
if (scd.regs[0x00].byte.l & 0x02)
{
m68k.memory_map[base].read8 = m68k.memory_map[base+1].read8 = NULL;
m68k.memory_map[base].read16 = m68k.memory_map[base+1].read16 = NULL;
@@ -748,7 +759,6 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
}
}
scd.regs[0x00].byte.l = data;
return;
}
@@ -777,7 +787,7 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
}
else
{
/* writing 0 to DMNA in 1M mode actually set DMNA bit */
/* writing 0 to DMNA in 1M mode actually sets DMNA bit */
data |= 0x02;
/* update BK0-1 & DMNA bits */
@@ -787,19 +797,32 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
}
else
{
/* writing 0 in 2M mode does nothing */
/* writing 0 to DMNA in 2M mode does nothing */
if (data & 0x02)
{
/* Word-RAM is assigned to SUB-CPU */
scd.dmna = 1;
/* clear RET bit */
/* clear RET bit and update BK0-1 & DMNA bits */
scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc3) | (data & 0xc2);
/* check if graphics operation is running */
if (scd.regs[0x58>>1].byte.h & 0x80)
{
/* relative SUB-CPU cycle counter */
unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE;
/* synchronize GFX processing with SUB-CPU (only if not already ahead) */
if (gfx.cycles < cycles)
{
gfx.cycles = cycles;
}
}
return;
}
}
/* update BK0-1 bits */
/* update BK0-1 bits only */
scd.regs[0x03>>1].byte.l = (scd.regs[0x02>>1].byte.l & ~0xc0) | (data & 0xc0);
return;
}
@@ -921,29 +944,40 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
/* RESET bit */
if (data & 0x01)
{
/* trigger reset on 0->1 transition */
/* SUB-CPU reset is triggered on /RESET input 0->1 transition */
if (!(scd.regs[0x00].byte.l & 0x01))
{
/* reset SUB-CPU */
s68k_pulse_reset();
}
/* BUSREQ bit */
if (data & 0x02)
{
/* SUB-CPU bus requested */
/* SUB-CPU is halted (/HALT input is asserted) */
s68k_pulse_halt();
}
else
{
/* SUB-CPU bus released */
/* SUB-CPU is running (/HALT input is released) */
s68k_clear_halt();
}
/* update BUSREQ and RESET bits */
scd.regs[0x00].byte.l = data & 0x03;
}
else
{
/* SUB-CPU is halted while !RESET is asserted */
/* SUB-CPU is halted (/HALT and /RESET inputs are asserted) */
s68k_pulse_halt();
/* RESET bit is cleared and BUSREQ bit is set to 1 (verified on real hardware) */
scd.regs[0x00].byte.l = 0x02;
}
/* BUSREQ bit remains set to 0 if SUB-CPU is halted while stopped (verified on real hardware) */
if (s68k.stopped & 0x01)
{
scd.regs[0x00].byte.l &= ~0x02;
}
/* check if SUB-CPU halt status has changed */
@@ -952,8 +986,8 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
/* PRG-RAM (128KB bank) is normally mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */
unsigned int base = scd.cartridge.boot + 0x02;
/* PRG-RAM can only be accessed from MAIN 68K & Z80 when SUB-CPU is halted (Dungeon Explorer USA version) */
if ((data & 0x03) != 0x01)
/* PRG-RAM can only be accessed from MAIN-CPU & Z80 when BUSREQ bit is set (Dungeon Explorer USA version) */
if (scd.regs[0x00].byte.l & 0x02)
{
m68k.memory_map[base].read8 = m68k.memory_map[base+1].read8 = NULL;
m68k.memory_map[base].read16 = m68k.memory_map[base+1].read16 = NULL;
@@ -989,9 +1023,6 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
}
}
/* update LSB only */
scd.regs[0x00].byte.l = data & 0xff;
return;
}
@@ -1014,7 +1045,7 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
}
else
{
/* writing 0 to DMNA in 1M mode actually set DMNA bit */
/* writing 0 to DMNA in 1M mode actually sets DMNA bit */
data |= 0x02;
/* update WP0-7, BK0-1 & DMNA bits */
@@ -1024,19 +1055,32 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
}
else
{
/* writing 0 in 2M mode does nothing */
/* writing 0 to DMNA in 2M mode does nothing */
if (data & 0x02)
{
/* Word-RAM is assigned to SUB-CPU */
scd.dmna = 1;
/* clear RET bit */
/* clear RET bit and update WP0-7 & BK0-1 bits */
scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc3) | (data & 0xffc2);
/* check if graphics operation is running */
if (scd.regs[0x58>>1].byte.h & 0x80)
{
/* relative SUB-CPU cycle counter */
unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE;
/* synchronize GFX processing with SUB-CPU (only if not already ahead) */
if (gfx.cycles < cycles)
{
gfx.cycles = cycles;
}
}
return;
}
}
/* update WP0-7 & BK0-1 bits */
/* update WP0-7 & BK0-1 bits only */
scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc0) | (data & 0xffc0);
return;
}
+1 -1
View File
@@ -3,7 +3,7 @@
* Main 68k bus handlers
*
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2019 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2023 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 -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_ */
+24 -7
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-2022 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 */
@@ -629,10 +639,17 @@ void z80_m3_port_w(unsigned int port, unsigned char data)
default:
{
/* write FM chip if enabled */
/* write to FM sound unit (FM-70) if enabled */
if (!(port & 4) && (config.ym2413 & 1))
{
fm_write(Z80.cycles, port, data);
/* FM output control "register" */
if (port & 2)
{
/* PSG output is automatically disabled (resp. enabled) by FM sound unit hardware if FM output is enabled (resp. disabled) */
psg_config(Z80.cycles, config.psg_preamp, (data & 0x01) ? 0x00 : 0xff);
}
return;
}
@@ -674,11 +691,11 @@ unsigned char z80_m3_port_r(unsigned int port)
default:
{
/* read FM chip if enabled */
/* read FM sound unit (FM-70) if enabled */
if (!(port & 4) && (config.ym2413 & 1))
{
/* I/O ports are automatically disabled by hardware */
return YM2413Read();
/* I/O ports are automatically disabled by FM sound unit hardware */
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-2022 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 -2
View File
@@ -88,6 +88,7 @@ void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup )
void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline)
{
int n;
int const chunk_count = in_width / sms_ntsc_in_chunk;
/* handle extra 0, 1, or 2 pixels by placing them at beginning of row */
@@ -102,9 +103,8 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
(SMS_NTSC_ADJ_IN( table[input[0]] )) & extra2,
(SMS_NTSC_ADJ_IN( table[input[extra2 & 1]] )) & extra1 );
sms_ntsc_out_t* restrict line_out = (sms_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]);
sms_ntsc_out_t* line_out = (sms_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]);
int n;
input += in_extra;
for ( n = chunk_count; n; --n )
+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
+1 -1
View File
@@ -112,7 +112,7 @@ void psg_init(PSG_TYPE type)
psg.noiseBitMask = noiseBitMask[type];
}
void psg_reset()
void psg_reset(void)
{
int i;
+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:
+246 -138
View File
@@ -25,7 +25,22 @@ to do:
*/
/** EkeEke (2011): removed multiple chips support, cleaned code & added FM board interface for Genesis Plus GX **/
/************************************************/
/** Modifications for Genesis Plus GX (EkeEke) **/
/************************************************/
/** 2011/xx/xx: removed multiple chips support, cleaned code & added FM board interface **/
/** 2021/04/23: fixed synchronization of carrier/modulator phase reset after channel Key ON (fixes Japanese Master System BIOS music) **/
/** 2021/04/24: fixed intruments ROM (verified on YM2413B die, cf. https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2#ym2413_instrument_rom) **/
/** 2021/04/24: fixed EG resolution bits (verified on YM2413B die, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2015-03-20) **/
/** 2021/04/24: fixed EG dump rate (verified on YM2413 real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2015-12-31) **/
/** 2021/04/25: fixed EG behavior for fastest attack rates (verified on YM2413 real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2017-01-26) **/
/** 2021/04/25: fixed EG behavior when SL = 0 (verified on YM2413 real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2015-12-24) **/
/** 2021/04/25: improved EG sustain phase transition comparator accuracy (verified on YM2413 real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2015-12-31) **/
/** 2021/05/04: improved EG increment steps accuracy (verified on YM2413 real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2015-03-20) **/
/** 2021/05/08: improved EG transitions accuracy (verified against https://github.com/nukeykt/Nuked-OPLL/blob/master/opll.c) **/
/** 2021/05/11: improved EG attack phase algorithm accuracy (verified on YM2413 real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2017-01-26) **/
/** 2022/08/07: fixed operator ouput when EG is off **/
/************************************************/
#include "shared.h"
@@ -40,7 +55,7 @@ to do:
#define ENV_LEN (1<<ENV_BITS)
#define ENV_STEP (128.0/ENV_LEN)
#define MAX_ATT_INDEX ((1<<(ENV_BITS-2))-1) /*255*/
#define MAX_ATT_INDEX ((1<<(ENV_BITS-3))-1) /*127*/
#define MIN_ATT_INDEX (0)
/* sinwave entries */
@@ -89,7 +104,7 @@ typedef struct
UINT8 eg_sh_dp; /* (dump state) */
UINT8 eg_sel_dp; /* (dump state) */
UINT8 eg_sh_ar; /* (attack state) */
UINT8 eg_sel_ar; /* (attack state) */
UINT16 eg_sel_ar; /* (attack state) */
UINT8 eg_sh_dr; /* (decay state) */
UINT8 eg_sel_dr; /* (decay state) */
UINT8 eg_sh_rr; /* (release state for non-perc.) */
@@ -219,67 +234,100 @@ static const UINT32 sl_tab[16]={
#undef SC
#define RATE_STEPS (8)
static const unsigned char eg_inc[15*RATE_STEPS]={
#define RATE_STEPS (16)
/*cycle:0 1 2 3 4 5 6 7*/
static const unsigned char eg_inc[14*RATE_STEPS]={
/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */
/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */
/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */
/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */
/*cycle:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15*/
/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */
/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */
/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */
/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */
/* 0 */ 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, /* infinity rates for decay(s) */
/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */
/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */
/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */
/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */
/* 1 */ 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, /* rates 01..12 0 for decay(s) (increment by 0 or 1) */
/* 2 */ 0,1, 1,1, 0,1, 0,1, 0,1, 1,1, 0,1, 0,1, /* rates 01..12 1 for decay(s) */
/* 3 */ 0,1, 1,1, 0,1, 1,1, 0,1, 1,1, 0,1, 1,1, /* rates 01..12 2 for decay(s) */
/* 4 */ 0,1, 1,1, 1,1, 1,1, 0,1, 1,1, 1,1, 1,1, /* rates 01..12 3 for decay(s) */
/* 5 */ 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, /* rate 13 0 for decay(s) (increment by 0 or 1) */
/* 6 */ 0,1, 0,1, 1,1, 1,1, 0,1, 0,1, 0,1, 0,1, /* rate 13 1 for decay(s) */
/* 7 */ 0,1, 0,1, 1,1, 1,1, 0,1, 0,1, 1,1, 1,1, /* rate 13 2 for decay(s) */
/* 8 */ 0,1, 0,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, /* rate 13 3 for decay(s) */
/* 9 */ 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, /* rate 14 0 for decay(s) (increment by 1) */
/*10 */ 1,1, 1,1, 2,2, 2,2, 1,1, 1,1, 1,1, 1,1, /* rate 14 1 for decay(s) */
/*11 */ 1,1, 1,1, 2,2, 2,2, 1,1, 1,1, 2,2, 2,2, /* rate 14 2 for decay(s) */
/*12 */ 1,1, 1,1, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, /* rate 14 3 for decay(s) */
/*13 */ 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, /* rates 15 0, 15 1, 15 2, 15 3 for decay(s) (increment by 2) */
/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */
/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */
/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
};
static const unsigned char eg_mul[17*RATE_STEPS]={
/*cycle:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15*/
/* 0 */ 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack */
/* 1 */ 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, /* rates 01..11 0 for attack */
/* 2 */ 0,1, 1,1, 0,1, 0,1, 0,1, 1,1, 0,1, 0,1, /* rates 01..11 1 for attack */
/* 3 */ 0,1, 1,1, 0,1, 1,1, 0,1, 1,1, 0,1, 1,1, /* rates 01..11 2 for attack */
/* 4 */ 0,1, 1,1, 1,1, 1,1, 0,1, 1,1, 1,1, 1,1, /* rates 01..11 3 for attack */
/* 5 */ 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, /* rate 12 0 for attack */
/* 6 */ 1,1, 1,1, 2,2, 2,2, 1,1, 1,1, 1,1, 1,1, /* rate 12 1 for attack */
/* 7 */ 1,1, 1,1, 2,2, 2,2, 1,1, 1,1, 2,2, 2,2, /* rate 12 2 for attack */
/* 8 */ 1,1, 1,1, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, /* rate 12 3 for attack */
/* 9 */ 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, /* rate 13 0 for attack */
/*10 */ 2,2, 2,2, 4,4, 4,4, 2,2, 2,2, 2,2, 2,2, /* rate 13 1 for attack */
/*11 */ 2,2, 2,2, 4,4, 4,4, 2,2, 2,2, 4,4, 4,4, /* rate 13 2 for attack */
/*12 */ 2,2, 2,2, 4,4, 4,4, 4,4, 4,4, 4,4, 4,4, /* rate 13 3 for attack */
/*13 */ 4,4, 4,4, 4,4, 4,4, 4,4, 4,4, 4,4, 4,4, /* rate 14 0 for attack */
/*14 */ 4,4, 4,4, 8,8, 8,8, 4,4, 4,4, 4,4, 4,4, /* rate 14 1 for attack */
/*15 */ 4,4, 4,4, 8,8, 8,8, 4,4, 4,4, 8,8, 8,8, /* rate 14 2 for attack */
/*16 */ 4,4, 4,4, 8,8, 8,8, 8,8, 8,8, 8,8, 8,8, /* rate 14 3 for attack */
};
#define O(a) (a*RATE_STEPS)
/*note that there is no O(13) in this table - it's directly in the code */
static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */
/* 16 infinite time rates */
O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
/* rates 00-12 */
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
O( 0),O( 1),O( 2),O( 3),
/* rate 00 */
O( 0),O( 0),O( 0),O( 0), /* never used since infinite time rates are directly forced in the code for rate 00 */
/* rate 13 */
O( 4),O( 5),O( 6),O( 7),
/* rates 01-11 */
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
O( 1),O( 2),O( 3),O( 4),
/* rate 14 */
O( 8),O( 9),O(10),O(11),
/* rate 12 */ /* only used for decay(s), handled directly in the code for attack */
O( 1),O( 2),O( 3),O( 4),
/* rate 15 */
O(12),O(12),O(12),O(12),
/* rate 13 */ /* only used for decay(s), handled directly in the code for attack */
O( 5),O( 6),O( 7),O( 8),
/* rate 14 */ /* only used for decay(s), handled directly in the code for attack */
O( 9),O(10),O(11),O(12),
/* rate 15 */ /* only used for decay(s), handled directly in the code for attack */
O(13),O(13),O(13),O(13),
/* 16 dummy rates (same as 15 3) */
O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
O(13),O(13),O(13),O(13),O(13),O(13),O(13),O(13),
O(13),O(13),O(13),O(13),O(13),O(13),O(13),O(13),
};
#undef O
@@ -287,15 +335,19 @@ O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */
/*shift 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0 */
/*mask 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0 */
/*NB: for attack, above mask values lower 2 bits are cleared and rate 12 shift value is equal to 0 */
#define O(a) (a*1)
static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */
/* 16 infinite time rates */
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
/* rates 00-12 */
O(13),O(13),O(13),O(13),
/* 16 infinite time rates */
O(13),O(13),O(13),O(13),O(13),O(13),O(13),O(13),
O(13),O(13),O(13),O(13),O(13),O(13),O(13),O(13),
/* rate 00 */
O(13),O(13),O(13),O(13), /* never used since infinite time rates are directly forced in the code for rate 00 */
/* rates 01-11 */
O(12),O(12),O(12),O(12),
O(11),O(11),O(11),O(11),
O(10),O(10),O(10),O(10),
@@ -307,15 +359,17 @@ O( 5),O( 5),O( 5),O( 5),
O( 4),O( 4),O( 4),O( 4),
O( 3),O( 3),O( 3),O( 3),
O( 2),O( 2),O( 2),O( 2),
/* rate 12 */ /* only used for decay(s), handled directly in the code for attack */
O( 1),O( 1),O( 1),O( 1),
/* rate 13 */
/* rate 13 */ /* only used for decay(s), handled directly in the code for attack */
O( 0),O( 0),O( 0),O( 0),
/* rate 14 */
/* rate 14 */ /* only used for decay(s), handled directly in the code for attack */
O( 0),O( 0),O( 0),O( 0),
/* rate 15 */
/* rate 15 */ /* only used for decay(s), handled directly in the code for attack */
O( 0),O( 0),O( 0),O( 0),
/* 16 dummy rates (same as 15 3) */
@@ -455,45 +509,71 @@ static const INT8 lfo_pm_table[8*8] = {
- LFO PM and AM enable are 100% correct
- waveform DC and DM select are 100% correct
*/
/* 2021/04/23: corrected with values extracted from YM2413 instrument ROM, cf. https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2#ym2413_instrument_rom */
static unsigned char table[19][8] = {
/* MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR */
/* 0 1 2 3 4 5 6 7 */
{0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 }, /* 0 */
/*{0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 }, */ /* 0 */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0 */
{0x61, 0x61, 0x1e, 0x17, 0xf0, 0x78, 0x00, 0x17 }, /* 1 */
{0x13, 0x41, 0x1e, 0x0d, 0xd7, 0xf7, 0x13, 0x13 }, /* 2 */
{0x13, 0x01, 0x99, 0x04, 0xf2, 0xf4, 0x11, 0x23 }, /* 3 */
{0x21, 0x61, 0x1b, 0x07, 0xaf, 0x64, 0x40, 0x27 }, /* 4 */
/*{0x61, 0x61, 0x1e, 0x17, 0xf0, 0x78, 0x00, 0x17 }, */ /* 1 */
{0x71, 0x61, 0x1e, 0x17, 0xd0, 0x78, 0x00, 0x17 }, /* 1 */
/*{0x13, 0x41, 0x1e, 0x0d, 0xd7, 0xf7, 0x13, 0x13 }, */ /* 2 */
{0x13, 0x41, 0x1a, 0x0d, 0xd8, 0xf7, 0x23, 0x13 }, /* 2 */
/*{0x13, 0x01, 0x99, 0x04, 0xf2, 0xf4, 0x11, 0x23 }, */ /* 3 */
{0x13, 0x01, 0x99, 0x00, 0xf2, 0xc4, 0x11, 0x23 }, /* 3 */
/*{0x21, 0x61, 0x1b, 0x07, 0xaf, 0x64, 0x40, 0x27 }, */ /* 4 */
{0x31, 0x61, 0x0e, 0x07, 0xa8, 0x64, 0x70, 0x27 }, /* 4 */
/*{0x22, 0x21, 0x1e, 0x09, 0xf0, 0x76, 0x08, 0x28 }, */ /* 5 */
{0x22, 0x21, 0x1e, 0x06, 0xf0, 0x75, 0x08, 0x18 }, /* 5 */
/*{0x22, 0x21, 0x1e, 0x06, 0xf0, 0x75, 0x08, 0x18 }, */ /* 5 */
{0x32, 0x21, 0x1e, 0x06, 0xe0, 0x76, 0x00, 0x28 }, /* 5 */
/*{0x31, 0x22, 0x16, 0x09, 0x90, 0x7f, 0x00, 0x08 }, */ /* 6 */
{0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x13 }, /* 6 */
/*{0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x13 }, */ /* 6 */
{0x31, 0x22, 0x16, 0x05, 0xe0, 0x71, 0x00, 0x18 }, /* 6 */
{0x21, 0x61, 0x1d, 0x07, 0x82, 0x80, 0x10, 0x17 }, /* 7 */
{0x23, 0x21, 0x2d, 0x16, 0xc0, 0x70, 0x07, 0x07 }, /* 8 */
{0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17 }, /* 9 */
/*{0x21, 0x61, 0x1d, 0x07, 0x82, 0x80, 0x10, 0x17 }, */ /* 7 */
{0x21, 0x61, 0x1d, 0x07, 0x82, 0x81, 0x10, 0x07 }, /* 7 */
/* {0x61, 0x61, 0x0c, 0x08, 0x85, 0xa0, 0x79, 0x07 }, */ /* A */
{0x61, 0x61, 0x0c, 0x18, 0x85, 0xf0, 0x70, 0x07 }, /* A */
/*{0x23, 0x21, 0x2d, 0x16, 0xc0, 0x70, 0x07, 0x07 }, */ /* 8 */
{0x23, 0x21, 0x2d, 0x14, 0xa2, 0x72, 0x00, 0x07 }, /* 8 */
{0x23, 0x01, 0x07, 0x11, 0xf0, 0xa4, 0x00, 0x22 }, /* B */
{0x97, 0xc1, 0x24, 0x07, 0xff, 0xf8, 0x22, 0x12 }, /* C */
{0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17 }, /* 9 */
/* {0x61, 0x10, 0x0c, 0x08, 0xf2, 0xc4, 0x40, 0xc8 }, */ /* D */
{0x61, 0x10, 0x0c, 0x05, 0xf2, 0xf4, 0x40, 0x44 }, /* D */
/*{0x61, 0x61, 0x0c, 0x08, 0x85, 0xa0, 0x79, 0x07 }, */ /* A */
/*{0x61, 0x61, 0x0c, 0x18, 0x85, 0xf0, 0x70, 0x07 }, */ /* A */
{0x41, 0x61, 0x0b, 0x18, 0x85, 0xf7, 0x71, 0x07 }, /* A */
{0x01, 0x01, 0x55, 0x03, 0xf3, 0x92, 0xf3, 0xf3 }, /* E */
{0x61, 0x41, 0x89, 0x03, 0xf1, 0xf4, 0xf0, 0x13 }, /* F */
/*{0x23, 0x01, 0x07, 0x11, 0xf0, 0xa4, 0x00, 0x22 }, */ /* B */
{0x13, 0x01, 0x83, 0x11, 0xfa, 0xe4, 0x10, 0x04 }, /* B */
/*{0x97, 0xc1, 0x24, 0x07, 0xff, 0xf8, 0x22, 0x12 }, */ /* C */
{0x17, 0xc1, 0x24, 0x07, 0xf8, 0xf8, 0x22, 0x12 }, /* C */
/*{0x61, 0x10, 0x0c, 0x08, 0xf2, 0xc4, 0x40, 0xc8 }, */ /* D */
/*{0x61, 0x10, 0x0c, 0x05, 0xf2, 0xf4, 0x40, 0x44 }, */ /* D */
{0x61, 0x50, 0x0c, 0x05, 0xc2, 0xf5, 0x20, 0x42 }, /* D */
/*{0x01, 0x01, 0x55, 0x03, 0xf3, 0x92, 0xf3, 0xf3 }, */ /* E */
{0x01, 0x01, 0x55, 0x03, 0xc9, 0x95, 0x03, 0x02 }, /* E */
/*{0x61, 0x41, 0x89, 0x03, 0xf1, 0xf4, 0xf0, 0x13 }, */ /* F */
{0x61, 0x41, 0x89, 0x03, 0xf1, 0xe4, 0x40, 0x13 }, /* F */
/* drum instruments definitions */
/* MULTI MULTI modTL xxx AR/DR AR/DR SL/RR SL/RR */
/* 0 1 2 3 4 5 6 7 */
{0x01, 0x01, 0x16, 0x00, 0xfd, 0xf8, 0x2f, 0x6d },/* BD(multi verified, modTL verified, mod env - verified(close), carr. env verifed) */
{0x01, 0x01, 0x00, 0x00, 0xd8, 0xd8, 0xf9, 0xf8 },/* HH(multi verified), SD(multi not used) */
{0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55 },/* TOM(multi,env verified), TOP CYM(multi verified, env verified) */
/*{0x01, 0x01, 0x16, 0x00, 0xfd, 0xf8, 0x2f, 0x6d },*/ /* BD(multi verified, modTL verified, mod env - verified(close), carr. env verifed) */
/*{0x01, 0x01, 0x00, 0x00, 0xd8, 0xd8, 0xf9, 0xf8 },*/ /* HH(multi verified), SD(multi not used) */
/*{0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55 },*/ /* TOM(multi,env verified), TOP CYM(multi verified, env verified) */
{0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d }, /* BD */
{0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x48 }, /* HH, SD */
{0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55 } /* TOM, TOP CYM */
};
static signed int output[2];
@@ -542,47 +622,55 @@ INLINE void advance(void)
switch(op->state)
{
case EG_DMP: /* dump phase */
/*dump phase is performed by both operators in each channel*/
/*when CARRIER envelope gets down to zero level,
** phases in BOTH opearators are reset (at the same time ?)
*/
if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_dp)-1) ) )
case EG_DMP: /* dump phase */
if ( (op->volume & ~3) == (MAX_ATT_INDEX & ~3) ) /* envelope level lowest 2 bits are ignored by the comparator */
{
op->volume += eg_inc[op->eg_sel_dp + ((ym2413.eg_cnt>>op->eg_sh_dp)&7)];
op->state = EG_ATT;
if ( op->volume >= MAX_ATT_INDEX )
/* force envelope to zero when attack rate is set to 15.0-15.3 */
if ((op->ar + op->ksr) >= 16+60)
{
op->volume = MAX_ATT_INDEX;
op->state = EG_ATT;
/* restart Phase Generator */
op->phase = 0;
op->volume = MIN_ATT_INDEX;
}
/*dump phase is performed by both operators in each channel*/
/*when CARRIER envelope gets down to zero level,
*phases in BOTH operators are reset (at the same time ?)
*/
if (i&1)
{
CH->SLOT[0].phase = CH->SLOT[1].phase = 0;
}
}
else if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_dp)-1) ) )
{
op->volume += eg_inc[op->eg_sel_dp + ((ym2413.eg_cnt>>op->eg_sh_dp)&15)];
}
break;
case EG_ATT: /* attack phase */
if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_ar)-1) ) )
case EG_ATT: /* attack phase */
if (op->volume == MIN_ATT_INDEX)
{
op->volume += (~op->volume *
(eg_inc[op->eg_sel_ar + ((ym2413.eg_cnt>>op->eg_sh_ar)&7)])
) >>2;
if (op->volume <= MIN_ATT_INDEX)
{
op->volume = MIN_ATT_INDEX;
op->state = EG_DEC;
}
op->state = EG_DEC;
}
else if ( !(ym2413.eg_cnt & (((1<<op->eg_sh_ar)-1) & ~3)) )
{
op->volume += (~op->volume * (eg_mul[op->eg_sel_ar + ((ym2413.eg_cnt>>op->eg_sh_ar)&15)]))>>4;
}
break;
case EG_DEC: /* decay phase */
if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_dr)-1) ) )
if ( (op->volume & ~7) == op->sl ) /* envelope level lowest 3 bits are ignored by the comparator */
{
op->volume += eg_inc[op->eg_sel_dr + ((ym2413.eg_cnt>>op->eg_sh_dr)&7)];
if ( op->volume >= op->sl )
op->state = EG_SUS;
op->state = EG_SUS;
}
else if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_dr)-1) ) )
{
op->volume += eg_inc[op->eg_sel_dr + ((ym2413.eg_cnt>>op->eg_sh_dr)&15)];
if ( (op->volume & ~3) == (MAX_ATT_INDEX & ~3) ) /* envelope level lowest 2 bits are ignored by the comparator */
{
op->state = EG_OFF;
}
}
break;
@@ -591,19 +679,20 @@ INLINE void advance(void)
one can change percusive/non-percussive modes on the fly and
the chip will remain in sustain phase - verified on real YM3812 */
if(op->eg_type) /* non-percussive mode (sustained tone) */
if (op->eg_type) /* non-percussive mode (sustained tone) */
{
/* do nothing */
}
else /* percussive mode */
else /* percussive mode */
{
/* during sustain phase chip adds Release Rate (in percussive mode) */
if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
{
op->volume += eg_inc[op->eg_sel_rr + ((ym2413.eg_cnt>>op->eg_sh_rr)&7)];
if ( op->volume >= MAX_ATT_INDEX )
op->volume = MAX_ATT_INDEX;
op->volume += eg_inc[op->eg_sel_rr + ((ym2413.eg_cnt>>op->eg_sh_rr)&15)];
if ( (op->volume & ~3) == (MAX_ATT_INDEX & ~3) ) /* envelope level lowest 2 bits are ignored by the comparator */
{
op->state = EG_OFF;
}
}
/* else do nothing in sustain phase */
}
@@ -629,7 +718,7 @@ INLINE void advance(void)
*/
if ( (i&1) || ((ym2413.rhythm&0x20) && (i>=12)) )/* exclude modulators */
{
if(op->eg_type) /* non-percussive mode (sustained tone) */
if (op->eg_type) /* non-percussive mode (sustained tone) */
/*this is correct: use RR when SUS = OFF*/
/*and use RS when SUS = ON*/
{
@@ -637,10 +726,9 @@ INLINE void advance(void)
{
if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_rs)-1) ) )
{
op->volume += eg_inc[op->eg_sel_rs + ((ym2413.eg_cnt>>op->eg_sh_rs)&7)];
if ( op->volume >= MAX_ATT_INDEX )
op->volume += eg_inc[op->eg_sel_rs + ((ym2413.eg_cnt>>op->eg_sh_rs)&15)];
if ( (op->volume & ~3) == (MAX_ATT_INDEX & ~3) ) /* envelope level lowest 2 bits are ignored by the comparator */
{
op->volume = MAX_ATT_INDEX;
op->state = EG_OFF;
}
}
@@ -649,23 +737,21 @@ INLINE void advance(void)
{
if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
{
op->volume += eg_inc[op->eg_sel_rr + ((ym2413.eg_cnt>>op->eg_sh_rr)&7)];
if ( op->volume >= MAX_ATT_INDEX )
op->volume += eg_inc[op->eg_sel_rr + ((ym2413.eg_cnt>>op->eg_sh_rr)&15)];
if ( (op->volume & ~3) == (MAX_ATT_INDEX & ~3) ) /* envelope level lowest 2 bits are ignored by the comparator */
{
op->volume = MAX_ATT_INDEX;
op->state = EG_OFF;
}
}
}
}
else /* percussive mode */
else /* percussive mode */
{
if ( !(ym2413.eg_cnt & ((1<<op->eg_sh_rs)-1) ) )
{
op->volume += eg_inc[op->eg_sel_rs + ((ym2413.eg_cnt>>op->eg_sh_rs)&7)];
if ( op->volume >= MAX_ATT_INDEX )
op->volume += eg_inc[op->eg_sel_rs + ((ym2413.eg_cnt>>op->eg_sh_rs)&15)];
if ( (op->volume & ~3) == (MAX_ATT_INDEX & ~3) ) /* envelope level lowest 2 bits are ignored by the comparator */
{
op->volume = MAX_ATT_INDEX;
op->state = EG_OFF;
}
}
@@ -673,8 +759,12 @@ INLINE void advance(void)
}
break;
default:
break;
case EG_OFF: /* envelope off */
op->volume = MAX_ATT_INDEX;
break;
default:
break;
}
}
}
@@ -766,7 +856,7 @@ INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsign
return tl_tab[p];
}
#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask))
#define volume_calc(OP) (((OP)-> state != EG_OFF) ? (OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask) : ENV_QUIET)
/* calculate output */
INLINE void chan_calc( YM2413_OPLL_CH *CH )
@@ -1119,9 +1209,8 @@ INLINE void KEY_OFF(YM2413_OPLL_SLOT *SLOT, UINT32 key_clr)
if( !SLOT->key )
{
/* phase -> Release */
if (SLOT->state>EG_REL)
SLOT->state = EG_REL;
/* phase -> Release (forced off if already at maximal attenuation level) */
SLOT->state = ( (SLOT->volume & ~3) == (MAX_ATT_INDEX & ~3) ) ? EG_OFF : EG_REL;
}
}
}
@@ -1142,21 +1231,30 @@ INLINE void CALC_FCSLOT(YM2413_OPLL_CH *CH,YM2413_OPLL_SLOT *SLOT)
SLOT->ksr = ksr;
/* calculate envelope generator rates */
if ((SLOT->ar + SLOT->ksr) < 16+62)
if ((SLOT->ar + SLOT->ksr) >= 16+60)
{
SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
/* attack phase is skipped in case attack rate is set to 15.0-15.3 before attack phase is started */
/* during attack phase, in case attack rate is changed to 15.0-15.3, attack phase is blocked */
/* (verified on real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2017-01-26) */
SLOT->eg_sh_ar = 13;
SLOT->eg_sel_ar = 0 * RATE_STEPS;
}
else
else if ((SLOT->ar + SLOT->ksr) >= 16+48)
{
/* attack rates 12.0 to 14.3 have similar specific behavior */
/* (verified on real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2017-01-26) */
SLOT->eg_sh_ar = 0;
SLOT->eg_sel_ar = 13*RATE_STEPS;
SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr] + (4 * RATE_STEPS);
}
else
{
SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr];
SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr];
}
SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
}
if (CH->sus)
@@ -1167,7 +1265,7 @@ INLINE void CALC_FCSLOT(YM2413_OPLL_CH *CH,YM2413_OPLL_SLOT *SLOT)
SLOT->eg_sh_rs = eg_rate_shift [SLOT_rs + SLOT->ksr ];
SLOT->eg_sel_rs = eg_rate_select[SLOT_rs + SLOT->ksr ];
SLOT_dp = 16 + (13<<2);
SLOT_dp = 16 + (12<<2);
SLOT->eg_sh_dp = eg_rate_shift [SLOT_dp + SLOT->ksr ];
SLOT->eg_sel_dp = eg_rate_select[SLOT_dp + SLOT->ksr ];
}
@@ -1225,15 +1323,25 @@ INLINE void set_ar_dr(int slot,int v)
SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0;
if ((SLOT->ar + SLOT->ksr) < 16+62)
if ((SLOT->ar + SLOT->ksr) >= 16+60)
{
SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
/* attack phase is skipped in case attack rate is set to 15.0-15.3 before attack phase is started */
/* during attack phase, in case attack rate is changed to 15.0-15.3, attack phase is blocked */
/* (verified on real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2017-01-26) */
SLOT->eg_sh_ar = 13;
SLOT->eg_sel_ar = 0 * RATE_STEPS;
}
else
else if ((SLOT->ar + SLOT->ksr) >= 16+48)
{
/* attack rates 12.0 to 14.3 have similar specific behavior */
/* (verified on real hardware, cf. https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2017-01-26) */
SLOT->eg_sh_ar = 0;
SLOT->eg_sel_ar = 13*RATE_STEPS;
SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr] + (4 * RATE_STEPS);
}
else
{
SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr];
SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr];
}
SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0;
+7 -4
View File
@@ -20,6 +20,9 @@
/*
** CHANGELOG:
**
** 11-05-2021 Eke-Eke (Genesis Plus GX):
** - fixed potential issue with SSG-EG inverted attenuation level on Key OFF
**
** 03-12-2017 Eke-Eke (Genesis Plus GX):
** - improved 9-bit DAC emulation accuracy
** - added discrete YM2612 DAC distortion emulation ("ladder effect")
@@ -684,7 +687,7 @@ INLINE void FM_KEYOFF(FM_CH *CH , int s )
{
/* convert EG attenuation level */
if (SLOT->ssgn ^ (SLOT->ssg&0x04))
SLOT->volume = (0x200 - SLOT->volume);
SLOT->volume = (0x200 - SLOT->volume) & MAX_ATT_INDEX;
/* force EG attenuation level */
if (SLOT->volume >= 0x200)
@@ -749,7 +752,7 @@ INLINE void FM_KEYOFF_CSM(FM_CH *CH , int s )
{
/* convert EG attenuation level */
if (SLOT->ssgn ^ (SLOT->ssg&0x04))
SLOT->volume = (0x200 - SLOT->volume);
SLOT->volume = (0x200 - SLOT->volume) & MAX_ATT_INDEX;
/* force EG attenuation level */
if (SLOT->volume >= 0x200)
@@ -776,7 +779,7 @@ INLINE void CSMKeyControll(FM_CH *CH)
ym2612.OPN.SL3.key_csm = 1;
}
INLINE void INTERNAL_TIMER_A()
INLINE void INTERNAL_TIMER_A(void)
{
if (ym2612.OPN.ST.mode & 0x01)
{
@@ -1031,7 +1034,7 @@ INLINE void set_sl_rr(FM_SLOT *SLOT,int v)
}
/* advance LFO to next sample */
INLINE void advance_lfo()
INLINE void advance_lfo(void)
{
if (ym2612.OPN.lfo_timer_overflow) /* LFO enabled ? */
{
+56 -50
View File
@@ -1,6 +1,6 @@
#ifdef HAVE_YM3438_CORE
/*
* Copyright (C) 2017 Alexey Khokholov (Nuke.YKT)
* Copyright (C) 2017-2018 Alexey Khokholov (Nuke.YKT)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -40,7 +40,7 @@
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
* OPL2 ROMs.
*
* version: 1.0.8
* version: 1.0.10
*/
#include <string.h>
@@ -235,7 +235,7 @@ static const Bit32u fm_algorithm[4][6][8] = {
static Bit32u chip_type = ym3438_mode_readmode;
void OPN2_DoIO(ym3438_t *chip)
static void OPN2_DoIO(ym3438_t *chip)
{
/* Write signal check */
chip->write_a_en = (chip->write_a & 0x03) == 0x01;
@@ -249,10 +249,10 @@ void OPN2_DoIO(ym3438_t *chip)
chip->write_busy_cnt &= 0x1f;
}
void OPN2_DoRegWrite(ym3438_t *chip)
static void OPN2_DoRegWrite(ym3438_t *chip)
{
Bit32u i;
Bit32u slot = chip->slot % 12;
Bit32u slot = chip->cycles % 12;
Bit32u address;
Bit32u channel = chip->channel;
/* Update registers */
@@ -379,7 +379,7 @@ void OPN2_DoRegWrite(ym3438_t *chip)
/* Data */
if (chip->write_d_en && (chip->write_data & 0x100) == 0)
{
switch (chip->address)
switch (chip->write_fm_mode_a)
{
case 0x21: /* LSI test 1 */
for (i = 0; i < 8; i++)
@@ -458,7 +458,7 @@ void OPN2_DoRegWrite(ym3438_t *chip)
/* Address */
if (chip->write_a_en)
{
chip->write_fm_mode_a = chip->write_data & 0xff;
chip->write_fm_mode_a = chip->write_data & 0x1ff;
}
}
@@ -468,16 +468,18 @@ void OPN2_DoRegWrite(ym3438_t *chip)
}
}
void OPN2_PhaseCalcIncrement(ym3438_t *chip)
static void OPN2_PhaseCalcIncrement(ym3438_t *chip)
{
Bit32u chan = chip->channel;
Bit32u slot = chip->cycles;
Bit32u fnum = chip->pg_fnum;
Bit32u fnum_h = fnum >> 4;
Bit32u fm;
Bit32u basefreq;
Bit8u lfo = chip->lfo_pm;
Bit8u lfo_l = lfo & 0x0f;
Bit8u pms = chip->pms[chip->channel];
Bit8u dt = chip->dt[chip->slot];
Bit8u pms = chip->pms[chan];
Bit8u dt = chip->dt[slot];
Bit8u dt_l = dt & 0x03;
Bit8u detune = 0;
Bit8u block, note;
@@ -531,32 +533,32 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
basefreq += detune;
}
basefreq &= 0x1ffff;
chip->pg_inc[chip->slot] = (basefreq * chip->multi[chip->slot]) >> 1;
chip->pg_inc[chip->slot] &= 0xfffff;
chip->pg_inc[slot] = (basefreq * chip->multi[slot]) >> 1;
chip->pg_inc[slot] &= 0xfffff;
}
void OPN2_PhaseGenerate(ym3438_t *chip)
static void OPN2_PhaseGenerate(ym3438_t *chip)
{
Bit32u slot;
/* Mask increment */
slot = (chip->slot + 20) % 24;
slot = (chip->cycles + 20) % 24;
if (chip->pg_reset[slot])
{
chip->pg_inc[slot] = 0;
}
/* Phase step */
slot = (chip->slot + 19) % 24;
chip->pg_phase[slot] += chip->pg_inc[slot];
chip->pg_phase[slot] &= 0xfffff;
slot = (chip->cycles + 19) % 24;
if (chip->pg_reset[slot] || chip->mode_test_21[3])
{
chip->pg_phase[slot] = 0;
}
chip->pg_phase[slot] += chip->pg_inc[slot];
chip->pg_phase[slot] &= 0xfffff;
}
void OPN2_EnvelopeSSGEG(ym3438_t *chip)
static void OPN2_EnvelopeSSGEG(ym3438_t *chip)
{
Bit32u slot = chip->slot;
Bit32u slot = chip->cycles;
Bit8u direction = 0;
chip->eg_ssg_pgrst_latch[slot] = 0;
chip->eg_ssg_repeat_latch[slot] = 0;
@@ -601,9 +603,9 @@ void OPN2_EnvelopeSSGEG(ym3438_t *chip)
chip->eg_ssg_enable[slot] = (chip->ssg_eg[slot] >> 3) & 0x01;
}
void OPN2_EnvelopeADSR(ym3438_t *chip)
static void OPN2_EnvelopeADSR(ym3438_t *chip)
{
Bit32u slot = (chip->slot + 22) % 24;
Bit32u slot = (chip->cycles + 22) % 24;
Bit8u nkon = chip->eg_kon_latch[slot];
Bit8u okon = chip->eg_kon[slot];
@@ -725,12 +727,12 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
chip->eg_state[slot] = nextstate;
}
void OPN2_EnvelopePrepare(ym3438_t *chip)
static void OPN2_EnvelopePrepare(ym3438_t *chip)
{
Bit8u rate;
Bit8u sum;
Bit8u inc = 0;
Bit32u slot = chip->slot;
Bit32u slot = chip->cycles;
Bit8u rate_sel;
/* Prepare increment */
@@ -813,9 +815,9 @@ void OPN2_EnvelopePrepare(ym3438_t *chip)
chip->eg_sl[0] = chip->sl[slot];
}
void OPN2_EnvelopeGenerate(ym3438_t *chip)
static void OPN2_EnvelopeGenerate(ym3438_t *chip)
{
Bit32u slot = (chip->slot + 23) % 24;
Bit32u slot = (chip->cycles + 23) % 24;
Bit16u level;
level = chip->eg_level[slot];
@@ -846,7 +848,7 @@ void OPN2_EnvelopeGenerate(ym3438_t *chip)
chip->eg_out[slot] = level;
}
void OPN2_UpdateLFO(ym3438_t *chip)
static void OPN2_UpdateLFO(ym3438_t *chip)
{
if ((chip->lfo_quotient & lfo_cycles[chip->lfo_freq]) == lfo_cycles[chip->lfo_freq])
{
@@ -860,14 +862,14 @@ void OPN2_UpdateLFO(ym3438_t *chip)
chip->lfo_cnt &= chip->lfo_en;
}
void OPN2_FMPrepare(ym3438_t *chip)
static void OPN2_FMPrepare(ym3438_t *chip)
{
Bit32u slot = (chip->slot + 6) % 24;
Bit32u slot = (chip->cycles + 6) % 24;
Bit32u channel = chip->channel;
Bit16s mod, mod1, mod2;
Bit32u op = slot / 6;
Bit8u connect = chip->connect[channel];
Bit32u prevslot = (chip->slot + 18) % 24;
Bit32u prevslot = (chip->cycles + 18) % 24;
/* Calculate modulation */
mod1 = mod2 = 0;
@@ -908,7 +910,7 @@ void OPN2_FMPrepare(ym3438_t *chip)
}
chip->fm_mod[slot] = mod;
slot = (chip->slot + 18) % 24;
slot = (chip->cycles + 18) % 24;
/* OP1 */
if (slot / 6 == 0)
{
@@ -922,9 +924,9 @@ void OPN2_FMPrepare(ym3438_t *chip)
}
}
void OPN2_ChGenerate(ym3438_t *chip)
static void OPN2_ChGenerate(ym3438_t *chip)
{
Bit32u slot = (chip->slot + 18) % 24;
Bit32u slot = (chip->cycles + 18) % 24;
Bit32u channel = chip->channel;
Bit32u op = slot / 6;
Bit32u test_dac = chip->mode_test_2c[5];
@@ -957,16 +959,17 @@ void OPN2_ChGenerate(ym3438_t *chip)
chip->ch_acc[channel] = sum;
}
void OPN2_ChOutput(ym3438_t *chip)
static void OPN2_ChOutput(ym3438_t *chip)
{
Bit32u cycles = chip->cycles;
Bit32u slot = chip->cycles;
Bit32u channel = chip->channel;
Bit32u test_dac = chip->mode_test_2c[5];
Bit16s out;
Bit16s sign;
Bit32u out_en;
chip->ch_read = chip->ch_lock;
if (chip->slot < 12)
if (slot < 12)
{
/* Ch 4,5,6 */
channel++;
@@ -1039,9 +1042,9 @@ void OPN2_ChOutput(ym3438_t *chip)
}
}
void OPN2_FMGenerate(ym3438_t *chip)
static void OPN2_FMGenerate(ym3438_t *chip)
{
Bit32u slot = (chip->slot + 19) % 24;
Bit32u slot = (chip->cycles + 19) % 24;
/* Calculate phase */
Bit16u phase = (chip->fm_mod[slot] + (chip->pg_phase[slot] >> 10)) & 0x3ff;
Bit16u quarter;
@@ -1077,7 +1080,7 @@ void OPN2_FMGenerate(ym3438_t *chip)
chip->fm_out[slot] = output;
}
void OPN2_DoTimerA(ym3438_t *chip)
static void OPN2_DoTimerA(ym3438_t *chip)
{
Bit16u time;
Bit8u load;
@@ -1126,7 +1129,7 @@ void OPN2_DoTimerA(ym3438_t *chip)
chip->timer_a_cnt = time & 0x3ff;
}
void OPN2_DoTimerB(ym3438_t *chip)
static void OPN2_DoTimerB(ym3438_t *chip)
{
Bit16u time;
Bit8u load;
@@ -1171,27 +1174,29 @@ void OPN2_DoTimerB(ym3438_t *chip)
chip->timer_b_cnt = time & 0xff;
}
void OPN2_KeyOn(ym3438_t*chip)
static void OPN2_KeyOn(ym3438_t*chip)
{
Bit32u slot = chip->cycles;
Bit32u chan = chip->channel;
/* Key On */
chip->eg_kon_latch[chip->slot] = chip->mode_kon[chip->slot];
chip->eg_kon_csm[chip->slot] = 0;
chip->eg_kon_latch[slot] = chip->mode_kon[slot];
chip->eg_kon_csm[slot] = 0;
if (chip->channel == 2 && chip->mode_kon_csm)
{
/* CSM Key On */
chip->eg_kon_latch[chip->slot] = 1;
chip->eg_kon_csm[chip->slot] = 1;
chip->eg_kon_latch[slot] = 1;
chip->eg_kon_csm[slot] = 1;
}
if (chip->cycles == chip->mode_kon_channel)
{
/* OP1 */
chip->mode_kon[chip->channel] = chip->mode_kon_operator[0];
chip->mode_kon[chan] = chip->mode_kon_operator[0];
/* OP2 */
chip->mode_kon[chip->channel + 12] = chip->mode_kon_operator[1];
chip->mode_kon[chan + 12] = chip->mode_kon_operator[1];
/* OP3 */
chip->mode_kon[chip->channel + 6] = chip->mode_kon_operator[2];
chip->mode_kon[chan + 6] = chip->mode_kon_operator[2];
/* OP4 */
chip->mode_kon[chip->channel + 18] = chip->mode_kon_operator[3];
chip->mode_kon[chan + 18] = chip->mode_kon_operator[3];
}
}
@@ -1220,6 +1225,7 @@ void OPN2_SetChipType(Bit32u type)
void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
{
Bit32u slot = chip->cycles;
chip->lfo_inc = chip->mode_test_21[1];
chip->pg_read >>= 1;
chip->eg_read[1] >>= 1;
@@ -1310,7 +1316,7 @@ void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
if (chip->mode_ch3)
{
/* Channel 3 special mode */
switch (chip->slot)
switch (slot)
{
case 1: /* OP1 */
chip->pg_fnum = chip->fnum_3ch[1];
@@ -1345,7 +1351,6 @@ void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
OPN2_UpdateLFO(chip);
OPN2_DoRegWrite(chip);
chip->cycles = (chip->cycles + 1) % 24;
chip->slot = chip->cycles;
chip->channel = chip->cycles % 6;
buffer[0] = chip->mol;
@@ -1397,6 +1402,7 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
if (chip->mode_test_21[6])
{
/* Read test data */
Bit32u slot = (chip->cycles + 18) % 24;
Bit16u testdata = ((chip->pg_read & 0x01) << 15)
| ((chip->eg_read[chip->mode_test_21[0]] & 0x01) << 14);
if (chip->mode_test_2c[4])
@@ -1405,7 +1411,7 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
}
else
{
testdata |= chip->fm_out[(chip->slot + 18) % 24] & 0x3fff;
testdata |= chip->fm_out[slot] & 0x3fff;
}
if (chip->mode_test_21[7])
{
+17 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 Alexey Khokholov (Nuke.YKT)
* Copyright (C) 2017-2018 Alexey Khokholov (Nuke.YKT)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -39,15 +39,19 @@
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
* OPL2 ROMs.
*
* version: 1.0.8
* version: 1.0.9
*/
#ifndef YM3438_H
#define YM3438_H
#ifdef __cplusplus
extern "C" {
#endif
enum {
ym3438_mode_ym2612 = 0x01, /* Enables YM2612 emulation (MD1, MD2 VA2) */
ym3438_mode_readmode = 0x02, /* Enables status read on any port (TeraDrive, MD1 VA7, MD2, etc) */
ym3438_mode_readmode = 0x02 /* Enables status read on any port (TeraDrive, MD1 VA7, MD2, etc) */
};
#include <stdint.h>
@@ -66,7 +70,6 @@ typedef int8_t Bit8s;
typedef struct
{
Bit32u cycles;
Bit32u slot;
Bit32u channel;
Bit16s mol, mor;
/* IO */
@@ -79,7 +82,7 @@ typedef struct
Bit8u write_busy_cnt;
Bit8u write_fm_address;
Bit8u write_fm_data;
Bit8u write_fm_mode_a;
Bit16u write_fm_mode_a;
Bit16u address;
Bit8u data;
Bit8u pin_test_in;
@@ -155,7 +158,7 @@ typedef struct
Bit8u timer_a_load_latch;
Bit8u timer_a_overflow_flag;
Bit8u timer_a_overflow;
Bit16u timer_b_cnt;
Bit8u timer_b_subcnt;
Bit16u timer_b_reg;
@@ -166,7 +169,7 @@ typedef struct
Bit8u timer_b_load_latch;
Bit8u timer_b_overflow_flag;
Bit8u timer_b_overflow;
/* Register set */
Bit8u mode_test_21[8];
Bit8u mode_test_2c[8];
@@ -178,7 +181,7 @@ typedef struct
Bit8u mode_kon_csm;
Bit8u dacen;
Bit16s dacdata;
Bit8u ks[24];
Bit8u ar[24];
Bit8u sr[24];
@@ -190,7 +193,7 @@ typedef struct
Bit8u am[24];
Bit8u tl[24];
Bit8u ssg_eg[24];
Bit16u fnum[6];
Bit8u block[6];
Bit8u kcode[6];
@@ -216,4 +219,9 @@ void OPN2_SetTestPin(ym3438_t *chip, Bit32u value);
Bit32u OPN2_ReadTestPin(ym3438_t *chip);
Bit32u OPN2_ReadIRQPin(ym3438_t *chip);
Bit8u OPN2_Read(ym3438_t *chip, Bit32u port);
#ifdef __cplusplus
}
#endif
#endif
+3 -3
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* Savestate support
*
* Copyright (C) 2007-2019 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -149,7 +149,7 @@ int state_load(unsigned char *state)
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_ISP,tmp32);
load_param(&m68k.cycles, sizeof(m68k.cycles));
load_param(&m68k.cycles, sizeof(m68k.cycles));
load_param(&m68k.int_level, sizeof(m68k.int_level));
load_param(&m68k.stopped, sizeof(m68k.stopped));
}
@@ -173,7 +173,7 @@ int state_load(unsigned char *state)
}
/* CD hardware */
bufferptr += scd_context_load(&state[bufferptr]);
bufferptr += scd_context_load(&state[bufferptr], version);
}
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{
+2 -2
View File
@@ -2,7 +2,7 @@
* Genesis Plus
* Savestate support
*
* Copyright (C) 2007-2019 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -40,7 +40,7 @@
#define _STATE_H_
#define STATE_SIZE 0xfd000
#define STATE_VERSION "GENPLUS-GX 1.7.5"
#define STATE_VERSION "GENPLUS-GX 1.7.6"
#define load_param(param, size) \
memcpy(param, &state[bufferptr], size); \
+7 -7
View File
@@ -5,7 +5,7 @@
* Support for 16-bit & 8-bit hardware modes
*
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2021 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -130,8 +130,8 @@ void audio_set_rate(int samplerate, double framerate)
/* resampled to desired rate at the end of each frame, using Blip Buffer. */
blip_set_rates(snd.blips[0], mclk, samplerate);
/* Mega CD sound hardware */
if (system_hw == SYSTEM_MCD)
/* Mega CD sound hardware enabled ? */
if (snd.blips[1] && snd.blips[2])
{
/* number of SCD master clocks run per second */
mclk = (mclk / system_clock) * SCD_CLOCK;
@@ -195,14 +195,14 @@ int audio_update(int16 *buffer)
/* run sound chips until end of frame */
int size = sound_update(mcycles_vdp);
/* Mega CD specific */
if (system_hw == SYSTEM_MCD)
/* Mega CD sound hardware enabled ? */
if (snd.blips[1] && snd.blips[2])
{
/* sync PCM chip with other sound chips */
pcm_update(size);
/* read CDDA samples */
cdd_read_audio(size);
/* read CD-DA samples */
cdd_update_audio(size);
#ifdef ALIGN_SND
/* return an aligned number of samples if required */
+13 -12
View File
@@ -5,7 +5,7 @@
* Support for 16-bit & 8-bit hardware modes
*
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2022 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -45,17 +45,18 @@
#include "blip_buf.h"
/* Supported hardware models */
#define SYSTEM_SG 0x10
#define SYSTEM_SGII 0x11
#define SYSTEM_MARKIII 0x12
#define SYSTEM_SMS 0x20
#define SYSTEM_SMS2 0x21
#define SYSTEM_GG 0x40
#define SYSTEM_GGMS 0x41
#define SYSTEM_MD 0x80
#define SYSTEM_PBC 0x81
#define SYSTEM_PICO 0x82
#define SYSTEM_MCD 0x84
#define SYSTEM_SG 0x01
#define SYSTEM_SGII 0x02
#define SYSTEM_SGII_RAM_EXT 0x03
#define SYSTEM_MARKIII 0x10
#define SYSTEM_SMS 0x20
#define SYSTEM_SMS2 0x21
#define SYSTEM_GG 0x40
#define SYSTEM_GGMS 0x41
#define SYSTEM_MD 0x80
#define SYSTEM_PBC 0x81
#define SYSTEM_PICO 0x82
#define SYSTEM_MCD 0x84
/* NTSC & PAL Master Clock frequencies */
#define MCLOCK_NTSC 53693175
+37 -14
View File
@@ -5,7 +5,7 @@
* Support for SG-1000 (TMS99xx & 315-5066), Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP
*
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2017 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2023 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -53,6 +53,12 @@
bg_name_dirty[name] |= (1 << ((addr >> 2) & 7)); \
}
/* HBLANK flag timings */
#define HBLANK_H32_START_MCYCLE (280)
#define HBLANK_H32_END_MCYCLE (860)
#define HBLANK_H40_START_MCYCLE (228)
#define HBLANK_H40_END_MCYCLE (872)
/* VDP context */
uint8 ALIGNED_(4) sat[0x400]; /* Internal copy of sprite attribute table */
uint8 ALIGNED_(4) vram[0x10000]; /* Video RAM (64K x 8-bit) */
@@ -142,6 +148,8 @@ static int fifo_idx; /* FIFO write index */
static int fifo_byte_access; /* FIFO byte access flag */
static uint32 fifo_cycles; /* FIFO next access cycle */
static int *fifo_timing; /* FIFO slots timing table */
static int hblank_start_cycle; /* HBLANK flag set cycle */
static int hblank_end_cycle; /* HBLANK flag clear cycle */
/* set Z80 or 68k interrupt lines */
static void (*set_irq_line)(unsigned int level);
@@ -323,6 +331,10 @@ void vdp_reset(void)
/* default FIFO access slots timings */
fifo_timing = (int *)fifo_timing_h32;
/* default HBLANK flag timings */
hblank_start_cycle = HBLANK_H32_START_MCYCLE;
hblank_end_cycle = HBLANK_H32_END_MCYCLE;
/* default overscan area */
if ((system_hw == SYSTEM_GG) && !config.gg_extra)
{
@@ -362,6 +374,7 @@ void vdp_reset(void)
{
case SYSTEM_SG:
case SYSTEM_SGII:
case SYSTEM_SGII_RAM_EXT:
{
/* SG-1000 (TMS99xx) or SG-1000 II (315-5066) VDP */
vdp_z80_data_w = vdp_z80_data_w_sg;
@@ -708,6 +721,10 @@ void vdp_68k_ctrl_w(unsigned int data)
}
}
/* Update address and code registers */
addr = addr_latch | (data & 0x3FFF);
code = ((code & 0x3C) | ((data >> 14) & 0x03));
/* Check CD0-CD1 bits */
if ((data & 0xC000) == 0x8000)
{
@@ -719,10 +736,6 @@ void vdp_68k_ctrl_w(unsigned int data)
/* Set pending flag (Mode 5 only) */
pending = reg[1] & 4;
}
/* Update address and code registers */
addr = addr_latch | (data & 0x3FFF);
code = ((code & 0x3C) | ((data >> 14) & 0x03));
}
else
{
@@ -1186,9 +1199,12 @@ unsigned int vdp_68k_ctrl_r(unsigned int cycles)
temp |= 0x08;
}
/* Adjust cycle count relatively to start of line */
cycles -= mcycles_vdp;
/* Cycle-accurate VINT flag (Ex-Mutants, Tyrant / Mega-Lo-Mania, Marvel Land) */
/* this allows VINT flag to be read just before vertical interrupt is being triggered */
if ((v_counter == bitmap.viewport.h) && (cycles >= (mcycles_vdp + 788)))
if ((v_counter == bitmap.viewport.h) && (cycles >= 788))
{
/* check Z80 interrupt state to assure VINT has not already been triggered (and flag cleared) */
if (Z80.irq_state != ASSERT_LINE)
@@ -1197,15 +1213,14 @@ unsigned int vdp_68k_ctrl_r(unsigned int cycles)
}
}
/* Cycle-accurate HBLANK flag (Sonic 3 & Sonic 2 "VS Modes", Bugs Bunny Double Trouble, Lemmings 2, Mega Turrican, V.R Troopers, Gouketsuji Ichizoku,...) */
/* NB: this is not 100% accurate (see hvc.h for horizontal events timings in H32 and H40 mode) but is close enough to make no noticeable difference for games */
if ((cycles % MCYCLES_PER_LINE) < 588)
/* Cycle-accurate HBLANK flag (Sonic 3 & Sonic 2 "VS Modes", Bugs Bunny Double Trouble, Lemmings 2, Mega Turrican, V.R Troopers, Gouketsuji Ichizoku, Ultraverse Prime, ...) */
if ((cycles >= hblank_start_cycle) && (cycles < hblank_end_cycle))
{
temp |= 0x04;
}
#ifdef LOGVDP
error("[%d(%d)][%d(%d)] VDP 68k status read -> 0x%x (0x%x) (%x)\n", v_counter, (v_counter + (cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, temp, status, m68k_get_reg(M68K_REG_PC));
error("[%d(%d)][%d(%d)] VDP 68k status read -> 0x%x (0x%x) (%x)\n", v_counter, (v_counter + cycles/MCYCLES_PER_LINE)%lines_per_frame, cycles + mcycles_vdp, cycles%MCYCLES_PER_LINE, temp, status, m68k_get_reg(M68K_REG_PC));
#endif
return (temp);
}
@@ -1691,7 +1706,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
}
else
{
render_bg = (reg[11] & 0x04) ? render_bg_m5_vs : render_bg_m5;
render_bg = (reg[11] & 0x04) ? (config.enhanced_vscroll ? render_bg_m5_vs_enhanced : render_bg_m5_vs) : render_bg_m5;
render_obj = (reg[12] & 0x08) ? render_obj_m5_ste : render_obj_m5;
}
@@ -1902,7 +1917,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
/* Vertical Scrolling mode */
if (d & 0x04)
{
render_bg = im2_flag ? render_bg_m5_im2_vs : render_bg_m5_vs;
render_bg = im2_flag ? render_bg_m5_im2_vs : (config.enhanced_vscroll ? render_bg_m5_vs_enhanced : render_bg_m5_vs);
}
else
{
@@ -1975,6 +1990,10 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
/* FIFO access slots timings */
fifo_timing = (int *)fifo_timing_h40;
/* HBLANK flag timings */
hblank_start_cycle = HBLANK_H32_START_MCYCLE;
hblank_end_cycle = HBLANK_H32_END_MCYCLE;
}
else
{
@@ -1995,6 +2014,10 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
/* FIFO access slots timings */
fifo_timing = (int *)fifo_timing_h32;
/* HBLANK flag timings */
hblank_start_cycle = HBLANK_H40_START_MCYCLE;
hblank_end_cycle = HBLANK_H40_END_MCYCLE;
}
/* Active screen width modified during VBLANK will be applied on upcoming frame */
@@ -2208,8 +2231,8 @@ static void vdp_bus_w(unsigned int data)
color_update_m5(0x00, data);
}
/* CRAM modified during HBLANK (Striker, Zero the Kamikaze, etc) */
if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (m68k.cycles <= (mcycles_vdp + 860)))
/* CRAM modified during HBLANK (Striker, Zero the Kamikaze, Yuu Yuu Hakusho, etc) */
if ((v_counter < bitmap.viewport.h) && (m68k.cycles <= (mcycles_vdp + 860)) && ((reg[1] & 0x40) || (index == border)))
{
/* Remap current line */
remap_line(v_counter);
+1 -1
View File
@@ -5,7 +5,7 @@
* Support for SG-1000 (TMS99xx & 315-5066), Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP
*
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2017 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2007-2023 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
+631 -1
View File
@@ -6,6 +6,7 @@
*
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2022 AlexKiri (enhanced vscroll mode rendering function)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -1035,6 +1036,7 @@ void color_update_m4(int index, unsigned int data)
case SYSTEM_SG:
case SYSTEM_SGII:
case SYSTEM_SGII_RAM_EXT:
{
/* Fixed TMS99xx palette */
if (index & 0x0F)
@@ -1847,6 +1849,295 @@ void render_bg_m5_vs(int line)
merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w);
}
/* Enhanced function that allows each cell to be vscrolled individually, instead of being limited to 2-cell */
void render_bg_m5_vs_enhanced(int line)
{
int column;
uint32 atex, atbuf, *src, *dst;
uint32 v_line, next_v_line, *nt;
/* Vertical scroll offset */
int v_offset = 0;
/* Common data */
uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)];
uint32 yscroll = 0;
uint32 pf_col_mask = playfield_col_mask;
uint32 pf_row_mask = playfield_row_mask;
uint32 pf_shift = playfield_shift;
uint32 *vs = (uint32 *)&vsram[0];
/* Window & Plane A */
int a = (reg[18] & 0x1F) << 3;
int w = (reg[18] >> 7) & 1;
/* Plane B width */
int start = 0;
int end = bitmap.viewport.w >> 4;
/* Plane B horizontal scroll */
#ifdef LSB_FIRST
uint32 shift = (xscroll >> 16) & 0x0F;
uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
#else
uint32 shift = (xscroll & 0x0F);
uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
#endif
/* Left-most column vertical scrolling when partially shown horizontally (verified on PAL MD2) */
/* TODO: check on Genesis 3 models since it apparently behaves differently */
/* In H32 mode, vertical scrolling is disabled, in H40 mode, same value is used for both planes */
/* See Formula One / Kawasaki Superbike Challenge (H32) & Gynoug / Cutie Suzuki no Ringside Angel (H40) */
if (reg[12] & 1)
{
yscroll = vs[19] & (vs[19] >> 16);
}
if(shift)
{
/* Plane B vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
/* Plane B line buffer */
dst = (uint32 *)&linebuf[0][0x10 + shift];
atbuf = nt[(index - 1) & pf_col_mask];
DRAW_COLUMN(atbuf, v_line)
}
else
{
/* Plane B line buffer */
dst = (uint32 *)&linebuf[0][0x20];
}
for(column = 0; column < end; column++, index++)
{
/* Plane B vertical scroll */
#ifdef LSB_FIRST
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#else
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#endif
if (column != end - 1)
{
/* The offset of the intermediary cell is an average of the offsets of the current 2-cell and the next 2-cell. */
/* For the last column, the previously calculated offset is used */
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
#else
GET_MSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
#ifdef LSB_FIRST
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
#else
v_line = (line + v_offset + vs[column]) & pf_row_mask;
#endif
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_MSB_TILE(atbuf, v_line)
#else
GET_LSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
}
if (w == (line >= a))
{
/* Window takes up entire line */
a = 0;
w = 1;
}
else
{
/* Window and Plane A share the line */
a = clip[0].enable;
w = clip[1].enable;
}
/* Plane A */
if (a)
{
/* Plane A width */
start = clip[0].left;
end = clip[0].right;
/* Plane A horizontal scroll */
#ifdef LSB_FIRST
shift = (xscroll & 0x0F);
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
#else
shift = (xscroll >> 16) & 0x0F;
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
#endif
if(shift)
{
/* Plane A vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
/* Plane A line buffer */
dst = (uint32 *)&linebuf[1][0x10 + shift + (start << 4)];
/* Window bug */
if (start)
{
atbuf = nt[index & pf_col_mask];
}
else
{
atbuf = nt[(index - 1) & pf_col_mask];
}
DRAW_COLUMN(atbuf, v_line)
}
else
{
/* Plane A line buffer */
dst = (uint32 *)&linebuf[1][0x20 + (start << 4)];
}
for(column = start; column < end; column++, index++)
{
/* Plane A vertical scroll */
#ifdef LSB_FIRST
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#else
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#endif
if (column != end - 1)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
#else
GET_MSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
#ifdef LSB_FIRST
v_line = (line + v_offset + vs[column]) & pf_row_mask;
#else
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
#endif
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_MSB_TILE(atbuf, v_line)
#else
GET_LSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
}
/* Window width */
start = clip[1].left;
end = clip[1].right;
}
/* Window */
if (w)
{
/* Window name table */
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
/* Pattern row index */
v_line = (line & 7) << 3;
/* Plane A line buffer */
dst = (uint32 *)&linebuf[1][0x20 + (start << 4)];
for(column = start; column < end; column++)
{
atbuf = nt[column];
DRAW_COLUMN(atbuf, v_line)
}
}
/* Merge background layers */
merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w);
}
void render_bg_m5_im2(int line)
{
int column;
@@ -2543,6 +2834,345 @@ void render_bg_m5_vs(int line)
}
}
void render_bg_m5_vs_enhanced(int line)
{
int column, start, end;
uint32 atex, atbuf, *src, *dst;
uint32 shift, index, v_line, next_v_line, *nt;
uint8 *lb;
/* Vertical scroll offset */
int v_offset = 0;
/* Scroll Planes common data */
uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)];
uint32 yscroll = 0;
uint32 pf_col_mask = playfield_col_mask;
uint32 pf_row_mask = playfield_row_mask;
uint32 pf_shift = playfield_shift;
uint32 *vs = (uint32 *)&vsram[0];
/* Number of columns to draw */
int width = bitmap.viewport.w >> 4;
/* Layer priority table */
uint8 *table = lut[(reg[12] & 8) >> 2];
/* Window vertical range (cell 0-31) */
int a = (reg[18] & 0x1F) << 3;
/* Window position (0=top, 1=bottom) */
int w = (reg[18] >> 7) & 1;
/* Test against current line */
if (w == (line >= a))
{
/* Window takes up entire line */
a = 0;
w = 1;
}
else
{
/* Window and Plane A share the line */
a = clip[0].enable;
w = clip[1].enable;
}
/* Left-most column vertical scrolling when partially shown horizontally */
/* Same value for both planes, only in 40-cell mode, verified on PAL MD2 */
/* See Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge */
if (reg[12] & 1)
{
yscroll = vs[19] & (vs[19] >> 16);
}
/* Plane A*/
if (a)
{
/* Plane A width */
start = clip[0].left;
end = clip[0].right;
/* Plane A horizontal scroll */
#ifdef LSB_FIRST
shift = (xscroll & 0x0F);
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
#else
shift = (xscroll >> 16) & 0x0F;
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
#endif
/* Background line buffer */
dst = (uint32 *)&linebuf[0][0x20 + (start << 4) + shift];
if(shift)
{
/* Left-most column is partially shown */
dst -= 4;
/* Plane A vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
/* Window bug */
if (start)
{
atbuf = nt[index & pf_col_mask];
}
else
{
atbuf = nt[(index-1) & pf_col_mask];
}
DRAW_COLUMN(atbuf, v_line)
}
for(column = start; column < end; column++, index++)
{
/* Plane A vertical scroll */
#ifdef LSB_FIRST
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#else
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#endif
if (column != end - 1)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
#else
GET_MSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
#ifdef LSB_FIRST
v_line = (line + v_offset + vs[column]) & pf_row_mask;
#else
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
#endif
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_MSB_TILE(atbuf, v_line)
#else
GET_LSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
}
/* Window width */
start = clip[1].left;
end = clip[1].right;
}
else
{
/* Window width */
start = 0;
end = width;
}
/* Window Plane */
if (w)
{
/* Background line buffer */
dst = (uint32 *)&linebuf[0][0x20 + (start << 4)];
/* Window name table */
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
/* Pattern row index */
v_line = (line & 7) << 3;
for(column = start; column < end; column++)
{
atbuf = nt[column];
DRAW_COLUMN(atbuf, v_line)
}
}
/* Plane B horizontal scroll */
#ifdef LSB_FIRST
shift = (xscroll >> 16) & 0x0F;
index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
#else
shift = (xscroll & 0x0F);
index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
#endif
/* Background line buffer */
lb = &linebuf[0][0x20];
if(shift)
{
/* Left-most column is partially shown */
lb -= (0x10 - shift);
/* Plane B vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[(index-1) & pf_col_mask];
DRAW_BG_COLUMN(atbuf, v_line, xscroll, yscroll)
}
for(column = 0; column < width; column++, index++)
{
/* Plane B vertical scroll */
#ifdef LSB_FIRST
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#else
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#endif
if (column != width - 1)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef ALIGN_LONG
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_MSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#else
GET_MSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + vs[column]) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_LSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#endif
#else /* NOT ALIGNED */
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_MSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#else
GET_MSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + vs[column]) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_LSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#endif
#endif /* ALIGN_LONG */
}
}
void render_bg_m5_im2(int line)
{
int column, start, end;
@@ -4125,7 +4755,7 @@ void render_line(int line)
/* Left-most column blanking */
if (reg[0] & 0x20)
{
if (system_hw > SYSTEM_SGII)
if (system_hw >= SYSTEM_MARKIII)
{
memset(&linebuf[0][0x20], 0x40, 8);
}
+2
View File
@@ -6,6 +6,7 @@
*
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2022 AlexKiri (enhanced vscroll mode rendering function)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -118,6 +119,7 @@ extern void render_bg_inv(int line);
extern void render_bg_m4(int line);
extern void render_bg_m5(int line);
extern void render_bg_m5_vs(int line);
extern void render_bg_m5_vs_enhanced(int line);
extern void render_bg_m5_im2(int line);
extern void render_bg_m5_im2_vs(int line);
extern void render_obj_tms(int line);
+3 -1
View File
@@ -210,6 +210,7 @@ UINT32 z80_cycle_ratio;
#endif
Z80_Regs Z80;
UINT8 z80_last_fetch;
unsigned char *z80_readmap[64];
unsigned char *z80_writemap[64];
@@ -660,7 +661,8 @@ INLINE UINT8 ROP(void)
{
unsigned pc = PCD;
PC++;
return cpu_readop(pc);
z80_last_fetch = cpu_readop(pc);
return z80_last_fetch;
}
/****************************************************************
+1
View File
@@ -50,6 +50,7 @@ typedef struct
extern Z80_Regs Z80;
extern UINT8 z80_last_fetch;
#ifdef Z80_OVERCLOCK_SHIFT
extern UINT32 z80_cycle_ratio;
+25 -28
View File
@@ -1,48 +1,43 @@
#ifndef _OSD_H
#define _OSD_H
#ifndef _OSD_H_
#define _OSD_H_
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "scrc32.h"
#define MAX_INPUTS 8
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef M_PI
#define M_PI 3.1415926535897932385
#endif
#define CHEATS_UPDATE() ROMCheatUpdate()
typedef struct
void osd_input_update(void);
int load_archive(char*, unsigned char*, int, char *);
extern void ROMCheatUpdate(void);
typedef struct
{
int8 device;
uint8 port;
uint8 padtype;
} t_input_config;
struct
typedef struct
{
char version[16];
uint8 hq_fm;
uint8 filter;
uint8 hq_psg;
uint8 ym2612;
uint8 ym2413;
uint8 cd_latency;
#ifdef HAVE_YM3438_CORE
uint8 ym3438;
#endif
#ifdef HAVE_OPLL_CORE
uint8 opll;
#endif
uint8 mono;
int16 psg_preamp;
int16 fm_preamp;
int16 lp_range;
int16 cdda_volume;
int16 pcm_volume;
uint16 lp_range;
int16 low_freq;
int16 high_freq;
int16 lg;
@@ -56,19 +51,25 @@ struct
uint8 addr_error;
uint8 bios;
uint8 lock_on;
uint8 add_on;
uint8 overscan;
uint8 gg_extra;
uint8 ntsc;
uint8 lcd;
uint8 gg_extra;
uint8 render;
uint8 enhanced_vscroll;
uint8 enhanced_vscroll_limit;
t_input_config input[MAX_INPUTS];
} config;
} t_config;
extern t_config config;
extern char GG_ROM[256];
extern char AR_ROM[256];
extern char SK_ROM[256];
extern char SK_UPMEM[256];
extern char GG_BIOS[256];
extern char MD_BIOS[256];
extern char CD_BIOS_EU[256];
extern char CD_BIOS_US[256];
extern char CD_BIOS_JP[256];
@@ -76,8 +77,4 @@ extern char MS_BIOS_US[256];
extern char MS_BIOS_EU[256];
extern char MS_BIOS_JP[256];
void osd_input_update(void);
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
extern void ROMCheatUpdate(void);
#endif /* _OSD_H */
#endif /* _OSD_H_ */
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef _S_CRC32_H
#define _S_CRC32_H
static const unsigned long crc_table[256] = {
static const unsigned int crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
@@ -61,7 +61,7 @@ static const unsigned long crc_table[256] = {
#define DO4_CRC32(buf) DO2_CRC32(buf); DO2_CRC32(buf);
#define DO8_CRC32(buf) DO4_CRC32(buf); DO4_CRC32(buf);
unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len)
unsigned int crc32(unsigned int crc, const unsigned char *buf, unsigned int len)
{
if (buf == 0) return 0L;
crc = crc ^ 0xffffffffL;
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef _S_CRC32_H
#define _S_CRC32_H
unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len);
unsigned int crc32(unsigned int crc, const unsigned char *buf, unsigned int len);
#endif