|
|
1.1 root 1: /*
2:
1.1.1.3 root 3: Copyright 1990,1991,1992 Eric R. Smith.
4:
1.1.1.6 ! root 5: Copyright 1992,1993,1994 Atari Corporation.
1.1.1.3 root 6:
7: All rights reserved.
1.1 root 8:
9: */
10:
11:
12:
13: /*
14:
15: * XBIOS replacement routines
16:
17: */
18:
19:
20:
21: #include "mint.h"
22:
23:
24:
1.1.1.6 ! root 25: /* tty structures for the BIOS devices -- see biosfs.c */
! 26:
! 27: extern struct tty sccb_tty, scca_tty, ttmfp_tty;
! 28:
! 29: extern struct bios_tty bttys[];
! 30:
! 31: extern short btty_max;
! 32:
! 33:
! 34:
1.1 root 35: extern int tosvers; /* from main.c */
36:
37:
38:
39: #define XBIOS_MAX 0x80
40:
41:
42:
43: Func xbios_tab[XBIOS_MAX]; /* initially all zeros */
44:
45: short xbios_max = XBIOS_MAX;
46:
47:
48:
49: /* NOTE: has_bconmap is initialized in main.c */
50:
51:
52:
53: int has_bconmap; /* flag: set if running under a version
54:
55: * of TOS which supports Bconmap
56:
57: */
58:
1.1.1.6 ! root 59: extern BCONMAP2_T *bconmap2; /* bconmap struct */
! 60:
! 61: #define MAPTAB (bconmap2->maptab)
! 62:
1.1 root 63:
64:
65: /*
66:
67: * Supexec() presents a lot of problems for us: for example, the user
68:
69: * may be calling the kernel, or may be changing interrupt vectors
70:
71: * unexpectedly. So we play some dirty tricks here: the function
72:
73: * call is treated like a signal handler, and we take advantage
74:
75: * of the fact that no context switches will take place while
76:
77: * in supervisor mode. ASSUMPTION: the user will not choose to
78:
79: * switch back to user mode, or if s/he does it will be as part
80:
81: * of a longjmp().
82:
83: *
84:
85: * BUG: if the user function switches to user mode, then back to
86:
87: * supervisor mode and returns, then the returned value may be
88:
89: * inaccurate (this happens if two programs make Supexec calls
90:
91: * at the same time).
92:
93: */
94:
95:
96:
1.1.1.3 root 97: long ARGS_ON_STACK (*usrcall) P_((long, long,long,long,long,long));
98:
99: long usrret;
1.1 root 100:
1.1.1.3 root 101: long usrarg1, usrarg2, usrarg3, usrarg4, usrarg5;
1.1 root 102:
103:
104:
1.1.1.3 root 105: #if 0
106:
107: /* moved to syscall.spp */
1.1 root 108:
1.1.1.2 root 109: static void ARGS_ON_STACK do_usrcall P_((void));
1.1 root 110:
111:
112:
1.1.1.2 root 113: static void ARGS_ON_STACK
1.1 root 114:
115: do_usrcall()
116:
117: {
118:
1.1.1.3 root 119: usrret = (*usrcall)((long)usrcall, usrarg1, usrarg2, usrarg3, usrarg4,
120:
121: usrarg5);
1.1 root 122:
123: }
124:
1.1.1.3 root 125: #endif
126:
1.1 root 127:
128:
1.1.1.2 root 129: long ARGS_ON_STACK
1.1 root 130:
131: supexec(funcptr, arg1, arg2, arg3, arg4, arg5)
132:
133: Func funcptr;
134:
135: long arg1, arg2, arg3, arg4, arg5;
136:
137: {
138:
139: short savesr;
140:
141: CONTEXT *syscall = &curproc->ctxt[SYSCALL];
142:
143:
144:
145: /* set things up so that "signal 0" will be handled by calling the user's
146:
147: * function.
148:
149: */
150:
151:
152:
153: usrcall = funcptr;
154:
155: usrarg1 = arg1;
156:
157: usrarg2 = arg2;
158:
159: usrarg3 = arg3;
160:
161: usrarg4 = arg4;
162:
163: usrarg5 = arg5;
164:
165: curproc->sighandle[0] = (long)do_usrcall;
166:
167: savesr = syscall->sr; /* save old super/user mode flag */
168:
169: syscall->sr |= 0x2000; /* set supervisor mode */
170:
171: handle_sig(0); /* actually call out to the user function */
172:
173: syscall->sr = savesr;
174:
175:
176:
177: /* do_usrcall saves the user's return value in usrret */
178:
179: return usrret;
180:
181: }
182:
183:
184:
185:
186:
187: /*
188:
189: * midiws: we have to replace this, because it's possible that the process'
190:
191: * view of what the MIDI port is has been changed by Fforce or Fmidipipe
192:
193: */
194:
195:
196:
1.1.1.2 root 197: long ARGS_ON_STACK
1.1 root 198:
199: midiws(cnt, buf)
200:
201: int cnt;
202:
203: const char *buf;
204:
205: {
206:
207: FILEPTR *f;
208:
209: long towrite = cnt+1;
210:
211:
212:
213: f = curproc->handle[-5]; /* MIDI output handle */
214:
215: if (!f) return EIHNDL;
216:
217:
218:
219: if (is_terminal(f)) {
220:
1.1.1.6 ! root 221: extern FILESYS bios_filesys;
! 222:
! 223:
! 224:
! 225: /* see if we can do fast RAW byte IO thru the device driver... */
! 226:
! 227: if ((f->fc.fs != &bios_filesys ||
! 228:
! 229: (towrite > 1 &&
! 230:
! 231: ((struct bios_file *)f->fc.index)->drvsize >
! 232:
! 233: offsetof (DEVDRV, writeb))) && f->dev->writeb) {
! 234:
! 235: struct tty *tty = (struct tty *)f->devinfo;
! 236:
! 237:
! 238:
! 239: tty_checkttou (f, tty);
! 240:
! 241: tty->state &= ~TS_COOKED;
! 242:
! 243: if ((towrite = (*f->dev->writeb)(f, buf, towrite)) != EUNDEV)
! 244:
! 245: return towrite;
! 246:
! 247: }
! 248:
1.1 root 249: while (cnt >= 0) {
250:
251: tty_putchar(f, (long)*buf, RAW);
252:
253: buf++; cnt--;
254:
255: }
256:
257: return towrite;
258:
259: }
260:
261: return (*f->dev->write)(f, buf, towrite);
262:
263: }
264:
265:
266:
267: /*
268:
269: * Modem control things: these are replaced because we handle
270:
271: * Bconmap ourselves
272:
273: */
274:
275:
276:
277: /* mapin: utility routine, does a Bconmap and keeps track
278:
279: * so we call the kernel only when necessary; call this
280:
281: * only if has_bconmap is "true".
282:
283: * Returns: 0 on failure, 1 on success.
284:
285: */
286:
287: int curbconmap;
288:
289:
290:
291: int
292:
293: mapin(dev)
294:
295: int dev;
296:
297: {
298:
1.1.1.2 root 299: long r;
1.1 root 300:
301:
302:
303: if (dev == curbconmap)
304:
305: return 1;
306:
307: r = Bconmap(dev);
308:
309: if (r) {
310:
311: curbconmap = dev;
312:
313: return 1;
314:
315: }
316:
317: return 0;
318:
319: }
320:
321:
322:
1.1.1.2 root 323: long ARGS_ON_STACK
1.1 root 324:
325: uiorec(dev)
326:
327: int dev;
328:
329: {
330:
1.1.1.2 root 331: TRACE(("Iorec(%d)", dev));
1.1 root 332:
1.1.1.6 ! root 333: if (dev == 0 && has_bconmap) {
! 334:
! 335: /* get around another BIOS Bug: in (at least) TOS 2.05 Iorec(0) is broken */
! 336:
! 337: if ((unsigned)curproc->bconmap-6 < btty_max)
! 338:
! 339: return (long)MAPTAB[curproc->bconmap-6].iorec;
1.1 root 340:
341: mapin(curproc->bconmap);
342:
1.1.1.6 ! root 343: }
! 344:
1.1 root 345: return (long)Iorec(dev);
346:
347: }
348:
349:
350:
1.1.1.2 root 351: long ARGS_ON_STACK
1.1 root 352:
353: rsconf(baud, flow, uc, rs, ts, sc)
354:
355: int baud, flow, uc, rs, ts, sc;
356:
357: {
358:
1.1.1.3 root 359: long rsval;
360:
1.1.1.2 root 361: static int oldbaud = -1;
1.1 root 362:
1.1.1.6 ! root 363: unsigned b = 0;
1.1.1.2 root 364:
1.1.1.6 ! root 365: struct bios_tty *t = bttys;
1.1.1.2 root 366:
367:
368:
369: TRACE(("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
370:
371: uc, rs, ts, sc));
1.1 root 372:
373:
374:
1.1.1.6 ! root 375: if (has_bconmap) {
1.1 root 376:
1.1.1.6 ! root 377: b = curproc->bconmap-6;
! 378:
! 379: if (b < btty_max)
! 380:
! 381: t += b;
! 382:
! 383: else
! 384:
! 385: t = 0;
! 386:
! 387: /* more bugs... serial1 is three-wire, requesting hardware flowcontrol
! 388:
! 389: * on it can confuse BIOS
! 390:
! 391: */
! 392:
! 393: if ((flow & 0x8002) == 2 && t && t->tty == &ttmfp_tty)
! 394:
! 395: flow &= ~2;
1.1 root 396:
1.1.1.3 root 397:
398:
399: #ifndef DONT_ONLY030_THIS
400:
1.1.1.4 root 401: /* Note: the code below must be included, even on a 68030, thanks to a bug
1.1.1.3 root 402:
1.1.1.4 root 403: * in the gcc and mntlib osbind.h file.
1.1.1.3 root 404:
1.1.1.4 root 405: */
1.1.1.3 root 406:
407:
1.1.1.2 root 408:
409: /*
410:
411: If this is an old TOS, try to rearrange things to support
412:
413: the following Rsconf() features:
414:
415: 1. Rsconf(-2, ...) does not return current baud (it crashes)
416:
417: -> keep track of old speed in static variable
418:
419: 2. Rsconf(b, ...) sends ASCII DEL to the modem unless b == -1
420:
421: -> make speed parameter -1 if new speed matches old speed
422:
423: 3. Rsconf() discards any buffered output
424:
425: -> use Iorec() to ensure all buffered data was sent before call
426:
427: */
428:
1.1.1.6 ! root 429: } else if (tosvers < 0x0104) {
1.1.1.3 root 430:
1.1.1.2 root 431: if (baud == -2) {
432:
1.1.1.6 ! root 433: /* 1.(0)4 Rsconf ignores its other args when asked for old speed, so can we */
1.1.1.2 root 434:
1.1.1.6 ! root 435: return oldbaud;
1.1.1.2 root 436:
437: } else if (baud == oldbaud)
438:
439: baud = -1;
440:
441: else if (baud > -1)
442:
443: oldbaud = baud;
444:
1.1.1.3 root 445: }
446:
1.1.1.6 ! root 447: if (t && baud != -2) {
! 448:
! 449: while (t->tty->hup_ospeed) {
! 450:
! 451: sleep (IO_Q, (long)&t->tty->state);
! 452:
! 453: }
! 454:
! 455: }
! 456:
! 457: #if 0 /* now handled in tty.c (real TIOCSETP) */
! 458:
1.1.1.3 root 459: /* This part _is_ necessary on TOS 1.04 */
460:
461: if (tosvers <= 0x0104) {
462:
463: int attempts = 0;
464:
465: short old_head;
466:
1.1.1.6 ! root 467: IOREC_T *ior= ((IOREC_T *) uiorec(0)) + 1; /* output record */
1.1.1.2 root 468:
1.1.1.3 root 469: old_head = ior->head;
470:
1.1.1.2 root 471: while (ior->head != ior->tail) {
472:
1.1.1.3 root 473: if (++attempts >= 50) { /* prevent getting stuck by flow control */
474:
475: if (old_head == ior->head)
476:
477: break;
478:
479: else {
480:
481: old_head = ior->head;
482:
483: attempts = 0;
484:
485: }
486:
487: }
488:
1.1.1.2 root 489: TRACE(("Rsconf() napping until transmit buf empty"));
490:
491: nap(200);
492:
493: }
494:
495: }
496:
1.1.1.6 ! root 497: #endif
! 498:
1.1.1.3 root 499: #endif /* ONLY030 */
500:
501:
502:
1.1.1.6 ! root 503: if (has_bconmap && t) {
! 504:
! 505: rsval = MAPTAB[b].rsconf;
! 506:
! 507: /* bug # x+1: at least up to TOS 2.05 SCC Rsconf forgets to or #0x700,sr...
! 508:
! 509: * use MAPTAB to call it directly, at ipl7 if it points to ROM
! 510:
! 511: */
! 512:
! 513: if (baud > -2 &&
1.1.1.2 root 514:
1.1.1.6 ! root 515: (b == 1 || t->tty == &scca_tty) &&
1.1.1.2 root 516:
1.1.1.6 ! root 517: (b = 1, rsval > 0xe00000L) && rsval < 0xefffffL)
1.1.1.2 root 518:
1.1.1.6 ! root 519: rsval = callout6spl7 (rsval, baud, flow, uc, rs, ts, sc);
! 520:
! 521: else
! 522:
! 523: rsval = callout6 (rsval, baud, flow, uc, rs, ts, sc);
! 524:
! 525: } else {
! 526:
! 527: if (has_bconmap)
! 528:
! 529: mapin(curproc->bconmap);
! 530:
! 531: rsval = Rsconf(baud, flow, uc, rs, ts, sc);
! 532:
! 533: }
1.1.1.3 root 534:
1.1.1.6 ! root 535: if (!t || baud <= -2)
! 536:
! 537: return rsval;
! 538:
! 539:
! 540:
! 541: if (baud >= 0) {
! 542:
! 543: t->vticks = 0;
! 544:
! 545: t->ospeed = t->ispeed = (unsigned)baud < t->maxbaud ?
! 546:
! 547: t->baudmap[baud] : -1;
! 548:
! 549: }
! 550:
! 551: #if 1
! 552:
! 553: if (b == 1 && flow >= 0) {
! 554:
! 555: /*
! 556:
! 557: * SCC can observe CD and CTS in hardware (w3 bit 5), turn on if
! 558:
! 559: * TF_CAR and T_RTSCTS
! 560:
! 561: */
! 562:
! 563: short sr;
! 564:
! 565: volatile char dummy, *control;
! 566:
! 567: unsigned char w3;
! 568:
! 569:
! 570:
! 571: control = (volatile char *)
! 572:
! 573: (t->tty == &scca_tty ? 0xffff8c81L : 0xffff8c85L);
! 574:
! 575: w3 = ((((unsigned char *) t->irec)[0x1d] << 1) & 0xc0) |
! 576:
! 577: ((!t->clocal &&
! 578:
! 579: (((unsigned char *) t->irec)[0x20] & 2)) ? 0x21 : 0x1);
! 580:
! 581: sr = spl7();
! 582:
! 583: dummy = *((volatile char *) 0xfffffa01L);
! 584:
! 585: *control = 3;
! 586:
! 587: dummy = *((volatile char *) 0xfffffa01L);
! 588:
! 589: *control = w3;
! 590:
! 591: spl(sr);
! 592:
! 593: }
! 594:
! 595: #endif
1.1.1.3 root 596:
1.1.1.2 root 597: return rsval;
1.1 root 598:
599: }
600:
601:
602:
1.1.1.2 root 603: long ARGS_ON_STACK
1.1 root 604:
605: bconmap(dev)
606:
607: int dev;
608:
609: {
610:
611: int old = curproc->bconmap;
612:
613:
614:
1.1.1.2 root 615: TRACE(("Bconmap(%d)", dev));
1.1 root 616:
617:
618:
619: if (has_bconmap) {
620:
621: if (dev == -1) return old;
622:
623: if (dev == -2) return Bconmap(-2);
624:
1.1.1.2 root 625: if (dev == 0) return 0; /* the user's just testing */
626:
1.1 root 627: if (mapin(dev) == 0) {
628:
1.1.1.2 root 629: DEBUG(("Bconmap: mapin(%d) failed", dev));
1.1 root 630:
631: return 0;
632:
633: }
634:
635: if (set_auxhandle(curproc, dev) == 0) {
636:
1.1.1.2 root 637: DEBUG(("Bconmap: Couldn't change AUX:"));
1.1 root 638:
639: return 0;
640:
641: }
642:
643: curproc->bconmap = dev;
644:
645: return old;
646:
647: }
648:
649: return EINVFN; /* no Bconmap available */
650:
651: }
652:
653:
654:
1.1.1.2 root 655: /*
656:
657: * cursconf(): this gets converted into an ioctl() call on
658:
659: * the appropriate device
660:
661: */
662:
663:
664:
665: long ARGS_ON_STACK
666:
667: cursconf(cmd, op)
668:
669: int cmd, op;
670:
671: {
672:
673: FILEPTR *f;
674:
675:
676:
677: f = curproc->handle[-1];
678:
679: if (!f || !is_terminal(f))
680:
681: return EINVFN;
682:
683: return
684:
685: (*f->dev->ioctl)(f, TCURSOFF+cmd, &op);
686:
687: }
688:
689:
690:
1.1.1.4 root 691:
692:
693: long ARGS_ON_STACK
694:
695: dosound(ptr)
696:
697: const char *ptr;
698:
699: {
700:
701: MEMREGION *r;
702:
703:
704:
1.1.1.5 root 705: if (!no_mem_prot && ((long)ptr >= 0)) {
1.1.1.4 root 706:
707: /* check that this process has access to the memory */
708:
709: /* (if not, the next line will cause a bus error) */
710:
1.1.1.5 root 711: #ifdef __TURBOC__
712:
713: /* work-around for buggy optimizer */
714:
1.1.1.6 ! root 715: char dummy = (*((volatile char *)ptr));
1.1.1.5 root 716:
1.1.1.6 ! root 717: UNUSED(dummy);
1.1.1.4 root 718:
1.1.1.6 ! root 719: #else
1.1.1.5 root 720:
1.1.1.6 ! root 721: (void)(*((volatile char *)ptr));
1.1.1.4 root 722:
1.1.1.5 root 723: #endif
1.1.1.4 root 724:
725: /* OK, now make sure that interrupt routines will have access,
726:
727: * too
728:
729: */
730:
731: r = addr2region((long)ptr);
732:
733: if (r && get_prot_mode(r) == PROT_P) {
734:
735: DEBUG(("Dosound: changing protection to Super"));
736:
737: mark_region(r, PROT_S);
738:
739: }
740:
741: }
742:
743:
744:
1.1.1.5 root 745: return call_dosound(ptr);
1.1.1.4 root 746:
747: }
748:
749:
750:
1.1 root 751: void
752:
753: init_xbios()
754:
755: {
756:
1.1.1.6 ! root 757: int i, oldmap;
! 758:
! 759:
! 760:
1.1.1.2 root 761: curbconmap = (has_bconmap) ? (int) Bconmap(-1) : 1;
1.1 root 762:
763:
764:
765: xbios_tab[0x0c] = midiws;
766:
767: xbios_tab[0x0e] = uiorec;
768:
769: xbios_tab[0x0f] = rsconf;
770:
1.1.1.2 root 771: xbios_tab[0x15] = cursconf;
772:
1.1.1.4 root 773: xbios_tab[0x20] = dosound;
774:
1.1 root 775: xbios_tab[0x26] = supexec;
776:
777: xbios_tab[0x2c] = bconmap;
778:
1.1.1.6 ! root 779:
! 780:
! 781: oldmap = curproc->bconmap = curbconmap;
! 782:
! 783: for (i=0; i<btty_max; i++) {
! 784:
! 785: int r;
! 786:
! 787: if (has_bconmap)
! 788:
! 789: curproc->bconmap = i+6;
! 790:
! 791: r = (int)rsconf(-2, -1, -1, -1, -1, -1);
! 792:
! 793: if (r < 0) {
! 794:
! 795: if (has_bconmap)
! 796:
! 797: mapin (curproc->bconmap);
! 798:
! 799: Rsconf((r=0), -1, -1, -1, -1, -1);
! 800:
! 801: }
! 802:
! 803: rsconf(r, -1, -1, -1, -1, -1);
! 804:
! 805: }
! 806:
! 807: if (has_bconmap)
! 808:
! 809: mapin (curproc->bconmap = oldmap);
! 810:
1.1 root 811: }
812:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.