diff --git a/libraries/example_lib b/libraries/example_lib deleted file mode 160000 index 1748169..0000000 --- a/libraries/example_lib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 17481696faee8126a032f4263b00757a9468200a diff --git a/libraries/example_lib/.gitignore b/libraries/example_lib/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/libraries/example_lib/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/libraries/example_lib/Makefile b/libraries/example_lib/Makefile new file mode 100644 index 0000000..c874112 --- /dev/null +++ b/libraries/example_lib/Makefile @@ -0,0 +1,10 @@ +CC = vc +aos68k +CFLAGS = -Iexample/include -Iinclude -I$(NDK_INC) + +all: TestExampleLib + +clean: + rm -f *.o TestExampleLib + +TestExampleLib: TestExampleLib.c + $(CC) $(CFLAGS) -lamiga -o $@ $^ diff --git a/libraries/example_lib/TestExampleLib.c b/libraries/example_lib/TestExampleLib.c new file mode 100644 index 0000000..9612015 --- /dev/null +++ b/libraries/example_lib/TestExampleLib.c @@ -0,0 +1,24 @@ +#include +#include + +#include + +#include +#include + +#include +#include + +struct ExampleBase *ExampleBase = NULL; + +int main(int argc, char **argv) +{ + ExampleBase = (APTR) OpenLibrary("example.library", 37); + if (ExampleBase) { + EXF_TestRequest("Test Message", "It works!", "OK"); + CloseLibrary((APTR) ExampleBase); + exit(0); + } + printf("\nLibrary opening failed\n"); + exit(20); +} diff --git a/libraries/example_lib/example/Makefile b/libraries/example_lib/example/Makefile new file mode 100644 index 0000000..b8f5c06 --- /dev/null +++ b/libraries/example_lib/example/Makefile @@ -0,0 +1,23 @@ +CC = vc +aos68k +CFLAGS = -O2 -+ -I$(NDK_INC) -DVBCC -c +LDFLAGS = -nostdlib -lamiga +LDLIBS = + +OBJS = startup.o libinit.o libfuncs.o + +all: example.library + +clean: + rm -f *.o example.library + +example.library: $(OBJS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) + +startup.o: startup.c + $(CC) $(CFLAGS) $^ + +libinit.o: libinit.c + $(CC) $(CFLAGS) $^ + +libfuncs.o: libfuncs.c + $(CC) $(CFLAGS) $^ diff --git a/libraries/example_lib/example/compiler.h b/libraries/example_lib/example/compiler.h new file mode 100644 index 0000000..8a9369d --- /dev/null +++ b/libraries/example_lib/example/compiler.h @@ -0,0 +1,23 @@ +#ifndef COMPILER_H +#define COMPILER_H + +#define SEGLISTPTR APTR + +#define __d0 __reg("d0") +#define __d1 __reg("d1") +#define __d2 __reg("d2") +#define __d3 __reg("d3") +#define __d4 __reg("d4") +#define __d5 __reg("d5") +#define __d6 __reg("d6") +#define __d7 __reg("d7") +#define __a0 __reg("a0") +#define __a1 __reg("a1") +#define __a2 __reg("a2") +#define __a3 __reg("a3") +#define __a4 __reg("a4") +#define __a5 __reg("a5") +#define __a6 __reg("a6") +#define __a7 __reg("a7") + +#endif /* COMPILER_H */ diff --git a/libraries/example_lib/example/include/example/example.h b/libraries/example_lib/example/include/example/example.h new file mode 100644 index 0000000..3a106ab --- /dev/null +++ b/libraries/example_lib/example/include/example/example.h @@ -0,0 +1,4 @@ +#ifndef EXAMPLE_EXAMPLE_H +#define EXAMPLE_EXAMPLE_H + +#endif /* EXAMPLE_EXAMPLE_H */ diff --git a/libraries/example_lib/example/include/example/examplebase.h b/libraries/example_lib/example/include/example/examplebase.h new file mode 100644 index 0000000..3f05a54 --- /dev/null +++ b/libraries/example_lib/example/include/example/examplebase.h @@ -0,0 +1,17 @@ +#ifndef EXAMPLE_EXAMPLEBASE_H +#define EXAMPLE_EXAMPLEBASE_H + +#ifndef EXEC_LIBRARIES +#include +#endif /* EXEC_LIBRARIES_H */ + +struct ExampleBase +{ + struct Library exb_LibNode; + SEGLISTPTR exb_SegList; + struct ExecBase *exb_SysBase; + struct IntuitionBase *exb_IntuitionBase; + struct GfxBase *exb_GfxBase; +}; + +#endif /* EXAMPLE_EXAMPLEBASE_H */ diff --git a/libraries/example_lib/example/libfuncs.c b/libraries/example_lib/example/libfuncs.c new file mode 100644 index 0000000..c22b64c --- /dev/null +++ b/libraries/example_lib/example/libfuncs.c @@ -0,0 +1,36 @@ +#include +#include + +#include +#include +#include + +#include "compiler.h" + + /* Please note, that &ExampleBase always resides in register __a6 as well, + but if we don't need it, we need not reference it here. + + Also note, that registers a0, a1, d0, d1 always are scratch registers, + so you usually should only *pass* parameters there, but make a copy + directly after entering the function. To avoid problems of kind + "implementation defined behaviour", you should make a copy of A6 too, + when it is actually used. + + In this example case, scratch register saving would not have been necessary + (since there are no other function calls inbetween), but we did it nevertheless. + */ + +ULONG EXF_TestRequest(register __d1 UBYTE *title_d1, register __d2 UBYTE *body, + register __d3 UBYTE *gadgets) +{ + UBYTE *title = title_d1; + struct EasyStruct estr; + + estr.es_StructSize = sizeof(struct EasyStruct); + estr.es_Flags = NULL; + estr.es_Title = title; + estr.es_TextFormat = body; + estr.es_GadgetFormat = gadgets; + + return (ULONG) EasyRequestArgs(NULL, &estr, NULL, NULL); +} diff --git a/libraries/example_lib/example/libfuncs.h b/libraries/example_lib/example/libfuncs.h new file mode 100644 index 0000000..eb74a40 --- /dev/null +++ b/libraries/example_lib/example/libfuncs.h @@ -0,0 +1,4 @@ +#include "compiler.h" + +extern ULONG EXF_TestRequest(register __d1 UBYTE *title_d1, register __d2 UBYTE *body, + register __d3 UBYTE *gadgets); diff --git a/libraries/example_lib/example/libinit.c b/libraries/example_lib/example/libinit.c new file mode 100644 index 0000000..8465921 --- /dev/null +++ b/libraries/example_lib/example/libinit.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include + +#include +#include "compiler.h" +#include "include/example/examplebase.h" + +ULONG L_OpenLibs(struct ExampleBase *ExampleBase); +void L_CloseLibs(void); + +struct ExecBase *SysBase = NULL; +struct IntuitionBase *IntuitionBase = NULL; +struct GfxBase *GfxBase = NULL; + +#define VERSION 37 +#define REVISION 32 + +#define EXLIBNAME "example" +#define EXLIBVER " 37.32 (2.3.99)" + +char ExLibName [] = EXLIBNAME ".library"; +char ExLibID [] = EXLIBNAME EXLIBVER; +char Copyright [] = "(C)opyright 1996-99 by Andreas R. Kleinert. All rights reserved."; +char VERSTRING [] = "\0$VER: " EXLIBNAME EXLIBVER; + +/* ---------------------------------------------------------------------------------------- + ! ROMTag and Library initialization structure: + ! + ! Below you find the ROMTag, which is the most important "magic" part of a library + ! (as for any other resident module). You should not need to modify any of the + ! structures directly, since all the data is referenced from constants from somewhere else. + ! + ! You may place the ROMTag directly after the LibStart (-> StartUp.c) function as well. + ! + ! Note, that the data initialization structure may be somewhat redundant - it's + ! for demonstration purposes. + ! + ! EndResident can be placed somewhere else - but it must follow the ROMTag and + ! it must not be placed in a different SECTION. + ---------------------------------------------------------------------------------------- */ + +extern ULONG InitTab[]; +extern APTR EndResident; /* below */ + +struct Resident ROMTag = /* do not change */ +{ + RTC_MATCHWORD, + &ROMTag, + &EndResident, + RTF_AUTOINIT, + VERSION, + NT_LIBRARY, + 0, + &ExLibName[0], + &ExLibID[0], + &InitTab[0] +}; + +APTR EndResident; + +struct MyDataInit /* do not change */ +{ + UWORD ln_Type_Init; UWORD ln_Type_Offset; UWORD ln_Type_Content; + UBYTE ln_Name_Init; UBYTE ln_Name_Offset; ULONG ln_Name_Content; + UWORD lib_Flags_Init; UWORD lib_Flags_Offset; UWORD lib_Flags_Content; + UWORD lib_Version_Init; UWORD lib_Version_Offset; UWORD lib_Version_Content; + UWORD lib_Revision_Init; UWORD lib_Revision_Offset; UWORD lib_Revision_Content; + UBYTE lib_IdString_Init; UBYTE lib_IdString_Offset; ULONG lib_IdString_Content; + ULONG ENDMARK; +} DataTab = { + 0xe000, 8, NT_LIBRARY, + 0x0080, 10, (ULONG) &ExLibName[0], + 0xe000, 14, LIBF_SUMUSED|LIBF_CHANGED, + 0xd000, 20, VERSION, + 0xd000, 22, REVISION, + 0x80, 24, (ULONG) &ExLibID[0], + (ULONG) 0 +}; + +/* ---------------------------------------------------------------------------------------- + ! L_OpenLibs: + ! + ! Since this one is called by InitLib, libraries not shareable between Processes or + ! libraries messing with RamLib (deadlock and crash) may not be opened here. + ! + ! You may bypass this by calling this function fromout LibOpen, but then you will + ! have to a) protect it by a semaphore and b) make sure, that libraries are only + ! opened once (when using global library bases). + ---------------------------------------------------------------------------------------- */ + +ULONG L_OpenLibs(struct ExampleBase *ExampleBase) +{ + SysBase = (*((struct ExecBase **) 4)); + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37); + if(!IntuitionBase) return FALSE; + + GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 37); + if (!GfxBase) return FALSE; + + ExampleBase->exb_IntuitionBase = IntuitionBase; + ExampleBase->exb_GfxBase = GfxBase; + ExampleBase->exb_SysBase = SysBase; + + return TRUE; +} + +/* ---------------------------------------------------------------------------------------- + ! L_CloseLibs: + ! + ! This one by default is called by ExpungeLib, which only can take place once + ! and thus per definition is single-threaded. + ! + ! When calling this fromout LibClose instead, you will have to protect it by a + ! semaphore, since you don't know whether a given CloseLibrary(foobase) may cause a Wait(). + ! Additionally, there should be protection, that a library won't be closed twice. + ---------------------------------------------------------------------------------------- */ + +void L_CloseLibs(void) +{ + if (GfxBase) CloseLibrary((struct Library *) GfxBase); + if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase); +} diff --git a/libraries/example_lib/example/startup.c b/libraries/example_lib/example/startup.c new file mode 100644 index 0000000..7419f23 --- /dev/null +++ b/libraries/example_lib/example/startup.c @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include +#include + +#include // 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; diff --git a/libraries/example_lib/fd/example.fd b/libraries/example_lib/fd/example.fd new file mode 100644 index 0000000..e1c031c --- /dev/null +++ b/libraries/example_lib/fd/example.fd @@ -0,0 +1,5 @@ +##base _ExampleBase +##bias 30 +##public +EXF_TestRequest(title,body,gadgets)(D1/D2/D3) +##end diff --git a/libraries/example_lib/include/clib/example_protos.h b/libraries/example_lib/include/clib/example_protos.h new file mode 100644 index 0000000..55b5e31 --- /dev/null +++ b/libraries/example_lib/include/clib/example_protos.h @@ -0,0 +1,19 @@ +/* +** $VER: example_protos.h 37.1 (4.12.96) +** +** prototypes for example.library +** +** (C) Copyright 1996 Andreas R. Kleinert +** All Rights Reserved. +*/ + +#ifndef CLIB_EXAMPLE_PROTOS_H +#define CLIB_EXAMPLE_PROTOS_H + +#ifndef EXAMPLE_EXAMPLE_H +#include +#endif /* EXAMPLE_EXAMPLE_H */ + +ULONG EXF_TestRequest( UBYTE *title, UBYTE *body, UBYTE *gadgets); + +#endif /* CLIB_EXAMPLE_PROTOS_H */ diff --git a/libraries/example_lib/include/example/example.h b/libraries/example_lib/include/example/example.h new file mode 100644 index 0000000..f68cd01 --- /dev/null +++ b/libraries/example_lib/include/example/example.h @@ -0,0 +1,15 @@ +/* +** $VER: example.h 37.1 (4.12.96) +** +** main include file for example.library +** +** (C) Copyright 1996 Andreas R. Kleinert +** All Rights Reserved. +*/ + +#ifndef EXAMPLE_EXAMPLE_H +#define EXAMPLE_EXAMPLE_H + + /* nothing defined yet */ + +#endif /* EXAMPLE_EXAMPLE_H */ diff --git a/libraries/example_lib/include/example/examplebase.h b/libraries/example_lib/include/example/examplebase.h new file mode 100644 index 0000000..7aead29 --- /dev/null +++ b/libraries/example_lib/include/example/examplebase.h @@ -0,0 +1,32 @@ +/* +** $VER: examplebase.h 37.30 (7.3.98) +** +** definition of ExampleBase +** +** (C) Copyright 1996-98 Andreas R. Kleinert +** All Rights Reserved. +*/ + +#ifndef EXAMPLE_EXAMPLEBASE_H +#define EXAMPLE_EXAMPLEBASE_H + +#ifdef __MAXON__ +#ifndef EXEC_LIBRARIES_H +#include +#endif +#else +#ifndef EXEC_LIBRARIES +#include +#endif /* EXEC_LIBRARIES_H */ +#endif + +struct ExampleBase +{ + struct Library exb_LibNode; + SEGLISTPTR exb_SegList; + struct ExecBase *exb_SysBase; + struct IntuitionBase *exb_IntuitionBase; + struct GfxBase *exb_GfxBase; +}; + +#endif /* EXAMPLE_EXAMPLEBASE_H */ diff --git a/libraries/example_lib/include/pragma/example_lib.h b/libraries/example_lib/include/pragma/example_lib.h new file mode 100644 index 0000000..c64eace --- /dev/null +++ b/libraries/example_lib/include/pragma/example_lib.h @@ -0,0 +1,19 @@ +#ifndef _INCLUDE_PRAGMA_EXAMPLE_LIB_H +#define _INCLUDE_PRAGMA_EXAMPLE_LIB_H + +#ifndef CLIB_EXAMPLE_PROTOS_H +#include +#endif + +#if defined(AZTEC_C) || defined(__MAXON__) || defined(__STORM__) +#pragma amicall(ExampleBase,0x01E,EXF_TestRequest(d1,d2,d3)) +#endif +#if defined(_DCC) || defined(__SASC) +#pragma libcall ExampleBase EXF_TestRequest 01E 32103 +#endif +#ifdef __STORM__ +#endif +#ifdef __SASC_60 +#endif + +#endif /* _INCLUDE_PRAGMA_EXAMPLE_LIB_H */ \ No newline at end of file diff --git a/libraries/example_lib/include/pragmas/example_pragmas.h b/libraries/example_lib/include/pragmas/example_pragmas.h new file mode 100644 index 0000000..ad22f82 --- /dev/null +++ b/libraries/example_lib/include/pragmas/example_pragmas.h @@ -0,0 +1,15 @@ +/* +** $VER: example_pragmas.h 37.1 (4.12.96) +** +** pragmas for example.library +** +** (C) Copyright 1996 Andreas R. Kleinert +** All Rights Reserved. +*/ + +#ifndef PRAGMAS_EXAMPLE_H +#define PRAGMAS_EXAMPLE_H + +#pragma libcall ExampleBase EXF_TestRequest 1e 32103 + +#endif /* PRAGMAS_EXAMPLE_H */ diff --git a/libraries/example_lib/include/proto/example.h b/libraries/example_lib/include/proto/example.h new file mode 100644 index 0000000..08fa38d --- /dev/null +++ b/libraries/example_lib/include/proto/example.h @@ -0,0 +1,16 @@ +/* +** $VER: example.h 37.1 (4.12.96) +** +** prototype/pragma include for example.library +** +** (C) Copyright 1996 Andreas R. Kleinert +** All Rights Reserved. +*/ + +#ifndef PROTO_EXAMPLE_H +#define PROTO_EXAMPLE_H + +#include +#include + +#endif /* PROTO_EXAMPLE_H */ diff --git a/libraries/example_lib/testsize.c b/libraries/example_lib/testsize.c new file mode 100644 index 0000000..357f643 --- /dev/null +++ b/libraries/example_lib/testsize.c @@ -0,0 +1,11 @@ +#include + +#define SEGLISTPTR APTR +#include "example/examplebase.h" +#include + +int main(int argc, char **argv) +{ + printf("ExampleBase size: %d\n", (int) sizeof(struct ExampleBase)); + return 0; +}