added the libraries subproject

This commit is contained in:
Wei-ju Wu 2016-06-15 10:33:09 -07:00
parent 9b22fcb802
commit 7f15fd6575
20 changed files with 609 additions and 1 deletions

@ -1 +0,0 @@
Subproject commit 17481696faee8126a032f4263b00757a9468200a

1
libraries/example_lib/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.o

View File

@ -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 $@ $^

View File

@ -0,0 +1,24 @@
#include <exec/types.h>
#include <exec/memory.h>
#include <example/example.h>
#include <proto/exec.h>
#include <proto/example.h>
#include <stdio.h>
#include <stdlib.h>
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);
}

View File

@ -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) $^

View File

@ -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 */

View File

@ -0,0 +1,4 @@
#ifndef EXAMPLE_EXAMPLE_H
#define EXAMPLE_EXAMPLE_H
#endif /* EXAMPLE_EXAMPLE_H */

View File

@ -0,0 +1,17 @@
#ifndef EXAMPLE_EXAMPLEBASE_H
#define EXAMPLE_EXAMPLEBASE_H
#ifndef EXEC_LIBRARIES
#include <exec/libraries.h>
#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 */

View File

@ -0,0 +1,36 @@
#include <exec/types.h>
#include <exec/memory.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <intuition/intuition.h>
#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);
}

View File

@ -0,0 +1,4 @@
#include "compiler.h"
extern ULONG EXF_TestRequest(register __d1 UBYTE *title_d1, register __d2 UBYTE *body,
register __d3 UBYTE *gadgets);

View File

@ -0,0 +1,127 @@
#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>
#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);
}

View File

@ -0,0 +1,208 @@
#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;

View File

@ -0,0 +1,5 @@
##base _ExampleBase
##bias 30
##public
EXF_TestRequest(title,body,gadgets)(D1/D2/D3)
##end

View File

@ -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 <example/example.h>
#endif /* EXAMPLE_EXAMPLE_H */
ULONG EXF_TestRequest( UBYTE *title, UBYTE *body, UBYTE *gadgets);
#endif /* CLIB_EXAMPLE_PROTOS_H */

View File

@ -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 */

View File

@ -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 <exec/libraries.h>
#endif
#else
#ifndef EXEC_LIBRARIES
#include <exec/libraries.h>
#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 */

View File

@ -0,0 +1,19 @@
#ifndef _INCLUDE_PRAGMA_EXAMPLE_LIB_H
#define _INCLUDE_PRAGMA_EXAMPLE_LIB_H
#ifndef CLIB_EXAMPLE_PROTOS_H
#include <clib/Example_protos.h>
#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 */

View File

@ -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 */

View File

@ -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 <clib/example_protos.h>
#include <pragmas/example_pragmas.h>
#endif /* PROTO_EXAMPLE_H */

View File

@ -0,0 +1,11 @@
#include <exec/libraries.h>
#define SEGLISTPTR APTR
#include "example/examplebase.h"
#include <stdio.h>
int main(int argc, char **argv)
{
printf("ExampleBase size: %d\n", (int) sizeof(struct ExampleBase));
return 0;
}