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

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

unix.superglobalmegacorp.com

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