home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Wedge.c
- * by Bart Whitebook
- *
- * Copyright (c) 1988 Commodore-Amiga, Inc.
- *
- * Executables based on this information may be used in software
- * for Commodore Amiga computers. All other rights reserved.
- *
- * This information is provided "as is"; no warranties are made.
- * All use is at your own risk, and no liability or responsibility is assumed.
- */
-
- /* This code was created under Greenhills.
- * It compiles under Manx with the cflags:
- *
- * +L +C +D +p -B -S -L100
- */
-
- /******************************************************************************
- *
- * Source Control
- * --------------
- * $Header: wedge.c,v 35.8 88/03/23 09:51:24 bart Exp $
- *
- * $Locker: $
- *
- * $Log: wedge.c,v $
- * Revision 35.8 88/03/23 09:51:24 bart
- * remove() mods
- *
- * Revision 35.7 88/03/22 18:55:42 bart
- * if(wp) in dispose
- *
- * Revision 35.6 88/03/22 15:17:24 bart
- * keep opencount
- *
- * Revision 35.0 88/03/01 11:20:28 bart
- * added to rcs for updating
- *
- *
- ******************************************************************************/
-
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/libraries.h>
-
- #ifdef DEBUG
- #define KPRINTF
- #endif
-
- #ifdef KPRINTF
- #define printf kprintf
- #endif
-
- #define JSR_ABS 0x4EB9
- #define JSR_dPC 0x4EBA
-
- #define JMP_ABS 0x4EF9
- #define JMP_dPC 0x4EFA
-
- #define RTS 0x4E75
-
- struct Wedge {
- UWORD wedge_Vectors[20];
- struct Library wedge_Library;
- WORD wedge_Offset;
- } ;
-
- /* support code for usecount */
-
- #define MOVEM_REG_SP 0x48E7
- #define REG_TO_MEM 0x0080
- #define LEA_dPC 0x41FA
- #define ADDQ_1 0x5250
- #define SUBQ_1 0x5350
- #define NO_OP 0x4E71
- #define MOVEM_SP_REG 0x4CDF
- #define MEM_TO_REG 0x0100
-
- new_wedge()
- {
- struct Wedge *wp = NULL;
-
- /* allocate a wedge */
-
- if(wp=(struct Wedge *)AllocMem(sizeof(struct Wedge),MEMF_PUBLIC|MEMF_CLEAR))
- {
- /* initialize the wedge library to default values */
-
- wp->wedge_Library.lib_Node.ln_Type = NT_LIBRARY;
- wp->wedge_Library.lib_NegSize = 12;
- wp->wedge_Library.lib_PosSize = sizeof(struct Library)+sizeof(WORD);
- wp->wedge_Library.lib_Version = 35;
- wp->wedge_Library.lib_Revision = 1;
-
- /* initialize the wedge vectors to default values */
-
- wp->wedge_Vectors[0] = MOVEM_REG_SP; /* increment opencount */
- wp->wedge_Vectors[1] = REG_TO_MEM;
- wp->wedge_Vectors[2] = LEA_dPC;
- wp->wedge_Vectors[3] = 0x0042;
- wp->wedge_Vectors[4] = ADDQ_1;
- wp->wedge_Vectors[5] = MOVEM_SP_REG;
- wp->wedge_Vectors[6] = MEM_TO_REG;
-
- wp->wedge_Vectors[7] = JSR_dPC; /* do wedge function */
- wp->wedge_Vectors[8] = 0x0004; /* default */
- wp->wedge_Vectors[9] = RTS; /* return */
-
- wp->wedge_Vectors[10] = MOVEM_REG_SP; /* decrement opencount */
- wp->wedge_Vectors[11] = REG_TO_MEM;
- wp->wedge_Vectors[12] = LEA_dPC;
- wp->wedge_Vectors[13] = 0x002E;
- wp->wedge_Vectors[14] = SUBQ_1;
- wp->wedge_Vectors[15] = MOVEM_SP_REG;
- wp->wedge_Vectors[16] = MEM_TO_REG;
-
- wp->wedge_Vectors[17] = JMP_dPC; /* do old function */
- wp->wedge_Vectors[18] = 0x0002; /* default */
- wp->wedge_Vectors[19] = RTS; /* return */
- }
-
- return((ULONG)wp);
- }
-
- dispose_wedge(wp)
- struct Wedge *wp;
- {
- /* to be strict, we must assume that some task's pc is */
- /* about to execute this wedge: so we must leave the wedge */
- /* in memory until the opencount of this wedge is 0 before */
- /* we are free to delink the wedge "function"... not that the */
- /* wedge structure itself must remain in memory when we are gone */
-
- if(wp)
- {
- Forbid();
-
- while(wp->wedge_Library.lib_OpenCnt != 0) WaitTOF();
-
- Disable();
-
- wp->wedge_Vectors[7] = JSR_dPC; /* install default function */
- wp->wedge_Vectors[8] = 0x0004; /* in place of wedge function */
- wp->wedge_Vectors[9] = RTS; /* and return */
-
- Enable();
-
- Permit();
- }
- }
-
- test_wedge(wp)
- struct Wedge *wp;
- {
- ULONG is_wedge = NULL;
- UBYTE *pred;
-
- /* make certain that wp is not odd -- it will be if wp == default vector */
-
- if(((ULONG)wp)^1)
- {
- if(wp->wedge_Library.lib_Node.ln_Type == NT_LIBRARY)
- {
- if(pred = wp->wedge_Library.lib_Node.ln_Pred)
- {
- if(((ULONG)pred)^1)
- {
- if(wp==(struct Wedge *)*(ULONG *)(pred+wp->wedge_Offset+2))
- {
- is_wedge = (ULONG)wp;
- }
- }
- }
- }
- }
- return(is_wedge);
- }
-
- link_wedge(lib,offset,wedge)
- UBYTE *lib;
- WORD offset;
- struct Wedge *wedge;
- {
- ULONG is_wedge = NULL;
- struct Wedge *owp;
- UBYTE *pred;
-
- if(owp = (struct Wedge *)test_wedge(*(ULONG *)(lib+offset+2)))
- {
- is_wedge = (ULONG)owp;
- owp->wedge_Library.lib_Node.ln_Pred = wedge;
- owp->wedge_Offset = -6;
- }
- return(is_wedge);
- }
-
- delink_wedge(lib,offset,wp)
- UBYTE *lib;
- WORD offset;
- struct Wedge *wp;
- {
- struct Wedge *owp = NULL;
- struct Wedge *nwp;
-
- if(wp)
- {
- /* prevent unpleasant suprises */
-
- Disable();
-
- /* is this still a valid wedge? */
-
- if(owp = (struct Wedge *)test_wedge(wp))
- {
- struct Library *pred = owp->wedge_Library.lib_Node.ln_Pred;
-
- /* yes, valid. does this wedge point to another wedge? */
-
- if( nwp = (struct Wedge *)
- test_wedge(*(ULONG *)(&owp->wedge_Vectors[18]))
- )
- {
- nwp->wedge_Library.lib_Node.ln_Pred = pred;
- }
-
- /* does the previous library point to this wedge's library */
-
- if(pred->lib_Node.ln_Succ == &owp->wedge_Library)
- {
- /* yes, make previous library point to next wedge's library */
-
- pred->lib_Node.ln_Succ == &nwp->wedge_Library;
- }
-
- /* make previous vector point to next vector */
-
- SetFunction( wp->wedge_Library.lib_Node.ln_Pred,
- wp->wedge_Offset,
- *(ULONG *)(&wp->wedge_Vectors[18]));
-
- /* now the wedge is delinked... */
- }
- else
- {
- /* wedge not validated... */
- /* assume that has been setfunction'ed away, */
- /* and may be setfunction'ed back in the near future: */
- /* install default function, if wedge not in use */
-
- if(wp->wedge_Library.lib_OpenCnt == 0)
- {
- wp->wedge_Vectors[7] = JSR_dPC;
- wp->wedge_Vectors[8] = 0x0004;
- wp->wedge_Vectors[9] = RTS;
- }
- }
-
- /* suprises ok now, i guess... */
-
- Enable();
- }
-
- return((ULONG)owp);
- }
-
- install_wedge(lib,offset,entry)
- struct Library *lib;
- WORD offset;
- ULONG entry;
- {
- struct Wedge *wp = NULL;
-
- if( (entry) && (wp = (struct Wedge *)new_wedge()) )
- {
- /* prevent unpleasant suprises */
-
- Disable();
-
- /* point this wedge at our new entry */
-
- wp->wedge_Vectors[7] = JSR_ABS;
- *(ULONG *)(&wp->wedge_Vectors[8]) = entry;
-
- /* point this wedge at the previous entry */
-
- wp->wedge_Library.lib_Node.ln_Pred = lib;
- wp->wedge_Offset = offset;
-
- /* link this wedge to existing wedge? */
-
- wp->wedge_Library.lib_Node.ln_Succ =
- (struct Node *) link_wedge(lib,offset,wp);
-
- /* install this wedge in place of the old entry */
-
- wp->wedge_Vectors[17] = JMP_ABS;
- *(ULONG *)(&wp->wedge_Vectors[18]) = SetFunction(lib,offset,wp);
-
- /* suprises ok now, i guess... */
-
- Enable();
- }
-
- return((ULONG)wp);
- }
-
- remove_wedge(wedge)
- struct Wedge *wedge;
- {
- delink_wedge(wedge);
- dispose_wedge(wedge);
- }
-
-