home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / SystemWedges / wedge.c < prev   
Encoding:
C/C++ Source or Header  |  1992-08-27  |  7.5 KB  |  320 lines

  1.  
  2. /*
  3.  *   Wedge.c
  4.  *   by Bart Whitebook
  5.  *
  6.  * Copyright (c) 1988 Commodore-Amiga, Inc.
  7.  *
  8.  * Executables based on this information may be used in software
  9.  * for Commodore Amiga computers.  All other rights reserved.
  10.  *
  11.  * This information is provided "as is"; no warranties are made.
  12.  * All use is at your own risk, and no liability or responsibility is assumed.
  13. */
  14.  
  15. /*  This code was created under Greenhills.
  16.  *  It compiles under Manx with the cflags:
  17.  *
  18.  *   +L +C +D +p -B -S -L100
  19.  */
  20.  
  21. /******************************************************************************
  22. *
  23. *   Source Control
  24. *   --------------
  25. *   $Header: wedge.c,v 35.8 88/03/23 09:51:24 bart Exp $
  26. *
  27. *   $Locker:  $
  28. *
  29. *   $Log:   wedge.c,v $
  30. *   Revision 35.8  88/03/23  09:51:24  bart
  31. *   remove() mods
  32. *   
  33. *   Revision 35.7  88/03/22  18:55:42  bart
  34. *   if(wp) in dispose
  35. *   
  36. *   Revision 35.6  88/03/22  15:17:24  bart
  37. *   keep opencount
  38. *   
  39. *   Revision 35.0  88/03/01  11:20:28  bart
  40. *   added to rcs for updating
  41. *   
  42. *
  43. ******************************************************************************/
  44.  
  45.  
  46. #include <exec/types.h>
  47. #include <exec/memory.h>
  48. #include <exec/nodes.h>
  49. #include <exec/lists.h>
  50. #include <exec/libraries.h>
  51.  
  52. #ifdef DEBUG
  53. #define KPRINTF
  54. #endif
  55.  
  56. #ifdef KPRINTF
  57. #define printf kprintf
  58. #endif
  59.  
  60. #define JSR_ABS   0x4EB9
  61. #define JSR_dPC   0x4EBA
  62.  
  63. #define JMP_ABS   0x4EF9
  64. #define JMP_dPC   0x4EFA
  65.  
  66. #define   RTS      0x4E75
  67.  
  68. struct Wedge {
  69.    UWORD   wedge_Vectors[20];
  70.    struct    Library   wedge_Library;
  71.    WORD   wedge_Offset;
  72. } ;
  73.  
  74. /* support code for usecount */
  75.  
  76. #define MOVEM_REG_SP 0x48E7
  77. #define REG_TO_MEM   0x0080
  78. #define LEA_dPC        0x41FA
  79. #define ADDQ_1        0x5250
  80. #define SUBQ_1        0x5350
  81. #define NO_OP       0x4E71
  82. #define MOVEM_SP_REG 0x4CDF
  83. #define MEM_TO_REG   0x0100
  84.  
  85. new_wedge()
  86. {
  87.    struct Wedge *wp = NULL;
  88.  
  89.    /* allocate a wedge */
  90.  
  91.    if(wp=(struct Wedge *)AllocMem(sizeof(struct Wedge),MEMF_PUBLIC|MEMF_CLEAR))
  92.    {
  93.       /* initialize the wedge library to default values */
  94.  
  95.       wp->wedge_Library.lib_Node.ln_Type = NT_LIBRARY;
  96.       wp->wedge_Library.lib_NegSize = 12;
  97.       wp->wedge_Library.lib_PosSize = sizeof(struct Library)+sizeof(WORD);
  98.       wp->wedge_Library.lib_Version = 35;
  99.       wp->wedge_Library.lib_Revision = 1;
  100.  
  101.       /* initialize the wedge vectors to default values */
  102.  
  103.       wp->wedge_Vectors[0]  = MOVEM_REG_SP;   /* increment opencount */
  104.       wp->wedge_Vectors[1]  = REG_TO_MEM;
  105.       wp->wedge_Vectors[2]  = LEA_dPC;
  106.       wp->wedge_Vectors[3]  = 0x0042;
  107.       wp->wedge_Vectors[4]  = ADDQ_1;
  108.       wp->wedge_Vectors[5]  = MOVEM_SP_REG;
  109.       wp->wedge_Vectors[6]  = MEM_TO_REG;
  110.  
  111.       wp->wedge_Vectors[7]  = JSR_dPC;      /* do wedge function */
  112.       wp->wedge_Vectors[8]  = 0x0004;          /* default */
  113.       wp->wedge_Vectors[9]  = RTS;         /* return */
  114.  
  115.       wp->wedge_Vectors[10] = MOVEM_REG_SP;   /* decrement opencount */
  116.       wp->wedge_Vectors[11] = REG_TO_MEM;
  117.       wp->wedge_Vectors[12] = LEA_dPC;
  118.       wp->wedge_Vectors[13] = 0x002E;
  119.       wp->wedge_Vectors[14] = SUBQ_1;
  120.       wp->wedge_Vectors[15] = MOVEM_SP_REG;
  121.       wp->wedge_Vectors[16] = MEM_TO_REG;
  122.  
  123.       wp->wedge_Vectors[17] = JMP_dPC;        /* do old function */
  124.       wp->wedge_Vectors[18] = 0x0002;         /* default */
  125.       wp->wedge_Vectors[19] = RTS;          /* return */
  126.    }
  127.  
  128.    return((ULONG)wp);
  129. }
  130.  
  131. dispose_wedge(wp)
  132. struct Wedge *wp;
  133. {
  134.    /* to be strict, we must assume that some task's pc is */
  135.    /* about to execute this wedge: so we must leave the wedge */
  136.    /* in memory until the opencount of this wedge is 0 before */
  137.    /* we are free to delink the wedge "function"... not that the */
  138.    /* wedge structure itself must remain in memory when we are gone */
  139.  
  140.    if(wp)
  141.    {
  142.       Forbid();
  143.  
  144.       while(wp->wedge_Library.lib_OpenCnt != 0) WaitTOF();
  145.  
  146.       Disable();
  147.  
  148.       wp->wedge_Vectors[7] = JSR_dPC;  /* install default function */
  149.       wp->wedge_Vectors[8] = 0x0004;   /* in place of wedge function */
  150.       wp->wedge_Vectors[9] = RTS;       /* and return */
  151.  
  152.       Enable();
  153.  
  154.       Permit();
  155.    }
  156. }
  157.  
  158. test_wedge(wp)
  159. struct Wedge *wp;
  160. {
  161.    ULONG is_wedge = NULL;
  162.    UBYTE *pred;
  163.  
  164.    /* make certain that wp is not odd -- it will be if wp == default vector */
  165.  
  166.    if(((ULONG)wp)^1)
  167.    {
  168.       if(wp->wedge_Library.lib_Node.ln_Type == NT_LIBRARY)
  169.       {
  170.          if(pred = wp->wedge_Library.lib_Node.ln_Pred)
  171.          {
  172.             if(((ULONG)pred)^1)
  173.             {
  174.                if(wp==(struct Wedge *)*(ULONG *)(pred+wp->wedge_Offset+2))
  175.                {
  176.                   is_wedge = (ULONG)wp;
  177.                }
  178.             }
  179.          }
  180.       }
  181.    }
  182.    return(is_wedge);
  183. }
  184.  
  185. link_wedge(lib,offset,wedge)
  186. UBYTE *lib;
  187. WORD offset;
  188. struct Wedge *wedge;
  189. {
  190.    ULONG is_wedge = NULL;
  191.    struct Wedge *owp;
  192.    UBYTE *pred;
  193.  
  194.    if(owp = (struct Wedge *)test_wedge(*(ULONG *)(lib+offset+2)))
  195.    {
  196.       is_wedge = (ULONG)owp;
  197.       owp->wedge_Library.lib_Node.ln_Pred = wedge;
  198.       owp->wedge_Offset = -6;
  199.    }
  200.    return(is_wedge);
  201. }
  202.  
  203. delink_wedge(lib,offset,wp)
  204. UBYTE *lib;
  205. WORD offset;
  206. struct Wedge *wp;
  207. {
  208.    struct Wedge *owp = NULL;
  209.    struct Wedge *nwp;
  210.  
  211.    if(wp)
  212.    {
  213.       /* prevent unpleasant suprises */
  214.  
  215.       Disable();
  216.  
  217.       /* is this still a valid wedge? */
  218.  
  219.       if(owp = (struct Wedge *)test_wedge(wp))
  220.       {
  221.          struct Library *pred = owp->wedge_Library.lib_Node.ln_Pred;
  222.  
  223.          /* yes, valid. does this wedge point to another wedge? */
  224.  
  225.          if( nwp = (struct Wedge *)
  226.                test_wedge(*(ULONG *)(&owp->wedge_Vectors[18]))
  227.            )
  228.          {
  229.             nwp->wedge_Library.lib_Node.ln_Pred = pred;
  230.          }
  231.  
  232.          /* does the previous library point to this wedge's library */
  233.  
  234.          if(pred->lib_Node.ln_Succ == &owp->wedge_Library)
  235.          {
  236.             /* yes, make previous library point to next wedge's library */
  237.  
  238.             pred->lib_Node.ln_Succ == &nwp->wedge_Library;
  239.          }
  240.  
  241.          /* make previous vector point to next vector */   
  242.  
  243.          SetFunction( wp->wedge_Library.lib_Node.ln_Pred,
  244.                    wp->wedge_Offset,
  245.                    *(ULONG *)(&wp->wedge_Vectors[18]));
  246.  
  247.          /* now the wedge is delinked... */
  248.       }
  249.       else
  250.       {
  251.          /* wedge not validated... */
  252.          /* assume that has been setfunction'ed away, */
  253.          /* and may be setfunction'ed back in the near future: */
  254.          /* install default function, if wedge not in use */
  255.  
  256.          if(wp->wedge_Library.lib_OpenCnt == 0)
  257.          {
  258.             wp->wedge_Vectors[7] = JSR_dPC; 
  259.             wp->wedge_Vectors[8] = 0x0004;   
  260.             wp->wedge_Vectors[9] = RTS;      
  261.          }
  262.       }
  263.  
  264.       /* suprises ok now, i guess... */
  265.  
  266.       Enable();
  267.    }
  268.  
  269.    return((ULONG)owp);
  270. }
  271.  
  272. install_wedge(lib,offset,entry)
  273. struct Library *lib;
  274. WORD offset;
  275. ULONG entry;
  276. {
  277.    struct Wedge *wp = NULL;
  278.  
  279.    if( (entry) && (wp = (struct Wedge *)new_wedge()) )
  280.    {
  281.       /* prevent unpleasant suprises */
  282.  
  283.       Disable();
  284.  
  285.       /* point this wedge at our new entry */
  286.  
  287.       wp->wedge_Vectors[7] = JSR_ABS;
  288.       *(ULONG *)(&wp->wedge_Vectors[8]) = entry;
  289.  
  290.       /* point this wedge at the previous entry */
  291.  
  292.       wp->wedge_Library.lib_Node.ln_Pred = lib;
  293.       wp->wedge_Offset = offset;
  294.  
  295.       /* link this wedge to existing wedge? */
  296.  
  297.       wp->wedge_Library.lib_Node.ln_Succ = 
  298.          (struct Node *) link_wedge(lib,offset,wp);
  299.  
  300.       /* install this wedge in place of the old entry */
  301.  
  302.       wp->wedge_Vectors[17] = JMP_ABS;
  303.       *(ULONG *)(&wp->wedge_Vectors[18]) = SetFunction(lib,offset,wp);
  304.  
  305.       /* suprises ok now, i guess... */
  306.  
  307.       Enable();
  308.    }
  309.  
  310.    return((ULONG)wp);
  311. }
  312.  
  313. remove_wedge(wedge)
  314. struct Wedge *wedge;
  315. {
  316.    delink_wedge(wedge);
  317.    dispose_wedge(wedge);
  318. }
  319.  
  320.