Skip to content

Commit

Permalink
Add mapper ocornut#32 MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF for "Super…
Browse files Browse the repository at this point in the history
… GG 68 in 1" multicart

Mapper ocornut#27 is skipped because I expect ocornut#90 may land first.
Mapper ocornut#28 is skipped because I expect ocornut#91 may land first.
Mapper ocornut#29 is skipped because I expect ocornut#93 may land first.
Mapper ocornut#30 is skipped because I expect ocornut#94 may land first.
Mapper ocornut#31 is skipped because I expect ocornut#95 may land first.

There is still some glitchiness in the save-state mechanism that needs to be resolved, but all games other than Choplifter at least start.

Qualify the name of this 68-in-1 with the first menu entry since there is apparently another same-looking cartridge which differs only in menu/games
  • Loading branch information
bsittler committed Mar 19, 2023
1 parent 3cb1c30 commit 1f0d195
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 4 deletions.
3 changes: 2 additions & 1 deletion meka/compat.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,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
Expand Down Expand Up @@ -1497,7 +1498,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 @@ -1289,6 +1289,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.
Expand Down
23 changes: 23 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 @@ -193,6 +194,9 @@ void Machine_Set_Handler_MemRW(void)
case MAPPER_SMS_Korean_MD_FFFA:
WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_MD_FFFA;
break;
case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF:
WrZ80 = WrZ80_NoHook = Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF;
break;
}
}

Expand Down Expand Up @@ -467,6 +471,25 @@ void Machine_Set_Mapping (void)
g_machine.mapper_regs[2] = 1;
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_SC3000_Survivors_Multicart:
g_machine.mapper_regs_count = 1;
for (int i = 0; i != MAPPER_REGS_MAX; i++)
Expand Down
64 changes: 64 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 @@ -928,6 +931,67 @@ WRITE_FUNC(Write_Mapper_SMS_Korean_MD_FFFA)
Write_Error(Addr, Value);
}

// Mapper #32
// Super GG 68 in 1 [Sonic Adventure]
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;
if ((Value == 0x01) && (g_machine.mapper_regs[4] == 0x00) && (g_machine.mapper_regs[5] == 0x00)) {
g_machine.mapper_regs[0] = 0x40;
}
} else if (Addr == 0xFFFE) {
g_machine.mapper_regs[2] = Value;
if ((Value == 0x01) && (g_machine.mapper_regs[0] == 0x40)) {
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);
}
} else if (Addr == 0xFFFF) {
g_machine.mapper_regs[1] = Value;
}
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);
}
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);
}
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 @@ -49,6 +49,7 @@
#define MAPPER_SMS_Korean_MD_FFF0 (24) // Registers at 0xFFF0 and 0xFFFF (Mega Mode Super Game 30 [SMS-MD])
#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_GG_FFF8_FFF9_FFFA_FFFE_FFFF (32) // Registers at 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFE, and 0xFFFF (Super GG 68 in 1 [Sonic Adventure])

#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 @@ -94,6 +95,7 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_0000_xor_FF);
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_GG_FFF8_FFF9_FFFA_FFFE_FFFF);
//-----------------------------------------------------------------------------
void Out_SC3000_SurvivorsMulticarts_DataWrite(u8 v);

Expand Down
52 changes: 49 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 @@ -141,13 +142,56 @@ void Load_Game_Fixup(void)
WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]);
WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[2]);
break;
case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF:
if (1) {
bool sega_mapper_active = g_machine.mapper_regs[0] & 0x80;
bool mapper_latch_open = g_machine.mapper_regs[0] & 0x40;
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 (mapper_latch_open) {
WrZ80_NoHook(0xFFF9, 0x00);
WrZ80_NoHook(0xFFF8, 0x00);
WrZ80_NoHook(0xFFFA, 0x01);
}
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;
}
}

// 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 @@ -335,6 +379,7 @@ int Save_Game_MSV(FILE *f)
case MAPPER_SMS_Korean_MD_FFF0:
case MAPPER_SMS_Korean_MD_FFF5:
case MAPPER_SMS_Korean_MD_FFFA:
case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF:
default:
fwrite (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change
break;
Expand Down Expand Up @@ -513,6 +558,7 @@ int Load_Game_MSV(FILE *f)
case MAPPER_SMS_Korean_MD_FFF0:
case MAPPER_SMS_Korean_MD_FFF5:
case MAPPER_SMS_Korean_MD_FFFA:
case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF:
default:
fread (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change
break;
Expand Down

0 comments on commit 1f0d195

Please sign in to comment.