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

1.1     ! root        1:  /* 
        !             2:   * UAE - The Un*x Amiga Emulator
        !             3:   * 
        !             4:   * AutoConfig devices
        !             5:   *
        !             6:   * (c) 1995 Bernd Schmidt
        !             7:   * (c) 1996 Ed Hanway
        !             8:   */
        !             9: 
        !            10: #include "sysconfig.h"
        !            11: #include "sysdeps.h"
        !            12: 
        !            13: #include "config.h"
        !            14: #include "options.h"
        !            15: #include "memory.h"
        !            16: #include "custom.h"
        !            17: #include "newcpu.h"
        !            18: #include "disk.h"
        !            19: #include "xwin.h"
        !            20: #include "autoconf.h"
        !            21: 
        !            22: static struct {
        !            23:     CPTR libbase;
        !            24:     TrapFunction functions[300]; /* I don't think any library has more than 300 functions */
        !            25: } libpatches[20];
        !            26: static int n_libpatches = 0;
        !            27: 
        !            28: ULONG Call68k_retaddr(CPTR address, int saveregs, CPTR retaddr)
        !            29: {
        !            30:     ULONG retval;
        !            31:     CPTR oldpc = m68k_getpc();
        !            32: 
        !            33:     struct regstruct backup_regs;
        !            34:     if (saveregs)
        !            35:        backup_regs = regs;
        !            36:     regs.a[7] -= 4;
        !            37:     put_long (regs.a[7], retaddr);
        !            38:     m68k_setpc(address);
        !            39:     m68k_go(0);
        !            40:     retval = regs.d[0];
        !            41:     if (saveregs)
        !            42:        regs = backup_regs;
        !            43:     m68k_setpc(oldpc);
        !            44:     return retval;
        !            45: }
        !            46: 
        !            47: ULONG Call68k(CPTR address, int saveregs)
        !            48: {
        !            49:     return Call68k_retaddr(address, saveregs, 0xF0FFF0);
        !            50: }
        !            51: 
        !            52: ULONG CallLib(CPTR base, WORD offset)
        !            53: {
        !            54:     int i;    
        !            55:     CPTR olda6 = regs.a[6];
        !            56:     ULONG retval;
        !            57: 
        !            58:     for (i = 0; i < n_libpatches; i++) {
        !            59:        if (libpatches[i].libbase == base && libpatches[i].functions[-offset/6] != NULL)
        !            60:            return (*libpatches[i].functions[-offset/6])();
        !            61:     }
        !            62:     
        !            63:     regs.a[6] = base;
        !            64:     retval = Call68k(base + offset, 1);
        !            65:     regs.a[6] = olda6;
        !            66:     return retval;
        !            67: }
        !            68: 
        !            69: /* @$%&� compiler bugs */
        !            70: static volatile int four = 4;
        !            71: 
        !            72: CPTR libemu_InstallFunctionFlags(TrapFunction f, CPTR libbase, int offset,
        !            73:                                 int flags)
        !            74: {
        !            75:     int i;
        !            76:     CPTR retval;
        !            77:     CPTR execbase = get_long(four);
        !            78:     ULONG addr = here();
        !            79:     calltrap2(deftrap2(f, flags));
        !            80:     dw(RTS);
        !            81:     
        !            82:     regs.a[1] = libbase;
        !            83:     regs.a[0] = offset;
        !            84:     regs.d[0] = addr;
        !            85:     retval = CallLib(execbase, -420);
        !            86:     for (i = 0; i < n_libpatches; i++) {
        !            87:        if (libpatches[i].libbase == libbase)
        !            88:            break;
        !            89:     }
        !            90:     if (i == n_libpatches) {
        !            91:        int j;
        !            92:        libpatches[i].libbase = libbase;
        !            93:        for (j = 0; j < 300; j++)
        !            94:            libpatches[i].functions[j] = NULL;
        !            95:        n_libpatches++;
        !            96:     }
        !            97:     libpatches[i].functions[-offset/6] = f;
        !            98:     return retval;
        !            99: }
        !           100: 
        !           101: CPTR libemu_InstallFunction(TrapFunction f, CPTR libbase, int offset)
        !           102: {
        !           103:     return libemu_InstallFunctionFlags(f, libbase, offset, 0);
        !           104: }
        !           105: 
        !           106: /* Commonly used autoconfig strings */
        !           107: 
        !           108: CPTR EXPANSION_explibname, EXPANSION_doslibname, EXPANSION_uaeversion;
        !           109: CPTR EXPANSION_uaedevname, EXPANSION_explibbase = 0, EXPANSION_haveV36;
        !           110: CPTR EXPANSION_bootcode;
        !           111: 
        !           112: static int current_deviceno = 0;
        !           113: 
        !           114: int get_new_device(char **devname, CPTR *devname_amiga)
        !           115: {
        !           116:     char buffer[80];
        !           117:     
        !           118:     sprintf(buffer,"UAE%d", current_deviceno);
        !           119: 
        !           120:     *devname_amiga = ds(*devname = strdup(buffer));
        !           121:     return current_deviceno++;
        !           122: }
        !           123: 
        !           124: /* ROM tag area memory access */
        !           125: 
        !           126: static UBYTE rtarea[65536];
        !           127: 
        !           128: static ULONG rtarea_lget(CPTR) REGPARAM;
        !           129: static UWORD rtarea_wget(CPTR) REGPARAM;
        !           130: static UBYTE rtarea_bget(CPTR) REGPARAM;
        !           131: static void  rtarea_lput(CPTR, ULONG) REGPARAM;
        !           132: static void  rtarea_wput(CPTR, UWORD) REGPARAM;
        !           133: static void  rtarea_bput(CPTR, UBYTE) REGPARAM;
        !           134: static UBYTE *rtarea_xlate(CPTR) REGPARAM;
        !           135: 
        !           136: addrbank rtarea_bank = {
        !           137:     rtarea_lget, rtarea_wget,
        !           138:     rtarea_lget, rtarea_wget, rtarea_bget,
        !           139:     rtarea_lput, rtarea_wput, rtarea_bput,
        !           140:     rtarea_xlate, default_check
        !           141: };
        !           142: 
        !           143: UBYTE *rtarea_xlate(CPTR addr)
        !           144: {
        !           145:     addr &= 0xFFFF;
        !           146:     return rtarea + addr;
        !           147: }
        !           148: 
        !           149: ULONG rtarea_lget(CPTR addr)
        !           150: {
        !           151:     addr &= 0xFFFF;
        !           152:     return (ULONG)(rtarea_wget(addr) << 16) + rtarea_wget(addr+2);
        !           153: }
        !           154: 
        !           155: UWORD rtarea_wget(CPTR addr)
        !           156: {
        !           157:     addr &= 0xFFFF;
        !           158:     return (rtarea[addr]<<8) + rtarea[addr+1];
        !           159: }
        !           160: 
        !           161: UBYTE rtarea_bget(CPTR addr)
        !           162: {
        !           163:     UWORD data;
        !           164:     addr &= 0xFFFF;
        !           165:     return rtarea[addr];
        !           166: }
        !           167: 
        !           168: void rtarea_lput(CPTR addr, ULONG value) { }
        !           169: void rtarea_bput(CPTR addr, UBYTE value) { }
        !           170: 
        !           171: /* Don't start at 0 -- can get bogus writes there. */
        !           172: static ULONG trap_base_addr = 0x00F00180;
        !           173: 
        !           174: /* We'll need a lot of these. */
        !           175: TrapFunction traps[16384];
        !           176: char trapmode[16384];
        !           177: 
        !           178: static int max_trap = 0;
        !           179: 
        !           180: int lasttrap;
        !           181: 
        !           182: void do_emultrap(int tr)
        !           183: {
        !           184:     struct regstruct backup_regs;
        !           185:     ULONG retval;
        !           186: 
        !           187:     if ((trapmode[tr] & 1) == 0)
        !           188:        backup_regs = regs;
        !           189:     retval = (*traps[tr])();
        !           190:     if ((trapmode[tr] & 1) == 0)
        !           191:         regs = backup_regs;
        !           192:     if ((trapmode[tr] & 2) == 0)
        !           193:        regs.d[0] = retval;
        !           194: }
        !           195: 
        !           196: void rtarea_wput(CPTR addr, UWORD value) 
        !           197: {
        !           198:     /* Save all registers */
        !           199:     struct regstruct backup_regs;
        !           200:     ULONG retval = 0;
        !           201:     ULONG func = ((addr  - trap_base_addr) & 0xFFFF) >> 1;
        !           202: 
        !           203:     if (func == 0) {
        !           204:        lasttrap = get_long(regs.a[7]);
        !           205:        regs.a[7] += 4;
        !           206:        regs.spcflags |= SPCFLAG_EMULTRAP;
        !           207:        return;
        !           208:     }
        !           209:     
        !           210:     backup_regs = regs;
        !           211:     if(func < max_trap) {
        !           212:        retval = (*traps[func])();
        !           213:     } else {
        !           214:        fprintf(stderr, "illegal emulator trap\n");
        !           215:     }
        !           216:     regs = backup_regs;
        !           217:     regs.d[0] = retval;
        !           218: }
        !           219: 
        !           220: /* some quick & dirty code to fill in the rt area and save me a lot of
        !           221:  * scratch paper
        !           222:  */
        !           223: 
        !           224: static int rt_addr = 0;
        !           225: static int rt_straddr = 0xFF00 - 2;
        !           226: 
        !           227: ULONG addr(int ptr)
        !           228: {
        !           229:     return (ULONG)ptr + 0x00F00000;
        !           230: }
        !           231: 
        !           232: void dw(UWORD data)
        !           233: {
        !           234:     rtarea[rt_addr++] = data >> 8;
        !           235:     rtarea[rt_addr++] = data;
        !           236: }
        !           237: 
        !           238: void dl(ULONG data)
        !           239: {
        !           240:     rtarea[rt_addr++] = data >> 24;
        !           241:     rtarea[rt_addr++] = data >> 16;
        !           242:     rtarea[rt_addr++] = data >> 8;
        !           243:     rtarea[rt_addr++] = data;
        !           244: }
        !           245: 
        !           246: /* store strings starting at the end of the rt area and working
        !           247:  * backward.  store pointer at current address
        !           248:  */
        !           249: 
        !           250: ULONG ds(char *str)
        !           251: {
        !           252:     int len = strlen(str) + 1;
        !           253: 
        !           254:     rt_straddr -= len;
        !           255:     strcpy(rtarea + rt_straddr, str);
        !           256:     
        !           257:     return addr(rt_straddr);
        !           258: }
        !           259: 
        !           260: void calltrap2(ULONG n)
        !           261: {
        !           262:     dw(0x4878); /* PEA.L n.w */
        !           263:     dw(n);
        !           264:     /* Call trap #0 is reserved for this */
        !           265:     dw(0x33C0);        /* MOVE.W D0,abs32 */
        !           266:     dl(trap_base_addr);
        !           267: }
        !           268: 
        !           269: void calltrap(ULONG n)
        !           270: {
        !           271: #if 1
        !           272:     dw(0x33C0);        /* MOVE.W D0,abs32 */
        !           273:     dl(n*2 + trap_base_addr);
        !           274: #else
        !           275:     calltrap2(n);
        !           276: #endif
        !           277: }
        !           278: 
        !           279: void org(ULONG a)
        !           280: {
        !           281:     rt_addr = a - 0x00F00000;
        !           282: }
        !           283: 
        !           284: ULONG here(void)
        !           285: {
        !           286:     return addr(rt_addr);
        !           287: }
        !           288: 
        !           289: int deftrap(TrapFunction func)
        !           290: {
        !           291:     int num = max_trap++;
        !           292:     traps[num] = func;
        !           293:     trapmode[num] = 0;
        !           294:     return num;
        !           295: }
        !           296: 
        !           297: int deftrap2(TrapFunction func, int mode)
        !           298: {
        !           299:     int num = max_trap++;
        !           300:     traps[num] = func;
        !           301:     trapmode[num] = mode;
        !           302:     return num;
        !           303: }
        !           304: 
        !           305: void align(int b)
        !           306: {
        !           307:     rt_addr = (rt_addr + (b-1)) & ~(b-1);
        !           308: }
        !           309: 
        !           310: static ULONG bootcode(void)
        !           311: {
        !           312:     regs.a[1] = EXPANSION_doslibname;
        !           313:     regs.d[0] = CallLib (regs.a[6], -96); /* FindResident() */
        !           314:     regs.a[0] = get_long(regs.d[0]+22); /* get dos.library rt_init */
        !           315:     return regs.a[0];
        !           316: }
        !           317: 
        !           318: void rtarea_init()
        !           319: {
        !           320:     ULONG a;
        !           321:     char uaever[100];
        !           322:     sprintf(uaever, "uae-%d.%d.%d", (version / 100) % 10, (version / 10) % 10, (version / 1) % 10);
        !           323: 
        !           324:     EXPANSION_uaeversion = ds(uaever);
        !           325:     EXPANSION_explibname = ds("expansion.library");
        !           326:     EXPANSION_doslibname = ds("dos.library");
        !           327:     EXPANSION_uaedevname = ds("uae.device");
        !           328: 
        !           329:     deftrap(NULL); /* Generic emulator trap */
        !           330:     lasttrap = 0;
        !           331: 
        !           332:     align(4);
        !           333:     EXPANSION_bootcode = here();
        !           334:     calltrap2(deftrap2(bootcode, 1));
        !           335:     dw(0x2040);                        /* move.l d0,a0 */
        !           336:     dw(0x4e90);                 /* jsr (a0) */
        !           337:     dw(RTS);
        !           338: 
        !           339:     a = here();
        !           340: 
        !           341:     /* Idle task */
        !           342:     org(0xF0FFF0 - 4);
        !           343:     dw(0x4E72); dw (0x2000); /* STOP 0x2000 */
        !           344:     
        !           345:     /* Standard "return from 68k mode" trap */
        !           346:     /*org(0xF0FFF0); */
        !           347:     calltrap2(0);
        !           348:     dw(RTS);
        !           349:     org(a);
        !           350: }

unix.superglobalmegacorp.com

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