trunk/src/emu/cpu/mips/mips3.c
| r245291 | r245292 | |
| 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)) |
| 153 | 151 | , c_icache_size(0) |
| 154 | 152 | , c_dcache_size(0) |
| 155 | 153 | , m_vtlb(NULL) |
| 156 | | , m_fastram_select(0) |
| 157 | 154 | , m_debugger_temp(0) |
| 158 | 155 | , m_cache(CACHE_SIZE + sizeof(internal_mips3_state)) |
| 159 | 156 | , m_drcuml(NULL) |
| r245291 | r245292 | |
| 164 | 161 | , m_nocode(NULL) |
| 165 | 162 | , m_out_of_cycles(NULL) |
| 166 | 163 | , m_tlb_mismatch(NULL) |
| 164 | , m_fastram_select(0) |
| 167 | 165 | , m_hotspot_select(0) |
| 168 | 166 | { |
| 169 | 167 | memset(m_fpmode, 0, sizeof(m_fpmode)); |
| r245291 | r245292 | |
| 998 | 996 | TLB HANDLING |
| 999 | 997 | ***************************************************************************/ |
| 1000 | 998 | |
| 1001 | | bool mips3_device::RBYTE(offs_t address, UINT32 *result) |
| 999 | inline int mips3_device::RBYTE(offs_t address, UINT32 *result) |
| 1002 | 1000 | { |
| 1003 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1001 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1004 | 1002 | if (tlbval & VTLB_READ_ALLOWED) |
| 1005 | 1003 | { |
| 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); |
| 1004 | *result = (*m_memory.read_byte)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| 1018 | 1005 | } |
| 1019 | 1006 | else |
| 1020 | 1007 | { |
| r245291 | r245292 | |
| 1027 | 1014 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1028 | 1015 | } |
| 1029 | 1016 | *result = 0; |
| 1030 | | return false; |
| 1017 | return 0; |
| 1031 | 1018 | } |
| 1032 | | return true; |
| 1019 | return 1; |
| 1033 | 1020 | } |
| 1034 | 1021 | |
| 1035 | | bool mips3_device::RHALF(offs_t address, UINT32 *result) |
| 1022 | |
| 1023 | inline int mips3_device::RHALF(offs_t address, UINT32 *result) |
| 1036 | 1024 | { |
| 1037 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1025 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1038 | 1026 | if (tlbval & VTLB_READ_ALLOWED) |
| 1039 | 1027 | { |
| 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); |
| 1028 | *result = (*m_memory.read_word)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| 1052 | 1029 | } |
| 1053 | 1030 | else |
| 1054 | 1031 | { |
| r245291 | r245292 | |
| 1061 | 1038 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1062 | 1039 | } |
| 1063 | 1040 | *result = 0; |
| 1064 | | return false; |
| 1041 | return 0; |
| 1065 | 1042 | } |
| 1066 | | return true; |
| 1043 | return 1; |
| 1067 | 1044 | } |
| 1068 | 1045 | |
| 1069 | | bool mips3_device::RWORD(offs_t address, UINT32 *result) |
| 1046 | |
| 1047 | inline int mips3_device::RWORD(offs_t address, UINT32 *result) |
| 1070 | 1048 | { |
| 1071 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1049 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1072 | 1050 | if (tlbval & VTLB_READ_ALLOWED) |
| 1073 | 1051 | { |
| 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); |
| 1052 | *result = (*m_memory.read_dword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| 1086 | 1053 | } |
| 1087 | 1054 | else |
| 1088 | 1055 | { |
| r245291 | r245292 | |
| 1095 | 1062 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1096 | 1063 | } |
| 1097 | 1064 | *result = 0; |
| 1098 | | return false; |
| 1065 | return 0; |
| 1099 | 1066 | } |
| 1100 | | return true; |
| 1067 | return 1; |
| 1101 | 1068 | } |
| 1102 | 1069 | |
| 1103 | | bool mips3_device::RWORD_MASKED(offs_t address, UINT32 *result, UINT32 mem_mask) |
| 1070 | |
| 1071 | inline int mips3_device::RWORD_MASKED(offs_t address, UINT32 *result, UINT32 mem_mask) |
| 1104 | 1072 | { |
| 1105 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1073 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1106 | 1074 | if (tlbval & VTLB_READ_ALLOWED) |
| 1107 | 1075 | { |
| 1108 | 1076 | *result = (*m_memory.read_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask); |
| r245291 | r245292 | |
| 1118 | 1086 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1119 | 1087 | } |
| 1120 | 1088 | *result = 0; |
| 1121 | | return false; |
| 1089 | return 0; |
| 1122 | 1090 | } |
| 1123 | | return true; |
| 1091 | return 1; |
| 1124 | 1092 | } |
| 1125 | 1093 | |
| 1126 | | bool mips3_device::RDOUBLE(offs_t address, UINT64 *result) |
| 1094 | |
| 1095 | inline int mips3_device::RDOUBLE(offs_t address, UINT64 *result) |
| 1127 | 1096 | { |
| 1128 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1097 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1129 | 1098 | if (tlbval & VTLB_READ_ALLOWED) |
| 1130 | 1099 | { |
| 1131 | 1100 | *result = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); |
| r245291 | r245292 | |
| 1141 | 1110 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1142 | 1111 | } |
| 1143 | 1112 | *result = 0; |
| 1144 | | return false; |
| 1113 | return 0; |
| 1145 | 1114 | } |
| 1146 | | return true; |
| 1115 | return 1; |
| 1147 | 1116 | } |
| 1148 | 1117 | |
| 1149 | | bool mips3_device::RDOUBLE_MASKED(offs_t address, UINT64 *result, UINT64 mem_mask) |
| 1118 | |
| 1119 | inline int mips3_device::RDOUBLE_MASKED(offs_t address, UINT64 *result, UINT64 mem_mask) |
| 1150 | 1120 | { |
| 1151 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1121 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1152 | 1122 | if (tlbval & VTLB_READ_ALLOWED) |
| 1153 | 1123 | { |
| 1154 | 1124 | *result = (*m_memory.read_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask); |
| r245291 | r245292 | |
| 1164 | 1134 | generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); |
| 1165 | 1135 | } |
| 1166 | 1136 | *result = 0; |
| 1167 | | return false; |
| 1137 | return 0; |
| 1168 | 1138 | } |
| 1169 | | return true; |
| 1139 | return 1; |
| 1170 | 1140 | } |
| 1171 | 1141 | |
| 1172 | | void mips3_device::WBYTE(offs_t address, UINT8 data) |
| 1142 | |
| 1143 | inline void mips3_device::WBYTE(offs_t address, UINT8 data) |
| 1173 | 1144 | { |
| 1174 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1145 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1175 | 1146 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1176 | 1147 | { |
| 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); |
| 1148 | (*m_memory.write_byte)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1189 | 1149 | } |
| 1190 | 1150 | else |
| 1191 | 1151 | { |
| r245291 | r245292 | |
| 1204 | 1164 | } |
| 1205 | 1165 | } |
| 1206 | 1166 | |
| 1207 | | void mips3_device::WHALF(offs_t address, UINT16 data) |
| 1167 | |
| 1168 | inline void mips3_device::WHALF(offs_t address, UINT16 data) |
| 1208 | 1169 | { |
| 1209 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1170 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1210 | 1171 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1211 | 1172 | { |
| 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); |
| 1173 | (*m_memory.write_word)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1224 | 1174 | } |
| 1225 | 1175 | else |
| 1226 | 1176 | { |
| r245291 | r245292 | |
| 1239 | 1189 | } |
| 1240 | 1190 | } |
| 1241 | 1191 | |
| 1242 | | void mips3_device::WWORD(offs_t address, UINT32 data) |
| 1192 | |
| 1193 | inline void mips3_device::WWORD(offs_t address, UINT32 data) |
| 1243 | 1194 | { |
| 1244 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1195 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1245 | 1196 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1246 | 1197 | { |
| 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); |
| 1198 | (*m_memory.write_dword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1259 | 1199 | } |
| 1260 | 1200 | else |
| 1261 | 1201 | { |
| r245291 | r245292 | |
| 1274 | 1214 | } |
| 1275 | 1215 | } |
| 1276 | 1216 | |
| 1277 | | void mips3_device::WWORD_MASKED(offs_t address, UINT32 data, UINT32 mem_mask) |
| 1217 | |
| 1218 | inline void mips3_device::WWORD_MASKED(offs_t address, UINT32 data, UINT32 mem_mask) |
| 1278 | 1219 | { |
| 1279 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1220 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1280 | 1221 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1281 | 1222 | { |
| 1282 | 1223 | (*m_memory.write_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask); |
| r245291 | r245292 | |
| 1298 | 1239 | } |
| 1299 | 1240 | } |
| 1300 | 1241 | |
| 1301 | | void mips3_device::WDOUBLE(offs_t address, UINT64 data) |
| 1242 | |
| 1243 | inline void mips3_device::WDOUBLE(offs_t address, UINT64 data) |
| 1302 | 1244 | { |
| 1303 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1245 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1246 | //printf("%08x: %08x\n", (UINT32)address, (UINT32)tlbval); |
| 1304 | 1247 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1305 | 1248 | { |
| 1306 | | (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1249 | (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); |
| 1307 | 1250 | } |
| 1308 | 1251 | else |
| 1309 | 1252 | { |
| r245291 | r245292 | |
| 1322 | 1265 | } |
| 1323 | 1266 | } |
| 1324 | 1267 | |
| 1325 | | void mips3_device::WDOUBLE_MASKED(offs_t address, UINT64 data, UINT64 mem_mask) |
| 1268 | |
| 1269 | inline void mips3_device::WDOUBLE_MASKED(offs_t address, UINT64 data, UINT64 mem_mask) |
| 1326 | 1270 | { |
| 1327 | | const UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1271 | UINT32 tlbval = m_tlb_table[address >> 12]; |
| 1328 | 1272 | if (tlbval & VTLB_WRITE_ALLOWED) |
| 1329 | 1273 | { |
| 1330 | 1274 | (*m_memory.write_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask); |
| r245291 | r245292 | |
| 1352 | 1296 | COP0 (SYSTEM) EXECUTION HANDLING |
| 1353 | 1297 | ***************************************************************************/ |
| 1354 | 1298 | |
| 1355 | | UINT64 mips3_device::get_cop0_reg(int idx) |
| 1299 | inline UINT64 mips3_device::get_cop0_reg(int idx) |
| 1356 | 1300 | { |
| 1357 | 1301 | if (idx == COP0_Count) |
| 1358 | 1302 | { |
| r245291 | r245292 | |
| 1385 | 1329 | return m_core->cpr[0][idx]; |
| 1386 | 1330 | } |
| 1387 | 1331 | |
| 1388 | | void mips3_device::set_cop0_reg(int idx, UINT64 val) |
| 1332 | inline void mips3_device::set_cop0_reg(int idx, UINT64 val) |
| 1389 | 1333 | { |
| 1390 | 1334 | switch (idx) |
| 1391 | 1335 | { |
| r245291 | r245292 | |
| 1462 | 1406 | m_core->ccr[0][idx] = val; |
| 1463 | 1407 | } |
| 1464 | 1408 | |
| 1465 | | void mips3_device::handle_cop0(UINT32 op) |
| 1409 | inline void mips3_device::handle_cop0(UINT32 op) |
| 1466 | 1410 | { |
| 1467 | 1411 | if ((SR & SR_KSU_MASK) != SR_KSU_KERNEL && !(SR & SR_COP0)) |
| 1468 | 1412 | { |
| r245291 | r245292 | |
| 1597 | 1541 | } |
| 1598 | 1542 | } |
| 1599 | 1543 | |
| 1600 | | void mips3_device::handle_cop1_fr0(UINT32 op) |
| 1544 | inline void mips3_device::handle_cop1_fr0(UINT32 op) |
| 1601 | 1545 | { |
| 1602 | 1546 | double dtemp; |
| 1603 | 1547 | |
| r245291 | r245292 | |
| 1956 | 1900 | } |
| 1957 | 1901 | |
| 1958 | 1902 | |
| 1959 | | void mips3_device::handle_cop1_fr1(UINT32 op) |
| 1903 | inline void mips3_device::handle_cop1_fr1(UINT32 op) |
| 1960 | 1904 | { |
| 1961 | 1905 | double dtemp; |
| 1962 | 1906 | |
| r245291 | r245292 | |
| 2320 | 2264 | COP1X (FPU EXTRA) EXECUTION HANDLING |
| 2321 | 2265 | ***************************************************************************/ |
| 2322 | 2266 | |
| 2323 | | void mips3_device::handle_cop1x_fr0(UINT32 op) |
| 2267 | inline void mips3_device::handle_cop1x_fr0(UINT32 op) |
| 2324 | 2268 | { |
| 2325 | 2269 | UINT64 temp64; |
| 2326 | 2270 | UINT32 temp; |
| r245291 | r245292 | |
| 2398 | 2342 | } |
| 2399 | 2343 | } |
| 2400 | 2344 | |
| 2401 | | void mips3_device::handle_cop1x_fr1(UINT32 op) |
| 2345 | |
| 2346 | inline void mips3_device::handle_cop1x_fr1(UINT32 op) |
| 2402 | 2347 | { |
| 2403 | 2348 | UINT64 temp64; |
| 2404 | 2349 | UINT32 temp; |
| r245291 | r245292 | |
| 2502 | 2447 | m_core->ccr[2][idx] = val; |
| 2503 | 2448 | } |
| 2504 | 2449 | |
| 2505 | | void mips3_device::handle_cop2(UINT32 op) |
| 2450 | inline void mips3_device::handle_integer_divide_by_zero(UINT32 op) |
| 2506 | 2451 | { |
| 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 | { |
| 2507 | 2479 | if (!(SR & SR_COP2)) |
| 2508 | 2480 | { |
| 2509 | 2481 | m_badcop_value = 2; |
| r245291 | r245292 | |
| 2554 | 2526 | CORE EXECUTION LOOP |
| 2555 | 2527 | ***************************************************************************/ |
| 2556 | 2528 | |
| 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 | | |
| 2710 | 2529 | void mips3_device::execute_run() |
| 2711 | 2530 | { |
| 2712 | 2531 | if (m_isdrc) |
| r245291 | r245292 | |
| 2783 | 2602 | switch (op >> 26) |
| 2784 | 2603 | { |
| 2785 | 2604 | case 0x00: /* SPECIAL */ |
| 2786 | | handle_special(op); |
| 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 | } |
| 2787 | 2732 | break; |
| 2788 | 2733 | |
| 2789 | 2734 | case 0x01: /* REGIMM */ |
| 2790 | | handle_regimm(op); |
| 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 | } |
| 2791 | 2753 | break; |
| 2792 | 2754 | |
| 2793 | 2755 | case 0x02: /* J */ ABSPC(LIMMVAL); break; |
| r245291 | r245292 | |
| 2857 | 2819 | case 0x36: /* LDC2 */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop2_reg(RTREG, temp64); break; |
| 2858 | 2820 | case 0x37: /* LD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) RTVAL64 = temp64; break; |
| 2859 | 2821 | case 0x38: /* SC */ if (RWORD(SIMMVAL+RSVAL32, &temp) && RTREG) |
| 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; |
| 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; |
| 2872 | 2834 | case 0x39: /* SWC1 */ WWORD(SIMMVAL+RSVAL32, get_cop1_reg32(RTREG)); break; |
| 2873 | 2835 | case 0x3a: /* SWC2 */ WWORD(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break; |
| 2874 | 2836 | case 0x3b: /* SWC3 */ invalid_instruction(op); break; |
| 2875 | 2837 | case 0x3c: /* SCD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) |
| 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; |
| 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; |
| 2888 | 2850 | case 0x3d: /* SDC1 */ WDOUBLE(SIMMVAL+RSVAL32, get_cop1_reg64(RTREG)); break; |
| 2889 | 2851 | case 0x3e: /* SDC2 */ WDOUBLE(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break; |
| 2890 | 2852 | case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break; |
trunk/src/emu/cpu/mips/mips3drc.c
| r245291 | r245292 | |
| 160 | 160 | region |
| 161 | 161 | -------------------------------------------------*/ |
| 162 | 162 | |
| 163 | | void mips3_device::add_fastram(offs_t start, offs_t end, UINT8 readonly, void *base) |
| 163 | void mips3_device::mips3drc_add_fastram(offs_t start, offs_t end, UINT8 readonly, void *base) |
| 164 | 164 | { |
| 165 | if (!machine().options().drc()) return; |
| 165 | 166 | if (m_fastram_select < ARRAY_LENGTH(m_fastram)) |
| 166 | 167 | { |
| 167 | 168 | m_fastram[m_fastram_select].start = start; |
| r245291 | r245292 | |
| 2053 | 2054 | return TRUE; |
| 2054 | 2055 | |
| 2055 | 2056 | case 0x1a: /* DIV - MIPS I */ |
| 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 |
| 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 | } |
| 2059 | 2092 | return TRUE; |
| 2093 | } |
| 2060 | 2094 | |
| 2061 | 2095 | case 0x1b: /* DIVU - MIPS I */ |
| 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 |
| 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 | } |
| 2065 | 2130 | return TRUE; |
| 2066 | 2131 | |
| 2067 | 2132 | case 0x1e: /* DDIV - MIPS III */ |
trunk/src/mame/drivers/cps2.c
| r245291 | r245292 | |
| 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 */ |
| 6812 | 6790 | ROM_LOAD16_WORD_SWAP( "pzfu.03a", 0x000000, 0x80000, CRC(346e62ef) SHA1(9db5ea0aac2d459be957f8b6e2e0d18421587d4d) ) |
| 6813 | 6791 | ROM_LOAD16_WORD_SWAP( "pzf.04", 0x080000, 0x80000, CRC(b80649e2) SHA1(5bfccd656aea7ff82e9a20bb5856f4ab99b5a007) ) |
| 6814 | 6792 | |
| r245291 | r245292 | |
| 6829 | 6807 | ROM_LOAD16_WORD_SWAP( "pzf.12m", 0x200000, 0x200000, CRC(399d2c7b) SHA1(e849dea97b8d16540415c0d9bbc4f9f4eb755ec4) ) |
| 6830 | 6808 | ROM_END |
| 6831 | 6809 | |
| 6832 | | |
| 6833 | 6810 | ROM_START( spf2xj ) |
| 6834 | 6811 | ROM_REGION(CODE_SIZE, "maincpu", 0 ) /* 68000 code */ |
| 6835 | 6812 | ROM_LOAD16_WORD_SWAP( "pzfj.03a", 0x000000, 0x80000, CRC(2070554a) SHA1(fa818e6bd2e11667345d3d8f2397b60802ef72f9) ) |
| r245291 | r245292 | |
| 8827 | 8804 | GAME( 1996, sfz2alj, sfz2al, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Street Fighter Zero 2 Alpha (Japan 960805)", GAME_SUPPORTS_SAVE ) |
| 8828 | 8805 | GAME( 1996, sfz2alh, sfz2al, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Street Fighter Zero 2 Alpha (Hispanic 960813)", GAME_SUPPORTS_SAVE ) |
| 8829 | 8806 | GAME( 1996, sfz2alb, sfz2al, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Street Fighter Zero 2 Alpha (Brazil 960813)", 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 ) |
| 8807 | GAME( 1996, spf2t, 0, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (USA 960620)", GAME_SUPPORTS_SAVE ) |
| 8832 | 8808 | GAME( 1996, spf2xj, spf2t, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II X (Japan 960531)", GAME_SUPPORTS_SAVE ) |
| 8833 | 8809 | GAME( 1996, spf2ta, spf2t, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (Asia 960529)", GAME_SUPPORTS_SAVE ) |
| 8834 | 8810 | GAME( 1996, spf2th, spf2t, cps2, cps2_2p2b, cps_state, cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (Hispanic 960531)", GAME_SUPPORTS_SAVE ) |