comparison 68kinst.c @ 638:8a3198c17207

Add support for 68020 addressing modes in decoder and disassembler
author Michael Pavone <pavone@retrodev.com>
date Tue, 14 Oct 2014 21:58:03 -0700
parents 22e357678fad
children 66857bd2df0b
comparison
equal deleted inserted replaced
637:d8d58eced22f 638:8a3198c17207
17 return (val & 0x80) ? val | 0xFFFFFF00 : val; 17 return (val & 0x80) ? val | 0xFFFFFF00 : val;
18 } 18 }
19 19
20 uint16_t *m68k_decode_op_ex(uint16_t *cur, uint8_t mode, uint8_t reg, uint8_t size, m68k_op_info *dst) 20 uint16_t *m68k_decode_op_ex(uint16_t *cur, uint8_t mode, uint8_t reg, uint8_t size, m68k_op_info *dst)
21 { 21 {
22 uint16_t ext; 22 uint16_t ext, tmp;
23 dst->addr_mode = mode; 23 dst->addr_mode = mode;
24 switch(mode) 24 switch(mode)
25 { 25 {
26 case MODE_REG: 26 case MODE_REG:
27 case MODE_AREG: 27 case MODE_AREG:
34 ext = *(++cur); 34 ext = *(++cur);
35 dst->params.regs.pri = reg; 35 dst->params.regs.pri = reg;
36 dst->params.regs.displacement = sign_extend16(ext); 36 dst->params.regs.displacement = sign_extend16(ext);
37 break; 37 break;
38 case MODE_AREG_INDEX_MEM: 38 case MODE_AREG_INDEX_MEM:
39 #ifdef M68020 39 dst->params.regs.pri = reg;
40 //TODO: implement me for M68020+ support 40 ext = *(++cur);
41 #else 41 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit
42 #ifdef M68020
43 dst->params.regs.scale = ext >> 9 & 3;
44 if (ext & 0x100)
45 {
46 dst->params.regs.disp_sizes = ext >> 4 & 3;
47 switch (dst->params.regs.disp_sizes)
48 {
49 case 0:
50 //reserved
51 return NULL;
52 case 1:
53 dst->params.regs.displacement = 0;
54 break;
55 case 2:
56 dst->params.regs.displacement = sign_extend16(*(cur++));
57 break;
58 case 3:
59 tmp = *(cur++);
60 dst->params.regs.displacement = tmp << 16 | *(cur++);
61 break;
62 }
63 if (ext & 0x3)
64 {
65 //memory indirect
66 switch (ext & 0xC4)
67 {
68 case 0x00:
69 dst->addr_mode = MODE_AREG_PREINDEX;
70 break;
71 case 0x04:
72 dst->addr_mode = MODE_AREG_POSTINDEX;
73 break;
74 case 0x40:
75 dst->addr_mode = MODE_AREG_MEM_INDIRECT;
76 break;
77 case 0x80:
78 dst->addr_mode = MODE_PREINDEX;
79 break;
80 case 0x84:
81 dst->addr_mode = MODE_POSTINDEX;
82 break;
83 case 0xC0:
84 dst->addr_mode = MODE_MEM_INDIRECT;
85 break;
86 }
87 dst->params.regs.disp_sizes |= ext << 4 & 0x30;
88 switch (ext & 0x3)
89 {
90 case 0:
91 //reserved
92 return NULL;
93 case 1:
94 dst->params.regs.outer_disp = 0;
95 break;
96 case 2:
97 dst->params.regs.outer_disp = sign_extend16(*(cur++));
98 break;
99 case 3:
100 tmp = *(cur++);
101 dst->params.regs.outer_disp = tmp << 16 | *(cur++);
102 break;
103 }
104 } else {
105 switch (ext >> 6 & 3)
106 {
107 case 0:
108 dst->addr_mode = MODE_AREG_INDEX_BASE_DISP;
109 break;
110 case 1:
111 dst->addr_mode = MODE_AREG_BASE_DISP;
112 break;
113 case 2:
114 dst->addr_mode = MODE_INDEX_BASE_DISP;
115 break;
116 case 3:
117 dst->addr_mode = MODE_BASE_DISP;
118 break;
119 }
120 }
121 } else {
122 #endif
42 dst->addr_mode = MODE_AREG_INDEX_DISP8; 123 dst->addr_mode = MODE_AREG_INDEX_DISP8;
43 dst->params.regs.pri = reg;
44 ext = *(++cur);
45 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit
46 dst->params.regs.displacement = sign_extend8(ext&0xFF); 124 dst->params.regs.displacement = sign_extend8(ext&0xFF);
47 #endif 125 #ifdef M68020
126 }
127 #endif
48 break; 128 break;
49 case MODE_PC_INDIRECT_ABS_IMMED: 129 case MODE_PC_INDIRECT_ABS_IMMED:
50 switch(reg) 130 switch(reg)
51 { 131 {
52 case 0: 132 case 0:
65 #else 145 #else
66 dst->addr_mode = MODE_PC_INDEX_DISP8; 146 dst->addr_mode = MODE_PC_INDEX_DISP8;
67 ext = *(++cur); 147 ext = *(++cur);
68 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit 148 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit
69 dst->params.regs.displacement = sign_extend8(ext&0xFF); 149 dst->params.regs.displacement = sign_extend8(ext&0xFF);
150 #endif
151
152 ext = *(++cur);
153 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit
154 #ifdef M68020
155 dst->params.regs.scale = ext >> 9 & 3;
156 if (ext & 0x100)
157 {
158 dst->params.regs.disp_sizes = ext >> 4 & 3;
159 switch (dst->params.regs.disp_sizes)
160 {
161 case 0:
162 //reserved
163 return NULL;
164 case 1:
165 dst->params.regs.displacement = 0;
166 break;
167 case 2:
168 dst->params.regs.displacement = sign_extend16(*(cur++));
169 break;
170 case 3:
171 tmp = *(cur++);
172 dst->params.regs.displacement = tmp << 16 | *(cur++);
173 break;
174 }
175 if (ext & 0x3)
176 {
177 //memory indirect
178 switch (ext & 0xC4)
179 {
180 case 0x00:
181 dst->addr_mode = MODE_PC_PREINDEX;
182 break;
183 case 0x04:
184 dst->addr_mode = MODE_PC_POSTINDEX;
185 break;
186 case 0x40:
187 dst->addr_mode = MODE_PC_MEM_INDIRECT;
188 break;
189 case 0x80:
190 dst->addr_mode = MODE_ZPC_PREINDEX;
191 break;
192 case 0x84:
193 dst->addr_mode = MODE_ZPC_POSTINDEX;
194 break;
195 case 0xC0:
196 dst->addr_mode = MODE_ZPC_MEM_INDIRECT;
197 break;
198 }
199 dst->params.regs.disp_sizes |= ext << 4 & 0x30;
200 switch (ext & 0x3)
201 {
202 case 0:
203 //reserved
204 return NULL;
205 case 1:
206 dst->params.regs.outer_disp = 0;
207 break;
208 case 2:
209 dst->params.regs.outer_disp = sign_extend16(*(cur++));
210 break;
211 case 3:
212 tmp = *(cur++);
213 dst->params.regs.outer_disp = tmp << 16 | *(cur++);
214 break;
215 }
216 } else {
217 switch (ext >> 6 & 3)
218 {
219 case 0:
220 dst->addr_mode = MODE_PC_INDEX_BASE_DISP;
221 break;
222 case 1:
223 dst->addr_mode = MODE_PC_BASE_DISP;
224 break;
225 case 2:
226 dst->addr_mode = MODE_ZPC_INDEX_BASE_DISP;
227 break;
228 case 3:
229 dst->addr_mode = MODE_ZPC_BASE_DISP;
230 break;
231 }
232 }
233 } else {
234 #endif
235 dst->addr_mode = MODE_PC_INDEX_DISP8;
236 dst->params.regs.displacement = sign_extend8(ext&0xFF);
237 #ifdef M68020
238 }
70 #endif 239 #endif
71 break; 240 break;
72 case 2: 241 case 2:
73 dst->addr_mode = MODE_PC_DISPLACE; 242 dst->addr_mode = MODE_PC_DISPLACE;
74 ext = *(++cur); 243 ext = *(++cur);
1612 break; 1781 break;
1613 case MODE_AREG_DISPLACE: 1782 case MODE_AREG_DISPLACE:
1614 ret = sprintf(dst, "%s (%d, a%d)", c, decoded->params.regs.displacement, decoded->params.regs.pri); 1783 ret = sprintf(dst, "%s (%d, a%d)", c, decoded->params.regs.displacement, decoded->params.regs.pri);
1615 break; 1784 break;
1616 case MODE_AREG_INDEX_DISP8: 1785 case MODE_AREG_INDEX_DISP8:
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'); 1786 #ifdef M68020
1618 break; 1787 if (decoded->params.regs.scale)
1788 {
1789 ret = sprintf(dst, "%s (%d, a%d, %c%d.%c*%d)", 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', 1 << decoded->params.regs.scale);
1790 } else {
1791 #endif
1792 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');
1793 #ifdef M68020
1794 }
1795 #endif
1796 break;
1797 #ifdef M68020
1798 case MODE_AREG_INDEX_BASE_DISP:
1799 if (decoded->params.regs.disp_sizes > 1)
1800 {
1801 ret = sprintf(dst, "%s (%d.%c, a%d, %c%d.%c*%d)", c, decoded->params.regs.displacement,
1802 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l', decoded->params.regs.pri,
1803 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1804 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1805 } else {
1806 ret = sprintf(dst, "%s (a%d, %c%d.%c*%d)", c, decoded->params.regs.pri,
1807 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1808 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1809 }
1810 break;
1811 case MODE_AREG_PREINDEX:
1812 switch (decoded->params.regs.disp_sizes)
1813 {
1814 case 0x11:
1815 //no base displacement or outer displacement
1816 ret = sprintf(dst, "%s ([a%d, %c%d.%c*%d])", c, decoded->params.regs.pri,
1817 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1818 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1819 break;
1820 case 0x12:
1821 case 0x13:
1822 //base displacement only
1823 ret = sprintf(dst, "%s ([%d.%c, a%d, %c%d.%c*%d])", c, decoded->params.regs.displacement,
1824 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri,
1825 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1826 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1827 break;
1828 case 0x21:
1829 case 0x31:
1830 //outer displacement only
1831 ret = sprintf(dst, "%s ([a%d, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.pri,
1832 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1833 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
1834 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1835 break;
1836 case 0x22:
1837 case 0x23:
1838 case 0x32:
1839 case 0x33:
1840 //both outer and inner displacement
1841 ret = sprintf(dst, "%s ([%d.%c, a%d, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement,
1842 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri,
1843 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1844 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
1845 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1846 break;
1847 }
1848 break;
1849 case MODE_AREG_POSTINDEX:
1850 switch (decoded->params.regs.disp_sizes)
1851 {
1852 case 0x11:
1853 //no base displacement or outer displacement
1854 ret = sprintf(dst, "%s ([a%d], %c%d.%c*%d)", c, decoded->params.regs.pri,
1855 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1856 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1857 break;
1858 case 0x12:
1859 case 0x13:
1860 //base displacement only
1861 ret = sprintf(dst, "%s ([%d.%c, a%d], %c%d.%c*%d)", c, decoded->params.regs.displacement,
1862 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri,
1863 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1864 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1865 break;
1866 case 0x21:
1867 case 0x31:
1868 //outer displacement only
1869 ret = sprintf(dst, "%s ([a%d], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.pri,
1870 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1871 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
1872 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1873 break;
1874 case 0x22:
1875 case 0x23:
1876 case 0x32:
1877 case 0x33:
1878 //both outer and inner displacement
1879 ret = sprintf(dst, "%s ([%d.%c, a%d], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement,
1880 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri,
1881 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1882 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
1883 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1884 break;
1885 }
1886 break;
1887 case MODE_AREG_MEM_INDIRECT:
1888 switch (decoded->params.regs.disp_sizes)
1889 {
1890 case 0x11:
1891 //no base displacement or outer displacement
1892 ret = sprintf(dst, "%s ([a%d])", c, decoded->params.regs.pri);
1893 break;
1894 case 0x12:
1895 case 0x13:
1896 //base displacement only
1897 ret = sprintf(dst, "%s ([%d.%c, a%d])", c, decoded->params.regs.displacement,
1898 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri);
1899 break;
1900 case 0x21:
1901 case 0x31:
1902 //outer displacement only
1903 ret = sprintf(dst, "%s ([a%d], %d.%c)", c, decoded->params.regs.pri, decoded->params.regs.outer_disp,
1904 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1905 break;
1906 case 0x22:
1907 case 0x23:
1908 case 0x32:
1909 case 0x33:
1910 //both outer and inner displacement
1911 ret = sprintf(dst, "%s ([%d.%c, a%d], %d.%c)", c, decoded->params.regs.displacement,
1912 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri,
1913 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1914 break;
1915 }
1916 break;
1917 case MODE_AREG_BASE_DISP:
1918 if (decoded->params.regs.disp_sizes > 1)
1919 {
1920 ret = sprintf(dst, "%s (%d.%c, a%d)", c, decoded->params.regs.displacement,
1921 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l', decoded->params.regs.pri);
1922 } else {
1923 //this is a lossy representation of the encoded instruction
1924 //not sure if there's a better way to print it though
1925 ret = sprintf(dst, "%s (a%d)", c, decoded->params.regs.pri);
1926 }
1927 break;
1928 case MODE_INDEX_BASE_DISP:
1929 if (decoded->params.regs.disp_sizes > 1)
1930 {
1931 ret = sprintf(dst, "%s (%d.%c, %c%d.%c*%d)", c, decoded->params.regs.displacement,
1932 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l',
1933 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1934 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1935 } else {
1936 ret = sprintf(dst, "%s (%c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
1937 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
1938 1 << decoded->params.regs.scale);
1939 }
1940 break;
1941 case MODE_PREINDEX:
1942 switch (decoded->params.regs.disp_sizes)
1943 {
1944 case 0x11:
1945 //no base displacement or outer displacement
1946 ret = sprintf(dst, "%s ([%c%d.%c*%d])", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
1947 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
1948 1 << decoded->params.regs.scale);
1949 break;
1950 case 0x12:
1951 case 0x13:
1952 //base displacement only
1953 ret = sprintf(dst, "%s ([%d.%c, %c%d.%c*%d])", c, decoded->params.regs.displacement,
1954 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
1955 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1956 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1957 break;
1958 case 0x21:
1959 case 0x31:
1960 //outer displacement only
1961 ret = sprintf(dst, "%s ([%c%d.%c*%d], %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
1962 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
1963 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp,
1964 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1965 break;
1966 case 0x22:
1967 case 0x23:
1968 case 0x32:
1969 case 0x33:
1970 //both outer and inner displacement
1971 ret = sprintf(dst, "%s ([%d.%c, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement,
1972 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
1973 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1974 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
1975 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
1976 break;
1977 }
1978 break;
1979 case MODE_POSTINDEX:
1980 switch (decoded->params.regs.disp_sizes)
1981 {
1982 case 0x11:
1983 //no base displacement or outer displacement
1984 ret = sprintf(dst, "%s ([], %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
1985 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
1986 1 << decoded->params.regs.scale);
1987 break;
1988 case 0x12:
1989 case 0x13:
1990 //base displacement only
1991 ret = sprintf(dst, "%s ([%d.%c], %c%d.%c*%d)", c, decoded->params.regs.displacement,
1992 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
1993 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
1994 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
1995 break;
1996 case 0x21:
1997 case 0x31:
1998 //outer displacement only
1999 ret = sprintf(dst, "%s ([], %c%d.%c*%d, %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2000 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2001 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp,
2002 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2003 break;
2004 case 0x22:
2005 case 0x23:
2006 case 0x32:
2007 case 0x33:
2008 //both outer and inner displacement
2009 ret = sprintf(dst, "%s ([%d.%c], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement,
2010 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2011 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2012 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
2013 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2014 break;
2015 }
2016 break;
2017 case MODE_MEM_INDIRECT:
2018 switch (decoded->params.regs.disp_sizes)
2019 {
2020 case 0x11:
2021 //no base displacement or outer displacement
2022 ret = sprintf(dst, "%s ([])", c);
2023 break;
2024 case 0x12:
2025 case 0x13:
2026 //base displacement only
2027 ret = sprintf(dst, "%s ([%d.%c])", c, decoded->params.regs.displacement,
2028 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l');
2029 break;
2030 case 0x21:
2031 case 0x31:
2032 //outer displacement only
2033 ret = sprintf(dst, "%s ([], %d.%c)", c, decoded->params.regs.outer_disp,
2034 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2035 break;
2036 case 0x22:
2037 case 0x23:
2038 case 0x32:
2039 case 0x33:
2040 //both outer and inner displacement
2041 ret = sprintf(dst, "%s ([%d.%c], %d.%c)", c, decoded->params.regs.displacement,
2042 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.outer_disp,
2043 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2044 break;
2045 }
2046 break;
2047 case MODE_BASE_DISP:
2048 if (decoded->params.regs.disp_sizes > 1)
2049 {
2050 ret = sprintf(dst, "%s (%d.%c)", c, decoded->params.regs.displacement,
2051 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l');
2052 } else {
2053 ret = sprintf(dst, "%s ()", c);
2054 }
2055 break;
2056 #endif
1619 case MODE_IMMEDIATE: 2057 case MODE_IMMEDIATE:
1620 case MODE_IMMEDIATE_WORD: 2058 case MODE_IMMEDIATE_WORD:
1621 ret = sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed); 2059 ret = sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed);
1622 break; 2060 break;
1623 case MODE_ABSOLUTE_SHORT: 2061 case MODE_ABSOLUTE_SHORT:
1624 if (labels) { 2062 if (labels) {
1625 ret = sprintf(dst, "%s ", c); 2063 ret = sprintf(dst, "%s ", c);
1626 ret += label_fun(dst+ret, decoded->params.immed, data); 2064 ret += label_fun(dst+ret, decoded->params.immed, data);
1627 strcat(dst+ret, ".w"); 2065 strcat(dst+ret, ".w");
1628 ret = ret + 2; 2066 ret = ret + 2;
1629 } else { 2067 } else {
1649 } else { 2087 } else {
1650 ret = sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement); 2088 ret = sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement);
1651 } 2089 }
1652 break; 2090 break;
1653 case MODE_PC_INDEX_DISP8: 2091 case MODE_PC_INDEX_DISP8:
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'); 2092 #ifdef M68020
2093 if (decoded->params.regs.scale)
2094 {
2095 ret = sprintf(dst, "%s (%d, pc, %c%d.%c*%d)", 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', 1 << decoded->params.regs.scale);
2096 } else {
2097 #endif
2098 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');
2099 #ifdef M68020
2100 }
2101 #endif
2102 break;
2103 #ifdef M68020
2104 case MODE_PC_INDEX_BASE_DISP:
2105 if (decoded->params.regs.disp_sizes > 1)
2106 {
2107 ret = sprintf(dst, "%s (%d.%c, pc, %c%d.%c*%d)", c, decoded->params.regs.displacement,
2108 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l',
2109 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2110 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
2111 } else {
2112 ret = sprintf(dst, "%s (pc, %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2113 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2114 1 << decoded->params.regs.scale);
2115 }
2116 break;
2117 case MODE_PC_PREINDEX:
2118 switch (decoded->params.regs.disp_sizes)
2119 {
2120 case 0x11:
2121 //no base displacement or outer displacement
2122 ret = sprintf(dst, "%s ([pc, %c%d.%c*%d])", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2123 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2124 1 << decoded->params.regs.scale);
2125 break;
2126 case 0x12:
2127 case 0x13:
2128 //base displacement only
2129 ret = sprintf(dst, "%s ([%d.%c, pc, %c%d.%c*%d])", c, decoded->params.regs.displacement,
2130 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2131 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2132 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
2133 break;
2134 case 0x21:
2135 case 0x31:
2136 //outer displacement only
2137 ret = sprintf(dst, "%s ([pc, %c%d.%c*%d], %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2138 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2139 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp,
2140 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2141 break;
2142 case 0x22:
2143 case 0x23:
2144 case 0x32:
2145 case 0x33:
2146 //both outer and inner displacement
2147 ret = sprintf(dst, "%s ([%d.%c, pc, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement,
2148 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2149 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2150 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
2151 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2152 break;
2153 }
2154 break;
2155 case MODE_PC_POSTINDEX:
2156 switch (decoded->params.regs.disp_sizes)
2157 {
2158 case 0x11:
2159 //no base displacement or outer displacement
2160 ret = sprintf(dst, "%s ([pc], %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2161 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2162 1 << decoded->params.regs.scale);
2163 break;
2164 case 0x12:
2165 case 0x13:
2166 //base displacement only
2167 ret = sprintf(dst, "%s ([%d.%c, pc], %c%d.%c*%d)", c, decoded->params.regs.displacement,
2168 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2169 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2170 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
2171 break;
2172 case 0x21:
2173 case 0x31:
2174 //outer displacement only
2175 ret = sprintf(dst, "%s ([pc], %c%d.%c*%d, %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2176 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2177 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp,
2178 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2179 break;
2180 case 0x22:
2181 case 0x23:
2182 case 0x32:
2183 case 0x33:
2184 //both outer and inner displacement
2185 ret = sprintf(dst, "%s ([%d.%c, pc], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement,
2186 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2187 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2188 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
2189 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2190 break;
2191 }
2192 break;
2193 case MODE_PC_MEM_INDIRECT:
2194 switch (decoded->params.regs.disp_sizes)
2195 {
2196 case 0x11:
2197 //no base displacement or outer displacement
2198 ret = sprintf(dst, "%s ([pc])", c);
2199 break;
2200 case 0x12:
2201 case 0x13:
2202 //base displacement only
2203 ret = sprintf(dst, "%s ([%d.%c, pc])", c, decoded->params.regs.displacement,
2204 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l');
2205 break;
2206 case 0x21:
2207 case 0x31:
2208 //outer displacement only
2209 ret = sprintf(dst, "%s ([pc], %d.%c)", c, decoded->params.regs.outer_disp,
2210 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2211 break;
2212 case 0x22:
2213 case 0x23:
2214 case 0x32:
2215 case 0x33:
2216 //both outer and inner displacement
2217 ret = sprintf(dst, "%s ([%d.%c, pc], %d.%c)", c, decoded->params.regs.displacement,
2218 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.outer_disp,
2219 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2220 break;
2221 }
2222 break;
2223 case MODE_PC_BASE_DISP:
2224 if (decoded->params.regs.disp_sizes > 1)
2225 {
2226 ret = sprintf(dst, "%s (%d.%c, pc)", c, decoded->params.regs.displacement,
2227 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l');
2228 } else {
2229 ret = sprintf(dst, "%s (pc)", c);
2230 }
2231 break;
2232 case MODE_ZPC_INDEX_BASE_DISP:
2233 if (decoded->params.regs.disp_sizes > 1)
2234 {
2235 ret = sprintf(dst, "%s (%d.%c, zpc, %c%d.%c*%d)", c, decoded->params.regs.displacement,
2236 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l',
2237 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2238 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
2239 } else {
2240 ret = sprintf(dst, "%s (zpc, %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2241 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2242 1 << decoded->params.regs.scale);
2243 }
2244 break;
2245 case MODE_ZPC_PREINDEX:
2246 switch (decoded->params.regs.disp_sizes)
2247 {
2248 case 0x11:
2249 //no base displacement or outer displacement
2250 ret = sprintf(dst, "%s ([zpc, %c%d.%c*%d])", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2251 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2252 1 << decoded->params.regs.scale);
2253 break;
2254 case 0x12:
2255 case 0x13:
2256 //base displacement only
2257 ret = sprintf(dst, "%s ([%d.%c, zpc, %c%d.%c*%d])", c, decoded->params.regs.displacement,
2258 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2259 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2260 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
2261 break;
2262 case 0x21:
2263 case 0x31:
2264 //outer displacement only
2265 ret = sprintf(dst, "%s ([zpc, %c%d.%c*%d], %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2266 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2267 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp,
2268 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2269 break;
2270 case 0x22:
2271 case 0x23:
2272 case 0x32:
2273 case 0x33:
2274 //both outer and inner displacement
2275 ret = sprintf(dst, "%s ([%d.%c, zpc, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement,
2276 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2277 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2278 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
2279 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2280 break;
2281 }
2282 break;
2283 case MODE_ZPC_POSTINDEX:
2284 switch (decoded->params.regs.disp_sizes)
2285 {
2286 case 0x11:
2287 //no base displacement or outer displacement
2288 ret = sprintf(dst, "%s ([zpc], %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2289 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2290 1 << decoded->params.regs.scale);
2291 break;
2292 case 0x12:
2293 case 0x13:
2294 //base displacement only
2295 ret = sprintf(dst, "%s ([%d.%c, zpc], %c%d.%c*%d)", c, decoded->params.regs.displacement,
2296 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2297 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2298 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale);
2299 break;
2300 case 0x21:
2301 case 0x31:
2302 //outer displacement only
2303 ret = sprintf(dst, "%s ([zpc], %c%d.%c*%d, %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd',
2304 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w',
2305 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp,
2306 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2307 break;
2308 case 0x22:
2309 case 0x23:
2310 case 0x32:
2311 case 0x33:
2312 //both outer and inner displacement
2313 ret = sprintf(dst, "%s ([%d.%c, zpc], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement,
2314 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l',
2315 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7,
2316 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale,
2317 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2318 break;
2319 }
2320 break;
2321 case MODE_ZPC_MEM_INDIRECT:
2322 switch (decoded->params.regs.disp_sizes)
2323 {
2324 case 0x11:
2325 //no base displacement or outer displacement
2326 ret = sprintf(dst, "%s ([zpc])", c);
2327 break;
2328 case 0x12:
2329 case 0x13:
2330 //base displacement only
2331 ret = sprintf(dst, "%s ([%d.%c, zpc])", c, decoded->params.regs.displacement,
2332 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l');
2333 break;
2334 case 0x21:
2335 case 0x31:
2336 //outer displacement only
2337 ret = sprintf(dst, "%s ([zpc], %d.%c)", c, decoded->params.regs.outer_disp,
2338 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2339 break;
2340 case 0x22:
2341 case 0x23:
2342 case 0x32:
2343 case 0x33:
2344 //both outer and inner displacement
2345 ret = sprintf(dst, "%s ([%d.%c, zpc], %d.%c)", c, decoded->params.regs.displacement,
2346 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.outer_disp,
2347 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l');
2348 break;
2349 }
2350 break;
2351 case MODE_ZPC_BASE_DISP:
2352 if (decoded->params.regs.disp_sizes > 1)
2353 {
2354 ret = sprintf(dst, "%s (%d.%c, zpc)", c, decoded->params.regs.displacement,
2355 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l');
2356 } else {
2357 ret = sprintf(dst, "%s (zpc)", c);
2358 }
2359 break;
2360 #endif
1655 default: 2361 default:
1656 ret = 0; 2362 ret = 0;
1657 } 2363 }
1658 #ifdef M68020 2364 #ifdef M68020
1659 if (decoded->addr_mode & M68K_FLAG_BITFIELD) 2365 if (decoded->addr_mode & M68K_FLAG_BITFIELD)