home *** CD-ROM | disk | FTP | other *** search
/ Kosovo Orphans' Appeal Charity CD / KosovoOrphansAppeal.iso / commercialdemos / claresmicrosupplies / pca / flexlib / c / flex
Text File  |  1996-04-30  |  20KB  |  839 lines

  1.  
  2. /************************************************************************/
  3. /*  Acorn Computers Ltd, 1992.                                         */
  4. /*                                                                      */
  5. /* This file forms part of an unsupported source release of RISC_OSLib. */
  6. /*                                                                      */
  7. /* It may be freely used to create executable images for saleable       */
  8. /* products but cannot be sold in source form or as an object library   */
  9. /* without the prior written consent of Acorn Computers Ltd.            */
  10. /*                                                                      */
  11. /* If this file is re-distributed (even if modified) it should retain   */
  12. /* this copyright notice.                                               */
  13. /*                                                                      */
  14. /************************************************************************/
  15.  
  16. /* Title: c.flex
  17.  * Purpose: provide memory allocation for interactive programs requiring
  18.  *          large chunks of store.
  19.  * History: IDJ: 06-Feb-92: prepared for source release
  20.  *          Andy Armstrong:  21-Oct-94: modified to use dynamic areas and callbacks.
  21.  *          David Jackson :  06-Sep-95: modified to use Virtual Memory
  22.  *          David Jackson :  19-Apr-96: modified to use Acorn Toolbox (Ugh!)
  23.  */
  24.  
  25. #define BOOL int
  26. #define TRUE 1
  27. #define FALSE 0
  28. #define TRACE 0
  29.  
  30. #include <stdlib.h>
  31. #include <stdarg.h>
  32. #include <string.h>
  33. #include <stdio.h>
  34. #include "kernel.h"
  35. #include "swis.h"
  36. #include "h.flex"
  37. #include "wimplib.h"
  38.  
  39.  
  40. /* #include "tracker.h" */
  41.  
  42. #ifndef OS_DynamicArea
  43. #define OS_DynamicArea  0x00066
  44. #endif
  45.  
  46. #ifndef Virtualise_Configure          
  47. #define Virtualise_Configure           0x04b6c0
  48. #endif
  49. #ifndef Virtualise_Start              
  50. #define Virtualise_Start               0x04b6c1
  51. #endif
  52. #ifndef Virtualise_End                
  53. #define Virtualise_End                 0x04b6c2
  54. #endif
  55. #ifndef Virtualise_Lock               
  56. #define Virtualise_Lock                0x04b6c3
  57. #endif
  58. #ifndef Virtualise_Unlock             
  59. #define Virtualise_Unlock              0x04b6c4
  60. #endif
  61. #ifndef Virtualise_MiscOp             
  62. #define Virtualise_MiscOp              0x04b6c5
  63. #endif
  64.  
  65.  
  66.  
  67. static int flex__initialised = 0;
  68. static int flex__da          = -1; /* or da number */
  69. static BOOL flex__VM         = FALSE;  /* is VM in use? */ 
  70. static int  _mblk;
  71.  
  72. static void werr(int fatal, char* format, ...);
  73. static char* msgs_lookup(char* tag);
  74.  
  75.  
  76. /* This implementation goes above the original value of GetEnv,
  77. to memory specifically requested from the Wimp. The heap is kept
  78. totally compacted all the time, with pages being given back to
  79. the Wimp whenever possible. */
  80.  
  81. typedef struct {
  82.   flex_ptr anchor;      /* *anchor should point back to here. */
  83. #ifdef flex_CALLBACK
  84.   flex_cbfunc cb;
  85.   void *handle;
  86. #endif    
  87.   int size;             /* in bytes. Exact size of logical area. */
  88.                         /* then the actual store follows. */
  89. } flex__rec;
  90.  
  91.  
  92. static void flex__fail(int i)
  93. {
  94.    werr(TRUE, msgs_lookup("flex1:Flex memory error (%d)"), i);
  95. #if TRACE
  96.    i = *(int *)-4 ;     /* go bang! */
  97. #else
  98.    i = i; /* avoid compiler warning. */
  99. #endif
  100. }
  101.  
  102.  
  103. static void flex__check(void)
  104. {
  105.    if(flex__initialised == 0)
  106.      werr(TRUE, msgs_lookup("flex3:Flex not initialised"));
  107. }
  108.  
  109.  
  110.  
  111. /* macro to avoid stack usage */
  112. #define roundup(n)  (0xfffffffc & (n + 3))
  113.  
  114. static char *flex__base;        /* lowest flex__rec - only for budging. */
  115. static char *flex__freep;       /* free flex memory */
  116. static char *flex__lim;         /* limit of flex memory */
  117. /* From base upwards, it's divided into store blocks of
  118.   a flex__rec
  119.   the space
  120.   align up to next word.
  121. */
  122.  
  123.  
  124. static void flex__wimpslot(char **top) 
  125. {
  126.    /* read/write the top of available memory. *top == 0 -> just read. */
  127.    int dud = -1;
  128.    int slot = ((int) *top);
  129.    _kernel_swi_regs r;
  130.    _kernel_oserror  *err;
  131.    int memlim, appspace, oldmemlim;
  132.  
  133.    if (slot != -1) slot -= 0x8000;
  134.  
  135.    /* read memory limit value */
  136.     r.r[0] = 0;
  137.     r.r[1] = 0;
  138.     r.r[2] = 0;
  139.     err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  140.     oldmemlim = memlim = r.r[1];
  141.  
  142.    /* read appspace value */
  143.     r.r[0] = 14;  /* Application space */
  144.     r.r[1] = 0;
  145.     r.r[2] = 0;
  146.     err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  147.     appspace = r.r[1];
  148.    /* set memory limit before slot size change ... */
  149.     if(appspace > memlim)
  150.     {
  151.        r.r[0] = 0;
  152.        r.r[1] = appspace;
  153.        r.r[2] = 0;
  154.        err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  155.     }
  156.  
  157.    /* set wimpslot size (or read it) */
  158.    
  159.    if (wimp_slot_size(slot,dud,&slot, &dud, &dud)!=NULL) werr(TRUE,msgs_lookup("fatal:Fatal Flex memory error"));
  160.  
  161.    *top = (char*) slot + 0x8000;
  162.  
  163.    /* .... and set memory limit back again */
  164.    if (appspace > memlim)
  165.    {
  166.        r.r[0] = 0;
  167.        r.r[1] = oldmemlim;
  168.        r.r[2] = 0;
  169.        err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  170.     }
  171.        
  172. }
  173.  
  174. static BOOL flex__more(int n)
  175. {
  176.    /* Tries to get at least n more bytes, raising flex__lim and
  177.    returning TRUE if it can. */
  178.    char *prev = flex__lim;
  179.  
  180.    if (flex__da != -1)
  181.    {  _kernel_swi_regs regs;
  182.       _kernel_oserror *err;
  183.  
  184.       regs.r[0] = flex__da;
  185.       regs.r[1] = n;
  186.  
  187.       err = _kernel_swi(OS_ChangeDynamicArea, ®s, ®s);
  188.       
  189.       if (err || regs.r[1] < n)
  190.       {  regs.r[1] = -regs.r[1];
  191.          _kernel_swi(OS_ChangeDynamicArea, ®s, ®s);
  192.          return FALSE;
  193.       }
  194.  
  195.       err = _kernel_swi(OS_ReadDynamicArea, ®s, ®s);
  196.       flex__lim = flex__base + regs.r[1];
  197.       return TRUE;
  198.    }
  199.    else
  200.    {  flex__lim += n;
  201.       flex__wimpslot(&flex__lim);
  202.  
  203.    
  204.       if (flex__lim < prev + n)
  205.       {
  206.          flex__lim = prev;             /* restore starting state:
  207.                                           extra memory is useless */
  208.          flex__wimpslot(&flex__lim);
  209.          return FALSE ;
  210.       }
  211.       else 
  212.          return TRUE ;
  213.    }
  214. }
  215.  
  216.  
  217. static void flex__give(void) 
  218. {
  219.    if (flex__da != -1)
  220.    {  _kernel_swi_regs regs;
  221.       _kernel_oserror *err;
  222.       
  223.       regs.r[0] = flex__da;
  224.       regs.r[1] = flex__freep - flex__lim; /* -ve */
  225.  
  226.       err = _kernel_swi(OS_ChangeDynamicArea, ®s, ®s);
  227.       if (!err)
  228.       {  err = _kernel_swi(OS_ReadDynamicArea, ®s, ®s);
  229.          flex__lim = flex__base + regs.r[1];
  230.       }
  231.    }
  232.    else
  233.    {
  234.       /* Gives away memory, lowering flex__lim, if possible. */
  235. #if TRACE
  236.       int prev = (int) flex__lim;
  237. #endif
  238.    
  239.       flex__lim = flex__freep;
  240.       flex__wimpslot(&flex__lim);
  241.  
  242.    }
  243. }
  244.  
  245.  
  246. static BOOL flex__ensure(int n) 
  247. {
  248.    n -= flex__lim - flex__freep;
  249.  
  250.    if (n <= 0 || flex__more(n)) 
  251.       return TRUE; 
  252.    else return FALSE;
  253. }
  254.  
  255. BOOL flex_alloc(flex_ptr anchor, int n)
  256. {
  257.    flex__rec *p;
  258.  
  259.    flex__check();
  260.  
  261.    if (n < 0 || ! flex__ensure(sizeof(flex__rec) + roundup(n))) 
  262.    {
  263.       *anchor = 0;
  264.       return FALSE;
  265.    }
  266.  
  267.    p = (flex__rec*) flex__freep;
  268.    flex__freep += sizeof(flex__rec) + roundup(n);
  269.  
  270.    p->anchor = anchor;
  271.    p->size = n;
  272. #ifdef flex_CALLBACK
  273.    p->cb = NULL;
  274.    p->handle = NULL;
  275. #endif      
  276.    *anchor = p + 1; /* sizeof(flex__rec), that is */
  277.    return TRUE;
  278. }
  279.  
  280. static void flex__reanchor(flex__rec *p, int by) 
  281. {
  282.    /* Move all the anchors from p upwards. This is in anticipation
  283.    of that block of the heap being shifted. */
  284.  
  285.    while (1) 
  286.    {
  287.       if ((int) p >= (int) flex__freep) break;
  288.  
  289.       if (*(p->anchor) != p + 1) flex__fail(6);
  290.       *(p->anchor) = ((char*) (p + 1)) + by;
  291.       p = (flex__rec*) (((char*) (p + 1)) + roundup(p->size));
  292.    }
  293. }
  294.  
  295. /* Notify all the blocks after and including p that the are about to move / have
  296.  moved */
  297.  
  298. #ifdef flex_CALLBACK
  299. #define flex__inlinenotify(b4, p)                                    \
  300.    do                                                                \
  301.    {  flex__rec *p2 = (p);                                           \
  302.       for (;;)                                                       \
  303.       {  if ((int) p2 >= (int) flex__freep) break;                   \
  304.          if (*(p2->anchor) != p2 + 1) flex__fail(6);                 \
  305.          if (p2->cb) p2->cb(b4, p2->handle);                         \
  306.          p2 = (flex__rec*) (((char*) (p2 + 1)) + roundup(p2->size)); \
  307.       }                                                              \
  308.    } while (0)
  309.  
  310. static void flex__notify(BOOL b4, flex__rec *p)
  311. {  flex__inlinenotify(b4, p);
  312. }
  313.  
  314. #else
  315. #define flex__inlinenotify(b4, p) (void) 0
  316. #define flex__notify(b4, p) (void) 0
  317. #endif
  318.  
  319. void flex_free(flex_ptr anchor)
  320. {
  321.    flex__rec *p = ((flex__rec*) *anchor) - 1;
  322.    int roundsize = roundup(p->size);
  323.    flex__rec *next = (flex__rec*) (((char*) (p + 1)) + roundsize);
  324.  
  325.    flex__check();
  326.  
  327.    if (p->anchor != anchor) 
  328.    {
  329.       flex__fail(0);
  330.    }
  331.  
  332.    flex__notify(TRUE, next);
  333.    flex__reanchor(next, - (sizeof(flex__rec) + roundsize));
  334.    memmove(p, next, flex__freep - (char*) next);
  335.    flex__freep -= sizeof(flex__rec) + roundsize;
  336.    flex__notify(FALSE, p);
  337.  
  338.    flex__give();
  339.  
  340.    *anchor = 0;
  341. }
  342.  
  343.  
  344. int flex_size(flex_ptr anchor)
  345.  {
  346.    flex__rec *p = ((flex__rec*) *anchor) - 1;
  347.    flex__check();
  348.  
  349.    if (p->anchor != anchor) 
  350.    {
  351.       flex__fail(4);
  352.    }
  353.  
  354.    return(p->size);
  355. }
  356.  
  357.  
  358. int flex_extend(flex_ptr anchor, int newsize)
  359. {
  360.    flex__rec *p = ((flex__rec*) *anchor) - 1;
  361.    flex__check();
  362.    return(flex_midextend(anchor, p->size, newsize - p->size));
  363. }
  364.  
  365.  
  366. BOOL flex_midextend(flex_ptr anchor, int at, int by)
  367. {
  368.    flex__rec *p;
  369.    flex__rec *next;
  370.  
  371.    flex__check();
  372.  
  373.    p = ((flex__rec*) *anchor) - 1;
  374.  
  375.    if (p->anchor != anchor) 
  376.       flex__fail(1);
  377.  
  378.    if (at > p->size) 
  379.       flex__fail(2);
  380.  
  381.    if (by < 0 && (-by) > at) 
  382.       flex__fail(3);
  383.  
  384.    if (by == 0) 
  385.    {
  386.       /* do nothing */
  387.    }
  388.    else if (by > 0) 
  389.    { 
  390.       /* extend */
  391.  
  392.       int growth = roundup(p->size + by) - roundup(p->size);
  393.       /* Amount by which the block will actually grow. */
  394.  
  395.       if (! flex__ensure(growth)) 
  396.          return FALSE;
  397.  
  398.       next = (flex__rec*) (((char*) (p + 1)) + roundup(p->size));
  399.       /* The move has to happen in two parts because the moving
  400.       of objects above is word-aligned, while the extension within
  401.       the object may not be. */
  402.  
  403.       flex__notify(TRUE, next);
  404.       flex__reanchor(next, growth);
  405.  
  406.       memmove(((char*) next) + roundup(growth), next, flex__freep - (char*) next
  407. );
  408.  
  409.       flex__freep += growth;
  410.       flex__notify(FALSE, (flex__rec *) (((char *) next) + roundup(growth)));
  411.  
  412.       memmove(((char*) (p + 1)) + at + by, ((char*) (p + 1)) + at, p->size - at)
  413. ;
  414.  
  415.       p->size += by;
  416.  
  417.    } 
  418.    else 
  419.    { 
  420.       /* The block shrinks. */
  421.       int shrinkage;
  422.  
  423.       next = (flex__rec*) (((char*) (p + 1)) + roundup(p->size));
  424.  
  425.       by = -by; /* a positive value now */
  426.       shrinkage = roundup(p->size) - roundup(p->size - by);
  427.         /* a positive value */
  428.  
  429.       memmove(((char*) (p + 1)) + at - by, ((char*) (p + 1)) + at, p->size - at)
  430. ;
  431.  
  432.       p->size -= by;
  433.  
  434.       flex__notify(TRUE, next);
  435.       flex__reanchor(next, - shrinkage);
  436.  
  437.       memmove(((char*) next) - shrinkage, next, flex__freep - (char*) next);
  438.  
  439.       flex__freep -= shrinkage;
  440.       flex__notify(FALSE, (flex__rec *) (((char *) next) - shrinkage));
  441.  
  442.       flex__give();
  443.  
  444.    } 
  445.  
  446.    return TRUE;
  447. }
  448.  
  449. #ifdef flex_CALLBACK
  450. void flex_register(flex_ptr anchor, flex_cbfunc cb, void *handle)
  451. {  flex__rec *p = ((flex__rec*) *anchor) - 1;
  452.  
  453.    flex__check();
  454.  
  455.    if (p->anchor != anchor) 
  456.    {
  457.       flex__fail(4);
  458.    }
  459.  
  460.    p->cb = cb;
  461.    p->handle = handle;
  462. }
  463. #endif
  464.  
  465. /* stack checking off */
  466. #pragma -s1
  467.  
  468. /* The underlying system asks us to move all flex store up (if n +ve) or
  469. down by n bytes. If you succeed, put the store allocated in *a and return
  470. the size. size >= roundup(n) on successful exit, and will be a multiple of
  471. four. If you fail, return what we can. 
  472. If n is -ve, no result is required: success is assumed. 
  473. */
  474.  
  475. extern int flex_budge(int n, void **a)
  476. {  if (flex__da != -1)
  477.       return flex_dont_budge(n, a);
  478.  
  479.    flex__inlinenotify(TRUE, (flex__rec *) flex__base);
  480.  
  481.    if (n >= 0) /* all moving up */
  482.    {
  483.       int roundupn = roundup(n);
  484.       int more = roundupn - (flex__lim - flex__freep);
  485.       
  486.       /* try to satisfy the request */
  487.       if (more > 0)   /* ie we have to increase slot */
  488.       {
  489.          char *prev = flex__lim;
  490.          flex__lim += more; 
  491.  
  492.          /* in-line implementation (of flex__wimpslot)  */
  493.          /*  to reduce stack requirements               */
  494.          {
  495.             int slot = ((int) flex__lim);
  496.             _kernel_swi_regs r;
  497.             _kernel_oserror  *err;
  498.             int memlim, appspace, oldmemlim;
  499.  
  500.             if (slot != -1) 
  501.                slot -= 0x8000;
  502.  
  503.             /* read memory limit value */
  504.             r.r[0] = 0;
  505.             r.r[1] = 0;
  506.             r.r[2] = 0;
  507.             err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  508.             oldmemlim = memlim = r.r[1];
  509.  
  510.             /* read appspace value */
  511.             r.r[0] = 14;  /* Application space */
  512.             r.r[1] = 0;
  513.             r.r[2] = 0;
  514.             err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  515.             appspace = r.r[1];
  516.  
  517.             /* set memory limit before slot size change ... */
  518.             if(appspace > memlim)
  519.             {
  520.                r.r[0] = 0;
  521.                r.r[1] = appspace;
  522.                r.r[2] = 0;
  523.                err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  524.             }
  525.  
  526.             /* set wimpslot size */
  527.             r.r[0] = slot;
  528.             r.r[1] = -1;
  529.             err =_kernel_swi(Wimp_SlotSize, &r, &r);
  530.             slot = r.r[0];
  531.             
  532.             flex__lim = (char*) slot + 0x8000;
  533.  
  534.             /* .... and set memory limit back again */
  535.             if (appspace > memlim)
  536.             {
  537.                r.r[0] = 0;
  538.                r.r[1] = oldmemlim;
  539.                r.r[2] = 0;
  540.                err = _kernel_swi(OS_ChangeEnvironment, &r, &r);
  541.             }
  542.          }
  543.  
  544.          /* if we couldn't satisfy it, still give back what we can, */
  545.          /* _kernel_alloc may be able to use it!!!!!                */
  546.          if (flex__lim < prev + more)
  547.              roundupn = flex__lim - flex__freep; /*all we got*/
  548.       }
  549.       
  550.       {
  551.            flex__rec *p = (flex__rec*)flex__base;
  552.            while (1) {
  553.                 if ((int) p >= (int) flex__freep) break;
  554.                 *(p->anchor) = ((char*) (p + 1)) + roundupn;
  555.                 p = (flex__rec*) (((char*) (p + 1)) + roundup(p->size));
  556.            }
  557.       }
  558.        
  559.       memmove(flex__base + roundupn, flex__base, flex__freep - flex__base);
  560.       *a = flex__base;
  561.       flex__base += roundupn;
  562.       flex__freep += roundupn;
  563.  
  564.       flex__inlinenotify(FALSE, (flex__rec *) flex__base);
  565.       return(roundupn);
  566.  
  567.    } 
  568.    else 
  569.    { 
  570.       /* all moving down */
  571.       int roundupn = roundup(-n); /* a +ve value */
  572.  
  573.       {
  574.          flex__rec *p = (flex__rec*)flex__base;
  575.          while (1) 
  576.          {
  577.              if ((int) p >= (int) flex__freep) break;
  578.              *(p->anchor) = ((char*) (p + 1)) + roundupn;
  579.              p = (flex__rec*) (((char*) (p + 1)) + roundup(p->size));
  580.          }
  581.       }
  582.       memmove(flex__base - roundupn, flex__base, flex__freep - flex__base);
  583.       flex__base -= roundupn;
  584.       flex__freep -= roundupn;
  585.       flex__inlinenotify(FALSE, (flex__rec *) flex__base);
  586.    }
  587.  
  588.  
  589.    return(0);
  590. }
  591.  
  592. extern int flex_dont_budge(int n, void **a)
  593. {  n = n;
  594.    a = a;
  595.    return 0;
  596. }
  597.  
  598. /* stack checks on again */
  599. #pragma -s0
  600.  
  601. static void flex__exit(void)
  602. {  _kernel_swi_regs regs;
  603.  
  604.    if (flex__da != -1)
  605.    {  regs.r[0] = 1;
  606.       regs.r[1] = flex__da;
  607.       _kernel_swi(OS_DynamicArea, ®s, ®s);
  608.    }
  609. }
  610.  
  611. void flex_initx(char *program_name, int *error_fd,int da,int maxsize,BOOL virtualise)
  612. {  flex__lim = (char *) -1;
  613.    _mblk=(int)error_fd;
  614.  
  615.    if (da) /* try to create a DA */
  616.    {  _kernel_oserror *err;
  617.       _kernel_swi_regs regs;
  618.  
  619.       regs.r[0] =    0;  /* create DA         */
  620.       regs.r[1] =   -1;  /* area number       */
  621.       regs.r[2] =    0;  /* initial size      */
  622.       regs.r[3] =   -1;  /* logical address   */
  623.       regs.r[4] = 0x80;  /* access privileges */
  624.       regs.r[5] =   maxsize;  /* max size          */
  625.       if (virtualise)                                       /*DJ    */
  626.        {                                                    /*DJ    */
  627.          regs.r[4] = regs.r[4]  | (1U <<31);                /*DJ    */
  628.          regs.r[5]=maxsize;                                 /*DJ    */
  629.                                                             /*DJ    */
  630.        }                                                    /*DJ    */
  631.       regs.r[6] =    0;  /* no routine yet    */
  632.       regs.r[7] =    0;  /* ws pointer        */
  633.       regs.r[8] = (int) program_name;  /* area name */
  634.  
  635.       err = _kernel_swi(OS_DynamicArea, ®s, ®s);
  636.  
  637.       if (!err)
  638.       {  flex__da   = regs.r[1];
  639.          flex__freep = flex__lim = flex__base = (char *) regs.r[3];
  640.          atexit(flex__exit);   
  641.          if (virtualise)
  642.            {
  643.             _kernel_swi(OS_ReadMemMapInfo,®s,®s);
  644.             regs.r[0]=regs.r[0]*regs.r[1];
  645.             regs.r[1]=regs.r[0];
  646.             regs.r[2]=regs.r[0]*.05;
  647.             _kernel_swi(Virtualise_Configure,®s,®s);
  648.                                                        
  649.             flex__VM=TRUE;
  650.            }
  651.          goto initok;
  652.       }
  653.    }
  654.  
  655.    flex__wimpslot(&flex__lim);  /* shrink */
  656.    flex__freep = flex__lim;
  657.    flex__base = flex__freep;
  658.    _kernel_register_slotextend(flex_dont_budge);
  659.  
  660. initok:
  661.    flex__initialised = 1;
  662.  
  663.    /* Check that we're in the Wimp environment. */
  664.    {
  665.       void *a;
  666.       if (! flex_alloc(&a, 1)) 
  667.          werr(TRUE, msgs_lookup("flex2:Not enough memory, or not within *desktop world."));
  668.  
  669.       flex_free(&a);
  670.    }
  671.  
  672. }
  673.  
  674. /* default flex_init() disables use of DA */
  675.  
  676. void flex_init(char *program_name, int *error_fd)
  677. {  flex_initx(program_name,error_fd,FALSE,-1,FALSE /* DJ 060995 */);
  678. }
  679.  
  680. int flex_isdynamic(void)
  681. {  return flex__da != -1;
  682. }                       
  683.  
  684.  
  685. BOOL flex_isVM(void)
  686. {
  687.  return flex__VM;
  688. }
  689.  
  690. _kernel_oserror * flex_VMConfigure(int def,int cache,int left)
  691.  
  692. {
  693. _kernel_swi_regs regs;
  694.  
  695.  regs.r[0]=def;
  696.  regs.r[1]=cache;
  697.  regs.r[2]=left;
  698.  return _kernel_swi(Virtualise_Configure,®s,®s);
  699. }
  700.  
  701.  
  702.  
  703. _kernel_oserror * flex_readVMConfigure(int * def ,int *cache,int *left)
  704.  
  705. {
  706. _kernel_oserror *err;
  707. _kernel_swi_regs regs;
  708.  
  709.  regs.r[0]=-1;
  710.  regs.r[1]=-1;
  711.  regs.r[2]=-1;
  712.  err=_kernel_swi(Virtualise_Configure,®s,®s);
  713.  
  714.  if (!err)
  715.  {
  716.  
  717.  *def    =regs.r[0];
  718.  *cache  =regs.r[1];
  719.  *left   =regs.r[2];
  720.  regs.r[0]=2;
  721.  regs.r[1]=flex__da;
  722.  _kernel_swi(OS_DynamicArea,®s,®s);
  723.  
  724. *def=regs.r[5];
  725.  }
  726.   
  727. return(err);
  728. }
  729.  
  730.  
  731. _kernel_oserror * flex_virtualstart(char * swapfile)
  732. {
  733. _kernel_swi_regs regs;
  734. _kernel_oserror *err;
  735.  
  736. regs.r[0]=flex__da;
  737. regs.r[1]=-1;
  738. regs.r[2]=(int) swapfile;
  739. err=_kernel_swi(Virtualise_Start,®s,®s);
  740.  
  741. if (!err) flex__VM=TRUE;
  742. return(err);
  743.  
  744. }
  745.  
  746.  
  747. _kernel_oserror * flex_virtualstop(void)
  748. {
  749. _kernel_swi_regs regs;
  750. _kernel_oserror *err;
  751.  
  752. regs.r[0]=flex__da;
  753. err=_kernel_swi(Virtualise_End,®s,®s);
  754.  
  755. if (!err) flex__VM=FALSE;
  756. return(err);
  757.  
  758. }
  759.  
  760.  
  761. _kernel_oserror * flex_lock(int start,int end)
  762. {
  763. _kernel_swi_regs regs;
  764. _kernel_oserror *err=NULL;
  765.  
  766. if (flex__VM)
  767.                         
  768. {
  769.    regs.r[0]=start;
  770.    regs.r[1]=end;
  771.    err=_kernel_swi(Virtualise_Lock,®s,®s);  
  772.  
  773. }
  774.  
  775. return(err);
  776. }
  777.  
  778.  
  779. _kernel_oserror * flex_unlock(int start,int end)
  780. {
  781. _kernel_swi_regs regs;
  782. _kernel_oserror *err=NULL;
  783.  
  784. if (flex__VM)
  785.                         
  786. {
  787.    regs.r[0]=start;
  788.    regs.r[1]=end;
  789.    err=_kernel_swi(Virtualise_Unlock,®s,®s);  
  790.  
  791. }
  792.  
  793. return(err);
  794. }
  795.  
  796.  
  797.  
  798. static void werr(int fatal, char* format, ...)
  799. {
  800.    va_list va;
  801.    _kernel_oserror e;
  802.  
  803.    e.errnum = 0;
  804.    va_start(va, format);
  805.    vsprintf(&e.errmess[0], format, va);
  806.    va_end(va);
  807.    wimp_report_error(&e, 0, "FlexLibrary",0,0,0);
  808.    if (fatal) exit(1);
  809. }
  810.  
  811. static char* msgs_lookup(char* tag)
  812. {
  813.  
  814.  _kernel_swi_regs regs;
  815.   char* p=tag;
  816.   while (*p++!=':') NULL;
  817.   p--;
  818.   *p++=0;
  819.  
  820.     regs.r[0] = _mblk;
  821.     regs.r[1] = (int) tag;
  822.     regs.r[2] = 0;
  823.  
  824.     if (_kernel_swi(MessageTrans_Lookup,®s,®s))
  825.      return p;
  826.     else return (char *) regs.r[2];
  827.  
  828.  
  829.  
  830.  
  831. }
  832.  
  833.  
  834.  
  835.  
  836.  
  837. /* end */
  838.  
  839.