trunk/src/mess/drivers/mz2000.c
r17665 | r17666 | |
8 | 8 | Basically a simpler version of Sharp MZ-2500 |
9 | 9 | |
10 | 10 | TODO: |
11 | | - cassette interface; |
| 11 | - cassette interface, basically any program that's bigger than 8kb fails to load; |
12 | 12 | - implement remaining video capabilities |
| 13 | - add 80b compatibility support; |
| 14 | - Vosque (color): keyboard doesn't work properly; |
13 | 15 | |
14 | 16 | ****************************************************************************/ |
15 | 17 | |
r17665 | r17666 | |
29 | 31 | #include "formats/basicdsk.h" |
30 | 32 | #include "formats/mz_cas.h" |
31 | 33 | |
| 34 | #define MASTER_CLOCK XTAL_17_73447MHz/5 /* TODO: was 4 MHz, but otherwise cassette won't work due of a bug with MZF support ... */ |
32 | 35 | |
33 | 36 | |
34 | 37 | class mz2000_state : public driver_device |
r17665 | r17666 | |
46 | 49 | UINT8 m_gvram_enable; |
47 | 50 | UINT8 m_gvram_bank; |
48 | 51 | |
49 | | UINT8 m_key_mux,m_pio_latchb; |
| 52 | UINT8 m_key_mux; |
50 | 53 | |
51 | 54 | UINT8 m_old_portc; |
52 | 55 | UINT8 m_width80; |
r17665 | r17666 | |
56 | 59 | UINT8 m_color_mode; |
57 | 60 | UINT8 m_has_fdc; |
58 | 61 | UINT8 m_hi_mode; |
| 62 | |
| 63 | UINT8 m_porta_latch; |
| 64 | UINT8 m_tape_ctrl; |
59 | 65 | DECLARE_READ8_MEMBER(mz2000_ipl_r); |
60 | 66 | DECLARE_READ8_MEMBER(mz2000_wram_r); |
61 | 67 | DECLARE_WRITE8_MEMBER(mz2000_wram_w); |
r17665 | r17666 | |
577 | 583 | */ |
578 | 584 | UINT8 res = 0x80; |
579 | 585 | |
580 | | res |= (state->m_cass->input() > 0.0038) ? 0x40 : 0x00; |
581 | | res |= ((state->m_cass->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) ? 0x00 : 0x20; |
582 | | res |= (state->m_cass->get_position() >= state->m_cass->get_length()) ? 0x08 : 0x00; |
| 586 | if(state->m_cass->get_image() != NULL) |
| 587 | { |
| 588 | res |= (state->m_cass->input() > 0.0038) ? 0x40 : 0x00; |
| 589 | res |= ((state->m_cass->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) ? 0x00 : 0x20; |
| 590 | res |= (state->m_cass->get_position() >= state->m_cass->get_length()) ? 0x08 : 0x00; |
| 591 | } |
| 592 | else |
| 593 | res |= 0x20; |
| 594 | |
583 | 595 | res |= (device->machine().primary_screen->vblank()) ? 0x00 : 0x01; |
584 | 596 | |
585 | | // popmessage("%02x",res); |
586 | | |
587 | 597 | return res; |
588 | 598 | } |
589 | 599 | |
r17665 | r17666 | |
596 | 606 | static WRITE8_DEVICE_HANDLER( mz2000_porta_w ) |
597 | 607 | { |
598 | 608 | /* |
599 | | TODO: it's likely to be a 0->1 transition |
| 609 | These are enabled thru a 0->1 transition |
600 | 610 | x--- ---- tape "APSS" |
601 | 611 | -x-- ---- tape "APLAY" |
602 | 612 | --x- ---- tape "AREW" |
r17665 | r17666 | |
608 | 618 | */ |
609 | 619 | mz2000_state *state = device->machine().driver_data<mz2000_state>(); |
610 | 620 | |
611 | | if((data & 8) == 0) // stop |
| 621 | if((state->m_tape_ctrl & 0x80) == 0 && data & 0x80) |
612 | 622 | { |
| 623 | //printf("Tape APSS control\n"); |
| 624 | } |
| 625 | |
| 626 | if((state->m_tape_ctrl & 0x40) == 0 && data & 0x40) |
| 627 | { |
| 628 | //printf("Tape APLAY control\n"); |
| 629 | } |
| 630 | |
| 631 | if((state->m_tape_ctrl & 0x20) == 0 && data & 0x20) |
| 632 | { |
| 633 | //printf("Tape AREW control\n"); |
| 634 | } |
| 635 | |
| 636 | if((state->m_tape_ctrl & 0x10) == 0 && data & 0x10) |
| 637 | { |
| 638 | //printf("reverse video control\n"); |
| 639 | } |
| 640 | |
| 641 | if((state->m_tape_ctrl & 0x08) == 0 && data & 0x08) // stop |
| 642 | { |
613 | 643 | state->m_cass->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR); |
614 | 644 | state->m_cass->change_state(CASSETTE_STOPPED,CASSETTE_MASK_UISTATE); |
615 | 645 | } |
616 | | if((data & 4) == 0) // play |
| 646 | |
| 647 | if((state->m_tape_ctrl & 0x04) == 0 && data & 0x04) // play |
617 | 648 | { |
618 | 649 | state->m_cass->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR); |
619 | 650 | state->m_cass->change_state(CASSETTE_PLAY,CASSETTE_MASK_UISTATE); |
620 | 651 | } |
| 652 | |
| 653 | if((state->m_tape_ctrl & 0x02) == 0 && data & 0x02) |
| 654 | { |
| 655 | //printf("Tape FF control\n"); |
| 656 | } |
| 657 | |
| 658 | if((state->m_tape_ctrl & 0x01) == 0 && data & 0x01) |
| 659 | { |
| 660 | //printf("Tape Rewind control\n"); |
| 661 | } |
| 662 | |
| 663 | state->m_tape_ctrl = data; |
621 | 664 | } |
622 | 665 | |
623 | 666 | static WRITE8_DEVICE_HANDLER( mz2000_portb_w ) |
r17665 | r17666 | |
673 | 716 | state->m_gvram_enable = ((data & 0xc0) == 0x80); |
674 | 717 | state->m_width80 = ((data & 0x20) >> 5); |
675 | 718 | state->m_key_mux = data & 0x1f; |
| 719 | |
| 720 | state->m_porta_latch = data; |
676 | 721 | } |
677 | 722 | |
678 | | static READ8_DEVICE_HANDLER( mz2000_pio1_porta_r ) |
| 723 | static READ8_DEVICE_HANDLER( mz2000_pio1_portb_r ) |
679 | 724 | { |
680 | 725 | mz2000_state *state = device->machine().driver_data<mz2000_state>(); |
681 | 726 | static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", |
r17665 | r17666 | |
691 | 736 | for(i=0;i<0xe;i++) |
692 | 737 | res &= device->machine().root_device().ioport(keynames[i])->read(); |
693 | 738 | |
694 | | state->m_pio_latchb = res; |
695 | | |
696 | 739 | return res; |
697 | 740 | } |
698 | 741 | |
699 | | state->m_pio_latchb = device->machine().root_device().ioport(keynames[state->m_key_mux & 0xf])->read(); |
700 | | |
701 | 742 | return device->machine().root_device().ioport(keynames[state->m_key_mux & 0xf])->read(); |
702 | 743 | } |
703 | 744 | |
| 745 | static READ8_DEVICE_HANDLER( mz2000_pio1_porta_r ) |
| 746 | { |
| 747 | mz2000_state *state = device->machine().driver_data<mz2000_state>(); |
| 748 | |
| 749 | return state->m_porta_latch; |
| 750 | } |
| 751 | |
704 | 752 | static Z80PIO_INTERFACE( mz2000_pio1_intf ) |
705 | 753 | { |
706 | 754 | DEVCB_NULL, |
707 | 755 | DEVCB_HANDLER( mz2000_pio1_porta_r ), |
708 | 756 | DEVCB_HANDLER( mz2000_pio1_porta_w ), |
709 | 757 | DEVCB_NULL, |
710 | | DEVCB_HANDLER( mz2000_pio1_porta_r ), |
| 758 | DEVCB_HANDLER( mz2000_pio1_portb_r ), |
711 | 759 | DEVCB_NULL, |
712 | 760 | DEVCB_NULL |
713 | 761 | }; |
r17665 | r17666 | |
778 | 826 | |
779 | 827 | static MACHINE_CONFIG_START( mz2000, mz2000_state ) |
780 | 828 | /* basic machine hardware */ |
781 | | MCFG_CPU_ADD("maincpu",Z80, XTAL_17_73447MHz/5) /* TODO: was 4 MHz, but otherwise cassette won't work */ |
| 829 | MCFG_CPU_ADD("maincpu",Z80, MASTER_CLOCK) |
782 | 830 | MCFG_CPU_PROGRAM_MAP(mz2000_map) |
783 | 831 | MCFG_CPU_IO_MAP(mz2000_io) |
784 | 832 | |
785 | 833 | MCFG_MACHINE_RESET(mz2000) |
786 | 834 | |
787 | 835 | MCFG_I8255_ADD( "i8255_0", ppi8255_intf ) |
788 | | MCFG_Z80PIO_ADD( "z80pio_1", 4000000, mz2000_pio1_intf ) |
| 836 | MCFG_Z80PIO_ADD( "z80pio_1", MASTER_CLOCK, mz2000_pio1_intf ) |
789 | 837 | MCFG_PIT8253_ADD("pit", mz2000_pit8253_intf) |
790 | 838 | |
791 | 839 | MCFG_MB8877_ADD("mb8877a",mz2000_mb8877a_interface) |