English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 03 August 2021, 15:12   #1
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Amiga library in high-level language

Are there any example codes of an Amiga library written in a high-level language? (Preferably C, but actually any.) I've found only two examples on the net (#1, #2) and both of them are assembly examples.

Edit: Okay, never mind, google did not throw this out...
TCH is offline  
Old 03 August 2021, 19:57   #2
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
I am trying to understand what this stuff does, how it does it and why, but the internal documentations are insufficient...

For example, here is the base
struct
of the example library:
Code:
struct ExampleBase
{
 struct Library         exb_LibNode;
 SEGLISTPTR             exb_SegList;
 struct ExecBase       *exb_SysBase;
 struct IntuitionBase  *exb_IntuitionBase;
 struct GfxBase        *exb_GfxBase;
};
Is there any documentation about what should be inside in this structure? I guess the pointers to the bases of intuition and graphics libraries are not mandatory, but the example library uses them, so it needs to store them.

Then there are the opener and closer functions:
Code:
ULONG __saveds __stdargs L_OpenLibs(struct ExampleBase *ExampleBase);
void  __saveds __stdargs L_CloseLibs(void);
Are
__saveds
and
__stdargs
mandatory for them; i mean an Amiga library has to have a near data section and it has to use the stack for arguments? (The closer function does not even has any arguments.)
TCH is offline  
Old 03 August 2021, 22:54   #3
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by TCH View Post
Is there any documentation about what should be inside in this structure?
The
struct Library
at the beginning is mandatory, as it describes your library. The rest of the structure is filled by data your library code needs.

Quote:
__saveds
and
__stdargs
mandatory for them;
I haven't seen your example library source. It probably uses a small data base register? Then you absolutely need
__saveds
, because your library code is called by other tasks which have not set up the base register as needed. I see no need for
__stdargs
, though.

Quote:
i mean an Amiga library has to have a near data section and it has to use the stack for arguments?
No, it doesn't have to use near data. Best is if your library has no data or bss sections at all. Preferably allocate your data in the library base structure.
Library functions always pass their arguments in registers.
phx is offline  
Old 03 August 2021, 23:48   #4
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Quote:
Originally Posted by phx View Post
The
struct Library
at the beginning is mandatory, as it describes your library. The rest of the structure is filled by data your library code needs.
Even the seglist is optional?
Quote:
Originally Posted by phx View Post
I haven't seen your example library source.
It's here.
Quote:
Originally Posted by phx View Post
It probably uses a small data base register? Then you absolutely need
__saveds
, because your library code is called by other tasks which have not set up the base register as needed. I see no need for
__stdargs
, though.
I see, thanks. How do i know if it does use small data base in C? Is there a macro for it? Or C just do that?
Quote:
Originally Posted by phx View Post
No, it doesn't have to use near data. Best is if your library has no data or bss sections at all. Preferably allocate your data in the library base structure.
Got, it, thank you.
Quote:
Originally Posted by phx View Post
Library functions always pass their arguments in registers.
In that case i see no reason for using
__stdargs
either, but then why does this library use it?
TCH is offline  
Old 04 August 2021, 03:06   #5
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
There is also this one:

https://github.com/bebbo/libnix/blob...es/simplelib.c

Compiles with:
m68k-amigaos-gcc -nostdlib -O3 -fomit-frame-pointer -fbaserel /opt/amiga/gcc6/m68k-amigaos/libnix/lib/libinit.o simplelib.c

(change the path to libinit.o according to your gcc prefix)

Haven't actually tested it. Disassembled executable looks fine at first glance.
alkis is offline  
Old 04 August 2021, 07:56   #6
Steady
Registered User
 
Join Date: May 2021
Location: Melbourne, Australia
Posts: 40
Don't worry too much about the fields that follow struct Library. They are for use by whatever library you are creating to store variables that the library might need to access, regardless of the application that opens the library and calls a function.

In particular, don't worry about the seglist. Unless you need to use seglist for some reason (and you will know if you do) then you can get rid of it.

The SysBase, IntuitionBase and GfxBase fields are so that your library can open the libraries it needs to use and store the base there so it can be accessed at any time you need. This takes the burden of opening and closing those libraries away from the caller (application), mostly because without clairvoyance how can the caller of a function know for sure which resources your library code needs now or in the future. Just be aware that you need to make provisions for accessing those library base variables instead of globals that are usually used for applications. This differs between C compilers. In assembler, just load the base into A6 and call in the usual way.

You can add any variable your library needs here which is accessed as a positive offset of your library's base address (you get it in register A6 when called).

Just be careful to restrict the globals to those values you need for the library itself, rather than support for the functions you provide. Your library functions should allocate values on the stack or in registers as applicable.

Good luck!

Last edited by Steady; 04 August 2021 at 07:57. Reason: clarity
Steady is offline  
Old 04 August 2021, 09:02   #7
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
@alkis: Thanks, but this one is libnix-dependent and
stabs.h
is full of assembly macros and i would like to make a pure C-based Amiga library.

@Steady: Thanks, that shed some light on a few things. But what the seglist is for? When i'll need it?
TCH is offline  
Old 04 August 2021, 15:21   #8
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
If you are using amiga-gcc you might also check https://github.com/bebbo/example.library
bebbo is offline  
Old 04 August 2021, 17:12   #9
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
Quote:
Originally Posted by TCH View Post
@Steady: Thanks, that shed some light on a few things. But what the seglist is for? When i'll need it?
You collect it in your LibInit() function, and return it as result code in LibExpunge() if your library can be removed from memory. It is the segment list that consists of your code, and it will be unloaded by dos if the library is supposed to be flushed from memory.
Thomas Richter is offline  
Old 04 August 2021, 17:20   #10
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
Quote:
Originally Posted by Steady View Post
In particular, don't worry about the seglist. Unless you need to use seglist for some reason (and you will know if you do) then you can get rid of it.
Heck, no! The seglist you need to cleanly remove your library from memory, see separate reply.


Quote:
Originally Posted by Steady View Post
The SysBase, IntuitionBase and GfxBase fields are so that your library can open the libraries it needs to use and store the base there so it can be accessed at any time you need.
Whether a library needs them is another question. SysBase you most likely do need, and it is better to get it through the library base than through AbsExecBase.


Quote:
Originally Posted by Steady View Post

This takes the burden of opening and closing those libraries away from the caller (application), mostly because without clairvoyance how can the caller of a function know for sure which resources your library code needs now or in the future.
Well, it is up to *your* library to open them if *your* library code needs them. Whether the caller code needs them is another question, but if so, the caller needs to open them, too. It is bad practise to "steal" library base pointers from another library.


Quote:
Originally Posted by Steady View Post


Just be aware that you need to make provisions for accessing those library base variables instead of globals that are usually used for applications. This differs between C compilers. In assembler, just load the base into A6 and call in the usual way.
This is compiler dependent. If you compile with SAS/C and LibCode, the compiler will be smart enough to store all your "globals" (actually, objects with external linkage) in the library base, and will access them through the library base. Other compilers may be less smart, and you may need to fiddle them then through the library base yourself.


Some care should be taken in designing LibOpen, LibClose and LibExpunge. LibInit() is usually called through RamLib, and thus can do a lot of things, then through ramlib, including activities that break a Forbid(). LibOpen(), LibClose() and LibExpunge() are called in the context of the task using the library, and under Forbid() state.



While there are ways around it, it is advisable (at those for those unexperienced with the pitalls of AmigaOs) to avoid any calls in these functions that may potentially break a Forbid() state. Such as opening other libraries, obtaining semaphores or performing I/O. Any such things should better happen in LibInit() where it is well-isolated from the rest of the system through ramlib.


Note that this changed in Kick 2.0, in Kick 1.3 it is even trickier.
Thomas Richter is offline  
Old 04 August 2021, 21:26   #11
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Quote:
Originally Posted by bebbo View Post
If you are using amiga-gcc you might also check https://github.com/bebbo/example.library
Thank you, this looks promising and simple enough for easy understanding. Although i have to ask, what is the "magic" part responsible for? I see, that it is a function array, but what purpose it does serve and why is that magical? That's the jump table for AmigaOS?
Yes, i do use amiga-gcc for development, but i also would like to support SAS/C and VBCC.
Quote:
Originally Posted by Thomas Richter View Post
You collect it in your LibInit() function, and return it as result code in LibExpunge() if your library can be removed from memory. It is the segment list that consists of your code, and it will be unloaded by dos if the library is supposed to be flushed from memory.
I am trying to understand this...so the seglist is essentially a pointer which points to the library's code segment and when the last program/library/handler/device/whatever closes the library, then DOS will call a "free" on it?
Quote:
Originally Posted by Thomas Richter View Post
Whether a library needs them is another question. SysBase you most likely do need, and it is better to get it through the library base than through AbsExecBase.
So, the
SysBase
is not mandatory, but highly recommended?
TCH is offline  
Old 04 August 2021, 22:31   #12
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by bebbo View Post
If you are using amiga-gcc you might also check https://github.com/bebbo/example.library
Since this is missing a makefile....what's the build invocation?
alkis is offline  
Old 04 August 2021, 22:54   #13
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by alkis View Post
Since this is missing a makefile....what's the build invocation?

Oh - it's an Eclipse project :-)

this should do it

m68k-amigaos-gcc -nostartfiles -o "example.library" alibrary.c myfx.c -Os

specify alibrary.c as the first file
bebbo is offline  
Old 05 August 2021, 02:13   #14
Steady
Registered User
 
Join Date: May 2021
Location: Melbourne, Australia
Posts: 40
Never mind. I had misremembered about the seglist and it is supplied by LibInit() as written by Thomas above. Apologies.

Last edited by Steady; 05 August 2021 at 03:30.
Steady is offline  
Old 05 August 2021, 06:46   #15
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
Quote:
Originally Posted by TCH View Post
Although i have to ask, what is the "magic" part responsible for? I see, that it is a function array, but what purpose it does serve and why is that magical?
The resident structure is required for the system to initialize the library, and the function array it points (indirectly) to is used to setup the trampoline functions to your library entries.


Quote:
Originally Posted by TCH View Post
That's the jump table for AmigaOS?
That, plus version information.


Quote:
Originally Posted by TCH View Post

so the seglist is essentially a pointer which points to the library's code segment and when the last program/library/handler/device/whatever closes the library, then DOS will call a "free" on it?
Yes, except that it is a BPTR (not a C pointer) and the function to release the segments is called UnloadSeg(), not free.



Quote:
Originally Posted by TCH View Post


So, the
SysBase
is not mandatory, but highly recommended?
Nothing in the system forces you to keep a copy of SysBase in the library. If you make a copy elsewhere, that is also good. Just saying, accessing exec.library through a base pointer (either in your library, or elsewhere) is better than fetching its entry point through AbsExecBase every call. The latter is slow because accesses to AbsExecBase have to be emulated for some configurations, most notably if debugging tools like MuForce are running.
Thomas Richter is offline  
Old 06 August 2021, 10:07   #16
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Quote:
Originally Posted by Thomas Richter View Post
The resident structure is required for the system to initialize the library, and the function array it points (indirectly) to is used to setup the trampoline functions to your library entries.
How does the Amiga recognize that there is a jump table + version information? By some markers? There is a
void foo() {}
line in the code, i guess that compiles to a single
rts
; is that necessary for something, like marking something? There is also this part
Code:
// dunno
long LibExtFunc(void) {
	return 0;
}
What is this responsible for?
Quote:
Originally Posted by Thomas Richter View Post
Yes, except that it is a BPTR (not a C pointer) and the function to release the segments is called UnloadSeg(), not free.
I meant "free" in as generic memory-freeing, not explicitly
free()
, but thanks for clarifying.
Quote:
Originally Posted by Thomas Richter View Post
Nothing in the system forces you to keep a copy of SysBase in the library. If you make a copy elsewhere, that is also good. Just saying, accessing exec.library through a base pointer (either in your library, or elsewhere) is better than fetching its entry point through AbsExecBase every call. The latter is slow because accesses to AbsExecBase have to be emulated for some configurations, most notably if debugging tools like MuForce are running.
Got it, thanks.
TCH is offline  
Old 06 August 2021, 11:10   #17
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
Quote:
Originally Posted by TCH View Post
How does the Amiga recognize that there is a jump table + version information?
It scans the code for the resident tag. That is, the structure that starts with the magic word 0x4afc, and is followed by a pointer to itself. This structure is a "struct Resident" and documented in exec/resident.h.


The infromation therein is used by the InitResident() function call to create the library, which includes building the jump table.


LibExtFunc() is currently not at all in use, but please return 0 for forward compaibility. There are at least some plans to use it in future versions for some kind of "Gestalt" function that returns properties of the library (or device), in a much better way than NSD could.
Thomas Richter is offline  
Old 08 August 2021, 12:24   #18
TCH
Newbie Amiga programmer
 
TCH's Avatar
 
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
Thanks, now almost everything seems to be clear, but what is that
void foo() {}
?
Does that needed there at all?

Last edited by TCH; 08 August 2021 at 12:30.
TCH is offline  
Old 08 August 2021, 12:59   #19
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
I don't see what this should be good for.
Thomas Richter is offline  
Old 08 August 2021, 20:50   #20
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by TCH View Post
Thanks, now almost everything seems to be clear, but what is that
void foo() {}
?
Does that needed there at all?

a leftover from - I don't remember... :-)


I put it once together from here and there (e.g. libnix library example) and tried to make it as simple as possible to be used with amiga-gcc.


Now I also added a semaphore to really init the library only once and created __myinit/__myexit functions in a separate file.


I added a variant to provide a separate base per opener too... untested ;-)

Last edited by bebbo; 08 August 2021 at 22:13.
bebbo is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
High-level steps for dragging an image between 2 windows? Warty Coders. C/C++ 2 12 March 2021 18:43
Any functional language for the Amiga? hth313 Coders. C/C++ 2 28 April 2019 20:08
Is there a high level copperlist decoder program? kamelito Coders. Asm / Hardware 10 02 January 2018 21:56
Amiga C programming language Kenan support.Apps 3 25 June 2013 18:50
High-level Apps for SysSpeed tygre request.Apps 8 01 February 2013 05:11

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 08:22.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.15293 seconds with 13 queries