Beispiel #1
0
/*
 * Handles the emulator's side of a 68k call (from an extended trap)
 */
static uae_u32 REGPARAM3 m68k_call_handler (TrapContext *dummy_ctx)
{
	TrapContext *context = current_context;

	uae_u32 sp;

	sp = m68k_areg (regs, 7);

	/* Push address of trap context on 68k stack. This is
	 * so the return trap can find this context. */
	sp -= sizeof (void *);
	put_pointer (sp, context);

	/* Push addr to return handler trap on 68k stack.
	 * When the called m68k function does an RTS, the CPU will pull this
	 * address off the stack and so call the return handler. */
	sp -= 4;
	put_long (sp, m68k_return_trapaddr);

	m68k_areg (regs, 7) = sp;

	/* Set PC to address of 68k function to call. */
	m68k_setpc (context->call68k_func_addr);
	fill_prefetch ();

	/* End critical section: allow other traps run. */
	uae_sem_post (&trap_mutex);

	/* Restore interrupts. */
	regs.intmask = context->saved_regs.intmask;

	/* Dummy return value. */
	return 0;
}
Beispiel #2
0
/*
 * This function is called by the 68k interpreter to handle an emulator trap.
 *
 * trap_num = number of trap to invoke
 * regs     = current 68k state
 */
void REGPARAM2 m68k_handle_trap (unsigned int trap_num)
{
	struct Trap *trap = &traps[trap_num];
	uae_u32 retval = 0;

	int has_retval = (trap->flags & TRAPFLAG_NO_RETVAL) == 0;
	int implicit_rts = (trap->flags & TRAPFLAG_DORET) != 0;

	if (trap->name && trap->name[0] != 0 && trace_traps)
		write_log (_T("TRAP: %s\n"), trap->name);

	if (trap_num < trap_count) {
		if (trap->flags & TRAPFLAG_EXTRA_STACK) {
			/* Handle an extended trap.
			 * Note: the return value of this trap is passed back to 68k
			 * space via a separate, dedicated simple trap which the trap
			 * handler causes to be invoked when it is done.
			 */
			trap_HandleExtendedTrap (trap->handler, has_retval);
		} else {
			/* Handle simple trap */
			retval = (trap->handler) (NULL);

			if (has_retval)
				m68k_dreg (regs, 0) = retval;

			if (implicit_rts) {
				m68k_do_rts ();
				fill_prefetch ();
			}
		}
	} else
		write_log (_T("Illegal emulator trap %d\n"), trap_num);
}
Beispiel #3
0
/*
 * Call m68k function from an extended trap handler
 *
 * This function is to be called from the trap context.
 */
static uae_u32 trap_Call68k (TrapContext *context, uaecptr func_addr)
{
	/* Enter critical section - only one trap at a time, please! */
	uae_sem_wait (&trap_mutex);
	current_context = context;

	/* Don't allow an interrupt and thus potentially another
	 * trap to be invoked while we hold the above mutex.
	 * This is probably just being paranoid. */
	regs.intmask = 7;

	/* Set up function call address. */
	context->call68k_func_addr = func_addr;

	/* Set PC to address of 68k call trap, so that it will be
	 * executed when emulator context resumes. */
	m68k_setpc (m68k_call_trapaddr);
	fill_prefetch ();

	/* Switch to emulator context. */
	uae_sem_post (&context->switch_to_emu_sem);

	/* Wait for 68k call return handler to switch back to us. */
	uae_sem_wait (&context->switch_to_trap_sem);

	/* End critical section. */
	uae_sem_post (&trap_mutex);

	/* Get return value from 68k function called. */
	return context->call68k_retval;
}
Beispiel #4
0
static void ersatz_init (void)
{
	int32_t f;
	uaecptr request;
	uaecptr a;

	already_failed = 0;
	write_log (_T("initializing kickstart replacement\n"));
	if (disk_empty (0)) {
		already_failed = 1;
		notify_user (NUMSG_KICKREP);
		uae_quit ();
		//uae_restart (-1, NULL);
		return;
	}

	regs.s = 0;
	/* Set some interrupt vectors */
	for (a = 8; a < 0xC0; a += 4) {
		put_long (a, 0xF8001A);
	}
	regs.isp = regs.msp = regs.usp = 0x800;
	m68k_areg (regs, 7) = 0x80000;
	regs.intmask = 0;

	/* Build a dummy execbase */
	put_long (4, m68k_areg (regs, 6) = 0x676);
	put_byte (0x676 + 0x129, 0);
	for (f = 1; f < 105; f++) {
		put_word (0x676 - 6*f, 0x4EF9);
		put_long (0x676 - 6*f + 2, 0xF8000C);
	}
	/* Some "supported" functions */
	put_long (0x676 - 456 + 2, 0xF80014);
	put_long (0x676 - 216 + 2, 0xF80020);
	put_long (0x676 - 198 + 2, 0xF80026);
	put_long (0x676 - 204 + 2, 0xF8002c);
	put_long (0x676 - 210 + 2, 0xF8002a);

	/* Build an IORequest */
	request = 0x800;
	put_word (request + 0x1C, 2);
	put_long (request + 0x28, 0x4000);
	put_long (request + 0x2C, 0);
	put_long (request + 0x24, 0x200 * 4);
	m68k_areg (regs, 1) = request;
	ersatz_doio ();
	/* kickstart disk loader */
	if (get_long (0x4000) == 0x4b49434b) {
		/* a kickstart disk was found in drive 0! */
		write_log (_T("Loading Kickstart rom image from Kickstart disk\n"));
		/* print some notes... */
		write_log (_T("NOTE: if UAE crashes set CPU to 68000 and/or chipmem size to 512KB!\n"));

		/* read rom image from kickstart disk */
		put_word (request + 0x1C, 2);
		put_long (request + 0x28, 0xF80000);
		put_long (request + 0x2C, 0x200);
		put_long (request + 0x24, 0x200 * 512);
		m68k_areg (regs, 1) = request;
		ersatz_doio ();

		/* read rom image once again to mirror address space.
		not elegant, but it works... */
		put_word (request + 0x1C, 2);
		put_long (request + 0x28, 0xFC0000);
		put_long (request + 0x2C, 0x200);
		put_long (request + 0x24, 0x200 * 512);
		m68k_areg (regs, 1) = request;
		ersatz_doio ();

		disk_eject (0);

		m68k_setpc (0xFC0002);
		fill_prefetch ();
		uae_reset (0);
		ersatzkickfile = 0;
		return;
	}

	m68k_setpc (0x400C);
	fill_prefetch ();

	/* Init the hardware */
	put_long (0x3000, 0xFFFFFFFEul);
	put_long (0xDFF080, 0x3000);
	put_word (0xDFF088, 0);
	put_word (0xDFF096, 0xE390);
	put_word (0xDFF09A, 0xE02C);
	put_word (0xDFF09E, 0x0000);
	put_word (0xDFF092, 0x0038);
	put_word (0xDFF094, 0x00D0);
	put_word (0xDFF08E, 0x2C81);
	put_word (0xDFF090, 0xF4C1);
	put_word (0xDFF02A, 0x8000);

	put_byte (0xBFD100, 0xF7);
	put_byte (0xBFEE01, 0);
	put_byte (0xBFEF01, 0x08);
	put_byte (0xBFDE00, 0x04);
	put_byte (0xBFDF00, 0x84);
	put_byte (0xBFDD00, 0x9F);
	put_byte (0xBFED01, 0x9F);
}