mirror of https://github.com/weiju/amiga-stuff
209 lines
7.7 KiB
C
209 lines
7.7 KiB
C
#include <exec/types.h>
|
|
#include <exec/memory.h>
|
|
#include <exec/libraries.h>
|
|
#include <exec/execbase.h>
|
|
#include <exec/resident.h>
|
|
#include <exec/initializers.h>
|
|
|
|
#include <proto/exec.h> // all other compilers
|
|
#include "compiler.h"
|
|
|
|
#include "include/example/examplebase.h"
|
|
#include "libfuncs.h"
|
|
|
|
extern ULONG L_OpenLibs(struct ExampleBase *ExampleBase);
|
|
extern void L_CloseLibs(void);
|
|
|
|
struct ExampleBase *InitLib(register __a6 struct ExecBase *sysbase,
|
|
register __a0 SEGLISTPTR seglist,
|
|
register __d0 struct ExampleBase *exb);
|
|
struct ExampleBase *OpenLib(register __a6 struct ExampleBase *ExampleBase);
|
|
SEGLISTPTR CloseLib(register __a6 struct ExampleBase *ExampleBase);
|
|
SEGLISTPTR ExpungeLib(register __a6 struct ExampleBase *exb);
|
|
ULONG ExtFuncLib(void);
|
|
|
|
extern APTR FuncTab[];
|
|
extern DataTab;
|
|
|
|
struct InitTable /* do not change */
|
|
{
|
|
ULONG LibBaseSize;
|
|
APTR *FunctionTable;
|
|
struct MyDataInit *DataTable;
|
|
APTR InitLibTable;
|
|
};
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
! LibStart:
|
|
!
|
|
! If someone tries to start a library as an executable, it must return (LONG) -1
|
|
! as result. That's what we are doing here.
|
|
---------------------------------------------------------------------------------------- */
|
|
|
|
LONG LibStart(void) { return -1; }
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
! Function and Data Tables:
|
|
!
|
|
! The function and data tables have been placed here for traditional reasons.
|
|
! Placing the RomTag structure before (-> LibInit.c) would also be a good idea,
|
|
! but it depends on whether you would like to keep the "version" stuff separately.
|
|
---------------------------------------------------------------------------------------- */
|
|
|
|
struct InitTable InitTab = {
|
|
(ULONG) sizeof(struct ExampleBase),
|
|
(APTR *) &FuncTab[0],
|
|
(struct MyDataInit *) &DataTab,
|
|
(APTR) InitLib
|
|
};
|
|
|
|
APTR FuncTab[] = {
|
|
(APTR) OpenLib,
|
|
(APTR) CloseLib,
|
|
(APTR) ExpungeLib,
|
|
(APTR) ExtFuncLib,
|
|
|
|
(APTR) EXF_TestRequest, /* add your own functions here */
|
|
(APTR) ((LONG)-1)
|
|
};
|
|
|
|
extern struct ExampleBase *ExampleBase;
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
! InitLib:
|
|
!
|
|
! This one is single-threaded by the Ramlib process. Theoretically you can do, what
|
|
! you like here, since you have full exclusive control over all the library code and data.
|
|
! But due to some bugs in Ramlib V37-40, you can easily cause a deadlock when opening
|
|
! certain libraries here (which open other libraries, that open other libraries, that...)
|
|
!
|
|
---------------------------------------------------------------------------------------- */
|
|
|
|
struct ExampleBase *InitLib(register __a6 struct ExecBase *sysbase,
|
|
register __a0 SEGLISTPTR seglist,
|
|
register __d0 struct ExampleBase *exb)
|
|
{
|
|
ExampleBase = exb;
|
|
ExampleBase->exb_SysBase = sysbase;
|
|
ExampleBase->exb_SegList = seglist;
|
|
|
|
if (L_OpenLibs(ExampleBase)) return ExampleBase;
|
|
|
|
L_CloseLibs();
|
|
|
|
{
|
|
ULONG negsize, possize, fullsize;
|
|
UBYTE *negptr = (UBYTE *) ExampleBase;
|
|
|
|
negsize = ExampleBase->exb_LibNode.lib_NegSize;
|
|
possize = ExampleBase->exb_LibNode.lib_PosSize;
|
|
fullsize = negsize + possize;
|
|
negptr -= negsize;
|
|
|
|
FreeMem(negptr, fullsize);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
! OpenLib:
|
|
!
|
|
! This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since a Wait() call
|
|
! would break this Forbid/Permit(), you are not allowed to start any operations that
|
|
! may cause a Wait() during their processing. It's possible, that future OS versions
|
|
! won't turn the multi-tasking off, but instead use semaphore protection for this
|
|
! function.
|
|
!
|
|
! Currently you only can bypass this restriction by supplying your own semaphore
|
|
! mechanism.
|
|
---------------------------------------------------------------------------------------- */
|
|
|
|
struct ExampleBase *OpenLib(register __a6 struct ExampleBase *ExampleBase)
|
|
{
|
|
ExampleBase->exb_LibNode.lib_OpenCnt++;
|
|
ExampleBase->exb_LibNode.lib_Flags &= ~LIBF_DELEXP;
|
|
return ExampleBase;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
! CloseLib:
|
|
!
|
|
! This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since a Wait() call
|
|
! would break this Forbid/Permit(), you are not allowed to start any operations that
|
|
! may cause a Wait() during their processing. It's possible, that future OS versions
|
|
! won't turn the multi-tasking off, but instead use semaphore protection for this
|
|
! function.
|
|
!
|
|
! Currently you only can bypass this restriction by supplying your own semaphore
|
|
! mechanism.
|
|
---------------------------------------------------------------------------------------- */
|
|
|
|
SEGLISTPTR CloseLib(register __a6 struct ExampleBase *ExampleBase)
|
|
{
|
|
ExampleBase->exb_LibNode.lib_OpenCnt--;
|
|
|
|
if (!ExampleBase->exb_LibNode.lib_OpenCnt) {
|
|
if (ExampleBase->exb_LibNode.lib_Flags & LIBF_DELEXP) {
|
|
return ExpungeLib(ExampleBase);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
! ExpungeLib:
|
|
!
|
|
! This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since a Wait() call
|
|
! would break this Forbid/Permit(), you are not allowed to start any operations that
|
|
! may cause a Wait() during their processing. It's possible, that future OS versions
|
|
! won't turn the multi-tasking off, but instead use semaphore protection for this
|
|
! function.
|
|
!
|
|
! Currently you only could bypass this restriction by supplying your own semaphore
|
|
! mechanism - but since expunging can't be done twice, one should avoid it here.
|
|
---------------------------------------------------------------------------------------- */
|
|
|
|
SEGLISTPTR ExpungeLib(register __a6 struct ExampleBase *exb)
|
|
{
|
|
struct ExampleBase *ExampleBase = exb;
|
|
SEGLISTPTR seglist;
|
|
|
|
if (!ExampleBase->exb_LibNode.lib_OpenCnt) {
|
|
ULONG negsize, possize, fullsize;
|
|
UBYTE *negptr = (UBYTE *) ExampleBase;
|
|
|
|
seglist = ExampleBase->exb_SegList;
|
|
Remove((struct Node *)ExampleBase);
|
|
L_CloseLibs();
|
|
|
|
negsize = ExampleBase->exb_LibNode.lib_NegSize;
|
|
possize = ExampleBase->exb_LibNode.lib_PosSize;
|
|
fullsize = negsize + possize;
|
|
negptr -= negsize;
|
|
|
|
FreeMem(negptr, fullsize);
|
|
return seglist;
|
|
}
|
|
|
|
ExampleBase->exb_LibNode.lib_Flags |= LIBF_DELEXP;
|
|
return NULL;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
! ExtFunct:
|
|
!
|
|
! This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since a Wait() call
|
|
! would break this Forbid/Permit(), you are not allowed to start any operations that
|
|
! may cause a Wait() during their processing. It's possible, that future OS versions
|
|
! won't turn the multi-tasking off, but instead use semaphore protection for this
|
|
! function.
|
|
!
|
|
! Currently you only can bypass this restriction by supplying your own semaphore
|
|
! mechanism - but since this function currently is unused, you should not touch
|
|
! it, either.
|
|
---------------------------------------------------------------------------------------- */
|
|
|
|
ULONG ExtFuncLib(void) { return NULL; }
|
|
|
|
struct ExampleBase *ExampleBase = NULL;
|