Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Arithmetic operators

 All basic arithmetic operators are supported. The following table shows them all. Result of example is shown in brackets for clarity of operator.

Operator symbolFunctionExample
+Addition12+13
-Unary minus, subtraction                          -10, 12 - 45                            
*Multiplication45 * 2 (90)
/Division256 / 8 (32)
>Unary division by 256>1024 (4)
%Modulus256%8 (0)
<Unary modulus by 256<65000 (232)
**Power2 ** 7 (128)
&Binary AND255 & 7 (7)
|Binary OR128 | 64 (192)
:Binary NOR128 : 128 (0)
^Binary XOR12 ^ 3 (15)
~Unary Binary NOT~128 (127)
<<Binary left shift2 << 4 (32)
>>Binary right shift128 >> 4 (8)


Arithmetic operators use the standard operator precedence, shown from highest to lowest:

0x $ @ ' (constant identifiers)
() []
~ > <
**
* / %
+- | ^ & : << >>

If you want to override the default operator precedence rules, use brackets () or []. The square bracket have been implemented as an alternative to avoid ambiguity with Z80 instruction mnemonics where indirect addressing uses the () as part of their syntax.


The # operator

This is not a real operator, though. It is only used as the first symbol in an expression to identify that this expression evaluates to a constant, i.e. containing no relocatable information. This feature may be necessary when you have to calculate a distance between two address labels without letting the assembler think it is a relocatable address. The assembler thinks that expressions containing address labels are relocatable items, which would create unwanted side effects during linking of object modules. However, since the assembler cannot see this as a constant expression, you have to force it as one.

Code Block
LD BC, end_relocator-relocator  ; Mpm adds an ORG constant during linking
LD BC, #end_relocator-relocator ; Mpm sees a constant expression

 

Relational operators

With relational operators you may form logical expressions resulting in true or false conditions. The resulting value of a true expression is 1. The resulting value of a false expression is 0. These operators are quite handy when you need to perform complex logic for conditional assembly in IF-ELSE-ENDIF conditional assembly. The following relational operators are available:

= equal to
<> not equal to
< less than
> larger than
<= less than or equal to
>= larger than or equal to
! not

You may link several relational expressions with the binary operators AND, OR, XOR and NOT.
It is perfectly legal to use relational expressions in parameters requiring an arithmetic value. For example:

Code Block
LD A, [USING_IBM = 1] | RTMFLAGS    ; use [] to ensure LD A,n instruction opcode

 

Predefined assembler variables

Apart from declaring your own constants, Mpm has a few pre-declared constants that might become useful in your programs.

On occasional circumstances it may be necessary to use the current location of the assembler program counter in an expression e.g. calculating a relative distance. This may be done with the help of the $PC identifier. An example:

Code Block
errmsg0: DEFM errmsg1 - $pc - 1, "File open error"
errmsg1: DEFM errmsg2 - $pc - 1, "Syntax error"
errmsg2:

 

Here, a length byte of the following string (excluding the length byte) is calculated by using the current $PC address value. When Mpm is starting a compile session, the system clock is fetched once and made available as integer variables:
$YEAR4-digit year value,  eg. 2006
$MONTHMonth of the year, range is 1 to 12.
$DAYThe day of the month, range is 1-31.
$HOURRange is 0-23.
$MINUTERange is 0-59.
$SECONDRange is 0-59.

 

Directive reference

The MPM Module Assembler directives are used to manipulate the Z80 assembler mnemonics, generate data structures, variables and constants - even including binary files while code generation is performed.

As the name imply they direct the assembler to perform other tasks than just parsing and compiling Z80 instruction mnemonics. All directives are treated as mnemonics by the assembler, i.e. it is necessary that they appear as the first command identifier on the source line (NOT necessarily the first character). Only one directive is allowed per single source line. As with Z80 mnemonics, directives are case insensitive.

The following syntax is used to describe the directives:

<> defines a syntactic entity, i.e. a number, character or string.
{} defines a repetition of a syntactic entity.
[] defines an option that may be left out.


ALIGN

ALIGN <no of bytes>

Align (or zero-pad) a specified number of bytes relative to the current PC. Argument value range = 1-16.

For example use ALIGN 4 to ensure that the new PC is located at a module address that is aligned in 4 byte entities. Another example would be to use ALIGN 2 to make sure that the next PC address is located at an even address. ALIGN only aligns addresses on the current module compilation - not on the entire scope of the linked modules. If you want to align all linked modules to even adresses, use an ALIGN at the end of each module.


ASCII, ASCIIZ, DM, DMZ, DEFM, DEFMZ

ASCII <string expression>
ASCIIZ
 <string expression>
DM <string expression>
DMZ <string expression>
DEFM <string expression>
DEFMZ <string expression>

All these directives is the same thing; to store a string at current PC. 

Strings are enclosed in double quotes. Strings may be concatenated with byte constants using '.' or ','.
This is useful if control characters (or even arithmetic expressions resulting into an 8bit value) need to be a part of the string and cannot be typed from the keyboard.

All directive names ending with a Z indicates that the end of the string is automatically null-terminated (appended with a 0 byte).

Example:

Code Block
languagecpp
ASCIIZ "This is a title", 13, 10
DEFM "(c) Zsoft 1995-2006", 13, 10, 'A', 0
DMZ 1 . "7#1" . 32 . 32 . 32+94 . 32+8 . 128