www.pudn.com > ncdzsrc.rar > asmintf.c


/*************************************************************************** 
 
	asmintf.c 
 
	Handling A68K MC68000 core. 
 
***************************************************************************/ 
 
#include "neogeocd.h" 
 
typedef struct 
{ 
	UINT32 d[8];             /* 0x0004 8 Data registers */ 
	UINT32 a[8];             /* 0x0024 8 Address registers */ 
 
	UINT32 isp;              /* 0x0048 */ 
 
	UINT32 sr_high;          /* 0x004C System registers */ 
	UINT32 ccr;              /* 0x0050 CCR in Intel Format */ 
	UINT32 x_carry;          /* 0x0054 Extended Carry */ 
 
	UINT32 pc;               /* 0x0058 Program Counter */ 
 
	UINT32 IRQ_level;        /* 0x005C IRQ level you want the MC68K process (0=None)  */ 
 
	/* Backward compatible with C emulator - Only set in Debug compile */ 
 
	UINT16 sr; 
	UINT16 filler; 
 
	int (*irq_callback)(int irqline); 
 
	UINT32 previous_pc;      /* last PC used */ 
 
	int (*reset_callback)(void); 
 
	UINT32 sfc;              /* Source Function Code. (68010) */ 
	UINT32 dfc;              /* Destination Function Code. (68010) */ 
	UINT32 usp;              /* User Stack (All) */ 
	UINT32 vbr;              /* Vector Base Register. (68010) */ 
 
	UINT32 BankID;           /* Memory bank in use */ 
	UINT32 CPUtype;          /* CPU Type 0=68000,1=68010,2=68020 */ 
	UINT32 FullPC; 
 
	struct m68k_memory_interface Memory_Interface; 
} a68k_cpu_context; 
 
 
extern void M68000_RESET(void); 
extern int M68000_RUN(void); 
 
extern a68k_cpu_context M68000_regs; 
 
int m68k_ICount; 
int illegal_op = 0; 
int illegal_pc = 0; 
int mem_amask = 0x00ffffff; 
 
#if M68K_DEBUG 
int m68k_debug = 0; 
int m68k_trace = 0; 
static char m68k_tracebuf[256]; 
#endif 
 
static a68k_cpu_context cpu_context; 
 
/* interface for 24-bit address bus, 16-bit data bus */ 
const struct m68k_memory_interface a68k_memory_intf = 
{ 
	0, 
	m68000_read_memory_8, 
	m68000_read_memory_16, 
	m68000_read_memory_32, 
	m68000_write_memory_8, 
	m68000_write_memory_16, 
	m68000_write_memory_32, 
	m68000_setopbase, 
 
	m68000_read_memory_8,				/* Encrypted Versions - not use */ 
	m68000_read_memory_16, 
	m68000_read_memory_32, 
	m68000_read_memory_16, 
	m68000_read_memory_32 
}; 
 
 
void m68000_init(void) 
{ 
	memset((void *)&M68000_regs, 0, sizeof(M68000_regs)); 
	M68000_RESET(); 
} 
 
 
void m68000_reset(int param) 
{ 
	UINT32 m68k_opbase = param ? 0x000000 : 0xc00000; 
 
	memset((void *)&M68000_regs, 0, sizeof(M68000_regs)); 
 
	M68000_regs.Memory_Interface = a68k_memory_intf; 
 
	m68000_setopbase(m68k_opbase); 
	m68000_set_reg(M68K_A7,  m68000_read_memory_32(m68k_opbase)); 
	m68000_set_reg(M68K_ISP, m68000_read_memory_32(m68k_opbase)); 
	m68000_set_reg(M68K_USP, m68000_read_memory_32(m68k_opbase)); 
	m68000_set_reg(M68K_PC,  m68000_read_memory_32(m68k_opbase + 4)); 
	m68000_set_reg(M68K_SR,  0x2700); 
	M68000_regs.sr_high = 0x27; 
} 
 
 
void m68000_exit(void) 
{ 
	/* nothing to do ? */ 
} 
 
 
int m68000_execute(int cycles) 
{ 
	if (M68000_regs.IRQ_level == 0x80) return cycles;	/* STOP with no IRQs */ 
 
	m68k_ICount += cycles; 
 
#if M68K_DEBUG 
	if (osd_is_key_pressed_memory(KEYCODE_F5)) 
	{ 
		m68k_debug = 1; 
		logerror("---- MC68000 trace start ----\n"); 
	} 
 
	if (m68k_debug) 
	{ 
		int start_cycles = cycles; 
 
		do 
		{ 
//			int break_point = 0xffffff; 
			int StartCycle = m68k_ICount; 
 
			m68k_ICount = 0; 
 
			// ブレークポイント指定時はトレース開始 
//			if (M68000_regs.pc == break_point) 
//				m68k_trace = 1; 
 
			if (m68k_trace) 
			{ 
				int opcode_len, pc, pause = 1; 
 
				pc = M68000_regs.pc; 
				opcode_len = m68000_dasm(m68k_tracebuf, pc); 
 
				M68000_RUN(); 
 
				// 特定の範囲をスキップしたい場合は↓を変更 
//				if (M68000_regs.pc >= 0x000000 && M68000_regs.pc <= 0x000000) 
//					pause = 0; 
 
				if (pause) 
				{ 
					logerror("%06x: %s\n", pc, m68k_tracebuf); 
 
					while (1) 
					{ 
						if (osd_is_key_pressed_memory(KEYCODE_SPACE)) 
							break; 
 
						if (osd_is_key_pressed_memory(KEYCODE_F4)) 
						{ 
							logerror("---- MC68000 trace end ----\n"); 
							m68k_trace = 0; 
							break; 
						} 
 
						if (osd_is_key_pressed_memory(KEYCODE_F5)) 
						{ 
							logerror("---- MC68000 debug end ----\n"); 
							m68k_debug = 0; 
							m68k_trace = 0; 
							break; 
						} 
 
						update_input_port(); 
					} 
				} 
			} 
			else 
			{ 
				M68000_RUN(); 
 
				if (osd_is_key_pressed_memory(KEYCODE_F5)) 
				{ 
					logerror("---- MC68000 debug end ----\n"); 
					m68k_trace = 0; 
					m68k_debug = 0; 
				} 
 
				if (osd_is_key_pressed_memory(KEYCODE_F4)) 
				{ 
					logerror("---- MC68000 trace start ----\n"); 
					m68k_trace = 1; 
				} 
			} 
 
			if (M68000_regs.IRQ_level & 0x80) 
			{ 
				logerror("---- cause NMI interrupt ----\n"); 
				return (cycles - m68k_ICount); 
			} 
 
			m68k_ICount += StartCycle; 
			update_input_port(); 
 
		} while (m68k_ICount > 0); 
 
		if ((M68000_regs.IRQ_level & 0x80) == 0) 
		{ 
			logerror("cycles end\n"); 
		} 
	} 
	else 
#endif 
		M68000_RUN(); 
 
	 return (cycles - m68k_ICount); 
} 
 
 
unsigned m68000_get_reg(int regnum) 
{ 
    switch (regnum) 
    { 
    	case REG_PC: 
		case M68K_PC:  return M68000_regs.pc; 
		case REG_SP: 
		case M68K_ISP: return M68000_regs.isp; 
		case M68K_USP: return M68000_regs.usp; 
		case M68K_SR:  return M68000_regs.sr; 
		case M68K_VBR: return M68000_regs.vbr; 
		case M68K_SFC: return M68000_regs.sfc; 
		case M68K_DFC: return M68000_regs.dfc; 
		case M68K_D0:  return M68000_regs.d[0]; 
		case M68K_D1:  return M68000_regs.d[1]; 
		case M68K_D2:  return M68000_regs.d[2]; 
		case M68K_D3:  return M68000_regs.d[3]; 
		case M68K_D4:  return M68000_regs.d[4]; 
		case M68K_D5:  return M68000_regs.d[5]; 
		case M68K_D6:  return M68000_regs.d[6]; 
		case M68K_D7:  return M68000_regs.d[7]; 
		case M68K_A0:  return M68000_regs.a[0]; 
		case M68K_A1:  return M68000_regs.a[1]; 
		case M68K_A2:  return M68000_regs.a[2]; 
		case M68K_A3:  return M68000_regs.a[3]; 
		case M68K_A4:  return M68000_regs.a[4]; 
		case M68K_A5:  return M68000_regs.a[5]; 
		case M68K_A6:  return M68000_regs.a[6]; 
		case M68K_A7:  return M68000_regs.a[7]; 
		case REG_PREVIOUSPC: return M68000_regs.previous_pc; 
/* TODO: Verify that this is the right thing to do for the purpose? */ 
		default: 
			if (regnum <= REG_SP_CONTENTS) 
			{ 
				unsigned offset = M68000_regs.isp + 4 * (REG_SP_CONTENTS - regnum); 
 
				if (offset < 0xfffffd) 
					return (*a68k_memory_intf.read32)(offset); 
            } 
    } 
    return 0; 
} 
 
 
void m68000_set_reg(int regnum, unsigned val) 
{ 
    switch (regnum) 
    { 
    	case REG_PC: 
		case M68K_PC: 
			M68000_regs.pc = val; 
			m68000_setopbase(val & 0xf00000); 
			break; 
		case REG_SP: 
		case M68K_ISP: M68000_regs.isp = val; break; 
		case M68K_USP: M68000_regs.usp = val; break; 
		case M68K_SR:  M68000_regs.sr = val; break; 
		case M68K_VBR: M68000_regs.vbr = val; break; 
		case M68K_SFC: M68000_regs.sfc = val; break; 
		case M68K_DFC: M68000_regs.dfc = val; break; 
		case M68K_D0:  M68000_regs.d[0] = val; break; 
		case M68K_D1:  M68000_regs.d[1] = val; break; 
		case M68K_D2:  M68000_regs.d[2] = val; break; 
		case M68K_D3:  M68000_regs.d[3] = val; break; 
		case M68K_D4:  M68000_regs.d[4] = val; break; 
		case M68K_D5:  M68000_regs.d[5] = val; break; 
		case M68K_D6:  M68000_regs.d[6] = val; break; 
		case M68K_D7:  M68000_regs.d[7] = val; break; 
		case M68K_A0:  M68000_regs.a[0] = val; break; 
		case M68K_A1:  M68000_regs.a[1] = val; break; 
		case M68K_A2:  M68000_regs.a[2] = val; break; 
		case M68K_A3:  M68000_regs.a[3] = val; break; 
		case M68K_A4:  M68000_regs.a[4] = val; break; 
		case M68K_A5:  M68000_regs.a[5] = val; break; 
		case M68K_A6:  M68000_regs.a[6] = val; break; 
		case M68K_A7:  M68000_regs.a[7] = val; break; 
/* TODO: Verify that this is the right thing to do for the purpose? */ 
		default: 
			if (regnum <= REG_SP_CONTENTS) 
			{ 
				unsigned offset = M68000_regs.isp + 4 * (REG_SP_CONTENTS - regnum); 
				if (offset < 0xfffffd) 
					(*a68k_memory_intf.write32)(offset, val); 
            } 
    } 
} 
 
 
INLINE void m68k_assert_irq(int int_line) 
{ 
	/* Save icount */ 
	int StartCount = m68k_ICount; 
 
	M68000_regs.IRQ_level = int_line; 
 
    /* Now check for Interrupt */ 
 
	m68k_ICount = -1; 
    M68000_RUN(); 
 
    /* Restore Count */ 
	m68k_ICount = StartCount; 
} 
 
 
INLINE void m68k_clear_irq(int int_line) 
{ 
	M68000_regs.IRQ_level = 0; 
} 
 
 
void m68000_set_irq_line(int irqline, int state) 
{ 
	if (irqline == IRQ_LINE_NMI) 
		irqline = 7; 
	switch (state) 
	{ 
		case CLEAR_LINE: 
			m68k_clear_irq(irqline); 
			return; 
		case ASSERT_LINE: 
			m68k_assert_irq(irqline); 
			return; 
		default: 
			m68k_assert_irq(irqline); 
			return; 
	} 
} 
 
 
void m68000_set_irq_callback(int (*callback)(int irqline)) 
{ 
	M68000_regs.irq_callback = callback; 
} 
 
 
void m68000_save_context(void) 
{ 
	memcpy(&cpu_context, &M68000_regs, sizeof(a68k_cpu_context)); 
} 
 
 
void m68000_restore_context(void) 
{ 
	memcpy(&M68000_regs, &cpu_context, sizeof(a68k_cpu_context)); 
} 
 
 
 
#if (M68K_DEBUG == 1) 
 
#include "d68k.h" 
 
unsigned m68000_dasm(char *buffer, unsigned pc) 
{ 
	return m68k_disassemble(buffer, pc); 
} 
 
#endif