Mercurial > repos > blastem
comparison 68kinst.c @ 634:4a6ec64acd79
Better support for labels sourced from VOS program module header
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 11 Oct 2014 22:18:49 -0700 |
parents | 47123183c336 |
children | 22e357678fad |
comparison
equal
deleted
inserted
replaced
633:a759f4e38488 | 634:4a6ec64acd79 |
---|---|
1531 "ISP" | 1531 "ISP" |
1532 #endif | 1532 #endif |
1533 }; | 1533 }; |
1534 #endif | 1534 #endif |
1535 | 1535 |
1536 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address) | 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) |
1537 { | 1537 { |
1538 char * c = need_comma ? "," : ""; | 1538 char * c = need_comma ? "," : ""; |
1539 switch(decoded->addr_mode) | 1539 switch(decoded->addr_mode) |
1540 { | 1540 { |
1541 case MODE_REG: | 1541 case MODE_REG: |
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'); | 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'); |
1555 case MODE_IMMEDIATE: | 1555 case MODE_IMMEDIATE: |
1556 case MODE_IMMEDIATE_WORD: | 1556 case MODE_IMMEDIATE_WORD: |
1557 return sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed); | 1557 return sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed); |
1558 case MODE_ABSOLUTE_SHORT: | 1558 case MODE_ABSOLUTE_SHORT: |
1559 if (labels) { | 1559 if (labels) { |
1560 return sprintf(dst, "%s ADR_%X.w", c, decoded->params.immed); | 1560 int ret = sprintf(dst, "%s ", c); |
1561 ret += label_fun(dst+ret, decoded->params.immed, data); | |
1562 strcat(dst+ret, ".w"); | |
1563 return ret + 2; | |
1561 } else { | 1564 } else { |
1562 return sprintf(dst, "%s $%X.w", c, decoded->params.immed); | 1565 return sprintf(dst, "%s $%X.w", c, decoded->params.immed); |
1563 } | 1566 } |
1564 case MODE_ABSOLUTE: | 1567 case MODE_ABSOLUTE: |
1565 if (labels) { | 1568 if (labels) { |
1566 return sprintf(dst, "%s ADR_%X.l", c, decoded->params.immed); | 1569 int ret = sprintf(dst, "%s ", c); |
1570 ret += label_fun(dst+ret, decoded->params.immed, data); | |
1571 strcat(dst+ret, ".l"); | |
1572 return ret + 2; | |
1567 } else { | 1573 } else { |
1568 return sprintf(dst, "%s $%X", c, decoded->params.immed); | 1574 return sprintf(dst, "%s $%X", c, decoded->params.immed); |
1569 } | 1575 } |
1570 case MODE_PC_DISPLACE: | 1576 case MODE_PC_DISPLACE: |
1571 if (labels) { | 1577 if (labels) { |
1572 return sprintf(dst, "%s ADR_%X(pc)", c, address + 2 + decoded->params.regs.displacement); | 1578 int ret = sprintf(dst, "%s ", c); |
1579 ret += label_fun(dst+ret, address + 2 + decoded->params.regs.displacement, data); | |
1580 strcat(dst+ret, "(pc)"); | |
1581 return ret + 4; | |
1573 } else { | 1582 } else { |
1574 return sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement); | 1583 return sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement); |
1575 } | 1584 } |
1576 case MODE_PC_INDEX_DISP8: | 1585 case MODE_PC_INDEX_DISP8: |
1577 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'); | 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'); |
1578 default: | 1587 default: |
1579 return 0; | 1588 return 0; |
1580 } | 1589 } |
1581 } | 1590 } |
1582 | 1591 |
1583 int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address) | 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) |
1584 { | 1593 { |
1585 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; | 1594 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; |
1586 char *rtype, *last_rtype; | 1595 char *rtype, *last_rtype; |
1587 int oplen; | 1596 int oplen; |
1588 if (decoded->addr_mode == MODE_REG) { | 1597 if (decoded->addr_mode == MODE_REG) { |
1632 if (last >= 0 && last != first) { | 1641 if (last >= 0 && last != first) { |
1633 oplen += sprintf(dst + oplen, "-%s%d", last_rtype, last); | 1642 oplen += sprintf(dst + oplen, "-%s%d", last_rtype, last); |
1634 } | 1643 } |
1635 return oplen; | 1644 return oplen; |
1636 } else { | 1645 } else { |
1637 return m68k_disasm_op(decoded, dst, need_comma, labels, address); | 1646 return m68k_disasm_op(decoded, dst, need_comma, labels, address, label_fun, data); |
1638 } | 1647 } |
1639 } | 1648 } |
1640 | 1649 |
1641 int m68k_disasm_ex(m68kinst * decoded, char * dst, uint8_t labels) | 1650 int m68k_default_label_fun(char * dst, uint32_t address, void * data) |
1651 { | |
1652 return sprintf(dst, "ADR_%X", address); | |
1653 } | |
1654 | |
1655 int m68k_disasm_ex(m68kinst * decoded, char * dst, uint8_t labels, format_label_fun label_fun, void * data) | |
1642 { | 1656 { |
1643 int ret,op1len; | 1657 int ret,op1len; |
1644 uint8_t size; | 1658 uint8_t size; |
1645 char * special_op = "CCR"; | 1659 char * special_op = "CCR"; |
1646 switch (decoded->op) | 1660 switch (decoded->op) |
1654 strcpy(dst+ret, cond_mnem[decoded->extra.cond]); | 1668 strcpy(dst+ret, cond_mnem[decoded->extra.cond]); |
1655 ret = strlen(dst); | 1669 ret = strlen(dst); |
1656 if (decoded->op != M68K_SCC) { | 1670 if (decoded->op != M68K_SCC) { |
1657 if (labels) { | 1671 if (labels) { |
1658 if (decoded->op == M68K_DBCC) { | 1672 if (decoded->op == M68K_DBCC) { |
1659 ret += sprintf(dst+ret, " d%d, ADR_%X", decoded->dst.params.regs.pri, decoded->address + 2 + decoded->src.params.immed); | 1673 ret += sprintf(dst+ret, " d%d, ", decoded->dst.params.regs.pri); |
1674 ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data); | |
1660 } else { | 1675 } else { |
1661 ret += sprintf(dst+ret, " ADR_%X", decoded->address + 2 + decoded->src.params.immed); | 1676 dst[ret++] = ' '; |
1677 ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data); | |
1662 } | 1678 } |
1663 } else { | 1679 } else { |
1664 if (decoded->op == M68K_DBCC) { | 1680 if (decoded->op == M68K_DBCC) { |
1665 ret += sprintf(dst+ret, " d%d, #%d <%X>", decoded->dst.params.regs.pri, decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); | 1681 ret += sprintf(dst+ret, " d%d, #%d <%X>", decoded->dst.params.regs.pri, decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); |
1666 } else { | 1682 } else { |
1670 return ret; | 1686 return ret; |
1671 } | 1687 } |
1672 break; | 1688 break; |
1673 case M68K_BSR: | 1689 case M68K_BSR: |
1674 if (labels) { | 1690 if (labels) { |
1675 ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "", | 1691 ret = sprintf(dst, "bsr%s ", decoded->variant == VAR_BYTE ? ".s" : ""); |
1676 decoded->address + 2 + decoded->src.params.immed); | 1692 ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data); |
1677 } else { | 1693 } else { |
1678 ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); | 1694 ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); |
1679 } | 1695 } |
1680 return ret; | 1696 return ret; |
1681 case M68K_MOVE_FROM_SR: | 1697 case M68K_MOVE_FROM_SR: |
1682 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 1698 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1683 ret += sprintf(dst + ret, " SR"); | 1699 ret += sprintf(dst + ret, " SR"); |
1684 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1, labels, decoded->address); | 1700 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1, labels, decoded->address, label_fun, data); |
1685 return ret; | 1701 return ret; |
1686 case M68K_ANDI_SR: | 1702 case M68K_ANDI_SR: |
1687 case M68K_EORI_SR: | 1703 case M68K_EORI_SR: |
1688 case M68K_MOVE_SR: | 1704 case M68K_MOVE_SR: |
1689 case M68K_ORI_SR: | 1705 case M68K_ORI_SR: |
1691 case M68K_ANDI_CCR: | 1707 case M68K_ANDI_CCR: |
1692 case M68K_EORI_CCR: | 1708 case M68K_EORI_CCR: |
1693 case M68K_MOVE_CCR: | 1709 case M68K_MOVE_CCR: |
1694 case M68K_ORI_CCR: | 1710 case M68K_ORI_CCR: |
1695 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 1711 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1696 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address); | 1712 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); |
1697 ret += sprintf(dst + ret, ", %s", special_op); | 1713 ret += sprintf(dst + ret, ", %s", special_op); |
1698 return ret; | 1714 return ret; |
1699 case M68K_MOVE_USP: | 1715 case M68K_MOVE_USP: |
1700 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 1716 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1701 if (decoded->src.addr_mode != MODE_UNUSED) { | 1717 if (decoded->src.addr_mode != MODE_UNUSED) { |
1702 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address); | 1718 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); |
1703 ret += sprintf(dst + ret, ", USP"); | 1719 ret += sprintf(dst + ret, ", USP"); |
1704 } else { | 1720 } else { |
1705 ret += sprintf(dst + ret, "USP, "); | 1721 ret += sprintf(dst + ret, "USP, "); |
1706 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address); | 1722 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data); |
1707 } | 1723 } |
1708 return ret; | 1724 return ret; |
1709 case M68K_INVALID: | 1725 case M68K_INVALID: |
1710 ret = sprintf(dst, "dc.w $%X", decoded->src.params.immed); | 1726 ret = sprintf(dst, "dc.w $%X", decoded->src.params.immed); |
1711 return ret; | 1727 return ret; |
1712 #ifdef M68010 | 1728 #ifdef M68010 |
1713 case M68K_MOVEC: | 1729 case M68K_MOVEC: |
1714 ret = sprintf(dst, "%s ", mnemonics[decoded->op]); | 1730 ret = sprintf(dst, "%s ", mnemonics[decoded->op]); |
1715 if (decoded->src.addr_mode == MODE_UNUSED) { | 1731 if (decoded->src.addr_mode == MODE_UNUSED) { |
1716 ret += sprintf(dst + ret, "%s, ", cr_mnem[decoded->src.params.immed]); | 1732 ret += sprintf(dst + ret, "%s, ", cr_mnem[decoded->src.params.immed]); |
1717 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address); | 1733 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data); |
1718 } else { | 1734 } else { |
1719 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address); | 1735 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); |
1720 ret += sprintf(dst + ret, ", %s", cr_mnem[decoded->dst.params.immed]); | 1736 ret += sprintf(dst + ret, ", %s", cr_mnem[decoded->dst.params.immed]); |
1721 } | 1737 } |
1722 return ret; | 1738 return ret; |
1723 #endif | 1739 #endif |
1724 default: | 1740 default: |
1727 mnemonics[decoded->op], | 1743 mnemonics[decoded->op], |
1728 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), | 1744 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), |
1729 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); | 1745 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); |
1730 } | 1746 } |
1731 if (decoded->op == M68K_MOVEM) { | 1747 if (decoded->op == M68K_MOVEM) { |
1732 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address); | 1748 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data); |
1733 ret += op1len; | 1749 ret += op1len; |
1734 ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len, labels, decoded->address); | 1750 ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len, labels, decoded->address, label_fun, data); |
1735 } else { | 1751 } else { |
1736 op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address); | 1752 op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); |
1737 ret += op1len; | 1753 ret += op1len; |
1738 ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len, labels, decoded->address); | 1754 ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len, labels, decoded->address, label_fun, data); |
1739 } | 1755 } |
1740 return ret; | 1756 return ret; |
1741 } | 1757 } |
1742 | 1758 |
1743 int m68k_disasm(m68kinst * decoded, char * dst) | 1759 int m68k_disasm(m68kinst * decoded, char * dst) |
1744 { | 1760 { |
1745 return m68k_disasm_ex(decoded, dst, 0); | 1761 return m68k_disasm_ex(decoded, dst, 0, NULL, NULL); |
1746 } | 1762 } |
1747 | 1763 |
1748 int m68k_disasm_labels(m68kinst * decoded, char * dst) | 1764 int m68k_disasm_labels(m68kinst * decoded, char * dst, format_label_fun label_fun, void * data) |
1749 { | 1765 { |
1750 return m68k_disasm_ex(decoded, dst, 1); | 1766 if (!label_fun) |
1767 { | |
1768 label_fun = m68k_default_label_fun; | |
1769 } | |
1770 return m68k_disasm_ex(decoded, dst, 1, label_fun, data); | |
1751 } | 1771 } |