trunk/src/mame/drivers/megaplay.c
| r22069 | r22070 | |
| 58 | 58 | |
| 59 | 59 | #define MASTER_CLOCK 53693100 |
| 60 | 60 | |
| 61 | | extern UINT8 segae_vintpending; |
| 62 | | extern UINT8 segae_hintpending; |
| 63 | | extern UINT8 *segae_vdp_regs[]; /* pointer to vdp's registers */ |
| 64 | | |
| 65 | 61 | // Interrupt handler - from drivers/segasyse.c |
| 66 | 62 | #if 0 |
| 63 | static UINT8 segae_vintpending; |
| 64 | static UINT8 segae_hintpending; |
| 65 | static UINT8 *segae_vdp_regs[]; /* pointer to vdp's registers */ |
| 66 | |
| 67 | 67 | static UINT8 hintcount; /* line interrupt counter, decreased each scanline */ |
| 68 | 68 | |
| 69 | 69 | static INTERRUPT_GEN (megaplay_bios_irq) |
| r22069 | r22070 | |
| 373 | 373 | |
| 374 | 374 | /*MEGAPLAY specific*/ |
| 375 | 375 | |
| 376 | | static READ8_HANDLER( megaplay_bios_banksel_r ) |
| 376 | READ8_MEMBER(mplay_state::megaplay_bios_banksel_r ) |
| 377 | 377 | { |
| 378 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 379 | | return state->m_bios_bank; |
| 378 | return m_bios_bank; |
| 380 | 379 | } |
| 381 | 380 | |
| 382 | | static WRITE8_HANDLER( megaplay_bios_banksel_w ) |
| 381 | WRITE8_MEMBER(mplay_state::megaplay_bios_banksel_w ) |
| 383 | 382 | { |
| 384 | 383 | /* Multi-slot note: |
| 385 | 384 | Bits 0 and 1 appear to determine the selected game slot. |
| 386 | 385 | It should be possible to multiplex different game ROMs at |
| 387 | 386 | 0x000000-0x3fffff based on these bits. |
| 388 | 387 | */ |
| 389 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 390 | | state->m_bios_bank = data; |
| 391 | | state->m_bios_mode = MP_ROM; |
| 388 | m_bios_bank = data; |
| 389 | m_bios_mode = MP_ROM; |
| 392 | 390 | // logerror("BIOS: ROM bank %i selected [0x%02x]\n",bios_bank >> 6, data); |
| 393 | 391 | } |
| 394 | 392 | |
| 395 | | static READ8_HANDLER( megaplay_bios_gamesel_r ) |
| 393 | READ8_MEMBER(mplay_state::megaplay_bios_gamesel_r ) |
| 396 | 394 | { |
| 397 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 398 | | return state->m_bios_6403; |
| 395 | return m_bios_6403; |
| 399 | 396 | } |
| 400 | 397 | |
| 401 | | static WRITE8_HANDLER( megaplay_bios_gamesel_w ) |
| 398 | WRITE8_MEMBER(mplay_state::megaplay_bios_gamesel_w ) |
| 402 | 399 | { |
| 403 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 404 | | state->m_bios_6403 = data; |
| 400 | m_bios_6403 = data; |
| 405 | 401 | |
| 406 | 402 | // logerror("BIOS: 0x6403 write: 0x%02x\n",data); |
| 407 | | state->m_bios_mode = data & 0x10; |
| 403 | m_bios_mode = data & 0x10; |
| 408 | 404 | } |
| 409 | 405 | |
| 410 | | static WRITE16_HANDLER( megaplay_io_write ) |
| 406 | WRITE16_MEMBER(mplay_state::megaplay_io_write ) |
| 411 | 407 | { |
| 412 | 408 | if (offset == 0x03) |
| 413 | | megadrive_io_data_regs[2] = (data & megadrive_io_ctrl_regs[2]) | (megadrive_io_data_regs[2] & ~megadrive_io_ctrl_regs[2]); |
| 409 | m_megadrive_io_data_regs[2] = (data & m_megadrive_io_ctrl_regs[2]) | (m_megadrive_io_data_regs[2] & ~m_megadrive_io_ctrl_regs[2]); |
| 414 | 410 | else |
| 415 | 411 | megadriv_68k_io_write(space, offset & 0x1f, data, 0xffff); |
| 416 | 412 | } |
| 417 | 413 | |
| 418 | | static READ16_HANDLER( megaplay_io_read ) |
| 414 | READ16_MEMBER(mplay_state::megaplay_io_read ) |
| 419 | 415 | { |
| 420 | 416 | if (offset == 0x03) |
| 421 | | return megadrive_io_data_regs[2]; |
| 417 | return m_megadrive_io_data_regs[2]; |
| 422 | 418 | else |
| 423 | 419 | return megadriv_68k_io_read(space, offset & 0x1f, 0xffff); |
| 424 | 420 | } |
| 425 | 421 | |
| 426 | | static READ8_HANDLER( bank_r ) |
| 422 | READ8_MEMBER(mplay_state::bank_r ) |
| 427 | 423 | { |
| 428 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 429 | | UINT8* bank = state->memregion("mtbios")->base(); |
| 430 | | UINT32 fulladdress = state->m_mp_bios_bank_addr + offset; |
| 424 | UINT8* bank = memregion("mtbios")->base(); |
| 425 | UINT32 fulladdress = m_mp_bios_bank_addr + offset; |
| 431 | 426 | |
| 432 | 427 | if (fulladdress <= 0x3fffff) // ROM Addresses |
| 433 | 428 | { |
| 434 | | if (state->m_bios_mode & MP_ROM) |
| 429 | if (m_bios_mode & MP_ROM) |
| 435 | 430 | { |
| 436 | | int sel = (state->m_bios_bank >> 6) & 0x03; |
| 431 | int sel = (m_bios_bank >> 6) & 0x03; |
| 437 | 432 | |
| 438 | 433 | if (sel == 0) |
| 439 | 434 | return 0xff; |
| 440 | 435 | else |
| 441 | 436 | return bank[0x10000 + (sel - 1) * 0x8000 + offset]; |
| 442 | 437 | } |
| 443 | | else if (state->m_bios_width & 0x08) |
| 438 | else if (m_bios_width & 0x08) |
| 444 | 439 | { |
| 445 | 440 | if (offset >= 0x2000) |
| 446 | | return state->m_ic36_ram[offset - 0x2000]; |
| 441 | return m_ic36_ram[offset - 0x2000]; |
| 447 | 442 | else |
| 448 | | return state->m_ic37_ram[(0x2000 * (state->m_bios_bank & 0x03)) + offset]; |
| 443 | return m_ic37_ram[(0x2000 * (m_bios_bank & 0x03)) + offset]; |
| 449 | 444 | } |
| 450 | 445 | else |
| 451 | 446 | { |
| 452 | | return space.machine().root_device().memregion("maincpu")->base()[fulladdress ^ 1]; |
| 447 | return machine().root_device().memregion("maincpu")->base()[fulladdress ^ 1]; |
| 453 | 448 | } |
| 454 | 449 | } |
| 455 | 450 | else if (fulladdress >= 0xa10000 && fulladdress <= 0xa1001f) // IO Acess |
| r22069 | r22070 | |
| 464 | 459 | |
| 465 | 460 | } |
| 466 | 461 | |
| 467 | | static WRITE8_HANDLER( bank_w ) |
| 462 | WRITE8_MEMBER(mplay_state::bank_w ) |
| 468 | 463 | { |
| 469 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 470 | | UINT32 fulladdress = state->m_mp_bios_bank_addr + offset; |
| 464 | UINT32 fulladdress = m_mp_bios_bank_addr + offset; |
| 471 | 465 | |
| 472 | 466 | if (fulladdress <= 0x3fffff) // ROM / Megaplay Custom Addresses |
| 473 | 467 | { |
| 474 | | if (offset <= 0x1fff && (state->m_bios_width & 0x08)) |
| 468 | if (offset <= 0x1fff && (m_bios_width & 0x08)) |
| 475 | 469 | { |
| 476 | | state->m_ic37_ram[(0x2000 * (state->m_bios_bank & 0x03)) + offset] = data; |
| 470 | m_ic37_ram[(0x2000 * (m_bios_bank & 0x03)) + offset] = data; |
| 477 | 471 | } |
| 478 | 472 | |
| 479 | | if(offset >= 0x2000 && (state->m_bios_width & 0x08)) |
| 473 | if(offset >= 0x2000 && (m_bios_width & 0x08)) |
| 480 | 474 | { |
| 481 | 475 | // ic36_ram[offset] = data; |
| 482 | | state->m_ic36_ram[offset - 0x2000] = data; |
| 476 | m_ic36_ram[offset - 0x2000] = data; |
| 483 | 477 | } |
| 484 | 478 | } |
| 485 | 479 | else if (fulladdress >= 0xa10000 && fulladdress <=0xa1001f) // IO Access |
| r22069 | r22070 | |
| 496 | 490 | /* Megaplay BIOS handles regs[2] at start in a different way compared to megadrive */ |
| 497 | 491 | /* other io data/ctrl regs are dealt with exactly like in the console */ |
| 498 | 492 | |
| 499 | | static READ8_HANDLER( megaplay_bios_6402_r ) |
| 493 | READ8_MEMBER(mplay_state::megaplay_bios_6402_r ) |
| 500 | 494 | { |
| 501 | | return megadrive_io_data_regs[2];// & 0xfe; |
| 495 | return m_megadrive_io_data_regs[2];// & 0xfe; |
| 502 | 496 | } |
| 503 | 497 | |
| 504 | | static WRITE8_HANDLER( megaplay_bios_6402_w ) |
| 498 | WRITE8_MEMBER(mplay_state::megaplay_bios_6402_w ) |
| 505 | 499 | { |
| 506 | | megadrive_io_data_regs[2] = (megadrive_io_data_regs[2] & 0x07) | ((data & 0x70) >> 1); |
| 500 | m_megadrive_io_data_regs[2] = (m_megadrive_io_data_regs[2] & 0x07) | ((data & 0x70) >> 1); |
| 507 | 501 | // logerror("BIOS: 0x6402 write: 0x%02x\n", data); |
| 508 | 502 | } |
| 509 | 503 | |
| 510 | | static READ8_HANDLER( megaplay_bios_6204_r ) |
| 504 | READ8_MEMBER(mplay_state::megaplay_bios_6204_r ) |
| 511 | 505 | { |
| 512 | | return megadrive_io_data_regs[2]; |
| 513 | | // return (state->m_bios_width & 0xf8) + (state->m_bios_6204 & 0x07); |
| 506 | return m_megadrive_io_data_regs[2]; |
| 507 | // return (m_bios_width & 0xf8) + (m_bios_6204 & 0x07); |
| 514 | 508 | } |
| 515 | 509 | |
| 516 | | static WRITE8_HANDLER( megaplay_bios_width_w ) |
| 510 | WRITE8_MEMBER(mplay_state::megaplay_bios_width_w ) |
| 517 | 511 | { |
| 518 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 519 | | state->m_bios_width = data; |
| 520 | | megadrive_io_data_regs[2] = (megadrive_io_data_regs[2] & 0x07) | ((data & 0xf8)); |
| 512 | m_bios_width = data; |
| 513 | m_megadrive_io_data_regs[2] = (m_megadrive_io_data_regs[2] & 0x07) | ((data & 0xf8)); |
| 521 | 514 | // logerror("BIOS: 0x6204 - Width write: %02x\n", data); |
| 522 | 515 | } |
| 523 | 516 | |
| 524 | | static READ8_HANDLER( megaplay_bios_6404_r ) |
| 517 | READ8_MEMBER(mplay_state::megaplay_bios_6404_r ) |
| 525 | 518 | { |
| 526 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 527 | 519 | // logerror("BIOS: 0x6404 read: returned 0x%02x\n",bios_6404 | (bios_6403 & 0x10) >> 4); |
| 528 | | return (state->m_bios_6404 & 0xfe) | ((state->m_bios_6403 & 0x10) >> 4); |
| 529 | | // return state->m_bios_6404 | (state->m_bios_6403 & 0x10) >> 4; |
| 520 | return (m_bios_6404 & 0xfe) | ((m_bios_6403 & 0x10) >> 4); |
| 521 | // return m_bios_6404 | (m_bios_6403 & 0x10) >> 4; |
| 530 | 522 | } |
| 531 | 523 | |
| 532 | | static WRITE8_HANDLER( megaplay_bios_6404_w ) |
| 524 | WRITE8_MEMBER(mplay_state::megaplay_bios_6404_w ) |
| 533 | 525 | { |
| 534 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 535 | | if(((state->m_bios_6404 & 0x0c) == 0x00) && ((data & 0x0c) == 0x0c)) |
| 536 | | space.machine().device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, PULSE_LINE); |
| 537 | | state->m_bios_6404 = data; |
| 526 | if(((m_bios_6404 & 0x0c) == 0x00) && ((data & 0x0c) == 0x0c)) |
| 527 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, PULSE_LINE); |
| 528 | m_bios_6404 = data; |
| 538 | 529 | |
| 539 | 530 | // logerror("BIOS: 0x6404 write: 0x%02x\n", data); |
| 540 | 531 | } |
| 541 | 532 | |
| 542 | | static READ8_HANDLER( megaplay_bios_6600_r ) |
| 533 | READ8_MEMBER(mplay_state::megaplay_bios_6600_r ) |
| 543 | 534 | { |
| 544 | 535 | /* Multi-slot note: |
| 545 | 536 | 0x6600 appears to be used to check for extra slots being used. |
| 546 | 537 | Enter the following line in place of the return statement in this |
| 547 | 538 | function to make the BIOS check all 4 slots (3 and 4 will be "not used") |
| 548 | | return (state->m_bios_6600 & 0xfe) | (state->m_bios_bank & 0x01); |
| 539 | return (m_bios_6600 & 0xfe) | (m_bios_bank & 0x01); |
| 549 | 540 | */ |
| 550 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 551 | | return state->m_bios_6600;// & 0xfe; |
| 541 | return m_bios_6600;// & 0xfe; |
| 552 | 542 | } |
| 553 | 543 | |
| 554 | | static WRITE8_HANDLER( megaplay_bios_6600_w ) |
| 544 | WRITE8_MEMBER(mplay_state::megaplay_bios_6600_w ) |
| 555 | 545 | { |
| 556 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 557 | | state->m_bios_6600 = data; |
| 546 | m_bios_6600 = data; |
| 558 | 547 | // logerror("BIOS: 0x6600 write: 0x%02x\n",data); |
| 559 | 548 | } |
| 560 | 549 | |
| 561 | | static WRITE8_HANDLER( megaplay_game_w ) |
| 550 | WRITE8_MEMBER(mplay_state::megaplay_game_w ) |
| 562 | 551 | { |
| 563 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 564 | | if (state->m_readpos == 1) |
| 565 | | state->m_game_banksel = 0; |
| 566 | | state->m_game_banksel |= (1 << (state->m_readpos - 1)) * (data & 0x01); |
| 552 | if (m_readpos == 1) |
| 553 | m_game_banksel = 0; |
| 554 | m_game_banksel |= (1 << (m_readpos - 1)) * (data & 0x01); |
| 567 | 555 | |
| 568 | | state->m_readpos++; |
| 556 | m_readpos++; |
| 569 | 557 | |
| 570 | | if (state->m_readpos > 9) |
| 558 | if (m_readpos > 9) |
| 571 | 559 | { |
| 572 | | state->m_bios_mode = MP_GAME; |
| 573 | | state->m_readpos = 1; |
| 574 | | // popmessage("Game bank selected: 0x%03x", state->m_game_banksel); |
| 575 | | logerror("BIOS [0x%04x]: 68K address space bank selected: 0x%03x\n", space.device().safe_pcbase(), state->m_game_banksel); |
| 560 | m_bios_mode = MP_GAME; |
| 561 | m_readpos = 1; |
| 562 | // popmessage("Game bank selected: 0x%03x", m_game_banksel); |
| 563 | logerror("BIOS [0x%04x]: 68K address space bank selected: 0x%03x\n", space.device().safe_pcbase(), m_game_banksel); |
| 576 | 564 | } |
| 577 | 565 | |
| 578 | | state->m_mp_bios_bank_addr = ((state->m_mp_bios_bank_addr >> 1) | (data << 23)) & 0xff8000; |
| 566 | m_mp_bios_bank_addr = ((m_mp_bios_bank_addr >> 1) | (data << 23)) & 0xff8000; |
| 579 | 567 | } |
| 580 | 568 | |
| 581 | 569 | static ADDRESS_MAP_START( megaplay_bios_map, AS_PROGRAM, 8, mplay_state ) |
| 582 | 570 | AM_RANGE(0x0000, 0x3fff) AM_ROM |
| 583 | 571 | AM_RANGE(0x4000, 0x4fff) AM_RAM |
| 584 | 572 | AM_RANGE(0x5000, 0x5fff) AM_RAM |
| 585 | | AM_RANGE(0x6000, 0x6000) AM_WRITE_LEGACY(megaplay_game_w) |
| 573 | AM_RANGE(0x6000, 0x6000) AM_WRITE(megaplay_game_w) |
| 586 | 574 | AM_RANGE(0x6200, 0x6200) AM_READ_PORT("DSW0") |
| 587 | 575 | AM_RANGE(0x6201, 0x6201) AM_READ_PORT("DSW1") |
| 588 | | AM_RANGE(0x6203, 0x6203) AM_READWRITE_LEGACY(megaplay_bios_banksel_r, megaplay_bios_banksel_w) |
| 589 | | AM_RANGE(0x6204, 0x6204) AM_READWRITE_LEGACY(megaplay_bios_6204_r, megaplay_bios_width_w) |
| 576 | AM_RANGE(0x6203, 0x6203) AM_READWRITE(megaplay_bios_banksel_r, megaplay_bios_banksel_w) |
| 577 | AM_RANGE(0x6204, 0x6204) AM_READWRITE(megaplay_bios_6204_r, megaplay_bios_width_w) |
| 590 | 578 | AM_RANGE(0x6400, 0x6400) AM_READ_PORT("TEST") |
| 591 | 579 | AM_RANGE(0x6401, 0x6401) AM_READ_PORT("COIN") |
| 592 | | AM_RANGE(0x6402, 0x6402) AM_READWRITE_LEGACY(megaplay_bios_6402_r, megaplay_bios_6402_w) |
| 593 | | AM_RANGE(0x6403, 0x6403) AM_READWRITE_LEGACY(megaplay_bios_gamesel_r, megaplay_bios_gamesel_w) |
| 594 | | AM_RANGE(0x6404, 0x6404) AM_READWRITE_LEGACY(megaplay_bios_6404_r, megaplay_bios_6404_w) |
| 595 | | AM_RANGE(0x6600, 0x6600) AM_READWRITE_LEGACY(megaplay_bios_6600_r, megaplay_bios_6600_w) |
| 580 | AM_RANGE(0x6402, 0x6402) AM_READWRITE(megaplay_bios_6402_r, megaplay_bios_6402_w) |
| 581 | AM_RANGE(0x6403, 0x6403) AM_READWRITE(megaplay_bios_gamesel_r, megaplay_bios_gamesel_w) |
| 582 | AM_RANGE(0x6404, 0x6404) AM_READWRITE(megaplay_bios_6404_r, megaplay_bios_6404_w) |
| 583 | AM_RANGE(0x6600, 0x6600) AM_READWRITE(megaplay_bios_6600_r, megaplay_bios_6600_w) |
| 596 | 584 | AM_RANGE(0x6001, 0x67ff) AM_WRITEONLY |
| 597 | 585 | AM_RANGE(0x6800, 0x77ff) AM_RAM AM_SHARE("ic3_ram") |
| 598 | | AM_RANGE(0x8000, 0xffff) AM_READWRITE_LEGACY(bank_r, bank_w) |
| 586 | AM_RANGE(0x8000, 0xffff) AM_READWRITE(bank_r, bank_w) |
| 599 | 587 | ADDRESS_MAP_END |
| 600 | 588 | |
| 601 | 589 | /* basically from src/drivers/segasyse.c */ |
| r22069 | r22070 | |
| 830 | 818 | ROM_END |
| 831 | 819 | |
| 832 | 820 | |
| 833 | | static void mplay_start(running_machine &machine) |
| 821 | void mplay_state::mplay_start() |
| 834 | 822 | { |
| 835 | | UINT8 *src = machine.root_device().memregion("mtbios")->base(); |
| 836 | | UINT8 *instruction_rom = machine.root_device().memregion("user1")->base(); |
| 837 | | UINT8 *game_rom = machine.root_device().memregion("maincpu")->base(); |
| 823 | UINT8 *src = machine().root_device().memregion("mtbios")->base(); |
| 824 | UINT8 *instruction_rom = machine().root_device().memregion("user1")->base(); |
| 825 | UINT8 *game_rom = machine().root_device().memregion("maincpu")->base(); |
| 838 | 826 | int offs; |
| 839 | 827 | |
| 840 | 828 | memmove(src + 0x10000, src + 0x8000, 0x18000); // move bios.. |
| r22069 | r22070 | |
| 850 | 838 | } |
| 851 | 839 | } |
| 852 | 840 | |
| 853 | | static READ16_HANDLER( megadriv_68k_read_z80_extra_ram ) |
| 841 | READ16_MEMBER(mplay_state::megadriv_68k_read_z80_extra_ram ) |
| 854 | 842 | { |
| 855 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 856 | | return state->m_ic36_ram[(offset << 1) ^ 1] | (state->m_ic36_ram[(offset << 1)] << 8); |
| 843 | return m_ic36_ram[(offset << 1) ^ 1] | (m_ic36_ram[(offset << 1)] << 8); |
| 857 | 844 | } |
| 858 | 845 | |
| 859 | | static WRITE16_HANDLER( megadriv_68k_write_z80_extra_ram ) |
| 846 | WRITE16_MEMBER(mplay_state::megadriv_68k_write_z80_extra_ram ) |
| 860 | 847 | { |
| 861 | | mplay_state *state = space.machine().driver_data<mplay_state>(); |
| 862 | 848 | if (!ACCESSING_BITS_0_7) // byte (MSB) access |
| 863 | 849 | { |
| 864 | | state->m_ic36_ram[(offset << 1)] = (data & 0xff00) >> 8; |
| 850 | m_ic36_ram[(offset << 1)] = (data & 0xff00) >> 8; |
| 865 | 851 | } |
| 866 | 852 | else if (!ACCESSING_BITS_8_15) |
| 867 | 853 | { |
| 868 | | state->m_ic36_ram[(offset << 1) ^ 1] = (data & 0x00ff); |
| 854 | m_ic36_ram[(offset << 1) ^ 1] = (data & 0x00ff); |
| 869 | 855 | } |
| 870 | 856 | else // for WORD access only the MSB is used, LSB is ignored |
| 871 | 857 | { |
| 872 | | state->m_ic36_ram[(offset << 1)] = (data & 0xff00) >> 8; |
| 858 | m_ic36_ram[(offset << 1)] = (data & 0xff00) >> 8; |
| 873 | 859 | } |
| 874 | 860 | } |
| 875 | 861 | |
| r22069 | r22070 | |
| 883 | 869 | |
| 884 | 870 | DRIVER_INIT_CALL(mpnew); |
| 885 | 871 | |
| 886 | | mplay_start(machine()); |
| 872 | mplay_start(); |
| 887 | 873 | |
| 888 | 874 | /* for now ... */ |
| 889 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0xa10000, 0xa1001f, FUNC(megaplay_io_read), FUNC(megaplay_io_write)); |
| 875 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa10000, 0xa1001f, read16_delegate(FUNC(mplay_state::megaplay_io_read),this), write16_delegate(FUNC(mplay_state::megaplay_io_write),this)); |
| 890 | 876 | |
| 891 | 877 | /* megaplay has ram shared with the bios cpu here */ |
| 892 | 878 | machine().device("genesis_snd_z80")->memory().space(AS_PROGRAM).install_ram(0x2000, 0x3fff, &m_ic36_ram[0]); |
| 893 | 879 | |
| 894 | 880 | /* instead of a RAM mirror the 68k sees the extra ram of the 2nd z80 too */ |
| 895 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0xa02000, 0xa03fff, FUNC(megadriv_68k_read_z80_extra_ram), FUNC(megadriv_68k_write_z80_extra_ram)); |
| 881 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa02000, 0xa03fff, read16_delegate(FUNC(mplay_state::megadriv_68k_read_z80_extra_ram),this), write16_delegate(FUNC(mplay_state::megadriv_68k_write_z80_extra_ram),this)); |
| 896 | 882 | |
| 897 | 883 | init_megatech_bios(machine()); |
| 898 | 884 | |
trunk/src/mame/machine/megadriv.c
| r22069 | r22070 | |
| 28 | 28 | |
| 29 | 29 | MACHINE_CONFIG_EXTERN( megadriv ); |
| 30 | 30 | |
| 31 | | timer_device* megadriv_scanline_timer; |
| 31 | extern timer_device* megadriv_scanline_timer; |
| 32 | 32 | |
| 33 | 33 | |
| 34 | 34 | void megadriv_z80_hold(running_machine &machine) |
| r22069 | r22070 | |
| 44 | 44 | state->m_z80snd->set_input_line(0, CLEAR_LINE); |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | | static void megadriv_z80_bank_w(address_space &space, UINT16 data) |
| 47 | void md_base_state::megadriv_z80_bank_w(UINT16 data) |
| 48 | 48 | { |
| 49 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 50 | | state->m_genz80.z80_bank_addr = ((state->m_genz80.z80_bank_addr >> 1) | (data << 23)) & 0xff8000; |
| 49 | m_genz80.z80_bank_addr = ((m_genz80.z80_bank_addr >> 1) | (data << 23)) & 0xff8000; |
| 51 | 50 | } |
| 52 | 51 | |
| 53 | | static WRITE16_HANDLER( megadriv_68k_z80_bank_write ) |
| 52 | WRITE16_MEMBER(md_base_state::megadriv_68k_z80_bank_write ) |
| 54 | 53 | { |
| 55 | 54 | //logerror("%06x: 68k writing bit to bank register %01x\n", space.device().safe_pc(),data&0x01); |
| 56 | | megadriv_z80_bank_w(space, data & 0x01); |
| 55 | megadriv_z80_bank_w(data & 0x01); |
| 57 | 56 | } |
| 58 | 57 | |
| 59 | | static WRITE8_HANDLER(megadriv_z80_z80_bank_w) |
| 58 | WRITE8_MEMBER(md_base_state::megadriv_z80_z80_bank_w) |
| 60 | 59 | { |
| 61 | 60 | //logerror("%04x: z80 writing bit to bank register %01x\n", space.device().safe_pc(),data&0x01); |
| 62 | | megadriv_z80_bank_w(space, data & 0x01); |
| 61 | megadriv_z80_bank_w(data & 0x01); |
| 63 | 62 | } |
| 64 | 63 | |
| 65 | | |
| 66 | | static DECLARE_READ16_HANDLER( megadriv_68k_check_z80_bus ); |
| 67 | | static DECLARE_WRITE16_HANDLER(megadriv_68k_req_z80_bus); |
| 68 | | |
| 69 | | static DECLARE_READ16_HANDLER( megadriv_68k_read_z80_ram ); |
| 70 | | static DECLARE_WRITE16_HANDLER( megadriv_68k_write_z80_ram ); |
| 71 | | |
| 72 | | static DECLARE_WRITE16_HANDLER( megadriv_68k_req_z80_reset ); |
| 73 | | |
| 74 | | |
| 75 | | |
| 76 | 64 | READ8_MEMBER(md_base_state::megadriv_68k_YM2612_read) |
| 77 | 65 | { |
| 78 | 66 | device_t *device = machine().device("ymsnd"); |
| r22069 | r22070 | |
| 106 | 94 | } |
| 107 | 95 | |
| 108 | 96 | /* Megadrive / Genesis has 3 I/O ports */ |
| 109 | | static emu_timer *io_timeout[3]; |
| 110 | | static int io_stage[3]; |
| 97 | static emu_timer *m_io_timeout[3]; |
| 98 | static int m_io_stage[3]; |
| 111 | 99 | |
| 112 | 100 | static TIMER_CALLBACK( io_timeout_timer_callback ) |
| 113 | 101 | { |
| 114 | | io_stage[(int)(FPTR)ptr] = -1; |
| 102 | m_io_stage[(int)(FPTR)ptr] = -1; |
| 115 | 103 | } |
| 116 | 104 | |
| 117 | 105 | static void init_megadri6_io(running_machine &machine) |
| r22069 | r22070 | |
| 120 | 108 | |
| 121 | 109 | for (i=0; i<3; i++) |
| 122 | 110 | { |
| 123 | | io_timeout[i] = machine.scheduler().timer_alloc(FUNC(io_timeout_timer_callback), (void*)(FPTR)i); |
| 111 | m_io_timeout[i] = machine.scheduler().timer_alloc(FUNC(io_timeout_timer_callback), (void*)(FPTR)i); |
| 124 | 112 | } |
| 125 | 113 | } |
| 126 | 114 | |
| r22069 | r22070 | |
| 213 | 201 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_PLAYER(2) PORT_NAME("P2 MODE") // mode |
| 214 | 202 | INPUT_PORTS_END |
| 215 | 203 | |
| 216 | | UINT8 megadrive_io_data_regs[3]; |
| 217 | | UINT8 megadrive_io_ctrl_regs[3]; |
| 218 | | static UINT8 megadrive_io_tx_regs[3]; |
| 219 | | int megadrive_6buttons_pad = 0; |
| 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; |
| 220 | 208 | |
| 221 | 209 | static void megadrive_reset_io(running_machine &machine) |
| 222 | 210 | { |
| 223 | 211 | int i; |
| 224 | 212 | |
| 225 | | megadrive_io_data_regs[0] = 0x7f; |
| 226 | | megadrive_io_data_regs[1] = 0x7f; |
| 227 | | megadrive_io_data_regs[2] = 0x7f; |
| 228 | | megadrive_io_ctrl_regs[0] = 0x00; |
| 229 | | megadrive_io_ctrl_regs[1] = 0x00; |
| 230 | | megadrive_io_ctrl_regs[2] = 0x00; |
| 231 | | megadrive_io_tx_regs[0] = 0xff; |
| 232 | | megadrive_io_tx_regs[1] = 0xff; |
| 233 | | megadrive_io_tx_regs[2] = 0xff; |
| 213 | m_megadrive_io_data_regs[0] = 0x7f; |
| 214 | m_megadrive_io_data_regs[1] = 0x7f; |
| 215 | m_megadrive_io_data_regs[2] = 0x7f; |
| 216 | m_megadrive_io_ctrl_regs[0] = 0x00; |
| 217 | m_megadrive_io_ctrl_regs[1] = 0x00; |
| 218 | m_megadrive_io_ctrl_regs[2] = 0x00; |
| 219 | m_megadrive_io_tx_regs[0] = 0xff; |
| 220 | m_megadrive_io_tx_regs[1] = 0xff; |
| 221 | m_megadrive_io_tx_regs[2] = 0xff; |
| 234 | 222 | |
| 235 | 223 | for (i=0; i<3; i++) |
| 236 | 224 | { |
| 237 | | io_stage[i] = -1; |
| 225 | m_io_stage[i] = -1; |
| 238 | 226 | } |
| 239 | 227 | } |
| 240 | 228 | |
| 241 | 229 | /************* 6 buttons version **************************/ |
| 242 | 230 | static UINT8 megadrive_io_read_data_port_6button(running_machine &machine, int portnum) |
| 243 | 231 | { |
| 244 | | UINT8 retdata, helper = (megadrive_io_ctrl_regs[portnum] & 0x3f) | 0xc0; // bits 6 & 7 always come from megadrive_io_data_regs |
| 232 | UINT8 retdata, helper = (m_megadrive_io_ctrl_regs[portnum] & 0x3f) | 0xc0; // bits 6 & 7 always come from m_megadrive_io_data_regs |
| 245 | 233 | static const char *const pad3names[] = { "PAD1", "PAD2", "IN0", "UNK" }; |
| 246 | 234 | static const char *const pad6names[] = { "EXTRA1", "EXTRA2", "IN0", "UNK" }; |
| 247 | 235 | |
| 248 | | if (megadrive_io_data_regs[portnum] & 0x40) |
| 236 | if (m_megadrive_io_data_regs[portnum] & 0x40) |
| 249 | 237 | { |
| 250 | | if (io_stage[portnum] == 2) |
| 238 | if (m_io_stage[portnum] == 2) |
| 251 | 239 | { |
| 252 | 240 | /* here we read B, C & the additional buttons */ |
| 253 | | retdata = (megadrive_io_data_regs[portnum] & helper) | |
| 241 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 254 | 242 | (((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x30) | |
| 255 | 243 | (machine.root_device().ioport(pad6names[portnum])->read_safe(0) & 0x0f)) & ~helper); |
| 256 | 244 | } |
| 257 | 245 | else |
| 258 | 246 | { |
| 259 | 247 | /* here we read B, C & the directional buttons */ |
| 260 | | retdata = (megadrive_io_data_regs[portnum] & helper) | |
| 248 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 261 | 249 | ((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x3f) & ~helper); |
| 262 | 250 | } |
| 263 | 251 | } |
| 264 | 252 | else |
| 265 | 253 | { |
| 266 | | if (io_stage[portnum] == 1) |
| 254 | if (m_io_stage[portnum] == 1) |
| 267 | 255 | { |
| 268 | 256 | /* here we read ((Start & A) >> 2) | 0x00 */ |
| 269 | | retdata = (megadrive_io_data_regs[portnum] & helper) | |
| 257 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 270 | 258 | (((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) & ~helper); |
| 271 | 259 | } |
| 272 | | else if (io_stage[portnum]==2) |
| 260 | else if (m_io_stage[portnum]==2) |
| 273 | 261 | { |
| 274 | 262 | /* here we read ((Start & A) >> 2) | 0x0f */ |
| 275 | | retdata = (megadrive_io_data_regs[portnum] & helper) | |
| 263 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 276 | 264 | ((((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | 0x0f) & ~helper); |
| 277 | 265 | } |
| 278 | 266 | else |
| 279 | 267 | { |
| 280 | 268 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 281 | | retdata = (megadrive_io_data_regs[portnum] & helper) | |
| 269 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 282 | 270 | ((((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 283 | 271 | (machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x03)) & ~helper); |
| 284 | 272 | } |
| 285 | 273 | } |
| 286 | 274 | |
| 287 | | // mame_printf_debug("read io data port stage %d port %d %02x\n",io_stage[portnum],portnum,retdata); |
| 275 | // mame_printf_debug("read io data port stage %d port %d %02x\n",m_io_stage[portnum],portnum,retdata); |
| 288 | 276 | |
| 289 | 277 | return retdata | (retdata << 8); |
| 290 | 278 | } |
| r22069 | r22070 | |
| 293 | 281 | /************* 3 buttons version **************************/ |
| 294 | 282 | UINT8 megadrive_io_read_data_port_3button(running_machine &machine, int portnum) |
| 295 | 283 | { |
| 296 | | UINT8 retdata, helper = (megadrive_io_ctrl_regs[portnum] & 0x7f) | 0x80; // bit 7 always comes from megadrive_io_data_regs |
| 284 | UINT8 retdata, helper = (m_megadrive_io_ctrl_regs[portnum] & 0x7f) | 0x80; // bit 7 always comes from m_megadrive_io_data_regs |
| 297 | 285 | static const char *const pad3names[] = { "PAD1", "PAD2", "IN0", "UNK" }; |
| 298 | 286 | |
| 299 | | if (megadrive_io_data_regs[portnum] & 0x40) |
| 287 | if (m_megadrive_io_data_regs[portnum] & 0x40) |
| 300 | 288 | { |
| 301 | 289 | /* here we read B, C & the directional buttons */ |
| 302 | | retdata = (megadrive_io_data_regs[portnum] & helper) | |
| 290 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 303 | 291 | (((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x3f) | 0x40) & ~helper); |
| 304 | 292 | } |
| 305 | 293 | else |
| 306 | 294 | { |
| 307 | 295 | /* here we read ((Start & A) >> 2) | Up and Down */ |
| 308 | | retdata = (megadrive_io_data_regs[portnum] & helper) | |
| 296 | retdata = (m_megadrive_io_data_regs[portnum] & helper) | |
| 309 | 297 | ((((machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0xc0) >> 2) | |
| 310 | 298 | (machine.root_device().ioport(pad3names[portnum])->read_safe(0) & 0x03) | 0x40) & ~helper); |
| 311 | 299 | } |
| r22069 | r22070 | |
| 343 | 331 | static UINT8 megadrive_io_read_ctrl_port(int portnum) |
| 344 | 332 | { |
| 345 | 333 | UINT8 retdata; |
| 346 | | retdata = megadrive_io_ctrl_regs[portnum]; |
| 334 | retdata = m_megadrive_io_ctrl_regs[portnum]; |
| 347 | 335 | //mame_printf_debug("read io ctrl port %d %02x\n",portnum,retdata); |
| 348 | 336 | |
| 349 | 337 | return retdata | (retdata << 8); |
| r22069 | r22070 | |
| 352 | 340 | static UINT8 megadrive_io_read_tx_port(int portnum) |
| 353 | 341 | { |
| 354 | 342 | UINT8 retdata; |
| 355 | | retdata = megadrive_io_tx_regs[portnum]; |
| 343 | retdata = m_megadrive_io_tx_regs[portnum]; |
| 356 | 344 | return retdata | (retdata << 8); |
| 357 | 345 | } |
| 358 | 346 | |
| r22069 | r22070 | |
| 367 | 355 | } |
| 368 | 356 | |
| 369 | 357 | |
| 370 | | READ16_HANDLER( megadriv_68k_io_read ) |
| 358 | READ16_MEMBER(md_base_state::megadriv_68k_io_read ) |
| 371 | 359 | { |
| 372 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 373 | 360 | UINT8 retdata; |
| 374 | 361 | |
| 375 | 362 | retdata = 0; |
| r22069 | r22070 | |
| 389 | 376 | { |
| 390 | 377 | case 0: |
| 391 | 378 | logerror("%06x read version register\n", space.device().safe_pc()); |
| 392 | | retdata = state->m_export << 7 | // Export |
| 393 | | state->m_pal << 6 | // NTSC or PAL? |
| 394 | | (state->m_segacd ? 0x00 : 0x20) | // 0x20 = no sega cd |
| 379 | retdata = m_export << 7 | // Export |
| 380 | m_pal << 6 | // NTSC or PAL? |
| 381 | (m_segacd ? 0x00 : 0x20) | // 0x20 = no sega cd |
| 395 | 382 | 0x00 | // Unused (Always 0) |
| 396 | 383 | 0x00 | // Bit 3 of Version Number |
| 397 | 384 | 0x00 | // Bit 2 of Version Number |
| r22069 | r22070 | |
| 436 | 423 | |
| 437 | 424 | static void megadrive_io_write_data_port_3button(running_machine &machine, int portnum, UINT16 data) |
| 438 | 425 | { |
| 439 | | megadrive_io_data_regs[portnum] = data; |
| 426 | m_megadrive_io_data_regs[portnum] = data; |
| 440 | 427 | //mame_printf_debug("Writing IO Data Register #%d data %04x\n",portnum,data); |
| 441 | 428 | |
| 442 | 429 | } |
| r22069 | r22070 | |
| 446 | 433 | |
| 447 | 434 | static void megadrive_io_write_data_port_6button(running_machine &machine, int portnum, UINT16 data) |
| 448 | 435 | { |
| 449 | | if (megadrive_io_ctrl_regs[portnum]&0x40) |
| 436 | if (m_megadrive_io_ctrl_regs[portnum]&0x40) |
| 450 | 437 | { |
| 451 | | if (((megadrive_io_data_regs[portnum]&0x40)==0x00) && ((data&0x40) == 0x40)) |
| 438 | if (((m_megadrive_io_data_regs[portnum]&0x40)==0x00) && ((data&0x40) == 0x40)) |
| 452 | 439 | { |
| 453 | | io_stage[portnum]++; |
| 454 | | io_timeout[portnum]->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(8192)); |
| 440 | m_io_stage[portnum]++; |
| 441 | m_io_timeout[portnum]->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(8192)); |
| 455 | 442 | } |
| 456 | 443 | |
| 457 | 444 | } |
| 458 | 445 | |
| 459 | | megadrive_io_data_regs[portnum] = data; |
| 446 | m_megadrive_io_data_regs[portnum] = data; |
| 460 | 447 | //mame_printf_debug("Writing IO Data Register #%d data %04x\n",portnum,data); |
| 461 | 448 | |
| 462 | 449 | } |
| r22069 | r22070 | |
| 466 | 453 | |
| 467 | 454 | static void megadrive_io_write_ctrl_port(running_machine &machine, int portnum, UINT16 data) |
| 468 | 455 | { |
| 469 | | megadrive_io_ctrl_regs[portnum] = data; |
| 456 | m_megadrive_io_ctrl_regs[portnum] = data; |
| 470 | 457 | // mame_printf_debug("Setting IO Control Register #%d data %04x\n",portnum,data); |
| 471 | 458 | } |
| 472 | 459 | |
| 473 | 460 | static void megadrive_io_write_tx_port(running_machine &machine, int portnum, UINT16 data) |
| 474 | 461 | { |
| 475 | | megadrive_io_tx_regs[portnum] = data; |
| 462 | m_megadrive_io_tx_regs[portnum] = data; |
| 476 | 463 | } |
| 477 | 464 | |
| 478 | 465 | static void megadrive_io_write_rx_port(running_machine &machine, int portnum, UINT16 data) |
| r22069 | r22070 | |
| 484 | 471 | } |
| 485 | 472 | |
| 486 | 473 | |
| 487 | | WRITE16_HANDLER( megadriv_68k_io_write ) |
| 474 | WRITE16_MEMBER(md_base_state::megadriv_68k_io_write ) |
| 488 | 475 | { |
| 489 | 476 | // mame_printf_debug("IO Write #%02x data %04x mem_mask %04x\n",offset,data,mem_mask); |
| 490 | 477 | |
| r22069 | r22070 | |
| 532 | 519 | AM_RANGE(0x000000, 0x3fffff) AM_ROM |
| 533 | 520 | /* (0x000000 - 0x3fffff) == GAME ROM (4Meg Max, Some games have special banking too) */ |
| 534 | 521 | |
| 535 | | AM_RANGE(0xa00000, 0xa01fff) AM_READWRITE_LEGACY(megadriv_68k_read_z80_ram,megadriv_68k_write_z80_ram) |
| 536 | | AM_RANGE(0xa02000, 0xa03fff) AM_WRITE_LEGACY(megadriv_68k_write_z80_ram) |
| 522 | AM_RANGE(0xa00000, 0xa01fff) AM_READWRITE(megadriv_68k_read_z80_ram,megadriv_68k_write_z80_ram) |
| 523 | AM_RANGE(0xa02000, 0xa03fff) AM_WRITE(megadriv_68k_write_z80_ram) |
| 537 | 524 | AM_RANGE(0xa04000, 0xa04003) AM_READWRITE8(megadriv_68k_YM2612_read,megadriv_68k_YM2612_write, 0xffff) |
| 538 | 525 | |
| 539 | | AM_RANGE(0xa06000, 0xa06001) AM_WRITE_LEGACY(megadriv_68k_z80_bank_write) |
| 526 | AM_RANGE(0xa06000, 0xa06001) AM_WRITE(megadriv_68k_z80_bank_write) |
| 540 | 527 | |
| 541 | | AM_RANGE(0xa10000, 0xa1001f) AM_READWRITE_LEGACY(megadriv_68k_io_read,megadriv_68k_io_write) |
| 528 | AM_RANGE(0xa10000, 0xa1001f) AM_READWRITE(megadriv_68k_io_read,megadriv_68k_io_write) |
| 542 | 529 | |
| 543 | | AM_RANGE(0xa11100, 0xa11101) AM_READWRITE_LEGACY(megadriv_68k_check_z80_bus,megadriv_68k_req_z80_bus) |
| 544 | | AM_RANGE(0xa11200, 0xa11201) AM_WRITE_LEGACY(megadriv_68k_req_z80_reset) |
| 530 | AM_RANGE(0xa11100, 0xa11101) AM_READWRITE(megadriv_68k_check_z80_bus,megadriv_68k_req_z80_bus) |
| 531 | AM_RANGE(0xa11200, 0xa11201) AM_WRITE(megadriv_68k_req_z80_reset) |
| 545 | 532 | |
| 546 | 533 | /* these are fake - remove allocs in VIDEO_START to use these to view ram instead */ |
| 547 | 534 | // AM_RANGE(0xb00000, 0xb0ffff) AM_RAM AM_SHARE("megadrive_vdp_vram") |
| r22069 | r22070 | |
| 560 | 547 | /* z80 sounds/sub CPU */ |
| 561 | 548 | |
| 562 | 549 | |
| 563 | | static READ16_HANDLER( megadriv_68k_read_z80_ram ) |
| 550 | READ16_MEMBER(md_base_state::megadriv_68k_read_z80_ram ) |
| 564 | 551 | { |
| 565 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 566 | 552 | //mame_printf_debug("read z80 ram %04x\n",mem_mask); |
| 567 | 553 | |
| 568 | | if ((state->m_genz80.z80_has_bus == 0) && (state->m_genz80.z80_is_reset == 0)) |
| 554 | if ((m_genz80.z80_has_bus == 0) && (m_genz80.z80_is_reset == 0)) |
| 569 | 555 | { |
| 570 | | return state->m_genz80.z80_prgram[(offset<<1)^1] | (state->m_genz80.z80_prgram[(offset<<1)]<<8); |
| 556 | return m_genz80.z80_prgram[(offset<<1)^1] | (m_genz80.z80_prgram[(offset<<1)]<<8); |
| 571 | 557 | } |
| 572 | 558 | else |
| 573 | 559 | { |
| r22069 | r22070 | |
| 576 | 562 | } |
| 577 | 563 | } |
| 578 | 564 | |
| 579 | | static WRITE16_HANDLER( megadriv_68k_write_z80_ram ) |
| 565 | WRITE16_MEMBER(md_base_state::megadriv_68k_write_z80_ram ) |
| 580 | 566 | { |
| 581 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 582 | 567 | //logerror("write z80 ram\n"); |
| 583 | 568 | |
| 584 | | if ((state->m_genz80.z80_has_bus == 0) && (state->m_genz80.z80_is_reset == 0)) |
| 569 | if ((m_genz80.z80_has_bus == 0) && (m_genz80.z80_is_reset == 0)) |
| 585 | 570 | { |
| 586 | 571 | if (!ACCESSING_BITS_0_7) // byte (MSB) access |
| 587 | 572 | { |
| 588 | | state->m_genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
| 573 | m_genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
| 589 | 574 | } |
| 590 | 575 | else if (!ACCESSING_BITS_8_15) |
| 591 | 576 | { |
| 592 | | state->m_genz80.z80_prgram[(offset<<1)^1] = (data & 0x00ff); |
| 577 | m_genz80.z80_prgram[(offset<<1)^1] = (data & 0x00ff); |
| 593 | 578 | } |
| 594 | 579 | else // for WORD access only the MSB is used, LSB is ignored |
| 595 | 580 | { |
| 596 | | state->m_genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
| 581 | m_genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
| 597 | 582 | } |
| 598 | 583 | } |
| 599 | 584 | else |
| r22069 | r22070 | |
| 603 | 588 | } |
| 604 | 589 | |
| 605 | 590 | |
| 606 | | static READ16_HANDLER( megadriv_68k_check_z80_bus ) |
| 591 | READ16_MEMBER(md_base_state::megadriv_68k_check_z80_bus ) |
| 607 | 592 | { |
| 608 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 609 | 593 | UINT16 retvalue; |
| 610 | 594 | |
| 611 | 595 | /* Double Dragon, Shadow of the Beast, Super Off Road, and Time Killers have buggy |
| r22069 | r22070 | |
| 621 | 605 | /* Check if the 68k has the z80 bus */ |
| 622 | 606 | if (!ACCESSING_BITS_0_7) // byte (MSB) access |
| 623 | 607 | { |
| 624 | | if (state->m_genz80.z80_has_bus || state->m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
| 608 | if (m_genz80.z80_has_bus || m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
| 625 | 609 | else retvalue = (nextvalue & 0xfeff); |
| 626 | 610 | |
| 627 | 611 | //logerror("%06x: 68000 check z80 Bus (byte MSB access) returning %04x mask %04x\n", space.device().safe_pc(),retvalue, mem_mask); |
| r22069 | r22070 | |
| 631 | 615 | else if (!ACCESSING_BITS_8_15) // is this valid? |
| 632 | 616 | { |
| 633 | 617 | //logerror("%06x: 68000 check z80 Bus (byte LSB access) %04x\n", space.device().safe_pc(),mem_mask); |
| 634 | | if (state->m_genz80.z80_has_bus || state->m_genz80.z80_is_reset) retvalue = 0x0001; |
| 618 | if (m_genz80.z80_has_bus || m_genz80.z80_is_reset) retvalue = 0x0001; |
| 635 | 619 | else retvalue = 0x0000; |
| 636 | 620 | |
| 637 | 621 | return retvalue; |
| r22069 | r22070 | |
| 639 | 623 | else |
| 640 | 624 | { |
| 641 | 625 | //logerror("%06x: 68000 check z80 Bus (word access) %04x\n", space.device().safe_pc(),mem_mask); |
| 642 | | if (state->m_genz80.z80_has_bus || state->m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
| 626 | if (m_genz80.z80_has_bus || m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
| 643 | 627 | else retvalue = (nextvalue & 0xfeff); |
| 644 | 628 | |
| 645 | 629 | // mame_printf_debug("%06x: 68000 check z80 Bus (word access) %04x %04x\n", space.device().safe_pc(),mem_mask, retvalue); |
| r22069 | r22070 | |
| 648 | 632 | } |
| 649 | 633 | |
| 650 | 634 | |
| 651 | | static TIMER_CALLBACK( megadriv_z80_run_state ) |
| 635 | TIMER_CALLBACK_MEMBER(md_base_state::megadriv_z80_run_state) |
| 652 | 636 | { |
| 653 | | md_base_state *state = machine.driver_data<md_base_state>(); |
| 654 | 637 | /* Is the z80 RESET line pulled? */ |
| 655 | | if (state->m_genz80.z80_is_reset) |
| 638 | if (m_genz80.z80_is_reset) |
| 656 | 639 | { |
| 657 | | state->m_z80snd->reset(); |
| 658 | | state->m_z80snd->suspend(SUSPEND_REASON_HALT, 1); |
| 659 | | machine.device("ymsnd")->reset(); |
| 640 | m_z80snd->reset(); |
| 641 | m_z80snd->suspend(SUSPEND_REASON_HALT, 1); |
| 642 | machine().device("ymsnd")->reset(); |
| 660 | 643 | } |
| 661 | 644 | else |
| 662 | 645 | { |
| 663 | 646 | /* Check if z80 has the bus */ |
| 664 | | if (state->m_genz80.z80_has_bus) |
| 665 | | state->m_z80snd->resume(SUSPEND_REASON_HALT); |
| 647 | if (m_genz80.z80_has_bus) |
| 648 | m_z80snd->resume(SUSPEND_REASON_HALT); |
| 666 | 649 | else |
| 667 | | state->m_z80snd->suspend(SUSPEND_REASON_HALT, 1); |
| 650 | m_z80snd->suspend(SUSPEND_REASON_HALT, 1); |
| 668 | 651 | } |
| 669 | 652 | } |
| 670 | 653 | |
| 671 | 654 | |
| 672 | | static WRITE16_HANDLER( megadriv_68k_req_z80_bus ) |
| 655 | WRITE16_MEMBER(md_base_state::megadriv_68k_req_z80_bus ) |
| 673 | 656 | { |
| 674 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 675 | 657 | /* Request the Z80 bus, allows 68k to read/write Z80 address space */ |
| 676 | 658 | if (!ACCESSING_BITS_0_7) // byte access |
| 677 | 659 | { |
| 678 | 660 | if (data & 0x0100) |
| 679 | 661 | { |
| 680 | 662 | //logerror("%06x: 68000 request z80 Bus (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 681 | | state->m_genz80.z80_has_bus = 0; |
| 663 | m_genz80.z80_has_bus = 0; |
| 682 | 664 | } |
| 683 | 665 | else |
| 684 | 666 | { |
| 685 | 667 | //logerror("%06x: 68000 return z80 Bus (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 686 | | state->m_genz80.z80_has_bus = 1; |
| 668 | m_genz80.z80_has_bus = 1; |
| 687 | 669 | } |
| 688 | 670 | } |
| 689 | 671 | else if (!ACCESSING_BITS_8_15) // is this valid? |
| r22069 | r22070 | |
| 691 | 673 | if (data & 0x0001) |
| 692 | 674 | { |
| 693 | 675 | //logerror("%06x: 68000 request z80 Bus (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 694 | | state->m_genz80.z80_has_bus = 0; |
| 676 | m_genz80.z80_has_bus = 0; |
| 695 | 677 | } |
| 696 | 678 | else |
| 697 | 679 | { |
| 698 | 680 | //logerror("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 699 | | state->m_genz80.z80_has_bus = 1; |
| 681 | m_genz80.z80_has_bus = 1; |
| 700 | 682 | } |
| 701 | 683 | } |
| 702 | 684 | else // word access |
| r22069 | r22070 | |
| 704 | 686 | if (data & 0x0100) |
| 705 | 687 | { |
| 706 | 688 | //logerror("%06x: 68000 request z80 Bus (word access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 707 | | state->m_genz80.z80_has_bus = 0; |
| 689 | m_genz80.z80_has_bus = 0; |
| 708 | 690 | } |
| 709 | 691 | else |
| 710 | 692 | { |
| 711 | 693 | //logerror("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 712 | | state->m_genz80.z80_has_bus = 1; |
| 694 | m_genz80.z80_has_bus = 1; |
| 713 | 695 | } |
| 714 | 696 | } |
| 715 | 697 | |
| 716 | 698 | /* If the z80 is running, sync the z80 execution state */ |
| 717 | | if (!state->m_genz80.z80_is_reset) |
| 718 | | space.machine().scheduler().timer_set(attotime::zero, FUNC(megadriv_z80_run_state)); |
| 699 | if (!m_genz80.z80_is_reset) |
| 700 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(md_base_state::megadriv_z80_run_state),this)); |
| 719 | 701 | } |
| 720 | 702 | |
| 721 | | static WRITE16_HANDLER ( megadriv_68k_req_z80_reset ) |
| 703 | WRITE16_MEMBER(md_base_state::megadriv_68k_req_z80_reset ) |
| 722 | 704 | { |
| 723 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 724 | 705 | if (!ACCESSING_BITS_0_7) // byte access |
| 725 | 706 | { |
| 726 | 707 | if (data & 0x0100) |
| 727 | 708 | { |
| 728 | 709 | //logerror("%06x: 68000 clear z80 reset (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 729 | | state->m_genz80.z80_is_reset = 0; |
| 710 | m_genz80.z80_is_reset = 0; |
| 730 | 711 | } |
| 731 | 712 | else |
| 732 | 713 | { |
| 733 | 714 | //logerror("%06x: 68000 start z80 reset (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 734 | | state->m_genz80.z80_is_reset = 1; |
| 715 | m_genz80.z80_is_reset = 1; |
| 735 | 716 | } |
| 736 | 717 | } |
| 737 | 718 | else if (!ACCESSING_BITS_8_15) // is this valid? |
| r22069 | r22070 | |
| 739 | 720 | if (data & 0x0001) |
| 740 | 721 | { |
| 741 | 722 | //logerror("%06x: 68000 clear z80 reset (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 742 | | state->m_genz80.z80_is_reset = 0; |
| 723 | m_genz80.z80_is_reset = 0; |
| 743 | 724 | } |
| 744 | 725 | else |
| 745 | 726 | { |
| 746 | 727 | //logerror("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 747 | | state->m_genz80.z80_is_reset = 1; |
| 728 | m_genz80.z80_is_reset = 1; |
| 748 | 729 | } |
| 749 | 730 | } |
| 750 | 731 | else // word access |
| r22069 | r22070 | |
| 752 | 733 | if (data & 0x0100) |
| 753 | 734 | { |
| 754 | 735 | //logerror("%06x: 68000 clear z80 reset (word access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 755 | | state->m_genz80.z80_is_reset = 0; |
| 736 | m_genz80.z80_is_reset = 0; |
| 756 | 737 | } |
| 757 | 738 | else |
| 758 | 739 | { |
| 759 | 740 | //logerror("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
| 760 | | state->m_genz80.z80_is_reset = 1; |
| 741 | m_genz80.z80_is_reset = 1; |
| 761 | 742 | } |
| 762 | 743 | } |
| 763 | | space.machine().scheduler().timer_set( attotime::zero, FUNC(megadriv_z80_run_state )); |
| 744 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(md_base_state::megadriv_z80_run_state),this)); |
| 764 | 745 | } |
| 765 | 746 | |
| 766 | 747 | |
| r22069 | r22070 | |
| 768 | 749 | // add-on hardware which changes the cpu mapping like the 32x and SegaCD. |
| 769 | 750 | // - we might need to add exceptions for example, z80 reading / writing the |
| 770 | 751 | // z80 area of the 68k if games misbehave |
| 771 | | static READ8_HANDLER( z80_read_68k_banked_data ) |
| 752 | READ8_MEMBER(md_base_state::z80_read_68k_banked_data ) |
| 772 | 753 | { |
| 773 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 774 | | address_space &space68k = state->m_maincpu->space(); |
| 775 | | UINT8 ret = space68k.read_byte(state->m_genz80.z80_bank_addr+offset); |
| 754 | address_space &space68k = m_maincpu->space(); |
| 755 | UINT8 ret = space68k.read_byte(m_genz80.z80_bank_addr+offset); |
| 776 | 756 | return ret; |
| 777 | 757 | } |
| 778 | 758 | |
| 779 | | static WRITE8_HANDLER( z80_write_68k_banked_data ) |
| 759 | WRITE8_MEMBER(md_base_state::z80_write_68k_banked_data ) |
| 780 | 760 | { |
| 781 | | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 782 | | address_space &space68k = state->m_maincpu->space(); |
| 783 | | space68k.write_byte(state->m_genz80.z80_bank_addr+offset,data); |
| 761 | address_space &space68k = m_maincpu->space(); |
| 762 | space68k.write_byte(m_genz80.z80_bank_addr+offset,data); |
| 784 | 763 | } |
| 785 | 764 | |
| 786 | 765 | |
| 787 | | static WRITE8_HANDLER( megadriv_z80_vdp_write ) |
| 766 | WRITE8_MEMBER(md_base_state::megadriv_z80_vdp_write ) |
| 788 | 767 | { |
| 789 | 768 | switch (offset) |
| 790 | 769 | { |
| r22069 | r22070 | |
| 804 | 783 | |
| 805 | 784 | |
| 806 | 785 | |
| 807 | | static READ8_HANDLER( megadriv_z80_vdp_read ) |
| 786 | READ8_MEMBER(md_base_state::megadriv_z80_vdp_read ) |
| 808 | 787 | { |
| 809 | 788 | mame_printf_debug("megadriv_z80_vdp_read %02x\n",offset); |
| 810 | 789 | return space.machine().rand(); |
| 811 | 790 | } |
| 812 | 791 | |
| 813 | | static READ8_HANDLER( megadriv_z80_unmapped_read ) |
| 792 | READ8_MEMBER(md_base_state::megadriv_z80_unmapped_read ) |
| 814 | 793 | { |
| 815 | 794 | return 0xff; |
| 816 | 795 | } |
| 817 | 796 | |
| 818 | | static ADDRESS_MAP_START( megadriv_z80_map, AS_PROGRAM, 8, driver_device ) |
| 797 | static ADDRESS_MAP_START( megadriv_z80_map, AS_PROGRAM, 8, md_base_state ) |
| 819 | 798 | AM_RANGE(0x0000, 0x1fff) AM_RAMBANK("bank1") AM_MIRROR(0x2000) // RAM can be accessed by the 68k |
| 820 | 799 | AM_RANGE(0x4000, 0x4003) AM_DEVREADWRITE_LEGACY("ymsnd", ym2612_r,ym2612_w) |
| 821 | 800 | |
| 822 | | AM_RANGE(0x6000, 0x6000) AM_WRITE_LEGACY(megadriv_z80_z80_bank_w) |
| 823 | | AM_RANGE(0x6001, 0x6001) AM_WRITE_LEGACY(megadriv_z80_z80_bank_w) // wacky races uses this address |
| 801 | AM_RANGE(0x6000, 0x6000) AM_WRITE(megadriv_z80_z80_bank_w) |
| 802 | AM_RANGE(0x6001, 0x6001) AM_WRITE(megadriv_z80_z80_bank_w) // wacky races uses this address |
| 824 | 803 | |
| 825 | | AM_RANGE(0x6100, 0x7eff) AM_READ_LEGACY(megadriv_z80_unmapped_read) |
| 804 | AM_RANGE(0x6100, 0x7eff) AM_READ(megadriv_z80_unmapped_read) |
| 826 | 805 | |
| 827 | | AM_RANGE(0x7f00, 0x7fff) AM_READWRITE_LEGACY(megadriv_z80_vdp_read,megadriv_z80_vdp_write) |
| 806 | AM_RANGE(0x7f00, 0x7fff) AM_READWRITE(megadriv_z80_vdp_read,megadriv_z80_vdp_write) |
| 828 | 807 | |
| 829 | | AM_RANGE(0x8000, 0xffff) AM_READWRITE_LEGACY(z80_read_68k_banked_data,z80_write_68k_banked_data) // The Z80 can read the 68k address space this way |
| 808 | AM_RANGE(0x8000, 0xffff) AM_READWRITE(z80_read_68k_banked_data,z80_write_68k_banked_data) // The Z80 can read the 68k address space this way |
| 830 | 809 | ADDRESS_MAP_END |
| 831 | 810 | |
| 832 | | static ADDRESS_MAP_START( megadriv_z80_io_map, AS_IO, 8, driver_device ) |
| 811 | static ADDRESS_MAP_START( megadriv_z80_io_map, AS_IO, 8, md_base_state ) |
| 833 | 812 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 834 | 813 | AM_RANGE(0x0000, 0xff) AM_NOP |
| 835 | 814 | ADDRESS_MAP_END |
| r22069 | r22070 | |
| 842 | 821 | AM_RANGE(0x000000, 0x0fffff) AM_ROM /* Cartridge Program Rom */ |
| 843 | 822 | AM_RANGE(0x200000, 0x2023ff) AM_RAM // tested |
| 844 | 823 | |
| 845 | | AM_RANGE(0xa00000, 0xa01fff) AM_READWRITE_LEGACY(megadriv_68k_read_z80_ram, megadriv_68k_write_z80_ram) |
| 846 | | AM_RANGE(0xa02000, 0xa03fff) AM_WRITE_LEGACY(megadriv_68k_write_z80_ram) |
| 824 | AM_RANGE(0xa00000, 0xa01fff) AM_READWRITE(megadriv_68k_read_z80_ram, megadriv_68k_write_z80_ram) |
| 825 | AM_RANGE(0xa02000, 0xa03fff) AM_WRITE(megadriv_68k_write_z80_ram) |
| 847 | 826 | AM_RANGE(0xa04000, 0xa04003) AM_READWRITE8(megadriv_68k_YM2612_read, megadriv_68k_YM2612_write, 0xffff) |
| 848 | | AM_RANGE(0xa06000, 0xa06001) AM_WRITE_LEGACY(megadriv_68k_z80_bank_write) |
| 827 | AM_RANGE(0xa06000, 0xa06001) AM_WRITE(megadriv_68k_z80_bank_write) |
| 849 | 828 | |
| 850 | | AM_RANGE(0xa10000, 0xa1001f) AM_READWRITE_LEGACY(megadriv_68k_io_read, megadriv_68k_io_write) |
| 851 | | AM_RANGE(0xa11100, 0xa11101) AM_READWRITE_LEGACY(megadriv_68k_check_z80_bus, megadriv_68k_req_z80_bus) |
| 852 | | AM_RANGE(0xa11200, 0xa11201) AM_WRITE_LEGACY(megadriv_68k_req_z80_reset) |
| 829 | AM_RANGE(0xa10000, 0xa1001f) AM_READWRITE(megadriv_68k_io_read, megadriv_68k_io_write) |
| 830 | AM_RANGE(0xa11100, 0xa11101) AM_READWRITE(megadriv_68k_check_z80_bus, megadriv_68k_req_z80_bus) |
| 831 | AM_RANGE(0xa11200, 0xa11201) AM_WRITE(megadriv_68k_req_z80_reset) |
| 853 | 832 | |
| 854 | 833 | AM_RANGE(0xc00000, 0xc0001f) AM_DEVREADWRITE("gen_vdp", sega_genesis_vdp_device, megadriv_vdp_r,megadriv_vdp_w) |
| 855 | 834 | AM_RANGE(0xd00000, 0xd0001f) AM_DEVREADWRITE("gen_vdp", sega_genesis_vdp_device, megadriv_vdp_r,megadriv_vdp_w) |
| r22069 | r22070 | |
| 902 | 881 | |
| 903 | 882 | MACHINE_START( megadriv ) |
| 904 | 883 | { |
| 905 | | if (megadrive_6buttons_pad) |
| 884 | if (m_megadrive_6buttons_pad) |
| 906 | 885 | init_megadri6_io(machine); |
| 907 | 886 | } |
| 908 | 887 | |
| r22069 | r22070 | |
| 919 | 898 | state->m_genz80.z80_has_bus = 1; |
| 920 | 899 | state->m_genz80.z80_bank_addr = 0; |
| 921 | 900 | state->m_vdp->set_scanline_counter(-1); |
| 922 | | machine.scheduler().timer_set(attotime::zero, FUNC(megadriv_z80_run_state)); |
| 901 | machine.scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(md_base_state::megadriv_z80_run_state),state)); |
| 923 | 902 | } |
| 924 | 903 | |
| 925 | 904 | megadrive_reset_io(machine); |
| r22069 | r22070 | |
| 1193 | 1172 | m68k_set_tas_callback(machine().device("maincpu"), megadriv_tas_callback); |
| 1194 | 1173 | |
| 1195 | 1174 | // the drivers which need 6 buttons pad set this to 1 in their init befare calling the megadrive init |
| 1196 | | if (megadrive_6buttons_pad) |
| 1175 | if (m_megadrive_6buttons_pad) |
| 1197 | 1176 | { |
| 1198 | 1177 | megadrive_io_read_data_port_ptr = megadrive_io_read_data_port_6button; |
| 1199 | 1178 | megadrive_io_write_data_port_ptr = megadrive_io_write_data_port_6button; |
| r22069 | r22070 | |
| 1320 | 1299 | } |
| 1321 | 1300 | |
| 1322 | 1301 | /* used by megatech */ |
| 1323 | | static READ8_HANDLER( z80_unmapped_port_r ) |
| 1302 | READ8_MEMBER(md_base_state::z80_unmapped_port_r ) |
| 1324 | 1303 | { |
| 1325 | 1304 | // printf("unmapped z80 port read %04x\n",offset); |
| 1326 | 1305 | return 0; |
| 1327 | 1306 | } |
| 1328 | 1307 | |
| 1329 | | static WRITE8_HANDLER( z80_unmapped_port_w ) |
| 1308 | WRITE8_MEMBER(md_base_state::z80_unmapped_port_w ) |
| 1330 | 1309 | { |
| 1331 | 1310 | // printf("unmapped z80 port write %04x\n",offset); |
| 1332 | 1311 | } |
| 1333 | 1312 | |
| 1334 | | static READ8_HANDLER( z80_unmapped_r ) |
| 1313 | READ8_MEMBER(md_base_state::z80_unmapped_r ) |
| 1335 | 1314 | { |
| 1336 | 1315 | printf("unmapped z80 read %04x\n",offset); |
| 1337 | 1316 | return 0; |
| 1338 | 1317 | } |
| 1339 | 1318 | |
| 1340 | | static WRITE8_HANDLER( z80_unmapped_w ) |
| 1319 | WRITE8_MEMBER(md_base_state::z80_unmapped_w ) |
| 1341 | 1320 | { |
| 1342 | 1321 | printf("unmapped z80 write %04x\n",offset); |
| 1343 | 1322 | } |
| 1344 | 1323 | |
| 1345 | 1324 | |
| 1346 | 1325 | /* sets the megadrive z80 to it's normal ports / map */ |
| 1347 | | void megatech_set_megadrive_z80_as_megadrive_z80(running_machine &machine, const char* tag) |
| 1326 | void mtech_state::megatech_set_megadrive_z80_as_megadrive_z80(const char* tag) |
| 1348 | 1327 | { |
| 1349 | | md_base_state *state = machine.driver_data<md_base_state>(); |
| 1350 | | device_t *ym = machine.device("ymsnd"); |
| 1328 | device_t *ym = machine().device("ymsnd"); |
| 1351 | 1329 | |
| 1352 | 1330 | /* INIT THE PORTS *********************************************************************************************/ |
| 1353 | | machine.device(tag)->memory().space(AS_IO).install_legacy_readwrite_handler(0x0000, 0xffff, FUNC(z80_unmapped_port_r), FUNC(z80_unmapped_port_w)); |
| 1331 | machine().device(tag)->memory().space(AS_IO).install_readwrite_handler(0x0000, 0xffff, read8_delegate(FUNC(mtech_state::z80_unmapped_port_r),this), write8_delegate(FUNC(mtech_state::z80_unmapped_port_w),this)); |
| 1354 | 1332 | |
| 1355 | 1333 | /* catch any addresses that don't get mapped */ |
| 1356 | | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x0000, 0xffff, FUNC(z80_unmapped_r), FUNC(z80_unmapped_w)); |
| 1334 | machine().device(tag)->memory().space(AS_PROGRAM).install_readwrite_handler(0x0000, 0xffff, read8_delegate(FUNC(mtech_state::z80_unmapped_r),this), write8_delegate(FUNC(mtech_state::z80_unmapped_w),this)); |
| 1357 | 1335 | |
| 1358 | 1336 | |
| 1359 | | machine.device(tag)->memory().space(AS_PROGRAM).install_readwrite_bank(0x0000, 0x1fff, "bank1"); |
| 1360 | | machine.root_device().membank("bank1")->set_base(state->m_genz80.z80_prgram); |
| 1337 | machine().device(tag)->memory().space(AS_PROGRAM).install_readwrite_bank(0x0000, 0x1fff, "bank1"); |
| 1338 | machine().root_device().membank("bank1")->set_base(m_genz80.z80_prgram); |
| 1361 | 1339 | |
| 1362 | | machine.device(tag)->memory().space(AS_PROGRAM).install_ram(0x0000, 0x1fff, state->m_genz80.z80_prgram); |
| 1340 | machine().device(tag)->memory().space(AS_PROGRAM).install_ram(0x0000, 0x1fff, m_genz80.z80_prgram); |
| 1363 | 1341 | |
| 1364 | 1342 | |
| 1365 | | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(*ym, 0x4000, 0x4003, FUNC(ym2612_r), FUNC(ym2612_w)); |
| 1366 | | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_write_handler (0x6000, 0x6000, FUNC(megadriv_z80_z80_bank_w)); |
| 1367 | | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_write_handler (0x6001, 0x6001, FUNC(megadriv_z80_z80_bank_w)); |
| 1368 | | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_read_handler (0x6100, 0x7eff, FUNC(megadriv_z80_unmapped_read)); |
| 1369 | | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x7f00, 0x7fff, FUNC(megadriv_z80_vdp_read), FUNC(megadriv_z80_vdp_write)); |
| 1370 | | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x8000, 0xffff, FUNC(z80_read_68k_banked_data), FUNC(z80_write_68k_banked_data)); |
| 1343 | machine().device(tag)->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(*ym, 0x4000, 0x4003, FUNC(ym2612_r), FUNC(ym2612_w)); |
| 1344 | machine().device(tag)->memory().space(AS_PROGRAM).install_write_handler (0x6000, 0x6000, write8_delegate(FUNC(mtech_state::megadriv_z80_z80_bank_w),this)); |
| 1345 | machine().device(tag)->memory().space(AS_PROGRAM).install_write_handler (0x6001, 0x6001, write8_delegate(FUNC(mtech_state::megadriv_z80_z80_bank_w),this)); |
| 1346 | machine().device(tag)->memory().space(AS_PROGRAM).install_read_handler (0x6100, 0x7eff, read8_delegate(FUNC(mtech_state::megadriv_z80_unmapped_read),this)); |
| 1347 | machine().device(tag)->memory().space(AS_PROGRAM).install_readwrite_handler(0x7f00, 0x7fff, read8_delegate(FUNC(mtech_state::megadriv_z80_vdp_read),this), write8_delegate(FUNC(mtech_state::megadriv_z80_vdp_write),this)); |
| 1348 | machine().device(tag)->memory().space(AS_PROGRAM).install_readwrite_handler(0x8000, 0xffff, read8_delegate(FUNC(mtech_state::z80_read_68k_banked_data),this), write8_delegate(FUNC(mtech_state::z80_write_68k_banked_data),this)); |
| 1371 | 1349 | } |
| 1372 | 1350 | |
| 1373 | 1351 | |