home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d169
/
src
/
dres
/
core
/
library.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-11-22
|
5KB
|
194 lines
/*
* 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);
}