home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #4 / amigamamagazinepolishissue1998.iso / datatypes / gifanimdtc201.lha / gifanim_datatype / stackswap.c < prev   
C/C++ Source or Header  |  1998-01-16  |  3KB  |  108 lines

  1.  
  2. /*
  3. **
  4. **  $VER: stackswap.c 1.5 (16.1.98)
  5. **  gifanim.datatype 1.5
  6. **
  7. **  Dispatch routine for a DataTypes class
  8. **
  9. **  Written 1997/1998 by Roland 'Gizzy' Mainz
  10. **  Original example source from David N. Junod
  11. **
  12. */
  13.  
  14. /* main includes */
  15. #include "classbase.h"
  16.  
  17. /*****************************************************************************/
  18.  
  19. typedef ULONG ASM (*DMHOOKFUNC)( REGA0 struct Hook *, REGA2 APTR, REGA1 APTR );
  20.  
  21. struct MyStackSwapStruct
  22. {
  23.     struct StackSwapStruct  stk;
  24.     struct IClass          *cl;
  25.     Object                 *o;
  26.     Msg                     msg;
  27. };
  28.  
  29. /*****************************************************************************/
  30.  
  31.  
  32. DISPATCHERFLAGS
  33. ULONG StackSwapDispatch( REGA0 struct IClass *cl, REGA2 Object *o, REGA1 Msg msg )
  34. {
  35.     struct ClassBase         *cb                 = (struct ClassBase *)(cl -> cl_UserData);
  36.     ULONG                     retval;
  37.     struct MyStackSwapStruct  mystk;
  38.     UBYTE                    *lower,
  39.                              *upper,
  40.                              *sp;
  41.     struct Task              *ThisTask;
  42.     ULONG                     stacksize,
  43.                               required_stacksize = (ULONG)(cl -> cl_Dispatcher . h_Data);
  44.  
  45.     /* Fill in data */
  46.     mystk . cl                = cl;
  47.     mystk . o                 = o;
  48.     mystk . msg               = msg;
  49.  
  50.     ThisTask = FindTask( NULL );
  51.     stacksize = (ULONG)(((UBYTE *)(ThisTask -> tc_SPReg)) - ((UBYTE *)(ThisTask -> tc_SPLower)));
  52.  
  53.     /* Enougth stack ? */
  54.     if( stacksize > ((required_stacksize * 2UL) / 3UL) )
  55.     {
  56.       retval = MyDispatch( (&mystk) );
  57.     }
  58.     else
  59.     {
  60.       /* Alloc a new stack frame... */
  61.       while( !(lower = (UBYTE *)AllocMem( required_stacksize, MEMF_PUBLIC )) );
  62.  
  63.       sp = upper = lower + required_stacksize;
  64.  
  65.       mystk . stk . stk_Lower   = lower;
  66.       mystk . stk . stk_Upper   = (ULONG)upper;
  67.       mystk . stk . stk_Pointer = sp;
  68.  
  69.       retval = SwapMe( (&mystk) );
  70.  
  71.       FreeMem( lower, required_stacksize );
  72.     }
  73.  
  74.     return( retval );
  75. }
  76.  
  77.  
  78. /* swap stack */
  79. DISPATCHERFLAGS
  80. ULONG SwapMe( REGA0 struct MyStackSwapStruct *mystk )
  81. {
  82.     register ULONG retval;
  83.  
  84. #define cb ((struct ClassBase *)(mystk -> cl -> cl_UserData))
  85.  
  86.     StackSwap( (&(mystk -> stk)) );
  87.  
  88.       retval = MyDispatch( mystk );
  89.  
  90.     StackSwap( (&(mystk -> stk)) );
  91.  
  92. #undef cb
  93.  
  94.     return( retval );
  95. }
  96.  
  97.  
  98. /* call class dispatcher */
  99. DISPATCHERFLAGS
  100. ULONG MyDispatch( REGA0 struct MyStackSwapStruct *mystk )
  101. {
  102.     struct IClass *cl  = mystk -> cl;
  103.  
  104.     return( (*((DMHOOKFUNC)(cl -> cl_Dispatcher . h_SubEntry)))( (&(cl -> cl_Dispatcher)), (APTR)(mystk -> o), (APTR)(mystk -> msg) ) );
  105. }
  106.  
  107.  
  108.