To call a function in an Amiga system library, an assembler application
must put the library's base address in register A6 and JSR to the
function's lvo relative to a6. for example to call the intuition function
displaybeep():
;***********************************************************************
xref _LVODisplayBeep
;...
move.l A6, -(sp) ;save the current contents of A6
;---- intuition.library must already be opened
;---- and IntuitionBase must contain its base address
move.l IntuitionBase, A6 ;put intuition base pointer in A6
jsr _LVODisplayBeep(A6) ;call DisplayBeep()
move.l (SP)+, A6 ;restore A6 to its original value
intuitionbase contains a pointer to the intuition library's library base
and _LVODisplayBeep is the lvo for the displaybeep() function. the
external reference (xref) to _LVODisplayBeep is resolved from the linker
library, amiga.lib. This linker library contains the LVO's for all of the
standard Amiga libraries. Each LVO label starts with "_LVO" followed by
the name of the library function.
System Functions Do Not Preserve D0, D1, A0 and A1.
---------------------------------------------------
If you need to preserve D0, D1, A0, or A1 between calls to system
functions, you will have to save and restore these values yourself.
Amiga system functions use these registers as scratch registers and
may write over the values your program left in these registers. The
system functions preserve the values of all other registers. The
result of a system function, if any, is returned in D0.
Some Task LVO Table LibFuncY()
--------- __________________ ----------
| |
| · |
main() | · |
· | JMP to LibFuncZ | {
· |- - - - - - - - - | blah = openblah();
x= ____\| JMP to LibFuncY |____\ dosomething();
LibFuncY() /|- - - - - - - - - | / closeblah(blah);
· | JMP to LibFuncX | }
· | · |
| · |
|__________________|
| |
| Library Base |
|__________________|
A task calls a which calls the which JMP's to the
library function... functions JMP vector... actual library function.
Figure 17-2: Calling a Library Function
The example above is the actual assembly code generated by the macro named
LINKLIB, which is defined in <exec/libraries.i>. the following fragment
performs the same function as the fragment above:
LINKLIB _LVODisplayBeep, IntuitionBase
The amiga.lib linker library also contains small functions called stubs
for each function in the Amiga OS. These stubs are normally for use with
C code.
Function parameters in C are normally pushed on the stack when a program
calls a function. This presents a bit of a problem for the C programmer
when calling Amiga OS functions because the Amiga OS functions expect
their parameters to be in specific CPU registers. Stubs solve this problem
by copying the parameters from the stack to the appropriate register.
For example, the Autodoc for the Intuition library function movewindow()
shows which registers MoveWindow() expects its parameters to be:
MoveWindow(window, deltaX, deltaY);
A0 D0 D1
The stub for movewindow() in amiga.lib has to copy window to register a0,
deltaX to register D0, and deltaY to register D1.
The stub also copies Intuition library base into A6 and does an
address-relative JSR to movewindow()'s lvo (relative to a6). the stub
gets the library base from a global variable in your code called
intuitionbase. if you are using the stubs in amiga.lib to call intuition
library functions, you must declare a global variable called
IntuitionBase. It must be called IntuitionBase because amiga.lib is
specifically looking for the label IntuitionBase.
/* This global declaration is here so amiga.lib can find
the intuition.library base pointer.
*/
struct Library *IntuitionBase;
...
void main(void)
{
...
/* initialize IntuitionBase */
if (IntuitionBase = OpenLibrary("intuition.library", 33L))
{
...
/* When this code gets linked with amiga.lib, the
linker extracts the DisplayBeep() stub routine from
from amiga.lib and copies it into the executable.
The stub copies whatever is in the variable
IntuitionBase into A6, and JSRs to
_LVODisplayBeep(A6).
*/
DisplayBeep();
...
CloseLibrary(IntuitionBase);
}
...
}
There is a specific label in amiga.lib for the library base of every
library in the Amiga operating system. The chart below lists the names of
the library base pointer amiga.lib associates with each Amiga OS library.
The labels for library bases are also in the "function offsets reference"
list in the Amiga ROM Kernel Reference Manual: Includes and Autodocs.
Table 17-1: Amiga.lib Library Base Labels
_________________________________________________________
| |
| Library Name Library Base Pointer Name |
|---------------------------------------------------------|
| asl.library aslbase |
| commodities.library cxbase |
| diskfont.library diskfontbase |
| * dos.library dosbase |
| * exec.library sysbase |
| expansion.library expansionbase |
| gadtools.library gadtoolsbase |
| graphics.library gfxbase |
| icon.library iconbase |
| iffparse.library iffparsebase |
| intuition.library intuitionbase |
| keymap.library keymapbase |
| layers.library layersbase |
| mathffp.library mathbase |
| mathieeedoubbas.library mathieeedoubbasbase |
| mathieeedoubtrans.library mathieeedoubtransbase |
| mathieeesingbas.library mathieeesingbasbase |
| mathieeesingtrans.library mathieeesingtransbase |
| mathtrans.library mathtransbase |
| rexxsys.library rexxsysbase |
| rexxsupport.library rexxsupbase |
| translator.library translatorbase |
| utility.library utilitybase |
| version .library (system private) |
| workbench.library workbenchbase |
| Library Name Library Base Pointer Name |
|---------------------------------------------------------|
| * Automatically opened by the standard C startup module |
|_________________________________________________________|
The chart mentions that SysBase and DOSBase are already set up by the
standard C startup module. For more information on the startup module,
You May Not Need amiga.lib.
---------------------------
Many C compilers provide ways of using pragmas or registerized
parameters, so that a C program does not have to link with an
amiga.lib stub to access a library function. See your compiler
documentation for more details.