Example #1
0
/*
 * Reset emulator
 */
static void do_reset_machine (int hardreset)
{
#ifdef SAVESTATE
    if (savestate_state == STATE_RESTORE)
	restore_state (savestate_fname);
    else if (savestate_state == STATE_REWIND)
	savestate_rewind ();
#endif
    /* following three lines must not be reordered or
     * fastram state restore breaks
     */
    reset_all_systems ();
    customreset ();
    m68k_reset ();
    if (hardreset) {
	memset (chipmemory, 0, allocated_chipmem);
	write_log ("chipmem cleared\n");
    }
#ifdef SAVESTATE
    /* We may have been restoring state, but we're done now.  */
    if (savestate_state == STATE_RESTORE || savestate_state == STATE_REWIND)
    {
	map_overlay (1);
	fill_prefetch_slow (&regs); /* compatibility with old state saves */
    }
    savestate_restore_finish ();
#endif

    fill_prefetch_slow (&regs);
    if (currprefs.produce_sound == 0)
	eventtab[ev_audio].active = 0;
    handle_active_events ();

    inputdevice_updateconfig (&currprefs);
}
Example #2
0
void REGPARAM2 call_calltrap (int func)
{
    uae_u32 retval = 0;
    int has_retval = (trapmode[func] & TRAPFLAG_NO_RETVAL) == 0;
    int implicit_rts = (trapmode[func] & TRAPFLAG_DORET) != 0;

    if (trapstr[func] && *trapstr[func] != 0 && trace_traps)
	write_log ("TRAP: %s\n", trapstr[func]);

    /* For monitoring only? */
    if (traps[func] == NULL) {
	m68k_setpc (trapoldfunc[func]);
	fill_prefetch_slow ();
	return;
    }

    if (func < max_trap) {
#ifdef CAN_DO_STACK_MAGIC
	if (trapmode[func] & TRAPFLAG_EXTRA_STACK) {
	    execute_fn_on_extra_stack(traps[func], has_retval);
	    return;
	}
#endif
	retval = (*traps[func])();
    } else
	write_log ("illegal emulator trap\n");

    if (has_retval)
	m68k_dreg (regs, 0) = retval;
    if (implicit_rts) {
	m68k_do_rts ();
	fill_prefetch_slow ();
    }
}
Example #3
0
/*
 * Handles the emulator's side of a 68k call (from an extended trap)
 */
static uae_u32 REGPARAM2 m68k_call_handler (struct regstruct *regs)
{
    ExtendedTrapContext *context = current_context;

    uae_u32 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 (regs, context->call68k_func_addr);
    fill_prefetch_slow (&context->regs);

    /* 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;
}
Example #4
0
/*
 * Call m68k function from an extended trap handler
 *
 * This function is to be called from the trap context.
 */
static uae_u32 trap_Call68k (ExtendedTrapContext *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. */
    context->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 (&context->regs, m68k_call_trapaddr);
    fill_prefetch_slow (&context->regs);

    /* 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;
}
Example #5
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 (L"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_slow ();
			}
		}
	} else
		write_log (L"Illegal emulator trap\n");
}
Example #6
0
static void do_stack_magic (TrapFunction f, struct extra_stack *s, int has_retval)
{
    switch (setjmp (s->stackswap_env)) {
     case 0:
	/* Returning directly */
	current_extra_stack = s;
	if (has_retval == -1) {
	    /*write_log ("finishing m68k mode return\n");*/
	    longjmp (s->m68kcall_env, 1);
	}
	/*write_log ("calling native function\n");*/
	transfer_control (s, EXTRA_STACK_SIZE, stack_stub, f, has_retval);
	/* not reached */
	abort ();

     case 1:
	/*write_log ("native function complete\n");*/
	/* Returning normally. */
	if (stack_has_retval (s, EXTRA_STACK_SIZE))
	    m68k_dreg (regs, 0) = get_retval_from_stack (s, EXTRA_STACK_SIZE);
	free_extra_stack (s);
	break;

     case 2: {
	/* Returning to do a m68k call. We're now back on the main stack. */
	uaecptr a7 = m68k_areg (regs, 7) -= (sizeof (void *) + 7) & ~3;
	/* Save stack to restore */
	*((void **)get_real_address (a7 + 4)) = s;
	/* Save special return address: this address contains a
	 * calltrap that will longjmp to the right stack. */
	put_long (m68k_areg (regs, 7), RTAREA_BASE + 0xFF00);
        m68k_setpc (s->m68kcall_addr);
        fill_prefetch_slow ();
	/*write_log ("native function calls m68k\n");*/
	break;
     }
    }
    current_extra_stack = 0;
}
Example #7
0
static void ersatz_init (void)
{
    int f;
    uaecptr request;
    uaecptr a;

    already_failed = 0;
    write_log ("initializing kickstart replacement\n");
    if (disk_empty (0)) {
	    already_failed = 1;
	    notify_user (NUMSG_KICKREP);
	    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 ("Loading Kickstart rom image from Kickstart disk\n");
	/* print some notes... */
	write_log ("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 (&regs, 0xFC0002);
	fill_prefetch_slow (&regs);
	uae_reset (0);
	ersatzkickfile = 0;
	return;
    }

    m68k_setpc (&regs, 0x400C);
    fill_prefetch_slow (&regs);

    /* 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);
}