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

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

unix.superglobalmegacorp.com

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