home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 10: Diskmags / nf_archive_10.iso / MAGS / PURE_B / PBMAG22A.MSA / MINT095S.ZIP / SRC / XBIOS.C < prev    next >
C/C++ Source or Header  |  1987-04-22  |  4KB  |  193 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
  3. */
  4.  
  5. /*
  6.  * XBIOS replacement routines
  7.  */
  8.  
  9. #include "mint.h"
  10.  
  11. extern int tosvers;    /* from main.c */
  12.  
  13. #define XBIOS_MAX 0x80
  14.  
  15. Func xbios_tab[XBIOS_MAX];    /* initially all zeros */
  16. short xbios_max = XBIOS_MAX;
  17.  
  18. /* NOTE: has_bconmap is initialized in main.c */
  19.  
  20. int has_bconmap;    /* flag: set if running under a version
  21.              * of TOS which supports Bconmap
  22.              */
  23.  
  24. /*
  25.  * Supexec() presents a lot of problems for us: for example, the user
  26.  * may be calling the kernel, or may be changing interrupt vectors
  27.  * unexpectedly. So we play some dirty tricks here: the function
  28.  * call is treated like a signal handler, and we take advantage
  29.  * of the fact that no context switches will take place while
  30.  * in supervisor mode. ASSUMPTION: the user will not choose to
  31.  * switch back to user mode, or if s/he does it will be as part
  32.  * of a longjmp().
  33.  *
  34.  * BUG: if the user function switches to user mode, then back to
  35.  * supervisor mode and returns, then the returned value may be
  36.  * inaccurate (this happens if two programs make Supexec calls
  37.  * at the same time).
  38.  */
  39.  
  40. static long (*usrcall) P_((long,long,long,long,long));
  41. static long usrret;
  42. static long usrarg1, usrarg2, usrarg3, usrarg4, usrarg5;
  43.  
  44. static void do_usrcall P_((void));
  45.  
  46. static void
  47. do_usrcall()
  48. {
  49.     usrret = (*usrcall)(usrarg1, usrarg2, usrarg3, usrarg4, usrarg5);
  50. }
  51.  
  52. long
  53. supexec(funcptr, arg1, arg2, arg3, arg4, arg5)
  54.     Func funcptr;
  55.     long arg1, arg2, arg3, arg4, arg5;
  56. {
  57.     short savesr;
  58.     CONTEXT *syscall = &curproc->ctxt[SYSCALL];
  59.  
  60. /* set things up so that "signal 0" will be handled by calling the user's
  61.  * function.
  62.  */
  63.  
  64.     usrcall = funcptr;
  65.     usrarg1 = arg1;
  66.     usrarg2 = arg2;
  67.     usrarg3 = arg3;
  68.     usrarg4 = arg4;
  69.     usrarg5 = arg5;
  70.     curproc->sighandle[0] = (long)do_usrcall;
  71.     savesr = syscall->sr;    /* save old super/user mode flag */
  72.     syscall->sr |= 0x2000;    /* set supervisor mode */
  73.     handle_sig(0);        /* actually call out to the user function */
  74.     syscall->sr = savesr;
  75.  
  76. /* do_usrcall saves the user's return value in usrret */
  77.     return usrret;
  78. }
  79.  
  80.  
  81. /*
  82.  * midiws: we have to replace this, because it's possible that the process'
  83.  * view of what the MIDI port is has been changed by Fforce or Fmidipipe
  84.  */
  85.  
  86. long
  87. midiws(cnt, buf)
  88.     int cnt;
  89.     const char *buf;
  90. {
  91.     FILEPTR *f;
  92.     long towrite = cnt+1;
  93.  
  94.     f = curproc->handle[-5];    /* MIDI output handle */
  95.     if (!f) return EIHNDL;
  96.  
  97.     if (is_terminal(f)) {
  98.         while (cnt >= 0) {
  99.             tty_putchar(f, (long)*buf, RAW);
  100.             buf++; cnt--;
  101.         }
  102.         return towrite;
  103.     }
  104.     return (*f->dev->write)(f, buf, towrite);
  105. }
  106.  
  107. /*
  108.  * Modem control things: these are replaced because we handle
  109.  * Bconmap ourselves
  110.  */
  111.  
  112. /* mapin: utility routine, does a Bconmap and keeps track
  113.  * so we call the kernel only when necessary; call this
  114.  * only if has_bconmap is "true".
  115.  * Returns: 0 on failure, 1 on success.
  116.  */
  117. int curbconmap;
  118.  
  119. int
  120. mapin(dev)
  121.     int dev;
  122. {
  123.     int r;
  124.  
  125.     if (dev == curbconmap)
  126.         return 1;
  127.     r = Bconmap(dev);
  128.     if (r) {
  129.         curbconmap = dev;
  130.         return 1;
  131.     }
  132.     return 0;
  133. }
  134.     
  135. long
  136. uiorec(dev)
  137.     int dev;
  138. {
  139.     TRACE("Iorec(%d)", dev);
  140.     if (dev == 0 && has_bconmap)
  141.         mapin(curproc->bconmap);
  142.     return (long)Iorec(dev);
  143. }
  144.  
  145. long
  146. rsconf(baud, flow, uc, rs, ts, sc)
  147.     int baud, flow, uc, rs, ts, sc;
  148. {
  149.     TRACE("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
  150.         uc, rs, ts, sc);
  151.  
  152.     if (has_bconmap)
  153.         mapin(curproc->bconmap);
  154.     return Rsconf(baud, flow, uc, rs, ts, sc);
  155. }
  156.  
  157. long
  158. bconmap(dev)
  159.     int dev;
  160. {
  161.     int old = curproc->bconmap;
  162.  
  163.     TRACE("Bconmap(%d)", dev);
  164.  
  165.     if (has_bconmap) {
  166.         if (dev == -1) return old;
  167.         if (dev == -2) return Bconmap(-2);
  168.         if (mapin(dev) == 0) {
  169.             DEBUG("Bconmap: mapin failed");
  170.             return 0;
  171.         }
  172.         if (set_auxhandle(curproc, dev) == 0) {
  173.             DEBUG("Bconmap: Couldn't change AUX:");
  174.             return 0;
  175.         }
  176.         curproc->bconmap = dev;
  177.         return old;
  178.     }
  179.     return EINVFN;    /* no Bconmap available */
  180. }
  181.  
  182. void
  183. init_xbios()
  184. {
  185.     curbconmap = (has_bconmap) ? Bconmap(-1) : 1;
  186.  
  187.     xbios_tab[0x0c] = midiws;
  188.     xbios_tab[0x0e] = uiorec;
  189.     xbios_tab[0x0f] = rsconf;
  190.     xbios_tab[0x26] = supexec;
  191.     xbios_tab[0x2c] = bconmap;
  192. }
  193.