trunk/src/mess/machine/sms.c
| r20377 | r20378 | |
| 27 | 27 | #define LGUN_X_INTERVAL 4 |
| 28 | 28 | |
| 29 | 29 | |
| 30 | | static void setup_rom(address_space &space); |
| 31 | | |
| 32 | | |
| 33 | 30 | TIMER_CALLBACK_MEMBER(sms_state::rapid_fire_callback) |
| 34 | 31 | { |
| 35 | 32 | m_rapid_fire_state_1 ^= 0xff; |
| r20377 | r20378 | |
| 285 | 282 | /* FIXME: this function is a hack for Light Phaser emulation. Theoretically |
| 286 | 283 | sms_vdp_hcount_latch() should be used instead, but it returns incorrect |
| 287 | 284 | position for unknown reason (timing?) */ |
| 288 | | static void sms_vdp_hcount_lphaser( running_machine &machine, int hpos ) |
| 285 | void sms_state::vdp_hcount_lphaser( int hpos ) |
| 289 | 286 | { |
| 290 | | sms_state *state = machine.driver_data<sms_state>(); |
| 291 | | int hpos_tmp = hpos + state->m_lphaser_x_offs; |
| 287 | int hpos_tmp = hpos + m_lphaser_x_offs; |
| 292 | 288 | UINT8 tmp = ((hpos_tmp - 46) >> 1) & 0xff; |
| 293 | 289 | |
| 294 | 290 | //printf ("sms_vdp_hcount_lphaser: hpos %3d hpos_tmp %3d => hcount %2X\n", hpos, hpos_tmp, tmp); |
| 295 | | state->m_vdp->hcount_latch_write(*state->m_space, 0, tmp); |
| 291 | m_vdp->hcount_latch_write(*m_space, 0, tmp); |
| 296 | 292 | } |
| 297 | 293 | |
| 298 | 294 | |
| r20377 | r20378 | |
| 318 | 314 | - The whole procedure is managed by a timer callback, that always reschedule |
| 319 | 315 | itself to run in some intervals when the beam is at the circular area. |
| 320 | 316 | */ |
| 321 | | static int lgun_bright_aim_area( running_machine &machine, emu_timer *timer, int lgun_x, int lgun_y ) |
| 317 | int sms_state::lgun_bright_aim_area( emu_timer *timer, int lgun_x, int lgun_y ) |
| 322 | 318 | { |
| 323 | | sms_state *state = machine.driver_data<sms_state>(); |
| 324 | 319 | const int r_x_r = LGUN_RADIUS * LGUN_RADIUS; |
| 325 | | screen_device *screen = machine.first_screen(); |
| 326 | | const rectangle &visarea = screen->visible_area(); |
| 327 | | int beam_x = screen->hpos(); |
| 328 | | int beam_y = screen->vpos(); |
| 320 | const rectangle &visarea = m_main_scr->visible_area(); |
| 321 | int beam_x = m_main_scr->hpos(); |
| 322 | int beam_y = m_main_scr->vpos(); |
| 329 | 323 | int dx, dy; |
| 330 | 324 | int result = 0; |
| 331 | 325 | int pos_changed = 0; |
| r20377 | r20378 | |
| 365 | 359 | |
| 366 | 360 | if (!pos_changed) |
| 367 | 361 | { |
| 368 | | bitmap_rgb32 &bitmap = state->m_vdp->get_bitmap(); |
| 362 | bitmap_rgb32 &bitmap = m_vdp->get_bitmap(); |
| 369 | 363 | |
| 370 | 364 | /* brightness of the lightgray color in the frame drawn by Light Phaser games */ |
| 371 | 365 | const UINT8 sensor_min_brightness = 0x7f; |
| r20377 | r20378 | |
| 390 | 384 | else |
| 391 | 385 | break; |
| 392 | 386 | } |
| 393 | | timer->adjust(machine.first_screen()->time_until_pos(beam_y, beam_x)); |
| 387 | timer->adjust(m_main_scr->time_until_pos(beam_y, beam_x)); |
| 394 | 388 | |
| 395 | 389 | return result; |
| 396 | 390 | } |
| 397 | 391 | |
| 398 | | static UINT8 sms_vdp_hcount( running_machine &machine ) |
| 392 | UINT8 sms_state::sms_vdp_hcount() |
| 399 | 393 | { |
| 400 | 394 | UINT8 tmp; |
| 401 | | screen_device *screen = machine.first_screen(); |
| 402 | | int hpos = screen->hpos(); |
| 395 | int hpos = m_main_scr->hpos(); |
| 403 | 396 | |
| 404 | 397 | /* alternative method: pass HCounter test, but some others fail */ |
| 405 | 398 | //int hpos_tmp = hpos; |
| r20377 | r20378 | |
| 408 | 401 | |
| 409 | 402 | UINT64 calc_cycles; |
| 410 | 403 | attotime time_end; |
| 411 | | int vpos = screen->vpos(); |
| 412 | | int max_hpos = screen->width() - 1; |
| 404 | int vpos = m_main_scr->vpos(); |
| 405 | int max_hpos = m_main_scr->width() - 1; |
| 413 | 406 | |
| 414 | 407 | if (hpos == max_hpos) |
| 415 | 408 | time_end = attotime::zero; |
| 416 | 409 | else |
| 417 | | time_end = screen->time_until_pos(vpos, max_hpos); |
| 418 | | calc_cycles = machine.device<cpu_device>("maincpu")->attotime_to_clocks(time_end); |
| 410 | time_end = m_main_scr->time_until_pos(vpos, max_hpos); |
| 411 | calc_cycles = m_main_cpu->attotime_to_clocks(time_end); |
| 419 | 412 | |
| 420 | 413 | /* equation got from SMSPower forum, posted by Flubba. */ |
| 421 | 414 | tmp = ((590 - (calc_cycles * 3)) / 4) & 0xff; |
| r20377 | r20378 | |
| 425 | 418 | } |
| 426 | 419 | |
| 427 | 420 | |
| 428 | | static void sms_vdp_hcount_latch( address_space &space ) |
| 421 | void sms_state::sms_vdp_hcount_latch( address_space &space ) |
| 429 | 422 | { |
| 430 | | sms_state *state = space.machine().driver_data<sms_state>(); |
| 431 | | UINT8 value = sms_vdp_hcount(space.machine()); |
| 423 | UINT8 value = sms_vdp_hcount(); |
| 432 | 424 | |
| 433 | | state->m_vdp->hcount_latch_write(space, 0, value); |
| 425 | m_vdp->hcount_latch_write(space, 0, value); |
| 434 | 426 | } |
| 435 | 427 | |
| 436 | 428 | |
| 437 | | static UINT16 screen_hpos_nonscaled( screen_device &screen, int scaled_hpos ) |
| 429 | UINT16 sms_state::screen_hpos_nonscaled(int scaled_hpos) |
| 438 | 430 | { |
| 439 | | const rectangle &visarea = screen.visible_area(); |
| 431 | const rectangle &visarea = m_main_scr->visible_area(); |
| 440 | 432 | int offset_x = (scaled_hpos * visarea.width()) / 255; |
| 441 | 433 | return visarea.min_x + offset_x; |
| 442 | 434 | } |
| 443 | 435 | |
| 444 | 436 | |
| 445 | | static UINT16 screen_vpos_nonscaled( screen_device &screen, int scaled_vpos ) |
| 437 | UINT16 sms_state::screen_vpos_nonscaled(int scaled_vpos) |
| 446 | 438 | { |
| 447 | | const rectangle &visarea = screen.visible_area(); |
| 439 | const rectangle &visarea = m_main_scr->visible_area(); |
| 448 | 440 | int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255; |
| 449 | 441 | return visarea.min_y + offset_y; |
| 450 | 442 | } |
| 451 | 443 | |
| 452 | 444 | |
| 453 | | static void lphaser1_sensor_check( running_machine &machine ) |
| 445 | void sms_state::lphaser1_sensor_check() |
| 454 | 446 | { |
| 455 | | sms_state *state = machine.driver_data<sms_state>(); |
| 456 | | const int x = screen_hpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER0")->read()); |
| 457 | | const int y = screen_vpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER1")->read()); |
| 447 | const int x = screen_hpos_nonscaled( ioport("LPHASER0")->read() ); |
| 448 | const int y = screen_vpos_nonscaled( ioport("LPHASER1")->read() ); |
| 458 | 449 | |
| 459 | | if (lgun_bright_aim_area(machine, state->m_lphaser_1_timer, x, y)) |
| 450 | if (lgun_bright_aim_area(m_lphaser_1_timer, x, y)) |
| 460 | 451 | { |
| 461 | | if (state->m_lphaser_1_latch == 0) |
| 452 | if (m_lphaser_1_latch == 0) |
| 462 | 453 | { |
| 463 | | state->m_lphaser_1_latch = 1; |
| 464 | | sms_vdp_hcount_lphaser(machine, x); |
| 454 | m_lphaser_1_latch = 1; |
| 455 | vdp_hcount_lphaser(x); |
| 465 | 456 | } |
| 466 | 457 | } |
| 467 | 458 | } |
| 468 | 459 | |
| 469 | | static void lphaser2_sensor_check( running_machine &machine ) |
| 460 | void sms_state::lphaser2_sensor_check() |
| 470 | 461 | { |
| 471 | | sms_state *state = machine.driver_data<sms_state>(); |
| 472 | | const int x = screen_hpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER2")->read()); |
| 473 | | const int y = screen_vpos_nonscaled(*machine.first_screen(), machine.root_device().ioport("LPHASER3")->read()); |
| 462 | const int x = screen_hpos_nonscaled( ioport("LPHASER2")->read() ); |
| 463 | const int y = screen_vpos_nonscaled( ioport("LPHASER3")->read() ); |
| 474 | 464 | |
| 475 | | if (lgun_bright_aim_area(machine, state->m_lphaser_2_timer, x, y)) |
| 465 | if (lgun_bright_aim_area(m_lphaser_2_timer, x, y)) |
| 476 | 466 | { |
| 477 | | if (state->m_lphaser_2_latch == 0) |
| 467 | if (m_lphaser_2_latch == 0) |
| 478 | 468 | { |
| 479 | | state->m_lphaser_2_latch = 1; |
| 480 | | sms_vdp_hcount_lphaser(machine, x); |
| 469 | m_lphaser_2_latch = 1; |
| 470 | vdp_hcount_lphaser(x); |
| 481 | 471 | } |
| 482 | 472 | } |
| 483 | 473 | } |
| r20377 | r20378 | |
| 492 | 482 | /* enable crosshair */ |
| 493 | 483 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); |
| 494 | 484 | if (!m_lphaser_1_timer->enabled()) |
| 495 | | lphaser1_sensor_check(machine()); |
| 485 | lphaser1_sensor_check(); |
| 496 | 486 | } |
| 497 | 487 | else |
| 498 | 488 | { |
| r20377 | r20378 | |
| 506 | 496 | /* enable crosshair */ |
| 507 | 497 | crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL); |
| 508 | 498 | if (!m_lphaser_2_timer->enabled()) |
| 509 | | lphaser2_sensor_check(machine()); |
| 499 | lphaser2_sensor_check(); |
| 510 | 500 | } |
| 511 | 501 | else |
| 512 | 502 | { |
| r20377 | r20378 | |
| 519 | 509 | |
| 520 | 510 | TIMER_CALLBACK_MEMBER(sms_state::lphaser_1_callback) |
| 521 | 511 | { |
| 522 | | lphaser1_sensor_check(machine()); |
| 512 | lphaser1_sensor_check(); |
| 523 | 513 | } |
| 524 | 514 | |
| 525 | 515 | |
| 526 | 516 | TIMER_CALLBACK_MEMBER(sms_state::lphaser_2_callback) |
| 527 | 517 | { |
| 528 | | lphaser2_sensor_check(machine()); |
| 518 | lphaser2_sensor_check(); |
| 529 | 519 | } |
| 530 | 520 | |
| 531 | 521 | |
| 532 | 522 | INPUT_CHANGED_MEMBER(sms_state::lgun1_changed) |
| 533 | 523 | { |
| 534 | 524 | if (!m_lphaser_1_timer || |
| 535 | | (machine().root_device().ioport("CTRLSEL")->read_safe(0x00) & 0x0f) != 0x01) |
| 525 | (ioport("CTRLSEL")->read_safe(0x00) & 0x0f) != 0x01) |
| 536 | 526 | return; |
| 537 | 527 | |
| 538 | 528 | if (newval != oldval) |
| 539 | | lphaser1_sensor_check(machine()); |
| 529 | lphaser1_sensor_check(); |
| 540 | 530 | } |
| 541 | 531 | |
| 542 | 532 | INPUT_CHANGED_MEMBER(sms_state::lgun2_changed) |
| 543 | 533 | { |
| 544 | 534 | if (!m_lphaser_2_timer || |
| 545 | | (machine().root_device().ioport("CTRLSEL")->read_safe(0x00) & 0xf0) != 0x10) |
| 535 | (ioport("CTRLSEL")->read_safe(0x00) & 0xf0) != 0x10) |
| 546 | 536 | return; |
| 547 | 537 | |
| 548 | 538 | if (newval != oldval) |
| 549 | | lphaser2_sensor_check(machine()); |
| 539 | lphaser2_sensor_check(); |
| 550 | 540 | } |
| 551 | 541 | |
| 552 | 542 | |
| 553 | | static void sms_get_inputs( address_space &space ) |
| 543 | void sms_state::sms_get_inputs( address_space &space ) |
| 554 | 544 | { |
| 555 | | sms_state *state = space.machine().driver_data<sms_state>(); |
| 556 | 545 | UINT8 data = 0x00; |
| 557 | | UINT32 cpu_cycles = downcast<cpu_device *>(&space.device())->total_cycles(); |
| 558 | | running_machine &machine = space.machine(); |
| 546 | UINT32 cpu_cycles = m_main_cpu->total_cycles(); |
| 559 | 547 | |
| 560 | | state->m_input_port0 = 0xff; |
| 561 | | state->m_input_port1 = 0xff; |
| 548 | m_input_port0 = 0xff; |
| 549 | m_input_port1 = 0xff; |
| 562 | 550 | |
| 563 | | if (cpu_cycles - state->m_last_paddle_read_time > 256) |
| 551 | if (cpu_cycles - m_last_paddle_read_time > 256) |
| 564 | 552 | { |
| 565 | | state->m_paddle_read_state ^= 0xff; |
| 566 | | state->m_last_paddle_read_time = cpu_cycles; |
| 553 | m_paddle_read_state ^= 0xff; |
| 554 | m_last_paddle_read_time = cpu_cycles; |
| 567 | 555 | } |
| 568 | 556 | |
| 569 | 557 | /* Check if lightgun has been chosen as input: if so, enable crosshair */ |
| 570 | | machine.scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sms_state::lightgun_tick),state)); |
| 558 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sms_state::lightgun_tick),this)); |
| 571 | 559 | |
| 572 | 560 | /* Player 1 */ |
| 573 | | switch (machine.root_device().ioport("CTRLSEL")->read_safe(0x00) & 0x0f) |
| 561 | switch (ioport("CTRLSEL")->read_safe(0x00) & 0x0f) |
| 574 | 562 | { |
| 575 | 563 | case 0x00: /* Joystick */ |
| 576 | | data = machine.root_device().ioport("PORT_DC")->read(); |
| 564 | data = ioport("PORT_DC")->read(); |
| 577 | 565 | /* Check Rapid Fire setting for Button A */ |
| 578 | | if (!(data & 0x10) && (machine.root_device().ioport("RFU")->read() & 0x01)) |
| 579 | | data |= state->m_rapid_fire_state_1 & 0x10; |
| 566 | if (!(data & 0x10) && (ioport("RFU")->read() & 0x01)) |
| 567 | data |= m_rapid_fire_state_1 & 0x10; |
| 580 | 568 | |
| 581 | 569 | /* Check Rapid Fire setting for Button B */ |
| 582 | | if (!(data & 0x20) && (machine.root_device().ioport("RFU")->read() & 0x02)) |
| 583 | | data |= state->m_rapid_fire_state_1 & 0x20; |
| 570 | if (!(data & 0x20) && (ioport("RFU")->read() & 0x02)) |
| 571 | data |= m_rapid_fire_state_1 & 0x20; |
| 584 | 572 | |
| 585 | | state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f); |
| 573 | m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f); |
| 586 | 574 | break; |
| 587 | 575 | |
| 588 | 576 | case 0x01: /* Light Phaser */ |
| 589 | | data = (machine.root_device().ioport("CTRLIPT")->read() & 0x01) << 4; |
| 577 | data = (ioport("CTRLIPT")->read() & 0x01) << 4; |
| 590 | 578 | if (!(data & 0x10)) |
| 591 | 579 | { |
| 592 | | if (machine.root_device().ioport("RFU")->read() & 0x01) |
| 593 | | data |= state->m_rapid_fire_state_1 & 0x10; |
| 580 | if (ioport("RFU")->read() & 0x01) |
| 581 | data |= m_rapid_fire_state_1 & 0x10; |
| 594 | 582 | } |
| 595 | 583 | /* just consider the button (trigger) bit */ |
| 596 | 584 | data |= ~0x10; |
| 597 | | state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f); |
| 585 | m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f); |
| 598 | 586 | break; |
| 599 | 587 | |
| 600 | 588 | case 0x02: /* Paddle Control */ |
| 601 | 589 | /* Get button A state */ |
| 602 | | data = machine.root_device().ioport("PADDLE0")->read(); |
| 590 | data = ioport("PADDLE0")->read(); |
| 603 | 591 | |
| 604 | | if (state->m_paddle_read_state) |
| 592 | if (m_paddle_read_state) |
| 605 | 593 | data = data >> 4; |
| 606 | 594 | |
| 607 | | state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x0f) | (state->m_paddle_read_state & 0x20) |
| 608 | | | ((machine.root_device().ioport("CTRLIPT")->read() & 0x02) << 3); |
| 595 | m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x0f) | (m_paddle_read_state & 0x20) |
| 596 | | ((ioport("CTRLIPT")->read() & 0x02) << 3); |
| 609 | 597 | break; |
| 610 | 598 | |
| 611 | 599 | case 0x04: /* Sega Sports Pad */ |
| 612 | | switch (state->m_sports_pad_state_1) |
| 600 | switch (m_sports_pad_state_1) |
| 613 | 601 | { |
| 614 | 602 | case 0: |
| 615 | | data = (state->m_sports_pad_1_x >> 4) & 0x0f; |
| 603 | data = (m_sports_pad_1_x >> 4) & 0x0f; |
| 616 | 604 | break; |
| 617 | 605 | case 1: |
| 618 | | data = state->m_sports_pad_1_x & 0x0f; |
| 606 | data = m_sports_pad_1_x & 0x0f; |
| 619 | 607 | break; |
| 620 | 608 | case 2: |
| 621 | | data = (state->m_sports_pad_1_y >> 4) & 0x0f; |
| 609 | data = (m_sports_pad_1_y >> 4) & 0x0f; |
| 622 | 610 | break; |
| 623 | 611 | case 3: |
| 624 | | data = state->m_sports_pad_1_y & 0x0f; |
| 612 | data = m_sports_pad_1_y & 0x0f; |
| 625 | 613 | break; |
| 626 | 614 | } |
| 627 | | state->m_input_port0 = (state->m_input_port0 & 0xc0) | data | ((machine.root_device().ioport("CTRLIPT")->read() & 0x0c) << 2); |
| 615 | m_input_port0 = (m_input_port0 & 0xc0) | data | ((ioport("CTRLIPT")->read() & 0x0c) << 2); |
| 628 | 616 | break; |
| 629 | 617 | } |
| 630 | 618 | |
| 631 | 619 | /* Player 2 */ |
| 632 | | switch (machine.root_device().ioport("CTRLSEL")->read_safe(0x00) & 0xf0) |
| 620 | switch (ioport("CTRLSEL")->read_safe(0x00) & 0xf0) |
| 633 | 621 | { |
| 634 | 622 | case 0x00: /* Joystick */ |
| 635 | | data = machine.root_device().ioport("PORT_DC")->read(); |
| 636 | | state->m_input_port0 = (state->m_input_port0 & 0x3f) | (data & 0xc0); |
| 623 | data = ioport("PORT_DC")->read(); |
| 624 | m_input_port0 = (m_input_port0 & 0x3f) | (data & 0xc0); |
| 637 | 625 | |
| 638 | | data = machine.root_device().ioport("PORT_DD")->read(); |
| 626 | data = ioport("PORT_DD")->read(); |
| 639 | 627 | /* Check Rapid Fire setting for Button A */ |
| 640 | | if (!(data & 0x04) && (machine.root_device().ioport("RFU")->read() & 0x04)) |
| 641 | | data |= state->m_rapid_fire_state_2 & 0x04; |
| 628 | if (!(data & 0x04) && (ioport("RFU")->read() & 0x04)) |
| 629 | data |= m_rapid_fire_state_2 & 0x04; |
| 642 | 630 | |
| 643 | 631 | /* Check Rapid Fire setting for Button B */ |
| 644 | | if (!(data & 0x08) && (machine.root_device().ioport("RFU")->read() & 0x08)) |
| 645 | | data |= state->m_rapid_fire_state_2 & 0x08; |
| 632 | if (!(data & 0x08) && (ioport("RFU")->read() & 0x08)) |
| 633 | data |= m_rapid_fire_state_2 & 0x08; |
| 646 | 634 | |
| 647 | | state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f); |
| 635 | m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f); |
| 648 | 636 | break; |
| 649 | 637 | |
| 650 | 638 | case 0x10: /* Light Phaser */ |
| 651 | | data = (machine.root_device().ioport("CTRLIPT")->read() & 0x10) >> 2; |
| 639 | data = (ioport("CTRLIPT")->read() & 0x10) >> 2; |
| 652 | 640 | if (!(data & 0x04)) |
| 653 | 641 | { |
| 654 | | if (machine.root_device().ioport("RFU")->read() & 0x04) |
| 655 | | data |= state->m_rapid_fire_state_2 & 0x04; |
| 642 | if (ioport("RFU")->read() & 0x04) |
| 643 | data |= m_rapid_fire_state_2 & 0x04; |
| 656 | 644 | } |
| 657 | 645 | /* just consider the button (trigger) bit */ |
| 658 | 646 | data |= ~0x04; |
| 659 | | state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f); |
| 647 | m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f); |
| 660 | 648 | break; |
| 661 | 649 | |
| 662 | 650 | case 0x20: /* Paddle Control */ |
| 663 | 651 | /* Get button A state */ |
| 664 | | data = machine.root_device().ioport("PADDLE1")->read(); |
| 665 | | if (state->m_paddle_read_state) |
| 652 | data = ioport("PADDLE1")->read(); |
| 653 | if (m_paddle_read_state) |
| 666 | 654 | data = data >> 4; |
| 667 | 655 | |
| 668 | | state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6); |
| 669 | | state->m_input_port1 = (state->m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (state->m_paddle_read_state & 0x08) |
| 670 | | | ((machine.root_device().ioport("CTRLIPT")->read() & 0x20) >> 3); |
| 656 | m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6); |
| 657 | m_input_port1 = (m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (m_paddle_read_state & 0x08) |
| 658 | | ((ioport("CTRLIPT")->read() & 0x20) >> 3); |
| 671 | 659 | break; |
| 672 | 660 | |
| 673 | 661 | case 0x40: /* Sega Sports Pad */ |
| 674 | | switch (state->m_sports_pad_state_2) |
| 662 | switch (m_sports_pad_state_2) |
| 675 | 663 | { |
| 676 | 664 | case 0: |
| 677 | | data = state->m_sports_pad_2_x & 0x0f; |
| 665 | data = m_sports_pad_2_x & 0x0f; |
| 678 | 666 | break; |
| 679 | 667 | case 1: |
| 680 | | data = (state->m_sports_pad_2_x >> 4) & 0x0f; |
| 668 | data = (m_sports_pad_2_x >> 4) & 0x0f; |
| 681 | 669 | break; |
| 682 | 670 | case 2: |
| 683 | | data = state->m_sports_pad_2_y & 0x0f; |
| 671 | data = m_sports_pad_2_y & 0x0f; |
| 684 | 672 | break; |
| 685 | 673 | case 3: |
| 686 | | data = (state->m_sports_pad_2_y >> 4) & 0x0f; |
| 674 | data = (m_sports_pad_2_y >> 4) & 0x0f; |
| 687 | 675 | break; |
| 688 | 676 | } |
| 689 | | state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6); |
| 690 | | state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data >> 2) | ((machine.root_device().ioport("CTRLIPT")->read() & 0xc0) >> 4); |
| 677 | m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6); |
| 678 | m_input_port1 = (m_input_port1 & 0xf0) | (data >> 2) | ((ioport("CTRLIPT")->read() & 0xc0) >> 4); |
| 691 | 679 | break; |
| 692 | 680 | } |
| 693 | 681 | } |
| r20377 | r20378 | |
| 774 | 762 | { |
| 775 | 763 | if (!m_paused) |
| 776 | 764 | { |
| 777 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 765 | m_main_cpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 778 | 766 | } |
| 779 | 767 | m_paused = 1; |
| 780 | 768 | } |
| r20377 | r20378 | |
| 889 | 877 | if ( sscope ) |
| 890 | 878 | { |
| 891 | 879 | // Scope is attached |
| 892 | | screen_device *screen = machine().first_screen(); |
| 893 | | |
| 894 | 880 | m_sscope_state = data; |
| 895 | 881 | |
| 896 | 882 | // There are occurrences when Sega Scope's state changes after VBLANK, or at |
| r20377 | r20378 | |
| 898 | 884 | // one exception is the first frame of Zaxxon 3-D's title screen. In that |
| 899 | 885 | // case, this method is enough for setting the intended state for the frame. |
| 900 | 886 | // No information found about a minimum time need for switch open/closed lens. |
| 901 | | if (screen->vpos() < (screen->height() >> 1)) |
| 887 | if (m_main_scr->vpos() < (m_main_scr->height() >> 1)) |
| 902 | 888 | { |
| 903 | 889 | m_frame_sscope_state = m_sscope_state; |
| 904 | 890 | } |
| r20377 | r20378 | |
| 1229 | 1215 | |
| 1230 | 1216 | logerror("bios write %02x, pc: %04x\n", data, space.device().safe_pc()); |
| 1231 | 1217 | |
| 1232 | | setup_rom(space); |
| 1218 | setup_rom(); |
| 1233 | 1219 | } |
| 1234 | 1220 | |
| 1235 | 1221 | |
| r20377 | r20378 | |
| 1363 | 1349 | } |
| 1364 | 1350 | |
| 1365 | 1351 | |
| 1366 | | static void setup_rom( address_space &space ) |
| 1352 | void sms_state::setup_rom() |
| 1367 | 1353 | { |
| 1368 | | sms_state *state = space.machine().driver_data<sms_state>(); |
| 1369 | | |
| 1370 | 1354 | /* 1. set up bank pointers to point to nothing */ |
| 1371 | | state->membank("bank1")->set_base(state->m_banking_none); |
| 1372 | | state->membank("bank2")->set_base(state->m_banking_none); |
| 1373 | | state->membank("bank7")->set_base(state->m_banking_none); |
| 1374 | | state->membank("bank3")->set_base(state->m_banking_none); |
| 1375 | | state->membank("bank4")->set_base(state->m_banking_none); |
| 1376 | | state->membank("bank5")->set_base(state->m_banking_none); |
| 1377 | | state->membank("bank6")->set_base(state->m_banking_none); |
| 1355 | membank("bank1")->set_base(m_banking_none); |
| 1356 | membank("bank2")->set_base(m_banking_none); |
| 1357 | membank("bank7")->set_base(m_banking_none); |
| 1358 | membank("bank3")->set_base(m_banking_none); |
| 1359 | membank("bank4")->set_base(m_banking_none); |
| 1360 | membank("bank5")->set_base(m_banking_none); |
| 1361 | membank("bank6")->set_base(m_banking_none); |
| 1378 | 1362 | |
| 1379 | 1363 | /* 2. check and set up expansion port */ |
| 1380 | | if (!(state->m_bios_port & IO_EXPANSION) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_CARD)) |
| 1364 | if (!(m_bios_port & IO_EXPANSION) && (m_bios_port & IO_CARTRIDGE) && (m_bios_port & IO_CARD)) |
| 1381 | 1365 | { |
| 1382 | 1366 | /* TODO: Implement me */ |
| 1383 | 1367 | logerror("Switching to unsupported expansion port.\n"); |
| 1384 | 1368 | } |
| 1385 | 1369 | |
| 1386 | 1370 | /* 3. check and set up card rom */ |
| 1387 | | if (!(state->m_bios_port & IO_CARD) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_EXPANSION)) |
| 1371 | if (!(m_bios_port & IO_CARD) && (m_bios_port & IO_CARTRIDGE) && (m_bios_port & IO_EXPANSION)) |
| 1388 | 1372 | { |
| 1389 | 1373 | /* TODO: Implement me */ |
| 1390 | 1374 | logerror("Switching to unsupported card rom port.\n"); |
| r20377 | r20378 | |
| 1393 | 1377 | /* 4. check and set up cartridge rom */ |
| 1394 | 1378 | /* if ((!(bios_port & IO_CARTRIDGE) && (bios_port & IO_EXPANSION) && (bios_port & IO_CARD)) || state->m_is_gamegear) { */ |
| 1395 | 1379 | /* Out Run Europa initially writes a value to port 3E where IO_CARTRIDGE, IO_EXPANSION and IO_CARD are reset */ |
| 1396 | | if ((!(state->m_bios_port & IO_CARTRIDGE)) || state->m_is_gamegear) |
| 1380 | if ((!(m_bios_port & IO_CARTRIDGE)) || m_is_gamegear) |
| 1397 | 1381 | { |
| 1398 | | state->membank("bank1")->set_base(state->m_banking_cart[1]); |
| 1399 | | state->membank("bank2")->set_base(state->m_banking_cart[2]); |
| 1400 | | state->membank("bank7")->set_base(state->m_banking_cart[7]); |
| 1401 | | state->membank("bank3")->set_base(state->m_banking_cart[3]); |
| 1402 | | state->membank("bank4")->set_base(state->m_banking_cart[3] + 0x2000); |
| 1403 | | state->membank("bank5")->set_base(state->m_banking_cart[5]); |
| 1404 | | state->membank("bank6")->set_base(state->m_banking_cart[5] + 0x2000); |
| 1382 | membank("bank1")->set_base(m_banking_cart[1]); |
| 1383 | membank("bank2")->set_base(m_banking_cart[2]); |
| 1384 | membank("bank7")->set_base(m_banking_cart[7]); |
| 1385 | membank("bank3")->set_base(m_banking_cart[3]); |
| 1386 | membank("bank4")->set_base(m_banking_cart[3] + 0x2000); |
| 1387 | membank("bank5")->set_base(m_banking_cart[5]); |
| 1388 | membank("bank6")->set_base(m_banking_cart[5] + 0x2000); |
| 1405 | 1389 | logerror("Switched in cartridge rom.\n"); |
| 1406 | 1390 | } |
| 1407 | 1391 | |
| 1408 | 1392 | /* 5. check and set up bios rom */ |
| 1409 | | if (!(state->m_bios_port & IO_BIOS_ROM)) |
| 1393 | if (!(m_bios_port & IO_BIOS_ROM)) |
| 1410 | 1394 | { |
| 1411 | 1395 | /* 0x0400 bioses */ |
| 1412 | | if (state->m_has_bios_0400) |
| 1396 | if (m_has_bios_0400) |
| 1413 | 1397 | { |
| 1414 | | state->membank("bank1")->set_base(state->m_banking_bios[1]); |
| 1398 | membank("bank1")->set_base(m_banking_bios[1]); |
| 1415 | 1399 | logerror("Switched in 0x0400 bios.\n"); |
| 1416 | 1400 | } |
| 1417 | 1401 | /* 0x2000 bioses */ |
| 1418 | | if (state->m_has_bios_2000) |
| 1402 | if (m_has_bios_2000) |
| 1419 | 1403 | { |
| 1420 | | state->membank("bank1")->set_base(state->m_banking_bios[1]); |
| 1421 | | state->membank("bank2")->set_base(state->m_banking_bios[2]); |
| 1404 | membank("bank1")->set_base(m_banking_bios[1]); |
| 1405 | membank("bank2")->set_base(m_banking_bios[2]); |
| 1422 | 1406 | logerror("Switched in 0x2000 bios.\n"); |
| 1423 | 1407 | } |
| 1424 | | if (state->m_has_bios_full) |
| 1408 | if (m_has_bios_full) |
| 1425 | 1409 | { |
| 1426 | | state->membank("bank1")->set_base(state->m_banking_bios[1]); |
| 1427 | | state->membank("bank2")->set_base(state->m_banking_bios[2]); |
| 1428 | | state->membank("bank7")->set_base(state->m_banking_bios[7]); |
| 1429 | | state->membank("bank3")->set_base(state->m_banking_bios[3]); |
| 1430 | | state->membank("bank4")->set_base(state->m_banking_bios[3] + 0x2000); |
| 1431 | | state->membank("bank5")->set_base(state->m_banking_bios[5]); |
| 1432 | | state->membank("bank6")->set_base(state->m_banking_bios[5] + 0x2000); |
| 1410 | membank("bank1")->set_base(m_banking_bios[1]); |
| 1411 | membank("bank2")->set_base(m_banking_bios[2]); |
| 1412 | membank("bank7")->set_base(m_banking_bios[7]); |
| 1413 | membank("bank3")->set_base(m_banking_bios[3]); |
| 1414 | membank("bank4")->set_base(m_banking_bios[3] + 0x2000); |
| 1415 | membank("bank5")->set_base(m_banking_bios[5]); |
| 1416 | membank("bank6")->set_base(m_banking_bios[5] + 0x2000); |
| 1433 | 1417 | logerror("Switched in full bios.\n"); |
| 1434 | 1418 | } |
| 1435 | 1419 | } |
| 1436 | 1420 | |
| 1437 | | if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM) |
| 1421 | if (m_cartridge[m_current_cartridge].features & CF_ONCART_RAM) |
| 1438 | 1422 | { |
| 1439 | | state->membank("bank5")->set_base(state->m_cartridge[state->m_current_cartridge].cartRAM); |
| 1440 | | state->membank("bank6")->set_base(state->m_cartridge[state->m_current_cartridge].cartRAM); |
| 1423 | membank("bank5")->set_base(m_cartridge[m_current_cartridge].cartRAM); |
| 1424 | membank("bank6")->set_base(m_cartridge[m_current_cartridge].cartRAM); |
| 1441 | 1425 | } |
| 1442 | 1426 | } |
| 1443 | 1427 | |
| r20377 | r20378 | |
| 1854 | 1838 | } |
| 1855 | 1839 | |
| 1856 | 1840 | |
| 1857 | | static void setup_cart_banks( running_machine &machine ) |
| 1841 | void sms_state::setup_cart_banks() |
| 1858 | 1842 | { |
| 1859 | | sms_state *state = machine.driver_data<sms_state>(); |
| 1860 | | if (state->m_cartridge[state->m_current_cartridge].ROM) |
| 1843 | if (m_cartridge[m_current_cartridge].ROM) |
| 1861 | 1844 | { |
| 1862 | | UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; |
| 1863 | | state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM; |
| 1864 | | state->m_banking_cart[2] = state->m_cartridge[state->m_current_cartridge].ROM + 0x0400; |
| 1865 | | state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((1 < rom_page_count) ? 0x4000 : 0); |
| 1866 | | state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + ((2 < rom_page_count) ? 0x8000 : 0); |
| 1867 | | state->m_banking_cart[7] = state->m_cartridge[state->m_current_cartridge].ROM + 0x2000; |
| 1845 | UINT8 rom_page_count = m_cartridge[m_current_cartridge].size / 0x4000; |
| 1846 | m_banking_cart[1] = m_cartridge[m_current_cartridge].ROM; |
| 1847 | m_banking_cart[2] = m_cartridge[m_current_cartridge].ROM + 0x0400; |
| 1848 | m_banking_cart[3] = m_cartridge[m_current_cartridge].ROM + ((1 < rom_page_count) ? 0x4000 : 0); |
| 1849 | m_banking_cart[5] = m_cartridge[m_current_cartridge].ROM + ((2 < rom_page_count) ? 0x8000 : 0); |
| 1850 | m_banking_cart[7] = m_cartridge[m_current_cartridge].ROM + 0x2000; |
| 1868 | 1851 | /* Codemasters mapper points to bank 0 for page 2 */ |
| 1869 | | if ( state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER ) |
| 1852 | if ( m_cartridge[m_current_cartridge].features & CF_CODEMASTERS_MAPPER ) |
| 1870 | 1853 | { |
| 1871 | | state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM; |
| 1854 | m_banking_cart[5] = m_cartridge[m_current_cartridge].ROM; |
| 1872 | 1855 | } |
| 1873 | 1856 | /* Nemesis starts with last 8kb bank in page 0 */ |
| 1874 | | if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_NEMESIS ) |
| 1857 | if (m_cartridge[m_current_cartridge].features & CF_KOREAN_ZEMINA_NEMESIS ) |
| 1875 | 1858 | { |
| 1876 | | state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000; |
| 1877 | | state->m_banking_cart[2] = state->m_cartridge[state->m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000 + 0x400; |
| 1859 | m_banking_cart[1] = m_cartridge[m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000; |
| 1860 | m_banking_cart[2] = m_cartridge[m_current_cartridge].ROM + ( rom_page_count - 1 ) * 0x4000 + 0x2000 + 0x400; |
| 1878 | 1861 | } |
| 1879 | 1862 | } |
| 1880 | 1863 | else |
| 1881 | 1864 | { |
| 1882 | | state->m_banking_cart[1] = state->m_banking_none; |
| 1883 | | state->m_banking_cart[2] = state->m_banking_none; |
| 1884 | | state->m_banking_cart[3] = state->m_banking_none; |
| 1885 | | state->m_banking_cart[5] = state->m_banking_none; |
| 1865 | m_banking_cart[1] = m_banking_none; |
| 1866 | m_banking_cart[2] = m_banking_none; |
| 1867 | m_banking_cart[3] = m_banking_none; |
| 1868 | m_banking_cart[5] = m_banking_none; |
| 1886 | 1869 | } |
| 1887 | 1870 | } |
| 1888 | 1871 | |
| 1889 | | static void setup_banks( running_machine &machine ) |
| 1872 | void sms_state::setup_banks() |
| 1890 | 1873 | { |
| 1891 | | sms_state *state = machine.driver_data<sms_state>(); |
| 1892 | | UINT8 *mem = machine.root_device().memregion("maincpu")->base(); |
| 1893 | | state->m_banking_none = mem; |
| 1894 | | state->m_banking_bios[1] = state->m_banking_cart[1] = mem; |
| 1895 | | state->m_banking_bios[2] = state->m_banking_cart[2] = mem; |
| 1896 | | state->m_banking_bios[3] = state->m_banking_cart[3] = mem; |
| 1897 | | state->m_banking_bios[4] = state->m_banking_cart[4] = mem; |
| 1898 | | state->m_banking_bios[5] = state->m_banking_cart[5] = mem; |
| 1899 | | state->m_banking_bios[6] = state->m_banking_cart[6] = mem; |
| 1900 | | state->m_banking_bios[7] = state->m_banking_cart[7] = mem; |
| 1874 | UINT8 *mem = memregion("maincpu")->base(); |
| 1875 | m_banking_none = mem; |
| 1876 | m_banking_bios[1] = m_banking_cart[1] = mem; |
| 1877 | m_banking_bios[2] = m_banking_cart[2] = mem; |
| 1878 | m_banking_bios[3] = m_banking_cart[3] = mem; |
| 1879 | m_banking_bios[4] = m_banking_cart[4] = mem; |
| 1880 | m_banking_bios[5] = m_banking_cart[5] = mem; |
| 1881 | m_banking_bios[6] = m_banking_cart[6] = mem; |
| 1882 | m_banking_bios[7] = m_banking_cart[7] = mem; |
| 1901 | 1883 | |
| 1902 | | state->m_BIOS = machine.root_device().memregion("user1")->base(); |
| 1884 | m_BIOS = memregion("user1")->base(); |
| 1903 | 1885 | |
| 1904 | | state->m_bios_page_count = (state->m_BIOS ? state->memregion("user1")->bytes() / 0x4000 : 0); |
| 1886 | m_bios_page_count = (m_BIOS ? memregion("user1")->bytes() / 0x4000 : 0); |
| 1905 | 1887 | |
| 1906 | | setup_cart_banks(machine); |
| 1888 | setup_cart_banks(); |
| 1907 | 1889 | |
| 1908 | | if (state->m_BIOS == NULL || state->m_BIOS[0] == 0x00) |
| 1890 | if (m_BIOS == NULL || m_BIOS[0] == 0x00) |
| 1909 | 1891 | { |
| 1910 | | state->m_BIOS = NULL; |
| 1911 | | state->m_bios_port |= IO_BIOS_ROM; |
| 1912 | | state->m_has_bios_0400 = 0; |
| 1913 | | state->m_has_bios_2000 = 0; |
| 1914 | | state->m_has_bios_full = 0; |
| 1915 | | state->m_has_bios = 0; |
| 1892 | m_BIOS = NULL; |
| 1893 | m_bios_port |= IO_BIOS_ROM; |
| 1894 | m_has_bios_0400 = 0; |
| 1895 | m_has_bios_2000 = 0; |
| 1896 | m_has_bios_full = 0; |
| 1897 | m_has_bios = 0; |
| 1916 | 1898 | } |
| 1917 | 1899 | |
| 1918 | | if (state->m_BIOS) |
| 1900 | if (m_BIOS) |
| 1919 | 1901 | { |
| 1920 | | state->m_banking_bios[1] = state->m_BIOS; |
| 1921 | | state->m_banking_bios[2] = state->m_BIOS + 0x0400; |
| 1922 | | state->m_banking_bios[3] = state->m_BIOS + ((1 < state->m_bios_page_count) ? 0x4000 : 0); |
| 1923 | | state->m_banking_bios[5] = state->m_BIOS + ((2 < state->m_bios_page_count) ? 0x8000 : 0); |
| 1902 | m_banking_bios[1] = m_BIOS; |
| 1903 | m_banking_bios[2] = m_BIOS + 0x0400; |
| 1904 | m_banking_bios[3] = m_BIOS + ((1 < m_bios_page_count) ? 0x4000 : 0); |
| 1905 | m_banking_bios[5] = m_BIOS + ((2 < m_bios_page_count) ? 0x8000 : 0); |
| 1924 | 1906 | } |
| 1925 | 1907 | } |
| 1926 | 1908 | |
| r20377 | r20378 | |
| 1933 | 1915 | m_lphaser_1_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_1_callback),this)); |
| 1934 | 1916 | m_lphaser_2_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_2_callback),this)); |
| 1935 | 1917 | |
| 1936 | | m_main_cpu = machine().device("maincpu"); |
| 1937 | | m_control_cpu = machine().device("control"); |
| 1938 | | m_vdp = machine().device<sega315_5124_device>("sms_vdp"); |
| 1939 | 1918 | m_eeprom = machine().device<eeprom_device>("eeprom"); |
| 1940 | 1919 | m_ym = machine().device("ym2413"); |
| 1941 | | m_main_scr = machine().device("screen"); |
| 1942 | 1920 | m_left_lcd = machine().device("left_lcd"); |
| 1943 | 1921 | m_right_lcd = machine().device("right_lcd"); |
| 1944 | 1922 | m_space = &machine().device("maincpu")->memory().space(AS_PROGRAM); |
| r20377 | r20378 | |
| 1965 | 1943 | |
| 1966 | 1944 | MACHINE_RESET_MEMBER(sms_state,sms) |
| 1967 | 1945 | { |
| 1968 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 1946 | address_space &space = m_main_cpu->space(AS_PROGRAM); |
| 1969 | 1947 | |
| 1970 | 1948 | m_ctrl_reg = 0xff; |
| 1971 | 1949 | if (m_has_fm) |
| r20377 | r20378 | |
| 2029 | 2007 | |
| 2030 | 2008 | m_store_control = 0; |
| 2031 | 2009 | |
| 2032 | | setup_banks(machine()); |
| 2010 | setup_banks(); |
| 2033 | 2011 | |
| 2034 | | setup_rom(space); |
| 2012 | setup_rom(); |
| 2035 | 2013 | |
| 2036 | 2014 | m_rapid_fire_state_1 = 0; |
| 2037 | 2015 | m_rapid_fire_state_2 = 0; |
| r20377 | r20378 | |
| 2073 | 2051 | if (slottype == 0) |
| 2074 | 2052 | m_current_cartridge = slot; |
| 2075 | 2053 | |
| 2076 | | setup_cart_banks(machine()); |
| 2054 | setup_cart_banks(); |
| 2077 | 2055 | membank("bank10")->set_base(m_banking_cart[3] + 0x2000); |
| 2078 | | setup_rom(space); |
| 2056 | setup_rom(); |
| 2079 | 2057 | } |
| 2080 | 2058 | |
| 2081 | 2059 | |
| r20377 | r20378 | |
| 2115 | 2093 | |
| 2116 | 2094 | WRITE_LINE_MEMBER(sms_state::sms_store_int_callback) |
| 2117 | 2095 | { |
| 2118 | | (m_store_control & 0x01 ? m_control_cpu : m_main_cpu)->execute().set_input_line(0, state); |
| 2096 | (m_store_control & 0x01 ? m_control_cpu : m_main_cpu)->set_input_line(0, state); |
| 2119 | 2097 | } |
| 2120 | 2098 | |
| 2121 | 2099 | |
| 2122 | | static void sms_set_zero_flag( running_machine &machine ) |
| 2123 | | { |
| 2124 | | sms_state *state = machine.driver_data<sms_state>(); |
| 2125 | | state->m_is_gamegear = 0; |
| 2126 | | state->m_is_region_japan = 0; |
| 2127 | | state->m_has_bios_0400 = 0; |
| 2128 | | state->m_has_bios_2000 = 0; |
| 2129 | | state->m_has_bios_full = 0; |
| 2130 | | state->m_has_bios = 0; |
| 2131 | | state->m_has_fm = 0; |
| 2132 | | } |
| 2133 | | |
| 2134 | 2100 | DRIVER_INIT_MEMBER(sms_state,sg1000m3) |
| 2135 | 2101 | { |
| 2136 | | sms_set_zero_flag(machine()); |
| 2137 | 2102 | m_is_region_japan = 1; |
| 2138 | 2103 | m_has_fm = 1; |
| 2139 | 2104 | } |
| r20377 | r20378 | |
| 2141 | 2106 | |
| 2142 | 2107 | DRIVER_INIT_MEMBER(sms_state,sms1) |
| 2143 | 2108 | { |
| 2144 | | sms_set_zero_flag(machine()); |
| 2145 | 2109 | m_has_bios_full = 1; |
| 2146 | 2110 | } |
| 2147 | 2111 | |
| 2148 | 2112 | |
| 2149 | 2113 | DRIVER_INIT_MEMBER(sms_state,smsj) |
| 2150 | 2114 | { |
| 2151 | | sms_set_zero_flag(machine()); |
| 2152 | 2115 | m_is_region_japan = 1; |
| 2153 | 2116 | m_has_bios_2000 = 1; |
| 2154 | 2117 | m_has_fm = 1; |
| r20377 | r20378 | |
| 2157 | 2120 | |
| 2158 | 2121 | DRIVER_INIT_MEMBER(sms_state,sms2kr) |
| 2159 | 2122 | { |
| 2160 | | sms_set_zero_flag(machine()); |
| 2161 | 2123 | m_is_region_japan = 1; |
| 2162 | 2124 | m_has_bios_full = 1; |
| 2163 | 2125 | m_has_fm = 1; |
| r20377 | r20378 | |
| 2166 | 2128 | |
| 2167 | 2129 | DRIVER_INIT_MEMBER(sms_state,smssdisp) |
| 2168 | 2130 | { |
| 2169 | | sms_set_zero_flag(machine()); |
| 2170 | 2131 | } |
| 2171 | 2132 | |
| 2172 | 2133 | |
| 2173 | 2134 | DRIVER_INIT_MEMBER(sms_state,gamegear) |
| 2174 | 2135 | { |
| 2175 | | sms_set_zero_flag(machine()); |
| 2176 | 2136 | m_is_gamegear = 1; |
| 2177 | 2137 | m_has_bios_0400 = 1; |
| 2178 | 2138 | } |
| r20377 | r20378 | |
| 2180 | 2140 | |
| 2181 | 2141 | DRIVER_INIT_MEMBER(sms_state,gamegeaj) |
| 2182 | 2142 | { |
| 2183 | | sms_set_zero_flag(machine()); |
| 2184 | 2143 | m_is_region_japan = 1; |
| 2185 | 2144 | m_is_gamegear = 1; |
| 2186 | 2145 | m_has_bios_0400 = 1; |
| r20377 | r20378 | |
| 2189 | 2148 | |
| 2190 | 2149 | VIDEO_START_MEMBER(sms_state,sms1) |
| 2191 | 2150 | { |
| 2192 | | screen_device *screen = machine().first_screen(); |
| 2193 | | |
| 2194 | | screen->register_screen_bitmap(m_prevleft_bitmap); |
| 2195 | | screen->register_screen_bitmap(m_prevright_bitmap); |
| 2151 | m_main_scr->register_screen_bitmap(m_prevleft_bitmap); |
| 2152 | m_main_scr->register_screen_bitmap(m_prevright_bitmap); |
| 2196 | 2153 | save_item(NAME(m_prevleft_bitmap)); |
| 2197 | 2154 | save_item(NAME(m_prevright_bitmap)); |
| 2198 | 2155 | } |