#ifndef M68K__HEADER
#define M68K__HEADER
#include "macros.h"
namespace m68k {
#if UINT_MAX > 0xffffffff
#define M68K_INT_GT_32_BIT 1
#else
#define M68K_INT_GT_32_BIT 0
#endif
#undef sint8
#undef sint16
#undef sint32
#undef sint64
#undef uint8
#undef uint16
#undef uint32
#undef uint64
#undef sint
#undef uint
#define sint8 signed char
#define sint16 signed short
#define sint32 signed int
#define uint8 unsigned char
#define uint16 unsigned short
#define uint32 unsigned int
#define sint signed int
#define uint unsigned int
#if M68K_USE_64_BIT
#define sint64 signed long long
#define uint64 unsigned long long
#else
#define sint64 sint32
#define uint64 uint32
#endif
#define MAKE_INT_8(A) (sint8)(A)
#define MAKE_INT_16(A) (sint16)(A)
#define MAKE_INT_32(A) (sint32)(A)
#define M68K_IRQ_NONE 0
#define M68K_IRQ_1 1
#define M68K_IRQ_2 2
#define M68K_IRQ_3 3
#define M68K_IRQ_4 4
#define M68K_IRQ_5 5
#define M68K_IRQ_6 6
#define M68K_IRQ_7 7
#define M68K_INT_ACK_AUTOVECTOR 0xffffffff
#define M68K_INT_ACK_SPURIOUS 0xfffffffe
typedef enum
{
M68K_REG_D0,
M68K_REG_D1,
M68K_REG_D2,
M68K_REG_D3,
M68K_REG_D4,
M68K_REG_D5,
M68K_REG_D6,
M68K_REG_D7,
M68K_REG_A0,
M68K_REG_A1,
M68K_REG_A2,
M68K_REG_A3,
M68K_REG_A4,
M68K_REG_A5,
M68K_REG_A6,
M68K_REG_A7,
M68K_REG_PC,
M68K_REG_SR,
M68K_REG_SP,
M68K_REG_USP,
M68K_REG_ISP,
#if M68K_EMULATE_PREFETCH
M68K_REG_PREF_ADDR,
M68K_REG_PREF_DATA,
#endif
M68K_REG_IR
} m68k_register_t;
typedef struct
{
void *param;
unsigned char *base;
unsigned int (*read8)(void *param, unsigned int address);
unsigned int (*read16)(void *param, unsigned int address);
void (*write8)(void *param, unsigned int address, unsigned int data);
void (*write16)(void *param, unsigned int address, unsigned int data);
} cpu_memory_map;
typedef struct
{
uint pc;
uint cycle;
uint detected;
} cpu_idle_t;
typedef struct _m68ki_cpu_core
{
cpu_memory_map memory_map[256];
cpu_idle_t poll;
uint irq_latency;
uint dar[16];
uint ppc;
uint pc;
uint sp[7];
uint vbr;
uint sfc;
uint dfc;
uint cacr;
uint caar;
uint ir;
uint t1_flag;
uint t0_flag;
uint s_flag;
uint m_flag;
uint x_flag;
uint n_flag;
uint not_z_flag;
uint v_flag;
uint c_flag;
uint int_mask;
uint int_level;
uint stopped;
#if M68K_EMULATE_PREFETCH
uint pref_addr;
uint pref_data;
#endif
uint sr_mask;
#if M68K_EMULATE_ADDRESS_ERROR
uint instr_mode;
uint run_mode;
uint aerr_enabled;
jmp_buf aerr_trap;
uint aerr_address;
uint aerr_write_mode;
uint aerr_fc;
#endif
#if M68K_EMULATE_TRACE
uint tracing;
#endif
#if M68K_EMULATE_FC
uint address_space;
#endif
uint cyc_bcc_notake_b;
uint cyc_bcc_notake_w;
uint cyc_dbcc_f_noexp;
uint cyc_dbcc_f_exp;
uint cyc_scc_r_true;
uint cyc_movem_w;
uint cyc_movem_l;
uint cyc_shift;
uint cyc_reset;
int initial_cycles;
int remaining_cycles;
int reset_cycles;
void *param;
uint virq_state;
uint nmi_pending;
const unsigned char* cyc_instruction;
const unsigned char* cyc_exception;
#if M68K_EMULATE_INT_ACK
int (*int_ack_callback)(m68ki_cpu_core *cpu, int int_line);
#endif
#if M68K_EMULATE_RESET
void (*reset_instr_callback)(m68ki_cpu_core *cpu);
#endif
#if M68K_TAS_HAS_CALLBACK
int (*tas_instr_callback)(m68ki_cpu_core *cpu);
#endif
#if M68K_EMULATE_FC
void (*set_fc_callback)(m68ki_cpu_core *cpu, unsigned int new_fc);
#endif
} m68ki_cpu_core;
#if M68K_EMULATE_INT_ACK == OPT_ON
void m68k_set_int_ack_callback(int (*callback)(void *param, int int_level));
#endif
#if M68K_EMULATE_RESET == OPT_ON
void m68k_set_reset_instr_callback(void (*callback)(void *param));
#endif
#if M68K_TAS_HAS_CALLBACK == OPT_ON
void m68k_set_tas_instr_callback(int (*callback)(void *param));
#endif
#if M68K_EMULATE_FC == OPT_ON
void m68k_set_fc_callback(void (*callback)(m68ki_cpu_core *cpu, unsigned int new_fc));
#endif
extern void m68k_init(m68ki_cpu_core *);
extern void m68k_pulse_reset(m68ki_cpu_core *);
extern int m68k_execute(m68ki_cpu_core *, unsigned int cycles);
#define ASSERT_LINE 1
#define RESET_LINE 0
void m68k_set_irq(m68ki_cpu_core *m68k, int irqline, int state);
extern void m68k_pulse_halt(m68ki_cpu_core *);
extern void m68k_clear_halt(m68ki_cpu_core *);
extern unsigned int m68k_get_reg(m68ki_cpu_core *, m68k_register_t reg);
extern void m68k_set_reg(m68ki_cpu_core *, m68k_register_t reg, unsigned int value);
}
#endif