M680x0 update

- Add CPU types 68EC030, 68030, and 68EC040
- Start of 030/040 PMMU, including stubbed PMOVE
This commit is contained in:
R. Belmont 2009-09-27 23:39:39 +00:00
parent 5fc5a8b203
commit 42951f5c7a
5 changed files with 859 additions and 573 deletions

View File

@ -26,7 +26,9 @@ enum
M68K_CPU_TYPE_68010, M68K_CPU_TYPE_68010,
M68K_CPU_TYPE_68EC020, M68K_CPU_TYPE_68EC020,
M68K_CPU_TYPE_68020, M68K_CPU_TYPE_68020,
M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */ M68K_CPU_TYPE_68EC030,
M68K_CPU_TYPE_68030,
M68K_CPU_TYPE_68EC040,
M68K_CPU_TYPE_68040, M68K_CPU_TYPE_68040,
M68K_CPU_TYPE_SCC68070 M68K_CPU_TYPE_SCC68070
}; };
@ -74,6 +76,9 @@ CPU_GET_INFO( m68008 );
CPU_GET_INFO( m68010 ); CPU_GET_INFO( m68010 );
CPU_GET_INFO( m68ec020 ); CPU_GET_INFO( m68ec020 );
CPU_GET_INFO( m68020 ); CPU_GET_INFO( m68020 );
CPU_GET_INFO( m68ec030 );
CPU_GET_INFO( m68030 );
CPU_GET_INFO( m68ec040 );
CPU_GET_INFO( m68040 ); CPU_GET_INFO( m68040 );
CPU_GET_INFO( scc68070 ); CPU_GET_INFO( scc68070 );
@ -83,6 +88,9 @@ CPU_GET_INFO( scc68070 );
#define CPU_M68010 CPU_GET_INFO_NAME( m68010 ) #define CPU_M68010 CPU_GET_INFO_NAME( m68010 )
#define CPU_M68EC020 CPU_GET_INFO_NAME( m68ec020 ) #define CPU_M68EC020 CPU_GET_INFO_NAME( m68ec020 )
#define CPU_M68020 CPU_GET_INFO_NAME( m68020 ) #define CPU_M68020 CPU_GET_INFO_NAME( m68020 )
#define CPU_M68EC030 CPU_GET_INFO_NAME( m68ec030 )
#define CPU_M68030 CPU_GET_INFO_NAME( m68030 )
#define CPU_M68EC040 CPU_GET_INFO_NAME( m68ec040 )
#define CPU_M68040 CPU_GET_INFO_NAME( m68040 ) #define CPU_M68040 CPU_GET_INFO_NAME( m68040 )
#define CPU_SCC68070 CPU_GET_INFO_NAME( scc68070 ) #define CPU_SCC68070 CPU_GET_INFO_NAME( scc68070 )

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
#if 0 #if 0
static const char copyright_notice[] = static const char copyright_notice[] =
"MUSASHI\n" "MUSASHI\n"
"Version 4.00 (2008-11-17)\n" "Version 4.10 (2009-09-27)\n"
"A portable Motorola M680x0 processor emulation engine.\n" "A portable Motorola M680x0 processor emulation engine.\n"
"Copyright Karl Stenerud. All rights reserved.\n" "Copyright Karl Stenerud. All rights reserved.\n"
"\n" "\n"
@ -17,7 +17,7 @@ static const char copyright_notice[] =
"(Karl Stenerud).\n" "(Karl Stenerud).\n"
"\n" "\n"
"The latest version of this code can be obtained at:\n" "The latest version of this code can be obtained at:\n"
"http://kstenerud.cjb.net\n" "http://kstenerud.cjb.net or http://mamedev.org\n"
; ;
#endif #endif
@ -85,7 +85,7 @@ const UINT32 m68ki_shift_32_table[65] =
/* Number of clock cycles to use for exception processing. /* Number of clock cycles to use for exception processing.
* I used 4 for any vectors that are undocumented for processing times. * I used 4 for any vectors that are undocumented for processing times.
*/ */
const UINT8 m68ki_exception_cycle_table[4][256] = const UINT8 m68ki_exception_cycle_table[5][256] =
{ {
{ /* 000 */ { /* 000 */
40, /* 0: Reset - Initial Stack Pointer */ 40, /* 0: Reset - Initial Stack Pointer */
@ -306,6 +306,79 @@ const UINT8 m68ki_exception_cycle_table[4][256] =
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
}, },
{ /* 030 - not correct */
4, /* 0: Reset - Initial Stack Pointer */
4, /* 1: Reset - Initial Program Counter */
50, /* 2: Bus Error (unemulated) */
50, /* 3: Address Error (unemulated) */
20, /* 4: Illegal Instruction */
38, /* 5: Divide by Zero */
40, /* 6: CHK */
20, /* 7: TRAPV */
34, /* 8: Privilege Violation */
25, /* 9: Trace */
20, /* 10: 1010 */
20, /* 11: 1111 */
4, /* 12: RESERVED */
4, /* 13: Coprocessor Protocol Violation (unemulated) */
4, /* 14: Format Error */
30, /* 15: Uninitialized Interrupt */
4, /* 16: RESERVED */
4, /* 17: RESERVED */
4, /* 18: RESERVED */
4, /* 19: RESERVED */
4, /* 20: RESERVED */
4, /* 21: RESERVED */
4, /* 22: RESERVED */
4, /* 23: RESERVED */
30, /* 24: Spurious Interrupt */
30, /* 25: Level 1 Interrupt Autovector */
30, /* 26: Level 2 Interrupt Autovector */
30, /* 27: Level 3 Interrupt Autovector */
30, /* 28: Level 4 Interrupt Autovector */
30, /* 29: Level 5 Interrupt Autovector */
30, /* 30: Level 6 Interrupt Autovector */
30, /* 31: Level 7 Interrupt Autovector */
20, /* 32: TRAP #0 */
20, /* 33: TRAP #1 */
20, /* 34: TRAP #2 */
20, /* 35: TRAP #3 */
20, /* 36: TRAP #4 */
20, /* 37: TRAP #5 */
20, /* 38: TRAP #6 */
20, /* 39: TRAP #7 */
20, /* 40: TRAP #8 */
20, /* 41: TRAP #9 */
20, /* 42: TRAP #10 */
20, /* 43: TRAP #11 */
20, /* 44: TRAP #12 */
20, /* 45: TRAP #13 */
20, /* 46: TRAP #14 */
20, /* 47: TRAP #15 */
4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
4, /* 49: FP Inexact Result (unemulated) */
4, /* 50: FP Divide by Zero (unemulated) */
4, /* 51: FP Underflow (unemulated) */
4, /* 52: FP Operand Error (unemulated) */
4, /* 53: FP Overflow (unemulated) */
4, /* 54: FP Signaling NAN (unemulated) */
4, /* 55: FP Unimplemented Data Type (unemulated) */
4, /* 56: MMU Configuration Error (unemulated) */
4, /* 57: MMU Illegal Operation Error (unemulated) */
4, /* 58: MMU Access Level Violation Error (unemulated) */
4, /* 59: RESERVED */
4, /* 60: RESERVED */
4, /* 61: RESERVED */
4, /* 62: RESERVED */
4, /* 63: RESERVED */
/* 64-255: User Defined */
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
},
{ /* 040 */ // TODO: these values are not correct { /* 040 */ // TODO: these values are not correct
4, /* 0: Reset - Initial Stack Pointer */ 4, /* 0: Reset - Initial Stack Pointer */
4, /* 1: Reset - Initial Program Counter */ 4, /* 1: Reset - Initial Program Counter */
@ -407,12 +480,13 @@ const UINT8 m68ki_ea_idx_cycle_table[64] =
CPU STATE DESCRIPTION CPU STATE DESCRIPTION
***************************************************************************/ ***************************************************************************/
#define MASK_ALL (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_040) #define MASK_ALL (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_EC040 | CPU_TYPE_040)
#define MASK_24BIT_SPACE (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020) #define MASK_24BIT_SPACE (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020)
#define MASK_32BIT_SPACE (CPU_TYPE_020 | CPU_TYPE_040) #define MASK_32BIT_SPACE (CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_EC040 | CPU_TYPE_040)
#define MASK_010_OR_LATER (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_040) #define MASK_010_OR_LATER (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040)
#define MASK_020_OR_LATER (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_040) #define MASK_020_OR_LATER (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_EC040 | CPU_TYPE_040)
#define MASK_040_OR_LATER (CPU_TYPE_040) #define MASK_030_OR_LATER (CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040)
#define MASK_040_OR_LATER (CPU_TYPE_040 | CPU_TYPE_EC040)
#define M68K_STATE_ENTRY(_name, _format, _member, _datamask, _flags, _mask) \ #define M68K_STATE_ENTRY(_name, _format, _member, _datamask, _flags, _mask) \
CPU_STATE_ENTRY(M68K_##_name, #_name, _format, m68ki_cpu_core, _member, _datamask, _mask, _flags) CPU_STATE_ENTRY(M68K_##_name, #_name, _format, m68ki_cpu_core, _member, _datamask, _mask, _flags)
@ -484,6 +558,9 @@ INLINE m68ki_cpu_core *get_safe_token(const device_config *device)
cpu_get_type(device) == CPU_M68010 || cpu_get_type(device) == CPU_M68010 ||
cpu_get_type(device) == CPU_M68EC020 || cpu_get_type(device) == CPU_M68EC020 ||
cpu_get_type(device) == CPU_M68020 || cpu_get_type(device) == CPU_M68020 ||
cpu_get_type(device) == CPU_M68EC030 ||
cpu_get_type(device) == CPU_M68030 ||
cpu_get_type(device) == CPU_M68EC040 ||
cpu_get_type(device) == CPU_M68040 || cpu_get_type(device) == CPU_M68040 ||
cpu_get_type(device) == CPU_SCC68070); cpu_get_type(device) == CPU_SCC68070);
return (m68ki_cpu_core *)device->token; return (m68ki_cpu_core *)device->token;
@ -1039,6 +1116,7 @@ static CPU_INIT( m68000 )
m68k->cyc_movem_l = 3; m68k->cyc_movem_l = 3;
m68k->cyc_shift = 1; m68k->cyc_shift = 1;
m68k->cyc_reset = 132; m68k->cyc_reset = 132;
m68k->has_pmmu = 0;
} }
CPU_GET_INFO( m68000 ) CPU_GET_INFO( m68000 )
@ -1082,6 +1160,7 @@ static CPU_INIT( m68008 )
m68k->cyc_movem_l = 3; m68k->cyc_movem_l = 3;
m68k->cyc_shift = 1; m68k->cyc_shift = 1;
m68k->cyc_reset = 132; m68k->cyc_reset = 132;
m68k->has_pmmu = 0;
} }
CPU_GET_INFO( m68008 ) CPU_GET_INFO( m68008 )
@ -1129,6 +1208,7 @@ static CPU_INIT( m68010 )
m68k->cyc_movem_l = 3; m68k->cyc_movem_l = 3;
m68k->cyc_shift = 1; m68k->cyc_shift = 1;
m68k->cyc_reset = 130; m68k->cyc_reset = 130;
m68k->has_pmmu = 0;
} }
CPU_GET_INFO( m68010 ) CPU_GET_INFO( m68010 )
@ -1172,6 +1252,7 @@ static CPU_INIT( m68020 )
m68k->cyc_movem_l = 2; m68k->cyc_movem_l = 2;
m68k->cyc_shift = 0; m68k->cyc_shift = 0;
m68k->cyc_reset = 518; m68k->cyc_reset = 518;
m68k->has_pmmu = 0;
} }
CPU_GET_INFO( m68020 ) CPU_GET_INFO( m68020 )
@ -1247,6 +1328,7 @@ static CPU_INIT( m68ec020 )
m68k->cyc_movem_l = 2; m68k->cyc_movem_l = 2;
m68k->cyc_shift = 0; m68k->cyc_shift = 0;
m68k->cyc_reset = 518; m68k->cyc_reset = 518;
m68k->has_pmmu = 0;
} }
CPU_GET_INFO( m68ec020 ) CPU_GET_INFO( m68ec020 )
@ -1266,6 +1348,125 @@ CPU_GET_INFO( m68ec020 )
} }
} }
/****************************************************************************
* M68030 section
****************************************************************************/
static CPU_INIT( m68030 )
{
m68ki_cpu_core *m68k = get_safe_token(device);
CPU_INIT_CALL(m68k);
m68k->cpu_type = CPU_TYPE_030;
m68k->state.subtypemask = m68k->cpu_type;
m68k->dasm_type = M68K_CPU_TYPE_68030;
m68k->memory = interface_d32;
m68k->sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m68k->cyc_instruction = m68ki_cycles[3];
m68k->cyc_exception = m68ki_exception_cycle_table[3];
m68k->cyc_bcc_notake_b = -2;
m68k->cyc_bcc_notake_w = 0;
m68k->cyc_dbcc_f_noexp = 0;
m68k->cyc_dbcc_f_exp = 4;
m68k->cyc_scc_r_true = 0;
m68k->cyc_movem_w = 2;
m68k->cyc_movem_l = 2;
m68k->cyc_shift = 0;
m68k->cyc_reset = 518;
m68k->has_pmmu = 1;
}
CPU_GET_INFO( m68030 )
{
m68ki_cpu_core *m68k = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL;
int sr;
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 20; break;
case CPUINFO_INT_MIN_CYCLES: info->i = 2; break;
case CPUINFO_INT_MAX_CYCLES: info->i = 158; break;
case CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 32; break;
case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 32; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m68030); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "68030"); break;
case CPUINFO_STR_FLAGS:
sr = m68ki_get_sr(m68k);
sprintf(info->s, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
sr & 0x8000 ? 'T':'.',
sr & 0x4000 ? 't':'.',
sr & 0x2000 ? 'S':'.',
sr & 0x1000 ? 'M':'.',
sr & 0x0800 ? '?':'.',
sr & 0x0400 ? 'I':'.',
sr & 0x0200 ? 'I':'.',
sr & 0x0100 ? 'I':'.',
sr & 0x0080 ? '?':'.',
sr & 0x0040 ? '?':'.',
sr & 0x0020 ? '?':'.',
sr & 0x0010 ? 'X':'.',
sr & 0x0008 ? 'N':'.',
sr & 0x0004 ? 'Z':'.',
sr & 0x0002 ? 'V':'.',
sr & 0x0001 ? 'C':'.');
break;
default: CPU_GET_INFO_CALL(m68k); break;
}
}
/****************************************************************************
* M680EC30 section
****************************************************************************/
static CPU_INIT( m68ec030 )
{
m68ki_cpu_core *m68k = get_safe_token(device);
CPU_INIT_CALL(m68k);
m68k->cpu_type = CPU_TYPE_EC030;
m68k->state.subtypemask = m68k->cpu_type;
m68k->dasm_type = M68K_CPU_TYPE_68EC030;
m68k->memory = interface_d32;
m68k->sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m68k->cyc_instruction = m68ki_cycles[3];
m68k->cyc_exception = m68ki_exception_cycle_table[3];
m68k->cyc_bcc_notake_b = -2;
m68k->cyc_bcc_notake_w = 0;
m68k->cyc_dbcc_f_noexp = 0;
m68k->cyc_dbcc_f_exp = 4;
m68k->cyc_scc_r_true = 0;
m68k->cyc_movem_w = 2;
m68k->cyc_movem_l = 2;
m68k->cyc_shift = 0;
m68k->cyc_reset = 518;
m68k->has_pmmu = 0; /* EC030 lacks the PMMU and is effectively a die-shrink 68020 */
}
CPU_GET_INFO( m68ec030 )
{
switch (state)
{
/* --- the following bits of info are returned as pointers to data or functions --- */
case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m68ec030); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "68EC030"); break;
default: CPU_GET_INFO_CALL(m68030); break;
}
}
/**************************************************************************** /****************************************************************************
* M68040 section * M68040 section
****************************************************************************/ ****************************************************************************/
@ -1281,8 +1482,8 @@ static CPU_INIT( m68040 )
m68k->dasm_type = M68K_CPU_TYPE_68040; m68k->dasm_type = M68K_CPU_TYPE_68040;
m68k->memory = interface_d32; m68k->memory = interface_d32;
m68k->sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ m68k->sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m68k->cyc_instruction = m68ki_cycles[2]; m68k->cyc_instruction = m68ki_cycles[4];
m68k->cyc_exception = m68ki_exception_cycle_table[2]; m68k->cyc_exception = m68ki_exception_cycle_table[4];
m68k->cyc_bcc_notake_b = -2; m68k->cyc_bcc_notake_b = -2;
m68k->cyc_bcc_notake_w = 0; m68k->cyc_bcc_notake_w = 0;
m68k->cyc_dbcc_f_noexp = 0; m68k->cyc_dbcc_f_noexp = 0;
@ -1292,6 +1493,7 @@ static CPU_INIT( m68040 )
m68k->cyc_movem_l = 2; m68k->cyc_movem_l = 2;
m68k->cyc_shift = 0; m68k->cyc_shift = 0;
m68k->cyc_reset = 518; m68k->cyc_reset = 518;
m68k->has_pmmu = 1;
} }
CPU_GET_INFO( m68040 ) CPU_GET_INFO( m68040 )
@ -1340,6 +1542,48 @@ CPU_GET_INFO( m68040 )
} }
} }
/****************************************************************************
* M680EC30 section
****************************************************************************/
static CPU_INIT( m68ec040 )
{
m68ki_cpu_core *m68k = get_safe_token(device);
CPU_INIT_CALL(m68k);
m68k->cpu_type = CPU_TYPE_EC040;
m68k->state.subtypemask = m68k->cpu_type;
m68k->dasm_type = M68K_CPU_TYPE_68EC040;
m68k->memory = interface_d32;
m68k->sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m68k->cyc_instruction = m68ki_cycles[4];
m68k->cyc_exception = m68ki_exception_cycle_table[4];
m68k->cyc_bcc_notake_b = -2;
m68k->cyc_bcc_notake_w = 0;
m68k->cyc_dbcc_f_noexp = 0;
m68k->cyc_dbcc_f_exp = 4;
m68k->cyc_scc_r_true = 0;
m68k->cyc_movem_w = 2;
m68k->cyc_movem_l = 2;
m68k->cyc_shift = 0;
m68k->cyc_reset = 518;
m68k->has_pmmu = 1;
}
CPU_GET_INFO( m68ec040 )
{
switch (state)
{
/* --- the following bits of info are returned as pointers to data or functions --- */
case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m68ec040); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "68EC040"); break;
default: CPU_GET_INFO_CALL(m68040); break;
}
}
/**************************************************************************** /****************************************************************************
* SCC-68070 section * SCC-68070 section
@ -1370,3 +1614,4 @@ CPU_GET_INFO( scc68070 )
default: CPU_GET_INFO_CALL(m68k); break; default: CPU_GET_INFO_CALL(m68k); break;
} }
} }

View File

@ -73,14 +73,16 @@ typedef struct _m68ki_cpu_core m68ki_cpu_core;
#define FUNCTION_CODE_CPU_SPACE 7 #define FUNCTION_CODE_CPU_SPACE 7
/* CPU types for deciding what to emulate */ /* CPU types for deciding what to emulate */
#define CPU_TYPE_000 1 #define CPU_TYPE_000 (0x00000001)
#define CPU_TYPE_008 2 #define CPU_TYPE_008 (0x00000002)
#define CPU_TYPE_010 4 #define CPU_TYPE_010 (0x00000004)
#define CPU_TYPE_EC020 8 #define CPU_TYPE_EC020 (0x00000008)
#define CPU_TYPE_020 16 #define CPU_TYPE_020 (0x00000010)
#define CPU_TYPE_040 32 #define CPU_TYPE_EC030 (0x00000020)
#define CPU_TYPE_060 64 #define CPU_TYPE_030 (0x00000040)
#define CPU_TYPE_SCC070 128 #define CPU_TYPE_EC040 (0x00000080)
#define CPU_TYPE_040 (0x00000100)
#define CPU_TYPE_SCC070 (0x00000200)
/* Different ways to stop the CPU */ /* Different ways to stop the CPU */
#define STOP_LEVEL_STOP 1 #define STOP_LEVEL_STOP 1
@ -217,20 +219,23 @@ typedef struct _m68ki_cpu_core m68ki_cpu_core;
/* These defines are dependant on the configuration defines in m68kconf.h */ /* These defines are dependant on the configuration defines in m68kconf.h */
/* Disable certain comparisons if we're not using all CPU types */ /* Disable certain comparisons if we're not using all CPU types */
#define CPU_TYPE_IS_040_PLUS(A) ((A) & CPU_TYPE_040) #define CPU_TYPE_IS_040_PLUS(A) ((A) & (CPU_TYPE_040 | CPU_TYPE_EC040))
#define CPU_TYPE_IS_040_LESS(A) 1 #define CPU_TYPE_IS_040_LESS(A) 1
#define CPU_TYPE_IS_020_PLUS(A) ((A) & (CPU_TYPE_020 | CPU_TYPE_040)) #define CPU_TYPE_IS_030_PLUS(A) ((A) & (CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040))
#define CPU_TYPE_IS_030_LESS(A) 1
#define CPU_TYPE_IS_020_PLUS(A) ((A) & (CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040))
#define CPU_TYPE_IS_020_LESS(A) 1 #define CPU_TYPE_IS_020_LESS(A) 1
#define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020)) #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
#define CPU_TYPE_IS_EC020_PLUS(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_040)) #define CPU_TYPE_IS_EC020_PLUS(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040))
#define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020)) #define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020))
#define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010) #define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010)
#define CPU_TYPE_IS_010_PLUS(A) ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_040)) #define CPU_TYPE_IS_010_PLUS(A) ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_040 | CPU_TYPE_EC040))
#define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_SCC070)) #define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010))
#define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000 || (A) == CPU_TYPE_008) #define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000 || (A) == CPU_TYPE_008)
@ -292,7 +297,6 @@ typedef struct _m68ki_cpu_core m68ki_cpu_core;
return m68k->initial_cycles; \ return m68k->initial_cycles; \
} \ } \
} }
#endif
#define m68ki_check_address_error(m68k, ADDR, WRITE_MODE, FC) \ #define m68ki_check_address_error(m68k, ADDR, WRITE_MODE, FC) \
if((ADDR)&1) \ if((ADDR)&1) \
@ -302,7 +306,7 @@ typedef struct _m68ki_cpu_core m68ki_cpu_core;
m68k->aerr_fc = FC; \ m68k->aerr_fc = FC; \
longjmp(m68k->aerr_trap, 1); \ longjmp(m68k->aerr_trap, 1); \
} }
#endif
/* -------------------------- EA / Operand Access ------------------------- */ /* -------------------------- EA / Operand Access ------------------------- */
@ -543,7 +547,7 @@ struct _m68k_memory_interface
struct _m68ki_cpu_core struct _m68ki_cpu_core
{ {
UINT32 cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, or 68020 */ UINT32 cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */
UINT32 dasm_type; /* disassembly type */ UINT32 dasm_type; /* disassembly type */
UINT32 dar[16]; /* Data and Address Registers */ UINT32 dar[16]; /* Data and Address Registers */
UINT32 ppc; /* Previous program counter */ UINT32 ppc; /* Previous program counter */
@ -576,6 +580,7 @@ struct _m68ki_cpu_core
UINT32 sr_mask; /* Implemented status register bits */ UINT32 sr_mask; /* Implemented status register bits */
UINT32 instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ UINT32 instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */
UINT32 run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ UINT32 run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */
int has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */
/* Clocks required for instructions / exceptions */ /* Clocks required for instructions / exceptions */
UINT32 cyc_bcc_notake_b; UINT32 cyc_bcc_notake_b;

View File

@ -3,7 +3,7 @@
/* ======================================================================== */ /* ======================================================================== */
/* /*
* MUSASHI * MUSASHI
* Version 3.32 * Version 4.10
* *
* A portable Motorola M680x0 processor emulation engine. * A portable Motorola M680x0 processor emulation engine.
* Copyright Karl Stenerud. All rights reserved. * Copyright Karl Stenerud. All rights reserved.
@ -16,12 +16,15 @@
* (Karl Stenerud). * (Karl Stenerud).
* *
* The latest version of this code can be obtained at: * The latest version of this code can be obtained at:
* http://kstenerud.cjb.net * http://kstenerud.cjb.net or http://mamedev.org/
*/ */
/* /*
* Modified For OpenVMS By: Robert Alan Byer * Modified For OpenVMS By: Robert Alan Byer
* byer@mail.ourservers.net * byer@mail.ourservers.net
*
* 68030 and PMMU by R. Belmont
* 68040 and FPU by Ville Linde
*/ */
@ -52,7 +55,7 @@
*/ */
static const char g_version[] = "3.32"; static const char g_version[] = "4.10";
/* ======================================================================== */ /* ======================================================================== */
/* =============================== INCLUDES =============================== */ /* =============================== INCLUDES =============================== */
@ -132,6 +135,7 @@ enum
CPU_TYPE_000 = 0, CPU_TYPE_000 = 0,
CPU_TYPE_010, CPU_TYPE_010,
CPU_TYPE_020, CPU_TYPE_020,
CPU_TYPE_030,
CPU_TYPE_040, CPU_TYPE_040,
NUM_CPUS NUM_CPUS
}; };
@ -182,7 +186,7 @@ typedef struct
char ea_allowed[EA_ALLOWED_LENGTH]; /* Effective addressing modes allowed */ char ea_allowed[EA_ALLOWED_LENGTH]; /* Effective addressing modes allowed */
char cpu_mode[NUM_CPUS]; /* User or supervisor mode */ char cpu_mode[NUM_CPUS]; /* User or supervisor mode */
char cpus[NUM_CPUS+1]; /* Allowed CPUs */ char cpus[NUM_CPUS+1]; /* Allowed CPUs */
unsigned char cycles[NUM_CPUS]; /* cycles for 000, 010, 020 */ unsigned char cycles[NUM_CPUS]; /* cycles for 000, 010, 020, 030, 040 */
} opcode_struct; } opcode_struct;
@ -313,22 +317,22 @@ static const int g_size_select_table[33] =
}; };
/* Extra cycles required for certain EA modes */ /* Extra cycles required for certain EA modes */
/* TODO: correct timings for 040 */ /* TODO: correct timings for 030, 040 */
static const int g_ea_cycle_table[13][NUM_CPUS][3] = static const int g_ea_cycle_table[13][NUM_CPUS][3] =
{/* 000 010 020 040 */ {/* 000 010 020 030 040 */
{{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */ {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AI */ {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AI */
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI */ {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI */
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI7 */ {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI7 */
{{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD */ {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD */
{{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD7 */ {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD7 */
{{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_DI */ {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_DI */
{{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_IX */ {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_IX */
{{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AW */ {{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AW */
{{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AL */ {{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AL */
{{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PCDI */ {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PCDI */
{{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_PCIX */ {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_PCIX */
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}, { 0, 2, 4}}, /* EA_MODE_I */ {{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}, { 0, 2, 4}, { 0, 2, 4}}, /* EA_MODE_I */
}; };
/* Extra cycles for JMP instruction (000, 010) */ /* Extra cycles for JMP instruction (000, 010) */
@ -1073,13 +1077,13 @@ static void populate_table(void)
/* Find the start of the table */ /* Find the start of the table */
while(strcmp(buff, ID_TABLE_START) != 0) while(strcmp(buff, ID_TABLE_START) != 0)
if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0) if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0)
error_exit("Premature EOF while reading table"); error_exit("(table_start) Premature EOF while reading table");
/* Process the entire table */ /* Process the entire table */
for(op = g_opcode_input_table;;op++) for(op = g_opcode_input_table;;op++)
{ {
if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0) if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0)
error_exit("Premature EOF while reading table"); error_exit("(inline) Premature EOF while reading table");
if(strlen(buff) == 0) if(strlen(buff) == 0)
continue; continue;
/* We finish when we find an input separator */ /* We finish when we find an input separator */
@ -1237,7 +1241,7 @@ int main(int argc, char *argv[])
int table_body_read = 0; int table_body_read = 0;
int ophandler_body_read = 0; int ophandler_body_read = 0;
printf("\n\tMusashi v%s 68000, 68008, 68010, 68EC020, 68020, 68040 emulator\n", g_version); printf("\n\tMusashi v%s 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, 68040 emulator\n", g_version);
printf("\tCopyright Karl Stenerud\n\n"); printf("\tCopyright Karl Stenerud\n\n");
/* Check if output path and source for the input file are given */ /* Check if output path and source for the input file are given */