4.2b Preliminary support for Banksets handling. Improved DMA timing. Small tweaks and improvements to compatibility across the board including handling more of the "stable" illegal opcodes for the 6502.

This commit is contained in:
wavemotion-dave 2022-11-08 07:53:14 -05:00
parent eb91c9c37a
commit aa02a71247
14 changed files with 839 additions and 460 deletions

Binary file not shown.

View file

@ -1,4 +1,4 @@
VERSION=4.2
VERSION=4.2b
TARGNAME=A7800DS
#---------------------------------------------------------------------------------

View file

@ -59,7 +59,7 @@ int bg2;
int bg3; // BG pointers
int bg0s, bg1s; // sub BG pointers
#define MAX_DEBUG 16
#define MAX_DEBUG 6
int debug[MAX_DEBUG]={0};
u8 DEBUG_DUMP = 0;
@ -81,36 +81,19 @@ static void DumpDebugData(void)
{
if (DEBUG_DUMP)
{
char dbgbuf[32];
for (int i=0; i<MAX_DEBUG; i++)
{
int idx=0;
int val = debug[i];
if (val < 0)
{
dbgbuf[idx++] = '-';
val = val * -1;
}
else
{
dbgbuf[idx++] = '0' + (int)val/10000000;
}
val = val % 10000000;
dbgbuf[idx++] = '0' + (int)val/1000000;
val = val % 1000000;
dbgbuf[idx++] = '0' + (int)val/100000;
val = val % 100000;
dbgbuf[idx++] = '0' + (int)val/10000;
val = val % 10000;
dbgbuf[idx++] = '0' + (int)val/1000;
val= val % 1000;
dbgbuf[idx++] = '0' + (int)val/100;
val = val % 100;
dbgbuf[idx++] = '0' + (int)val/10;
dbgbuf[idx++] = '0' + (int)val%10;
dbgbuf[idx++] = 0;
dsPrintValue(0,3+i,0, dbgbuf);
sprintf(fpsbuf, "D%-2d: %08ld %08XH", i, debug[i], debug[i]);
dsPrintValue(0,2+i,0, fpsbuf);
}
extern byte last_illegal_opcode;
if (last_illegal_opcode >= 0)
{
sprintf(fpsbuf, "ILLOP=%02X", last_illegal_opcode);
dsPrintValue(24,21,0, fpsbuf);
}
}
}
@ -216,14 +199,13 @@ void dsInitScreenMain(void)
if (isDSiMode()) isDS_LITE = false;
else isDS_LITE = true;
vramSetBankB(VRAM_B_LCD ); // Need to do this early so we can steal a bit of this RAM for bank swap...
vramSetBankB(VRAM_B_LCD ); // We're stealing 64K at 0x06830000
vramSetBankD(VRAM_D_LCD ); // Not using this for video but 128K of faster RAM always useful! Mapped at 0x06860000 - Used for Cart Bankswitch
vramSetBankE(VRAM_E_LCD ); // Not using this for video but 64K of faster RAM always useful! Mapped at 0x06880000 - Used for Cart Bankswitch
vramSetBankF(VRAM_F_LCD ); // Not using this for video but 16K of faster RAM always useful! Mapped at 0x06890000 - ..
vramSetBankG(VRAM_G_LCD ); // Not using this for video but 16K of faster RAM always useful! Mapped at 0x06894000 - ..
vramSetBankH(VRAM_H_LCD ); // Not using this for video but 32K of faster RAM always useful! Mapped at 0x06898000 - ..
vramSetBankI(VRAM_I_LCD ); // Not using this for video but 16K of faster RAM always useful! Mapped at 0x068A0000 - ..
vramSetBankI(VRAM_I_LCD ); // Not using this for video but 16K of faster RAM always useful! Mapped at 0x068A0000 - ..
}
void dsInitTimer(void)
@ -237,7 +219,7 @@ void dsShowScreenEmu(void)
// Change vram
videoSetMode(MODE_5_2D | DISPLAY_BG2_ACTIVE | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
vramSetBankB(VRAM_B_LCD ); // Need to do this early so we can steal a bit of this RAM for bank swap...
vramSetBankB(VRAM_B_LCD ); // We're stealing 64K at 0x06830000
vramSetBankD(VRAM_D_LCD ); // Not using this for video but 128K of faster RAM always useful! Mapped at 0x06860000 - Used for Cart Bankswitch
vramSetBankE(VRAM_E_LCD ); // Not using this for video but 64K of faster RAM always useful! Mapped at 0x06880000 - Used for Cart Bankswitch
vramSetBankF(VRAM_F_LCD ); // Not using this for video but 16K of faster RAM always useful! Mapped at 0x06890000 - ..
@ -247,9 +229,6 @@ void dsShowScreenEmu(void)
bg0 = bgInit(3, BgType_Bmp8, BgSize_B8_512x512, 0,0);
bg1 = bgInit(2, BgType_Bmp8, BgSize_B8_512x512, 0,0);
REG_BLDCNT = BLEND_ALPHA | BLEND_SRC_BG2 | BLEND_DST_BG3;
REG_BLDALPHA = (8 << 8) | 8; // 50% / 50%
// Setup video scaling...
bufVideo = BG_GFX;
cxBG = (myCartInfo.xOffset << 8);
@ -339,6 +318,10 @@ void dsLoadGame(char *filename)
if (DEBUG_DUMP)
{
char dbgbuf[32];
extern word cardtype;
sprintf(dbgbuf, "CARDTYPE: %04X", cardtype);
dsPrintValue(0,21,0, (char*)dbgbuf);
dsPrintValue(0,22,0, (char*)cartridge_digest);
}

View file

@ -164,24 +164,22 @@ struct options_t
{
const char *label;
u8 isNumeric; // 0=String List, 1=Positive 8-bit, 2=Negative 8-bit
const char *option[12];
const char *option[15];
u8 *option_val;
u8 option_max;
};
const struct options_t Game_Option_Table[] =
{
{"CART TYPE", 0, {"NORMAL/FLAT", "SUPERCART", "SUPER LARGE", "SUPER RAM", "SUPER ROM", "SUPER RAM X2", "ABSOLUTE", "ACTIVISION", "FRACTALUS", "FLAT WITH RAM"},&myCartInfo.cardtype, 10},
{"CART TYPE", 0, {"NORMAL/FLAT", "SUPERCART", "SUPER LARGE", "SUPER RAM", "SUPER ROM", "SUPER RAM X2", "ABSOLUTE", "ACTIVISION", "FRACTALUS", "FLAT WITH RAM", "BANKSETS", "BANKSETS RAM", "BANKSETS HALT"},&myCartInfo.cardtype, 13},
{"HIGHSCORE", 0, {"DISABLED", "ENABLED"}, &myCartInfo.hsc, 2},
{"FRAMESKIP", 0, {"DISABLED", "MEDIUM 3/4", "HIGH 1/2"}, &myCartInfo.frameSkip, 3},
{"POKEY", 0, {"NONE", "AT 4000", "AT 450", "AT 800"}, &myCartInfo.pokeyType, 4},
{"STEALS CYC", 0, {"NO", "YES"}, &myCartInfo.steals_cycles, 2},
{"USES WSYNC", 0, {"NO", "YES"}, &myCartInfo.uses_wsync, 2},
{"DMA ADJUST", 2, {"-25","+25"}, (u8*)&myCartInfo.dma_adjust, 2},
{"LEFT DIFF", 0, {"A", "B"} , &myCartInfo.diff1, 2},
{"RIGHT DIFF", 0, {"A", "B"} , &myCartInfo.diff2, 2},
{"LEFT JOY", 0, {"NONE", "JOYSTICK", "LIGHTGUN", "PADDLES", "TWIN STICKS", "SOTA"}, &myCartInfo.cardctrl1, 6},
{"RIGHT JOY", 0, {"NONE", "JOYSTICK", "LIGHTGUN", "PADDLES", "TWIN STICKS", "SOTA"}, &myCartInfo.cardctrl2, 6},
{"RIGHT JOY", 0, {"NONE", "JOYSTICK", "LIGHTGUN", "PADDLES", "TWIN STICKS", "SOTA"}, &myCartInfo.cardctrl2, 6},
{"X OFFSET", 2, {"-50", "+50"}, (u8*)&myCartInfo.xOffset, 2},
{"Y OFFSET", 2, {"-50", "+50"}, (u8*)&myCartInfo.yOffset, 2},
{"X SCALE", 2, {"+200", "+320"}, (u8*)&myCartInfo.xScale, 2},

View file

@ -13,9 +13,9 @@
// ---------------------------
// Config handling...
// ---------------------------
#define CONFIG_VER 0x0006
#define CONFIG_VER 0x0007
#define MAX_CONFIGS 360
#define MAX_CONFIGS 700
struct AllConfig_t
{

View file

@ -31,6 +31,9 @@ char cartridge_title[256];
byte cartridge_digest[256];
char cartridge_filename[256];
word cardtype = 0x0000;
bool write_only_pokey_at_4000 = false;
// -------------------------------------------------------------------------------------------------
// We allow cart sizes up to 1024K which is pretty huge - I've not seen any ROMs bigger than this.
// -------------------------------------------------------------------------------------------------
@ -49,6 +52,11 @@ u8 *shadow_ram __attribute__((section(".dtcm"))) = 0;
// ---------------------------------------------------------------------------------------
byte ex_ram_buffer[0x8000] ALIGN(32) = {0};
// ------------------------------------------------------------------------------------
// For the new banksets scheme, we use a 64K buffer to mirror the 7800 address space.
// ------------------------------------------------------------------------------------
byte banksets_memory[64*1024] ALIGN(32);
// ----------------------------------------------------------------------------
// HasHeader
// ----------------------------------------------------------------------------
@ -84,9 +92,9 @@ ITCM_CODE void cartridge_WriteBank(word address, byte bank)
if (last_ex_ram_bank != ex_ram_bank)
{
u32 *src = ex_ram_bank ? (u32*)0x06820000 : (u32*)0x06824000; // Only for the DSi.. see DS_LITE handling below
u32 *src = ex_ram_bank ? (u32*)0x06830000 : (u32*)0x06834000; // Only for the DSi.. see DS_LITE handling below
u32 *dest = (u32*)(memory_ram+0x4000);
shadow_ram = ex_ram_bank ? (u8*)0x06820000 : (u8*)0x06824000; // // Only for the DSi.. see DS_LITE handling below
shadow_ram = ex_ram_bank ? (u8*)0x06830000 : (u8*)0x06834000; // // Only for the DSi.. see DS_LITE handling below
if (isDS_LITE) // Unfortunately non DSi can't write 8-bit values to LCD RAM... so we have to do this the slow way
{
@ -125,9 +133,9 @@ ITCM_CODE void cartridge_SwapRAM_DragonFlyStyle(u8 data)
if (last_ex_ram_bank_df != ex_ram_bank_df)
{
u32 *src = ex_ram_bank_df ? (u32*)0x06820000 : (u32*)0x06824000; // Only for the DSi.. see DS_LITE handling below
u32 *src = ex_ram_bank_df ? (u32*)0x06830000 : (u32*)0x06834000; // Only for the DSi.. see DS_LITE handling below
u32 *dest = (u32*)(memory_ram+0x4000);
shadow_ram = ex_ram_bank_df ? (u8*)0x06820000 : (u8*)0x06824000; // Only for the DSi.. see DS_LITE handling below
shadow_ram = ex_ram_bank_df ? (u8*)0x06830000 : (u8*)0x06834000; // Only for the DSi.. see DS_LITE handling below
if (isDS_LITE) // Unfortunately non DSi can't write 8-bit values to LCD RAM... so we have to do this the slow way
{
@ -187,7 +195,7 @@ static void cartridge_ReadHeader(const byte* header) {
// bit 14 = halt banked ram
// bit 15 = pokey at $800
word cardtype = (header[53] << 8) | header[54];
cardtype = (header[53] << 8) | header[54];
myCartInfo.cardtype = (cartridge_size <= 65536) ? CARTRIDGE_TYPE_NORMAL : CARTRIDGE_TYPE_SUPERCART; // Default guess... may be overridden below
@ -198,6 +206,12 @@ static void cartridge_ReadHeader(const byte* header) {
if (cardtype & 0x0020) myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_RAMX2;
if (cardtype & 0x0100) myCartInfo.cardtype = CARTRIDGE_TYPE_ACTIVISION;
if (cardtype & 0x0200) myCartInfo.cardtype = CARTRIDGE_TYPE_ABSOLUTE;
if (cardtype & 0x2000) // Banksets
{
myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS; // Default to Banksets (no RAM)
if (cardtype & 0x0004) myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS_RAM; // RAM @4000 enabled
if (cardtype & 0x4000) myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS_HALTRAM; // Banked Halt RAM @4000 enabled
}
if (cardtype & 0x0040) myCartInfo.pokeyType = POKEY_AT_450;
if (cardtype & 0x8000) myCartInfo.pokeyType = POKEY_AT_800;
@ -207,15 +221,15 @@ static void cartridge_ReadHeader(const byte* header) {
myCartInfo.cardctrl2 = header[56];
myCartInfo.region = header[57] & 1;
myCartInfo.hsc = (header[58]&1 ? HSC_YES:HSC_NO);
myCartInfo.steals_cycles = STEAL_CYCLE; // By default, assume the cart steal cycles
myCartInfo.uses_wsync = USES_WSYNC; // By default, assume the cart uses wsync
myCartInfo.dma_adjust = 0;
last_bank = 255;
last_ex_ram_bank = 0;
ex_ram_bank = 0;
last_ex_ram_bank_df = 0;
write_only_pokey_at_4000 = false;
ex_ram_bank_df = 0;
if (isDS_LITE) shadow_ram = ex_ram_bank ? (u8*)(ex_ram_buffer+0x0000) : (u8*)(ex_ram_buffer+0x4000); // for DS-Lite
else shadow_ram = ex_ram_bank ? (u8*)0x06820000 : (u8*)0x06824000; // // Only for the DSi.. see DS_LITE handling above
else shadow_ram = ex_ram_bank ? (u8*)0x06830000 : (u8*)0x06834000; // // Only for the DSi.. see DS_LITE handling above
shadow_ram -= 0x4000; // Makes for faster indexing in Memory.c
}
@ -232,8 +246,11 @@ static bool _cartridge_Load(uint size)
cartridge_Release();
memset(ex_ram_buffer, 0x00, sizeof(ex_ram_buffer)); // Clear the EX RAM memory
memset(banksets_memory, 0xFF, sizeof(banksets_memory)); // Clear the banksets ROM memory area
memset(banksets_memory+0x4000, 0x00, 0x4000); // Clear banksets RAM memory area
byte header[128] = {0}; // We might have a header... this will buffer it
static byte header[128] = {0}; // We might have a header... this will buffer it
for(index = 0; index < 128; index++)
{
header[index] = cartridge_buffer[index];
@ -286,7 +303,7 @@ static bool _cartridge_Load(uint size)
u32 *fast_mem = (u32*)0x06860000;
memcpy(fast_mem, cartridge_buffer, (272 * 1024));
memset((u8*)0x06820000, 0x00, 0x20000); // Clear this 128K chunk of fast VRAM as we use it for RAM bankswitch
memset((u8*)0x06830000, 0x00, (64*1024)); // Clear this 128K chunk of fast VRAM as we use it for RAM bankswitch
hash_Compute(cartridge_buffer, cartridge_size, cartridge_digest);
return true;
@ -335,7 +352,7 @@ bool cartridge_Load(char *filename)
// SUPERCART Games that are 128+K in size with nothing mapped in at 0x4000
// SUPERCART_LARGE Games that are 144+K in size with the extra 16K bank 0 fixed at 0x4000
// SUPERCART_RAM Games that are 128+K in size with extra 16K of RAM at 0x4000
// SUPERCART_ROM Games that are 128+K in size with bank 6 fixed at 0x4000
// SUPERCART_ROM Games that are 128+K in size with the second-to-last bank fixed at 0x4000
//
// For the "Super Carts" the 16K at 0xC000 is the last bank in the ROM.
// For the "Super Carts" the 16K at 0x8000 is the bankswapping bank and is switched by writing
@ -349,72 +366,104 @@ bool cartridge_Load(char *filename)
// ------------------------------------------------------------------------------------------
void cartridge_Store( )
{
uint offset, lastBank;
switch(myCartInfo.cardtype)
{
case CARTRIDGE_TYPE_NORMAL:
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
break;
case CARTRIDGE_TYPE_FLAT_WITH_RAM:
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
memory_ClearROM(16384, 16384);
break;
case CARTRIDGE_TYPE_SUPERCART: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
}
} break;
case CARTRIDGE_TYPE_SUPERCART_LARGE: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(0));
}
} break;
case CARTRIDGE_TYPE_SUPERCART_RAM: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_ClearROM(16384, 16384);
}
} break;
case CARTRIDGE_TYPE_SUPERCART_RAMX2: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_ClearROM(16384, 16384);
}
} break;
case CARTRIDGE_TYPE_SUPERCART_ROM: {
uint offset = cartridge_size - 16384;
uint lastBank = (cartridge_size/16384)-1;
case CARTRIDGE_TYPE_SUPERCART:
offset = cartridge_size - 16384;
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
break;
case CARTRIDGE_TYPE_SUPERCART_LARGE:
offset = cartridge_size - 16384;
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(0));
break;
case CARTRIDGE_TYPE_SUPERCART_RAM:
offset = cartridge_size - 16384;
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_ClearROM(16384, 16384);
break;
case CARTRIDGE_TYPE_SUPERCART_RAMX2:
offset = cartridge_size - 16384;
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_ClearROM(16384, 16384);
break;
case CARTRIDGE_TYPE_SUPERCART_ROM:
offset = cartridge_size - 16384;
lastBank = (cartridge_size/16384)-1;
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(lastBank-1));
} break;
break;
case CARTRIDGE_TYPE_ABSOLUTE:
memory_WriteROM(16384, 16384, cartridge_buffer);
memory_WriteROM(32768, 32768, cartridge_buffer + cartridge_GetBankOffset(2));
break;
case CARTRIDGE_TYPE_ACTIVISION:
if(122880 < cartridge_size) {
memory_WriteROM(40960, 16384, cartridge_buffer);
memory_WriteROM(16384, 8192, cartridge_buffer + 106496);
memory_WriteROM(24576, 8192, cartridge_buffer + 98304);
memory_WriteROM(32768, 8192, cartridge_buffer + 122880);
memory_WriteROM(57344, 8192, cartridge_buffer + 114688);
memory_WriteROM(40960, 16384, cartridge_buffer);
memory_WriteROM(16384, 8192, cartridge_buffer + 106496);
memory_WriteROM(24576, 8192, cartridge_buffer + 98304);
memory_WriteROM(32768, 8192, cartridge_buffer + 122880);
memory_WriteROM(57344, 8192, cartridge_buffer + 114688);
break;
case CARTRIDGE_TYPE_FRACTALUS:
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
memory_ClearROM(0x4000, 0x4000);
break;
case CARTRIDGE_TYPE_BANKSETS:
if ((cartridge_size/2) <= (52 * 1024))
{
offset = 0;
memory_WriteROM(65536 - (cartridge_size/2), (cartridge_size/2), cartridge_buffer + offset);
memcpy(&banksets_memory[65536 - (cartridge_size/2)], cartridge_buffer + (cartridge_size/2), (cartridge_size/2));
if ((cartridge_size/2) >= (48*1024)) write_only_pokey_at_4000 = true;
}
else
{
offset = (cartridge_size/2) - 0x4000;
memory_WriteROM(0xC000, 0x4000, cartridge_buffer + offset);
memcpy(&banksets_memory[0xC000], &cartridge_buffer[cartridge_size - 0x4000], 0x4000);
}
break;
case CARTRIDGE_TYPE_FRACTALUS:
case CARTRIDGE_TYPE_BANKSETS_RAM:
case CARTRIDGE_TYPE_BANKSETS_HALTRAM:
if ((cartridge_size/2) <= (52 * 1024))
{
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
memory_ClearROM(0x4000, 0x4000);
memory_WriteROM(65536 - (cartridge_size/2), (cartridge_size/2), cartridge_buffer);
memcpy(&banksets_memory[65536 - (cartridge_size/2)], cartridge_buffer + (cartridge_size/2), (cartridge_size/2));
if ((cartridge_size/2) >= (48*1024)) write_only_pokey_at_4000 = true;
}
else
{
memory_WriteROM(0xC000, 0x4000, cartridge_buffer + (cartridge_size/2) - 0x4000);
memcpy(&banksets_memory[0xC000], cartridge_buffer + (cartridge_size) - 0x4000, 0x4000);
}
memory_ClearROM(0x4000, 0x4000);
memset(&banksets_memory[0x4000], 0x00, 0x4000);
break;
}
}
// ----------------------------------------------------------------------------
// Write
// Cart Write - this may cause a bankswitch
// ----------------------------------------------------------------------------
ITCM_CODE void cartridge_Write(word address, byte data) {
switch(myCartInfo.cardtype)
@ -429,22 +478,51 @@ ITCM_CODE void cartridge_Write(word address, byte data) {
}
else if (address == 0xFFFF) cartridge_SwapRAM_DragonFlyStyle(data); // For the Dragonfly way of RAM banking
break;
case CARTRIDGE_TYPE_SUPERCART_LARGE:
if ((address & 0xC000) == 0x8000) // Is this a bankswitching write?
{
cartridge_WriteBank(32768, data+1);
}
break;
case CARTRIDGE_TYPE_ABSOLUTE:
if(address == 32768 && (data == 1 || data == 2)) {
if(address == 32768 && (data == 1 || data == 2))
{
cartridge_WriteBank(16384, data-1);
}
break;
case CARTRIDGE_TYPE_ACTIVISION:
if(address >= 65408) {
if(address >= 65408)
{
cartridge_WriteBank(40960, (address & 7));
}
break;
case CARTRIDGE_TYPE_BANKSETS:
case CARTRIDGE_TYPE_BANKSETS_RAM:
if ((address & 0xC000) == 0x8000) // Is this a bankswitching write?
{
cartridge_WriteBank(0x8000, data);
memcpy(&banksets_memory[0x8000], &cartridge_buffer[(cartridge_size/2) + (data*0x4000)], 0x4000);
}
break;
case CARTRIDGE_TYPE_BANKSETS_HALTRAM:
if ((address & 0xC000) == 0x8000) // Is this a bankswitching write?
{
// We need to swap in the main Sally memory...
cartridge_WriteBank(0x8000, data);
// And also swap in the Maria memory... this ROM starts half-way up the main cartridge_buffer[]
memcpy(&banksets_memory[0x8000], &cartridge_buffer[(cartridge_size/2) + (data*0x4000)], 0x4000);
}
else if ((address & 0xC000) == 0xC000) // Are we writing to MARIA HALT RAM?
{
// Write the data into the 0x4000-0x7FFF region - for Sally, this is write only but will be seen by Maria
banksets_memory[0x4000 + (address & 0x3FFF)] = data;
}
break;
}
}
@ -473,15 +551,15 @@ void cartridge_Release( )
myCartInfo.hsc = false;
myCartInfo.cardctrl1 = 0;
myCartInfo.cardctrl2 = 0;
myCartInfo.steals_cycles = STEAL_CYCLE;
myCartInfo.uses_wsync = USES_WSYNC;
myCartInfo.hasHeader = false;
myCartInfo.dma_adjust = 0;
last_bank = 255;
last_ex_ram_bank = 0;
ex_ram_bank = 0;
last_ex_ram_bank_df = 0;
ex_ram_bank_df = 0;
ex_ram_bank_df = 0;
write_only_pokey_at_4000 = false;
if (isDS_LITE) shadow_ram = ex_ram_bank ? (u8*)(ex_ram_buffer+0x0000) : (u8*)(ex_ram_buffer+0x4000); // for DS-Lite
else shadow_ram = ex_ram_bank ? (u8*)0x06820000 : (u8*)0x06824000; // // Only for the DSi.. see DS_LITE handling above
else shadow_ram = ex_ram_bank ? (u8*)0x06830000 : (u8*)0x06834000; // // Only for the DSi.. see DS_LITE handling above
shadow_ram -= 0x4000; // Makes for faster indexing in Memory.c
}

View file

@ -84,6 +84,8 @@
#define CARTRIDGE_TYPE_FRACTALUS 8
#define CARTRIDGE_TYPE_FLAT_WITH_RAM 9
#define CARTRIDGE_TYPE_BANKSETS 10
#define CARTRIDGE_TYPE_BANKSETS_RAM 11
#define CARTRIDGE_TYPE_BANKSETS_HALTRAM 12
#define CT_NORMAL CARTRIDGE_TYPE_NORMAL
#define CT_SUPCAR CARTRIDGE_TYPE_SUPERCART
@ -96,6 +98,8 @@
#define CT_FRACTALUS CARTRIDGE_TYPE_FRACTALUS
#define CT_FLATWRAM CARTRIDGE_TYPE_FLAT_WITH_RAM
#define CT_BANKSETS CARTRIDGE_TYPE_BANKSETS
#define CT_BANKSRAM CARTRIDGE_TYPE_BANKSETS_RAM
#define CT_BANKSHALT CARTRIDGE_TYPE_BANKSETS_HALTRAM
extern bool cartridge_Load(char* filename);
extern void cartridge_Store( );

View file

@ -31,158 +31,158 @@ extern uint cartridge_size;
Database_Entry game_list[] = {
{"f5150c0fc1948832211e57852abb0c6e", "Utility Cart", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 220, 0}, // title=7800 Utility Cart
{"4332c24e4f3bc72e7fe1b77adf66c2b7", "3D Asteroids", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=3D Asteroids
{"0be996d25144966d5541c9eb4919b289", "Ace of Aces", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Ace Of Aces
{"877dcc97a775ed55081864b2dbf5f1e2", "Alien Brigade", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 7, 21, 264, 230, 1}, // title=Alien Brigade
{"d99bff88cd3cce191c26f5755842eb21", "Arkanoid", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 8, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"212ee2a6e66d8bb7fbf26f343cc8dc19", "Arkanoid", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 8, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"89b8b3df46733e0c4d57aeb9bb245e6f", "Armor Attack II", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 220, 0}, // title=Armor Attack II
{"a65f79ad4a0bbdecd59d5f7eb3623fd7", "Asteroids Deluxe (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 230, 0}, // title=Asteroids Deluxe
{"07342c78619ba6ffcc61c10e907e3b50", "Asteroids", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 230, 0}, // title=Asteroids
{"3d38281ed8a8d8c7cd457a18c92c8604", "Astro Blaster", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 8, 320, 210, 0}, // title=Astro Blaster
{"a51e5df28a0fe8c52e9d28fb5f8e44a6", "Astro Fighter", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 32, 8, 320, 210, 0}, // title=Astro Fighter
{"7cdfbe37634e7dcd4dc67db7edbcd3ba", "Baby Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 32, 11, 320, 221, 0}, // title=Baby Pac Man
{"8fc3a695eaea3984912d98ed4a543376", "Ballblazer", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 6, 11, 262, 220, 0}, // title=Ballblazer
{"42682415906c21c6af80e4198403ffda", "Barnyard Blaster", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Barnyard Blaster
{"f5f6b69c5eb4b55fc163158d1a6b423e", "Basketbrawl", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 1}, // title=Basketbrawl
{"78b1061d651ef806becac1dd3fda29a0", "Beef Drop", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 7, 256, 220, 0}, // title=Beef Drop (Final Atariage)
{"34483432b92f565f4ced82a141119164", "Bentley Bear", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 3, 11, 256, 220, 0}, // title=Bentley Bear's Crystal Quest
{"4e325918a8b3bbcf2f9405040abcfc6d", "Older b*nQ", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 17, 256, 220, 0}, // title=BonQ (found on Atairage Age site)
{"9fa7743a016c9b7015ee1d386326f88e", "b*nQ", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 17, 256, 220, 0}, // title=BonQ (final Atariage)
{"4a8a22cff154f479f1ddaa386f21fc39", "Boom", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 6, 256, 220, 0}, // title=Boom!
{"000b5888d2489f7e256d80a0848ecd14", "Cannon in D for Defense", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 223, 0}, // title=Cannon in D for Defense (demo 03)
{"5a09946e57dbe30408a8f253a28d07db", "Centipede", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 24, 15, 300, 230, 0}, // title=Centipede
{"20660b667df538ec32a8e1b998438604", "Frameless Centipede", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 24, 15, 300, 230, 0}, // title=Centipede - Frameless Hack
{"a4b5d742860beb25c29def4530194c1e", "Chase", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 8, 18, 269, 233, 0}, // title=Chase
{"93e4387864b014c155d7c17877990d1e", "Choplifter", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Choplifter
{"2e8e28f6ad8b9b9267d518d880c73ebb", "Commando", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 1}, // title=Commando
{"db691469128d9a4217ec7e315930b646", "Crack'ed", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 16, 256, 229, 0}, // title=Crack'ed
{"299d31c8e181fdd011df2014451bdf0f", "Crazy Brix", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 4, 256, 203, 0}, // title=Crazy Brix
{"2d2fe4da9f1bae102fa8ca2d8830a626", "Crazy Otto", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 8, 256, 232, 0}, // title=Crazy Otto
{"a94e4560b6ad053a1c24e096f1262ebf", "Crossbow", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 5, 11, 267, 231, 0}, // title=Crossbow
{"179b76ff729d4849b8f66a502398acae", "Dark Chambers", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 12, 256, 220, 0}, // title=Dark Chambers
{"95ac811c7d27af0032ba090f28c107bd", "Desert Falcon", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 6, 18, 261, 234, 0}, // title=Desert Falcon
{"731879ea82fc0ca245e39e036fe293e6", "Dig Dug", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 220, 0}, // title=Dig Dug
{"5e332fbfc1e0fc74223d2e73271ce650", "Donkey Kong Jr", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 13, 256, 220, 0}, // title=Donkey Kong Jr
{"19f1ee292a23636bd57d408b62de79c7", "Donkey Kong", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 13, 256, 220, 0}, // title=Donkey Kong
{"c3107d3e3e17d67e3a11d47a5946a4f3", "DONKEY KONG XM", CT_SUPLRG, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 210, 0}, // title=Donkey Kong XM Demo (purposely set HSC to false - game HSC is buggy)
{"543484c00ba233736bcaba2da20eeea9", "Double Dragon", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 1}, // title=Double Dragon
{"94009ccfdcd4f55d24033ca06269ba6a", "Dragon's Descent", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 15, 256, 234, 0}, // title=Dragon's Descent 1.7
{"cad9b532a4ced6793e18ba7237e44d40", "Dragon's Havoc", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 6, 14, 256, 232, 0}, // title=Dragon's Havoc
{"2a3cb324b75af461fc974b02e6b30b5d", "Dragon's Havoc", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 6, 14, 256, 232, 0}, // title=Dragon's Havoc - Newest 2022
{"a9f29004412621f20ad9f5c51cc11486", "Draker Quest II", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 15, 256, 230, 0}, // title=Draker Quest II
{"fab1290f9a4c4f2b4d831c8a57f969f5", "Draker Quest", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 230, 0}, // title=Draker Quest
{"b3143adbbb7d7d189e918e5b29d55a72", "Dungeon Stalker", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 14, 256, 220, 0}, // title=Dungeon Stalker (homebrew)
{"7099cc31cbc492d525d218efe88b8685", "xxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 230, 0}, // title=E.X.O. (Alpha)
{"faea27017447dd8bae677d91125a8135", "xxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 230, 0}, // title=E.X.O. (Beta)
{"a44e8b7b7881beb0fe3c71a1a04441c8", "EXO", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 15, 256, 234, 0}, // title=E.X.O. (RC Demo)
{"2251a6a0f3aec84cc0aff66fc9fa91e8", "F-18 Hornet", CT_ABSOLU, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=F-18 Hornet
{"6287727ab36391a62f728bbdee88675c", "Failsafe", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 257, 220, 0}, // title=Failsafe (homebrew)
{"d25d5d19188e9f149977c49eb0367cd1", "Fatal Run", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Fatal Run
{"07dbbfe612a0a28e283c01545e59f25e", "Fight Night", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Fight Night
{"cf76b00244105b8e03cdc37677ec1073", "Food Fight", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 255, 227, 0}, // title=Food Fight
{"e7d89669a7f92ec2cc99d9663a28671c", "Frenzy (w-Berzerk)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 5, 320, 206, 0}, // title=Frenzy (with Berzerk) (homebrew)
{"26031dea7251fb861cb55f86742c9d6e", "Frenzy (w-Berzerk)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 5, 320, 206, 0}, // title=Frenzy (with Berzerk) (homebrew) - Newest 2021
{"6053233cb59c0b4ca633623fd76c4576", "Froggie", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 34, 7, 320, 205, 0}, // title=Froggie (homebrew)
{"4b8f22fc4b022a7ea1b4148195b85d4a", "Frogus", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 15, 256, 224, 0}, // title=Frogus
{"fb8d803b328b2e442548f7799cfa9a4a", "Galaga", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 229, 0}, // title=Galaga
{"2f4ae1015a345652b36004a8c62a4ac6", "Galaxian", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 14, 4, 282, 200, 0}, // title=Galaxian
{"06204dadc975be5e5e37e7cc66f984cf", "Gato", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Gato
{"e443f7fb5be3283dd44c0f5d80c3a7b3", "GoSub", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 13, 11, 280, 234, 0}, // title=GoSub
{"1e21bf1d9d7b3c0cebaac576964c9eb2", "Graze Suit Alpha", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 10, 256, 220, 1}, // title=Graze Suit Alpha
{"fd9e78e201b6baafddfd3e1fbfe6ba31", "Hat Trick", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 16, 256, 227, 0}, // title=Hat Trick
{"c3672482ca93f70eafd9134b936c3feb", "Ikari Warriors", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 16, 256, 230, 0}, // title=Ikari Warriors
{"baebc9246c087e893dfa489632157180", "Impossible Mission", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Impossible Mission
{"1745feadabb24e7cefc375904c73fa4c", "Alternate Impossible Mission", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Impossible Mission
{"045fd12050b7f2b842d5970f2414e912", "Jinks", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 3, 11, 261, 234, 0}, // title=Jinks
{"f18b3b897a25ab3885b43b4bd141b396", "Joust", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 234, 0}, // title=Joust
{"e54edc299e72d22d0ba05d16f3393e8c", "Jr. Pac-Man (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 4, 13, 268, 234, 0}, // title=Jr Pac-Man
{"c3a5a8692a423d43d9d28dd5b7d109d9", "Karateka", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Karateka
{"6b8600aabd11f834448e910801f4e0bc", "KC Munchkin", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 3, 11, 256, 225, 0}, // title=KC Munchkin
{"2d8fc6f9d3f5a6ca99d13c601f9adbb9", "Keystone", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 220, 0}, // title=Keystone_Koppers_RC4_demo.a78
{"17b3b764d33eae9b5260f01df7bb9d2f", "Klax", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 19, 256, 234, 0}, // title=Klax (fixed)
{"5fb805f2b69820a9b196f5fed2a23c99", "Klax", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 19, 256, 234, 0}, // title=Klax
{"1d47c3802135d864dc1d922ec27aa708", "Knight Guy On Board", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 233, 0}, // title=Knight Guy On Board - 30 Squares Of Fate
{"f57d0af323d4e173fb49ed447f0563d7", "Kung Fu Master", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 22, 16, 276, 225, 0}, // title=Kung Fu Master
{"fe657a1b8a34b2c0e1d2171166d40926", "Legend of Silverpeak", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 6, 256, 201, 1}, // title=Legend of Silverpeak
{"431ca060201ee1f9eb49d44962874049", "Mario", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 13, 256, 220, 0}, // title=Mario Bros.
{"37b5692e33a98115e574185fa8398c22", "Mat Mania Challenge", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Mat Mania Challenge
{"f2f5e5841e4dda89a2faf8933dc33ea6", "Mean 18 Ultimate Golf", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Mean 18 Ultimate Golf
{"bedc30ec43587e0c98fc38c39c1ef9d0", "Meltdown", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Meltdown
{"c3f6201d6a9388e860328c963a3301cc", "Meteor Shower", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 12, 256, 220, 0}, // title=Meteor Shower
{"bc1e905db1008493a9632aa83ab4682b", "Midnight Mutants", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 12, 256, 226, 1}, // title=Midnight Mutants
{"6afb86a5d2d890fba68169f136d41b79", "Millie and Molly", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 13, 256, 220, 0}, // title=Millie and Molly (Demo)
{"017066f522908081ec3ee624f5e4a8aa", "Missing in Action", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, SKIP_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Missing in Action
{"181a9978d9da7a7e21f770808cc681f2", "Merlain", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 320, 234, 0}, // title=Merlain
{"5fe8ef9e368acd5699e5a453082b7636", "Morf", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 16, 256, 224, 0}, // title=Morf
{"1c860298a8966cc8e176ab8453b172c3", "Monster Maze", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 13, 256, 220, 0}, // title=Monster Maze
{"9ff38ea62004201d870caa8bd9463525", "Moon Cresta (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 4, 320, 210, 0}, // title=Moon Cresta
{"3bc8f554cf86f8132a623cc2201a564b", "Motor Psycho", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 1}, // title=Motor Psycho
{"fc0ea52a9fac557251b65ee680d951e5", "Ms. Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 224, 0}, // title=Ms. Pac-Man
{"cf007563fe94cacf5ea5295dc93ce9ef", "Ms. Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 8, 256, 217, 0}, // title=Ms. Pac-Man (Bob's Enhancements)
{"2a17dc5a61be342dd00af719cc335852", "Ms Pac-Man 320", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 5, 15, 265, 230, 0}, // title=Ms Pac-Man 320
{"220121f771fc4b98cef97dc040e8d378", "Ninja Golf", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 10, 19, 270, 234, 1}, // title=Ninja Golf
{"74569571a208f8b0b1ccfb22d7c914e1", "One On One", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 224, 0}, // title=One On One
{"60982f430b762343d53e48f70acfa6d0", "Pac-Man 320", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 6, 16, 264, 233, 0}, // title=Pac-Man 320
{"5013b69cb05b21a1194ce48517df7bfc", "Pac-Man Collection", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 10, 10, 281, 231, 0}, // title=Pac-Man Collection (homebrew)
{"f2512870a8abc82df42b2721f8c9e7af", "Pac-Man 40th Anniversary", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 9, 9, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Newest
{"a59d362e3a391ff1482131aa0818ad3e", "Pac-Man 40th Anniversary", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 9, 9, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Older
{"1330d23ebad9b5ded92ebeacdf305abd", "Pac-Man 40th Anniversary", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 9, 9, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - PMC_XM Newest
{"2b60de20a55056a11e6412a22445296f", "Pac-Man XM-S", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 11, 16, 279, 233, 0}, // title=Pac-Man Collection 40th - Short Mazes (2022) - Newest
{"c80edcd555cd3d81f664e5f02826dc26", "Pac-Man XM-S", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 11, 16, 279, 233, 0}, // title=Pac-Man Collection 40th - Short Mazes (2022)
{"d0bf3b841ad4bbd356e9588874749a13", "Pac-Man Plus 320", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 10, 11, 274, 233, 0}, // title=Pac-Man Plus 320
{"1a5207870dec6fae9111cb747e20d8e3", "Pete Rose Baseball", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Pete Rose Baseball
{"ec206c8db4316eb1ebce9fc960da7d8f", "Pit Fighter", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Pit Fighter
{"33aea1e2b6634a1dec8c7006d9afda22", "Planet Smashers", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 14, 256, 226, 0}, // title=Planet Smashers
{"74f0283c566bdee8543e4fdc5cb8b201", "Plutos XM", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 16, 256, 234, 0}, // title=Plutos XM
{"86546808dc60961cdb1b20e761c50ab1", "Plutos", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 16, 256, 234, 0}, // title=Plutos (non-XM)
{"584582bb09ee8122e7fc09dc7d1ed813", "Pole Position II", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 35, 11, 320, 230, 0}, // title=Pole Position II
{"1745feadabb24e7cefc375904c73fa4c", "Possible Mission", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Possible Mission
{"0710aa2620435230da6a7cf3f620210d", "Demo 2.7f Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 9, 256, 210, 0}, // title=Popeye Demo 2.7f (homebrew)
{"81187dbc08934214bd55187d4b8149dd", "Demo 2.8 Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 9, 256, 210, 0}, // title=Popeye Demo 2.8 (homebrew)
{"640c7827fe63082efbaffc13f7983744", "Demo 2.9 Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 9, 256, 210, 0}, // title=Popeye Demo 2.9 (homebrew)
{"631262731c193928d01365d2bc31b64f", "Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 9, 256, 210, 0}, // title=Popeye Demo 1.0RC
{"ac03806cef2558fc795a7d5d8dba7bc0", "Rampage", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Rampage
{"383ed9bd1efb9b6cb3388a777678c928", "Realsports Baseball", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 1}, // title=Realsports Baseball
{"130b1a3792c65dfe107d7a49592449ed", "Realsports Baseball", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 1}, // title=Realsports Baseball
{"8f7eb10ad0bd75474abf0c6c36c08486", "Rescue On Fractalus", CT_FRACTALUS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Rescue On Fractalus
{"43525a0405184875c2ecfd0196886a34", "Rip-Off", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 16, 256, 233, 0}, // title=Rip-Off
{"66ecaafe1b82ae68ffc96267aaf7a4d7", "Robotron", CT_NORMAL, POKEY_NONE, TWIN,TWIN, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 5, 11, 270, 234, 0}, // title=Robotron
{"b6561537290e6e25e1249394366c3c63", "Robbo", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Robbo
{"fc525819ec2bdc4a30bb2e55524f8d81", "Robot's Rumble", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 10, 256, 217, 0}, // title=Robot's Rumble (2022)
{"a3a85e507d6f718972b1464ce1aaf8a4", "Scramble", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 4, 320, 205, 0}, // title=Scramble (homebrew)
{"980c35ae9625773a450aa7ef51751c04", "Scrapyard Dog", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 1}, // title=Scrapyard Dog
{"b697d9c2d1b9f6cb21041286d1bbfa7f", "Sentinel", CT_SUPROM, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Sentinel
{"9bd70c06d3386f76f8162881699a777a", "Serpentine", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 220, 0}, // title=Serpentine (homebrew)
{"96f69b85e0b43bbebbbd59bb8276a372", "Sick Pickles", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 233, 0}, // title=Sick Pickles
{"771cb4609347657f63e6f0eb26036e35", "Space Duel", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 11, 256, 220, 0}, // title=Space Duel (homebrew)
{"6adf79558a3d7f5beca1bb8d34337417", "Space Invaders", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 7, 320, 210, 0}, // title=Space Invaders (Homebrew)
{"19844117863cd38d4e1e4cbc867ae599", "Spire of the Ancients", CT_SUPLRG, POKEY_NONE, SOTA,SOTA, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 31, 16, 320, 230, 1}, // title=Spire of the Ancients
{"19844117863cd38d4e1e4cbc867ae599", "SotA", CT_SUPLRG, POKEY_NONE, SOTA,SOTA, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 31, 16, 320, 230, 1}, // title=Spire of the Ancients
{"cbb0746192540a13b4c7775c7ce2021f", "Summer Games", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 12, 256, 220, 0}, // title=Summer Games
{"81cee326b99d6831de10a566e338bd25", "Super Circus AA-NTSC-joy-4000", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 12, 256, 220, 0}, // title=Super Circus Atariage (Pokey 4000)
{"cc18e3b37a507c4217eb6cb1de8c8538", "Super Huey UH-IX", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Super Huey UH-IX
{"7ab539bb0e99e1e5a1c89230bde64610", "Super Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 4, 256, 225, 0}, // title=Super Pac-Man
{"59b5793bece1c80f77b55d60fb39cb94", "Super Skatebordin'", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Super Skatebordin'
{"44f862bca77d68b56b32534eda5c198d", "Tank Command", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Tank Command
{"1af475ff6429a160752b592f0f92b287", "Title Match Pro Wrestling", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Title Match Pro Wrestling
{"a60e4b608505d1fb201703b266f754a7", "Time Salvo", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 15, 256, 230, 0}, // title=Time Salvo
{"c3903ab01a51222a52197dbfe6538ecf", "Tomcat F-14 Simulator", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Tomcat F-14 Simulator
{"208ef955fa90a29815eb097bce89bace", "Touchdown Football", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Touchdown Football
{"8d64763db3100aadc552db5e6868506a", "Tower Toppler", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 7, 256, 230, 0}, // title=Tower Toppler
{"79df20ee86a989e669158bcb9d113e8a", "UniWarS", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 9, 4, 282, 200, 0}, // title=UniWarS
{"acf63758ecf3f3dd03e9d654ae6b69b7", "Water Ski", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 2, 256, 197, 0}, // title=Water Ski
{"427cb05d0a1abb068998e2760d77f4fb", "Water Ski", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 2, 256, 197, 0}, // title=Water Ski
{"3799d72f78dda2ee87b0ef8bf7b91186", "Winter Games", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 11, 256, 220, 0}, // title=Winter Games
{"846751861993b907c512cc9c10c67035", "Wizards Dungeon", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 17, 256, 224, 0}, // title=Wizards Dungeon
{"05fb699db9eef564e2fe45c568746dbc", "Xenophobe", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 15, 11, 284, 234, 0}, // title=Xenophobe
{"d7dc17379aa25e5ae3c14b9e780c6f6d", "Xevious", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 15, 256, 220, 0}, // title=Xevious
{"d7dc17379aa25e5ae3c14b9e780c6f6d", "Xevious X", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 15, 256, 220, 0}, // title=Xevious X
{"e1b290ee690c0cd6525773a2025177d5", "1942", CT_SUPRAMX2,POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 5, 256, 203, 1}, // title=1942 (Standard Banking RAM)
{"0fec9c1f5973c7a1dc55318ec97d8d17", "1942", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 5, 256, 203, 1}, // title=1942 (Dragonfly Banking RAM)
{"f5150c0fc1948832211e57852abb0c6e", "Utility Cart", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=7800 Utility Cart
{"4332c24e4f3bc72e7fe1b77adf66c2b7", "3D Asteroids", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=3D Asteroids
{"0be996d25144966d5541c9eb4919b289", "Ace of Aces", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Ace Of Aces
{"877dcc97a775ed55081864b2dbf5f1e2", "Alien Brigade", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 7, 22, 264, 230, 1}, // title=Alien Brigade
{"d99bff88cd3cce191c26f5755842eb21", "Arkanoid", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"212ee2a6e66d8bb7fbf26f343cc8dc19", "Arkanoid", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"89b8b3df46733e0c4d57aeb9bb245e6f", "Armor Attack II", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=Armor Attack II
{"a65f79ad4a0bbdecd59d5f7eb3623fd7", "Asteroids Deluxe (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 230, 0}, // title=Asteroids Deluxe
{"07342c78619ba6ffcc61c10e907e3b50", "Asteroids", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 230, 0}, // title=Asteroids
{"3d38281ed8a8d8c7cd457a18c92c8604", "Astro Blaster", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 0, 30, 9, 320, 210, 0}, // title=Astro Blaster
{"a51e5df28a0fe8c52e9d28fb5f8e44a6", "Astro Fighter", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 32, 9, 320, 210, 0}, // title=Astro Fighter
{"7cdfbe37634e7dcd4dc67db7edbcd3ba", "Baby Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 32, 12, 320, 221, 0}, // title=Baby Pac Man
{"8fc3a695eaea3984912d98ed4a543376", "Ballblazer", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 6, 12, 262, 220, 0}, // title=Ballblazer
{"42682415906c21c6af80e4198403ffda", "Barnyard Blaster", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Barnyard Blaster
{"f5f6b69c5eb4b55fc163158d1a6b423e", "Basketbrawl", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 1}, // title=Basketbrawl
{"78b1061d651ef806becac1dd3fda29a0", "Beef Drop", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 8, 256, 220, 0}, // title=Beef Drop (Final Atariage)
{"34483432b92f565f4ced82a141119164", "Bentley Bear", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 3, 14, 256, 220, 0}, // title=Bentley Bear's Crystal Quest
{"4e325918a8b3bbcf2f9405040abcfc6d", "Older b*nQ", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 18, 256, 220, 0}, // title=BonQ (found on Atairage Age site)
{"9fa7743a016c9b7015ee1d386326f88e", "b*nQ", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 18, 256, 220, 0}, // title=BonQ (final Atariage)
{"4a8a22cff154f479f1ddaa386f21fc39", "Boom", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 7, 256, 220, 0}, // title=Boom!
{"000b5888d2489f7e256d80a0848ecd14", "Cannon in D for Defense", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 223, 0}, // title=Cannon in D for Defense (demo 03)
{"5a09946e57dbe30408a8f253a28d07db", "Centipede", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 24, 16, 300, 230, 0}, // title=Centipede
{"20660b667df538ec32a8e1b998438604", "Frameless Centipede", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 24, 16, 300, 230, 0}, // title=Centipede - Frameless Hack
{"a4b5d742860beb25c29def4530194c1e", "Chase", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 8, 19, 269, 233, 0}, // title=Chase
{"93e4387864b014c155d7c17877990d1e", "Choplifter", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Choplifter
{"2e8e28f6ad8b9b9267d518d880c73ebb", "Commando", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 1}, // title=Commando
{"db691469128d9a4217ec7e315930b646", "Crack'ed", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 18, 256, 229, 0}, // title=Crack'ed
{"299d31c8e181fdd011df2014451bdf0f", "Crazy Brix", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 5, 256, 203, 0}, // title=Crazy Brix
{"2d2fe4da9f1bae102fa8ca2d8830a626", "Crazy Otto", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 9, 256, 232, 0}, // title=Crazy Otto
{"a94e4560b6ad053a1c24e096f1262ebf", "Crossbow", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 5, 12, 267, 231, 0}, // title=Crossbow
{"179b76ff729d4849b8f66a502398acae", "Dark Chambers", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 13, 256, 219, 0}, // title=Dark Chambers
{"95ac811c7d27af0032ba090f28c107bd", "Desert Falcon", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 6, 19, 261, 234, 0}, // title=Desert Falcon
{"731879ea82fc0ca245e39e036fe293e6", "Dig Dug", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=Dig Dug
{"5e332fbfc1e0fc74223d2e73271ce650", "Donkey Kong Jr", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 14, 256, 220, 0}, // title=Donkey Kong Jr
{"19f1ee292a23636bd57d408b62de79c7", "Donkey Kong", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 14, 256, 220, 0}, // title=Donkey Kong
{"c3107d3e3e17d67e3a11d47a5946a4f3", "DONKEY KONG XM", CT_SUPLRG, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 210, 0}, // title=Donkey Kong XM Demo (purposely set HSC to false - game HSC is buggy)
{"543484c00ba233736bcaba2da20eeea9", "Double Dragon", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 1}, // title=Double Dragon
{"94009ccfdcd4f55d24033ca06269ba6a", "Dragon's Descent", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 16, 256, 234, 0}, // title=Dragon's Descent 1.7
{"cad9b532a4ced6793e18ba7237e44d40", "Dragon's Havoc", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 6, 15, 256, 232, 0}, // title=Dragon's Havoc
{"2a3cb324b75af461fc974b02e6b30b5d", "Dragon's Havoc", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 6, 15, 256, 232, 0}, // title=Dragon's Havoc - Newest 2022
{"a9f29004412621f20ad9f5c51cc11486", "Draker Quest II", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 16, 256, 230, 0}, // title=Draker Quest II
{"fab1290f9a4c4f2b4d831c8a57f969f5", "Draker Quest", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 230, 0}, // title=Draker Quest
{"b3143adbbb7d7d189e918e5b29d55a72", "Dungeon Stalker", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 15, 256, 220, 0}, // title=Dungeon Stalker (homebrew)
{"7099cc31cbc492d525d218efe88b8685", "xxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 230, 0}, // title=E.X.O. (Alpha)
{"faea27017447dd8bae677d91125a8135", "xxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 230, 0}, // title=E.X.O. (Beta)
{"a44e8b7b7881beb0fe3c71a1a04441c8", "EXO", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 16, 256, 234, 0}, // title=E.X.O. (RC Demo)
{"2251a6a0f3aec84cc0aff66fc9fa91e8", "F-18 Hornet", CT_ABSOLU, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=F-18 Hornet
{"6287727ab36391a62f728bbdee88675c", "Failsafe", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 14, 257, 220, 0}, // title=Failsafe (homebrew)
{"d25d5d19188e9f149977c49eb0367cd1", "Fatal Run", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Fatal Run
{"07dbbfe612a0a28e283c01545e59f25e", "Fight Night", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Fight Night
{"cf76b00244105b8e03cdc37677ec1073", "Food Fight", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 255, 227, 0}, // title=Food Fight
{"e7d89669a7f92ec2cc99d9663a28671c", "Frenzy (w-Berzerk)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, -2, 30, 6, 320, 206, 0}, // title=Frenzy (with Berzerk) (homebrew)
{"26031dea7251fb861cb55f86742c9d6e", "Frenzy (w-Berzerk)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, -2, 30, 6, 320, 206, 0}, // title=Frenzy (with Berzerk) (homebrew) - Newest 2021
{"6053233cb59c0b4ca633623fd76c4576", "Froggie", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 34, 8, 320, 205, 0}, // title=Froggie (homebrew)
{"4b8f22fc4b022a7ea1b4148195b85d4a", "Frogus", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 16, 256, 224, 0}, // title=Frogus
{"fb8d803b328b2e442548f7799cfa9a4a", "Galaga", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 229, 0}, // title=Galaga
{"2f4ae1015a345652b36004a8c62a4ac6", "Galaxian", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 14, 5, 282, 200, 0}, // title=Galaxian
{"06204dadc975be5e5e37e7cc66f984cf", "Gato", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Gato
{"e443f7fb5be3283dd44c0f5d80c3a7b3", "GoSub", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 13, 12, 280, 234, 0}, // title=GoSub
{"1e21bf1d9d7b3c0cebaac576964c9eb2", "Graze Suit Alpha", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 11, 256, 220, 1}, // title=Graze Suit Alpha
{"fd9e78e201b6baafddfd3e1fbfe6ba31", "Hat Trick", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 17, 256, 227, 0}, // title=Hat Trick
{"c3672482ca93f70eafd9134b936c3feb", "Ikari Warriors", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 17, 256, 230, 0}, // title=Ikari Warriors
{"baebc9246c087e893dfa489632157180", "Impossible Mission", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Impossible Mission
{"1745feadabb24e7cefc375904c73fa4c", "Alternate Impossible Mission", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Impossible Mission
{"045fd12050b7f2b842d5970f2414e912", "Jinks", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 3, 12, 261, 234, 0}, // title=Jinks
{"f18b3b897a25ab3885b43b4bd141b396", "Joust", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 234, 0}, // title=Joust
{"e54edc299e72d22d0ba05d16f3393e8c", "Jr. Pac-Man (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 4, 14, 268, 234, 0}, // title=Jr Pac-Man
{"c3a5a8692a423d43d9d28dd5b7d109d9", "Karateka", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Karateka
{"6b8600aabd11f834448e910801f4e0bc", "KC Munchkin", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 3, 12, 256, 225, 0}, // title=KC Munchkin
{"2d8fc6f9d3f5a6ca99d13c601f9adbb9", "Keystone", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=Keystone_Koppers_RC4_demo.a78
{"17b3b764d33eae9b5260f01df7bb9d2f", "Klax", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 20, 256, 234, 0}, // title=Klax (fixed)
{"5fb805f2b69820a9b196f5fed2a23c99", "Klax", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 20, 256, 234, 0}, // title=Klax
{"1d47c3802135d864dc1d922ec27aa708", "Knight Guy On Board", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 0, 0, 12, 256, 233, 0}, // title=Knight Guy On Board - 30 Squares Of Fate
{"f57d0af323d4e173fb49ed447f0563d7", "Kung Fu Master", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 22, 17, 276, 225, 0}, // title=Kung Fu Master
{"fe657a1b8a34b2c0e1d2171166d40926", "Legend of Silverpeak", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 7, 256, 201, 1}, // title=Legend of Silverpeak
{"431ca060201ee1f9eb49d44962874049", "Mario", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 14, 256, 220, 0}, // title=Mario Bros.
{"37b5692e33a98115e574185fa8398c22", "Mat Mania Challenge", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Mat Mania Challenge
{"f2f5e5841e4dda89a2faf8933dc33ea6", "Mean 18 Ultimate Golf", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Mean 18 Ultimate Golf
{"bedc30ec43587e0c98fc38c39c1ef9d0", "Meltdown", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Meltdown
{"c3f6201d6a9388e860328c963a3301cc", "Meteor Shower", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 13, 256, 220, 0}, // title=Meteor Shower
{"bc1e905db1008493a9632aa83ab4682b", "Midnight Mutants", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 13, 256, 226, 1}, // title=Midnight Mutants
{"6afb86a5d2d890fba68169f136d41b79", "Millie and Molly", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 14, 256, 220, 0}, // title=Millie and Molly (Demo)
{"017066f522908081ec3ee624f5e4a8aa", "Missing in Action", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Missing in Action
{"181a9978d9da7a7e21f770808cc681f2", "Merlain", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 320, 234, 0}, // title=Merlain
{"5fe8ef9e368acd5699e5a453082b7636", "Morf", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 17, 256, 224, 0}, // title=Morf
{"1c860298a8966cc8e176ab8453b172c3", "Monster Maze", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 14, 256, 220, 0}, // title=Monster Maze
{"9ff38ea62004201d870caa8bd9463525", "Moon Cresta (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 30, 5, 320, 210, 0}, // title=Moon Cresta
{"3bc8f554cf86f8132a623cc2201a564b", "Motor Psycho", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 1}, // title=Motor Psycho
{"fc0ea52a9fac557251b65ee680d951e5", "Ms. Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 224, 0}, // title=Ms. Pac-Man
{"cf007563fe94cacf5ea5295dc93ce9ef", "Ms. Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 9, 256, 217, 0}, // title=Ms. Pac-Man (Bob's Enhancements)
{"2a17dc5a61be342dd00af719cc335852", "Ms Pac-Man 320", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 5, 16, 265, 230, 0}, // title=Ms Pac-Man 320
{"220121f771fc4b98cef97dc040e8d378", "Ninja Golf", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 10, 20, 270, 234, 1}, // title=Ninja Golf
{"74569571a208f8b0b1ccfb22d7c914e1", "One On One", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 224, 0}, // title=One On One
{"60982f430b762343d53e48f70acfa6d0", "Pac-Man 320", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 6, 17, 264, 233, 0}, // title=Pac-Man 320
{"5013b69cb05b21a1194ce48517df7bfc", "Pac-Man Collection", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 0, 10, 11, 281, 231, 0}, // title=Pac-Man Collection (homebrew)
{"f2512870a8abc82df42b2721f8c9e7af", "Pac-Man 40th Anniversary", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 9, 10, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Newest
{"a59d362e3a391ff1482131aa0818ad3e", "Pac-Man 40th Anniversary", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 9, 10, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Older
{"1330d23ebad9b5ded92ebeacdf305abd", "Pac-Man 40th Anniversary", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 9, 10, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - PMC_XM Newest
{"2b60de20a55056a11e6412a22445296f", "Pac-Man XM-S", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 11, 17, 279, 233, 0}, // title=Pac-Man Collection 40th - Short Mazes (2022) - Newest
{"c80edcd555cd3d81f664e5f02826dc26", "Pac-Man XM-S", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 11, 17, 279, 233, 0}, // title=Pac-Man Collection 40th - Short Mazes (2022)
{"d0bf3b841ad4bbd356e9588874749a13", "Pac-Man Plus 320", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 10, 12, 274, 233, 0}, // title=Pac-Man Plus 320
{"1a5207870dec6fae9111cb747e20d8e3", "Pete Rose Baseball", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Pete Rose Baseball
{"ec206c8db4316eb1ebce9fc960da7d8f", "Pit Fighter", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Pit Fighter
{"33aea1e2b6634a1dec8c7006d9afda22", "Planet Smashers", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 15, 256, 226, 0}, // title=Planet Smashers
{"74f0283c566bdee8543e4fdc5cb8b201", "Plutos XM", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 0, 0, 17, 256, 234, 0}, // title=Plutos XM
{"86546808dc60961cdb1b20e761c50ab1", "Plutos", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 0, 0, 17, 256, 234, 0}, // title=Plutos (non-XM)
{"584582bb09ee8122e7fc09dc7d1ed813", "Pole Position II", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 35, 12, 320, 230, 0}, // title=Pole Position II
{"1745feadabb24e7cefc375904c73fa4c", "Possible Mission", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Possible Mission
{"0710aa2620435230da6a7cf3f620210d", "Demo 2.7f Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 10, 256, 210, 0}, // title=Popeye Demo 2.7f (homebrew)
{"81187dbc08934214bd55187d4b8149dd", "Demo 2.8 Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 10, 256, 210, 0}, // title=Popeye Demo 2.8 (homebrew)
{"640c7827fe63082efbaffc13f7983744", "Demo 2.9 Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 10, 256, 210, 0}, // title=Popeye Demo 2.9 (homebrew)
{"631262731c193928d01365d2bc31b64f", "Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 10, 256, 210, 0}, // title=Popeye Demo 1.0RC
{"ac03806cef2558fc795a7d5d8dba7bc0", "Rampage", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Rampage
{"383ed9bd1efb9b6cb3388a777678c928", "Realsports Baseball", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 1}, // title=Realsports Baseball
{"130b1a3792c65dfe107d7a49592449ed", "Realsports Baseball", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 1}, // title=Realsports Baseball
{"8f7eb10ad0bd75474abf0c6c36c08486", "Rescue On Fractalus", CT_FRACTALUS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Rescue On Fractalus
{"43525a0405184875c2ecfd0196886a34", "Rip-Off", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 233, 0}, // title=Rip-Off
{"66ecaafe1b82ae68ffc96267aaf7a4d7", "Robotron", CT_NORMAL, POKEY_NONE, TWIN,TWIN, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 5, 13, 270, 234, 0}, // title=Robotron
{"b6561537290e6e25e1249394366c3c63", "Robbo", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Robbo
{"fc525819ec2bdc4a30bb2e55524f8d81", "Robot's Rumble", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 11, 256, 217, 0}, // title=Robot's Rumble (2022)
{"a3a85e507d6f718972b1464ce1aaf8a4", "Scramble", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 30, 5, 320, 205, 0}, // title=Scramble (homebrew)
{"980c35ae9625773a450aa7ef51751c04", "Scrapyard Dog", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 1}, // title=Scrapyard Dog
{"b697d9c2d1b9f6cb21041286d1bbfa7f", "Sentinel", CT_SUPROM, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Sentinel
{"9bd70c06d3386f76f8162881699a777a", "Serpentine", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=Serpentine (homebrew)
{"96f69b85e0b43bbebbbd59bb8276a372", "Sick Pickles", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 233, 0}, // title=Sick Pickles
{"771cb4609347657f63e6f0eb26036e35", "Space Duel", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=Space Duel (homebrew)
{"6adf79558a3d7f5beca1bb8d34337417", "Space Invaders", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 30, 8, 320, 210, 0}, // title=Space Invaders (Homebrew)
{"19844117863cd38d4e1e4cbc867ae599", "Spire of the Ancients", CT_SUPLRG, POKEY_NONE, SOTA,SOTA, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 31, 17, 320, 230, 1}, // title=Spire of the Ancients
{"19844117863cd38d4e1e4cbc867ae599", "SotA", CT_SUPLRG, POKEY_NONE, SOTA,SOTA, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 31, 17, 320, 230, 1}, // title=Spire of the Ancients
{"cbb0746192540a13b4c7775c7ce2021f", "Summer Games", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 13, 256, 220, 0}, // title=Summer Games
{"81cee326b99d6831de10a566e338bd25", "Super Circus AA-NTSC-joy-4000", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 13, 256, 220, 0}, // title=Super Circus Atariage (Pokey 4000)
{"cc18e3b37a507c4217eb6cb1de8c8538", "Super Huey UH-IX", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Super Huey UH-IX
{"7ab539bb0e99e1e5a1c89230bde64610", "Super Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 5, 256, 225, 0}, // title=Super Pac-Man
{"59b5793bece1c80f77b55d60fb39cb94", "Super Skatebordin'", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Super Skatebordin'
{"44f862bca77d68b56b32534eda5c198d", "Tank Command", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Tank Command
{"1af475ff6429a160752b592f0f92b287", "Title Match Pro Wrestling", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Title Match Pro Wrestling
{"a60e4b608505d1fb201703b266f754a7", "Time Salvo", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 16, 256, 230, 0}, // title=Time Salvo
{"c3903ab01a51222a52197dbfe6538ecf", "Tomcat F-14 Simulator", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Tomcat F-14 Simulator
{"208ef955fa90a29815eb097bce89bace", "Touchdown Football", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Touchdown Football
{"8d64763db3100aadc552db5e6868506a", "Tower Toppler", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 8, 256, 230, 0}, // title=Tower Toppler
{"79df20ee86a989e669158bcb9d113e8a", "UniWarS", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 9, 5, 282, 200, 0}, // title=UniWarS
{"acf63758ecf3f3dd03e9d654ae6b69b7", "Water Ski", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 3, 256, 197, 0}, // title=Water Ski
{"427cb05d0a1abb068998e2760d77f4fb", "Water Ski", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 3, 256, 197, 0}, // title=Water Ski
{"3799d72f78dda2ee87b0ef8bf7b91186", "Winter Games", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 13, 256, 220, 0}, // title=Winter Games
{"846751861993b907c512cc9c10c67035", "Wizards Dungeon", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 18, 256, 224, 0}, // title=Wizards Dungeon
{"05fb699db9eef564e2fe45c568746dbc", "Xenophobe", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 15, 13, 284, 234, 0}, // title=Xenophobe
{"d7dc17379aa25e5ae3c14b9e780c6f6d", "Xevious", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 16, 256, 220, 0}, // title=Xevious
{"d7dc17379aa25e5ae3c14b9e780c6f6d", "Xevious X", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 16, 256, 220, 0}, // title=Xevious X
{"e1b290ee690c0cd6525773a2025177d5", "1942", CT_SUPRAMX2,POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 6, 256, 203, 1}, // title=1942 (Standard Banking RAM)
{"0fec9c1f5973c7a1dc55318ec97d8d17", "1942", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 6, 256, 203, 1}, // title=1942 (Dragonfly Banking RAM)
{"","",CT_NORMAL,0,0,0,0,0,0,0,0,0,0},
{"","",CT_NORMAL,0,0,0,0,0,0,0,0,0,0,0},
};
@ -268,12 +268,12 @@ bool database_Load(byte *digest)
myCartInfo.yScale = 220;
myCartInfo.diff1 = DIFF_A;
myCartInfo.diff2 = DIFF_A;
myCartInfo.steals_cycles = STEAL_CYCLE;
myCartInfo.uses_wsync = USES_WSYNC;
myCartInfo.spare1 = 0;
myCartInfo.spare2 = 0;
myCartInfo.spare3 = 0;
myCartInfo.spare4 = 1;
myCartInfo.spare4 = 1;
myCartInfo.spare16 = 0x0000;
myCartInfo.dma_adjust = 0;
// -------------------------------------------------------------------
// If the game has no .a78 header, do our best to guess these...

View file

@ -37,19 +37,19 @@ typedef struct {
u8 diff1;
u8 diff2;
u8 region;
u8 steals_cycles;
u8 uses_wsync;
u8 hsc;
short xOffset;
short yOffset;
short xScale;
short yScale;
s16 dma_adjust;
s16 xOffset;
s16 yOffset;
s16 xScale;
s16 yScale;
u8 frameSkip;
u8 hasHeader;
u8 spare1;
u8 spare2;
u8 spare3;
u8 spare4;
s16 spare16;
} Database_Entry;

View file

@ -26,6 +26,7 @@
#include "Maria.h"
#include "ProSystem.h"
#include "Database.h"
extern uint bRenderFrame;
@ -70,11 +71,68 @@ word *framePtr __attribute__((section(".dtcm"))) = (word *)0;
u32 color_lookup_160AB[256][256];
byte color_lookup_320AC[256] __attribute__((section(".dtcm")));
u32 maria_charbase __attribute__((section(".dtcm")));
u16 banksets_mask __attribute__((section(".dtcm"))) = 0x0000;
void mariabank_RenderScanlineTOP(void);
void mariabank_RenderScanline(void);
extern u32 bg32;
// ----------------------------------------------------------------------------
//ClearCells - 4 bytes at a time
// Reset
// ----------------------------------------------------------------------------
void maria_Reset( ) {
maria_surface = bufVideo;
maria_scanline = 1;
memset(maria_surface, 0, MARIA_SURFACE_SIZE);
// These values need to be reset to allow switching between carts.
// This appears to be a bug in the ProSystem emulator.
//
maria_cycles = 0;
maria_dpp.w = 0;
maria_dp.w = 0;
maria_pp.w = 0;
maria_horizontal = 0;
maria_palette = 0;
maria_offset = 0;
maria_h08 = 0;
maria_h16 = 0;
maria_h8_h16 = 0x0000;
maria_wmode = 0;
bg32 = 0x00000000;
bg8=0x00;
maria_charbase = 0;
banksets_mask = 0x0000;
if ((myCartInfo.cardtype == CARTRIDGE_TYPE_BANKSETS) || (myCartInfo.cardtype == CARTRIDGE_TYPE_BANKSETS_RAM)) banksets_mask = 0x8000;
if ((myCartInfo.cardtype == CARTRIDGE_TYPE_BANKSETS_HALTRAM)) banksets_mask = 0xC000;
// ----------------------------------------------------------------------------------
// Build the 160 A/B color lookup table for a few frames of increased performance
// ----------------------------------------------------------------------------------
for (uint color=0; color<256; color++)
{
for (uint color1=0; color1<256; color1++)
{
color_lookup_160AB[color][color1] = color | (color<<8) | (color1<<16) | (color1<<24);
}
color_lookup_320AC[color] = (color & 28) | ((color & 1) << 1);
}
}
// ----------------------------------------------------------------------------
// Clear
// ----------------------------------------------------------------------------
void maria_Clear( )
{
maria_surface = bufVideo;
memset(maria_surface, 0x00, MARIA_SURFACE_SIZE);
}
// ----------------------------------------------------------------------------
// ClearCells - 4 bytes at a time
// ----------------------------------------------------------------------------
static inline void _maria_ClearCells4(void)
{
@ -152,9 +210,9 @@ static inline void maria_StoreCellWriteMode(byte data)
// ----------------------------------------------------------------------------
// IsHolyDMA
// IsHoleyDMA
// ----------------------------------------------------------------------------
static inline bool maria_IsHolyDMA( )
static inline bool maria_IsHoleyDMA( )
{
if(maria_pp.w & 0x8000)
{
@ -192,47 +250,6 @@ static u8 write_mode_lookup[256] __attribute__((section(".dtcm"))) =
0x33, 0x37, 0x3B, 0x3F, 0x73, 0x77, 0x7B, 0x7F, 0xB3, 0xB7, 0xBB, 0xBF, 0xF3, 0xF7, 0xFB, 0xFF
};
// ----------------------------------------------------------------------------
// StoreGraphic
// ----------------------------------------------------------------------------
static inline void maria_StoreGraphic( )
{
byte data = memory_ram[maria_pp.w];
if(maria_wmode)
{
if(maria_IsHolyDMA())
{
maria_horizontal += 2;
}
else
{
maria_StoreCellWriteMode(write_mode_lookup[data]);
}
}
else
{
#ifdef KANGAROO_MODE_SUPPORTED
if(maria_IsHolyDMA())
{
maria_horizontal += 4;
}
else if (!data)
{
_maria_ClearCells4();
}
#else
if(maria_IsHolyDMA() || !data)
{
maria_horizontal += 4;
}
#endif
else
{
_maria_StoreCells4(data);
}
}
maria_pp.w++;
}
static u8 write_mode_lookup_mode2A[] __attribute__((section(".dtcm"))) =
{
@ -275,6 +292,7 @@ static u8 write_mode_lookup_mode2B[] __attribute__((section(".dtcm"))) =
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13
};
// ----------------------------------------------------------------------------
// WriteLineRAM
// ----------------------------------------------------------------------------
@ -376,10 +394,60 @@ static inline void maria_WriteLineRAM(word* buffer)
}
}
// ==============================================================================
// Functions below this point read into the 7800 Cart Address Space... and must
// be handled differently for the new 'banksets' scheme - bankset versions of
// these functions can be found further down the source code...
// ==============================================================================
// ----------------------------------------------------------------------------
// StoreGraphic
// ----------------------------------------------------------------------------
static inline void maria_StoreGraphic( )
{
byte data = memory_ram[maria_pp.w];
if(maria_wmode)
{
if(maria_IsHoleyDMA())
{
maria_horizontal += 2;
}
else
{
maria_StoreCellWriteMode(write_mode_lookup[data]);
}
}
else
{
#ifdef KANGAROO_MODE_SUPPORTED
if(maria_IsHoleyDMA())
{
maria_horizontal += 4;
}
else if (!data)
{
_maria_ClearCells4();
}
#else
if(maria_IsHoleyDMA() || !data)
{
maria_horizontal += 4;
}
#endif
else
{
_maria_StoreCells4(data);
}
}
maria_pp.w++;
}
// ----------------------------------------------------------------------------
// StoreLineRAM
// ----------------------------------------------------------------------------
ITCM_CODE void maria_StoreLineRAM( )
ITCM_CODE static void maria_StoreLineRAM( )
{
uint index;
@ -418,7 +486,7 @@ ITCM_CODE void maria_StoreLineRAM( )
}
else
{
maria_cycles += 12; // Maria cycles (Header 5 byte)
maria_cycles += 10; // Maria cycles (Header 5 byte)
maria_palette = (memory_ram[maria_dp.w] & 0xE0) >> 3;
width = memory_ram[maria_dp.w++] & 31;
width = (width == 0) ? 32: ((~width) & 31) + 1;
@ -454,8 +522,7 @@ ITCM_CODE void maria_StoreLineRAM( )
}
maria_pp.w &= 0xFFFF; // Pole Position II and Failsafe both require that we wrap this...
}
maria_cycles += (6*width); // Compensate Maria cycles for Indirect 1 byte
if (cwidth) maria_cycles += (3*width); // Compensate Maria cycles for Indirect 2 byte
maria_cycles += ((cwidth ? 9:6)*width); // Maria cycles for Indirect 1 byte (6 cycles) or 2 bytes (9 cycles)
}
maria_dp.w &= 0xFFFF; // Super Pac-Man requires that we wrap this...
@ -466,46 +533,6 @@ ITCM_CODE void maria_StoreLineRAM( )
}
}
// ----------------------------------------------------------------------------
// Reset
// ----------------------------------------------------------------------------
void maria_Reset( ) {
maria_surface = bufVideo;
maria_scanline = 1;
memset(maria_surface, 0, MARIA_SURFACE_SIZE);
// These values need to be reset to allow switching between carts.
// This appears to be a bug in the ProSystem emulator.
//
maria_cycles = 0;
maria_dpp.w = 0;
maria_dp.w = 0;
maria_pp.w = 0;
maria_horizontal = 0;
maria_palette = 0;
maria_offset = 0;
maria_h08 = 0;
maria_h16 = 0;
maria_h8_h16 = 0x0000;
maria_wmode = 0;
bg32 = 0x00000000;
bg8=0x00;
maria_charbase = 0;
// ----------------------------------------------------------------------------------
// Build the 160 A/B color lookup table for a few frames of increased performance
// ----------------------------------------------------------------------------------
for (uint color=0; color<256; color++)
{
for (uint color1=0; color1<256; color1++)
{
color_lookup_160AB[color][color1] = color | (color<<8) | (color1<<16) | (color1<<24);
}
color_lookup_320AC[color] = (color & 28) | ((color & 1) << 1);
}
}
// ----------------------------------------------------------------------------
// RenderScanline
// ----------------------------------------------------------------------------
@ -527,27 +554,28 @@ ITCM_CODE void maria_RenderScanlineTOP(void)
}
else
{
maria_cycles += 15; // Maria cycles (DMA Startup + End of VBLANK)
if (banksets_mask) return mariabank_RenderScanlineTOP();
maria_dpp.b.l = memory_ram[DPPL];
maria_dpp.b.h = memory_ram[DPPH];
maria_h08 = memory_ram[maria_dpp.w] & 32;
maria_h16 = memory_ram[maria_dpp.w] & 64;
maria_h8_h16 = (maria_h08 ? 2048:0) | (maria_h16 ? 4096:0);
maria_offset = memory_ram[maria_dpp.w] & 15;
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
maria_dp.b.h = memory_ram[maria_dpp.w + 1];
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
if(memory_ram[maria_dpp.w] & 128)
{
maria_cycles += 20; // Maria cycles (NMI) /*29, 16, 20*/
sally_ExecuteNMI( );
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
maria_dp.b.h = memory_ram[maria_dpp.w + 1];
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
}
maria_StoreLineRAM( );
if(--maria_offset < 0)
{
maria_cycles += 10; // Maria cycles (Last line of zone) ( /*20*/
maria_cycles += 15; // Maria cycles (Startup+Shutdown Last line of zone) - Techncially 24 but we know we're over estimating so....
maria_dpp.w += 3;
maria_h08 = memory_ram[maria_dpp.w] & 32;
maria_h16 = memory_ram[maria_dpp.w] & 64;
@ -555,25 +583,21 @@ ITCM_CODE void maria_RenderScanlineTOP(void)
maria_offset = memory_ram[maria_dpp.w] & 15;
if(memory_ram[maria_dpp.w] & 128)
{
maria_cycles += 20; // Maria cycles (NMI) /*29, 16, 20*/
sally_ExecuteNMI( );
}
}
else
{
maria_cycles += 4; // Maria cycles (Other lines of zone)
}
} else maria_cycles += 10; // Maria cycles (Startup+Shutdown Other lines of zone) - Technically 16 but we know we're over estimating so....
}
}
ITCM_CODE void maria_RenderScanline(void)
{
maria_cycles = 0;
//
// Displays the background color when Maria is disabled (if applicable)
//
if ((memory_ram[CTRL] & 96) != 64)
{
maria_cycles = 0;
u32 *bgstart = (u32*)framePtr;
for(uint index = 0; index < MARIA_LINERAM_SIZE/4; index++ )
{
@ -582,7 +606,8 @@ ITCM_CODE void maria_RenderScanline(void)
}
else
{
maria_cycles = 9; // Maria cycles (DMA Startup)
if (banksets_mask) return mariabank_RenderScanline();
// This is where we render the video memory...
if (bRenderFrame) // Skip every other frame...
{
@ -590,11 +615,14 @@ ITCM_CODE void maria_RenderScanline(void)
framePtr += 256;
}
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
maria_dp.b.h = memory_ram[maria_dpp.w + 1];
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
maria_StoreLineRAM( );
if(--maria_offset < 0)
{
maria_cycles += 15; // Maria cycles (Startup+Shutdown Last line of zone) - Techncially 24 but we know we're over estimating so....
maria_dpp.w += 3;
maria_h08 = memory_ram[maria_dpp.w] & 32;
maria_h16 = memory_ram[maria_dpp.w] & 64;
@ -602,18 +630,228 @@ ITCM_CODE void maria_RenderScanline(void)
maria_offset = memory_ram[maria_dpp.w] & 15;
if(memory_ram[maria_dpp.w] & 128)
{
maria_cycles += 26; // Maria cycles (NMI) /*29, 16, 20*/
sally_ExecuteNMI( );
}
else maria_cycles += 6; // Maria cycles (Last line of zone) ( /*20*/
}
else maria_cycles += 10; // Maria cycles (Startup+Shutdown Other lines of zone) - Techncially 16 but we know we're over estimating so....
}
}
// ----------------------------------------------------------------------------
// Clear
// ----------------------------------------------------------------------------
void maria_Clear( )
// =======================================================================================
// BANKSET Handling
// We subsitutue out the maria_XXXX() calls with mariabank_XXXX() calls that will fetch
// non-system memory from the Maria portion of the banksets memory.
// =======================================================================================
extern byte banksets_memory[];
inline byte bankset_memory_read(word address)
{
maria_surface = bufVideo;
memset(maria_surface, 0x00, MARIA_SURFACE_SIZE);
// -----------------------------------------------------------------------
// banksets_mask will be either 0x8000 (if we are only swapping in ROM)
// or 0xC000 (if we are swapping in ROM and RAM). The lower memory is
// always system memory and we get that from memory_ram[]
// -----------------------------------------------------------------------
if (address & banksets_mask) return banksets_memory[address];
else return memory_ram[address];
}
// ----------------------------------------------------------------------------
// StoreGraphic
// ----------------------------------------------------------------------------
static inline void mariabank_StoreGraphic( )
{
byte data = bankset_memory_read(maria_pp.w);
if(maria_wmode)
{
if(maria_IsHoleyDMA())
{
maria_horizontal += 2;
}
else
{
maria_StoreCellWriteMode(write_mode_lookup[data]);
}
}
else
{
#ifdef KANGAROO_MODE_SUPPORTED
if(maria_IsHoleyDMA())
{
maria_horizontal += 4;
}
else if (!data)
{
_maria_ClearCells4();
}
#else
if(maria_IsHoleyDMA() || !data)
{
maria_horizontal += 4;
}
#endif
else
{
_maria_StoreCells4(data);
}
}
maria_pp.w++;
}
// ----------------------------------------------------------------------------
// StoreLineRAM
// ----------------------------------------------------------------------------
ITCM_CODE static void mariabank_StoreLineRAM( )
{
uint index;
if (bRenderFrame) // Skip every other frame...
{
u32 *ptr=(u32*)maria_lineRAM;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0; *ptr = 0;
write_mask_low = ((memory_ram[CTRL] & 3)) ? 0x0F : 0x03;
write_mask_high = ((memory_ram[CTRL] & 3)) ? 0xF0 : 0x30;
}
maria_pp.b.l = bankset_memory_read(maria_dp.w++);
uint mode = bankset_memory_read(maria_dp.w++);
maria_pp.b.h = bankset_memory_read(maria_dp.w++);
while(mode & 0x5f)
{
uint width;
uint indirect = 0;
if(mode & 31)
{
maria_cycles += 8; // Maria cycles (Header 4 byte)
maria_palette = (mode & 0xE0) >> 3;
maria_horizontal = bankset_memory_read(maria_dp.w++);
width = (~mode & 31) + 1;
}
else
{
maria_cycles += 10; // Maria cycles (Header 5 byte)
maria_palette = (bankset_memory_read(maria_dp.w) & 0xE0) >> 3;
width = bankset_memory_read(maria_dp.w++) & 31;
width = (width == 0) ? 32: ((~width) & 31) + 1;
maria_horizontal = bankset_memory_read(maria_dp.w++);
indirect = mode & 32;
maria_wmode = mode & 128;
}
if(!indirect)
{
if (bRenderFrame)
{
maria_pp.b.h += maria_offset;
for(index = 0; index < width; index++)
{
mariabank_StoreGraphic();
}
maria_pp.w &= 0xFFFF; // Pole Position II and Failsafe both require that we wrap this...
}
maria_cycles += (3*width); // Maria cycles (Direct graphic read)
}
else
{
uint cwidth = (memory_ram[CTRL] & 16);
if (bRenderFrame)
{
lpair basePP = maria_pp;
for(index = 0; index < width; index++)
{
maria_pp.w = ((maria_charbase + maria_offset) << 8) | bankset_memory_read(basePP.w++);
mariabank_StoreGraphic( ); //maria_cycles += 6; // Maria cycles (Indirect, 1 byte)
if(cwidth) mariabank_StoreGraphic( ); //maria_cycles += 3; // Maria cycles (Indirect, 2 bytes)
}
maria_pp.w &= 0xFFFF; // Pole Position II and Failsafe both require that we wrap this...
}
maria_cycles += ((cwidth ? 9:6)*width); // Maria cycles for Indirect 1 byte (6 cycles) or 2 bytes (9 cycles)
}
maria_dp.w &= 0xFFFF; // Super Pac-Man requires that we wrap this...
maria_pp.b.l = bankset_memory_read(maria_dp.w++);
mode = bankset_memory_read(maria_dp.w++);
maria_pp.b.h = bankset_memory_read(maria_dp.w++);
}
}
ITCM_CODE void mariabank_RenderScanlineTOP(void)
{
maria_dpp.b.l = bankset_memory_read(DPPL);
maria_dpp.b.h = bankset_memory_read(DPPH);
maria_h08 = bankset_memory_read(maria_dpp.w) & 32;
maria_h16 = bankset_memory_read(maria_dpp.w) & 64;
maria_h8_h16 = (maria_h08 ? 2048:0) | (maria_h16 ? 4096:0);
maria_offset = bankset_memory_read(maria_dpp.w) & 15;
maria_dp.b.h = bankset_memory_read(maria_dpp.w + 1);
maria_dp.b.l = bankset_memory_read(maria_dpp.w + 2);
if(bankset_memory_read(maria_dpp.w) & 128)
{
sally_ExecuteNMI( );
maria_dp.b.h = bankset_memory_read(maria_dpp.w + 1);
maria_dp.b.l = bankset_memory_read(maria_dpp.w + 2);
}
mariabank_StoreLineRAM( );
if(--maria_offset < 0)
{
maria_cycles += 15; // Maria cycles (Startup+Shutdown Last line of zone) - Techncially 24 but we know we're over estimating so....
maria_dpp.w += 3;
maria_h08 = bankset_memory_read(maria_dpp.w) & 32;
maria_h16 = bankset_memory_read(maria_dpp.w) & 64;
maria_h8_h16 = (maria_h08 ? 2048:0) | (maria_h16 ? 4096:0);
maria_offset = bankset_memory_read(maria_dpp.w) & 15;
if(bankset_memory_read(maria_dpp.w) & 128)
{
sally_ExecuteNMI( );
}
}
else maria_cycles += 10; // Maria cycles (Startup+Shutdown Other lines of zone) - Techncially 16 but we know we're over estimating so....
}
ITCM_CODE void mariabank_RenderScanline(void)
{
// This is where we render the video memory...
if (bRenderFrame) // Skip every other frame...
{
maria_WriteLineRAM(framePtr);
framePtr += 256;
}
maria_dp.b.h = bankset_memory_read(maria_dpp.w + 1);
maria_dp.b.l = bankset_memory_read(maria_dpp.w + 2);
mariabank_StoreLineRAM( );
if(--maria_offset < 0)
{
maria_cycles += 15; // Maria cycles (Startup+Shutdown Last line of zone) - Techncially 24 but we know we're over estimating so....
maria_dpp.w += 3;
maria_h08 = bankset_memory_read(maria_dpp.w) & 32;
maria_h16 = bankset_memory_read(maria_dpp.w) & 64;
maria_h8_h16 = (maria_h08 ? 2048:0) | (maria_h16 ? 4096:0);
maria_offset = bankset_memory_read(maria_dpp.w) & 15;
if(bankset_memory_read(maria_dpp.w) & 128)
{
sally_ExecuteNMI( );
}
}
else maria_cycles += 10; // Maria cycles (Startup+Shutdown Other lines of zone) - Techncially 16 but we know we're over estimating so....
}

View file

@ -28,9 +28,10 @@
#include "Database.h"
byte memory_ram[MEMORY_SIZE] ALIGN(32) = {0};
byte memory_rom[MEMORY_SIZE] ALIGN(32) = {0};
byte is_memory_writable[MEMORY_SIZE] ALIGN(32) = {0};
extern bool ram_dirty[];
extern bool write_only_pokey_at_4000;
// ----------------------------------------------------------------------------
// Reset
@ -40,10 +41,10 @@ void memory_Reset( )
uint index;
for(index = 0; index < MEMORY_SIZE; index++) {
memory_ram[index] = 0;
memory_rom[index] = 1;
is_memory_writable[index] = 0;
}
for(index = 0; index < 16384; index++) {
memory_rom[index] = 0;
is_memory_writable[index] = 0xFF;
}
}
@ -72,7 +73,7 @@ ITCM_CODE byte memory_Read_Slower(word address)
{
if (myCartInfo.pokeyType == POKEY_AT_4000)
{
if ((address & 0xFFF0) == 0x4000) return pokey_GetRegister(address);
if (((address & 0xFFF0) == 0x4000) && (!write_only_pokey_at_4000)) return pokey_GetRegister(address);
}
else
{
@ -119,8 +120,8 @@ ITCM_CODE void memory_Write(word address, byte data)
}
}
}
if(!memory_rom[address])
if (is_memory_writable[address])
{
if ((address & 0xF800)) // Base RAM is at 0x1800 so this will find anything that is RAM...
{
@ -188,11 +189,8 @@ ITCM_CODE void memory_Write(word address, byte data)
tia_MemoryChannel(1);
break;
case WSYNC:
if (myCartInfo.uses_wsync)
{
memory_ram[WSYNC] = true;
riot_and_wsync |= 0x01;
}
memory_ram[WSYNC] = true;
riot_and_wsync |= 0x01;
break;
case SWCHB:
/*gdement: Writing here actually writes to DRB inside the RIOT chip.
@ -220,7 +218,7 @@ ITCM_CODE void memory_Write(word address, byte data)
break;
default:
memory_ram[address] = data;
#if 0 // Technically the RAM mirrors are here but we don't really care... we assume anyone using a mirror will read back from that same mirror location.
#ifdef RAM_MIRRORS_ENABLED // Technically the RAM mirrors are here but we don't really care... we assume anyone using a mirror will read back from that same mirror location.
if (address >= 8256)
{
// 0x2040 -> 0x20ff (0x2000)
@ -263,17 +261,17 @@ ITCM_CODE void memory_Write(word address, byte data)
ITCM_CODE void memory_WriteROM(word address, u32 size, const byte* data)
{
u32* ramPtr = (u32*)&memory_ram[address];
u32* romPtr = (u32*)&memory_rom[address];
u32* romPtr = (u32*)&is_memory_writable[address];
u32* dataPtr = (u32*)data;
for (u32 i=0; i<(size>>2); i++)
{
*ramPtr++ = *dataPtr++;
*romPtr++ = 0x01010101;
*romPtr++ = 0x00000000;
}
}
// ----------------------------------------------------------------------------
// WriteROMFast (assumes memory_rom[] already set properly)
// WriteROMFast (assumes is_memory_writable[] already set properly)
// size is already in multiples of u32 dwords
// ----------------------------------------------------------------------------
ITCM_CODE void memory_WriteROMFast(word address, u32 size, const u32* data)
@ -297,5 +295,5 @@ ITCM_CODE void memory_WriteROMFast(word address, u32 size, const u32* data)
void memory_ClearROM(word address, word size)
{
memset(&memory_ram[address], 0x00, size);
memset(&memory_rom[address], 0x00, size);
memset(&is_memory_writable[address], 0xFF, size);
}

View file

@ -81,22 +81,20 @@ ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
// ------------------------------------------------------------
for (maria_scanline = 1; maria_scanline <= 16; maria_scanline++)
{
if (myCartInfo.steals_cycles == STEAL_CYCLE)
prosystem_cycles = 0; // Some fudge for Maria Cycle counting which is not exact. This buys us a few more cycles.
else
prosystem_cycles %= CYCLES_PER_SCANLINE; // Otherwise cycle "exact"
prosystem_cycles = 0;
if (maria_scanline & 0x10)
{
memory_ram[MSTAT] = 0;
framePtr = (word*)(maria_surface);
sally_Execute(HBLANK);
maria_RenderScanlineTOP( );
if(myCartInfo.steals_cycles == STEAL_CYCLE)
{
prosystem_cycles += maria_cycles;
if(riot_and_wsync&2) riot_UpdateTimer( maria_cycles >> 2 );
}
// Cycle Stealing happens here... with a fudge adjustment...
if (maria_cycles > 0) maria_cycles += (int)myCartInfo.dma_adjust;
prosystem_cycles += maria_cycles;
if(riot_and_wsync&2) riot_UpdateTimer( maria_cycles >> 2 );
}
else
{
@ -113,24 +111,20 @@ ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
}
// ------------------------------------------------------------
// Up to line 26 is "off-screen" so we don't bother to render
// Up to line 25 is "off-screen" so we don't bother to render
// ------------------------------------------------------------
for (; maria_scanline < 26; maria_scanline++)
for (; maria_scanline < 25; maria_scanline++)
{
if (myCartInfo.steals_cycles == STEAL_CYCLE)
prosystem_cycles = 0; // Some fudge for Maria Cycle counting which is not exact. This buys us a few more cycles.
else
prosystem_cycles %= CYCLES_PER_SCANLINE; // Otherwise cycle "exact"
prosystem_cycles = 0;
sally_Execute(HBLANK);
maria_RenderScanline( );
if(myCartInfo.steals_cycles == STEAL_CYCLE)
{
prosystem_cycles += maria_cycles;
if(riot_and_wsync&2) riot_UpdateTimer( maria_cycles >> 2 );
}
// Cycle Stealing happens here... with a fudge adjustment...
if (maria_cycles > 0) maria_cycles += (int)myCartInfo.dma_adjust;
prosystem_cycles += maria_cycles;
if(riot_and_wsync&2) riot_UpdateTimer( maria_cycles >> 2 );
sally_Execute(CYCLES_PER_SCANLINE);
@ -142,7 +136,7 @@ ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
}
// -----------------------------------------------------------------------------------
// At line 26 we can start to render the scanlines if we are not skipping this frame.
// At line 25 we can start to render the scanlines if we are not skipping this frame.
// -----------------------------------------------------------------------------------
bRenderFrame = gTotalAtariFrames & frameSkipMask;
@ -151,10 +145,7 @@ ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
// ------------------------------------------------------------
for (; maria_scanline < 258; maria_scanline++)
{
if (myCartInfo.steals_cycles == STEAL_CYCLE)
prosystem_cycles = 0; // Some fudge for Maria Cycle counting which is not exact. This buys us a few more cycles.
else
prosystem_cycles %= CYCLES_PER_SCANLINE; // Otherwise cycle "exact"
prosystem_cycles = 0;
if (maria_scanline == 247)
{
@ -165,11 +156,10 @@ ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
maria_RenderScanline( );
if(myCartInfo.steals_cycles == STEAL_CYCLE)
{
prosystem_cycles += maria_cycles;
if(riot_and_wsync&2) riot_UpdateTimer( maria_cycles >> 2 );
}
// Cycle Stealing happens here... with a fudge adjustment...
if (maria_cycles > 0) maria_cycles += (int)myCartInfo.dma_adjust;
prosystem_cycles += maria_cycles;
if(riot_and_wsync&2) riot_UpdateTimer( maria_cycles >> 2 );
sally_Execute(CYCLES_PER_SCANLINE);
@ -184,10 +174,7 @@ ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
for (; maria_scanline < 262; maria_scanline++)
{
if (myCartInfo.steals_cycles == STEAL_CYCLE)
prosystem_cycles = 0; // Some fudge for Maria Cycle counting which is not exact. This buys us a few more cycles.
else
prosystem_cycles %= CYCLES_PER_SCANLINE; // Otherwise cycle "exact"
prosystem_cycles = 0;
sally_Execute(HBLANK);

View file

@ -41,6 +41,7 @@
#include "shared.h"
//#define KANGAROO_MODE_SUPPORTED 1 // Uncomment this for KANGAROO support. Slightly slower and virtually no game uses it... but more accurate
//#define RAM_MIRRORS_ENABLED 1 // Uncomment if you want to have RAM mirrors handled (slower and no games need it as of this writing)
extern int debug[];
extern u8 isDS_LITE;

View file

@ -36,6 +36,8 @@ PCUnion sally_pc __attribute__((section(".dtcm"))) = {0};
static PCUnion sally_address __attribute__((section(".dtcm")));
static uint sally_cyclesX4 __attribute__((section(".dtcm")));
byte last_illegal_opcode = 0;
#define _fC 0x01
#define _fZ 0x02
#define _fI 0x04
@ -56,22 +58,22 @@ static const Vector SALLY_IRQ = {65535, 65534};
static uint SALLY_CYCLESX4[256] __attribute__((section(".dtcm"))) =
{
7*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,0*4,4*4,6*4,0*4,
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
6*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,4*4,2*4,2*4,2*4,4*4,4*4,6*4,0*4,
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,3*4,4*4,6*4,0*4,
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,4*4,2*4,2*4,0*4,5*4,4*4,6*4,0*4,
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
0*4,6*4,0*4,0*4,3*4,3*4,3*4,0*4,2*4,0*4,2*4,0*4,4*4,4*4,4*4,0*4,
2*4,6*4,0*4,0*4,4*4,4*4,4*4,0*4,2*4,5*4,2*4,0*4,0*4,5*4,0*4,0*4,
2*4,6*4,2*4,0*4,3*4,3*4,3*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,4*4,0*4,
2*4,5*4,0*4,0*4,4*4,4*4,4*4,0*4,2*4,4*4,2*4,0*4,4*4,4*4,4*4,0*4,
2*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,0*4,
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
2*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,0*4,
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4
7*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,0*4,4*4,6*4,0*4, //00
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //10
6*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,4*4,2*4,2*4,2*4,4*4,4*4,6*4,0*4, //20
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //30
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,3*4,4*4,6*4,0*4, //40
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //50
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,4*4,2*4,2*4,0*4,5*4,4*4,6*4,0*4, //60
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //70
0*4,6*4,0*4,6*4,3*4,3*4,3*4,3*4,2*4,0*4,2*4,0*4,4*4,4*4,4*4,4*4, //80
2*4,6*4,0*4,0*4,4*4,4*4,4*4,4*4,2*4,5*4,2*4,0*4,0*4,5*4,0*4,0*4, //90
2*4,6*4,2*4,6*4,3*4,3*4,3*4,3*4,2*4,2*4,2*4,0*4,4*4,4*4,4*4,4*4, //A0
2*4,5*4,0*4,5*4,4*4,4*4,4*4,4*4,2*4,4*4,2*4,0*4,4*4,4*4,4*4,4*4, //B0
2*4,6*4,0*4,8*4,3*4,3*4,5*4,5*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,6*4, //C0
2*4,5*4,0*4,8*4,0*4,4*4,6*4,6*4,2*4,4*4,0*4,7*4,0*4,4*4,7*4,7*4, //D0
2*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,0*4, //E0
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4 //F0
};
@ -844,7 +846,7 @@ static inline void sally_STA( ) {
// ----------------------------------------------------------------------------
// STX
// ----------------------------------------------------------------------------
static inline void sally_stx( ) {
static inline void sally_STX( ) {
memory_Write(sally_address.w, sally_x);
}
@ -902,6 +904,18 @@ static inline void sally_TYA( ) {
sally_Flags(sally_a);
}
static inline void sally_SAX( ) {
sally_STA();
sally_STX();
}
static inline void sally_DCP( ) {
sally_DEC();
sally_CMP();
}
// ----------------------------------------------------------------------------
// Reset
// ----------------------------------------------------------------------------
@ -912,6 +926,7 @@ void sally_Reset( ) {
sally_p = _fT;
sally_s = 0;
sally_pc.w = 0;
last_illegal_opcode = 0;
}
// ----------------------------------------------------------------------------
@ -1405,7 +1420,7 @@ ITCM_CODE void sally_Execute(unsigned int cycles )
l_0x86:
sally_ZeroPage( );
sally_stx( );
sally_STX( );
goto next_inst;
l_0x88:
@ -1428,7 +1443,7 @@ ITCM_CODE void sally_Execute(unsigned int cycles )
l_0x8e:
sally_Absolute( );
sally_stx( );
sally_STX( );
goto next_inst;
l_0x90:
@ -1453,7 +1468,7 @@ ITCM_CODE void sally_Execute(unsigned int cycles )
l_0x96:
sally_ZeroPageY( );
sally_stx( );
sally_STX( );
goto next_inst;
l_0x98:
@ -1822,6 +1837,100 @@ ITCM_CODE void sally_Execute(unsigned int cycles )
}
goto next_inst;
// --------------------------------------------------------------------------------------------------
// Here starts the "undocumented" aka "illegal" OP Codes... but they are stable and sometimes used!
// --------------------------------------------------------------------------------------------------
l_0xa3:
sally_IndirectX( );
sally_LDA( );
sally_LDX( );
goto next_inst;
l_0xb3:
sally_IndirectY( );
sally_LDA( );
sally_LDX( );
goto next_inst;
l_0xaf:
sally_Absolute( );
sally_LDA( );
sally_LDX( );
goto next_inst;
l_0xbf:
sally_AbsoluteY( );
sally_LDA( );
sally_LDX( );
goto next_inst;
l_0xa7:
sally_ZeroPage( );
sally_LDA( );
sally_LDX( );
goto next_inst;
l_0xb7:
sally_ZeroPageY( );
sally_LDA( );
sally_LDX( );
goto next_inst;
l_0x87:
sally_ZeroPage( );
sally_SAX( );
goto next_inst;
l_0x97:
sally_ZeroPageY( );
sally_SAX( );
goto next_inst;
l_0x83:
sally_IndirectX( );
sally_SAX( );
goto next_inst;
l_0x8f:
sally_Absolute( );
sally_SAX( );
goto next_inst;
l_0xc7:
sally_ZeroPage( );
sally_DCP( );
goto next_inst;
l_0xd7:
sally_ZeroPageX( );
sally_DCP( );
goto next_inst;
l_0xc3:
sally_IndirectX( );
sally_DCP( );
goto next_inst;
l_0xd3:
sally_IndirectY( );
sally_DCP( );
goto next_inst;
l_0xcf:
sally_Absolute( );
sally_DCP( );
goto next_inst;
l_0xdf:
sally_AbsoluteX( );
sally_DCP( );
goto next_inst;
l_0xdb:
sally_AbsoluteY( );
sally_DCP( );
goto next_inst;
l_0xff:
l_0xfc:
l_0xfb:
@ -1835,40 +1944,23 @@ l_0xeb:
l_0xe7:
l_0xe3:
l_0xe2:
l_0xdf:
l_0xdc:
l_0xdb:
l_0xda:
l_0xd7:
l_0xd4:
l_0xd3:
l_0xd2:
l_0xcf:
l_0xcb:
l_0xc7:
l_0xc3:
l_0xc2:
l_0xbf:
l_0xbb:
l_0xb7:
l_0xb3:
l_0xb2:
l_0xaf:
l_0xab:
l_0xa7:
l_0xa3:
l_0x9f:
l_0x9e:
l_0x9c:
l_0x9b:
l_0x97:
l_0x93:
l_0x92:
l_0x8f:
l_0x8b:
l_0x89:
l_0x87:
l_0x83:
l_0x82:
l_0x80:
l_0x7f:
@ -1924,7 +2016,7 @@ l_0x07:
l_0x04:
l_0x03:
l_0x02:
last_illegal_opcode = sally_opcode;
next_inst:
prosystem_cycles += sally_cyclesX4;
if (riot_and_wsync)