trunk/src/mame/machine/smpc.c
| r20602 | r20603 | |
| 852 | 852 | * |
| 853 | 853 | *******************************************/ |
| 854 | 854 | |
| 855 | | READ8_HANDLER( saturn_SMPC_r ) |
| 855 | /* |
| 856 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 857 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 858 | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 859 | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 860 | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 861 | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 862 | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 863 | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 864 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 R") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 865 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 866 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 867 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 868 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P1 L") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 869 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 870 | PORT_BIT( 0x0003, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) |
| 871 | |
| 872 | 0 Start A 0 0 Down Up |
| 873 | */ |
| 874 | |
| 875 | UINT8 saturn_state::smpc_th_control_mode(UINT8 pad_n) |
| 856 | 876 | { |
| 857 | | saturn_state *state = space.machine().driver_data<saturn_state>(); |
| 877 | int th; |
| 878 | const char *const padnames[] = { "JOY1", "JOY2" }; |
| 879 | UINT8 res; |
| 880 | |
| 881 | th = (pad_n == 0) ? ((m_smpc.PDR1>>6) & 1) : ((m_smpc.PDR2>>6) & 1); |
| 882 | |
| 883 | if (LOG_SMPC) printf("SMPC: SH-2 TH control mode, returning pad data %d for phase %d\n",pad_n+1, th); |
| 884 | |
| 885 | switch(th) |
| 886 | { |
| 887 | case 1: |
| 888 | res = th<<7; |
| 889 | // 1 C B Right Left Down Up |
| 890 | res|= (((machine().root_device().ioport(padnames[pad_n])->read()>>4)) & 0x30); // C & B |
| 891 | res|= (((machine().root_device().ioport(padnames[pad_n])->read()>>12)) & 0xf); |
| 892 | break; |
| 893 | case 0: |
| 894 | res = th<<7; |
| 895 | // 0 Start A 0 0 Down Up |
| 896 | res|= (((machine().root_device().ioport(padnames[pad_n])->read()>>6)) & 0x30); // Start & A |
| 897 | res|= (((machine().root_device().ioport(padnames[pad_n])->read()>>12)) & 0x3); |
| 898 | break; |
| 899 | } |
| 900 | |
| 901 | return res; |
| 902 | } |
| 903 | |
| 904 | UINT8 saturn_state::smpc_direct_mode(UINT8 pad_n) |
| 905 | { |
| 906 | int hshake; |
| 907 | const int shift_bit[4] = { 4, 12, 8, 0 }; |
| 908 | const char *const padnames[] = { "JOY1", "JOY2" }; |
| 909 | |
| 910 | hshake = (pad_n == 0) ? ((m_smpc.PDR1>>5) & 3) : ((m_smpc.PDR2>>5) & 3); |
| 911 | |
| 912 | if (LOG_SMPC) logerror("SMPC: SH-2 direct mode, returning data for phase %d\n", hshake); |
| 913 | |
| 914 | return 0x80 | 0x10 | ((machine().root_device().ioport(padnames[pad_n])->read()>>shift_bit[hshake]) & 0xf); |
| 915 | } |
| 916 | |
| 917 | READ8_MEMBER( saturn_state::saturn_SMPC_r ) |
| 918 | { |
| 858 | 919 | UINT8 return_data = 0; |
| 859 | 920 | |
| 860 | 921 | if (!(offset & 1)) // avoid reading to even bytes (TODO: is it 0s or 1s?) |
| 861 | 922 | return 0x00; |
| 862 | 923 | |
| 863 | 924 | if(offset >= 0x21 && offset <= 0x5f) |
| 864 | | return_data = state->m_smpc.OREG[(offset-0x21) >> 1]; |
| 925 | return_data = m_smpc.OREG[(offset-0x21) >> 1]; |
| 865 | 926 | |
| 866 | 927 | if (offset == 0x61) |
| 867 | | return_data = state->m_smpc.SR; |
| 928 | return_data = m_smpc.SR; |
| 868 | 929 | |
| 869 | 930 | if (offset == 0x63) |
| 870 | 931 | { |
| 871 | 932 | //printf("SF %d %d\n",space.machine().primary_screen->hpos(),space.machine().primary_screen->vpos()); |
| 872 | | return_data = state->m_smpc.SF; |
| 933 | return_data = m_smpc.SF; |
| 873 | 934 | } |
| 874 | 935 | |
| 875 | 936 | if (offset == 0x75 || offset == 0x77)//PDR1/2 read |
| 876 | 937 | { |
| 877 | | if ((state->m_smpc.IOSEL1 && offset == 0x75) || (state->m_smpc.IOSEL2 && offset == 0x77)) |
| 938 | if ((m_smpc.IOSEL1 && offset == 0x75) || (m_smpc.IOSEL2 && offset == 0x77)) |
| 878 | 939 | { |
| 879 | | int hshake; |
| 880 | | const int shift_bit[4] = { 4, 12, 8, 0 }; |
| 881 | | const char *const padnames[] = { "JOY1", "JOY2" }; |
| 940 | UINT8 cur_ddr; |
| 882 | 941 | |
| 883 | | if(space.machine().root_device().ioport("INPUT_TYPE")->read() && !(space.debugger_access())) |
| 942 | if(machine().root_device().ioport("INPUT_TYPE")->read() && !(space.debugger_access())) |
| 884 | 943 | { |
| 885 | 944 | popmessage("Warning: read with SH-2 direct mode with a non-pad device"); |
| 886 | 945 | return 0; |
| 887 | 946 | } |
| 888 | 947 | |
| 889 | | if(offset == 0x75) |
| 890 | | hshake = (state->m_smpc.PDR1>>5) & 3; |
| 891 | | else |
| 892 | | hshake = (state->m_smpc.PDR2>>5) & 3; |
| 948 | cur_ddr = (offset == 0x75) ? m_smpc.DDR1 : m_smpc.DDR2; |
| 893 | 949 | |
| 894 | | if (LOG_SMPC) logerror("SMPC: SH-2 direct mode, returning data for phase %d\n", hshake); |
| 895 | | |
| 896 | | return_data = 0x80 | 0x10 | ((space.machine().root_device().ioport(padnames[offset == 0x77])->read()>>shift_bit[hshake]) & 0xf); |
| 950 | switch(cur_ddr & 0x60) |
| 951 | { |
| 952 | case 0x40: return_data = smpc_th_control_mode(offset == 0x77); break; |
| 953 | case 0x60: return_data = smpc_direct_mode(offset == 0x77); break; |
| 954 | default: |
| 955 | popmessage("SMPC: unemulated control method %02x, contact MAMEdev",cur_ddr & 0x60); |
| 956 | return_data = 0; |
| 957 | break; |
| 958 | } |
| 897 | 959 | } |
| 898 | 960 | } |
| 899 | 961 | |
| 900 | 962 | if (LOG_SMPC) logerror ("cpu %s (PC=%08X) SMPC: Read from Byte Offset %02x (%d) Returns %02x\n", space.device().tag(), space.device().safe_pc(), offset, offset>>1, return_data); |
| 901 | 963 | |
| 902 | | |
| 903 | 964 | return return_data; |
| 904 | 965 | } |
| 905 | 966 | |
| 906 | | WRITE8_HANDLER( saturn_SMPC_w ) |
| 967 | WRITE8_MEMBER( saturn_state::saturn_SMPC_w ) |
| 907 | 968 | { |
| 908 | | saturn_state *state = space.machine().driver_data<saturn_state>(); |
| 909 | | |
| 910 | 969 | if (LOG_SMPC) logerror ("8-bit SMPC Write to Offset %02x (reg %d) with Data %02x\n", offset, offset>>1, data); |
| 911 | 970 | |
| 912 | 971 | if (!(offset & 1)) // avoid writing to even bytes |
| 913 | 972 | return; |
| 914 | 973 | |
| 915 | 974 | if(offset >= 1 && offset <= 0xd) |
| 916 | | state->m_smpc.IREG[offset >> 1] = data; |
| 975 | m_smpc.IREG[offset >> 1] = data; |
| 917 | 976 | |
| 918 | 977 | if(offset == 1) //IREG0, check if a BREAK / CONTINUE request for INTBACK command |
| 919 | 978 | { |
| 920 | | if(state->m_smpc.intback_stage) |
| 979 | if(m_smpc.intback_stage) |
| 921 | 980 | { |
| 922 | 981 | if(data & 0x40) |
| 923 | 982 | { |
| 924 | 983 | if(LOG_PAD_CMD) printf("SMPC: BREAK request\n"); |
| 925 | | state->m_smpc.SR &= 0x0f; |
| 926 | | state->m_smpc.intback_stage = 0; |
| 984 | m_smpc.SR &= 0x0f; |
| 985 | m_smpc.intback_stage = 0; |
| 927 | 986 | } |
| 928 | 987 | else if(data & 0x80) |
| 929 | 988 | { |
| 930 | 989 | if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n"); |
| 931 | | space.machine().scheduler().timer_set(attotime::from_usec(700), FUNC(intback_peripheral),0); /* TODO: is timing correct? */ |
| 932 | | state->m_smpc.OREG[31] = 0x10; |
| 933 | | state->m_smpc.SF = 0x01; //TODO: set hand-shake flag? |
| 990 | machine().scheduler().timer_set(attotime::from_usec(700), FUNC(intback_peripheral),0); /* TODO: is timing correct? */ |
| 991 | m_smpc.OREG[31] = 0x10; |
| 992 | m_smpc.SF = 0x01; //TODO: set hand-shake flag? |
| 934 | 993 | } |
| 935 | 994 | } |
| 936 | 995 | } |
| r20602 | r20603 | |
| 942 | 1001 | // we've processed the command, clear status flag |
| 943 | 1002 | if(data != 0x10 && data != 2 && data != 3 && data != 6 && data != 7 && data != 0x0e && data != 0x0f && data != 0x19 && data != 0x1a) |
| 944 | 1003 | { |
| 945 | | state->m_smpc.OREG[31] = data; //read-back for last command issued |
| 946 | | state->m_smpc.SF = 0x00; //clear hand-shake flag |
| 1004 | m_smpc.OREG[31] = data; //read-back for last command issued |
| 1005 | m_smpc.SF = 0x00; //clear hand-shake flag |
| 947 | 1006 | } |
| 948 | 1007 | /*TODO:emulate the timing of each command...*/ |
| 949 | 1008 | } |
| 950 | 1009 | |
| 951 | 1010 | if (offset == 0x63) |
| 952 | | state->m_smpc.SF = data & 1; // hand-shake flag |
| 1011 | m_smpc.SF = data & 1; // hand-shake flag |
| 953 | 1012 | |
| 954 | 1013 | if(offset == 0x75) // PDR1 |
| 955 | | state->m_smpc.PDR1 = (data & state->m_smpc.DDR1); |
| 1014 | m_smpc.PDR1 = (data & m_smpc.DDR1); |
| 956 | 1015 | |
| 957 | 1016 | if(offset == 0x77) // PDR2 |
| 958 | | state->m_smpc.PDR2 = (data & state->m_smpc.DDR2); |
| 1017 | m_smpc.PDR2 = (data & m_smpc.DDR2); |
| 959 | 1018 | |
| 960 | 1019 | if(offset == 0x79) |
| 961 | | state->m_smpc.DDR1 = data & 0x7f; |
| 1020 | m_smpc.DDR1 = data & 0x7f; |
| 962 | 1021 | |
| 963 | 1022 | if(offset == 0x7b) |
| 964 | | state->m_smpc.DDR2 = data & 0x7f; |
| 1023 | m_smpc.DDR2 = data & 0x7f; |
| 965 | 1024 | |
| 966 | 1025 | if(offset == 0x7d) |
| 967 | 1026 | { |
| 968 | | state->m_smpc.IOSEL1 = data & 1; |
| 969 | | state->m_smpc.IOSEL2 = (data & 2) >> 1; |
| 1027 | m_smpc.IOSEL1 = data & 1; |
| 1028 | m_smpc.IOSEL2 = (data & 2) >> 1; |
| 970 | 1029 | } |
| 971 | 1030 | |
| 972 | 1031 | if(offset == 0x7f) |
| 973 | 1032 | { |
| 974 | 1033 | //enable PAD irq & VDP2 external latch for port 1/2 |
| 975 | | state->m_smpc.EXLE1 = (data & 1) >> 0; |
| 976 | | state->m_smpc.EXLE2 = (data & 2) >> 1; |
| 1034 | m_smpc.EXLE1 = (data & 1) >> 0; |
| 1035 | m_smpc.EXLE2 = (data & 2) >> 1; |
| 977 | 1036 | } |
| 978 | 1037 | } |
trunk/src/mame/drivers/saturn.c
| r20602 | r20603 | |
| 727 | 727 | |
| 728 | 728 | static ADDRESS_MAP_START( saturn_mem, AS_PROGRAM, 32, saturn_state ) |
| 729 | 729 | AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios |
| 730 | | AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8_LEGACY(saturn_SMPC_r, saturn_SMPC_w,0xffffffff) |
| 730 | AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(saturn_SMPC_r, saturn_SMPC_w,0xffffffff) |
| 731 | 731 | AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r, saturn_backupram_w,0xffffffff) AM_SHARE("share1") |
| 732 | 732 | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("workram_l") |
| 733 | 733 | AM_RANGE(0x01000000, 0x017fffff) AM_WRITE(minit_w) |
| r20602 | r20603 | |
| 819 | 819 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 820 | 820 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 821 | 821 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P1 L") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 822 | | PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) //read '1' when direct mode is polled |
| 822 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 823 | PORT_BIT( 0x0003, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) |
| 823 | 824 | |
| 825 | |
| 824 | 826 | #define SATURN_PAD_P2(_mask_, _val_) \ |
| 825 | 827 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 826 | 828 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| r20602 | r20603 | |
| 835 | 837 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 836 | 838 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 837 | 839 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P2 L") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 838 | | PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) //read '1' when direct mode is polled |
| 840 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 841 | PORT_BIT( 0x0003, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) |
| 839 | 842 | |
| 840 | 843 | #define MD_PAD_P1(_mask_, _val_) \ |
| 841 | 844 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |