home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * LIBRARY.C
- *
- * Example fully working library for Aztec C ... with comments (which is
- * a miracle in itself). By Matthew Dillon. PUBLIC DOMAIN.
- *
- * Aztec Compile with +BCDLp
- * +B No startup reference
- * +C Large code
- * +D Large data
- * +L 32 bit Integers
- * +p compatibility mode (D2/D3 preserved)
- *
- * 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.
- */
-
- #define NULL 0L
-
- typedef struct Library LIB;
-
- extern LIB *MakeLibrary();
-
- #define VERSION 1 /* NOTE! String in dc.b below must also be */
- #define REVISION 3 /* Changed! */
-
- #asm
- VERSION equ 1
-
- ; RLIB.ASM
- ;
- ; Run-time library tag
-
- 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 VERSION ;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 "dres.library",0
- _Libid: dc.b "dres.library 1.3 (29 Sep 1988)",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
-
- __LibOpen: cifc _LibOpen
- __LibClose: cifc _LibClose
- __LibExpunge: cifc _LibExpunge
-
- #endasm
-
- extern char Libname[1];
- extern char Libid[1];
-
- LIB *Lib, *DResBase; /* Library Base pointer */
- long Seglist; /* Save the DOS seglist */
-
-
- /*
- * 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().
- */
-
- #include "libfuncs.h"
-
- LIB *
- CInit(segment)
- {
- extern long SysBase;
- extern long DOSBase;
-
- SysBase = *(long *)4;
- DOSBase = OpenLibrary("dos.library", 0);
- if (DOSBase == NULL)
- return(NULL);
- DResBase = Lib = MakeLibrary(LibVectors,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 = VERSION;
- Lib->lib_Revision = REVISION;
- 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;
- {
- extern long DOSBase;
-
- if (lib->lib_OpenCnt) {
- lib->lib_Flags |= LIBF_DELEXP;
- return(NULL);
- }
- if (DOSBase) {
- CloseLibrary(DOSBase);
- DOSBase = NULL;
- }
- Remove(lib);
- FreeMem((char *)lib-lib->lib_NegSize, lib->lib_NegSize+lib->lib_PosSize);
- return(Seglist);
- }
-
-