trunk/src/emu/cpu/arcompact/arcompact.h
| r242541 | r242542 | |
| 150 | 150 | ARCOMPACT_RETTYPE arcompact_handle04_01(OPS_32); |
| 151 | 151 | ARCOMPACT_RETTYPE arcompact_handle04_02(OPS_32); |
| 152 | 152 | ARCOMPACT_RETTYPE arcompact_handle04_03(OPS_32); |
| 153 | | ARCOMPACT_RETTYPE arcompact_handle04_04(OPS_32); |
| 153 | // ARCOMPACT_RETTYPE arcompact_handle04_04(OPS_32); |
| 154 | 154 | ARCOMPACT_RETTYPE arcompact_handle04_05(OPS_32); |
| 155 | | ARCOMPACT_RETTYPE arcompact_handle04_06(OPS_32); |
| 155 | // ARCOMPACT_RETTYPE arcompact_handle04_06(OPS_32); |
| 156 | 156 | ARCOMPACT_RETTYPE arcompact_handle04_07(OPS_32); |
| 157 | 157 | ARCOMPACT_RETTYPE arcompact_handle04_08(OPS_32); |
| 158 | 158 | ARCOMPACT_RETTYPE arcompact_handle04_09(OPS_32); |
| r242541 | r242542 | |
| 768 | 768 | ARCOMPACT_RETTYPE get_insruction(OPS_32); |
| 769 | 769 | |
| 770 | 770 | ARCOMPACT_HANDLER04_TYPE_PM(04_00); |
| 771 | ARCOMPACT_HANDLER04_TYPE_PM(04_04); |
| 772 | ARCOMPACT_HANDLER04_TYPE_PM(04_06); |
| 771 | 773 | ARCOMPACT_HANDLER04_TYPE_PM(04_0a); |
| 772 | 774 | ARCOMPACT_HANDLER04_TYPE_PM(04_20); |
| 773 | 775 | |
| r242541 | r242542 | |
| 796 | 798 | int m_delaylinks; |
| 797 | 799 | UINT32 m_delayjump; |
| 798 | 800 | |
| 799 | | |
| 801 | // f e d c| b a 9 8| 7 6 5 4| 3 2 1 0 |
| 802 | // - - - L| Z N C V| U DE AE A2|A1 E2 E1 H |
| 803 | UINT32 m_status32; |
| 800 | 804 | }; |
| 801 | 805 | |
| 806 | #define V_OVERFLOW_FLAG (0x00000100) |
| 807 | #define C_CARRY_FLAG (0x00000200) |
| 808 | #define N_NEGATIVE_FLAG (0x00000400) |
| 809 | #define Z_ZERO_FLAG (0x00000800) |
| 802 | 810 | |
| 811 | // V = overflow (set if signed operation would overflow) |
| 812 | #define STATUS32_SET_V (m_status32 |= V_OVERFLOW_FLAG) |
| 813 | #define STATUS32_CLEAR_V (m_status32 &= ~V_OVERFLOW_FLAG) |
| 814 | #define STATUS32_CHECK_V (m_status32 & V_OVERFLOW_FLAG) |
| 815 | |
| 816 | // C = carry (unsigned op, carry set is same condition as LO Lower Than, carry clear is same condition as HS Higher Same) |
| 817 | #define STATUS32_SET_C (m_status32 |= C_CARRY_FLAG) |
| 818 | #define STATUS32_CLEAR_C (m_status32 &= ~C_CARRY_FLAG) |
| 819 | #define STATUS32_CHECK_C (m_status32 & C_CARRY_FLAG) |
| 820 | |
| 821 | // N = negative (set if most significant bit of result is set) |
| 822 | #define STATUS32_SET_N (m_status32 |= N_NEGATIVE_FLAG) |
| 823 | #define STATUS32_CLEAR_N (m_status32 &= ~N_NEGATIVE_FLAG) |
| 824 | #define STATUS32_CHECK_N (m_status32 & N_NEGATIVE_FLAG) |
| 825 | |
| 826 | // Z = zero (set if result is zero, ie both values the same for CMP) |
| 827 | #define STATUS32_SET_Z (m_status32 |= Z_ZERO_FLAG) |
| 828 | #define STATUS32_CLEAR_Z (m_status32 &= ~Z_ZERO_FLAG) |
| 829 | #define STATUS32_CHECK_Z (m_status32 & Z_ZERO_FLAG) |
| 830 | |
| 831 | |
| 803 | 832 | extern const device_type ARCA5; |
| 804 | 833 | |
| 805 | 834 | |
trunk/src/emu/cpu/arcompact/arcompact_execute.c
| r242541 | r242542 | |
| 17 | 17 | |
| 18 | 18 | while (m_icount > 0) |
| 19 | 19 | { |
| 20 | | debugger_instruction_hook(this, m_pc<<1); |
| 20 | debugger_instruction_hook(this, m_pc); |
| 21 | 21 | |
| 22 | 22 | // printf("new pc %04x\n", m_pc); |
| 23 | 23 | |
| r242541 | r242542 | |
| 1751 | 1751 | return arcompact_handle04_helper(PARAMS, opcodes_04[0x03], /*"SBC"*/ 0,0); |
| 1752 | 1752 | } |
| 1753 | 1753 | |
| 1754 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_04(OPS_32) |
| 1754 | |
| 1755 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_04_p00(OPS_32) |
| 1755 | 1756 | { |
| 1756 | | return arcompact_handle04_helper(PARAMS, opcodes_04[0x04], /*"AND"*/ 0,0); |
| 1757 | int size = 4; |
| 1758 | UINT32 limm = 0; |
| 1759 | int got_limm = 0; |
| 1760 | |
| 1761 | COMMON32_GET_breg; |
| 1762 | COMMON32_GET_F; |
| 1763 | COMMON32_GET_creg |
| 1764 | COMMON32_GET_areg |
| 1765 | |
| 1766 | UINT32 b, c; |
| 1767 | |
| 1768 | if (breg == LIMM_REG) |
| 1769 | { |
| 1770 | GET_LIMM_32; |
| 1771 | size = 8; |
| 1772 | got_limm = 1; |
| 1773 | b = limm; |
| 1774 | } |
| 1775 | else |
| 1776 | { |
| 1777 | b = m_regs[breg]; |
| 1778 | } |
| 1779 | |
| 1780 | if (creg == LIMM_REG) |
| 1781 | { |
| 1782 | if (!got_limm) |
| 1783 | { |
| 1784 | GET_LIMM_32; |
| 1785 | size = 8; |
| 1786 | } |
| 1787 | c = limm; |
| 1788 | } |
| 1789 | else |
| 1790 | { |
| 1791 | c = m_regs[creg]; |
| 1792 | } |
| 1793 | // todo: is and a, limm, limm valid? (it's pointless.) |
| 1794 | |
| 1795 | // todo: if areg = LIMM then there is no result (but since that register can never be read, I guess it doesn't matter if we store it there anyway?) |
| 1796 | m_regs[areg] = b & c; |
| 1797 | |
| 1798 | if (F) |
| 1799 | { |
| 1800 | arcompact_fatal("arcompact_handle04_04_p00 (AND) (F set)\n"); // not yet supported |
| 1801 | } |
| 1802 | |
| 1803 | return m_pc + (size >> 0);} |
| 1804 | |
| 1805 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_04_p01(OPS_32) |
| 1806 | { |
| 1807 | int size = 4; |
| 1808 | arcompact_fatal("arcompact_handle04_04_p01 (AND)\n"); |
| 1809 | return m_pc + (size >> 0); |
| 1757 | 1810 | } |
| 1758 | 1811 | |
| 1812 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_04_p10(OPS_32) |
| 1813 | { |
| 1814 | int size = 4; |
| 1815 | arcompact_fatal("arcompact_handle04_04_p10 (AND)\n"); |
| 1816 | return m_pc + (size >> 0); |
| 1817 | } |
| 1818 | |
| 1819 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_04_p11_m0(OPS_32) |
| 1820 | { |
| 1821 | int size = 4; |
| 1822 | arcompact_fatal("arcompact_handle04_04_p11_m0 (AND)\n"); |
| 1823 | return m_pc + (size >> 0); |
| 1824 | } |
| 1825 | |
| 1826 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_04_p11_m1(OPS_32) |
| 1827 | { |
| 1828 | int size = 4; |
| 1829 | arcompact_fatal("arcompact_handle04_04_p11_m1 (AND)\n"); |
| 1830 | return m_pc + (size >> 0); |
| 1831 | } |
| 1832 | |
| 1833 | |
| 1759 | 1834 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_05(OPS_32) |
| 1760 | 1835 | { |
| 1761 | 1836 | return arcompact_handle04_helper(PARAMS, opcodes_04[0x05], /*"OR"*/ 0,0); |
| 1762 | 1837 | } |
| 1763 | 1838 | |
| 1764 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_06(OPS_32) |
| 1839 | |
| 1840 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_06_p00(OPS_32) |
| 1765 | 1841 | { |
| 1766 | | return arcompact_handle04_helper(PARAMS, opcodes_04[0x06], /*"BIC"*/ 0,0); |
| 1842 | int size = 4; |
| 1843 | arcompact_fatal("arcompact_handle04_06_p00 (BIC)\n"); |
| 1844 | return m_pc + (size >> 0); |
| 1845 | |
| 1767 | 1846 | } |
| 1768 | 1847 | |
| 1848 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_06_p01(OPS_32) |
| 1849 | { |
| 1850 | int size = 4; |
| 1851 | arcompact_fatal("arcompact_handle04_06_p01 (BIC)\n"); |
| 1852 | return m_pc + (size >> 0); |
| 1853 | } |
| 1854 | |
| 1855 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_06_p10(OPS_32) |
| 1856 | { |
| 1857 | int size = 4; |
| 1858 | arcompact_fatal("arcompact_handle04_06_p10 (BIC)\n"); |
| 1859 | return m_pc + (size >> 0); |
| 1860 | } |
| 1861 | |
| 1862 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_06_p11_m0(OPS_32) |
| 1863 | { |
| 1864 | int size = 4; |
| 1865 | arcompact_fatal("arcompact_handle04_06_p11_m0 (BIC)\n"); |
| 1866 | return m_pc + (size >> 0); |
| 1867 | } |
| 1868 | |
| 1869 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_06_p11_m1(OPS_32) |
| 1870 | { |
| 1871 | int size = 4; |
| 1872 | arcompact_fatal("arcompact_handle04_06_p11_m1 (BIC)\n"); |
| 1873 | return m_pc + (size >> 0); |
| 1874 | } |
| 1875 | |
| 1876 | |
| 1769 | 1877 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_07(OPS_32) |
| 1770 | 1878 | { |
| 1771 | 1879 | return arcompact_handle04_helper(PARAMS, opcodes_04[0x07], /*"XOR"*/ 0,0); |
| r242541 | r242542 | |
| 2660 | 2768 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_00_07_01(OPS_16) { arcompact_log("UNIMP_S"); return m_pc + (2 >> 0);} // Unimplemented Instruction, same as illegal, but recommended to fill blank space |
| 2661 | 2769 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_00_07_04(OPS_16) { arcompact_log("JEQ_S [blink]"); return m_pc + (2 >> 0);} |
| 2662 | 2770 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_00_07_05(OPS_16) { arcompact_log("JNE_S [blink]"); return m_pc + (2 >> 0);} |
| 2663 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_00_07_06(OPS_16) { arcompact_log("J_S [blink]"); return m_pc + (2 >> 0);} |
| 2771 | |
| 2772 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_00_07_06(OPS_16) // J_S [blink] |
| 2773 | { |
| 2774 | return m_regs[REG_BLINK]; |
| 2775 | } |
| 2776 | |
| 2777 | |
| 2664 | 2778 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_00_07_07(OPS_16) { arcompact_log("J_S.D [blink]"); return m_pc + (2 >> 0);} |
| 2665 | 2779 | |
| 2666 | 2780 | |
| r242541 | r242542 | |
| 2917 | 3031 | } |
| 2918 | 3032 | |
| 2919 | 3033 | // op bits remaining for 0x18_06_xx subgroups 0x0700 |
| 2920 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_06_01(OPS_16) |
| 3034 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_06_01(OPS_16) // POP_S b |
| 2921 | 3035 | { |
| 2922 | | arcompact_log("unimplemented POP_S %04x", op); |
| 3036 | int breg; |
| 3037 | COMMON16_GET_breg; |
| 3038 | REG_16BIT_RANGE(breg); |
| 3039 | |
| 3040 | m_regs[breg] = READ32(m_regs[REG_SP] >> 2); |
| 3041 | m_regs[REG_SP] += 4; |
| 3042 | |
| 2923 | 3043 | return m_pc + (2 >> 0); |
| 2924 | 3044 | } |
| 2925 | 3045 | |
| 2926 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_06_11(OPS_16) |
| 3046 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_06_11(OPS_16) // POP_S blink |
| 2927 | 3047 | { |
| 2928 | | arcompact_log("unimplemented POP_S [BLINK] %04x", op); |
| 3048 | // breg bits are reserved |
| 3049 | m_regs[REG_BLINK] = READ32(m_regs[REG_SP] >> 2 ); |
| 3050 | m_regs[REG_SP] += 4; |
| 3051 | |
| 2929 | 3052 | return m_pc + (2 >> 0); |
| 2930 | 3053 | } |
| 2931 | 3054 | |
| 2932 | 3055 | // op bits remaining for 0x18_07_xx subgroups 0x0700 |
| 2933 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_07_01(OPS_16) |
| 3056 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_07_01(OPS_16) // PUSH_S b |
| 2934 | 3057 | { |
| 2935 | 3058 | int breg; |
| 2936 | 3059 | COMMON16_GET_breg; |
| r242541 | r242542 | |
| 2944 | 3067 | } |
| 2945 | 3068 | |
| 2946 | 3069 | |
| 2947 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_07_11(OPS_16) |
| 3070 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle18_07_11(OPS_16) // PUSH_S [blink] |
| 2948 | 3071 | { |
| 2949 | 3072 | // breg bits are reserved |
| 2950 | 3073 | |
| r242541 | r242542 | |
| 2975 | 3098 | |
| 2976 | 3099 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1b(OPS_16) // MOV_S b, u8 |
| 2977 | 3100 | { |
| 2978 | | int breg, u; |
| 3101 | int breg; |
| 3102 | UINT32 u; |
| 2979 | 3103 | COMMON16_GET_breg; |
| 2980 | 3104 | COMMON16_GET_u8; |
| 2981 | 3105 | REG_16BIT_RANGE(breg); |
| r242541 | r242542 | |
| 2987 | 3111 | |
| 2988 | 3112 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1c_00(OPS_16) // ADD_S b, b, u7 |
| 2989 | 3113 | { |
| 2990 | | int breg, u; |
| 3114 | int breg; |
| 3115 | UINT32 u; |
| 2991 | 3116 | COMMON16_GET_breg; |
| 2992 | 3117 | COMMON16_GET_u7; |
| 2993 | 3118 | REG_16BIT_RANGE(breg); |
| r242541 | r242542 | |
| 2997 | 3122 | return m_pc + (2 >> 0); |
| 2998 | 3123 | } |
| 2999 | 3124 | |
| 3000 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1c_01(OPS_16) |
| 3125 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1c_01(OPS_16) // CMP b, u7 |
| 3001 | 3126 | { |
| 3002 | | arcompact_log("unimplemented CMP_S %04x", op); |
| 3127 | int breg; |
| 3128 | UINT32 u; |
| 3129 | COMMON16_GET_breg; |
| 3130 | COMMON16_GET_u7; |
| 3131 | REG_16BIT_RANGE(breg); |
| 3132 | |
| 3133 | // flag setting ALWAYS occurs on CMP operations, even 16-bit ones even without a .F opcode type |
| 3134 | |
| 3135 | // TODO: verify this flag setting logic |
| 3136 | |
| 3137 | // unsigned checks |
| 3138 | if (m_regs[breg] == u) |
| 3139 | { |
| 3140 | STATUS32_SET_Z; |
| 3141 | } |
| 3142 | else |
| 3143 | { |
| 3144 | STATUS32_CLEAR_Z; |
| 3145 | } |
| 3146 | |
| 3147 | if (m_regs[breg] < u) |
| 3148 | { |
| 3149 | STATUS32_SET_C; |
| 3150 | } |
| 3151 | else |
| 3152 | { |
| 3153 | STATUS32_CLEAR_C; |
| 3154 | } |
| 3155 | // signed checks |
| 3156 | INT32 temp = (INT32)m_regs[breg] - (INT32)u; |
| 3157 | |
| 3158 | if (temp < 0) |
| 3159 | { |
| 3160 | STATUS32_SET_N; |
| 3161 | } |
| 3162 | else |
| 3163 | { |
| 3164 | STATUS32_CLEAR_N; |
| 3165 | } |
| 3166 | |
| 3167 | // if signs of source values don't match, and sign of result doesn't match the first source value, then we've overflowed? |
| 3168 | if ((m_regs[breg] & 0x80000000) != (u & 0x80000000)) |
| 3169 | { |
| 3170 | if ((m_regs[breg] & 0x80000000) != (temp & 0x80000000)) |
| 3171 | { |
| 3172 | STATUS32_SET_V; |
| 3173 | } |
| 3174 | else |
| 3175 | { |
| 3176 | STATUS32_CLEAR_V; |
| 3177 | } |
| 3178 | } |
| 3179 | |
| 3180 | // only sets flags, no result written |
| 3181 | |
| 3003 | 3182 | return m_pc + (2 >> 0); |
| 3004 | 3183 | } |
| 3005 | 3184 | |
| r242541 | r242542 | |
| 3010 | 3189 | } |
| 3011 | 3190 | |
| 3012 | 3191 | |
| 3013 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1d_00(OPS_16) { return arcompact_handle1d_helper(PARAMS,"BREQ_S"); } |
| 3192 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1d_00(OPS_16) // BREQ b,0,s8 |
| 3193 | { |
| 3194 | int breg; |
| 3195 | COMMON16_GET_breg; |
| 3196 | REG_16BIT_RANGE(breg); |
| 3197 | |
| 3198 | if (!m_regs[breg]) |
| 3199 | { |
| 3200 | int s = (op & 0x007f) >> 0; op &= ~0x007f; |
| 3201 | if (s & 0x40) s = -0x40 + (s & 0x3f); |
| 3202 | UINT32 realaddress = PC_ALIGNED32 + (s * 2); |
| 3203 | //m_regs[REG_BLINK] = m_pc + (2 >> 0); // don't link |
| 3204 | return realaddress; |
| 3205 | } |
| 3206 | |
| 3207 | return m_pc + (2 >> 0); |
| 3208 | } |
| 3209 | |
| 3210 | |
| 3014 | 3211 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1d_01(OPS_16) { return arcompact_handle1d_helper(PARAMS,"BRNE_S"); } |
| 3015 | 3212 | |
| 3016 | 3213 | |
| r242541 | r242542 | |
| 3022 | 3219 | |
| 3023 | 3220 | |
| 3024 | 3221 | |
| 3025 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1e_00(OPS_16) { return arcompact_handle1e_0x_helper(PARAMS, "BL_S"); } |
| 3222 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1e_00(OPS_16) // B_S s10 (branch always) |
| 3223 | { |
| 3224 | int s = (op & 0x01ff) >> 0; op &= ~0x01ff; |
| 3225 | if (s & 0x100) s = -0x100 + (s & 0xff); |
| 3226 | UINT32 realaddress = PC_ALIGNED32 + (s * 2); |
| 3227 | //m_regs[REG_BLINK] = m_pc + (2 >> 0); // don't link |
| 3228 | return realaddress; |
| 3229 | } |
| 3230 | |
| 3026 | 3231 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1e_01(OPS_16) { return arcompact_handle1e_0x_helper(PARAMS, "BEQ_S"); } |
| 3027 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1e_02(OPS_16) { return arcompact_handle1e_0x_helper(PARAMS, "BNE_S"); } |
| 3028 | 3232 | |
| 3233 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1e_02(OPS_16) // BNE_S s10 (branch if zero bit isn't set) |
| 3234 | { |
| 3235 | if (!STATUS32_CHECK_Z) |
| 3236 | { |
| 3237 | int s = (op & 0x01ff) >> 0; op &= ~0x01ff; |
| 3238 | if (s & 0x100) s = -0x100 + (s & 0xff); |
| 3239 | UINT32 realaddress = PC_ALIGNED32 + (s * 2); |
| 3240 | //m_regs[REG_BLINK] = m_pc + (2 >> 0); // don't link |
| 3241 | return realaddress; |
| 3242 | } |
| 3243 | |
| 3244 | return m_pc + (2 >> 0); |
| 3245 | } |
| 3246 | |
| 3029 | 3247 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1e_03_0x_helper(OPS_16, const char* optext) |
| 3030 | 3248 | { |
| 3031 | 3249 | arcompact_log("unimplemented %s %04x", optext, op); |