If you compile plugins for the Motorola 680x0 processors or for WarpOS you have to make sure
that all your functions that will be called by Hollywood are declared using the __saveds
keyword or your compiler's equivalent of this keyword (some compilers use a
function called geta4()
or a __geta4
keyword instead). This is to make sure that
the compiler generates code that loads the near data pointer in register a4
on each
function entry so that your function is able to access its data. If you don't use
__saveds
in your functions that can be called from Hollywood, then the index register
will still point to to the data section within Hollywood and not within your plugin
which will lead to all sorts of trouble.
Note that you need not use __saveds
for all your functions but only the ones
that Hollywood will directly call into. This includes the functions your plugin
exports, the Lua functions offered by your plugin as well as callback functions
within your plugin whose pointers you pass to Hollywood functions.
When declaring your plugin functions, the HW_EXPORT
macro will automatically set
__saveds
for you, e.g.
HW_EXPORT int InitPlugin(hwPluginBase *self, hwPluginAPI *cl, STRPTR p) { ... } |
However, you will also need to use __saveds
when defining the
Lua functions for your HWPLUG_CAPS_LIBRARY
plugin, e.g.
static SAVEDS int MyDiv(lua_State *L) { double a = luaL_checknumber(L, 1); double b = luaL_checknumber(L, 2); // catch division by zero CPU exception and handle // it cleanly if(b == 0) return ERR_ZERODIVISION; lua_pushnumber(L, a / b); // push 1 to indicate one return value return 1; } static const struct hwCmdStruct plug_commands[] = { {"MyDiv", MyDiv}, ... {NULL, NULL} }; |
Here we use the macro SAVEDS
which will only insert the __saveds
keyword
when building for 680x0 or WarpOS-based systems.
Finally, don't forget to set __saveds
when writing callback functions that you pass
to a Hollywood API call. These must also be declared with the __saveds
keyword because,
obviously, Hollywood calls into them, e.g.
static SAVEDS int dispatcher(APTR h, int op, APTR data, APTR udata) { ... } handle = hw_AttachDisplaySatellite(&id, dispatcher, data, tags); |
Make sure that you don't forget the __saveds
keyword for all these functions! Trying
to debug a crash that is caused by a missing __saveds
declaration can be a really
frustrating experience because very strange things will start to happen if the data
index register hasn't been set up correctly.