Example #1
0
/* Pulse the RESET line on the CPU */
void m68k_pulse_reset(m68ki_cpu_core *m68k)
{
	/* Clear all stop levels and eat up all remaining cycles */
	m68k->stopped = 0;
	if (m68k->remaining_cycles > 0)
		m68k->remaining_cycles = 0;

#if M68K_EMULATE_ADDRESS_ERROR
	m68k->run_mode = RUN_MODE_BERR_AERR_RESET;
#endif

	/* Turn off tracing */
	m68k->t1_flag = m68k->t0_flag = 0;
	m68ki_clear_trace();
	/* Interrupt mask to level 7 */
	m68k->int_mask = 0x0700;
	m68k->int_level = 0;
	m68k->virq_state = 0;
	/* Reset VBR */
	m68k->vbr = 0;
	/* Go to supervisor mode */
	m68ki_set_sm_flag(m68k, SFLAG_SET | MFLAG_CLEAR);

	/* Invalidate the prefetch queue */
	/* Set to arbitrary number since our first fetch is from 0 */
#if M68K_EMULATE_PREFETCH
	m68k->pref_addr = 0x1000;
#endif

	/* Read the initial stack pointer and program counter */
	m68ki_jump(m68k, 0);
	REG_SP = m68ki_read_imm_32(m68k);
	REG_PC = m68ki_read_imm_32(m68k);
	m68ki_jump(m68k, REG_PC);

#if M68K_EMULATE_ADDRESS_ERROR
	m68k->run_mode = RUN_MODE_NORMAL;
#endif

	m68k->reset_cycles = m68k->cyc_exception[EXCEPTION_RESET];
}
// Service an interrupt request and start exception processing
void m68ki_exception_interrupt(uint32_t intLevel)
{
#if 0
	uint vector;
	uint sr;
	uint new_pc;

	/* Turn off the stopped state */
	CPU_STOPPED &= ~STOP_LEVEL_STOP;

	/* If we are halted, don't do anything */
	if(CPU_STOPPED)
		return;

	/* Acknowledge the interrupt */
	vector = m68ki_int_ack(int_level);

	/* Get the interrupt vector */
	if(vector == M68K_INT_ACK_AUTOVECTOR)
		/* Use the autovectors.  This is the most commonly used implementation */
		vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
	else if(vector == M68K_INT_ACK_SPURIOUS)
		/* Called if no devices respond to the interrupt acknowledge */
		vector = EXCEPTION_SPURIOUS_INTERRUPT;
	else if(vector > 255)
	{
		M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n",
			 m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector));
		return;
	}

	/* Start exception processing */
	sr = m68ki_init_exception();

	/* Set the interrupt mask to the level of the one being serviced */
	FLAG_INT_MASK = int_level<<8;

	/* Get the new PC */
	new_pc = m68ki_read_data_32((vector<<2) + REG_VBR);

	/* If vector is uninitialized, call the uninitialized interrupt vector */
	if(new_pc == 0)
		new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR);

	/* Generate a stack frame */
	m68ki_stack_frame_0000(REG_PC, sr, vector);

	if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
	{
		/* Create throwaway frame */
		m68ki_set_sm_flag(FLAG_S);	/* clear M */
		sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */
		m68ki_stack_frame_0001(REG_PC, sr, vector);
	}

	m68ki_jump(new_pc);

	/* Defer cycle counting until later */
	CPU_INT_CYCLES += CYC_EXCEPTION[vector];

#if !M68K_EMULATE_INT_ACK
	/* Automatically clear IRQ if we are not using an acknowledge scheme */
	CPU_INT_LEVEL = 0;
#endif /* M68K_EMULATE_INT_ACK */
#else
	// Turn off the stopped state (N.B.: normal 68K behavior!)
	regs.stopped = 0;

//JLH: need to add halt state?
// prolly, for debugging/alpine mode... :-/
// but then again, this should be handled already by the main execution loop :-P
	// If we are halted, don't do anything
//	if (regs.stopped)
//		return;

	// Acknowledge the interrupt (NOTE: This is a user supplied function!)
	uint32_t vector = irq_ack_handler(intLevel);

	// Get the interrupt vector
	if (vector == M68K_INT_ACK_AUTOVECTOR)
		// Use the autovectors.  This is the most commonly used implementation
		vector = EXCEPTION_INTERRUPT_AUTOVECTOR + intLevel;
	else if (vector == M68K_INT_ACK_SPURIOUS)
		// Called if no devices respond to the interrupt acknowledge
		vector = EXCEPTION_SPURIOUS_INTERRUPT;
	else if (vector > 255)
	{
//		M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n",
//			 m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector));
		return;
	}

	// Start exception processing
	uint32_t sr = m68ki_init_exception();

	// Set the interrupt mask to the level of the one being serviced
	regs.intmask = intLevel;

#if 0
extern int startM68KTracing;
if (startM68KTracing)
{
	printf("IRQ: old PC=%06X, ", regs.pc);
}
#endif

	// Get the new PC
	uint32_t newPC = m68k_read_memory_32(vector << 2);

#if 0
if (startM68KTracing)
{
	printf("new PC=%06X, vector=%u, ", newPC, vector);
}
#endif

	// If vector is uninitialized, call the uninitialized interrupt vector
	if (newPC == 0)
		newPC = m68k_read_memory_32(EXCEPTION_UNINITIALIZED_INTERRUPT << 2);

	// Generate a stack frame
	m68ki_stack_frame_3word(regs.pc, sr);

	m68k_setpc(newPC);
#if 0
if (startM68KTracing)
{
	printf("(PC=%06X)\n", regs.pc);
}
#endif

	// Defer cycle counting until later
	regs.interruptCycles += 56;	// NOT ACCURATE-- !!! FIX !!!
//	CPU_INT_CYCLES += CYC_EXCEPTION[vector];
#endif
}
// Pulse the RESET line on the CPU
void m68k_pulse_reset(void)
{
	static uint32_t emulation_initialized = 0;

	// The first call to this function initializes the opcode handler jump table
	if (!emulation_initialized)
	{
#if 0
		m68ki_build_opcode_table();
		m68k_set_int_ack_callback(NULL);
		m68k_set_bkpt_ack_callback(NULL);
		m68k_set_reset_instr_callback(NULL);
		m68k_set_pc_changed_callback(NULL);
		m68k_set_fc_callback(NULL);
		m68k_set_instr_hook_callback(NULL);
#else
		// Build opcode handler table here...
		read_table68k();
		do_merges();
		BuildCPUFunctionTable();
#endif
		emulation_initialized = 1;
	}

//	if (CPU_TYPE == 0)	/* KW 990319 */
//		m68k_set_cpu_type(M68K_CPU_TYPE_68000);

#if 0
	/* Clear all stop levels and eat up all remaining cycles */
	CPU_STOPPED = 0;
	SET_CYCLES(0);

	/* Turn off tracing */
	FLAG_T1 = FLAG_T0 = 0;
	m68ki_clear_trace();
	/* Interrupt mask to level 7 */
	FLAG_INT_MASK = 0x0700;
	/* Reset VBR */
	REG_VBR = 0;
	/* Go to supervisor mode */
	m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);

	/* Invalidate the prefetch queue */
#if M68K_EMULATE_PREFETCH
	/* Set to arbitrary number since our first fetch is from 0 */
	CPU_PREF_ADDR = 0x1000;
#endif /* M68K_EMULATE_PREFETCH */

	/* Read the initial stack pointer and program counter */
	m68ki_jump(0);
	REG_SP = m68ki_read_imm_32();
	REG_PC = m68ki_read_imm_32();
	m68ki_jump(REG_PC);
#else
	regs.spcflags = 0;
	regs.stopped = 0;
	regs.remainingCycles = 0;
	
	regs.intmask = 0x07;
	regs.s = 1;								// Supervisor mode ON

	// Read initial SP and PC
	m68k_areg(regs, 7) = m68k_read_memory_32(0);
	m68k_setpc(m68k_read_memory_32(4));
	refill_prefetch(m68k_getpc(), 0);
#endif
}