comparison 68kinst.c @ 1463:63f309cfbef9

Fix what are hopefully th elast of the 68K instruction decoder bugs revealed by r57shell/realmonster's test ROM
author Michael Pavone <pavone@retrodev.com>
date Fri, 08 Sep 2017 00:38:10 -0700
parents d276ec2fff11
children dc1eab3ec092
comparison
equal deleted inserted replaced
1462:d276ec2fff11 1463:63f309cfbef9
393 reg = *istream & 0x7; 393 reg = *istream & 0x7;
394 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; 394 decoded->src.addr_mode = MODE_IMMEDIATE_WORD;
395 decoded->src.params.immed = *(++istream) & 0xFF; 395 decoded->src.params.immed = *(++istream) & 0xFF;
396 decoded->extra.size = OPSIZE_BYTE; 396 decoded->extra.size = OPSIZE_BYTE;
397 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 397 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
398 if (!istream || !m68k_valid_immed_dst(&decoded->dst)) { 398 if (
399 !istream || !m68k_valid_immed_dst(&decoded->dst)
400 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst))
401 ) {
399 decoded->op = M68K_INVALID; 402 decoded->op = M68K_INVALID;
400 break; 403 break;
401 } 404 }
402 if (decoded->dst.addr_mode == MODE_REG) { 405 if (decoded->dst.addr_mode == MODE_REG) {
403 decoded->extra.size = OPSIZE_LONG; 406 decoded->extra.size = OPSIZE_LONG;
627 immed = *(++istream); 630 immed = *(++istream);
628 decoded->src.params.immed = (immed << 16) | *(++istream); 631 decoded->src.params.immed = (immed << 16) | *(++istream);
629 break; 632 break;
630 } 633 }
631 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 634 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
632 if (!istream || !m68k_valid_immed_dst(&(decoded->dst))) { 635 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
633 decoded->op = M68K_INVALID; 636 decoded->op = M68K_INVALID;
634 break; 637 break;
635 } 638 }
636 break; 639 break;
637 case 7: 640 case 7:
895 } else { 898 } else {
896 if (size == OPSIZE_INVALID) { 899 if (size == OPSIZE_INVALID) {
897 decoded->op = M68K_TAS; 900 decoded->op = M68K_TAS;
898 decoded->extra.size = OPSIZE_BYTE; 901 decoded->extra.size = OPSIZE_BYTE;
899 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); 902 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst));
900 if (!istream) { 903 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) {
901 decoded->op = M68K_INVALID; 904 decoded->op = M68K_INVALID;
902 break; 905 break;
903 } 906 }
904 } else { 907 } else {
905 decoded->op = M68K_TST; 908 decoded->op = M68K_TST;
1196 decoded->extra.size = size; 1199 decoded->extra.size = size;
1197 if (opmode & 0x4) { 1200 if (opmode & 0x4) {
1198 decoded->src.addr_mode = MODE_REG; 1201 decoded->src.addr_mode = MODE_REG;
1199 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; 1202 decoded->src.params.regs.pri = (*istream >> 9) & 0x7;
1200 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1203 istream = m68k_decode_op(istream, size, &(decoded->dst));
1201 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 1204 if (!istream || !m68k_valid_full_arith_dst(&(decoded->dst))) {
1202 decoded->op = M68K_INVALID; 1205 decoded->op = M68K_INVALID;
1203 break; 1206 break;
1204 } 1207 }
1205 } else { 1208 } else {
1206 decoded->dst.addr_mode = MODE_REG; 1209 decoded->dst.addr_mode = MODE_REG;
1317 decoded->extra.size = size; 1320 decoded->extra.size = size;
1318 decoded->dst.addr_mode = MODE_REG; 1321 decoded->dst.addr_mode = MODE_REG;
1319 } 1322 }
1320 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1323 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1321 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1324 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
1322 if (!istream) { 1325 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) {
1323 decoded->op = M68K_INVALID; 1326 decoded->op = M68K_INVALID;
1324 break; 1327 break;
1325 } 1328 }
1326 } 1329 }
1327 break; 1330 break;
1340 decoded->op = M68K_MULS; 1343 decoded->op = M68K_MULS;
1341 decoded->extra.size = OPSIZE_WORD; 1344 decoded->extra.size = OPSIZE_WORD;
1342 decoded->dst.addr_mode = MODE_REG; 1345 decoded->dst.addr_mode = MODE_REG;
1343 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1346 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1344 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1347 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src));
1345 if (!istream) { 1348 if (!istream || decoded->src.addr_mode == MODE_AREG) {
1346 decoded->op = M68K_INVALID; 1349 decoded->op = M68K_INVALID;
1347 break; 1350 break;
1348 } 1351 }
1349 } else if(!(*istream & 0xF0)) { 1352 } else if(!(*istream & 0xF0)) {
1350 decoded->op = M68K_ABCD; 1353 decoded->op = M68K_ABCD;
1362 decoded->src.addr_mode = MODE_REG; 1365 decoded->src.addr_mode = MODE_REG;
1363 decoded->dst.addr_mode = MODE_AREG; 1366 decoded->dst.addr_mode = MODE_AREG;
1364 } else { 1367 } else {
1365 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG; 1368 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG;
1366 } 1369 }
1370 } else if (*istream & 0x40) {
1371 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_REG;
1367 } else { 1372 } else {
1368 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_REG; 1373 decoded->op = M68K_INVALID;
1374 break;
1369 } 1375 }
1370 } else { 1376 } else {
1371 decoded->op = M68K_AND; 1377 decoded->op = M68K_AND;
1372 decoded->extra.size = (*istream >> 6) & 0x3; 1378 decoded->extra.size = (*istream >> 6) & 0x3;
1373 decoded->src.addr_mode = MODE_REG; 1379 decoded->src.addr_mode = MODE_REG;
1374 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1380 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream);
1375 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); 1381 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst));
1376 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 1382 if (!istream || !m68k_valid_full_arith_dst(&(decoded->dst))) {
1377 decoded->op = M68K_INVALID; 1383 decoded->op = M68K_INVALID;
1378 break; 1384 break;
1379 } 1385 }
1380 } 1386 }
1381 } else { 1387 } else {
1383 decoded->op = M68K_MULU; 1389 decoded->op = M68K_MULU;
1384 decoded->extra.size = OPSIZE_WORD; 1390 decoded->extra.size = OPSIZE_WORD;
1385 decoded->dst.addr_mode = MODE_REG; 1391 decoded->dst.addr_mode = MODE_REG;
1386 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1392 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1387 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1393 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src));
1388 if (!istream) { 1394 if (!istream || decoded->src.addr_mode == MODE_AREG) {
1389 decoded->op = M68K_INVALID; 1395 decoded->op = M68K_INVALID;
1390 break; 1396 break;
1391 } 1397 }
1392 } else { 1398 } else {
1393 decoded->op = M68K_AND; 1399 decoded->op = M68K_AND;