From 298676294a547326cfb45e55502bdf4a24904c74 Mon Sep 17 00:00:00 2001 From: ekeeke Date: Mon, 9 Aug 2021 16:05:24 +0200 Subject: [PATCH] [Core/MD] fixed Game Genie / (Pro) Action Replay lock-on support with ROM larger than 8MB --- core/cart_hw/areplay.c | 94 +++++++++++--------------- core/cart_hw/areplay.h | 2 +- core/cart_hw/ggenie.c | 27 ++++---- core/cart_hw/ggenie.h | 2 +- core/cart_hw/md_cart.c | 146 ++++++++++++++++++++--------------------- core/cart_hw/md_cart.h | 4 +- core/cd_hw/cd_cart.h | 2 +- 7 files changed, 126 insertions(+), 151 deletions(-) diff --git a/core/cart_hw/areplay.c b/core/cart_hw/areplay.c index b066716..1b99a70 100644 --- a/core/cart_hw/areplay.c +++ b/core/cart_hw/areplay.c @@ -1,6 +1,6 @@ /**************************************************************************** * Genesis Plus - * Action Replay / Pro Action Replay emulation + * Action Replay / Pro Action Replay hardware support * * Copyright (C) 2009-2021 Eke-Eke (Genesis Plus GX) * @@ -45,8 +45,7 @@ static struct { uint8 enabled; uint8 status; - uint8 *rom; - uint8 *ram; + uint8 ram[0x10000]; uint16 regs[13]; uint16 old[4]; uint16 data[4]; @@ -54,64 +53,52 @@ static struct } action_replay; static void ar_write_regs(uint32 address, uint32 data); -static void ar_write_regs_2(uint32 address, uint32 data); +static void ar2_write_reg(uint32 address, uint32 data); static void ar_write_ram_8(uint32 address, uint32 data); void areplay_init(void) { - int size; - - memset(&action_replay,0,sizeof(action_replay)); + action_replay.enabled = action_replay.status = 0; - /* store Action replay ROM (max. 128KB) & RAM (64KB) above cartridge ROM (max. 8MB) */ - if (cart.romsize > 0x800000) return; - action_replay.rom = cart.rom + 0x800000; - action_replay.ram = cart.rom + 0x820000; - - /* try to load Action Replay ROM file */ - size = load_archive(AR_ROM, action_replay.rom, 0x20000, NULL); - - /* detect Action Replay board type */ - switch (size) + /* try to load Action Replay ROM file (max. 64KB) */ + if (load_archive(AR_ROM, cart.lockrom, 0x10000, NULL) > 0) { - case 0x8000: + /* detect Action Replay board type */ + if (!memcmp(cart.lockrom + 0x120, "ACTION REPLAY ", 16)) { - if (!memcmp(action_replay.rom + 0x120, "ACTION REPLAY ", 16)) - { - /* normal Action Replay (32K) */ - action_replay.enabled = TYPE_AR; - - /* internal registers mapped at $010000-$01ffff */ - m68k.memory_map[0x01].write16 = ar_write_regs; - break; - } - } + /* normal Action Replay (32KB ROM) */ + action_replay.enabled = TYPE_AR; - case 0x10000: - case 0x20000: + /* $0000-$7fff mirrored into $8000-$ffff */ + memcpy(cart.lockrom + 0x8000, cart.lockrom, 0x8000); + + /* internal registers mapped at $010000-$01ffff */ + m68k.memory_map[0x01].write16 = ar_write_regs; + } + else { /* Read stack pointer MSB */ - uint8 sp = READ_BYTE(action_replay.rom, 0x01); + uint8 sp = cart.lockrom[0x01]; /* Detect board version */ - if ((sp == 0x42) && !memcmp(action_replay.rom + 0x120, "ACTION REPLAY 2 ", 16)) + if ((sp == 0x42) && !memcmp(cart.lockrom + 0x120, "ACTION REPLAY 2 ", 16)) { - /* PRO Action Replay 1 (64/128K) */ + /* PRO Action Replay (2x32KB ROM) */ action_replay.enabled = TYPE_PRO1; /* internal registers mapped at $010000-$01ffff */ m68k.memory_map[0x01].write16 = ar_write_regs; } - else if ((sp == 0x60) && !memcmp(action_replay.rom + 0x3c6, "ACTION REPLAY II", 16)) + else if ((sp == 0x60) && !memcmp(cart.lockrom + 0x3c6, "ACTION REPLAY II", 16)) { - /* PRO Action Replay 2 (64K) */ + /* PRO Action Replay 2 (2x32KB ROM) */ action_replay.enabled = TYPE_PRO2; - /* internal registers mapped at $100000-$10ffff */ - m68k.memory_map[0x10].write16 = ar_write_regs_2; + /* internal register mapped at $100000-$10ffff */ + m68k.memory_map[0x10].write16 = ar2_write_reg; } - /* internal RAM (64k), mapped at $420000-$42ffff or $600000-$60ffff */ + /* internal RAM (64KB), mapped at $420000-$42ffff or $600000-$60ffff */ if (action_replay.enabled) { m68k.memory_map[sp].base = action_replay.ram; @@ -120,28 +107,22 @@ void areplay_init(void) m68k.memory_map[sp].write8 = ar_write_ram_8; m68k.memory_map[sp].write16 = NULL; } - break; } - default: - { - break; - } - } - #ifdef LSB_FIRST - if (action_replay.enabled) - { - int i; - for (i= 0; i 0x800000) return; - ggenie.rom = cart.rom + 0x800000; - - /* Try to load Game Genie ROM file */ - if (load_archive(GG_ROM, ggenie.rom, 0x8000, NULL) > 0) + /* Try to load Game Genie ROM file (32KB) */ + if (load_archive(GG_ROM, cart.lockrom, 0x8000, NULL) > 0) { #ifdef LSB_FIRST int i; for (i=0; i<0x8000; i+=2) { /* Byteswap ROM */ - uint8 temp = ggenie.rom[i]; - ggenie.rom[i] = ggenie.rom[i+1]; - ggenie.rom[i+1] = temp; + uint8 temp = cart.lockrom[i]; + cart.lockrom[i] = cart.lockrom[i+1]; + cart.lockrom[i+1] = temp; } #endif /* $0000-$7fff mirrored into $8000-$ffff */ - memcpy(ggenie.rom + 0x8000, ggenie.rom, 0x8000); + memcpy(cart.lockrom + 0x8000, cart.lockrom, 0x8000); /* Game Genie hardware is enabled */ ggenie.enabled = 1; @@ -113,7 +108,7 @@ void ggenie_reset(int hard) } /* Game Genie ROM is mapped at $000000-$007fff */ - m68k.memory_map[0].base = ggenie.rom; + m68k.memory_map[0].base = cart.lockrom; /* Internal registers are mapped at $000000-$00001f */ m68k.memory_map[0].write8 = ggenie_write_byte; @@ -214,7 +209,7 @@ static void ggenie_write_regs(unsigned int offset, unsigned int data) else { /* $0000-$7ffff reads mapped to Game Genie ROM */ - m68k.memory_map[0].base = ggenie.rom; + m68k.memory_map[0].base = cart.lockrom; m68k.memory_map[0].read8 = NULL; m68k.memory_map[0].read16 = NULL; diff --git a/core/cart_hw/ggenie.h b/core/cart_hw/ggenie.h index b61f611..0e36ff9 100644 --- a/core/cart_hw/ggenie.h +++ b/core/cart_hw/ggenie.h @@ -1,6 +1,6 @@ /**************************************************************************** * Genesis Plus - * Game Genie Hardware emulation + * Game Genie hardware support * * Copyright (C) 2009-2021 Eke-Eke (Genesis Plus GX) * diff --git a/core/cart_hw/md_cart.c b/core/cart_hw/md_cart.c index 5c7602b..6ff9e9f 100644 --- a/core/cart_hw/md_cart.c +++ b/core/cart_hw/md_cart.c @@ -453,79 +453,6 @@ void md_cart_init(void) svp_init(); } - /********************************************** - LOCK-ON - ***********************************************/ - - /* clear existing patches */ - ggenie_shutdown(); - areplay_shutdown(); - - /* initialize extra hardware */ - switch (config.lock_on) - { - case TYPE_GG: - { - ggenie_init(); - break; - } - - case TYPE_AR: - { - areplay_init(); - break; - } - - case TYPE_SK: - { - /* store Sonic & Knuckles ROM files after cartridge ROM area */ - if (cart.romsize > 0x400000) break; - - /* try to load Sonic & Knuckles ROM file (2MB) */ - if (load_archive(SK_ROM, cart.rom + 0x400000, 0x200000, NULL) == 0x200000) - { - /* check ROM header */ - if (!memcmp(cart.rom + 0x400000 + 0x120, "SONIC & KNUCKLES",16)) - { - /* try to load Sonic 2 & Knuckles upmem ROM file (256KB) */ - if (load_archive(SK_UPMEM, cart.rom + 0x600000, 0x40000, NULL) == 0x40000) - { - /* $000000-$1FFFFF is mapped to S&K ROM */ - for (i=0x00; i<0x20; i++) - { - m68k.memory_map[i].base = cart.rom + 0x400000 + (i << 16); - } - -#ifdef LSB_FIRST - for (i=0; i<0x200000; i+=2) - { - /* Byteswap ROM */ - uint8 temp = cart.rom[i + 0x400000]; - cart.rom[i + 0x400000] = cart.rom[i + 0x400000 + 1]; - cart.rom[i + 0x400000 + 1] = temp; - } - - for (i=0; i<0x40000; i+=2) - { - /* Byteswap ROM */ - uint8 temp = cart.rom[i + 0x600000]; - cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1]; - cart.rom[i + 0x600000 + 1] = temp; - } -#endif - cart.special |= HW_LOCK_ON; - } - } - } - break; - } - - default: - { - break; - } - } - /********************************************** CARTRIDGE EXTRA HARDWARE ***********************************************/ @@ -760,6 +687,79 @@ void md_cart_init(void) { cart.hw.time_w = default_time_w; } + + /********************************************** + LOCK-ON + ***********************************************/ + + /* clear existing patches */ + ggenie_shutdown(); + areplay_shutdown(); + + /* initialize extra hardware */ + switch (config.lock_on) + { + case TYPE_GG: + { + ggenie_init(); + break; + } + + case TYPE_AR: + { + areplay_init(); + break; + } + + case TYPE_SK: + { + /* store Sonic & Knuckles ROM files after cartridge ROM area */ + if (cart.romsize > 0x400000) break; + + /* try to load Sonic & Knuckles ROM file (2MB) */ + if (load_archive(SK_ROM, cart.rom + 0x400000, 0x200000, NULL) == 0x200000) + { + /* check ROM header */ + if (!memcmp(cart.rom + 0x400000 + 0x120, "SONIC & KNUCKLES",16)) + { + /* try to load Sonic 2 & Knuckles upmem ROM file (256KB) */ + if (load_archive(SK_UPMEM, cart.rom + 0x600000, 0x40000, NULL) == 0x40000) + { + /* $000000-$1FFFFF is mapped to S&K ROM */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].base = cart.rom + 0x400000 + (i << 16); + } + +#ifdef LSB_FIRST + for (i=0; i<0x200000; i+=2) + { + /* Byteswap ROM */ + uint8 temp = cart.rom[i + 0x400000]; + cart.rom[i + 0x400000] = cart.rom[i + 0x400000 + 1]; + cart.rom[i + 0x400000 + 1] = temp; + } + + for (i=0; i<0x40000; i+=2) + { + /* Byteswap ROM */ + uint8 temp = cart.rom[i + 0x600000]; + cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1]; + cart.rom[i + 0x600000 + 1] = temp; + } +#endif + cart.special |= HW_LOCK_ON; + } + } + } + break; + } + + default: + { + break; + } + } } /* hardware that need to be reseted on power on */ diff --git a/core/cart_hw/md_cart.h b/core/cart_hw/md_cart.h index 0343030..b34fb8f 100644 --- a/core/cart_hw/md_cart.h +++ b/core/cart_hw/md_cart.h @@ -81,10 +81,10 @@ typedef struct uint32 mask; /* ROM mask */ uint8 special; /* custom external hardware (Lock-On, J-Cart, 3-D glasses, Terebi Oekaki,...) */ cart_hw_t hw; /* cartridge internal hardware */ - uint8 rom[MAXROMSIZE]; /* ROM area */ + uint8 lockrom[0x10000]; /* Game Genie / (Pro) Action Replay Lock-On ROM area (max 64KB) */ + uint8 rom[MAXROMSIZE]; /* cartridge ROM area */ } md_cart_t; - /* Function prototypes */ extern void md_cart_init(void); extern void md_cart_reset(int hard_reset); diff --git a/core/cd_hw/cd_cart.h b/core/cd_hw/cd_cart.h index a0e7482..c708a78 100644 --- a/core/cd_hw/cd_cart.h +++ b/core/cd_hw/cd_cart.h @@ -41,7 +41,7 @@ typedef struct { uint8 reserved[0x80]; /* reserved for ROM cartridge infos (see md_cart.h) */ - uint8 area[0x830000]; /* cartridge ROM/RAM area (max. 8MB ROM + Pro Action Replay 128KB ROM / 64KB RAM) */ + uint8 area[0x810000]; /* cartridge ROM/RAM area (max. 8MB ROM + Pro Action Replay 64KB ROM) */ uint8 boot; /* cartridge boot mode (0x00: boot from CD with ROM/RAM cartridge enabled, 0x40: boot from ROM cartridge with CD enabled) */ uint8 id; /* RAM cartridge ID (related to RAM size, 0 if disabled) */ uint8 prot; /* RAM cartridge write protection */