--- uae/src/autoconf.c 2018/04/24 16:39:54 1.1.1.3 +++ uae/src/autoconf.c 2018/04/24 17:16:25 1.1.1.12 @@ -10,346 +10,80 @@ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "options.h" -#include "machdep/m68k.h" #include "uae.h" #include "memory.h" #include "custom.h" -#include "readcpu.h" #include "newcpu.h" -#include "compiler.h" #include "autoconf.h" +#include "traps.h" #include "osdep/exectasks.h" -/* We'll need a lot of these. */ -#define MAX_TRAPS 4096 -static TrapFunction traps[MAX_TRAPS]; -static int trapmode[MAX_TRAPS]; -static const char *trapstr[MAX_TRAPS]; -static uaecptr trapoldfunc[MAX_TRAPS]; - -static int max_trap = 0; -int lasttrap; - -/* Stack management */ - -/* The mechanism for doing m68k calls from native code is as follows: - * - * m68k code executes, stack is main - * calltrap to execute_fn_on_extra_stack. new stack is allocated - * do_stack_magic is called for the first time - * current context is saved with setjmp [0] - * transfer_control is done - * native code executes on new stack - * native code calls call_m68k - * setjmp saves current context [1] - * longjmp back to execute_fn_on_extra_stack [0] - * pointer to new stack is saved on m68k stack. m68k return address set - * to 0xF0FF00. m68k PC set to called function - * m68k function executes, stack is main - * m68k function returns to 0xF0FF00 - * calltrap to m68k_mode_return - * do_stack_magic is called again - * current context is saved again with setjmp [0] - * this time, transfer_control is _not_ done, instead a longjmp[1] - * to the previously saved context - * native code executes again on temp stack - * native function returns to stack_stub - * longjmp[0] back to old context - * back again! - * - * A bearded man enters the room, carrying a bowl of spaghetti. - */ - -/* This _shouldn't_ crash with a stack size of 4096, but it does... - * might be a bug */ -#ifndef EXTRA_STACK_SIZE -#define EXTRA_STACK_SIZE 65536 -#endif - -static void *extra_stack_list = NULL; - -static void *get_extra_stack(void) -{ - void *s = extra_stack_list; - if (s) - extra_stack_list = *(void **)s; - if (!s) - s = xmalloc (EXTRA_STACK_SIZE); - return s; -} - -static void free_extra_stack (void *s) -{ - *(void **)s = extra_stack_list; - extra_stack_list = s; -} - -static void stack_stub (void *s, TrapFunction f, uae_u32 *retval) -{ -#ifdef CAN_DO_STACK_MAGIC - /*printf("in stack_stub: %p %p %p %x\n", s, f, retval, (int)*retval);*/ - *retval = f(); - /*write_log ("returning from stack_stub\n");*/ - longjmp(((jmp_buf *)s)[0], 1); -#endif -} - -static void *current_extra_stack = NULL; -static uaecptr m68k_calladdr; - -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 */ - 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. */ - 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), 0xF0FF00); - m68k_setpc (m68k_calladdr); - fill_prefetch_0 (); - /*write_log ("native function calls m68k\n");*/ - break; - } - current_extra_stack = 0; -#endif -} - -static uae_u32 execute_fn_on_extra_stack(TrapFunction f, int has_retval) -{ - uae_u32 retval = 0; -#ifdef CAN_DO_STACK_MAGIC - void *s = get_extra_stack(); - do_stack_magic (f, s, has_retval); -#endif - return 0; -} - -static uae_u32 m68k_mode_return(void) -{ -#ifdef CAN_DO_STACK_MAGIC - uaecptr a7 = m68k_areg(regs, 7); - void *s = *(void **)get_real_address(a7); - m68k_areg(regs, 7) += (sizeof (void *) + 3) & ~3; - /*write_log ("doing m68k mode return\n");*/ - do_stack_magic (NULL, s, -1); -#endif - return 0; -} - -static uae_u32 call_m68k(uaecptr addr, int saveregs) -{ - volatile uae_u32 retval = 0; - volatile int do_save = saveregs; - if (current_extra_stack == NULL) - abort(); -#ifdef CAN_DO_STACK_MAGIC - { - volatile struct regstruct saved_regs; - jmp_buf *j = (jmp_buf *)current_extra_stack; - - if (do_save) - saved_regs = regs; - m68k_calladdr = addr; - switch (setjmp(j[1])) { - case 0: - /*write_log ("doing call\n");*/ - /* Returning directly: now switch to main stack and do the call */ - longjmp (j[0], 2); - case 1: - /*write_log ("returning from call\n");*/ - retval = m68k_dreg (regs, 0); - if (do_save) - regs = saved_regs; - /* Returning after the call. */ - break; - } - } -#endif - return retval; -} - -uae_u32 CallLib(uaecptr base, uae_s16 offset) -{ - int i; - uaecptr olda6 = m68k_areg(regs, 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 - m68k_areg(regs, 6) = base; - retval = call_m68k(base + offset, 1); - m68k_areg(regs, 6) = olda6; - return retval; -} - /* Commonly used autoconfig strings */ uaecptr EXPANSION_explibname, EXPANSION_doslibname, EXPANSION_uaeversion; uaecptr EXPANSION_uaedevname, EXPANSION_explibbase = 0, EXPANSION_haveV36; uaecptr EXPANSION_bootcode, EXPANSION_nullfunc; - -static int current_deviceno = 0; - -int get_new_device(char **devname, uaecptr *devname_amiga) -{ - char buffer[80]; - - sprintf(buffer,"UAE%d", current_deviceno); - - *devname_amiga = ds(*devname = my_strdup(buffer)); - return current_deviceno++; -} +uaecptr EXPANSION_cddevice; /* ROM tag area memory access */ -static uae_u8 rtarea[65536]; +static uae_u8 *rtarea; -static uae_u32 rtarea_lget(uaecptr) REGPARAM; -static uae_u32 rtarea_wget(uaecptr) REGPARAM; -static uae_u32 rtarea_bget(uaecptr) REGPARAM; -static void rtarea_lput(uaecptr, uae_u32) REGPARAM; -static void rtarea_wput(uaecptr, uae_u32) REGPARAM; -static void rtarea_bput(uaecptr, uae_u32) REGPARAM; -static uae_u8 *rtarea_xlate(uaecptr) REGPARAM; +static uae_u32 rtarea_lget (uaecptr) REGPARAM; +static uae_u32 rtarea_wget (uaecptr) REGPARAM; +static uae_u32 rtarea_bget (uaecptr) REGPARAM; +static void rtarea_lput (uaecptr, uae_u32) REGPARAM; +static void rtarea_wput (uaecptr, uae_u32) REGPARAM; +static void rtarea_bput (uaecptr, uae_u32) REGPARAM; +static uae_u8 *rtarea_xlate (uaecptr) REGPARAM; addrbank rtarea_bank = { rtarea_lget, rtarea_wget, rtarea_bget, rtarea_lput, rtarea_wput, rtarea_bput, - rtarea_xlate, default_check + rtarea_xlate, default_check, NULL }; -uae_u8 REGPARAM2 *rtarea_xlate(uaecptr addr) +uae_u8 REGPARAM2 *rtarea_xlate (uaecptr addr) { addr &= 0xFFFF; return rtarea + addr; } -uae_u32 REGPARAM2 rtarea_lget(uaecptr addr) +uae_u32 REGPARAM2 rtarea_lget (uaecptr addr) { + special_mem |= S_READ; addr &= 0xFFFF; - return (uae_u32)(rtarea_wget(addr) << 16) + rtarea_wget(addr+2); + return (uae_u32)(rtarea_wget (addr) << 16) + rtarea_wget (addr+2); } -uae_u32 REGPARAM2 rtarea_wget(uaecptr addr) +uae_u32 REGPARAM2 rtarea_wget (uaecptr addr) { + special_mem |= S_READ; addr &= 0xFFFF; return (rtarea[addr]<<8) + rtarea[addr+1]; } -uae_u32 REGPARAM2 rtarea_bget(uaecptr addr) +uae_u32 REGPARAM2 rtarea_bget (uaecptr addr) { - uae_u16 data; + special_mem |= S_READ; addr &= 0xFFFF; return rtarea[addr]; } -void REGPARAM2 rtarea_lput(uaecptr addr, uae_u32 value) { } -void REGPARAM2 rtarea_wput(uaecptr addr, uae_u32 value) { } -void REGPARAM2 rtarea_bput(uaecptr addr, uae_u32 value) { } - -static int trace_traps = 1; - -void REGPARAM2 call_calltrap(int func) +void REGPARAM2 rtarea_lput (uaecptr addr, uae_u32 value) { - 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) { - sprintf (warning_buffer, "TRAP: %s\n", trapstr[func]); - write_log (warning_buffer); - } - - /* For monitoring only? */ - if (traps[func] == NULL) { - m68k_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 { - fprintf(stderr, "illegal emulator trap\n"); - } - if (has_retval) - m68k_dreg(regs, 0) = retval; - if (implicit_rts) { - m68k_do_rts (); - fill_prefetch_0 (); - } + special_mem |= S_WRITE; } -/* @$%&§ compiler bugs */ -static volatile int four = 4; +void REGPARAM2 rtarea_wput (uaecptr addr, uae_u32 value) +{ + special_mem |= S_WRITE; +} -uaecptr libemu_InstallFunctionFlags(TrapFunction f, uaecptr libbase, int offset, - int flags, const char *tracename) +void REGPARAM2 rtarea_bput (uaecptr addr, uae_u32 value) { - int i; - uaecptr retval; - uaecptr execbase = get_long(four); - int trnum; - uaecptr addr = here(); - calltrap(trnum = deftrap2(f, flags, tracename)); - dw(RTS); - - m68k_areg(regs, 1) = libbase; - m68k_areg(regs, 0) = offset; - m68k_dreg(regs, 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; + special_mem |= S_WRITE; } /* some quick & dirty code to fill in the rt area and save me a lot of @@ -359,23 +93,23 @@ uaecptr libemu_InstallFunctionFlags(Trap static int rt_addr = 0; static int rt_straddr = 0xFF00 - 2; -uae_u32 addr(int ptr) +uae_u32 addr (int ptr) { - return (uae_u32)ptr + 0x00F00000; + return (uae_u32)ptr + RTAREA_BASE; } -void db(uae_u8 data) +void db (uae_u8 data) { rtarea[rt_addr++] = data; } -void dw(uae_u16 data) +void dw (uae_u16 data) { rtarea[rt_addr++] = data >> 8; rtarea[rt_addr++] = data; } -void dl(uae_u32 data) +void dl (uae_u32 data) { rtarea[rt_addr++] = data >> 24; rtarea[rt_addr++] = data >> 16; @@ -387,87 +121,96 @@ void dl(uae_u32 data) * backward. store pointer at current address */ -uae_u32 ds(char *str) +uae_u32 ds (char *str) { - int len = strlen(str) + 1; + int len = strlen (str) + 1; rt_straddr -= len; - strcpy((char *)rtarea + rt_straddr, str); + strcpy ((char *)rtarea + rt_straddr, str); - return addr(rt_straddr); + return addr (rt_straddr); } -void calltrap(uae_u32 n) +void calltrap (uae_u32 n) { - dw(0xA000 + n); + dw (0xA000 + n); } -void org(uae_u32 a) +void org (uae_u32 a) { - rt_addr = a - 0x00F00000; + rt_addr = a - RTAREA_BASE; } -uae_u32 here(void) +uae_u32 here (void) { - return addr(rt_addr); + return addr (rt_addr); } -int deftrap2(TrapFunction func, int mode, const char *str) +void align (int b) { - int num = max_trap++; - traps[num] = func; - trapstr[num] = str; - trapmode[num] = mode; - return num; + rt_addr = (rt_addr + b - 1) & ~(b - 1); } -int deftrap(TrapFunction func) +static uae_u32 nullfunc(void) { - return deftrap2(func, 0, ""); + write_log ("Null function called\n"); + return 0; } -void align(int b) +static uae_u32 getchipmemsize (void) { - rt_addr = (rt_addr + (b-1)) & ~(b-1); + return allocated_chipmem; } -static uae_u32 nullfunc(void) +static uae_u32 uae_puts (void) { - fprintf(stderr, "Null function called\n"); + puts (get_real_address (m68k_areg (regs, 0))); return 0; } -static uae_u32 getchipmemsize (void) +static void rtarea_init_mem (void) { - return chipmem_size; + rtarea = mapped_malloc (0x10000, "rtarea"); + if (!rtarea) { + write_log ("virtual memory exhausted (rtarea)!\n"); + abort (); + } + rtarea_bank.baseaddr = rtarea; } -void rtarea_init() +void rtarea_init (void) { uae_u32 a; char uaever[100]; - sprintf(uaever, "uae-%d.%d.%d", (version / 100) % 10, (version / 10) % 10, (version / 1) % 10); - EXPANSION_uaeversion = ds(uaever); - EXPANSION_explibname = ds("expansion.library"); - EXPANSION_doslibname = ds("dos.library"); - EXPANSION_uaedevname = ds("uae.device"); - - deftrap(NULL); /* Generic emulator trap */ - lasttrap = 0; - - EXPANSION_nullfunc = here(); - calltrap(deftrap(nullfunc)); - dw(RTS); + rtarea_init_mem (); + + sprintf (uaever, "uae-%s", PACKAGE_VERSION); + + EXPANSION_uaeversion = ds (uaever); + EXPANSION_explibname = ds ("expansion.library"); + EXPANSION_doslibname = ds ("dos.library"); + EXPANSION_uaedevname = ds ("uae.device"); + + deftrap (NULL); /* Generic emulator trap */ + + EXPANSION_nullfunc = here (); + calltrap (deftrap (nullfunc)); + dw (RTS); a = here(); /* Standard "return from 68k mode" trap */ - org(0xF0FF00); + org (RTAREA_BASE + 0xFF00); calltrap (deftrap2 (m68k_mode_return, TRAPFLAG_NO_RETVAL, "")); - org (0xF0FF80); + org (RTAREA_BASE + 0xFF80); calltrap (deftrap2 (getchipmemsize, TRAPFLAG_DORET, "")); - org(a); + + org (RTAREA_BASE + 0xFF10); + calltrap (deftrap2 (uae_puts, TRAPFLAG_NO_RETVAL, "")); + dw (RTS); + + org (a); filesys_install_code (); }