Annotation of uae/src/autoconf.c, revision 1.1.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.