Mercurial > repos > blastem
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) |