diff --git a/meka/compat.txt b/meka/compat.txt index 306b6a89..e25ce6a3 100644 --- a/meka/compat.txt +++ b/meka/compat.txt @@ -1148,6 +1148,7 @@ GG Portrait - Pai Chen (JP) Ok GG Portrait - Yuuki Akira (JP) Ok GG Shinobi, The (JP) Ok + GG Super 56 in 1 (B) [Mega Man] *Ok Global Gladiators Ok G-LOC - Air Battle Ok G-LOC - Air Battle [v0] (JP) Ok @@ -1412,6 +1413,7 @@ Super Battletank Ok Super Columns Ok Super Columns (JP) Ok + Super GG 68 in 1 [Sonic Adventure] *Ok Super Golf (JP) Ok Super Kick Off [SMS-GG] Ok Superman - The Man of Steel Ok @@ -1472,6 +1474,7 @@ Winter Olympics / Winter Olympics Games Ok Winter Olympics (JP) Ok Wizard Pinball Ok + Wise Gear GG 32 in 1 [Nettou Samurai] *Ok Wolfchild Ok Wonder Boy Ok Wonder Boy (JP) Ok @@ -1502,7 +1505,7 @@ Zoop (US) Ok Zoop [Proto] (US) Ok ----------------------------------------------------------------------------- - 517 games tested - 506 are "Ok" - Compatibility rate: 97.63% + 520 games tested - 509 are "Ok" - Compatibility rate: 97.88% ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- diff --git a/meka/meka.nam b/meka/meka.nam index 35d87c35..85e88a07 100644 --- a/meka/meka.nam +++ b/meka/meka.nam @@ -1045,6 +1045,7 @@ GG 695cc120 FCC991E880B52D60 GG Portrait - Pai Chen/COUNTRY=JP/PRODUCT_NO=G-3 GG 51159f8f 5D96967FEE1C49A5 GG Portrait - Yuuki Akira/COUNTRY=JP/PRODUCT_NO=G-3386 GG 83926bd1 7EC1D6C6D2A7119B GG Shinobi, The/COUNTRY=JP/PRODUCT_NO=G-3302 GG d2b6021e F0E8A87399B7C4F9 Global Gladiators/COUNTRY=US,EU/PRODUCT_NO=T-70058,T-70058-50 +GG 271f40a3 92CBD58C8243F885 GG Super 56 in 1 (B) [Mega Man]/EMU_MAPPER=32 GG 18de59ed 093B5C63C1FA1E24 G-LOC - Air Battle/NAME_BR=G-LOC/COUNTRY=US,EU,BR/PRODUCT_NO=2301,012120 GG 2333f615 9B4CDA9945218AB6 G-LOC - Air Battle [v0]/COUNTRY=JP/PRODUCT_NO=G-3204 GG 33237f50 6949D8B6CE13CD12 G-LOC - Air Battle [v1]/COUNTRY=JP/PRODUCT_NO=G-3204 @@ -1296,6 +1297,7 @@ GG b421c057 96BD12C62621B8D6 Striker/COUNTRY=EU/PRODUCT_NO=2551-50 GG 73d6745a 18CC99C9849C9901 Super Battletank/COUNTRY=US/PRODUCT_NO=1239 GG 8ba43af3 DAA4C785B7042952 Super Columns/COUNTRY=US,EU/PRODUCT_NO=2449,2449-50 GG 2a100717 E7260408CEC8EE63 Super Columns/COUNTRY=JP/PRODUCT_NO=G-3226 +GG 99ee7296 8F378BEF3668D84A Super GG 68 in 1 [Sonic Adventure]/EMU_MAPPER=32 GG 528cbbce FAE75543A7740E5E Super Golf/COUNTRY=JP/PRODUCT_NO=T-26017,T-26027 GG 73df5a15 43574420E8CF212A Superman - The Man of Steel/COUNTRY=EU/PRODUCT_NO=T-70068,70068-00 GG aa3f2172 0A5C6040EBCF152B Superman - The Man of Steel [Proto]/FLAGS=PROTO/COMMENT=Prototype version of the game. @@ -1348,6 +1350,7 @@ GG d460cc7f 32EEB88F6A58E2F5 WildSnake [Proto]/COUNTRY=US/PRODUCT_NO=T-124028 GG ce1108fd 5EF9334D02922E67 Wimbledon/NAME_US=Wimbledon Tennis/COUNTRY=JP,EU,US/PRODUCT_NO=G-3221,2323 GG d15d335b 8C9DF406D503E322 Winter Olympics/NAME_US=Winter Olympics Games/COUNTRY=US,EU/PRODUCT_NO=T-79088,T-79088-18 GG d5195a39 5AE30E1DD51AC5E4 Winter Olympics/COUNTRY=JP/PRODUCT_NO=G-3342 +GG 133d89ad 289FF33D45085864 Wise Gear GG 32 in 1 [Nettou Samurai]/EMU_MAPPER=32 GG 9e03f96c C2DB65453292985D Wizard Pinball/COUNTRY=EU/PRODUCT_NO=T-88088-50 GG 840a8f8e 9C35260DA7367AA5 Wolfchild/COUNTRY=EU/PRODUCT_NO=T-70078-50 GG 9c0e5a04 902D4CDEE014FD28 Woody Pop [v0]/COUNTRY=JP/PRODUCT_NO=G-3101 diff --git a/meka/srcs/machine.cpp b/meka/srcs/machine.cpp index f6adcfdb..fcc3a6dd 100644 --- a/meka/srcs/machine.cpp +++ b/meka/srcs/machine.cpp @@ -22,6 +22,7 @@ #include "tvtype.h" #include "sound/fmunit.h" #include "sound/psg.h" +#include "app_game.h" //----------------------------------------------------------------------------- // Data @@ -196,6 +197,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_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF; + break; case MAPPER_SMS_Korean_MSX_SMS_8000: WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_MSX_SMS_8000; break; @@ -488,6 +492,25 @@ void Machine_Set_Mapping (void) g_machine.mapper_regs[0] = 0; break; + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 6; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + case MAPPER_SMS_Korean_MSX_SMS_8000: Map_8k_ROM(0, 0x3c & tsms.Pages_Mask_8k); Map_8k_ROM(1, 0x3c & tsms.Pages_Mask_8k); diff --git a/meka/srcs/mappers.cpp b/meka/srcs/mappers.cpp index 7610fbee..b713b269 100644 --- a/meka/srcs/mappers.cpp +++ b/meka/srcs/mappers.cpp @@ -14,6 +14,9 @@ #include "shared.h" #include "mappers.h" #include "eeprom.h" +#include "vdp.h" +#include "video.h" +#include "app_game.h" //----------------------------------------------------------------------------- // Data @@ -952,6 +955,65 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_32KB_2000) Write_Error (Addr, Value); } +// Mapper #32 +// Super GG 68 in 1 [Sonic Adventure] +// GG Super 56 in 1 (B) [Mega Man] +WRITE_FUNC(Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF) +{ + if ((Addr == 0xFFF8) || (Addr == 0xFFF9) || (Addr == 0xFFFA) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFF8) { + g_machine.mapper_regs[5] = Value; + } else if (Addr == 0xFFF9) { + g_machine.mapper_regs[4] = Value; + } else if (Addr == 0xFFFA) { + g_machine.mapper_regs[3] = Value; + } else if (Addr == 0xFFFE) { + g_machine.mapper_regs[2] = Value; + } else if (Addr == 0xFFFF) { + g_machine.mapper_regs[1] = Value; + } + if (Addr == 0xFFF8 || Addr == 0xFFFA) { + bool second_megabyte_active = (g_machine.mapper_regs[4] & 0x12) || (g_machine.mapper_regs[3] & 0x04); + bool sega_mapper_active = (g_machine.mapper_regs[4] & 0x1E) || (g_machine.mapper_regs[3] & 0x04); + g_machine.mapper_regs[0] = (g_machine.mapper_regs[5] & 0x1F) | (second_megabyte_active ? 0x20 : 0x00) | (sega_mapper_active ? 0x80 : 0x00); + bool sms_gg_mode_active = (g_machine.mapper_regs[4] & 0x80) || (g_machine.mapper_regs[3] & 0x01); + if (sms_gg_mode_active) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + } + if (1) { + bool sega_mapper_active = g_machine.mapper_regs[0] & 0x80; + bool second_megabyte_active = g_machine.mapper_regs[0] & 0x20; + unsigned int sega_mapper_mask = sega_mapper_active ? (second_megabyte_active ? 0x1F : 0x0F) : 0x01; + unsigned int page_0000_8k = (g_machine.mapper_regs[0] & 0x3F) * 4; + unsigned int page_4000_8k = page_0000_8k + ((g_machine.mapper_regs[2] & sega_mapper_mask) * 2); + unsigned int page_8000_8k = page_0000_8k + ((g_machine.mapper_regs[1] & sega_mapper_mask) * 2); + Map_8k_ROM(0, page_0000_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (page_0000_8k | 0x01) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, page_4000_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (page_4000_8k | 0x01) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, page_8000_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (page_8000_8k | 0x01) & tsms.Pages_Mask_8k); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + //return; + } + + 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); +} + // Mapper #40 // Zemina Best 88 (KR) // Zemina Best 25 (KR) diff --git a/meka/srcs/mappers.h b/meka/srcs/mappers.h index 0ea32122..2c02dad5 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_GG_FFF8_FFF9_FFFA_FFFE_FFFF (32) // Registers at 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFE, and 0xFFFF (Super GG 68 in 1 [Sonic Adventure], GG Super 56 in 1 (B) [Mega Man]) #define MAPPER_SMS_Korean_MSX_SMS_8000 (40) // Register at 0x8000 with 8KB granularity and both MSX and SMS game support (Zemina Best 88 [MISSING 64K]) #define READ_FUNC(_NAME) u8 _NAME(register u16 Addr) @@ -97,6 +98,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_GG_FFF8_FFF9_FFFA_FFFE_FFFF); WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_SMS_8000); //----------------------------------------------------------------------------- void Out_SC3000_SurvivorsMulticarts_DataWrite(u8 v); diff --git a/meka/srcs/saves.cpp b/meka/srcs/saves.cpp index 34012e4e..71a74f99 100644 --- a/meka/srcs/saves.cpp +++ b/meka/srcs/saves.cpp @@ -26,6 +26,7 @@ void Load_Game_Fixup(void) { int i; u8 b; + bool sms_gg_mode_in_mapper = false; // CPU #ifdef MARAT_Z80 @@ -144,6 +145,41 @@ void Load_Game_Fixup(void) case MAPPER_SMS_Korean_MSX_32KB_2000: WrZ80_NoHook(0x2000, g_machine.mapper_regs[0]); break; + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + if (1) { + bool sega_mapper_active = g_machine.mapper_regs[0] & 0x80; + bool second_megabyte_active = g_machine.mapper_regs[0] & 0x20; + unsigned int base_page_32k = g_machine.mapper_regs[0] & 0x1F; + unsigned int reg_FFF8 = g_machine.mapper_regs[5]; + unsigned int reg_FFF9 = g_machine.mapper_regs[4]; + unsigned int reg_FFFA = g_machine.mapper_regs[3]; + unsigned int reg_FFFE = g_machine.mapper_regs[2]; + unsigned int reg_FFFF = g_machine.mapper_regs[1]; + WrZ80_NoHook(0xFFF9, 0x00); + WrZ80_NoHook(0xFFF8, 0x00); + WrZ80_NoHook(0xFFFA, 0x01); + WrZ80_NoHook(0xFFF8, base_page_32k); + WrZ80_NoHook(0xFFF9, (reg_FFF9 & 0x80) | ((sega_mapper_active && second_megabyte_active) ? 0x12 : 0x00) | ((sega_mapper_active && !second_megabyte_active) ? 0x0C : 0x00)); + WrZ80_NoHook(0xFFFA, (reg_FFFA & 0x01) | ((sega_mapper_active && second_megabyte_active) ? 0x04 : 0x00)); + WrZ80_NoHook(0xFFFE, 0x01); + if (g_machine.mapper_regs[1] != reg_FFFF) { + WrZ80_NoHook(0xFFFF, reg_FFFF); + } + if (g_machine.mapper_regs[2] != reg_FFFE) { + WrZ80_NoHook(0xFFFE, reg_FFFE); + } + if (g_machine.mapper_regs[4] != reg_FFF9) { + WrZ80_NoHook(0xFFF9, reg_FFF9); + } + if (g_machine.mapper_regs[5] != reg_FFF8) { + WrZ80_NoHook(0xFFF8, reg_FFF8); + } + if (g_machine.mapper_regs[3] != reg_FFFA) { + WrZ80_NoHook(0xFFFA, reg_FFFA); + } + sms_gg_mode_in_mapper = true; + } + break; case MAPPER_SMS_Korean_MSX_SMS_8000: { int mapper_page = g_machine.mapper_regs[0]; @@ -155,9 +191,11 @@ void Load_Game_Fixup(void) } // VDP/Graphic related - tsms.VDP_Video_Change |= VDP_VIDEO_CHANGE_ALL; - VDP_UpdateLineLimits(); - // FALSE!!! // tsms.VDP_Line = 224; + if (!sms_gg_mode_in_mapper) { + tsms.VDP_Video_Change |= VDP_VIDEO_CHANGE_ALL; + VDP_UpdateLineLimits(); + // FALSE!!! // tsms.VDP_Line = 224; + } // Rewrite all VDP registers (we can do that since it has zero side-effect) for (i = 0; i < 16; i ++) @@ -346,6 +384,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_GG_FFF8_FFF9_FFFA_FFFE_FFFF: case MAPPER_SMS_Korean_MSX_SMS_8000: default: fwrite (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change @@ -526,6 +565,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_GG_FFF8_FFF9_FFFA_FFFE_FFFF: case MAPPER_SMS_Korean_MSX_SMS_8000: default: fread (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change