Annotation of uae/src/autoconf.c, revision 1.1.1.11

1.1.1.3   root        1:  /*
1.1       root        2:   * UAE - The Un*x Amiga Emulator
1.1.1.3   root        3:   *
1.1       root        4:   * AutoConfig devices
                      5:   *
1.1.1.2   root        6:   * Copyright 1995, 1996 Bernd Schmidt
                      7:   * Copyright 1996 Ed Hanway
1.1       root        8:   */
                      9: 
                     10: #include "sysconfig.h"
                     11: #include "sysdeps.h"
                     12: 
                     13: #include "config.h"
                     14: #include "options.h"
1.1.1.3   root       15: #include "uae.h"
1.1       root       16: #include "memory.h"
                     17: #include "custom.h"
                     18: #include "newcpu.h"
                     19: #include "autoconf.h"
1.1.1.3   root       20: #include "osdep/exectasks.h"
1.1       root       21: 
1.1.1.2   root       22: /* We'll need a lot of these. */
                     23: #define MAX_TRAPS 4096
                     24: static TrapFunction traps[MAX_TRAPS];
1.1.1.3   root       25: static int trapmode[MAX_TRAPS];
1.1.1.2   root       26: static const char *trapstr[MAX_TRAPS];
1.1.1.3   root       27: static uaecptr trapoldfunc[MAX_TRAPS];
1.1.1.2   root       28: 
                     29: static int max_trap = 0;
                     30: int lasttrap;
                     31: 
1.1.1.3   root       32: /* Stack management */
                     33: 
                     34: /* The mechanism for doing m68k calls from native code is as follows:
                     35:  *
                     36:  * m68k code executes, stack is main
                     37:  * calltrap to execute_fn_on_extra_stack. new stack is allocated
                     38:  * do_stack_magic is called for the first time
                     39:  * current context is saved with setjmp [0]
                     40:  *  transfer_control is done
                     41:  *   native code executes on new stack
                     42:  *   native code calls call_m68k
                     43:  *   setjmp saves current context [1]
                     44:  *  longjmp back to execute_fn_on_extra_stack [0]
                     45:  * pointer to new stack is saved on m68k stack. m68k return address set
1.1.1.10  root       46:  * to RTAREA_BASE + 0xFF00. m68k PC set to called function
1.1.1.3   root       47:  * m68k function executes, stack is main
1.1.1.10  root       48:  * m68k function returns to RTAREA_BASE + 0xFF00
1.1.1.3   root       49:  * calltrap to m68k_mode_return
                     50:  * do_stack_magic is called again
                     51:  * current context is saved again with setjmp [0]
                     52:  *  this time, transfer_control is _not_ done, instead a longjmp[1]
                     53:  *  to the previously saved context
                     54:  *   native code executes again on temp stack
                     55:  *   native function returns to stack_stub
                     56:  *  longjmp[0] back to old context
                     57:  * back again!
                     58:  *
                     59:  * A bearded man enters the room, carrying a bowl of spaghetti.
                     60:  */
                     61: 
                     62: /* This _shouldn't_ crash with a stack size of 4096, but it does...
                     63:  * might be a bug */
                     64: #ifndef EXTRA_STACK_SIZE
                     65: #define EXTRA_STACK_SIZE 65536
                     66: #endif
                     67: 
                     68: static void *extra_stack_list = NULL;
                     69: 
1.1.1.4   root       70: static void *get_extra_stack (void)
1.1.1.3   root       71: {
                     72:     void *s = extra_stack_list;
                     73:     if (s)
                     74:        extra_stack_list = *(void **)s;
                     75:     if (!s)
                     76:        s = xmalloc (EXTRA_STACK_SIZE);
                     77:     return s;
1.1       root       78: }
                     79: 
1.1.1.3   root       80: static void free_extra_stack (void *s)
1.1       root       81: {
1.1.1.3   root       82:     *(void **)s = extra_stack_list;
                     83:     extra_stack_list = s;
1.1       root       84: }
                     85: 
1.1.1.3   root       86: static void stack_stub (void *s, TrapFunction f, uae_u32 *retval)
1.1       root       87: {
1.1.1.3   root       88: #ifdef CAN_DO_STACK_MAGIC
                     89:     /*printf("in stack_stub: %p %p %p %x\n", s, f, retval, (int)*retval);*/
1.1.1.4   root       90:     *retval = f ();
1.1.1.3   root       91:     /*write_log ("returning from stack_stub\n");*/
1.1.1.4   root       92:     longjmp (((jmp_buf *)s)[0], 1);
1.1.1.3   root       93: #endif
                     94: }
1.1       root       95: 
1.1.1.3   root       96: static void *current_extra_stack = NULL;
                     97: static uaecptr m68k_calladdr;
                     98: 
1.1.1.4   root       99: static void do_stack_magic (TrapFunction f, void *s, int has_retval)
1.1.1.3   root      100: {
                    101: #ifdef CAN_DO_STACK_MAGIC
                    102:     uaecptr a7;
                    103:     jmp_buf *j = (jmp_buf *)s;
1.1.1.4   root      104:     switch (setjmp (j[0])) {
1.1.1.3   root      105:      case 0:
                    106:        /* Returning directly */
                    107:        current_extra_stack = s;
                    108:        if (has_retval == -1) {
                    109:            /*write_log ("finishing m68k mode return\n");*/
1.1.1.4   root      110:            longjmp (j[1], 1);
1.1.1.3   root      111:        }
                    112:        /*write_log ("calling native function\n");*/
                    113:        transfer_control (s, EXTRA_STACK_SIZE, stack_stub, f, has_retval);
                    114:        /* not reached */
1.1.1.4   root      115:        abort ();
1.1.1.3   root      116: 
                    117:      case 1:
                    118:        /*write_log ("native function complete\n");*/
                    119:        /* Returning normally. */
                    120:        if (stack_has_retval (s, EXTRA_STACK_SIZE))
                    121:            m68k_dreg (regs, 0) = get_retval_from_stack (s, EXTRA_STACK_SIZE);
                    122:        free_extra_stack (s);
                    123:        break;
                    124: 
                    125:      case 2:
                    126:        /* Returning to do a m68k call. We're now back on the main stack. */
                    127:        a7 = m68k_areg(regs, 7) -= (sizeof (void *) + 7) & ~3;
                    128:        /* Save stack to restore */
                    129:        *((void **)get_real_address (a7 + 4)) = s;
                    130:        /* Save special return address: this address contains a
                    131:         * calltrap that will longjmp to the right stack. */
1.1.1.10  root      132:        put_long (m68k_areg (regs, 7), RTAREA_BASE + 0xFF00);
1.1.1.3   root      133:        m68k_setpc (m68k_calladdr);
1.1.1.11! root      134:        fill_prefetch_slow ();
1.1.1.3   root      135:        /*write_log ("native function calls m68k\n");*/
                    136:        break;
1.1       root      137:     }
1.1.1.3   root      138:     current_extra_stack = 0;
                    139: #endif
1.1       root      140: }
                    141: 
1.1.1.4   root      142: static uae_u32 execute_fn_on_extra_stack (TrapFunction f, int has_retval)
1.1       root      143: {
1.1.1.3   root      144: #ifdef CAN_DO_STACK_MAGIC
1.1.1.4   root      145:     void *s = get_extra_stack ();
1.1.1.3   root      146:     do_stack_magic (f, s, has_retval);
                    147: #endif
                    148:     return 0;
                    149: }
1.1.1.2   root      150: 
1.1.1.4   root      151: static uae_u32 m68k_mode_return (void)
1.1.1.3   root      152: {
                    153: #ifdef CAN_DO_STACK_MAGIC
                    154:     uaecptr a7 = m68k_areg(regs, 7);
                    155:     void *s = *(void **)get_real_address(a7);
                    156:     m68k_areg(regs, 7) += (sizeof (void *) + 3) & ~3;
                    157:     /*write_log ("doing m68k mode return\n");*/
                    158:     do_stack_magic (NULL, s, -1);
                    159: #endif
                    160:     return 0;
                    161: }
1.1.1.2   root      162: 
1.1.1.4   root      163: static uae_u32 call_m68k (uaecptr addr, int saveregs)
1.1.1.3   root      164: {
                    165:     volatile uae_u32 retval = 0;
                    166:     volatile int do_save = saveregs;
                    167:     if (current_extra_stack == NULL)
                    168:        abort();
                    169: #ifdef CAN_DO_STACK_MAGIC
                    170:     {
                    171:        volatile struct regstruct saved_regs;
                    172:        jmp_buf *j = (jmp_buf *)current_extra_stack;
                    173: 
                    174:        if (do_save)
                    175:            saved_regs = regs;
                    176:        m68k_calladdr = addr;
                    177:        switch (setjmp(j[1])) {
                    178:         case 0:
                    179:            /*write_log ("doing call\n");*/
                    180:            /* Returning directly: now switch to main stack and do the call */
                    181:            longjmp (j[0], 2);
                    182:         case 1:
                    183:            /*write_log ("returning from call\n");*/
                    184:            retval = m68k_dreg (regs, 0);
                    185:            if (do_save)
                    186:                regs = saved_regs;
                    187:            /* Returning after the call. */
1.1       root      188:            break;
1.1.1.3   root      189:        }
1.1       root      190:     }
1.1.1.3   root      191: #endif
1.1       root      192:     return retval;
                    193: }
                    194: 
1.1.1.4   root      195: uae_u32 CallLib (uaecptr base, uae_s16 offset)
1.1       root      196: {
1.1.1.3   root      197:     int i;
                    198:     uaecptr olda6 = m68k_areg(regs, 6);
                    199:     uae_u32 retval;
                    200: #if 0
                    201:     for (i = 0; i < n_libpatches; i++) {
                    202:        if (libpatches[i].libbase == base && libpatches[i].functions[-offset/6] != NULL)
                    203:            return (*libpatches[i].functions[-offset/6])();
                    204:     }
                    205: #endif
                    206:     m68k_areg(regs, 6) = base;
                    207:     retval = call_m68k(base + offset, 1);
                    208:     m68k_areg(regs, 6) = olda6;
                    209:     return retval;
1.1       root      210: }
                    211: 
                    212: /* Commonly used autoconfig strings */
                    213: 
1.1.1.3   root      214: uaecptr EXPANSION_explibname, EXPANSION_doslibname, EXPANSION_uaeversion;
                    215: uaecptr EXPANSION_uaedevname, EXPANSION_explibbase = 0, EXPANSION_haveV36;
                    216: uaecptr EXPANSION_bootcode, EXPANSION_nullfunc;
1.1.1.10  root      217: uaecptr EXPANSION_cddevice;
1.1       root      218: 
                    219: /* ROM tag area memory access */
                    220: 
1.1.1.9   root      221: static uae_u8 *rtarea;
1.1       root      222: 
1.1.1.4   root      223: static uae_u32 rtarea_lget (uaecptr) REGPARAM;
                    224: static uae_u32 rtarea_wget (uaecptr) REGPARAM;
                    225: static uae_u32 rtarea_bget (uaecptr) REGPARAM;
                    226: static void rtarea_lput (uaecptr, uae_u32) REGPARAM;
                    227: static void rtarea_wput (uaecptr, uae_u32) REGPARAM;
                    228: static void rtarea_bput (uaecptr, uae_u32) REGPARAM;
                    229: static uae_u8 *rtarea_xlate (uaecptr) REGPARAM;
1.1       root      230: 
                    231: addrbank rtarea_bank = {
                    232:     rtarea_lget, rtarea_wget, rtarea_bget,
                    233:     rtarea_lput, rtarea_wput, rtarea_bput,
1.1.1.9   root      234:     rtarea_xlate, default_check, NULL
1.1       root      235: };
                    236: 
1.1.1.4   root      237: uae_u8 REGPARAM2 *rtarea_xlate (uaecptr addr)
1.1       root      238: {
                    239:     addr &= 0xFFFF;
                    240:     return rtarea + addr;
                    241: }
                    242: 
1.1.1.4   root      243: uae_u32 REGPARAM2 rtarea_lget (uaecptr addr)
1.1       root      244: {
1.1.1.7   root      245:     special_mem |= S_READ;
1.1       root      246:     addr &= 0xFFFF;
1.1.1.4   root      247:     return (uae_u32)(rtarea_wget (addr) << 16) + rtarea_wget (addr+2);
1.1       root      248: }
                    249: 
1.1.1.4   root      250: uae_u32 REGPARAM2 rtarea_wget (uaecptr addr)
1.1       root      251: {
1.1.1.7   root      252:     special_mem |= S_READ;
1.1       root      253:     addr &= 0xFFFF;
                    254:     return (rtarea[addr]<<8) + rtarea[addr+1];
                    255: }
                    256: 
1.1.1.4   root      257: uae_u32 REGPARAM2 rtarea_bget (uaecptr addr)
1.1       root      258: {
1.1.1.7   root      259:     special_mem |= S_READ;
1.1       root      260:     addr &= 0xFFFF;
                    261:     return rtarea[addr];
                    262: }
                    263: 
1.1.1.7   root      264: void REGPARAM2 rtarea_lput (uaecptr addr, uae_u32 value)
                    265: {
                    266:     special_mem |= S_WRITE;
                    267: }
                    268: 
                    269: void REGPARAM2 rtarea_wput (uaecptr addr, uae_u32 value)
                    270: {
                    271:     special_mem |= S_WRITE;
                    272: }
                    273: 
                    274: void REGPARAM2 rtarea_bput (uaecptr addr, uae_u32 value)
                    275: {
                    276:     special_mem |= S_WRITE;
                    277: }
1.1       root      278: 
1.1.1.3   root      279: static int trace_traps = 1;
1.1       root      280: 
1.1.1.3   root      281: void REGPARAM2 call_calltrap(int func)
1.1       root      282: {
1.1.1.3   root      283:     uae_u32 retval = 0;
                    284:     int has_retval = (trapmode[func] & TRAPFLAG_NO_RETVAL) == 0;
                    285:     int implicit_rts = (trapmode[func] & TRAPFLAG_DORET) != 0;
1.1       root      286: 
1.1.1.4   root      287:     if (*trapstr[func] != 0 && trace_traps)
                    288:        write_log ("TRAP: %s\n", trapstr[func]);
1.1.1.2   root      289: 
                    290:     /* For monitoring only? */
1.1.1.3   root      291:     if (traps[func] == NULL) {
                    292:        m68k_setpc(trapoldfunc[func]);
1.1.1.11! root      293:        fill_prefetch_slow ();
1.1.1.2   root      294:        return;
                    295:     }
1.1.1.3   root      296: 
                    297:     if (func < max_trap) {
                    298:        if (trapmode[func] & TRAPFLAG_EXTRA_STACK) {
                    299:            execute_fn_on_extra_stack(traps[func], has_retval);
                    300:            return;
                    301:        }
                    302:        retval = (*traps[func])();
1.1.1.4   root      303:     } else
                    304:        write_log ("illegal emulator trap\n");
                    305: 
1.1.1.3   root      306:     if (has_retval)
1.1.1.2   root      307:        m68k_dreg(regs, 0) = retval;
1.1.1.3   root      308:     if (implicit_rts) {
                    309:        m68k_do_rts ();
1.1.1.11! root      310:        fill_prefetch_slow ();
1.1.1.2   root      311:     }
1.1       root      312: }
                    313: 
1.1.1.3   root      314: /* @$%&� compiler bugs */
                    315: static volatile int four = 4;
                    316: 
1.1.1.4   root      317: uaecptr libemu_InstallFunctionFlags (TrapFunction f, uaecptr libbase, int offset,
                    318:                                     int flags, const char *tracename)
1.1       root      319: {
1.1.1.3   root      320:     int i;
                    321:     uaecptr retval;
1.1.1.4   root      322:     uaecptr execbase = get_long (four);
1.1.1.3   root      323:     int trnum;
                    324:     uaecptr addr = here();
1.1.1.4   root      325:     calltrap (trnum = deftrap2 (f, flags, tracename));
                    326:     dw (RTS);
1.1.1.3   root      327: 
                    328:     m68k_areg(regs, 1) = libbase;
                    329:     m68k_areg(regs, 0) = offset;
                    330:     m68k_dreg(regs, 0) = addr;
1.1.1.4   root      331:     retval = CallLib (execbase, -420);
1.1.1.3   root      332: 
                    333:     trapoldfunc[trnum] = retval;
                    334: #if 0
                    335:     for (i = 0; i < n_libpatches; i++) {
                    336:        if (libpatches[i].libbase == libbase)
                    337:            break;
1.1       root      338:     }
1.1.1.3   root      339:     if (i == n_libpatches) {
                    340:        int j;
                    341:        libpatches[i].libbase = libbase;
                    342:        for (j = 0; j < 300; j++)
                    343:            libpatches[i].functions[j] = NULL;
                    344:        n_libpatches++;
1.1       root      345:     }
1.1.1.3   root      346:     libpatches[i].functions[-offset/6] = f;
                    347: #endif
                    348:     return retval;
1.1       root      349: }
                    350: 
                    351: /* some quick & dirty code to fill in the rt area and save me a lot of
                    352:  * scratch paper
                    353:  */
                    354: 
                    355: static int rt_addr = 0;
                    356: static int rt_straddr = 0xFF00 - 2;
                    357: 
1.1.1.4   root      358: uae_u32 addr (int ptr)
1.1       root      359: {
1.1.1.10  root      360:     return (uae_u32)ptr + RTAREA_BASE;
1.1       root      361: }
                    362: 
1.1.1.4   root      363: void db (uae_u8 data)
1.1.1.3   root      364: {
                    365:     rtarea[rt_addr++] = data;
                    366: }
                    367: 
1.1.1.4   root      368: void dw (uae_u16 data)
1.1       root      369: {
                    370:     rtarea[rt_addr++] = data >> 8;
                    371:     rtarea[rt_addr++] = data;
                    372: }
                    373: 
1.1.1.4   root      374: void dl (uae_u32 data)
1.1       root      375: {
                    376:     rtarea[rt_addr++] = data >> 24;
                    377:     rtarea[rt_addr++] = data >> 16;
                    378:     rtarea[rt_addr++] = data >> 8;
                    379:     rtarea[rt_addr++] = data;
                    380: }
                    381: 
                    382: /* store strings starting at the end of the rt area and working
                    383:  * backward.  store pointer at current address
                    384:  */
                    385: 
1.1.1.4   root      386: uae_u32 ds (char *str)
1.1       root      387: {
1.1.1.4   root      388:     int len = strlen (str) + 1;
1.1       root      389: 
                    390:     rt_straddr -= len;
1.1.1.4   root      391:     strcpy ((char *)rtarea + rt_straddr, str);
1.1.1.3   root      392: 
1.1.1.4   root      393:     return addr (rt_straddr);
1.1       root      394: }
                    395: 
1.1.1.4   root      396: void calltrap (uae_u32 n)
1.1       root      397: {
1.1.1.4   root      398:     dw (0xA000 + n);
1.1       root      399: }
                    400: 
1.1.1.4   root      401: void org (uae_u32 a)
1.1       root      402: {
1.1.1.10  root      403:     rt_addr = a - RTAREA_BASE;
1.1       root      404: }
                    405: 
1.1.1.4   root      406: uae_u32 here (void)
1.1       root      407: {
1.1.1.4   root      408:     return addr (rt_addr);
1.1       root      409: }
                    410: 
1.1.1.4   root      411: int deftrap2 (TrapFunction func, int mode, const char *str)
1.1       root      412: {
                    413:     int num = max_trap++;
                    414:     traps[num] = func;
1.1.1.3   root      415:     trapstr[num] = str;
                    416:     trapmode[num] = mode;
1.1       root      417:     return num;
                    418: }
                    419: 
1.1.1.4   root      420: int deftrap (TrapFunction func)
1.1       root      421: {
1.1.1.4   root      422:     return deftrap2 (func, 0, "");
1.1       root      423: }
                    424: 
1.1.1.4   root      425: void align (int b)
1.1       root      426: {
1.1.1.4   root      427:     rt_addr = (rt_addr + b - 1) & ~(b - 1);
1.1       root      428: }
                    429: 
1.1.1.3   root      430: static uae_u32 nullfunc(void)
1.1       root      431: {
1.1.1.10  root      432:     write_log ("Null function called\n");
1.1.1.3   root      433:     return 0;
1.1.1.2   root      434: }
                    435: 
1.1.1.3   root      436: static uae_u32 getchipmemsize (void)
1.1.1.2   root      437: {
1.1.1.4   root      438:     return allocated_chipmem;
1.1       root      439: }
                    440: 
1.1.1.8   root      441: static uae_u32 uae_puts (void)
                    442: {
                    443:     puts (get_real_address (m68k_areg (regs, 0)));
                    444:     return 0;
                    445: }
                    446: 
1.1.1.9   root      447: static void rtarea_init_mem (void)
                    448: {
                    449:     rtarea = mapped_malloc (0x10000, "rtarea");
                    450:     if (!rtarea) {
                    451:        write_log ("virtual memory exhausted (rtarea)!\n");
                    452:        abort ();
                    453:     }
                    454:     rtarea_bank.baseaddr = rtarea;
                    455: }
                    456: 
1.1.1.4   root      457: void rtarea_init (void)
1.1       root      458: {
1.1.1.3   root      459:     uae_u32 a;
1.1       root      460:     char uaever[100];
1.1.1.9   root      461: 
                    462:     rtarea_init_mem ();
                    463: 
1.1.1.4   root      464:     sprintf (uaever, "uae-%d.%d.%d", UAEMAJOR, UAEMINOR, UAESUBREV);
1.1       root      465: 
1.1.1.4   root      466:     EXPANSION_uaeversion = ds (uaever);
                    467:     EXPANSION_explibname = ds ("expansion.library");
                    468:     EXPANSION_doslibname = ds ("dos.library");
                    469:     EXPANSION_uaedevname = ds ("uae.device");
1.1       root      470: 
1.1.1.4   root      471:     deftrap (NULL); /* Generic emulator trap */
1.1       root      472:     lasttrap = 0;
                    473: 
1.1.1.4   root      474:     EXPANSION_nullfunc = here ();
                    475:     calltrap (deftrap (nullfunc));
                    476:     dw (RTS);
1.1.1.3   root      477: 
1.1.1.2   root      478:     a = here();
1.1       root      479:     /* Standard "return from 68k mode" trap */
1.1.1.10  root      480:     org (RTAREA_BASE + 0xFF00);
1.1.1.3   root      481:     calltrap (deftrap2 (m68k_mode_return, TRAPFLAG_NO_RETVAL, ""));
                    482: 
1.1.1.10  root      483:     org (RTAREA_BASE + 0xFF80);
1.1.1.3   root      484:     calltrap (deftrap2 (getchipmemsize, TRAPFLAG_DORET, ""));
1.1.1.8   root      485: 
1.1.1.10  root      486:     org (RTAREA_BASE + 0xFF10);
1.1.1.8   root      487:     calltrap (deftrap2 (uae_puts, TRAPFLAG_NO_RETVAL, ""));
                    488:     dw (RTS);
                    489: 
1.1.1.4   root      490:     org (a);
1.1.1.2   root      491: 
1.1.1.3   root      492:     filesys_install_code ();
                    493: }
1.1.1.2   root      494: 
1.1.1.3   root      495: volatile int uae_int_requested = 0;
1.1.1.2   root      496: 
1.1.1.3   root      497: void set_uae_int_flag (void)
                    498: {
                    499:     rtarea[0xFFFB] = uae_int_requested;
1.1.1.2   root      500: }
                    501: 
                    502: void rtarea_setup(void)
                    503: {
                    504: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.