Interfaces

There are three language interfaces for the DATAdesign engine. You should only read about those interfaces that you are going to use. However it may sometimes be interesting to read about the other interfaces as well, as this may give you some additional information (especilly for assembler programmers). The source code for the C interface is provided on disk, so that may also be interesting to have a look at, and this for both C and Assembler programmers. The commands are all treated together, explaining what they do, and giving the specific details for each of the interfaces.


SuperBASIC interface

Actually, there isn't much which has to be mentioned before listing all the commands. You just interface through the Sbasic commands. But you have to know some details.

All routines which need a buffer- or indexid have an optional parameter at the start. If you explicitly specify this buffer- or indexid, then it has to be preceeded by a hash (#). This is similar to the passing of channel ids to the i/o commands like print. If you don't pass a buffer- or indexid, then the default bufferid and/or indexid will be used.

You also have to know how errors are dealt with. All of the routines will only interupt the program in either of two occasions, that is if the DATAdesign engine is not initialised, or when a bad parameter is encountered. Parameters can only be bad when the type of the parameter is completely wrong, or in the case of a fieldid, when it is passed as the fieldname and no field with the given name exists. Do note that fieldnames are case dependant.

In all other cases that errors are encountered, they will be returned in a special variable called dd_err. Three important remarks have to be made about this.

parameters

The Sbasic interface allows for some parameters to be left out, or just not specified, or to have several types. If there are default values for a parameter, then the default will be mentioned after the name in square brackets. If there is no default, but the parameter doesn't have to be specified, then the type will be put in square brackets. The possible parameter types are :

bufferid
always has to be a float. Can be left out (like with channel id's). If not stated the default will be used.
indexid
always has to be a float. Can be left out (like with channel id's). If not stated the default index of the default buffer will be used. If the given id was actually a bufferid, then the default index for that buffer will be used.
field
This parameter can be specified either as the fieldid, or as the fieldname. Fieldnames are case relevant. An error will be reported if the fieldname does not exist. The fieldid can be passed as an integer or as a float. If no value is given for this field, then the default will be used.
compare
This parameter can be passed either as an integer or float, or as a string. When passed as a numerical value, you have to add the values you want together. When passed as a string you just combine the specific characters. So "-C" or 48 would give the same result : reverse order and case dependant.
string
This parameter always has to be specified between quotes. If no string is specified, than a NULL string (that is "", the empty string) will be used.
short
This parameter can always be specified either as an integer or as a float. If this parameter is not optional and is not specified, then an error will be reported.
long
This parameter can only be passed as a float. If this parameter is not optional and is not specified, then an error will be reported.
char
This parameter is always specified as a string. The first character in the given string is the passed character.
float
This parameter has to be passed as a float, and will internally be converted to an IEEE double.
double
This parameter is passed as a pointer to 8 bytes in memory which should contain an IEEE double.
pointer
This is a parameter, passed in a float, which has to point to a piece of memory which can be written into, i.e. a piece of memory which was allocated with a call to ALCHP or RESPR or similar.
special
There is also a parameter which can have any of the types string, long, short, char, float. The actual type is then dependant on some other part of the parameter parsing, or some internal structures of the DATAdesign engine. Parsing these parameters will cause an error when the wrong type is used (not in dd_err), so you should be carefull.
pointer to special
This parameter is passed as a pointer to 8 bytes in memory which should contain either 8 characters (each in one byte, value 0 used for filling when less than 8 chars used), a long (in the first four bytes), a short (in the first 2 bytes), a char (also the second byte, first byte 0), or an IEEE double (conversion of a float to a double can be done with the SETfloat and GETdouble commands on a field in an empty record) (all eight bytes).

If a parameter is followed with updated, then the value of the parameter will be changed according to the command. If the parameter is not passed as a variable, and is not a pointer, then nothing is updated.

Assembler "interface"

The entire DATAdesign engine is provided as an extension thing, and so you can hardly discuss an assembler interface. All the actual interfacing can be done with the standard thing system. If you want more information about this, you should buy "QDOS Reference Manual", available from Jochen Merz (and probably some others as well).

But we have also provided a few routines which are actually very similar to the access routines for the Menu Extension (also from Jochen Merz; also an extension thing). These routines are used to call and release one specific extension at a time. It is however adviceable to keep one of the extensions "in use" during the execution of your program, as this prevents your buffer(s) from getting lost during execution of your program (this can only happen if someone gets the stupid idea to either remove the DATAdesign files job or DATAdesign.engine thing). You could use the "INFO" extension for this. This is an empty extension, which only contains some data which is used by the engine itself, and which is always the first extension in the list. Never actually call this extension !

So here are the access routines:

Use DATAdesign engine DDE_USE
        entry                       exit
d0                                  return
d2.l    extension id
a1                                  address of thing extension
error return:
-thing not implemented
-engine not found
-any other error
                  
Free DATAdesign engine DDE_FREE
no parameters, no return
                         
Call DATAdesign engine extension jsr $18(a1)
         entry                       exit
d0                                   return
a0       address of thing extension
a1       ptr to parameter list

The address of thing extension is the return value of the call to DDE_USE and can also be placed in any other address register.

These routines can be found in the library file engine_lib.

Naturally, it is also possible to use the C-interface directly from assembler if you prefer to do so.

parameters

The standard extension thing protocol is used.

bufferid
always passed in two long words. The second long word is the actual bufferid. If the MS (most significant) word of the first long word is zero, then the default buffer will be used, and the second long word becomes irrelevant.
indexid
always passed in two long words. The second long word is the indexid. If the MS word of the first long word is zero, then the default index of the default buffer will be used, and the second long word becomes irrelevant. If the given id was actually a bufferid, then the default index for that buffer will be used.
The engine will automatically recognise whether the given parameter was an indexid or a bufferid.
field
always passed as a long word. Only the LS word is important. If the value -1 is passed then the default field will be used.
string
strings are always passed as two long words. There are two possibilities. If you want to pass a standard QL string, then the MS word of the first long word has to be $0100, and the second long word is the pointer to the string. If you want to pass a substring (just a series of chars), then the MS word of the first long word has to be $0200, and the LS word has to be the length. The second long word contains the pointer to the substring.
short
this parameter is passed in a long word. The value is in the LS word.
long
this parameter is passed in a long word.
char
this parameter is passed as the LS byte of a long word.
double
this parameter is passed as an 8 bytes IEEE double.
return/update string
the returned string can be either a QL string, or a C string (null terminated). The C string is treated as return substring. The parameter is passed as two long words. The second long word is a pointer to the place where the string must be filled in. The first long word contains the type in the MS word, $a100 for QL string, $a200 for substring, and the maximum number of characters in the LS word.
return/update xxx
passed as two long words. The MS word of the first long word is $a000, the second long word must be a pointer to the place where the return value must be filled in, or where the value can be read and written after processing. If the update parameter doesn't have to be passed, and you don't want it updated, you should clear the first long word.
special
there is also a parameter which can have any of the types string, long, short, char, double. The actual type is then dependant on some other part of the parameter parsing. It is passed in two long words, and the value is left justified. Char is then considered as a unsigned word. A string is max 8 chars, unused bytes must be zero.
pointer to special
this parameter is passed as a pointer to 8 bytes in memory which should contain either 8 characters (each in one byte, value 0 used for filling when less than 8 chars used), a long (in the first four bytes), a short (in the first 2 bytes), a char (also the second byte, first byte 0), or an IEEE double (all eight bytes). It is passed as two long words, the pointer has to be in the second long word.

C interface

There isn't much which has to be said about the C interface except all the commands. But before any of the commands can be called, you have to initialise the DATAdesign variable which contains the address of the DATAdesign.engine thing and which is used by all the other commands and macros. This can be done with the DDinit() routine. This also makes sure that your job uses the DATAdesign.engine thing. The thing can also be released with a call to DDfree().

To be able to use the C interface in your C program files you have to include the "DATAdesign.h" file. You will also have to link the DATAdesign_lib file with your own source code files.

parameters

All parameters are of a standard C data-type. There is however one exception. Some routines require a pointer to a special 8 byte parameter. This parameter can be considered as a union like this:

    union special {
        char string_par[8];
        long long_par;
        short short_par;
        short char_par;
        double double_par;
    };
It may also be interesting to have a look at the special data type in the Assembler interface, and at the source of the C interface.

Furthermore, bufferid and indexid parameters are passed as a long. If a zero is passed, then the default buffer- or indexid will be used.

All C interface functions return the error which occurs during the execution of the engine.


PROGS, Professional & Graphical Software
last edited September 6, 1996