trunk/src/emu/cpu/mips/mips3.c
| r245293 | r245294 | |
| 148 | 148 | , m_pfnmask(0) |
| 149 | 149 | , m_tlbentries(0) |
| 150 | 150 | , m_bigendian(endianness == ENDIANNESS_BIG) |
| 151 | , m_byte_xor(m_bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0)) |
| 152 | , m_word_xor(m_bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0)) |
| 151 | 153 | , c_icache_size(0) |
| 152 | 154 | , c_dcache_size(0) |
| 153 | 155 | , m_vtlb(NULL) |
| 156 | , m_fastram_select(0) |
| 154 | 157 | , m_debugger_temp(0) |
| 155 | 158 | , m_cache(CACHE_SIZE + sizeof(internal_mips3_state)) |
| 156 | 159 | , m_drcuml(NULL) |
| r245293 | r245294 | |
| 161 | 164 | , m_nocode(NULL) |
| 162 | 165 | , m_out_of_cycles(NULL) |
| 163 | 166 | , m_tlb_mismatch(NULL) |
| 164 | | , m_fastram_select(0) |
| 165 | 167 | , m_hotspot_select(0) |
| 166 | 168 | { |
| 167 | 169 | memset(m_fpmode, 0, sizeof(m_fpmode)); |
| r245293 | r245294 | |
| 996 | 998 | TLB HANDLING |
| 997 | 999 | ***************************************************************************/ |
| 998 | 1000 | |
| 999 | | inline int mips3_device::RBYTE(offs_t address, UINT32 *result) |
| 1001 | bool mips3_device::RBYTE(offs_t address, UINT32 *result) |
| 1000 | 1002 | { |
| 1001 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1003 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1002 | 1004 | if (tlbval & VTLB_READ_ALLOWED) |
| 1003 | 1005 | { |
| 1004 | | *result = (*m_memory.read_byte)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| 1006 | const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); |
| 1007 | for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) |
| 1008 | { |
| 1009 | if (tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end) |
| 1010 | { |
| 1011 | continue; |
| 1012 | } |
| 1013 | UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; |
| 1014 | *result = fastbase[tlbaddress ^ m_byte_xor]; |
| 1015 | return true; |
| 1016 | } |
| 1017 | *result = (*m_memory.read_byte)(*m_program, tlbaddress); |
| 1005 | 1018 | } |
| 1006 | 1019 | else |
| 1007 | 1020 | { |
| r245293 | r245294 | |
| 1014 | 1027 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1015 | 1028 | } |
| 1016 | 1029 | *result = 0; |
| 1017 | | return 0; |
| 1030 | return false; |
| 1018 | 1031 | } |
| 1019 | | return 1; |
| 1032 | return true; |
| 1020 | 1033 | } |
| 1021 | 1034 | |
| 1022 | | |
| 1023 | | inline int mips3_device::RHALF(offs_t address, UINT32 *result) |
| 1035 | bool mips3_device::RHALF(offs_t address, UINT32 *result) |
| 1024 | 1036 | { |
| 1025 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1037 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1026 | 1038 | if (tlbval & VTLB_READ_ALLOWED) |
| 1027 | 1039 | { |
| 1028 | | *result = (*m_memory.read_word)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| 1040 | const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); |
| 1041 | for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) |
| 1042 | { |
| 1043 | if (tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end) |
| 1044 | { |
| 1045 | continue; |
| 1046 | } |
| 1047 | UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; |
| 1048 | *result = ((UINT16*)fastbase)[(tlbaddress ^ m_word_xor) >> 1]; |
| 1049 | return true; |
| 1050 | } |
| 1051 | *result = (*m_memory.read_word)(*m_program, tlbaddress); |
| 1029 | 1052 | } |
| 1030 | 1053 | else |
| 1031 | 1054 | { |
| r245293 | r245294 | |
| 1038 | 1061 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1039 | 1062 | } |
| 1040 | 1063 | *result = 0; |
| 1041 | | return 0; |
| 1064 | return false; |
| 1042 | 1065 | } |
| 1043 | | return 1; |
| 1066 | return true; |
| 1044 | 1067 | } |
| 1045 | 1068 | |
| 1046 | | |
| 1047 | | inline int mips3_device::RWORD(offs_t address, UINT32 *result) |
| 1069 | bool mips3_device::RWORD(offs_t address, UINT32 *result) |
| 1048 | 1070 | { |
| 1049 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1071 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1050 | 1072 | if (tlbval & VTLB_READ_ALLOWED) |
| 1051 | 1073 | { |
| 1052 | | *result = (*m_memory.read_dword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| 1074 | const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); |
| 1075 | for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) |
| 1076 | { |
| 1077 | if (tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end) |
| 1078 | { |
| 1079 | continue; |
| 1080 | } |
| 1081 | UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; |
| 1082 | *result = ((UINT32*)fastbase)[tlbaddress >> 2]; |
| 1083 | return true; |
| 1084 | } |
| 1085 | *result = (*m_memory.read_dword)(*m_program, tlbaddress); |
| 1053 | 1086 | } |
| 1054 | 1087 | else |
| 1055 | 1088 | { |
| r245293 | r245294 | |
| 1062 | 1095 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1063 | 1096 | } |
| 1064 | 1097 | *result = 0; |
| 1065 | | return 0; |
| 1098 | return false; |
| 1066 | 1099 | } |
| 1067 | | return 1; |
| 1100 | return true; |
| 1068 | 1101 | } |
| 1069 | 1102 | |
| 1070 | | |
| 1071 | | inline int mips3_device::RWORD_MASKED(offs_t address, UINT32 *result, UINT32 mem_mask) |
| 1103 | bool mips3_device::RWORD_MASKED(offs_t address, UINT32 *result, UINT32 mem_mask) |
| 1072 | 1104 | { |
| 1073 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1105 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1074 | 1106 | if (tlbval & VTLB_READ_ALLOWED) |
| 1075 | 1107 | { |
| 1076 | 1108 | *result = (*m_memory.read_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask); |
| r245293 | r245294 | |
| 1086 | 1118 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1087 | 1119 | } |
| 1088 | 1120 | *result = 0; |
| 1089 | | return 0; |
| 1121 | return false; |
| 1090 | 1122 | } |
| 1091 | | return 1; |
| 1123 | return true; |
| 1092 | 1124 | } |
| 1093 | 1125 | |
| 1094 | | |
| 1095 | | inline int mips3_device::RDOUBLE(offs_t address, UINT64 *result) |
| 1126 | bool mips3_device::RDOUBLE(offs_t address, UINT64 *result) |
| 1096 | 1127 | { |
| 1097 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1128 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1098 | 1129 | if (tlbval & VTLB_READ_ALLOWED) |
| 1099 | 1130 | { |
| 1100 | 1131 | *result = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| r245293 | r245294 | |
| 1110 | 1141 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1111 | 1142 | } |
| 1112 | 1143 | *result = 0; |
| 1113 | | return 0; |
| 1144 | return false; |
| 1114 | 1145 | } |
| 1115 | | return 1; |
| 1146 | return true; |
| 1116 | 1147 | } |
| 1117 | 1148 | |
| 1118 | | |
| 1119 | | inline int mips3_device::RDOUBLE_MASKED(offs_t address, UINT64 *result, UINT64 mem_mask) |
| 1149 | bool mips3_device::RDOUBLE_MASKED(offs_t address, UINT64 *result, UINT64 mem_mask) |
| 1120 | 1150 | { |
| 1121 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1151 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1122 | 1152 | if (tlbval & VTLB_READ_ALLOWED) |
| 1123 | 1153 | { |
| 1124 | 1154 | *result = (*m_memory.read_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask); |
| r245293 | r245294 | |
| 1134 | 1164 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1135 | 1165 | } |
| 1136 | 1166 | *result = 0; |
| 1137 | | return 0; |
| 1167 | return false; |
| 1138 | 1168 | } |
| 1139 | | return 1; |
| 1169 | return true; |
| 1140 | 1170 | } |
| 1141 | 1171 | |
| 1142 | | |
| 1143 | | inline void mips3_device::WBYTE(offs_t address, UINT8 data) |
| 1172 | void mips3_device::WBYTE(offs_t address, UINT8 data) |
| 1144 | 1173 | { |
| 1145 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1174 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1146 | 1175 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1147 | 1176 | { |
| 1148 | | (*m_memory.write_byte)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1177 | const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); |
| 1178 | for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) |
| 1179 | { |
| 1180 | if (m_fastram[ramnum].readonly == TRUE || tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end) |
| 1181 | { |
| 1182 | continue; |
| 1183 | } |
| 1184 | UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; |
| 1185 | fastbase[tlbaddress ^ m_byte_xor] = data; |
| 1186 | return; |
| 1187 | } |
| 1188 | (*m_memory.write_byte)(*m_program, tlbaddress, data); |
| 1149 | 1189 | } |
| 1150 | 1190 | else |
| 1151 | 1191 | { |
| r245293 | r245294 | |
| 1164 | 1204 | } |
| 1165 | 1205 | } |
| 1166 | 1206 | |
| 1167 | | |
| 1168 | | inline void mips3_device::WHALF(offs_t address, UINT16 data) |
| 1207 | void mips3_device::WHALF(offs_t address, UINT16 data) |
| 1169 | 1208 | { |
| 1170 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1209 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1171 | 1210 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1172 | 1211 | { |
| 1173 | | (*m_memory.write_word)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1212 | const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); |
| 1213 | for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) |
| 1214 | { |
| 1215 | if (m_fastram[ramnum].readonly == TRUE || tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end) |
| 1216 | { |
| 1217 | continue; |
| 1218 | } |
| 1219 | void *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; |
| 1220 | ((UINT16*)fastbase)[(tlbaddress ^ m_word_xor) >> 1] = data; |
| 1221 | return; |
| 1222 | } |
| 1223 | (*m_memory.write_word)(*m_program, tlbaddress, data); |
| 1174 | 1224 | } |
| 1175 | 1225 | else |
| 1176 | 1226 | { |
| r245293 | r245294 | |
| 1189 | 1239 | } |
| 1190 | 1240 | } |
| 1191 | 1241 | |
| 1192 | | |
| 1193 | | inline void mips3_device::WWORD(offs_t address, UINT32 data) |
| 1242 | void mips3_device::WWORD(offs_t address, UINT32 data) |
| 1194 | 1243 | { |
| 1195 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1244 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1196 | 1245 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1197 | 1246 | { |
| 1198 | | (*m_memory.write_dword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1247 | const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); |
| 1248 | for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) |
| 1249 | { |
| 1250 | if (m_fastram[ramnum].readonly == TRUE || tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end) |
| 1251 | { |
| 1252 | continue; |
| 1253 | } |
| 1254 | void *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; |
| 1255 | ((UINT32*)fastbase)[tlbaddress >> 2] = data; |
| 1256 | return; |
| 1257 | } |
| 1258 | (*m_memory.write_dword)(*m_program, tlbaddress, data); |
| 1199 | 1259 | } |
| 1200 | 1260 | else |
| 1201 | 1261 | { |
| r245293 | r245294 | |
| 1214 | 1274 | } |
| 1215 | 1275 | } |
| 1216 | 1276 | |
| 1217 | | |
| 1218 | | inline void mips3_device::WWORD_MASKED(offs_t address, UINT32 data, UINT32 mem_mask) |
| 1277 | void mips3_device::WWORD_MASKED(offs_t address, UINT32 data, UINT32 mem_mask) |
| 1219 | 1278 | { |
| 1220 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1279 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1221 | 1280 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1222 | 1281 | { |
| 1223 | 1282 | (*m_memory.write_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask); |
| r245293 | r245294 | |
| 1239 | 1298 | } |
| 1240 | 1299 | } |
| 1241 | 1300 | |
| 1242 | | |
| 1243 | | inline void mips3_device::WDOUBLE(offs_t address, UINT64 data) |
| 1301 | void mips3_device::WDOUBLE(offs_t address, UINT64 data) |
| 1244 | 1302 | { |
| 1245 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1246 | | //printf("%08x: %08x\n", (UINT32)address, (UINT32)tlbval); |
| 1303 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1247 | 1304 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1248 | 1305 | { |
| 1249 | | (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1306 | (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1250 | 1307 | } |
| 1251 | 1308 | else |
| 1252 | 1309 | { |
| r245293 | r245294 | |
| 1265 | 1322 | } |
| 1266 | 1323 | } |
| 1267 | 1324 | |
| 1268 | | |
| 1269 | | inline void mips3_device::WDOUBLE_MASKED(offs_t address, UINT64 data, UINT64 mem_mask) |
| 1325 | void mips3_device::WDOUBLE_MASKED(offs_t address, UINT64 data, UINT64 mem_mask) |
| 1270 | 1326 | { |
| 1271 | | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1327 | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1272 | 1328 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1273 | 1329 | { |
| 1274 | 1330 | (*m_memory.write_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask); |
| r245293 | r245294 | |
| 1296 | 1352 | COP0 (SYSTEM) EXECUTION HANDLING |
| 1297 | 1353 | ***************************************************************************/ |
| 1298 | 1354 | |
| 1299 | | inline UINT64 mips3_device::get_cop0_reg(int idx) |
| 1355 | UINT64 mips3_device::get_cop0_reg(int idx) |
| 1300 | 1356 | { |
| 1301 | 1357 | if (idx == COP0_Count) |
| 1302 | 1358 | { |
| r245293 | r245294 | |
| 1329 | 1385 | return m_core->cpr[0][idx]; |
| 1330 | 1386 | } |
| 1331 | 1387 | |
| 1332 | | inline void mips3_device::set_cop0_reg(int idx, UINT64 val) |
| 1388 | void mips3_device::set_cop0_reg(int idx, UINT64 val) |
| 1333 | 1389 | { |
| 1334 | 1390 | switch (idx) |
| 1335 | 1391 | { |
| r245293 | r245294 | |
| 1406 | 1462 | m_core->ccr[0][idx] = val; |
| 1407 | 1463 | } |
| 1408 | 1464 | |
| 1409 | | inline void mips3_device::handle_cop0(UINT32 op) |
| 1465 | void mips3_device::handle_cop0(UINT32 op) |
| 1410 | 1466 | { |
| 1411 | 1467 | if ((SR & SR_KSU_MASK) != SR_KSU_KERNEL && !(SR & SR_COP0)) |
| 1412 | 1468 | { |
| r245293 | r245294 | |
| 1541 | 1597 | } |
| 1542 | 1598 | } |
| 1543 | 1599 | |
| 1544 | | inline void mips3_device::handle_cop1_fr0(UINT32 op) |
| 1600 | void mips3_device::handle_cop1_fr0(UINT32 op) |
| 1545 | 1601 | { |
| 1546 | 1602 | double dtemp; |
| 1547 | 1603 | |
| r245293 | r245294 | |
| 1900 | 1956 | } |
| 1901 | 1957 | |
| 1902 | 1958 | |
| 1903 | | inline void mips3_device::handle_cop1_fr1(UINT32 op) |
| 1959 | void mips3_device::handle_cop1_fr1(UINT32 op) |
| 1904 | 1960 | { |
| 1905 | 1961 | double dtemp; |
| 1906 | 1962 | |
| r245293 | r245294 | |
| 2264 | 2320 | COP1X (FPU EXTRA) EXECUTION HANDLING |
| 2265 | 2321 | ***************************************************************************/ |
| 2266 | 2322 | |
| 2267 | | inline void mips3_device::handle_cop1x_fr0(UINT32 op) |
| 2323 | void mips3_device::handle_cop1x_fr0(UINT32 op) |
| 2268 | 2324 | { |
| 2269 | 2325 | UINT64 temp64; |
| 2270 | 2326 | UINT32 temp; |
| r245293 | r245294 | |
| 2342 | 2398 | } |
| 2343 | 2399 | } |
| 2344 | 2400 | |
| 2345 | | |
| 2346 | | inline void mips3_device::handle_cop1x_fr1(UINT32 op) |
| 2401 | void mips3_device::handle_cop1x_fr1(UINT32 op) |
| 2347 | 2402 | { |
| 2348 | 2403 | UINT64 temp64; |
| 2349 | 2404 | UINT32 temp; |
| r245293 | r245294 | |
| 2447 | 2502 | m_core->ccr[2][idx] = val; |
| 2448 | 2503 | } |
| 2449 | 2504 | |
| 2450 | | inline void mips3_device::handle_integer_divide_by_zero(UINT32 op) |
| 2505 | void mips3_device::handle_cop2(UINT32 op) |
| 2451 | 2506 | { |
| 2452 | | HIVAL64 = (INT32)RSVAL32; |
| 2453 | | if (m_flavor == MIPS3_TYPE_VR4300) |
| 2454 | | { |
| 2455 | | if (RSVAL32 >= 0) |
| 2456 | | { |
| 2457 | | LOVAL64 = (INT32)0x7fffffff; |
| 2458 | | } |
| 2459 | | else |
| 2460 | | { |
| 2461 | | LOVAL64 = (INT32)0x80000001; |
| 2462 | | } |
| 2463 | | } |
| 2464 | | else |
| 2465 | | { |
| 2466 | | if (RSVAL32 >= 0) |
| 2467 | | { |
| 2468 | | LOVAL64 = -1; |
| 2469 | | } |
| 2470 | | else |
| 2471 | | { |
| 2472 | | LOVAL64 = 1; |
| 2473 | | } |
| 2474 | | } |
| 2475 | | } |
| 2476 | | |
| 2477 | | inline void mips3_device::handle_cop2(UINT32 op) |
| 2478 | | { |
| 2479 | 2507 | if (!(SR & SR_COP2)) |
| 2480 | 2508 | { |
| 2481 | 2509 | m_badcop_value = 2; |
| r245293 | r245294 | |
| 2526 | 2554 | CORE EXECUTION LOOP |
| 2527 | 2555 | ***************************************************************************/ |
| 2528 | 2556 | |
| 2557 | void mips3_device::handle_regimm(UINT32 op) |
| 2558 | { |
| 2559 | switch (RTREG) |
| 2560 | { |
| 2561 | case 0x00: /* BLTZ */ if ((INT64)RSVAL64 < 0) ADDPC(SIMMVAL); break; |
| 2562 | case 0x01: /* BGEZ */ if ((INT64)RSVAL64 >= 0) ADDPC(SIMMVAL); break; |
| 2563 | case 0x02: /* BLTZL */ if ((INT64)RSVAL64 < 0) ADDPC(SIMMVAL); else m_core->pc += 4; break; |
| 2564 | case 0x03: /* BGEZL */ if ((INT64)RSVAL64 >= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break; |
| 2565 | case 0x08: /* TGEI */ if ((INT64)RSVAL64 >= SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2566 | case 0x09: /* TGEIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2567 | case 0x0a: /* TLTI */ if ((INT64)RSVAL64 < SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2568 | case 0x0b: /* TLTIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2569 | case 0x0c: /* TEQI */ if (RSVAL64 == UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2570 | case 0x0e: /* TNEI */ if (RSVAL64 != UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2571 | case 0x10: /* BLTZAL */ if ((INT64)RSVAL64 < 0) ADDPCL(SIMMVAL,31); break; |
| 2572 | case 0x11: /* BGEZAL */ if ((INT64)RSVAL64 >= 0) ADDPCL(SIMMVAL,31); break; |
| 2573 | case 0x12: /* BLTZALL */ if ((INT64)RSVAL64 < 0) ADDPCL(SIMMVAL,31) else m_core->pc += 4; break; |
| 2574 | case 0x13: /* BGEZALL */ if ((INT64)RSVAL64 >= 0) ADDPCL(SIMMVAL,31) else m_core->pc += 4; break; |
| 2575 | default: /* ??? */ invalid_instruction(op); break; |
| 2576 | } |
| 2577 | } |
| 2578 | |
| 2579 | void mips3_device::handle_special(UINT32 op) |
| 2580 | { |
| 2581 | switch (op & 63) |
| 2582 | { |
| 2583 | case 0x00: /* SLL */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 << SHIFT); break; |
| 2584 | case 0x01: /* MOVF - R5000*/if (RDREG && GET_FCC((op >> 18) & 7) == ((op >> 16) & 1)) RDVAL64 = RSVAL64; break; |
| 2585 | case 0x02: /* SRL */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 >> SHIFT); break; |
| 2586 | case 0x03: /* SRA */ if (RDREG) RDVAL64 = (INT32)RTVAL32 >> SHIFT; break; |
| 2587 | case 0x04: /* SLLV */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 << (RSVAL32 & 31)); break; |
| 2588 | case 0x06: /* SRLV */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 >> (RSVAL32 & 31)); break; |
| 2589 | case 0x07: /* SRAV */ if (RDREG) RDVAL64 = (INT32)RTVAL32 >> (RSVAL32 & 31); break; |
| 2590 | case 0x08: /* JR */ SETPC(RSVAL32); break; |
| 2591 | case 0x09: /* JALR */ SETPCL(RSVAL32,RDREG); break; |
| 2592 | case 0x0a: /* MOVZ - R5000 */if (RTVAL64 == 0) { if (RDREG) RDVAL64 = RSVAL64; } break; |
| 2593 | case 0x0b: /* MOVN - R5000 */if (RTVAL64 != 0) { if (RDREG) RDVAL64 = RSVAL64; } break; |
| 2594 | case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL, 1); break; |
| 2595 | case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK, 1); break; |
| 2596 | case 0x0f: /* SYNC */ /* effective no-op */ break; |
| 2597 | case 0x10: /* MFHI */ if (RDREG) RDVAL64 = HIVAL64; break; |
| 2598 | case 0x11: /* MTHI */ HIVAL64 = RSVAL64; break; |
| 2599 | case 0x12: /* MFLO */ if (RDREG) RDVAL64 = LOVAL64; break; |
| 2600 | case 0x13: /* MTLO */ LOVAL64 = RSVAL64; break; |
| 2601 | case 0x14: /* DSLLV */ if (RDREG) RDVAL64 = RTVAL64 << (RSVAL32 & 63); break; |
| 2602 | case 0x16: /* DSRLV */ if (RDREG) RDVAL64 = RTVAL64 >> (RSVAL32 & 63); break; |
| 2603 | case 0x17: /* DSRAV */ if (RDREG) RDVAL64 = (INT64)RTVAL64 >> (RSVAL32 & 63); break; |
| 2604 | case 0x18: /* MULT */ |
| 2605 | { |
| 2606 | UINT64 temp64 = (INT64)(INT32)RSVAL32 * (INT64)(INT32)RTVAL32; |
| 2607 | LOVAL64 = (INT32)temp64; |
| 2608 | HIVAL64 = (INT32)(temp64 >> 32); |
| 2609 | m_core->icount -= 3; |
| 2610 | break; |
| 2611 | } |
| 2612 | case 0x19: /* MULTU */ |
| 2613 | { |
| 2614 | UINT64 temp64 = (UINT64)RSVAL32 * (UINT64)RTVAL32; |
| 2615 | LOVAL64 = (INT32)temp64; |
| 2616 | HIVAL64 = (INT32)(temp64 >> 32); |
| 2617 | m_core->icount -= 3; |
| 2618 | break; |
| 2619 | } |
| 2620 | case 0x1a: /* DIV */ |
| 2621 | if (RTVAL32) |
| 2622 | { |
| 2623 | LOVAL64 = (INT32)((INT32)RSVAL32 / (INT32)RTVAL32); |
| 2624 | HIVAL64 = (INT32)((INT32)RSVAL32 % (INT32)RTVAL32); |
| 2625 | } |
| 2626 | m_core->icount -= 35; |
| 2627 | break; |
| 2628 | case 0x1b: /* DIVU */ |
| 2629 | if (RTVAL32) |
| 2630 | { |
| 2631 | LOVAL64 = (INT32)(RSVAL32 / RTVAL32); |
| 2632 | HIVAL64 = (INT32)(RSVAL32 % RTVAL32); |
| 2633 | } |
| 2634 | m_core->icount -= 35; |
| 2635 | break; |
| 2636 | case 0x1c: /* DMULT */ |
| 2637 | { |
| 2638 | UINT64 temp64 = (INT64)RSVAL64 * (INT64)RTVAL64; |
| 2639 | LOVAL64 = temp64; |
| 2640 | HIVAL64 = (INT64)temp64 >> 63; |
| 2641 | m_core->icount -= 7; |
| 2642 | break; |
| 2643 | } |
| 2644 | case 0x1d: /* DMULTU */ |
| 2645 | { |
| 2646 | UINT64 temp64 = (UINT64)RSVAL64 * (UINT64)RTVAL64; |
| 2647 | LOVAL64 = temp64; |
| 2648 | HIVAL64 = 0; |
| 2649 | m_core->icount -= 7; |
| 2650 | break; |
| 2651 | } |
| 2652 | case 0x1e: /* DDIV */ |
| 2653 | if (RTVAL64) |
| 2654 | { |
| 2655 | LOVAL64 = (INT64)RSVAL64 / (INT64)RTVAL64; |
| 2656 | HIVAL64 = (INT64)RSVAL64 % (INT64)RTVAL64; |
| 2657 | } |
| 2658 | m_core->icount -= 67; |
| 2659 | break; |
| 2660 | case 0x1f: /* DDIVU */ |
| 2661 | if (RTVAL64) |
| 2662 | { |
| 2663 | LOVAL64 = RSVAL64 / RTVAL64; |
| 2664 | HIVAL64 = RSVAL64 % RTVAL64; |
| 2665 | } |
| 2666 | m_core->icount -= 67; |
| 2667 | break; |
| 2668 | case 0x20: /* ADD */ |
| 2669 | if (ENABLE_OVERFLOWS && RSVAL32 > ~RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2670 | else if (RDREG) RDVAL64 = (INT32)(RSVAL32 + RTVAL32); |
| 2671 | break; |
| 2672 | case 0x21: /* ADDU */ if (RDREG) RDVAL64 = (INT32)(RSVAL32 + RTVAL32); break; |
| 2673 | case 0x22: /* SUB */ |
| 2674 | if (ENABLE_OVERFLOWS && RSVAL32 < RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2675 | else if (RDREG) RDVAL64 = (INT32)(RSVAL32 - RTVAL32); |
| 2676 | break; |
| 2677 | case 0x23: /* SUBU */ if (RDREG) RDVAL64 = (INT32)(RSVAL32 - RTVAL32); break; |
| 2678 | case 0x24: /* AND */ if (RDREG) RDVAL64 = RSVAL64 & RTVAL64; break; |
| 2679 | case 0x25: /* OR */ if (RDREG) RDVAL64 = RSVAL64 | RTVAL64; break; |
| 2680 | case 0x26: /* XOR */ if (RDREG) RDVAL64 = RSVAL64 ^ RTVAL64; break; |
| 2681 | case 0x27: /* NOR */ if (RDREG) RDVAL64 = ~(RSVAL64 | RTVAL64); break; |
| 2682 | case 0x2a: /* SLT */ if (RDREG) RDVAL64 = (INT64)RSVAL64 < (INT64)RTVAL64; break; |
| 2683 | case 0x2b: /* SLTU */ if (RDREG) RDVAL64 = (UINT64)RSVAL64 < (UINT64)RTVAL64; break; |
| 2684 | case 0x2c: /* DADD */ |
| 2685 | if (ENABLE_OVERFLOWS && RSVAL64 > ~RTVAL64) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2686 | else if (RDREG) RDVAL64 = RSVAL64 + RTVAL64; |
| 2687 | break; |
| 2688 | case 0x2d: /* DADDU */ if (RDREG) RDVAL64 = RSVAL64 + RTVAL64; break; |
| 2689 | case 0x2e: /* DSUB */ |
| 2690 | if (ENABLE_OVERFLOWS && RSVAL64 < RTVAL64) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2691 | else if (RDREG) RDVAL64 = RSVAL64 - RTVAL64; |
| 2692 | break; |
| 2693 | case 0x2f: /* DSUBU */ if (RDREG) RDVAL64 = RSVAL64 - RTVAL64; break; |
| 2694 | case 0x30: /* TGE */ if ((INT64)RSVAL64 >= (INT64)RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2695 | case 0x31: /* TGEU */ if (RSVAL64 >= RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2696 | case 0x32: /* TLT */ if ((INT64)RSVAL64 < (INT64)RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2697 | case 0x33: /* TLTU */ if (RSVAL64 < RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2698 | case 0x34: /* TEQ */ if (RSVAL64 == RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2699 | case 0x36: /* TNE */ if (RSVAL64 != RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2700 | case 0x38: /* DSLL */ if (RDREG) RDVAL64 = RTVAL64 << SHIFT; break; |
| 2701 | case 0x3a: /* DSRL */ if (RDREG) RDVAL64 = RTVAL64 >> SHIFT; break; |
| 2702 | case 0x3b: /* DSRA */ if (RDREG) RDVAL64 = (INT64)RTVAL64 >> SHIFT; break; |
| 2703 | case 0x3c: /* DSLL32 */ if (RDREG) RDVAL64 = RTVAL64 << (SHIFT + 32); break; |
| 2704 | case 0x3e: /* DSRL32 */ if (RDREG) RDVAL64 = RTVAL64 >> (SHIFT + 32); break; |
| 2705 | case 0x3f: /* DSRA32 */ if (RDREG) RDVAL64 = (INT64)RTVAL64 >> (SHIFT + 32); break; |
| 2706 | default: /* ??? */ invalid_instruction(op); break; |
| 2707 | } |
| 2708 | } |
| 2709 | |
| 2529 | 2710 | void mips3_device::execute_run() |
| 2530 | 2711 | { |
| 2531 | 2712 | if (m_isdrc) |
| r245293 | r245294 | |
| 2602 | 2783 | switch (op >> 26) |
| 2603 | 2784 | { |
| 2604 | 2785 | case 0x00: /* SPECIAL */ |
| 2605 | | switch (op & 63) |
| 2606 | | { |
| 2607 | | case 0x00: /* SLL */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 << SHIFT); break; |
| 2608 | | case 0x01: /* MOVF - R5000*/if (RDREG && GET_FCC((op >> 18) & 7) == ((op >> 16) & 1)) RDVAL64 = RSVAL64; break; |
| 2609 | | case 0x02: /* SRL */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 >> SHIFT); break; |
| 2610 | | case 0x03: /* SRA */ if (RDREG) RDVAL64 = (INT32)RTVAL32 >> SHIFT; break; |
| 2611 | | case 0x04: /* SLLV */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 << (RSVAL32 & 31)); break; |
| 2612 | | case 0x06: /* SRLV */ if (RDREG) RDVAL64 = (INT32)(RTVAL32 >> (RSVAL32 & 31)); break; |
| 2613 | | case 0x07: /* SRAV */ if (RDREG) RDVAL64 = (INT32)RTVAL32 >> (RSVAL32 & 31); break; |
| 2614 | | case 0x08: /* JR */ SETPC(RSVAL32); break; |
| 2615 | | case 0x09: /* JALR */ SETPCL(RSVAL32,RDREG); break; |
| 2616 | | case 0x0a: /* MOVZ - R5000 */if (RTVAL64 == 0) { if (RDREG) RDVAL64 = RSVAL64; } break; |
| 2617 | | case 0x0b: /* MOVN - R5000 */if (RTVAL64 != 0) { if (RDREG) RDVAL64 = RSVAL64; } break; |
| 2618 | | case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL, 1); break; |
| 2619 | | case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK, 1); break; |
| 2620 | | case 0x0f: /* SYNC */ /* effective no-op */ break; |
| 2621 | | case 0x10: /* MFHI */ if (RDREG) RDVAL64 = HIVAL64; break; |
| 2622 | | case 0x11: /* MTHI */ HIVAL64 = RSVAL64; break; |
| 2623 | | case 0x12: /* MFLO */ if (RDREG) RDVAL64 = LOVAL64; break; |
| 2624 | | case 0x13: /* MTLO */ LOVAL64 = RSVAL64; break; |
| 2625 | | case 0x14: /* DSLLV */ if (RDREG) RDVAL64 = RTVAL64 << (RSVAL32 & 63); break; |
| 2626 | | case 0x16: /* DSRLV */ if (RDREG) RDVAL64 = RTVAL64 >> (RSVAL32 & 63); break; |
| 2627 | | case 0x17: /* DSRAV */ if (RDREG) RDVAL64 = (INT64)RTVAL64 >> (RSVAL32 & 63); break; |
| 2628 | | case 0x18: /* MULT */ |
| 2629 | | temp64 = (INT64)(INT32)RSVAL32 * (INT64)(INT32)RTVAL32; |
| 2630 | | LOVAL64 = (INT32)temp64; |
| 2631 | | HIVAL64 = (INT32)(temp64 >> 32); |
| 2632 | | m_core->icount -= 3; |
| 2633 | | break; |
| 2634 | | case 0x19: /* MULTU */ |
| 2635 | | temp64 = (UINT64)RSVAL32 * (UINT64)RTVAL32; |
| 2636 | | LOVAL64 = (INT32)temp64; |
| 2637 | | HIVAL64 = (INT32)(temp64 >> 32); |
| 2638 | | m_core->icount -= 3; |
| 2639 | | break; |
| 2640 | | case 0x1a: /* DIV */ |
| 2641 | | if (RTVAL32) |
| 2642 | | { |
| 2643 | | LOVAL64 = (INT32)((INT32)RSVAL32 / (INT32)RTVAL32); |
| 2644 | | HIVAL64 = (INT32)((INT32)RSVAL32 % (INT32)RTVAL32); |
| 2645 | | } |
| 2646 | | else |
| 2647 | | { |
| 2648 | | handle_integer_divide_by_zero(op); |
| 2649 | | } |
| 2650 | | m_core->icount -= 35; |
| 2651 | | break; |
| 2652 | | case 0x1b: /* DIVU */ |
| 2653 | | if (RTVAL32) |
| 2654 | | { |
| 2655 | | LOVAL64 = (INT32)(RSVAL32 / RTVAL32); |
| 2656 | | HIVAL64 = (INT32)(RSVAL32 % RTVAL32); |
| 2657 | | } |
| 2658 | | else |
| 2659 | | { |
| 2660 | | handle_integer_divide_by_zero(op); |
| 2661 | | } |
| 2662 | | m_core->icount -= 35; |
| 2663 | | break; |
| 2664 | | case 0x1c: /* DMULT */ |
| 2665 | | temp64 = (INT64)RSVAL64 * (INT64)RTVAL64; |
| 2666 | | LOVAL64 = temp64; |
| 2667 | | HIVAL64 = (INT64)temp64 >> 63; |
| 2668 | | m_core->icount -= 7; |
| 2669 | | break; |
| 2670 | | case 0x1d: /* DMULTU */ |
| 2671 | | temp64 = (UINT64)RSVAL64 * (UINT64)RTVAL64; |
| 2672 | | LOVAL64 = temp64; |
| 2673 | | HIVAL64 = 0; |
| 2674 | | m_core->icount -= 7; |
| 2675 | | break; |
| 2676 | | case 0x1e: /* DDIV */ |
| 2677 | | if (RTVAL64) |
| 2678 | | { |
| 2679 | | LOVAL64 = (INT64)RSVAL64 / (INT64)RTVAL64; |
| 2680 | | HIVAL64 = (INT64)RSVAL64 % (INT64)RTVAL64; |
| 2681 | | } |
| 2682 | | m_core->icount -= 67; |
| 2683 | | break; |
| 2684 | | case 0x1f: /* DDIVU */ |
| 2685 | | if (RTVAL64) |
| 2686 | | { |
| 2687 | | LOVAL64 = RSVAL64 / RTVAL64; |
| 2688 | | HIVAL64 = RSVAL64 % RTVAL64; |
| 2689 | | } |
| 2690 | | m_core->icount -= 67; |
| 2691 | | break; |
| 2692 | | case 0x20: /* ADD */ |
| 2693 | | if (ENABLE_OVERFLOWS && RSVAL32 > ~RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2694 | | else if (RDREG) RDVAL64 = (INT32)(RSVAL32 + RTVAL32); |
| 2695 | | break; |
| 2696 | | case 0x21: /* ADDU */ if (RDREG) RDVAL64 = (INT32)(RSVAL32 + RTVAL32); break; |
| 2697 | | case 0x22: /* SUB */ |
| 2698 | | if (ENABLE_OVERFLOWS && RSVAL32 < RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2699 | | else if (RDREG) RDVAL64 = (INT32)(RSVAL32 - RTVAL32); |
| 2700 | | break; |
| 2701 | | case 0x23: /* SUBU */ if (RDREG) RDVAL64 = (INT32)(RSVAL32 - RTVAL32); break; |
| 2702 | | case 0x24: /* AND */ if (RDREG) RDVAL64 = RSVAL64 & RTVAL64; break; |
| 2703 | | case 0x25: /* OR */ if (RDREG) RDVAL64 = RSVAL64 | RTVAL64; break; |
| 2704 | | case 0x26: /* XOR */ if (RDREG) RDVAL64 = RSVAL64 ^ RTVAL64; break; |
| 2705 | | case 0x27: /* NOR */ if (RDREG) RDVAL64 = ~(RSVAL64 | RTVAL64); break; |
| 2706 | | case 0x2a: /* SLT */ if (RDREG) RDVAL64 = (INT64)RSVAL64 < (INT64)RTVAL64; break; |
| 2707 | | case 0x2b: /* SLTU */ if (RDREG) RDVAL64 = (UINT64)RSVAL64 < (UINT64)RTVAL64; break; |
| 2708 | | case 0x2c: /* DADD */ |
| 2709 | | if (ENABLE_OVERFLOWS && RSVAL64 > ~RTVAL64) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2710 | | else if (RDREG) RDVAL64 = RSVAL64 + RTVAL64; |
| 2711 | | break; |
| 2712 | | case 0x2d: /* DADDU */ if (RDREG) RDVAL64 = RSVAL64 + RTVAL64; break; |
| 2713 | | case 0x2e: /* DSUB */ |
| 2714 | | if (ENABLE_OVERFLOWS && RSVAL64 < RTVAL64) generate_exception(EXCEPTION_OVERFLOW, 1); |
| 2715 | | else if (RDREG) RDVAL64 = RSVAL64 - RTVAL64; |
| 2716 | | break; |
| 2717 | | case 0x2f: /* DSUBU */ if (RDREG) RDVAL64 = RSVAL64 - RTVAL64; break; |
| 2718 | | case 0x30: /* TGE */ if ((INT64)RSVAL64 >= (INT64)RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2719 | | case 0x31: /* TGEU */ if (RSVAL64 >= RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2720 | | case 0x32: /* TLT */ if ((INT64)RSVAL64 < (INT64)RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2721 | | case 0x33: /* TLTU */ if (RSVAL64 < RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2722 | | case 0x34: /* TEQ */ if (RSVAL64 == RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2723 | | case 0x36: /* TNE */ if (RSVAL64 != RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2724 | | case 0x38: /* DSLL */ if (RDREG) RDVAL64 = RTVAL64 << SHIFT; break; |
| 2725 | | case 0x3a: /* DSRL */ if (RDREG) RDVAL64 = RTVAL64 >> SHIFT; break; |
| 2726 | | case 0x3b: /* DSRA */ if (RDREG) RDVAL64 = (INT64)RTVAL64 >> SHIFT; break; |
| 2727 | | case 0x3c: /* DSLL32 */ if (RDREG) RDVAL64 = RTVAL64 << (SHIFT + 32); break; |
| 2728 | | case 0x3e: /* DSRL32 */ if (RDREG) RDVAL64 = RTVAL64 >> (SHIFT + 32); break; |
| 2729 | | case 0x3f: /* DSRA32 */ if (RDREG) RDVAL64 = (INT64)RTVAL64 >> (SHIFT + 32); break; |
| 2730 | | default: /* ??? */ invalid_instruction(op); break; |
| 2731 | | } |
| 2786 | handle_special(op); |
| 2732 | 2787 | break; |
| 2733 | 2788 | |
| 2734 | 2789 | case 0x01: /* REGIMM */ |
| 2735 | | switch (RTREG) |
| 2736 | | { |
| 2737 | | case 0x00: /* BLTZ */ if ((INT64)RSVAL64 < 0) ADDPC(SIMMVAL); break; |
| 2738 | | case 0x01: /* BGEZ */ if ((INT64)RSVAL64 >= 0) ADDPC(SIMMVAL); break; |
| 2739 | | case 0x02: /* BLTZL */ if ((INT64)RSVAL64 < 0) ADDPC(SIMMVAL); else m_core->pc += 4; break; |
| 2740 | | case 0x03: /* BGEZL */ if ((INT64)RSVAL64 >= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break; |
| 2741 | | case 0x08: /* TGEI */ if ((INT64)RSVAL64 >= SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2742 | | case 0x09: /* TGEIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2743 | | case 0x0a: /* TLTI */ if ((INT64)RSVAL64 < SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2744 | | case 0x0b: /* TLTIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2745 | | case 0x0c: /* TEQI */ if (RSVAL64 == UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2746 | | case 0x0e: /* TNEI */ if (RSVAL64 != UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break; |
| 2747 | | case 0x10: /* BLTZAL */ if ((INT64)RSVAL64 < 0) ADDPCL(SIMMVAL,31); break; |
| 2748 | | case 0x11: /* BGEZAL */ if ((INT64)RSVAL64 >= 0) ADDPCL(SIMMVAL,31); break; |
| 2749 | | case 0x12: /* BLTZALL */ if ((INT64)RSVAL64 < 0) ADDPCL(SIMMVAL,31) else m_core->pc += 4; break; |
| 2750 | | case 0x13: /* BGEZALL */ if ((INT64)RSVAL64 >= 0) ADDPCL(SIMMVAL,31) else m_core->pc += 4; break; |
| 2751 | | default: /* ??? */ invalid_instruction(op); break; |
| 2752 | | } |
| 2790 | handle_regimm(op); |
| 2753 | 2791 | break; |
| 2754 | 2792 | |
| 2755 | 2793 | case 0x02: /* J */ ABSPC(LIMMVAL); break; |
| r245293 | r245294 | |
| 2819 | 2857 | case 0x36: /* LDC2 */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop2_reg(RTREG, temp64); break; |
| 2820 | 2858 | case 0x37: /* LD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) RTVAL64 = temp64; break; |
| 2821 | 2859 | case 0x38: /* SC */ if (RWORD(SIMMVAL+RSVAL32, &temp) && RTREG) |
| 2822 | | { |
| 2823 | | if (temp == m_ll_value) |
| 2824 | | { |
| 2825 | | WWORD(SIMMVAL+RSVAL32, RTVAL32); |
| 2826 | | RTVAL64 = (UINT32)1; |
| 2827 | | } |
| 2828 | | else |
| 2829 | | { |
| 2830 | | RTVAL64 = (UINT32)0; |
| 2831 | | } |
| 2832 | | } |
| 2833 | | break; |
| 2860 | { |
| 2861 | if (temp == m_ll_value) |
| 2862 | { |
| 2863 | WWORD(SIMMVAL+RSVAL32, RTVAL32); |
| 2864 | RTVAL64 = (UINT32)1; |
| 2865 | } |
| 2866 | else |
| 2867 | { |
| 2868 | RTVAL64 = (UINT32)0; |
| 2869 | } |
| 2870 | } |
| 2871 | break; |
| 2834 | 2872 | case 0x39: /* SWC1 */ WWORD(SIMMVAL+RSVAL32, get_cop1_reg32(RTREG)); break; |
| 2835 | 2873 | case 0x3a: /* SWC2 */ WWORD(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break; |
| 2836 | 2874 | case 0x3b: /* SWC3 */ invalid_instruction(op); break; |
| 2837 | 2875 | case 0x3c: /* SCD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) |
| 2838 | | { |
| 2839 | | if (temp64 == m_lld_value) |
| 2840 | | { |
| 2841 | | WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); |
| 2842 | | RTVAL64 = 1; |
| 2843 | | } |
| 2844 | | else |
| 2845 | | { |
| 2846 | | RTVAL64 = 0; |
| 2847 | | } |
| 2848 | | } |
| 2849 | | break; |
| 2876 | { |
| 2877 | if (temp64 == m_lld_value) |
| 2878 | { |
| 2879 | WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); |
| 2880 | RTVAL64 = 1; |
| 2881 | } |
| 2882 | else |
| 2883 | { |
| 2884 | RTVAL64 = 0; |
| 2885 | } |
| 2886 | } |
| 2887 | break; |
| 2850 | 2888 | case 0x3d: /* SDC1 */ WDOUBLE(SIMMVAL+RSVAL32, get_cop1_reg64(RTREG)); break; |
| 2851 | 2889 | case 0x3e: /* SDC2 */ WDOUBLE(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break; |
| 2852 | 2890 | case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break; |
trunk/src/emu/cpu/mips/mips3drc.c
| r245293 | r245294 | |
| 160 | 160 | region |
| 161 | 161 | -------------------------------------------------*/ |
| 162 | 162 | |
| 163 | | void mips3_device::mips3drc_add_fastram(offs_t start, offs_t end, UINT8 readonly, void *base) |
| 163 | void mips3_device::add_fastram(offs_t start, offs_t end, UINT8 readonly, void *base) |
| 164 | 164 | { |
| 165 | | if (!machine().options().drc()) return; |
| 166 | 165 | if (m_fastram_select < ARRAY_LENGTH(m_fastram)) |
| 167 | 166 | { |
| 168 | 167 | m_fastram[m_fastram_select].start = start; |
| r245293 | r245294 | |
| 2054 | 2053 | return TRUE; |
| 2055 | 2054 | |
| 2056 | 2055 | case 0x1a: /* DIV - MIPS I */ |
| 2057 | | { |
| 2058 | | if (m_drcoptions & MIPS3DRC_ACCURATE_DIVZERO) |
| 2059 | | { |
| 2060 | | code_label divzero, done; |
| 2061 | | |
| 2062 | | UML_CMP(block, R32(RTREG), 0); // cmp <rtreg>, 0 |
| 2063 | | UML_JMPc(block, COND_E, divzero = compiler->labelnum++); // jmp divzero,E |
| 2064 | | |
| 2065 | | UML_DIVS(block, I0, I1, R32(RSREG), R32(RTREG)); // divs i0,i1,<rsreg>,<rtreg> |
| 2066 | | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2067 | | UML_DSEXT(block, HI64, I1, SIZE_DWORD); // dsext hi,i1,dword |
| 2068 | | UML_JMP(block, done = compiler->labelnum++); // jmp done |
| 2069 | | |
| 2070 | | UML_LABEL(block, divzero); // divzero: |
| 2071 | | if (m_flavor != MIPS3_TYPE_VR4300) |
| 2072 | | { |
| 2073 | | UML_MOVc(block, COND_L, I0, 0x00000001); // mov i0,0x00000001,L |
| 2074 | | UML_MOVc(block, COND_GE, I0, 0xffffffff); // mov i0,0xffffffff,GE |
| 2075 | | } |
| 2076 | | else |
| 2077 | | { |
| 2078 | | UML_MOVc(block, COND_L, I0, 0x80000001); // mov i0,0x80000001,L |
| 2079 | | UML_MOVc(block, COND_GE, I0, 0x7fffffff); // mov i0,0x7fffffff,GE |
| 2080 | | } |
| 2081 | | UML_DSEXT(block, HI64, R32(RSREG), SIZE_DWORD); // dsext hi,<rsreg>,dword |
| 2082 | | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2083 | | |
| 2084 | | UML_LABEL(block, done); // done: |
| 2085 | | } |
| 2086 | | else |
| 2087 | | { |
| 2088 | | UML_DIVS(block, I0, I1, R32(RSREG), R32(RTREG)); // divs i0,i1,<rsreg>,<rtreg> |
| 2089 | | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2090 | | UML_DSEXT(block, HI64, I1, SIZE_DWORD); // dsext hi,i1,dword |
| 2091 | | } |
| 2056 | UML_DIVS(block, I0, I1, R32(RSREG), R32(RTREG)); // divs i0,i1,<rsreg>,<rtreg> |
| 2057 | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2058 | UML_DSEXT(block, HI64, I1, SIZE_DWORD); // dsext hi,i1,dword |
| 2092 | 2059 | return TRUE; |
| 2093 | | } |
| 2094 | 2060 | |
| 2095 | 2061 | case 0x1b: /* DIVU - MIPS I */ |
| 2096 | | if (m_drcoptions & MIPS3DRC_ACCURATE_DIVZERO) |
| 2097 | | { |
| 2098 | | code_label divzero, done; |
| 2099 | | |
| 2100 | | UML_CMP(block, R32(RTREG), 0); // cmp <rtreg>, 0 |
| 2101 | | UML_JMPc(block, COND_E, divzero = compiler->labelnum++); // jmp divzero,E |
| 2102 | | |
| 2103 | | UML_DIVU(block, I0, I1, R32(RSREG), R32(RTREG)); // divu i0,i1,<rsreg>,<rtreg> |
| 2104 | | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2105 | | UML_DSEXT(block, HI64, I1, SIZE_DWORD); // dsext hi,i1,dword |
| 2106 | | UML_JMP(block, done = compiler->labelnum++); // jmp done |
| 2107 | | |
| 2108 | | UML_LABEL(block, divzero); // divzero: |
| 2109 | | if (m_flavor != MIPS3_TYPE_VR4300) |
| 2110 | | { |
| 2111 | | UML_MOVc(block, COND_L, I0, 0x00000001); // mov i0,0x00000001,L |
| 2112 | | UML_MOVc(block, COND_GE, I0, 0xffffffff); // mov i0,0xffffffff,GE |
| 2113 | | } |
| 2114 | | else |
| 2115 | | { |
| 2116 | | UML_MOVc(block, COND_L, I0, 0x80000001); // mov i0,0x80000001,L |
| 2117 | | UML_MOVc(block, COND_GE, I0, 0x7fffffff); // mov i0,0x7fffffff,GE |
| 2118 | | } |
| 2119 | | UML_DSEXT(block, HI64, R32(RSREG), SIZE_DWORD); // dsext hi,<rsreg>,dword |
| 2120 | | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2121 | | |
| 2122 | | UML_LABEL(block, done); // done: |
| 2123 | | } |
| 2124 | | else |
| 2125 | | { |
| 2126 | | UML_DIVU(block, I0, I1, R32(RSREG), R32(RTREG)); // divu i0,i1,<rsreg>,<rtreg> |
| 2127 | | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2128 | | UML_DSEXT(block, HI64, I1, SIZE_DWORD); // dsext hi,i1,dword |
| 2129 | | } |
| 2062 | UML_DIVU(block, I0, I1, R32(RSREG), R32(RTREG)); // divu i0,i1,<rsreg>,<rtreg> |
| 2063 | UML_DSEXT(block, LO64, I0, SIZE_DWORD); // dsext lo,i0,dword |
| 2064 | UML_DSEXT(block, HI64, I1, SIZE_DWORD); // dsext hi,i1,dword |
| 2130 | 2065 | return TRUE; |
| 2131 | 2066 | |
| 2132 | 2067 | case 0x1e: /* DDIV - MIPS III */ |
trunk/src/mame/drivers/cps2.c
| r245293 | r245294 | |
| 6787 | 6787 | |
| 6788 | 6788 | ROM_START( spf2t ) |
| 6789 | 6789 | ROM_REGION(CODE_SIZE, "maincpu", 0 ) /* 68000 code */ |
| 6790 | ROM_LOAD16_WORD_SWAP( "pzfe.03", 0x000000, 0x80000, CRC(2af51954) SHA1(51f8797918391e772cf3cc27074ed6ca419806bd) ) |
| 6791 | ROM_LOAD16_WORD_SWAP( "pzf.04", 0x080000, 0x80000, CRC(b80649e2) SHA1(5bfccd656aea7ff82e9a20bb5856f4ab99b5a007) ) // marked pzfe.04 but same as pzf.04 |
| 6792 | |
| 6793 | ROM_REGION( 0xC00000, "gfx", 0 ) |
| 6794 | ROM_FILL( 0x000000, 0x800000, 0 ) |
| 6795 | ROMX_LOAD( "pzf.14m", 0x800000, 0x100000, CRC(2d4881cb) SHA1(fd3baa183c25bed153b19c251980e2fb761600e2) , ROM_GROUPWORD | ROM_SKIP(6) ) |
| 6796 | ROMX_LOAD( "pzf.16m", 0x800002, 0x100000, CRC(4b0fd1be) SHA1(377aafdcdb7a866b1c8487670e3598d8197976e4) , ROM_GROUPWORD | ROM_SKIP(6) ) |
| 6797 | ROMX_LOAD( "pzf.18m", 0x800004, 0x100000, CRC(e43aac33) SHA1(d041e0688c3807d3363861a7f216de43b34d846c) , ROM_GROUPWORD | ROM_SKIP(6) ) |
| 6798 | ROMX_LOAD( "pzf.20m", 0x800006, 0x100000, CRC(7f536ff1) SHA1(905b9d62ef7bef47297c7f4a4dd697aed6df38a5) , ROM_GROUPWORD | ROM_SKIP(6) ) |
| 6799 | |
| 6800 | ROM_REGION(QSOUND_SIZE, "audiocpu", 0 ) /* 64k for the audio CPU (+banks) */ |
| 6801 | ROM_LOAD( "pzf.01", 0x00000, 0x08000, CRC(600fb2a3) SHA1(1fab1c2a23bf6ad8309d29ddbbc29435a8aeea13) ) |
| 6802 | ROM_CONTINUE( 0x10000, 0x18000 ) |
| 6803 | ROM_LOAD( "pzf.02", 0x28000, 0x20000, CRC(496076e0) SHA1(1ee4e135140afd0e8e03231e570cd77d140f6367) ) |
| 6804 | |
| 6805 | ROM_REGION( 0x400000, "qsound", 0 ) /* QSound samples */ |
| 6806 | ROM_LOAD16_WORD_SWAP( "pzf.11m", 0x000000, 0x200000, CRC(78442743) SHA1(b61190bb586871de6d54af580e3e1d9cc0de0acb) ) |
| 6807 | ROM_LOAD16_WORD_SWAP( "pzf.12m", 0x200000, 0x200000, CRC(399d2c7b) SHA1(e849dea97b8d16540415c0d9bbc4f9f4eb755ec4) ) |
| 6808 | ROM_END |
| 6809 | |
| 6810 | ROM_START( spf2tu ) |
| 6811 | ROM_REGION(CODE_SIZE, "maincpu", 0 ) /* 68000 code */ |
| 6790 | 6812 | ROM_LOAD16_WORD_SWAP( "pzfu.03a", 0x000000, 0x80000, CRC(346e62ef) SHA1(9db5ea0aac2d459be957f8b6e2e0d18421587d4d) ) |
| 6791 | 6813 | ROM_LOAD16_WORD_SWAP( "pzf.04", 0x080000, 0x80000, CRC(b80649e2) SHA1(5bfccd656aea7ff82e9a20bb5856f4ab99b5a007) ) |
| 6792 | 6814 | |
| r245293 | r245294 | |
| 6807 | 6829 | ROM_LOAD16_WORD_SWAP( "pzf.12m", 0x200000, 0x200000, CRC(399d2c7b) SHA1(e849dea97b8d16540415c0d9bbc4f9f4eb755ec4) ) |
| 6808 | 6830 | ROM_END |
| 6809 | 6831 | |
| 6832 | |
| 6810 | 6833 | ROM_START( spf2xj ) |
| 6811 | 6834 | ROM_REGION(CODE_SIZE, "maincpu", 0 ) /* 68000 code */ |
| 6812 | 6835 | ROM_LOAD16_WORD_SWAP( "pzfj.03a", 0x000000, 0x80000, CRC(2070554a) SHA1(fa818e6bd2e11667345d3d8f2397b60802ef72f9) ) |
| r245293 | r245294 | |
| 8804 | 8827 | GAME( 1996, sfz2alj, sfz2al, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Street Fighter Zero 2 Alpha (Japan 960805)", GAME_SUPPORTS_SAVE ) |
| 8805 | 8828 | GAME( 1996, sfz2alh, sfz2al, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Street Fighter Zero 2 Alpha (Hispanic 960813)", GAME_SUPPORTS_SAVE ) |
| 8806 | 8829 | GAME( 1996, sfz2alb, sfz2al, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Street Fighter Zero 2 Alpha (Brazil 960813)", GAME_SUPPORTS_SAVE ) |
| 8807 | | GAME( 1996, spf2t, 0, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (USA 960620)", GAME_SUPPORTS_SAVE ) |
| 8830 | GAME( 1996, spf2t, 0, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (Euro 960529)", GAME_SUPPORTS_SAVE ) |
| 8831 | GAME( 1996, spf2tu, spf2t, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (USA 960620)", GAME_SUPPORTS_SAVE ) |
| 8808 | 8832 | GAME( 1996, spf2xj, spf2t, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II X (Japan 960531)", GAME_SUPPORTS_SAVE ) |
| 8809 | 8833 | GAME( 1996, spf2ta, spf2t, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (Asia 960529)", GAME_SUPPORTS_SAVE ) |
| 8810 | 8834 | GAME( 1996, spf2th, spf2t, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (Hispanic 960531)", GAME_SUPPORTS_SAVE ) |