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

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

unix.superglobalmegacorp.com

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