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