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

1.1       root        1:  /* 
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      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       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"
                     20: #include "disk.h"
                     21: #include "xwin.h"
                     22: #include "autoconf.h"
                     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];
        !            27: static char trapmode[MAX_TRAPS];
        !            28: static const char *trapstr[MAX_TRAPS];
        !            29: static CPTR trapoldfunc[MAX_TRAPS];
        !            30: 
        !            31: static int max_trap = 0;
        !            32: static int trace_traps = 0;
        !            33: int lasttrap;
        !            34: 
1.1       root       35: static struct {
                     36:     CPTR libbase;
                     37:     TrapFunction functions[300]; /* I don't think any library has more than 300 functions */
                     38: } libpatches[20];
                     39: static int n_libpatches = 0;
                     40: 
                     41: ULONG Call68k_retaddr(CPTR address, int saveregs, CPTR retaddr)
                     42: {
                     43:     ULONG retval;
                     44:     CPTR oldpc = m68k_getpc();
                     45: 
                     46:     struct regstruct backup_regs;
1.1.1.2 ! root       47:     struct flag_struct backup_flags;
        !            48:     
        !            49:     if (saveregs) {
1.1       root       50:        backup_regs = regs;
1.1.1.2 ! root       51:        backup_flags = regflags;
        !            52:     }
        !            53:     m68k_areg(regs, 7) -= 4;
        !            54:     put_long (m68k_areg(regs, 7), retaddr);
1.1       root       55:     m68k_setpc(address);
                     56:     m68k_go(0);
1.1.1.2 ! root       57:     retval = m68k_dreg(regs, 0);
        !            58:     if (saveregs) {
1.1       root       59:        regs = backup_regs;
1.1.1.2 ! root       60:        regflags = backup_flags;
        !            61:     }
1.1       root       62:     m68k_setpc(oldpc);
                     63:     return retval;
                     64: }
                     65: 
                     66: ULONG Call68k(CPTR address, int saveregs)
                     67: {
                     68:     return Call68k_retaddr(address, saveregs, 0xF0FFF0);
                     69: }
                     70: 
                     71: ULONG CallLib(CPTR base, WORD offset)
                     72: {
                     73:     int i;    
1.1.1.2 ! root       74:     CPTR olda6 = m68k_areg(regs, 6);
1.1       root       75:     ULONG retval;
                     76: 
                     77:     for (i = 0; i < n_libpatches; i++) {
                     78:        if (libpatches[i].libbase == base && libpatches[i].functions[-offset/6] != NULL)
                     79:            return (*libpatches[i].functions[-offset/6])();
                     80:     }
                     81:     
1.1.1.2 ! root       82:     m68k_areg(regs, 6) = base;
1.1       root       83:     retval = Call68k(base + offset, 1);
1.1.1.2 ! root       84:     m68k_areg(regs, 6) = olda6;
1.1       root       85:     return retval;
                     86: }
                     87: 
                     88: /* @$%&� compiler bugs */
                     89: static volatile int four = 4;
                     90: 
                     91: CPTR libemu_InstallFunctionFlags(TrapFunction f, CPTR libbase, int offset,
1.1.1.2 ! root       92:                                 int flags, const char *tracename)
1.1       root       93: {
                     94:     int i;
                     95:     CPTR retval;
                     96:     CPTR execbase = get_long(four);
1.1.1.2 ! root       97:     int trnum;
1.1       root       98:     ULONG addr = here();
1.1.1.2 ! root       99:     calltrap2(trnum = deftrap2(f, flags, tracename));
1.1       root      100:     dw(RTS);
                    101:     
1.1.1.2 ! root      102:     m68k_areg(regs, 1) = libbase;
        !           103:     m68k_areg(regs, 0) = offset;
        !           104:     m68k_dreg(regs, 0) = addr;
1.1       root      105:     retval = CallLib(execbase, -420);
1.1.1.2 ! root      106: 
        !           107:     trapoldfunc[trnum] = retval;
        !           108: 
1.1       root      109:     for (i = 0; i < n_libpatches; i++) {
                    110:        if (libpatches[i].libbase == libbase)
                    111:            break;
                    112:     }
                    113:     if (i == n_libpatches) {
                    114:        int j;
                    115:        libpatches[i].libbase = libbase;
                    116:        for (j = 0; j < 300; j++)
                    117:            libpatches[i].functions[j] = NULL;
                    118:        n_libpatches++;
                    119:     }
                    120:     libpatches[i].functions[-offset/6] = f;
                    121:     return retval;
                    122: }
                    123: 
1.1.1.2 ! root      124: CPTR libemu_InstallFunction(TrapFunction f, CPTR libbase, int offset,
        !           125:                            const char *tracename)
1.1       root      126: {
1.1.1.2 ! root      127:     return libemu_InstallFunctionFlags(f, libbase, offset, 0, tracename);
1.1       root      128: }
                    129: 
                    130: /* Commonly used autoconfig strings */
                    131: 
                    132: CPTR EXPANSION_explibname, EXPANSION_doslibname, EXPANSION_uaeversion;
                    133: CPTR EXPANSION_uaedevname, EXPANSION_explibbase = 0, EXPANSION_haveV36;
1.1.1.2 ! root      134: CPTR EXPANSION_bootcode, EXPANSION_nullfunc;
1.1       root      135: 
                    136: static int current_deviceno = 0;
                    137: 
                    138: int get_new_device(char **devname, CPTR *devname_amiga)
                    139: {
                    140:     char buffer[80];
                    141:     
                    142:     sprintf(buffer,"UAE%d", current_deviceno);
                    143: 
1.1.1.2 ! root      144:     *devname_amiga = ds(*devname = my_strdup(buffer));
1.1       root      145:     return current_deviceno++;
                    146: }
                    147: 
                    148: /* ROM tag area memory access */
                    149: 
                    150: static UBYTE rtarea[65536];
                    151: 
                    152: static ULONG rtarea_lget(CPTR) REGPARAM;
1.1.1.2 ! root      153: static ULONG rtarea_wget(CPTR) REGPARAM;
        !           154: static ULONG rtarea_bget(CPTR) REGPARAM;
1.1       root      155: static void  rtarea_lput(CPTR, ULONG) REGPARAM;
1.1.1.2 ! root      156: static void  rtarea_wput(CPTR, ULONG) REGPARAM;
        !           157: static void  rtarea_bput(CPTR, ULONG) REGPARAM;
1.1       root      158: static UBYTE *rtarea_xlate(CPTR) REGPARAM;
                    159: 
                    160: addrbank rtarea_bank = {
                    161:     rtarea_lget, rtarea_wget,
                    162:     rtarea_lget, rtarea_wget, rtarea_bget,
                    163:     rtarea_lput, rtarea_wput, rtarea_bput,
                    164:     rtarea_xlate, default_check
                    165: };
                    166: 
1.1.1.2 ! root      167: UBYTE REGPARAM2 *rtarea_xlate(CPTR addr) 
1.1       root      168: {
                    169:     addr &= 0xFFFF;
                    170:     return rtarea + addr;
                    171: }
                    172: 
1.1.1.2 ! root      173: ULONG REGPARAM2 rtarea_lget(CPTR addr)
1.1       root      174: {
                    175:     addr &= 0xFFFF;
                    176:     return (ULONG)(rtarea_wget(addr) << 16) + rtarea_wget(addr+2);
                    177: }
                    178: 
1.1.1.2 ! root      179: ULONG REGPARAM2 rtarea_wget(CPTR addr)
1.1       root      180: {
                    181:     addr &= 0xFFFF;
                    182:     return (rtarea[addr]<<8) + rtarea[addr+1];
                    183: }
                    184: 
1.1.1.2 ! root      185: ULONG REGPARAM2 rtarea_bget(CPTR addr)
1.1       root      186: {
                    187:     UWORD data;
                    188:     addr &= 0xFFFF;
                    189:     return rtarea[addr];
                    190: }
                    191: 
1.1.1.2 ! root      192: void REGPARAM2 rtarea_lput(CPTR addr, ULONG value) { }
        !           193: void REGPARAM2 rtarea_bput(CPTR addr, ULONG value) { }
1.1       root      194: 
                    195: /* Don't start at 0 -- can get bogus writes there. */
                    196: static ULONG trap_base_addr = 0x00F00180;
                    197: 
                    198: void do_emultrap(int tr)
                    199: {
                    200:     struct regstruct backup_regs;
                    201:     ULONG retval;
                    202: 
1.1.1.2 ! root      203:     if (*trapstr[tr] != 0 && trace_traps)
        !           204:        fprintf(stderr, "TRAP: %s\n", trapstr[tr]);
        !           205: 
        !           206:     /* For monitoring only? */
        !           207:     if (traps[tr] == NULL) {
        !           208:        Call68k(trapoldfunc[tr], 0);
        !           209:        if (*trapstr[tr] != 0 && trace_traps)
        !           210:            fprintf(stderr, "RET : %s\n", trapstr[tr]);
        !           211:        return;
        !           212:     }
        !           213:     
        !           214:     if ((trapmode[tr] & TRAPFLAG_NOREGSAVE) == 0)
1.1       root      215:        backup_regs = regs;
1.1.1.2 ! root      216:     
1.1       root      217:     retval = (*traps[tr])();
1.1.1.2 ! root      218:     
        !           219:     if ((trapmode[tr] & TRAPFLAG_NOREGSAVE) == 0)
1.1       root      220:         regs = backup_regs;
1.1.1.2 ! root      221:     if ((trapmode[tr] & TRAPFLAG_NORETVAL) == 0) {
        !           222:        m68k_dreg(regs, 0) = retval;
        !           223:     }
1.1       root      224: }
                    225: 
1.1.1.2 ! root      226: void REGPARAM2 rtarea_wput(CPTR addr, ULONG value)
1.1       root      227: {
                    228:     /* Save all registers */
                    229:     struct regstruct backup_regs;
                    230:     ULONG retval = 0;
                    231:     ULONG func = ((addr  - trap_base_addr) & 0xFFFF) >> 1;
                    232: 
                    233:     if (func == 0) {
1.1.1.2 ! root      234:        lasttrap = get_long(m68k_areg(regs, 7));
        !           235:        m68k_areg(regs, 7) += 4;
1.1       root      236:        regs.spcflags |= SPCFLAG_EMULTRAP;
                    237:        return;
                    238:     }
                    239:     
                    240:     backup_regs = regs;
                    241:     if(func < max_trap) {
                    242:        retval = (*traps[func])();
                    243:     } else {
                    244:        fprintf(stderr, "illegal emulator trap\n");
                    245:     }
                    246:     regs = backup_regs;
1.1.1.2 ! root      247:     m68k_dreg(regs, 0) = retval;
1.1       root      248: }
                    249: 
                    250: /* some quick & dirty code to fill in the rt area and save me a lot of
                    251:  * scratch paper
                    252:  */
                    253: 
                    254: static int rt_addr = 0;
                    255: static int rt_straddr = 0xFF00 - 2;
                    256: 
                    257: ULONG addr(int ptr)
                    258: {
                    259:     return (ULONG)ptr + 0x00F00000;
                    260: }
                    261: 
                    262: void dw(UWORD data)
                    263: {
                    264:     rtarea[rt_addr++] = data >> 8;
                    265:     rtarea[rt_addr++] = data;
                    266: }
                    267: 
                    268: void dl(ULONG data)
                    269: {
                    270:     rtarea[rt_addr++] = data >> 24;
                    271:     rtarea[rt_addr++] = data >> 16;
                    272:     rtarea[rt_addr++] = data >> 8;
                    273:     rtarea[rt_addr++] = data;
                    274: }
                    275: 
                    276: /* store strings starting at the end of the rt area and working
                    277:  * backward.  store pointer at current address
                    278:  */
                    279: 
                    280: ULONG ds(char *str)
                    281: {
                    282:     int len = strlen(str) + 1;
                    283: 
                    284:     rt_straddr -= len;
1.1.1.2 ! root      285:     strcpy((char *)rtarea + rt_straddr, str);
1.1       root      286:     
                    287:     return addr(rt_straddr);
                    288: }
                    289: 
                    290: void calltrap2(ULONG n)
                    291: {
                    292:     dw(0x4878); /* PEA.L n.w */
                    293:     dw(n);
                    294:     /* Call trap #0 is reserved for this */
                    295:     dw(0x33C0);        /* MOVE.W D0,abs32 */
                    296:     dl(trap_base_addr);
                    297: }
                    298: 
                    299: void calltrap(ULONG n)
                    300: {
                    301: #if 1
                    302:     dw(0x33C0);        /* MOVE.W D0,abs32 */
                    303:     dl(n*2 + trap_base_addr);
                    304: #else
                    305:     calltrap2(n);
                    306: #endif
                    307: }
                    308: 
                    309: void org(ULONG a)
                    310: {
                    311:     rt_addr = a - 0x00F00000;
                    312: }
                    313: 
                    314: ULONG here(void)
                    315: {
                    316:     return addr(rt_addr);
                    317: }
                    318: 
                    319: int deftrap(TrapFunction func)
                    320: {
                    321:     int num = max_trap++;
                    322:     traps[num] = func;
                    323:     trapmode[num] = 0;
1.1.1.2 ! root      324:     trapstr[num] = "";
1.1       root      325:     return num;
                    326: }
                    327: 
1.1.1.2 ! root      328: int deftrap2(TrapFunction func, int mode, const char *str)
1.1       root      329: {
                    330:     int num = max_trap++;
                    331:     traps[num] = func;
                    332:     trapmode[num] = mode;
1.1.1.2 ! root      333:     trapstr[num] = str;
1.1       root      334:     return num;
                    335: }
                    336: 
                    337: void align(int b)
                    338: {
                    339:     rt_addr = (rt_addr + (b-1)) & ~(b-1);
                    340: }
                    341: 
                    342: static ULONG bootcode(void)
                    343: {
1.1.1.2 ! root      344:     m68k_areg(regs, 1) = EXPANSION_doslibname;
        !           345:     m68k_dreg(regs, 0) = CallLib (m68k_areg(regs, 6), -96); /* FindResident() */
        !           346:     m68k_areg(regs, 0) = get_long(m68k_dreg(regs, 0) + 22); /* get dos.library rt_init */
        !           347:     return m68k_areg(regs, 0);
        !           348: }
        !           349: 
        !           350: static ULONG nullfunc(void)
        !           351: {
        !           352:     fprintf(stderr, "Null function called\n");
        !           353:     return 0;
1.1       root      354: }
                    355: 
                    356: void rtarea_init()
                    357: {
                    358:     ULONG a;
                    359:     char uaever[100];
                    360:     sprintf(uaever, "uae-%d.%d.%d", (version / 100) % 10, (version / 10) % 10, (version / 1) % 10);
                    361: 
                    362:     EXPANSION_uaeversion = ds(uaever);
                    363:     EXPANSION_explibname = ds("expansion.library");
                    364:     EXPANSION_doslibname = ds("dos.library");
                    365:     EXPANSION_uaedevname = ds("uae.device");
                    366: 
                    367:     deftrap(NULL); /* Generic emulator trap */
                    368:     lasttrap = 0;
                    369: 
                    370:     align(4);
                    371:     EXPANSION_bootcode = here();
1.1.1.2 ! root      372:     calltrap2(deftrap2(bootcode, 1, ""));
1.1       root      373:     dw(0x2040);                        /* move.l d0,a0 */
                    374:     dw(0x4e90);                 /* jsr (a0) */
                    375:     dw(RTS);
                    376: 
1.1.1.2 ! root      377:     EXPANSION_nullfunc = here();
        !           378:     calltrap(deftrap(nullfunc));
        !           379:     dw(RTS);
1.1       root      380:     
1.1.1.2 ! root      381:     a = here();
1.1       root      382:     /* Standard "return from 68k mode" trap */
1.1.1.2 ! root      383:     org(0xF0FFF0);
1.1       root      384:     calltrap2(0);
                    385:     dw(RTS);
                    386:     org(a);
                    387: }
1.1.1.2 ! root      388: 
        !           389: static ULONG hyperchip_init(void)
        !           390: {
        !           391: #if 0 /* This doesn't work either. Arrrgh!! */
        !           392:     CPTR execbase = get_long(4);
        !           393:     CPTR memlist = execbase + 322;
        !           394:     CPTR memh;
        !           395:     
        !           396:     for (;;) {
        !           397:        memh = get_long(memlist);
        !           398:        if (get_long(memh) == 0) {
        !           399:            fprintf(stderr, "No chip memory !?!??\n");
        !           400:            return 0;
        !           401:        }
        !           402: 
        !           403:        if (get_word(memh + 14) == 3)
        !           404:            break;
        !           405: 
        !           406:        memlist = memh;
        !           407:     }
        !           408:     put_long(memh + 24, get_long(memh + 24) + chipmem_size - 0x200000);
        !           409:     put_long(memh + 28, get_long(memh + 28) + chipmem_size - 0x200000);
        !           410:     memlist = memh + 16;
        !           411:     for (;;) {
        !           412:        memh = get_long(memlist);
        !           413:        if (memh == 0)
        !           414:            break;
        !           415:        memlist = memh;
        !           416:     }
        !           417:     put_long(memlist, 0x200000);
        !           418:     put_long(0x200000, 0);
        !           419:     put_long(0x200004, chipmem_size - 0x200000);
        !           420: #endif
        !           421:     return 0;
        !           422: }
        !           423: 
        !           424: void rtarea_setup(void)
        !           425: {
        !           426: #if 0
        !           427:     if (chipmem_size > 0x200000) {
        !           428:        CPTR a = here();
        !           429:        /* Build a struct Resident for the 8MB chipmem support */
        !           430:        dw(0x4AFC);
        !           431:        dl(a);
        !           432:        dl(a + 0x1A); /* Continue scan here */
        !           433:        dw(0x0101); /* RTF_COLDSTART; Version 1 */
        !           434:        dw(0x0305); /* NT_DEVICE; pri 05 */
        !           435:        a = ds("UAE HyperChip (tm)");
        !           436:        dl(a); dl(a); /* Identification */
        !           437:        dl(here() + 4); /* Init code */
        !           438:        
        !           439:        calltrap(deftrap(hyperchip_init));
        !           440: #if 0 /* This doesn't work for some reason */
        !           441:        dw(0x2c78); dw(4); /* move.l $4,a6 */
        !           442:        dw(0x203c); dl(chipmem_size - 0x200000);
        !           443:        dw(0x7203); dw(0x74f6);
        !           444:        dw(0x207c); dl(0x200000);
        !           445:        dw(0x227c); dl(ds("Chip RAM"));
        !           446:        dw(0x4eee); dw(0xfd96); /* jmp AddMemList(a6) */
        !           447: #endif
        !           448:     }
        !           449: #endif
        !           450: }

unix.superglobalmegacorp.com

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