[wrap]
MAME source file: / src / emu / cpuintrf.h [download] (view on mamedev.org)
/***************************************************************************

    cpuintrf.h

    Core CPU interface functions and definitions.

    Copyright Nicola Salmoria and the MAME Team.
    Visit http://mamedev.org for licensing and usage restrictions.

***************************************************************************/

#pragma once

#ifndef __CPUINTRF_H__
#define __CPUINTRF_H__

#include "devintrf.h"
#include "memory.h"
#include "watchdog.h"
#include "state.h"


/***************************************************************************
    CONSTANTS
***************************************************************************/

#define MAX_CPU 8
#define MAX_INPUT_EVENTS		32


/* Interrupt line constants */
enum
{
	/* line states */
	CLEAR_LINE = 0,				/* clear (a fired, held or pulsed) line */
	ASSERT_LINE,				/* assert an interrupt immediately */
	HOLD_LINE,					/* hold interrupt line until acknowledged */
	PULSE_LINE,					/* pulse interrupt line for one instruction */

	/* input lines */
	MAX_INPUT_LINES = 32+3,
	INPUT_LINE_IRQ0 = 0,
	INPUT_LINE_IRQ1 = 1,
	INPUT_LINE_IRQ2 = 2,
	INPUT_LINE_IRQ3 = 3,
	INPUT_LINE_IRQ4 = 4,
	INPUT_LINE_IRQ5 = 5,
	INPUT_LINE_IRQ6 = 6,
	INPUT_LINE_IRQ7 = 7,
	INPUT_LINE_IRQ8 = 8,
	INPUT_LINE_IRQ9 = 9,
	INPUT_LINE_NMI = MAX_INPUT_LINES - 3,

	/* special input lines that are implemented in the core */
	INPUT_LINE_RESET = MAX_INPUT_LINES - 2,
	INPUT_LINE_HALT = MAX_INPUT_LINES - 1,

	/* output lines */
	MAX_OUTPUT_LINES = 32
};


/* Maximum number of registers of any CPU */
enum
{
	MAX_REGS = 256
};


/* CPU information constants */
enum
{
	/* --- the following bits of info are returned as 64-bit signed integers --- */
	CPUINFO_INT_FIRST = 0x00000,

	CPUINFO_INT_CONTEXT_SIZE = CPUINFO_INT_FIRST,		/* R/O: size of CPU context in bytes */
	CPUINFO_INT_INPUT_LINES,							/* R/O: number of input lines */
	CPUINFO_INT_OUTPUT_LINES,							/* R/O: number of output lines */
	CPUINFO_INT_DEFAULT_IRQ_VECTOR,						/* R/O: default IRQ vector */
	CPUINFO_INT_ENDIANNESS,								/* R/O: either CPU_IS_BE or CPU_IS_LE */
	CPUINFO_INT_CLOCK_MULTIPLIER,						/* R/O: internal clock multiplier */
	CPUINFO_INT_CLOCK_DIVIDER,							/* R/O: internal clock divider */
	CPUINFO_INT_MIN_INSTRUCTION_BYTES,					/* R/O: minimum bytes per instruction */
	CPUINFO_INT_MAX_INSTRUCTION_BYTES,					/* R/O: maximum bytes per instruction */
	CPUINFO_INT_MIN_CYCLES,								/* R/O: minimum cycles for a single instruction */
	CPUINFO_INT_MAX_CYCLES,								/* R/O: maximum cycles for a single instruction */

	CPUINFO_INT_DATABUS_WIDTH,							/* R/O: data bus size for each address space (8,16,32,64) */
	CPUINFO_INT_DATABUS_WIDTH_LAST = CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACES - 1,
	CPUINFO_INT_ADDRBUS_WIDTH,							/* R/O: address bus size for each address space (12-32) */
	CPUINFO_INT_ADDRBUS_WIDTH_LAST = CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACES - 1,
	CPUINFO_INT_ADDRBUS_SHIFT,							/* R/O: shift applied to addresses each address space (+3 means >>3, -1 means <<1) */
	CPUINFO_INT_ADDRBUS_SHIFT_LAST = CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACES - 1,
	CPUINFO_INT_LOGADDR_WIDTH,							/* R/O: address bus size for logical accesses in each space (0=same as physical) */
	CPUINFO_INT_LOGADDR_WIDTH_LAST = CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACES - 1,
	CPUINFO_INT_PAGE_SHIFT,								/* R/O: size of a page log 2 (i.e., 12=4096), or 0 if paging not supported */
	CPUINFO_INT_PAGE_SHIFT_LAST = CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACES - 1,

	CPUINFO_INT_SP,										/* R/W: the current stack pointer value */
	CPUINFO_INT_PC,										/* R/W: the current PC value */
	CPUINFO_INT_PREVIOUSPC,								/* R/W: the previous PC value */
	CPUINFO_INT_INPUT_STATE,							/* R/W: states for each input line */
	CPUINFO_INT_INPUT_STATE_LAST = CPUINFO_INT_INPUT_STATE + MAX_INPUT_LINES - 1,
	CPUINFO_INT_OUTPUT_STATE,							/* R/W: states for each output line */
	CPUINFO_INT_OUTPUT_STATE_LAST = CPUINFO_INT_OUTPUT_STATE + MAX_OUTPUT_LINES - 1,
	CPUINFO_INT_REGISTER,								/* R/W: values of up to MAX_REGs registers */
	CPUINFO_INT_REGISTER_LAST = CPUINFO_INT_REGISTER + MAX_REGS - 1,

	CPUINFO_INT_CPU_SPECIFIC = 0x08000,					/* R/W: CPU-specific values start here */

	/* --- the following bits of info are returned as pointers to data or functions --- */
	CPUINFO_PTR_FIRST = 0x10000,

	CPUINFO_PTR_SET_INFO = CPUINFO_PTR_FIRST,			/* R/O: void (*set_info)(UINT32 state, INT64 data, void *ptr) */
	CPUINFO_PTR_GET_CONTEXT,							/* R/O: void (*get_context)(void *buffer) */
	CPUINFO_PTR_SET_CONTEXT,							/* R/O: void (*set_context)(void *buffer) */
	CPUINFO_PTR_INIT,									/* R/O: void (*init)(int index, int clock, int (*irqcallback)(const device_config *device, int)) */
	CPUINFO_PTR_RESET,									/* R/O: void (*reset)(void) */
	CPUINFO_PTR_EXIT,									/* R/O: void (*exit)(void) */
	CPUINFO_PTR_EXECUTE,								/* R/O: int (*execute)(int cycles) */
	CPUINFO_PTR_BURN,									/* R/O: void (*burn)(int cycles) */
	CPUINFO_PTR_DISASSEMBLE,							/* R/O: offs_t (*disassemble)(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram) */
	CPUINFO_PTR_TRANSLATE,								/* R/O: int (*translate)(int space, int intention, offs_t *address) */
	CPUINFO_PTR_READ,									/* R/O: int (*read)(int space, UINT32 offset, int size, UINT64 *value) */
	CPUINFO_PTR_WRITE,									/* R/O: int (*write)(int space, UINT32 offset, int size, UINT64 value) */
	CPUINFO_PTR_READOP,									/* R/O: int (*readop)(UINT32 offset, int size, UINT64 *value) */
	CPUINFO_PTR_DEBUG_INIT,								/* R/O: void (*debug_init)(void) */
	CPUINFO_PTR_INSTRUCTION_COUNTER,					/* R/O: int *icount */
	CPUINFO_PTR_INTERNAL_MEMORY_MAP,					/* R/O: const addrmap_token *map */
	CPUINFO_PTR_INTERNAL_MEMORY_MAP_LAST = CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACES - 1,
	CPUINFO_PTR_DEBUG_REGISTER_LIST,					/* R/O: int *list: list of registers for the debugger */
	CPUINFO_PTR_VALIDITY_CHECK,							/* R/O: int (*validity_check)(const void *config) */

	CPUINFO_PTR_CPU_SPECIFIC = 0x18000,					/* R/W: CPU-specific values start here */

	/* --- the following bits of info are returned as NULL-terminated strings --- */
	CPUINFO_STR_FIRST = 0x20000,

	CPUINFO_STR_NAME = CPUINFO_STR_FIRST,				/* R/O: name of the CPU */
	CPUINFO_STR_CORE_FAMILY,							/* R/O: family of the CPU */
	CPUINFO_STR_CORE_VERSION,							/* R/O: version of the CPU core */
	CPUINFO_STR_CORE_FILE,								/* R/O: file containing the CPU core */
	CPUINFO_STR_CORE_CREDITS,							/* R/O: credits for the CPU core */
	CPUINFO_STR_FLAGS,									/* R/O: string representation of the main flags value */
	CPUINFO_STR_REGISTER,								/* R/O: string representation of up to MAX_REGs registers */
	CPUINFO_STR_REGISTER_LAST = CPUINFO_STR_REGISTER + MAX_REGS - 1,

	CPUINFO_STR_CPU_SPECIFIC = 0x28000					/* R/W: CPU-specific values start here */
};


/* get_reg/set_reg constants */
enum
{
	/* This value is passed to activecpu_get_reg to retrieve the previous
     * program counter value, ie. before a CPU emulation started
     * to fetch opcodes and arguments for the current instrution. */
	REG_PREVIOUSPC = CPUINFO_INT_PREVIOUSPC - CPUINFO_INT_REGISTER,

	/* This value is passed to activecpu_get_reg to retrieve the current
     * program counter value. */
	REG_PC = CPUINFO_INT_PC - CPUINFO_INT_REGISTER,

	/* This value is passed to activecpu_get_reg to retrieve the current
     * stack pointer value. */
	REG_SP = CPUINFO_INT_SP - CPUINFO_INT_REGISTER
};


/* Endianness constants */
enum
{
	CPU_IS_LE = 0,				/* emulated CPU is little endian */
	CPU_IS_BE					/* emulated CPU is big endian */
};


/* Translation intentions */
#define TRANSLATE_TYPE_MASK		0x03		/* read write or fetch */
#define TRANSLATE_USER_MASK		0x04		/* user mode or fully privileged */
#define TRANSLATE_DEBUG_MASK	0x08		/* debug mode (no side effects) */

#define TRANSLATE_READ			0			/* translate for read */
#define TRANSLATE_WRITE			1			/* translate for write */
#define TRANSLATE_FETCH			2			/* translate for instruction fetch */
#define TRANSLATE_READ_USER		(TRANSLATE_READ | TRANSLATE_USER_MASK)
#define TRANSLATE_WRITE_USER	(TRANSLATE_WRITE | TRANSLATE_USER_MASK)
#define TRANSLATE_FETCH_USER	(TRANSLATE_FETCH | TRANSLATE_USER_MASK)
#define TRANSLATE_READ_DEBUG	(TRANSLATE_READ | TRANSLATE_DEBUG_MASK)
#define TRANSLATE_WRITE_DEBUG	(TRANSLATE_WRITE | TRANSLATE_DEBUG_MASK)
#define TRANSLATE_FETCH_DEBUG	(TRANSLATE_FETCH | TRANSLATE_DEBUG_MASK)


/* Disassembler constants */
#define DASMFLAG_SUPPORTED		0x80000000	/* are disassembly flags supported? */
#define DASMFLAG_STEP_OUT		0x40000000	/* this instruction should be the end of a step out sequence */
#define DASMFLAG_STEP_OVER		0x20000000	/* this instruction should be stepped over by setting a breakpoint afterwards */
#define DASMFLAG_OVERINSTMASK	0x18000000	/* number of extra instructions to skip when stepping over */
#define DASMFLAG_OVERINSTSHIFT	27			/* bits to shift after masking to get the value */
#define DASMFLAG_LENGTHMASK 	0x0000ffff	/* the low 16-bits contain the actual length */
#define DASMFLAG_STEP_OVER_EXTRA(x)			((x) << DASMFLAG_OVERINSTSHIFT)


/* list of all possible CPUs we might be compiled with */
enum _cpu_type
{
	CPU_DUMMY,
	CPU_Z80,
	CPU_Z180,
	CPU_8080,
	CPU_8085A,
	CPU_M6502,
	CPU_M65C02,
	CPU_M65SC02,
	CPU_M65CE02,
	CPU_M6509,
	CPU_M6510,
	CPU_M6510T,
	CPU_M7501,
	CPU_M8502,
	CPU_N2A03,
	CPU_DECO16,
	CPU_M4510,
	CPU_H6280,
	CPU_I8086,
	CPU_I8088,
	CPU_I80186,
	CPU_I80188,
	CPU_I80286,
	CPU_V20,
	CPU_V25,
	CPU_V30,
	CPU_V33,
	CPU_V35,
	CPU_V60,
	CPU_V70,
	CPU_I8035,
	CPU_I8048,
	CPU_I8648,
	CPU_I8748,
	CPU_MB8884,
	CPU_N7751,
	CPU_I8039,
	CPU_I8049,
	CPU_I8749,
	CPU_M58715,
	CPU_I8041,
	CPU_I8741,
	CPU_I8042,
	CPU_I8242,
	CPU_I8742,
	CPU_I8031,
	CPU_I8032,
	CPU_I8051,
	CPU_I8052,
	CPU_I8751,
	CPU_I8752,
	CPU_I80C31,
	CPU_I80C32,
	CPU_I80C51,
	CPU_I80C52,
	CPU_I87C51,
	CPU_I87C52,
	CPU_AT89C4051,
	CPU_DS5002FP,
	CPU_M6800,
	CPU_M6801,
	CPU_M6802,
	CPU_M6803,
	CPU_M6808,
	CPU_HD63701,
	CPU_NSC8105,
	CPU_M6805,
	CPU_M68705,
	CPU_HD63705,
	CPU_HD6309,
	CPU_M6809,
	CPU_M6809E,
	CPU_KONAMI,
	CPU_M68000,
	CPU_M68008,
	CPU_M68010,
	CPU_M68EC020,
	CPU_M68020,
	CPU_M68040,
	CPU_T11,
	CPU_S2650,
	CPU_TMS34010,
	CPU_TMS34020,
	CPU_TI990_10,
	CPU_TMS9900,
	CPU_TMS9980,
	CPU_TMS9995,
	CPU_Z8000,
	CPU_TMS32010,
	CPU_TMS32025,
	CPU_TMS32026,
	CPU_TMS32031,
	CPU_TMS32032,
	CPU_TMS32051,
	CPU_CCPU,
	CPU_ADSP2100,
 	CPU_ADSP2101,
	CPU_ADSP2104,
	CPU_ADSP2105,
	CPU_ADSP2115,
	CPU_ADSP2181,
	CPU_PSXCPU,
	CPU_ASAP,
	CPU_UPD7810,
	CPU_UPD7807,
	CPU_UPD7801,
	CPU_UPD78C05,
	CPU_UPD78C06,
	CPU_JAGUARGPU,
	CPU_JAGUARDSP,
	CPU_CQUESTSND,
	CPU_CQUESTROT,
	CPU_CQUESTLIN,
	CPU_R3000BE,
	CPU_R3000LE,
	CPU_R3041BE,
	CPU_R3041LE,
	CPU_R4600BE,
	CPU_R4600LE,
	CPU_R4650BE,
	CPU_R4650LE,
	CPU_R4700BE,
	CPU_R4700LE,
	CPU_R5000BE,
	CPU_R5000LE,
	CPU_QED5271BE,
	CPU_QED5271LE,
	CPU_RM7000BE,
	CPU_RM7000LE,
	CPU_ARM,
	CPU_ARM7,
	CPU_SH1,
	CPU_SH2,
	CPU_SH4,
	CPU_DSP32C,
	CPU_PIC16C54,
	CPU_PIC16C55,
	CPU_PIC16C56,
	CPU_PIC16C57,
	CPU_PIC16C58,
	CPU_G65816,
	CPU_SPC700,
	CPU_E116T,
	CPU_E116XT,
	CPU_E116XS,
	CPU_E116XSR,
	CPU_E132N,
	CPU_E132T,
	CPU_E132XN,
	CPU_E132XT,
	CPU_E132XS,
	CPU_E132XSR,
	CPU_GMS30C2116,
	CPU_GMS30C2132,
	CPU_GMS30C2216,
	CPU_GMS30C2232,
	CPU_I386,
	CPU_I486,
	CPU_PENTIUM,
	CPU_MEDIAGX,
	CPU_I960,
	CPU_H83002,
	CPU_H83007,
	CPU_H83044,
	CPU_H83334,
	CPU_V810,
	CPU_M37702,
	CPU_M37710,
	CPU_PPC403GA,
	CPU_PPC403GCX,
	CPU_PPC601,
	CPU_PPC602,
	CPU_PPC603,
	CPU_PPC603E,
	CPU_PPC603R,
	CPU_PPC604,
	CPU_MPC8240,
	CPU_SE3208,
	CPU_MC68HC11,
	CPU_ADSP21062,
	CPU_DSP56156,
	CPU_RSP,
	CPU_ALPHA8201,
	CPU_ALPHA8301,
	CPU_CDP1802,
	CPU_COP401,
	CPU_COP410,
	CPU_COP411,
	CPU_COP402,
	CPU_COP420,
	CPU_COP421,
	CPU_COP422,
	CPU_COP404,
	CPU_COP424,
	CPU_COP425,
	CPU_COP426,
	CPU_COP444,
	CPU_COP445,
	CPU_TMP90840,
	CPU_TMP90841,
	CPU_TMP91640,
	CPU_TMP91641,
	CPU_APEXC,
	CPU_CP1610,
	CPU_F8,
	CPU_LH5801,
	CPU_PDP1,
	CPU_SATURN,
	CPU_SC61860,
	CPU_TX0_64KW,
	CPU_TX0_8KW,
	CPU_LR35902,
	CPU_TMS7000,
	CPU_TMS7000_EXL,
	CPU_SM8500,
	CPU_V30MZ,
	CPU_MB8841,
	CPU_MB8842,
	CPU_MB8843,
	CPU_MB8844,
	CPU_MB86233,
	CPU_SSP1601,
	CPU_MINX,
	CPU_CXD8661R,
    CPU_COUNT
};
typedef enum _cpu_type cpu_type;



/***************************************************************************
    MACROS
***************************************************************************/

#define IRQ_CALLBACK(func)			int func(const device_config *device, int irqline)

#define CPU_GET_INFO_NAME(name)		cpu_get_info_##name
#define CPU_GET_INFO(name)			void CPU_GET_INFO_NAME(name)(const device_config *device, UINT32 state, cpuinfo *info)
#define CPU_GET_INFO_CALL(name)		CPU_GET_INFO_NAME(name)(device, state, info)

#define CPU_SET_INFO_NAME(name)		cpu_set_info_##name
#define CPU_SET_INFO(name)			void CPU_SET_INFO_NAME(name)(const device_config *device, UINT32 state, cpuinfo *info)
#define CPU_SET_INFO_CALL(name)		CPU_SET_INFO_NAME(name)(device, state, info)

#define CPU_INIT_NAME(name)			cpu_init_##name
#define CPU_INIT(name)				void CPU_INIT_NAME(name)(const device_config *device, int index, int clock, cpu_irq_callback irqcallback)
#define CPU_INIT_CALL(name)			CPU_INIT_NAME(name)(device, index, clock, irqcallback)

#define CPU_RESET_NAME(name)		cpu_reset_##name
#define CPU_RESET(name)				void CPU_RESET_NAME(name)(const device_config *device)
#define CPU_RESET_CALL(name)		CPU_RESET_NAME(name)(device)

#define CPU_EXIT_NAME(name)			cpu_exit_##name
#define CPU_EXIT(name)				void CPU_EXIT_NAME(name)(const device_config *device)
#define CPU_EXIT_CALL(name)			CPU_EXIT_NAME(name)(device)

#define CPU_EXECUTE_NAME(name)		cpu_execute_##name
#define CPU_EXECUTE(name)			int CPU_EXECUTE_NAME(name)(const device_config *device, int cycles)
#define CPU_EXECUTE_CALL(name)		CPU_EXECUTE_NAME(name)(device, cycles)

#define CPU_BURN_NAME(name)			cpu_burn_##name
#define CPU_BURN(name)				void CPU_BURN_NAME(name)(const device_config *device, int cycles)
#define CPU_BURN_CALL(name)			CPU_BURN_NAME(name)(device, cycles)

#define CPU_TRANSLATE_NAME(name)	cpu_translate_##name
#define CPU_TRANSLATE(name)			int CPU_TRANSLATE_NAME(name)(const device_config *device, int space, int intention, offs_t *address)
#define CPU_TRANSLATE_CALL(name)	CPU_TRANSLATE_NAME(name)(device, space, intention, address)

#define CPU_READ_NAME(name)			cpu_read_##name
#define CPU_READ(name)				int CPU_READ_NAME(name)(const device_config *device, int space, UINT32 offset, int size, UINT64 *value)
#define CPU_READ_CALL(name)			CPU_READ_NAME(name)(device, space, offset, size, value)

#define CPU_WRITE_NAME(name)		cpu_write_##name
#define CPU_WRITE(name)				int CPU_WRITE_NAME(name)(const device_config *device, int space, UINT32 offset, int size, UINT64 value)
#define CPU_WRITE_CALL(name)		CPU_WRITE_NAME(name)(device, space, offset, size, value)

#define CPU_READOP_NAME(name)		cpu_readop_##name
#define CPU_READOP(name)			int CPU_READOP_NAME(name)(const device_config *device, UINT32 offset, int size, UINT64 *value)
#define CPU_READOP_CALL(name)		CPU_READOP_NAME(name)(device, offset, size, value)

#define CPU_DEBUG_INIT_NAME(name) 	cpu_debug_init_##name
#define CPU_DEBUG_INIT(name)		void CPU_DEBUG_INIT_NAME(name)(const device_config *device)
#define CPU_DEBUG_INIT_CALL(name)	CPU_DEBUG_INIT_NAME(name)(device)

#define CPU_DISASSEMBLE_NAME(name)	cpu_disassemble_##name
#define CPU_DISASSEMBLE(name)		offs_t CPU_DISASSEMBLE_NAME(name)(const device_config *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
#define CPU_DISASSEMBLE_CALL(name)	CPU_DISASSEMBLE_NAME(name)(device, buffer, pc, oprom, opram)

#define CPU_VALIDITY_CHECK_NAME(name)	cpu_validity_check_##name
#define CPU_VALIDITY_CHECK(name)		int CPU_VALIDITY_CHECK_NAME(name)(const game_driver *driver, const void *config)
#define CPU_VALIDITY_CHECK_CALL(name)	CPU_VALIDITY_CHECK_NAME(name)(driver, config)

#define CPU_GET_CONTEXT_NAME(name)	cpu_get_context_##name
#define CPU_GET_CONTEXT(name)		void CPU_GET_CONTEXT_NAME(name)(void *dst)
#define CPU_GET_CONTEXT_CALL(name)	CPU_GET_CONTEXT_NAME(name)(buffer)

#define CPU_SET_CONTEXT_NAME(name)	cpu_set_context_##name
#define CPU_SET_CONTEXT(name)		void CPU_SET_CONTEXT_NAME(name)(void *src)
#define CPU_SET_CONTEXT_CALL(name)	CPU_SET_CONTEXT_NAME(name)(buffer)


/* helpers for accessing common CPU state */
#define cpu_get_context_size(cpu)			cpu_get_info_int(cpu, CPUINFO_INT_CONTEXT_SIZE)
#define cpu_get_input_lines(cpu)			cpu_get_info_int(cpu, CPUINFO_INT_INPUT_LINES)
#define cpu_get_output_lines(cpu)			cpu_get_info_int(cpu, CPUINFO_INT_OUTPUT_LINES)
#define cpu_get_default_irq_vector(cpu)		cpu_get_info_int(cpu, CPUINFO_INT_DEFAULT_IRQ_VECTOR)
#define cpu_get_endianness(cpu)				cpu_get_info_int(cpu, CPUINFO_INT_ENDIANNESS)
#define cpu_get_clock_multiplier(cpu)		cpu_get_info_int(cpu, CPUINFO_INT_CLOCK_MULTIPLIER)
#define cpu_get_clock_divider(cpu)			cpu_get_info_int(cpu, CPUINFO_INT_CLOCK_DIVIDER)
#define cpu_get_min_opcode_bytes(cpu)		cpu_get_info_int(cpu, CPUINFO_INT_MIN_INSTRUCTION_BYTES)
#define cpu_get_max_opcode_bytes(cpu)		cpu_get_info_int(cpu, CPUINFO_INT_MAX_INSTRUCTION_BYTES)
#define cpu_get_min_cycles(cpu)				cpu_get_info_int(cpu, CPUINFO_INT_MIN_CYCLES)
#define cpu_get_max_cycles(cpu)				cpu_get_info_int(cpu, CPUINFO_INT_MAX_CYCLES)
#define cpu_get_databus_width(cpu, space)	cpu_get_info_int(cpu, CPUINFO_INT_DATABUS_WIDTH + (space))
#define cpu_get_addrbus_width(cpu, space)	cpu_get_info_int(cpu, CPUINFO_INT_ADDRBUS_WIDTH + (space))
#define cpu_get_addrbus_shift(cpu, space)	cpu_get_info_int(cpu, CPUINFO_INT_ADDRBUS_SHIFT + (space))
#define cpu_get_logaddr_width(cpu, space)	cpu_get_info_int(cpu, CPUINFO_INT_LOGADDR_WIDTH + (space))
#define cpu_get_page_shift(cpu, space)		cpu_get_info_int(cpu, CPUINFO_INT_PAGE_SHIFT + (space))
#define cpu_get_reg(cpu, reg)				cpu_get_info_int(cpu, CPUINFO_INT_REGISTER + (reg))
#define	cpu_get_previouspc(cpu)				((offs_t)cpu_get_reg(cpu, REG_PREVIOUSPC))
#define	cpu_get_pc(cpu)						((offs_t)cpu_get_reg(cpu, REG_PC))
#define	cpu_get_sp(cpu)						cpu_get_reg(cpu, REG_SP)
#define cpu_get_icount_ptr(cpu)				(int *)cpu_get_info_ptr(cpu, CPUINFO_PTR_INSTRUCTION_COUNTER)
#define cpu_get_debug_register_list(cpu)	cpu_get_info_ptr(cpu, CPUINFO_PTR_DEBUG_REGISTER_LIST)
#define cpu_get_name(cpu)					cpu_get_info_string(cpu, CPUINFO_STR_NAME)
#define cpu_get_core_family(cpu)			cpu_get_info_string(cpu, CPUINFO_STR_CORE_FAMILY)
#define cpu_get_core_version(cpu)			cpu_get_info_string(cpu, CPUINFO_STR_CORE_VERSION)
#define cpu_get_core_file(cpu)				cpu_get_info_string(cpu, CPUINFO_STR_CORE_FILE)
#define cpu_get_core_credits(cpu)			cpu_get_info_string(cpu, CPUINFO_STR_CORE_CREDITS)
#define cpu_get_flags_string(cpu)			cpu_get_info_string(cpu, CPUINFO_STR_FLAGS)
#define cpu_get_irq_string(cpu, irq)		cpu_get_info_string(cpu, CPUINFO_STR_IRQ_STATE + (irq))
#define cpu_get_reg_string(cpu, reg)		cpu_get_info_string(cpu, CPUINFO_STR_REGISTER + (reg))
#define cpu_set_reg(cpu, reg, val)			cpu_set_info_int(cpu, CPUINFO_INT_REGISTER + (reg), (val))


/* helpers for accessing common CPU type state */
#define cputype_get_context_size(cputype)			cputype_get_info_int(cputype, CPUINFO_INT_CONTEXT_SIZE)
#define cputype_get_input_lines(cputype)			cputype_get_info_int(cputype, CPUINFO_INT_INPUT_LINES)
#define cputype_get_output_lines(cputype)			cputype_get_info_int(cputype, CPUINFO_INT_OUTPUT_LINES)
#define cputype_get_default_irq_vector(cputype)		cputype_get_info_int(cputype, CPUINFO_INT_DEFAULT_IRQ_VECTOR)
#define cputype_get_endianness(cputype)				cputype_get_info_int(cputype, CPUINFO_INT_ENDIANNESS)
#define cputype_get_clock_multiplier(cputype)		cputype_get_info_int(cputype, CPUINFO_INT_CLOCK_MULTIPLIER)
#define cputype_get_clock_divider(cputype)			cputype_get_info_int(cputype, CPUINFO_INT_CLOCK_DIVIDER)
#define cputype_get_min_instruction_bytes(cputype)	cputype_get_info_int(cputype, CPUINFO_INT_MIN_INSTRUCTION_BYTES)
#define cputype_get_max_instruction_bytes(cputype)	cputype_get_info_int(cputype, CPUINFO_INT_MAX_INSTRUCTION_BYTES)
#define cputype_get_min_cycles(cputype)				cputype_get_info_int(cputype, CPUINFO_INT_MIN_CYCLES)
#define cputype_get_max_cycles(cputype)				cputype_get_info_int(cputype, CPUINFO_INT_MAX_CYCLES)
#define cputype_get_databus_width(cputype, space)	cputype_get_info_int(cputype, CPUINFO_INT_DATABUS_WIDTH + (space))
#define cputype_get_addrbus_width(cputype, space)	cputype_get_info_int(cputype, CPUINFO_INT_ADDRBUS_WIDTH + (space))
#define cputype_get_addrbus_shift(cputype, space)	cputype_get_info_int(cputype, CPUINFO_INT_ADDRBUS_SHIFT + (space))
#define cputype_get_page_shift(cputype, space)		cputype_get_info_int(cputype, CPUINFO_INT_PAGE_SHIFT + (space))
#define cputype_get_debug_register_list(cputype)	cputype_get_info_ptr(cputype, CPUINFO_PTR_DEBUG_REGISTER_LIST)
#define cputype_get_name(cputype)					cputype_get_info_string(cputype, CPUINFO_STR_NAME)
#define cputype_get_core_family(cputype)			cputype_get_info_string(cputype, CPUINFO_STR_CORE_FAMILY)
#define cputype_get_core_version(cputype)			cputype_get_info_string(cputype, CPUINFO_STR_CORE_VERSION)
#define cputype_get_core_file(cputype)				cputype_get_info_string(cputype, CPUINFO_STR_CORE_FILE)
#define cputype_get_core_credits(cputype)			cputype_get_info_string(cputype, CPUINFO_STR_CORE_CREDITS)


/* helpers for using machine/cputag instead of cpu objects */
#define cputag_reset(mach, tag)						cpu_reset(cputag_get_cpu(mach, tag))
#define cputag_get_index(mach, tag)					cpu_get_index(cputag_get_cpu(mach, tag))
#define cputag_get_address_space(mach, tag, space)	cpu_get_address_space(cputag_get_cpu(mach, tag), space)



/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

/* opaque definition of CPU debugging info */
typedef struct _cpu_debug_data cpu_debug_data;


/* forward declaration of this union */
typedef union _cpuinfo cpuinfo;


/* define the various callback functions */
typedef int (*cpu_irq_callback)(const device_config *device, int irqnum);

typedef void (*cpu_get_info_func)(const device_config *device, UINT32 state, cpuinfo *info);
typedef void (*cpu_set_info_func)(const device_config *device, UINT32 state, cpuinfo *info);
typedef void (*cpu_init_func)(const device_config *device, int index, int clock, cpu_irq_callback irqcallback);
typedef void (*cpu_reset_func)(const device_config *device);
typedef void (*cpu_exit_func)(const device_config *device);
typedef int	(*cpu_execute_func)(const device_config *device, int cycles);
typedef void (*cpu_burn_func)(const device_config *device, int cycles);
typedef int	(*cpu_translate_func)(const device_config *device, int space, int intention, offs_t *address);
typedef int	(*cpu_read_func)(const device_config *device, int space, UINT32 offset, int size, UINT64 *value);
typedef int	(*cpu_write_func)(const device_config *device, int space, UINT32 offset, int size, UINT64 value);
typedef int	(*cpu_readop_func)(const device_config *device, UINT32 offset, int size, UINT64 *value);
typedef void (*cpu_debug_init_func)(const device_config *device);
typedef offs_t (*cpu_disassemble_func)(const device_config *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);

typedef int (*cpu_validity_check_func)(const game_driver *driver, const void *config);
typedef void (*cpu_get_context_func)(void *buffer);
typedef void (*cpu_set_context_func)(void *buffer);


/* cpuinfo union used to pass data to/from the get_info/set_info functions */
union _cpuinfo
{
	INT64					i;							/* generic integers */
	void *					p;							/* generic pointers */
	genf *  				f;							/* generic function pointers */
	char *					s;							/* generic strings */

	cpu_set_info_func		setinfo;					/* CPUINFO_PTR_SET_INFO */
	cpu_get_context_func	getcontext;					/* CPUINFO_PTR_GET_CONTEXT */
	cpu_set_context_func	setcontext;					/* CPUINFO_PTR_SET_CONTEXT */
	cpu_init_func			init;						/* CPUINFO_PTR_INIT */
	cpu_reset_func			reset;						/* CPUINFO_PTR_RESET */
	cpu_exit_func			exit;						/* CPUINFO_PTR_EXIT */
	cpu_execute_func		execute;					/* CPUINFO_PTR_EXECUTE */
	cpu_burn_func			burn;						/* CPUINFO_PTR_BURN */
	cpu_translate_func		translate;					/* CPUINFO_PTR_TRANSLATE */
	cpu_read_func			read;						/* CPUINFO_PTR_READ */
	cpu_write_func			write;						/* CPUINFO_PTR_WRITE */
	cpu_readop_func			readop;						/* CPUINFO_PTR_READOP */
	cpu_debug_init_func		debug_init;					/* CPUINFO_PTR_DEBUG_INIT */
	cpu_disassemble_func	disassemble;				/* CPUINFO_PTR_DISASSEMBLE */
	cpu_validity_check_func	validity_check;				/* CPUINFO_PTR_VALIDITY_CHECK */
	int *					icount;						/* CPUINFO_PTR_INSTRUCTION_COUNTER */
	const addrmap8_token *	internal_map8;				/* CPUINFO_PTR_INTERNAL_MEMORY_MAP */
	const addrmap16_token *	internal_map16;				/* CPUINFO_PTR_INTERNAL_MEMORY_MAP */
	const addrmap32_token *	internal_map32;				/* CPUINFO_PTR_INTERNAL_MEMORY_MAP */
	const addrmap64_token *	internal_map64;				/* CPUINFO_PTR_INTERNAL_MEMORY_MAP */
};


/* partial data hanging off of the classtoken */
typedef struct _cpu_class_header cpu_class_header;
struct _cpu_class_header
{
	int						index;					/* index of this CPU */
	cpu_type				cputype; 				/* type index of this CPU */
	cpu_debug_data *		debug;					/* debugging data */
	const address_space *	space[ADDRESS_SPACES];	/* address spaces */

	/* table of core functions */
	cpu_get_info_func		get_info;
	cpu_set_info_func		set_info;
	cpu_get_context_func	get_context;
	cpu_set_context_func	set_context;
	cpu_init_func			init;
	cpu_reset_func			reset;
	cpu_exit_func			exit;
	cpu_execute_func		execute;
	cpu_burn_func			burn;
	cpu_translate_func		translate;
	cpu_disassemble_func	disassemble;
	cpu_disassemble_func 	dasm_override;

	/* other frequently-needed information */
	INT8					address_shift[ADDRESS_SPACES];
	UINT32					clock_divider;
	UINT32					clock_multiplier;
};



/***************************************************************************
    FUNCTION PROTOTYPES
***************************************************************************/


/* ----- global management ----- */

/* reset the internal CPU tracking */
void cpuintrf_init(running_machine *machine);

/* circular string buffer */
char *cpuintrf_temp_str(void);



/* ----- live context control ----- */

/* remember the current context and push a new one on the stack */
void cpu_push_context(const device_config *cpu);

/* restore the previously saved context */
void cpu_pop_context(void);

/* return the index of the active CPU (deprecated soon) */
int cpunum_get_active(void);

/* find a CPU in the machine by searching */
int cpu_get_index_slow(const device_config *cpu);



/* ----- live CPU accessors ----- */

/* initialize a live CPU */
void cpu_init(const device_config *cpu, int index, int clock, cpu_irq_callback irqcallback);

/* free a live CPU */
void cpu_exit(const device_config *cpu);

/* return information about a live CPU */
INT64 cpu_get_info_int(const device_config *cpu, UINT32 state);
void *cpu_get_info_ptr(const device_config *cpu, UINT32 state);
genf *cpu_get_info_fct(const device_config *cpu, UINT32 state);
const char *cpu_get_info_string(const device_config *cpu, UINT32 state);

/* set information about a live CPU */
void cpu_set_info_int(const device_config *cpu, UINT32 state, INT64 data);
void cpu_set_info_ptr(const device_config *cpu, UINT32 state, void *data);
void cpu_set_info_fct(const device_config *cpu, UINT32 state, genf *data);

/* execute the requested cycles on a given CPU */
int cpu_execute(const device_config *cpu, int cycles);

/* signal a reset for a given CPU */
void cpu_reset(const device_config *cpu);

/* return the PC, corrected to a byte offset and translated to physical space, on a given CPU */
offs_t cpu_get_physical_pc_byte(const device_config *cpu);

/* disassemble a line at a given PC on a given CPU */
offs_t cpu_dasm(const device_config *cpu, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);

/* set a dasm override handler */
void cpu_set_dasm_override(const device_config *cpu, cpu_disassemble_func dasm_override);



/* ----- CPU type accessors ----- */

/* return a header template for a given CPU type */
const cpu_class_header *cputype_get_header_template(cpu_type cputype);

/* return information about a given CPU type */
INT64 cputype_get_info_int(cpu_type cputype, UINT32 state);
void *cputype_get_info_ptr(cpu_type cputype, UINT32 state);
genf *cputype_get_info_fct(cpu_type cputype, UINT32 state);
const char *cputype_get_info_string(cpu_type cputype, UINT32 state);




/***************************************************************************
    INLINE FUNCTIONS
***************************************************************************/

/*-------------------------------------------------
    safe_cpu_get_pc - return the current PC or ~0
    if the CPU is invalid
-------------------------------------------------*/

INLINE offs_t safe_cpu_get_pc(const device_config *cpu)
{
	return (cpu != NULL) ? cpu_get_pc(cpu) : ~0;
}


/*-------------------------------------------------
    cpu_get_index - return the index of the
    specified CPU (deprecated soon)
-------------------------------------------------*/

INLINE int cpu_get_index(const device_config *cpu)
{
	cpu_class_header *classheader = cpu->classtoken;
	return (classheader != NULL) ? classheader->index : cpu_get_index_slow(cpu);
}


/*-------------------------------------------------
    cpu_get_debug_data - return a pointer to
    the given CPU's debugger data
-------------------------------------------------*/

INLINE cpu_debug_data *cpu_get_debug_data(const device_config *cpu)
{
	cpu_class_header *classheader = cpu->classtoken;
	return classheader->debug;
}


/*-------------------------------------------------
    cpu_get_address_space - return a pointer to
    the given CPU's address space
-------------------------------------------------*/

INLINE const address_space *cpu_get_address_space(const device_config *cpu, int spacenum)
{
	cpu_class_header *classheader = cpu->classtoken;
	return classheader->space[spacenum];
}


/*-------------------------------------------------
    cpu_address_to_byte - convert an address in
    the specified address space to a byte offset
-------------------------------------------------*/

INLINE offs_t cpu_address_to_byte(const device_config *cpu, int space, offs_t address)
{
	cpu_class_header *classheader = cpu->classtoken;
	int shift = classheader->address_shift[space];
	return (shift < 0) ? (address << -shift) : (address >> shift);
}


/*-------------------------------------------------
    cpu_address_to_byte_end - convert an address
    in the specified address space to a byte
    offset specifying the last byte covered by
    the address
-------------------------------------------------*/

INLINE offs_t cpu_address_to_byte_end(const device_config *cpu, int space, offs_t address)
{
	cpu_class_header *classheader = cpu->classtoken;
	int shift = classheader->address_shift[space];
	return (shift < 0) ? ((address << -shift) | ((1 << -shift) - 1)) : (address >> shift);
}


/*-------------------------------------------------
    cpu_byte_to_address - convert a byte offset
    to an address in the specified address space
-------------------------------------------------*/

INLINE offs_t cpu_byte_to_address(const device_config *cpu, int space, offs_t address)
{
	cpu_class_header *classheader = cpu->classtoken;
	int shift = classheader->address_shift[space];
	return (shift < 0) ? (address >> -shift) : (address << shift);
}


/*-------------------------------------------------
    cpu_byte_to_address_end - convert a byte offset
    to an address in the specified address space
    specifying the last address covered by the
    byte
-------------------------------------------------*/

INLINE offs_t cpu_byte_to_address_end(const device_config *cpu, int space, offs_t address)
{
	cpu_class_header *classheader = cpu->classtoken;
	int shift = classheader->address_shift[space];
	return (shift < 0) ? (address >> -shift) : ((address << shift) | ((1 << shift) - 1));
}


/*-------------------------------------------------
    cpu_address_physical - return the physical
    address corresponding to the given logical
    address
-------------------------------------------------*/

INLINE offs_t cpu_address_physical(const device_config *cpu, int space, int intention, offs_t address)
{
	cpu_class_header *classheader = cpu->classtoken;
	if (classheader->translate != NULL)
		(*classheader->translate)(cpu, space, intention, &address);
	return address;
}

#endif	/* __CPUINTRF_H__ */
  
2004-2008 MAWS all copyrights belong to their respective owners