A library in Amiga programming is exactly as you describe - you obtain a pointer to the library base address, and then call a function by loading the library base address into A6, the required parameters into the documented registers, and then doing a jsr to an A6-relative address.
It is unusual to refer to the function addresses by number. The Amiga standard header files will define symbolic names. My memory is a bit hazy, but I think the code you quoted would more commonly be written as:
include "exec/exec.i"
...
jsr _LVOForbid(a6)
(_LVO
is a standard prefix for library function symbols; LVO stands for library vector offset.)
Yes, a pointer to exec.library is always at $4, and this is (in theory, but not in practice) the only fixed address you should ever use in AmigaOS. To obtain the base address for any other library, you have to ask exec.library. It has a function OpenLibrary which takes a library name and a minimum version and will return to you the base address of the requested library.
If you follow the pattern of getting the pointer to exec.library from $4 and then calling OpenLibrary
for every other library, then you will be compatible with different Kickstart versions. Well-written libraries will be backward-compatible, that is, the old functions will continue to be work as is on newer Kickstarts. This is why OpenLibrary
takes a library version number: you must ask for the smallest version number that contains all the functions you need. If the library is not present with the requested version number or newer, OpenLibrary
will return NULL
(which is a condition you should test for!)
The libraries themselves don't contain the symbol names of the functions - they are fully linked and resolved so there's no symbol table. So you will need the header files to use the symbolic names, at least when you are programming in assembly. When programming in C, you would normally link with a stub linker library that defines functions with the same names, and performs the library call on your behalf.
It is mandatory to put the library base pointer into A6 (necessary so that the library can find its own data; there are very few exceptions to this rule) but once you have completed the library call, you can clear A6 and use it for other purposes. You can have multiple libraries open at once; typically you would store their pointer in a variable, and load the variable into A6 just before making a library call.
http://amigadev.elowar.com/ contains lots of information about developing for AmigaOS, including descriptions of all the standard libraries.