Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mapper #50 MAPPER_GG_Super_16_in_1_Columns_FFFx for "Game Gear Super 16 in 1 ~ Wudi Xilie [Columns] (Unl)" #118

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion meka/compat.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,7 @@
Galaga '91 (JP) Ok
Gamble Panic (JP) Ok
Gambler Jikochuushin Ha (JP) Ok
Game Gear Super 16 in 1 ~ Wudi Xilie [Columns] *Ok
Garou Densetsu Special (JP) Ok
Ganbare Gorby! (JP) Ok
Garfield: Caught in the Act Ok
Expand Down Expand Up @@ -1498,7 +1499,7 @@
Zoop (US) Ok
Zoop [Proto] (US) Ok
-----------------------------------------------------------------------------
517 games tested - 506 are "Ok" - Compatibility rate: 97.63%
518 games tested - 507 are "Ok" - Compatibility rate: 97.88%
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions meka/meka.nam
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ GG 09534742 45190AB92665163E Gamble Panic/COUNTRY=JP/PRODUCT_NO=G-3364
GG 423803a7 9E7E0CAD62261E85 Gambler Jikochuushin Ha/COUNTRY=JP/PRODUCT_NO=G-3309,G-3339
GG 0593ba24 905D6D377D1F9D36 Galaga '91/COUNTRY=JP/PRODUCT_NO=T-14057/COMMENT=Japanese version of "Galaga 2".
GG 95ecece2 432C080C09AD5275 Galaga 2/COUNTRY=EU/PRODUCT_NO=2322/COMMENT=Export version of "Galaga '91".
GG 01d9f565 8A21D815D0D74879 Game Gear Super 16 in 1 ~ Wudi Xilie [Columns]/EMU_MAPPER=50
GG cd53f3af 5434506F49A77C4D Garfield: Caught in the Act/COUNTRY=US,EU/PRODUCT_NO=2560,2560-50
GG 9afb6f33 CE07E49360532BD6 Garou Densetsu Special/COUNTRY=JP/PRODUCT_NO=T-103017/COMMENT=Japanese version of "Fatal Fury Special".
GG 0e300223 27BA4F0E3A5DBF6C Gear Stadium/COUNTRY=JP/PRODUCT_NO=T-14037/COMMENT=Japanese version of "Batter Up".
Expand Down
22 changes: 22 additions & 0 deletions meka/srcs/machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "tvtype.h"
#include "sound/fmunit.h"
#include "sound/psg.h"
#include "app_game.h"

//-----------------------------------------------------------------------------
// Data
Expand Down Expand Up @@ -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_Super_16_in_1_Columns_FFFx:
WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_16_in_1_Columns_FFFx;
break;
}
}

Expand Down Expand Up @@ -485,6 +489,24 @@ void Machine_Set_Mapping (void)
g_machine.mapper_regs[0] = 0;
break;

case MAPPER_GG_Super_16_in_1_Columns_FFFx:
Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k);
Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k);
Map_8k_ROM(2, 2 & tsms.Pages_Mask_8k);
Map_8k_ROM(3, 3 & tsms.Pages_Mask_8k);
Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); // should actually be all zeroes initially
Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); // should actually be all zeroes initially
Map_8k_RAM(6, 0);
Map_8k_RAM(7, 0);
g_machine.mapper_regs_count = 3;
for (int i = 0; i != MAPPER_REGS_MAX; i++)
g_machine.mapper_regs[i] = 0;
drv_set(DRV_GG);
gamebox_resize_all();
VDP_UpdateLineLimits();
Video_GameMode_UpdateBounds();
break;

case MAPPER_SC3000_Survivors_Multicart:
g_machine.mapper_regs_count = 1;
for (int i = 0; i != MAPPER_REGS_MAX; i++)
Expand Down
65 changes: 65 additions & 0 deletions meka/srcs/mappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#include "shared.h"
#include "mappers.h"
#include "eeprom.h"
#include "vdp.h"
#include "video.h"
#include "app_game.h"

//-----------------------------------------------------------------------------
// Data
Expand Down Expand Up @@ -952,6 +955,68 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_32KB_2000)
Write_Error (Addr, Value);
}

// Mapper #50
// Game Gear Super 16 in 1 ~ Wudi Xilie [Columns] (Unl)
WRITE_FUNC (Write_Mapper_GG_Super_16_in_1_Columns_FFFx)
{
const unsigned int incomplete_address_decoding_assumed_bits = 0x000F;

if ((Addr | incomplete_address_decoding_assumed_bits) == 0xFFFF) // Configurable segment -----------------------------------------------
{
if ((Value & 0xC0) == 0xC0) {
g_machine.mapper_regs[0] = (g_machine.mapper_regs[0] & 0x3F) | ((Value & 0x30) << 2);
} else if ((Value & 0xC0) == 0x80) {
g_machine.mapper_regs[0] = (g_machine.mapper_regs[0] & 0xCF) | (Value & 0x30);
} else if ((Value & 0xC0) == 0x40) {
g_machine.mapper_regs[0] = (g_machine.mapper_regs[0] & 0xF3) | ((Value & 0x30) >> 2);
}

bool sega_mode = (g_machine.mapper_regs[0] & 0x40) ? true : false;
bool sms_gg_mode = (g_machine.mapper_regs[0] & 0x10) ? true : false;

// not sure whether real hardware aliases these too
if (Addr == 0xFFFF) {
g_machine.mapper_regs[1] = Value & 0x0F;
}
if (Addr == 0xFFFE) {
g_machine.mapper_regs[2] = Value & 0x0F;
}

if (((Value & 0xC0) == 0x00) && !sega_mode) {
g_machine.mapper_regs[0] = (g_machine.mapper_regs[0] & 0xFC) | ((Value & 0x30) >> 4);
}

unsigned int base_page_32k = g_machine.mapper_regs[0] & 0x0F;
unsigned int page_8000_offset_16k = sega_mode ? g_machine.mapper_regs[1] : 0;
unsigned int page_4000_offset_16k = sega_mode ? g_machine.mapper_regs[2] : 1;

if (sms_gg_mode) {
drv_set(DRV_SMS);
} else {
drv_set(DRV_GG);
}
gamebox_resize_all();
VDP_UpdateLineLimits();
Video_GameMode_UpdateBounds();

Map_8k_ROM(0, ((base_page_32k * 4) | 0) & tsms.Pages_Mask_8k);
Map_8k_ROM(1, ((base_page_32k * 4) | 1) & tsms.Pages_Mask_8k);
Map_8k_ROM(2, ((base_page_32k * 4) | (page_4000_offset_16k * 2) | 0) & tsms.Pages_Mask_8k);
Map_8k_ROM(3, ((base_page_32k * 4) | (page_4000_offset_16k * 2) | 1) & tsms.Pages_Mask_8k);
Map_8k_ROM(4, ((base_page_32k * 4) | (page_8000_offset_16k * 2) | 0) & tsms.Pages_Mask_8k);
Map_8k_ROM(5, ((base_page_32k * 4) | (page_8000_offset_16k * 2) | 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.
Expand Down
2 changes: 2 additions & 0 deletions meka/srcs/mappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_Super_16_in_1_Columns_FFFx (50) // Register at 0xFFFx (Game Gear Super 16 in 1 ~ Wudi Xilie [Columns])

#define READ_FUNC(_NAME) u8 _NAME(register u16 Addr)
#define WRITE_FUNC(_NAME) void _NAME(register u16 Addr, register u8 Value)
Expand Down Expand Up @@ -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_GG_Super_16_in_1_Columns_FFFx);
//-----------------------------------------------------------------------------
void Out_SC3000_SurvivorsMulticarts_DataWrite(u8 v);

Expand Down
44 changes: 41 additions & 3 deletions meka/srcs/saves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "vmachine.h"
#include "sound/fmunit.h"
#include "sound/psg.h"
#include "video.h"
#include "app_game.h"

//-----------------------------------------------------------------------------
// Functions
Expand All @@ -26,6 +28,7 @@ void Load_Game_Fixup(void)
{
int i;
u8 b;
bool sms_gg_mode_in_mapper = false;

// CPU
#ifdef MARAT_Z80
Expand Down Expand Up @@ -144,13 +147,46 @@ void Load_Game_Fixup(void)
case MAPPER_SMS_Korean_MSX_32KB_2000:
WrZ80_NoHook(0x2000, g_machine.mapper_regs[0]);
break;
case MAPPER_GG_Super_16_in_1_Columns_FFFx:
if (1) {
// these mapper writes will configure SMS-GG mode if needed
unsigned int mode_bits = g_machine.mapper_regs[0] & 0xF0;
unsigned int base_page_32k = g_machine.mapper_regs[0] & 0x0F;
unsigned int page_8000_offset_16k = g_machine.mapper_regs[1];
unsigned int page_4000_offset_16k = g_machine.mapper_regs[2];

// restore "sega" mode paging registers
WrZ80_NoHook(0xFFFF, page_8000_offset_16k);
WrZ80_NoHook(0xFFFE, page_4000_offset_16k);

// use 0xFFF8 for the rest of the writes to prevent
// paging register aliasing (not sure whether real
// hardware works this way, but our implementaiton
// does)

// configure base page
WrZ80_NoHook(0xFFF8, 0xC0);
WrZ80_NoHook(0xFFF8, 0x40 | ((base_page_32k & 0x0C) << 2));
WrZ80_NoHook(0xFFF8, 0x00 | ((base_page_32k & 0x03) << 4));

// restore SMS-GG mode if needed
WrZ80_NoHook(0xFFF8, 0x80 | (mode_bits & 0x30));

// restore "sega" mode if needed
WrZ80_NoHook(0xFFF8, 0xC0 | ((mode_bits & 0xC0) >> 2));

sms_gg_mode_in_mapper = true;
}
break;
}
}

// 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 ++)
Expand Down Expand Up @@ -339,6 +375,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_Super_16_in_1_Columns_FFFx:
default:
fwrite (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change
break;
Expand Down Expand Up @@ -518,6 +555,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_Super_16_in_1_Columns_FFFx:
default:
fread (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change
break;
Expand Down