comparison 68kinst.c @ 823:b1b5a7e7d955

Detect invalid destination modes for immediate variant opcodes. This fixes a crash bug in Bill's Tomato Game on Windows
author Michael Pavone <pavone@retrodev.com>
date Mon, 03 Aug 2015 22:30:29 -0700
parents f822d9216968
children b4cf6573a3f8
comparison
equal deleted inserted replaced
822:ac65086c031e 823:b1b5a7e7d955
254 return NULL; 254 return NULL;
255 } 255 }
256 break; 256 break;
257 } 257 }
258 return cur; 258 return cur;
259 }
260
261 uint8_t m68k_valid_immed_dst(m68k_op_info *dst)
262 {
263 if (dst->addr_mode == MODE_AREG || dst->addr_mode == MODE_IMMEDIATE) {
264 return 0;
265 }
266 return 1;
267 }
268
269 uint8_t m68k_valid_immed_limited_dst(m68k_op_info *dst)
270 {
271 if (dst->addr_mode == MODE_AREG || dst->addr_mode > MODE_ABSOLUTE) {
272 return 0;
273 }
274 return 1;
259 } 275 }
260 276
261 uint16_t *m68k_decode_op(uint16_t *cur, uint8_t size, m68k_op_info *dst) 277 uint16_t *m68k_decode_op(uint16_t *cur, uint8_t size, m68k_op_info *dst)
262 { 278 {
263 uint8_t mode = (*cur >> 3) & 0x7; 279 uint8_t mode = (*cur >> 3) & 0x7;
404 immed = *(++istream); 420 immed = *(++istream);
405 decoded->src.params.immed = immed << 16 | *(++istream); 421 decoded->src.params.immed = immed << 16 | *(++istream);
406 break; 422 break;
407 } 423 }
408 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 424 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
409 if (!istream) { 425 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
410 decoded->op = M68K_INVALID; 426 decoded->op = M68K_INVALID;
411 break; 427 break;
412 } 428 }
413 } 429 }
414 break; 430 break;
443 immed = *(++istream); 459 immed = *(++istream);
444 decoded->src.params.immed = immed << 16 | *(++istream); 460 decoded->src.params.immed = immed << 16 | *(++istream);
445 break; 461 break;
446 } 462 }
447 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 463 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
448 if (!istream) { 464 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
449 decoded->op = M68K_INVALID; 465 decoded->op = M68K_INVALID;
450 break; 466 break;
451 } 467 }
452 } 468 }
453 break; 469 break;
470 immed = *(++istream); 486 immed = *(++istream);
471 decoded->src.params.immed = immed << 16 | *(++istream); 487 decoded->src.params.immed = immed << 16 | *(++istream);
472 break; 488 break;
473 } 489 }
474 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 490 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
475 if (!istream) { 491 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
476 decoded->op = M68K_INVALID; 492 decoded->op = M68K_INVALID;
477 break; 493 break;
478 } 494 }
479 break; 495 break;
480 case 3: 496 case 3:
496 immed = *(++istream); 512 immed = *(++istream);
497 decoded->src.params.immed = immed << 16 | *(++istream); 513 decoded->src.params.immed = immed << 16 | *(++istream);
498 break; 514 break;
499 } 515 }
500 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 516 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
501 if (!istream) { 517 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
502 decoded->op = M68K_INVALID; 518 decoded->op = M68K_INVALID;
503 break; 519 break;
504 } 520 }
505 break; 521 break;
506 case 4: 522 case 4:
559 immed = *(++istream); 575 immed = *(++istream);
560 decoded->src.params.immed = immed << 16 | *(++istream); 576 decoded->src.params.immed = immed << 16 | *(++istream);
561 break; 577 break;
562 } 578 }
563 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 579 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
564 if (!istream) { 580 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
565 decoded->op = M68K_INVALID; 581 decoded->op = M68K_INVALID;
566 break; 582 break;
567 } 583 }
568 } 584 }
569 break; 585 break;
586 immed = *(++istream); 602 immed = *(++istream);
587 decoded->src.params.immed = (immed << 16) | *(++istream); 603 decoded->src.params.immed = (immed << 16) | *(++istream);
588 break; 604 break;
589 } 605 }
590 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 606 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
591 if (!istream) { 607 if (!istream || !m68k_valid_immed_dst(&(decoded->dst))) {
592 decoded->op = M68K_INVALID; 608 decoded->op = M68K_INVALID;
593 break; 609 break;
594 } 610 }
595 break; 611 break;
596 case 7: 612 case 7: