Mercurial > repos > blastem
comparison 68kinst.c @ 636:22e357678fad
Add support for 68020 bitfield instructions
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 12 Oct 2014 19:03:05 -0700 |
parents | 4a6ec64acd79 |
children | 8a3198c17207 |
comparison
equal
deleted
inserted
replaced
635:6992a1b07714 | 636:22e357678fad |
---|---|
1301 decoded->dst.params.regs.pri = *istream & 0x7; | 1301 decoded->dst.params.regs.pri = *istream & 0x7; |
1302 | 1302 |
1303 } else { | 1303 } else { |
1304 #ifdef M68020 | 1304 #ifdef M68020 |
1305 //TODO: Implement bitfield instructions for M68020+ support | 1305 //TODO: Implement bitfield instructions for M68020+ support |
1306 switch (*istream >> 8 & 7) | |
1307 { | |
1308 case 0: | |
1309 decoded->op = M68K_BFTST; //<ea> | |
1310 break; | |
1311 case 1: | |
1312 decoded->op = M68K_BFEXTU; //<ea>, Dn | |
1313 break; | |
1314 case 2: | |
1315 decoded->op = M68K_BFCHG; //<ea> | |
1316 break; | |
1317 case 3: | |
1318 decoded->op = M68K_BFEXTS; //<ea>, Dn | |
1319 break; | |
1320 case 4: | |
1321 decoded->op = M68K_BFCLR; //<ea> | |
1322 break; | |
1323 case 5: | |
1324 decoded->op = M68K_BFFFO; //<ea>, Dn | |
1325 break; | |
1326 case 6: | |
1327 decoded->op = M68K_BFSET; //<ea> | |
1328 break; | |
1329 case 7: | |
1330 decoded->op = M68K_BFINS; //Dn, <ea> | |
1331 break; | |
1332 } | |
1333 opmode = *istream >> 3 & 0x7; | |
1334 reg = *istream & 0x7; | |
1335 m68k_op_info *ea, *other; | |
1336 if (decoded->op == M68K_BFEXTU || decoded->op == M68K_BFEXTS || decoded->op == M68K_BFFFO) | |
1337 { | |
1338 ea = &(decoded->src); | |
1339 other = &(decoded->dst); | |
1340 } else { | |
1341 ea = &(decoded->dst); | |
1342 other = &(decoded->dst); | |
1343 } | |
1344 if (*istream & 0x100) | |
1345 { | |
1346 immed = *(istream++); | |
1347 other->addr_mode = MODE_REG; | |
1348 other->params.regs.pri = immed >> 12 & 0x7; | |
1349 } else { | |
1350 immed = *(istream++); | |
1351 } | |
1352 decoded->extra.size = OPSIZE_UNSIZED; | |
1353 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, ea); | |
1354 ea->addr_mode |= M68K_FLAG_BITFIELD; | |
1355 ea->bitfield = immed & 0xFFF; | |
1306 #endif | 1356 #endif |
1307 } | 1357 } |
1308 break; | 1358 break; |
1309 case COPROC: | 1359 case COPROC: |
1310 //TODO: Implement me | 1360 //TODO: Implement me |
1464 #ifdef M68010 | 1514 #ifdef M68010 |
1465 "bkpt", | 1515 "bkpt", |
1466 "move", //from ccr | 1516 "move", //from ccr |
1467 "movec", | 1517 "movec", |
1468 "moves", | 1518 "moves", |
1519 "rtd", | |
1469 #endif | 1520 #endif |
1470 #ifdef M68020 | 1521 #ifdef M68020 |
1471 "bfchg", | 1522 "bfchg", |
1472 "bfclr", | 1523 "bfclr", |
1473 "bfexts", | 1524 "bfexts", |
1534 #endif | 1585 #endif |
1535 | 1586 |
1536 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data) | 1587 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data) |
1537 { | 1588 { |
1538 char * c = need_comma ? "," : ""; | 1589 char * c = need_comma ? "," : ""; |
1539 switch(decoded->addr_mode) | 1590 int ret = 0; |
1591 #ifdef M68020 | |
1592 uint8_t addr_mode = decoded->addr_mode & (~M68K_FLAG_BITFIELD); | |
1593 #else | |
1594 uint8_t addr_mode = decoded->addr_mode; | |
1595 #endif | |
1596 switch(addr_mode) | |
1540 { | 1597 { |
1541 case MODE_REG: | 1598 case MODE_REG: |
1542 return sprintf(dst, "%s d%d", c, decoded->params.regs.pri); | 1599 ret = sprintf(dst, "%s d%d", c, decoded->params.regs.pri); |
1600 break; | |
1543 case MODE_AREG: | 1601 case MODE_AREG: |
1544 return sprintf(dst, "%s a%d", c, decoded->params.regs.pri); | 1602 ret = sprintf(dst, "%s a%d", c, decoded->params.regs.pri); |
1603 break; | |
1545 case MODE_AREG_INDIRECT: | 1604 case MODE_AREG_INDIRECT: |
1546 return sprintf(dst, "%s (a%d)", c, decoded->params.regs.pri); | 1605 ret = sprintf(dst, "%s (a%d)", c, decoded->params.regs.pri); |
1606 break; | |
1547 case MODE_AREG_POSTINC: | 1607 case MODE_AREG_POSTINC: |
1548 return sprintf(dst, "%s (a%d)+", c, decoded->params.regs.pri); | 1608 ret = sprintf(dst, "%s (a%d)+", c, decoded->params.regs.pri); |
1609 break; | |
1549 case MODE_AREG_PREDEC: | 1610 case MODE_AREG_PREDEC: |
1550 return sprintf(dst, "%s -(a%d)", c, decoded->params.regs.pri); | 1611 ret = sprintf(dst, "%s -(a%d)", c, decoded->params.regs.pri); |
1612 break; | |
1551 case MODE_AREG_DISPLACE: | 1613 case MODE_AREG_DISPLACE: |
1552 return sprintf(dst, "%s (%d, a%d)", c, decoded->params.regs.displacement, decoded->params.regs.pri); | 1614 ret = sprintf(dst, "%s (%d, a%d)", c, decoded->params.regs.displacement, decoded->params.regs.pri); |
1615 break; | |
1553 case MODE_AREG_INDEX_DISP8: | 1616 case MODE_AREG_INDEX_DISP8: |
1554 return sprintf(dst, "%s (%d, a%d, %c%d.%c)", c, decoded->params.regs.displacement, decoded->params.regs.pri, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); | 1617 ret = sprintf(dst, "%s (%d, a%d, %c%d.%c)", c, decoded->params.regs.displacement, decoded->params.regs.pri, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); |
1618 break; | |
1555 case MODE_IMMEDIATE: | 1619 case MODE_IMMEDIATE: |
1556 case MODE_IMMEDIATE_WORD: | 1620 case MODE_IMMEDIATE_WORD: |
1557 return sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed); | 1621 ret = sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed); |
1622 break; | |
1558 case MODE_ABSOLUTE_SHORT: | 1623 case MODE_ABSOLUTE_SHORT: |
1559 if (labels) { | 1624 if (labels) { |
1560 int ret = sprintf(dst, "%s ", c); | 1625 ret = sprintf(dst, "%s ", c); |
1561 ret += label_fun(dst+ret, decoded->params.immed, data); | 1626 ret += label_fun(dst+ret, decoded->params.immed, data); |
1562 strcat(dst+ret, ".w"); | 1627 strcat(dst+ret, ".w"); |
1563 return ret + 2; | 1628 ret = ret + 2; |
1564 } else { | 1629 } else { |
1565 return sprintf(dst, "%s $%X.w", c, decoded->params.immed); | 1630 ret = sprintf(dst, "%s $%X.w", c, decoded->params.immed); |
1566 } | 1631 } |
1632 break; | |
1567 case MODE_ABSOLUTE: | 1633 case MODE_ABSOLUTE: |
1568 if (labels) { | 1634 if (labels) { |
1569 int ret = sprintf(dst, "%s ", c); | 1635 ret = sprintf(dst, "%s ", c); |
1570 ret += label_fun(dst+ret, decoded->params.immed, data); | 1636 ret += label_fun(dst+ret, decoded->params.immed, data); |
1571 strcat(dst+ret, ".l"); | 1637 strcat(dst+ret, ".l"); |
1572 return ret + 2; | 1638 ret = ret + 2; |
1573 } else { | 1639 } else { |
1574 return sprintf(dst, "%s $%X", c, decoded->params.immed); | 1640 ret = sprintf(dst, "%s $%X", c, decoded->params.immed); |
1575 } | 1641 } |
1642 break; | |
1576 case MODE_PC_DISPLACE: | 1643 case MODE_PC_DISPLACE: |
1577 if (labels) { | 1644 if (labels) { |
1578 int ret = sprintf(dst, "%s ", c); | 1645 ret = sprintf(dst, "%s ", c); |
1579 ret += label_fun(dst+ret, address + 2 + decoded->params.regs.displacement, data); | 1646 ret += label_fun(dst+ret, address + 2 + decoded->params.regs.displacement, data); |
1580 strcat(dst+ret, "(pc)"); | 1647 strcat(dst+ret, "(pc)"); |
1581 return ret + 4; | 1648 ret = ret + 4; |
1582 } else { | 1649 } else { |
1583 return sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement); | 1650 ret = sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement); |
1584 } | 1651 } |
1652 break; | |
1585 case MODE_PC_INDEX_DISP8: | 1653 case MODE_PC_INDEX_DISP8: |
1586 return sprintf(dst, "%s (%d, pc, %c%d.%c)", c, decoded->params.regs.displacement, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); | 1654 ret = sprintf(dst, "%s (%d, pc, %c%d.%c)", c, decoded->params.regs.displacement, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); |
1587 default: | 1655 default: |
1588 return 0; | 1656 ret = 0; |
1589 } | 1657 } |
1658 #ifdef M68020 | |
1659 if (decoded->addr_mode & M68K_FLAG_BITFIELD) | |
1660 { | |
1661 switch (decoded->bitfield & 0x820) | |
1662 { | |
1663 case 0: | |
1664 return ret + sprintf(dst+ret, " {$%X:%d}", decoded->bitfield >> 6 & 0x1F, decoded->bitfield & 0x1F ? decoded->bitfield & 0x1F : 32); | |
1665 case 0x20: | |
1666 return ret + sprintf(dst+ret, " {$%X:d%d}", decoded->bitfield >> 6 & 0x1F, decoded->bitfield & 0x7); | |
1667 case 0x800: | |
1668 return ret + sprintf(dst+ret, " {d%d:%d}", decoded->bitfield >> 6 & 0x7, decoded->bitfield & 0x1F ? decoded->bitfield & 0x1F : 32); | |
1669 case 0x820: | |
1670 return ret + sprintf(dst+ret, " {d%d:d%d}", decoded->bitfield >> 6 & 0x7, decoded->bitfield & 0x7); | |
1671 } | |
1672 } | |
1673 #endif | |
1674 return ret; | |
1590 } | 1675 } |
1591 | 1676 |
1592 int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data) | 1677 int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data) |
1593 { | 1678 { |
1594 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; | 1679 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; |