Update Musashi to 3.32 (MAME version 0.128)
This commit is contained in:
parent
a63d902eb7
commit
5292cab48d
|
@ -114,7 +114,7 @@ psikyo_tile_func.h = $(srcdir)dep/generated/psikyo_tile_func.h
|
|||
pgm_sprite.h = $(srcdir)dep/generated/pgm_sprite.h
|
||||
build_details.h = $(srcdir)dep/generated/build_details.h
|
||||
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kopnz.o $(objdir)cpu/m68k/m68kopdm.o $(objdir)cpu/m68k/m68kopac.o $(objdir)cpu/m68k/m68kops.o \
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kops.o \
|
||||
$(foreach file,$(autobj:.o=.c), \
|
||||
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
||||
$(firstword $(subst .c,.o,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
||||
|
|
|
@ -127,7 +127,7 @@ psikyo_tile_func.h = $(srcdir)dep/generated/psikyo_tile_func.h
|
|||
pgm_sprite.h = $(srcdir)dep/generated/pgm_sprite.h
|
||||
build_details.h = $(srcdir)dep/generated/build_details.h
|
||||
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kopnz.o $(objdir)cpu/m68k/m68kopdm.o $(objdir)cpu/m68k/m68kopac.o $(objdir)cpu/m68k/m68kops.o \
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kops.o \
|
||||
$(foreach file,$(autobj:.o=.c), \
|
||||
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
||||
$(firstword $(subst .c,.o,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
||||
|
|
|
@ -229,7 +229,7 @@ cave_sprite_func.h = $(srcdir)depend/generated/cave_sprite_func.h
|
|||
psikyo_tile_func.h = $(srcdir)depend/generated/psikyo_tile_func.h
|
||||
pgm_sprite.h = $(srcdir)depend/generated/pgm_sprite.h
|
||||
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kopnz.o $(objdir)cpu/m68k/m68kopdm.o $(objdir)cpu/m68k/m68kopac.o $(objdir)cpu/m68k/m68kops.o \
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kops.o \
|
||||
$(foreach file,$(autobj:.o=.c), \
|
||||
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
||||
$(firstword $(subst .c,.o,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
||||
|
|
|
@ -128,7 +128,7 @@ psikyo_tile_func.h = $(srcdir)dep/generated/psikyo_tile_func.h
|
|||
pgm_sprite.h = $(srcdir)dep/generated/pgm_sprite.h
|
||||
build_details.h = $(srcdir)dep/generated/build_details.h
|
||||
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kopnz.o $(objdir)cpu/m68k/m68kopdm.o $(objdir)cpu/m68k/m68kopac.o $(objdir)cpu/m68k/m68kops.o $(objdir)burner/win32/resource.res \
|
||||
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kops.o $(objdir)burner/win32/resource.res \
|
||||
$(foreach file,$(autobj:.o=.c), \
|
||||
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
||||
$(firstword $(subst .c,.o,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
||||
|
|
|
@ -107,7 +107,7 @@ inline static void CheckBreakpoint_W(UINT32 a, const UINT32 m)
|
|||
}
|
||||
}
|
||||
|
||||
inline static void CheckBreakpoint_PC()
|
||||
inline static void CheckBreakpoint_PC(unsigned int /*pc*/)
|
||||
{
|
||||
for (INT32 i = 0; BreakpointFetch[i].address; i++) {
|
||||
if (BreakpointFetch[i].address == (UINT32)SekGetPC(-1)) {
|
||||
|
@ -122,7 +122,7 @@ inline static void CheckBreakpoint_PC()
|
|||
}
|
||||
}
|
||||
|
||||
inline static void SingleStep_PC()
|
||||
inline static void SingleStep_PC(unsigned int /*pc*/)
|
||||
{
|
||||
#ifdef EMU_A68K
|
||||
UpdateA68KContext();
|
||||
|
@ -512,7 +512,7 @@ struct A68KContext* SekRegs[SEK_MAX] = { NULL, };
|
|||
#endif
|
||||
|
||||
struct A68KInter {
|
||||
void (__fastcall *DebugCallback) ();
|
||||
void (__fastcall *DebugCallback) (unsigned int pc);
|
||||
UINT8 (__fastcall *Read8) (UINT32 a);
|
||||
UINT16 (__fastcall *Read16)(UINT32 a);
|
||||
UINT32 (__fastcall *Read32)(UINT32 a);
|
||||
|
@ -556,8 +556,8 @@ void __fastcall A68KWrite16(UINT32 a,UINT16 d) { WriteWord(a,d);}
|
|||
void __fastcall A68KWrite32(UINT32 a,UINT32 d) { WriteLong(a,d);}
|
||||
|
||||
#if defined (FBA_DEBUG)
|
||||
void __fastcall A68KCheckBreakpoint() { CheckBreakpoint_PC(); }
|
||||
void __fastcall A68KSingleStep() { SingleStep_PC(); }
|
||||
void __fastcall A68KCheckBreakpoint(unsigned int pc) { CheckBreakpoint_PC(pc); }
|
||||
void __fastcall A68KSingleStep(unsigned int pc) { SingleStep_PC(pc); }
|
||||
#endif
|
||||
|
||||
#ifdef EMU_A68K
|
||||
|
@ -592,8 +592,8 @@ void __fastcall M68KWriteByteBP(UINT32 a, UINT32 d) { WriteByteBP(a, d); }
|
|||
void __fastcall M68KWriteWordBP(UINT32 a, UINT32 d) { WriteWordBP(a, d); }
|
||||
void __fastcall M68KWriteLongBP(UINT32 a, UINT32 d) { WriteLongBP(a, d); }
|
||||
|
||||
void M68KCheckBreakpoint() { CheckBreakpoint_PC(); }
|
||||
void M68KSingleStep() { SingleStep_PC(); }
|
||||
void M68KCheckBreakpoint(unsigned int pc) { CheckBreakpoint_PC(pc); }
|
||||
void M68KSingleStep(unsigned int pc) { SingleStep_PC(pc); }
|
||||
|
||||
UINT32 (__fastcall *M68KReadByteDebug)(UINT32);
|
||||
UINT32 (__fastcall *M68KReadWordDebug)(UINT32);
|
||||
|
|
|
@ -10,23 +10,24 @@
|
|||
/* ======================================================================== */
|
||||
/*
|
||||
* MUSASHI
|
||||
* Version 3.3
|
||||
* Version 3.32
|
||||
*
|
||||
* A portable Motorola M680x0 processor emulation engine.
|
||||
* Copyright 1998-2001 Karl Stenerud. All rights reserved.
|
||||
* Copyright Karl Stenerud. All rights reserved.
|
||||
*
|
||||
* This code may be freely used for non-commercial purposes as long as this
|
||||
* copyright notice remains unaltered in the source code and any binary files
|
||||
* containing this code in compiled form.
|
||||
*
|
||||
* All other lisencing terms must be negotiated with the author
|
||||
* All other licensing terms must be negotiated with the author
|
||||
* (Karl Stenerud).
|
||||
*
|
||||
* The latest version of this code can be obtained at:
|
||||
* http://kstenerud.cjb.net
|
||||
*/
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
|
||||
/* ============================ GENERAL DEFINES =========================== */
|
||||
|
||||
/* ======================================================================== */
|
||||
|
@ -76,7 +77,7 @@ enum
|
|||
};
|
||||
|
||||
/* Registers used by m68k_get_reg() and m68k_set_reg() */
|
||||
typedef enum
|
||||
enum _m68k_register_t
|
||||
{
|
||||
/* Real registers */
|
||||
M68K_REG_D0, /* Data registers */
|
||||
|
@ -109,8 +110,8 @@ typedef enum
|
|||
|
||||
/* Assumed registers */
|
||||
/* These are cheat registers which emulate the 1-longword prefetch
|
||||
* present in the 68000 and 68010.
|
||||
*/
|
||||
* present in the 68000 and 68010.
|
||||
*/
|
||||
M68K_REG_PREF_ADDR, /* Last prefetch address */
|
||||
M68K_REG_PREF_DATA, /* Last prefetch data */
|
||||
|
||||
|
@ -118,7 +119,10 @@ typedef enum
|
|||
M68K_REG_PPC, /* Previous value in the program counter */
|
||||
M68K_REG_IR, /* Instruction register */
|
||||
M68K_REG_CPU_TYPE /* Type of CPU being run */
|
||||
} m68k_register_t;
|
||||
};
|
||||
typedef enum _m68k_register_t m68k_register_t;
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ====================== FUNCTIONS CALLED BY THE CPU ===================== */
|
||||
|
@ -236,6 +240,14 @@ void m68k_set_cmpild_instr_callback(void (*callback)(unsigned int val, int reg)
|
|||
*/
|
||||
void m68k_set_rte_instr_callback(void (*callback)(void));
|
||||
|
||||
/* Set the callback for the TAS instruction.
|
||||
* You must enable M68K_TAS_HAS_CALLBACK in m68kconf.h.
|
||||
* The CPU calls this callback every time it encounters a TAS instruction.
|
||||
* Default behavior: return 1, allow writeback.
|
||||
*/
|
||||
void m68k_set_tas_instr_callback(int (*callback)(void));
|
||||
|
||||
|
||||
|
||||
/* Set the callback for informing of a large PC change.
|
||||
* You must enable M68K_MONITOR_PC in m68kconf.h.
|
||||
|
@ -262,7 +274,7 @@ void m68k_set_fc_callback(void (*callback)(unsigned int new_fc));
|
|||
* instruction cycle.
|
||||
* Default behavior: do nothing.
|
||||
*/
|
||||
void m68k_set_instr_hook_callback(void (*callback)(void));
|
||||
void m68k_set_instr_hook_callback(void (*callback)(unsigned int pc));
|
||||
|
||||
|
||||
|
||||
|
@ -308,6 +320,12 @@ void m68k_end_timeslice(void); /* End timeslice now */
|
|||
*/
|
||||
void m68k_set_irq(unsigned int int_level);
|
||||
|
||||
/* Set the virtual irq lines, where the highest level
|
||||
* active line is automatically selected. If you use this function,
|
||||
* do not use m68k_set_irq.
|
||||
*/
|
||||
void m68k_set_virq(unsigned int level, unsigned int active);
|
||||
unsigned int m68k_get_virq(unsigned int level);
|
||||
|
||||
/* Halt the CPU as if you pulsed the HALT pin. */
|
||||
void m68k_pulse_halt(void);
|
||||
|
@ -325,7 +343,7 @@ unsigned int m68k_get_context(void* dst);
|
|||
void m68k_set_context(void* dst);
|
||||
|
||||
/* Register the CPU state information */
|
||||
void m68k_state_register(const char *type);
|
||||
void m68k_state_register(const char *type, int index);
|
||||
|
||||
|
||||
/* Peek at the internals of a CPU context. This can either be a context
|
||||
|
@ -345,6 +363,11 @@ unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cp
|
|||
*/
|
||||
unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type);
|
||||
|
||||
/* Same as above but accepts raw opcode data directly rather than fetching
|
||||
* via the read/write interfaces.
|
||||
*/
|
||||
unsigned int m68k_disassemble_raw(char* str_buff, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type);
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================= CONFIGURATION ============================ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,16 +3,16 @@
|
|||
/* ======================================================================== */
|
||||
/*
|
||||
* MUSASHI
|
||||
* Version 3.3
|
||||
* Version 3.32
|
||||
*
|
||||
* A portable Motorola M680x0 processor emulation engine.
|
||||
* Copyright 1998-2001 Karl Stenerud. All rights reserved.
|
||||
* Copyright Karl Stenerud. All rights reserved.
|
||||
*
|
||||
* This code may be freely used for non-commercial purposes as long as this
|
||||
* copyright notice remains unaltered in the source code and any binary files
|
||||
* containing this code in compiled form.
|
||||
*
|
||||
* All other lisencing terms must be negotiated with the author
|
||||
* All other licensing terms must be negotiated with the author
|
||||
* (Karl Stenerud).
|
||||
*
|
||||
* The latest version of this code can be obtained at:
|
||||
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef M68KCONF__HEADER
|
||||
#define M68KCONF__HEADER
|
||||
|
@ -37,6 +38,26 @@
|
|||
#define OPT_SPECIFY_HANDLER 2
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== MAME STUFF ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* If you're compiling this for MAME, only change M68K_COMPILE_FOR_MAME
|
||||
* to OPT_ON and use m68kmame.h to configure the 68k core.
|
||||
*/
|
||||
#ifndef M68K_COMPILE_FOR_MAME
|
||||
#define M68K_COMPILE_FOR_MAME OPT_ON
|
||||
#endif /* M68K_COMPILE_FOR_MAME */
|
||||
|
||||
|
||||
#if M68K_COMPILE_FOR_MAME == OPT_OFF
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================= CONFIGURATION ============================ */
|
||||
/* ======================================================================== */
|
||||
|
@ -46,6 +67,7 @@
|
|||
#define M68K_EMULATE_010 OPT_ON
|
||||
#define M68K_EMULATE_EC020 OPT_ON
|
||||
#define M68K_EMULATE_020 OPT_OFF
|
||||
#define M68K_EMULATE_040 OPT_OFF
|
||||
|
||||
|
||||
/* If ON, the CPU will call m68k_read_immediate_xx() for immediate addressing
|
||||
|
@ -93,15 +115,19 @@
|
|||
* instruction.
|
||||
*/
|
||||
#define M68K_CMPILD_HAS_CALLBACK OPT_SPECIFY_HANDLER
|
||||
//#define M68K_CMPILD_CALLBACK(v,r) your_cmpild_handler_function(v,r)
|
||||
#define M68K_CMPILD_CALLBACK(v, r) M68KcmpildCallback(v, r)
|
||||
|
||||
/* If ON, CPU will call the callback when it encounters a rte
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_RTE_HAS_CALLBACK OPT_SPECIFY_HANDLER
|
||||
//#define M68K_RTE_CALLBACK() your_rte_handler_function()
|
||||
#define M68K_RTE_CALLBACK() M68KRTECallback()
|
||||
#define M68K_RTE_CALLBACK() M68KRTECallback()
|
||||
|
||||
/* If ON, CPU will call the callback when it encounters a tas
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_TAS_HAS_CALLBACK OPT_ON
|
||||
#define M68K_TAS_CALLBACK() your_tas_handler_function()
|
||||
|
||||
|
||||
/* If ON, CPU will call the set fc callback on every memory access to
|
||||
|
@ -260,6 +286,8 @@ void __fastcall M68KWriteLong(unsigned int a, unsigned int d);
|
|||
#define m68k_write_memory_32(address, value) M68KWriteLong(address, value)
|
||||
#endif /* FBA_DEBUG */
|
||||
|
||||
#endif /* M68K_COMPILE_FOR_MAME */
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
|
|
|
@ -3,17 +3,17 @@
|
|||
/* ======================================================================== */
|
||||
|
||||
#if 1
|
||||
static const char* copyright_notice =
|
||||
static const char copyright_notice[] =
|
||||
"MUSASHI\n"
|
||||
"Version 3.3 (2001-01-29)\n"
|
||||
"Version 3.32 (2007-12-15)\n"
|
||||
"A portable Motorola M680x0 processor emulation engine.\n"
|
||||
"Copyright 1998-2001 Karl Stenerud. All rights reserved.\n"
|
||||
"Copyright Karl Stenerud. All rights reserved.\n"
|
||||
"\n"
|
||||
"This code may be freely used for non-commercial purpooses as long as this\n"
|
||||
"copyright notice remains unaltered in the source code and any binary files\n"
|
||||
"containing this code in compiled form.\n"
|
||||
"\n"
|
||||
"All other lisencing terms must be negotiated with the author\n"
|
||||
"All other licensing terms must be negotiated with the author\n"
|
||||
"(Karl Stenerud).\n"
|
||||
"\n"
|
||||
"The latest version of this code can be obtained at:\n"
|
||||
|
@ -32,8 +32,12 @@ static const char* copyright_notice =
|
|||
/* ================================ INCLUDES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
extern void m68040_fpu_op0(void);
|
||||
extern void m68040_fpu_op1(void);
|
||||
|
||||
#include "m68kops.h"
|
||||
#include "m68kcpu.h"
|
||||
#include "m68kfpu.c"
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================= DATA ================================= */
|
||||
|
@ -45,7 +49,7 @@ uint m68ki_tracing = 0;
|
|||
uint m68ki_address_space;
|
||||
|
||||
#ifdef M68K_LOG_ENABLE
|
||||
const char* m68ki_cpu_names[] =
|
||||
const char *const m68ki_cpu_names[] =
|
||||
{
|
||||
"Invalid CPU",
|
||||
"M68000",
|
||||
|
@ -79,7 +83,7 @@ uint m68ki_aerr_write_mode;
|
|||
uint m68ki_aerr_fc;
|
||||
|
||||
/* Used by shift & rotate instructions */
|
||||
uint8 m68ki_shift_8_table[65] =
|
||||
const uint8 m68ki_shift_8_table[65] =
|
||||
{
|
||||
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
|
@ -88,7 +92,7 @@ uint8 m68ki_shift_8_table[65] =
|
|||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
uint16 m68ki_shift_16_table[65] =
|
||||
const uint16 m68ki_shift_16_table[65] =
|
||||
{
|
||||
0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
|
||||
0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,
|
||||
|
@ -99,7 +103,7 @@ uint16 m68ki_shift_16_table[65] =
|
|||
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
|
||||
0xffff, 0xffff
|
||||
};
|
||||
uint m68ki_shift_32_table[65] =
|
||||
const uint m68ki_shift_32_table[65] =
|
||||
{
|
||||
0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
|
||||
0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
|
||||
|
@ -118,7 +122,7 @@ uint m68ki_shift_32_table[65] =
|
|||
/* Number of clock cycles to use for exception processing.
|
||||
* I used 4 for any vectors that are undocumented for processing times.
|
||||
*/
|
||||
uint8 m68ki_exception_cycle_table[3][256] =
|
||||
const uint8 m68ki_exception_cycle_table[4][256] =
|
||||
{
|
||||
{ /* 000 */
|
||||
4, /* 0: Reset - Initial Stack Pointer */
|
||||
|
@ -338,10 +342,83 @@ uint8 m68ki_exception_cycle_table[3][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
|
||||
},
|
||||
{ /* 040 */ // TODO: these values are 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
|
||||
}
|
||||
};
|
||||
|
||||
uint8 m68ki_ea_idx_cycle_table[64] =
|
||||
const uint8 m68ki_ea_idx_cycle_table[64] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, /* ..01.000 no memory indirect, base NULL */
|
||||
|
@ -402,6 +479,12 @@ static void default_rte_instr_callback(void)
|
|||
{
|
||||
}
|
||||
|
||||
/* Called when a tas instruction is executed */
|
||||
static int default_tas_instr_callback(void)
|
||||
{
|
||||
return 1; // allow writeback
|
||||
}
|
||||
|
||||
/* Called when the program counter changed by a large value */
|
||||
static unsigned int default_pc_changed_callback_data;
|
||||
static void default_pc_changed_callback(unsigned int new_pc)
|
||||
|
@ -417,7 +500,7 @@ static void default_set_fc_callback(unsigned int new_fc)
|
|||
}
|
||||
|
||||
/* Called every instruction cycle prior to execution */
|
||||
static void default_instr_hook_callback(void)
|
||||
static void default_instr_hook_callback(unsigned int pc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -487,11 +570,11 @@ unsigned int m68k_get_reg(void* context, m68k_register_t regnum)
|
|||
case CPU_TYPE_010: return (unsigned int)M68K_CPU_TYPE_68010;
|
||||
case CPU_TYPE_EC020: return (unsigned int)M68K_CPU_TYPE_68EC020;
|
||||
case CPU_TYPE_020: return (unsigned int)M68K_CPU_TYPE_68020;
|
||||
case CPU_TYPE_040: return (unsigned int)M68K_CPU_TYPE_68040;
|
||||
}
|
||||
return M68K_CPU_TYPE_INVALID;
|
||||
default: return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void m68k_set_reg(m68k_register_t regnum, unsigned int value)
|
||||
|
@ -571,6 +654,11 @@ void m68k_set_rte_instr_callback(void (*callback)(void))
|
|||
CALLBACK_RTE_INSTR = callback ? callback : default_rte_instr_callback;
|
||||
}
|
||||
|
||||
void m68k_set_tas_instr_callback(int (*callback)(void))
|
||||
{
|
||||
CALLBACK_TAS_INSTR = callback ? callback : default_tas_instr_callback;
|
||||
}
|
||||
|
||||
void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc))
|
||||
{
|
||||
CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback;
|
||||
|
@ -581,7 +669,7 @@ void m68k_set_fc_callback(void (*callback)(unsigned int new_fc))
|
|||
CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;
|
||||
}
|
||||
|
||||
void m68k_set_instr_hook_callback(void (*callback)(void))
|
||||
void m68k_set_instr_hook_callback(void (*callback)(unsigned int pc))
|
||||
{
|
||||
CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
|
||||
}
|
||||
|
@ -607,7 +695,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
CYC_MOVEM_L = 3;
|
||||
CYC_SHIFT = 1;
|
||||
CYC_RESET = 132;
|
||||
break;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68008:
|
||||
CPU_TYPE = CPU_TYPE_008;
|
||||
CPU_ADDRESS_MASK = 0x003fffff;
|
||||
|
@ -623,7 +711,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
CYC_MOVEM_L = 3;
|
||||
CYC_SHIFT = 1;
|
||||
CYC_RESET = 132;
|
||||
break;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68010:
|
||||
CPU_TYPE = CPU_TYPE_010;
|
||||
CPU_ADDRESS_MASK = 0x00ffffff;
|
||||
|
@ -639,7 +727,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
CYC_MOVEM_L = 3;
|
||||
CYC_SHIFT = 1;
|
||||
CYC_RESET = 130;
|
||||
break;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68EC020:
|
||||
CPU_TYPE = CPU_TYPE_EC020;
|
||||
CPU_ADDRESS_MASK = 0x00ffffff;
|
||||
|
@ -655,7 +743,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
CYC_MOVEM_L = 2;
|
||||
CYC_SHIFT = 0;
|
||||
CYC_RESET = 518;
|
||||
break;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68020:
|
||||
CPU_TYPE = CPU_TYPE_020;
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
|
@ -671,27 +759,40 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
CYC_MOVEM_L = 2;
|
||||
CYC_SHIFT = 0;
|
||||
CYC_RESET = 518;
|
||||
break;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68040: // TODO: these values are not correct
|
||||
CPU_TYPE = CPU_TYPE_040;
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[2];
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[2];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
CYC_DBCC_F_NOEXP = 0;
|
||||
CYC_DBCC_F_EXP = 4;
|
||||
CYC_SCC_R_TRUE = 0;
|
||||
CYC_MOVEM_W = 2;
|
||||
CYC_MOVEM_L = 2;
|
||||
CYC_SHIFT = 0;
|
||||
CYC_RESET = 518;
|
||||
return;
|
||||
}
|
||||
|
||||
m68ki_build_opcode_table(CPU_TYPE_IS_000(CPU_TYPE));
|
||||
}
|
||||
|
||||
/* Execute some instructions until we use up num_cycles clock cycles */
|
||||
/* ASG: removed per-instruction interrupt checks */
|
||||
int m68k_execute(int num_cycles)
|
||||
{
|
||||
/* Set our pool of clock cycles available */
|
||||
SET_CYCLES(num_cycles);
|
||||
m68ki_initial_cycles = num_cycles;
|
||||
|
||||
/* See if interrupts came in */
|
||||
m68ki_check_interrupts();
|
||||
|
||||
/* Make sure we're not stopped */
|
||||
if(!CPU_STOPPED)
|
||||
{
|
||||
/* Set our pool of clock cycles available */
|
||||
SET_CYCLES(num_cycles);
|
||||
m68ki_initial_cycles = num_cycles;
|
||||
|
||||
/* ASG: update cycles */
|
||||
USE_CYCLES(CPU_INT_CYCLES);
|
||||
CPU_INT_CYCLES = 0;
|
||||
|
||||
/* Return point if we had an address error */
|
||||
m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
|
@ -705,7 +806,7 @@ int m68k_execute(int num_cycles)
|
|||
m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
/* Call external hook to peek at CPU */
|
||||
m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_instr_hook(REG_PC); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
/* Record previous program counter */
|
||||
REG_PPC = REG_PC;
|
||||
|
@ -721,20 +822,12 @@ int m68k_execute(int num_cycles)
|
|||
|
||||
/* set previous PC to current PC for the next entry into the loop */
|
||||
REG_PPC = REG_PC;
|
||||
|
||||
/* ASG: update cycles */
|
||||
USE_CYCLES(CPU_INT_CYCLES);
|
||||
CPU_INT_CYCLES = 0;
|
||||
|
||||
/* return how many clocks we used */
|
||||
return m68ki_initial_cycles - GET_CYCLES();
|
||||
}
|
||||
else
|
||||
SET_CYCLES(0);
|
||||
|
||||
/* We get here if the CPU is stopped or halted */
|
||||
SET_CYCLES(0);
|
||||
CPU_INT_CYCLES = 0;
|
||||
|
||||
return num_cycles;
|
||||
/* return how many clocks we used */
|
||||
return m68ki_initial_cycles - GET_CYCLES();
|
||||
}
|
||||
|
||||
|
||||
|
@ -758,7 +851,7 @@ void m68k_modify_timeslice(int cycles)
|
|||
|
||||
void m68k_end_timeslice(void)
|
||||
{
|
||||
m68ki_initial_cycles -= GET_CYCLES();
|
||||
m68ki_initial_cycles = GET_CYCLES();
|
||||
SET_CYCLES(0);
|
||||
}
|
||||
|
||||
|
@ -775,9 +868,29 @@ void m68k_set_irq(unsigned int int_level)
|
|||
/* A transition from < 7 to 7 always interrupts (NMI) */
|
||||
/* Note: Level 7 can also level trigger like a normal IRQ */
|
||||
if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
|
||||
m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */
|
||||
m68ki_cpu.nmi_pending = TRUE;
|
||||
}
|
||||
|
||||
void m68k_set_virq(unsigned int level, unsigned int active)
|
||||
{
|
||||
uint state = m68ki_cpu.virq_state;
|
||||
uint blevel;
|
||||
|
||||
if(active)
|
||||
state |= 1 << level;
|
||||
else
|
||||
m68ki_check_interrupts(); /* Level triggered (IRQ) */
|
||||
state &= ~(1 << level);
|
||||
m68ki_cpu.virq_state = state;
|
||||
|
||||
for(blevel = 7; blevel > 0; blevel--)
|
||||
if(state & (1 << blevel))
|
||||
break;
|
||||
m68k_set_irq(blevel);
|
||||
}
|
||||
|
||||
unsigned int m68k_get_virq(unsigned int level)
|
||||
{
|
||||
return (m68ki_cpu.virq_state & (1 << level)) ? 1 : 0;
|
||||
}
|
||||
|
||||
void m68k_init(void)
|
||||
|
@ -787,7 +900,7 @@ void m68k_init(void)
|
|||
/* The first call to this function initializes the opcode handler jump table */
|
||||
if(!emulation_initialized)
|
||||
{
|
||||
m68ki_build_opcode_table(CPU_TYPE_IS_000(CPU_TYPE));
|
||||
m68ki_build_opcode_table();
|
||||
emulation_initialized = 1;
|
||||
}
|
||||
|
||||
|
@ -796,6 +909,7 @@ void m68k_init(void)
|
|||
m68k_set_reset_instr_callback(NULL);
|
||||
m68k_set_cmpild_instr_callback(NULL);
|
||||
m68k_set_rte_instr_callback(NULL);
|
||||
m68k_set_tas_instr_callback(NULL);
|
||||
m68k_set_pc_changed_callback(NULL);
|
||||
m68k_set_fc_callback(NULL);
|
||||
m68k_set_instr_hook_callback(NULL);
|
||||
|
@ -815,6 +929,8 @@ void m68k_pulse_reset(void)
|
|||
m68ki_clear_trace();
|
||||
/* Interrupt mask to level 7 */
|
||||
FLAG_INT_MASK = 0x0700;
|
||||
CPU_INT_LEVEL = 0;
|
||||
m68ki_cpu.virq_state = 0;
|
||||
/* Reset VBR */
|
||||
REG_VBR = 0;
|
||||
/* Go to supervisor mode */
|
||||
|
@ -868,22 +984,22 @@ void m68k_set_context(void* src)
|
|||
|
||||
#if M68K_COMPILE_FOR_MAME == OPT_ON
|
||||
|
||||
#include "state.h"
|
||||
#include "deprecat.h"
|
||||
|
||||
static struct {
|
||||
UINT16 sr;
|
||||
int stopped;
|
||||
int halted;
|
||||
UINT8 stopped;
|
||||
UINT8 halted;
|
||||
} m68k_substate;
|
||||
|
||||
static void m68k_prepare_substate(void)
|
||||
static void m68k_prepare_substate(running_machine *machine, void *param)
|
||||
{
|
||||
m68k_substate.sr = m68ki_get_sr();
|
||||
m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;
|
||||
m68k_substate.halted = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;
|
||||
}
|
||||
|
||||
static void m68k_post_load(void)
|
||||
static void m68k_post_load(running_machine *machine, void *param)
|
||||
{
|
||||
m68ki_set_sr_noint_nosp(m68k_substate.sr);
|
||||
CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0
|
||||
|
@ -891,31 +1007,28 @@ static void m68k_post_load(void)
|
|||
m68ki_jump(REG_PC);
|
||||
}
|
||||
|
||||
void m68k_state_register(const char *type)
|
||||
void m68k_state_register(const char *type, int index)
|
||||
{
|
||||
int cpu = cpu_getactivecpu();
|
||||
|
||||
state_save_register_UINT32(type, cpu, "D" , REG_D, 8);
|
||||
state_save_register_UINT32(type, cpu, "A" , REG_A, 8);
|
||||
state_save_register_UINT32(type, cpu, "PPC" , ®_PPC, 1);
|
||||
state_save_register_UINT32(type, cpu, "PC" , ®_PC, 1);
|
||||
state_save_register_UINT32(type, cpu, "USP" , ®_USP, 1);
|
||||
state_save_register_UINT32(type, cpu, "ISP" , ®_ISP, 1);
|
||||
state_save_register_UINT32(type, cpu, "MSP" , ®_MSP, 1);
|
||||
state_save_register_UINT32(type, cpu, "VBR" , ®_VBR, 1);
|
||||
state_save_register_UINT32(type, cpu, "SFC" , ®_SFC, 1);
|
||||
state_save_register_UINT32(type, cpu, "DFC" , ®_DFC, 1);
|
||||
state_save_register_UINT32(type, cpu, "CACR" , ®_CACR, 1);
|
||||
state_save_register_UINT32(type, cpu, "CAAR" , ®_CAAR, 1);
|
||||
state_save_register_UINT16(type, cpu, "SR" , &m68k_substate.sr, 1);
|
||||
state_save_register_UINT32(type, cpu, "INT_LEVEL" , &CPU_INT_LEVEL, 1);
|
||||
state_save_register_UINT32(type, cpu, "INT_CYCLES", &CPU_INT_CYCLES, 1);
|
||||
state_save_register_int (type, cpu, "STOPPED" , &m68k_substate.stopped);
|
||||
state_save_register_int (type, cpu, "HALTED" , &m68k_substate.halted);
|
||||
state_save_register_UINT32(type, cpu, "PREF_ADDR" , &CPU_PREF_ADDR, 1);
|
||||
state_save_register_UINT32(type, cpu, "PREF_DATA" , &CPU_PREF_DATA, 1);
|
||||
state_save_register_func_presave(m68k_prepare_substate);
|
||||
state_save_register_func_postload(m68k_post_load);
|
||||
/* Note, D covers A because the dar array is common, REG_A=REG_D+8 */
|
||||
state_save_register_item_array(type, index, REG_D);
|
||||
state_save_register_item(type, index, REG_PPC);
|
||||
state_save_register_item(type, index, REG_PC);
|
||||
state_save_register_item(type, index, REG_USP);
|
||||
state_save_register_item(type, index, REG_ISP);
|
||||
state_save_register_item(type, index, REG_MSP);
|
||||
state_save_register_item(type, index, REG_VBR);
|
||||
state_save_register_item(type, index, REG_SFC);
|
||||
state_save_register_item(type, index, REG_DFC);
|
||||
state_save_register_item(type, index, REG_CACR);
|
||||
state_save_register_item(type, index, REG_CAAR);
|
||||
state_save_register_item(type, index, m68k_substate.sr);
|
||||
state_save_register_item(type, index, CPU_INT_LEVEL);
|
||||
state_save_register_item(type, index, m68k_substate.stopped);
|
||||
state_save_register_item(type, index, m68k_substate.halted);
|
||||
state_save_register_item(type, index, CPU_PREF_ADDR);
|
||||
state_save_register_item(type, index, CPU_PREF_DATA);
|
||||
state_save_register_presave(Machine, m68k_prepare_substate, NULL);
|
||||
state_save_register_postload(Machine, m68k_post_load, NULL);
|
||||
}
|
||||
|
||||
#endif /* M68K_COMPILE_FOR_MAME */
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
/* ======================================================================== */
|
||||
/*
|
||||
* MUSASHI
|
||||
* Version 3.3
|
||||
* Version 3.32
|
||||
*
|
||||
* A portable Motorola M680x0 processor emulation engine.
|
||||
* Copyright 1998-2001 Karl Stenerud. All rights reserved.
|
||||
* Copyright Karl Stenerud. All rights reserved.
|
||||
*
|
||||
* This code may be freely used for non-commercial purposes as long as this
|
||||
* copyright notice remains unaltered in the source code and any binary files
|
||||
* containing this code in compiled form.
|
||||
*
|
||||
* All other lisencing terms must be negotiated with the author
|
||||
* All other licensing terms must be negotiated with the author
|
||||
* (Karl Stenerud).
|
||||
*
|
||||
* The latest version of this code can be obtained at:
|
||||
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef M68KCPU__HEADER
|
||||
#define M68KCPU__HEADER
|
||||
|
@ -58,10 +58,10 @@
|
|||
|
||||
#define sint8 signed char /* ASG: changed from char to signed char */
|
||||
#define sint16 signed short
|
||||
#define sint32 signed int
|
||||
#define sint32 signed int /* AWJ: changed from long to int */
|
||||
#define uint8 unsigned char
|
||||
#define uint16 unsigned short
|
||||
#define uint32 unsigned int
|
||||
#define uint32 unsigned int /* AWJ: changed from long to int */
|
||||
|
||||
/* signed and unsigned int must be at least 32 bits wide */
|
||||
#define sint signed int
|
||||
|
@ -159,6 +159,7 @@
|
|||
#define CPU_TYPE_010 4
|
||||
#define CPU_TYPE_EC020 8
|
||||
#define CPU_TYPE_020 16
|
||||
#define CPU_TYPE_040 32
|
||||
|
||||
/* Different ways to stop the CPU */
|
||||
#define STOP_LEVEL_STOP 1
|
||||
|
@ -264,8 +265,8 @@
|
|||
#define LSL_32(A, C) ((A) << (C))
|
||||
#else
|
||||
/* We have to do this because the morons at ANSI decided that shifts
|
||||
* by >= data size are undefined.
|
||||
*/
|
||||
* by >= data size are undefined.
|
||||
*/
|
||||
#define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
|
||||
#define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
|
||||
#endif /* M68K_INT_GT_32_BIT */
|
||||
|
@ -315,6 +316,11 @@
|
|||
#define REG_CAAR m68ki_cpu.caar
|
||||
#define REG_IR m68ki_cpu.ir
|
||||
|
||||
#define REG_FP m68ki_cpu.fpr
|
||||
#define REG_FPCR m68ki_cpu.fpcr
|
||||
#define REG_FPSR m68ki_cpu.fpsr
|
||||
#define REG_FPIAR m68ki_cpu.fpiar
|
||||
|
||||
#define FLAG_T1 m68ki_cpu.t1_flag
|
||||
#define FLAG_T0 m68ki_cpu.t0_flag
|
||||
#define FLAG_S m68ki_cpu.s_flag
|
||||
|
@ -327,7 +333,6 @@
|
|||
#define FLAG_INT_MASK m68ki_cpu.int_mask
|
||||
|
||||
#define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */
|
||||
#define CPU_INT_CYCLES m68ki_cpu.int_cycles /* ASG */
|
||||
#define CPU_STOPPED m68ki_cpu.stopped
|
||||
#define CPU_PREF_ADDR m68ki_cpu.pref_addr
|
||||
#define CPU_PREF_DATA m68ki_cpu.pref_data
|
||||
|
@ -354,6 +359,7 @@
|
|||
#define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback
|
||||
#define CALLBACK_CMPILD_INSTR m68ki_cpu.cmpild_instr_callback
|
||||
#define CALLBACK_RTE_INSTR m68ki_cpu.rte_instr_callback
|
||||
#define CALLBACK_TAS_INSTR m68ki_cpu.tas_instr_callback
|
||||
#define CALLBACK_PC_CHANGED m68ki_cpu.pc_changed_callback
|
||||
#define CALLBACK_SET_FC m68ki_cpu.set_fc_callback
|
||||
#define CALLBACK_INSTR_HOOK m68ki_cpu.instr_hook_callback
|
||||
|
@ -365,8 +371,16 @@
|
|||
/* These defines are dependant on the configuration defines in m68kconf.h */
|
||||
|
||||
/* Disable certain comparisons if we're not using all CPU types */
|
||||
#if M68K_EMULATE_040
|
||||
#define CPU_TYPE_IS_040_PLUS(A) ((A) & CPU_TYPE_040)
|
||||
#define CPU_TYPE_IS_040_LESS(A) 1
|
||||
#else
|
||||
#define CPU_TYPE_IS_040_PLUS(A) 0
|
||||
#define CPU_TYPE_IS_040_LESS(A) 1
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_020
|
||||
#define CPU_TYPE_IS_020_PLUS(A) ((A) & CPU_TYPE_020)
|
||||
#define CPU_TYPE_IS_020_PLUS(A) ((A) & (CPU_TYPE_020 | CPU_TYPE_040))
|
||||
#define CPU_TYPE_IS_020_LESS(A) 1
|
||||
#else
|
||||
#define CPU_TYPE_IS_020_PLUS(A) 0
|
||||
|
@ -374,7 +388,7 @@
|
|||
#endif
|
||||
|
||||
#if M68K_EMULATE_EC020
|
||||
#define CPU_TYPE_IS_EC020_PLUS(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_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020))
|
||||
#else
|
||||
#define CPU_TYPE_IS_EC020_PLUS(A) CPU_TYPE_IS_020_PLUS(A)
|
||||
|
@ -383,7 +397,7 @@
|
|||
|
||||
#if M68K_EMULATE_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))
|
||||
#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_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010))
|
||||
#else
|
||||
#define CPU_TYPE_IS_010(A) 0
|
||||
|
@ -397,7 +411,7 @@
|
|||
#define CPU_TYPE_IS_020_VARIANT(A) 0
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010
|
||||
#if M68K_EMULATE_040 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010
|
||||
#define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000 || (A) == CPU_TYPE_008)
|
||||
#else
|
||||
#define CPU_TYPE_IS_000(A) 1
|
||||
|
@ -466,14 +480,25 @@
|
|||
#define m68ki_rte_callback()
|
||||
#endif /* M68K_RTE_HAS_CALLBACK */
|
||||
|
||||
#if M68K_INSTRUCTION_HOOK
|
||||
#if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
|
||||
#define m68ki_instr_hook() M68K_INSTRUCTION_CALLBACK()
|
||||
#if M68K_TAS_HAS_CALLBACK
|
||||
#if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER
|
||||
#define m68ki_tas_callback() M68K_TAS_CALLBACK()
|
||||
#else
|
||||
#define m68ki_instr_hook() CALLBACK_INSTR_HOOK()
|
||||
#define m68ki_tas_callback() CALLBACK_TAS_INSTR()
|
||||
#endif
|
||||
#else
|
||||
#define m68ki_instr_hook()
|
||||
#define m68ki_tas_callback()
|
||||
#endif /* M68K_TAS_HAS_CALLBACK */
|
||||
|
||||
|
||||
#if M68K_INSTRUCTION_HOOK
|
||||
#if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
|
||||
#define m68ki_instr_hook(pc) M68K_INSTRUCTION_CALLBACK(pc)
|
||||
#else
|
||||
#define m68ki_instr_hook(pc) CALLBACK_INSTR_HOOK(pc)
|
||||
#endif
|
||||
#else
|
||||
#define m68ki_instr_hook(pc)
|
||||
#endif /* M68K_INSTRUCTION_HOOK */
|
||||
|
||||
#if M68K_MONITOR_PC
|
||||
|
@ -536,7 +561,6 @@
|
|||
if(CPU_STOPPED) \
|
||||
{ \
|
||||
SET_CYCLES(0); \
|
||||
CPU_INT_CYCLES = 0; \
|
||||
return m68ki_initial_cycles; \
|
||||
} \
|
||||
}
|
||||
|
@ -549,16 +573,23 @@
|
|||
m68ki_aerr_fc = FC; \
|
||||
longjmp(m68ki_aerr_trap, 1); \
|
||||
}
|
||||
|
||||
#define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC) \
|
||||
if (CPU_TYPE_IS_010_LESS(CPU_TYPE)) \
|
||||
{ \
|
||||
m68ki_check_address_error(ADDR, WRITE_MODE, FC) \
|
||||
}
|
||||
#else
|
||||
#define m68ki_set_address_error_trap()
|
||||
#define m68ki_check_address_error(ADDR, WRITE_MODE, FC)
|
||||
#define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC)
|
||||
#endif /* M68K_ADDRESS_ERROR */
|
||||
|
||||
/* Logging */
|
||||
#if M68K_LOG_ENABLE
|
||||
#include <stdio.h>
|
||||
extern FILE* M68K_LOG_FILEHANDLE
|
||||
extern char* m68ki_cpu_names[];
|
||||
extern const char *const m68ki_cpu_names[];
|
||||
|
||||
#define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A
|
||||
#if M68K_LOG_1010_1111
|
||||
|
@ -807,7 +838,16 @@
|
|||
/* =============================== PROTOTYPES ============================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
typedef struct
|
||||
typedef union _fp_reg fp_reg;
|
||||
union _fp_reg
|
||||
{
|
||||
uint64 i;
|
||||
double f;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _m68ki_cpu_core m68ki_cpu_core;
|
||||
struct _m68ki_cpu_core
|
||||
{
|
||||
uint cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, or 68020 */
|
||||
uint dar[16]; /* Data and Address Registers */
|
||||
|
@ -820,6 +860,10 @@ typedef struct
|
|||
uint cacr; /* Cache Control Register (m68020, unemulated) */
|
||||
uint caar; /* Cache Address Register (m68020, unemulated) */
|
||||
uint ir; /* Instruction Register */
|
||||
fp_reg fpr[8]; /* FPU Data Register (m68040) */
|
||||
uint fpiar; /* FPU Instruction Address Register (m68040) */
|
||||
uint fpsr; /* FPU Status Register (m68040) */
|
||||
uint fpcr; /* FPU Control Register (m68040) */
|
||||
uint t1_flag; /* Trace 1 */
|
||||
uint t0_flag; /* Trace 0 */
|
||||
uint s_flag; /* Supervisor */
|
||||
|
@ -831,7 +875,6 @@ typedef struct
|
|||
uint c_flag; /* Carry */
|
||||
uint int_mask; /* I0-I2 */
|
||||
uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */
|
||||
uint int_cycles; /* ASG: extra cycles from generated interrupts */
|
||||
uint stopped; /* Stopped state */
|
||||
uint pref_addr; /* Last prefetch address */
|
||||
uint pref_data; /* Data in the prefetch queue */
|
||||
|
@ -850,8 +893,13 @@ typedef struct
|
|||
uint cyc_movem_l;
|
||||
uint cyc_shift;
|
||||
uint cyc_reset;
|
||||
uint8* cyc_instruction;
|
||||
uint8* cyc_exception;
|
||||
|
||||
/* Virtual IRQ lines state */
|
||||
uint virq_state;
|
||||
uint nmi_pending;
|
||||
|
||||
const uint8* cyc_instruction;
|
||||
const uint8* cyc_exception;
|
||||
|
||||
/* Callbacks to host */
|
||||
int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */
|
||||
|
@ -859,22 +907,23 @@ typedef struct
|
|||
void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */
|
||||
void (*cmpild_instr_callback)(unsigned int, int); /* Called when a CMPI.L #v, Dn instruction is encountered */
|
||||
void (*rte_instr_callback)(void); /* Called when a RTE instruction is encountered */
|
||||
int (*tas_instr_callback)(void); /* Called when a TAS instruction is encountered, allows / disallows writeback */
|
||||
void (*pc_changed_callback)(unsigned int new_pc); /* Called when the PC changes by a large amount */
|
||||
void (*set_fc_callback)(unsigned int new_fc); /* Called when the CPU function code changes */
|
||||
void (*instr_hook_callback)(void); /* Called every instruction cycle prior to execution */
|
||||
void (*instr_hook_callback)(unsigned int pc); /* Called every instruction cycle prior to execution */
|
||||
|
||||
} m68ki_cpu_core;
|
||||
};
|
||||
|
||||
|
||||
extern m68ki_cpu_core m68ki_cpu;
|
||||
extern sint m68ki_remaining_cycles;
|
||||
extern uint m68ki_tracing;
|
||||
extern uint8 m68ki_shift_8_table[];
|
||||
extern uint16 m68ki_shift_16_table[];
|
||||
extern uint m68ki_shift_32_table[];
|
||||
extern uint8 m68ki_exception_cycle_table[][256];
|
||||
extern const uint8 m68ki_shift_8_table[];
|
||||
extern const uint16 m68ki_shift_16_table[];
|
||||
extern const uint m68ki_shift_32_table[];
|
||||
extern const uint8 m68ki_exception_cycle_table[][256];
|
||||
extern uint m68ki_address_space;
|
||||
extern uint8 m68ki_ea_idx_cycle_table[];
|
||||
extern const uint8 m68ki_ea_idx_cycle_table[];
|
||||
|
||||
extern uint m68ki_aerr_address;
|
||||
extern uint m68ki_aerr_write_mode;
|
||||
|
@ -1015,13 +1064,19 @@ INLINE uint m68ki_read_imm_16(void)
|
|||
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||
#if M68K_EMULATE_PREFETCH
|
||||
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
||||
{
|
||||
uint result;
|
||||
if(REG_PC != CPU_PREF_ADDR)
|
||||
{
|
||||
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
||||
CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
CPU_PREF_ADDR = REG_PC;
|
||||
CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
}
|
||||
result = MASK_OUT_ABOVE_16(CPU_PREF_DATA);
|
||||
REG_PC += 2;
|
||||
return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3));
|
||||
CPU_PREF_ADDR = REG_PC;
|
||||
CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
REG_PC += 2;
|
||||
return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2));
|
||||
|
@ -1034,20 +1089,21 @@ INLINE uint m68ki_read_imm_32(void)
|
|||
|
||||
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
||||
|
||||
if(REG_PC != CPU_PREF_ADDR)
|
||||
{
|
||||
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
||||
CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
CPU_PREF_ADDR = REG_PC;
|
||||
CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
}
|
||||
temp_val = CPU_PREF_DATA;
|
||||
temp_val = MASK_OUT_ABOVE_16(CPU_PREF_DATA);
|
||||
REG_PC += 2;
|
||||
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
||||
{
|
||||
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
||||
CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16));
|
||||
}
|
||||
CPU_PREF_ADDR = REG_PC;
|
||||
CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
|
||||
temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(CPU_PREF_DATA));
|
||||
REG_PC += 2;
|
||||
CPU_PREF_ADDR = REG_PC;
|
||||
CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR));
|
||||
|
||||
return temp_val;
|
||||
#else
|
||||
|
@ -1076,13 +1132,13 @@ INLINE uint m68ki_read_8_fc(uint address, uint fc)
|
|||
INLINE uint m68ki_read_16_fc(uint address, uint fc)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||
return m68k_read_memory_16(ADDRESS_68K(address));
|
||||
}
|
||||
INLINE uint m68ki_read_32_fc(uint address, uint fc)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||
return m68k_read_memory_32(ADDRESS_68K(address));
|
||||
}
|
||||
|
||||
|
@ -1094,13 +1150,13 @@ INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
|
|||
INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68k_write_memory_16(ADDRESS_68K(address), value);
|
||||
}
|
||||
INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68k_write_memory_32(ADDRESS_68K(address), value);
|
||||
}
|
||||
|
||||
|
@ -1108,7 +1164,7 @@ INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
|||
INLINE void m68ki_write_32_pd_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68k_write_memory_32_pd(ADDRESS_68K(address), value);
|
||||
}
|
||||
#endif
|
||||
|
@ -1550,10 +1606,10 @@ INLINE void m68ki_stack_frame_buserr(uint sr)
|
|||
m68ki_push_16(REG_IR);
|
||||
m68ki_push_32(m68ki_aerr_address); /* access address */
|
||||
/* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC
|
||||
* R/W 0 = write, 1 = read
|
||||
* I/N 0 = instruction, 1 = not
|
||||
* FC 3-bit function code
|
||||
*/
|
||||
* R/W 0 = write, 1 = read
|
||||
* I/N 0 = instruction, 1 = not
|
||||
* FC 3-bit function code
|
||||
*/
|
||||
m68ki_push_16(m68ki_aerr_write_mode | CPU_INSTR_MODE | m68ki_aerr_fc);
|
||||
}
|
||||
|
||||
|
@ -1563,9 +1619,9 @@ INLINE void m68ki_stack_frame_buserr(uint sr)
|
|||
void m68ki_stack_frame_1000(uint pc, uint sr, uint vector)
|
||||
{
|
||||
/* VERSION
|
||||
* NUMBER
|
||||
* INTERNAL INFORMATION, 16 WORDS
|
||||
*/
|
||||
* NUMBER
|
||||
* INTERNAL INFORMATION, 16 WORDS
|
||||
*/
|
||||
m68ki_fake_push_32();
|
||||
m68ki_fake_push_32();
|
||||
m68ki_fake_push_32();
|
||||
|
@ -1883,12 +1939,12 @@ INLINE void m68ki_exception_address_error(void)
|
|||
uint sr = m68ki_init_exception();
|
||||
|
||||
/* If we were processing a bus error, address error, or reset,
|
||||
* this is a catastrophic failure.
|
||||
* Halt the CPU
|
||||
*/
|
||||
* this is a catastrophic failure.
|
||||
* Halt the CPU
|
||||
*/
|
||||
if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET)
|
||||
{
|
||||
m68k_read_memory_8(0x00ffff01);
|
||||
m68k_read_memory_8(0x00ffff01);
|
||||
CPU_STOPPED = STOP_LEVEL_HALT;
|
||||
return;
|
||||
}
|
||||
|
@ -1968,7 +2024,7 @@ void m68ki_exception_interrupt(uint int_level)
|
|||
m68ki_jump(new_pc);
|
||||
|
||||
/* Defer cycle counting until later */
|
||||
CPU_INT_CYCLES += CYC_EXCEPTION[vector];
|
||||
USE_CYCLES(CYC_EXCEPTION[vector]);
|
||||
|
||||
#if !M68K_EMULATE_INT_ACK
|
||||
/* Automatically clear IRQ if we are not using an acknowledge scheme */
|
||||
|
@ -1980,7 +2036,12 @@ void m68ki_exception_interrupt(uint int_level)
|
|||
/* ASG: Check for interrupts */
|
||||
INLINE void m68ki_check_interrupts(void)
|
||||
{
|
||||
if(CPU_INT_LEVEL > FLAG_INT_MASK)
|
||||
if(m68ki_cpu.nmi_pending)
|
||||
{
|
||||
m68ki_cpu.nmi_pending = FALSE;
|
||||
m68ki_exception_interrupt(7);
|
||||
}
|
||||
else if(CPU_INT_LEVEL > FLAG_INT_MASK)
|
||||
m68ki_exception_interrupt(CPU_INT_LEVEL>>8);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,828 @@
|
|||
#define fatalerror printf
|
||||
|
||||
#define FPCC_N 0x08000000
|
||||
#define FPCC_Z 0x04000000
|
||||
#define FPCC_I 0x02000000
|
||||
#define FPCC_NAN 0x01000000
|
||||
|
||||
#define DOUBLE_INFINITY U64(0x7ff0000000000000)
|
||||
#define DOUBLE_EXPONENT U64(0x7ff0000000000000)
|
||||
#define DOUBLE_MANTISSA U64(0x000fffffffffffff)
|
||||
|
||||
INLINE void SET_CONDITION_CODES(fp_reg reg)
|
||||
{
|
||||
REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
|
||||
|
||||
// sign flag
|
||||
if (reg.i & U64(0x8000000000000000))
|
||||
{
|
||||
REG_FPSR |= FPCC_N;
|
||||
}
|
||||
|
||||
// zero flag
|
||||
if ((reg.i & U64(0x7fffffffffffffff)) == 0)
|
||||
{
|
||||
REG_FPSR |= FPCC_Z;
|
||||
}
|
||||
|
||||
// infinity flag
|
||||
if ((reg.i & U64(0x7fffffffffffffff)) == DOUBLE_INFINITY)
|
||||
{
|
||||
REG_FPSR |= FPCC_I;
|
||||
}
|
||||
|
||||
// NaN flag
|
||||
if (((reg.i & DOUBLE_EXPONENT) == DOUBLE_EXPONENT) && ((reg.i & DOUBLE_MANTISSA) != 0))
|
||||
{
|
||||
REG_FPSR |= FPCC_NAN;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE int TEST_CONDITION(int condition)
|
||||
{
|
||||
int n = (REG_FPSR & FPCC_N) != 0;
|
||||
int z = (REG_FPSR & FPCC_Z) != 0;
|
||||
int nan = (REG_FPSR & FPCC_NAN) != 0;
|
||||
int r = 0;
|
||||
switch (condition)
|
||||
{
|
||||
case 0x00: return 0; // False
|
||||
case 0x01: return (z); // Equal
|
||||
case 0x0e: return (!z); // Not Equal
|
||||
case 0x0f: return 1; // True
|
||||
case 0x12: return (!(nan || z || n)); // Greater Than
|
||||
case 0x13: return (z || !(nan || n)); // Greater or Equal
|
||||
case 0x14: return (n && !(nan || z)); // Less Than
|
||||
case 0x15: return (z || (n && !nan)); // Less Than or Equal
|
||||
case 0x1a: return (nan || !(n || z)); // Not Less Than or Equal
|
||||
case 0x1b: return (nan || z || !n); // Not Less Than
|
||||
case 0x1c: return (nan || (n && !z)); // Not Greater or Equal Than
|
||||
case 0x1d: return (nan || z || n); // Not Greater Than
|
||||
|
||||
default: fatalerror("M68040: test_condition: unhandled condition %02X\n", condition);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static UINT8 READ_EA_8(int ea)
|
||||
{
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
{
|
||||
return REG_D[reg];
|
||||
}
|
||||
case 5: // (d16, An)
|
||||
{
|
||||
UINT32 ea = EA_AY_DI_8();
|
||||
return m68ki_read_8(ea);
|
||||
}
|
||||
case 6: // (An) + (Xn) + d8
|
||||
{
|
||||
UINT32 ea = EA_AY_IX_8();
|
||||
return m68ki_read_8(ea);
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 1: // (xxx).L
|
||||
{
|
||||
UINT32 d1 = OPER_I_16();
|
||||
UINT32 d2 = OPER_I_16();
|
||||
UINT32 ea = (d1 << 16) | d2;
|
||||
return m68ki_read_8(ea);
|
||||
}
|
||||
case 4: // #<data>
|
||||
{
|
||||
return OPER_I_8();
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT16 READ_EA_16(int ea)
|
||||
{
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
{
|
||||
return (UINT16)(REG_D[reg]);
|
||||
}
|
||||
case 2: // (An)
|
||||
{
|
||||
UINT32 ea = REG_A[reg];
|
||||
return m68ki_read_16(ea);
|
||||
}
|
||||
case 5: // (d16, An)
|
||||
{
|
||||
UINT32 ea = EA_AY_DI_16();
|
||||
return m68ki_read_16(ea);
|
||||
}
|
||||
case 6: // (An) + (Xn) + d8
|
||||
{
|
||||
UINT32 ea = EA_AY_IX_16();
|
||||
return m68ki_read_16(ea);
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 1: // (xxx).L
|
||||
{
|
||||
UINT32 d1 = OPER_I_16();
|
||||
UINT32 d2 = OPER_I_16();
|
||||
UINT32 ea = (d1 << 16) | d2;
|
||||
return m68ki_read_16(ea);
|
||||
}
|
||||
case 4: // #<data>
|
||||
{
|
||||
return OPER_I_16();
|
||||
}
|
||||
|
||||
default: fatalerror("MC68040: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT32 READ_EA_32(int ea)
|
||||
{
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
{
|
||||
return REG_D[reg];
|
||||
}
|
||||
case 2: // (An)
|
||||
{
|
||||
UINT32 ea = REG_A[reg];
|
||||
return m68ki_read_32(ea);
|
||||
}
|
||||
case 3: // (An)+
|
||||
{
|
||||
UINT32 ea = EA_AY_PI_32();
|
||||
return m68ki_read_32(ea);
|
||||
}
|
||||
case 5: // (d16, An)
|
||||
{
|
||||
UINT32 ea = EA_AY_DI_32();
|
||||
return m68ki_read_32(ea);
|
||||
}
|
||||
case 6: // (An) + (Xn) + d8
|
||||
{
|
||||
UINT32 ea = EA_AY_IX_32();
|
||||
return m68ki_read_32(ea);
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 1: // (xxx).L
|
||||
{
|
||||
UINT32 d1 = OPER_I_16();
|
||||
UINT32 d2 = OPER_I_16();
|
||||
UINT32 ea = (d1 << 16) | d2;
|
||||
return m68ki_read_32(ea);
|
||||
}
|
||||
case 2: // (d16, PC)
|
||||
{
|
||||
UINT32 ea = EA_PCDI_32();
|
||||
return m68ki_read_32(ea);
|
||||
}
|
||||
case 4: // #<data>
|
||||
{
|
||||
return OPER_I_32();
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void WRITE_EA_32(int ea, UINT32 data)
|
||||
{
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
{
|
||||
REG_D[reg] = data;
|
||||
break;
|
||||
}
|
||||
case 2: // (An)
|
||||
{
|
||||
UINT32 ea = REG_A[reg];
|
||||
m68ki_write_32(ea, data);
|
||||
break;
|
||||
}
|
||||
case 3: // (An)+
|
||||
{
|
||||
UINT32 ea = EA_AY_PI_32();
|
||||
m68ki_write_32(ea, data);
|
||||
break;
|
||||
}
|
||||
case 4: // -(An)
|
||||
{
|
||||
UINT32 ea = EA_AY_PD_32();
|
||||
m68ki_write_32(ea, data);
|
||||
break;
|
||||
}
|
||||
case 5: // (d16, An)
|
||||
{
|
||||
UINT32 ea = EA_AY_DI_32();
|
||||
m68ki_write_32(ea, data);
|
||||
break;
|
||||
}
|
||||
case 6: // (An) + (Xn) + d8
|
||||
{
|
||||
UINT32 ea = EA_AY_IX_32();
|
||||
m68ki_write_32(ea, data);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 1: // (xxx).L
|
||||
{
|
||||
UINT32 d1 = OPER_I_16();
|
||||
UINT32 d2 = OPER_I_16();
|
||||
UINT32 ea = (d1 << 16) | d2;
|
||||
m68ki_write_32(ea, data);
|
||||
break;
|
||||
}
|
||||
case 2: // (d16, PC)
|
||||
{
|
||||
UINT32 ea = EA_PCDI_32();
|
||||
m68ki_write_32(ea, data);
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT64 READ_EA_64(int ea)
|
||||
{
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
UINT32 h1, h2;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 2: // (An)
|
||||
{
|
||||
UINT32 ea = REG_A[reg];
|
||||
h1 = m68ki_read_32(ea+0);
|
||||
h2 = m68ki_read_32(ea+4);
|
||||
return (UINT64)(h1) << 32 | (UINT64)(h2);
|
||||
}
|
||||
case 3: // (An)+
|
||||
{
|
||||
UINT32 ea = REG_A[reg];
|
||||
REG_A[reg] += 8;
|
||||
h1 = m68ki_read_32(ea+0);
|
||||
h2 = m68ki_read_32(ea+4);
|
||||
return (UINT64)(h1) << 32 | (UINT64)(h2);
|
||||
}
|
||||
case 5: // (d16, An)
|
||||
{
|
||||
UINT32 ea = EA_AY_DI_32();
|
||||
h1 = m68ki_read_32(ea+0);
|
||||
h2 = m68ki_read_32(ea+4);
|
||||
return (UINT64)(h1) << 32 | (UINT64)(h2);
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 4: // #<data>
|
||||
{
|
||||
h1 = OPER_I_32();
|
||||
h2 = OPER_I_32();
|
||||
return (UINT64)(h1) << 32 | (UINT64)(h2);
|
||||
}
|
||||
case 2: // (d16, PC)
|
||||
{
|
||||
UINT32 ea = EA_PCDI_32();
|
||||
h1 = m68ki_read_32(ea+0);
|
||||
h2 = m68ki_read_32(ea+4);
|
||||
return (UINT64)(h1) << 32 | (UINT64)(h2);
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void WRITE_EA_64(int ea, UINT64 data)
|
||||
{
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 2: // (An)
|
||||
{
|
||||
UINT32 ea = REG_A[reg];
|
||||
m68ki_write_32(ea, (UINT32)(data >> 32));
|
||||
m68ki_write_32(ea, (UINT32)(data));
|
||||
break;
|
||||
}
|
||||
case 4: // -(An)
|
||||
{
|
||||
UINT32 ea;
|
||||
REG_A[reg] -= 8;
|
||||
ea = REG_A[reg];
|
||||
m68ki_write_32(ea+0, (UINT32)(data >> 32));
|
||||
m68ki_write_32(ea+4, (UINT32)(data));
|
||||
break;
|
||||
}
|
||||
case 5: // (d16, An)
|
||||
{
|
||||
UINT32 ea = EA_AY_DI_32();
|
||||
m68ki_write_32(ea+0, (UINT32)(data >> 32));
|
||||
m68ki_write_32(ea+4, (UINT32)(data));
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (UINT32)(data >> 32), (UINT32)(data), REG_PC);
|
||||
}
|
||||
}
|
||||
|
||||
static fp_reg READ_EA_FPE(int ea)
|
||||
{
|
||||
fp_reg r;
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
// TODO: convert to extended floating-point!
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 3: // (An)+
|
||||
{
|
||||
UINT32 d1,d2,d3;
|
||||
UINT32 ea = REG_A[reg];
|
||||
REG_A[reg] += 12;
|
||||
d1 = m68ki_read_32(ea+0);
|
||||
d2 = m68ki_read_32(ea+4);
|
||||
d3 = m68ki_read_32(ea+8);
|
||||
r.i = (UINT64)(d1) << 32 | (UINT64)(d2);
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void WRITE_EA_FPE(int ea, fp_reg fpr)
|
||||
{
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
// TODO: convert to extended floating-point!
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 4: // -(An)
|
||||
{
|
||||
UINT32 ea;
|
||||
REG_A[reg] -= 12;
|
||||
ea = REG_A[reg];
|
||||
m68ki_write_32(ea+0, (UINT32)(fpr.i >> 32));
|
||||
m68ki_write_32(ea+4, (UINT32)(fpr.i));
|
||||
m68ki_write_32(ea+8, 0);
|
||||
break;
|
||||
}
|
||||
default: fatalerror("MC68040: WRITE_EA_FPE: unhandled mode %d, reg %d, data %f at %08X\n", mode, reg, fpr.f, REG_PC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fpgen_rm_reg(UINT16 w2)
|
||||
{
|
||||
int ea = REG_IR & 0x3f;
|
||||
int rm = (w2 >> 14) & 0x1;
|
||||
int src = (w2 >> 10) & 0x7;
|
||||
int dst = (w2 >> 7) & 0x7;
|
||||
int opmode = w2 & 0x7f;
|
||||
double source;
|
||||
|
||||
if (rm)
|
||||
{
|
||||
switch (src)
|
||||
{
|
||||
case 0: // Long-Word Integer
|
||||
{
|
||||
INT32 d = READ_EA_32(ea);
|
||||
source = (double)(d);
|
||||
break;
|
||||
}
|
||||
case 1: // Single-precision Real
|
||||
{
|
||||
UINT32 d = READ_EA_32(ea);
|
||||
source = (double)(*(float*)&d);
|
||||
break;
|
||||
}
|
||||
case 2: // Extended-precision Real
|
||||
{
|
||||
fatalerror("fpgen_rm_reg: extended-precision real load unimplemented at %08X\n", REG_PC-4);
|
||||
break;
|
||||
}
|
||||
case 3: // Packed-decimal Real
|
||||
{
|
||||
fatalerror("fpgen_rm_reg: packed-decimal real load unimplemented at %08X\n", REG_PC-4);
|
||||
break;
|
||||
}
|
||||
case 4: // Word Integer
|
||||
{
|
||||
INT16 d = READ_EA_16(ea);
|
||||
source = (double)(d);
|
||||
break;
|
||||
}
|
||||
case 5: // Double-precision Real
|
||||
{
|
||||
UINT64 d = READ_EA_64(ea);
|
||||
source = *(double*)&d;
|
||||
break;
|
||||
}
|
||||
case 6: // Byte Integer
|
||||
{
|
||||
INT8 d = READ_EA_8(ea);
|
||||
source = (double)(d);
|
||||
break;
|
||||
}
|
||||
default: fatalerror("fmove_rm_reg: invalid source specifier at %08X\n", REG_PC-4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
source = REG_FP[src].f;
|
||||
}
|
||||
|
||||
switch (opmode)
|
||||
{
|
||||
case 0x00: // FMOVE
|
||||
{
|
||||
REG_FP[dst].f = source;
|
||||
USE_CYCLES(4);
|
||||
break;
|
||||
}
|
||||
case 0x04: // FSQRT
|
||||
{
|
||||
REG_FP[dst].f = sqrt(source);
|
||||
SET_CONDITION_CODES(REG_FP[dst]);
|
||||
USE_CYCLES(109);
|
||||
break;
|
||||
}
|
||||
case 0x18: // FABS
|
||||
{
|
||||
REG_FP[dst].f = fabs(source);
|
||||
SET_CONDITION_CODES(REG_FP[dst]);
|
||||
USE_CYCLES(3);
|
||||
break;
|
||||
}
|
||||
case 0x1a: // FNEG
|
||||
{
|
||||
REG_FP[dst].f = -source;
|
||||
SET_CONDITION_CODES(REG_FP[dst]);
|
||||
USE_CYCLES(3);
|
||||
break;
|
||||
}
|
||||
case 0x20: // FDIV
|
||||
{
|
||||
REG_FP[dst].f /= source;
|
||||
USE_CYCLES(43);
|
||||
break;
|
||||
}
|
||||
case 0x22: // FADD
|
||||
{
|
||||
REG_FP[dst].f += source;
|
||||
SET_CONDITION_CODES(REG_FP[dst]);
|
||||
USE_CYCLES(9);
|
||||
break;
|
||||
}
|
||||
case 0x23: // FMUL
|
||||
{
|
||||
REG_FP[dst].f *= source;
|
||||
SET_CONDITION_CODES(REG_FP[dst]);
|
||||
USE_CYCLES(11);
|
||||
break;
|
||||
}
|
||||
case 0x28: // FSUB
|
||||
{
|
||||
REG_FP[dst].f -= source;
|
||||
SET_CONDITION_CODES(REG_FP[dst]);
|
||||
USE_CYCLES(9);
|
||||
break;
|
||||
}
|
||||
case 0x38: // FCMP
|
||||
{
|
||||
fp_reg res;
|
||||
res.f = REG_FP[dst].f - source;
|
||||
SET_CONDITION_CODES(res);
|
||||
USE_CYCLES(7);
|
||||
break;
|
||||
}
|
||||
case 0x3a: // FTST
|
||||
{
|
||||
fp_reg res;
|
||||
res.f = source;
|
||||
SET_CONDITION_CODES(res);
|
||||
USE_CYCLES(7);
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
|
||||
}
|
||||
}
|
||||
|
||||
static void fmove_reg_mem(UINT16 w2)
|
||||
{
|
||||
int ea = REG_IR & 0x3f;
|
||||
int src = (w2 >> 7) & 0x7;
|
||||
int dst = (w2 >> 10) & 0x7;
|
||||
//int kfactor = w2 & 0x7f;
|
||||
|
||||
switch (dst)
|
||||
{
|
||||
case 0: // Long-Word Integer
|
||||
{
|
||||
INT32 d = (INT32)(REG_FP[src].f);
|
||||
WRITE_EA_32(ea, d);
|
||||
break;
|
||||
}
|
||||
case 1: // Single-precision Real
|
||||
{
|
||||
float f = (float)(REG_FP[src].f);
|
||||
UINT32 d = *(UINT32 *)&f;
|
||||
WRITE_EA_32(ea, d);
|
||||
break;
|
||||
}
|
||||
case 2: // Extended-precision Real
|
||||
{
|
||||
fatalerror("fmove_reg_mem: extended-precision real store unimplemented at %08X\n", REG_PC-4);
|
||||
break;
|
||||
}
|
||||
case 3: // Packed-decimal Real with Static K-factor
|
||||
{
|
||||
fatalerror("fmove_reg_mem: packed-decimal real store unimplemented at %08X\n", REG_PC-4);
|
||||
break;
|
||||
}
|
||||
case 4: // Word Integer
|
||||
{
|
||||
fatalerror("fmove_reg_mem: word integer store unimplemented at %08X\n", REG_PC-4);
|
||||
break;
|
||||
}
|
||||
case 5: // Double-precision Real
|
||||
{
|
||||
UINT64 d = REG_FP[src].i;
|
||||
WRITE_EA_64(ea, d);
|
||||
break;
|
||||
}
|
||||
case 6: // Byte Integer
|
||||
{
|
||||
fatalerror("fmove_reg_mem: byte integer store unimplemented at %08X\n", REG_PC-4);
|
||||
break;
|
||||
}
|
||||
case 7: // Packed-decimal Real with Dynamic K-factor
|
||||
{
|
||||
fatalerror("fmove_reg_mem: packed-decimal real store unimplemented at %08X\n", REG_PC-4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
USE_CYCLES(12);
|
||||
}
|
||||
|
||||
static void fmove_fpcr(UINT16 w2)
|
||||
{
|
||||
int ea = REG_IR & 0x3f;
|
||||
int dir = (w2 >> 13) & 0x1;
|
||||
int reg = (w2 >> 10) & 0x7;
|
||||
|
||||
if (dir) // From system control reg to <ea>
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 1: WRITE_EA_32(ea, REG_FPIAR); break;
|
||||
case 2: WRITE_EA_32(ea, REG_FPSR); break;
|
||||
case 4: WRITE_EA_32(ea, REG_FPCR); break;
|
||||
default: fatalerror("fmove_fpcr: unknown reg %d, dir %d\n", reg, dir);
|
||||
}
|
||||
}
|
||||
else // From <ea> to system control reg
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 1: REG_FPIAR = READ_EA_32(ea); break;
|
||||
case 2: REG_FPSR = READ_EA_32(ea); break;
|
||||
case 4: REG_FPCR = READ_EA_32(ea); break;
|
||||
default: fatalerror("fmove_fpcr: unknown reg %d, dir %d\n", reg, dir);
|
||||
}
|
||||
}
|
||||
|
||||
USE_CYCLES(10);
|
||||
}
|
||||
|
||||
static void fmovem(UINT16 w2)
|
||||
{
|
||||
int i;
|
||||
int ea = REG_IR & 0x3f;
|
||||
int dir = (w2 >> 13) & 0x1;
|
||||
int mode = (w2 >> 11) & 0x3;
|
||||
int reglist = w2 & 0xff;
|
||||
|
||||
if (dir) // From FP regs to mem
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Static register list, predecrement addressing mode
|
||||
{
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
if (reglist & (1 << i))
|
||||
{
|
||||
WRITE_EA_FPE(ea, REG_FP[i]);
|
||||
USE_CYCLES(2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
|
||||
}
|
||||
}
|
||||
else // From mem to FP regs
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 2: // Static register list, postincrement addressing mode
|
||||
{
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
if (reglist & (1 << i))
|
||||
{
|
||||
REG_FP[7-i] = READ_EA_FPE(ea);
|
||||
USE_CYCLES(2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fbcc16(void)
|
||||
{
|
||||
INT32 offset;
|
||||
int condition = REG_IR & 0x3f;
|
||||
|
||||
offset = (INT16)(OPER_I_16());
|
||||
|
||||
// TODO: condition and jump!!!
|
||||
if (TEST_CONDITION(condition))
|
||||
{
|
||||
m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_branch_16(offset-2);
|
||||
}
|
||||
|
||||
USE_CYCLES(7);
|
||||
}
|
||||
|
||||
static void fbcc32(void)
|
||||
{
|
||||
INT32 offset;
|
||||
int condition = REG_IR & 0x3f;
|
||||
|
||||
offset = OPER_I_32();
|
||||
|
||||
// TODO: condition and jump!!!
|
||||
if (TEST_CONDITION(condition))
|
||||
{
|
||||
m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_branch_32(offset-4);
|
||||
}
|
||||
|
||||
USE_CYCLES(7);
|
||||
}
|
||||
|
||||
|
||||
void m68040_fpu_op0(void)
|
||||
{
|
||||
switch ((REG_IR >> 6) & 0x3)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
UINT16 w2 = OPER_I_16();
|
||||
switch ((w2 >> 13) & 0x7)
|
||||
{
|
||||
case 0x0: // FPU ALU FP, FP
|
||||
case 0x2: // FPU ALU ea, FP
|
||||
{
|
||||
fpgen_rm_reg(w2);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3: // FMOVE FP, ea
|
||||
{
|
||||
fmove_reg_mem(w2);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4: // FMOVE ea, FPCR
|
||||
case 0x5: // FMOVE FPCR, ea
|
||||
{
|
||||
fmove_fpcr(w2);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x6: // FMOVEM ea, list
|
||||
case 0x7: // FMOVEM list, ea
|
||||
{
|
||||
fmovem(w2);
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("m68040_fpu_op0: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // FBcc disp16
|
||||
{
|
||||
fbcc16();
|
||||
break;
|
||||
}
|
||||
case 3: // FBcc disp32
|
||||
{
|
||||
fbcc32();
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("m68040_fpu_op0: unimplemented main op %d\n", (REG_IR >> 6) & 0x3);
|
||||
}
|
||||
}
|
||||
|
||||
void m68040_fpu_op1(void)
|
||||
{
|
||||
int ea = REG_IR & 0x3f;
|
||||
|
||||
switch ((REG_IR >> 6) & 0x3)
|
||||
{
|
||||
case 0: // FSAVE <ea>
|
||||
{
|
||||
WRITE_EA_32(ea, 0x00000000);
|
||||
// TODO: correct state frame
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // FRESTORE <ea>
|
||||
{
|
||||
READ_EA_32(ea);
|
||||
// TODO: correct state frame
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3,16 +3,16 @@
|
|||
/* ======================================================================== */
|
||||
/*
|
||||
* MUSASHI
|
||||
* Version 3.3
|
||||
* Version 3.32
|
||||
*
|
||||
* A portable Motorola M680x0 processor emulation engine.
|
||||
* Copyright 1998-2001 Karl Stenerud. All rights reserved.
|
||||
* Copyright Karl Stenerud. All rights reserved.
|
||||
*
|
||||
* This code may be freely used for non-commercial purposes as long as this
|
||||
* copyright notice remains unaltered in the source code and any binary files
|
||||
* containing this code in compiled form.
|
||||
*
|
||||
* All other lisencing terms must be negotiated with the author
|
||||
* All other licensing terms must be negotiated with the author
|
||||
* (Karl Stenerud).
|
||||
*
|
||||
* The latest version of this code can be obtained at:
|
||||
|
@ -52,7 +52,7 @@
|
|||
*/
|
||||
|
||||
|
||||
const char* g_version = "3.3";
|
||||
static const char g_version[] = "3.32";
|
||||
|
||||
/* ======================================================================== */
|
||||
/* =============================== INCLUDES =============================== */
|
||||
|
@ -88,9 +88,6 @@ const char* g_version = "3.3";
|
|||
#define FILENAME_INPUT "m68k_in.c"
|
||||
#define FILENAME_PROTOTYPE "m68kops.h"
|
||||
#define FILENAME_TABLE "m68kops.c"
|
||||
#define FILENAME_OPS_AC "m68kopac.c"
|
||||
#define FILENAME_OPS_DM "m68kopdm.c"
|
||||
#define FILENAME_OPS_NZ "m68kopnz.c"
|
||||
|
||||
|
||||
/* Identifier sequences recognized by this program */
|
||||
|
@ -130,10 +127,12 @@ const char* g_version = "3.3";
|
|||
/* ============================== PROTOTYPES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
CPU_TYPE_000 = 0,
|
||||
CPU_TYPE_010,
|
||||
CPU_TYPE_020,
|
||||
CPU_TYPE_040,
|
||||
NUM_CPUS
|
||||
};
|
||||
|
||||
|
@ -229,7 +228,6 @@ int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char*
|
|||
void add_replace_string(replace_struct* replace, const char* search_str, const char* replace_str);
|
||||
void write_body(FILE* filep, body_struct* body, replace_struct* replace);
|
||||
void get_base_name(char* base_name, opcode_struct* op);
|
||||
void write_prototype(FILE* filep, char* base_name);
|
||||
void write_function_name(FILE* filep, char* base_name);
|
||||
void add_opcode_output_table_entry(opcode_struct* op, char* name);
|
||||
static int DECL_SPEC compare_nof_true_bits(const void* aptr, const void* bptr);
|
||||
|
@ -239,7 +237,7 @@ void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode);
|
|||
void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode);
|
||||
void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op);
|
||||
void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset);
|
||||
void process_opcode_handlers(void);
|
||||
void process_opcode_handlers(FILE* filep);
|
||||
void populate_table(void);
|
||||
void read_insert(char* insert);
|
||||
|
||||
|
@ -256,9 +254,6 @@ char g_input_filename[M68K_MAX_PATH] = FILENAME_INPUT;
|
|||
FILE* g_input_file = NULL;
|
||||
FILE* g_prototype_file = NULL;
|
||||
FILE* g_table_file = NULL;
|
||||
FILE* g_ops_ac_file = NULL;
|
||||
FILE* g_ops_dm_file = NULL;
|
||||
FILE* g_ops_nz_file = NULL;
|
||||
|
||||
int g_num_functions = 0; /* Number of functions processed */
|
||||
int g_num_primitives = 0; /* Number of function primitives read */
|
||||
|
@ -270,7 +265,7 @@ opcode_struct g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH];
|
|||
opcode_struct g_opcode_output_table[MAX_OPCODE_OUTPUT_TABLE_LENGTH];
|
||||
int g_opcode_output_table_length = 0;
|
||||
|
||||
ea_info_struct g_ea_info_table[13] =
|
||||
const ea_info_struct g_ea_info_table[13] =
|
||||
{/* fname ea mask match */
|
||||
{"", "", 0x00, 0x00}, /* EA_MODE_NONE */
|
||||
{"ai", "AY_AI", 0x38, 0x10}, /* EA_MODE_AI */
|
||||
|
@ -288,7 +283,7 @@ ea_info_struct g_ea_info_table[13] =
|
|||
};
|
||||
|
||||
|
||||
const char* g_cc_table[16][2] =
|
||||
const char *const g_cc_table[16][2] =
|
||||
{
|
||||
{ "t", "T"}, /* 0000 */
|
||||
{ "f", "F"}, /* 0001 */
|
||||
|
@ -309,7 +304,7 @@ const char* g_cc_table[16][2] =
|
|||
};
|
||||
|
||||
/* size to index translator (0 -> 0, 8 and 16 -> 1, 32 -> 2) */
|
||||
int g_size_select_table[33] =
|
||||
const int g_size_select_table[33] =
|
||||
{
|
||||
0, /* unsized */
|
||||
0, 0, 0, 0, 0, 0, 0, 1, /* 8 */
|
||||
|
@ -318,25 +313,26 @@ int g_size_select_table[33] =
|
|||
};
|
||||
|
||||
/* Extra cycles required for certain EA modes */
|
||||
int g_ea_cycle_table[13][NUM_CPUS][3] =
|
||||
{/* 000 010 020 */
|
||||
{{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */
|
||||
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_AI */
|
||||
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_PI */
|
||||
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_PI7 */
|
||||
{{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}}, /* EA_MODE_PD */
|
||||
{{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}}, /* EA_MODE_PD7 */
|
||||
{{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}}, /* EA_MODE_DI */
|
||||
{{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}}, /* EA_MODE_IX */
|
||||
{{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}}, /* EA_MODE_AW */
|
||||
{{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}}, /* EA_MODE_AL */
|
||||
{{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}}, /* EA_MODE_PCDI */
|
||||
{{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}}, /* EA_MODE_PCIX */
|
||||
{{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}}, /* EA_MODE_I */
|
||||
/* TODO: correct timings for 040 */
|
||||
const int g_ea_cycle_table[13][NUM_CPUS][3] =
|
||||
{/* 000 010 020 040 */
|
||||
{{ 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}}, /* EA_MODE_PI */
|
||||
{{ 0, 4, 8}, { 0, 4, 8}, { 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}}, /* EA_MODE_PD7 */
|
||||
{{ 0, 8, 12}, { 0, 8, 12}, { 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, 8, 12}, { 0, 8, 12}, { 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, 8, 12}, { 0, 8, 12}, { 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, 4, 8}, { 0, 4, 8}, { 0, 2, 4}, { 0, 2, 4}}, /* EA_MODE_I */
|
||||
};
|
||||
|
||||
/* Extra cycles for JMP instruction (000, 010) */
|
||||
int g_jmp_cycle_table[13] =
|
||||
const int g_jmp_cycle_table[13] =
|
||||
{
|
||||
0, /* EA_MODE_NONE */
|
||||
4, /* EA_MODE_AI */
|
||||
|
@ -354,7 +350,7 @@ int g_jmp_cycle_table[13] =
|
|||
};
|
||||
|
||||
/* Extra cycles for JSR instruction (000, 010) */
|
||||
int g_jsr_cycle_table[13] =
|
||||
const int g_jsr_cycle_table[13] =
|
||||
{
|
||||
0, /* EA_MODE_NONE */
|
||||
4, /* EA_MODE_AI */
|
||||
|
@ -372,7 +368,7 @@ int g_jsr_cycle_table[13] =
|
|||
};
|
||||
|
||||
/* Extra cycles for LEA instruction (000, 010) */
|
||||
int g_lea_cycle_table[13] =
|
||||
const int g_lea_cycle_table[13] =
|
||||
{
|
||||
0, /* EA_MODE_NONE */
|
||||
4, /* EA_MODE_AI */
|
||||
|
@ -390,7 +386,7 @@ int g_lea_cycle_table[13] =
|
|||
};
|
||||
|
||||
/* Extra cycles for PEA instruction (000, 010) */
|
||||
int g_pea_cycle_table[13] =
|
||||
const int g_pea_cycle_table[13] =
|
||||
{
|
||||
0, /* EA_MODE_NONE */
|
||||
6, /* EA_MODE_AI */
|
||||
|
@ -408,7 +404,7 @@ int g_pea_cycle_table[13] =
|
|||
};
|
||||
|
||||
/* Extra cycles for MOVEM instruction (000, 010) */
|
||||
int g_movem_cycle_table[13] =
|
||||
const int g_movem_cycle_table[13] =
|
||||
{
|
||||
0, /* EA_MODE_NONE */
|
||||
0, /* EA_MODE_AI */
|
||||
|
@ -426,7 +422,7 @@ int g_movem_cycle_table[13] =
|
|||
};
|
||||
|
||||
/* Extra cycles for MOVES instruction (010) */
|
||||
int g_moves_cycle_table[13][3] =
|
||||
const int g_moves_cycle_table[13][3] =
|
||||
{
|
||||
{ 0, 0, 0}, /* EA_MODE_NONE */
|
||||
{ 0, 4, 6}, /* EA_MODE_AI */
|
||||
|
@ -444,7 +440,7 @@ int g_moves_cycle_table[13][3] =
|
|||
};
|
||||
|
||||
/* Extra cycles for CLR instruction (010) */
|
||||
int g_clr_cycle_table[13][3] =
|
||||
const int g_clr_cycle_table[13][3] =
|
||||
{
|
||||
{ 0, 0, 0}, /* EA_MODE_NONE */
|
||||
{ 0, 4, 6}, /* EA_MODE_AI */
|
||||
|
@ -479,9 +475,6 @@ void error_exit(const char* fmt, ...)
|
|||
|
||||
if(g_prototype_file) fclose(g_prototype_file);
|
||||
if(g_table_file) fclose(g_table_file);
|
||||
if(g_ops_ac_file) fclose(g_ops_ac_file);
|
||||
if(g_ops_dm_file) fclose(g_ops_dm_file);
|
||||
if(g_ops_nz_file) fclose(g_ops_nz_file);
|
||||
if(g_input_file) fclose(g_input_file);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -498,9 +491,6 @@ void perror_exit(const char* fmt, ...)
|
|||
|
||||
if(g_prototype_file) fclose(g_prototype_file);
|
||||
if(g_table_file) fclose(g_table_file);
|
||||
if(g_ops_ac_file) fclose(g_ops_ac_file);
|
||||
if(g_ops_dm_file) fclose(g_ops_dm_file);
|
||||
if(g_ops_nz_file) fclose(g_ops_nz_file);
|
||||
if(g_input_file) fclose(g_input_file);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -788,16 +778,10 @@ void get_base_name(char* base_name, opcode_struct* op)
|
|||
sprintf(base_name+strlen(base_name), "_%s", op->spec_ea);
|
||||
}
|
||||
|
||||
/* Write the prototype of an opcode handler function */
|
||||
void write_prototype(FILE* filep, char* base_name)
|
||||
{
|
||||
fprintf(filep, "void %s(void);\n", base_name);
|
||||
}
|
||||
|
||||
/* Write the name of an opcode handler function */
|
||||
void write_function_name(FILE* filep, char* base_name)
|
||||
{
|
||||
fprintf(filep, "void %s(void)\n", base_name);
|
||||
fprintf(filep, "static void %s(void)\n", base_name);
|
||||
}
|
||||
|
||||
void add_opcode_output_table_entry(opcode_struct* op, char* name)
|
||||
|
@ -880,7 +864,6 @@ void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* rep
|
|||
/* Set the opcode structure and write the tables, prototypes, etc */
|
||||
set_opcode_struct(opinfo, op, ea_mode);
|
||||
get_base_name(str, op);
|
||||
write_prototype(g_prototype_file, str);
|
||||
add_opcode_output_table_entry(op, str);
|
||||
write_function_name(filep, str);
|
||||
|
||||
|
@ -999,10 +982,9 @@ void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct*
|
|||
}
|
||||
|
||||
/* Process the opcode handlers section of the input file */
|
||||
void process_opcode_handlers(void)
|
||||
void process_opcode_handlers(FILE* filep)
|
||||
{
|
||||
FILE* input_file = g_input_file;
|
||||
FILE* output_file;
|
||||
char func_name[MAX_LINE_LENGTH+1];
|
||||
char oper_name[MAX_LINE_LENGTH+1];
|
||||
int oper_size;
|
||||
|
@ -1012,9 +994,6 @@ void process_opcode_handlers(void)
|
|||
replace_struct* replace = malloc(sizeof(replace_struct));
|
||||
body_struct* body = malloc(sizeof(body_struct));
|
||||
|
||||
|
||||
output_file = g_ops_ac_file;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
/* Find the first line of the function */
|
||||
|
@ -1057,23 +1036,17 @@ void process_opcode_handlers(void)
|
|||
if(opinfo == NULL)
|
||||
error_exit("Unable to find matching table entry for %s", func_name);
|
||||
|
||||
/* Change output files if we pass 'c' or 'n' */
|
||||
if(output_file == g_ops_ac_file && oper_name[0] > 'c')
|
||||
output_file = g_ops_dm_file;
|
||||
else if(output_file == g_ops_dm_file && oper_name[0] > 'm')
|
||||
output_file = g_ops_nz_file;
|
||||
|
||||
replace->length = 0;
|
||||
|
||||
/* Generate opcode variants */
|
||||
if(strcmp(opinfo->name, "bcc") == 0 || strcmp(opinfo->name, "scc") == 0)
|
||||
generate_opcode_cc_variants(output_file, body, replace, opinfo, 1);
|
||||
generate_opcode_cc_variants(filep, body, replace, opinfo, 1);
|
||||
else if(strcmp(opinfo->name, "dbcc") == 0)
|
||||
generate_opcode_cc_variants(output_file, body, replace, opinfo, 2);
|
||||
generate_opcode_cc_variants(filep, body, replace, opinfo, 2);
|
||||
else if(strcmp(opinfo->name, "trapcc") == 0)
|
||||
generate_opcode_cc_variants(output_file, body, replace, opinfo, 4);
|
||||
generate_opcode_cc_variants(filep, body, replace, opinfo, 4);
|
||||
else
|
||||
generate_opcode_ea_variants(output_file, body, replace, opinfo);
|
||||
generate_opcode_ea_variants(filep, body, replace, opinfo);
|
||||
}
|
||||
|
||||
free(replace);
|
||||
|
@ -1246,7 +1219,9 @@ int main(int argc, char **argv)
|
|||
/* Inserts */
|
||||
char temp_insert[MAX_INSERT_LENGTH+1];
|
||||
char prototype_footer_insert[MAX_INSERT_LENGTH+1];
|
||||
char table_header_insert[MAX_INSERT_LENGTH+1];
|
||||
char table_footer_insert[MAX_INSERT_LENGTH+1];
|
||||
char ophandler_header_insert[MAX_INSERT_LENGTH+1];
|
||||
char ophandler_footer_insert[MAX_INSERT_LENGTH+1];
|
||||
/* Flags if we've processed certain parts already */
|
||||
int prototype_header_read = 0;
|
||||
|
@ -1258,8 +1233,8 @@ int main(int argc, char **argv)
|
|||
int table_body_read = 0;
|
||||
int ophandler_body_read = 0;
|
||||
|
||||
printf("\n\t\tMusashi v%s 68000, 68008, 68010, 68EC020, 68020 emulator\n", g_version);
|
||||
printf("\t\tCopyright 1998-2000 Karl Stenerud (karl@mame.net)\n\n");
|
||||
printf("\n\tMusashi v%s 68000, 68008, 68010, 68EC020, 68020, 68040 emulator\n", g_version);
|
||||
printf("\tCopyright Karl Stenerud (karl@mame.net)\n\n");
|
||||
|
||||
/* Check if output path and source for the input file are given */
|
||||
if(argc > 1)
|
||||
|
@ -1291,18 +1266,6 @@ int main(int argc, char **argv)
|
|||
if((g_table_file = fopen(filename, "w")) == NULL)
|
||||
perror_exit("Unable to create table file (%s)\n", filename);
|
||||
|
||||
sprintf(filename, "%s%s", output_path, FILENAME_OPS_AC);
|
||||
if((g_ops_ac_file = fopen(filename, "w")) == NULL)
|
||||
perror_exit("Unable to create ops ac file (%s)\n", filename);
|
||||
|
||||
sprintf(filename, "%s%s", output_path, FILENAME_OPS_DM);
|
||||
if((g_ops_dm_file = fopen(filename, "w")) == NULL)
|
||||
perror_exit("Unable to create ops dm file (%s)\n", filename);
|
||||
|
||||
sprintf(filename, "%s%s", output_path, FILENAME_OPS_NZ);
|
||||
if((g_ops_nz_file = fopen(filename, "w")) == NULL)
|
||||
perror_exit("Unable to create ops nz file (%s)\n", filename);
|
||||
|
||||
if((g_input_file=fopen(g_input_filename, "r")) == NULL)
|
||||
perror_exit("can't open %s for input", g_input_filename);
|
||||
|
||||
|
@ -1318,18 +1281,6 @@ int main(int argc, char **argv)
|
|||
if((g_table_file = fopen(filename, "wt")) == NULL)
|
||||
perror_exit("Unable to create table file (%s)\n", filename);
|
||||
|
||||
sprintf(filename, "%s%s", output_path, FILENAME_OPS_AC);
|
||||
if((g_ops_ac_file = fopen(filename, "wt")) == NULL)
|
||||
perror_exit("Unable to create ops ac file (%s)\n", filename);
|
||||
|
||||
sprintf(filename, "%s%s", output_path, FILENAME_OPS_DM);
|
||||
if((g_ops_dm_file = fopen(filename, "wt")) == NULL)
|
||||
perror_exit("Unable to create ops dm file (%s)\n", filename);
|
||||
|
||||
sprintf(filename, "%s%s", output_path, FILENAME_OPS_NZ);
|
||||
if((g_ops_nz_file = fopen(filename, "wt")) == NULL)
|
||||
perror_exit("Unable to create ops nz file (%s)\n", filename);
|
||||
|
||||
if((g_input_file=fopen(g_input_filename, "rt")) == NULL)
|
||||
perror_exit("can't open %s for input", g_input_filename);
|
||||
|
||||
|
@ -1358,18 +1309,14 @@ int main(int argc, char **argv)
|
|||
{
|
||||
if(table_header_read)
|
||||
error_exit("Duplicate table header");
|
||||
read_insert(temp_insert);
|
||||
fprintf(g_table_file, "%s", temp_insert);
|
||||
read_insert(table_header_insert);
|
||||
table_header_read = 1;
|
||||
}
|
||||
else if(strcmp(section_id, ID_OPHANDLER_HEADER) == 0)
|
||||
{
|
||||
if(ophandler_header_read)
|
||||
error_exit("Duplicate opcode handler header");
|
||||
read_insert(temp_insert);
|
||||
fprintf(g_ops_ac_file, "%s\n\n", temp_insert);
|
||||
fprintf(g_ops_dm_file, "%s\n\n", temp_insert);
|
||||
fprintf(g_ops_nz_file, "%s\n\n", temp_insert);
|
||||
read_insert(ophandler_header_insert);
|
||||
ophandler_header_read = 1;
|
||||
}
|
||||
else if(strcmp(section_id, ID_PROTOTYPE_FOOTER) == 0)
|
||||
|
@ -1422,7 +1369,9 @@ int main(int argc, char **argv)
|
|||
if(ophandler_body_read)
|
||||
error_exit("Duplicate opcode handler section");
|
||||
|
||||
process_opcode_handlers();
|
||||
fprintf(g_table_file, "%s\n\n", ophandler_header_insert);
|
||||
process_opcode_handlers(g_table_file);
|
||||
fprintf(g_table_file, "%s\n\n", ophandler_footer_insert);
|
||||
|
||||
ophandler_body_read = 1;
|
||||
}
|
||||
|
@ -1446,13 +1395,11 @@ int main(int argc, char **argv)
|
|||
if(!ophandler_body_read)
|
||||
error_exit("Missing opcode handler body");
|
||||
|
||||
fprintf(g_table_file, "%s\n\n", table_header_insert);
|
||||
print_opcode_output_table(g_table_file);
|
||||
fprintf(g_table_file, "%s\n\n", table_footer_insert);
|
||||
|
||||
fprintf(g_prototype_file, "%s\n\n", prototype_footer_insert);
|
||||
fprintf(g_table_file, "%s\n\n", table_footer_insert);
|
||||
fprintf(g_ops_ac_file, "%s\n\n", ophandler_footer_insert);
|
||||
fprintf(g_ops_dm_file, "%s\n\n", ophandler_footer_insert);
|
||||
fprintf(g_ops_nz_file, "%s\n\n", ophandler_footer_insert);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1465,9 +1412,6 @@ int main(int argc, char **argv)
|
|||
/* Close all files and exit */
|
||||
fclose(g_prototype_file);
|
||||
fclose(g_table_file);
|
||||
fclose(g_ops_ac_file);
|
||||
fclose(g_ops_dm_file);
|
||||
fclose(g_ops_nz_file);
|
||||
fclose(g_input_file);
|
||||
|
||||
printf("Generated %d opcode handlers from %d primitives\n", g_num_functions, g_num_primitives);
|
||||
|
|
Loading…
Reference in New Issue