home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * TESTLIB.C
- *
- * Example fully working library for Aztec C ... with comments (which is
- * a miracle in itself). By Matthew Dillon. PUBLIC DOMAIN.
- *
- * Aztec Compile with +BCDL
- * +B No startup reference
- * +C Large code
- * +D Large data
- * +L 32 bit Integers
- *
- * Since Original release, the following has been fixed:
- * -slight bug in LibClose() .. did not expunge library if DELEXP set
- * on final close. (thanks to Rico Mariani for finding the bug)
- * -Now uses MakeLibrary call rather than a hardwired Library structure.
- */
-
- #asm
- ; RLIB.ASM
- ;
- ; Run-time library tag
-
- FAR code
- FAR data
-
- public _CInit
- public _LibOpen
- public _LibClose
- public _LibExpunge
-
- Start: clr.l D0
- rts
-
- InitDesc: dc.w $4AFC ;RTC_MATCHWORD
- dc.l InitDesc ;Pointer to beginning
- dc.l EndCode ;Note sure it matters
- dc.b 0 ;flags (NO RTF_AUTOINIT)
- dc.b 0 ;version
- dc.b 9 ;NT_LIBRARY
- dc.b 0 ;priority (doesn't matter)
- dc.l _Libname ;Name of library
- dc.l _Libid ;ID string (note CR-LF at end)
- dc.l Init ;Pointer to init routine
-
- _Libname: dc.b "testlib.library",0
- _Libid: dc.b "testlib.library 1.0 (02 Oct 1987)",13,10,0
- EndCode:
-
- Init: move.l A6,-(sp) ;Must save A6
- move.l A0,-(sp) ;Segment list
- jsr _CInit
- addq.l #4,sp
- move.l (sp)+,A6
- rts
-
- cifc macro
- move.l D0,-(sp) ;Make a C call and save A6 to boot
- move.l A6,-(sp)
- jsr \1
- move.l (sp)+,A6
- addq.l #4,sp
- rts
- endm
-
- _ALibOpen: cifc _LibOpen
- _ALibClose: cifc _LibClose
- _ALibExpunge: cifc _LibExpunge
-
- #endasm
-
- extern char Libname[1];
- extern char Libid[1];
-
- extern long ALibExpunge(), ALibClose(), ALibOpen();
- extern long Lib_Add(), Lib_Sub();
-
- typedef struct Library LIB;
-
- LIB *Lib; /* Library Base pointer */
- long Seglist; /* Save the DOS seglist */
-
- extern LIB *MakeLibrary();
- extern void *AllocMem();
-
- /*
- * The Initialization routine is given only a seglist pointer. Since
- * we are NOT AUTOINIT we must construct and add the library ourselves
- * and return either NULL or the library pointer. Exec has Forbid()
- * for us during the call.
- *
- * If you have an extended library structure you must specify the size
- * of the extended structure in MakeLibrary().
- */
-
- LIB *
- CInit(segment)
- {
- extern long SysBase;
- static long (*Vectors[])() = {
- ALibOpen,ALibClose,ALibExpunge,NULL,
- Lib_Add, Lib_Sub, (long (*)())-1
- };
-
- SysBase = *(long *)4;
- Lib = MakeLibrary(Vectors,NULL,NULL,sizeof(LIB),NULL);
- Lib->lib_Node.ln_Type = NT_LIBRARY;
- Lib->lib_Node.ln_Name = Libname;
- Lib->lib_Flags = LIBF_CHANGED|LIBF_SUMUSED;
- Lib->lib_Version = 0;
- Lib->lib_Revision = 0;
- Lib->lib_IdString = (APTR)Libid;
- Seglist = segment;
- AddLibrary(Lib);
- return(Lib);
- }
-
- /*
- * Open is given the library pointer and the version request. Either
- * return the library pointer or NULL. Remove the DELAYED-EXPUNGE flag.
- * Exec has Forbid() for us during the call.
- */
-
- LIB *
- LibOpen(lib,version)
- LIB *lib;
- {
- ++lib->lib_OpenCnt;
- lib->lib_Flags &= ~LIBF_DELEXP;
- return(lib);
- }
-
- /*
- * Close is given the library pointer and the version request. Be sure
- * not to decrement the open count if already zero. If the open count
- * is or becomes zero AND there is a LIBF_DELEXP, we expunge the library
- * and return the seglist. Otherwise we return NULL.
- *
- * Note that this routine never sets LIBF_DELEXP on its own.
- *
- * Exec has Forbid() for us during the call.
- */
-
- LibClose(lib)
- LIB *lib;
- {
- if (lib->lib_OpenCnt && --lib->lib_OpenCnt)
- return(NULL);
- if (lib->lib_Flags & LIBF_DELEXP)
- return(LibExpunge(lib));
- return(NULL);
- }
-
- /*
- * We expunge the library and return the Seglist ONLY if the open count
- * is zero. If the open count is not zero we set the DELAYED-EXPUNGE
- * flag and return NULL.
- *
- * Exec has Forbid() for us during the call. NOTE ALSO that Expunge
- * might be called from the memory allocator and thus we CANNOT DO A
- * Wait() or otherwise take a long time to complete (straight from RKM).
- *
- * Apparently RemLibrary(lib) calls our expunge routine and would
- * therefore freeze if we called it ourselves. As far as I can tell
- * from RKM, LibExpunge(lib) must remove the library itself as shown
- * below.
- */
-
- LibExpunge(lib)
- LIB *lib;
- {
- if (lib->lib_OpenCnt) {
- lib->lib_Flags |= LIBF_DELEXP;
- return(NULL);
- }
- Remove(lib);
- FreeMem((char *)lib-lib->lib_NegSize, lib->lib_NegSize+lib->lib_PosSize);
- return(Seglist);
- }
-
- /*
- * The Library routines themselves. Note that we must also save A6 if
- * any library routine makes a library call to another library. These
- * examples do not and thus you can remove the #asm statements in them if
- * you wish... just DON'T FORGET!
- *
- * The reason A6 must be saved is that Aztec library interface routines
- * (e.g. FindTask(), OpenWindow(), etc....) trash A6 on purpose to make
- * the interface routine faster.
- *
- * D2 and D3 are automatically saved/restored via the +p compile option
- * A0,A1,D0,D1 are always scratch. In an assembly interface, these might
- * also contain arguments... but they are still scratch.
- */
-
- Lib_Add(n)
- {
- #asm
- move.l A6,-(sp)
- #endasm
-
- ++n; /* do stuff here */
-
- #asm
- move.l (sp)+,A6
- #endasm
- return(n);
- }
-
- Lib_Sub(n)
- {
- #asm
- move.l A6,-(sp)
- #endasm
-
- --n; /* do stuff here */
-
- #asm
- move.l (sp)+,A6
- #endasm
- return(n);
- }
-
-
-