|
|
1.1 root 1: /*
2:
1.1.1.3 ! root 3: Copyright 1990,1991,1992 Eric R. Smith.
! 4:
! 5: Copyright 1992 Atari Corporation.
! 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:
! 333: /* Note: in theory, the code below shouldn't be necessary
! 334:
! 335: if we're running on a 68030 chip; after all, in such a case
! 336:
! 337: we MUST have TOS 1.6 or better...
! 338:
! 339: However, the code breaks if we comment this out, even though
! 340:
! 341: tosvers is indeed > 0x0104. Must be a compiler bug, but it's
! 342:
! 343: nothing obvious!
! 344:
! 345: */
! 346:
! 347:
1.1.1.2 root 348:
349: /*
350:
351: If this is an old TOS, try to rearrange things to support
352:
353: the following Rsconf() features:
354:
355: 1. Rsconf(-2, ...) does not return current baud (it crashes)
356:
357: -> keep track of old speed in static variable
358:
359: 2. Rsconf(b, ...) sends ASCII DEL to the modem unless b == -1
360:
361: -> make speed parameter -1 if new speed matches old speed
362:
363: 3. Rsconf() discards any buffered output
364:
365: -> use Iorec() to ensure all buffered data was sent before call
366:
367: */
368:
1.1.1.3 ! root 369: else if (tosvers < 0x0104) {
! 370:
1.1.1.2 root 371: if (baud == -2) {
372:
373: ret_oldbaud = 1;
374:
375: baud = -1;
376:
377: } else if (baud == oldbaud)
378:
379: baud = -1;
380:
381: else if (baud > -1)
382:
383: oldbaud = baud;
384:
1.1.1.3 ! root 385: }
! 386:
! 387: /* This part _is_ necessary on TOS 1.04 */
! 388:
! 389: if (tosvers <= 0x0104) {
! 390:
! 391: int attempts = 0;
! 392:
! 393: short old_head;
! 394:
1.1.1.2 root 395: ior = ((IOREC_T *) uiorec(0)) + 1; /* output record */
396:
1.1.1.3 ! root 397: old_head = ior->head;
! 398:
1.1.1.2 root 399: while (ior->head != ior->tail) {
400:
1.1.1.3 ! root 401: if (++attempts >= 50) { /* prevent getting stuck by flow control */
! 402:
! 403: if (old_head == ior->head)
! 404:
! 405: break;
! 406:
! 407: else {
! 408:
! 409: old_head = ior->head;
! 410:
! 411: attempts = 0;
! 412:
! 413: }
! 414:
! 415: }
! 416:
1.1.1.2 root 417: TRACE(("Rsconf() napping until transmit buf empty"));
418:
419: nap(200);
420:
421: }
422:
423: }
424:
1.1.1.3 ! root 425: #endif /* ONLY030 */
! 426:
! 427:
! 428:
1.1.1.2 root 429: rsval = Rsconf(baud, flow, uc, rs, ts, sc);
430:
431: if (ret_oldbaud)
432:
433: rsval = (long) oldbaud;
434:
1.1.1.3 ! root 435:
! 436:
1.1.1.2 root 437: return rsval;
1.1 root 438:
439: }
440:
441:
442:
1.1.1.2 root 443: long ARGS_ON_STACK
1.1 root 444:
445: bconmap(dev)
446:
447: int dev;
448:
449: {
450:
451: int old = curproc->bconmap;
452:
453:
454:
1.1.1.2 root 455: TRACE(("Bconmap(%d)", dev));
1.1 root 456:
457:
458:
459: if (has_bconmap) {
460:
461: if (dev == -1) return old;
462:
463: if (dev == -2) return Bconmap(-2);
464:
1.1.1.2 root 465: if (dev == 0) return 0; /* the user's just testing */
466:
1.1 root 467: if (mapin(dev) == 0) {
468:
1.1.1.2 root 469: DEBUG(("Bconmap: mapin(%d) failed", dev));
1.1 root 470:
471: return 0;
472:
473: }
474:
475: if (set_auxhandle(curproc, dev) == 0) {
476:
1.1.1.2 root 477: DEBUG(("Bconmap: Couldn't change AUX:"));
1.1 root 478:
479: return 0;
480:
481: }
482:
483: curproc->bconmap = dev;
484:
485: return old;
486:
487: }
488:
489: return EINVFN; /* no Bconmap available */
490:
491: }
492:
493:
494:
1.1.1.2 root 495: /*
496:
497: * cursconf(): this gets converted into an ioctl() call on
498:
499: * the appropriate device
500:
501: */
502:
503:
504:
505: long ARGS_ON_STACK
506:
507: cursconf(cmd, op)
508:
509: int cmd, op;
510:
511: {
512:
513: FILEPTR *f;
514:
515:
516:
517: f = curproc->handle[-1];
518:
519: if (!f || !is_terminal(f))
520:
521: return EINVFN;
522:
523: return
524:
525: (*f->dev->ioctl)(f, TCURSOFF+cmd, &op);
526:
527: }
528:
529:
530:
1.1 root 531: void
532:
533: init_xbios()
534:
535: {
536:
1.1.1.2 root 537: curbconmap = (has_bconmap) ? (int) Bconmap(-1) : 1;
1.1 root 538:
539:
540:
541: xbios_tab[0x0c] = midiws;
542:
543: xbios_tab[0x0e] = uiorec;
544:
545: xbios_tab[0x0f] = rsconf;
546:
1.1.1.2 root 547: xbios_tab[0x15] = cursconf;
548:
1.1 root 549: xbios_tab[0x26] = supexec;
550:
551: xbios_tab[0x2c] = bconmap;
552:
553: }
554:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.