Skip to Content

Directives

The directives of the Klive Z80 Assembler representation are used for preprocessing, similarly to those in the C and C++ programming languages, though their semantics are different.

Although you can add comments to the end of directives, they may not have labels.

The #IF Directive

You can use this directive for conditional compilation. The argument of the directive is a conditional expression, and it determines on which branch the compilation goes on. #IF works in concert with #ELSE and #ENDIF:

; Block #1 #if 2 > 3 ld a,b #endif ; Block #2; #if 2 < 3 nop #else ld b,c #endif ; Block #3 #if $ > $+2 nop #else ld b,c #endif

Here, since the condition is false, Block #1 does not generate output. Block #2 emits a nop, as the condition is true. The false condition value in Block #3 moves code parsing to the #else branch, emitting a ld b,c instruction.

The #IFDEF and #IFNDEF Directives

These directives work similarly to #IF. However, they check if a particular symbol has (#IFDEF) or has not (#IFNDEF) been defined. So, their single argument is an identifier name.

The #IFMOD and #IFNMOD Directives

These directives work similarly to #IF. However, these check if the code’s current model is specified with the identifier following the IFMOD or IFNMOD pragma. Here is a short sample of using this directive:

.model Spectrum48 #ifmod Spectrum128 BorderColor: .equ 5 RetAddr: .equ #2604 #else BorderColor: .equ 4 RetAddr: .equ #12a2 #endif Start: .org #8000 ld a,BorderColor out (#fe),a jp RetAddr

You can use only these identifiers with this pragma (case-insensitively): SPECTRUM48, SPECTRUM128, SPECTRUMP3, NEXT.

The #DEFINE and #UNDEF Directives

You can explicitly define a symbol with the #DEFINE directive. Such a symbol has no concrete value, just its existence. With #UNDEF, you may declare a symbol undefined.

#define SYMB ; Block #1 #ifdef SYMB ld a,b #endif #undef SYMB ; Block #2; #ifdef SYMB nop #else ld b,c #endif

According to this definition, the first block emits a ld, a,b instruction, and the second one emits a ld b,c instruction.

The #INCLUDE Directive

You can use this directive to load and process a source file from within another source file.

#INCLUDE accepts a string that names a file with its extension. The file name may contain either an absolute or a relative path. When a relative path is provided, its starting point is always the source file with the #INCLUDE directive.

Assume that this code is in the C:\Work folder:

#include "Symbol.z80asm" #include "./MyRules.z80asm" #include "/Common/scroll.z80asm"

The compiler will check the C:\Work folder for the first two include files and C:\Work\Commmon for the third one.

The #LINE Directive

#LINE changes the source location that the compiler reports for the lines that follow it: in error messages, in the source map, and in the list file. The IDE uses these locations to set breakpoints and to highlight the current execution point, so a tool that generates assembly code can make the debugger point to its own source file instead of the generated code.

#LINE accepts a line number, which may be an expression, and an optional file name as a string. The line after the directive is reported as that line of that file; the subsequent lines are numbered from there. Without a file name, the current file is kept. A relative file name is resolved the same way as in #INCLUDE, but the file is not read.

#line 10 "game.zxbas" ld a,2 ; reported as line 10 of game.zxbas call $1601 ; reported as line 11 of game.zxbas

#LINE affects only the file in which it is used; the lines of an included file keep their own locations.

Last updated on