Call Library

From Freepascal Amiga wiki
Jump to: navigation, search

How to call a library function:

As Example the AddTail function of the Exec.library. First you need the parameter line and the offset of the function in the library both you can find in the includes of the Amiga system. Take care with other libraries the Base must be open before using, ExecBase is an exception its always open to the program and accessible via AOS_ExecBase

AROS (i386, x86_64)

AddTail you can find in Includes/clib/exec_protos.h

  AROS_LP2(void, AddTail,
         AROS_LPA(struct List *, list, A0),
         AROS_LPA(struct Node *, node, A1),
         LIBBASETYPEPTR, SysBase, 41, Exec

This means its has 2 parameters (LP2),no return value (void) so its a procedure, the name is AddTail first parameter is a Pointer to a List (Pascal its a PList) with name list and so on. Most important the Library Base (SysBase = ExecBase) and Offset = 41. Now we bring all this together to our syscall function in pascal

  procedure AddTail(list: PList; Node: PNode); syscall AOS_ExecBase 41;

Now this Library function can be used all over freepascal.

Amiga (m68k), MorphOS

AddTail you can find in Includes/inline/exec.h

  AddTail(list, node) \
         LP2NR(0xf6, AddTail, struct List *, list, A0, struct Node *, node, A1, \
         , EXEC_BASE_NAME)

This means its has 2 parameters (LP2NR), the name is AddTail first parameter is a Pointer to a List (Pascal its a PList) with name list and so on. Most important the Library Base (EXEC_BASE_NAME) and Offset: 0xf6 = 246. Now we bring all this together to our syscall function in pascal:

  procedure AddTail(list: PList location 'a0'; Node: PNode location 'a1'); syscall AOS_ExecBase 246;

Now this Library function can be used all over freepascal.

AmigaOS4 (powerpc)

AddTail you can find in include_h/interfaces/exec.h

struct ExecIFace
{
	struct InterfaceData Data;

	ULONG APICALL (*Obtain)(struct ExecIFace *Self);
// ...
        void APICALL (*AddTail)(struct ExecIFace *Self, struct List * list, struct Node * node);
};

From this entry we can read the return value (void) so its a procedure and the parameter, the first parameter is always the interface self, this will be added by the syscall automtically, so we can ignore it. Most tricky problem is the needed offset. You have to count the position in this structure. The first field Data (struct InterfaceData) has a size of 60 bytes. so the first function Entry (it is always Obtain) has the Offset 60. You have to count every function entry in the list. Every entry is a function Pointer and we are on a 32 Bit processor every Entry adds 4 bytes to the Offset. AddTail is the 8th function entry (starting from 1) which results in an Offset of 60 + 4 * (8-1) = 88 for AddTail. AmigaOS4 uses Interfaces instead of the LibBase to make the function jumps. Currently there is no direct support for Interfaces in freepascal. The syscalls can be used in the same way as on the other platforms, because the the function offsets are exactly the same relative to the interface as relative to the libbase for the other platforms. The only thing you should remember is that you need to open the 'main' interface of the library and supply this Pointer as the Base for Syscalls.

Now we bring all this together to our syscall function in pascal:

  procedure AddTail(list: PList; Node: PNode); syscall IExec 88;

Now this Library function can be used all over freepascal.