Mercurial > repos > blastem
comparison 68kinst.c @ 2133:8554751f17b5
Remove use of get_native_pointer in 68K instruction decoding in preparation for word RAM interleaving
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 17 Mar 2022 22:41:42 -0700 |
parents | dc1eab3ec092 |
children | 53411df7fc71 |
comparison
equal
deleted
inserted
replaced
2132:7451f970ee66 | 2133:8554751f17b5 |
---|---|
15 uint32_t sign_extend8(uint32_t val) | 15 uint32_t sign_extend8(uint32_t val) |
16 { | 16 { |
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 #define INVALID_ADDRESS 0xFFFFFFFF |
21 | |
22 uint32_t m68k_decode_op_ex(uint16_t opcode, uint32_t address, m68k_fetch_fun fetch, void *data, uint8_t mode, uint8_t reg, uint8_t size, m68k_op_info *dst) | |
21 { | 23 { |
22 uint16_t ext, tmp; | 24 uint16_t ext, tmp; |
23 dst->addr_mode = mode; | 25 dst->addr_mode = mode; |
24 switch(mode) | 26 switch(mode) |
25 { | 27 { |
29 case MODE_AREG_POSTINC: | 31 case MODE_AREG_POSTINC: |
30 case MODE_AREG_PREDEC: | 32 case MODE_AREG_PREDEC: |
31 dst->params.regs.pri = reg; | 33 dst->params.regs.pri = reg; |
32 break; | 34 break; |
33 case MODE_AREG_DISPLACE: | 35 case MODE_AREG_DISPLACE: |
34 ext = *(++cur); | 36 ext = fetch(address, data); |
37 address += 2; | |
35 dst->params.regs.pri = reg; | 38 dst->params.regs.pri = reg; |
36 dst->params.regs.displacement = sign_extend16(ext); | 39 dst->params.regs.displacement = sign_extend16(ext); |
37 break; | 40 break; |
38 case MODE_AREG_INDEX_MEM: | 41 case MODE_AREG_INDEX_MEM: |
39 dst->params.regs.pri = reg; | 42 dst->params.regs.pri = reg; |
40 ext = *(++cur); | 43 ext = fetch(address, data); |
44 address += 2; | |
41 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit | 45 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit |
42 #ifdef M68020 | 46 #ifdef M68020 |
43 dst->params.regs.scale = ext >> 9 & 3; | 47 dst->params.regs.scale = ext >> 9 & 3; |
44 if (ext & 0x100) | 48 if (ext & 0x100) |
45 { | 49 { |
46 dst->params.regs.disp_sizes = ext >> 4 & 3; | 50 dst->params.regs.disp_sizes = ext >> 4 & 3; |
47 switch (dst->params.regs.disp_sizes) | 51 switch (dst->params.regs.disp_sizes) |
48 { | 52 { |
49 case 0: | 53 case 0: |
50 //reserved | 54 //reserved |
51 return NULL; | 55 return INVALID_ADDRESS; |
52 case 1: | 56 case 1: |
53 dst->params.regs.displacement = 0; | 57 dst->params.regs.displacement = 0; |
54 break; | 58 break; |
55 case 2: | 59 case 2: |
56 dst->params.regs.displacement = sign_extend16(*(cur++)); | 60 dst->params.regs.displacement = sign_extend16(fetch(address, data)); |
61 address += 2; | |
57 break; | 62 break; |
58 case 3: | 63 case 3: |
59 tmp = *(cur++); | 64 tmp = fetch(address, data); |
60 dst->params.regs.displacement = tmp << 16 | *(cur++); | 65 address += 2; |
66 dst->params.regs.displacement = tmp << 16 | fetch(address, data); | |
67 address += 2; | |
61 break; | 68 break; |
62 } | 69 } |
63 if (ext & 0x3) | 70 if (ext & 0x3) |
64 { | 71 { |
65 //memory indirect | 72 //memory indirect |
87 dst->params.regs.disp_sizes |= ext << 4 & 0x30; | 94 dst->params.regs.disp_sizes |= ext << 4 & 0x30; |
88 switch (ext & 0x3) | 95 switch (ext & 0x3) |
89 { | 96 { |
90 case 0: | 97 case 0: |
91 //reserved | 98 //reserved |
92 return NULL; | 99 return INVALID_ADDRESS; |
93 case 1: | 100 case 1: |
94 dst->params.regs.outer_disp = 0; | 101 dst->params.regs.outer_disp = 0; |
95 break; | 102 break; |
96 case 2: | 103 case 2: |
97 dst->params.regs.outer_disp = sign_extend16(*(cur++)); | 104 dst->params.regs.outer_disp = sign_extend16(fetch(address, data)); |
105 address += 2; | |
98 break; | 106 break; |
99 case 3: | 107 case 3: |
100 tmp = *(cur++); | 108 tmp = fetch(address, data); |
101 dst->params.regs.outer_disp = tmp << 16 | *(cur++); | 109 address += 2; |
110 dst->params.regs.outer_disp = tmp << 16 | fetch(address, data); | |
111 address += 2; | |
102 break; | 112 break; |
103 } | 113 } |
104 } else { | 114 } else { |
105 switch (ext >> 6 & 3) | 115 switch (ext >> 6 & 3) |
106 { | 116 { |
129 case MODE_PC_INDIRECT_ABS_IMMED: | 139 case MODE_PC_INDIRECT_ABS_IMMED: |
130 switch(reg) | 140 switch(reg) |
131 { | 141 { |
132 case 0: | 142 case 0: |
133 dst->addr_mode = MODE_ABSOLUTE_SHORT; | 143 dst->addr_mode = MODE_ABSOLUTE_SHORT; |
134 ext = *(++cur); | 144 ext = fetch(address, data); |
145 address += 2; | |
135 dst->params.immed = sign_extend16(ext); | 146 dst->params.immed = sign_extend16(ext); |
136 break; | 147 break; |
137 case 1: | 148 case 1: |
138 dst->addr_mode = MODE_ABSOLUTE; | 149 dst->addr_mode = MODE_ABSOLUTE; |
139 ext = *(++cur); | 150 ext = fetch(address, data); |
140 dst->params.immed = ext << 16 | *(++cur); | 151 address += 2; |
152 dst->params.immed = ext << 16 | fetch(address, data); | |
153 address += 2; | |
141 break; | 154 break; |
142 case 3: | 155 case 3: |
143 ext = *(++cur); | 156 ext = fetch(address, data); |
157 address += 2; | |
144 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit | 158 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit |
145 #ifdef M68020 | 159 #ifdef M68020 |
146 dst->params.regs.scale = ext >> 9 & 3; | 160 dst->params.regs.scale = ext >> 9 & 3; |
147 if (ext & 0x100) | 161 if (ext & 0x100) |
148 { | 162 { |
149 dst->params.regs.disp_sizes = ext >> 4 & 3; | 163 dst->params.regs.disp_sizes = ext >> 4 & 3; |
150 switch (dst->params.regs.disp_sizes) | 164 switch (dst->params.regs.disp_sizes) |
151 { | 165 { |
152 case 0: | 166 case 0: |
153 //reserved | 167 //reserved |
154 return NULL; | 168 return INVALID_ADDRESS; |
155 case 1: | 169 case 1: |
156 dst->params.regs.displacement = 0; | 170 dst->params.regs.displacement = 0; |
157 break; | 171 break; |
158 case 2: | 172 case 2: |
159 dst->params.regs.displacement = sign_extend16(*(cur++)); | 173 dst->params.regs.displacement = sign_extend16(fetch(address, data)); |
174 address += 2; | |
160 break; | 175 break; |
161 case 3: | 176 case 3: |
162 tmp = *(cur++); | 177 tmp = *(cur++); |
163 dst->params.regs.displacement = tmp << 16 | *(cur++); | 178 dst->params.regs.displacement = tmp << 16 | fetch(address, data); |
179 address += 2; | |
164 break; | 180 break; |
165 } | 181 } |
166 if (ext & 0x3) | 182 if (ext & 0x3) |
167 { | 183 { |
168 //memory indirect | 184 //memory indirect |
190 dst->params.regs.disp_sizes |= ext << 4 & 0x30; | 206 dst->params.regs.disp_sizes |= ext << 4 & 0x30; |
191 switch (ext & 0x3) | 207 switch (ext & 0x3) |
192 { | 208 { |
193 case 0: | 209 case 0: |
194 //reserved | 210 //reserved |
195 return NULL; | 211 return INVALID_ADDRESS; |
196 case 1: | 212 case 1: |
197 dst->params.regs.outer_disp = 0; | 213 dst->params.regs.outer_disp = 0; |
198 break; | 214 break; |
199 case 2: | 215 case 2: |
200 dst->params.regs.outer_disp = sign_extend16(*(cur++)); | 216 dst->params.regs.outer_disp = sign_extend16(fetch(address, data)); |
217 address += 2; | |
201 break; | 218 break; |
202 case 3: | 219 case 3: |
203 tmp = *(cur++); | 220 tmp = fetch(address, data); |
204 dst->params.regs.outer_disp = tmp << 16 | *(cur++); | 221 address += 2; |
222 dst->params.regs.outer_disp = tmp << 16 | fetch(address, data); | |
223 address += 2; | |
205 break; | 224 break; |
206 } | 225 } |
207 } else { | 226 } else { |
208 switch (ext >> 6 & 3) | 227 switch (ext >> 6 & 3) |
209 { | 228 { |
229 } | 248 } |
230 #endif | 249 #endif |
231 break; | 250 break; |
232 case 2: | 251 case 2: |
233 dst->addr_mode = MODE_PC_DISPLACE; | 252 dst->addr_mode = MODE_PC_DISPLACE; |
234 ext = *(++cur); | 253 ext = fetch(address, data); |
254 address += 2; | |
235 dst->params.regs.displacement = sign_extend16(ext); | 255 dst->params.regs.displacement = sign_extend16(ext); |
236 break; | 256 break; |
237 case 4: | 257 case 4: |
238 dst->addr_mode = MODE_IMMEDIATE; | 258 dst->addr_mode = MODE_IMMEDIATE; |
239 ext = *(++cur); | 259 ext = fetch(address, data); |
260 address += 2; | |
240 switch (size) | 261 switch (size) |
241 { | 262 { |
242 case OPSIZE_BYTE: | 263 case OPSIZE_BYTE: |
243 dst->params.immed = ext & 0xFF; | 264 dst->params.immed = ext & 0xFF; |
244 break; | 265 break; |
245 case OPSIZE_WORD: | 266 case OPSIZE_WORD: |
246 dst->params.immed = ext; | 267 dst->params.immed = ext; |
247 break; | 268 break; |
248 case OPSIZE_LONG: | 269 case OPSIZE_LONG: |
249 dst->params.immed = ext << 16 | *(++cur); | 270 dst->params.immed = ext << 16 | fetch(address, data); |
271 address += 2; | |
250 break; | 272 break; |
251 } | 273 } |
252 break; | 274 break; |
253 default: | 275 default: |
254 return NULL; | 276 return INVALID_ADDRESS; |
255 } | 277 } |
256 break; | 278 break; |
257 } | 279 } |
258 return cur; | 280 return address; |
259 } | 281 } |
260 | 282 |
261 uint8_t m68k_valid_immed_dst(m68k_op_info *dst) | 283 uint8_t m68k_valid_immed_dst(m68k_op_info *dst) |
262 { | 284 { |
263 if (dst->addr_mode == MODE_AREG || dst->addr_mode == MODE_IMMEDIATE) { | 285 if (dst->addr_mode == MODE_AREG || dst->addr_mode == MODE_IMMEDIATE) { |
288 return 0; | 310 return 0; |
289 } | 311 } |
290 return m68k_valid_immed_limited_dst(dst); | 312 return m68k_valid_immed_limited_dst(dst); |
291 } | 313 } |
292 | 314 |
293 uint16_t *m68k_decode_op(uint16_t *cur, uint8_t size, m68k_op_info *dst) | 315 uint32_t m68k_decode_op(uint16_t opcode, uint32_t address, m68k_fetch_fun fetch, void *data, uint8_t size, m68k_op_info *dst) |
294 { | 316 { |
295 uint8_t mode = (*cur >> 3) & 0x7; | 317 uint8_t mode = (opcode >> 3) & 0x7; |
296 uint8_t reg = *cur & 0x7; | 318 uint8_t reg = opcode & 0x7; |
297 return m68k_decode_op_ex(cur, mode, reg, size, dst); | 319 return m68k_decode_op_ex(opcode, address, fetch, data, mode, reg, size, dst); |
298 } | 320 } |
299 | 321 |
300 void m68k_decode_cond(uint16_t op, m68kinst * decoded) | 322 void m68k_decode_cond(uint16_t op, m68kinst * decoded) |
301 { | 323 { |
302 decoded->extra.cond = (op >> 0x8) & 0xF; | 324 decoded->extra.cond = (op >> 0x8) & 0xF; |
305 uint8_t m68k_reg_quick_field(uint16_t op) | 327 uint8_t m68k_reg_quick_field(uint16_t op) |
306 { | 328 { |
307 return (op >> 9) & 0x7; | 329 return (op >> 9) & 0x7; |
308 } | 330 } |
309 | 331 |
310 uint16_t * m68k_decode(uint16_t * istream, m68kinst * decoded, uint32_t address) | 332 uint32_t m68k_decode(m68k_fetch_fun fetch, void *data, m68kinst * decoded, uint32_t address) |
311 { | 333 { |
312 uint16_t *start = istream; | 334 uint32_t start_address = address; |
313 uint8_t optype = *istream >> 12; | 335 uint16_t opcode = fetch(address, data); |
336 address += 2; | |
337 uint8_t optype = opcode >> 12; | |
314 uint8_t size; | 338 uint8_t size; |
315 uint8_t reg; | 339 uint8_t reg; |
316 uint8_t opmode; | 340 uint8_t opmode; |
317 uint32_t immed; | 341 uint32_t immed; |
318 decoded->op = M68K_INVALID; | 342 decoded->op = M68K_INVALID; |
319 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_UNUSED; | 343 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_UNUSED; |
320 decoded->variant = VAR_NORMAL; | 344 decoded->variant = VAR_NORMAL; |
321 decoded->address = address; | 345 decoded->address = start_address; |
322 switch(optype) | 346 switch(optype) |
323 { | 347 { |
324 case BIT_MOVEP_IMMED: | 348 case BIT_MOVEP_IMMED: |
325 if ((*istream & 0x138) == 0x108) { | 349 if ((opcode & 0x138) == 0x108) { |
326 //MOVEP | 350 //MOVEP |
327 decoded->op = M68K_MOVEP; | 351 decoded->op = M68K_MOVEP; |
328 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; | 352 decoded->extra.size = opcode & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; |
329 if (*istream & 0x80) { | 353 if (opcode & 0x80) { |
330 //memory dest | 354 //memory dest |
331 decoded->src.addr_mode = MODE_REG; | 355 decoded->src.addr_mode = MODE_REG; |
332 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 356 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode); |
333 decoded->dst.addr_mode = MODE_AREG_DISPLACE; | 357 decoded->dst.addr_mode = MODE_AREG_DISPLACE; |
334 decoded->dst.params.regs.pri = *istream & 0x7; | 358 decoded->dst.params.regs.pri = opcode & 0x7; |
335 decoded->dst.params.regs.displacement = *(++istream); | 359 decoded->dst.params.regs.displacement = fetch(address, data); |
360 address += 2; | |
336 } else { | 361 } else { |
337 //memory source | 362 //memory source |
338 decoded->dst.addr_mode = MODE_REG; | 363 decoded->dst.addr_mode = MODE_REG; |
339 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 364 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
340 decoded->src.addr_mode = MODE_AREG_DISPLACE; | 365 decoded->src.addr_mode = MODE_AREG_DISPLACE; |
341 decoded->src.params.regs.pri = *istream & 0x7; | 366 decoded->src.params.regs.pri = opcode & 0x7; |
342 decoded->src.params.regs.displacement = *(++istream); | 367 decoded->src.params.regs.displacement = fetch(address, data); |
343 } | 368 address += 2; |
344 } else if (*istream & 0x100) { | 369 } |
370 } else if (opcode & 0x100) { | |
345 //BTST, BCHG, BCLR, BSET | 371 //BTST, BCHG, BCLR, BSET |
346 switch ((*istream >> 6) & 0x3) | 372 switch ((opcode >> 6) & 0x3) |
347 { | 373 { |
348 case 0: | 374 case 0: |
349 decoded->op = M68K_BTST; | 375 decoded->op = M68K_BTST; |
350 break; | 376 break; |
351 case 1: | 377 case 1: |
357 case 3: | 383 case 3: |
358 decoded->op = M68K_BSET; | 384 decoded->op = M68K_BSET; |
359 break; | 385 break; |
360 } | 386 } |
361 decoded->src.addr_mode = MODE_REG; | 387 decoded->src.addr_mode = MODE_REG; |
362 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 388 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode); |
363 decoded->extra.size = OPSIZE_BYTE; | 389 decoded->extra.size = OPSIZE_BYTE; |
364 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); | 390 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->dst)); |
365 if ( | 391 if ( |
366 !istream || decoded->dst.addr_mode == MODE_AREG | 392 address == INVALID_ADDRESS || decoded->dst.addr_mode == MODE_AREG |
367 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) | 393 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) |
368 ) { | 394 ) { |
369 decoded->op = M68K_INVALID; | 395 decoded->op = M68K_INVALID; |
370 break; | 396 break; |
371 } | 397 } |
372 if (decoded->dst.addr_mode == MODE_REG) { | 398 if (decoded->dst.addr_mode == MODE_REG) { |
373 decoded->extra.size = OPSIZE_LONG; | 399 decoded->extra.size = OPSIZE_LONG; |
374 } | 400 } |
375 } else if ((*istream & 0xF00) == 0x800) { | 401 } else if ((opcode & 0xF00) == 0x800) { |
376 //BTST, BCHG, BCLR, BSET | 402 //BTST, BCHG, BCLR, BSET |
377 switch ((*istream >> 6) & 0x3) | 403 switch ((opcode >> 6) & 0x3) |
378 { | 404 { |
379 case 0: | 405 case 0: |
380 decoded->op = M68K_BTST; | 406 decoded->op = M68K_BTST; |
381 break; | 407 break; |
382 case 1: | 408 case 1: |
387 break; | 413 break; |
388 case 3: | 414 case 3: |
389 decoded->op = M68K_BSET; | 415 decoded->op = M68K_BSET; |
390 break; | 416 break; |
391 } | 417 } |
392 opmode = (*istream >> 3) & 0x7; | 418 opmode = (opcode >> 3) & 0x7; |
393 reg = *istream & 0x7; | 419 reg = opcode & 0x7; |
394 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; | 420 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; |
395 decoded->src.params.immed = *(++istream) & 0xFF; | 421 decoded->src.params.immed = fetch(address, data) & 0xFF; |
422 address += 2; | |
396 decoded->extra.size = OPSIZE_BYTE; | 423 decoded->extra.size = OPSIZE_BYTE; |
397 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 424 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst)); |
398 if ( | 425 if ( |
399 !istream || !m68k_valid_immed_dst(&decoded->dst) | 426 address == INVALID_ADDRESS || !m68k_valid_immed_dst(&decoded->dst) |
400 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) | 427 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) |
401 ) { | 428 ) { |
402 decoded->op = M68K_INVALID; | 429 decoded->op = M68K_INVALID; |
403 break; | 430 break; |
404 } | 431 } |
405 if (decoded->dst.addr_mode == MODE_REG) { | 432 if (decoded->dst.addr_mode == MODE_REG) { |
406 decoded->extra.size = OPSIZE_LONG; | 433 decoded->extra.size = OPSIZE_LONG; |
407 } | 434 } |
408 } else if ((*istream & 0xC0) == 0xC0) { | 435 } else if ((opcode & 0xC0) == 0xC0) { |
409 #ifdef M68020 | 436 #ifdef M68020 |
410 //CMP2, CHK2, CAS, CAS2, RTM, CALLM | 437 //CMP2, CHK2, CAS, CAS2, RTM, CALLM |
411 #endif | 438 #endif |
412 } else { | 439 } else { |
413 switch ((*istream >> 9) & 0x7) | 440 switch ((opcode >> 9) & 0x7) |
414 { | 441 { |
415 case 0: | 442 case 0: |
416 if ((*istream & 0xFF) == 0x3C) { | 443 if ((opcode & 0xFF) == 0x3C) { |
417 decoded->op = M68K_ORI_CCR; | 444 decoded->op = M68K_ORI_CCR; |
418 decoded->extra.size = OPSIZE_BYTE; | 445 decoded->extra.size = OPSIZE_BYTE; |
419 decoded->src.addr_mode = MODE_IMMEDIATE; | 446 decoded->src.addr_mode = MODE_IMMEDIATE; |
420 decoded->src.params.immed = *(++istream) & 0xFF; | 447 decoded->src.params.immed = fetch(address, data) & 0xFF; |
421 } else if((*istream & 0xFF) == 0x7C) { | 448 address += 2; |
449 } else if((opcode & 0xFF) == 0x7C) { | |
422 decoded->op = M68K_ORI_SR; | 450 decoded->op = M68K_ORI_SR; |
423 decoded->extra.size = OPSIZE_WORD; | 451 decoded->extra.size = OPSIZE_WORD; |
424 decoded->src.addr_mode = MODE_IMMEDIATE; | 452 decoded->src.addr_mode = MODE_IMMEDIATE; |
425 decoded->src.params.immed = *(++istream); | 453 decoded->src.params.immed = fetch(address, data); |
454 address += 2; | |
426 } else { | 455 } else { |
427 decoded->op = M68K_OR; | 456 decoded->op = M68K_OR; |
428 decoded->variant = VAR_IMMEDIATE; | 457 decoded->variant = VAR_IMMEDIATE; |
429 decoded->src.addr_mode = MODE_IMMEDIATE; | 458 decoded->src.addr_mode = MODE_IMMEDIATE; |
430 decoded->extra.size = size = (*istream >> 6) & 3; | 459 decoded->extra.size = size = (opcode >> 6) & 3; |
431 reg = *istream & 0x7; | 460 reg = opcode & 0x7; |
432 opmode = (*istream >> 3) & 0x7; | 461 opmode = (opcode >> 3) & 0x7; |
433 switch (size) | 462 switch (size) |
434 { | 463 { |
435 case OPSIZE_BYTE: | 464 case OPSIZE_BYTE: |
436 decoded->src.params.immed = *(++istream) & 0xFF; | 465 decoded->src.params.immed = fetch(address, data) & 0xFF; |
466 address += 2; | |
437 break; | 467 break; |
438 case OPSIZE_WORD: | 468 case OPSIZE_WORD: |
439 decoded->src.params.immed = *(++istream); | 469 decoded->src.params.immed = fetch(address, data); |
470 address += 2; | |
440 break; | 471 break; |
441 case OPSIZE_LONG: | 472 case OPSIZE_LONG: |
442 immed = *(++istream); | 473 immed = fetch(address, data); |
443 decoded->src.params.immed = immed << 16 | *(++istream); | 474 address += 2; |
475 decoded->src.params.immed = immed << 16 | fetch(address, data); | |
476 address += 2; | |
444 break; | 477 break; |
445 } | 478 } |
446 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 479 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst)); |
447 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | 480 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) { |
448 decoded->op = M68K_INVALID; | 481 decoded->op = M68K_INVALID; |
449 break; | 482 break; |
450 } | 483 } |
451 } | 484 } |
452 break; | 485 break; |
453 case 1: | 486 case 1: |
454 //ANDI, ANDI to CCR, ANDI to SR | 487 //ANDI, ANDI to CCR, ANDI to SR |
455 if ((*istream & 0xFF) == 0x3C) { | 488 if ((opcode & 0xFF) == 0x3C) { |
456 decoded->op = M68K_ANDI_CCR; | 489 decoded->op = M68K_ANDI_CCR; |
457 decoded->extra.size = OPSIZE_BYTE; | 490 decoded->extra.size = OPSIZE_BYTE; |
458 decoded->src.addr_mode = MODE_IMMEDIATE; | 491 decoded->src.addr_mode = MODE_IMMEDIATE; |
459 decoded->src.params.immed = *(++istream) & 0xFF; | 492 decoded->src.params.immed = fetch(address, data) & 0xFF; |
460 } else if((*istream & 0xFF) == 0x7C) { | 493 address += 2; |
494 } else if((opcode & 0xFF) == 0x7C) { | |
461 decoded->op = M68K_ANDI_SR; | 495 decoded->op = M68K_ANDI_SR; |
462 decoded->extra.size = OPSIZE_WORD; | 496 decoded->extra.size = OPSIZE_WORD; |
463 decoded->src.addr_mode = MODE_IMMEDIATE; | 497 decoded->src.addr_mode = MODE_IMMEDIATE; |
464 decoded->src.params.immed = *(++istream); | 498 decoded->src.params.immed = fetch(address, data); |
499 address += 2; | |
465 } else { | 500 } else { |
466 decoded->op = M68K_AND; | 501 decoded->op = M68K_AND; |
467 decoded->variant = VAR_IMMEDIATE; | 502 decoded->variant = VAR_IMMEDIATE; |
468 decoded->src.addr_mode = MODE_IMMEDIATE; | 503 decoded->src.addr_mode = MODE_IMMEDIATE; |
469 decoded->extra.size = size = (*istream >> 6) & 3; | 504 decoded->extra.size = size = (opcode >> 6) & 3; |
470 reg = *istream & 0x7; | 505 reg = opcode & 0x7; |
471 opmode = (*istream >> 3) & 0x7; | 506 opmode = (opcode >> 3) & 0x7; |
472 switch (size) | 507 switch (size) |
473 { | 508 { |
474 case OPSIZE_BYTE: | 509 case OPSIZE_BYTE: |
475 decoded->src.params.immed = *(++istream) & 0xFF; | 510 decoded->src.params.immed = fetch(address, data) & 0xFF; |
511 address += 2; | |
476 break; | 512 break; |
477 case OPSIZE_WORD: | 513 case OPSIZE_WORD: |
478 decoded->src.params.immed = *(++istream); | 514 decoded->src.params.immed = fetch(address, data); |
515 address += 2; | |
479 break; | 516 break; |
480 case OPSIZE_LONG: | 517 case OPSIZE_LONG: |
481 immed = *(++istream); | 518 immed = fetch(address, data); |
482 decoded->src.params.immed = immed << 16 | *(++istream); | 519 address += 2; |
520 decoded->src.params.immed = immed << 16 | fetch(address, data); | |
521 address += 2; | |
483 break; | 522 break; |
484 } | 523 } |
485 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 524 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst)); |
486 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | 525 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) { |
487 decoded->op = M68K_INVALID; | 526 decoded->op = M68K_INVALID; |
488 break; | 527 break; |
489 } | 528 } |
490 } | 529 } |
491 break; | 530 break; |
492 case 2: | 531 case 2: |
493 decoded->op = M68K_SUB; | 532 decoded->op = M68K_SUB; |
494 decoded->variant = VAR_IMMEDIATE; | 533 decoded->variant = VAR_IMMEDIATE; |
495 decoded->src.addr_mode = MODE_IMMEDIATE; | 534 decoded->src.addr_mode = MODE_IMMEDIATE; |
496 decoded->extra.size = size = (*istream >> 6) & 3; | 535 decoded->extra.size = size = (opcode >> 6) & 3; |
497 reg = *istream & 0x7; | 536 reg = opcode & 0x7; |
498 opmode = (*istream >> 3) & 0x7; | 537 opmode = (opcode >> 3) & 0x7; |
499 switch (size) | 538 switch (size) |
500 { | 539 { |
501 case OPSIZE_BYTE: | 540 case OPSIZE_BYTE: |
502 decoded->src.params.immed = *(++istream) & 0xFF; | 541 decoded->src.params.immed = fetch(address, data) & 0xFF; |
542 address += 2; | |
503 break; | 543 break; |
504 case OPSIZE_WORD: | 544 case OPSIZE_WORD: |
505 decoded->src.params.immed = *(++istream); | 545 decoded->src.params.immed = fetch(address, data); |
546 address += 2; | |
506 break; | 547 break; |
507 case OPSIZE_LONG: | 548 case OPSIZE_LONG: |
508 immed = *(++istream); | 549 immed = fetch(address, data); |
509 decoded->src.params.immed = immed << 16 | *(++istream); | 550 address += 2; |
510 break; | 551 decoded->src.params.immed = immed << 16 | fetch(address, data); |
511 } | 552 address += 2; |
512 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 553 break; |
513 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | 554 } |
555 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst)); | |
556 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | |
514 decoded->op = M68K_INVALID; | 557 decoded->op = M68K_INVALID; |
515 break; | 558 break; |
516 } | 559 } |
517 break; | 560 break; |
518 case 3: | 561 case 3: |
519 decoded->op = M68K_ADD; | 562 decoded->op = M68K_ADD; |
520 decoded->variant = VAR_IMMEDIATE; | 563 decoded->variant = VAR_IMMEDIATE; |
521 decoded->src.addr_mode = MODE_IMMEDIATE; | 564 decoded->src.addr_mode = MODE_IMMEDIATE; |
522 decoded->extra.size = size = (*istream >> 6) & 3; | 565 decoded->extra.size = size = (opcode >> 6) & 3; |
523 reg = *istream & 0x7; | 566 reg = opcode & 0x7; |
524 opmode = (*istream >> 3) & 0x7; | 567 opmode = (opcode >> 3) & 0x7; |
525 switch (size) | 568 switch (size) |
526 { | 569 { |
527 case OPSIZE_BYTE: | 570 case OPSIZE_BYTE: |
528 decoded->src.params.immed = *(++istream) & 0xFF; | 571 decoded->src.params.immed = fetch(address, data) & 0xFF; |
572 address += 2; | |
529 break; | 573 break; |
530 case OPSIZE_WORD: | 574 case OPSIZE_WORD: |
531 decoded->src.params.immed = *(++istream); | 575 decoded->src.params.immed = fetch(address, data); |
576 address += 2; | |
532 break; | 577 break; |
533 case OPSIZE_LONG: | 578 case OPSIZE_LONG: |
534 immed = *(++istream); | 579 immed = fetch(address, data); |
535 decoded->src.params.immed = immed << 16 | *(++istream); | 580 address += 2; |
536 break; | 581 decoded->src.params.immed = immed << 16 | fetch(address, data); |
537 } | 582 address += 2; |
538 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 583 break; |
539 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | 584 } |
585 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst)); | |
586 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | |
540 decoded->op = M68K_INVALID; | 587 decoded->op = M68K_INVALID; |
541 break; | 588 break; |
542 } | 589 } |
543 break; | 590 break; |
544 case 4: | 591 case 4: |
545 //BTST, BCHG, BCLR, BSET | 592 //BTST, BCHG, BCLR, BSET |
546 //Seems like this should be unnecessary since bit instructions are explicitly handled above | 593 //Seems like this should be unnecessary since bit instructions are explicitly handled above |
547 //Possible this is redundant or the case above is overly restrictive | 594 //Possible this is redundant or the case above is overly restrictive |
548 //TODO: Investigate whether this can be removed | 595 //TODO: Investigate whether this can be removed |
549 switch ((*istream >> 6) & 0x3) | 596 switch ((opcode >> 6) & 0x3) |
550 { | 597 { |
551 case 0: | 598 case 0: |
552 decoded->op = M68K_BTST; | 599 decoded->op = M68K_BTST; |
553 break; | 600 break; |
554 case 1: | 601 case 1: |
560 case 3: | 607 case 3: |
561 decoded->op = M68K_BSET; | 608 decoded->op = M68K_BSET; |
562 break; | 609 break; |
563 } | 610 } |
564 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; | 611 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; |
565 decoded->src.params.immed = *(++istream) & 0xFF; | 612 decoded->src.params.immed = fetch(address, data) & 0xFF; |
566 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 613 address += 2; |
614 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_BYTE, &(decoded->dst)); | |
567 if ( | 615 if ( |
568 !istream || !m68k_valid_immed_dst(&decoded->dst) | 616 address == INVALID_ADDRESS || !m68k_valid_immed_dst(&decoded->dst) |
569 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) | 617 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) |
570 ) { | 618 ) { |
571 decoded->op = M68K_INVALID; | 619 decoded->op = M68K_INVALID; |
572 break; | 620 break; |
573 } | 621 } |
574 break; | 622 break; |
575 case 5: | 623 case 5: |
576 //EORI, EORI to CCR, EORI to SR | 624 //EORI, EORI to CCR, EORI to SR |
577 if ((*istream & 0xFF) == 0x3C) { | 625 if ((opcode & 0xFF) == 0x3C) { |
578 decoded->op = M68K_EORI_CCR; | 626 decoded->op = M68K_EORI_CCR; |
579 decoded->extra.size = OPSIZE_BYTE; | 627 decoded->extra.size = OPSIZE_BYTE; |
580 decoded->src.addr_mode = MODE_IMMEDIATE; | 628 decoded->src.addr_mode = MODE_IMMEDIATE; |
581 decoded->src.params.immed = *(++istream) & 0xFF; | 629 decoded->src.params.immed = fetch(address, data) & 0xFF; |
582 } else if((*istream & 0xFF) == 0x7C) { | 630 address += 2; |
631 } else if((opcode & 0xFF) == 0x7C) { | |
583 decoded->op = M68K_EORI_SR; | 632 decoded->op = M68K_EORI_SR; |
584 decoded->extra.size = OPSIZE_WORD; | 633 decoded->extra.size = OPSIZE_WORD; |
585 decoded->src.addr_mode = MODE_IMMEDIATE; | 634 decoded->src.addr_mode = MODE_IMMEDIATE; |
586 decoded->src.params.immed = *(++istream); | 635 decoded->src.params.immed = fetch(address, data); |
636 address += 2; | |
587 } else { | 637 } else { |
588 decoded->op = M68K_EOR; | 638 decoded->op = M68K_EOR; |
589 decoded->variant = VAR_IMMEDIATE; | 639 decoded->variant = VAR_IMMEDIATE; |
590 decoded->src.addr_mode = MODE_IMMEDIATE; | 640 decoded->src.addr_mode = MODE_IMMEDIATE; |
591 decoded->extra.size = size = (*istream >> 6) & 3; | 641 decoded->extra.size = size = (opcode >> 6) & 3; |
592 reg = *istream & 0x7; | 642 reg = opcode & 0x7; |
593 opmode = (*istream >> 3) & 0x7; | 643 opmode = (opcode >> 3) & 0x7; |
594 switch (size) | 644 switch (size) |
595 { | 645 { |
596 case OPSIZE_BYTE: | 646 case OPSIZE_BYTE: |
597 decoded->src.params.immed = *(++istream) & 0xFF; | 647 decoded->src.params.immed = fetch(address, data) & 0xFF; |
648 address += 2; | |
598 break; | 649 break; |
599 case OPSIZE_WORD: | 650 case OPSIZE_WORD: |
600 decoded->src.params.immed = *(++istream); | 651 decoded->src.params.immed = fetch(address, data); |
652 address += 2; | |
601 break; | 653 break; |
602 case OPSIZE_LONG: | 654 case OPSIZE_LONG: |
603 immed = *(++istream); | 655 immed = fetch(address, data); |
604 decoded->src.params.immed = immed << 16 | *(++istream); | 656 address += 2; |
657 decoded->src.params.immed = immed << 16 | fetch(address, data); | |
658 address += 2; | |
605 break; | 659 break; |
606 } | 660 } |
607 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 661 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst)); |
608 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | 662 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) { |
609 decoded->op = M68K_INVALID; | 663 decoded->op = M68K_INVALID; |
610 break; | 664 break; |
611 } | 665 } |
612 } | 666 } |
613 break; | 667 break; |
614 case 6: | 668 case 6: |
615 decoded->op = M68K_CMP; | 669 decoded->op = M68K_CMP; |
616 decoded->variant = VAR_IMMEDIATE; | 670 decoded->variant = VAR_IMMEDIATE; |
617 decoded->extra.size = (*istream >> 6) & 0x3; | 671 decoded->extra.size = (opcode >> 6) & 0x3; |
618 decoded->src.addr_mode = MODE_IMMEDIATE; | 672 decoded->src.addr_mode = MODE_IMMEDIATE; |
619 reg = *istream & 0x7; | 673 reg = opcode & 0x7; |
620 opmode = (*istream >> 3) & 0x7; | 674 opmode = (opcode >> 3) & 0x7; |
621 switch (decoded->extra.size) | 675 switch (decoded->extra.size) |
622 { | 676 { |
623 case OPSIZE_BYTE: | 677 case OPSIZE_BYTE: |
624 decoded->src.params.immed = *(++istream) & 0xFF; | 678 decoded->src.params.immed = fetch(address, data) & 0xFF; |
679 address += 2; | |
625 break; | 680 break; |
626 case OPSIZE_WORD: | 681 case OPSIZE_WORD: |
627 decoded->src.params.immed = *(++istream); | 682 decoded->src.params.immed = fetch(address, data); |
683 address += 2; | |
628 break; | 684 break; |
629 case OPSIZE_LONG: | 685 case OPSIZE_LONG: |
630 immed = *(++istream); | 686 immed = fetch(address, data); |
631 decoded->src.params.immed = (immed << 16) | *(++istream); | 687 address += 2; |
632 break; | 688 decoded->src.params.immed = (immed << 16) | fetch(address, data); |
633 } | 689 address += 2; |
634 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 690 break; |
635 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | 691 } |
692 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst)); | |
693 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) { | |
636 decoded->op = M68K_INVALID; | 694 decoded->op = M68K_INVALID; |
637 break; | 695 break; |
638 } | 696 } |
639 break; | 697 break; |
640 case 7: | 698 case 7: |
641 #ifdef M68010 | 699 #ifdef M68010 |
642 decoded->op = M68K_MOVES; | 700 decoded->op = M68K_MOVES; |
643 decoded->extra.size = *istream >> 6 & 0x3; | 701 decoded->extra.size = opcode >> 6 & 0x3; |
644 immed = *(++istream); | 702 immed = fetch(address, data); |
703 address += 2; | |
645 reg = immed >> 12 & 0x7; | 704 reg = immed >> 12 & 0x7; |
646 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; | 705 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; |
647 if (immed & 0x800) { | 706 if (immed & 0x800) { |
648 decoded->src.addr_mode = opmode; | 707 decoded->src.addr_mode = opmode; |
649 decoded->src.params.regs.pri = reg; | 708 decoded->src.params.regs.pri = reg; |
650 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->dst)); | 709 address = m68k_decode_op_ex(opcode, address, fetch, data, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->dst)); |
651 } else { | 710 } else { |
652 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->src)); | 711 address = m68k_decode_op_ex(opcode, address, fetch, data, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->src)); |
653 decoded->dst.addr_mode = opmode; | 712 decoded->dst.addr_mode = opmode; |
654 decoded->dst.params.regs.pri = reg; | 713 decoded->dst.params.regs.pri = reg; |
655 } | 714 } |
656 #endif | 715 #endif |
657 break; | 716 break; |
661 case MOVE_BYTE: | 720 case MOVE_BYTE: |
662 case MOVE_LONG: | 721 case MOVE_LONG: |
663 case MOVE_WORD: | 722 case MOVE_WORD: |
664 decoded->op = M68K_MOVE; | 723 decoded->op = M68K_MOVE; |
665 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG); | 724 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG); |
666 opmode = (*istream >> 6) & 0x7; | 725 opmode = (opcode >> 6) & 0x7; |
667 reg = m68k_reg_quick_field(*istream); | 726 reg = m68k_reg_quick_field(opcode); |
668 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 727 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
669 if (!istream || (decoded->src.addr_mode == MODE_AREG && optype == MOVE_BYTE)) { | 728 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && optype == MOVE_BYTE)) { |
670 decoded->op = M68K_INVALID; | 729 decoded->op = M68K_INVALID; |
671 break; | 730 break; |
672 } | 731 } |
673 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 732 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst)); |
674 if (!istream || decoded->dst.addr_mode > MODE_ABSOLUTE || (decoded->dst.addr_mode == MODE_AREG && optype == MOVE_BYTE)) { | 733 if (address == INVALID_ADDRESS || decoded->dst.addr_mode > MODE_ABSOLUTE || (decoded->dst.addr_mode == MODE_AREG && optype == MOVE_BYTE)) { |
675 decoded->op = M68K_INVALID; | 734 decoded->op = M68K_INVALID; |
676 break; | 735 break; |
677 } | 736 } |
678 break; | 737 break; |
679 case MISC: | 738 case MISC: |
680 | 739 |
681 if ((*istream & 0x1C0) == 0x1C0) { | 740 if ((opcode & 0x1C0) == 0x1C0) { |
682 decoded->op = M68K_LEA; | 741 decoded->op = M68K_LEA; |
683 decoded->extra.size = OPSIZE_LONG; | 742 decoded->extra.size = OPSIZE_LONG; |
684 decoded->dst.addr_mode = MODE_AREG; | 743 decoded->dst.addr_mode = MODE_AREG; |
685 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 744 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
686 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 745 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
687 if ( | 746 if ( |
688 !istream || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG | 747 address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG |
689 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC | 748 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC |
690 || decoded->src.addr_mode == MODE_IMMEDIATE | 749 || decoded->src.addr_mode == MODE_IMMEDIATE |
691 ) { | 750 ) { |
692 decoded->op = M68K_INVALID; | 751 decoded->op = M68K_INVALID; |
693 break; | 752 break; |
694 } | 753 } |
695 } else { | 754 } else { |
696 if (*istream & 0x100) { | 755 if (opcode & 0x100) { |
697 decoded->op = M68K_CHK; | 756 decoded->op = M68K_CHK; |
698 if ((*istream & 0x180) == 0x180) { | 757 if ((opcode & 0x180) == 0x180) { |
699 decoded->extra.size = OPSIZE_WORD; | 758 decoded->extra.size = OPSIZE_WORD; |
700 } else { | 759 } else { |
701 //only on M68020+ | 760 //only on M68020+ |
702 #ifdef M68020 | 761 #ifdef M68020 |
703 decoded->extra.size = OPSIZE_LONG; | 762 decoded->extra.size = OPSIZE_LONG; |
705 decoded->op = M68K_INVALID; | 764 decoded->op = M68K_INVALID; |
706 break; | 765 break; |
707 #endif | 766 #endif |
708 } | 767 } |
709 decoded->dst.addr_mode = MODE_REG; | 768 decoded->dst.addr_mode = MODE_REG; |
710 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 769 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
711 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 770 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
712 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 771 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
713 decoded->op = M68K_INVALID; | 772 decoded->op = M68K_INVALID; |
714 break; | 773 break; |
715 } | 774 } |
716 } else { | 775 } else { |
717 opmode = (*istream >> 3) & 0x7; | 776 opmode = (opcode >> 3) & 0x7; |
718 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { | 777 if ((opcode & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { |
719 //TODO: Check for invalid modes that are dependent on direction | 778 //TODO: Check for invalid modes that are dependent on direction |
720 decoded->op = M68K_MOVEM; | 779 decoded->op = M68K_MOVEM; |
721 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; | 780 decoded->extra.size = opcode & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; |
722 reg = *istream & 0x7; | 781 reg = opcode & 0x7; |
723 if(*istream & 0x400) { | 782 if(opcode & 0x400) { |
724 decoded->dst.addr_mode = MODE_REG; | 783 decoded->dst.addr_mode = MODE_REG; |
725 decoded->dst.params.immed = *(++istream); | 784 decoded->dst.params.immed = fetch(address, data); |
726 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); | 785 address += 2; |
727 if (!istream || decoded->src.addr_mode == MODE_AREG_PREDEC || decoded->src.addr_mode == MODE_IMMEDIATE) { | 786 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->src)); |
787 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG_PREDEC || decoded->src.addr_mode == MODE_IMMEDIATE) { | |
728 decoded->op = M68K_INVALID; | 788 decoded->op = M68K_INVALID; |
729 break; | 789 break; |
730 } | 790 } |
731 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) { | 791 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) { |
732 //adjust displacement to account for extra instruction word | 792 //adjust displacement to account for extra instruction word |
733 decoded->src.params.regs.displacement += 2; | 793 decoded->src.params.regs.displacement += 2; |
734 } | 794 } |
735 } else { | 795 } else { |
736 decoded->src.addr_mode = MODE_REG; | 796 decoded->src.addr_mode = MODE_REG; |
737 decoded->src.params.immed = *(++istream); | 797 decoded->src.params.immed = fetch(address, data); |
738 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 798 address += 2; |
739 if (!istream || !m68k_valid_movem_dst(&decoded->dst)) { | 799 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst)); |
800 if (address == INVALID_ADDRESS || !m68k_valid_movem_dst(&decoded->dst)) { | |
740 decoded->op = M68K_INVALID; | 801 decoded->op = M68K_INVALID; |
741 break; | 802 break; |
742 } | 803 } |
743 } | 804 } |
744 } else { | 805 } else { |
745 optype = (*istream >> 9) & 0x7; | 806 optype = (opcode >> 9) & 0x7; |
746 size = (*istream >> 6) & 0x3; | 807 size = (opcode >> 6) & 0x3; |
747 switch(optype) | 808 switch(optype) |
748 { | 809 { |
749 case 0: | 810 case 0: |
750 //Move from SR or NEGX | 811 //Move from SR or NEGX |
751 if (size == OPSIZE_INVALID) { | 812 if (size == OPSIZE_INVALID) { |
753 size = OPSIZE_WORD; | 814 size = OPSIZE_WORD; |
754 } else { | 815 } else { |
755 decoded->op = M68K_NEGX; | 816 decoded->op = M68K_NEGX; |
756 } | 817 } |
757 decoded->extra.size = size; | 818 decoded->extra.size = size; |
758 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 819 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
759 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { | 820 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) { |
760 decoded->op = M68K_INVALID; | 821 decoded->op = M68K_INVALID; |
761 break; | 822 break; |
762 } | 823 } |
763 break; | 824 break; |
764 case 1: | 825 case 1: |
772 #endif | 833 #endif |
773 } else { | 834 } else { |
774 decoded->op = M68K_CLR; | 835 decoded->op = M68K_CLR; |
775 } | 836 } |
776 decoded->extra.size = size; | 837 decoded->extra.size = size; |
777 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 838 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
778 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { | 839 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) { |
779 decoded->op = M68K_INVALID; | 840 decoded->op = M68K_INVALID; |
780 break; | 841 break; |
781 } | 842 } |
782 break; | 843 break; |
783 case 2: | 844 case 2: |
784 //MOVE to CCR or NEG | 845 //MOVE to CCR or NEG |
785 if (size == OPSIZE_INVALID) { | 846 if (size == OPSIZE_INVALID) { |
786 decoded->op = M68K_MOVE_CCR; | 847 decoded->op = M68K_MOVE_CCR; |
787 size = OPSIZE_WORD; | 848 size = OPSIZE_WORD; |
788 istream= m68k_decode_op(istream, size, &(decoded->src)); | 849 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->src)); |
789 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 850 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
790 decoded->op = M68K_INVALID; | 851 decoded->op = M68K_INVALID; |
791 break; | 852 break; |
792 } | 853 } |
793 } else { | 854 } else { |
794 decoded->op = M68K_NEG; | 855 decoded->op = M68K_NEG; |
795 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 856 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
796 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { | 857 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) { |
797 decoded->op = M68K_INVALID; | 858 decoded->op = M68K_INVALID; |
798 break; | 859 break; |
799 } | 860 } |
800 } | 861 } |
801 decoded->extra.size = size; | 862 decoded->extra.size = size; |
803 case 3: | 864 case 3: |
804 //MOVE to SR or NOT | 865 //MOVE to SR or NOT |
805 if (size == OPSIZE_INVALID) { | 866 if (size == OPSIZE_INVALID) { |
806 decoded->op = M68K_MOVE_SR; | 867 decoded->op = M68K_MOVE_SR; |
807 size = OPSIZE_WORD; | 868 size = OPSIZE_WORD; |
808 istream= m68k_decode_op(istream, size, &(decoded->src)); | 869 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->src)); |
809 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 870 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
810 decoded->op = M68K_INVALID; | 871 decoded->op = M68K_INVALID; |
811 break; | 872 break; |
812 } | 873 } |
813 } else { | 874 } else { |
814 decoded->op = M68K_NOT; | 875 decoded->op = M68K_NOT; |
815 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 876 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
816 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { | 877 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) { |
817 decoded->op = M68K_INVALID; | 878 decoded->op = M68K_INVALID; |
818 break; | 879 break; |
819 } | 880 } |
820 } | 881 } |
821 decoded->extra.size = size; | 882 decoded->extra.size = size; |
822 break; | 883 break; |
823 case 4: | 884 case 4: |
824 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA | 885 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA |
825 switch((*istream >> 3) & 0x3F) | 886 switch((opcode >> 3) & 0x3F) |
826 { | 887 { |
827 case 1: | 888 case 1: |
828 #ifdef M68020 | 889 #ifdef M68020 |
829 decoded->op = M68K_LINK; | 890 decoded->op = M68K_LINK; |
830 decoded->extra.size = OPSIZE_LONG; | 891 decoded->extra.size = OPSIZE_LONG; |
831 reg = *istream & 0x7; | 892 reg = opcode & 0x7; |
832 immed = *(++istream) << 16; | 893 immed = fetch(address, data) << 16; |
833 immed |= *(++istream); | 894 address += 2; |
895 immed |= fetch(address, data); | |
896 address += 2; | |
834 #endif | 897 #endif |
835 break; | 898 break; |
836 case 8: | 899 case 8: |
837 decoded->op = M68K_SWAP; | 900 decoded->op = M68K_SWAP; |
838 decoded->src.addr_mode = MODE_REG; | 901 decoded->src.addr_mode = MODE_REG; |
839 decoded->src.params.regs.pri = *istream & 0x7; | 902 decoded->src.params.regs.pri = opcode & 0x7; |
840 decoded->extra.size = OPSIZE_WORD; | 903 decoded->extra.size = OPSIZE_WORD; |
841 break; | 904 break; |
842 case 9: | 905 case 9: |
843 #ifdef M68010 | 906 #ifdef M68010 |
844 decoded->op = M68K_BKPT; | 907 decoded->op = M68K_BKPT; |
845 decoded->src.addr_mode = MODE_IMMEDIATE; | 908 decoded->src.addr_mode = MODE_IMMEDIATE; |
846 decoded->extra.size = OPSIZE_UNSIZED; | 909 decoded->extra.size = OPSIZE_UNSIZED; |
847 decoded->src.params.immed = *istream & 0x7; | 910 decoded->src.params.immed = opcode & 0x7; |
848 #endif | 911 #endif |
849 break; | 912 break; |
850 case 0x10: | 913 case 0x10: |
851 decoded->op = M68K_EXT; | 914 decoded->op = M68K_EXT; |
852 decoded->dst.addr_mode = MODE_REG; | 915 decoded->dst.addr_mode = MODE_REG; |
853 decoded->dst.params.regs.pri = *istream & 0x7; | 916 decoded->dst.params.regs.pri = opcode & 0x7; |
854 decoded->extra.size = OPSIZE_WORD; | 917 decoded->extra.size = OPSIZE_WORD; |
855 break; | 918 break; |
856 case 0x18: | 919 case 0x18: |
857 decoded->op = M68K_EXT; | 920 decoded->op = M68K_EXT; |
858 decoded->dst.addr_mode = MODE_REG; | 921 decoded->dst.addr_mode = MODE_REG; |
859 decoded->dst.params.regs.pri = *istream & 0x7; | 922 decoded->dst.params.regs.pri = opcode & 0x7; |
860 decoded->extra.size = OPSIZE_LONG; | 923 decoded->extra.size = OPSIZE_LONG; |
861 break; | 924 break; |
862 case 0x38: | 925 case 0x38: |
863 #ifdef M68020 | 926 #ifdef M68020 |
864 #endif | 927 #endif |
865 break; | 928 break; |
866 default: | 929 default: |
867 if (!(*istream & 0x1C0)) { | 930 if (!(opcode & 0x1C0)) { |
868 decoded->op = M68K_NBCD; | 931 decoded->op = M68K_NBCD; |
869 decoded->extra.size = OPSIZE_BYTE; | 932 decoded->extra.size = OPSIZE_BYTE; |
870 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 933 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_BYTE, &(decoded->dst)); |
871 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { | 934 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) { |
872 decoded->op = M68K_INVALID; | 935 decoded->op = M68K_INVALID; |
873 break; | 936 break; |
874 } | 937 } |
875 } else if((*istream & 0x1C0) == 0x40) { | 938 } else if((opcode & 0x1C0) == 0x40) { |
876 decoded->op = M68K_PEA; | 939 decoded->op = M68K_PEA; |
877 decoded->extra.size = OPSIZE_LONG; | 940 decoded->extra.size = OPSIZE_LONG; |
878 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 941 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_LONG, &(decoded->src)); |
879 if ( | 942 if ( |
880 !istream || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG | 943 address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG |
881 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC | 944 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC |
882 || decoded->src.addr_mode == MODE_IMMEDIATE | 945 || decoded->src.addr_mode == MODE_IMMEDIATE |
883 ) { | 946 ) { |
884 decoded->op = M68K_INVALID; | 947 decoded->op = M68K_INVALID; |
885 break; | 948 break; |
887 } | 950 } |
888 } | 951 } |
889 break; | 952 break; |
890 case 5: | 953 case 5: |
891 //BGND, ILLEGAL, TAS, TST | 954 //BGND, ILLEGAL, TAS, TST |
892 optype = *istream & 0xFF; | 955 optype = opcode & 0xFF; |
893 if (optype == 0xFA) { | 956 if (optype == 0xFA) { |
894 //BGND - CPU32 only | 957 //BGND - CPU32 only |
895 } else if (optype == 0xFC) { | 958 } else if (optype == 0xFC) { |
896 decoded->op = M68K_ILLEGAL; | 959 decoded->op = M68K_ILLEGAL; |
897 decoded->extra.size = OPSIZE_UNSIZED; | 960 decoded->extra.size = OPSIZE_UNSIZED; |
898 } else { | 961 } else { |
899 if (size == OPSIZE_INVALID) { | 962 if (size == OPSIZE_INVALID) { |
900 decoded->op = M68K_TAS; | 963 decoded->op = M68K_TAS; |
901 decoded->extra.size = OPSIZE_BYTE; | 964 decoded->extra.size = OPSIZE_BYTE; |
902 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); | 965 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->dst)); |
903 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { | 966 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) { |
904 decoded->op = M68K_INVALID; | 967 decoded->op = M68K_INVALID; |
905 break; | 968 break; |
906 } | 969 } |
907 } else { | 970 } else { |
908 decoded->op = M68K_TST; | 971 decoded->op = M68K_TST; |
909 decoded->extra.size = size; | 972 decoded->extra.size = size; |
910 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 973 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
911 if (!istream) { | 974 if (address == INVALID_ADDRESS) { |
912 decoded->op = M68K_INVALID; | 975 decoded->op = M68K_INVALID; |
913 break; | 976 break; |
914 } | 977 } |
915 #ifndef M68020 | 978 #ifndef M68020 |
916 if (!m68k_valid_immed_limited_dst(&decoded->src)) { | 979 if (!m68k_valid_immed_limited_dst(&decoded->src)) { |
927 //TODO: Implement these for 68020+ support | 990 //TODO: Implement these for 68020+ support |
928 #endif | 991 #endif |
929 break; | 992 break; |
930 case 7: | 993 case 7: |
931 //TRAP, LINK.w, UNLNK, MOVE USP, RESET, NOP, STOP, RTE, RTD, RTS, TRAPV, RTR, MOVEC, JSR, JMP | 994 //TRAP, LINK.w, UNLNK, MOVE USP, RESET, NOP, STOP, RTE, RTD, RTS, TRAPV, RTR, MOVEC, JSR, JMP |
932 if (*istream & 0x80) { | 995 if (opcode & 0x80) { |
933 //JSR, JMP | 996 //JSR, JMP |
934 if (*istream & 0x40) { | 997 if (opcode & 0x40) { |
935 decoded->op = M68K_JMP; | 998 decoded->op = M68K_JMP; |
936 } else { | 999 } else { |
937 decoded->op = M68K_JSR; | 1000 decoded->op = M68K_JSR; |
938 } | 1001 } |
939 decoded->extra.size = OPSIZE_UNSIZED; | 1002 decoded->extra.size = OPSIZE_UNSIZED; |
940 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src)); | 1003 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_UNSIZED, &(decoded->src)); |
941 if ( | 1004 if ( |
942 !istream | 1005 address == INVALID_ADDRESS |
943 || (decoded->src.addr_mode < MODE_AREG_DISPLACE && decoded->src.addr_mode != MODE_AREG_INDIRECT) | 1006 || (decoded->src.addr_mode < MODE_AREG_DISPLACE && decoded->src.addr_mode != MODE_AREG_INDIRECT) |
944 || decoded->src.addr_mode == MODE_IMMEDIATE | 1007 || decoded->src.addr_mode == MODE_IMMEDIATE |
945 ) { | 1008 ) { |
946 decoded->op = M68K_INVALID; | 1009 decoded->op = M68K_INVALID; |
947 break; | 1010 break; |
948 } | 1011 } |
949 } else { | 1012 } else { |
950 //it would appear bit 6 needs to be set for it to be a valid instruction here | 1013 //it would appear bit 6 needs to be set for it to be a valid instruction here |
951 if (!(*istream & 0x40)) { | 1014 if (!(opcode & 0x40)) { |
952 decoded->op = M68K_INVALID; | 1015 decoded->op = M68K_INVALID; |
953 break; | 1016 break; |
954 } | 1017 } |
955 switch((*istream >> 3) & 0x7) | 1018 switch((opcode >> 3) & 0x7) |
956 { | 1019 { |
957 case 0: | 1020 case 0: |
958 case 1: | 1021 case 1: |
959 //TRAP | 1022 //TRAP |
960 decoded->op = M68K_TRAP; | 1023 decoded->op = M68K_TRAP; |
961 decoded->extra.size = OPSIZE_UNSIZED; | 1024 decoded->extra.size = OPSIZE_UNSIZED; |
962 decoded->src.addr_mode = MODE_IMMEDIATE; | 1025 decoded->src.addr_mode = MODE_IMMEDIATE; |
963 decoded->src.params.immed = *istream & 0xF; | 1026 decoded->src.params.immed = opcode & 0xF; |
964 break; | 1027 break; |
965 case 2: | 1028 case 2: |
966 //LINK.w | 1029 //LINK.w |
967 decoded->op = M68K_LINK; | 1030 decoded->op = M68K_LINK; |
968 decoded->extra.size = OPSIZE_WORD; | 1031 decoded->extra.size = OPSIZE_WORD; |
969 decoded->src.addr_mode = MODE_AREG; | 1032 decoded->src.addr_mode = MODE_AREG; |
970 decoded->src.params.regs.pri = *istream & 0x7; | 1033 decoded->src.params.regs.pri = opcode & 0x7; |
971 decoded->dst.addr_mode = MODE_IMMEDIATE; | 1034 decoded->dst.addr_mode = MODE_IMMEDIATE; |
972 decoded->dst.params.immed = sign_extend16(*(++istream)); | 1035 decoded->dst.params.immed = sign_extend16(fetch(address, data)); |
1036 address += 2; | |
973 break; | 1037 break; |
974 case 3: | 1038 case 3: |
975 //UNLK | 1039 //UNLK |
976 decoded->op = M68K_UNLK; | 1040 decoded->op = M68K_UNLK; |
977 decoded->extra.size = OPSIZE_UNSIZED; | 1041 decoded->extra.size = OPSIZE_UNSIZED; |
978 decoded->dst.addr_mode = MODE_AREG; | 1042 decoded->dst.addr_mode = MODE_AREG; |
979 decoded->dst.params.regs.pri = *istream & 0x7; | 1043 decoded->dst.params.regs.pri = opcode & 0x7; |
980 break; | 1044 break; |
981 case 4: | 1045 case 4: |
982 case 5: | 1046 case 5: |
983 //MOVE USP | 1047 //MOVE USP |
984 decoded->op = M68K_MOVE_USP; | 1048 decoded->op = M68K_MOVE_USP; |
985 if (*istream & 0x8) { | 1049 if (opcode & 0x8) { |
986 decoded->dst.addr_mode = MODE_AREG; | 1050 decoded->dst.addr_mode = MODE_AREG; |
987 decoded->dst.params.regs.pri = *istream & 0x7; | 1051 decoded->dst.params.regs.pri = opcode & 0x7; |
988 } else { | 1052 } else { |
989 decoded->src.addr_mode = MODE_AREG; | 1053 decoded->src.addr_mode = MODE_AREG; |
990 decoded->src.params.regs.pri = *istream & 0x7; | 1054 decoded->src.params.regs.pri = opcode & 0x7; |
991 } | 1055 } |
992 break; | 1056 break; |
993 case 6: | 1057 case 6: |
994 decoded->extra.size = OPSIZE_UNSIZED; | 1058 decoded->extra.size = OPSIZE_UNSIZED; |
995 switch(*istream & 0x7) | 1059 switch(opcode & 0x7) |
996 { | 1060 { |
997 case 0: | 1061 case 0: |
998 decoded->op = M68K_RESET; | 1062 decoded->op = M68K_RESET; |
999 break; | 1063 break; |
1000 case 1: | 1064 case 1: |
1001 decoded->op = M68K_NOP; | 1065 decoded->op = M68K_NOP; |
1002 break; | 1066 break; |
1003 case 2: | 1067 case 2: |
1004 decoded->op = M68K_STOP; | 1068 decoded->op = M68K_STOP; |
1005 decoded->src.addr_mode = MODE_IMMEDIATE; | 1069 decoded->src.addr_mode = MODE_IMMEDIATE; |
1006 decoded->src.params.immed =*(++istream); | 1070 decoded->src.params.immed =fetch(address, data); |
1071 address += 2; | |
1007 break; | 1072 break; |
1008 case 3: | 1073 case 3: |
1009 decoded->op = M68K_RTE; | 1074 decoded->op = M68K_RTE; |
1010 break; | 1075 break; |
1011 case 4: | 1076 case 4: |
1012 #ifdef M68010 | 1077 #ifdef M68010 |
1013 decoded->op = M68K_RTD; | 1078 decoded->op = M68K_RTD; |
1014 decoded->src.addr_mode = MODE_IMMEDIATE; | 1079 decoded->src.addr_mode = MODE_IMMEDIATE; |
1015 decoded->src.params.immed =*(++istream); | 1080 decoded->src.params.immed =fetch(address, data); |
1081 address += 2; | |
1016 #endif | 1082 #endif |
1017 break; | 1083 break; |
1018 case 5: | 1084 case 5: |
1019 decoded->op = M68K_RTS; | 1085 decoded->op = M68K_RTS; |
1020 break; | 1086 break; |
1028 break; | 1094 break; |
1029 case 7: | 1095 case 7: |
1030 //MOVEC | 1096 //MOVEC |
1031 #ifdef M68010 | 1097 #ifdef M68010 |
1032 decoded->op = M68K_MOVEC; | 1098 decoded->op = M68K_MOVEC; |
1033 immed = *(++istream); | 1099 immed = fetch(address, data); |
1100 address += 2; | |
1034 reg = immed >> 12 & 0x7; | 1101 reg = immed >> 12 & 0x7; |
1035 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; | 1102 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; |
1036 immed &= 0xFFF; | 1103 immed &= 0xFFF; |
1037 if (immed & 0x800) { | 1104 if (immed & 0x800) { |
1038 if (immed > MAX_HIGH_CR) { | 1105 if (immed > MAX_HIGH_CR) { |
1065 } | 1132 } |
1066 } | 1133 } |
1067 } | 1134 } |
1068 break; | 1135 break; |
1069 case QUICK_ARITH_LOOP: | 1136 case QUICK_ARITH_LOOP: |
1070 size = (*istream >> 6) & 3; | 1137 size = (opcode >> 6) & 3; |
1071 if (size == 0x3) { | 1138 if (size == 0x3) { |
1072 //DBcc, TRAPcc or Scc | 1139 //DBcc, TRAPcc or Scc |
1073 m68k_decode_cond(*istream, decoded); | 1140 m68k_decode_cond(opcode, decoded); |
1074 if (((*istream >> 3) & 0x7) == 1) { | 1141 if (((opcode >> 3) & 0x7) == 1) { |
1075 decoded->op = M68K_DBCC; | 1142 decoded->op = M68K_DBCC; |
1076 decoded->src.addr_mode = MODE_IMMEDIATE; | 1143 decoded->src.addr_mode = MODE_IMMEDIATE; |
1077 decoded->dst.addr_mode = MODE_REG; | 1144 decoded->dst.addr_mode = MODE_REG; |
1078 decoded->dst.params.regs.pri = *istream & 0x7; | 1145 decoded->dst.params.regs.pri = opcode & 0x7; |
1079 decoded->src.params.immed = sign_extend16(*(++istream)); | 1146 decoded->src.params.immed = sign_extend16(fetch(address, data)); |
1080 } else if(((*istream >> 3) & 0x7) == 1 && (*istream & 0x7) > 1 && (*istream & 0x7) < 5) { | 1147 address += 2; |
1148 } else if(((opcode >> 3) & 0x7) == 1 && (opcode & 0x7) > 1 && (opcode & 0x7) < 5) { | |
1081 #ifdef M68020 | 1149 #ifdef M68020 |
1082 decoded->op = M68K_TRAPCC; | 1150 decoded->op = M68K_TRAPCC; |
1083 decoded->src.addr_mode = MODE_IMMEDIATE; | 1151 decoded->src.addr_mode = MODE_IMMEDIATE; |
1084 //TODO: Figure out what to do with OPMODE and optional extention words | 1152 //TODO: Figure out what to do with OPMODE and optional extention words |
1085 #endif | 1153 #endif |
1086 } else { | 1154 } else { |
1087 decoded->op = M68K_SCC; | 1155 decoded->op = M68K_SCC; |
1088 decoded->extra.cond = (*istream >> 8) & 0xF; | 1156 decoded->extra.cond = (opcode >> 8) & 0xF; |
1089 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 1157 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_BYTE, &(decoded->dst)); |
1090 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { | 1158 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) { |
1091 decoded->op = M68K_INVALID; | 1159 decoded->op = M68K_INVALID; |
1092 break; | 1160 break; |
1093 } | 1161 } |
1094 } | 1162 } |
1095 } else { | 1163 } else { |
1096 //ADDQ, SUBQ | 1164 //ADDQ, SUBQ |
1097 decoded->variant = VAR_QUICK; | 1165 decoded->variant = VAR_QUICK; |
1098 decoded->extra.size = size; | 1166 decoded->extra.size = size; |
1099 decoded->src.addr_mode = MODE_IMMEDIATE; | 1167 decoded->src.addr_mode = MODE_IMMEDIATE; |
1100 immed = m68k_reg_quick_field(*istream); | 1168 immed = m68k_reg_quick_field(opcode); |
1101 if (!immed) { | 1169 if (!immed) { |
1102 immed = 8; | 1170 immed = 8; |
1103 } | 1171 } |
1104 decoded->src.params.immed = immed; | 1172 decoded->src.params.immed = immed; |
1105 if (*istream & 0x100) { | 1173 if (opcode & 0x100) { |
1106 decoded->op = M68K_SUB; | 1174 decoded->op = M68K_SUB; |
1107 } else { | 1175 } else { |
1108 decoded->op = M68K_ADD; | 1176 decoded->op = M68K_ADD; |
1109 } | 1177 } |
1110 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1178 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
1111 if (!istream || decoded->dst.addr_mode > MODE_ABSOLUTE || (size == OPSIZE_BYTE && decoded->dst.addr_mode == MODE_AREG)) { | 1179 if (address == INVALID_ADDRESS || decoded->dst.addr_mode > MODE_ABSOLUTE || (size == OPSIZE_BYTE && decoded->dst.addr_mode == MODE_AREG)) { |
1112 decoded->op = M68K_INVALID; | 1180 decoded->op = M68K_INVALID; |
1113 break; | 1181 break; |
1114 } | 1182 } |
1115 } | 1183 } |
1116 break; | 1184 break; |
1117 case BRANCH: | 1185 case BRANCH: |
1118 m68k_decode_cond(*istream, decoded); | 1186 m68k_decode_cond(opcode, decoded); |
1119 decoded->op = decoded->extra.cond == COND_FALSE ? M68K_BSR : M68K_BCC; | 1187 decoded->op = decoded->extra.cond == COND_FALSE ? M68K_BSR : M68K_BCC; |
1120 decoded->src.addr_mode = MODE_IMMEDIATE; | 1188 decoded->src.addr_mode = MODE_IMMEDIATE; |
1121 immed = *istream & 0xFF; | 1189 immed = opcode & 0xFF; |
1122 if (immed == 0) { | 1190 if (immed == 0) { |
1123 decoded->variant = VAR_WORD; | 1191 decoded->variant = VAR_WORD; |
1124 immed = *(++istream); | 1192 immed = fetch(address, data); |
1193 address += 2; | |
1125 immed = sign_extend16(immed); | 1194 immed = sign_extend16(immed); |
1126 #ifdef M68020 | 1195 #ifdef M68020 |
1127 } else if (immed == 0xFF) { | 1196 } else if (immed == 0xFF) { |
1128 decoded->variant = VAR_LONG; | 1197 decoded->variant = VAR_LONG; |
1129 immed = *(++istream) << 16; | 1198 immed = fetch(address, data) << 16; |
1130 immed |= *(++istream); | 1199 address += 2; |
1200 immed |= fetch(address, data); | |
1201 address += 2; | |
1131 #endif | 1202 #endif |
1132 } else { | 1203 } else { |
1133 decoded->variant = VAR_BYTE; | 1204 decoded->variant = VAR_BYTE; |
1134 immed = sign_extend8(immed); | 1205 immed = sign_extend8(immed); |
1135 } | 1206 } |
1136 decoded->src.params.immed = immed; | 1207 decoded->src.params.immed = immed; |
1137 break; | 1208 break; |
1138 case MOVEQ: | 1209 case MOVEQ: |
1139 if (*istream & 0x100) { | 1210 if (opcode & 0x100) { |
1140 decoded->op = M68K_INVALID; | 1211 decoded->op = M68K_INVALID; |
1141 break; | 1212 break; |
1142 } | 1213 } |
1143 decoded->op = M68K_MOVE; | 1214 decoded->op = M68K_MOVE; |
1144 decoded->variant = VAR_QUICK; | 1215 decoded->variant = VAR_QUICK; |
1145 decoded->extra.size = OPSIZE_LONG; | 1216 decoded->extra.size = OPSIZE_LONG; |
1146 decoded->src.addr_mode = MODE_IMMEDIATE; | 1217 decoded->src.addr_mode = MODE_IMMEDIATE; |
1147 decoded->src.params.immed = sign_extend8(*istream & 0xFF); | 1218 decoded->src.params.immed = sign_extend8(opcode & 0xFF); |
1148 decoded->dst.addr_mode = MODE_REG; | 1219 decoded->dst.addr_mode = MODE_REG; |
1149 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1220 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1150 immed = *istream & 0xFF; | 1221 immed = opcode & 0xFF; |
1151 break; | 1222 break; |
1152 case OR_DIV_SBCD: | 1223 case OR_DIV_SBCD: |
1153 //for OR, if opmode bit 2 is 1, then src = Dn, dst = <ea> | 1224 //for OR, if opmode bit 2 is 1, then src = Dn, dst = <ea> |
1154 opmode = (*istream >> 6) & 0x7; | 1225 opmode = (opcode >> 6) & 0x7; |
1155 size = opmode & 0x3; | 1226 size = opmode & 0x3; |
1156 if (size == OPSIZE_INVALID || (opmode & 0x4 && !(*istream & 0x30))) { | 1227 if (size == OPSIZE_INVALID || (opmode & 0x4 && !(opcode & 0x30))) { |
1157 switch(opmode) | 1228 switch(opmode) |
1158 { | 1229 { |
1159 case 3: | 1230 case 3: |
1160 decoded->op = M68K_DIVU; | 1231 decoded->op = M68K_DIVU; |
1161 decoded->extra.size = OPSIZE_WORD; | 1232 decoded->extra.size = OPSIZE_WORD; |
1162 decoded->dst.addr_mode = MODE_REG; | 1233 decoded->dst.addr_mode = MODE_REG; |
1163 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1234 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7; |
1164 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1235 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src)); |
1165 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1236 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
1166 decoded->op = M68K_INVALID; | 1237 decoded->op = M68K_INVALID; |
1167 break; | 1238 break; |
1168 } | 1239 } |
1169 break; | 1240 break; |
1170 case 4: | 1241 case 4: |
1171 decoded->op = M68K_SBCD; | 1242 decoded->op = M68K_SBCD; |
1172 decoded->extra.size = OPSIZE_BYTE; | 1243 decoded->extra.size = OPSIZE_BYTE; |
1173 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG; | 1244 decoded->dst.addr_mode = decoded->src.addr_mode = opcode & 0x8 ? MODE_AREG_PREDEC : MODE_REG; |
1174 decoded->src.params.regs.pri = *istream & 0x7; | 1245 decoded->src.params.regs.pri = opcode & 0x7; |
1175 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1246 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7; |
1176 break; | 1247 break; |
1177 case 5: | 1248 case 5: |
1178 #ifdef M68020 | 1249 #ifdef M68020 |
1179 #endif | 1250 #endif |
1180 break; | 1251 break; |
1184 break; | 1255 break; |
1185 case 7: | 1256 case 7: |
1186 decoded->op = M68K_DIVS; | 1257 decoded->op = M68K_DIVS; |
1187 decoded->extra.size = OPSIZE_WORD; | 1258 decoded->extra.size = OPSIZE_WORD; |
1188 decoded->dst.addr_mode = MODE_REG; | 1259 decoded->dst.addr_mode = MODE_REG; |
1189 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1260 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7; |
1190 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1261 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src)); |
1191 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1262 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
1192 decoded->op = M68K_INVALID; | 1263 decoded->op = M68K_INVALID; |
1193 break; | 1264 break; |
1194 } | 1265 } |
1195 break; | 1266 break; |
1196 } | 1267 } |
1197 } else { | 1268 } else { |
1198 decoded->op = M68K_OR; | 1269 decoded->op = M68K_OR; |
1199 decoded->extra.size = size; | 1270 decoded->extra.size = size; |
1200 if (opmode & 0x4) { | 1271 if (opmode & 0x4) { |
1201 decoded->src.addr_mode = MODE_REG; | 1272 decoded->src.addr_mode = MODE_REG; |
1202 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; | 1273 decoded->src.params.regs.pri = (opcode >> 9) & 0x7; |
1203 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1274 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
1204 if (!istream || !m68k_valid_full_arith_dst(&(decoded->dst))) { | 1275 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&(decoded->dst))) { |
1205 decoded->op = M68K_INVALID; | 1276 decoded->op = M68K_INVALID; |
1206 break; | 1277 break; |
1207 } | 1278 } |
1208 } else { | 1279 } else { |
1209 decoded->dst.addr_mode = MODE_REG; | 1280 decoded->dst.addr_mode = MODE_REG; |
1210 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1281 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7; |
1211 istream = m68k_decode_op(istream, size, &(decoded->src)); | 1282 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->src)); |
1212 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1283 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
1213 decoded->op = M68K_INVALID; | 1284 decoded->op = M68K_INVALID; |
1214 break; | 1285 break; |
1215 } | 1286 } |
1216 } | 1287 } |
1217 } | 1288 } |
1218 break; | 1289 break; |
1219 case SUB_SUBX: | 1290 case SUB_SUBX: |
1220 size = (*istream >> 6) & 0x3; | 1291 size = (opcode >> 6) & 0x3; |
1221 decoded->op = M68K_SUB; | 1292 decoded->op = M68K_SUB; |
1222 if (*istream & 0x100) { | 1293 if (opcode & 0x100) { |
1223 //<ea> destination, SUBA.l or SUBX | 1294 //<ea> destination, SUBA.l or SUBX |
1224 if (*istream & 0x30 || size == OPSIZE_INVALID) { | 1295 if (opcode & 0x30 || size == OPSIZE_INVALID) { |
1225 if (size == OPSIZE_INVALID) { | 1296 if (size == OPSIZE_INVALID) { |
1226 //SUBA.l | 1297 //SUBA.l |
1227 decoded->extra.size = OPSIZE_LONG; | 1298 decoded->extra.size = OPSIZE_LONG; |
1228 decoded->dst.addr_mode = MODE_AREG; | 1299 decoded->dst.addr_mode = MODE_AREG; |
1229 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1300 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1230 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 1301 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_LONG, &(decoded->src)); |
1231 if (!istream) { | 1302 if (address == INVALID_ADDRESS) { |
1232 decoded->op = M68K_INVALID; | 1303 decoded->op = M68K_INVALID; |
1233 break; | 1304 break; |
1234 } | 1305 } |
1235 } else { | 1306 } else { |
1236 decoded->extra.size = size; | 1307 decoded->extra.size = size; |
1237 decoded->src.addr_mode = MODE_REG; | 1308 decoded->src.addr_mode = MODE_REG; |
1238 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1309 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode); |
1239 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1310 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
1240 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) { | 1311 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&decoded->dst)) { |
1241 decoded->op = M68K_INVALID; | 1312 decoded->op = M68K_INVALID; |
1242 break; | 1313 break; |
1243 } | 1314 } |
1244 } | 1315 } |
1245 } else { | 1316 } else { |
1246 //SUBX | 1317 //SUBX |
1247 decoded->op = M68K_SUBX; | 1318 decoded->op = M68K_SUBX; |
1248 decoded->extra.size = size; | 1319 decoded->extra.size = size; |
1249 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1320 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1250 decoded->src.params.regs.pri = *istream & 0x7; | 1321 decoded->src.params.regs.pri = opcode & 0x7; |
1251 if (*istream & 0x8) { | 1322 if (opcode & 0x8) { |
1252 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; | 1323 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; |
1253 } else { | 1324 } else { |
1254 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; | 1325 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; |
1255 } | 1326 } |
1256 } | 1327 } |
1261 decoded->dst.addr_mode = MODE_AREG; | 1332 decoded->dst.addr_mode = MODE_AREG; |
1262 } else { | 1333 } else { |
1263 decoded->extra.size = size; | 1334 decoded->extra.size = size; |
1264 decoded->dst.addr_mode = MODE_REG; | 1335 decoded->dst.addr_mode = MODE_REG; |
1265 } | 1336 } |
1266 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1337 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1267 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1338 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
1268 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { | 1339 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { |
1269 decoded->op = M68K_INVALID; | 1340 decoded->op = M68K_INVALID; |
1270 break; | 1341 break; |
1271 } | 1342 } |
1272 } | 1343 } |
1273 break; | 1344 break; |
1274 case A_LINE: | 1345 case A_LINE: |
1275 decoded->op = M68K_A_LINE_TRAP; | 1346 decoded->op = M68K_A_LINE_TRAP; |
1276 break; | 1347 break; |
1277 case CMP_XOR: | 1348 case CMP_XOR: |
1278 size = (*istream >> 6) & 0x3; | 1349 size = (opcode >> 6) & 0x3; |
1279 decoded->op = M68K_CMP; | 1350 decoded->op = M68K_CMP; |
1280 if (*istream & 0x100) { | 1351 if (opcode & 0x100) { |
1281 //CMPM or CMPA.l or EOR | 1352 //CMPM or CMPA.l or EOR |
1282 if (size == OPSIZE_INVALID) { | 1353 if (size == OPSIZE_INVALID) { |
1283 decoded->extra.size = OPSIZE_LONG; | 1354 decoded->extra.size = OPSIZE_LONG; |
1284 decoded->dst.addr_mode = MODE_AREG; | 1355 decoded->dst.addr_mode = MODE_AREG; |
1285 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1356 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1286 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1357 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
1287 if (!istream) { | 1358 if (address == INVALID_ADDRESS) { |
1288 decoded->op = M68K_INVALID; | 1359 decoded->op = M68K_INVALID; |
1289 break; | 1360 break; |
1290 } | 1361 } |
1291 } else { | 1362 } else { |
1292 reg = m68k_reg_quick_field(*istream); | 1363 reg = m68k_reg_quick_field(opcode); |
1293 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1364 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
1294 if (!istream) { | 1365 if (address == INVALID_ADDRESS) { |
1295 decoded->op = M68K_INVALID; | 1366 decoded->op = M68K_INVALID; |
1296 break; | 1367 break; |
1297 } | 1368 } |
1298 decoded->extra.size = size; | 1369 decoded->extra.size = size; |
1299 if (decoded->dst.addr_mode == MODE_AREG) { | 1370 if (decoded->dst.addr_mode == MODE_AREG) { |
1318 decoded->dst.addr_mode = MODE_AREG; | 1389 decoded->dst.addr_mode = MODE_AREG; |
1319 } else { | 1390 } else { |
1320 decoded->extra.size = size; | 1391 decoded->extra.size = size; |
1321 decoded->dst.addr_mode = MODE_REG; | 1392 decoded->dst.addr_mode = MODE_REG; |
1322 } | 1393 } |
1323 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1394 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1324 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1395 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
1325 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { | 1396 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { |
1326 decoded->op = M68K_INVALID; | 1397 decoded->op = M68K_INVALID; |
1327 break; | 1398 break; |
1328 } | 1399 } |
1329 } | 1400 } |
1330 break; | 1401 break; |
1336 //10001 -one of each | 1407 //10001 -one of each |
1337 //AND opmodes: | 1408 //AND opmodes: |
1338 //operand order bit + 2 size bits (00 - 10) | 1409 //operand order bit + 2 size bits (00 - 10) |
1339 //no address register direct addressing | 1410 //no address register direct addressing |
1340 //data register direct not allowed when <ea> is the source (operand order bit of 1) | 1411 //data register direct not allowed when <ea> is the source (operand order bit of 1) |
1341 if (*istream & 0x100) { | 1412 if (opcode & 0x100) { |
1342 if ((*istream & 0xC0) == 0xC0) { | 1413 if ((opcode & 0xC0) == 0xC0) { |
1343 decoded->op = M68K_MULS; | 1414 decoded->op = M68K_MULS; |
1344 decoded->extra.size = OPSIZE_WORD; | 1415 decoded->extra.size = OPSIZE_WORD; |
1345 decoded->dst.addr_mode = MODE_REG; | 1416 decoded->dst.addr_mode = MODE_REG; |
1346 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1417 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1347 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1418 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src)); |
1348 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1419 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
1349 decoded->op = M68K_INVALID; | 1420 decoded->op = M68K_INVALID; |
1350 break; | 1421 break; |
1351 } | 1422 } |
1352 } else if(!(*istream & 0xF0)) { | 1423 } else if(!(opcode & 0xF0)) { |
1353 decoded->op = M68K_ABCD; | 1424 decoded->op = M68K_ABCD; |
1354 decoded->extra.size = OPSIZE_BYTE; | 1425 decoded->extra.size = OPSIZE_BYTE; |
1355 decoded->src.params.regs.pri = *istream & 0x7; | 1426 decoded->src.params.regs.pri = opcode & 0x7; |
1356 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1427 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1357 decoded->dst.addr_mode = decoded->src.addr_mode = (*istream & 8) ? MODE_AREG_PREDEC : MODE_REG; | 1428 decoded->dst.addr_mode = decoded->src.addr_mode = (opcode & 8) ? MODE_AREG_PREDEC : MODE_REG; |
1358 } else if(!(*istream & 0x30)) { | 1429 } else if(!(opcode & 0x30)) { |
1359 decoded->op = M68K_EXG; | 1430 decoded->op = M68K_EXG; |
1360 decoded->extra.size = OPSIZE_LONG; | 1431 decoded->extra.size = OPSIZE_LONG; |
1361 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1432 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode); |
1362 decoded->dst.params.regs.pri = *istream & 0x7; | 1433 decoded->dst.params.regs.pri = opcode & 0x7; |
1363 if (*istream & 0x8) { | 1434 if (opcode & 0x8) { |
1364 if (*istream & 0x80) { | 1435 if (opcode & 0x80) { |
1365 decoded->src.addr_mode = MODE_REG; | 1436 decoded->src.addr_mode = MODE_REG; |
1366 decoded->dst.addr_mode = MODE_AREG; | 1437 decoded->dst.addr_mode = MODE_AREG; |
1367 } else { | 1438 } else { |
1368 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG; | 1439 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG; |
1369 } | 1440 } |
1370 } else if (*istream & 0x40) { | 1441 } else if (opcode & 0x40) { |
1371 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_REG; | 1442 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_REG; |
1372 } else { | 1443 } else { |
1373 decoded->op = M68K_INVALID; | 1444 decoded->op = M68K_INVALID; |
1374 break; | 1445 break; |
1375 } | 1446 } |
1376 } else { | 1447 } else { |
1377 decoded->op = M68K_AND; | 1448 decoded->op = M68K_AND; |
1378 decoded->extra.size = (*istream >> 6) & 0x3; | 1449 decoded->extra.size = (opcode >> 6) & 0x3; |
1379 decoded->src.addr_mode = MODE_REG; | 1450 decoded->src.addr_mode = MODE_REG; |
1380 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1451 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode); |
1381 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); | 1452 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->dst)); |
1382 if (!istream || !m68k_valid_full_arith_dst(&(decoded->dst))) { | 1453 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&(decoded->dst))) { |
1383 decoded->op = M68K_INVALID; | 1454 decoded->op = M68K_INVALID; |
1384 break; | 1455 break; |
1385 } | 1456 } |
1386 } | 1457 } |
1387 } else { | 1458 } else { |
1388 if ((*istream & 0xC0) == 0xC0) { | 1459 if ((opcode & 0xC0) == 0xC0) { |
1389 decoded->op = M68K_MULU; | 1460 decoded->op = M68K_MULU; |
1390 decoded->extra.size = OPSIZE_WORD; | 1461 decoded->extra.size = OPSIZE_WORD; |
1391 decoded->dst.addr_mode = MODE_REG; | 1462 decoded->dst.addr_mode = MODE_REG; |
1392 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1463 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1393 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1464 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src)); |
1394 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1465 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
1395 decoded->op = M68K_INVALID; | 1466 decoded->op = M68K_INVALID; |
1396 break; | 1467 break; |
1397 } | 1468 } |
1398 } else { | 1469 } else { |
1399 decoded->op = M68K_AND; | 1470 decoded->op = M68K_AND; |
1400 decoded->extra.size = (*istream >> 6) & 0x3; | 1471 decoded->extra.size = (opcode >> 6) & 0x3; |
1401 decoded->dst.addr_mode = MODE_REG; | 1472 decoded->dst.addr_mode = MODE_REG; |
1402 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1473 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1403 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1474 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
1404 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1475 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) { |
1405 decoded->op = M68K_INVALID; | 1476 decoded->op = M68K_INVALID; |
1406 break; | 1477 break; |
1407 } | 1478 } |
1408 } | 1479 } |
1409 } | 1480 } |
1410 break; | 1481 break; |
1411 case ADD_ADDX: | 1482 case ADD_ADDX: |
1412 size = (*istream >> 6) & 0x3; | 1483 size = (opcode >> 6) & 0x3; |
1413 decoded->op = M68K_ADD; | 1484 decoded->op = M68K_ADD; |
1414 if (*istream & 0x100) { | 1485 if (opcode & 0x100) { |
1415 //<ea> destination, ADDA.l or ADDX | 1486 //<ea> destination, ADDA.l or ADDX |
1416 if (*istream & 0x30 || size == OPSIZE_INVALID) { | 1487 if (opcode & 0x30 || size == OPSIZE_INVALID) { |
1417 if (size == OPSIZE_INVALID) { | 1488 if (size == OPSIZE_INVALID) { |
1418 //ADDA.l | 1489 //ADDA.l |
1419 decoded->extra.size = OPSIZE_LONG; | 1490 decoded->extra.size = OPSIZE_LONG; |
1420 decoded->dst.addr_mode = MODE_AREG; | 1491 decoded->dst.addr_mode = MODE_AREG; |
1421 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1492 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1422 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 1493 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_LONG, &(decoded->src)); |
1423 if (!istream) { | 1494 if (address == INVALID_ADDRESS) { |
1424 decoded->op = M68K_INVALID; | 1495 decoded->op = M68K_INVALID; |
1425 break; | 1496 break; |
1426 } | 1497 } |
1427 } else { | 1498 } else { |
1428 decoded->extra.size = size; | 1499 decoded->extra.size = size; |
1429 decoded->src.addr_mode = MODE_REG; | 1500 decoded->src.addr_mode = MODE_REG; |
1430 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1501 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode); |
1431 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1502 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst)); |
1432 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) { | 1503 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&decoded->dst)) { |
1433 decoded->op = M68K_INVALID; | 1504 decoded->op = M68K_INVALID; |
1434 break; | 1505 break; |
1435 } | 1506 } |
1436 } | 1507 } |
1437 } else { | 1508 } else { |
1438 //ADDX | 1509 //ADDX |
1439 decoded->op = M68K_ADDX; | 1510 decoded->op = M68K_ADDX; |
1440 decoded->extra.size = size; | 1511 decoded->extra.size = size; |
1441 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1512 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1442 decoded->src.params.regs.pri = *istream & 0x7; | 1513 decoded->src.params.regs.pri = opcode & 0x7; |
1443 if (*istream & 0x8) { | 1514 if (opcode & 0x8) { |
1444 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; | 1515 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; |
1445 } else { | 1516 } else { |
1446 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; | 1517 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; |
1447 } | 1518 } |
1448 } | 1519 } |
1453 decoded->dst.addr_mode = MODE_AREG; | 1524 decoded->dst.addr_mode = MODE_AREG; |
1454 } else { | 1525 } else { |
1455 decoded->extra.size = size; | 1526 decoded->extra.size = size; |
1456 decoded->dst.addr_mode = MODE_REG; | 1527 decoded->dst.addr_mode = MODE_REG; |
1457 } | 1528 } |
1458 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1529 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode); |
1459 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1530 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src)); |
1460 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { | 1531 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { |
1461 decoded->op = M68K_INVALID; | 1532 decoded->op = M68K_INVALID; |
1462 break; | 1533 break; |
1463 } | 1534 } |
1464 } | 1535 } |
1465 break; | 1536 break; |
1466 case SHIFT_ROTATE: | 1537 case SHIFT_ROTATE: |
1467 if ((*istream & 0x8C0) == 0xC0) { | 1538 if ((opcode & 0x8C0) == 0xC0) { |
1468 switch((*istream >> 8) & 0x7) | 1539 switch((opcode >> 8) & 0x7) |
1469 { | 1540 { |
1470 case 0: | 1541 case 0: |
1471 decoded->op = M68K_ASR; | 1542 decoded->op = M68K_ASR; |
1472 break; | 1543 break; |
1473 case 1: | 1544 case 1: |
1491 case 7: | 1562 case 7: |
1492 decoded->op = M68K_ROL; | 1563 decoded->op = M68K_ROL; |
1493 break; | 1564 break; |
1494 } | 1565 } |
1495 decoded->extra.size = OPSIZE_WORD; | 1566 decoded->extra.size = OPSIZE_WORD; |
1496 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); | 1567 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->dst)); |
1497 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) { | 1568 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&decoded->dst)) { |
1498 decoded->op = M68K_INVALID; | 1569 decoded->op = M68K_INVALID; |
1499 break; | 1570 break; |
1500 } | 1571 } |
1501 } else if((*istream & 0xC0) != 0xC0) { | 1572 } else if((opcode & 0xC0) != 0xC0) { |
1502 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) | 1573 switch(((opcode >> 2) & 0x6) | ((opcode >> 8) & 1)) |
1503 { | 1574 { |
1504 case 0: | 1575 case 0: |
1505 decoded->op = M68K_ASR; | 1576 decoded->op = M68K_ASR; |
1506 break; | 1577 break; |
1507 case 1: | 1578 case 1: |
1524 break; | 1595 break; |
1525 case 7: | 1596 case 7: |
1526 decoded->op = M68K_ROL; | 1597 decoded->op = M68K_ROL; |
1527 break; | 1598 break; |
1528 } | 1599 } |
1529 decoded->extra.size = (*istream >> 6) & 0x3; | 1600 decoded->extra.size = (opcode >> 6) & 0x3; |
1530 immed = (*istream >> 9) & 0x7; | 1601 immed = (opcode >> 9) & 0x7; |
1531 if (*istream & 0x20) { | 1602 if (opcode & 0x20) { |
1532 decoded->src.addr_mode = MODE_REG; | 1603 decoded->src.addr_mode = MODE_REG; |
1533 decoded->src.params.regs.pri = immed; | 1604 decoded->src.params.regs.pri = immed; |
1534 } else { | 1605 } else { |
1535 decoded->src.addr_mode = MODE_IMMEDIATE; | 1606 decoded->src.addr_mode = MODE_IMMEDIATE; |
1536 if (!immed) { | 1607 if (!immed) { |
1538 } | 1609 } |
1539 decoded->src.params.immed = immed; | 1610 decoded->src.params.immed = immed; |
1540 decoded->variant = VAR_QUICK; | 1611 decoded->variant = VAR_QUICK; |
1541 } | 1612 } |
1542 decoded->dst.addr_mode = MODE_REG; | 1613 decoded->dst.addr_mode = MODE_REG; |
1543 decoded->dst.params.regs.pri = *istream & 0x7; | 1614 decoded->dst.params.regs.pri = opcode & 0x7; |
1544 | 1615 |
1545 } else { | 1616 } else { |
1546 #ifdef M68020 | 1617 #ifdef M68020 |
1547 //TODO: Implement bitfield instructions for M68020+ support | 1618 //TODO: Implement bitfield instructions for M68020+ support |
1548 switch (*istream >> 8 & 7) | 1619 switch (opcode >> 8 & 7) |
1549 { | 1620 { |
1550 case 0: | 1621 case 0: |
1551 decoded->op = M68K_BFTST; //<ea> | 1622 decoded->op = M68K_BFTST; //<ea> |
1552 break; | 1623 break; |
1553 case 1: | 1624 case 1: |
1570 break; | 1641 break; |
1571 case 7: | 1642 case 7: |
1572 decoded->op = M68K_BFINS; //Dn, <ea> | 1643 decoded->op = M68K_BFINS; //Dn, <ea> |
1573 break; | 1644 break; |
1574 } | 1645 } |
1575 opmode = *istream >> 3 & 0x7; | 1646 opmode = opcode >> 3 & 0x7; |
1576 reg = *istream & 0x7; | 1647 reg = opcode & 0x7; |
1577 m68k_op_info *ea, *other; | 1648 m68k_op_info *ea, *other; |
1578 if (decoded->op == M68K_BFEXTU || decoded->op == M68K_BFEXTS || decoded->op == M68K_BFFFO) | 1649 if (decoded->op == M68K_BFEXTU || decoded->op == M68K_BFEXTS || decoded->op == M68K_BFFFO) |
1579 { | 1650 { |
1580 ea = &(decoded->src); | 1651 ea = &(decoded->src); |
1581 other = &(decoded->dst); | 1652 other = &(decoded->dst); |
1582 } else { | 1653 } else { |
1583 ea = &(decoded->dst); | 1654 ea = &(decoded->dst); |
1584 other = &(decoded->dst); | 1655 other = &(decoded->dst); |
1585 } | 1656 } |
1586 if (*istream & 0x100) | 1657 if (opcode & 0x100) |
1587 { | 1658 { |
1588 immed = *(istream++); | 1659 immed = fetch(address, data); |
1660 address += 2; | |
1589 other->addr_mode = MODE_REG; | 1661 other->addr_mode = MODE_REG; |
1590 other->params.regs.pri = immed >> 12 & 0x7; | 1662 other->params.regs.pri = immed >> 12 & 0x7; |
1591 } else { | 1663 } else { |
1592 immed = *(istream++); | 1664 immed = fetch(address, data); |
1665 address += 2; | |
1593 } | 1666 } |
1594 decoded->extra.size = OPSIZE_UNSIZED; | 1667 decoded->extra.size = OPSIZE_UNSIZED; |
1595 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, ea); | 1668 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, ea); |
1596 ea->addr_mode |= M68K_FLAG_BITFIELD; | 1669 ea->addr_mode |= M68K_FLAG_BITFIELD; |
1597 ea->bitfield = immed & 0xFFF; | 1670 ea->bitfield = immed & 0xFFF; |
1598 #endif | 1671 #endif |
1599 } | 1672 } |
1600 break; | 1673 break; |
1602 //TODO: Decode FPU instructions for members of the 68K family with an FPU | 1675 //TODO: Decode FPU instructions for members of the 68K family with an FPU |
1603 decoded->op = M68K_F_LINE_TRAP; | 1676 decoded->op = M68K_F_LINE_TRAP; |
1604 break; | 1677 break; |
1605 } | 1678 } |
1606 if (decoded->op == M68K_INVALID) { | 1679 if (decoded->op == M68K_INVALID) { |
1607 decoded->src.params.immed = *start; | 1680 decoded->src.params.immed = opcode; |
1608 decoded->bytes = 2; | 1681 decoded->bytes = 2; |
1609 return start + 1; | 1682 return start_address + 2; |
1610 } | 1683 } |
1611 decoded->bytes = 2 * (istream + 1 - start); | 1684 decoded->bytes = address - start_address; |
1612 return istream+1; | 1685 return address; |
1613 } | 1686 } |
1614 | 1687 |
1615 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) | 1688 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) |
1616 { | 1689 { |
1617 if(inst->op == M68K_BCC || inst->op == M68K_BSR || inst->op == M68K_DBCC) { | 1690 if(inst->op == M68K_BCC || inst->op == M68K_BSR || inst->op == M68K_DBCC) { |
2607 } | 2680 } |
2608 return ret; | 2681 return ret; |
2609 #endif | 2682 #endif |
2610 default: | 2683 default: |
2611 size = decoded->extra.size; | 2684 size = decoded->extra.size; |
2612 uint8_t is_quick = decoded->variant == VAR_QUICK && decoded->op != M68K_ASL && decoded->op != M68K_ASR | 2685 uint8_t is_quick = decoded->variant == VAR_QUICK && decoded->op != M68K_ASL && decoded->op != M68K_ASR |
2613 && decoded->op != M68K_LSL && decoded->op != M68K_LSR && decoded->op != M68K_ROXR && decoded->op != M68K_ROXL | 2686 && decoded->op != M68K_LSL && decoded->op != M68K_LSR && decoded->op != M68K_ROXR && decoded->op != M68K_ROXL |
2614 && decoded->op != M68K_ROR && decoded->op != M68K_ROL; | 2687 && decoded->op != M68K_ROR && decoded->op != M68K_ROL; |
2615 ret = sprintf(dst, "%s%s%s", | 2688 ret = sprintf(dst, "%s%s%s", |
2616 mnemonics[decoded->op], | 2689 mnemonics[decoded->op], |
2617 is_quick ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), | 2690 is_quick ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), |