trunk/src/mame/drivers/segac2.c
| r22070 | r22071 | |
| 88 | 88 | #define LOG_PALETTE 0 |
| 89 | 89 | #define LOG_IOCHIP 0 |
| 90 | 90 | |
| 91 | | int segac2_bg_pal_lookup[4]; |
| 92 | | int segac2_sp_pal_lookup[4]; |
| 93 | | |
| 94 | | static void recompute_palette_tables( running_machine &machine ); |
| 95 | | |
| 96 | 91 | /****************************************************************************** |
| 97 | 92 | Machine init |
| 98 | 93 | ******************************************************************************* |
| r22070 | r22071 | |
| 114 | 109 | { |
| 115 | 110 | // megadriv_scanline_timer = machine().device<timer_device>("md_scan_timer"); |
| 116 | 111 | // megadriv_scanline_timer->adjust(attotime::zero); |
| 117 | | segac2_bg_pal_lookup[0] = 0x00; |
| 118 | | segac2_bg_pal_lookup[1] = 0x10; |
| 119 | | segac2_bg_pal_lookup[2] = 0x20; |
| 120 | | segac2_bg_pal_lookup[3] = 0x30; |
| 112 | m_segac2_bg_pal_lookup[0] = 0x00; |
| 113 | m_segac2_bg_pal_lookup[1] = 0x10; |
| 114 | m_segac2_bg_pal_lookup[2] = 0x20; |
| 115 | m_segac2_bg_pal_lookup[3] = 0x30; |
| 121 | 116 | |
| 122 | | segac2_sp_pal_lookup[0] = 0x00; |
| 123 | | segac2_sp_pal_lookup[1] = 0x10; |
| 124 | | segac2_sp_pal_lookup[2] = 0x20; |
| 125 | | segac2_sp_pal_lookup[3] = 0x30; |
| 117 | m_segac2_sp_pal_lookup[0] = 0x00; |
| 118 | m_segac2_sp_pal_lookup[1] = 0x10; |
| 119 | m_segac2_sp_pal_lookup[2] = 0x20; |
| 120 | m_segac2_sp_pal_lookup[3] = 0x30; |
| 126 | 121 | |
| 127 | 122 | megadriv_reset_vdp(machine()); |
| 128 | 123 | |
| r22070 | r22071 | |
| 140 | 135 | m_bg_palbase = 0; |
| 141 | 136 | m_sp_palbase = 0; |
| 142 | 137 | |
| 143 | | recompute_palette_tables(machine()); |
| 138 | recompute_palette_tables(); |
| 144 | 139 | |
| 145 | 140 | } |
| 146 | 141 | |
| r22070 | r22071 | |
| 159 | 154 | ******************************************************************************/ |
| 160 | 155 | |
| 161 | 156 | /* handle writes to the UPD7759 */ |
| 162 | | static WRITE16_DEVICE_HANDLER( segac2_upd7759_w ) |
| 157 | WRITE16_MEMBER(segac2_state::segac2_upd7759_w ) |
| 163 | 158 | { |
| 164 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 165 | | |
| 159 | device_t *upd = machine().device("upd"); |
| 166 | 160 | /* make sure we have a UPD chip */ |
| 167 | | if (!state->m_sound_banks) |
| 161 | if (!m_sound_banks) |
| 168 | 162 | return; |
| 169 | 163 | |
| 170 | 164 | /* only works if we're accessing the low byte */ |
| 171 | 165 | if (ACCESSING_BITS_0_7) |
| 172 | 166 | { |
| 173 | | upd7759_port_w(device, space, 0, data & 0xff); |
| 174 | | upd7759_start_w(device, 0); |
| 175 | | upd7759_start_w(device, 1); |
| 167 | upd7759_port_w(upd, space, 0, data & 0xff); |
| 168 | upd7759_start_w(upd, 0); |
| 169 | upd7759_start_w(upd, 1); |
| 176 | 170 | } |
| 177 | 171 | } |
| 178 | 172 | |
| r22070 | r22071 | |
| 195 | 189 | ******************************************************************************/ |
| 196 | 190 | |
| 197 | 191 | /* handle reads from the paletteram */ |
| 198 | | static READ16_HANDLER( palette_r ) |
| 192 | READ16_MEMBER(segac2_state::palette_r ) |
| 199 | 193 | { |
| 200 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 201 | 194 | offset &= 0x1ff; |
| 202 | | if (state->m_segac2_alt_palette_mode) |
| 195 | if (m_segac2_alt_palette_mode) |
| 203 | 196 | offset = ((offset << 1) & 0x100) | ((offset << 2) & 0x80) | ((~offset >> 2) & 0x40) | ((offset >> 1) & 0x20) | (offset & 0x1f); |
| 204 | 197 | |
| 205 | | return state->m_paletteram[offset + state->m_palbank * 0x200]; |
| 198 | return m_paletteram[offset + m_palbank * 0x200]; |
| 206 | 199 | } |
| 207 | 200 | |
| 208 | 201 | /* handle writes to the paletteram */ |
| 209 | | static WRITE16_HANDLER( palette_w ) |
| 202 | WRITE16_MEMBER(segac2_state::palette_w ) |
| 210 | 203 | { |
| 211 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 212 | 204 | int r, g, b, newword; |
| 213 | 205 | int tmpr, tmpg, tmpb; |
| 214 | 206 | |
| 215 | 207 | /* adjust for the palette bank */ |
| 216 | 208 | offset &= 0x1ff; |
| 217 | | if (state->m_segac2_alt_palette_mode) |
| 209 | if (m_segac2_alt_palette_mode) |
| 218 | 210 | offset = ((offset << 1) & 0x100) | ((offset << 2) & 0x80) | ((~offset >> 2) & 0x40) | ((offset >> 1) & 0x20) | (offset & 0x1f); |
| 219 | | offset += state->m_palbank * 0x200; |
| 211 | offset += m_palbank * 0x200; |
| 220 | 212 | |
| 221 | 213 | /* combine data */ |
| 222 | | COMBINE_DATA(&state->m_paletteram[offset]); |
| 223 | | newword = state->m_paletteram[offset]; |
| 214 | COMBINE_DATA(&m_paletteram[offset]); |
| 215 | newword = m_paletteram[offset]; |
| 224 | 216 | |
| 225 | 217 | /* up to 8 bits */ |
| 226 | 218 | r = ((newword << 1) & 0x1e) | ((newword >> 12) & 0x01); |
| r22070 | r22071 | |
| 276 | 268 | |
| 277 | 269 | ******************************************************************************/ |
| 278 | 270 | |
| 279 | | static void recompute_palette_tables( running_machine &machine ) |
| 271 | void segac2_state::recompute_palette_tables() |
| 280 | 272 | { |
| 281 | | segac2_state *state = machine.driver_data<segac2_state>(); |
| 282 | 273 | int i; |
| 283 | 274 | |
| 284 | 275 | for (i = 0; i < 4; i++) |
| 285 | 276 | { |
| 286 | | int bgpal = 0x000 + state->m_bg_palbase * 0x40 + i * 0x10; |
| 287 | | int sppal = 0x100 + state->m_sp_palbase * 0x40 + i * 0x10; |
| 277 | int bgpal = 0x000 + m_bg_palbase * 0x40 + i * 0x10; |
| 278 | int sppal = 0x100 + m_sp_palbase * 0x40 + i * 0x10; |
| 288 | 279 | |
| 289 | | if (!state->m_segac2_alt_palette_mode) |
| 280 | if (!m_segac2_alt_palette_mode) |
| 290 | 281 | { |
| 291 | | segac2_bg_pal_lookup[i] = 0x200 * state->m_palbank + bgpal; |
| 292 | | segac2_sp_pal_lookup[i] = 0x200 * state->m_palbank + sppal; |
| 282 | m_segac2_bg_pal_lookup[i] = 0x200 * m_palbank + bgpal; |
| 283 | m_segac2_sp_pal_lookup[i] = 0x200 * m_palbank + sppal; |
| 293 | 284 | } |
| 294 | 285 | else |
| 295 | 286 | { |
| 296 | | segac2_bg_pal_lookup[i] = 0x200 * state->m_palbank + ((bgpal << 1) & 0x180) + ((~bgpal >> 2) & 0x40) + (bgpal & 0x30); |
| 297 | | segac2_sp_pal_lookup[i] = 0x200 * state->m_palbank + ((~sppal << 2) & 0x100) + ((sppal << 2) & 0x80) + ((~sppal >> 2) & 0x40) + ((sppal >> 2) & 0x20) + (sppal & 0x10); |
| 287 | m_segac2_bg_pal_lookup[i] = 0x200 * m_palbank + ((bgpal << 1) & 0x180) + ((~bgpal >> 2) & 0x40) + (bgpal & 0x30); |
| 288 | m_segac2_sp_pal_lookup[i] = 0x200 * m_palbank + ((~sppal << 2) & 0x100) + ((sppal << 2) & 0x80) + ((~sppal >> 2) & 0x40) + ((sppal >> 2) & 0x20) + (sppal & 0x10); |
| 298 | 289 | } |
| 299 | 290 | } |
| 300 | 291 | |
| r22070 | r22071 | |
| 313 | 304 | |
| 314 | 305 | ******************************************************************************/ |
| 315 | 306 | |
| 316 | | static READ16_HANDLER( io_chip_r ) |
| 307 | READ16_MEMBER(segac2_state::io_chip_r ) |
| 317 | 308 | { |
| 318 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 319 | 309 | static const char *const portnames[] = { "P1", "P2", "PORTC", "PORTD", "SERVICE", "COINAGE", "DSW", "PORTH" }; |
| 320 | 310 | offset &= 0x1f/2; |
| 321 | 311 | |
| r22070 | r22071 | |
| 331 | 321 | case 0x0c/2: |
| 332 | 322 | case 0x0e/2: |
| 333 | 323 | /* if the port is configured as an output, return the last thing written */ |
| 334 | | if (state->m_misc_io_data[0x1e/2] & (1 << offset)) |
| 335 | | return state->m_misc_io_data[offset]; |
| 324 | if (m_misc_io_data[0x1e/2] & (1 << offset)) |
| 325 | return m_misc_io_data[offset]; |
| 336 | 326 | |
| 337 | 327 | /* otherwise, return an input port */ |
| 338 | | if (offset == 0x04/2 && state->m_sound_banks) |
| 328 | if (offset == 0x04/2 && m_sound_banks) |
| 339 | 329 | return (space.machine().root_device().ioport(portnames[offset])->read() & 0xbf) | (upd7759_busy_r(space.machine().device("upd")) << 6); |
| 340 | 330 | return space.machine().root_device().ioport(portnames[offset])->read(); |
| 341 | 331 | |
| r22070 | r22071 | |
| 352 | 342 | /* CNT register & mirror */ |
| 353 | 343 | case 0x18/2: |
| 354 | 344 | case 0x1c/2: |
| 355 | | return state->m_misc_io_data[0x1c/2]; |
| 345 | return m_misc_io_data[0x1c/2]; |
| 356 | 346 | |
| 357 | 347 | /* port direction register & mirror */ |
| 358 | 348 | case 0x1a/2: |
| 359 | 349 | case 0x1e/2: |
| 360 | | return state->m_misc_io_data[0x1e/2]; |
| 350 | return m_misc_io_data[0x1e/2]; |
| 361 | 351 | } |
| 362 | 352 | return 0xffff; |
| 363 | 353 | } |
| 364 | 354 | |
| 365 | 355 | |
| 366 | | static WRITE16_HANDLER( io_chip_w ) |
| 356 | WRITE16_MEMBER(segac2_state::io_chip_w ) |
| 367 | 357 | { |
| 368 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 369 | 358 | UINT8 newbank; |
| 370 | 359 | // UINT8 old; |
| 371 | 360 | |
| 372 | 361 | /* generic implementation */ |
| 373 | 362 | offset &= 0x1f/2; |
| 374 | | // old = state->m_misc_io_data[offset]; |
| 375 | | state->m_misc_io_data[offset] = data; |
| 363 | // old = m_misc_io_data[offset]; |
| 364 | m_misc_io_data[offset] = data; |
| 376 | 365 | |
| 377 | 366 | switch (offset) |
| 378 | 367 | { |
| r22070 | r22071 | |
| 416 | 405 | D0 : To A9 of color RAM |
| 417 | 406 | */ |
| 418 | 407 | newbank = data & 3; |
| 419 | | if (newbank != state->m_palbank) |
| 408 | if (newbank != m_palbank) |
| 420 | 409 | { |
| 421 | 410 | //space.machine().primary_screen->update_partial(space.machine().primary_screen->vpos() + 1); |
| 422 | | state->m_palbank = newbank; |
| 423 | | recompute_palette_tables(space.machine()); |
| 411 | m_palbank = newbank; |
| 412 | recompute_palette_tables(); |
| 424 | 413 | } |
| 425 | | if (state->m_sound_banks > 1) |
| 414 | if (m_sound_banks > 1) |
| 426 | 415 | { |
| 427 | 416 | device_t *upd = space.machine().device("upd"); |
| 428 | | newbank = (data >> 2) & (state->m_sound_banks - 1); |
| 417 | newbank = (data >> 2) & (m_sound_banks - 1); |
| 429 | 418 | upd7759_set_bank_base(upd, newbank * 0x20000); |
| 430 | 419 | } |
| 431 | 420 | break; |
| 432 | 421 | |
| 433 | 422 | /* CNT register */ |
| 434 | 423 | case 0x1c/2: |
| 435 | | if (state->m_sound_banks > 1) |
| 424 | if (m_sound_banks > 1) |
| 436 | 425 | { |
| 437 | 426 | device_t *upd = space.machine().device("upd"); |
| 438 | 427 | upd7759_reset_w(upd, (data >> 1) & 1); |
| r22070 | r22071 | |
| 452 | 441 | |
| 453 | 442 | ******************************************************************************/ |
| 454 | 443 | |
| 455 | | static WRITE16_HANDLER( control_w ) |
| 444 | WRITE16_MEMBER(segac2_state::control_w ) |
| 456 | 445 | { |
| 457 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 458 | 446 | /* skip if not LSB */ |
| 459 | 447 | if (!ACCESSING_BITS_0_7) |
| 460 | 448 | return; |
| r22070 | r22071 | |
| 462 | 450 | |
| 463 | 451 | /* bit 0 controls display enable */ |
| 464 | 452 | //segac2_enable_display(space.machine(), ~data & 1); |
| 465 | | state->m_segac2_enable_display = ~data & 1; |
| 453 | m_segac2_enable_display = ~data & 1; |
| 466 | 454 | |
| 467 | 455 | /* bit 1 resets the protection */ |
| 468 | 456 | if (!(data & 2)) |
| 469 | | state->m_prot_write_buf = state->m_prot_read_buf = 0; |
| 457 | m_prot_write_buf = m_prot_read_buf = 0; |
| 470 | 458 | |
| 471 | 459 | /* bit 2 controls palette shuffling; only ribbit and twinsqua use this feature */ |
| 472 | | state->m_segac2_alt_palette_mode = ((~data & 4) >> 2); |
| 473 | | recompute_palette_tables(space.machine()); |
| 460 | m_segac2_alt_palette_mode = ((~data & 4) >> 2); |
| 461 | recompute_palette_tables(); |
| 474 | 462 | } |
| 475 | 463 | |
| 476 | 464 | |
| r22070 | r22071 | |
| 488 | 476 | ******************************************************************************/ |
| 489 | 477 | |
| 490 | 478 | /* protection chip reads */ |
| 491 | | static READ16_HANDLER( prot_r ) |
| 479 | READ16_MEMBER(segac2_state::prot_r ) |
| 492 | 480 | { |
| 493 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 494 | | if (LOG_PROTECTION) logerror("%06X:protection r=%02X\n", space.device().safe_pcbase(), state->m_prot_func ? state->m_prot_read_buf : 0xff); |
| 495 | | return state->m_prot_read_buf | 0xf0; |
| 481 | if (LOG_PROTECTION) logerror("%06X:protection r=%02X\n", space.device().safe_pcbase(), m_prot_func ? m_prot_read_buf : 0xff); |
| 482 | return m_prot_read_buf | 0xf0; |
| 496 | 483 | } |
| 497 | 484 | |
| 498 | 485 | |
| 499 | 486 | /* protection chip writes */ |
| 500 | | static WRITE16_HANDLER( prot_w ) |
| 487 | WRITE16_MEMBER(segac2_state::prot_w ) |
| 501 | 488 | { |
| 502 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 503 | 489 | int new_sp_palbase = (data >> 2) & 3; |
| 504 | 490 | int new_bg_palbase = data & 3; |
| 505 | 491 | int table_index; |
| r22070 | r22071 | |
| 509 | 495 | return; |
| 510 | 496 | |
| 511 | 497 | /* compute the table index */ |
| 512 | | table_index = (state->m_prot_write_buf << 4) | state->m_prot_read_buf; |
| 498 | table_index = (m_prot_write_buf << 4) | m_prot_read_buf; |
| 513 | 499 | |
| 514 | 500 | /* keep track of the last write for the next table lookup */ |
| 515 | | state->m_prot_write_buf = data & 0x0f; |
| 501 | m_prot_write_buf = data & 0x0f; |
| 516 | 502 | |
| 517 | 503 | /* determine the value to return, should a read occur */ |
| 518 | | if (state->m_prot_func) |
| 519 | | state->m_prot_read_buf = state->m_prot_func(table_index); |
| 520 | | if (LOG_PROTECTION) logerror("%06X:protection w=%02X, new result=%02X\n", space.device().safe_pcbase(), data & 0x0f, state->m_prot_read_buf); |
| 504 | if (m_prot_func) |
| 505 | m_prot_read_buf = m_prot_func(table_index); |
| 506 | if (LOG_PROTECTION) logerror("%06X:protection w=%02X, new result=%02X\n", space.device().safe_pcbase(), data & 0x0f, m_prot_read_buf); |
| 521 | 507 | |
| 522 | 508 | /* if the palette changed, force an update */ |
| 523 | | if (new_sp_palbase != state->m_sp_palbase || new_bg_palbase != state->m_bg_palbase) |
| 509 | if (new_sp_palbase != m_sp_palbase || new_bg_palbase != m_bg_palbase) |
| 524 | 510 | { |
| 525 | 511 | //space.machine().primary_screen->update_partial(space.machine().primary_screen->vpos() + 1); |
| 526 | | state->m_sp_palbase = new_sp_palbase; |
| 527 | | state->m_bg_palbase = new_bg_palbase; |
| 528 | | recompute_palette_tables(space.machine()); |
| 529 | | if (LOG_PALETTE) logerror("Set palbank: %d/%d (scan=%d)\n", state->m_bg_palbase, state->m_sp_palbase, space.machine().primary_screen->vpos()); |
| 512 | m_sp_palbase = new_sp_palbase; |
| 513 | m_bg_palbase = new_bg_palbase; |
| 514 | recompute_palette_tables(); |
| 515 | if (LOG_PALETTE) logerror("Set palbank: %d/%d (scan=%d)\n", m_bg_palbase, m_sp_palbase, space.machine().primary_screen->vpos()); |
| 530 | 516 | } |
| 531 | 517 | } |
| 532 | 518 | |
| r22070 | r22071 | |
| 542 | 528 | |
| 543 | 529 | ******************************************************************************/ |
| 544 | 530 | |
| 545 | | static WRITE16_HANDLER( counter_timer_w ) |
| 531 | WRITE16_MEMBER(segac2_state::counter_timer_w ) |
| 546 | 532 | { |
| 547 | 533 | /* only LSB matters */ |
| 548 | 534 | if (ACCESSING_BITS_0_7) |
| r22070 | r22071 | |
| 590 | 576 | |
| 591 | 577 | ******************************************************************************/ |
| 592 | 578 | |
| 593 | | static READ16_HANDLER( printer_r ) |
| 579 | READ16_MEMBER(segac2_state::printer_r ) |
| 594 | 580 | { |
| 595 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 596 | | return state->m_cam_data; |
| 581 | return m_cam_data; |
| 597 | 582 | } |
| 598 | 583 | |
| 599 | | static WRITE16_HANDLER( print_club_camera_w ) |
| 584 | WRITE16_MEMBER(segac2_state::print_club_camera_w ) |
| 600 | 585 | { |
| 601 | | segac2_state *state = space.machine().driver_data<segac2_state>(); |
| 602 | | state->m_cam_data = data; |
| 586 | m_cam_data = data; |
| 603 | 587 | } |
| 604 | 588 | |
| 605 | 589 | |
| r22070 | r22071 | |
| 615 | 599 | |
| 616 | 600 | static ADDRESS_MAP_START( main_map, AS_PROGRAM, 16, segac2_state ) |
| 617 | 601 | AM_RANGE(0x000000, 0x1fffff) AM_ROM |
| 618 | | AM_RANGE(0x800000, 0x800001) AM_MIRROR(0x13fdfe) AM_READWRITE_LEGACY(prot_r, prot_w) |
| 619 | | AM_RANGE(0x800200, 0x800201) AM_MIRROR(0x13fdfe) AM_WRITE_LEGACY(control_w) |
| 620 | | AM_RANGE(0x840000, 0x84001f) AM_MIRROR(0x13fee0) AM_READWRITE_LEGACY(io_chip_r, io_chip_w) |
| 602 | AM_RANGE(0x800000, 0x800001) AM_MIRROR(0x13fdfe) AM_READWRITE(prot_r, prot_w) |
| 603 | AM_RANGE(0x800200, 0x800201) AM_MIRROR(0x13fdfe) AM_WRITE(control_w) |
| 604 | AM_RANGE(0x840000, 0x84001f) AM_MIRROR(0x13fee0) AM_READWRITE(io_chip_r, io_chip_w) |
| 621 | 605 | AM_RANGE(0x840100, 0x840107) AM_MIRROR(0x13fef8) AM_DEVREADWRITE8_LEGACY("ymsnd", ym3438_r, ym3438_w, 0x00ff) |
| 622 | | AM_RANGE(0x880100, 0x880101) AM_MIRROR(0x13fefe) AM_WRITE_LEGACY(counter_timer_w) |
| 623 | | AM_RANGE(0x8c0000, 0x8c0fff) AM_MIRROR(0x13f000) AM_READWRITE_LEGACY(palette_r, palette_w) AM_SHARE("paletteram") |
| 606 | AM_RANGE(0x880100, 0x880101) AM_MIRROR(0x13fefe) AM_WRITE(counter_timer_w) |
| 607 | AM_RANGE(0x8c0000, 0x8c0fff) AM_MIRROR(0x13f000) AM_READWRITE(palette_r, palette_w) AM_SHARE("paletteram") |
| 624 | 608 | AM_RANGE(0xc00000, 0xc0001f) AM_MIRROR(0x18ff00) AM_DEVREADWRITE("gen_vdp", sega_genesis_vdp_device, megadriv_vdp_r,megadriv_vdp_w) |
| 625 | 609 | AM_RANGE(0xe00000, 0xe0ffff) AM_MIRROR(0x1f0000) AM_RAM AM_SHARE("nvram") |
| 626 | 610 | ADDRESS_MAP_END |
| r22070 | r22071 | |
| 1294 | 1278 | switch (src & 0x1c0) |
| 1295 | 1279 | { |
| 1296 | 1280 | case 0x000: |
| 1297 | | desty[x] = paldata[(src&0x0f) | segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x800]; |
| 1281 | desty[x] = paldata[(src&0x0f) | m_segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x800]; |
| 1298 | 1282 | break; |
| 1299 | 1283 | case 0x040: |
| 1300 | | desty[x] = paldata[(src&0x0f) | segac2_bg_pal_lookup[(src & 0x30)>>4]]; |
| 1284 | desty[x] = paldata[(src&0x0f) | m_segac2_bg_pal_lookup[(src & 0x30)>>4]]; |
| 1301 | 1285 | break; |
| 1302 | 1286 | case 0x080: |
| 1303 | | desty[x] = paldata[(src&0x0f) | segac2_sp_pal_lookup[(src & 0x30)>>4]]; |
| 1287 | desty[x] = paldata[(src&0x0f) | m_segac2_sp_pal_lookup[(src & 0x30)>>4]]; |
| 1304 | 1288 | break; |
| 1305 | 1289 | case 0x0c0: |
| 1306 | 1290 | // bg pen |
| 1307 | | desty[x] = paldata[(src&0x0f) | segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x1000]; |
| 1291 | desty[x] = paldata[(src&0x0f) | m_segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x1000]; |
| 1308 | 1292 | break; |
| 1309 | 1293 | case 0x100: |
| 1310 | 1294 | // shadow |
| 1311 | | desty[x] = paldata[(src&0x0f) | segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x800]; |
| 1295 | desty[x] = paldata[(src&0x0f) | m_segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x800]; |
| 1312 | 1296 | break; |
| 1313 | 1297 | case 0x140: |
| 1314 | 1298 | // normal |
| 1315 | | desty[x] = paldata[(src&0x0f) | segac2_bg_pal_lookup[(src & 0x30)>>4]]; |
| 1299 | desty[x] = paldata[(src&0x0f) | m_segac2_bg_pal_lookup[(src & 0x30)>>4]]; |
| 1316 | 1300 | break; |
| 1317 | 1301 | case 0x180: |
| 1318 | 1302 | // sprite |
| 1319 | | desty[x] = paldata[(src&0x0f) | segac2_sp_pal_lookup[(src & 0x30)>>4]]; |
| 1303 | desty[x] = paldata[(src&0x0f) | m_segac2_sp_pal_lookup[(src & 0x30)>>4]]; |
| 1320 | 1304 | break; |
| 1321 | 1305 | case 0x1c0: |
| 1322 | 1306 | // highlight |
| 1323 | | desty[x] = paldata[(src&0x0f) | segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x1000]; |
| 1307 | desty[x] = paldata[(src&0x0f) | m_segac2_bg_pal_lookup[(src & 0x30)>>4] | 0x1000]; |
| 1324 | 1308 | break; |
| 1325 | 1309 | } |
| 1326 | 1310 | } |
| r22070 | r22071 | |
| 1850 | 1834 | |
| 1851 | 1835 | ******************************************************************************/ |
| 1852 | 1836 | |
| 1853 | | void segac2_state::segac2_common_init(running_machine& machine, int (*func)(int in)) |
| 1837 | void segac2_state::segac2_common_init(int (*func)(int in)) |
| 1854 | 1838 | { |
| 1855 | | segac2_state *state = machine.driver_data<segac2_state>(); |
| 1856 | | device_t *upd = machine.device("upd"); |
| 1857 | | |
| 1858 | 1839 | DRIVER_INIT_CALL(megadriv_c2); |
| 1840 | device_t *upd = machine().device("upd"); |
| 1859 | 1841 | |
| 1860 | | state->m_prot_func = func; |
| 1842 | m_prot_func = func; |
| 1861 | 1843 | |
| 1862 | 1844 | if (upd != NULL) |
| 1863 | | machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(*upd, 0x880000, 0x880001, 0, 0x13fefe, FUNC(segac2_upd7759_w)); |
| 1845 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x880000, 0x880001, 0, 0x13fefe, write16_delegate(FUNC(segac2_state::segac2_upd7759_w),this)); |
| 1864 | 1846 | } |
| 1865 | 1847 | |
| 1866 | 1848 | |
| r22070 | r22071 | |
| 2090 | 2072 | |
| 2091 | 2073 | DRIVER_INIT_MEMBER(segac2_state,c2boot) |
| 2092 | 2074 | { |
| 2093 | | segac2_common_init(machine(), NULL); |
| 2075 | segac2_common_init(NULL); |
| 2094 | 2076 | } |
| 2095 | 2077 | |
| 2096 | 2078 | DRIVER_INIT_MEMBER(segac2_state,bloxeedc) |
| 2097 | 2079 | { |
| 2098 | | segac2_common_init(machine(), NULL); |
| 2080 | segac2_common_init(NULL); |
| 2099 | 2081 | } |
| 2100 | 2082 | |
| 2101 | 2083 | DRIVER_INIT_MEMBER(segac2_state,columns) |
| 2102 | 2084 | { |
| 2103 | | segac2_common_init(machine(), prot_func_columns); |
| 2085 | segac2_common_init(prot_func_columns); |
| 2104 | 2086 | } |
| 2105 | 2087 | |
| 2106 | 2088 | DRIVER_INIT_MEMBER(segac2_state,columns2) |
| 2107 | 2089 | { |
| 2108 | | segac2_common_init(machine(), prot_func_columns2); |
| 2090 | segac2_common_init(prot_func_columns2); |
| 2109 | 2091 | } |
| 2110 | 2092 | |
| 2111 | 2093 | DRIVER_INIT_MEMBER(segac2_state,tfrceac) |
| 2112 | 2094 | { |
| 2113 | | segac2_common_init(machine(), prot_func_tfrceac); |
| 2095 | segac2_common_init(prot_func_tfrceac); |
| 2114 | 2096 | } |
| 2115 | 2097 | |
| 2116 | 2098 | DRIVER_INIT_MEMBER(segac2_state,tfrceacb) |
| 2117 | 2099 | { |
| 2118 | 2100 | /* disable the palette bank switching from the protection chip */ |
| 2119 | | segac2_common_init(machine(), NULL); |
| 2101 | segac2_common_init(NULL); |
| 2120 | 2102 | machine().device("maincpu")->memory().space(AS_PROGRAM).nop_write(0x800000, 0x800001); |
| 2121 | 2103 | } |
| 2122 | 2104 | |
| 2123 | 2105 | DRIVER_INIT_MEMBER(segac2_state,borench) |
| 2124 | 2106 | { |
| 2125 | | segac2_common_init(machine(), prot_func_borench); |
| 2107 | segac2_common_init(prot_func_borench); |
| 2126 | 2108 | } |
| 2127 | 2109 | |
| 2128 | 2110 | DRIVER_INIT_MEMBER(segac2_state,twinsqua) |
| 2129 | 2111 | { |
| 2130 | | segac2_common_init(machine(), prot_func_twinsqua); |
| 2112 | segac2_common_init(prot_func_twinsqua); |
| 2131 | 2113 | } |
| 2132 | 2114 | |
| 2133 | 2115 | DRIVER_INIT_MEMBER(segac2_state,ribbit) |
| 2134 | 2116 | { |
| 2135 | | segac2_common_init(machine(), prot_func_ribbit); |
| 2117 | segac2_common_init(prot_func_ribbit); |
| 2136 | 2118 | } |
| 2137 | 2119 | |
| 2138 | 2120 | DRIVER_INIT_MEMBER(segac2_state,puyo) |
| 2139 | 2121 | { |
| 2140 | | segac2_common_init(machine(), prot_func_puyo); |
| 2122 | segac2_common_init(prot_func_puyo); |
| 2141 | 2123 | } |
| 2142 | 2124 | |
| 2143 | 2125 | DRIVER_INIT_MEMBER(segac2_state,tantr) |
| 2144 | 2126 | { |
| 2145 | | segac2_common_init(machine(), prot_func_tantr); |
| 2127 | segac2_common_init(prot_func_tantr); |
| 2146 | 2128 | } |
| 2147 | 2129 | |
| 2148 | 2130 | DRIVER_INIT_MEMBER(segac2_state,tantrkor) |
| 2149 | 2131 | { |
| 2150 | | segac2_common_init(machine(), prot_func_tantrkor); |
| 2132 | segac2_common_init(prot_func_tantrkor); |
| 2151 | 2133 | } |
| 2152 | 2134 | |
| 2153 | 2135 | DRIVER_INIT_MEMBER(segac2_state,potopoto) |
| 2154 | 2136 | { |
| 2155 | | segac2_common_init(machine(), prot_func_potopoto); |
| 2137 | segac2_common_init(prot_func_potopoto); |
| 2156 | 2138 | } |
| 2157 | 2139 | |
| 2158 | 2140 | DRIVER_INIT_MEMBER(segac2_state,stkclmns) |
| 2159 | 2141 | { |
| 2160 | | segac2_common_init(machine(), prot_func_stkclmns); |
| 2142 | segac2_common_init(prot_func_stkclmns); |
| 2161 | 2143 | } |
| 2162 | 2144 | |
| 2163 | 2145 | DRIVER_INIT_MEMBER(segac2_state,stkclmnj) |
| 2164 | 2146 | { |
| 2165 | | segac2_common_init(machine(), prot_func_stkclmnj); |
| 2147 | segac2_common_init(prot_func_stkclmnj); |
| 2166 | 2148 | } |
| 2167 | 2149 | |
| 2168 | 2150 | DRIVER_INIT_MEMBER(segac2_state,ichir) |
| 2169 | 2151 | { |
| 2170 | | segac2_common_init(machine(), prot_func_ichir); |
| 2152 | segac2_common_init(prot_func_ichir); |
| 2171 | 2153 | } |
| 2172 | 2154 | |
| 2173 | 2155 | DRIVER_INIT_MEMBER(segac2_state,ichirk) |
| 2174 | 2156 | { |
| 2175 | | segac2_common_init(machine(), prot_func_ichirk); |
| 2157 | segac2_common_init(prot_func_ichirk); |
| 2176 | 2158 | } |
| 2177 | 2159 | |
| 2178 | 2160 | DRIVER_INIT_MEMBER(segac2_state,ichirj) |
| 2179 | 2161 | { |
| 2180 | | segac2_common_init(machine(), prot_func_ichirj); |
| 2162 | segac2_common_init(prot_func_ichirj); |
| 2181 | 2163 | } |
| 2182 | 2164 | |
| 2183 | | static READ16_HANDLER( ichirjbl_prot_r ) |
| 2165 | READ16_MEMBER(segac2_state::ichirjbl_prot_r ) |
| 2184 | 2166 | { |
| 2185 | 2167 | return 0x00f5; |
| 2186 | 2168 | } |
| 2187 | 2169 | |
| 2188 | 2170 | DRIVER_INIT_MEMBER(segac2_state,ichirjbl) |
| 2189 | 2171 | { |
| 2190 | | segac2_common_init(machine(), NULL); |
| 2172 | segac2_common_init(NULL); |
| 2191 | 2173 | |
| 2192 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x840108, 0x840109, FUNC(ichirjbl_prot_r) ); |
| 2174 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x840108, 0x840109, read16_delegate(FUNC(segac2_state::ichirjbl_prot_r),this) ); |
| 2193 | 2175 | } |
| 2194 | 2176 | |
| 2195 | 2177 | DRIVER_INIT_MEMBER(segac2_state,puyopuy2) |
| 2196 | 2178 | { |
| 2197 | | segac2_common_init(machine(), prot_func_puyopuy2); |
| 2179 | segac2_common_init(prot_func_puyopuy2); |
| 2198 | 2180 | } |
| 2199 | 2181 | |
| 2200 | 2182 | DRIVER_INIT_MEMBER(segac2_state,zunkyou) |
| 2201 | 2183 | { |
| 2202 | | segac2_common_init(machine(), prot_func_zunkyou); |
| 2184 | segac2_common_init(prot_func_zunkyou); |
| 2203 | 2185 | } |
| 2204 | 2186 | |
| 2205 | 2187 | |
| 2206 | 2188 | DRIVER_INIT_MEMBER(segac2_state,pclub) |
| 2207 | 2189 | { |
| 2208 | | segac2_common_init(machine(), prot_func_pclub); |
| 2190 | segac2_common_init(prot_func_pclub); |
| 2209 | 2191 | |
| 2210 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880120, 0x880121, FUNC(printer_r) );/*Print Club Vol.1*/ |
| 2211 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880124, 0x880125, FUNC(printer_r) );/*Print Club Vol.2*/ |
| 2212 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x880124, 0x880125, FUNC(print_club_camera_w)); |
| 2192 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880120, 0x880121, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.1*/ |
| 2193 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880124, 0x880125, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.2*/ |
| 2194 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x880124, 0x880125, write16_delegate(FUNC(segac2_state::print_club_camera_w),this)); |
| 2213 | 2195 | } |
| 2214 | 2196 | |
| 2215 | 2197 | DRIVER_INIT_MEMBER(segac2_state,pclubjv2) |
| 2216 | 2198 | { |
| 2217 | | segac2_common_init(machine(), prot_func_pclubjv2); |
| 2199 | segac2_common_init(prot_func_pclubjv2); |
| 2218 | 2200 | |
| 2219 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880120, 0x880121, FUNC(printer_r) );/*Print Club Vol.1*/ |
| 2220 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880124, 0x880125, FUNC(printer_r) );/*Print Club Vol.2*/ |
| 2221 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x880124, 0x880125, FUNC(print_club_camera_w)); |
| 2201 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880120, 0x880121, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.1*/ |
| 2202 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880124, 0x880125, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.2*/ |
| 2203 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x880124, 0x880125, write16_delegate(FUNC(segac2_state::print_club_camera_w),this)); |
| 2222 | 2204 | } |
| 2223 | 2205 | |
| 2224 | 2206 | DRIVER_INIT_MEMBER(segac2_state,pclubjv4) |
| 2225 | 2207 | { |
| 2226 | | segac2_common_init(machine(), prot_func_pclubjv4); |
| 2208 | segac2_common_init(prot_func_pclubjv4); |
| 2227 | 2209 | |
| 2228 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880120, 0x880121, FUNC(printer_r) );/*Print Club Vol.1*/ |
| 2229 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880124, 0x880125, FUNC(printer_r) );/*Print Club Vol.2*/ |
| 2230 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x880124, 0x880125, FUNC(print_club_camera_w)); |
| 2210 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880120, 0x880121, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.1*/ |
| 2211 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880124, 0x880125, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.2*/ |
| 2212 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x880124, 0x880125, write16_delegate(FUNC(segac2_state::print_club_camera_w),this)); |
| 2231 | 2213 | } |
| 2232 | 2214 | |
| 2233 | 2215 | DRIVER_INIT_MEMBER(segac2_state,pclubjv5) |
| 2234 | 2216 | { |
| 2235 | | segac2_common_init(machine(), prot_func_pclubjv5); |
| 2217 | segac2_common_init(prot_func_pclubjv5); |
| 2236 | 2218 | |
| 2237 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880120, 0x880121, FUNC(printer_r) );/*Print Club Vol.1*/ |
| 2238 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x880124, 0x880125, FUNC(printer_r) );/*Print Club Vol.2*/ |
| 2239 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x880124, 0x880125, FUNC(print_club_camera_w)); |
| 2219 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880120, 0x880121, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.1*/ |
| 2220 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x880124, 0x880125, read16_delegate(FUNC(segac2_state::printer_r),this) );/*Print Club Vol.2*/ |
| 2221 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x880124, 0x880125, write16_delegate(FUNC(segac2_state::print_club_camera_w),this)); |
| 2240 | 2222 | } |
| 2241 | 2223 | |
| 2242 | 2224 | |
trunk/src/mame/drivers/megatech.c
| r22070 | r22071 | |
| 207 | 207 | INPUT_PORTS_END |
| 208 | 208 | |
| 209 | 209 | /* MEGATECH specific */ |
| 210 | | static READ8_HANDLER( megatech_cart_select_r ) |
| 210 | READ8_MEMBER(mtech_state::megatech_cart_select_r ) |
| 211 | 211 | { |
| 212 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 213 | | return state->m_mt_cart_select_reg; |
| 212 | return m_mt_cart_select_reg; |
| 214 | 213 | } |
| 215 | 214 | |
| 216 | 215 | |
| 217 | 216 | |
| 218 | | static TIMER_CALLBACK( megatech_z80_run_state ) |
| 217 | TIMER_CALLBACK_MEMBER(mtech_state::megatech_z80_run_state ) |
| 219 | 218 | { |
| 220 | | mtech_state *state = machine.driver_data<mtech_state>(); |
| 221 | 219 | char tempname[20]; |
| 222 | 220 | UINT8* game_region; |
| 223 | 221 | |
| 224 | 222 | sprintf(tempname, "game%d", param); |
| 225 | | game_region = state->memregion(tempname)->base(); |
| 223 | game_region = memregion(tempname)->base(); |
| 226 | 224 | |
| 227 | | memcpy(state->memregion("maincpu")->base(), game_region, 0x400000); |
| 225 | memcpy(memregion("maincpu")->base(), game_region, 0x400000); |
| 228 | 226 | |
| 229 | | if (!state->m_cart_is_genesis[param]) |
| 227 | if (!m_cart_is_genesis[param]) |
| 230 | 228 | { |
| 231 | 229 | printf("enabling SMS Z80\n"); |
| 232 | | state->m_current_game_is_sms = 1; |
| 233 | | megatech_set_genz80_as_sms_standard_map(machine, "genesis_snd_z80", MAPPER_STANDARD); |
| 230 | m_current_game_is_sms = 1; |
| 231 | megatech_set_genz80_as_sms_standard_map(machine(), "genesis_snd_z80", MAPPER_STANDARD); |
| 234 | 232 | //machine.device("genesis_snd_z80")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 235 | | machine.device("genesis_snd_z80")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 233 | machine().device("genesis_snd_z80")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 236 | 234 | } |
| 237 | 235 | else |
| 238 | 236 | { |
| 239 | 237 | printf("disabling SMS Z80\n"); |
| 240 | | state->m_current_game_is_sms = 0; |
| 241 | | state->megatech_set_megadrive_z80_as_megadrive_z80("genesis_snd_z80"); |
| 242 | | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 238 | m_current_game_is_sms = 0; |
| 239 | megatech_set_megadrive_z80_as_megadrive_z80("genesis_snd_z80"); |
| 240 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 243 | 241 | //machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 244 | 242 | } |
| 245 | 243 | } |
| 246 | 244 | |
| 247 | | static TIMER_CALLBACK( megatech_z80_stop_state ) |
| 245 | TIMER_CALLBACK_MEMBER(mtech_state::megatech_z80_stop_state ) |
| 248 | 246 | { |
| 249 | 247 | UINT8* game_region; |
| 250 | 248 | char tempname[20]; |
| r22070 | r22071 | |
| 252 | 250 | printf("megatech_select_game %d\n", param+1); |
| 253 | 251 | |
| 254 | 252 | sprintf(tempname, "game%d", param); |
| 255 | | game_region = machine.root_device().memregion(tempname)->base(); |
| 253 | game_region = machine().root_device().memregion(tempname)->base(); |
| 256 | 254 | |
| 257 | | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 258 | | machine.device("genesis_snd_z80")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 255 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 256 | machine().device("genesis_snd_z80")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 259 | 257 | //machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 260 | 258 | //machine.device("genesis_snd_z80")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 261 | | machine.device("ymsnd")->reset(); |
| 259 | machine().device("ymsnd")->reset(); |
| 262 | 260 | |
| 263 | | megadriv_stop_scanline_timer(machine);// stop the scanline timer for the genesis vdp... it can be restarted in video eof when needed |
| 261 | megadriv_stop_scanline_timer();// stop the scanline timer for the genesis vdp... it can be restarted in video eof when needed |
| 264 | 262 | segae_md_sms_stop_scanline_timer();// stop the scanline timer for the sms vdp |
| 265 | 263 | |
| 266 | 264 | |
| r22070 | r22071 | |
| 268 | 266 | if (game_region) |
| 269 | 267 | { |
| 270 | 268 | { |
| 271 | | machine.scheduler().timer_set(attotime::zero, FUNC(megatech_z80_run_state), param); |
| 269 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(mtech_state::megatech_z80_run_state),this), param); |
| 272 | 270 | } |
| 273 | 271 | } |
| 274 | 272 | else |
| 275 | 273 | { |
| 276 | 274 | /* no cart.. */ |
| 277 | | memset(machine.root_device().memregion("mtbios")->base() + 0x8000, 0x00, 0x8000); |
| 278 | | memset(machine.root_device().memregion("maincpu")->base(), 0x00, 0x400000); |
| 275 | memset(machine().root_device().memregion("mtbios")->base() + 0x8000, 0x00, 0x8000); |
| 276 | memset(machine().root_device().memregion("maincpu")->base(), 0x00, 0x400000); |
| 279 | 277 | } |
| 280 | 278 | |
| 281 | 279 | return; |
| 282 | 280 | } |
| 283 | 281 | |
| 284 | | static void megatech_select_game(running_machine &machine, int gameno) |
| 282 | void mtech_state::megatech_select_game(int gameno) |
| 285 | 283 | { |
| 286 | | machine.scheduler().timer_set(attotime::zero, FUNC(megatech_z80_stop_state), gameno); |
| 284 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(mtech_state::megatech_z80_stop_state),this), gameno); |
| 287 | 285 | } |
| 288 | 286 | |
| 289 | | static WRITE8_HANDLER( megatech_cart_select_w ) |
| 287 | WRITE8_MEMBER(mtech_state::megatech_cart_select_w ) |
| 290 | 288 | { |
| 291 | 289 | /* seems to write the slot number.. |
| 292 | 290 | but it stores something in (banked?) ram |
| 293 | 291 | because it always seems to show the |
| 294 | 292 | same instructions ... */ |
| 295 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 296 | | state->m_mt_cart_select_reg = data; |
| 293 | m_mt_cart_select_reg = data; |
| 297 | 294 | |
| 298 | | megatech_select_game(space.machine(), state->m_mt_cart_select_reg); |
| 295 | megatech_select_game(m_mt_cart_select_reg); |
| 299 | 296 | } |
| 300 | 297 | |
| 301 | 298 | |
| 302 | | static READ8_HANDLER( bios_ctrl_r ) |
| 299 | READ8_MEMBER(mtech_state::bios_ctrl_r ) |
| 303 | 300 | { |
| 304 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 305 | | |
| 306 | 301 | if (offset == 0) |
| 307 | 302 | return 0; |
| 308 | 303 | if (offset == 2) |
| 309 | | return state->m_bios_ctrl[offset] & 0xfe; |
| 304 | return m_bios_ctrl[offset] & 0xfe; |
| 310 | 305 | |
| 311 | | return state->m_bios_ctrl[offset]; |
| 306 | return m_bios_ctrl[offset]; |
| 312 | 307 | } |
| 313 | 308 | |
| 314 | | static WRITE8_HANDLER( bios_ctrl_w ) |
| 309 | WRITE8_MEMBER(mtech_state::bios_ctrl_w ) |
| 315 | 310 | { |
| 316 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 317 | | |
| 318 | 311 | if (offset == 1) |
| 319 | 312 | { |
| 320 | 313 | output_set_value("Alarm_sound", data>>7 & 0x01); |
| 321 | | state->m_bios_ctrl_inputs = data & 0x04; // Genesis/SMS input ports disable bit |
| 314 | m_bios_ctrl_inputs = data & 0x04; // Genesis/SMS input ports disable bit |
| 322 | 315 | } |
| 323 | 316 | else if (offset == 2) |
| 324 | 317 | { |
| 325 | 318 | output_set_value("Flash_screen", data>>1 & 0x01); |
| 326 | 319 | } |
| 327 | 320 | |
| 328 | | state->m_bios_ctrl[offset] = data; |
| 321 | m_bios_ctrl[offset] = data; |
| 329 | 322 | } |
| 330 | 323 | |
| 331 | 324 | /* this sets 0x300000 which may indicate that the 68k can see the instruction rom |
| 332 | 325 | there, this limiting the max game rom capacity to 3meg. */ |
| 333 | 326 | |
| 334 | | static READ8_HANDLER( megatech_z80_read_68k_banked_data ) |
| 327 | READ8_MEMBER(mtech_state::megatech_z80_read_68k_banked_data ) |
| 335 | 328 | { |
| 336 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 337 | 329 | address_space &space68k = space.machine().device<legacy_cpu_device>("maincpu")->space(); |
| 338 | | UINT8 ret = space68k.read_byte(state->m_mt_bank_addr + offset); |
| 330 | UINT8 ret = space68k.read_byte(m_mt_bank_addr + offset); |
| 339 | 331 | return ret; |
| 340 | 332 | } |
| 341 | 333 | |
| 342 | | static WRITE8_HANDLER( megatech_z80_write_68k_banked_data ) |
| 334 | WRITE8_MEMBER(mtech_state::megatech_z80_write_68k_banked_data ) |
| 343 | 335 | { |
| 344 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 345 | 336 | address_space &space68k = space.machine().device<legacy_cpu_device>("maincpu")->space(); |
| 346 | | space68k.write_byte(state->m_mt_bank_addr + offset,data); |
| 337 | space68k.write_byte(m_mt_bank_addr + offset,data); |
| 347 | 338 | } |
| 348 | 339 | |
| 349 | | static void megatech_z80_bank_w(running_machine &machine, UINT16 data) |
| 340 | void mtech_state::megatech_z80_bank_w(UINT16 data) |
| 350 | 341 | { |
| 351 | | mtech_state *state = machine.driver_data<mtech_state>(); |
| 352 | | state->m_mt_bank_addr = ((state->m_mt_bank_addr >> 1) | (data << 23)) & 0xff8000; |
| 342 | m_mt_bank_addr = ((m_mt_bank_addr >> 1) | (data << 23)) & 0xff8000; |
| 353 | 343 | } |
| 354 | 344 | |
| 355 | | static WRITE8_HANDLER( mt_z80_bank_w ) |
| 345 | WRITE8_MEMBER(mtech_state::mt_z80_bank_w ) |
| 356 | 346 | { |
| 357 | | megatech_z80_bank_w(space.machine(), data & 1); |
| 347 | megatech_z80_bank_w(data & 1); |
| 358 | 348 | } |
| 359 | 349 | |
| 360 | | static READ8_HANDLER( megatech_banked_ram_r ) |
| 350 | READ8_MEMBER(mtech_state::megatech_banked_ram_r ) |
| 361 | 351 | { |
| 362 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 363 | | return state->m_megatech_banked_ram[offset + 0x1000 * (state->m_mt_cart_select_reg & 0x07)]; |
| 352 | return m_megatech_banked_ram[offset + 0x1000 * (m_mt_cart_select_reg & 0x07)]; |
| 364 | 353 | } |
| 365 | 354 | |
| 366 | | static WRITE8_HANDLER( megatech_banked_ram_w ) |
| 355 | WRITE8_MEMBER(mtech_state::megatech_banked_ram_w ) |
| 367 | 356 | { |
| 368 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 369 | | state->m_megatech_banked_ram[offset + 0x1000 * (state->m_mt_cart_select_reg & 0x07)] = data; |
| 357 | m_megatech_banked_ram[offset + 0x1000 * (m_mt_cart_select_reg & 0x07)] = data; |
| 370 | 358 | } |
| 371 | 359 | |
| 372 | 360 | |
| 373 | 361 | |
| 374 | 362 | static ADDRESS_MAP_START( megatech_bios_map, AS_PROGRAM, 8, mtech_state ) |
| 375 | 363 | AM_RANGE(0x0000, 0x2fff) AM_ROM // from bios rom (0x0000-0x2fff populated in ROM) |
| 376 | | AM_RANGE(0x3000, 0x3fff) AM_READWRITE_LEGACY(megatech_banked_ram_r, megatech_banked_ram_w) // copies instruction data here at startup, must be banked |
| 364 | AM_RANGE(0x3000, 0x3fff) AM_READWRITE(megatech_banked_ram_r, megatech_banked_ram_w) // copies instruction data here at startup, must be banked |
| 377 | 365 | AM_RANGE(0x4000, 0x5fff) AM_RAM // plain ram? |
| 378 | | AM_RANGE(0x6000, 0x6000) AM_WRITE_LEGACY(mt_z80_bank_w ) |
| 366 | AM_RANGE(0x6000, 0x6000) AM_WRITE(mt_z80_bank_w ) |
| 379 | 367 | AM_RANGE(0x6400, 0x6400) AM_READ_PORT("BIOS_DSW0") |
| 380 | 368 | AM_RANGE(0x6401, 0x6401) AM_READ_PORT("BIOS_DSW1") |
| 381 | | AM_RANGE(0x6404, 0x6404) AM_READWRITE_LEGACY(megatech_cart_select_r, megatech_cart_select_w) // cart select & ram bank |
| 369 | AM_RANGE(0x6404, 0x6404) AM_READWRITE(megatech_cart_select_r, megatech_cart_select_w) // cart select & ram bank |
| 382 | 370 | AM_RANGE(0x6800, 0x6800) AM_READ_PORT("BIOS_IN0") |
| 383 | 371 | AM_RANGE(0x6801, 0x6801) AM_READ_PORT("BIOS_IN1") |
| 384 | | AM_RANGE(0x6802, 0x6807) AM_READWRITE_LEGACY(bios_ctrl_r, bios_ctrl_w) |
| 372 | AM_RANGE(0x6802, 0x6807) AM_READWRITE(bios_ctrl_r, bios_ctrl_w) |
| 385 | 373 | // AM_RANGE(0x6805, 0x6805) AM_READ_PORT("???") |
| 386 | 374 | AM_RANGE(0x7000, 0x77ff) AM_ROM // from bios rom (0x7000-0x77ff populated in ROM) |
| 387 | 375 | //AM_RANGE(0x7800, 0x7fff) AM_RAM // ? |
| 388 | | AM_RANGE(0x8000, 0x9fff) AM_READWRITE_LEGACY(megatech_z80_read_68k_banked_data, megatech_z80_write_68k_banked_data) // window into 68k address space, reads instr rom and writes to reset banks on z80 carts? |
| 376 | AM_RANGE(0x8000, 0x9fff) AM_READWRITE(megatech_z80_read_68k_banked_data, megatech_z80_write_68k_banked_data) // window into 68k address space, reads instr rom and writes to reset banks on z80 carts? |
| 389 | 377 | ADDRESS_MAP_END |
| 390 | 378 | |
| 391 | 379 | |
| 392 | | static WRITE8_HANDLER( megatech_bios_port_ctrl_w ) |
| 380 | WRITE8_MEMBER(mtech_state::megatech_bios_port_ctrl_w ) |
| 393 | 381 | { |
| 394 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 395 | | state->m_bios_port_ctrl = data; |
| 382 | m_bios_port_ctrl = data; |
| 396 | 383 | } |
| 397 | 384 | |
| 398 | | static READ8_HANDLER( megatech_bios_joypad_r ) |
| 385 | READ8_MEMBER(mtech_state::megatech_bios_joypad_r ) |
| 399 | 386 | { |
| 400 | | mtech_state *state = space.machine().driver_data<mtech_state>(); |
| 401 | | return megatech_bios_port_cc_dc_r(space.machine(), offset, state->m_bios_port_ctrl); |
| 387 | return megatech_bios_port_cc_dc_r(offset, m_bios_port_ctrl); |
| 402 | 388 | } |
| 403 | 389 | |
| 404 | | static WRITE8_HANDLER (megatech_bios_port_7f_w) |
| 390 | WRITE8_MEMBER(mtech_state::megatech_bios_port_7f_w) |
| 405 | 391 | { |
| 406 | 392 | // popmessage("CPU #3: I/O port 0x7F write, data %02x", data); |
| 407 | 393 | } |
| r22070 | r22071 | |
| 410 | 396 | |
| 411 | 397 | static ADDRESS_MAP_START( megatech_bios_portmap, AS_IO, 8, mtech_state ) |
| 412 | 398 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 413 | | AM_RANGE(0x3f, 0x3f) AM_WRITE_LEGACY(megatech_bios_port_ctrl_w) |
| 399 | AM_RANGE(0x3f, 0x3f) AM_WRITE(megatech_bios_port_ctrl_w) |
| 414 | 400 | |
| 415 | | AM_RANGE(0x7f, 0x7f) AM_READWRITE_LEGACY(sms_vcounter_r, megatech_bios_port_7f_w) |
| 401 | AM_RANGE(0x7f, 0x7f) AM_READ_LEGACY(sms_vcounter_r) AM_WRITE(megatech_bios_port_7f_w) |
| 416 | 402 | AM_RANGE(0xbe, 0xbe) AM_DEVREADWRITE( "vdp1", sega315_5124_device, vram_read, vram_write ) |
| 417 | 403 | AM_RANGE(0xbf, 0xbf) AM_DEVREADWRITE( "vdp1", sega315_5124_device, register_read, register_write ) |
| 418 | 404 | |
| 419 | | AM_RANGE(0xdc, 0xdd) AM_READ_LEGACY(megatech_bios_joypad_r) // player inputs |
| 405 | AM_RANGE(0xdc, 0xdd) AM_READ(megatech_bios_joypad_r) // player inputs |
| 420 | 406 | ADDRESS_MAP_END |
| 421 | 407 | |
| 422 | 408 | |
| r22070 | r22071 | |
| 471 | 457 | |
| 472 | 458 | MACHINE_RESET_CALL_LEGACY(megadriv); |
| 473 | 459 | MACHINE_RESET_CALL_LEGACY(megatech_md_sms); |
| 474 | | megatech_select_game(machine(), 0); |
| 460 | megatech_select_game(0); |
| 475 | 461 | } |
| 476 | 462 | |
| 477 | 463 | UINT32 mtech_state::screen_update_megatech_menu(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| r22070 | r22071 | |
| 568 | 554 | |
| 569 | 555 | DEVICE_IMAGE_LOAD_MEMBER( mtech_state, megatech_cart ) |
| 570 | 556 | { |
| 571 | | mtech_state *state = image.device().machine().driver_data<mtech_state>(); |
| 572 | 557 | const struct megatech_cart_region *mt_cart = &megatech_cart_table[0], *this_cart; |
| 573 | 558 | const char *pcb_name; |
| 574 | 559 | |
| r22070 | r22071 | |
| 598 | 583 | if (!mame_stricmp("genesis", pcb_name)) |
| 599 | 584 | { |
| 600 | 585 | mame_printf_debug("%s is genesis\n", mt_cart->tag); |
| 601 | | state->m_cart_is_genesis[this_cart->slot] = 1; |
| 586 | m_cart_is_genesis[this_cart->slot] = 1; |
| 602 | 587 | } |
| 603 | 588 | else if (!mame_stricmp("sms", pcb_name)) |
| 604 | 589 | { |
| 605 | 590 | mame_printf_debug("%s is sms\n", mt_cart->tag); |
| 606 | | state->m_cart_is_genesis[this_cart->slot] = 0; |
| 591 | m_cart_is_genesis[this_cart->slot] = 0; |
| 607 | 592 | } |
| 608 | 593 | else |
| 609 | 594 | { |
trunk/src/mame/machine/megadriv.c
| r22070 | r22071 | |
| 93 | 93 | } |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | | /* Megadrive / Genesis has 3 I/O ports */ |
| 97 | | static emu_timer *m_io_timeout[3]; |
| 98 | | static int m_io_stage[3]; |
| 99 | | |
| 100 | | static TIMER_CALLBACK( io_timeout_timer_callback ) |
| 96 | TIMER_CALLBACK_MEMBER(md_base_state::io_timeout_timer_callback) |
| 101 | 97 | { |
| 102 | 98 | m_io_stage[(int)(FPTR)ptr] = -1; |
| 103 | 99 | } |
| 104 | 100 | |
| 105 | | static void init_megadri6_io(running_machine &machine) |
| 101 | void md_base_state::init_megadri6_io() |
| 106 | 102 | { |
| 107 | 103 | int i; |
| 108 | 104 | |
| 109 | 105 | for (i=0; i<3; i++) |
| 110 | 106 | { |
| 111 | | m_io_timeout[i] = machine.scheduler().timer_alloc(FUNC(io_timeout_timer_callback), (void*)(FPTR)i); |
| 107 | m_io_timeout[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(md_base_state::io_timeout_timer_callback),this), (void*)(FPTR)i); |
| 112 | 108 | } |
| 113 | 109 | } |
| 114 | 110 | |
| 115 | | /* pointers to our io data read/write functions */ |
| 116 | | UINT8 (*megadrive_io_read_data_port_ptr)(running_machine &machine, int offset); |
| 117 | | void (*megadrive_io_write_data_port_ptr)(running_machine &machine, int offset, UINT16 data); |
| 118 | | |
| 119 | 111 | /* |
| 120 | 112 | |
| 121 | 113 | A10001h = A0 Version register |
| r22070 | r22071 | |
| 201 | 193 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_PLAYER(2) PORT_NAME("P2 MODE") // mode |
| 202 | 194 | INPUT_PORTS_END |
| 203 | 195 | |
| 204 | | UINT8 m_megadrive_io_data_regs[3]; |
| 205 | | UINT8 m_megadrive_io_ctrl_regs[3]; |
| 206 | | static UINT8 m_megadrive_io_tx_regs[3]; |
| 207 | | int m_megadrive_6buttons_pad = 0; |
| 208 | | |
| 209 | | static void megadrive_reset_io(running_machine &machine) |
| 196 | void md_base_state::megadrive_reset_io() |
| 210 | 197 | { |
| 211 | 198 | int i; |
| 212 | 199 | |
| r22070 | r22071 | |
| 227 | 214 | } |
| 228 | 215 | |
| 229 | 216 | /************* 6 buttons version **************************/ |
| 230 | | static UINT8 megadrive_io_read_data_port_6button(running_machine &machine, int portnum) |
| 217 | READ8_MEMBER(md_base_state::megadrive_io_read_data_port_6button) |
| 231 | 218 | { |
| 219 | int portnum = offset; |
| 232 | 220 | UINT8 retdata, helper = (m_megadrive_io_ctrl_regs[portnum] & 0x3f) | 0xc0; // bits 6 & 7 always come from m_megadrive_io_data_regs |
| 233 | 221 | static const char *const pad3names[] = { "PAD1", "PAD2", "IN0", "UNK" }; |
| 234 | 222 | static const char *const pad6names[] = { "EXTRA1", "EXTRA2", "IN0", "UNK" }; |
| r22070 | r22071 | |
| 239 | 227 | { |
| 240 | 228 | /* here we read B, C & the additional buttons */ |
| 241 | 229 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 242 | | (((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x30) | |
| 243 | | (machine.root_device().ioport(pad6names[portnum])->read_safe(0) & 0x0f)) & ~helper); |
| 230 | (((ioport(pad3names[portnum])->read_safe(0) & 0x30) | |
| 231 | (ioport(pad6names[portnum])->read_safe(0) & 0x0f)) & ~helper); |
| 244 | 232 | } |
| 245 | 233 | else |
| 246 | 234 | { |
| 247 | 235 | /* here we read B, C & the directional buttons */ |
| 248 | 236 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 249 | | ((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x3f) & ~helper); |
| 237 | ((ioport(pad3names[portnum])->read_safe(0) & 0x3f) & ~helper); |
| 250 | 238 | } |
| 251 | 239 | } |
| 252 | 240 | else |
| r22070 | r22071 | |
| 255 | 243 | { |
| 256 | 244 | /* here we read ((Start & A) >> 2) | 0x00 */ |
| 257 | 245 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 258 | | (((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) & ~helper); |
| 246 | (((ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) & ~helper); |
| 259 | 247 | } |
| 260 | 248 | else if (m_io_stage[portnum]==2) |
| 261 | 249 | { |
| 262 | 250 | /* here we read ((Start & A) >> 2) | 0x0f */ |
| 263 | 251 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 264 | | ((((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | 0x0f) & ~helper); |
| 252 | ((((ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | 0x0f) & ~helper); |
| 265 | 253 | } |
| 266 | 254 | else |
| 267 | 255 | { |
| 268 | 256 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 269 | 257 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 270 | | ((((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 271 | | (machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x03)) & ~helper); |
| 258 | ((((ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 259 | (ioport(pad3names[portnum])->read_safe(0) & 0x03)) & ~helper); |
| 272 | 260 | } |
| 273 | 261 | } |
| 274 | 262 | |
| r22070 | r22071 | |
| 279 | 267 | |
| 280 | 268 | |
| 281 | 269 | /************* 3 buttons version **************************/ |
| 282 | | UINT8 megadrive_io_read_data_port_3button(running_machine &machine, int portnum) |
| 270 | READ8_MEMBER(md_base_state::megadrive_io_read_data_port_3button) |
| 283 | 271 | { |
| 272 | int portnum = offset; |
| 284 | 273 | UINT8 retdata, helper = (m_megadrive_io_ctrl_regs[portnum] & 0x7f) | 0x80; // bit 7 always comes from m_megadrive_io_data_regs |
| 285 | 274 | static const char *const pad3names[] = { "PAD1", "PAD2", "IN0", "UNK" }; |
| 286 | 275 | |
| r22070 | r22071 | |
| 288 | 277 | { |
| 289 | 278 | /* here we read B, C & the directional buttons */ |
| 290 | 279 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 291 | | (((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x3f) | 0x40) & ~helper); |
| 280 | (((ioport(pad3names[portnum])->read_safe(0) & 0x3f) | 0x40) & ~helper); |
| 292 | 281 | } |
| 293 | 282 | else |
| 294 | 283 | { |
| 295 | 284 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 296 | 285 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 297 | | ((((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 298 | | (machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x03) | 0x40) & ~helper); |
| 286 | ((((ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 287 | (ioport(pad3names[portnum])->read_safe(0) & 0x03) | 0x40) & ~helper); |
| 299 | 288 | } |
| 300 | 289 | |
| 301 | 290 | return retdata; |
| 302 | 291 | } |
| 303 | 292 | |
| 304 | 293 | /* used by megatech bios, the test mode accesses the joypad/stick inputs like this */ |
| 305 | | UINT8 megatech_bios_port_cc_dc_r(running_machine &machine, int offset, int ctrl) |
| 294 | UINT8 md_base_state::megatech_bios_port_cc_dc_r(int offset, int ctrl) |
| 306 | 295 | { |
| 307 | 296 | UINT8 retdata; |
| 308 | 297 | |
| 309 | 298 | if (ctrl == 0x55) |
| 310 | 299 | { |
| 311 | 300 | /* A keys */ |
| 312 | | retdata = ((machine.root_device().ioport("PAD1")->read() & 0x40) >> 2) | |
| 313 | | ((machine.root_device().ioport("PAD2")->read() & 0x40) >> 4) | 0xeb; |
| 301 | retdata = ((ioport("PAD1")->read() & 0x40) >> 2) | |
| 302 | ((ioport("PAD2")->read() & 0x40) >> 4) | 0xeb; |
| 314 | 303 | } |
| 315 | 304 | else |
| 316 | 305 | { |
| 317 | 306 | if (offset == 0) |
| 318 | 307 | { |
| 319 | | retdata = (machine.root_device().ioport("PAD1")->read() & 0x3f) | ((machine.root_device().ioport("PAD2")->read() & 0x03) << 6); |
| 308 | retdata = (ioport("PAD1")->read() & 0x3f) | ((ioport("PAD2")->read() & 0x03) << 6); |
| 320 | 309 | } |
| 321 | 310 | else |
| 322 | 311 | { |
| 323 | | retdata = ((machine.root_device().ioport("PAD2")->read() & 0x3c) >> 2) | 0xf0; |
| 312 | retdata = ((ioport("PAD2")->read() & 0x3c) >> 2) | 0xf0; |
| 324 | 313 | } |
| 325 | 314 | |
| 326 | 315 | } |
| r22070 | r22071 | |
| 328 | 317 | return retdata; |
| 329 | 318 | } |
| 330 | 319 | |
| 331 | | static UINT8 megadrive_io_read_ctrl_port(int portnum) |
| 320 | UINT8 md_base_state::megadrive_io_read_ctrl_port(int portnum) |
| 332 | 321 | { |
| 333 | 322 | UINT8 retdata; |
| 334 | 323 | retdata = m_megadrive_io_ctrl_regs[portnum]; |
| r22070 | r22071 | |
| 337 | 326 | return retdata | (retdata << 8); |
| 338 | 327 | } |
| 339 | 328 | |
| 340 | | static UINT8 megadrive_io_read_tx_port(int portnum) |
| 329 | UINT8 md_base_state::megadrive_io_read_tx_port(int portnum) |
| 341 | 330 | { |
| 342 | 331 | UINT8 retdata; |
| 343 | 332 | retdata = m_megadrive_io_tx_regs[portnum]; |
| 344 | 333 | return retdata | (retdata << 8); |
| 345 | 334 | } |
| 346 | 335 | |
| 347 | | static UINT8 megadrive_io_read_rx_port(int portnum) |
| 336 | UINT8 md_base_state::megadrive_io_read_rx_port(int portnum) |
| 348 | 337 | { |
| 349 | 338 | return 0x00; |
| 350 | 339 | } |
| 351 | 340 | |
| 352 | | static UINT8 megadrive_io_read_sctrl_port(int portnum) |
| 341 | UINT8 md_base_state::megadrive_io_read_sctrl_port(int portnum) |
| 353 | 342 | { |
| 354 | 343 | return 0x00; |
| 355 | 344 | } |
| r22070 | r22071 | |
| 392 | 381 | case 0x2: |
| 393 | 382 | case 0x3: |
| 394 | 383 | // retdata = megadrive_io_read_data_port(offset-1); |
| 395 | | retdata = megadrive_io_read_data_port_ptr(space.machine(), offset-1); |
| 384 | retdata = m_megadrive_io_read_data_port_ptr(space, offset-1, 0xff); |
| 396 | 385 | break; |
| 397 | 386 | |
| 398 | 387 | case 0x4: |
| r22070 | r22071 | |
| 421 | 410 | } |
| 422 | 411 | |
| 423 | 412 | |
| 424 | | static void megadrive_io_write_data_port_3button(running_machine &machine, int portnum, UINT16 data) |
| 413 | WRITE16_MEMBER(md_base_state::megadrive_io_write_data_port_3button) |
| 425 | 414 | { |
| 415 | int portnum = offset; |
| 426 | 416 | m_megadrive_io_data_regs[portnum] = data; |
| 427 | 417 | //mame_printf_debug("Writing IO Data Register #%d data %04x\n",portnum,data); |
| 428 | 418 | |
| r22070 | r22071 | |
| 431 | 421 | |
| 432 | 422 | /****************************** 6 buttons version*****************************/ |
| 433 | 423 | |
| 434 | | static void megadrive_io_write_data_port_6button(running_machine &machine, int portnum, UINT16 data) |
| 424 | WRITE16_MEMBER(md_base_state::megadrive_io_write_data_port_6button) |
| 435 | 425 | { |
| 426 | int portnum = offset; |
| 436 | 427 | if (m_megadrive_io_ctrl_regs[portnum]&0x40) |
| 437 | 428 | { |
| 438 | 429 | if (((m_megadrive_io_data_regs[portnum]&0x40)==0x00) && ((data&0x40) == 0x40)) |
| 439 | 430 | { |
| 440 | 431 | m_io_stage[portnum]++; |
| 441 | | m_io_timeout[portnum]->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(8192)); |
| 432 | m_io_timeout[portnum]->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(8192)); |
| 442 | 433 | } |
| 443 | 434 | |
| 444 | 435 | } |
| r22070 | r22071 | |
| 451 | 442 | |
| 452 | 443 | /*************************** 3 buttons version ****************************/ |
| 453 | 444 | |
| 454 | | static void megadrive_io_write_ctrl_port(running_machine &machine, int portnum, UINT16 data) |
| 445 | void md_base_state::megadrive_io_write_ctrl_port(int portnum, UINT16 data) |
| 455 | 446 | { |
| 456 | 447 | m_megadrive_io_ctrl_regs[portnum] = data; |
| 457 | 448 | // mame_printf_debug("Setting IO Control Register #%d data %04x\n",portnum,data); |
| 458 | 449 | } |
| 459 | 450 | |
| 460 | | static void megadrive_io_write_tx_port(running_machine &machine, int portnum, UINT16 data) |
| 451 | void md_base_state::megadrive_io_write_tx_port(int portnum, UINT16 data) |
| 461 | 452 | { |
| 462 | 453 | m_megadrive_io_tx_regs[portnum] = data; |
| 463 | 454 | } |
| 464 | 455 | |
| 465 | | static void megadrive_io_write_rx_port(running_machine &machine, int portnum, UINT16 data) |
| 456 | void md_base_state::megadrive_io_write_rx_port(int portnum, UINT16 data) |
| 466 | 457 | { |
| 467 | 458 | } |
| 468 | 459 | |
| 469 | | static void megadrive_io_write_sctrl_port(running_machine &machine, int portnum, UINT16 data) |
| 460 | void md_base_state::megadrive_io_write_sctrl_port(int portnum, UINT16 data) |
| 470 | 461 | { |
| 471 | 462 | } |
| 472 | 463 | |
| r22070 | r22071 | |
| 488 | 479 | case 0x2: |
| 489 | 480 | case 0x3: |
| 490 | 481 | // megadrive_io_write_data_port(offset-1,data); |
| 491 | | megadrive_io_write_data_port_ptr(space.machine(), offset-1,data); |
| 482 | m_megadrive_io_write_data_port_ptr(space, offset-1,data, 0xffff); |
| 492 | 483 | break; |
| 493 | 484 | |
| 494 | 485 | case 0x4: |
| 495 | 486 | case 0x5: |
| 496 | 487 | case 0x6: |
| 497 | | megadrive_io_write_ctrl_port(space.machine(),offset-4,data); |
| 488 | megadrive_io_write_ctrl_port(offset-4,data); |
| 498 | 489 | break; |
| 499 | 490 | |
| 500 | 491 | /* Serial I/O Registers */ |
| 501 | 492 | |
| 502 | | case 0x7: megadrive_io_write_tx_port(space.machine(),0,data); break; |
| 503 | | case 0x8: megadrive_io_write_rx_port(space.machine(),0,data); break; |
| 504 | | case 0x9: megadrive_io_write_sctrl_port(space.machine(),0,data); break; |
| 493 | case 0x7: megadrive_io_write_tx_port(0,data); break; |
| 494 | case 0x8: megadrive_io_write_rx_port(0,data); break; |
| 495 | case 0x9: megadrive_io_write_sctrl_port(0,data); break; |
| 505 | 496 | |
| 506 | | case 0xa: megadrive_io_write_tx_port(space.machine(),1,data); break; |
| 507 | | case 0xb: megadrive_io_write_rx_port(space.machine(),1,data); break; |
| 508 | | case 0xc: megadrive_io_write_sctrl_port(space.machine(),1,data); break; |
| 497 | case 0xa: megadrive_io_write_tx_port(1,data); break; |
| 498 | case 0xb: megadrive_io_write_rx_port(1,data); break; |
| 499 | case 0xc: megadrive_io_write_sctrl_port(1,data); break; |
| 509 | 500 | |
| 510 | | case 0xd: megadrive_io_write_tx_port(space.machine(),2,data); break; |
| 511 | | case 0xe: megadrive_io_write_rx_port(space.machine(),2,data); break; |
| 512 | | case 0xf: megadrive_io_write_sctrl_port(space.machine(),2,data); break; |
| 501 | case 0xd: megadrive_io_write_tx_port(2,data); break; |
| 502 | case 0xe: megadrive_io_write_rx_port(2,data); break; |
| 503 | case 0xf: megadrive_io_write_sctrl_port(2,data); break; |
| 513 | 504 | } |
| 514 | 505 | } |
| 515 | 506 | |
| r22070 | r22071 | |
| 881 | 872 | |
| 882 | 873 | MACHINE_START( megadriv ) |
| 883 | 874 | { |
| 884 | | if (m_megadrive_6buttons_pad) |
| 885 | | init_megadri6_io(machine); |
| 875 | md_base_state *state = machine.driver_data<md_base_state>(); |
| 876 | if (state->m_megadrive_6buttons_pad) |
| 877 | state->init_megadri6_io(); |
| 886 | 878 | } |
| 887 | 879 | |
| 888 | 880 | MACHINE_RESET( megadriv ) |
| r22070 | r22071 | |
| 901 | 893 | machine.scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(md_base_state::megadriv_z80_run_state),state)); |
| 902 | 894 | } |
| 903 | 895 | |
| 904 | | megadrive_reset_io(machine); |
| 896 | state->megadrive_reset_io(); |
| 905 | 897 | |
| 906 | 898 | if (!state->m_vdp->m_use_alt_timing) |
| 907 | 899 | { |
| r22070 | r22071 | |
| 924 | 916 | state->m_32x->pause_cpu(); |
| 925 | 917 | } |
| 926 | 918 | |
| 927 | | void megadriv_stop_scanline_timer(running_machine &machine) |
| 919 | void md_base_state::megadriv_stop_scanline_timer() |
| 928 | 920 | { |
| 929 | | md_base_state *state = machine.driver_data<md_base_state>(); |
| 930 | | |
| 931 | | if (!state->m_vdp->m_use_alt_timing) |
| 921 | if (!m_vdp->m_use_alt_timing) |
| 932 | 922 | megadriv_scanline_timer->reset(); |
| 933 | 923 | } |
| 934 | 924 | |
| r22070 | r22071 | |
| 1174 | 1164 | // the drivers which need 6 buttons pad set this to 1 in their init befare calling the megadrive init |
| 1175 | 1165 | if (m_megadrive_6buttons_pad) |
| 1176 | 1166 | { |
| 1177 | | megadrive_io_read_data_port_ptr = megadrive_io_read_data_port_6button; |
| 1178 | | megadrive_io_write_data_port_ptr = megadrive_io_write_data_port_6button; |
| 1167 | m_megadrive_io_read_data_port_ptr = read8_delegate(FUNC(md_base_state::megadrive_io_read_data_port_6button),this); |
| 1168 | m_megadrive_io_write_data_port_ptr = write16_delegate(FUNC(md_base_state::megadrive_io_write_data_port_6button),this); |
| 1179 | 1169 | mame_printf_debug("6 button game\n"); |
| 1180 | 1170 | } |
| 1181 | 1171 | else |
| 1182 | 1172 | { |
| 1183 | | megadrive_io_read_data_port_ptr = megadrive_io_read_data_port_3button; |
| 1184 | | megadrive_io_write_data_port_ptr = megadrive_io_write_data_port_3button; |
| 1173 | m_megadrive_io_read_data_port_ptr = read8_delegate(FUNC(md_base_state::megadrive_io_read_data_port_3button),this); |
| 1174 | m_megadrive_io_write_data_port_ptr = write16_delegate(FUNC(md_base_state::megadrive_io_write_data_port_3button),this); |
| 1185 | 1175 | mame_printf_debug("3 button game\n"); |
| 1186 | 1176 | } |
| 1187 | 1177 | |
| r22070 | r22071 | |
| 1294 | 1284 | DRIVER_INIT_MEMBER(md_base_state,mpnew) |
| 1295 | 1285 | { |
| 1296 | 1286 | DRIVER_INIT_CALL(megadrij); |
| 1297 | | megadrive_io_read_data_port_ptr = megadrive_io_read_data_port_3button; |
| 1298 | | megadrive_io_write_data_port_ptr = megadrive_io_write_data_port_3button; |
| 1287 | m_megadrive_io_read_data_port_ptr = read8_delegate(FUNC(md_base_state::megadrive_io_read_data_port_3button),this); |
| 1288 | m_megadrive_io_write_data_port_ptr = write16_delegate(FUNC(md_base_state::megadrive_io_write_data_port_3button),this); |
| 1299 | 1289 | } |
| 1300 | 1290 | |
| 1301 | 1291 | /* used by megatech */ |
trunk/src/mame/includes/megadriv.h
| r22070 | r22071 | |
| 39 | 39 | MACHINE_CONFIG_EXTERN( md_pal ); |
| 40 | 40 | MACHINE_CONFIG_EXTERN( md_bootleg ); // for topshoot.c & hshavoc.c |
| 41 | 41 | |
| 42 | | extern UINT8 megatech_bios_port_cc_dc_r(running_machine &machine, int offset, int ctrl); |
| 43 | | extern void megadriv_stop_scanline_timer(running_machine &machine); |
| 44 | | |
| 45 | | |
| 46 | | /* These are needed to create external input handlers (see e.g. MESS) */ |
| 47 | | /* Regs are also used by Megaplay! */ |
| 48 | | extern UINT8 (*megadrive_io_read_data_port_ptr)(running_machine &machine, int offset); |
| 49 | | extern void (*megadrive_io_write_data_port_ptr)(running_machine &machine, int offset, UINT16 data); |
| 50 | | extern UINT8 m_megadrive_io_data_regs[3]; |
| 51 | | extern UINT8 m_megadrive_io_ctrl_regs[3]; |
| 52 | | |
| 53 | 42 | MACHINE_START( megadriv ); |
| 54 | 43 | MACHINE_RESET( megadriv ); |
| 55 | 44 | VIDEO_START( megadriv ); |
| r22070 | r22071 | |
| 88 | 77 | m_vdp(*this,"gen_vdp"), |
| 89 | 78 | m_32x(*this,"sega32x"), |
| 90 | 79 | m_segacd(*this,"segacd"), |
| 91 | | m_megadrive_ram(*this,"megadrive_ram") |
| 80 | m_megadrive_ram(*this,"megadrive_ram"), |
| 81 | m_megadrive_6buttons_pad(0) |
| 92 | 82 | { } |
| 93 | 83 | required_device<cpu_device> m_maincpu; |
| 94 | 84 | optional_device<cpu_device> m_z80snd; |
| r22070 | r22071 | |
| 135 | 125 | DECLARE_READ8_MEMBER( z80_unmapped_r ); |
| 136 | 126 | DECLARE_WRITE8_MEMBER( z80_unmapped_w ); |
| 137 | 127 | TIMER_CALLBACK_MEMBER(megadriv_z80_run_state); |
| 128 | |
| 129 | /* Megadrive / Genesis has 3 I/O ports */ |
| 130 | emu_timer *m_io_timeout[3]; |
| 131 | int m_io_stage[3]; |
| 132 | UINT8 m_megadrive_io_data_regs[3]; |
| 133 | UINT8 m_megadrive_io_ctrl_regs[3]; |
| 134 | UINT8 m_megadrive_io_tx_regs[3]; |
| 135 | int m_megadrive_6buttons_pad; |
| 136 | read8_delegate m_megadrive_io_read_data_port_ptr; |
| 137 | write16_delegate m_megadrive_io_write_data_port_ptr; |
| 138 | |
| 139 | |
| 140 | TIMER_CALLBACK_MEMBER( io_timeout_timer_callback ); |
| 141 | void init_megadri6_io(); |
| 142 | void megadrive_reset_io(); |
| 143 | DECLARE_READ8_MEMBER(megadrive_io_read_data_port_6button); |
| 144 | DECLARE_READ8_MEMBER(megadrive_io_read_data_port_3button); |
| 145 | UINT8 megatech_bios_port_cc_dc_r(int offset, int ctrl); |
| 146 | UINT8 megadrive_io_read_ctrl_port(int portnum); |
| 147 | UINT8 megadrive_io_read_tx_port(int portnum); |
| 148 | UINT8 megadrive_io_read_rx_port(int portnum); |
| 149 | UINT8 megadrive_io_read_sctrl_port(int portnum); |
| 150 | |
| 151 | DECLARE_WRITE16_MEMBER(megadrive_io_write_data_port_3button); |
| 152 | DECLARE_WRITE16_MEMBER(megadrive_io_write_data_port_6button); |
| 153 | void megadrive_io_write_ctrl_port(int portnum, UINT16 data); |
| 154 | void megadrive_io_write_tx_port(int portnum, UINT16 data); |
| 155 | void megadrive_io_write_rx_port(int portnum, UINT16 data); |
| 156 | void megadrive_io_write_sctrl_port(int portnum, UINT16 data); |
| 157 | |
| 158 | void megadriv_stop_scanline_timer(); |
| 138 | 159 | }; |
| 139 | 160 | |
| 140 | 161 | class md_boot_state : public md_base_state |
| r22070 | r22071 | |
| 285 | 306 | DECLARE_DRIVER_INIT(pclubjv2); |
| 286 | 307 | DECLARE_DRIVER_INIT(pclubjv4); |
| 287 | 308 | DECLARE_DRIVER_INIT(pclubjv5); |
| 288 | | void segac2_common_init(running_machine& machine, int (*func)(int in)); |
| 309 | void segac2_common_init(int (*func)(int in)); |
| 289 | 310 | DECLARE_VIDEO_START(segac2_new); |
| 290 | 311 | DECLARE_MACHINE_START(segac2); |
| 291 | 312 | DECLARE_MACHINE_RESET(segac2); |
| 292 | 313 | |
| 293 | 314 | UINT32 screen_update_segac2_new(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 315 | int m_segac2_bg_pal_lookup[4]; |
| 316 | int m_segac2_sp_pal_lookup[4]; |
| 317 | void recompute_palette_tables(); |
| 318 | |
| 319 | DECLARE_WRITE16_MEMBER( segac2_upd7759_w ); |
| 320 | DECLARE_READ16_MEMBER( palette_r ); |
| 321 | DECLARE_WRITE16_MEMBER( palette_w ); |
| 322 | DECLARE_READ16_MEMBER( io_chip_r ); |
| 323 | DECLARE_WRITE16_MEMBER( io_chip_w ); |
| 324 | DECLARE_WRITE16_MEMBER( control_w ); |
| 325 | DECLARE_READ16_MEMBER( prot_r ); |
| 326 | DECLARE_WRITE16_MEMBER( prot_w ); |
| 327 | DECLARE_WRITE16_MEMBER( counter_timer_w ); |
| 328 | DECLARE_READ16_MEMBER( printer_r ); |
| 329 | DECLARE_WRITE16_MEMBER( print_club_camera_w ); |
| 330 | DECLARE_READ16_MEMBER(ichirjbl_prot_r); |
| 294 | 331 | }; |
| 295 | 332 | |
| 296 | 333 | class mplay_state : public md_base_state |
| r22070 | r22071 | |
| 395 | 432 | UINT32 screen_update_megatech_menu(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 396 | 433 | |
| 397 | 434 | void megatech_set_megadrive_z80_as_megadrive_z80(const char* tag); |
| 435 | |
| 436 | DECLARE_READ8_MEMBER( megatech_cart_select_r ); |
| 437 | TIMER_CALLBACK_MEMBER( megatech_z80_run_state ); |
| 438 | TIMER_CALLBACK_MEMBER( megatech_z80_stop_state ); |
| 439 | void megatech_select_game(int gameno); |
| 440 | DECLARE_WRITE8_MEMBER( megatech_cart_select_w ); |
| 441 | DECLARE_READ8_MEMBER( bios_ctrl_r ); |
| 442 | DECLARE_WRITE8_MEMBER( bios_ctrl_w ); |
| 443 | DECLARE_READ8_MEMBER( megatech_z80_read_68k_banked_data ); |
| 444 | DECLARE_WRITE8_MEMBER( megatech_z80_write_68k_banked_data ); |
| 445 | void megatech_z80_bank_w(UINT16 data); |
| 446 | DECLARE_WRITE8_MEMBER( mt_z80_bank_w ); |
| 447 | DECLARE_READ8_MEMBER( megatech_banked_ram_r ); |
| 448 | DECLARE_WRITE8_MEMBER( megatech_banked_ram_w ); |
| 449 | DECLARE_WRITE8_MEMBER( megatech_bios_port_ctrl_w ); |
| 450 | DECLARE_READ8_MEMBER( megatech_bios_joypad_r ); |
| 451 | DECLARE_WRITE8_MEMBER (megatech_bios_port_7f_w); |
| 398 | 452 | }; |
| 399 | 453 | |
| 400 | 454 | |
trunk/src/mess/drivers/megadriv.c
| r22070 | r22071 | |
| 24 | 24 | m_slotcart(*this, "mdslot") |
| 25 | 25 | { } |
| 26 | 26 | |
| 27 | | emu_timer *m_mess_io_timeout[3]; |
| 28 | | int m_mess_io_stage[3]; |
| 29 | | |
| 30 | 27 | optional_device<md_cart_slot_device> m_slotcart; |
| 31 | 28 | |
| 32 | 29 | DECLARE_DRIVER_INIT(mess_md_common); |
| 33 | 30 | DECLARE_DRIVER_INIT(genesis); |
| 34 | 31 | DECLARE_DRIVER_INIT(md_eur); |
| 35 | 32 | DECLARE_DRIVER_INIT(md_jpn); |
| 33 | |
| 34 | READ8_MEMBER(mess_md_io_read_data_port); |
| 35 | WRITE16_MEMBER(mess_md_io_write_data_port); |
| 36 | |
| 36 | 37 | }; |
| 37 | 38 | |
| 38 | 39 | class pico_state : public md_cons_state |
| r22070 | r22071 | |
| 44 | 45 | |
| 45 | 46 | optional_device<pico_cart_slot_device> m_picocart; |
| 46 | 47 | UINT8 m_page_register; |
| 48 | |
| 49 | UINT16 pico_read_penpos(int pen); |
| 50 | DECLARE_READ16_HANDLER(pico_68k_io_read); |
| 51 | DECLARE_WRITE16_MEMBER(pico_68k_io_write); |
| 47 | 52 | }; |
| 48 | 53 | |
| 49 | 54 | |
| r22070 | r22071 | |
| 53 | 58 | * |
| 54 | 59 | *************************************/ |
| 55 | 60 | |
| 56 | | /* We need to always initialize 6 buttons pad */ |
| 57 | | static TIMER_CALLBACK( mess_io_timeout_timer_callback ) |
| 58 | | { |
| 59 | | md_cons_state *state = machine.driver_data<md_cons_state>(); |
| 60 | | state->m_mess_io_stage[(int)(FPTR)ptr] = -1; |
| 61 | | } |
| 62 | | |
| 63 | | static void mess_init_6buttons_pad(running_machine &machine) |
| 64 | | { |
| 65 | | md_cons_state *state = machine.driver_data<md_cons_state>(); |
| 66 | | int i; |
| 67 | | |
| 68 | | for (i = 0; i < 3; i++) |
| 69 | | { |
| 70 | | state->m_mess_io_timeout[i] = machine.scheduler().timer_alloc(FUNC(mess_io_timeout_timer_callback), (void*)(FPTR)i); |
| 71 | | state->m_mess_io_stage[i] = -1; |
| 72 | | } |
| 73 | | } |
| 74 | | |
| 75 | 61 | /* These overwrite the MAME ones in DRIVER_INIT */ |
| 76 | 62 | /* They're needed to give the users the choice between different controllers */ |
| 77 | | static UINT8 mess_md_io_read_data_port(running_machine &machine, int portnum) |
| 63 | READ8_MEMBER(md_cons_state::mess_md_io_read_data_port) |
| 78 | 64 | { |
| 79 | | md_cons_state *state = machine.driver_data<md_cons_state>(); |
| 65 | int portnum = offset; |
| 80 | 66 | static const char *const pad6names[2][4] = { |
| 81 | 67 | { "PAD1_6B", "PAD2_6B", "UNUSED", "UNUSED" }, |
| 82 | 68 | { "EXTRA1", "EXTRA2", "UNUSED", "UNUSED" } |
| r22070 | r22071 | |
| 91 | 77 | switch (portnum) |
| 92 | 78 | { |
| 93 | 79 | case 0: |
| 94 | | controller = (machine.root_device().ioport("CTRLSEL")->read() & 0x0f); |
| 80 | controller = (ioport("CTRLSEL")->read() & 0x0f); |
| 95 | 81 | break; |
| 96 | 82 | |
| 97 | 83 | case 1: |
| 98 | | controller = (machine.root_device().ioport("CTRLSEL")->read() & 0xf0); |
| 84 | controller = (ioport("CTRLSEL")->read() & 0xf0); |
| 99 | 85 | break; |
| 100 | 86 | |
| 101 | 87 | default: |
| r22070 | r22071 | |
| 108 | 94 | { |
| 109 | 95 | if (m_megadrive_io_data_regs[portnum] & 0x40) |
| 110 | 96 | { |
| 111 | | if (state->m_mess_io_stage[portnum] == 2) |
| 97 | if (m_io_stage[portnum] == 2) |
| 112 | 98 | { |
| 113 | 99 | /* here we read B, C & the additional buttons */ |
| 114 | 100 | retdata = (m_megadrive_io_data_regs[portnum] & helper_6b) | |
| 115 | | (((state->ioport(pad6names[0][portnum])->read_safe(0) & 0x30) | |
| 116 | | (state->ioport(pad6names[1][portnum])->read_safe(0) & 0x0f)) & ~helper_6b); |
| 101 | (((ioport(pad6names[0][portnum])->read_safe(0) & 0x30) | |
| 102 | (ioport(pad6names[1][portnum])->read_safe(0) & 0x0f)) & ~helper_6b); |
| 117 | 103 | } |
| 118 | 104 | else |
| 119 | 105 | { |
| 120 | 106 | /* here we read B, C & the directional buttons */ |
| 121 | 107 | retdata = (m_megadrive_io_data_regs[portnum] & helper_6b) | |
| 122 | | ((state->ioport(pad6names[0][portnum])->read_safe(0) & 0x3f) & ~helper_6b); |
| 108 | ((ioport(pad6names[0][portnum])->read_safe(0) & 0x3f) & ~helper_6b); |
| 123 | 109 | } |
| 124 | 110 | } |
| 125 | 111 | else |
| 126 | 112 | { |
| 127 | | if (state->m_mess_io_stage[portnum] == 1) |
| 113 | if (m_io_stage[portnum] == 1) |
| 128 | 114 | { |
| 129 | 115 | /* here we read ((Start & A) >> 2) | 0x00 */ |
| 130 | 116 | retdata = (m_megadrive_io_data_regs[portnum] & helper_6b) | |
| 131 | | (((state->ioport(pad6names[0][portnum])->read_safe(0) & 0xc0) >> 2) & ~helper_6b); |
| 117 | (((ioport(pad6names[0][portnum])->read_safe(0) & 0xc0) >> 2) & ~helper_6b); |
| 132 | 118 | } |
| 133 | | else if (state->m_mess_io_stage[portnum]==2) |
| 119 | else if (m_io_stage[portnum]==2) |
| 134 | 120 | { |
| 135 | 121 | /* here we read ((Start & A) >> 2) | 0x0f */ |
| 136 | 122 | retdata = (m_megadrive_io_data_regs[portnum] & helper_6b) | |
| 137 | | ((((state->ioport(pad6names[0][portnum])->read_safe(0) & 0xc0) >> 2) | 0x0f) & ~helper_6b); |
| 123 | ((((ioport(pad6names[0][portnum])->read_safe(0) & 0xc0) >> 2) | 0x0f) & ~helper_6b); |
| 138 | 124 | } |
| 139 | 125 | else |
| 140 | 126 | { |
| 141 | 127 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 142 | 128 | retdata = (m_megadrive_io_data_regs[portnum] & helper_6b) | |
| 143 | | ((((state->ioport(pad6names[0][portnum])->read_safe(0) & 0xc0) >> 2) | |
| 144 | | (state->ioport(pad6names[0][portnum])->read_safe(0) & 0x03)) & ~helper_6b); |
| 129 | ((((ioport(pad6names[0][portnum])->read_safe(0) & 0xc0) >> 2) | |
| 130 | (ioport(pad6names[0][portnum])->read_safe(0) & 0x03)) & ~helper_6b); |
| 145 | 131 | } |
| 146 | 132 | } |
| 147 | 133 | |
| r22070 | r22071 | |
| 153 | 139 | else |
| 154 | 140 | { |
| 155 | 141 | UINT8 svp_test = 0; |
| 156 | | if (state->m_slotcart) |
| 157 | | svp_test = state->m_slotcart->read_test(); |
| 142 | if (m_slotcart) |
| 143 | svp_test = m_slotcart->read_test(); |
| 158 | 144 | |
| 159 | 145 | // handle test input for SVP test |
| 160 | 146 | if (portnum == 0 && svp_test) |
| r22070 | r22071 | |
| 165 | 151 | { |
| 166 | 152 | /* here we read B, C & the directional buttons */ |
| 167 | 153 | retdata = (m_megadrive_io_data_regs[portnum] & helper_3b) | |
| 168 | | (((state->ioport(pad3names[portnum])->read_safe(0) & 0x3f) | 0x40) & ~helper_3b); |
| 154 | (((ioport(pad3names[portnum])->read_safe(0) & 0x3f) | 0x40) & ~helper_3b); |
| 169 | 155 | } |
| 170 | 156 | else |
| 171 | 157 | { |
| 172 | 158 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 173 | 159 | retdata = (m_megadrive_io_data_regs[portnum] & helper_3b) | |
| 174 | | ((((state->ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 175 | | (state->ioport(pad3names[portnum])->read_safe(0) & 0x03) | 0x40) & ~helper_3b); |
| 160 | ((((ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 161 | (ioport(pad3names[portnum])->read_safe(0) & 0x03) | 0x40) & ~helper_3b); |
| 176 | 162 | } |
| 177 | 163 | } |
| 178 | 164 | |
| r22070 | r22071 | |
| 180 | 166 | } |
| 181 | 167 | |
| 182 | 168 | |
| 183 | | static void mess_md_io_write_data_port(running_machine &machine, int portnum, UINT16 data) |
| 169 | WRITE16_MEMBER(md_cons_state::mess_md_io_write_data_port) |
| 184 | 170 | { |
| 185 | | md_cons_state *state = machine.driver_data<md_cons_state>(); |
| 171 | int portnum = offset; |
| 186 | 172 | int controller; |
| 187 | 173 | |
| 188 | 174 | switch (portnum) |
| 189 | 175 | { |
| 190 | 176 | case 0: |
| 191 | | controller = (machine.root_device().ioport("CTRLSEL")->read() & 0x0f); |
| 177 | controller = (ioport("CTRLSEL")->read() & 0x0f); |
| 192 | 178 | break; |
| 193 | 179 | |
| 194 | 180 | case 1: |
| 195 | | controller = (machine.root_device().ioport("CTRLSEL")->read() & 0xf0); |
| 181 | controller = (ioport("CTRLSEL")->read() & 0xf0); |
| 196 | 182 | break; |
| 197 | 183 | |
| 198 | 184 | default: |
| r22070 | r22071 | |
| 206 | 192 | { |
| 207 | 193 | if (((m_megadrive_io_data_regs[portnum] & 0x40) == 0x00) && ((data & 0x40) == 0x40)) |
| 208 | 194 | { |
| 209 | | state->m_mess_io_stage[portnum]++; |
| 210 | | state->m_mess_io_timeout[portnum]->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(8192)); |
| 195 | m_io_stage[portnum]++; |
| 196 | m_io_timeout[portnum]->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(8192)); |
| 211 | 197 | } |
| 212 | 198 | |
| 213 | 199 | } |
| r22070 | r22071 | |
| 331 | 317 | { |
| 332 | 318 | md_cons_state *state = machine.driver_data<md_cons_state>(); |
| 333 | 319 | |
| 334 | | mess_init_6buttons_pad(machine); |
| 320 | state->init_megadri6_io(); |
| 335 | 321 | |
| 336 | 322 | vdp_get_word_from_68k_mem = vdp_get_word_from_68k_mem_console; |
| 337 | 323 | |
| r22070 | r22071 | |
| 460 | 446 | |
| 461 | 447 | DRIVER_INIT_MEMBER(md_cons_state,mess_md_common) |
| 462 | 448 | { |
| 463 | | megadrive_io_read_data_port_ptr = mess_md_io_read_data_port; |
| 464 | | megadrive_io_write_data_port_ptr = mess_md_io_write_data_port; |
| 449 | m_megadrive_io_read_data_port_ptr = read8_delegate(FUNC(md_cons_state::mess_md_io_read_data_port),this); |
| 450 | m_megadrive_io_write_data_port_ptr = write16_delegate(FUNC(md_cons_state::mess_md_io_write_data_port),this); |
| 465 | 451 | } |
| 466 | 452 | |
| 467 | 453 | DRIVER_INIT_MEMBER(md_cons_state,genesis) |
| r22070 | r22071 | |
| 892 | 878 | #define PICO_PENX 1 |
| 893 | 879 | #define PICO_PENY 2 |
| 894 | 880 | |
| 895 | | static UINT16 pico_read_penpos(running_machine &machine, int pen) |
| 881 | UINT16 pico_state::pico_read_penpos(int pen) |
| 896 | 882 | { |
| 897 | 883 | UINT16 penpos = 0; |
| 898 | 884 | |
| 899 | 885 | switch (pen) |
| 900 | 886 | { |
| 901 | 887 | case PICO_PENX: |
| 902 | | penpos = machine.root_device().ioport("PENX")->read_safe(0); |
| 888 | penpos = ioport("PENX")->read_safe(0); |
| 903 | 889 | penpos |= 0x6; |
| 904 | 890 | penpos = penpos * 320 / 255; |
| 905 | 891 | penpos += 0x3d; |
| 906 | 892 | break; |
| 907 | 893 | case PICO_PENY: |
| 908 | | penpos = machine.root_device().ioport("PENY")->read_safe(0); |
| 894 | penpos = ioport("PENY")->read_safe(0); |
| 909 | 895 | penpos |= 0x6; |
| 910 | 896 | penpos = penpos * 251 / 255; |
| 911 | 897 | penpos += 0x1fc; |
| r22070 | r22071 | |
| 915 | 901 | return penpos; |
| 916 | 902 | } |
| 917 | 903 | |
| 918 | | static READ16_HANDLER( pico_68k_io_read ) |
| 904 | READ16_HANDLER(pico_state::pico_68k_io_read ) |
| 919 | 905 | { |
| 920 | | pico_state *state = space.machine().driver_data<pico_state>(); |
| 921 | 906 | UINT8 retdata = 0; |
| 922 | 907 | |
| 923 | 908 | switch (offset) |
| 924 | 909 | { |
| 925 | 910 | case 0: /* Version register ?XX?????? where XX is 00 for japan, 01 for europe and 10 for USA*/ |
| 926 | | retdata = (state->m_export << 6) | (state->m_pal << 5); |
| 911 | retdata = (m_export << 6) | (m_pal << 5); |
| 927 | 912 | break; |
| 928 | 913 | case 1: |
| 929 | | retdata = state->ioport("PAD")->read_safe(0); |
| 914 | retdata = ioport("PAD")->read_safe(0); |
| 930 | 915 | break; |
| 931 | 916 | |
| 932 | 917 | /* |
| r22070 | r22071 | |
| 941 | 926 | 0x2f8 - 0x3f3 (storyware) |
| 942 | 927 | */ |
| 943 | 928 | case 2: |
| 944 | | retdata = pico_read_penpos(space.machine(), PICO_PENX) >> 8; |
| 929 | retdata = pico_read_penpos(PICO_PENX) >> 8; |
| 945 | 930 | break; |
| 946 | 931 | case 3: |
| 947 | | retdata = pico_read_penpos(space.machine(), PICO_PENX) & 0x00ff; |
| 932 | retdata = pico_read_penpos(PICO_PENX) & 0x00ff; |
| 948 | 933 | break; |
| 949 | 934 | case 4: |
| 950 | | retdata = pico_read_penpos(space.machine(), PICO_PENY) >> 8; |
| 935 | retdata = pico_read_penpos(PICO_PENY) >> 8; |
| 951 | 936 | break; |
| 952 | 937 | case 5: |
| 953 | | retdata = pico_read_penpos(space.machine(), PICO_PENY) & 0x00ff; |
| 938 | retdata = pico_read_penpos(PICO_PENY) & 0x00ff; |
| 954 | 939 | break; |
| 955 | 940 | case 6: |
| 956 | 941 | /* Page register : |
| r22070 | r22071 | |
| 959 | 944 | either page 5 or page 6 is often unused. |
| 960 | 945 | */ |
| 961 | 946 | { |
| 962 | | UINT8 tmp = state->ioport("PAGE")->read_safe(0); |
| 963 | | if (tmp == 2 && state->m_page_register != 0x3f) |
| 947 | UINT8 tmp = ioport("PAGE")->read_safe(0); |
| 948 | if (tmp == 2 && m_page_register != 0x3f) |
| 964 | 949 | { |
| 965 | | state->m_page_register <<= 1; |
| 966 | | state->m_page_register |= 1; |
| 950 | m_page_register <<= 1; |
| 951 | m_page_register |= 1; |
| 967 | 952 | } |
| 968 | | if (tmp == 1 && state->m_page_register != 0x00) |
| 969 | | state->m_page_register >>= 1; |
| 970 | | retdata = state->m_page_register; |
| 953 | if (tmp == 1 && m_page_register != 0x00) |
| 954 | m_page_register >>= 1; |
| 955 | retdata = m_page_register; |
| 971 | 956 | break; |
| 972 | 957 | } |
| 973 | 958 | case 7: |
| r22070 | r22071 | |
| 985 | 970 | return retdata | retdata << 8; |
| 986 | 971 | } |
| 987 | 972 | |
| 988 | | static WRITE16_HANDLER( pico_68k_io_write ) |
| 973 | WRITE16_MEMBER(pico_state::pico_68k_io_write ) |
| 989 | 974 | { |
| 990 | 975 | switch (offset) |
| 991 | 976 | { |
| r22070 | r22071 | |
| 995 | 980 | static ADDRESS_MAP_START( pico_mem, AS_PROGRAM, 16, pico_state ) |
| 996 | 981 | AM_RANGE(0x000000, 0x3fffff) AM_ROM |
| 997 | 982 | |
| 998 | | AM_RANGE(0x800000, 0x80001f) AM_READWRITE_LEGACY(pico_68k_io_read, pico_68k_io_write) |
| 983 | AM_RANGE(0x800000, 0x80001f) AM_READWRITE(pico_68k_io_read, pico_68k_io_write) |
| 999 | 984 | |
| 1000 | 985 | AM_RANGE(0xc00000, 0xc0001f) AM_DEVREADWRITE("gen_vdp", sega_genesis_vdp_device, megadriv_vdp_r,megadriv_vdp_w) |
| 1001 | 986 | AM_RANGE(0xe00000, 0xe0ffff) AM_RAM AM_MIRROR(0x1f0000) |