Each kernel function is declared like this:
kFooBar(state_t *s, int funct_nr, int argc, heap_ptr argp);
So this is how you should start. The four parameters (think of them as the Four Accessories of a kernel function) mean the following:
- state_t *s
- A pointer to the state you are operating on.
- int funct_nr
- The number of this function. Mostly irrelevant.
- int argc
- The number of arguments.
- heap_ptr argp
- Heap pointer to the first argument.
"s" contains a lot of important and interesting data. Have a look at src/include/engine.h for a complete description. What you will probably need mostly will be the heap, (s->heap), a unsigned char pointer, and the accumulator (s->acc), a word (guint16), which is used to return values to the SCI program.
Some kernel functions don't even need to refer to the heap. However, most of them are passed at least one, if not more parameters. This may sound shocking to you, but there is an easy way to work around the neccessity of peeling them off the heap manually: Use the PARAM macros. They are used as follows:
- Returns the value of the parameter x. Does not check for validity.
- Same as PARAM(x), but casts the parameter to be unsigned.
- PARAM_OR_ALT(x, y)
- Checks if PARAM(x) is valid and returns it, or returns y if PARAM(x) is invalid.
- UPARAM_OR_ALT(x, y)
- PARAM_OR_ALT(x, y) unsigned.
Several kernel functions assume default values if a specific parameter is not present, to simplify the use of optional parameters. Use the UPARAM_OR_ALT(x, y) macros to detect this case, and you'll rarely have to care about using argc directly.