|
|
1.1 root 1: /*
2:
1.1.1.3 root 3: Copyright 1990,1991,1992 Eric R. Smith.
4:
1.1.1.4 ! root 5: Copyright 1992,1993 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:
25: extern int tosvers; /* from main.c */
26:
27:
28:
29: #define XBIOS_MAX 0x80
30:
31:
32:
33: Func xbios_tab[XBIOS_MAX]; /* initially all zeros */
34:
35: short xbios_max = XBIOS_MAX;
36:
37:
38:
39: /* NOTE: has_bconmap is initialized in main.c */
40:
41:
42:
43: int has_bconmap; /* flag: set if running under a version
44:
45: * of TOS which supports Bconmap
46:
47: */
48:
49:
50:
51: /*
52:
53: * Supexec() presents a lot of problems for us: for example, the user
54:
55: * may be calling the kernel, or may be changing interrupt vectors
56:
57: * unexpectedly. So we play some dirty tricks here: the function
58:
59: * call is treated like a signal handler, and we take advantage
60:
61: * of the fact that no context switches will take place while
62:
63: * in supervisor mode. ASSUMPTION: the user will not choose to
64:
65: * switch back to user mode, or if s/he does it will be as part
66:
67: * of a longjmp().
68:
69: *
70:
71: * BUG: if the user function switches to user mode, then back to
72:
73: * supervisor mode and returns, then the returned value may be
74:
75: * inaccurate (this happens if two programs make Supexec calls
76:
77: * at the same time).
78:
79: */
80:
81:
82:
1.1.1.3 root 83: long ARGS_ON_STACK (*usrcall) P_((long, long,long,long,long,long));
84:
85: long usrret;
1.1 root 86:
1.1.1.3 root 87: long usrarg1, usrarg2, usrarg3, usrarg4, usrarg5;
1.1 root 88:
89:
90:
1.1.1.3 root 91: #if 0
92:
93: /* moved to syscall.spp */
1.1 root 94:
1.1.1.2 root 95: static void ARGS_ON_STACK do_usrcall P_((void));
1.1 root 96:
97:
98:
1.1.1.2 root 99: static void ARGS_ON_STACK
1.1 root 100:
101: do_usrcall()
102:
103: {
104:
1.1.1.3 root 105: usrret = (*usrcall)((long)usrcall, usrarg1, usrarg2, usrarg3, usrarg4,
106:
107: usrarg5);
1.1 root 108:
109: }
110:
1.1.1.3 root 111: #endif
112:
1.1 root 113:
114:
1.1.1.2 root 115: long ARGS_ON_STACK
1.1 root 116:
117: supexec(funcptr, arg1, arg2, arg3, arg4, arg5)
118:
119: Func funcptr;
120:
121: long arg1, arg2, arg3, arg4, arg5;
122:
123: {
124:
125: short savesr;
126:
127: CONTEXT *syscall = &curproc->ctxt[SYSCALL];
128:
129:
130:
131: /* set things up so that "signal 0" will be handled by calling the user's
132:
133: * function.
134:
135: */
136:
137:
138:
139: usrcall = funcptr;
140:
141: usrarg1 = arg1;
142:
143: usrarg2 = arg2;
144:
145: usrarg3 = arg3;
146:
147: usrarg4 = arg4;
148:
149: usrarg5 = arg5;
150:
151: curproc->sighandle[0] = (long)do_usrcall;
152:
153: savesr = syscall->sr; /* save old super/user mode flag */
154:
155: syscall->sr |= 0x2000; /* set supervisor mode */
156:
157: handle_sig(0); /* actually call out to the user function */
158:
159: syscall->sr = savesr;
160:
161:
162:
163: /* do_usrcall saves the user's return value in usrret */
164:
165: return usrret;
166:
167: }
168:
169:
170:
171:
172:
173: /*
174:
175: * midiws: we have to replace this, because it's possible that the process'
176:
177: * view of what the MIDI port is has been changed by Fforce or Fmidipipe
178:
179: */
180:
181:
182:
1.1.1.2 root 183: long ARGS_ON_STACK
1.1 root 184:
185: midiws(cnt, buf)
186:
187: int cnt;
188:
189: const char *buf;
190:
191: {
192:
193: FILEPTR *f;
194:
195: long towrite = cnt+1;
196:
197:
198:
199: f = curproc->handle[-5]; /* MIDI output handle */
200:
201: if (!f) return EIHNDL;
202:
203:
204:
205: if (is_terminal(f)) {
206:
207: while (cnt >= 0) {
208:
209: tty_putchar(f, (long)*buf, RAW);
210:
211: buf++; cnt--;
212:
213: }
214:
215: return towrite;
216:
217: }
218:
219: return (*f->dev->write)(f, buf, towrite);
220:
221: }
222:
223:
224:
225: /*
226:
227: * Modem control things: these are replaced because we handle
228:
229: * Bconmap ourselves
230:
231: */
232:
233:
234:
235: /* mapin: utility routine, does a Bconmap and keeps track
236:
237: * so we call the kernel only when necessary; call this
238:
239: * only if has_bconmap is "true".
240:
241: * Returns: 0 on failure, 1 on success.
242:
243: */
244:
245: int curbconmap;
246:
247:
248:
249: int
250:
251: mapin(dev)
252:
253: int dev;
254:
255: {
256:
1.1.1.2 root 257: long r;
1.1 root 258:
259:
260:
261: if (dev == curbconmap)
262:
263: return 1;
264:
265: r = Bconmap(dev);
266:
267: if (r) {
268:
269: curbconmap = dev;
270:
271: return 1;
272:
273: }
274:
275: return 0;
276:
277: }
278:
279:
280:
1.1.1.2 root 281: long ARGS_ON_STACK
1.1 root 282:
283: uiorec(dev)
284:
285: int dev;
286:
287: {
288:
1.1.1.2 root 289: TRACE(("Iorec(%d)", dev));
1.1 root 290:
291: if (dev == 0 && has_bconmap)
292:
293: mapin(curproc->bconmap);
294:
295: return (long)Iorec(dev);
296:
297: }
298:
299:
300:
1.1.1.2 root 301: long ARGS_ON_STACK
1.1 root 302:
303: rsconf(baud, flow, uc, rs, ts, sc)
304:
305: int baud, flow, uc, rs, ts, sc;
306:
307: {
308:
1.1.1.3 root 309: long rsval;
310:
1.1.1.2 root 311: static int oldbaud = -1;
1.1 root 312:
1.1.1.2 root 313: int ret_oldbaud = 0;
314:
315: IOREC_T *ior;
316:
317:
318:
319: TRACE(("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
320:
321: uc, rs, ts, sc));
1.1 root 322:
323:
324:
325: if (has_bconmap)
326:
327: mapin(curproc->bconmap);
328:
1.1.1.3 root 329:
330:
331: #ifndef DONT_ONLY030_THIS
332:
1.1.1.4 ! root 333: /* Note: the code below must be included, even on a 68030, thanks to a bug
1.1.1.3 root 334:
1.1.1.4 ! root 335: * in the gcc and mntlib osbind.h file.
1.1.1.3 root 336:
1.1.1.4 ! root 337: */
1.1.1.3 root 338:
339:
1.1.1.2 root 340:
341: /*
342:
343: If this is an old TOS, try to rearrange things to support
344:
345: the following Rsconf() features:
346:
347: 1. Rsconf(-2, ...) does not return current baud (it crashes)
348:
349: -> keep track of old speed in static variable
350:
351: 2. Rsconf(b, ...) sends ASCII DEL to the modem unless b == -1
352:
353: -> make speed parameter -1 if new speed matches old speed
354:
355: 3. Rsconf() discards any buffered output
356:
357: -> use Iorec() to ensure all buffered data was sent before call
358:
359: */
360:
1.1.1.3 root 361: else if (tosvers < 0x0104) {
362:
1.1.1.2 root 363: if (baud == -2) {
364:
365: ret_oldbaud = 1;
366:
367: baud = -1;
368:
369: } else if (baud == oldbaud)
370:
371: baud = -1;
372:
373: else if (baud > -1)
374:
375: oldbaud = baud;
376:
1.1.1.3 root 377: }
378:
379: /* This part _is_ necessary on TOS 1.04 */
380:
381: if (tosvers <= 0x0104) {
382:
383: int attempts = 0;
384:
385: short old_head;
386:
1.1.1.2 root 387: ior = ((IOREC_T *) uiorec(0)) + 1; /* output record */
388:
1.1.1.3 root 389: old_head = ior->head;
390:
1.1.1.2 root 391: while (ior->head != ior->tail) {
392:
1.1.1.3 root 393: if (++attempts >= 50) { /* prevent getting stuck by flow control */
394:
395: if (old_head == ior->head)
396:
397: break;
398:
399: else {
400:
401: old_head = ior->head;
402:
403: attempts = 0;
404:
405: }
406:
407: }
408:
1.1.1.2 root 409: TRACE(("Rsconf() napping until transmit buf empty"));
410:
411: nap(200);
412:
413: }
414:
415: }
416:
1.1.1.3 root 417: #endif /* ONLY030 */
418:
419:
420:
1.1.1.2 root 421: rsval = Rsconf(baud, flow, uc, rs, ts, sc);
422:
423: if (ret_oldbaud)
424:
425: rsval = (long) oldbaud;
426:
1.1.1.3 root 427:
428:
1.1.1.2 root 429: return rsval;
1.1 root 430:
431: }
432:
433:
434:
1.1.1.2 root 435: long ARGS_ON_STACK
1.1 root 436:
437: bconmap(dev)
438:
439: int dev;
440:
441: {
442:
443: int old = curproc->bconmap;
444:
445:
446:
1.1.1.2 root 447: TRACE(("Bconmap(%d)", dev));
1.1 root 448:
449:
450:
451: if (has_bconmap) {
452:
453: if (dev == -1) return old;
454:
455: if (dev == -2) return Bconmap(-2);
456:
1.1.1.2 root 457: if (dev == 0) return 0; /* the user's just testing */
458:
1.1 root 459: if (mapin(dev) == 0) {
460:
1.1.1.2 root 461: DEBUG(("Bconmap: mapin(%d) failed", dev));
1.1 root 462:
463: return 0;
464:
465: }
466:
467: if (set_auxhandle(curproc, dev) == 0) {
468:
1.1.1.2 root 469: DEBUG(("Bconmap: Couldn't change AUX:"));
1.1 root 470:
471: return 0;
472:
473: }
474:
475: curproc->bconmap = dev;
476:
477: return old;
478:
479: }
480:
481: return EINVFN; /* no Bconmap available */
482:
483: }
484:
485:
486:
1.1.1.2 root 487: /*
488:
489: * cursconf(): this gets converted into an ioctl() call on
490:
491: * the appropriate device
492:
493: */
494:
495:
496:
497: long ARGS_ON_STACK
498:
499: cursconf(cmd, op)
500:
501: int cmd, op;
502:
503: {
504:
505: FILEPTR *f;
506:
507:
508:
509: f = curproc->handle[-1];
510:
511: if (!f || !is_terminal(f))
512:
513: return EINVFN;
514:
515: return
516:
517: (*f->dev->ioctl)(f, TCURSOFF+cmd, &op);
518:
519: }
520:
521:
522:
1.1.1.4 ! root 523:
! 524:
! 525: long ARGS_ON_STACK
! 526:
! 527: dosound(ptr)
! 528:
! 529: const char *ptr;
! 530:
! 531: {
! 532:
! 533: MEMREGION *r;
! 534:
! 535:
! 536:
! 537: if (!no_mem_prot) {
! 538:
! 539: /* check that this process has access to the memory */
! 540:
! 541: /* (if not, the next line will cause a bus error) */
! 542:
! 543: (void)(*((volatile char *)ptr));
! 544:
! 545:
! 546:
! 547: /* OK, now make sure that interrupt routines will have access,
! 548:
! 549: * too
! 550:
! 551: */
! 552:
! 553: r = addr2region((long)ptr);
! 554:
! 555: if (r && get_prot_mode(r) == PROT_P) {
! 556:
! 557: DEBUG(("Dosound: changing protection to Super"));
! 558:
! 559: mark_region(r, PROT_S);
! 560:
! 561: }
! 562:
! 563: }
! 564:
! 565:
! 566:
! 567: Dosound(ptr);
! 568:
! 569: return 0;
! 570:
! 571: }
! 572:
! 573:
! 574:
1.1 root 575: void
576:
577: init_xbios()
578:
579: {
580:
1.1.1.2 root 581: curbconmap = (has_bconmap) ? (int) Bconmap(-1) : 1;
1.1 root 582:
583:
584:
585: xbios_tab[0x0c] = midiws;
586:
587: xbios_tab[0x0e] = uiorec;
588:
589: xbios_tab[0x0f] = rsconf;
590:
1.1.1.2 root 591: xbios_tab[0x15] = cursconf;
592:
1.1.1.4 ! root 593: xbios_tab[0x20] = dosound;
! 594:
1.1 root 595: xbios_tab[0x26] = supexec;
596:
597: xbios_tab[0x2c] = bconmap;
598:
599: }
600:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.