2.2 Preprocessor directives

-----------------------------

C-- has no preprocessor, but several functions greatly resemble those of

the C preprocessor.

These so-called translator directives, which all begin with ? or #, are

listed below with their purposes:

? align [val] aligns program data to even address

(default) or to address which is a multiple

of the value 'val'.

? aligncode [val] aligns program code to even address

(default) or to address which is a multiple

of the value 'val'. Use 0x90 (NOP) to fill

unused memory cells

? aligner (aligner value) defines value of insertion byte

? alignword (TRUE or FALSE) permits or do not permits alignment of

variables of type word an int to even

address (default TRUE)

? argc (TRUE or FALSE) does or does not include alternate

command-line handler

? atexit adds support for ATEXIT() to startup code

? code32 (TRUE/FALSE) does or does not permit generation of 32-bit

code

? codesize optimizes code size (at the expense of

speed)

? compilerversion indicates which version of the compiler is

needed to compile this program

? ctrl_c (TRUE or FALSE ) permits or does not permit the program to

ignore Ctl-C [default FALSE]

? dataseg (value) tells the compiler the RAM segment address

for variables when compiling ROM BIOS.

? define (identifier) (token) defines the identifier.

? DOSrequired (number) specifies the minimum required version of

DOS: high-order byte - version number,

low-order byte - modification number.

0x0101 for version 1.1 DOS

0x0315 for version 3.21 DOS

0x0303 for version 3.3 DOS

0x0600 for version 6.0 DOS

0x0602 for version 6.2 DOS and etc.

? dosstring (TRUE/FALSE) tells the compiler that '$' must be used as

the string end

? else generates generates alternate code if ?ifdef of

?ifndef are FALSE.

? endif indicates the end of action of the

directives ifdef or ifndef

? fastcallapi (FALSE/TRUE) does or does not permit generation of a fast

call to API functions (by default

permitted). Used in compiling Windows

programs.

? fixuptable (TRUE/FALSE) does or does not permit creation of FixUp

tables (by default does not permit this).

Used when compiling Windows programs.

? ifdef (identifier) if an identifier is defined, returns TRUE,

otherwise FALSE

? imagebase value assigns the address of Image Base (by

default 0x400000). Used in compiling

Windows programs.

? ifndef (identifier) if an identifier is defined, returns FALSE,

otherwise TRUE

? include ("filename") includes another file

? includepath ("path") tells the compiler where to search for

included files

? initallvar initializes to 0 all uninitialized

variables

? jumptomain (NONE, SHORT, NEAR or FALSE)

specifes type of jump to main() (default

NEAR)

? maxerrors (number) maximum number of errors found after which

the translator stops (default 16)

? movedatarom (TRUE/FALSE) tells compiler to move data from ROM to RAM

? parsecommandline (TRUE or FALSE)

includes a block of code for parsing the

command line (default FALSE)

? pragma can declare several other directives

? print (number or string) prints to screen a number or string

? printhex (number) prints to screen a hexadecimal number

? randombyte inserts a random value byte into the program

code

? resize (TRUE or FALSE) includes a function for changing the size of

the memory block allocated by the program

after it is running to the minimum required

(default TRUE)

? resizemessage (string) message printed to screen before emergency

interrupt of the program if the change in

size of the memory block allocated by the

program was not performed

? setdinproc this directive causes the compiler to

immediately insert into the code of the

program being compiled all dynamic

functions called earlier

? sizerom (value) tells the controller ROM size

? speed optimizes speed (default) at the expense of

code size

? stack (number) defines the size of the program stack in

bytes

? startaddress (number) sets the start address of the beginning of

the code (default 0x100)

? startuptomain in .com files, places startup code in main()

? startusevar (number) indicates the address used by memory cells

for uninitialized variables

? sysattribute (value) sends the compiler the attribute of the

driver being created. By default 0x2000.

Works only with /SYS.

? sysname <text string> sends the compiler the name of the driver

being compiled. By default this is NO_NAME.

Names may be up to 8 characters long. Works

only with /SYS.

? syscommand <command_0>,<command_1>,...<command_n>;

required when creating drivers. Sends the

compiler a list of names of functions for

processing the driver commands. Works only

with /SYS.

? undef cancels constants declared by ? define

? use8086 limits compiler to generating object code

for 8086/8088 (default)

? use8088 limits compiler to generating object code

for 8088/8086.

? use80186 allows generation of object code commands

and optimization for 80186

? use80286 allows generation of object code commands

and optimization for processor 80286.

? use80386 allows generation of object code commands

and optimization for processor 80386.

? use80486 allows generation of object code commands

and optimization for processor 80486.

? usePentium allows generation of object code commands

and optimization for processor Pentium.

? useMMX allows generation of object code commands

and optimization for processor Pentium MMX.

? usestartup permits use of memory cells occupied by

startup code of program

? warning (TRUE or FALSE) does or does not permit output of warnings.

Works only within the current file and does

not affect included files.

? winmonoblock FALSE prevents placing tables of file format PE

into one section

2.2.1 ?ifdef/?ifndef

~~~~~~~~~~~~~~~~~~~~~

The directive '?ifdef' used to operate if there was a constant in the

code being compiled, regardless of its value, while ?ifndef operated only

if there was no constant Now ?ifdef operates only if there is a constant

which does not have the value FALSE, while ?ifndef operates both if there

is no constant and if the constant has the value FALSE.

The constants codesize and speed, which take on the values TRUE or

FALSE depending on optimization mode, are reserved for ?ifdef and

?ifndef. This can be used to create more flexible libraries.

You can check the CPU type for which you are compiling by using

statements like:

?ifdef cpu > 1 // if compiling for an 80186 or later cpu

?ifndef cpu >= 2 // -------//------------- an 80286 or later

?ifdef cpu == 3 // -------//------------- an 80386

?ifdef cpu != 0 // -------//------------- a cpu other than an 8086

?ifdef cpu < 3 // -------//------------- a cpu older than an 80386

?ifdef cpu <= 2 // -------//------------- an 80286 or older cpu

This is used to write code for specific cpu's.

2.2.2 ?initallvar

~~~~~~~~~~~~~~~~~~

When TRUE, switches on the mode in which all uninitialized variables

are set to zero and are located where they were declared. The practical

outcome is that uninitialized variables disappear, which may be useful

when writing drivers and TSRs.

If set to FALSE the mode is switched off (default FALSE).

2.2.3 ?usestartup

~~~~~~~~~~~~~~~~~~

Permits the compiler to reuse memory cells used by the startup code

to store uninitialized variables. This may be useful for obtaining more

compact code than in normal programs, in particular TSR's.

Used only for generating .com files.

2.2.4 ?startusevar

~~~~~~~~~~~~~~~~~~~

Indicates the starting address from which the compiler assigns memory

for uninitialized variables. For example, '?startusevar 0x53' instructs

the compiler to locate uninitialized variables starting at address 0x53.

This can be useful for obtaining more compact code, in the case of both

TSR's and ordinary programs.

Used only for generating .com files.

2.2.5 ?atexit

~~~~~~~~~~~~~~

Adds support for ATEXIT to the startup code, reserves space for

storing 16 function addresses, and changes the code of ABORT and EXIT.

ATEXIT registers the function whose address is passed to it as a

parameter of the program-termination function. This function is called at

program termination by the functions ABORT or EXIT or by the instruction

RET from main.

Up to 16 functions may be registered. They are called in the

opposite order from that in which they were registered.

2.2.6 ?startuptomain

~~~~~~~~~~~~~~~~~~~~~

Tells the compiler to do a 'jmp' to the beginning of main() at the

start of a file. Before starting to compile this function, the compiler

starts to compile the startup code and then continues compiling main().

Thus the startup code is not at the start of the file as is usually the

case, but in the body of main(). This can be usedful when compiling TSR's.

Used only in compiling .com files.

2.2.7 ?undef

~~~~~~~~~~~~~

Cancels constants declared by ?define. Used to modify the value of a

constant during compilation.

2.2.8 ?align and ?aligncode

~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The directive '?align' does a single alignment of data to an even

address. If a value is included, alignment will be done to an address

which is a multiple of this value. For example, '?align 4' adds the data

segment to an address which is a multiple of 4. During alignment, bytes

whose values are defined by '?aligner' are inserted (default zero).

'?align' aligns only in the data segment. In memory models for which the

data and code segments coincide, this directive can also be used for

aligning the start of a function.

The directive '?aligncode [value]' does an alignment in the code

segment to an address which is a multiple of a value (by default to an

even address). The byte value used to fill unused memory cells is 0x90 -

the NOP instruction code. This value cannot be changed. The directive may

also be used within executable code. For instance, to obtain fast code

for a 486, align the start of functions and loops to an address which is

a multiple of 16.

2.2.9 ?pragma

~~~~~~~~~~~~~~

This multifunctional directive has its own directives:

option

Tells the compiler to include command-line options. Certain options

cannot be used, while others may be placed only at the start of the

source code. Example:

#pragma option w32c

Tells the compiler to produce a 32-bit console Windows file.

startup

Indicates the function to be executed before starting 'main'. The

format is as follows:

#pragma startup procname

There is no limit on the number of times this directive can be used

in a program, but in reality this is only a few thousand times.

line

Displays the current line number and file name, and optionally also

the string contents after the word 'line'. For example:

#pragma line information

Displays the line number and file name, as well as any message to the

right of the word 'line'.

resource

May have the values 'start' or 'end', which mark the start and end of

a resource block when it is used directly in the source code rather than

in a separate file. For example:

#pragma resource start

MyMenu MENU DISCARDABLE

BEGIN POPUP "Files",HELP

BEGIN

MENUITEM "Open", ID_OPEN

MENUITEM "Save", ID_SAVE

MENUITEM SEPARATOR

MENUITEM "Exit", ID_EXIT

END

MENUITEM "Other", 65535

END

#pragma resource end