/* callback.h - define callback functions for loadable modules */ #ifndef _CALLBACK_H #define _CALLBACK_H /* A loadable module is a 'C' source program which has been compiled under BC or TC using tiny model with -r save regs. bcc -mt -r source.c link source.obj,source.exe,source.map, cs.lib rem note that c0t.obj is NOT linked in exe2bin source.exe source.bin copy source.bin sys:usr\charon\spool Tiny model programs have only one segment, DS=CS=SS The data segment is composed of static initialized data and unititialized data (BSS). Charon runs multiple copies of the module by generating a unique data/stack area, and using a shared code segment. Each instance of the module has its own stack and BSS data, but shares the static data. Therefore, if you intend to keep 'local' data that persists between callbacks, you must store it a) on the stack, or b) in unitialized data. The module's context is switched during every callback (ala windows). If you want to share a writable variable between all instances, be sure that it is not located within the last paragraph of the static data segment, as the BSS area is rounded down to the previous paragraph. Therefore up to 15 bytes of static data may not actually be common between instances. This amount is called the `Pump Size' and can be determined using the Object Information Display of Charon. This .h file provides the defines and mechanisms to allow the module creator to test the module as a stand-alone program, conversion to a module involves recompiling with a #define set. Callbacks are achieved by defining a few common functions that provide I/O for the module. The '_start' procedure must be the first procedure defined in the executable file. You may have other procedures, but they must be defined after _start. the definition for _start is int _start(argc, char *argv[], struct NXlate far *callptr) where callptr is a far ptr to a data item that must be returned in all callbacks. The callback.c module includes a definition for _start which calls a main(int argc, char *argv[]) function... Before including this module, you must #define a setting to indicate if the program will be a module, or standalone. #define STANDALONE 0 compile as module #define STANDALONE 1 compile as standalone program */ #define STDIN 0 #define STDOUT 1 #define STDERR 2 #define CB_READ 0 #define CB_WRITE 1 #define CB_GETENV 2 #define CB_SETENV 3 #define CB_TELLP 4 #define CB_SEEKP 5 #define CB_MAXCALLS 5 /* define valid return codes, OR them together optional returncode in lower byte */ #define RT_CHANGED_TEXT 0x4000 /* the output file was updated */ #define RT_CHANGED_TAGS 0x2000 /* the file attribute tags were changed */ #define RT_FAILED 0x1000 /* I couldn't translate this file */ #define RT_OK 0x0800 /* I did what I could and I finished ok */ #define MAX_STRING 256 #ifndef MASTER_SOURCE #ifndef STANDALONE #error You must define the STANDALONE def #endif #if !defined(__TINY__) #error You must compile in the tiny model only #endif #if defined(__OVERLAY__) #error You must not compile with overlays #endif int read(int handle, char *buffer, int count); /* returns bytes read */ int write(int handle, char *buffer, int count); /* returns bytes written */ char *getenv(char *string); #if STANDALONE #define tellp(handle) lseek(handle,0L,1) #define setenv(s) putenv(s) #else void setenv(char *string); long tellp(int handle); #endif long seekp(int handle, long offset, int whence); int fprintf(int handle, char *format, ...); #ifndef SEEK_CUR #define SEEK_CUR 1 #define SEEK_END 2 #define SEEK_SET 0 #endif #endif #endif