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

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.1.6 ! root       49: #define        SERDEV 6        /* First serial port */
        !            50: 
1.1       root       51: 
                     52: 
                     53: /* BIOS devices 0..MAX_BHANDLE-1 can be redirected to GEMDOS files */
                     54: 
                     55: #define MAX_BHANDLE    4
                     56: 
                     57: 
                     58: 
                     59: /* BIOS redirection maps */
                     60: 
1.1.1.2   root       61: const short binput[MAX_BHANDLE] = { -3, -2, -1, -4 };
1.1       root       62: 
1.1.1.2   root       63: const short boutput[MAX_BHANDLE] = { -3, -2, -1, -5 };
1.1       root       64: 
                     65: 
                     66: 
                     67: /* tty structures for the BIOS devices -- see biosfs.c */
                     68: 
1.1.1.6 ! root       69: extern struct tty con_tty, aux_tty, midi_tty, sccb_tty, scca_tty, ttmfp_tty;
        !            70: 
        !            71: extern struct bios_tty bttys[], midi_btty;
        !            72: 
        !            73: extern short btty_max;
1.1       root       74: 
                     75: 
                     76: 
                     77: extern int tosvers;    /* from main.c */
                     78: 
1.1.1.4   root       79: 
                     80: 
1.1       root       81: char *kbshft;          /* set in main.c */
                     82: 
                     83: 
                     84: 
1.1.1.5   root       85: short console_in;      /* wait condition for console input */
                     86: 
                     87: 
                     88: 
1.1.1.6 ! root       89: /* save cluster sizes of BIOS drives 0..31 (used in tosfs.c) */
        !            90: 
        !            91: unsigned short clsizb[32];
        !            92: 
        !            93: 
        !            94: 
1.1       root       95: /* some BIOS vectors; note that the routines at these vectors may do nasty
                     96: 
                     97:  * things to registers!
                     98: 
                     99:  */
                    100: 
                    101: 
                    102: 
1.1.1.2   root      103: #define RWABS *((long *)0x476L)
1.1       root      104: 
1.1.1.2   root      105: #define MEDIACH *((long *)0x47eL)
1.1       root      106: 
1.1.1.2   root      107: #define GETBPB *((long *)0x472L)
1.1       root      108: 
                    109: 
                    110: 
1.1.1.3   root      111: 
                    112: 
1.1.1.2   root      113: /* these are supposed to be tables holding the addresses of the
1.1       root      114: 
1.1.1.2   root      115:  * first 8 BconXXX functions, but in fact only the first 5 are
1.1       root      116: 
1.1.1.2   root      117:  * placed here (and device 5 only has Bconout implemented; 
1.1       root      118: 
1.1.1.2   root      119:  * we don't use that device (raw console) anyway).
1.1       root      120: 
1.1.1.2   root      121:  */
                    122: 
                    123: 
                    124: 
                    125: #define xconstat ((long *)0x51eL)
                    126: 
                    127: #define xconin         ((long *)0x53eL)
                    128: 
                    129: #define xcostat ((long *)0x55eL)
                    130: 
                    131: #define xconout        ((long *)0x57eL)
                    132: 
                    133: 
                    134: 
1.1.1.6 ! root      135: #if 1
        !           136: 
        !           137: /* if the system has Bconmap the ones >= 6 are in a table available
        !           138: 
        !           139:  * thru Bconmap(-2)...
        !           140: 
        !           141:  */
        !           142: 
        !           143: #define MAPTAB (bconmap2->maptab)
        !           144: 
        !           145: 
        !           146: 
        !           147: /* and then do BCOSTAT ourselves, the BIOS SCC ones are often broken */
        !           148: 
        !           149: #define BCOSTAT(dev) \
        !           150: 
        !           151:        (((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
        !           152: 
        !           153:           (int)callout1(xcostat[dev], dev) : Bcostat(dev)) : \
        !           154: 
        !           155:           ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
        !           156: 
        !           157:                bcxstat(MAPTAB[dev-SERDEV].iorec+1) : Bcostat(dev)))
        !           158: 
        !           159: #define BCONOUT(dev, c) \
        !           160: 
        !           161:        (((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
        !           162: 
        !           163:           callout2(xconout[dev], dev, c) : Bconout(dev, c)) : \
        !           164: 
        !           165:           ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
        !           166: 
        !           167:                callout2(MAPTAB[dev-SERDEV].bconout, dev, c) : Bconout(dev, c)))
        !           168: 
        !           169: #define BCONSTAT(dev) \
        !           170: 
        !           171:        (((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
        !           172: 
        !           173:           (int)callout1(xconstat[dev], dev) : Bconstat(dev)) : \
        !           174: 
        !           175:           ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
        !           176: 
        !           177:                (int)callout1(MAPTAB[dev-SERDEV].bconstat, dev) : Bconstat(dev)))
        !           178: 
        !           179: #define BCONIN(dev) \
        !           180: 
        !           181:        (((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
        !           182: 
        !           183:           callout1(xconin[dev], dev) : Bconin(dev)) : \
        !           184: 
        !           185:           ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
        !           186: 
        !           187:                callout1(MAPTAB[dev-SERDEV].bconin, dev) : Bconin(dev)))
        !           188: 
        !           189: #else
        !           190: 
1.1.1.2   root      191: #define BCOSTAT(dev) \
                    192: 
1.1.1.4   root      193:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1.1.2   root      194: 
                    195:           (int)callout1(xcostat[dev], dev) : Bcostat(dev))
1.1       root      196: 
1.1.1.2   root      197: #define BCONOUT(dev, c) \
1.1       root      198: 
1.1.1.4   root      199:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1       root      200: 
1.1.1.2   root      201:           callout2(xconout[dev], dev, c) : Bconout(dev, c))
1.1       root      202: 
1.1.1.2   root      203: #define BCONSTAT(dev) \
1.1       root      204: 
1.1.1.4   root      205:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1.1.2   root      206: 
                    207:           (int)callout1(xconstat[dev], dev) : Bconstat(dev))
                    208: 
                    209: #define BCONIN(dev) \
                    210: 
1.1.1.4   root      211:        ((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
1.1.1.2   root      212: 
                    213:           callout1(xconin[dev], dev) : Bconin(dev))
1.1       root      214: 
1.1.1.6 ! root      215: #endif
        !           216: 
1.1.1.3   root      217: 
                    218: 
1.1.1.6 ! root      219: /* variables for monitoring the keyboard */
1.1.1.3   root      220: 
1.1.1.6 ! root      221: IOREC_T        *keyrec;                /* keyboard i/o record pointer */
1.1.1.3   root      222: 
1.1.1.6 ! root      223: BCONMAP2_T *bconmap2;          /* bconmap struct */
1.1.1.3   root      224: 
1.1.1.6 ! root      225: short  kintr = 0;              /* keyboard interrupt pending (see intr.s) */
1.1.1.3   root      226: 
1.1       root      227: 
                    228: 
1.1.1.6 ! root      229: /* replacement *costat for BCOSTAT above */
1.1       root      230: 
1.1.1.6 ! root      231: INLINE static int bcxstat (IOREC_T *wrec)
1.1       root      232: 
1.1.1.6 ! root      233: {
        !           234: 
        !           235:        unsigned s = wrec->head - wrec->tail;
        !           236: 
        !           237:        if ((int)s <= 0)
        !           238: 
        !           239:                s += wrec->buflen;
        !           240: 
        !           241:        return s < 3 ? 0 : -1;
        !           242: 
        !           243: }
1.1       root      244: 
                    245: 
                    246: 
                    247: /* Getmpb is not allowed under MiNT */
                    248: 
                    249: 
                    250: 
1.1.1.2   root      251: long ARGS_ON_STACK
1.1       root      252: 
                    253: getmpb(ptr)
                    254: 
                    255:        void *ptr;
                    256: 
                    257: {
                    258: 
1.1.1.2   root      259:        UNUSED(ptr);
                    260: 
                    261: 
                    262: 
                    263:        DEBUG(("failed call to Getmpb"));
1.1       root      264: 
                    265:        return -1;
                    266: 
                    267: }
                    268: 
                    269: 
                    270: 
1.1.1.6 ! root      271: INLINE static int
        !           272: 
        !           273: isonline(b)
        !           274: 
        !           275:        struct bios_tty *b;
        !           276: 
        !           277: {
        !           278: 
        !           279:        if (b->tty == &aux_tty) {
        !           280: 
        !           281:        /* modem1 */
        !           282: 
        !           283:        /* CD is !bit 1 on the 68901 GPIP port */
        !           284: 
        !           285:                return (1 << 1) & ~*((volatile char *) 0xfffffa01L);
        !           286: 
        !           287:        } else if (b->tty == &sccb_tty) {
        !           288: 
        !           289:        /* modem2 */
        !           290: 
        !           291:        /* CD is bit 3 of read register 0 on SCC port B */
        !           292: 
        !           293:                short sr = spl7();
        !           294: 
        !           295:                unsigned char r;
        !           296: 
        !           297:                volatile char dummy;
        !           298: 
        !           299:                dummy = *((volatile char *) 0xfffffa01L);
        !           300: 
        !           301:                r = (1 << 3) & *((volatile char *) 0xffff8c85L);
        !           302: 
        !           303:                spl(sr);
        !           304: 
        !           305:                return r;
        !           306: 
        !           307:        } else if (b->tty == &scca_tty) {
        !           308: 
        !           309:        /* serial2 */
        !           310: 
        !           311:        /* like modem2, only port A */
        !           312: 
        !           313:                short sr = spl7();
        !           314: 
        !           315:                unsigned char r;
        !           316: 
        !           317:                volatile char dummy;
        !           318: 
        !           319:                dummy = *((volatile char *) 0xfffffa01L);
        !           320: 
        !           321:                r = (1 << 3) & *((volatile char *) 0xffff8c81L);
        !           322: 
        !           323:                spl(sr);
        !           324: 
        !           325:                return r;
        !           326: 
        !           327:        } else {
        !           328: 
        !           329:        /* unknown port, assume CD always on. */
        !           330: 
        !           331:                return 1;
        !           332: 
        !           333:        }
        !           334: 
        !           335: }
        !           336: 
        !           337: 
        !           338: 
        !           339: INLINE static int
        !           340: 
        !           341: isbrk(b)
        !           342: 
        !           343:        struct bios_tty *b;
        !           344: 
        !           345: {
        !           346: 
        !           347:        if (b->tty == &aux_tty) {
        !           348: 
        !           349:        /* modem1 */
        !           350: 
        !           351:        /* break is bit 3 in the 68901 RSR */
        !           352: 
        !           353:                return (1 << 3) & *((volatile char *) 0xfffffa2bL);
        !           354: 
        !           355:        } else if (b->tty == &sccb_tty) {
        !           356: 
        !           357:        /* modem2 */
        !           358: 
        !           359:        /* break is bit 7 of read register 0 on SCC port B */
        !           360: 
        !           361:                short sr = spl7();
        !           362: 
        !           363:                unsigned char r;
        !           364: 
        !           365:                volatile char dummy;
        !           366: 
        !           367:                dummy = *((volatile char *) 0xfffffa01L);
        !           368: 
        !           369:                r = (1 << 7) & *((volatile char *) 0xffff8c85L);
        !           370: 
        !           371:                spl(sr);
        !           372: 
        !           373:                return r;
        !           374: 
        !           375:        } else if (b->tty == &scca_tty) {
        !           376: 
        !           377:        /* serial2 */
        !           378: 
        !           379:        /* like modem2, only port A */
        !           380: 
        !           381:                short sr = spl7();
        !           382: 
        !           383:                unsigned char r;
        !           384: 
        !           385:                volatile char dummy;
        !           386: 
        !           387:                dummy = *((volatile char *) 0xfffffa01L);
        !           388: 
        !           389:                r = (1 << 7) & *((volatile char *) 0xffff8c81L);
        !           390: 
        !           391:                spl(sr);
        !           392: 
        !           393:                return r;
        !           394: 
        !           395:        } else if (b->tty == &ttmfp_tty) {
        !           396: 
        !           397:        /* serial1 */
        !           398: 
        !           399:                return (1 << 3) & *((volatile char *) 0xfffffaabL);
        !           400: 
        !           401:        } else {
        !           402: 
        !           403:        /* unknown port, cannot detect breaks... */
        !           404: 
        !           405:                return 0;
        !           406: 
        !           407:        }
        !           408: 
        !           409: }
        !           410: 
        !           411: 
        !           412: 
        !           413: INLINE unsigned
        !           414: 
        !           415: ionwrite(wrec)
        !           416: 
        !           417:        IOREC_T *wrec;
        !           418: 
        !           419: {
        !           420: 
        !           421:        unsigned s = wrec->head - wrec->tail;
        !           422: 
        !           423:        if ((int)s <= 0)
        !           424: 
        !           425:                s += wrec->buflen;
        !           426: 
        !           427:        if ((int)(s -= 2) < 0)
        !           428: 
        !           429:                s = 0;
        !           430: 
        !           431:        return s;
        !           432: 
        !           433: }
        !           434: 
        !           435: 
        !           436: 
        !           437: INLINE unsigned
        !           438: 
        !           439: ionread(irec)
        !           440: 
        !           441:        IOREC_T *irec;
        !           442: 
        !           443: {
        !           444: 
        !           445:        unsigned r = irec->tail - irec->head;
        !           446: 
        !           447:        if ((int)r < 0)
        !           448: 
        !           449:                r += irec->buflen;
        !           450: 
        !           451:        return r;
        !           452: 
        !           453: }
        !           454: 
        !           455: 
        !           456: 
        !           457: INLINE unsigned
        !           458: 
        !           459: btty_ionread(b)
        !           460: 
        !           461:        struct bios_tty *b;
        !           462: 
        !           463: {
        !           464: 
        !           465:        long ret = 0;
        !           466: 
        !           467: #if 1
        !           468: 
        !           469: /* try trap #1 first, to read hardware fifos too...
        !           470: 
        !           471:  * (except for modem1/serial1 which are always in one-interrupt-per-byte mode)
        !           472: 
        !           473:  */
        !           474: 
        !           475:        if (b != bttys && b->tty != &ttmfp_tty &&
        !           476: 
        !           477:            !rsvf_ioctl (b->tosfd, &ret, FIONREAD))
        !           478: 
        !           479:                return ret;
        !           480: 
        !           481: #endif
        !           482: 
        !           483:        return ionread (b->irec);
        !           484: 
        !           485: }
        !           486: 
        !           487: 
        !           488: 
        !           489: #define _hz_200 (*((long *)0x4baL))
        !           490: 
        !           491: 
        !           492: 
        !           493: INLINE static void
        !           494: 
        !           495: checkbtty(b, sig)
        !           496: 
        !           497:        struct bios_tty *b;
        !           498: 
        !           499:        int sig;
        !           500: 
        !           501: {
        !           502: 
        !           503:        long *l;
        !           504: 
        !           505: 
        !           506: 
        !           507:        if (!b->irec)
        !           508: 
        !           509:                return;
        !           510: 
        !           511:        if (!b->clocal && !isonline(b)) {
        !           512: 
        !           513:                b->vticks = 0;
        !           514: 
        !           515:                b->bticks = _hz_200 + 0x80000000L;
        !           516: 
        !           517:                if (!(b->tty->state & TS_BLIND)) {
        !           518: 
        !           519: /* just lost carrier...  set TS_BLIND, let reads and writes return */
        !           520: 
        !           521:                        b->tty->state |= TS_BLIND;
        !           522: 
        !           523:                        iocsbrk (b->bdev, TIOCCBRK, b);
        !           524: 
        !           525:                        if (sig) {
        !           526: 
        !           527:                                b->orec->tail = b->orec->head;
        !           528: 
        !           529:                                DEBUG(("checkbtty: bdev %d disconnect", b->bdev));
        !           530: 
        !           531:                                if (!(b->tty->sg.sg_flags & T_NOFLSH))
        !           532: 
        !           533:                                        iread (b->bdev, (char *) NULL, 0, 1, 0);
        !           534: 
        !           535:                                if (b->tty->pgrp)
        !           536: 
        !           537: /* ...and here is the long missed :) SIGHUP  */
        !           538: 
        !           539:                                        killgroup(b->tty->pgrp, SIGHUP, 1);
        !           540: 
        !           541:                        }
        !           542: 
        !           543:                        wake(IO_Q, (long)b);
        !           544: 
        !           545:                        wake(IO_Q, (long)&b->tty->state);
        !           546: 
        !           547:                }
        !           548: 
        !           549:                return;
        !           550: 
        !           551:        }
        !           552: 
        !           553:        if (b->tty->state & TS_BLIND) {
        !           554: 
        !           555: /* just got carrier (or entered local mode), clear TS_BLIND and
        !           556: 
        !           557:  * wake whoever waits for it */
        !           558: 
        !           559:                b->tty->state &= ~(TS_BLIND|TS_HOLD);
        !           560: 
        !           561:                wake(IO_Q, (long)&b->tty->state);
        !           562: 
        !           563:        }
        !           564: 
        !           565:        if (sig) {
        !           566: 
        !           567:                if (b->brkint && isbrk(b)) {
        !           568: 
        !           569:                        if (!b->bticks) {
        !           570: 
        !           571: /* the break should last for more than 200 ms or the equivalent of
        !           572: 
        !           573:  * 48 10-bit chars at ispeed (then its probably not line noise...)
        !           574: 
        !           575:  */
        !           576: 
        !           577:                                if ((unsigned long)b->ispeed <= 2400)
        !           578: 
        !           579:                                        b->bticks = _hz_200+40L;
        !           580: 
        !           581:                                else
        !           582: 
        !           583:                                        b->bticks = _hz_200+(480L*200L/(unsigned long)b->ispeed);
        !           584: 
        !           585:                                if (!b->bticks)
        !           586: 
        !           587:                                        b->bticks = 1;
        !           588: 
        !           589:                        } else if (_hz_200 - b->bticks > 0) {
        !           590: 
        !           591: /* every break only one interrupt please */
        !           592: 
        !           593:                                b->bticks += 0x80000000L;
        !           594: 
        !           595:                                DEBUG(("checkbtty: bdev %d break(int)", b->bdev));
        !           596: 
        !           597:                                if (!(b->tty->sg.sg_flags & T_NOFLSH))
        !           598: 
        !           599:                                        iread (b->bdev, (char *) NULL, 0, 1, 0);
        !           600: 
        !           601:                                if (b->tty->pgrp)
        !           602: 
        !           603:                                        killgroup(b->tty->pgrp, SIGINT, 1);
        !           604: 
        !           605:                        }
        !           606: 
        !           607:                } else
        !           608: 
        !           609:                        b->bticks = 0;
        !           610: 
        !           611:        }
        !           612: 
        !           613:        if (!b->vticks || _hz_200 - b->vticks > 0) {
        !           614: 
        !           615:                long r;
        !           616: 
        !           617: 
        !           618: 
        !           619:                if ((r = (long)b->tty->vmin - btty_ionread(b)) <= 0) {
        !           620: 
        !           621:                        b->vticks = 0;
        !           622: 
        !           623:                        wake(IO_Q, (long)b);
        !           624: 
        !           625:                        l = b->rsel;
        !           626: 
        !           627:                        if (*l)
        !           628: 
        !           629:                                wakeselect(*l);
        !           630: 
        !           631:                } else if ((--r, r *= 2000L) > (unsigned long)b->ispeed) {
        !           632: 
        !           633:                        b->vticks = _hz_200 + (r/(unsigned long)b->ispeed);
        !           634: 
        !           635:                        if (!b->vticks)
        !           636: 
        !           637:                                b->vticks = 1;
        !           638: 
        !           639:                } else
        !           640: 
        !           641:                        b->vticks = 0;
        !           642: 
        !           643:        }
        !           644: 
        !           645:        if (b->tty->state & TS_HOLD)
        !           646: 
        !           647:                return;
        !           648: 
        !           649:        l = b->wsel;
        !           650: 
        !           651:        if (*l) {
        !           652: 
        !           653:                short i = b->orec->tail - b->orec->head;
        !           654: 
        !           655:                if (i < 0)
        !           656: 
        !           657:                        i += b->orec->buflen;
        !           658: 
        !           659:                if (i < b->orec->hi_water)
        !           660: 
        !           661:                        wakeselect(*l);
        !           662: 
        !           663:        }
        !           664: 
        !           665: }
        !           666: 
        !           667: 
        !           668: 
        !           669: void
        !           670: 
        !           671: checkbttys(void)
        !           672: 
        !           673: {
        !           674: 
        !           675:        struct bios_tty *b;
        !           676: 
        !           677: 
        !           678: 
        !           679:        for (b=bttys;b<bttys+btty_max;b++) {
        !           680: 
        !           681:                checkbtty(b, 1);
        !           682: 
        !           683:        }
        !           684: 
        !           685:        b=&midi_btty;
        !           686: 
        !           687:        if (!b->vticks || _hz_200 - b->vticks > 0) {
        !           688: 
        !           689:                long r, *l;
        !           690: 
        !           691: 
        !           692: 
        !           693:                if ((r = (long)b->tty->vmin - ionread(b->irec)) <= 0) {
        !           694: 
        !           695:                        b->vticks = 0;
        !           696: 
        !           697:                        wake(IO_Q, (long)b);
        !           698: 
        !           699:                        l = b->rsel;
        !           700: 
        !           701:                        if (*l)
        !           702: 
        !           703:                                wakeselect(*l);
        !           704: 
        !           705:                } else if ((--r, r *= 2000L) > (unsigned long)31250) {
        !           706: 
        !           707:                        b->vticks = _hz_200 + (r/(unsigned long)31250);
        !           708: 
        !           709:                        if (!b->vticks)
        !           710: 
        !           711:                                b->vticks = 1;
        !           712: 
        !           713:                } else
        !           714: 
        !           715:                        b->vticks = 0;
        !           716: 
        !           717:        }
        !           718: 
        !           719: }
        !           720: 
        !           721: 
        !           722: 
        !           723: void
        !           724: 
        !           725: checkbttys_vbl(void)
        !           726: 
        !           727: {
        !           728: 
        !           729:        struct bios_tty *b;
        !           730: 
        !           731: 
        !           732: 
        !           733:        for (b=bttys;b<bttys+btty_max;b++) {
        !           734: 
        !           735:                if (!b->clocal && b->orec->tail != b->orec->head && !isonline(b))
        !           736: 
        !           737:                        b->orec->tail = b->orec->head;
        !           738: 
        !           739:        }
        !           740: 
        !           741: }
        !           742: 
        !           743: 
        !           744: 
        !           745: /* check 1 tty without raising sigs, needed after turning off local mode
        !           746: 
        !           747:  * (to avoid getting SIGHUP'd immediately...)
        !           748: 
        !           749:  */
        !           750: 
        !           751: 
        !           752: 
        !           753: void
        !           754: 
        !           755: checkbtty_nsig(b)
        !           756: 
        !           757:        struct bios_tty *b;
        !           758: 
        !           759: {
        !           760: 
        !           761:        checkbtty(b, 0);
        !           762: 
        !           763: }
        !           764: 
1.1       root      765: 
                    766: 
                    767: /*
                    768: 
                    769:  * Note that BIOS handles 0 - MAX_BHANDLE now reference file handles;
                    770: 
                    771:  * to get the physical devices, go through u:\dev\
                    772: 
                    773:  *
                    774: 
                    775:  * A note on translation: all of the bco[n]XXX functions have a "u"
                    776: 
                    777:  * variant that is actually what the user calls. For example,
                    778: 
                    779:  * ubconstat is the function that gets control after the user does
                    780: 
                    781:  * a Bconstat. It figures out what device or file handle is
                    782: 
                    783:  * appropriate. Typically, it will be a biosfs file handle; a
                    784: 
                    785:  * request is sent to biosfs, and biosfs in turn figures out
                    786: 
                    787:  * the "real" device and calls bconstat.
                    788: 
                    789:  */
                    790: 
                    791: 
                    792: 
1.1.1.2   root      793: /*
                    794: 
                    795:  * WARNING: syscall.spp assumes that ubconstat never blocks.
                    796: 
                    797:  */
                    798: 
                    799: long ARGS_ON_STACK
1.1       root      800: 
                    801: ubconstat(dev)
                    802: 
                    803: int dev;
                    804: 
                    805: {
                    806: 
1.1.1.2   root      807:        if (dev < MAX_BHANDLE) {
                    808: 
                    809:                FILEPTR *f = curproc->handle[binput[dev]];
1.1       root      810: 
1.1.1.2   root      811:                return file_instat(f) ? -1 : 0;
                    812: 
                    813:        }
1.1       root      814: 
                    815:        else
                    816: 
                    817:                return bconstat(dev);
                    818: 
                    819: }
                    820: 
                    821: 
                    822: 
                    823: long
                    824: 
                    825: bconstat(dev)
                    826: 
                    827: int dev;
                    828: 
                    829: {
                    830: 
                    831:        if (dev == CONSDEV) {
                    832: 
                    833:                if (checkkeys()) return 0;
                    834: 
                    835:                return (keyrec->head != keyrec->tail) ? -1 : 0;
                    836: 
                    837:        }
                    838: 
                    839:        if (dev == AUXDEV && has_bconmap)
                    840: 
                    841:                dev = curproc->bconmap;
                    842: 
                    843: 
                    844: 
1.1.1.2   root      845:        return BCONSTAT(dev);
1.1       root      846: 
                    847: }
                    848: 
                    849: 
                    850: 
                    851: /* bconin: input a character */
                    852: 
1.1.1.2   root      853: /*
1.1       root      854: 
1.1.1.2   root      855:  * WARNING: syscall.spp assumes that ubconin never
1.1       root      856: 
1.1.1.2   root      857:  * blocks if ubconstat returns non-zero.
                    858: 
                    859:  */
                    860: 
                    861: long ARGS_ON_STACK
1.1       root      862: 
                    863: ubconin(dev)
                    864: 
                    865: int dev;
                    866: 
                    867: {
                    868: 
1.1.1.2   root      869:        if (dev < MAX_BHANDLE) {
                    870: 
                    871:                FILEPTR *f = curproc->handle[binput[dev]];
1.1       root      872: 
1.1.1.2   root      873:                return file_getchar(f, RAW);
                    874: 
                    875:        }
1.1       root      876: 
                    877:        else
                    878: 
                    879:                return bconin(dev);
                    880: 
                    881: }
                    882: 
                    883: 
                    884: 
                    885: long
                    886: 
                    887: bconin(dev)
                    888: 
                    889: int dev;
                    890: 
                    891: {
                    892: 
                    893:        IOREC_T *k;
                    894: 
                    895:        long r;
                    896: 
                    897:        short h;
                    898: 
                    899: 
                    900: 
                    901:        if (dev == CONSDEV) {
                    902: 
                    903:                k = keyrec;
                    904: 
                    905: again:
                    906: 
                    907:                while (k->tail == k->head) {
                    908: 
1.1.1.5   root      909:                        sleep(IO_Q, (long)&console_in);
1.1       root      910: 
                    911:                }
                    912: 
                    913: 
                    914: 
                    915:                if (checkkeys()) goto again;
                    916: 
                    917: 
                    918: 
                    919:                h = k->head + 4;
                    920: 
                    921:                if (h >= k->buflen)
                    922: 
                    923:                        h = 0;
                    924: 
                    925:                r = *((long *)(k->bufaddr + h));
                    926: 
                    927:                k->head = h;
                    928: 
                    929:                return r;
                    930: 
                    931:        }
                    932: 
                    933:        else {
                    934: 
1.1.1.6 ! root      935:                if (dev == AUXDEV) {
        !           936: 
        !           937:                        if (has_bconmap) {
        !           938: 
        !           939:                                dev = curproc->bconmap;
        !           940: 
        !           941:                                h = dev-SERDEV;
        !           942: 
        !           943:                        } else
1.1       root      944: 
1.1.1.6 ! root      945:                                h = 0;
        !           946: 
        !           947:                } else
        !           948: 
        !           949:                        h = dev-SERDEV;
        !           950: 
        !           951: 
        !           952: 
        !           953:                if ((unsigned)h < btty_max || dev == 3) {
        !           954: 
        !           955:                        if (has_bconmap && dev != 3) {  /* help the compiler... :) */
        !           956: 
        !           957:                                long *statc;
        !           958: 
        !           959: 
        !           960: 
        !           961:                                while (!callout1(*(statc=&MAPTAB[dev-SERDEV].bconstat), dev))
        !           962: 
        !           963:                                        sleep(IO_Q, (long)&bttys[h]);
        !           964: 
        !           965:                                return callout1(statc[1], dev);
        !           966: 
        !           967:                        }
1.1       root      968: 
1.1.1.6 ! root      969:                        while (!BCONSTAT(dev))
1.1       root      970: 
1.1.1.6 ! root      971:                                sleep(IO_Q, (long)(dev == 3 ? &midi_btty :
1.1       root      972: 
1.1.1.6 ! root      973:                                                                &bttys[h]));
        !           974: 
        !           975:                } else if (dev > 0) {
1.1       root      976: 
1.1.1.5   root      977:                        unsigned long tick;
                    978: 
                    979: 
                    980: 
                    981:                        tick = *((unsigned long *)0x4baL);
                    982: 
1.1.1.2   root      983:                        while (!BCONSTAT(dev)) {
1.1       root      984: 
1.1.1.5   root      985: /* make blocking (for longer) reads eat less CPU...
                    986: 
                    987:  * if yield()ed > 2 seconds and still no data continue with nap
                    988: 
                    989:  */
                    990: 
                    991:                        if ((*((unsigned long *)0x4baL) - tick) > 400)
                    992: 
                    993:                                nap(60);
                    994: 
                    995:                        else
                    996: 
1.1       root      997:                                yield();
                    998: 
                    999:                        }
                   1000: 
1.1.1.2   root     1001:                }
                   1002: 
1.1       root     1003:        }
                   1004: 
                   1005: 
                   1006: 
1.1.1.2   root     1007:        r = BCONIN(dev);
1.1       root     1008: 
                   1009: 
                   1010: 
                   1011:        return r;
                   1012: 
                   1013: }
                   1014: 
                   1015: 
                   1016: 
                   1017: /* bconout: output a character.
                   1018: 
                   1019:  * returns 0 for failure, nonzero for success
                   1020: 
                   1021:  */
                   1022: 
                   1023: 
                   1024: 
1.1.1.2   root     1025: long ARGS_ON_STACK
1.1       root     1026: 
                   1027: ubconout(dev, c)
                   1028: 
                   1029: int dev, c;
                   1030: 
                   1031: {
                   1032: 
                   1033:        FILEPTR *f;
                   1034: 
1.1.1.2   root     1035:        char outp;
                   1036: 
1.1       root     1037: 
                   1038: 
                   1039:        if (dev < MAX_BHANDLE) {
                   1040: 
                   1041:                f = curproc->handle[boutput[dev]];
                   1042: 
                   1043:                if (!f) return 0;
                   1044: 
                   1045:                if (is_terminal(f)) {
                   1046: 
                   1047:                        return tty_putchar(f, ((long)c)&0x00ff, RAW);
                   1048: 
                   1049:                }
                   1050: 
1.1.1.2   root     1051:                outp = c;
1.1       root     1052: 
1.1.1.2   root     1053:                return (*f->dev->write)(f, &outp, 1L);
1.1       root     1054: 
                   1055:        }
                   1056: 
                   1057:        else if (dev == 5) {
                   1058: 
                   1059:                c &= 0x00ff;
                   1060: 
                   1061:                f = curproc->handle[-1];
                   1062: 
                   1063:                if (!f) return 0;
                   1064: 
                   1065:                if (is_terminal(f)) {
                   1066: 
                   1067:                        if (c < ' ') {
                   1068: 
                   1069:                        /* MW hack for quoted characters */
                   1070: 
                   1071:                                tty_putchar(f, (long)'\033', RAW);
                   1072: 
                   1073:                                tty_putchar(f, (long)'Q', RAW);
                   1074: 
                   1075:                        }
                   1076: 
                   1077:                        return tty_putchar(f, ((long)c)&0x00ff, RAW);
                   1078: 
                   1079:                }
                   1080: 
                   1081:        /* note: we're assuming sizeof(int) == 2 here! */
                   1082: 
1.1.1.2   root     1083:                outp = c;
                   1084: 
                   1085:                return (*f->dev->write)(f, &outp, 1L);
1.1       root     1086: 
                   1087:        } else
                   1088: 
                   1089:                return bconout(dev, c);
                   1090: 
                   1091: }
                   1092: 
                   1093: 
                   1094: 
                   1095: long
                   1096: 
                   1097: bconout(dev, c)
                   1098: 
                   1099: int dev,c;
                   1100: 
                   1101: {
                   1102: 
                   1103:        int statdev;
                   1104: 
                   1105:        long endtime;
                   1106: 
1.1.1.3   root     1107: #define curtime *((unsigned long *)0x4baL)
1.1       root     1108: 
                   1109: 
                   1110: 
                   1111:        if (dev == AUXDEV && has_bconmap) {
                   1112: 
                   1113:                dev = curproc->bconmap;
                   1114: 
                   1115:        }
                   1116: 
                   1117: 
                   1118: 
                   1119: /* compensate for a known BIOS bug; MIDI and IKBD are switched */
                   1120: 
                   1121:        if (dev == 3) {         /* MIDI */
                   1122: 
                   1123:                statdev = 4;
                   1124: 
                   1125:        } else if (dev == 4) {
                   1126: 
                   1127:                statdev = 3;
                   1128: 
1.1.1.3   root     1129:        } else {
1.1       root     1130: 
                   1131:                statdev = dev;
                   1132: 
1.1.1.3   root     1133:        }
                   1134: 
1.1       root     1135: 
                   1136: 
1.1.1.4   root     1137: /* provide a 10 second time out for the printer */
1.1       root     1138: 
1.1.1.2   root     1139:        if (!BCOSTAT(statdev)) {
1.1       root     1140: 
1.1.1.4   root     1141:                if (dev != PRNDEV) {
                   1142: 
                   1143:                        do {
                   1144: 
                   1145:        /* BUG: Speedo GDOS isn't re-entrant; so printer output to the
                   1146: 
                   1147:         * serial port could cause problems
1.1       root     1148: 
1.1.1.4   root     1149:         */
                   1150: 
                   1151:                                yield();
                   1152: 
                   1153:                        } while (!BCOSTAT(statdev));
                   1154: 
                   1155:                } else {
                   1156: 
                   1157:                        endtime = curtime + 10*200L;
                   1158: 
                   1159:                        do {
1.1       root     1160: 
1.1.1.3   root     1161: #if 0
                   1162: 
1.1.1.4   root     1163:        /* Speedo GDOS isn't re-entrant, so we can't give up CPU
                   1164: 
                   1165:         * time here :-(
                   1166: 
                   1167:         */
                   1168: 
                   1169:                                yield();
1.1.1.2   root     1170: 
1.1.1.3   root     1171: #endif
1.1       root     1172: 
1.1.1.4   root     1173:                        } while (!BCOSTAT(statdev) && curtime < endtime);
                   1174: 
                   1175:                        if ( curtime >= endtime) return 0;
1.1.1.3   root     1176: 
1.1.1.4   root     1177:                }
1.1.1.2   root     1178: 
                   1179:        }
1.1       root     1180: 
                   1181: 
                   1182: 
                   1183: /* special case: many text accelerators return a bad value from
                   1184: 
                   1185:  * Bconout, so we ignore the returned value for the console
                   1186: 
1.1.1.4   root     1187:  * Sigh. serptch2 and hsmodem1 also screw this up, so for now let's
                   1188: 
                   1189:  * only count on it being correct for the printer.
                   1190: 
1.1       root     1191:  */
                   1192: 
1.1.1.4   root     1193:        if (dev == PRNDEV) {
1.1       root     1194: 
                   1195: /* NOTE: if your compiler complains about the next line, then Bconout is
                   1196: 
                   1197:  * improperly declared in your osbind.h header file. it should be returning
                   1198: 
                   1199:  * a long value; some libraries incorrectly have Bconout returning void
                   1200: 
                   1201:  * (or cast the returned value to void)
                   1202: 
                   1203:  */
                   1204: 
1.1.1.2   root     1205:                return BCONOUT(dev,c);
1.1       root     1206: 
                   1207:        } else {
                   1208: 
1.1.1.2   root     1209:                (void)BCONOUT(dev, c);
1.1       root     1210: 
                   1211:                return 1;
                   1212: 
                   1213:        }
                   1214: 
                   1215: }
                   1216: 
                   1217: 
                   1218: 
                   1219: /* rwabs: various disk stuff */
                   1220: 
                   1221: 
                   1222: 
1.1.1.2   root     1223: long ARGS_ON_STACK
1.1       root     1224: 
                   1225: rwabs(rwflag, buffer, number, recno, dev, lrecno)
                   1226: 
                   1227: int rwflag, number, recno, dev;
                   1228: 
                   1229: void *buffer;
                   1230: 
                   1231: long lrecno;
                   1232: 
                   1233: {
                   1234: 
                   1235:        long r;
                   1236: 
1.1.1.2   root     1237:        extern PROC *dlockproc[];       /* in dosdir.c */
                   1238: 
1.1.1.5   root     1239:        extern int aliasdrv[];          /* in filesys.c */
                   1240: 
1.1.1.2   root     1241: 
                   1242: 
1.1.1.6 ! root     1243:        /* jr: inspect bit 3 of rwflag!!! */
        !          1244: 
        !          1245:        
        !          1246: 
        !          1247:        if (!(rwflag & 8) && dev >= 0 && dev < NUM_DRIVES) {
1.1.1.2   root     1248: 
1.1.1.5   root     1249:                if (aliasdrv[dev]) {
                   1250: 
                   1251:                        dev = aliasdrv[dev] - 1;
                   1252: 
                   1253:                }
                   1254: 
                   1255:                if (dlockproc[dev] && dlockproc[dev] != curproc) {
1.1.1.2   root     1256: 
                   1257:                        DEBUG(("Rwabs: device %c is locked", dev+'A'));
                   1258: 
                   1259:                        return ELOCKED;
                   1260: 
                   1261:                }
                   1262: 
                   1263:        }
                   1264: 
1.1       root     1265: 
                   1266: 
1.1.1.6 ! root     1267: #if 0  /* commented out so that loadable file systems work :-( */
1.1.1.5   root     1268: 
                   1269: /* only the superuser can make Rwabs calls directly */
1.1       root     1270: 
                   1271: 
                   1272: 
1.1.1.5   root     1273:        if (curproc->in_dos || (curproc->euid == 0))
                   1274: 
                   1275:        /* Note that some (most?) Rwabs device drivers don't bother saving
                   1276: 
                   1277:         * registers, whereas our compiler expects politeness. So we go
                   1278: 
                   1279:         * via callout(), which will save registers for us.
                   1280: 
                   1281:         */
                   1282: 
                   1283:                r = callout(RWABS, rwflag, buffer, number, recno, dev, lrecno);
                   1284: 
                   1285:        else {
                   1286: 
                   1287:                DEBUG(("Rwabs by non privileged process!"));
                   1288: 
                   1289:                r = EACCDN;
                   1290: 
                   1291:        }
                   1292: 
                   1293: #else
1.1       root     1294: 
                   1295:        r = callout(RWABS, rwflag, buffer, number, recno, dev, lrecno);
                   1296: 
1.1.1.5   root     1297: #endif
                   1298: 
1.1       root     1299:        return r;
                   1300: 
                   1301: }
                   1302: 
                   1303: 
                   1304: 
                   1305: /* setexc: set exception vector */
                   1306: 
                   1307: 
                   1308: 
1.1.1.2   root     1309: long ARGS_ON_STACK
1.1       root     1310: 
                   1311: setexc(number, vector)
                   1312: 
                   1313: int number;
                   1314: 
                   1315: long vector;
                   1316: 
                   1317: {
                   1318: 
                   1319:        long *place;
                   1320: 
                   1321:        long old;
                   1322: 
                   1323:        extern long save_dos, save_bios, save_xbios;    /* in main.c */
                   1324: 
1.1.1.3   root     1325:        extern int no_mem_prot;                         /* in main.c */
1.1       root     1326: 
                   1327: 
                   1328: 
                   1329:        place = (long *)(((long)number) << 2);
                   1330: 
                   1331:        if (number == 0x21)                             /* trap_1 */
                   1332: 
                   1333:                old = save_dos;
                   1334: 
                   1335:        else if (number == 0x2d)                        /* trap_13 */
                   1336: 
                   1337:                old = save_bios;
                   1338: 
                   1339:        else if (number == 0x2e)                        /* trap_14 */
                   1340: 
                   1341:                old = save_xbios;
                   1342: 
                   1343:        else if (number == 0x101)
                   1344: 
                   1345:                old = (long)curproc->criticerr;         /* critical error vector */
                   1346: 
                   1347:        else if (number == 0x102)
                   1348: 
                   1349:                old = curproc->ctxt[SYSCALL].term_vec;  /* GEMDOS term vector */
                   1350: 
                   1351:        else
                   1352: 
                   1353:                old = *place;
                   1354: 
                   1355: 
                   1356: 
                   1357:        if (vector > 0) {
                   1358: 
1.1.1.3   root     1359:        /* validate vector; this will cause a bus error if mem
                   1360: 
                   1361:         * protection is on and the current process doesn't have
                   1362: 
                   1363:         * access to the memory
                   1364: 
                   1365:         */
                   1366: 
                   1367:                if (*((long *)vector) == 0xDEADBEEFL)
                   1368: 
                   1369:                        return old;
                   1370: 
                   1371: 
                   1372: 
1.1       root     1373:                if (number == 0x21)
                   1374: 
                   1375:                        save_dos = vector;
                   1376: 
                   1377:                else if (number == 0x2d)
                   1378: 
                   1379:                        save_bios = vector;
                   1380: 
                   1381:                else if (number == 0x2e)
                   1382: 
                   1383:                        save_xbios = vector;
                   1384: 
                   1385:                else if (number == 0x102)
                   1386: 
                   1387:                        curproc->ctxt[SYSCALL].term_vec = vector;
                   1388: 
                   1389:                else if (number == 0x101) {
                   1390: 
                   1391:                        long mintcerr;
                   1392: 
                   1393: 
                   1394: 
                   1395:                /*
                   1396: 
                   1397:                 * problem: lots of TSR's look for the Setexc(0x101,...)
                   1398: 
                   1399:                 * that the AES does at startup time; so we have
                   1400: 
                   1401:                 * to pass it along.
                   1402: 
                   1403:                 */
                   1404: 
                   1405:                        mintcerr = (long) Setexc(0x101, (void *)vector);
                   1406: 
1.1.1.2   root     1407:                        curproc->criticerr = (long ARGS_ON_STACK (*) P_((long))) *place;
1.1       root     1408: 
                   1409:                        *place = mintcerr;
                   1410: 
                   1411:                }
                   1412: 
                   1413:                else {
                   1414: 
1.1.1.3   root     1415:                        if (!no_mem_prot) {
                   1416: 
                   1417:                        /*
                   1418: 
                   1419:                         * if memory protection is on, the vector should be
                   1420: 
                   1421:                         * pointing at supervisor or global memory
                   1422: 
                   1423:                         */
                   1424: 
                   1425:                            MEMREGION *r;
                   1426: 
                   1427: 
                   1428: 
                   1429:                            r = addr2region(vector);
                   1430: 
                   1431:                            if (r && get_prot_mode(r) == PROT_P) {
                   1432: 
                   1433:                                DEBUG(("Changing protection to Supervisor because of Setexc"));
                   1434: 
                   1435:                                mark_region(r, PROT_S);
                   1436: 
                   1437:                            }
                   1438: 
                   1439:                        }
                   1440: 
1.1       root     1441:                /* We would do just *place = vector except that
                   1442: 
                   1443:                 * someone else might be intercepting Setexc looking
                   1444: 
                   1445:                 * for something in particular...
                   1446: 
                   1447:                 */
                   1448: 
                   1449:                        old = (long) Setexc(number, (void *)vector);
                   1450: 
                   1451:                }
                   1452: 
                   1453:        }
                   1454: 
1.1.1.3   root     1455: 
                   1456: 
                   1457:        TRACE(("Setexc %d, %lx -> %lx", number, vector, old));
                   1458: 
1.1       root     1459:        return old;
                   1460: 
                   1461: }
                   1462: 
                   1463: 
                   1464: 
                   1465: /* tickcal: return milliseconds per system clock tick */
                   1466: 
                   1467: 
                   1468: 
1.1.1.2   root     1469: long ARGS_ON_STACK
1.1       root     1470: 
                   1471: tickcal()
                   1472: 
                   1473: {
                   1474: 
                   1475:        return (long) (*( (unsigned *) 0x0442L ));
                   1476: 
                   1477: }
                   1478: 
                   1479: 
                   1480: 
                   1481: /* getbpb: get BIOS parameter block */
                   1482: 
                   1483: 
                   1484: 
1.1.1.2   root     1485: long ARGS_ON_STACK
1.1       root     1486: 
                   1487: getbpb(dev)
                   1488: 
                   1489: int dev;
                   1490: 
                   1491: {
                   1492: 
                   1493:        long r;
                   1494: 
                   1495: 
                   1496: 
                   1497: /* we can't trust the Getbpb routine to accurately save all registers,
                   1498: 
                   1499:  * so we do it ourselves
                   1500: 
                   1501:  */
                   1502: 
1.1.1.4   root     1503:        r = callout1(GETBPB, dev);
1.1       root     1504: 
                   1505: /* 
                   1506: 
                   1507:  * There is a bug in the  TOS  disk handling routines (well several actually).
                   1508: 
                   1509:  * If the directory size of Getbpb() is returned as zero then the drive 'dies'
                   1510: 
                   1511:  * and wont read any new disks even with the 'ESC' enforced disk change . This
                   1512: 
                   1513:  * is present even in TOS 1.6 (not sure about 1.62 though). This small routine
                   1514: 
                   1515:  * changes the dir size to '1' if it is zero . It may make some non-TOS disks
                   1516: 
                   1517:  * look a bit weird but that's better than killing the drive .
                   1518: 
                   1519:  */
                   1520: 
                   1521:        if (r) {
                   1522: 
                   1523:                if ( ((short *)r)[3] == 0)      /* 0 directory size? */
                   1524: 
                   1525:                        ((short *)r)[3] = 1;
                   1526: 
1.1.1.6 ! root     1527: 
        !          1528: 
        !          1529:                /* jr: save cluster size in area */
        !          1530: 
        !          1531:                if (dev >= 0 && dev < 32)
        !          1532: 
        !          1533:                        clsizb[dev] = ((unsigned short *)r)[2];
        !          1534: 
1.1       root     1535:        }
                   1536: 
                   1537:        return r;
                   1538: 
                   1539: }
                   1540: 
                   1541: 
                   1542: 
                   1543: /* bcostat: return output device status */
                   1544: 
                   1545: 
                   1546: 
1.1.1.2   root     1547: /* WARNING: syscall.spp assumes that ubcostat never
                   1548: 
                   1549:  * blocks
                   1550: 
                   1551:  */
                   1552: 
                   1553: long ARGS_ON_STACK
1.1       root     1554: 
                   1555: ubcostat(dev)
                   1556: 
                   1557: int dev;
                   1558: 
                   1559: {
                   1560: 
1.1.1.2   root     1561:        FILEPTR *f;
                   1562: 
                   1563: 
                   1564: 
1.1       root     1565: /* the BIOS switches MIDI (3) and IKBD (4) (a bug, but it can't be corrected) */
                   1566: 
                   1567:        if (dev == 4) {         /* really the MIDI port */
                   1568: 
1.1.1.2   root     1569:                f = curproc->handle[boutput[3]];
                   1570: 
                   1571:                return file_outstat(f) ? -1 : 0;
1.1       root     1572: 
                   1573:        }
                   1574: 
                   1575:        if (dev == 3)
                   1576: 
1.1.1.2   root     1577:                return BCOSTAT(dev);
1.1       root     1578: 
                   1579: 
                   1580: 
1.1.1.2   root     1581:        if (dev < MAX_BHANDLE) {
1.1       root     1582: 
1.1.1.2   root     1583:                f = curproc->handle[boutput[dev]];
1.1       root     1584: 
1.1.1.2   root     1585:                return file_outstat(f) ? -1 : 0;
                   1586: 
                   1587:        } else
1.1       root     1588: 
                   1589:                return bcostat(dev);
                   1590: 
                   1591: }
                   1592: 
                   1593: 
                   1594: 
                   1595: long
                   1596: 
                   1597: bcostat(dev)
                   1598: 
                   1599: int dev;
                   1600: 
                   1601: {
                   1602: 
                   1603: 
                   1604: 
                   1605:        if (dev == CONSDEV) {
                   1606: 
                   1607:                return -1;
                   1608: 
                   1609:        }
                   1610: 
                   1611:        else if (dev == AUXDEV && has_bconmap) {
                   1612: 
                   1613:                dev = curproc->bconmap;
                   1614: 
                   1615:        }
                   1616: 
                   1617: /* compensate here for the BIOS bug, so that the MIDI and IKBD files work
                   1618: 
                   1619:  * correctly
                   1620: 
                   1621:  */
                   1622: 
                   1623:        else if (dev == 3) dev = 4;
                   1624: 
                   1625:        else if (dev == 4) dev = 3;
                   1626: 
                   1627: 
                   1628: 
1.1.1.2   root     1629:        return BCOSTAT(dev);
1.1       root     1630: 
                   1631: }
                   1632: 
                   1633: 
                   1634: 
                   1635: /* mediach: check for media change */
                   1636: 
                   1637: 
                   1638: 
1.1.1.2   root     1639: long ARGS_ON_STACK
1.1       root     1640: 
                   1641: mediach(dev)
                   1642: 
                   1643: int dev;
                   1644: 
                   1645: {
                   1646: 
                   1647:        long r;
                   1648: 
                   1649: 
                   1650: 
1.1.1.3   root     1651:        r = callout1(MEDIACH, dev);
1.1       root     1652: 
                   1653:        return r;
                   1654: 
                   1655: }
                   1656: 
                   1657: 
                   1658: 
                   1659: /* drvmap: return drives connected to system */
                   1660: 
                   1661: 
                   1662: 
1.1.1.2   root     1663: long ARGS_ON_STACK
1.1       root     1664: 
                   1665: drvmap()
                   1666: 
                   1667: {
                   1668: 
                   1669:        return *( (long *)0x4c2L );
                   1670: 
                   1671: }
                   1672: 
                   1673: 
                   1674: 
                   1675: /* kbshift: return (and possibly change) keyboard shift key status */
                   1676: 
1.1.1.2   root     1677: /* WARNING: syscall.spp assumes that kbshift never blocks, and never
1.1       root     1678: 
1.1.1.2   root     1679:  * calls any underlying TOS functions
1.1       root     1680: 
1.1.1.2   root     1681:  */
                   1682: 
                   1683: long ARGS_ON_STACK
1.1       root     1684: 
                   1685: kbshift(mode)
                   1686: 
                   1687: int mode;
                   1688: 
                   1689: {
                   1690: 
                   1691:        int oldshft;
                   1692: 
                   1693: 
                   1694: 
                   1695:        oldshft = *((unsigned char *)kbshft);
                   1696: 
                   1697:        if (mode >= 0)
                   1698: 
                   1699:                *kbshft = mode;
                   1700: 
                   1701:        return oldshft;
                   1702: 
                   1703: }
                   1704: 
                   1705: 
                   1706: 
                   1707: 
                   1708: 
                   1709: /* special Bconout buffering code:
                   1710: 
                   1711:  * Because system call overhead is so high, programs that do output
                   1712: 
                   1713:  * with Bconout suffer in performance. To compensate for this,
                   1714: 
                   1715:  * Bconout is special-cased in syscall.s, and if possible characters
                   1716: 
                   1717:  * are placed in the 256 byte bconbuf buffer. This buffer is flushed
                   1718: 
                   1719:  * when any system call other than Bconout happens, or when a context
                   1720: 
                   1721:  * switch occurs.
                   1722: 
                   1723:  */
                   1724: 
                   1725: 
                   1726: 
                   1727: short bconbsiz;                        /* number of characters in buffer */
                   1728: 
                   1729: unsigned char bconbuf[256];    /* buffer contents */
                   1730: 
                   1731: short bconbdev;                        /* BIOS device for which the buffer is valid */
                   1732: 
                   1733:                                /* (-1 means no buffering is active) */
                   1734: 
                   1735: 
                   1736: 
                   1737: /*
                   1738: 
                   1739:  * flush pending BIOS output. Return 0 if some bytes were not successfully
                   1740: 
                   1741:  * written, non-zero otherwise (just like bconout)
                   1742: 
                   1743:  */
                   1744: 
                   1745: 
                   1746: 
1.1.1.2   root     1747: long ARGS_ON_STACK
1.1       root     1748: 
                   1749: bflush()               /* flush bios output */
                   1750: 
                   1751: {
                   1752: 
                   1753:        long ret, bsiz;
                   1754: 
                   1755:        unsigned char *s;
                   1756: 
                   1757:        FILEPTR *f;
                   1758: 
                   1759:        short dev;
                   1760: 
                   1761:        short statdev;
                   1762: 
1.1.1.2   root     1763:        long lbconbuf[256];
                   1764: 
1.1       root     1765: 
                   1766: 
                   1767:        if ((dev = bconbdev) < 0) return 0;
                   1768: 
                   1769: 
                   1770: 
                   1771: /*
                   1772: 
                   1773:  * Here we lock the BIOS buffering mechanism by setting bconbdev to -1
                   1774: 
                   1775:  * This is necessary because if two or more programs try to do
                   1776: 
                   1777:  * buffered BIOS output at the same time, they can get seriously
                   1778: 
                   1779:  * mixed up. We unlock by setting bconbdev to 0.
                   1780: 
                   1781:  *
                   1782: 
                   1783:  * NOTE: some code (e.g. in sleep()) checks for bconbsiz != 0 in
                   1784: 
                   1785:  * order to see if we need to do a bflush; if one is already in
                   1786: 
                   1787:  * progress, it's pointless to do this, so we save a bit of
                   1788: 
                   1789:  * time by setting bconbsiz to 0 here.
                   1790: 
                   1791:  */
                   1792: 
                   1793:        bconbdev = -1;
                   1794: 
                   1795:        bsiz = bconbsiz;
                   1796: 
1.1.1.2   root     1797:        if (bsiz == 0) return 0;
                   1798: 
1.1       root     1799:        bconbsiz = 0;
                   1800: 
                   1801: 
                   1802: 
                   1803: /* BIOS handles 0..MAX_BHANDLE-1 are aliases for special GEMDOS files */
                   1804: 
                   1805:        if (dev < MAX_BHANDLE || dev == 5) {
                   1806: 
                   1807:                if (dev == 5)
                   1808: 
                   1809:                        f = curproc->handle[-1];
                   1810: 
                   1811:                else
                   1812: 
                   1813:                        f = curproc->handle[boutput[dev]];
                   1814: 
                   1815: 
                   1816: 
                   1817:                if (!f) {
                   1818: 
                   1819:                        bconbdev = 0;
                   1820: 
                   1821:                        return 0;
                   1822: 
                   1823:                }
                   1824: 
                   1825:                if (is_terminal(f)) {
                   1826: 
1.1.1.6 ! root     1827:                        int oldflags = f->flags;
        !          1828: 
        !          1829: 
        !          1830: 
1.1       root     1831:                        s = bconbuf;
                   1832: 
1.1.1.6 ! root     1833: /* turn off NDELAY for this write... */
        !          1834: 
        !          1835:                        f->flags &= ~O_NDELAY;
        !          1836: 
1.1       root     1837:                        if (dev == 5) {
                   1838: 
                   1839:                            while (bsiz-- > 0) {
                   1840: 
                   1841:                                if (*s < ' ') {
                   1842: 
                   1843:                        /* use ESC-Q to quote control character */
                   1844: 
                   1845:                                        (void)tty_putchar(f, (long)'\033',
                   1846: 
                   1847:                                                                RAW);
                   1848: 
                   1849:                                        (void)tty_putchar(f, (long)'Q',
                   1850: 
                   1851:                                                                RAW);
                   1852: 
                   1853:                                }
                   1854: 
                   1855:                                (void) tty_putchar(f, (long)*s++, RAW);
                   1856: 
                   1857:                            }
                   1858: 
                   1859:                        } else {
                   1860: 
1.1.1.6 ! root     1861:                            long *where, nbytes;
        !          1862: 
1.1.1.2   root     1863: #if 1
                   1864: 
1.1.1.6 ! root     1865:                            extern FILESYS bios_filesys;
        !          1866: 
        !          1867: 
        !          1868: 
        !          1869:                            /* see if we can do fast RAW byte IO thru the device driver... */
        !          1870: 
        !          1871:                            if ((f->fc.fs != &bios_filesys ||
        !          1872: 
        !          1873:                                    (bsiz > 1 &&
        !          1874: 
        !          1875:                                     ((struct bios_file *)f->fc.index)->drvsize >
        !          1876: 
        !          1877:                                            offsetof (DEVDRV, writeb))) && f->dev->writeb) {
        !          1878: 
        !          1879:                                struct tty *tty = (struct tty *)f->devinfo;
        !          1880: 
        !          1881: 
        !          1882: 
        !          1883:                                tty_checkttou (f, tty);
1.1.1.2   root     1884: 
1.1.1.6 ! root     1885:                                tty->state &= ~TS_COOKED;
1.1.1.2   root     1886: 
1.1.1.6 ! root     1887:                                if ((ret = (*f->dev->writeb)(f, (char *)s, bsiz)) != EUNDEV) {
        !          1888: 
        !          1889:                                        f->flags = oldflags;
        !          1890: 
        !          1891:                                        bconbdev = 0;
        !          1892: 
        !          1893:                                        return ret;
        !          1894: 
        !          1895:                                }
        !          1896: 
        !          1897:                            }
        !          1898: 
        !          1899: #endif
1.1.1.2   root     1900: 
                   1901: /* the tty_putchar should set up terminal modes correctly */
                   1902: 
                   1903:                            (void) tty_putchar(f, (long)*s++, RAW);
                   1904: 
                   1905:                            where = lbconbuf;
                   1906: 
                   1907:                            nbytes = 0;
                   1908: 
                   1909:                            while (--bsiz > 0) {
                   1910: 
                   1911:                                *where++ = *s++; nbytes+=4;
                   1912: 
                   1913:                            }
                   1914: 
                   1915:                            if (nbytes)
                   1916: 
                   1917:                                (*f->dev->write)(f, (char *)lbconbuf, nbytes);
                   1918: 
1.1       root     1919:                        }
                   1920: 
                   1921:                        ret = -1;
                   1922: 
1.1.1.6 ! root     1923:                        f->flags = oldflags;
        !          1924: 
1.1       root     1925:                } else {
                   1926: 
                   1927:                        ret = (*f->dev->write)(f, (char *)bconbuf, bsiz);
                   1928: 
                   1929:                }
                   1930: 
                   1931:                bconbdev = 0;
                   1932: 
                   1933:                return ret;
                   1934: 
                   1935:        }
                   1936: 
                   1937: 
                   1938: 
                   1939: /* Otherwise, we have a real BIOS device */
                   1940: 
                   1941: 
                   1942: 
                   1943:        if (dev == AUXDEV && has_bconmap) {
                   1944: 
                   1945:                dev = curproc->bconmap;
                   1946: 
                   1947:                statdev = dev;
                   1948: 
                   1949:        }
                   1950: 
1.1.1.6 ! root     1951:        if ((ret = iwrite (dev, bconbuf, bsiz, 0, 0)) != EUNDEV) {
1.1       root     1952: 
1.1.1.6 ! root     1953:                bconbdev = 0;
        !          1954: 
        !          1955:                return ret;
        !          1956: 
        !          1957:        } else if (dev == 3) {          /* MIDI */
        !          1958: 
        !          1959:        /* compensate for a known BIOS bug; MIDI and IKBD are switched */
1.1       root     1960: 
                   1961:                statdev = 4;
                   1962: 
                   1963:        } else if (dev == 4) {
                   1964: 
                   1965:                statdev = 3;
                   1966: 
                   1967:        } else
                   1968: 
                   1969:                statdev = dev;
                   1970: 
                   1971:                
                   1972: 
                   1973:        s = bconbuf;
                   1974: 
                   1975:        while (bsiz-- > 0) {
                   1976: 
1.1.1.2   root     1977:                while (!BCOSTAT(statdev)) yield();
1.1       root     1978: 
1.1.1.2   root     1979:                (void)BCONOUT(dev,*s);
1.1       root     1980: 
                   1981:                s++;
                   1982: 
                   1983:        }
                   1984: 
                   1985:        bconbdev = 0;
                   1986: 
                   1987:        return 1L;
                   1988: 
                   1989: }
                   1990: 
                   1991: 
                   1992: 
                   1993: /* initialize bios table */
                   1994: 
                   1995: 
                   1996: 
                   1997: #define BIOS_MAX 0x20
                   1998: 
                   1999: 
                   2000: 
                   2001: Func bios_tab[BIOS_MAX] = {
                   2002: 
                   2003:        getmpb,
                   2004: 
                   2005:        ubconstat,
                   2006: 
                   2007:        ubconin,
                   2008: 
                   2009:        ubconout,
                   2010: 
1.1.1.2   root     2011: 
                   2012: 
1.1       root     2013:        rwabs,
                   2014: 
                   2015:        setexc,
                   2016: 
                   2017:        tickcal,
                   2018: 
                   2019:        getbpb,
                   2020: 
1.1.1.2   root     2021: 
                   2022: 
1.1       root     2023:        ubcostat,
                   2024: 
                   2025:        mediach,
                   2026: 
                   2027:        drvmap,
                   2028: 
                   2029:        kbshift,
                   2030: 
1.1.1.2   root     2031: 
                   2032: 
1.1       root     2033:        0, 0, 0, 0,
                   2034: 
                   2035:        0, 0, 0, 0, 0, 0, 0, 0,
                   2036: 
                   2037:        0, 0, 0, 0, 0, 0, 0, 0
                   2038: 
                   2039: };
                   2040: 
                   2041: 
                   2042: 
                   2043: short bios_max = BIOS_MAX;
                   2044: 
                   2045: 
                   2046: 
                   2047: /*
                   2048: 
                   2049:  * BIOS initialization routine: gets keyboard buffer pointers, for the
                   2050: 
                   2051:  * interrupt routine below
                   2052: 
                   2053:  */
                   2054: 
                   2055: 
                   2056: 
                   2057: void
                   2058: 
                   2059: init_bios()
                   2060: 
                   2061: {
                   2062: 
                   2063:        keyrec = (IOREC_T *)Iorec(1);
                   2064: 
                   2065: }
                   2066: 
                   2067: 
                   2068: 
                   2069: /*
                   2070: 
1.1.1.2   root     2071:  * do_bconin: try to do a bconin function quickly, without
                   2072: 
                   2073:  * blocking. If we can't do it without blocking, we return
                   2074: 
                   2075:  * 0x0123dead and the calling trap #13 code falls through
                   2076: 
                   2077:  * to the normal bconin stuff. We can't block here because
                   2078: 
                   2079:  * the trap #13 code hasn't yet saved registers or other
                   2080: 
                   2081:  * context bits, so sleep() wouldn't work properly.
                   2082: 
                   2083:  */
                   2084: 
                   2085: 
                   2086: 
                   2087: #define WOULDBLOCK 0x0123deadL
                   2088: 
                   2089: 
                   2090: 
                   2091: /* WARNING: syscall.spp assumes that do_bconin never blocks */
                   2092: 
                   2093: 
                   2094: 
                   2095: long ARGS_ON_STACK
                   2096: 
                   2097: do_bconin(dev)
                   2098: 
                   2099:        int dev;
                   2100: 
                   2101: {
                   2102: 
                   2103:        FILEPTR *f;
                   2104: 
1.1.1.6 ! root     2105:        long r, nread;
1.1.1.2   root     2106: 
                   2107:        unsigned char c;
                   2108: 
                   2109: 
                   2110: 
                   2111:        if (dev < MAX_BHANDLE) {
                   2112: 
                   2113:                f = curproc->handle[binput[dev]];
                   2114: 
                   2115:                if (!f) return 0;
                   2116: 
1.1.1.6 ! root     2117:                nread = 0;
1.1.1.2   root     2118: 
1.1.1.6 ! root     2119:                (void)(*f->dev->ioctl)(f, FIONREAD, &nread);
1.1.1.2   root     2120: 
1.1.1.6 ! root     2121:                if (!nread) return WOULDBLOCK;  /* data not ready */
1.1.1.2   root     2122: 
                   2123:                if (is_terminal(f))
                   2124: 
                   2125:                        r = tty_getchar(f, RAW);
                   2126: 
                   2127:                else {
                   2128: 
                   2129:                        r = (*f->dev->read)(f, (char *)&c, 1L);
                   2130: 
                   2131:                        r = (r == 1) ? c : MiNTEOF;
                   2132: 
                   2133:                }
                   2134: 
                   2135:        } else {
                   2136: 
                   2137:                if (!bconstat(dev))
                   2138: 
                   2139:                        r = WOULDBLOCK;
                   2140: 
                   2141:                else
                   2142: 
                   2143:                        r = bconin(dev);
                   2144: 
                   2145:        }
                   2146: 
                   2147:        return r;
                   2148: 
                   2149: }
                   2150: 
                   2151: 
                   2152: 
                   2153: /*
                   2154: 
1.1       root     2155:  * routine for checking keyboard (called by sleep() on any context
                   2156: 
                   2157:  * switch where a keyboard event occured). returns 1 if a special
                   2158: 
                   2159:  * control character was eaten, 0 if not
                   2160: 
                   2161:  */
                   2162: 
                   2163: 
                   2164: 
                   2165: int
                   2166: 
                   2167: checkkeys()
                   2168: 
                   2169: {
                   2170: 
                   2171:        char scan, ch;
                   2172: 
                   2173:        short shift;
                   2174: 
                   2175:        int sig, ret;
                   2176: 
                   2177:        struct tty *tty = &con_tty;
                   2178: 
                   2179:        extern char mshift;             /* for mouse -- see biosfs.c */
                   2180: 
                   2181:        static short oldktail = 0;
                   2182: 
                   2183: 
                   2184: 
                   2185:        ret = 0;
                   2186: 
                   2187:        mshift = kbshift(-1);
                   2188: 
                   2189:        while (oldktail != keyrec->tail) {
                   2190: 
                   2191: 
                   2192: 
                   2193: /* BUG: we really should check the shift status _at the time the key was
                   2194: 
                   2195:  * pressed_, not now!
                   2196: 
                   2197:  */
                   2198: 
                   2199:                sig = 0;
                   2200: 
                   2201:                shift = mshift;
                   2202: 
                   2203:                oldktail += 4;
                   2204: 
                   2205:                if (oldktail >= keyrec->buflen)
                   2206: 
                   2207:                        oldktail = 0;
                   2208: 
                   2209: 
                   2210: 
                   2211:                scan = (keyrec->bufaddr + oldktail)[1];
                   2212: 
                   2213: /* function key?? */
                   2214: 
                   2215:                if ( (scan >= 0x3b && scan <= 0x44) ||
                   2216: 
                   2217:                     (scan >= 0x54 && scan <= 0x5d) ||
                   2218: 
                   2219:                     scan == DEL || scan == UNDO) {
                   2220: 
                   2221:                        if ( (shift & CTRLALT) == CTRLALT ) {
                   2222: 
                   2223:                                oldktail = keyrec->head = keyrec->tail;
                   2224: 
                   2225:                                do_func_key(scan);
                   2226: 
1.1.1.2   root     2227:                                /* do_func_key may have read some keys */
                   2228: 
                   2229:                                oldktail = keyrec->head;
                   2230: 
                   2231:                                mshift = kbshift (-1);
                   2232: 
1.1       root     2233:                                ret = 1;
                   2234: 
                   2235:                                continue;
                   2236: 
                   2237:                        }
                   2238: 
                   2239:                }
                   2240: 
                   2241: 
                   2242: 
                   2243: /* check for special control keys, etc. */
                   2244: 
                   2245: /* BUG: this doesn't exactly match TOS' behavior, particularly for
                   2246: 
                   2247:  * ^S/^Q
                   2248: 
                   2249:  */
                   2250: 
                   2251:                if ((tty->state & TS_COOKED) || (shift & CTRLALT) == CTRLALT) {
                   2252: 
                   2253:                        ch = (keyrec->bufaddr + keyrec->tail)[3];
                   2254: 
                   2255:                        if (ch == UNDEF)
                   2256: 
                   2257:                                ;       /* do nothing */
                   2258: 
                   2259:                        else if (ch == tty->tc.t_intrc)
                   2260: 
                   2261:                                sig = SIGINT;
                   2262: 
                   2263:                        else if (ch == tty->tc.t_quitc)
                   2264: 
                   2265:                                sig = SIGQUIT;
                   2266: 
                   2267:                        else if (ch == tty->ltc.t_suspc)
                   2268: 
                   2269:                                sig = SIGTSTP;
                   2270: 
                   2271:                        else if (ch == tty->tc.t_stopc) {
                   2272: 
                   2273:                                tty->state |= TS_HOLD;
                   2274: 
                   2275:                                ret = 1;
                   2276: 
                   2277:                                keyrec->head = oldktail;
                   2278: 
                   2279:                                continue;
                   2280: 
                   2281:                        }
                   2282: 
                   2283:                        else if (ch == tty->tc.t_startc) {
                   2284: 
                   2285:                                tty->state &= ~TS_HOLD;
                   2286: 
                   2287:                                ret = 1;
                   2288: 
                   2289:                                keyrec->head = oldktail;
                   2290: 
                   2291:                                continue;
                   2292: 
                   2293:                        }
                   2294: 
                   2295:                        if (sig) {
                   2296: 
                   2297:                                tty->state &= ~TS_HOLD;
                   2298: 
                   2299:                                if (!(tty->sg.sg_flags & T_NOFLSH))
                   2300: 
                   2301:                                    oldktail = keyrec->head = keyrec->tail;
                   2302: 
1.1.1.6 ! root     2303:                                killgroup(tty->pgrp, sig, 1);
1.1       root     2304: 
                   2305:                                ret = 1;
                   2306: 
                   2307:                        }
                   2308: 
                   2309:                        else if (tty->state & TS_HOLD) {
                   2310: 
                   2311:                                keyrec->head = oldktail;
                   2312: 
                   2313:                                ret = 1;
                   2314: 
                   2315:                        }
                   2316: 
                   2317:                }
                   2318: 
                   2319: 
                   2320: 
                   2321:        }
                   2322: 
                   2323: 
                   2324: 
1.1.1.5   root     2325:        if (keyrec->head != keyrec->tail) {
1.1       root     2326: 
1.1.1.5   root     2327:        /* wake up any processes waiting in bconin() */
1.1       root     2328: 
1.1.1.5   root     2329:                wake(IO_Q, (long)&console_in);
                   2330: 
                   2331:        /* wake anyone that did a select() on the keyboard */
                   2332: 
                   2333:                if (tty->rsel)
                   2334: 
                   2335:                        wakeselect(tty->rsel);
                   2336: 
                   2337:        }
1.1       root     2338: 
                   2339: 
                   2340: 
                   2341:        return ret;
                   2342: 
                   2343: }
                   2344: 
                   2345: 
                   2346: 
1.1.1.3   root     2347: 
                   2348: 
                   2349: /*
                   2350: 
                   2351:  * special vector stuff: we try to save as many vectors as possible,
                   2352: 
                   2353:  * just in case we need to restore them later
                   2354: 
                   2355:  *
                   2356: 
                   2357:  * BUG: this really should be integrated with the init_intr routine
                   2358: 
                   2359:  * in main.c
                   2360: 
                   2361:  */
                   2362: 
                   2363: 
                   2364: 
                   2365: #define A(x) ((long *)(long)(x))
                   2366: 
                   2367: #define L(x) (long)(x)
                   2368: 
                   2369: 
                   2370: 
                   2371: struct vectab {
                   2372: 
                   2373:        long *addr;
                   2374: 
                   2375:        long def_value;
                   2376: 
                   2377: } VEC[] = {
                   2378: 
                   2379: {A(0x28), 0},  /* Line A */
                   2380: 
                   2381: {A(0x2c), 0},  /* Line F */
                   2382: 
                   2383: {A(0x60), 0},  /* spurious interrupt */
                   2384: 
                   2385: {A(0x64), 0},          /* level 1 interrupt */
                   2386: 
                   2387: {A(0x68), 0},  /* level 2 interrupt */
                   2388: 
                   2389: {A(0x6c), 0},  /* level 3 interrupt */
                   2390: 
                   2391: {A(0x70), 0},  /* level 4 interrupt */
                   2392: 
                   2393: {A(0x74), 0},  /* level 5 interrupt */
                   2394: 
                   2395: {A(0x78), 0},  /* level 6 interrupt */
                   2396: 
                   2397: {A(0x7c), 0},  /* level 7 interrupt */
                   2398: 
                   2399: {A(0x100), 0}, /* various MFP interrupts */
                   2400: 
                   2401: {A(0x104), 0},
                   2402: 
                   2403: {A(0x108), 0},
                   2404: 
                   2405: {A(0x10c), 0},
                   2406: 
                   2407: {A(0x110), 0},
                   2408: 
                   2409: {A(0x114), 0},
                   2410: 
                   2411: {A(0x118), 0},
                   2412: 
                   2413: {A(0x11c), 0},
                   2414: 
                   2415: {A(0x120), 0},
                   2416: 
                   2417: {A(0x124), 0},
                   2418: 
                   2419: {A(0x128), 0},
                   2420: 
                   2421: {A(0x12c), 0},
                   2422: 
                   2423: {A(0x130), 0},
                   2424: 
                   2425: {A(0x134), 0},
                   2426: 
                   2427: {A(0x138), 0},
                   2428: 
                   2429: {A(0x13c), 0},
                   2430: 
                   2431: {A(0x400), 0}, /* etv_timer */
                   2432: 
                   2433: {A(0x4f6), 0},  /* shell_p */
                   2434: 
                   2435: 
                   2436: 
                   2437: {A(0), 0}      /* special tag indicating end of list */
                   2438: 
                   2439: };
                   2440: 
                   2441: 
                   2442: 
                   2443: void
                   2444: 
                   2445: init_vectors() 
                   2446: 
                   2447: {
                   2448: 
                   2449:        struct vectab *v;
                   2450: 
                   2451: 
                   2452: 
                   2453:        for (v = VEC; v->addr; v++) {
                   2454: 
                   2455:                v->def_value = *(v->addr);
                   2456: 
                   2457:        } 
                   2458: 
                   2459: }
                   2460: 
                   2461: 
                   2462: 
                   2463: #if 0  /* bad code */
                   2464: 
                   2465: 
                   2466: 
                   2467: /* unhook a vector; if possible, do this with XBRA, but
                   2468: 
                   2469:  * if that isn't possible force the vector to have the
                   2470: 
                   2471:  * same value it had when MiNT started
                   2472: 
                   2473:  */
                   2474: 
                   2475: 
                   2476: 
                   2477: static void
                   2478: 
                   2479: unhook(v, where)
                   2480: 
                   2481:        struct vectab *v;
                   2482: 
                   2483:        long where;
                   2484: 
                   2485: {
                   2486: 
                   2487:        xbra_vec *xbra;
                   2488: 
                   2489:        long newval;
                   2490: 
                   2491:        int cookie;
                   2492: 
                   2493: 
                   2494: 
                   2495: /* to check for XBRA, we need access to the memory where the
                   2496: 
                   2497:  * vector is
                   2498: 
                   2499:  */
                   2500: 
                   2501:        cookie = prot_temp(where - 12, 16L, -1);
                   2502: 
                   2503: 
                   2504: 
                   2505:        if (cookie == 0)
                   2506: 
                   2507:                newval = v->def_value;
                   2508: 
                   2509:        else {
                   2510: 
                   2511:                xbra = (xbra_vec *)(where - 12);
                   2512: 
                   2513:                if (xbra->xbra_magic == XBRA_MAGIC) {
                   2514: 
                   2515:                        newval = (long)xbra->next;
                   2516: 
                   2517:                } else {
                   2518: 
                   2519:                        newval = v->def_value;
                   2520: 
                   2521:                }
                   2522: 
                   2523:        }
                   2524: 
                   2525:        *(v->addr) = newval;
                   2526: 
                   2527: 
                   2528: 
                   2529:        (void)prot_temp(where - 12, 16L, cookie);
                   2530: 
                   2531: }
                   2532: 
                   2533: #endif
                   2534: 
                   2535: 
                   2536: 
                   2537: /*
                   2538: 
                   2539:  * unlink_vectors(start, end): any of the "normal" system vectors
                   2540: 
                   2541:  * pointing into a freed memory region must be reset to their
                   2542: 
                   2543:  * default values, or else we'll get a memory protection violation
                   2544: 
                   2545:  * next time the vector gets called
                   2546: 
                   2547:  */
                   2548: 
                   2549: 
                   2550: 
                   2551: void
                   2552: 
                   2553: unlink_vectors(start, end)
                   2554: 
                   2555:        long start, end;
                   2556: 
                   2557: {
                   2558: 
                   2559: #if 0  /* this code is hosed somewhere */
                   2560: 
                   2561: 
                   2562: 
                   2563:        struct vectab *v;
                   2564: 
                   2565:        long where, *p;
                   2566: 
                   2567:        int i;
                   2568: 
                   2569: 
                   2570: 
                   2571: /* first, unhook any VBL handlers */
                   2572: 
                   2573:        i = *((short *)0x454L); /* i = nvbls */
                   2574: 
                   2575:        p = *((long **)0x456L); /* p = _vblqueue */
                   2576: 
                   2577:        while (i-- > 0) {
                   2578: 
                   2579:                where = *p;
                   2580: 
                   2581:                if (where >= start && where < end)
                   2582: 
                   2583:                        *p = 0;
                   2584: 
                   2585:                p++;
                   2586: 
                   2587:        }
                   2588: 
                   2589: 
                   2590: 
                   2591: /* next, unhook various random vectors */
                   2592: 
                   2593:        for (v = VEC; v->addr; v++) {
                   2594: 
                   2595:                where = *(v->addr);
                   2596: 
                   2597:                if (where >= start && where < end) {
                   2598: 
                   2599:                        unhook(v, where);
                   2600: 
                   2601:                }
                   2602: 
                   2603:        }
                   2604: 
1.1.1.4   root     2605: #else
                   2606: 
                   2607:        UNUSED(start); UNUSED(end);
                   2608: 
1.1.1.3   root     2609: #endif
                   2610: 
                   2611: }
                   2612: 
                   2613: 
1.1       root     2614: 

unix.superglobalmegacorp.com

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