Annotation of MiNT/src/bios.c, revision 1.1.1.5

1.1       root        1: /*
                      2: 
1.1.1.3   root        3: Copyright 1990,1991,1992 Eric R. Smith.
                      4: 
1.1.1.5 ! root        5: Copyright 1992,1993,1994 Atari Corporation.
1.1.1.3   root        6: 
                      7: All rights reserved.
1.1       root        8: 
                      9: */
                     10: 
                     11: 
                     12: 
                     13: /*
                     14: 
                     15:  * BIOS replacement routines
                     16: 
                     17:  */
                     18: 
                     19: 
                     20: 
                     21: #include "mint.h"
                     22: 
1.1.1.3   root       23: #include "xbra.h"
                     24: 
1.1       root       25: 
                     26: 
                     27: #define UNDEF 0                /* should match definition in tty.c */
                     28: 
                     29: 
                     30: 
                     31: /* some key definitions */
                     32: 
                     33: #define CTRLALT 0xc
                     34: 
                     35: #define DEL 0x53       /* scan code of delete key */
                     36: 
                     37: #define UNDO 0x61      /* scan code of undo key */
                     38: 
                     39: 
                     40: 
                     41: /* BIOS device definitions */
                     42: 
                     43: #define CONSDEV 2
                     44: 
                     45: #define AUXDEV 1
                     46: 
1.1.1.4   root       47: #define PRNDEV 0
                     48: 
1.1       root       49: 
                     50: 
                     51: /* BIOS devices 0..MAX_BHANDLE-1 can be redirected to GEMDOS files */
                     52: 
                     53: #define MAX_BHANDLE    4
                     54: 
                     55: 
                     56: 
                     57: /* BIOS redirection maps */
                     58: 
1.1.1.2   root       59: const short binput[MAX_BHANDLE] = { -3, -2, -1, -4 };
1.1       root       60: 
1.1.1.2   root       61: const short boutput[MAX_BHANDLE] = { -3, -2, -1, -5 };
1.1       root       62: 
                     63: 
                     64: 
                     65: /* tty structures for the BIOS devices -- see biosfs.c */
                     66: 
                     67: extern struct tty con_tty, aux_tty, midi_tty;
                     68: 
                     69: 
                     70: 
                     71: extern int tosvers;    /* from main.c */
                     72: 
1.1.1.4   root       73: 
                     74: 
1.1       root       75: char *kbshft;          /* set in main.c */
                     76: 
                     77: 
                     78: 
1.1.1.5 ! root       79: short console_in;      /* wait condition for console input */
        !            80: 
        !            81: 
        !            82: 
1.1       root       83: /* some BIOS vectors; note that the routines at these vectors may do nasty
                     84: 
                     85:  * things to registers!
                     86: 
                     87:  */
                     88: 
                     89: 
                     90: 
1.1.1.2   root       91: #define RWABS *((long *)0x476L)
1.1       root       92: 
1.1.1.2   root       93: #define MEDIACH *((long *)0x47eL)
1.1       root       94: 
1.1.1.2   root       95: #define GETBPB *((long *)0x472L)
1.1       root       96: 
                     97: 
                     98: 
1.1.1.3   root       99: 
                    100: 
                    101: #if 1
                    102: 
1.1.1.2   root      103: /* these are supposed to be tables holding the addresses of the
1.1       root      104: 
1.1.1.2   root      105:  * first 8 BconXXX functions, but in fact only the first 5 are
1.1       root      106: 
1.1.1.2   root      107:  * placed here (and device 5 only has Bconout implemented; 
1.1       root      108: 
1.1.1.2   root      109:  * we don't use that device (raw console) anyway).
1.1       root      110: 
1.1.1.2   root      111:  */
                    112: 
                    113: 
                    114: 
                    115: #define xconstat ((long *)0x51eL)
                    116: 
                    117: #define xconin         ((long *)0x53eL)
                    118: 
                    119: #define xcostat ((long *)0x55eL)
                    120: 
                    121: #define xconout        ((long *)0x57eL)
                    122: 
                    123: 
                    124: 
                    125: #define BCOSTAT(dev) \
                    126: 
1.1.1.4   root      127:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1.1.2   root      128: 
                    129:           (int)callout1(xcostat[dev], dev) : Bcostat(dev))
1.1       root      130: 
1.1.1.2   root      131: #define BCONOUT(dev, c) \
1.1       root      132: 
1.1.1.4   root      133:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1       root      134: 
1.1.1.2   root      135:           callout2(xconout[dev], dev, c) : Bconout(dev, c))
1.1       root      136: 
1.1.1.2   root      137: #define BCONSTAT(dev) \
1.1       root      138: 
1.1.1.4   root      139:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1.1.2   root      140: 
                    141:           (int)callout1(xconstat[dev], dev) : Bconstat(dev))
                    142: 
                    143: #define BCONIN(dev) \
                    144: 
1.1.1.4   root      145:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1.1.2   root      146: 
                    147:           callout1(xconin[dev], dev) : Bconin(dev))
1.1       root      148: 
1.1.1.3   root      149: #else
                    150: 
                    151: #define BCOSTAT(dev) Bcostat(dev)
                    152: 
                    153: #define BCONOUT(dev,c) Bconout(dev,c)
                    154: 
                    155: #define BCONSTAT(dev) Bconstat(dev)
                    156: 
                    157: #define BCONIN(dev) Bconin(dev)
                    158: 
                    159: #endif
                    160: 
1.1       root      161: 
                    162: 
                    163: /* variables for monitoring the keyboard */
                    164: 
                    165: IOREC_T        *keyrec;                /* keyboard i/o record pointer */
                    166: 
                    167: short  kintr = 0;              /* keyboard interrupt pending (see intr.s) */
                    168: 
                    169: 
                    170: 
                    171: /* Getmpb is not allowed under MiNT */
                    172: 
                    173: 
                    174: 
1.1.1.2   root      175: long ARGS_ON_STACK
1.1       root      176: 
                    177: getmpb(ptr)
                    178: 
                    179:        void *ptr;
                    180: 
                    181: {
                    182: 
1.1.1.2   root      183:        UNUSED(ptr);
                    184: 
                    185: 
                    186: 
                    187:        DEBUG(("failed call to Getmpb"));
1.1       root      188: 
                    189:        return -1;
                    190: 
                    191: }
                    192: 
                    193: 
                    194: 
                    195: 
                    196: 
                    197: /*
                    198: 
                    199:  * Note that BIOS handles 0 - MAX_BHANDLE now reference file handles;
                    200: 
                    201:  * to get the physical devices, go through u:\dev\
                    202: 
                    203:  *
                    204: 
                    205:  * A note on translation: all of the bco[n]XXX functions have a "u"
                    206: 
                    207:  * variant that is actually what the user calls. For example,
                    208: 
                    209:  * ubconstat is the function that gets control after the user does
                    210: 
                    211:  * a Bconstat. It figures out what device or file handle is
                    212: 
                    213:  * appropriate. Typically, it will be a biosfs file handle; a
                    214: 
                    215:  * request is sent to biosfs, and biosfs in turn figures out
                    216: 
                    217:  * the "real" device and calls bconstat.
                    218: 
                    219:  */
                    220: 
                    221: 
                    222: 
1.1.1.2   root      223: /*
                    224: 
                    225:  * WARNING: syscall.spp assumes that ubconstat never blocks.
                    226: 
                    227:  */
                    228: 
                    229: long ARGS_ON_STACK
1.1       root      230: 
                    231: ubconstat(dev)
                    232: 
                    233: int dev;
                    234: 
                    235: {
                    236: 
1.1.1.2   root      237:        if (dev < MAX_BHANDLE) {
                    238: 
                    239:                FILEPTR *f = curproc->handle[binput[dev]];
1.1       root      240: 
1.1.1.2   root      241:                return file_instat(f) ? -1 : 0;
                    242: 
                    243:        }
1.1       root      244: 
                    245:        else
                    246: 
                    247:                return bconstat(dev);
                    248: 
                    249: }
                    250: 
                    251: 
                    252: 
                    253: long
                    254: 
                    255: bconstat(dev)
                    256: 
                    257: int dev;
                    258: 
                    259: {
                    260: 
                    261:        if (dev == CONSDEV) {
                    262: 
                    263:                if (checkkeys()) return 0;
                    264: 
                    265:                return (keyrec->head != keyrec->tail) ? -1 : 0;
                    266: 
                    267:        }
                    268: 
                    269:        if (dev == AUXDEV && has_bconmap)
                    270: 
                    271:                dev = curproc->bconmap;
                    272: 
                    273: 
                    274: 
1.1.1.2   root      275:        return BCONSTAT(dev);
1.1       root      276: 
                    277: }
                    278: 
                    279: 
                    280: 
                    281: /* bconin: input a character */
                    282: 
1.1.1.2   root      283: /*
1.1       root      284: 
1.1.1.2   root      285:  * WARNING: syscall.spp assumes that ubconin never
1.1       root      286: 
1.1.1.2   root      287:  * blocks if ubconstat returns non-zero.
                    288: 
                    289:  */
                    290: 
                    291: long ARGS_ON_STACK
1.1       root      292: 
                    293: ubconin(dev)
                    294: 
                    295: int dev;
                    296: 
                    297: {
                    298: 
1.1.1.2   root      299:        if (dev < MAX_BHANDLE) {
                    300: 
                    301:                FILEPTR *f = curproc->handle[binput[dev]];
1.1       root      302: 
1.1.1.2   root      303:                return file_getchar(f, RAW);
                    304: 
                    305:        }
1.1       root      306: 
                    307:        else
                    308: 
                    309:                return bconin(dev);
                    310: 
                    311: }
                    312: 
                    313: 
                    314: 
                    315: long
                    316: 
                    317: bconin(dev)
                    318: 
                    319: int dev;
                    320: 
                    321: {
                    322: 
                    323:        IOREC_T *k;
                    324: 
                    325:        long r;
                    326: 
                    327:        short h;
                    328: 
                    329: 
                    330: 
                    331:        if (dev == CONSDEV) {
                    332: 
                    333:                k = keyrec;
                    334: 
                    335: again:
                    336: 
                    337:                while (k->tail == k->head) {
                    338: 
1.1.1.5 ! root      339:                        sleep(IO_Q, (long)&console_in);
1.1       root      340: 
                    341:                }
                    342: 
                    343: 
                    344: 
                    345:                if (checkkeys()) goto again;
                    346: 
                    347: 
                    348: 
                    349:                h = k->head + 4;
                    350: 
                    351:                if (h >= k->buflen)
                    352: 
                    353:                        h = 0;
                    354: 
                    355:                r = *((long *)(k->bufaddr + h));
                    356: 
                    357:                k->head = h;
                    358: 
                    359:                return r;
                    360: 
                    361:        }
                    362: 
                    363:        else {
                    364: 
                    365:                if (dev == AUXDEV && has_bconmap)
                    366: 
                    367:                        dev = curproc->bconmap;
                    368: 
                    369: 
                    370: 
1.1.1.2   root      371:                if (dev > 0) {
1.1       root      372: 
1.1.1.5 ! root      373:                        unsigned long tick;
        !           374: 
        !           375: 
        !           376: 
        !           377:                        tick = *((unsigned long *)0x4baL);
        !           378: 
1.1.1.2   root      379:                        while (!BCONSTAT(dev)) {
1.1       root      380: 
1.1.1.5 ! root      381: /* make blocking (for longer) reads eat less CPU...
        !           382: 
        !           383:  * if yield()ed > 2 seconds and still no data continue with nap
        !           384: 
        !           385:  */
        !           386: 
        !           387:                        if ((*((unsigned long *)0x4baL) - tick) > 400)
        !           388: 
        !           389:                                nap(60);
        !           390: 
        !           391:                        else
        !           392: 
1.1       root      393:                                yield();
                    394: 
                    395:                        }
                    396: 
1.1.1.2   root      397:                }
                    398: 
1.1       root      399:        }
                    400: 
                    401: 
                    402: 
1.1.1.2   root      403:        r = BCONIN(dev);
1.1       root      404: 
                    405: 
                    406: 
                    407:        return r;
                    408: 
                    409: }
                    410: 
                    411: 
                    412: 
                    413: /* bconout: output a character.
                    414: 
                    415:  * returns 0 for failure, nonzero for success
                    416: 
                    417:  */
                    418: 
                    419: 
                    420: 
1.1.1.2   root      421: long ARGS_ON_STACK
1.1       root      422: 
                    423: ubconout(dev, c)
                    424: 
                    425: int dev, c;
                    426: 
                    427: {
                    428: 
                    429:        FILEPTR *f;
                    430: 
1.1.1.2   root      431:        char outp;
                    432: 
1.1       root      433: 
                    434: 
                    435:        if (dev < MAX_BHANDLE) {
                    436: 
                    437:                f = curproc->handle[boutput[dev]];
                    438: 
                    439:                if (!f) return 0;
                    440: 
                    441:                if (is_terminal(f)) {
                    442: 
                    443:                        return tty_putchar(f, ((long)c)&0x00ff, RAW);
                    444: 
                    445:                }
                    446: 
1.1.1.2   root      447:                outp = c;
1.1       root      448: 
1.1.1.2   root      449:                return (*f->dev->write)(f, &outp, 1L);
1.1       root      450: 
                    451:        }
                    452: 
                    453:        else if (dev == 5) {
                    454: 
                    455:                c &= 0x00ff;
                    456: 
                    457:                f = curproc->handle[-1];
                    458: 
                    459:                if (!f) return 0;
                    460: 
                    461:                if (is_terminal(f)) {
                    462: 
                    463:                        if (c < ' ') {
                    464: 
                    465:                        /* MW hack for quoted characters */
                    466: 
                    467:                                tty_putchar(f, (long)'\033', RAW);
                    468: 
                    469:                                tty_putchar(f, (long)'Q', RAW);
                    470: 
                    471:                        }
                    472: 
                    473:                        return tty_putchar(f, ((long)c)&0x00ff, RAW);
                    474: 
                    475:                }
                    476: 
                    477:        /* note: we're assuming sizeof(int) == 2 here! */
                    478: 
1.1.1.2   root      479:                outp = c;
                    480: 
                    481:                return (*f->dev->write)(f, &outp, 1L);
1.1       root      482: 
                    483:        } else
                    484: 
                    485:                return bconout(dev, c);
                    486: 
                    487: }
                    488: 
                    489: 
                    490: 
                    491: long
                    492: 
                    493: bconout(dev, c)
                    494: 
                    495: int dev,c;
                    496: 
                    497: {
                    498: 
                    499:        int statdev;
                    500: 
                    501:        long endtime;
                    502: 
1.1.1.3   root      503: #define curtime *((unsigned long *)0x4baL)
1.1       root      504: 
                    505: 
                    506: 
                    507:        if (dev == AUXDEV && has_bconmap) {
                    508: 
                    509:                dev = curproc->bconmap;
                    510: 
                    511:        }
                    512: 
                    513: 
                    514: 
                    515: /* compensate for a known BIOS bug; MIDI and IKBD are switched */
                    516: 
                    517:        if (dev == 3) {         /* MIDI */
                    518: 
                    519:                statdev = 4;
                    520: 
                    521:        } else if (dev == 4) {
                    522: 
                    523:                statdev = 3;
                    524: 
1.1.1.3   root      525:        } else {
1.1       root      526: 
                    527:                statdev = dev;
                    528: 
1.1.1.3   root      529:        }
                    530: 
1.1       root      531: 
                    532: 
1.1.1.4   root      533: /* provide a 10 second time out for the printer */
1.1       root      534: 
1.1.1.2   root      535:        if (!BCOSTAT(statdev)) {
1.1       root      536: 
1.1.1.4   root      537:                if (dev != PRNDEV) {
                    538: 
                    539:                        do {
                    540: 
                    541:        /* BUG: Speedo GDOS isn't re-entrant; so printer output to the
                    542: 
                    543:         * serial port could cause problems
1.1       root      544: 
1.1.1.4   root      545:         */
                    546: 
                    547:                                yield();
                    548: 
                    549:                        } while (!BCOSTAT(statdev));
                    550: 
                    551:                } else {
                    552: 
                    553:                        endtime = curtime + 10*200L;
                    554: 
                    555:                        do {
1.1       root      556: 
1.1.1.3   root      557: #if 0
                    558: 
1.1.1.4   root      559:        /* Speedo GDOS isn't re-entrant, so we can't give up CPU
                    560: 
                    561:         * time here :-(
                    562: 
                    563:         */
                    564: 
                    565:                                yield();
1.1.1.2   root      566: 
1.1.1.3   root      567: #endif
1.1       root      568: 
1.1.1.4   root      569:                        } while (!BCOSTAT(statdev) && curtime < endtime);
                    570: 
                    571:                        if ( curtime >= endtime) return 0;
1.1.1.3   root      572: 
1.1.1.4   root      573:                }
1.1.1.2   root      574: 
                    575:        }
1.1       root      576: 
                    577: 
                    578: 
                    579: /* special case: many text accelerators return a bad value from
                    580: 
                    581:  * Bconout, so we ignore the returned value for the console
                    582: 
1.1.1.4   root      583:  * Sigh. serptch2 and hsmodem1 also screw this up, so for now let's
                    584: 
                    585:  * only count on it being correct for the printer.
                    586: 
1.1       root      587:  */
                    588: 
1.1.1.4   root      589:        if (dev == PRNDEV) {
1.1       root      590: 
                    591: /* NOTE: if your compiler complains about the next line, then Bconout is
                    592: 
                    593:  * improperly declared in your osbind.h header file. it should be returning
                    594: 
                    595:  * a long value; some libraries incorrectly have Bconout returning void
                    596: 
                    597:  * (or cast the returned value to void)
                    598: 
                    599:  */
                    600: 
1.1.1.2   root      601:                return BCONOUT(dev,c);
1.1       root      602: 
                    603:        } else {
                    604: 
1.1.1.2   root      605:                (void)BCONOUT(dev, c);
1.1       root      606: 
                    607:                return 1;
                    608: 
                    609:        }
                    610: 
                    611: }
                    612: 
                    613: 
                    614: 
                    615: /* rwabs: various disk stuff */
                    616: 
                    617: 
                    618: 
1.1.1.2   root      619: long ARGS_ON_STACK
1.1       root      620: 
                    621: rwabs(rwflag, buffer, number, recno, dev, lrecno)
                    622: 
                    623: int rwflag, number, recno, dev;
                    624: 
                    625: void *buffer;
                    626: 
                    627: long lrecno;
                    628: 
                    629: {
                    630: 
                    631:        long r;
                    632: 
1.1.1.2   root      633:        extern PROC *dlockproc[];       /* in dosdir.c */
                    634: 
1.1.1.5 ! root      635:        extern int aliasdrv[];          /* in filesys.c */
        !           636: 
1.1.1.2   root      637: 
                    638: 
1.1.1.5 ! root      639:        if (dev >= 0 && dev < NUM_DRIVES) {
1.1.1.2   root      640: 
1.1.1.5 ! root      641:                if (aliasdrv[dev]) {
        !           642: 
        !           643:                        dev = aliasdrv[dev] - 1;
        !           644: 
        !           645:                }
        !           646: 
        !           647:                if (dlockproc[dev] && dlockproc[dev] != curproc) {
1.1.1.2   root      648: 
                    649:                        DEBUG(("Rwabs: device %c is locked", dev+'A'));
                    650: 
                    651:                        return ELOCKED;
                    652: 
                    653:                }
                    654: 
                    655:        }
                    656: 
1.1       root      657: 
                    658: 
1.1.1.5 ! root      659: #if 1
        !           660: 
        !           661: /* only the superuser can make Rwabs calls directly */
1.1       root      662: 
                    663: 
                    664: 
1.1.1.5 ! root      665:        if (curproc->in_dos || (curproc->euid == 0))
        !           666: 
        !           667:        /* Note that some (most?) Rwabs device drivers don't bother saving
        !           668: 
        !           669:         * registers, whereas our compiler expects politeness. So we go
        !           670: 
        !           671:         * via callout(), which will save registers for us.
        !           672: 
        !           673:         */
        !           674: 
        !           675:                r = callout(RWABS, rwflag, buffer, number, recno, dev, lrecno);
        !           676: 
        !           677:        else {
        !           678: 
        !           679:                DEBUG(("Rwabs by non privileged process!"));
        !           680: 
        !           681:                r = EACCDN;
        !           682: 
        !           683:        }
        !           684: 
        !           685: #else
1.1       root      686: 
                    687:        r = callout(RWABS, rwflag, buffer, number, recno, dev, lrecno);
                    688: 
1.1.1.5 ! root      689: #endif
        !           690: 
1.1       root      691:        return r;
                    692: 
                    693: }
                    694: 
                    695: 
                    696: 
                    697: /* setexc: set exception vector */
                    698: 
                    699: 
                    700: 
1.1.1.2   root      701: long ARGS_ON_STACK
1.1       root      702: 
                    703: setexc(number, vector)
                    704: 
                    705: int number;
                    706: 
                    707: long vector;
                    708: 
                    709: {
                    710: 
                    711:        long *place;
                    712: 
                    713:        long old;
                    714: 
                    715:        extern long save_dos, save_bios, save_xbios;    /* in main.c */
                    716: 
1.1.1.3   root      717:        extern int no_mem_prot;                         /* in main.c */
1.1       root      718: 
                    719: 
                    720: 
                    721:        place = (long *)(((long)number) << 2);
                    722: 
                    723:        if (number == 0x21)                             /* trap_1 */
                    724: 
                    725:                old = save_dos;
                    726: 
                    727:        else if (number == 0x2d)                        /* trap_13 */
                    728: 
                    729:                old = save_bios;
                    730: 
                    731:        else if (number == 0x2e)                        /* trap_14 */
                    732: 
                    733:                old = save_xbios;
                    734: 
                    735:        else if (number == 0x101)
                    736: 
                    737:                old = (long)curproc->criticerr;         /* critical error vector */
                    738: 
                    739:        else if (number == 0x102)
                    740: 
                    741:                old = curproc->ctxt[SYSCALL].term_vec;  /* GEMDOS term vector */
                    742: 
                    743:        else
                    744: 
                    745:                old = *place;
                    746: 
                    747: 
                    748: 
                    749:        if (vector > 0) {
                    750: 
1.1.1.3   root      751:        /* validate vector; this will cause a bus error if mem
                    752: 
                    753:         * protection is on and the current process doesn't have
                    754: 
                    755:         * access to the memory
                    756: 
                    757:         */
                    758: 
                    759:                if (*((long *)vector) == 0xDEADBEEFL)
                    760: 
                    761:                        return old;
                    762: 
                    763: 
                    764: 
1.1       root      765:                if (number == 0x21)
                    766: 
                    767:                        save_dos = vector;
                    768: 
                    769:                else if (number == 0x2d)
                    770: 
                    771:                        save_bios = vector;
                    772: 
                    773:                else if (number == 0x2e)
                    774: 
                    775:                        save_xbios = vector;
                    776: 
                    777:                else if (number == 0x102)
                    778: 
                    779:                        curproc->ctxt[SYSCALL].term_vec = vector;
                    780: 
                    781:                else if (number == 0x101) {
                    782: 
                    783:                        long mintcerr;
                    784: 
                    785: 
                    786: 
                    787:                /*
                    788: 
                    789:                 * problem: lots of TSR's look for the Setexc(0x101,...)
                    790: 
                    791:                 * that the AES does at startup time; so we have
                    792: 
                    793:                 * to pass it along.
                    794: 
                    795:                 */
                    796: 
                    797:                        mintcerr = (long) Setexc(0x101, (void *)vector);
                    798: 
1.1.1.2   root      799:                        curproc->criticerr = (long ARGS_ON_STACK (*) P_((long))) *place;
1.1       root      800: 
                    801:                        *place = mintcerr;
                    802: 
                    803:                }
                    804: 
                    805:                else {
                    806: 
1.1.1.3   root      807:                        if (!no_mem_prot) {
                    808: 
                    809:                        /*
                    810: 
                    811:                         * if memory protection is on, the vector should be
                    812: 
                    813:                         * pointing at supervisor or global memory
                    814: 
                    815:                         */
                    816: 
                    817:                            MEMREGION *r;
                    818: 
                    819: 
                    820: 
                    821:                            r = addr2region(vector);
                    822: 
                    823:                            if (r && get_prot_mode(r) == PROT_P) {
                    824: 
                    825:                                DEBUG(("Changing protection to Supervisor because of Setexc"));
                    826: 
                    827:                                mark_region(r, PROT_S);
                    828: 
                    829:                            }
                    830: 
                    831:                        }
                    832: 
1.1       root      833:                /* We would do just *place = vector except that
                    834: 
                    835:                 * someone else might be intercepting Setexc looking
                    836: 
                    837:                 * for something in particular...
                    838: 
                    839:                 */
                    840: 
                    841:                        old = (long) Setexc(number, (void *)vector);
                    842: 
                    843:                }
                    844: 
                    845:        }
                    846: 
1.1.1.3   root      847: 
                    848: 
                    849:        TRACE(("Setexc %d, %lx -> %lx", number, vector, old));
                    850: 
1.1       root      851:        return old;
                    852: 
                    853: }
                    854: 
                    855: 
                    856: 
                    857: /* tickcal: return milliseconds per system clock tick */
                    858: 
                    859: 
                    860: 
1.1.1.2   root      861: long ARGS_ON_STACK
1.1       root      862: 
                    863: tickcal()
                    864: 
                    865: {
                    866: 
                    867:        return (long) (*( (unsigned *) 0x0442L ));
                    868: 
                    869: }
                    870: 
                    871: 
                    872: 
                    873: /* getbpb: get BIOS parameter block */
                    874: 
                    875: 
                    876: 
1.1.1.2   root      877: long ARGS_ON_STACK
1.1       root      878: 
                    879: getbpb(dev)
                    880: 
                    881: int dev;
                    882: 
                    883: {
                    884: 
                    885:        long r;
                    886: 
                    887: 
                    888: 
                    889: /* we can't trust the Getbpb routine to accurately save all registers,
                    890: 
                    891:  * so we do it ourselves
                    892: 
                    893:  */
                    894: 
1.1.1.4   root      895:        r = callout1(GETBPB, dev);
1.1       root      896: 
                    897: /* 
                    898: 
                    899:  * There is a bug in the  TOS  disk handling routines (well several actually).
                    900: 
                    901:  * If the directory size of Getbpb() is returned as zero then the drive 'dies'
                    902: 
                    903:  * and wont read any new disks even with the 'ESC' enforced disk change . This
                    904: 
                    905:  * is present even in TOS 1.6 (not sure about 1.62 though). This small routine
                    906: 
                    907:  * changes the dir size to '1' if it is zero . It may make some non-TOS disks
                    908: 
                    909:  * look a bit weird but that's better than killing the drive .
                    910: 
                    911:  */
                    912: 
                    913:        if (r) {
                    914: 
                    915:                if ( ((short *)r)[3] == 0)      /* 0 directory size? */
                    916: 
                    917:                        ((short *)r)[3] = 1;
                    918: 
                    919:        }
                    920: 
                    921:        return r;
                    922: 
                    923: }
                    924: 
                    925: 
                    926: 
                    927: /* bcostat: return output device status */
                    928: 
                    929: 
                    930: 
1.1.1.2   root      931: /* WARNING: syscall.spp assumes that ubcostat never
                    932: 
                    933:  * blocks
                    934: 
                    935:  */
                    936: 
                    937: long ARGS_ON_STACK
1.1       root      938: 
                    939: ubcostat(dev)
                    940: 
                    941: int dev;
                    942: 
                    943: {
                    944: 
1.1.1.2   root      945:        FILEPTR *f;
                    946: 
                    947: 
                    948: 
1.1       root      949: /* the BIOS switches MIDI (3) and IKBD (4) (a bug, but it can't be corrected) */
                    950: 
                    951:        if (dev == 4) {         /* really the MIDI port */
                    952: 
1.1.1.2   root      953:                f = curproc->handle[boutput[3]];
                    954: 
                    955:                return file_outstat(f) ? -1 : 0;
1.1       root      956: 
                    957:        }
                    958: 
                    959:        if (dev == 3)
                    960: 
1.1.1.2   root      961:                return BCOSTAT(dev);
1.1       root      962: 
                    963: 
                    964: 
1.1.1.2   root      965:        if (dev < MAX_BHANDLE) {
1.1       root      966: 
1.1.1.2   root      967:                f = curproc->handle[boutput[dev]];
1.1       root      968: 
1.1.1.2   root      969:                return file_outstat(f) ? -1 : 0;
                    970: 
                    971:        } else
1.1       root      972: 
                    973:                return bcostat(dev);
                    974: 
                    975: }
                    976: 
                    977: 
                    978: 
                    979: long
                    980: 
                    981: bcostat(dev)
                    982: 
                    983: int dev;
                    984: 
                    985: {
                    986: 
                    987: 
                    988: 
                    989:        if (dev == CONSDEV) {
                    990: 
                    991:                return -1;
                    992: 
                    993:        }
                    994: 
                    995:        else if (dev == AUXDEV && has_bconmap) {
                    996: 
                    997:                dev = curproc->bconmap;
                    998: 
                    999:        }
                   1000: 
                   1001: /* compensate here for the BIOS bug, so that the MIDI and IKBD files work
                   1002: 
                   1003:  * correctly
                   1004: 
                   1005:  */
                   1006: 
                   1007:        else if (dev == 3) dev = 4;
                   1008: 
                   1009:        else if (dev == 4) dev = 3;
                   1010: 
                   1011: 
                   1012: 
1.1.1.2   root     1013:        return BCOSTAT(dev);
1.1       root     1014: 
                   1015: }
                   1016: 
                   1017: 
                   1018: 
                   1019: /* mediach: check for media change */
                   1020: 
                   1021: 
                   1022: 
1.1.1.2   root     1023: long ARGS_ON_STACK
1.1       root     1024: 
                   1025: mediach(dev)
                   1026: 
                   1027: int dev;
                   1028: 
                   1029: {
                   1030: 
                   1031:        long r;
                   1032: 
                   1033: 
                   1034: 
1.1.1.3   root     1035:        r = callout1(MEDIACH, dev);
1.1       root     1036: 
                   1037:        return r;
                   1038: 
                   1039: }
                   1040: 
                   1041: 
                   1042: 
                   1043: /* drvmap: return drives connected to system */
                   1044: 
                   1045: 
                   1046: 
1.1.1.2   root     1047: long ARGS_ON_STACK
1.1       root     1048: 
                   1049: drvmap()
                   1050: 
                   1051: {
                   1052: 
                   1053:        return *( (long *)0x4c2L );
                   1054: 
                   1055: }
                   1056: 
                   1057: 
                   1058: 
                   1059: /* kbshift: return (and possibly change) keyboard shift key status */
                   1060: 
1.1.1.2   root     1061: /* WARNING: syscall.spp assumes that kbshift never blocks, and never
1.1       root     1062: 
1.1.1.2   root     1063:  * calls any underlying TOS functions
1.1       root     1064: 
1.1.1.2   root     1065:  */
                   1066: 
                   1067: long ARGS_ON_STACK
1.1       root     1068: 
                   1069: kbshift(mode)
                   1070: 
                   1071: int mode;
                   1072: 
                   1073: {
                   1074: 
                   1075:        int oldshft;
                   1076: 
                   1077: 
                   1078: 
                   1079:        oldshft = *((unsigned char *)kbshft);
                   1080: 
                   1081:        if (mode >= 0)
                   1082: 
                   1083:                *kbshft = mode;
                   1084: 
                   1085:        return oldshft;
                   1086: 
                   1087: }
                   1088: 
                   1089: 
                   1090: 
                   1091: 
                   1092: 
                   1093: /* special Bconout buffering code:
                   1094: 
                   1095:  * Because system call overhead is so high, programs that do output
                   1096: 
                   1097:  * with Bconout suffer in performance. To compensate for this,
                   1098: 
                   1099:  * Bconout is special-cased in syscall.s, and if possible characters
                   1100: 
                   1101:  * are placed in the 256 byte bconbuf buffer. This buffer is flushed
                   1102: 
                   1103:  * when any system call other than Bconout happens, or when a context
                   1104: 
                   1105:  * switch occurs.
                   1106: 
                   1107:  */
                   1108: 
                   1109: 
                   1110: 
                   1111: short bconbsiz;                        /* number of characters in buffer */
                   1112: 
                   1113: unsigned char bconbuf[256];    /* buffer contents */
                   1114: 
                   1115: short bconbdev;                        /* BIOS device for which the buffer is valid */
                   1116: 
                   1117:                                /* (-1 means no buffering is active) */
                   1118: 
                   1119: 
                   1120: 
                   1121: /*
                   1122: 
                   1123:  * flush pending BIOS output. Return 0 if some bytes were not successfully
                   1124: 
                   1125:  * written, non-zero otherwise (just like bconout)
                   1126: 
                   1127:  */
                   1128: 
                   1129: 
                   1130: 
1.1.1.2   root     1131: long ARGS_ON_STACK
1.1       root     1132: 
                   1133: bflush()               /* flush bios output */
                   1134: 
                   1135: {
                   1136: 
                   1137:        long ret, bsiz;
                   1138: 
                   1139:        unsigned char *s;
                   1140: 
                   1141:        FILEPTR *f;
                   1142: 
                   1143:        short dev;
                   1144: 
                   1145:        short statdev;
                   1146: 
1.1.1.2   root     1147:        long lbconbuf[256];
                   1148: 
1.1       root     1149: 
                   1150: 
                   1151:        if ((dev = bconbdev) < 0) return 0;
                   1152: 
                   1153: 
                   1154: 
                   1155: /*
                   1156: 
                   1157:  * Here we lock the BIOS buffering mechanism by setting bconbdev to -1
                   1158: 
                   1159:  * This is necessary because if two or more programs try to do
                   1160: 
                   1161:  * buffered BIOS output at the same time, they can get seriously
                   1162: 
                   1163:  * mixed up. We unlock by setting bconbdev to 0.
                   1164: 
                   1165:  *
                   1166: 
                   1167:  * NOTE: some code (e.g. in sleep()) checks for bconbsiz != 0 in
                   1168: 
                   1169:  * order to see if we need to do a bflush; if one is already in
                   1170: 
                   1171:  * progress, it's pointless to do this, so we save a bit of
                   1172: 
                   1173:  * time by setting bconbsiz to 0 here.
                   1174: 
                   1175:  */
                   1176: 
                   1177:        bconbdev = -1;
                   1178: 
                   1179:        bsiz = bconbsiz;
                   1180: 
1.1.1.2   root     1181:        if (bsiz == 0) return 0;
                   1182: 
1.1       root     1183:        bconbsiz = 0;
                   1184: 
                   1185: 
                   1186: 
                   1187: /* BIOS handles 0..MAX_BHANDLE-1 are aliases for special GEMDOS files */
                   1188: 
                   1189:        if (dev < MAX_BHANDLE || dev == 5) {
                   1190: 
                   1191:                if (dev == 5)
                   1192: 
                   1193:                        f = curproc->handle[-1];
                   1194: 
                   1195:                else
                   1196: 
                   1197:                        f = curproc->handle[boutput[dev]];
                   1198: 
                   1199: 
                   1200: 
                   1201:                if (!f) {
                   1202: 
                   1203:                        bconbdev = 0;
                   1204: 
                   1205:                        return 0;
                   1206: 
                   1207:                }
                   1208: 
                   1209:                if (is_terminal(f)) {
                   1210: 
                   1211:                        s = bconbuf;
                   1212: 
                   1213:                        if (dev == 5) {
                   1214: 
                   1215:                            while (bsiz-- > 0) {
                   1216: 
                   1217:                                if (*s < ' ') {
                   1218: 
                   1219:                        /* use ESC-Q to quote control character */
                   1220: 
                   1221:                                        (void)tty_putchar(f, (long)'\033',
                   1222: 
                   1223:                                                                RAW);
                   1224: 
                   1225:                                        (void)tty_putchar(f, (long)'Q',
                   1226: 
                   1227:                                                                RAW);
                   1228: 
                   1229:                                }
                   1230: 
                   1231:                                (void) tty_putchar(f, (long)*s++, RAW);
                   1232: 
                   1233:                            }
                   1234: 
                   1235:                        } else {
                   1236: 
1.1.1.2   root     1237: #if 1
                   1238: 
                   1239:                            long *where, nbytes;
                   1240: 
                   1241: 
                   1242: 
                   1243: /* the tty_putchar should set up terminal modes correctly */
                   1244: 
                   1245:                            (void) tty_putchar(f, (long)*s++, RAW);
                   1246: 
                   1247:                            where = lbconbuf;
                   1248: 
                   1249:                            nbytes = 0;
                   1250: 
                   1251:                            while (--bsiz > 0) {
                   1252: 
                   1253:                                *where++ = *s++; nbytes+=4;
                   1254: 
                   1255:                            }
                   1256: 
                   1257:                            if (nbytes)
                   1258: 
                   1259:                                (*f->dev->write)(f, (char *)lbconbuf, nbytes);
                   1260: 
                   1261: #else
                   1262: 
1.1       root     1263:                            while (bsiz-- > 0) {
                   1264: 
                   1265:                                (void) tty_putchar(f, (long)*s++, RAW);
                   1266: 
                   1267:                            }
                   1268: 
1.1.1.2   root     1269: #endif
                   1270: 
1.1       root     1271:                        }
                   1272: 
                   1273:                        ret = -1;
                   1274: 
                   1275:                } else {
                   1276: 
                   1277:                        ret = (*f->dev->write)(f, (char *)bconbuf, bsiz);
                   1278: 
                   1279:                }
                   1280: 
                   1281:                bconbdev = 0;
                   1282: 
                   1283:                return ret;
                   1284: 
                   1285:        }
                   1286: 
                   1287: 
                   1288: 
                   1289: /* Otherwise, we have a real BIOS device */
                   1290: 
                   1291: 
                   1292: 
                   1293:        if (dev == AUXDEV && has_bconmap) {
                   1294: 
                   1295:                dev = curproc->bconmap;
                   1296: 
                   1297:                statdev = dev;
                   1298: 
                   1299:        }
                   1300: 
                   1301: /* compensate for a known BIOS bug; MIDI and IKBD are switched */
                   1302: 
                   1303:        else if (dev == 3) {            /* MIDI */
                   1304: 
                   1305:                statdev = 4;
                   1306: 
                   1307:        } else if (dev == 4) {
                   1308: 
                   1309:                statdev = 3;
                   1310: 
                   1311:        } else
                   1312: 
                   1313:                statdev = dev;
                   1314: 
                   1315:                
                   1316: 
                   1317:        s = bconbuf;
                   1318: 
                   1319:        while (bsiz-- > 0) {
                   1320: 
1.1.1.2   root     1321:                while (!BCOSTAT(statdev)) yield();
1.1       root     1322: 
1.1.1.2   root     1323:                (void)BCONOUT(dev,*s);
1.1       root     1324: 
                   1325:                s++;
                   1326: 
                   1327:        }
                   1328: 
                   1329:        bconbdev = 0;
                   1330: 
                   1331:        return 1L;
                   1332: 
                   1333: }
                   1334: 
                   1335: 
                   1336: 
                   1337: /* initialize bios table */
                   1338: 
                   1339: 
                   1340: 
                   1341: #define BIOS_MAX 0x20
                   1342: 
                   1343: 
                   1344: 
                   1345: Func bios_tab[BIOS_MAX] = {
                   1346: 
                   1347:        getmpb,
                   1348: 
                   1349:        ubconstat,
                   1350: 
                   1351:        ubconin,
                   1352: 
                   1353:        ubconout,
                   1354: 
1.1.1.2   root     1355: 
                   1356: 
1.1       root     1357:        rwabs,
                   1358: 
                   1359:        setexc,
                   1360: 
                   1361:        tickcal,
                   1362: 
                   1363:        getbpb,
                   1364: 
1.1.1.2   root     1365: 
                   1366: 
1.1       root     1367:        ubcostat,
                   1368: 
                   1369:        mediach,
                   1370: 
                   1371:        drvmap,
                   1372: 
                   1373:        kbshift,
                   1374: 
1.1.1.2   root     1375: 
                   1376: 
1.1       root     1377:        0, 0, 0, 0,
                   1378: 
                   1379:        0, 0, 0, 0, 0, 0, 0, 0,
                   1380: 
                   1381:        0, 0, 0, 0, 0, 0, 0, 0
                   1382: 
                   1383: };
                   1384: 
                   1385: 
                   1386: 
                   1387: short bios_max = BIOS_MAX;
                   1388: 
                   1389: 
                   1390: 
                   1391: /*
                   1392: 
                   1393:  * BIOS initialization routine: gets keyboard buffer pointers, for the
                   1394: 
                   1395:  * interrupt routine below
                   1396: 
                   1397:  */
                   1398: 
                   1399: 
                   1400: 
                   1401: void
                   1402: 
                   1403: init_bios()
                   1404: 
                   1405: {
                   1406: 
                   1407:        keyrec = (IOREC_T *)Iorec(1);
                   1408: 
                   1409: }
                   1410: 
                   1411: 
                   1412: 
                   1413: /*
                   1414: 
1.1.1.2   root     1415:  * do_bconin: try to do a bconin function quickly, without
                   1416: 
                   1417:  * blocking. If we can't do it without blocking, we return
                   1418: 
                   1419:  * 0x0123dead and the calling trap #13 code falls through
                   1420: 
                   1421:  * to the normal bconin stuff. We can't block here because
                   1422: 
                   1423:  * the trap #13 code hasn't yet saved registers or other
                   1424: 
                   1425:  * context bits, so sleep() wouldn't work properly.
                   1426: 
                   1427:  */
                   1428: 
                   1429: 
                   1430: 
                   1431: #define WOULDBLOCK 0x0123deadL
                   1432: 
                   1433: 
                   1434: 
                   1435: /* WARNING: syscall.spp assumes that do_bconin never blocks */
                   1436: 
                   1437: 
                   1438: 
                   1439: long ARGS_ON_STACK
                   1440: 
                   1441: do_bconin(dev)
                   1442: 
                   1443:        int dev;
                   1444: 
                   1445: {
                   1446: 
                   1447:        FILEPTR *f;
                   1448: 
                   1449:        long r;
                   1450: 
                   1451:        unsigned char c;
                   1452: 
                   1453: 
                   1454: 
                   1455:        if (dev < MAX_BHANDLE) {
                   1456: 
                   1457:                f = curproc->handle[binput[dev]];
                   1458: 
                   1459:                if (!f) return 0;
                   1460: 
                   1461:                r = 0;
                   1462: 
                   1463:                (void)(*f->dev->ioctl)(f, FIONREAD, &r);
                   1464: 
                   1465:                if (!r) return WOULDBLOCK;      /* data not ready */
                   1466: 
                   1467:                if (is_terminal(f))
                   1468: 
                   1469:                        r = tty_getchar(f, RAW);
                   1470: 
                   1471:                else {
                   1472: 
                   1473:                        r = (*f->dev->read)(f, (char *)&c, 1L);
                   1474: 
                   1475:                        r = (r == 1) ? c : MiNTEOF;
                   1476: 
                   1477:                }
                   1478: 
                   1479:        } else {
                   1480: 
                   1481:                if (!bconstat(dev))
                   1482: 
                   1483:                        r = WOULDBLOCK;
                   1484: 
                   1485:                else
                   1486: 
                   1487:                        r = bconin(dev);
                   1488: 
                   1489:        }
                   1490: 
                   1491:        return r;
                   1492: 
                   1493: }
                   1494: 
                   1495: 
                   1496: 
                   1497: /*
                   1498: 
1.1       root     1499:  * routine for checking keyboard (called by sleep() on any context
                   1500: 
                   1501:  * switch where a keyboard event occured). returns 1 if a special
                   1502: 
                   1503:  * control character was eaten, 0 if not
                   1504: 
                   1505:  */
                   1506: 
                   1507: 
                   1508: 
                   1509: int
                   1510: 
                   1511: checkkeys()
                   1512: 
                   1513: {
                   1514: 
                   1515:        char scan, ch;
                   1516: 
                   1517:        short shift;
                   1518: 
                   1519:        int sig, ret;
                   1520: 
                   1521:        struct tty *tty = &con_tty;
                   1522: 
                   1523:        extern char mshift;             /* for mouse -- see biosfs.c */
                   1524: 
                   1525:        static short oldktail = 0;
                   1526: 
                   1527: 
                   1528: 
                   1529:        ret = 0;
                   1530: 
                   1531:        mshift = kbshift(-1);
                   1532: 
                   1533:        while (oldktail != keyrec->tail) {
                   1534: 
                   1535: 
                   1536: 
                   1537: /* BUG: we really should check the shift status _at the time the key was
                   1538: 
                   1539:  * pressed_, not now!
                   1540: 
                   1541:  */
                   1542: 
                   1543:                sig = 0;
                   1544: 
                   1545:                shift = mshift;
                   1546: 
                   1547:                oldktail += 4;
                   1548: 
                   1549:                if (oldktail >= keyrec->buflen)
                   1550: 
                   1551:                        oldktail = 0;
                   1552: 
                   1553: 
                   1554: 
                   1555:                scan = (keyrec->bufaddr + oldktail)[1];
                   1556: 
                   1557: /* function key?? */
                   1558: 
                   1559:                if ( (scan >= 0x3b && scan <= 0x44) ||
                   1560: 
                   1561:                     (scan >= 0x54 && scan <= 0x5d) ||
                   1562: 
                   1563:                     scan == DEL || scan == UNDO) {
                   1564: 
                   1565:                        if ( (shift & CTRLALT) == CTRLALT ) {
                   1566: 
                   1567:                                oldktail = keyrec->head = keyrec->tail;
                   1568: 
                   1569:                                do_func_key(scan);
                   1570: 
1.1.1.2   root     1571:                                /* do_func_key may have read some keys */
                   1572: 
                   1573:                                oldktail = keyrec->head;
                   1574: 
                   1575:                                mshift = kbshift (-1);
                   1576: 
1.1       root     1577:                                ret = 1;
                   1578: 
                   1579:                                continue;
                   1580: 
                   1581:                        }
                   1582: 
                   1583:                }
                   1584: 
                   1585: 
                   1586: 
                   1587: /* check for special control keys, etc. */
                   1588: 
                   1589: /* BUG: this doesn't exactly match TOS' behavior, particularly for
                   1590: 
                   1591:  * ^S/^Q
                   1592: 
                   1593:  */
                   1594: 
                   1595:                if ((tty->state & TS_COOKED) || (shift & CTRLALT) == CTRLALT) {
                   1596: 
                   1597:                        ch = (keyrec->bufaddr + keyrec->tail)[3];
                   1598: 
                   1599:                        if (ch == UNDEF)
                   1600: 
                   1601:                                ;       /* do nothing */
                   1602: 
                   1603:                        else if (ch == tty->tc.t_intrc)
                   1604: 
                   1605:                                sig = SIGINT;
                   1606: 
                   1607:                        else if (ch == tty->tc.t_quitc)
                   1608: 
                   1609:                                sig = SIGQUIT;
                   1610: 
                   1611:                        else if (ch == tty->ltc.t_suspc)
                   1612: 
                   1613:                                sig = SIGTSTP;
                   1614: 
                   1615:                        else if (ch == tty->tc.t_stopc) {
                   1616: 
                   1617:                                tty->state |= TS_HOLD;
                   1618: 
                   1619:                                ret = 1;
                   1620: 
                   1621:                                keyrec->head = oldktail;
                   1622: 
                   1623:                                continue;
                   1624: 
                   1625:                        }
                   1626: 
                   1627:                        else if (ch == tty->tc.t_startc) {
                   1628: 
                   1629:                                tty->state &= ~TS_HOLD;
                   1630: 
                   1631:                                ret = 1;
                   1632: 
                   1633:                                keyrec->head = oldktail;
                   1634: 
                   1635:                                continue;
                   1636: 
                   1637:                        }
                   1638: 
                   1639:                        if (sig) {
                   1640: 
                   1641:                                tty->state &= ~TS_HOLD;
                   1642: 
                   1643:                                if (!(tty->sg.sg_flags & T_NOFLSH))
                   1644: 
                   1645:                                    oldktail = keyrec->head = keyrec->tail;
                   1646: 
                   1647:                                killgroup(tty->pgrp, sig);
                   1648: 
                   1649:                                ret = 1;
                   1650: 
                   1651:                        }
                   1652: 
                   1653:                        else if (tty->state & TS_HOLD) {
                   1654: 
                   1655:                                keyrec->head = oldktail;
                   1656: 
                   1657:                                ret = 1;
                   1658: 
                   1659:                        }
                   1660: 
                   1661:                }
                   1662: 
                   1663: 
                   1664: 
                   1665:        }
                   1666: 
                   1667: 
                   1668: 
1.1.1.5 ! root     1669:        if (keyrec->head != keyrec->tail) {
1.1       root     1670: 
1.1.1.5 ! root     1671:        /* wake up any processes waiting in bconin() */
1.1       root     1672: 
1.1.1.5 ! root     1673:                wake(IO_Q, (long)&console_in);
        !          1674: 
        !          1675:        /* wake anyone that did a select() on the keyboard */
        !          1676: 
        !          1677:                if (tty->rsel)
        !          1678: 
        !          1679:                        wakeselect(tty->rsel);
        !          1680: 
        !          1681:        }
1.1       root     1682: 
                   1683: 
                   1684: 
                   1685:        return ret;
                   1686: 
                   1687: }
                   1688: 
                   1689: 
                   1690: 
1.1.1.3   root     1691: 
                   1692: 
                   1693: /*
                   1694: 
                   1695:  * special vector stuff: we try to save as many vectors as possible,
                   1696: 
                   1697:  * just in case we need to restore them later
                   1698: 
                   1699:  *
                   1700: 
                   1701:  * BUG: this really should be integrated with the init_intr routine
                   1702: 
                   1703:  * in main.c
                   1704: 
                   1705:  */
                   1706: 
                   1707: 
                   1708: 
                   1709: #define A(x) ((long *)(long)(x))
                   1710: 
                   1711: #define L(x) (long)(x)
                   1712: 
                   1713: 
                   1714: 
                   1715: struct vectab {
                   1716: 
                   1717:        long *addr;
                   1718: 
                   1719:        long def_value;
                   1720: 
                   1721: } VEC[] = {
                   1722: 
                   1723: {A(0x28), 0},  /* Line A */
                   1724: 
                   1725: {A(0x2c), 0},  /* Line F */
                   1726: 
                   1727: {A(0x60), 0},  /* spurious interrupt */
                   1728: 
                   1729: {A(0x64), 0},          /* level 1 interrupt */
                   1730: 
                   1731: {A(0x68), 0},  /* level 2 interrupt */
                   1732: 
                   1733: {A(0x6c), 0},  /* level 3 interrupt */
                   1734: 
                   1735: {A(0x70), 0},  /* level 4 interrupt */
                   1736: 
                   1737: {A(0x74), 0},  /* level 5 interrupt */
                   1738: 
                   1739: {A(0x78), 0},  /* level 6 interrupt */
                   1740: 
                   1741: {A(0x7c), 0},  /* level 7 interrupt */
                   1742: 
                   1743: {A(0x100), 0}, /* various MFP interrupts */
                   1744: 
                   1745: {A(0x104), 0},
                   1746: 
                   1747: {A(0x108), 0},
                   1748: 
                   1749: {A(0x10c), 0},
                   1750: 
                   1751: {A(0x110), 0},
                   1752: 
                   1753: {A(0x114), 0},
                   1754: 
                   1755: {A(0x118), 0},
                   1756: 
                   1757: {A(0x11c), 0},
                   1758: 
                   1759: {A(0x120), 0},
                   1760: 
                   1761: {A(0x124), 0},
                   1762: 
                   1763: {A(0x128), 0},
                   1764: 
                   1765: {A(0x12c), 0},
                   1766: 
                   1767: {A(0x130), 0},
                   1768: 
                   1769: {A(0x134), 0},
                   1770: 
                   1771: {A(0x138), 0},
                   1772: 
                   1773: {A(0x13c), 0},
                   1774: 
                   1775: {A(0x400), 0}, /* etv_timer */
                   1776: 
                   1777: {A(0x4f6), 0},  /* shell_p */
                   1778: 
                   1779: 
                   1780: 
                   1781: {A(0), 0}      /* special tag indicating end of list */
                   1782: 
                   1783: };
                   1784: 
                   1785: 
                   1786: 
                   1787: void
                   1788: 
                   1789: init_vectors() 
                   1790: 
                   1791: {
                   1792: 
                   1793:        struct vectab *v;
                   1794: 
                   1795: 
                   1796: 
                   1797:        for (v = VEC; v->addr; v++) {
                   1798: 
                   1799:                v->def_value = *(v->addr);
                   1800: 
                   1801:        } 
                   1802: 
                   1803: }
                   1804: 
                   1805: 
                   1806: 
                   1807: #if 0  /* bad code */
                   1808: 
                   1809: 
                   1810: 
                   1811: /* unhook a vector; if possible, do this with XBRA, but
                   1812: 
                   1813:  * if that isn't possible force the vector to have the
                   1814: 
                   1815:  * same value it had when MiNT started
                   1816: 
                   1817:  */
                   1818: 
                   1819: 
                   1820: 
                   1821: static void
                   1822: 
                   1823: unhook(v, where)
                   1824: 
                   1825:        struct vectab *v;
                   1826: 
                   1827:        long where;
                   1828: 
                   1829: {
                   1830: 
                   1831:        xbra_vec *xbra;
                   1832: 
                   1833:        long newval;
                   1834: 
                   1835:        int cookie;
                   1836: 
                   1837: 
                   1838: 
                   1839: /* to check for XBRA, we need access to the memory where the
                   1840: 
                   1841:  * vector is
                   1842: 
                   1843:  */
                   1844: 
                   1845:        cookie = prot_temp(where - 12, 16L, -1);
                   1846: 
                   1847: 
                   1848: 
                   1849:        if (cookie == 0)
                   1850: 
                   1851:                newval = v->def_value;
                   1852: 
                   1853:        else {
                   1854: 
                   1855:                xbra = (xbra_vec *)(where - 12);
                   1856: 
                   1857:                if (xbra->xbra_magic == XBRA_MAGIC) {
                   1858: 
                   1859:                        newval = (long)xbra->next;
                   1860: 
                   1861:                } else {
                   1862: 
                   1863:                        newval = v->def_value;
                   1864: 
                   1865:                }
                   1866: 
                   1867:        }
                   1868: 
                   1869:        *(v->addr) = newval;
                   1870: 
                   1871: 
                   1872: 
                   1873:        (void)prot_temp(where - 12, 16L, cookie);
                   1874: 
                   1875: }
                   1876: 
                   1877: #endif
                   1878: 
                   1879: 
                   1880: 
                   1881: /*
                   1882: 
                   1883:  * unlink_vectors(start, end): any of the "normal" system vectors
                   1884: 
                   1885:  * pointing into a freed memory region must be reset to their
                   1886: 
                   1887:  * default values, or else we'll get a memory protection violation
                   1888: 
                   1889:  * next time the vector gets called
                   1890: 
                   1891:  */
                   1892: 
                   1893: 
                   1894: 
                   1895: void
                   1896: 
                   1897: unlink_vectors(start, end)
                   1898: 
                   1899:        long start, end;
                   1900: 
                   1901: {
                   1902: 
                   1903: #if 0  /* this code is hosed somewhere */
                   1904: 
                   1905: 
                   1906: 
                   1907:        struct vectab *v;
                   1908: 
                   1909:        long where, *p;
                   1910: 
                   1911:        int i;
                   1912: 
                   1913: 
                   1914: 
                   1915: /* first, unhook any VBL handlers */
                   1916: 
                   1917:        i = *((short *)0x454L); /* i = nvbls */
                   1918: 
                   1919:        p = *((long **)0x456L); /* p = _vblqueue */
                   1920: 
                   1921:        while (i-- > 0) {
                   1922: 
                   1923:                where = *p;
                   1924: 
                   1925:                if (where >= start && where < end)
                   1926: 
                   1927:                        *p = 0;
                   1928: 
                   1929:                p++;
                   1930: 
                   1931:        }
                   1932: 
                   1933: 
                   1934: 
                   1935: /* next, unhook various random vectors */
                   1936: 
                   1937:        for (v = VEC; v->addr; v++) {
                   1938: 
                   1939:                where = *(v->addr);
                   1940: 
                   1941:                if (where >= start && where < end) {
                   1942: 
                   1943:                        unhook(v, where);
                   1944: 
                   1945:                }
                   1946: 
                   1947:        }
                   1948: 
1.1.1.4   root     1949: #else
                   1950: 
                   1951:        UNUSED(start); UNUSED(end);
                   1952: 
1.1.1.3   root     1953: #endif
                   1954: 
                   1955: }
                   1956: 
                   1957: 
1.1       root     1958: 

unix.superglobalmegacorp.com

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