|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.