diff --git a/meka/compat.txt b/meka/compat.txt index ab16dc0f..15fd6de4 100644 --- a/meka/compat.txt +++ b/meka/compat.txt @@ -549,6 +549,8 @@ Summer Games [Proto 0] - Ok (No audio) Summer Games [Proto 1] FM Ok Suho Jeonsa (KR) - Ok + Super 2 in 1 - Sonic & Alien Storm [SMS-GG] - *Ok + Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] - *Ok Super Basketball [Demo] - Ok Super Bioman I (KR) - Ok Super Boy I (KR) - Ok @@ -622,6 +624,7 @@ Ultima IV FM Ok Ultima IV [Proto] FM Ok Ultimate Soccer - Ok + Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] - *Ok Vigilante FM Ok Virtua Fighter Animation - Ok Walter Payton Football - Ok @@ -672,7 +675,7 @@ Zillion II: The Tri Formation [Proto] FM Ok Zool - Ok ----------------------------------------------------------------------------- - 651 games tested - 647 are "Ok" + 654 games tested - 650 are "Ok" ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- diff --git a/meka/meka.nam b/meka/meka.nam index 77c032bf..5439e36f 100644 --- a/meka/meka.nam +++ b/meka/meka.nam @@ -641,6 +641,8 @@ SMS 8da5c93f AF2D01D4A78C8B91 Summer Games/NAME_BR=Jogos OlĂ­mpicos/COUNTRY=EU SMS 4f530cb2 D1B42E8EF4C358B0 Summer Games [Proto 0]/FLAGS=PROTO/COMMENT=Early prototype version of the game. No audio. SMS 80eb1fff 420EEF0B240F3152 Summer Games [Proto 1]/FLAGS=PROTO/COMMENT=Prototype version of the game. SMS 01686d67 88E8E8D0608B22CB Suho Jeonsa/COUNTRY=KR/PRODUCT_NO=DS-G402 +SMS c5c66fa8 414DF3905F54E953 Super 2 in 1 - Sonic & Alien Storm [SMS-GG]/FLAGS=SMSGG_MODE/EMU_MAPPER=47 +SMS 4f72c1fc 0FE54D8F9C2ED591 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG]/FLAGS=SMSGG_MODE/EMU_MAPPER=47 SMS 0dbf3b4a 01EF5A009C6701B2 Super Basketball [Demo]/FLAGS=PROTO/COUNTRY=US/COMMENT=Rolling non-interactive demo to advertise unreleased game. Was shown at the CES exposition floor in USA (around 1989?). SMS a66d26cf 5E7FE6D39D642445 Super Bioman I/COUNTRY=KR SMS bf5a994a 8DF09E55615029B6 Super Boy I/COUNTRY=KR @@ -717,6 +719,7 @@ SMS e1714a88 830DC65B43CD65DA TV Colosso (As Aventuras da)/COUNTRY=BR/PRODUCT_ SMS b52d60c8 3EEC41D938FA3456 Ultima IV/COUNTRY=EU,BR/PRODUCT_NO=9501 SMS de9f8517 A9FD5B95131658E9 Ultima IV [Proto]/FLAGS=PROTO/COMMENT=Prototype version of the game. SMS 15668ca4 7638A4C78062F114 Ultimate Soccer/COUNTRY=EU,BR/PRODUCT_NO=7119,024440 +SMS f4de22f1 F0B71C1C94F56830 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG]/FLAGS=SMSGG_MODE/EMU_MAPPER=47 SMS dfb0b161 826B0C3B91EAF65B Vigilante/COUNTRY=US,EU,BR/PRODUCT_NO=7023 SMS 57f1545b 63CE90266CDA3B98 Virtua Fighter Animation/COUNTRY=BR/PRODUCT_NO=030020/COMMENT=This is a port from the Game Gear version. SMS 3d55759b 2893A79D37A62301 Walter Payton Football/COUNTRY=US/PRODUCT_NO=7020/COMMENT=US version of "American Pro Football". diff --git a/meka/srcs/machine.cpp b/meka/srcs/machine.cpp index f23e934f..662ff339 100644 --- a/meka/srcs/machine.cpp +++ b/meka/srcs/machine.cpp @@ -196,6 +196,9 @@ void Machine_Set_Handler_MemRW(void) case MAPPER_SMS_Korean_MSX_32KB_2000: WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_MSX_32KB_2000; break; + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Power_256KB_FFFF_FFFE; + break; } } @@ -485,6 +488,37 @@ void Machine_Set_Mapping (void) g_machine.mapper_regs[0] = 0; break; + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + if (true) { + // FIXME: Right now this uses reset rather than power-cycle to + // trigger the outer multicart cycling. This is because Meka + // does not yet have hooks for mappers to respond reliably to + // power-cycling, nor does it have key bindings to allow easy + // use of power-cycling multicarts + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[1] = 1; + if (SRAM[0x7FFF] != 0xAA) { + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = 0x00; + } else { + SRAM[0x7FFE] += 0x10; + SRAM[0x7FFE] = ((SRAM[0x7FFE] * 2) & tsms.Pages_Mask_8k) / 2; + } + g_machine.mapper_regs[0] = SRAM[0x7FFE]; + unsigned int base_page_8k = g_machine.mapper_regs[0] * 2; + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (base_page_8k | 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (base_page_8k | 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + } + break; + case MAPPER_SC3000_Survivors_Multicart: g_machine.mapper_regs_count = 1; for (int i = 0; i != MAPPER_REGS_MAX; i++) diff --git a/meka/srcs/mappers.cpp b/meka/srcs/mappers.cpp index 00bf3386..4ae50f82 100644 --- a/meka/srcs/mappers.cpp +++ b/meka/srcs/mappers.cpp @@ -952,6 +952,36 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_32KB_2000) Write_Error (Addr, Value); } +// Mapper #47 +// Super 2 in 1 - Sonic & Alien Storm [SMS-GG] +// Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] +WRITE_FUNC(Write_Mapper_SMS_Power_256KB_FFFF_FFFE) +{ + if (Addr == 0xFFFF) // Upper reconfigurable segment ----------------------------------------------- + { + g_machine.mapper_regs[1] = Value & 0x0f; + unsigned int upper_page_8k = (g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 2; + Map_8k_ROM(4, upper_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (upper_page_8k | 1) & tsms.Pages_Mask_8k); + } + else if (Addr == 0xFFFE) // Lower reconfigurable segment ----------------------------------------------- + { + g_machine.mapper_regs[2] = Value & 0x0f; + unsigned int lower_page_8k = (g_machine.mapper_regs[0] + g_machine.mapper_regs[2]) * 2; + Map_8k_ROM(2, lower_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (lower_page_8k | 1) & tsms.Pages_Mask_8k); + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + // Based on MSX ASCII 8KB mapper? http://bifi.msxnet.org/msxnet/tech/megaroms.html#ascii8 // - This mapper requires 4 registers to save bank switching state. // However, all other mappers so far used only 3 registers, stored as 3 bytes. diff --git a/meka/srcs/mappers.h b/meka/srcs/mappers.h index 3711266f..d88aec18 100644 --- a/meka/srcs/mappers.h +++ b/meka/srcs/mappers.h @@ -50,6 +50,7 @@ #define MAPPER_SMS_Korean_MD_FFF5 (25) // Registers at 0xFFF5 and 0xFFFF (Jaemiissneun Game Mo-eumjip 42/65 Hap [SMS-MD], Pigu Wang Hap ~ Jaemiiss-neun Game Mo-eumjip [SMS-MD]) #define MAPPER_SMS_Korean_MD_FFFA (26) // Registers at 0xFFFA and 0xFFFF (Game Jiphap 30 Hap [SMS-MD]) #define MAPPER_SMS_Korean_MSX_32KB_2000 (27) // Register at 0x2000 (2 Hap in 1 (Moai-ui bomul, David-2)) +#define MAPPER_SMS_Power_256KB_FFFF_FFFE (47) // Power-cycling multicart of 256KB SMS games (Super 2 in 1 - Sonic & Alien Storm [SMS-GG], Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG]) #define READ_FUNC(_NAME) u8 _NAME(register u16 Addr) #define WRITE_FUNC(_NAME) void _NAME(register u16 Addr, register u8 Value) @@ -96,6 +97,7 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_MD_FFF0); WRITE_FUNC (Write_Mapper_SMS_Korean_MD_FFF5); WRITE_FUNC (Write_Mapper_SMS_Korean_MD_FFFA); WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_32KB_2000); +WRITE_FUNC (Write_Mapper_SMS_Power_256KB_FFFF_FFFE); //----------------------------------------------------------------------------- void Out_SC3000_SurvivorsMulticarts_DataWrite(u8 v); diff --git a/meka/srcs/saves.cpp b/meka/srcs/saves.cpp index 09bb14b8..44248eea 100644 --- a/meka/srcs/saves.cpp +++ b/meka/srcs/saves.cpp @@ -144,6 +144,17 @@ void Load_Game_Fixup(void) case MAPPER_SMS_Korean_MSX_32KB_2000: WrZ80_NoHook(0x2000, g_machine.mapper_regs[0]); break; + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + if (true) { + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = g_machine.mapper_regs[0]; + unsigned int base_page_8k = g_machine.mapper_regs[0] * 2; + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[2]); + } + break; } } @@ -339,6 +350,7 @@ int Save_Game_MSV(FILE *f) case MAPPER_SMS_Korean_MD_FFF5: case MAPPER_SMS_Korean_MD_FFFA: case MAPPER_SMS_Korean_MSX_32KB_2000: + case MAPPER_SMS_Power_256KB_FFFF_FFFE: default: fwrite (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change break; @@ -518,6 +530,7 @@ int Load_Game_MSV(FILE *f) case MAPPER_SMS_Korean_MD_FFF5: case MAPPER_SMS_Korean_MD_FFFA: case MAPPER_SMS_Korean_MSX_32KB_2000: + case MAPPER_SMS_Power_256KB_FFFF_FFFE: default: fread (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change break;