| Making Kernel-Based Programs

Previous | Making TIGCC Programs | Next

To produce a kernel-based program, i.e. a program which will need PreOS, DoorsOS, UniversalOS, TeOS, etc. for executing, simply define the global preprocessor symbol `USE_KERNEL` at the begining of your program, before including any other header files from the library. Alternatively, the old method (including the doors.h header file before including any other header files from the library) still works. In fact, if `USE_KERNEL` is defined, including any header file from the library will include `doors.h` automatically (if it is not included explicitely before). So, explicitely including `doors.h` is really necessary only if your program does not include any other header file from the library (which is extremely unlikely).
Here is a Kernighan & Ritchie "Hello world" example (kernel version, called "Hello World 4"), which works exactly like the example given in the previous section (Making Kernel-Less Programs):

    #define USE_KERNEL          // include kernel support

    #define USE_TI89            // produce all types of files
    #define USE_TI92PLUS
    #define USE_V200

    #include <stdio.h>          // standard ANSI C input/output support
    #include <kbd.h>            // keyboard handling support, needed for ngetchx

    void _main(void)            // main entry point is function _main
    {
      clrscr ();                // clear the screen and reset print position
      printf ("Hello world!");  // do you know what this is?
      ngetchx ();               // wait for a keypress
    }

Note that the directive `SAVE_SCREEN` is not included like in the NoStub version. DoorsOS saves and restores the screen content by default, so no extra intervention is necessary.
Of course, it is better again to use TIOS specific functions than ANSI C console functions, so an extended "Hello world" TI-specific example (kernel-based version), which does the same as in the NoStub case, follows (called "Hello World 5"):

    #define USE_KERNEL

    #define USE_TI89
    #define USE_TI92PLUS
    #define USE_V200

    #include <graph.h>
    #include <kbd.h>

    void _main(void)
    {
      static WIN_RECT rect = {0, 0, 100, 14};
      ClrScr ();
      FontSetSys (F_8x10);
      DrawStr (3, 3, "Hello world!", A_NORMAL);
      DrawClipRect (&rect, ScrRect, A_NORMAL);
      ngetchx ();
    }

See graph.h and kbd.h for detailed descriptions of the used functions and data types. Be aware of the slight difference between ClrScr defined in graph.h and clrscr defined in stdio.h.
To compile this program, you can use the TIGCC Integrated Environment, or you can type from the command line (if the file is named "hello.c"):
tigcc -O2 hello.c
Always include the '-O2' or '-Os' switch: it will turn on optimization (click here to see much more about compiler command line options). See also the notes given with the example in the previous section.
If you make programs spread in more than one file, you must define `USE_KERNEL` (or include doors.h) in each file!
The advantage of kernel-based programs lies in the fact that they are often (but not always) shorter than NoStub programs if the program contains a lot of ROM calls. Kernel-based programs can also call routines from external files (often called "libraries") without special library support inside the program. Any other features supported with this library of header files work in both kernel and NoStub mode, so if the difference in the program size is not too large, and if no external libraries are needed, NoStub mode is recommended. Note that routines defined in these header files contain most of the routines which are seen in various external libraries, sometimes maybe with different name and syntax.
Additionally, if you want to make your program even smaller but only want to support new versions of the PreOS kernel, you can define `USE_PREOS_COMPRESSED_TABLES`. This will create compressed versions of the relocation tables, which are not available in older kernels. If you try to run the program with an old kernel installed, you will get an error message.
If you make a kernel-based program, knowing the following facts may be useful:

- You can produce an external library file by defining the global symbol `_library`, i.e. by putting `int _library` in your program. If the name of your library is for example MyLib, all symbols with names like MyLib__nnnn will be exported as public. To make life easier, use the `#define` directive. For example, if you want to export function named MyFunc, you can, for example, put the directive `#define MyFunc MyLib__0005` at the beginning of your library. The same directive must be included in the program which wants to use the function MyFunc from the library MyLib. Also, the prototype of the imported function also needs to be defined.
- Kernel-based programs may have an exit point. The function with name `_exit` will be executed if and only if the program is terminated in an abnormal way, for example if there was an error, or if the user pressed STO+ON.

See also: doors.h