uaecptr libemu_InstallFunctionFlags (TrapFunction f, uaecptr libbase, int offset, int flags, const char *tracename) { int i; uaecptr retval; uaecptr execbase = get_long (four); int trnum; uaecptr addr = here(); calltrap (trnum = deftrap2 (f, flags, tracename)); dw (RTS); _68k_areg(1) = libbase; _68k_areg(0) = offset; _68k_dreg(0) = addr; retval = CallLib (execbase, -420); trapoldfunc[trnum] = retval; #if 0 for (i = 0; i < n_libpatches; i++) { if (libpatches[i].libbase == libbase) break; } if (i == n_libpatches) { int j; libpatches[i].libbase = libbase; for (j = 0; j < 300; j++) libpatches[i].functions[j] = NULL; n_libpatches++; } libpatches[i].functions[-offset/6] = f; #endif return retval; }
uae_u32 CallLib (uaecptr base, uae_s16 offset) { int i; uaecptr olda6 = _68k_areg(6); uae_u32 retval; _68k_areg(6) = base; retval = call_m68k(base + offset, 1); _68k_areg(6) = olda6; return retval; }
static uae_u32 m68k_mode_return (void) { #ifdef CAN_DO_STACK_MAGIC uaecptr a7 = _68k_areg(7); void *s = *(void **)get_real_address(a7); _68k_areg(7) += (sizeof (void *) + 3) & ~3; /*write_log ("doing m68k mode return\n");*/ do_stack_magic (NULL, s, -1); #endif return 0; }
static void ersatz_doio (void) { uaecptr request = _68k_areg(1); switch (get_word (request + 0x1C)) { case 9: /* TD_MOTOR is harmless */ case 2: case 0x8002: /* READ commands */ break; default: write_log ("Only CMD_READ supported in DoIO()\n"); return; } { uaecptr dest = get_long (request + 0x28); int start = get_long (request + 0x2C) / 512; int nsecs = get_long (request + 0x24) / 512; int tr = start / 11; int sec = start % 11; while (nsecs--) { DISK_ersatz_read (tr, sec, dest); dest += 512; if (++sec == 11) sec = 0, tr++; } } }
uae_u32 CallLib (uaecptr base, uae_s16 offset) { int i; uaecptr olda6 = _68k_areg(6); uae_u32 retval; #if 0 for (i = 0; i < n_libpatches; i++) { if (libpatches[i].libbase == base && libpatches[i].functions[-offset/6] != NULL) return (*libpatches[i].functions[-offset/6])(); } #endif _68k_areg(6) = base; retval = call_m68k(base + offset, 1); _68k_areg(6) = olda6; return retval; }
void carga(void) { unsigned pc,sr,a0,a1,a2,a3,a4,a5,a6,a7,d0,d1,d2,d3,d4,d5,d6,d7; FILE *f=fopen("/tmp/uae4all_guarda","rb"); if (f) { fread((void *)&pc,sizeof(unsigned),1,f); fread((void *)&sr,sizeof(unsigned),1,f); fread((void *)&a0,sizeof(unsigned),1,f); fread((void *)&a1,sizeof(unsigned),1,f); fread((void *)&a2,sizeof(unsigned),1,f); fread((void *)&a3,sizeof(unsigned),1,f); fread((void *)&a4,sizeof(unsigned),1,f); fread((void *)&a5,sizeof(unsigned),1,f); fread((void *)&a6,sizeof(unsigned),1,f); fread((void *)&a7,sizeof(unsigned),1,f); fread((void *)&d0,sizeof(unsigned),1,f); fread((void *)&d1,sizeof(unsigned),1,f); fread((void *)&d2,sizeof(unsigned),1,f); fread((void *)&d3,sizeof(unsigned),1,f); fread((void *)&d4,sizeof(unsigned),1,f); fread((void *)&d5,sizeof(unsigned),1,f); fread((void *)&d6,sizeof(unsigned),1,f); fread((void *)&d7,sizeof(unsigned),1,f); fread((void *)chipmemory,1,allocated_chipmem,f); fclose(f); { unsigned char *p=(unsigned char *)chipmemory; unsigned i; for (i=0; i<allocated_chipmem; i+=2) { unsigned char t=p[i]; p[i]=p[i+1]; p[i+1]=t; } } _68k_areg(0)=a0; _68k_areg(1)=a1; _68k_areg(2)=a2; _68k_areg(3)=a3; _68k_areg(4)=a4; _68k_areg(5)=a5; _68k_areg(6)=a6; _68k_areg(7)=a7; _68k_dreg(0)=d0; _68k_dreg(1)=d1; _68k_dreg(2)=d2; _68k_dreg(3)=d3; _68k_dreg(4)=d4; _68k_dreg(5)=d5; _68k_dreg(6)=d6; _68k_dreg(7)=d7; _68k_sreg=sr; _68k_setpc(pc); } }
uaecptr libemu_InstallFunctionFlags (TrapFunction f, uaecptr libbase, int offset, int flags, const char *tracename) { int i; uaecptr retval; uaecptr execbase = get_long (four); int trnum; uaecptr addr = here(); calltrap (trnum = deftrap2 (f, flags, tracename)); dw (RTS); _68k_areg(1) = libbase; _68k_areg(0) = offset; _68k_dreg(0) = addr; retval = CallLib (execbase, -420); trapoldfunc[trnum] = retval; return retval; }
static void do_stack_magic (TrapFunction f, void *s, int has_retval) { #ifdef CAN_DO_STACK_MAGIC uaecptr a7; jmp_buf *j = (jmp_buf *)s; switch (setjmp (j[0])) { case 0: /* Returning directly */ current_extra_stack = s; if (has_retval == -1) { /*write_log ("finishing m68k mode return\n");*/ longjmp (j[1], 1); } /*write_log ("calling native function\n");*/ transfer_control (s, EXTRA_STACK_SIZE, stack_stub, f, has_retval); /* not reached */ return; case 1: /*write_log ("native function complete\n");*/ /* Returning normally. */ if (stack_has_retval (s, EXTRA_STACK_SIZE)) _68k_dreg (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. */ a7 = _68k_areg(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 (_68k_areg (7), RTAREA_BASE + 0xFF00); _68k_setpc (m68k_calladdr); fill_prefetch_0 (); /*write_log ("native function calls m68k\n");*/ break; } current_extra_stack = 0; #endif }
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] != 0 && trace_traps) write_log ("TRAP: %s\n", trapstr[func]); /* For monitoring only? */ if (traps[func] == NULL) { _68k_setpc(trapoldfunc[func]); fill_prefetch_0 (); return; } if (func < max_trap) { if (trapmode[func] & TRAPFLAG_EXTRA_STACK) { execute_fn_on_extra_stack(traps[func], has_retval); return; } retval = (*traps[func])(); } else write_log ("illegal emulator trap\n"); if (has_retval) _68k_dreg(0) = retval; if (implicit_rts) { #ifndef USE_FAME_CORE m68k_do_rts (); #else /* WinUAE code - m68k_do_rts() */ _68k_setpc(get_long(_68k_areg(7))); _68k_areg(7) += 4; /*******************************/ #endif fill_prefetch_0 (); } }
void ersatz_perform (uae_u16 what) { switch (what) { case EOP_INIT: ersatz_init (); break; case EOP_SERVEINT: /* Just reset all the interrupt request bits */ put_word (0xDFF09C, get_word (0xDFF01E) & 0x3FFF); break; case EOP_DOIO: ersatz_doio (); break; case EOP_AVAILMEM: _68k_dreg(0) = _68k_dreg(1) & 4 ? 0 : 0x70000; break; case EOP_ALLOCMEM: _68k_dreg(0) = _68k_dreg(1) & 4 ? 0 : 0x0F000; break; case EOP_ALLOCABS: _68k_dreg(0) = _68k_areg(1); break; case EOP_NIMP: write_log ("Unimplemented Kickstart function called\n"); uae_quit (); /* fall through */ case EOP_LOOP: _68k_setpc (0xF80010); break; case EOP_OPENLIB: default: write_log ("Internal error. Giving up.\n"); return; } }
static void uae4all_reset(void) { int i; #if !defined(USE_CYCLONE_CORE) && !defined(USE_FAME_CORE_ARM2) m68k_set_context(&micontexto); #endif m68k_reset(); for(i=1; i<8; i++) #if defined(DEBUG_INTERRUPTS) M68KCONTEXT.interrupts[i]=0xFF; #else M68KCONTEXT.interrupts[i]=0x18+i; #endif M68KCONTEXT.interrupts[0]=0; m68k_irq_update(0); mispcflags=0; _68k_areg(7) = get_long (0x00f80000); _68k_setpc(get_long (0x00f80004)); //_68k_sreg = 0x2700; // already done by m68k_reset() mispcflags=0; #ifdef DEBUG_FRAMERATE uae4all_update_time(); #endif }
static void ersatz_init (void) { int f; uaecptr request; uaecptr a; if (disk_empty (0)) { write_log ("You need to have a diskfile in DF0 to use the Kickstart replacement!\n"); uae_quit (); _68k_setpc (0xF80010); return; } _68k_sreg = 0; /* Set some interrupt vectors */ for (a = 8; a < 0xC0; a += 4) { put_long (a, 0xF8001A); } _68k_ispreg = _68k_mspreg = _68k_uspreg = 0x800; _68k_areg(7) = 0x80000; #ifndef USE_FAME_CORE _68k_intmask = 0; #endif /* Build a dummy execbase */ put_long (4, _68k_areg(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); _68k_areg(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); _68k_areg(1) = request; ersatz_doio (); /* read rom image once ajain 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); _68k_areg(1) = request; ersatz_doio (); disk_eject (0); _68k_setpc (0xFC0002); fill_prefetch_0 (); uae_reset (); ersatzkickfile = 0; return; } _68k_setpc (0x400C); fill_prefetch_0 (); /* 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); }
static uae_u32 uae_puts (void) { dbg((const char *)(get_real_address (_68k_areg (0)))); return 0; }