summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Phil Bennett <philipjbennett@users.noreply.github.com>2010-12-22 22:46:53 +0000
committer Phil Bennett <philipjbennett@users.noreply.github.com>2010-12-22 22:46:53 +0000
commit86fd47653b1820ed0ac6d4dd4ff8af70aadcb742 (patch)
treedf9afb5281a783928b41baaea5e506116f9fcee1 /src
parent8ac798287baa3b04df2de1063f07bcdc0e835d14 (diff)
04147: raiden: crashes if you use -debug switch [Alex Jackson]
---------- Forwarded message ---------- From: Alex Jackson <awj_in_japan@hotmail.com> Date: Mon, Dec 20, 2010 at 3:37 AM Subject: MT bug 04147 fix; trivial debugger fix To: submit@mamedev.org i86length.diff fixes MT bug 04147: raiden: crashes if you use -debug switch. My patch makes the i386 and nec disassemblers enforce the same maximum instruction length as CPUINFO_INT_MAX_INSTRUCTION_BYTES (previously the disassemblers always enforced a maximum length of 15 bytes, but the value of CPUINFO_INT_MAX_INSTRUCTION_BYTES varied between CPUs... this was my fault, sorry) The maximum legal instruction length on the 80286 is 10 bytes, and on the 80386 and all later Intel and clone CPUs it's 15 bytes. Exceeding the limit causes an illegal instruction exception. Intel CPUs prior to the 80286, and NEC-V CPUs, don't enforce a maximum instruction length (they don't even have an "illegal instruction" exception), but the longest possible instruction without redundant prefixes is 8 bytes on both, so I've made that the maximum instruction length for disassembly purposes. debugger.diff fixes a trivial bug in the debugger dump commands. 0x7f is not a printable character in either ASCII or UTF-8... so don't print it in the "ASCII" column when hex dumping. --AWJ
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/i386/i386dasm.c43
-rw-r--r--src/emu/cpu/i86/i286.c4
-rw-r--r--src/emu/cpu/i86/i86.c4
-rw-r--r--src/emu/cpu/nec/necdasm.c10
4 files changed, 45 insertions, 16 deletions
diff --git a/src/emu/cpu/i386/i386dasm.c b/src/emu/cpu/i386/i386dasm.c
index abe7bc9bfba..d28db9aac7f 100644
--- a/src/emu/cpu/i386/i386dasm.c
+++ b/src/emu/cpu/i386/i386dasm.c
@@ -1092,6 +1092,7 @@ static const char *const i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "??
static int address_size;
static int operand_size;
+static int max_length;
static UINT64 pc;
static UINT8 modrm;
static UINT32 segment;
@@ -1106,7 +1107,7 @@ static UINT8 curmode;
INLINE UINT8 FETCH(void)
{
- if ((opcode_ptr - opcode_ptr_base) + 1 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 1 > max_length)
return 0xff;
pc++;
return *opcode_ptr++;
@@ -1115,7 +1116,7 @@ INLINE UINT8 FETCH(void)
INLINE UINT16 FETCH16(void)
{
UINT16 d;
- if ((opcode_ptr - opcode_ptr_base) + 2 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 2 > max_length)
return 0xffff;
d = opcode_ptr[0] | (opcode_ptr[1] << 8);
opcode_ptr += 2;
@@ -1126,7 +1127,7 @@ INLINE UINT16 FETCH16(void)
INLINE UINT32 FETCH32(void)
{
UINT32 d;
- if ((opcode_ptr - opcode_ptr_base) + 4 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 4 > max_length)
return 0xffffffff;
d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24);
opcode_ptr += 4;
@@ -1136,7 +1137,7 @@ INLINE UINT32 FETCH32(void)
INLINE UINT8 FETCHD(void)
{
- if ((opcode_ptr - opcode_ptr_base) + 1 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 1 > max_length)
return 0xff;
pc++;
return *opcode_ptr++;
@@ -1145,7 +1146,7 @@ INLINE UINT8 FETCHD(void)
INLINE UINT16 FETCHD16(void)
{
UINT16 d;
- if ((opcode_ptr - opcode_ptr_base) + 2 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 2 > max_length)
return 0xffff;
d = opcode_ptr[0] | (opcode_ptr[1] << 8);
opcode_ptr += 2;
@@ -1156,7 +1157,7 @@ INLINE UINT16 FETCHD16(void)
INLINE UINT32 FETCHD32(void)
{
UINT32 d;
- if ((opcode_ptr - opcode_ptr_base) + 4 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 4 > max_length)
return 0xffffffff;
d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24);
opcode_ptr += 4;
@@ -2128,8 +2129,34 @@ int i386_dasm_one_ex(char *buffer, UINT64 eip, const UINT8 *oprom, int mode)
UINT8 op;
opcode_ptr = opcode_ptr_base = oprom;
- address_size = (mode == 16) ? 0 : (mode == 32) ? 1 : 2;
- operand_size = (mode == 16) ? 0 : 1;
+ switch(mode)
+ {
+ case 1: /* 8086/8088/80186/80188 */
+ address_size = 0;
+ operand_size = 0;
+ max_length = 8; /* maximum without redundant prefixes - not enforced by chip */
+ break;
+ case 2: /* 80286 */
+ address_size = 0;
+ operand_size = 0;
+ max_length = 10;
+ break;
+ case 16: /* 80386+ 16-bit code segment */
+ address_size = 0;
+ operand_size = 0;
+ max_length = 15;
+ break;
+ case 32: /* 80386+ 32-bit code segment */
+ address_size = 1;
+ operand_size = 1;
+ max_length = 15;
+ break;
+ case 64: /* x86_64 */
+ address_size = 2;
+ operand_size = 1;
+ max_length = 15;
+ break;
+ }
pc = eip;
dasm_flags = 0;
segment = 0;
diff --git a/src/emu/cpu/i86/i286.c b/src/emu/cpu/i86/i286.c
index 04dc06235c4..7ada6251f9f 100644
--- a/src/emu/cpu/i86/i286.c
+++ b/src/emu/cpu/i86/i286.c
@@ -246,7 +246,7 @@ extern int i386_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, int mode)
static CPU_DISASSEMBLE( i80286 )
{
- return i386_dasm_one(buffer, pc, oprom, 16);
+ return i386_dasm_one(buffer, pc, oprom, 2);
}
static CPU_INIT( i80286 )
@@ -401,7 +401,7 @@ CPU_GET_INFO( i80286 )
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
- case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 15; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 10; break;
case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
case CPUINFO_INT_MAX_CYCLES: info->i = 50; break;
diff --git a/src/emu/cpu/i86/i86.c b/src/emu/cpu/i86/i86.c
index cbc2f041931..f8187b4ac45 100644
--- a/src/emu/cpu/i86/i86.c
+++ b/src/emu/cpu/i86/i86.c
@@ -342,7 +342,7 @@ static CPU_EXECUTE( i8086 )
static CPU_DISASSEMBLE( i8086 )
{
- return i386_dasm_one(buffer, pc, oprom, 16);
+ return i386_dasm_one(buffer, pc, oprom, 1);
}
@@ -557,7 +557,7 @@ CPU_GET_INFO( i8086 )
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
- case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 16; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 8; break;
case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
case CPUINFO_INT_MAX_CYCLES: info->i = 50; break;
diff --git a/src/emu/cpu/nec/necdasm.c b/src/emu/cpu/nec/necdasm.c
index 35c57ea40b2..c3cb7d1ac56 100644
--- a/src/emu/cpu/nec/necdasm.c
+++ b/src/emu/cpu/nec/necdasm.c
@@ -881,9 +881,11 @@ static char modrm_string[256];
#define MODRM_REG1 ((modrm >> 3) & 0x7)
#define MODRM_REG2 (modrm & 0x7)
+#define MAX_LENGTH 8
+
INLINE UINT8 FETCH(void)
{
- if ((opcode_ptr - opcode_ptr_base) + 1 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH)
return 0xff;
pc++;
return *opcode_ptr++;
@@ -892,7 +894,7 @@ INLINE UINT8 FETCH(void)
INLINE UINT16 FETCH16(void)
{
UINT16 d;
- if ((opcode_ptr - opcode_ptr_base) + 2 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH)
return 0xffff;
d = opcode_ptr[0] | (opcode_ptr[1] << 8);
opcode_ptr += 2;
@@ -902,7 +904,7 @@ INLINE UINT16 FETCH16(void)
INLINE UINT8 FETCHD(void)
{
- if ((opcode_ptr - opcode_ptr_base) + 1 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH)
return 0xff;
pc++;
return *opcode_ptr++;
@@ -911,7 +913,7 @@ INLINE UINT8 FETCHD(void)
INLINE UINT16 FETCHD16(void)
{
UINT16 d;
- if ((opcode_ptr - opcode_ptr_base) + 2 > 15)
+ if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH)
return 0xffff;
d = opcode_ptr[0] | (opcode_ptr[1] << 8);
opcode_ptr += 2;