diff 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
line wrap: on
line diff
--- a/68kinst.c	Mon Aug 03 20:06:56 2015 -0700
+++ b/68kinst.c	Mon Aug 03 22:30:29 2015 -0700
@@ -258,6 +258,22 @@
 	return cur;
 }
 
+uint8_t m68k_valid_immed_dst(m68k_op_info *dst)
+{
+	if (dst->addr_mode == MODE_AREG || dst->addr_mode == MODE_IMMEDIATE) {
+		return 0;
+	}
+	return 1;
+}
+
+uint8_t m68k_valid_immed_limited_dst(m68k_op_info *dst)
+{
+	if (dst->addr_mode == MODE_AREG || dst->addr_mode > MODE_ABSOLUTE) {
+		return 0;
+	}
+	return 1;
+}
+
 uint16_t *m68k_decode_op(uint16_t *cur, uint8_t size, m68k_op_info *dst)
 {
 	uint8_t mode = (*cur >> 3) & 0x7;
@@ -406,7 +422,7 @@
 						break;
 					}
 					istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
-					if (!istream) {
+					if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
 						decoded->op = M68K_INVALID;
 						break;
 					}
@@ -445,7 +461,7 @@
 						break;
 					}
 					istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
-					if (!istream) {
+					if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
 						decoded->op = M68K_INVALID;
 						break;
 					}
@@ -472,7 +488,7 @@
 					break;
 				}
 				istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
-				if (!istream) {
+				if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
 					decoded->op = M68K_INVALID;
 					break;
 				}
@@ -498,7 +514,7 @@
 					break;
 				}
 				istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
-				if (!istream) {
+				if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
 					decoded->op = M68K_INVALID;
 					break;
 				}
@@ -561,7 +577,7 @@
 						break;
 					}
 					istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
-					if (!istream) {
+					if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
 						decoded->op = M68K_INVALID;
 						break;
 					}
@@ -588,7 +604,7 @@
 					break;
 				}
 				istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
-				if (!istream) {
+				if (!istream || !m68k_valid_immed_dst(&(decoded->dst))) {
 					decoded->op = M68K_INVALID;
 					break;
 				}