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