diff --git a/core/cart_hw/sms_cart.c b/core/cart_hw/sms_cart.c index cee3905..c4aba91 100644 --- a/core/cart_hw/sms_cart.c +++ b/core/cart_hw/sms_cart.c @@ -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 */ diff --git a/core/input_hw/gamepad.c b/core/input_hw/gamepad.c index a523b30..7e6ec58 100644 --- a/core/input_hw/gamepad.c +++ b/core/input_hw/gamepad.c @@ -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; +} diff --git a/core/input_hw/gamepad.h b/core/input_hw/gamepad.h index 5100e01..9c75bde 100644 --- a/core/input_hw/gamepad.h +++ b/core/input_hw/gamepad.h @@ -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 diff --git a/core/input_hw/input.c b/core/input_hw/input.c index f318008..3ad7958 100644 --- a/core/input_hw/input.c +++ b/core/input_hw/input.c @@ -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; diff --git a/core/input_hw/input.h b/core/input_hw/input.h index 23715e9..f6fdec0 100644 --- a/core/input_hw/input.h +++ b/core/input_hw/input.h @@ -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) */ diff --git a/core/io_ctrl.c b/core/io_ctrl.c index 398b8f8..7dfcf3d 100644 --- a/core/io_ctrl.c +++ b/core/io_ctrl.c @@ -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; diff --git a/gx/gui/menu.c b/gx/gui/menu.c index 2f88420..d170f01 100644 --- a/gx/gui/menu.c +++ b/gx/gui/menu.c @@ -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; } diff --git a/gx/images/Ctrl_ms4play.png b/gx/images/Ctrl_ms4play.png new file mode 100644 index 0000000..3a05924 Binary files /dev/null and b/gx/images/Ctrl_ms4play.png differ