Skip to content
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 @@ -1454,6 +1454,7 @@
Tom and Jerry: The Movie (JP) Ok
Torarete Tamaruka!? (JP) Ok
True Lies Ok
Turbo 9 in 1 [Street Fighter 2] *Ok
Ultimate Soccer Ok
Urban Strike Ok
Vampire - Master of Darkness (US) 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 @@ -1332,6 +1332,7 @@ GG a1453efa D9F631F59C7933C3 Tom and Jerry: The Movie/COUNTRY=JP,BR/PRODUCT_N
GG 5cd33ff2 DC1F080D96A53D78 Tom and Jerry: The Movie/COUNTRY=US,EU/PRODUCT_NO=2434
GG 5bcf9b97 F9471D41510253BC Torarete Tamaruka!?/COUNTRY=JP/PRODUCT_NO=G-3348
GG 5173b02a B31BDB3827A8440C True Lies/COUNTRY=US,EU,JP/PRODUCT_NO=T-81318,T-81318-50,T-81167
GG 763b5d62 BD832687D3D0244C Turbo 9 in 1 [Street Fighter 2]/EMU_MAPPER=30
GG 820965a3 78192012DB30BF73 Ultimate Soccer/COUNTRY=JP,EU,BR/PRODUCT_NO=G-3333,075300
GG 185e9fc1 07D77087D26DD517 Urban Strike/COUNTRY=US/PRODUCT_NO=T-100048
GG 7ec64025 84C269594C15F3A4 Vampire - Master of Darkness/COUNTRY=US/PRODUCT_NO=2437/COMMENT=US version of "In the Wake of Vampire" (Japan) and "Master of Darkness" (Europe).
Expand Down
24 changes: 24 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_Turbo_9_in_1_8000_4000:
WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Turbo_9_in_1_8000_4000;
break;
}
}

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

case MAPPER_GG_Turbo_9_in_1_8000_4000:
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 = 3;
for (int i = 0; i != MAPPER_REGS_MAX; i++)
g_machine.mapper_regs[i] = 0;
g_machine.mapper_regs[0] = 0x80;
g_machine.mapper_regs[2] = 1;
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
63 changes: 63 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,66 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_32KB_2000)
Write_Error (Addr, Value);
}

// Mapper #30
// Turbo 9 in 1
WRITE_FUNC(Write_Mapper_GG_Turbo_9_in_1_8000_4000)
{
if (Addr == 0x8000 || Addr == 0x4000) // Configurable segment -----------------------------------------------
{
if (Addr == 0x8000) {
g_machine.mapper_regs[1] = Value;
}
if (Addr == 0x4000) {
g_machine.mapper_regs[2] = Value;
}
if ((g_machine.mapper_regs[2] == 0x11) && (g_machine.mapper_regs[0] == 0x80)) {
// use of 0x80 to signal the initial state is a Meka
// extension but does not conflict with the menu code's
// use of the mapper
g_machine.mapper_regs[0] = g_machine.mapper_regs[1];
g_machine.mapper_regs[1] = 0;
g_machine.mapper_regs[2] = 1;
} else if ((g_machine.mapper_regs[2] == 0x11) && (g_machine.mapper_regs[1] == 0x80)) {
// use of 0x80 to return to the initial state is a Meka
// extension but does not conflict with the menu code's
// use of the mapper, nor does it conflict with the one
// game that uses the mapper
g_machine.mapper_regs[0] = 0x80;
g_machine.mapper_regs[1] = 0;
g_machine.mapper_regs[2] = 1;
}
Map_8k_ROM(0, (g_machine.mapper_regs[0] * 2) & tsms.Pages_Mask_8k);
Map_8k_ROM(1, (g_machine.mapper_regs[0] * 2 + 1) & tsms.Pages_Mask_8k);
Map_8k_ROM(2, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[2]) * 2) & tsms.Pages_Mask_8k);
Map_8k_ROM(3, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[2]) * 2 + 1) & tsms.Pages_Mask_8k);
Map_8k_ROM(4, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 2) & tsms.Pages_Mask_8k);
Map_8k_ROM(5, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 2 + 1) & tsms.Pages_Mask_8k);
// It is unclear how the cartridge decides whether to switch
// from native GG mode (which is the power-on default) to
// SMS-GG mode, but it appears to happen at the moment 0x11 is
// written to 0x4000 *unless* 0x0a was the most recent value
// previously written to 0x4000.
if ((g_machine.mapper_regs[0] != 0x80) && (g_machine.mapper_regs[0] != 0x0a)) {
drv_set(DRV_SMS);
} else {
drv_set(DRV_GG);
}
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);
}

// 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_Turbo_9_in_1_8000_4000 (30) // Registers at 0x8000 and 0x4000 (Turbo 9 in 1)

#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_Turbo_9_in_1_8000_4000);
//-----------------------------------------------------------------------------
void Out_SC3000_SurvivorsMulticarts_DataWrite(u8 v);

Expand Down
29 changes: 26 additions & 3 deletions meka/srcs/saves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,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 +145,33 @@ void Load_Game_Fixup(void)
case MAPPER_SMS_Korean_MSX_32KB_2000:
WrZ80_NoHook(0x2000, g_machine.mapper_regs[0]);
break;
case MAPPER_GG_Turbo_9_in_1_8000_4000:
if (1) {
unsigned int base_page_16k = g_machine.mapper_regs[0];
unsigned int page_8000_offset_16k = g_machine.mapper_regs[1];
unsigned int page_4000_offset_16k = g_machine.mapper_regs[2];
// use of 0x80 to return to the initial state is a Meka
// extension but does not conflict with the menu code's
// use of the mapper, nor does it conflict with the one
// game that uses the mapper
WrZ80_NoHook(0x8000, 0x80);
WrZ80_NoHook(0x4000, 0x11);
WrZ80_NoHook(0x8000, base_page_16k);
WrZ80_NoHook(0x4000, 0x11);
WrZ80_NoHook(0x4000, page_4000_offset_16k);
WrZ80_NoHook(0x8000, page_8000_offset_16k);
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 +360,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_Turbo_9_in_1_8000_4000:
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 +540,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_Turbo_9_in_1_8000_4000:
default:
fread (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change
break;
Expand Down