src/mess/drivers/genesis.c
| r3298 | r3299 | |
| 61 | 61 | static int megadrive_region_pal = 0; |
| 62 | 62 | |
| 63 | 63 | |
| 64 | /************************************* |
| 65 | * |
| 66 | * Input handlers |
| 67 | * |
| 68 | *************************************/ |
| 64 | 69 | |
| 70 | /* We need to always initialize 6 buttons pad */ |
| 71 | static emu_timer *mess_io_timeout[3]; |
| 72 | static int mess_io_stage[3]; |
| 73 | |
| 74 | static TIMER_CALLBACK( mess_io_timeout_timer_callback ) |
| 75 | { |
| 76 | mess_io_stage[(int)(FPTR)ptr] = -1; |
| 77 | } |
| 78 | |
| 79 | static void mess_init_6buttons_pad(void) |
| 80 | { |
| 81 | int i; |
| 82 | |
| 83 | for (i = 0; i < 3; i++) |
| 84 | { |
| 85 | mess_io_timeout[i] = timer_alloc(mess_io_timeout_timer_callback, (void*)(FPTR)i); |
| 86 | mess_io_stage[i] = -1; |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | /* These overwrite the MAME ones in DRIVER_INIT */ |
| 91 | /* They're needed to give the users the choice between different controllers */ |
| 92 | static UINT8 mess_md_io_read_data_port(int portnum) |
| 93 | { |
| 94 | static const char *const pad6names[2][4] = {{ "PAD1_6B", "PAD2_6B", "UNUSED", "UNUSED" }, |
| 95 | { "EXTRA1", "EXTRA2", "UNUSED", "UNUSED" }}; |
| 96 | static const char *const pad3names[4] = { "PAD1_3B", "PAD2_3B", "UNUSED", "UNUSED" }; |
| 97 | |
| 98 | UINT8 retdata; |
| 99 | int controller; |
| 100 | UINT8 helper_6b = (megadrive_io_ctrl_regs[portnum] & 0x3f) | 0xc0; // bits 6 & 7 always come from megadrive_io_data_regs |
| 101 | UINT8 helper_3b = (megadrive_io_ctrl_regs[portnum] & 0x7f) | 0x80; // bit 7 always comes from megadrive_io_data_regs |
| 102 | |
| 103 | switch (portnum) |
| 104 | { |
| 105 | case 0: |
| 106 | controller = (input_port_read(Machine, "CTRLSEL") & 0x0f); |
| 107 | break; |
| 108 | |
| 109 | case 1: |
| 110 | controller = (input_port_read(Machine, "CTRLSEL") & 0xf0); |
| 111 | break; |
| 112 | |
| 113 | default: |
| 114 | controller = 0; |
| 115 | break; |
| 116 | } |
| 117 | |
| 118 | /* Are we using a 6 buttons Joypad? */ |
| 119 | if (controller) |
| 120 | { |
| 121 | if (megadrive_io_data_regs[portnum] & 0x40) |
| 122 | { |
| 123 | if (mess_io_stage[portnum] == 2) |
| 124 | { |
| 125 | /* here we read B, C & the additional buttons */ |
| 126 | retdata = (megadrive_io_data_regs[portnum] & helper_6b) | |
| 127 | (((input_port_read_safe(Machine, pad6names[0][portnum], 0) & 0x30) | |
| 128 | (input_port_read_safe(Machine, pad6names[1][portnum], 0) & 0x0f)) & ~helper_6b); |
| 129 | } |
| 130 | else |
| 131 | { |
| 132 | /* here we read B, C & the directional buttons */ |
| 133 | retdata = (megadrive_io_data_regs[portnum] & helper_6b) | |
| 134 | ((input_port_read_safe(Machine, pad6names[0][portnum], 0) & 0x3f) & ~helper_6b); |
| 135 | } |
| 136 | } |
| 137 | else |
| 138 | { |
| 139 | if (mess_io_stage[portnum] == 1) |
| 140 | { |
| 141 | /* here we read ((Start & A) >> 2) | 0x00 */ |
| 142 | retdata = (megadrive_io_data_regs[portnum] & helper_6b) | |
| 143 | (((input_port_read_safe(Machine, pad6names[0][portnum], 0) & 0xc0) >> 2) & ~helper_6b); |
| 144 | } |
| 145 | else if (mess_io_stage[portnum]==2) |
| 146 | { |
| 147 | /* here we read ((Start & A) >> 2) | 0x0f */ |
| 148 | retdata = (megadrive_io_data_regs[portnum] & helper_6b) | |
| 149 | ((((input_port_read_safe(Machine, pad6names[0][portnum], 0) & 0xc0) >> 2) | 0x0f) & ~helper_6b); |
| 150 | } |
| 151 | else |
| 152 | { |
| 153 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 154 | retdata = (megadrive_io_data_regs[portnum] & helper_6b) | |
| 155 | ((((input_port_read_safe(Machine, pad6names[0][portnum], 0) & 0xc0) >> 2) | |
| 156 | (input_port_read_safe(Machine, pad6names[0][portnum], 0) & 0x03)) & ~helper_6b); |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | // mame_printf_debug("read io data port stage %d port %d %02x\n",mess_io_stage[portnum],portnum,retdata); |
| 161 | |
| 162 | retdata |= (retdata << 8); |
| 163 | } |
| 164 | /* Otherwise it's a 3 buttons Joypad */ |
| 165 | else |
| 166 | { |
| 167 | if (megadrive_io_data_regs[portnum] & 0x40) |
| 168 | { |
| 169 | /* here we read B, C & the directional buttons */ |
| 170 | retdata = (megadrive_io_data_regs[portnum] & helper_3b) | |
| 171 | (((input_port_read_safe(Machine, pad3names[portnum], 0) & 0x3f) | 0x40) & ~helper_3b); |
| 172 | } |
| 173 | else |
| 174 | { |
| 175 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 176 | retdata = (megadrive_io_data_regs[portnum] & helper_3b) | |
| 177 | ((((input_port_read_safe(Machine, pad3names[portnum], 0) & 0xc0) >> 2) | |
| 178 | (input_port_read_safe(Machine, pad3names[portnum], 0) & 0x03) | 0x40) & ~helper_3b); |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | return retdata; |
| 183 | } |
| 184 | |
| 185 | |
| 186 | static void mess_md_io_write_data_port(int portnum, UINT16 data) |
| 187 | { |
| 188 | int controller; |
| 189 | |
| 190 | switch (portnum) |
| 191 | { |
| 192 | case 0: |
| 193 | controller = (input_port_read(Machine, "CTRLSEL") & 0x0f); |
| 194 | break; |
| 195 | |
| 196 | case 1: |
| 197 | controller = (input_port_read(Machine, "CTRLSEL") & 0xf0); |
| 198 | break; |
| 199 | |
| 200 | default: |
| 201 | controller = 0; |
| 202 | break; |
| 203 | } |
| 204 | |
| 205 | if (controller) |
| 206 | { |
| 207 | if (megadrive_io_ctrl_regs[portnum] & 0x40) |
| 208 | { |
| 209 | if (((megadrive_io_data_regs[portnum] & 0x40) == 0x00) && ((data & 0x40) == 0x40)) |
| 210 | { |
| 211 | mess_io_stage[portnum]++; |
| 212 | timer_adjust_oneshot(mess_io_timeout[portnum], ATTOTIME_IN_CYCLES(8192,0), 0); |
| 213 | } |
| 214 | |
| 215 | } |
| 216 | } |
| 217 | megadrive_io_data_regs[portnum] = data; |
| 218 | //mame_printf_debug("Writing IO Data Register #%d data %04x\n",portnum,data); |
| 219 | } |
| 220 | |
| 221 | |
| 65 | 222 | /************************************* |
| 66 | 223 | * |
| 224 | * Input ports |
| 225 | * |
| 226 | *************************************/ |
| 227 | |
| 228 | |
| 229 | INPUT_PORTS_START( md ) |
| 230 | PORT_START("CTRLSEL") /* Controller selection */ |
| 231 | PORT_CATEGORY_CLASS( 0x0f, 0x00, "Player 1 Controller" ) |
| 232 | PORT_CATEGORY_ITEM( 0x00, "Joystick 3 Buttons", 10 ) |
| 233 | PORT_CATEGORY_ITEM( 0x01, "Joystick 6 Buttons", 11 ) |
| 234 | // PORT_CATEGORY_ITEM( 0x02, "Sega Mouse", 12 ) |
| 235 | /* there exists both a 2 buttons version of the Mouse (Jpn ver, to be used with RPGs, it |
| 236 | can aslo be used as trackball) and a 3 buttons version (US ver, no trackball feats.) */ |
| 237 | // PORT_CATEGORY_ITEM( 0x03, "Sega Menacer", 13 ) |
| 238 | // PORT_CATEGORY_ITEM( 0x04, "Konami Justifier", 14 ) |
| 239 | // PORT_CATEGORY_ITEM( 0x05, "Team Player (Sega Multitap)", 15 ) |
| 240 | // PORT_CATEGORY_ITEM( 0x06, "4-Play (EA Multitap)", 16 ) |
| 241 | // PORT_CATEGORY_ITEM( 0x07, "J-Cart", 17 ) |
| 242 | PORT_CATEGORY_CLASS( 0xf0, 0x00, "Player 2 Controller" ) |
| 243 | PORT_CATEGORY_ITEM( 0x00, "Joystick 3 Buttons", 20 ) |
| 244 | PORT_CATEGORY_ITEM( 0x10, "Joystick 6 Buttons", 21 ) |
| 245 | |
| 246 | PORT_START("PAD1_3B") /* Joypad 1 (3 button + start) NOT READ DIRECTLY */ |
| 247 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(10) |
| 248 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(10) |
| 249 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(10) |
| 250 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(10) |
| 251 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 B") PORT_CATEGORY(10) |
| 252 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 C") PORT_CATEGORY(10) |
| 253 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 A") PORT_CATEGORY(10) |
| 254 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CATEGORY(10) |
| 255 | |
| 256 | PORT_START("PAD2_3B") /* Joypad 2 (3 button + start) NOT READ DIRECTLY */ |
| 257 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(20) |
| 258 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(20) |
| 259 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(20) |
| 260 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(20) |
| 261 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 B") PORT_CATEGORY(20) |
| 262 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 C") PORT_CATEGORY(20) |
| 263 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 A") PORT_CATEGORY(20) |
| 264 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CATEGORY(20) |
| 265 | |
| 266 | PORT_START("PAD1_6B") /* Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */ |
| 267 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(11) |
| 268 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(11) |
| 269 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(11) |
| 270 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) PORT_CATEGORY(11) |
| 271 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 B") PORT_CATEGORY(11) |
| 272 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 C") PORT_CATEGORY(11) |
| 273 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 A") PORT_CATEGORY(11) |
| 274 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CATEGORY(11) |
| 275 | |
| 276 | PORT_START("EXTRA1") /* Extra buttons for Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */ |
| 277 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1) PORT_NAME("P1 Z") PORT_CATEGORY(11) |
| 278 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_NAME("P1 Y") PORT_CATEGORY(11) |
| 279 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 X") PORT_CATEGORY(11) |
| 280 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(1) PORT_NAME("P1 Mode") PORT_CATEGORY(11) |
| 281 | |
| 282 | PORT_START("PAD2_6B") /* Joypad 2 (6 button + start + mode) NOT READ DIRECTLY */ |
| 283 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(21) |
| 284 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(21) |
| 285 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(21) |
| 286 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) PORT_CATEGORY(21) |
| 287 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 B") PORT_CATEGORY(21) |
| 288 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 C") PORT_CATEGORY(21) |
| 289 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 A") PORT_CATEGORY(21) |
| 290 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CATEGORY(21) |
| 291 | |
| 292 | PORT_START("EXTRA2") /* Extra buttons for Joypad 2 (6 button + start + mode) NOT READ DIRECTLY */ |
| 293 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2) PORT_NAME("P2 Z") PORT_CATEGORY(21) |
| 294 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2) PORT_NAME("P2 Y") PORT_CATEGORY(21) |
| 295 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 X") PORT_CATEGORY(21) |
| 296 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(2) PORT_NAME("P2 Mode") PORT_CATEGORY(21) |
| 297 | |
| 298 | PORT_START("RESET") /* Buttons on Genesis Console */ |
| 299 | PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Reset Button") PORT_IMPULSE(1) // reset, resets 68k (and..?) |
| 300 | INPUT_PORTS_END |
| 301 | |
| 302 | |
| 303 | INPUT_PORTS_START( md_svp ) |
| 304 | PORT_INCLUDE( md ) |
| 305 | |
| 306 | /* We need this as long as we only have the US version of the SVP add-on, |
| 307 | otherwise we could not play Non-US Virtua Racing versions */ |
| 308 | PORT_START("REGION") |
| 309 | /* Region setting for Console */ |
| 310 | PORT_CONFNAME( 0x000f, 0x0000, DEF_STR( Region ) ) |
| 311 | PORT_CONFSETTING( 0x0000, "Use Default Choice" ) |
| 312 | PORT_CONFSETTING( 0x0001, "US (NTSC, 60fps)" ) |
| 313 | PORT_CONFSETTING( 0x0002, "Japan (NTSC, 60fps)" ) |
| 314 | PORT_CONFSETTING( 0x0003, "Europe (PAL, 50fps)" ) |
| 315 | INPUT_PORTS_END |
| 316 | |
| 317 | |
| 318 | /************************************* |
| 319 | * |
| 67 | 320 | * Machine driver |
| 68 | 321 | * |
| 69 | 322 | *************************************/ |
| r3298 | r3299 | |
| 72 | 325 | { |
| 73 | 326 | MACHINE_RESET_CALL( megadriv ); |
| 74 | 327 | MACHINE_RESET_CALL( md_mappers ); |
| 328 | |
| 329 | mess_init_6buttons_pad(); |
| 75 | 330 | } |
| 76 | 331 | |
| 77 | 332 | static MACHINE_DRIVER_START( ms_megadriv ) |
| r3298 | r3299 | |
| 118 | 373 | ROM_END |
| 119 | 374 | |
| 120 | 375 | |
| 121 | | |
| 122 | 376 | /************************************* |
| 123 | 377 | * |
| 124 | 378 | * Driver initialization |
| r3298 | r3299 | |
| 129 | 383 | { |
| 130 | 384 | DRIVER_INIT_CALL(gencommon); |
| 131 | 385 | DRIVER_INIT_CALL(megadriv); |
| 386 | |
| 387 | megadrive_io_read_data_port_ptr = mess_md_io_read_data_port; |
| 388 | megadrive_io_write_data_port_ptr = mess_md_io_write_data_port; |
| 132 | 389 | } |
| 133 | 390 | |
| 391 | static DRIVER_INIT( gensvp ) |
| 392 | { |
| 393 | DRIVER_INIT_CALL(gencommon); |
| 394 | DRIVER_INIT_CALL(megadsvp); |
| 395 | } |
| 396 | |
| 134 | 397 | static DRIVER_INIT( md_eur ) |
| 135 | 398 | { |
| 136 | 399 | DRIVER_INIT_CALL(gencommon); |
| r3298 | r3299 | |
| 404 | 667 | ***************************************************************************/ |
| 405 | 668 | |
| 406 | 669 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT CONFIG COMPANY FULLNAME */ |
| 407 | | CONS( 1989, genesis, 0, 0, ms_megadriv, megadri6, genesis, genesis, "Sega", "Genesis (USA, NTSC)", 0) |
| 408 | | CONS( 1993, gensvp, genesis, 0, ms_megdsvp, megdsvp, megadsvp, genesis, "Sega", "Genesis (USA, NTSC, w/SVP)", 0) |
| 409 | | CONS( 1990, megadriv, genesis, 0, ms_megadriv, megadri6, md_eur, genesis, "Sega", "Mega Drive (Europe, PAL)", 0) |
| 410 | | CONS( 1988, megadrij, genesis, 0, ms_megadriv, megadri6, md_jpn, genesis, "Sega", "Mega Drive (Japan, NTSC)", 0) |
| 670 | CONS( 1989, genesis, 0, 0, ms_megadriv, md, genesis, genesis, "Sega", "Genesis (USA, NTSC)", 0) |
| 671 | CONS( 1993, gensvp, genesis, 0, ms_megdsvp, md_svp, gensvp, genesis, "Sega", "Genesis (USA, NTSC, w/SVP)", 0) |
| 672 | CONS( 1990, megadriv, genesis, 0, ms_megadriv, md, md_eur, genesis, "Sega", "Mega Drive (Europe, PAL)", 0) |
| 673 | CONS( 1988, megadrij, genesis, 0, ms_megadriv, md, md_jpn, genesis, "Sega", "Mega Drive (Japan, NTSC)", 0) |
| 411 | 674 | CONS( 1994, pico, 0, 0, pico, pico, md_eur, pico, "Sega", "Pico (Europe, PAL)", 0) |
| 412 | 675 | CONS( 1994, picou, pico, 0, pico, pico, genesis, pico, "Sega", "Pico (USA, NTSC)", 0) |
| 413 | 676 | CONS( 1993, picoj, pico, 0, pico, pico, md_jpn, pico, "Sega", "Pico (Japan, NTSC)", 0) |