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

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