03 August 2021, 15:12 | #1 |
Newbie Amiga programmer
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... |
03 August 2021, 19:57 | #2 |
Newbie Amiga programmer
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 structof 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; }; Then there are the opener and closer functions: Code:
ULONG __saveds __stdargs L_OpenLibs(struct ExampleBase *ExampleBase); void __saveds __stdargs L_CloseLibs(void); __savedsand __stdargsmandatory 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.) |
03 August 2021, 22:54 | #3 | |||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
|
Quote:
struct Libraryat the beginning is mandatory, as it describes your library. The rest of the structure is filled by data your library code needs. Quote:
__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:
Library functions always pass their arguments in registers. |
|||
03 August 2021, 23:48 | #4 | |||
Newbie Amiga programmer
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
|
Quote:
Quote:
Quote:
In that case i see no reason for using __stdargseither, but then why does this library use it? |
|||
04 August 2021, 03:06 | #5 |
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. |
04 August 2021, 07:56 | #6 |
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 |
04 August 2021, 09:02 | #7 |
Newbie Amiga programmer
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
|
@alkis: Thanks, but this one is libnix-dependent and
stabs.his 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? |
04 August 2021, 15:21 | #8 |
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
|
04 August 2021, 17:12 | #9 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,233
|
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.
|
04 August 2021, 17:20 | #10 | ||||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,233
|
Quote:
Quote:
Quote:
Quote:
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. |
||||
04 August 2021, 21:26 | #11 | |||
Newbie Amiga programmer
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
|
Quote:
Yes, i do use amiga-gcc for development, but i also would like to support SAS/C and VBCC. Quote:
Quote:
SysBaseis not mandatory, but highly recommended? |
|||
04 August 2021, 22:31 | #12 | |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
Quote:
|
|
04 August 2021, 22:54 | #13 |
bye
Join Date: Jun 2016
Location: Some / Where
Posts: 680
|
|
05 August 2021, 02:13 | #14 |
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. |
05 August 2021, 06:46 | #15 | ||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,233
|
Quote:
That, plus version information. Quote:
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. |
||
06 August 2021, 10:07 | #16 | |||
Newbie Amiga programmer
Join Date: Jun 2012
Location: Front of my A500+
Age: 38
Posts: 372
|
Quote:
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; } Quote:
free(), but thanks for clarifying. Quote:
|
|||
06 August 2021, 11:10 | #17 | |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,233
|
Quote:
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. |
|
08 August 2021, 12:24 | #18 |
Newbie Amiga programmer
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. |
08 August 2021, 12:59 | #19 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,233
|
I don't see what this should be good for.
|
08 August 2021, 20:50 | #20 | |
bye
Join Date: Jun 2016
Location: Some / Where
Posts: 680
|
Quote:
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. |
|
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 |
|
|