Internal Access Routines

# Internal Access Routines

The subject matter of this chapter is highly technical. It is unlikely to be of interest to the normal Alice user.

Alice offers several interface routines that provide access to internal features of the operating system and Alice, as well as to library routines of the C programming language. As Alice develops, more routines will be added to the package. Library functions for supported routines can be found on your disk in \aplib.

If you wish to use these routines directly, you do so at your own risk. Looking Glass Software reserves the right to change these routines without notice. Several of these routines are already different on different machines.

Most of the routines described below have no typechecking or argument checking of any kind. It's easy to go wrong and foul up your program, so beware!

Full descriptions of most of the routines are found in a special appendix in file ``/alice/help/cproc''. In this chapter, we will only cover the basics.

## Interface Routines

There are three interface subprograms: `CProc` , `CIntFunc` , and `CPtrFunc` . We will generally refer to these as the `CProc` family, since they are very similar in form.

All routines called by the interface subprograms are actually written in the C language or are library routines meant to be called by C programs. Familiarity with C and C libraries is an asset when working with these routines.

The interface routines push arguments onto the stack the way a C function would expect to see them. Each interface subprogram can take up to seven arguments. The first argument is a number indicating the C routine you wish to call. The rest of the arguments are passed to that routine.

The three interface subprograms reflect the three different ways to call an internal routine. `CProc` is used to call C routines that do not return values. `CIntFunc` calls C routines that return integer values. `CPtrFunc` calls C routines that return pointer values. With MS-DOS, pointers are 32 bits and consist of a segment and offset of 16 bits each. If you have a manual for a C compiler, these are known as Large Model pointers. You can build them with the `RawPointer` function and take them apart with the `address` function. CPtrFunc returns a value of type `Pointer` . You should assign this value to a standard Pascal pointer variable, i.e. a pointer to a specific type.

## Strings

When strings are passed to `CProc` and friends, the strings are treated as pointers. In other words, Alice creates a pointer to the actual string and passes that. Often, C routines use this pointer to store things in the string. This will work, but you may run into trouble if the string you pass is not long enough to hold what the C routine stores there.

We should also note that Alice will not know whether a C routine has stored anything in a string. This means that Alice may give you ``uninitialized variable'' error messages even if the C routine has stored useful information in the string. It is best to make sure all strings passed to C routines have already had values assigned to them.

When dealing with pointers and strings, the following definitions are used.

>     type
>         bigstr = packed array[1..32000] of char;
>         strptr = ^bigstr;

Such a string variable should never be created, of course. Pointers to it are valid however, and you will never have to deal with array bounds checking problems.

## Real Numbers

You can pass a C routine a real number or a pointer to a real number, but you can't return one.

## The SysPointer Routine

Alice maintains an array of pointers to important variables within the system. As with `CProc` and friends, use of most of these pointers is unsupported. However, the `SysPointer` function can be used to obtain the value of any of these pointers and hence to obtain or change the value of Alice's variables.

`SysPointer` always returns a pointer to an Alice variable. This variable may itself be a pointer to something useful. Thus in many cases, the type of the value returned is a pointer to a pointer. You should declare variables of the appropriate type and assign the result of `SysPointer` to them.

`SysPointer` takes a single integer argument. A list of possible SysPointer calls is given in the special appendix in the file ``/alice/help/syspointer''.