Mercurial > repos > blastem
comparison 68kinst.c @ 176:e2918b5208eb
Print a message when we try to run an invalid instruction, not when we try to translate it
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 06 Jan 2013 21:42:57 -0800 |
parents | 5559616e6bd8 |
children | 3b4ef459aa8d |
comparison
equal
deleted
inserted
replaced
175:7504200cac86 | 176:e2918b5208eb |
---|---|
83 case OPSIZE_LONG: | 83 case OPSIZE_LONG: |
84 dst->params.immed = ext << 16 | *(++cur); | 84 dst->params.immed = ext << 16 | *(++cur); |
85 break; | 85 break; |
86 } | 86 } |
87 break; | 87 break; |
88 default: | |
89 return NULL; | |
88 } | 90 } |
89 break; | 91 break; |
90 } | 92 } |
91 return cur; | 93 return cur; |
92 } | 94 } |
108 return (op >> 9) & 0x7; | 110 return (op >> 9) & 0x7; |
109 } | 111 } |
110 | 112 |
111 uint16_t * m68k_decode(uint16_t * istream, m68kinst * decoded, uint32_t address) | 113 uint16_t * m68k_decode(uint16_t * istream, m68kinst * decoded, uint32_t address) |
112 { | 114 { |
115 uint16_t *start = istream; | |
113 uint8_t optype = *istream >> 12; | 116 uint8_t optype = *istream >> 12; |
114 uint8_t size; | 117 uint8_t size; |
115 uint8_t reg; | 118 uint8_t reg; |
116 uint8_t opmode; | 119 uint8_t opmode; |
117 uint32_t immed; | 120 uint32_t immed; |
160 } | 163 } |
161 decoded->src.addr_mode = MODE_REG; | 164 decoded->src.addr_mode = MODE_REG; |
162 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 165 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
163 decoded->extra.size = OPSIZE_BYTE; | 166 decoded->extra.size = OPSIZE_BYTE; |
164 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); | 167 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); |
168 if (!istream) { | |
169 decoded->op = M68K_INVALID; | |
170 return start+1; | |
171 } | |
165 if (decoded->dst.addr_mode == MODE_REG) { | 172 if (decoded->dst.addr_mode == MODE_REG) { |
166 decoded->extra.size = OPSIZE_LONG; | 173 decoded->extra.size = OPSIZE_LONG; |
167 } | 174 } |
168 } else if ((*istream & 0xF00) == 0x800) { | 175 } else if ((*istream & 0xF00) == 0x800) { |
169 //BTST, BCHG, BCLR, BSET | 176 //BTST, BCHG, BCLR, BSET |
186 reg = *istream & 0x7; | 193 reg = *istream & 0x7; |
187 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; | 194 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; |
188 decoded->src.params.immed = *(++istream) & 0xFF; | 195 decoded->src.params.immed = *(++istream) & 0xFF; |
189 decoded->extra.size = OPSIZE_BYTE; | 196 decoded->extra.size = OPSIZE_BYTE; |
190 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 197 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
198 if (!istream) { | |
199 decoded->op = M68K_INVALID; | |
200 return start+1; | |
201 } | |
191 if (decoded->dst.addr_mode == MODE_REG) { | 202 if (decoded->dst.addr_mode == MODE_REG) { |
192 decoded->extra.size = OPSIZE_LONG; | 203 decoded->extra.size = OPSIZE_LONG; |
193 } | 204 } |
194 } else if ((*istream & 0xC0) == 0xC0) { | 205 } else if ((*istream & 0xC0) == 0xC0) { |
195 #ifdef M68020 | 206 #ifdef M68020 |
228 immed = *(++istream); | 239 immed = *(++istream); |
229 decoded->src.params.immed = immed << 16 | *(++istream); | 240 decoded->src.params.immed = immed << 16 | *(++istream); |
230 break; | 241 break; |
231 } | 242 } |
232 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 243 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
244 if (!istream) { | |
245 decoded->op = M68K_INVALID; | |
246 return start+1; | |
247 } | |
233 } | 248 } |
234 break; | 249 break; |
235 case 1: | 250 case 1: |
236 //ANDI, ANDI to CCR, ANDI to SR | 251 //ANDI, ANDI to CCR, ANDI to SR |
237 if ((*istream & 0xFF) == 0x3C) { | 252 if ((*istream & 0xFF) == 0x3C) { |
263 immed = *(++istream); | 278 immed = *(++istream); |
264 decoded->src.params.immed = immed << 16 | *(++istream); | 279 decoded->src.params.immed = immed << 16 | *(++istream); |
265 break; | 280 break; |
266 } | 281 } |
267 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 282 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
283 if (!istream) { | |
284 decoded->op = M68K_INVALID; | |
285 return start+1; | |
286 } | |
268 } | 287 } |
269 break; | 288 break; |
270 case 2: | 289 case 2: |
271 decoded->op = M68K_SUB; | 290 decoded->op = M68K_SUB; |
272 decoded->variant = VAR_IMMEDIATE; | 291 decoded->variant = VAR_IMMEDIATE; |
286 immed = *(++istream); | 305 immed = *(++istream); |
287 decoded->src.params.immed = immed << 16 | *(++istream); | 306 decoded->src.params.immed = immed << 16 | *(++istream); |
288 break; | 307 break; |
289 } | 308 } |
290 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 309 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
310 if (!istream) { | |
311 decoded->op = M68K_INVALID; | |
312 return start+1; | |
313 } | |
291 break; | 314 break; |
292 case 3: | 315 case 3: |
293 decoded->op = M68K_ADD; | 316 decoded->op = M68K_ADD; |
294 decoded->variant = VAR_IMMEDIATE; | 317 decoded->variant = VAR_IMMEDIATE; |
295 decoded->src.addr_mode = MODE_IMMEDIATE; | 318 decoded->src.addr_mode = MODE_IMMEDIATE; |
308 immed = *(++istream); | 331 immed = *(++istream); |
309 decoded->src.params.immed = immed << 16 | *(++istream); | 332 decoded->src.params.immed = immed << 16 | *(++istream); |
310 break; | 333 break; |
311 } | 334 } |
312 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 335 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
336 if (!istream) { | |
337 decoded->op = M68K_INVALID; | |
338 return start+1; | |
339 } | |
313 break; | 340 break; |
314 case 4: | 341 case 4: |
315 //BTST, BCHG, BCLR, BSET | 342 //BTST, BCHG, BCLR, BSET |
316 switch ((*istream >> 6) & 0x3) | 343 switch ((*istream >> 6) & 0x3) |
317 { | 344 { |
329 break; | 356 break; |
330 } | 357 } |
331 decoded->src.addr_mode = MODE_IMMEDIATE; | 358 decoded->src.addr_mode = MODE_IMMEDIATE; |
332 decoded->src.params.immed = *(++istream) & 0xFF; | 359 decoded->src.params.immed = *(++istream) & 0xFF; |
333 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 360 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); |
361 if (!istream) { | |
362 decoded->op = M68K_INVALID; | |
363 return start+1; | |
364 } | |
334 break; | 365 break; |
335 case 5: | 366 case 5: |
336 //EORI, EORI to CCR, EORI to SR | 367 //EORI, EORI to CCR, EORI to SR |
337 if ((*istream & 0xFF) == 0x3C) { | 368 if ((*istream & 0xFF) == 0x3C) { |
338 decoded->op = M68K_EORI_CCR; | 369 decoded->op = M68K_EORI_CCR; |
363 immed = *(++istream); | 394 immed = *(++istream); |
364 decoded->src.params.immed = immed << 16 | *(++istream); | 395 decoded->src.params.immed = immed << 16 | *(++istream); |
365 break; | 396 break; |
366 } | 397 } |
367 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 398 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
399 if (!istream) { | |
400 decoded->op = M68K_INVALID; | |
401 return start+1; | |
402 } | |
368 } | 403 } |
369 break; | 404 break; |
370 case 6: | 405 case 6: |
371 decoded->op = M68K_CMP; | 406 decoded->op = M68K_CMP; |
372 decoded->variant = VAR_IMMEDIATE; | 407 decoded->variant = VAR_IMMEDIATE; |
386 immed = *(++istream); | 421 immed = *(++istream); |
387 decoded->src.params.immed = (immed << 16) | *(++istream); | 422 decoded->src.params.immed = (immed << 16) | *(++istream); |
388 break; | 423 break; |
389 } | 424 } |
390 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 425 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
426 if (!istream) { | |
427 decoded->op = M68K_INVALID; | |
428 return start+1; | |
429 } | |
391 break; | 430 break; |
392 case 7: | 431 case 7: |
393 | 432 |
394 | 433 |
395 break; | 434 break; |
402 decoded->op = M68K_MOVE; | 441 decoded->op = M68K_MOVE; |
403 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG); | 442 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG); |
404 opmode = (*istream >> 6) & 0x7; | 443 opmode = (*istream >> 6) & 0x7; |
405 reg = m68k_reg_quick_field(*istream); | 444 reg = m68k_reg_quick_field(*istream); |
406 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 445 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
446 if (!istream) { | |
447 decoded->op = M68K_INVALID; | |
448 return start+1; | |
449 } | |
407 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 450 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
451 if (!istream) { | |
452 decoded->op = M68K_INVALID; | |
453 return start+1; | |
454 } | |
408 break; | 455 break; |
409 case MISC: | 456 case MISC: |
410 | 457 |
411 if ((*istream & 0x1C0) == 0x1C0) { | 458 if ((*istream & 0x1C0) == 0x1C0) { |
412 decoded->op = M68K_LEA; | 459 decoded->op = M68K_LEA; |
413 decoded->extra.size = OPSIZE_LONG; | 460 decoded->extra.size = OPSIZE_LONG; |
414 decoded->dst.addr_mode = MODE_AREG; | 461 decoded->dst.addr_mode = MODE_AREG; |
415 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 462 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
416 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 463 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
464 if (!istream) { | |
465 decoded->op = M68K_INVALID; | |
466 return start+1; | |
467 } | |
417 } else { | 468 } else { |
418 if (*istream & 0x100) { | 469 if (*istream & 0x100) { |
419 decoded->op = M68K_CHK; | 470 decoded->op = M68K_CHK; |
420 if ((*istream & 0x180) == 0x180) { | 471 if ((*istream & 0x180) == 0x180) { |
421 decoded->extra.size = OPSIZE_WORD; | 472 decoded->extra.size = OPSIZE_WORD; |
427 decoded->op = M68K_INVALID; | 478 decoded->op = M68K_INVALID; |
428 break; | 479 break; |
429 #endif | 480 #endif |
430 } | 481 } |
431 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 482 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
483 if (!istream) { | |
484 decoded->op = M68K_INVALID; | |
485 return start+1; | |
486 } | |
432 decoded->dst.addr_mode = MODE_REG; | 487 decoded->dst.addr_mode = MODE_REG; |
433 decoded->dst.addr_mode = m68k_reg_quick_field(*istream); | 488 decoded->dst.addr_mode = m68k_reg_quick_field(*istream); |
434 } else { | 489 } else { |
435 opmode = (*istream >> 3) & 0x7; | 490 opmode = (*istream >> 3) & 0x7; |
436 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { | 491 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { |
440 reg = *istream & 0x7; | 495 reg = *istream & 0x7; |
441 if(*istream & 0x400) { | 496 if(*istream & 0x400) { |
442 decoded->dst.addr_mode = MODE_REG; | 497 decoded->dst.addr_mode = MODE_REG; |
443 decoded->dst.params.immed = *(++istream); | 498 decoded->dst.params.immed = *(++istream); |
444 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); | 499 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); |
500 if (!istream) { | |
501 decoded->op = M68K_INVALID; | |
502 return start+1; | |
503 } | |
445 } else { | 504 } else { |
446 decoded->src.addr_mode = MODE_REG; | 505 decoded->src.addr_mode = MODE_REG; |
447 decoded->src.params.immed = *(++istream); | 506 decoded->src.params.immed = *(++istream); |
448 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 507 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
508 if (!istream) { | |
509 decoded->op = M68K_INVALID; | |
510 return start+1; | |
511 } | |
449 } | 512 } |
450 } else { | 513 } else { |
451 optype = (*istream >> 9) & 0x7; | 514 optype = (*istream >> 9) & 0x7; |
452 size = (*istream >> 6) & 0x3; | 515 size = (*istream >> 6) & 0x3; |
453 switch(optype) | 516 switch(optype) |
460 } else { | 523 } else { |
461 decoded->op = M68K_NEGX; | 524 decoded->op = M68K_NEGX; |
462 } | 525 } |
463 decoded->extra.size = size; | 526 decoded->extra.size = size; |
464 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 527 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
528 if (!istream) { | |
529 decoded->op = M68K_INVALID; | |
530 return start+1; | |
531 } | |
465 break; | 532 break; |
466 case 1: | 533 case 1: |
467 //MOVE from CCR or CLR | 534 //MOVE from CCR or CLR |
468 if (size == OPSIZE_INVALID) { | 535 if (size == OPSIZE_INVALID) { |
469 #ifdef M68010 | 536 #ifdef M68010 |
475 } else { | 542 } else { |
476 decoded->op = M68K_CLR; | 543 decoded->op = M68K_CLR; |
477 } | 544 } |
478 decoded->extra.size = size; | 545 decoded->extra.size = size; |
479 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 546 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
547 if (!istream) { | |
548 decoded->op = M68K_INVALID; | |
549 return start+1; | |
550 } | |
480 break; | 551 break; |
481 case 2: | 552 case 2: |
482 //MOVE to CCR or NEG | 553 //MOVE to CCR or NEG |
483 if (size == OPSIZE_INVALID) { | 554 if (size == OPSIZE_INVALID) { |
484 decoded->op = M68K_MOVE_CCR; | 555 decoded->op = M68K_MOVE_CCR; |
485 size = OPSIZE_WORD; | 556 size = OPSIZE_WORD; |
486 istream= m68k_decode_op(istream, size, &(decoded->src)); | 557 istream= m68k_decode_op(istream, size, &(decoded->src)); |
558 if (!istream) { | |
559 decoded->op = M68K_INVALID; | |
560 return start+1; | |
561 } | |
487 } else { | 562 } else { |
488 decoded->op = M68K_NEG; | 563 decoded->op = M68K_NEG; |
489 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 564 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
565 if (!istream) { | |
566 decoded->op = M68K_INVALID; | |
567 return start+1; | |
568 } | |
490 } | 569 } |
491 decoded->extra.size = size; | 570 decoded->extra.size = size; |
492 break; | 571 break; |
493 case 3: | 572 case 3: |
494 //MOVE to SR or NOT | 573 //MOVE to SR or NOT |
495 if (size == OPSIZE_INVALID) { | 574 if (size == OPSIZE_INVALID) { |
496 decoded->op = M68K_MOVE_SR; | 575 decoded->op = M68K_MOVE_SR; |
497 size = OPSIZE_WORD; | 576 size = OPSIZE_WORD; |
498 istream= m68k_decode_op(istream, size, &(decoded->src)); | 577 istream= m68k_decode_op(istream, size, &(decoded->src)); |
578 if (!istream) { | |
579 decoded->op = M68K_INVALID; | |
580 return start+1; | |
581 } | |
499 } else { | 582 } else { |
500 decoded->op = M68K_NOT; | 583 decoded->op = M68K_NOT; |
501 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 584 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
585 if (!istream) { | |
586 decoded->op = M68K_INVALID; | |
587 return start+1; | |
588 } | |
502 } | 589 } |
503 decoded->extra.size = size; | 590 decoded->extra.size = size; |
504 break; | 591 break; |
505 case 4: | 592 case 4: |
506 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA | 593 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA |
548 default: | 635 default: |
549 if (!(*istream & 0x1C0)) { | 636 if (!(*istream & 0x1C0)) { |
550 decoded->op = M68K_NBCD; | 637 decoded->op = M68K_NBCD; |
551 decoded->extra.size = OPSIZE_BYTE; | 638 decoded->extra.size = OPSIZE_BYTE; |
552 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 639 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); |
640 if (!istream) { | |
641 decoded->op = M68K_INVALID; | |
642 return start+1; | |
643 } | |
553 } else if((*istream & 0x1C0) == 0x40) { | 644 } else if((*istream & 0x1C0) == 0x40) { |
554 decoded->op = M68K_PEA; | 645 decoded->op = M68K_PEA; |
555 decoded->extra.size = OPSIZE_LONG; | 646 decoded->extra.size = OPSIZE_LONG; |
556 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 647 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); |
648 if (!istream) { | |
649 decoded->op = M68K_INVALID; | |
650 return start+1; | |
651 } | |
557 } | 652 } |
558 } | 653 } |
559 break; | 654 break; |
560 case 5: | 655 case 5: |
561 //BGND, ILLEGAL, TAS, TST | 656 //BGND, ILLEGAL, TAS, TST |
570 decoded->op = M68K_TAS; | 665 decoded->op = M68K_TAS; |
571 } else { | 666 } else { |
572 decoded->op = M68K_TST; | 667 decoded->op = M68K_TST; |
573 decoded->extra.size = size; | 668 decoded->extra.size = size; |
574 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 669 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
670 if (!istream) { | |
671 decoded->op = M68K_INVALID; | |
672 return start+1; | |
673 } | |
575 } | 674 } |
576 } | 675 } |
577 break; | 676 break; |
578 case 6: | 677 case 6: |
579 //MULU, MULS, DIVU, DIVUL, DIVS, DIVSL | 678 //MULU, MULS, DIVU, DIVUL, DIVS, DIVSL |
590 } else { | 689 } else { |
591 decoded->op = M68K_JSR; | 690 decoded->op = M68K_JSR; |
592 } | 691 } |
593 decoded->extra.size = OPSIZE_UNSIZED; | 692 decoded->extra.size = OPSIZE_UNSIZED; |
594 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src)); | 693 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src)); |
694 if (!istream) { | |
695 decoded->op = M68K_INVALID; | |
696 return start+1; | |
697 } | |
595 } else { | 698 } else { |
596 //it would appear bit 6 needs to be set for it to be a valid instruction here | 699 //it would appear bit 6 needs to be set for it to be a valid instruction here |
597 switch((*istream >> 3) & 0x7) | 700 switch((*istream >> 3) & 0x7) |
598 { | 701 { |
599 case 0: | 702 case 0: |
700 #endif | 803 #endif |
701 } else { | 804 } else { |
702 decoded->op = M68K_SCC; | 805 decoded->op = M68K_SCC; |
703 decoded->extra.cond = (*istream >> 8) & 0xF; | 806 decoded->extra.cond = (*istream >> 8) & 0xF; |
704 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 807 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); |
808 if (!istream) { | |
809 decoded->op = M68K_INVALID; | |
810 return start+1; | |
811 } | |
705 } | 812 } |
706 } else { | 813 } else { |
707 //ADDQ, SUBQ | 814 //ADDQ, SUBQ |
708 decoded->variant = VAR_QUICK; | 815 decoded->variant = VAR_QUICK; |
709 decoded->extra.size = size; | 816 decoded->extra.size = size; |
717 decoded->op = M68K_SUB; | 824 decoded->op = M68K_SUB; |
718 } else { | 825 } else { |
719 decoded->op = M68K_ADD; | 826 decoded->op = M68K_ADD; |
720 } | 827 } |
721 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 828 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
829 if (!istream) { | |
830 decoded->op = M68K_INVALID; | |
831 return start+1; | |
832 } | |
722 } | 833 } |
723 break; | 834 break; |
724 case BRANCH: | 835 case BRANCH: |
725 m68k_decode_cond(*istream, decoded); | 836 m68k_decode_cond(*istream, decoded); |
726 decoded->op = decoded->extra.cond == COND_FALSE ? M68K_BSR : M68K_BCC; | 837 decoded->op = decoded->extra.cond == COND_FALSE ? M68K_BSR : M68K_BCC; |
763 decoded->op = M68K_DIVU; | 874 decoded->op = M68K_DIVU; |
764 decoded->extra.size = OPSIZE_WORD; | 875 decoded->extra.size = OPSIZE_WORD; |
765 decoded->dst.addr_mode = MODE_REG; | 876 decoded->dst.addr_mode = MODE_REG; |
766 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 877 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; |
767 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 878 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
879 if (!istream) { | |
880 decoded->op = M68K_INVALID; | |
881 return start+1; | |
882 } | |
768 break; | 883 break; |
769 case 4: | 884 case 4: |
770 decoded->op = M68K_SBCD; | 885 decoded->op = M68K_SBCD; |
771 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG; | 886 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG; |
772 decoded->src.params.regs.pri = *istream & 0x7; | 887 decoded->src.params.regs.pri = *istream & 0x7; |
784 decoded->op = M68K_DIVS; | 899 decoded->op = M68K_DIVS; |
785 decoded->extra.size = OPSIZE_WORD; | 900 decoded->extra.size = OPSIZE_WORD; |
786 decoded->dst.addr_mode = MODE_REG; | 901 decoded->dst.addr_mode = MODE_REG; |
787 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 902 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; |
788 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 903 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
904 if (!istream) { | |
905 decoded->op = M68K_INVALID; | |
906 return start+1; | |
907 } | |
789 break; | 908 break; |
790 } | 909 } |
791 } else { | 910 } else { |
792 decoded->op = M68K_OR; | 911 decoded->op = M68K_OR; |
793 decoded->extra.size = size; | 912 decoded->extra.size = size; |
794 if (opmode & 0x4) { | 913 if (opmode & 0x4) { |
795 decoded->src.addr_mode = MODE_REG; | 914 decoded->src.addr_mode = MODE_REG; |
796 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; | 915 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; |
797 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 916 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
917 if (!istream) { | |
918 decoded->op = M68K_INVALID; | |
919 return start+1; | |
920 } | |
798 } else { | 921 } else { |
799 decoded->dst.addr_mode = MODE_REG; | 922 decoded->dst.addr_mode = MODE_REG; |
800 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 923 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; |
801 istream = m68k_decode_op(istream, size, &(decoded->src)); | 924 istream = m68k_decode_op(istream, size, &(decoded->src)); |
925 if (!istream) { | |
926 decoded->op = M68K_INVALID; | |
927 return start+1; | |
928 } | |
802 } | 929 } |
803 } | 930 } |
804 break; | 931 break; |
805 case SUB_SUBX: | 932 case SUB_SUBX: |
806 size = (*istream >> 6) & 0x3; | 933 size = (*istream >> 6) & 0x3; |
812 //SUBA.l | 939 //SUBA.l |
813 decoded->extra.size = OPSIZE_LONG; | 940 decoded->extra.size = OPSIZE_LONG; |
814 decoded->dst.addr_mode = MODE_AREG; | 941 decoded->dst.addr_mode = MODE_AREG; |
815 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 942 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
816 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 943 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); |
944 if (!istream) { | |
945 decoded->op = M68K_INVALID; | |
946 return start+1; | |
947 } | |
817 } else { | 948 } else { |
818 decoded->extra.size = size; | 949 decoded->extra.size = size; |
819 decoded->src.addr_mode = MODE_REG; | 950 decoded->src.addr_mode = MODE_REG; |
820 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 951 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
821 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 952 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
953 if (!istream) { | |
954 decoded->op = M68K_INVALID; | |
955 return start+1; | |
956 } | |
822 } | 957 } |
823 } else { | 958 } else { |
824 //SUBX | 959 //SUBX |
825 decoded->op = M68K_SUBX; | 960 decoded->op = M68K_SUBX; |
826 decoded->extra.size = size; | 961 decoded->extra.size = size; |
827 istream = m68k_decode_op(istream, size, &(decoded->src)); | 962 istream = m68k_decode_op(istream, size, &(decoded->src)); |
963 if (!istream) { | |
964 decoded->op = M68K_INVALID; | |
965 return start+1; | |
966 } | |
828 decoded->dst.addr_mode = decoded->src.addr_mode; | 967 decoded->dst.addr_mode = decoded->src.addr_mode; |
829 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 968 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
830 } | 969 } |
831 } else { | 970 } else { |
832 if (size == OPSIZE_INVALID) { | 971 if (size == OPSIZE_INVALID) { |
837 decoded->extra.size = size; | 976 decoded->extra.size = size; |
838 decoded->dst.addr_mode = MODE_REG; | 977 decoded->dst.addr_mode = MODE_REG; |
839 } | 978 } |
840 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 979 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
841 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 980 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
981 if (!istream) { | |
982 decoded->op = M68K_INVALID; | |
983 return start+1; | |
984 } | |
842 } | 985 } |
843 break; | 986 break; |
844 case RESERVED: | 987 case RESERVED: |
845 break; | 988 break; |
846 case CMP_XOR: | 989 case CMP_XOR: |
851 if (size == OPSIZE_INVALID) { | 994 if (size == OPSIZE_INVALID) { |
852 decoded->extra.size = OPSIZE_LONG; | 995 decoded->extra.size = OPSIZE_LONG; |
853 decoded->dst.addr_mode = MODE_AREG; | 996 decoded->dst.addr_mode = MODE_AREG; |
854 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 997 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
855 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 998 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
999 if (!istream) { | |
1000 decoded->op = M68K_INVALID; | |
1001 return start+1; | |
1002 } | |
856 } else { | 1003 } else { |
857 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1004 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
1005 if (!istream) { | |
1006 decoded->op = M68K_INVALID; | |
1007 return start+1; | |
1008 } | |
858 if (decoded->src.addr_mode == MODE_AREG) { | 1009 if (decoded->src.addr_mode == MODE_AREG) { |
859 //CMPM | 1010 //CMPM |
860 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; | 1011 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; |
861 decoded->src.params.regs.pri = decoded->dst.params.regs.pri; | 1012 decoded->src.params.regs.pri = decoded->dst.params.regs.pri; |
862 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1013 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
877 decoded->extra.size = size; | 1028 decoded->extra.size = size; |
878 decoded->dst.addr_mode = MODE_REG; | 1029 decoded->dst.addr_mode = MODE_REG; |
879 } | 1030 } |
880 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1031 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
881 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1032 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
1033 if (!istream) { | |
1034 decoded->op = M68K_INVALID; | |
1035 return start+1; | |
1036 } | |
882 } | 1037 } |
883 break; | 1038 break; |
884 case AND_MUL_ABCD_EXG: | 1039 case AND_MUL_ABCD_EXG: |
885 //page 575 for summary | 1040 //page 575 for summary |
886 //EXG opmodes: | 1041 //EXG opmodes: |
896 decoded->op = M68K_MULS; | 1051 decoded->op = M68K_MULS; |
897 decoded->extra.size = OPSIZE_WORD; | 1052 decoded->extra.size = OPSIZE_WORD; |
898 decoded->dst.addr_mode = MODE_REG; | 1053 decoded->dst.addr_mode = MODE_REG; |
899 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1054 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
900 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1055 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
1056 if (!istream) { | |
1057 decoded->op = M68K_INVALID; | |
1058 return start+1; | |
1059 } | |
901 } else if(!(*istream & 0xF0)) { | 1060 } else if(!(*istream & 0xF0)) { |
902 decoded->op = M68K_ABCD; | 1061 decoded->op = M68K_ABCD; |
903 decoded->extra.size = OPSIZE_BYTE; | 1062 decoded->extra.size = OPSIZE_BYTE; |
904 decoded->src.params.regs.pri = *istream & 0x7; | 1063 decoded->src.params.regs.pri = *istream & 0x7; |
905 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1064 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
923 decoded->op = M68K_AND; | 1082 decoded->op = M68K_AND; |
924 decoded->extra.size = (*istream >> 6) & 0x3; | 1083 decoded->extra.size = (*istream >> 6) & 0x3; |
925 decoded->src.addr_mode = MODE_REG; | 1084 decoded->src.addr_mode = MODE_REG; |
926 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1085 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
927 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); | 1086 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); |
1087 if (!istream) { | |
1088 decoded->op = M68K_INVALID; | |
1089 return start+1; | |
1090 } | |
928 } | 1091 } |
929 } else { | 1092 } else { |
930 if ((*istream & 0xC0) == 0xC0) { | 1093 if ((*istream & 0xC0) == 0xC0) { |
931 decoded->op = M68K_MULU; | 1094 decoded->op = M68K_MULU; |
932 decoded->extra.size = OPSIZE_WORD; | 1095 decoded->extra.size = OPSIZE_WORD; |
933 decoded->dst.addr_mode = MODE_REG; | 1096 decoded->dst.addr_mode = MODE_REG; |
934 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1097 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
935 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1098 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
1099 if (!istream) { | |
1100 decoded->op = M68K_INVALID; | |
1101 return start+1; | |
1102 } | |
936 } else { | 1103 } else { |
937 decoded->op = M68K_AND; | 1104 decoded->op = M68K_AND; |
938 decoded->extra.size = (*istream >> 6) & 0x3; | 1105 decoded->extra.size = (*istream >> 6) & 0x3; |
939 decoded->dst.addr_mode = MODE_REG; | 1106 decoded->dst.addr_mode = MODE_REG; |
940 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1107 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
941 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1108 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
1109 if (!istream) { | |
1110 decoded->op = M68K_INVALID; | |
1111 return start+1; | |
1112 } | |
942 } | 1113 } |
943 } | 1114 } |
944 break; | 1115 break; |
945 case ADD_ADDX: | 1116 case ADD_ADDX: |
946 size = (*istream >> 6) & 0x3; | 1117 size = (*istream >> 6) & 0x3; |
952 //ADDA.l | 1123 //ADDA.l |
953 decoded->extra.size = OPSIZE_LONG; | 1124 decoded->extra.size = OPSIZE_LONG; |
954 decoded->dst.addr_mode = MODE_AREG; | 1125 decoded->dst.addr_mode = MODE_AREG; |
955 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1126 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
956 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 1127 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); |
1128 if (!istream) { | |
1129 decoded->op = M68K_INVALID; | |
1130 return start+1; | |
1131 } | |
957 } else { | 1132 } else { |
958 decoded->extra.size = size; | 1133 decoded->extra.size = size; |
959 decoded->src.addr_mode = MODE_REG; | 1134 decoded->src.addr_mode = MODE_REG; |
960 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1135 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
961 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1136 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
1137 if (!istream) { | |
1138 decoded->op = M68K_INVALID; | |
1139 return start+1; | |
1140 } | |
962 } | 1141 } |
963 } else { | 1142 } else { |
964 //ADDX | 1143 //ADDX |
965 decoded->op = M68K_ADDX; | 1144 decoded->op = M68K_ADDX; |
966 //FIXME: Size is not technically correct | 1145 //FIXME: Size is not technically correct |
967 decoded->extra.size = size; | 1146 decoded->extra.size = size; |
968 istream = m68k_decode_op(istream, size, &(decoded->src)); | 1147 istream = m68k_decode_op(istream, size, &(decoded->src)); |
1148 if (!istream) { | |
1149 decoded->op = M68K_INVALID; | |
1150 return start+1; | |
1151 } | |
969 decoded->dst.addr_mode = decoded->src.addr_mode; | 1152 decoded->dst.addr_mode = decoded->src.addr_mode; |
970 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1153 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
971 } | 1154 } |
972 } else { | 1155 } else { |
973 if (size == OPSIZE_INVALID) { | 1156 if (size == OPSIZE_INVALID) { |
978 decoded->extra.size = size; | 1161 decoded->extra.size = size; |
979 decoded->dst.addr_mode = MODE_REG; | 1162 decoded->dst.addr_mode = MODE_REG; |
980 } | 1163 } |
981 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1164 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
982 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1165 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
1166 if (!istream) { | |
1167 decoded->op = M68K_INVALID; | |
1168 return start+1; | |
1169 } | |
983 } | 1170 } |
984 break; | 1171 break; |
985 case SHIFT_ROTATE: | 1172 case SHIFT_ROTATE: |
986 if ((*istream & 0x8C0) == 0xC0) { | 1173 if ((*istream & 0x8C0) == 0xC0) { |
987 switch((*istream >> 8) & 0x7) | 1174 switch((*istream >> 8) & 0x7) |
1011 decoded->op = M68K_ROL; | 1198 decoded->op = M68K_ROL; |
1012 break; | 1199 break; |
1013 } | 1200 } |
1014 decoded->extra.size = OPSIZE_WORD; | 1201 decoded->extra.size = OPSIZE_WORD; |
1015 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); | 1202 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); |
1203 if (!istream) { | |
1204 decoded->op = M68K_INVALID; | |
1205 return start+1; | |
1206 } | |
1016 } else if((*istream & 0xC0) != 0xC0) { | 1207 } else if((*istream & 0xC0) != 0xC0) { |
1017 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) | 1208 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) |
1018 { | 1209 { |
1019 case 0: | 1210 case 0: |
1020 decoded->op = M68K_ASR; | 1211 decoded->op = M68K_ASR; |