mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-25 18:51:49 +01:00
[Core/IO] added homemade Master System multitap emulation (BOom)
This commit is contained in:
parent
262a8c7fbc
commit
df6dbe855a
@ -254,6 +254,9 @@ static const rominfo_t game_list[] =
|
||||
{0xE42E4998, 0, 0, SYSTEM_SPORTSPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Sports Pad Football */
|
||||
{0x41C948BF, 0, 0, SYSTEM_SPORTSPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Sports Pad Soccer */
|
||||
|
||||
/* games requiring homemade multitap */
|
||||
{0xFAB6F52F, 0, 0, SYSTEM_MS4PLAY, MAPPER_NONE, SYSTEM_SMS2, REGION_USA}, /* BOom */
|
||||
|
||||
/* games supporting YM2413 FM */
|
||||
{0x1C951F8E, 0, 1, SYSTEM_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* After Burner */
|
||||
{0xC13896D5, 0, 1, SYSTEM_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Alex Kidd: The Lost Stars */
|
||||
|
@ -1,9 +1,9 @@
|
||||
/***************************************************************************************
|
||||
* Genesis Plus
|
||||
* 3-Buttons & 6-Buttons pad support
|
||||
* Support for J-CART & 4-Way Play adapters
|
||||
* 2-Buttons, 3-Buttons & 6-Buttons controller support
|
||||
* Additional support for J-Cart, 4-Way Play & homemade Master System multitap
|
||||
*
|
||||
* Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2014 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -47,7 +47,13 @@ static struct
|
||||
uint8 Timeout;
|
||||
} gamepad[MAX_DEVICES];
|
||||
|
||||
static uint8 pad_index;
|
||||
static struct
|
||||
{
|
||||
uint8 Latch;
|
||||
uint8 Counter;
|
||||
} flipflop[2];
|
||||
|
||||
static uint8 latch;
|
||||
|
||||
|
||||
void gamepad_reset(int port)
|
||||
@ -57,8 +63,12 @@ void gamepad_reset(int port)
|
||||
gamepad[port].Counter = 0;
|
||||
gamepad[port].Timeout = 0;
|
||||
|
||||
/* reset pad index (4-WayPlay) */
|
||||
pad_index = 0;
|
||||
/* reset 4-WayPlay latch */
|
||||
latch = 0;
|
||||
|
||||
/* reset Master System multitap flip-flop */
|
||||
flipflop[port>>2].Latch = 0;
|
||||
flipflop[port>>2].Counter = 0;
|
||||
}
|
||||
|
||||
void gamepad_refresh(int port)
|
||||
@ -192,13 +202,15 @@ void gamepad_2_write(unsigned char data, unsigned char mask)
|
||||
|
||||
unsigned char wayplay_1_read(void)
|
||||
{
|
||||
if (pad_index < 4)
|
||||
/* check if TH on port B is HIGH */
|
||||
if (latch & 0x04)
|
||||
{
|
||||
return gamepad_read(pad_index);
|
||||
/* 4-WayPlay detection : xxxxx00 */
|
||||
return 0x7c;
|
||||
}
|
||||
|
||||
/* multitap detection */
|
||||
return 0x70;
|
||||
/* TR & TL on port B select controller # (0-3) */
|
||||
return gamepad_read(latch);
|
||||
}
|
||||
|
||||
unsigned char wayplay_2_read(void)
|
||||
@ -208,18 +220,14 @@ unsigned char wayplay_2_read(void)
|
||||
|
||||
void wayplay_1_write(unsigned char data, unsigned char mask)
|
||||
{
|
||||
if (pad_index < 4)
|
||||
{
|
||||
gamepad_write(pad_index, data, mask);
|
||||
}
|
||||
/* TR & TL on port B select controller # (0-3) */
|
||||
gamepad_write(latch & 0x03, data, mask);
|
||||
}
|
||||
|
||||
void wayplay_2_write(unsigned char data, unsigned char mask)
|
||||
{
|
||||
if ((mask & 0x70) == 0x70)
|
||||
{
|
||||
pad_index = (data & 0x70) >> 4;
|
||||
}
|
||||
/* latch TH, TR & TL state on port B */
|
||||
latch = ((data & mask) >> 4) & 0x07;
|
||||
}
|
||||
|
||||
|
||||
@ -239,3 +247,48 @@ void jcart_write(unsigned int address, unsigned int data)
|
||||
gamepad_write(6, (data & 1) << 6, 0x40);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Master System multitap ports handler (original design by Furrtek) */
|
||||
/* cf. http://www.smspower.org/uploads/Homebrew/BOoM-SMS-sms4p_2.png */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
unsigned char ms4play_1_read(void)
|
||||
{
|
||||
return gamepad_read(flipflop[0].Counter);
|
||||
}
|
||||
|
||||
unsigned char ms4play_2_read(void)
|
||||
{
|
||||
return gamepad_read(flipflop[1].Counter + 4);
|
||||
}
|
||||
|
||||
void ms4play_1_write(unsigned char data, unsigned char mask)
|
||||
{
|
||||
/* update bits set as output only */
|
||||
data = (flipflop[0].Latch & ~mask) | (data & mask);
|
||||
|
||||
/* check TH 1->0 transitions */
|
||||
if ((flipflop[0].Latch & 0x40) && !(data & 0x40))
|
||||
{
|
||||
flipflop[0].Counter = (flipflop[0].Counter + 1) & 0x03;
|
||||
}
|
||||
|
||||
/* update internal state */
|
||||
flipflop[0].Latch = data;
|
||||
}
|
||||
|
||||
void ms4play_2_write(unsigned char data, unsigned char mask)
|
||||
{
|
||||
/* update bits set as output only */
|
||||
data = (flipflop[1].Latch & ~mask) | (data & mask);
|
||||
|
||||
/* check TH=1 to TH=0 transition */
|
||||
if ((flipflop[1].Latch & 0x40) && !(data & 0x40))
|
||||
{
|
||||
flipflop[1].Counter = (flipflop[1].Counter + 1) & 0x03;
|
||||
}
|
||||
|
||||
/* update internal state */
|
||||
flipflop[1].Latch = data;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
/***************************************************************************************
|
||||
* Genesis Plus
|
||||
* 3-Buttons & 6-Buttons pad support
|
||||
* Support for J-CART & 4-Way Play adapters
|
||||
* 2-Buttons, 3-Buttons & 6-Buttons controller support
|
||||
* Additional support for J-Cart, 4-Way Play & homemade Master System multitap
|
||||
*
|
||||
* Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2014 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -53,5 +53,9 @@ extern void wayplay_1_write(unsigned char data, unsigned char mask);
|
||||
extern void wayplay_2_write(unsigned char data, unsigned char mask);
|
||||
extern unsigned int jcart_read(unsigned int address);
|
||||
extern void jcart_write(unsigned int address, unsigned int data);
|
||||
extern unsigned char ms4play_1_read(void);
|
||||
extern unsigned char ms4play_2_read(void);
|
||||
extern void ms4play_1_write(unsigned char data, unsigned char mask);
|
||||
extern void ms4play_2_write(unsigned char data, unsigned char mask);
|
||||
|
||||
#endif
|
||||
|
@ -170,6 +170,19 @@ void input_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_MS4PLAY:
|
||||
{
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (player < MAX_INPUTS)
|
||||
{
|
||||
input.dev[i] = DEVICE_PAD2B;
|
||||
player++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_LIGHTPHASER:
|
||||
{
|
||||
input.dev[0] = DEVICE_LIGHTGUN;
|
||||
@ -276,6 +289,19 @@ void input_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_MS4PLAY:
|
||||
{
|
||||
for (i=4; i<8; i++)
|
||||
{
|
||||
if (player < MAX_INPUTS)
|
||||
{
|
||||
input.dev[i] = DEVICE_PAD2B;
|
||||
player++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_LIGHTPHASER:
|
||||
{
|
||||
input.dev[4] = DEVICE_LIGHTGUN;
|
||||
|
@ -51,12 +51,12 @@
|
||||
#define SYSTEM_JUSTIFIER (4) /* Konami Justifiers (port B only) */
|
||||
#define SYSTEM_XE_A1P (5) /* XE-A1P analog controller (port A only) */
|
||||
#define SYSTEM_ACTIVATOR (6) /* Sega Activator */
|
||||
#define SYSTEM_MS_GAMEPAD (7) /* single 2-buttons Control Pad (Master System) */
|
||||
#define SYSTEM_LIGHTPHASER (7) /* Sega Light Phaser (Master System) */
|
||||
#define SYSTEM_PADDLE (8) /* Sega Paddle Control (Master System) */
|
||||
#define SYSTEM_SPORTSPAD (9) /* Sega Sports Pad (Master System) */
|
||||
#define SYSTEM_TEAMPLAYER (10) /* Multi Tap -- Sega TeamPlayer */
|
||||
#define SYSTEM_WAYPLAY (11) /* Multi Tap -- EA 4-Way Play (use both ports) */
|
||||
#define SYSTEM_MS4PLAY (10) /* Multi Tap -- Master System homemade */
|
||||
#define SYSTEM_TEAMPLAYER (11) /* Multi Tap -- Sega TeamPlayer */
|
||||
#define SYSTEM_WAYPLAY (12) /* Multi Tap -- EA 4-Way Play (use both ports) */
|
||||
|
||||
/* Device type */
|
||||
#define NO_DEVICE (0xff) /* unconnected device (fixed ID for Team Player) */
|
||||
|
@ -122,6 +122,13 @@ void io_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_MS4PLAY:
|
||||
{
|
||||
port[0].data_w = ms4play_1_write;
|
||||
port[0].data_r = ms4play_1_read;
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_LIGHTPHASER:
|
||||
{
|
||||
port[0].data_w = dummy_write;
|
||||
@ -209,6 +216,13 @@ void io_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_MS4PLAY:
|
||||
{
|
||||
port[1].data_w = ms4play_2_write;
|
||||
port[1].data_r = ms4play_2_read;
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSTEM_LIGHTPHASER:
|
||||
{
|
||||
port[1].data_w = dummy_write;
|
||||
|
@ -108,6 +108,7 @@ extern const u8 Ctrl_paddle_png[];
|
||||
extern const u8 Ctrl_sportspad_png[];
|
||||
extern const u8 Ctrl_none_png[];
|
||||
extern const u8 Ctrl_teamplayer_png[];
|
||||
extern const u8 Ctrl_ms4play_png[];
|
||||
extern const u8 Ctrl_pad_auto_png[];
|
||||
extern const u8 Ctrl_pad2b_png[];
|
||||
extern const u8 Ctrl_pad3b_png[];
|
||||
@ -2028,7 +2029,7 @@ static void ctrlmenu(void)
|
||||
u32 exp, index = 0;
|
||||
|
||||
/* System devices */
|
||||
gui_item items_sys[2][12] =
|
||||
gui_item items_sys[2][13] =
|
||||
{
|
||||
{
|
||||
{NULL,Ctrl_none_png ,"","Select Port 1 device",110,130,48,72},
|
||||
@ -2041,6 +2042,7 @@ static void ctrlmenu(void)
|
||||
{NULL,Ctrl_lightphaser_png,"","Select Port 1 device", 89,109,88,92},
|
||||
{NULL,Ctrl_paddle_png ,"","Select Port 1 device", 86,117,96,84},
|
||||
{NULL,Ctrl_sportspad_png ,"","Select Port 1 device", 95,117,76,84},
|
||||
{NULL,Ctrl_ms4play_png ,"","Select Port 1 device", 94,100,80,100},
|
||||
{NULL,Ctrl_teamplayer_png ,"","Select Port 1 device", 94,109,80,92},
|
||||
{NULL,Ctrl_4wayplay_png ,"","Select Port 1 device", 98,110,72,92}
|
||||
},
|
||||
@ -2055,6 +2057,7 @@ static void ctrlmenu(void)
|
||||
{NULL,Ctrl_lightphaser_png,"","Select Port 2 device", 89,279,88,92},
|
||||
{NULL,Ctrl_paddle_png ,"","Select Port 2 device", 86,287,96,84},
|
||||
{NULL,Ctrl_sportspad_png ,"","Select Port 2 device", 95,287,76,84},
|
||||
{NULL,Ctrl_ms4play_png ,"","Select Port 1 device", 94,270,80,100},
|
||||
{NULL,Ctrl_teamplayer_png ,"","Select Port 2 device", 94,279,80,92},
|
||||
{NULL,Ctrl_4wayplay_png ,"","Select Port 2 device", 98,280,72,92}
|
||||
}
|
||||
@ -2121,7 +2124,7 @@ static void ctrlmenu(void)
|
||||
button_player_none_data.texture[0] = gxTextureOpenPNG(button_player_none_data.image[0],0);
|
||||
|
||||
/* initialize custom images */
|
||||
for (i=0; i<12; i++)
|
||||
for (i=0; i<13; i++)
|
||||
{
|
||||
items_sys[1][i].texture = items_sys[0][i].texture = gxTextureOpenPNG(items_sys[0][i].data,0);
|
||||
}
|
||||
@ -2415,8 +2418,17 @@ static void ctrlmenu(void)
|
||||
case DEVICE_PAD3B:
|
||||
case DEVICE_PAD6B:
|
||||
{
|
||||
items = items_special[0];
|
||||
special = &config.input[player].padtype;
|
||||
if (input.system[index/4] == SYSTEM_MS4PLAY)
|
||||
{
|
||||
/* force 2-buttons pad */
|
||||
items = items_special[3];
|
||||
special = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
items = items_special[0];
|
||||
special = &config.input[player].padtype;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
BIN
gx/images/Ctrl_ms4play.png
Normal file
BIN
gx/images/Ctrl_ms4play.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
Loading…
Reference in New Issue
Block a user