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

1.1       root        1: /*
                      2: 
                      3: Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
                      4: 
                      5: */
                      6: 
                      7: 
                      8: 
                      9: /*
                     10: 
                     11:  * BIOS replacement routines
                     12: 
                     13:  */
                     14: 
                     15: 
                     16: 
                     17: #include "mint.h"
                     18: 
                     19: 
                     20: 
                     21: #define UNDEF 0                /* should match definition in tty.c */
                     22: 
                     23: 
                     24: 
                     25: /* some key definitions */
                     26: 
                     27: #define CTRLALT 0xc
                     28: 
                     29: #define DEL 0x53       /* scan code of delete key */
                     30: 
                     31: #define UNDO 0x61      /* scan code of undo key */
                     32: 
                     33: 
                     34: 
                     35: /* BIOS device definitions */
                     36: 
                     37: #define CONSDEV 2
                     38: 
                     39: #define AUXDEV 1
                     40: 
                     41: 
                     42: 
                     43: /* BIOS devices 0..MAX_BHANDLE-1 can be redirected to GEMDOS files */
                     44: 
                     45: #define MAX_BHANDLE    4
                     46: 
                     47: 
                     48: 
                     49: /* BIOS redirection maps */
                     50: 
1.1.1.2 ! root       51: const short binput[MAX_BHANDLE] = { -3, -2, -1, -4 };
1.1       root       52: 
1.1.1.2 ! root       53: const short boutput[MAX_BHANDLE] = { -3, -2, -1, -5 };
1.1       root       54: 
                     55: 
                     56: 
                     57: /* tty structures for the BIOS devices -- see biosfs.c */
                     58: 
                     59: extern struct tty con_tty, aux_tty, midi_tty;
                     60: 
                     61: 
                     62: 
                     63: extern int tosvers;    /* from main.c */
                     64: 
                     65: char *kbshft;          /* set in main.c */
                     66: 
                     67: 
                     68: 
                     69: /* some BIOS vectors; note that the routines at these vectors may do nasty
                     70: 
                     71:  * things to registers!
                     72: 
                     73:  */
                     74: 
                     75: 
                     76: 
1.1.1.2 ! root       77: #define RWABS *((long *)0x476L)
1.1       root       78: 
1.1.1.2 ! root       79: #define MEDIACH *((long *)0x47eL)
1.1       root       80: 
1.1.1.2 ! root       81: #define GETBPB *((long *)0x472L)
1.1       root       82: 
                     83: 
                     84: 
1.1.1.2 ! root       85: /* these are supposed to be tables holding the addresses of the
1.1       root       86: 
1.1.1.2 ! root       87:  * first 8 BconXXX functions, but in fact only the first 5 are
1.1       root       88: 
1.1.1.2 ! root       89:  * placed here (and device 5 only has Bconout implemented; 
1.1       root       90: 
1.1.1.2 ! root       91:  * we don't use that device (raw console) anyway).
1.1       root       92: 
1.1.1.2 ! root       93:  */
        !            94: 
        !            95: 
        !            96: 
        !            97: #define xconstat ((long *)0x51eL)
        !            98: 
        !            99: #define xconin         ((long *)0x53eL)
        !           100: 
        !           101: #define xcostat ((long *)0x55eL)
        !           102: 
        !           103: #define xconout        ((long *)0x57eL)
        !           104: 
        !           105: 
        !           106: 
        !           107: #define BCOSTAT(dev) \
        !           108: 
        !           109:        ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
        !           110: 
        !           111:           (int)callout1(xcostat[dev], dev) : Bcostat(dev))
1.1       root      112: 
1.1.1.2 ! root      113: #define BCONOUT(dev, c) \
1.1       root      114: 
1.1.1.2 ! root      115:        ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
1.1       root      116: 
1.1.1.2 ! root      117:           callout2(xconout[dev], dev, c) : Bconout(dev, c))
1.1       root      118: 
1.1.1.2 ! root      119: #define BCONSTAT(dev) \
1.1       root      120: 
1.1.1.2 ! root      121:        ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
        !           122: 
        !           123:           (int)callout1(xconstat[dev], dev) : Bconstat(dev))
        !           124: 
        !           125: #define BCONIN(dev) \
        !           126: 
        !           127:        ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
        !           128: 
        !           129:           callout1(xconin[dev], dev) : Bconin(dev))
1.1       root      130: 
                    131: 
                    132: 
                    133: /* variables for monitoring the keyboard */
                    134: 
                    135: IOREC_T        *keyrec;                /* keyboard i/o record pointer */
                    136: 
                    137: short  kintr = 0;              /* keyboard interrupt pending (see intr.s) */
                    138: 
                    139: 
                    140: 
                    141: /* Getmpb is not allowed under MiNT */
                    142: 
                    143: 
                    144: 
1.1.1.2 ! root      145: long ARGS_ON_STACK
1.1       root      146: 
                    147: getmpb(ptr)
                    148: 
                    149:        void *ptr;
                    150: 
                    151: {
                    152: 
1.1.1.2 ! root      153:        UNUSED(ptr);
        !           154: 
        !           155: 
        !           156: 
        !           157:        DEBUG(("failed call to Getmpb"));
1.1       root      158: 
                    159:        return -1;
                    160: 
                    161: }
                    162: 
                    163: 
                    164: 
                    165: 
                    166: 
                    167: /*
                    168: 
                    169:  * Note that BIOS handles 0 - MAX_BHANDLE now reference file handles;
                    170: 
                    171:  * to get the physical devices, go through u:\dev\
                    172: 
                    173:  *
                    174: 
                    175:  * A note on translation: all of the bco[n]XXX functions have a "u"
                    176: 
                    177:  * variant that is actually what the user calls. For example,
                    178: 
                    179:  * ubconstat is the function that gets control after the user does
                    180: 
                    181:  * a Bconstat. It figures out what device or file handle is
                    182: 
                    183:  * appropriate. Typically, it will be a biosfs file handle; a
                    184: 
                    185:  * request is sent to biosfs, and biosfs in turn figures out
                    186: 
                    187:  * the "real" device and calls bconstat.
                    188: 
                    189:  */
                    190: 
                    191: 
                    192: 
1.1.1.2 ! root      193: /*
        !           194: 
        !           195:  * WARNING: syscall.spp assumes that ubconstat never blocks.
        !           196: 
        !           197:  */
        !           198: 
        !           199: long ARGS_ON_STACK
1.1       root      200: 
                    201: ubconstat(dev)
                    202: 
                    203: int dev;
                    204: 
                    205: {
                    206: 
1.1.1.2 ! root      207:        if (dev < MAX_BHANDLE) {
        !           208: 
        !           209:                FILEPTR *f = curproc->handle[binput[dev]];
1.1       root      210: 
1.1.1.2 ! root      211:                return file_instat(f) ? -1 : 0;
        !           212: 
        !           213:        }
1.1       root      214: 
                    215:        else
                    216: 
                    217:                return bconstat(dev);
                    218: 
                    219: }
                    220: 
                    221: 
                    222: 
                    223: long
                    224: 
                    225: bconstat(dev)
                    226: 
                    227: int dev;
                    228: 
                    229: {
                    230: 
                    231:        if (dev == CONSDEV) {
                    232: 
                    233:                if (checkkeys()) return 0;
                    234: 
                    235:                return (keyrec->head != keyrec->tail) ? -1 : 0;
                    236: 
                    237:        }
                    238: 
                    239:        if (dev == AUXDEV && has_bconmap)
                    240: 
                    241:                dev = curproc->bconmap;
                    242: 
                    243: 
                    244: 
1.1.1.2 ! root      245:        return BCONSTAT(dev);
1.1       root      246: 
                    247: }
                    248: 
                    249: 
                    250: 
                    251: /* bconin: input a character */
                    252: 
1.1.1.2 ! root      253: /*
1.1       root      254: 
1.1.1.2 ! root      255:  * WARNING: syscall.spp assumes that ubconin never
1.1       root      256: 
1.1.1.2 ! root      257:  * blocks if ubconstat returns non-zero.
        !           258: 
        !           259:  */
        !           260: 
        !           261: long ARGS_ON_STACK
1.1       root      262: 
                    263: ubconin(dev)
                    264: 
                    265: int dev;
                    266: 
                    267: {
                    268: 
1.1.1.2 ! root      269:        if (dev < MAX_BHANDLE) {
        !           270: 
        !           271:                FILEPTR *f = curproc->handle[binput[dev]];
1.1       root      272: 
1.1.1.2 ! root      273:                return file_getchar(f, RAW);
        !           274: 
        !           275:        }
1.1       root      276: 
                    277:        else
                    278: 
                    279:                return bconin(dev);
                    280: 
                    281: }
                    282: 
                    283: 
                    284: 
                    285: long
                    286: 
                    287: bconin(dev)
                    288: 
                    289: int dev;
                    290: 
                    291: {
                    292: 
                    293:        IOREC_T *k;
                    294: 
                    295:        long r;
                    296: 
                    297:        short h;
                    298: 
                    299: 
                    300: 
                    301:        if (dev == CONSDEV) {
                    302: 
                    303:                k = keyrec;
                    304: 
                    305: again:
                    306: 
                    307:                while (k->tail == k->head) {
                    308: 
                    309:                        yield();
                    310: 
                    311:                }
                    312: 
                    313: 
                    314: 
                    315:                if (checkkeys()) goto again;
                    316: 
                    317: 
                    318: 
                    319:                h = k->head + 4;
                    320: 
                    321:                if (h >= k->buflen)
                    322: 
                    323:                        h = 0;
                    324: 
                    325:                r = *((long *)(k->bufaddr + h));
                    326: 
                    327:                k->head = h;
                    328: 
                    329:                return r;
                    330: 
                    331:        }
                    332: 
                    333:        else {
                    334: 
                    335:                if (dev == AUXDEV && has_bconmap)
                    336: 
                    337:                        dev = curproc->bconmap;
                    338: 
                    339: 
                    340: 
1.1.1.2 ! root      341:                if (dev > 0) {
1.1       root      342: 
1.1.1.2 ! root      343:                        while (!BCONSTAT(dev)) {
1.1       root      344: 
                    345:                                yield();
                    346: 
                    347:                        }
                    348: 
1.1.1.2 ! root      349:                }
        !           350: 
1.1       root      351:        }
                    352: 
                    353: 
                    354: 
1.1.1.2 ! root      355:        r = BCONIN(dev);
1.1       root      356: 
                    357: 
                    358: 
                    359:        return r;
                    360: 
                    361: }
                    362: 
                    363: 
                    364: 
                    365: /* bconout: output a character.
                    366: 
                    367:  * returns 0 for failure, nonzero for success
                    368: 
                    369:  */
                    370: 
                    371: 
                    372: 
1.1.1.2 ! root      373: long ARGS_ON_STACK
1.1       root      374: 
                    375: ubconout(dev, c)
                    376: 
                    377: int dev, c;
                    378: 
                    379: {
                    380: 
                    381:        FILEPTR *f;
                    382: 
1.1.1.2 ! root      383:        char outp;
        !           384: 
1.1       root      385: 
                    386: 
                    387:        if (dev < MAX_BHANDLE) {
                    388: 
                    389:                f = curproc->handle[boutput[dev]];
                    390: 
                    391:                if (!f) return 0;
                    392: 
                    393:                if (is_terminal(f)) {
                    394: 
                    395:                        return tty_putchar(f, ((long)c)&0x00ff, RAW);
                    396: 
                    397:                }
                    398: 
1.1.1.2 ! root      399:                outp = c;
1.1       root      400: 
1.1.1.2 ! root      401:                return (*f->dev->write)(f, &outp, 1L);
1.1       root      402: 
                    403:        }
                    404: 
                    405:        else if (dev == 5) {
                    406: 
                    407:                c &= 0x00ff;
                    408: 
                    409:                f = curproc->handle[-1];
                    410: 
                    411:                if (!f) return 0;
                    412: 
                    413:                if (is_terminal(f)) {
                    414: 
                    415:                        if (c < ' ') {
                    416: 
                    417:                        /* MW hack for quoted characters */
                    418: 
                    419:                                tty_putchar(f, (long)'\033', RAW);
                    420: 
                    421:                                tty_putchar(f, (long)'Q', RAW);
                    422: 
                    423:                        }
                    424: 
                    425:                        return tty_putchar(f, ((long)c)&0x00ff, RAW);
                    426: 
                    427:                }
                    428: 
                    429:        /* note: we're assuming sizeof(int) == 2 here! */
                    430: 
1.1.1.2 ! root      431:                outp = c;
        !           432: 
        !           433:                return (*f->dev->write)(f, &outp, 1L);
1.1       root      434: 
                    435:        } else
                    436: 
                    437:                return bconout(dev, c);
                    438: 
                    439: }
                    440: 
                    441: 
                    442: 
                    443: long
                    444: 
                    445: bconout(dev, c)
                    446: 
                    447: int dev,c;
                    448: 
                    449: {
                    450: 
                    451:        int statdev;
                    452: 
                    453:        long endtime;
                    454: 
                    455:        extern long searchtime; /* in dosdir.c; updated once per second */
                    456: 
                    457: 
                    458: 
                    459:        if (dev == AUXDEV && has_bconmap) {
                    460: 
                    461:                dev = curproc->bconmap;
                    462: 
                    463:        }
                    464: 
                    465: 
                    466: 
                    467: /* compensate for a known BIOS bug; MIDI and IKBD are switched */
                    468: 
                    469:        if (dev == 3) {         /* MIDI */
                    470: 
                    471:                statdev = 4;
                    472: 
                    473:        } else if (dev == 4) {
                    474: 
                    475:                statdev = 3;
                    476: 
                    477:        } else
                    478: 
                    479:                statdev = dev;
                    480: 
                    481: 
                    482: 
                    483: /* provide a 10 second time out */
                    484: 
1.1.1.2 ! root      485:        if (!BCOSTAT(statdev)) {
1.1       root      486: 
1.1.1.2 ! root      487:                endtime = searchtime + 10;
1.1       root      488: 
1.1.1.2 ! root      489:                do {
1.1       root      490: 
1.1.1.2 ! root      491:                        yield();
        !           492: 
        !           493:                } while (!BCOSTAT(statdev) && searchtime < endtime);
1.1       root      494: 
1.1.1.2 ! root      495:                if ( searchtime >= endtime) return 0;
        !           496: 
        !           497:        }
1.1       root      498: 
                    499: 
                    500: 
                    501: /* special case: many text accelerators return a bad value from
                    502: 
                    503:  * Bconout, so we ignore the returned value for the console
                    504: 
                    505:  */
                    506: 
                    507:        if (dev != CONSDEV) {
                    508: 
                    509: /* NOTE: if your compiler complains about the next line, then Bconout is
                    510: 
                    511:  * improperly declared in your osbind.h header file. it should be returning
                    512: 
                    513:  * a long value; some libraries incorrectly have Bconout returning void
                    514: 
                    515:  * (or cast the returned value to void)
                    516: 
                    517:  */
                    518: 
1.1.1.2 ! root      519:                return BCONOUT(dev,c);
1.1       root      520: 
                    521:        } else {
                    522: 
1.1.1.2 ! root      523:                (void)BCONOUT(dev, c);
1.1       root      524: 
                    525:                return 1;
                    526: 
                    527:        }
                    528: 
                    529: }
                    530: 
                    531: 
                    532: 
                    533: /* rwabs: various disk stuff */
                    534: 
                    535: 
                    536: 
1.1.1.2 ! root      537: /* BUG: Rwabs should respect Dlock */
        !           538: 
        !           539: 
        !           540: 
        !           541: long ARGS_ON_STACK
1.1       root      542: 
                    543: rwabs(rwflag, buffer, number, recno, dev, lrecno)
                    544: 
                    545: int rwflag, number, recno, dev;
                    546: 
                    547: void *buffer;
                    548: 
                    549: long lrecno;
                    550: 
                    551: {
                    552: 
                    553:        long r;
                    554: 
1.1.1.2 ! root      555:        extern PROC *dlockproc[];       /* in dosdir.c */
        !           556: 
        !           557: 
        !           558: 
        !           559:        if (dev >= 0 && dev < NUM_DRIVES && dlockproc[dev]) {
        !           560: 
        !           561:                if (dlockproc[dev] != curproc) {
        !           562: 
        !           563:                        DEBUG(("Rwabs: device %c is locked", dev+'A'));
        !           564: 
        !           565:                        return ELOCKED;
        !           566: 
        !           567:                }
        !           568: 
        !           569:        }
        !           570: 
1.1       root      571: 
                    572: 
                    573: /* Note that some (most?) Rwabs device drivers don't bother saving
                    574: 
                    575:  * registers, whereas our compiler expects politeness. So we go
                    576: 
                    577:  * via callout(), which will save registers for us.
                    578: 
                    579:  */
                    580: 
                    581:        r = callout(RWABS, rwflag, buffer, number, recno, dev, lrecno);
                    582: 
                    583:        return r;
                    584: 
                    585: }
                    586: 
                    587: 
                    588: 
                    589: /* setexc: set exception vector */
                    590: 
                    591: 
                    592: 
1.1.1.2 ! root      593: long ARGS_ON_STACK
1.1       root      594: 
                    595: setexc(number, vector)
                    596: 
                    597: int number;
                    598: 
                    599: long vector;
                    600: 
                    601: {
                    602: 
                    603:        long *place;
                    604: 
                    605:        long old;
                    606: 
                    607:        extern long save_dos, save_bios, save_xbios;    /* in main.c */
                    608: 
                    609: 
                    610: 
1.1.1.2 ! root      611:        TRACE(("Setexc %d, %lx", number, vector));
1.1       root      612: 
                    613:        place = (long *)(((long)number) << 2);
                    614: 
                    615:        if (number == 0x21)                             /* trap_1 */
                    616: 
                    617:                old = save_dos;
                    618: 
                    619:        else if (number == 0x2d)                        /* trap_13 */
                    620: 
                    621:                old = save_bios;
                    622: 
                    623:        else if (number == 0x2e)                        /* trap_14 */
                    624: 
                    625:                old = save_xbios;
                    626: 
                    627:        else if (number == 0x101)
                    628: 
                    629:                old = (long)curproc->criticerr;         /* critical error vector */
                    630: 
                    631:        else if (number == 0x102)
                    632: 
                    633:                old = curproc->ctxt[SYSCALL].term_vec;  /* GEMDOS term vector */
                    634: 
                    635:        else
                    636: 
                    637:                old = *place;
                    638: 
                    639: 
                    640: 
                    641:        if (vector > 0) {
                    642: 
                    643:                if (number == 0x21)
                    644: 
                    645:                        save_dos = vector;
                    646: 
                    647:                else if (number == 0x2d)
                    648: 
                    649:                        save_bios = vector;
                    650: 
                    651:                else if (number == 0x2e)
                    652: 
                    653:                        save_xbios = vector;
                    654: 
                    655:                else if (number == 0x102)
                    656: 
                    657:                        curproc->ctxt[SYSCALL].term_vec = vector;
                    658: 
                    659:                else if (number == 0x101) {
                    660: 
                    661:                        long mintcerr;
                    662: 
                    663: 
                    664: 
                    665:                /*
                    666: 
                    667:                 * problem: lots of TSR's look for the Setexc(0x101,...)
                    668: 
                    669:                 * that the AES does at startup time; so we have
                    670: 
                    671:                 * to pass it along.
                    672: 
                    673:                 */
                    674: 
                    675:                        mintcerr = (long) Setexc(0x101, (void *)vector);
                    676: 
1.1.1.2 ! root      677:                        curproc->criticerr = (long ARGS_ON_STACK (*) P_((long))) *place;
1.1       root      678: 
                    679:                        *place = mintcerr;
                    680: 
                    681:                }
                    682: 
                    683:                else {
                    684: 
                    685:                /* We would do just *place = vector except that
                    686: 
                    687:                 * someone else might be intercepting Setexc looking
                    688: 
                    689:                 * for something in particular...
                    690: 
                    691:                 */
                    692: 
                    693:                        old = (long) Setexc(number, (void *)vector);
                    694: 
                    695:                }
                    696: 
                    697:        }
                    698: 
                    699:        return old;
                    700: 
                    701: }
                    702: 
                    703: 
                    704: 
                    705: /* tickcal: return milliseconds per system clock tick */
                    706: 
                    707: 
                    708: 
1.1.1.2 ! root      709: long ARGS_ON_STACK
1.1       root      710: 
                    711: tickcal()
                    712: 
                    713: {
                    714: 
                    715:        return (long) (*( (unsigned *) 0x0442L ));
                    716: 
                    717: }
                    718: 
                    719: 
                    720: 
                    721: /* getbpb: get BIOS parameter block */
                    722: 
                    723: 
                    724: 
1.1.1.2 ! root      725: long ARGS_ON_STACK
1.1       root      726: 
                    727: getbpb(dev)
                    728: 
                    729: int dev;
                    730: 
                    731: {
                    732: 
                    733:        long r;
                    734: 
                    735: 
                    736: 
                    737: /* we can't trust the Getbpb routine to accurately save all registers,
                    738: 
                    739:  * so we do it ourselves
                    740: 
                    741:  */
                    742: 
                    743:        r = callout(GETBPB, dev);
                    744: 
                    745: /* 
                    746: 
                    747:  * There is a bug in the  TOS  disk handling routines (well several actually).
                    748: 
                    749:  * If the directory size of Getbpb() is returned as zero then the drive 'dies'
                    750: 
                    751:  * and wont read any new disks even with the 'ESC' enforced disk change . This
                    752: 
                    753:  * is present even in TOS 1.6 (not sure about 1.62 though). This small routine
                    754: 
                    755:  * changes the dir size to '1' if it is zero . It may make some non-TOS disks
                    756: 
                    757:  * look a bit weird but that's better than killing the drive .
                    758: 
                    759:  */
                    760: 
                    761:        if (r) {
                    762: 
                    763:                if ( ((short *)r)[3] == 0)      /* 0 directory size? */
                    764: 
                    765:                        ((short *)r)[3] = 1;
                    766: 
                    767:        }
                    768: 
                    769:        return r;
                    770: 
                    771: }
                    772: 
                    773: 
                    774: 
                    775: /* bcostat: return output device status */
                    776: 
                    777: 
                    778: 
1.1.1.2 ! root      779: /* WARNING: syscall.spp assumes that ubcostat never
        !           780: 
        !           781:  * blocks
        !           782: 
        !           783:  */
        !           784: 
        !           785: long ARGS_ON_STACK
1.1       root      786: 
                    787: ubcostat(dev)
                    788: 
                    789: int dev;
                    790: 
                    791: {
                    792: 
1.1.1.2 ! root      793:        FILEPTR *f;
        !           794: 
        !           795: 
        !           796: 
1.1       root      797: /* the BIOS switches MIDI (3) and IKBD (4) (a bug, but it can't be corrected) */
                    798: 
                    799:        if (dev == 4) {         /* really the MIDI port */
                    800: 
1.1.1.2 ! root      801:                f = curproc->handle[boutput[3]];
        !           802: 
        !           803:                return file_outstat(f) ? -1 : 0;
1.1       root      804: 
                    805:        }
                    806: 
                    807:        if (dev == 3)
                    808: 
1.1.1.2 ! root      809:                return BCOSTAT(dev);
1.1       root      810: 
                    811: 
                    812: 
1.1.1.2 ! root      813:        if (dev < MAX_BHANDLE) {
1.1       root      814: 
1.1.1.2 ! root      815:                f = curproc->handle[boutput[dev]];
1.1       root      816: 
1.1.1.2 ! root      817:                return file_outstat(f) ? -1 : 0;
        !           818: 
        !           819:        } else
1.1       root      820: 
                    821:                return bcostat(dev);
                    822: 
                    823: }
                    824: 
                    825: 
                    826: 
                    827: long
                    828: 
                    829: bcostat(dev)
                    830: 
                    831: int dev;
                    832: 
                    833: {
                    834: 
                    835: 
                    836: 
                    837:        if (dev == CONSDEV) {
                    838: 
                    839:                return -1;
                    840: 
                    841:        }
                    842: 
                    843:        else if (dev == AUXDEV && has_bconmap) {
                    844: 
                    845:                dev = curproc->bconmap;
                    846: 
                    847:        }
                    848: 
                    849: /* compensate here for the BIOS bug, so that the MIDI and IKBD files work
                    850: 
                    851:  * correctly
                    852: 
                    853:  */
                    854: 
                    855:        else if (dev == 3) dev = 4;
                    856: 
                    857:        else if (dev == 4) dev = 3;
                    858: 
                    859: 
                    860: 
1.1.1.2 ! root      861:        return BCOSTAT(dev);
1.1       root      862: 
                    863: }
                    864: 
                    865: 
                    866: 
                    867: /* mediach: check for media change */
                    868: 
                    869: 
                    870: 
1.1.1.2 ! root      871: long ARGS_ON_STACK
1.1       root      872: 
                    873: mediach(dev)
                    874: 
                    875: int dev;
                    876: 
                    877: {
                    878: 
                    879:        long r;
                    880: 
                    881: 
                    882: 
                    883:        r = callout(MEDIACH, dev);
                    884: 
                    885:        return r;
                    886: 
                    887: }
                    888: 
                    889: 
                    890: 
                    891: /* drvmap: return drives connected to system */
                    892: 
                    893: 
                    894: 
1.1.1.2 ! root      895: long ARGS_ON_STACK
1.1       root      896: 
                    897: drvmap()
                    898: 
                    899: {
                    900: 
                    901:        return *( (long *)0x4c2L );
                    902: 
                    903: }
                    904: 
                    905: 
                    906: 
                    907: /* kbshift: return (and possibly change) keyboard shift key status */
                    908: 
1.1.1.2 ! root      909: /* WARNING: syscall.spp assumes that kbshift never blocks, and never
1.1       root      910: 
1.1.1.2 ! root      911:  * calls any underlying TOS functions
1.1       root      912: 
1.1.1.2 ! root      913:  */
        !           914: 
        !           915: long ARGS_ON_STACK
1.1       root      916: 
                    917: kbshift(mode)
                    918: 
                    919: int mode;
                    920: 
                    921: {
                    922: 
                    923:        int oldshft;
                    924: 
                    925: 
                    926: 
                    927:        oldshft = *((unsigned char *)kbshft);
                    928: 
                    929:        if (mode >= 0)
                    930: 
                    931:                *kbshft = mode;
                    932: 
                    933:        return oldshft;
                    934: 
                    935: }
                    936: 
                    937: 
                    938: 
                    939: 
                    940: 
                    941: /* special Bconout buffering code:
                    942: 
                    943:  * Because system call overhead is so high, programs that do output
                    944: 
                    945:  * with Bconout suffer in performance. To compensate for this,
                    946: 
                    947:  * Bconout is special-cased in syscall.s, and if possible characters
                    948: 
                    949:  * are placed in the 256 byte bconbuf buffer. This buffer is flushed
                    950: 
                    951:  * when any system call other than Bconout happens, or when a context
                    952: 
                    953:  * switch occurs.
                    954: 
                    955:  */
                    956: 
                    957: 
                    958: 
                    959: short bconbsiz;                        /* number of characters in buffer */
                    960: 
                    961: unsigned char bconbuf[256];    /* buffer contents */
                    962: 
                    963: short bconbdev;                        /* BIOS device for which the buffer is valid */
                    964: 
                    965:                                /* (-1 means no buffering is active) */
                    966: 
                    967: 
                    968: 
                    969: /*
                    970: 
                    971:  * flush pending BIOS output. Return 0 if some bytes were not successfully
                    972: 
                    973:  * written, non-zero otherwise (just like bconout)
                    974: 
                    975:  */
                    976: 
                    977: 
                    978: 
1.1.1.2 ! root      979: long ARGS_ON_STACK
1.1       root      980: 
                    981: bflush()               /* flush bios output */
                    982: 
                    983: {
                    984: 
                    985:        long ret, bsiz;
                    986: 
                    987:        unsigned char *s;
                    988: 
                    989:        FILEPTR *f;
                    990: 
                    991:        short dev;
                    992: 
                    993:        short statdev;
                    994: 
1.1.1.2 ! root      995:        long lbconbuf[256];
        !           996: 
1.1       root      997: 
                    998: 
                    999:        if ((dev = bconbdev) < 0) return 0;
                   1000: 
                   1001: 
                   1002: 
                   1003: /*
                   1004: 
                   1005:  * Here we lock the BIOS buffering mechanism by setting bconbdev to -1
                   1006: 
                   1007:  * This is necessary because if two or more programs try to do
                   1008: 
                   1009:  * buffered BIOS output at the same time, they can get seriously
                   1010: 
                   1011:  * mixed up. We unlock by setting bconbdev to 0.
                   1012: 
                   1013:  *
                   1014: 
                   1015:  * NOTE: some code (e.g. in sleep()) checks for bconbsiz != 0 in
                   1016: 
                   1017:  * order to see if we need to do a bflush; if one is already in
                   1018: 
                   1019:  * progress, it's pointless to do this, so we save a bit of
                   1020: 
                   1021:  * time by setting bconbsiz to 0 here.
                   1022: 
                   1023:  */
                   1024: 
                   1025:        bconbdev = -1;
                   1026: 
                   1027:        bsiz = bconbsiz;
                   1028: 
1.1.1.2 ! root     1029:        if (bsiz == 0) return 0;
        !          1030: 
1.1       root     1031:        bconbsiz = 0;
                   1032: 
                   1033: 
                   1034: 
                   1035: /* BIOS handles 0..MAX_BHANDLE-1 are aliases for special GEMDOS files */
                   1036: 
                   1037:        if (dev < MAX_BHANDLE || dev == 5) {
                   1038: 
                   1039:                if (dev == 5)
                   1040: 
                   1041:                        f = curproc->handle[-1];
                   1042: 
                   1043:                else
                   1044: 
                   1045:                        f = curproc->handle[boutput[dev]];
                   1046: 
                   1047: 
                   1048: 
                   1049:                if (!f) {
                   1050: 
                   1051:                        bconbdev = 0;
                   1052: 
                   1053:                        return 0;
                   1054: 
                   1055:                }
                   1056: 
                   1057:                if (is_terminal(f)) {
                   1058: 
                   1059:                        s = bconbuf;
                   1060: 
                   1061:                        if (dev == 5) {
                   1062: 
                   1063:                            while (bsiz-- > 0) {
                   1064: 
                   1065:                                if (*s < ' ') {
                   1066: 
                   1067:                        /* use ESC-Q to quote control character */
                   1068: 
                   1069:                                        (void)tty_putchar(f, (long)'\033',
                   1070: 
                   1071:                                                                RAW);
                   1072: 
                   1073:                                        (void)tty_putchar(f, (long)'Q',
                   1074: 
                   1075:                                                                RAW);
                   1076: 
                   1077:                                }
                   1078: 
                   1079:                                (void) tty_putchar(f, (long)*s++, RAW);
                   1080: 
                   1081:                            }
                   1082: 
                   1083:                        } else {
                   1084: 
1.1.1.2 ! root     1085: #if 1
        !          1086: 
        !          1087:                            long *where, nbytes;
        !          1088: 
        !          1089: 
        !          1090: 
        !          1091: /* the tty_putchar should set up terminal modes correctly */
        !          1092: 
        !          1093:                            (void) tty_putchar(f, (long)*s++, RAW);
        !          1094: 
        !          1095:                            where = lbconbuf;
        !          1096: 
        !          1097:                            nbytes = 0;
        !          1098: 
        !          1099:                            while (--bsiz > 0) {
        !          1100: 
        !          1101:                                *where++ = *s++; nbytes+=4;
        !          1102: 
        !          1103:                            }
        !          1104: 
        !          1105:                            if (nbytes)
        !          1106: 
        !          1107:                                (*f->dev->write)(f, (char *)lbconbuf, nbytes);
        !          1108: 
        !          1109: #else
        !          1110: 
1.1       root     1111:                            while (bsiz-- > 0) {
                   1112: 
                   1113:                                (void) tty_putchar(f, (long)*s++, RAW);
                   1114: 
                   1115:                            }
                   1116: 
1.1.1.2 ! root     1117: #endif
        !          1118: 
1.1       root     1119:                        }
                   1120: 
                   1121:                        ret = -1;
                   1122: 
                   1123:                } else {
                   1124: 
                   1125:                        ret = (*f->dev->write)(f, (char *)bconbuf, bsiz);
                   1126: 
                   1127:                }
                   1128: 
                   1129:                bconbdev = 0;
                   1130: 
                   1131:                return ret;
                   1132: 
                   1133:        }
                   1134: 
                   1135: 
                   1136: 
                   1137: /* Otherwise, we have a real BIOS device */
                   1138: 
                   1139: 
                   1140: 
                   1141:        if (dev == AUXDEV && has_bconmap) {
                   1142: 
                   1143:                dev = curproc->bconmap;
                   1144: 
                   1145:                statdev = dev;
                   1146: 
                   1147:        }
                   1148: 
                   1149: /* compensate for a known BIOS bug; MIDI and IKBD are switched */
                   1150: 
                   1151:        else if (dev == 3) {            /* MIDI */
                   1152: 
                   1153:                statdev = 4;
                   1154: 
                   1155:        } else if (dev == 4) {
                   1156: 
                   1157:                statdev = 3;
                   1158: 
                   1159:        } else
                   1160: 
                   1161:                statdev = dev;
                   1162: 
                   1163:                
                   1164: 
                   1165:        s = bconbuf;
                   1166: 
                   1167:        while (bsiz-- > 0) {
                   1168: 
1.1.1.2 ! root     1169:                while (!BCOSTAT(statdev)) yield();
1.1       root     1170: 
1.1.1.2 ! root     1171:                (void)BCONOUT(dev,*s);
1.1       root     1172: 
                   1173:                s++;
                   1174: 
                   1175:        }
                   1176: 
                   1177:        bconbdev = 0;
                   1178: 
                   1179:        return 1L;
                   1180: 
                   1181: }
                   1182: 
                   1183: 
                   1184: 
                   1185: /* initialize bios table */
                   1186: 
                   1187: 
                   1188: 
                   1189: #define BIOS_MAX 0x20
                   1190: 
                   1191: 
                   1192: 
                   1193: Func bios_tab[BIOS_MAX] = {
                   1194: 
                   1195:        getmpb,
                   1196: 
                   1197:        ubconstat,
                   1198: 
                   1199:        ubconin,
                   1200: 
                   1201:        ubconout,
                   1202: 
1.1.1.2 ! root     1203: 
        !          1204: 
1.1       root     1205:        rwabs,
                   1206: 
                   1207:        setexc,
                   1208: 
                   1209:        tickcal,
                   1210: 
                   1211:        getbpb,
                   1212: 
1.1.1.2 ! root     1213: 
        !          1214: 
1.1       root     1215:        ubcostat,
                   1216: 
                   1217:        mediach,
                   1218: 
                   1219:        drvmap,
                   1220: 
                   1221:        kbshift,
                   1222: 
1.1.1.2 ! root     1223: 
        !          1224: 
1.1       root     1225:        0, 0, 0, 0,
                   1226: 
                   1227:        0, 0, 0, 0, 0, 0, 0, 0,
                   1228: 
                   1229:        0, 0, 0, 0, 0, 0, 0, 0
                   1230: 
                   1231: };
                   1232: 
                   1233: 
                   1234: 
                   1235: short bios_max = BIOS_MAX;
                   1236: 
                   1237: 
                   1238: 
                   1239: /*
                   1240: 
                   1241:  * BIOS initialization routine: gets keyboard buffer pointers, for the
                   1242: 
                   1243:  * interrupt routine below
                   1244: 
                   1245:  */
                   1246: 
                   1247: 
                   1248: 
                   1249: void
                   1250: 
                   1251: init_bios()
                   1252: 
                   1253: {
                   1254: 
                   1255:        keyrec = (IOREC_T *)Iorec(1);
                   1256: 
                   1257: }
                   1258: 
                   1259: 
                   1260: 
                   1261: /*
                   1262: 
1.1.1.2 ! root     1263:  * do_bconin: try to do a bconin function quickly, without
        !          1264: 
        !          1265:  * blocking. If we can't do it without blocking, we return
        !          1266: 
        !          1267:  * 0x0123dead and the calling trap #13 code falls through
        !          1268: 
        !          1269:  * to the normal bconin stuff. We can't block here because
        !          1270: 
        !          1271:  * the trap #13 code hasn't yet saved registers or other
        !          1272: 
        !          1273:  * context bits, so sleep() wouldn't work properly.
        !          1274: 
        !          1275:  */
        !          1276: 
        !          1277: 
        !          1278: 
        !          1279: #define WOULDBLOCK 0x0123deadL
        !          1280: 
        !          1281: 
        !          1282: 
        !          1283: /* WARNING: syscall.spp assumes that do_bconin never blocks */
        !          1284: 
        !          1285: 
        !          1286: 
        !          1287: long ARGS_ON_STACK
        !          1288: 
        !          1289: do_bconin(dev)
        !          1290: 
        !          1291:        int dev;
        !          1292: 
        !          1293: {
        !          1294: 
        !          1295:        FILEPTR *f;
        !          1296: 
        !          1297:        long r;
        !          1298: 
        !          1299:        unsigned char c;
        !          1300: 
        !          1301: 
        !          1302: 
        !          1303:        if (dev < MAX_BHANDLE) {
        !          1304: 
        !          1305:                f = curproc->handle[binput[dev]];
        !          1306: 
        !          1307:                if (!f) return 0;
        !          1308: 
        !          1309:                r = 0;
        !          1310: 
        !          1311:                (void)(*f->dev->ioctl)(f, FIONREAD, &r);
        !          1312: 
        !          1313:                if (!r) return WOULDBLOCK;      /* data not ready */
        !          1314: 
        !          1315:                if (is_terminal(f))
        !          1316: 
        !          1317:                        r = tty_getchar(f, RAW);
        !          1318: 
        !          1319:                else {
        !          1320: 
        !          1321:                        r = (*f->dev->read)(f, (char *)&c, 1L);
        !          1322: 
        !          1323:                        r = (r == 1) ? c : MiNTEOF;
        !          1324: 
        !          1325:                }
        !          1326: 
        !          1327:        } else {
        !          1328: 
        !          1329:                if (!bconstat(dev))
        !          1330: 
        !          1331:                        r = WOULDBLOCK;
        !          1332: 
        !          1333:                else
        !          1334: 
        !          1335:                        r = bconin(dev);
        !          1336: 
        !          1337:        }
        !          1338: 
        !          1339:        return r;
        !          1340: 
        !          1341: }
        !          1342: 
        !          1343: 
        !          1344: 
        !          1345: /*
        !          1346: 
1.1       root     1347:  * routine for checking keyboard (called by sleep() on any context
                   1348: 
                   1349:  * switch where a keyboard event occured). returns 1 if a special
                   1350: 
                   1351:  * control character was eaten, 0 if not
                   1352: 
                   1353:  */
                   1354: 
                   1355: 
                   1356: 
                   1357: int
                   1358: 
                   1359: checkkeys()
                   1360: 
                   1361: {
                   1362: 
                   1363:        char scan, ch;
                   1364: 
                   1365:        short shift;
                   1366: 
                   1367:        int sig, ret;
                   1368: 
                   1369:        struct tty *tty = &con_tty;
                   1370: 
                   1371:        extern char mshift;             /* for mouse -- see biosfs.c */
                   1372: 
                   1373:        static short oldktail = 0;
                   1374: 
                   1375: 
                   1376: 
                   1377:        ret = 0;
                   1378: 
                   1379:        mshift = kbshift(-1);
                   1380: 
                   1381:        while (oldktail != keyrec->tail) {
                   1382: 
                   1383: 
                   1384: 
                   1385: /* BUG: we really should check the shift status _at the time the key was
                   1386: 
                   1387:  * pressed_, not now!
                   1388: 
                   1389:  */
                   1390: 
                   1391:                sig = 0;
                   1392: 
                   1393:                shift = mshift;
                   1394: 
                   1395:                oldktail += 4;
                   1396: 
                   1397:                if (oldktail >= keyrec->buflen)
                   1398: 
                   1399:                        oldktail = 0;
                   1400: 
                   1401: 
                   1402: 
                   1403:                scan = (keyrec->bufaddr + oldktail)[1];
                   1404: 
                   1405: /* function key?? */
                   1406: 
                   1407:                if ( (scan >= 0x3b && scan <= 0x44) ||
                   1408: 
                   1409:                     (scan >= 0x54 && scan <= 0x5d) ||
                   1410: 
                   1411:                     scan == DEL || scan == UNDO) {
                   1412: 
                   1413:                        if ( (shift & CTRLALT) == CTRLALT ) {
                   1414: 
                   1415:                                oldktail = keyrec->head = keyrec->tail;
                   1416: 
                   1417:                                do_func_key(scan);
                   1418: 
1.1.1.2 ! root     1419:                                /* do_func_key may have read some keys */
        !          1420: 
        !          1421:                                oldktail = keyrec->head;
        !          1422: 
        !          1423:                                mshift = kbshift (-1);
        !          1424: 
1.1       root     1425:                                ret = 1;
                   1426: 
                   1427:                                continue;
                   1428: 
                   1429:                        }
                   1430: 
                   1431:                }
                   1432: 
                   1433: 
                   1434: 
                   1435: /* check for special control keys, etc. */
                   1436: 
                   1437: /* BUG: this doesn't exactly match TOS' behavior, particularly for
                   1438: 
                   1439:  * ^S/^Q
                   1440: 
                   1441:  */
                   1442: 
                   1443:                if ((tty->state & TS_COOKED) || (shift & CTRLALT) == CTRLALT) {
                   1444: 
                   1445:                        ch = (keyrec->bufaddr + keyrec->tail)[3];
                   1446: 
                   1447:                        if (ch == UNDEF)
                   1448: 
                   1449:                                ;       /* do nothing */
                   1450: 
                   1451:                        else if (ch == tty->tc.t_intrc)
                   1452: 
                   1453:                                sig = SIGINT;
                   1454: 
                   1455:                        else if (ch == tty->tc.t_quitc)
                   1456: 
                   1457:                                sig = SIGQUIT;
                   1458: 
                   1459:                        else if (ch == tty->ltc.t_suspc)
                   1460: 
                   1461:                                sig = SIGTSTP;
                   1462: 
                   1463:                        else if (ch == tty->tc.t_stopc) {
                   1464: 
                   1465:                                tty->state |= TS_HOLD;
                   1466: 
                   1467:                                ret = 1;
                   1468: 
                   1469:                                keyrec->head = oldktail;
                   1470: 
                   1471:                                continue;
                   1472: 
                   1473:                        }
                   1474: 
                   1475:                        else if (ch == tty->tc.t_startc) {
                   1476: 
                   1477:                                tty->state &= ~TS_HOLD;
                   1478: 
                   1479:                                ret = 1;
                   1480: 
                   1481:                                keyrec->head = oldktail;
                   1482: 
                   1483:                                continue;
                   1484: 
                   1485:                        }
                   1486: 
                   1487:                        if (sig) {
                   1488: 
                   1489:                                tty->state &= ~TS_HOLD;
                   1490: 
                   1491:                                if (!(tty->sg.sg_flags & T_NOFLSH))
                   1492: 
                   1493:                                    oldktail = keyrec->head = keyrec->tail;
                   1494: 
                   1495:                                killgroup(tty->pgrp, sig);
                   1496: 
                   1497:                                ret = 1;
                   1498: 
                   1499:                        }
                   1500: 
                   1501:                        else if (tty->state & TS_HOLD) {
                   1502: 
                   1503:                                keyrec->head = oldktail;
                   1504: 
                   1505:                                ret = 1;
                   1506: 
                   1507:                        }
                   1508: 
                   1509:                }
                   1510: 
                   1511: 
                   1512: 
                   1513:        }
                   1514: 
                   1515: 
                   1516: 
                   1517: /* has someone done select() on the keyboard?? */
                   1518: 
                   1519:        if (tty->rsel && keyrec->head != keyrec->tail)
                   1520: 
                   1521:                wakeselect(tty->rsel);
                   1522: 
                   1523: 
                   1524: 
                   1525:        return ret;
                   1526: 
                   1527: }
                   1528: 
                   1529: 
                   1530: 
                   1531: /* do_func_key moved to debug.c */
                   1532: 

unix.superglobalmegacorp.com

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