Next Previous Contents

4. Converting loadable drivers

4.1 Differences between static linking and runtime loading

One main use of the utility is conversion of loadable drivers, so they may be linked statically to an application. Statically linking will cause a few things to be different from runtime loading:

4.2 Additional requirements

All loadable drivers used by cc65 have a header and a jump table at the start of the code segment. The header is needed to detect the driver (it may also contain some data that is necessary to access the driver). The jump table is used to access the functions in the driver code.

When loading a driver at runtime, the load address of the driver is also the address of the code segment, so the locations of the header and jump table are known. However, when linking the driver statically, it is up to the programmer to provide this information to the driver API.

For this purpose, it is necessary to define a code segment label that can be accessed from the outside later. Please note that the converter does currently not create such a label without being ordered to do so, even if the input file is a cc65 module.

To create such a label, use the --code-label option when calling the converter. Be sure to begin the label with a leading underscore when accessing it from C code. In your code, define an arbitrary variable with this name. Use the address of this variable as the address of the code segment of the driver. Be sure to never modify the variable which is in reality the start of your driver!

4.3 Example - Convert and link a graphics driver

As an example, here are some instructions to convert and use the c64-hi.tgi graphics driver:

First, convert the driver, generating a label named "_c64_hi" for the code segment. Use the assembler to generate an object file from the assembler output.

        co65 --code-label _c64_hi c64-hi.tgi
        ca65 c64-hi.s
  

Next, change your C code to declare a variable that is actually the address of the driver:

        extern void c64_hi[];
  

Instead of loading and unloading the driver, change the code to install and uninstall the driver, which will be already in memory after linking:

        /* Install the driver */
        tgi_install (c64_hi);

        ...

        /* Uninstall the driver */
        tgi_uninstall ();
  

Don't forget to link the driver object file to your application, otherwise you will get an "undefined external" error for the _c64_hi symbol.


Next Previous Contents