Mercurial > repos > blastem
comparison 68kinst.c @ 8:23b83d94c633
Finish bit/movep/immediate group except for 68020 instructions
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 09 Nov 2012 22:01:26 -0800 |
parents | 85699517043f |
children | 0a0cd3705c19 |
comparison
equal
deleted
inserted
replaced
7:a74c2969e8f3 | 8:23b83d94c633 |
---|---|
122 break; | 122 break; |
123 } | 123 } |
124 decoded->src.addr_mode = MODE_REG; | 124 decoded->src.addr_mode = MODE_REG; |
125 decoded->src.params.regs.pri = m68K_reg_quick_field(*istream); | 125 decoded->src.params.regs.pri = m68K_reg_quick_field(*istream); |
126 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->dst)); | 126 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->dst)); |
127 } else if ((*istream & 0xF00) == 0x800) { | |
128 } else if ((*istream & 0xC0) == 0xC0) { | |
129 #ifdef M68020 | |
130 //CMP2, CHK2, CAS, CAS2, RTM, CALLM | |
131 #endif | |
127 } else { | 132 } else { |
128 switch ((*istream >> 9) & 0x7) | 133 switch ((*istream >> 9) & 0x7) |
129 { | 134 { |
130 case 0: | 135 case 0: |
131 if ((*istream & 0xFF) == 0x3C) { | 136 if ((*istream & 0xFF) == 0x3C) { |
137 decoded->op = M68K_ORI_SR; | 142 decoded->op = M68K_ORI_SR; |
138 decoded->extra.size = OPSIZE_WORD; | 143 decoded->extra.size = OPSIZE_WORD; |
139 decoded->src.addr_mode = MODE_IMMEDIATE; | 144 decoded->src.addr_mode = MODE_IMMEDIATE; |
140 decoded->src.params.u16 = *(++istream); | 145 decoded->src.params.u16 = *(++istream); |
141 } else { | 146 } else { |
142 //ORI, CMP2.b, CHK2.b | 147 decoded->op = M68K_OR; |
143 if ((*istream & 0xC0) != 0xC0) { | 148 decoded->variant = VAR_IMMEDIATE; |
144 decoded->op = M68K_OR; | 149 decoded->src.addr_mode = MODE_IMMEDIATE; |
145 decoded->src.addr_mode = MODE_IMMEDIATE; | 150 decoded->extra.size = size = (*istream >> 6) & 3; |
146 decoded->extra.size = size = (*istream >> 6) & 3; | 151 reg = *istream & 0x7; |
147 reg = *istream & 0x7; | 152 opmode = (*istream >> 3) & 0x7; |
148 opmode = (*istream >> 3) & 0x7; | 153 switch (size) |
149 switch (size) | 154 { |
150 { | 155 case OPSIZE_BYTE: |
151 case OPSIZE_BYTE: | 156 decoded->src.params.u8 = *(++istream); |
152 decoded->src.params.u8 = *(++istream); | 157 break; |
153 break; | 158 case OPSIZE_WORD: |
154 case OPSIZE_WORD: | 159 decoded->src.params.u16 = *(++istream); |
155 decoded->src.params.16 = *(++istream); | 160 break; |
156 break; | 161 case OPSIZE_LONG: |
157 case OPSIZE_LONG: | 162 immed = *(++istream); |
158 immed = *(++istream); | 163 decoded->src.params.u32 = immed << 16 | *(++istream); |
159 decoded->src.params.u32 = immed << 16 | *(++istream); | 164 break; |
160 break; | |
161 } | |
162 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
163 } else { | |
164 #ifdef M68020 | |
165 //TODO: Implement me for 68020 support | |
166 #endif | |
167 } | 165 } |
166 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
168 } | 167 } |
169 break; | 168 break; |
170 case 1: | 169 case 1: |
171 //ANDI, ANDI to CCR, ANDI to SR, CMP2.w CHK2.w | 170 //ANDI, ANDI to CCR, ANDI to SR |
172 if ((*istream & 0xFF) == 0x3C) { | 171 if ((*istream & 0xFF) == 0x3C) { |
173 decoded->op = M68K_ANDI_CCR; | 172 decoded->op = M68K_ANDI_CCR; |
174 decoded->extra.size = OPSIZE_BYTE; | 173 decoded->extra.size = OPSIZE_BYTE; |
175 decoded->src.addr_mode = MODE_IMMEDIATE; | 174 decoded->src.addr_mode = MODE_IMMEDIATE; |
176 decoded->src.params.u8 = *(++istream); | 175 decoded->src.params.u8 = *(++istream); |
178 decoded->op = M68K_ANDI_SR; | 177 decoded->op = M68K_ANDI_SR; |
179 decoded->extra.size = OPSIZE_WORD; | 178 decoded->extra.size = OPSIZE_WORD; |
180 decoded->src.addr_mode = MODE_IMMEDIATE; | 179 decoded->src.addr_mode = MODE_IMMEDIATE; |
181 decoded->src.params.u16 = *(++istream); | 180 decoded->src.params.u16 = *(++istream); |
182 } else { | 181 } else { |
183 //ANDI, CMP2.w, CHK2.w | 182 decoded->op = M68K_AND; |
184 if ((*istream & 0xC0) != 0xC0) { | 183 decoded->variant = VAR_IMMEDIATE; |
185 decoded->op = M68K_AND; | |
186 decoded->src.addr_mode = MODE_IMMEDIATE; | |
187 decoded->extra.size = size = (*istream >> 6) & 3; | |
188 reg = *istream & 0x7; | |
189 opmode = (*istream >> 3) & 0x7; | |
190 switch (size) | |
191 { | |
192 case OPSIZE_BYTE: | |
193 decoded->src.params.u8 = *(++istream); | |
194 break; | |
195 case OPSIZE_WORD: | |
196 decoded->src.params.16 = *(++istream); | |
197 break; | |
198 case OPSIZE_LONG: | |
199 immed = *(++istream); | |
200 decoded->src.params.u32 = immed << 16 | *(++istream); | |
201 break; | |
202 } | |
203 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
204 } else { | |
205 #ifdef M68020 | |
206 //TODO: Implement me for 68020 support | |
207 #endif | |
208 } | |
209 } | |
210 break; | |
211 case 2: | |
212 //SUBI, CMP2.l, CHK2.l | |
213 if ((*istream & 0xC0) != 0xC0) { | |
214 decoded->op = M68K_SUB; | |
215 decoded->src.addr_mode = MODE_IMMEDIATE; | 184 decoded->src.addr_mode = MODE_IMMEDIATE; |
216 decoded->extra.size = size = (*istream >> 6) & 3; | 185 decoded->extra.size = size = (*istream >> 6) & 3; |
217 reg = *istream & 0x7; | 186 reg = *istream & 0x7; |
218 opmode = (*istream >> 3) & 0x7; | 187 opmode = (*istream >> 3) & 0x7; |
219 switch (size) | 188 switch (size) |
220 { | 189 { |
221 case OPSIZE_BYTE: | 190 case OPSIZE_BYTE: |
222 decoded->src.params.u8 = *(++istream); | 191 decoded->src.params.u8 = *(++istream); |
223 break; | 192 break; |
224 case OPSIZE_WORD: | 193 case OPSIZE_WORD: |
225 decoded->src.params.16 = *(++istream); | 194 decoded->src.params.u16 = *(++istream); |
226 break; | 195 break; |
227 case OPSIZE_LONG: | 196 case OPSIZE_LONG: |
228 immed = *(++istream); | 197 immed = *(++istream); |
229 decoded->src.params.u32 = immed << 16 | *(++istream); | 198 decoded->src.params.u32 = immed << 16 | *(++istream); |
230 break; | 199 break; |
231 } | 200 } |
232 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 201 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
233 } else { | 202 } |
234 #ifdef M68020 | 203 break; |
235 //TODO: Implement me for 68020 support | 204 case 2: |
236 #endif | 205 decoded->op = M68K_SUB; |
237 } | 206 decoded->variant = VAR_IMMEDIATE; |
207 decoded->src.addr_mode = MODE_IMMEDIATE; | |
208 decoded->extra.size = size = (*istream >> 6) & 3; | |
209 reg = *istream & 0x7; | |
210 opmode = (*istream >> 3) & 0x7; | |
211 switch (size) | |
212 { | |
213 case OPSIZE_BYTE: | |
214 decoded->src.params.u8 = *(++istream); | |
215 break; | |
216 case OPSIZE_WORD: | |
217 decoded->src.params.u16 = *(++istream); | |
218 break; | |
219 case OPSIZE_LONG: | |
220 immed = *(++istream); | |
221 decoded->src.params.u32 = immed << 16 | *(++istream); | |
222 break; | |
223 } | |
224 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
238 break; | 225 break; |
239 case 3: | 226 case 3: |
240 //RTM, CALLM, ADDI | 227 decoded->op = M68K_ADD; |
241 if ((*istream & 0xC0) != 0xC0) { | 228 decoded->variant = VAR_IMMEDIATE; |
242 decoded->op = M68K_ADD; | 229 decoded->src.addr_mode = MODE_IMMEDIATE; |
243 decoded->src.addr_mode = MODE_IMMEDIATE; | 230 decoded->extra.size = size = (*istream >> 6) & 3; |
244 decoded->extra.size = size = (*istream >> 6) & 3; | 231 reg = *istream & 0x7; |
245 reg = *istream & 0x7; | 232 opmode = (*istream >> 3) & 0x7; |
246 opmode = (*istream >> 3) & 0x7; | 233 switch (size) |
247 switch (size) | 234 { |
248 { | 235 case OPSIZE_BYTE: |
249 case OPSIZE_BYTE: | 236 decoded->src.params.u8 = *(++istream); |
250 decoded->src.params.u8 = *(++istream); | 237 break; |
251 break; | 238 case OPSIZE_WORD: |
252 case OPSIZE_WORD: | 239 decoded->src.params.u16 = *(++istream); |
253 decoded->src.params.16 = *(++istream); | 240 break; |
254 break; | 241 case OPSIZE_LONG: |
255 case OPSIZE_LONG: | 242 immed = *(++istream); |
256 immed = *(++istream); | 243 decoded->src.params.u32 = immed << 16 | *(++istream); |
257 decoded->src.params.u32 = immed << 16 | *(++istream); | 244 break; |
258 break; | 245 } |
259 } | 246 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
260 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
261 } else { | |
262 #ifdef M68020 | |
263 //TODO: Implement me for 68020 support | |
264 #endif | |
265 } | |
266 break; | 247 break; |
267 case 4: | 248 case 4: |
268 //BTST, BCHG, BCLR, BSET | 249 //BTST, BCHG, BCLR, BSET |
269 switch ((*istream >> 6) & 0x3) | 250 switch ((*istream >> 6) & 0x3) |
270 { | 251 { |
296 decoded->op = M68K_EORI_SR; | 277 decoded->op = M68K_EORI_SR; |
297 decoded->extra.size = OPSIZE_WORD; | 278 decoded->extra.size = OPSIZE_WORD; |
298 decoded->src.addr_mode = MODE_IMMEDIATE; | 279 decoded->src.addr_mode = MODE_IMMEDIATE; |
299 decoded->src.params.u16 = *(++istream); | 280 decoded->src.params.u16 = *(++istream); |
300 } else { | 281 } else { |
301 //EORI, CMP2.w, CHK2.w | 282 decoded->op = M68K_EOR; |
302 if ((*istream & 0xC0) != 0xC0) { | 283 decoded->variant = VAR_IMMEDIATE; |
303 decoded->op = M68K_EOR; | 284 decoded->src.addr_mode = MODE_IMMEDIATE; |
304 decoded->src.addr_mode = MODE_IMMEDIATE; | 285 decoded->extra.size = size = (*istream >> 6) & 3; |
305 decoded->extra.size = size = (*istream >> 6) & 3; | 286 reg = *istream & 0x7; |
306 reg = *istream & 0x7; | 287 opmode = (*istream >> 3) & 0x7; |
307 opmode = (*istream >> 3) & 0x7; | 288 switch (size) |
308 switch (size) | 289 { |
309 { | 290 case OPSIZE_BYTE: |
310 case OPSIZE_BYTE: | 291 decoded->src.params.u8 = *(++istream); |
311 decoded->src.params.u8 = *(++istream); | 292 break; |
312 break; | 293 case OPSIZE_WORD: |
313 case OPSIZE_WORD: | 294 decoded->src.params.u16 = *(++istream); |
314 decoded->src.params.16 = *(++istream); | 295 break; |
315 break; | 296 case OPSIZE_LONG: |
316 case OPSIZE_LONG: | 297 immed = *(++istream); |
317 immed = *(++istream); | 298 decoded->src.params.u32 = immed << 16 | *(++istream); |
318 decoded->src.params.u32 = immed << 16 | *(++istream); | 299 break; |
319 break; | |
320 } | |
321 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
322 } | 300 } |
301 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
323 } | 302 } |
324 break; | 303 break; |
325 case 6: | 304 case 6: |
305 decoded->op = M68K_CMP; | |
306 decoded->variant = VAR_IMMEDIATE; | |
307 decoded->extra.size = (*istream >> 6) & 0x3; | |
308 decoded->src.addr_mode = MODE_IMMEDIATE; | |
309 reg = *istream & 0x7; | |
310 opmode = (*istream >> 3) & 0x7; | |
311 switch (decoded->extra.size) | |
312 { | |
313 case OPSIZE_BYTE: | |
314 decoded->src.params.u8 = *(++istream); | |
315 break; | |
316 case OPSIZE_WORD: | |
317 decoded->src.params.u16 = *(++istream); | |
318 break; | |
319 case OPSIZE_LONG: | |
320 immed = *(++istream); | |
321 decoded->src.params.u32 = (immed << 16) | *(++istream); | |
322 break; | |
323 } | |
324 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | |
325 break; | |
326 case 7: | |
327 //MOVEP | |
328 deocded->op = M68K_MOVEP; | |
329 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; | |
330 if (*istream & 0x80) { | |
331 //memory dest | |
332 decoded->src.addr_mode = MODE_REG; | |
333 decoded->src.params.regs.pri = m68K_reg_quick_field(*istream); | |
334 decoded->dst.addr_mode = MODE_AREG_DISPLACE; | |
335 decoded->dst.params.regs.pri = *istream & 0x7; | |
336 } else { | |
337 //memory source | |
338 decoded->dst.addr_mode = MODE_REG; | |
339 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); | |
340 decoded->sr.addr_mode = MODE_AREG_DISPLACE; | |
341 decoded->sr.params.regs.pri = *istream & 0x7; | |
342 } | |
343 immed = *(++istream); | |
326 | 344 |
327 break; | |
328 case 7: | |
329 break; | 345 break; |
330 } | 346 } |
331 } | 347 } |
332 break; | 348 break; |
333 case MOVE_BYTE: | 349 case MOVE_BYTE: |
858 ret = sprintf(dst, "bsr%s", decoded->variant == VAR_BYTE ? ".s" : ""); | 874 ret = sprintf(dst, "bsr%s", decoded->variant == VAR_BYTE ? ".s" : ""); |
859 } else { | 875 } else { |
860 size = decoded->extra.size; | 876 size = decoded->extra.size; |
861 ret = sprintf(dst, "%s%s.%c", | 877 ret = sprintf(dst, "%s%s.%c", |
862 mnemonics[decoded->op], | 878 mnemonics[decoded->op], |
863 decoded->variant == VAR_QUICK ? "q" : "", | 879 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), |
864 decoded->extra.size == OPSIZE_BYTE ? 'b' : (size == OPSIZE_WORD ? 'w' : 'l')); | 880 decoded->extra.size == OPSIZE_BYTE ? 'b' : (size == OPSIZE_WORD ? 'w' : 'l')); |
865 } | 881 } |
866 op1len = m68K_disasm_op(&(decoded->src), size, dst + ret, 0); | 882 op1len = m68K_disasm_op(&(decoded->src), size, dst + ret, 0); |
867 ret += op1len; | 883 ret += op1len; |
868 ret += m68K_disasm_op(&(decoded->dst), size, dst + ret, op1len); | 884 ret += m68K_disasm_op(&(decoded->dst), size, dst + ret, op1len); |