RASM V1.6 : Reference Manual

Édouard BERGÉ
Stéphane SIKORA

February 8, 2022


1 Introduction
 1.1 Features
2 Usage
 2.1 Command line
 2.2 Exported file names
 2.3 Symbol exports
 2.4 Including files
 2.5 Dependencies options
 2.6 Compatibility options
 2.7 Debug options
 2.8 More options
3 Source code format
 3.2 Labels
 3.3 Z80 Instructions
  3.3.1 IX, IY registers
  3.3.2 Undocumented opcodes syntax
  3.3.3 Shortcuts
 3.4 Memory related directives
  3.4.1 ORG Directive
  3.4.2 ALIGN
  3.4.3 LIMIT
  3.4.4 PROTECT
 3.5 Data definition
  3.5.1 DB, DEFB, DM, DEFM
  3.5.2 DEFW
  3.5.3 DEFI
  3.5.4 DEFR
  3.5.5 DEFS
  3.5.6 STR
  3.5.7 CHARSET
  3.5.8 $ Operator
4 Expressions
 4.1 Aliases and Variables
  4.1.1 Constants or Alias
  4.1.2 Variables
 4.2 Literal values
  4.2.1 Allowed chars
 4.3 Operators
 4.4 Operators priorities
5 Preprocessor
 5.1 Debugging and asserting
  5.1.1 PRINT
  5.1.2 FAIL
  5.1.3 STOP
  5.1.4 NOEXPORT
 5.2 Conditional code directives
  5.2.1 ASSERT
  5.2.2 IF, IFNOT
  5.2.4 UNDEF
  5.2.6 SWITCH
 5.3 Loops and Macros
  5.3.1 REPEAT
  5.3.2 WHILE, WEND
  5.3.3 Macros
 5.4 Labels and modules
  5.4.1 Local labels
  5.4.2 Proximity labels
  5.4.3 Mixing different kinds of labels
  5.4.4 Modules
 5.5 Structures
  5.5.1 STRUCT
  5.5.2 SIZEOF
  5.5.3 STRUCT Array
 5.6 Duration of a block
6 Crunch and import directives
 6.1 File Import
  6.1.1 INCLUDE
  6.1.2 INCBIN
  6.1.3 Multiple files import
  6.1.4 Audio Files
 6.2 Crunching
  6.2.1 Crunched Section
  6.2.2 Crunched Binaries
  6.2.3 SUMMEM
  6.2.4 XORMEM
7 Amstrad CPC Specific features
 7.1 Bank Management
  7.1.1 BANK Prefix
  7.1.2 PAGE Prefix
  7.1.3 PAGESET Prefix
 7.2 AMSDOS headers and DSK files
  7.2.1 AMSDOS Header
  7.2.2 SAVE directive
 7.3 Snapshot and Cartridges
  7.3.1 BUILDSNA
  7.3.2 SETCPC
  7.3.3 SETCRTC
  7.3.4 SETSNA
  7.3.6 BANK
  7.3.7 RUN
 7.4 Specific Directives for snapshot images
  7.4.1 BANKSET
  7.4.3 Export option
 7.5 CPC+ Colors
  7.5.1 GET_R, GET_G, GET_B
  7.5.2 SET_R, SET_G, SET_B
 7.6 Deprecated Directives
  7.6.1 NOCODE
8 ZX Specific features
 8.1 HOBETA Directive
 8.2 BUILDZX Directive
 8.3 Options
9 Compiling and Embedding
 9.1 Building RASM
 9.2 Embedding RASM
  9.2.1 Errors and Symbols
A Syntactic coloration
 A.1 Syntax color with VIM
B Z80 Opcodes
 B.1 Main Instructions
 B.2 Extended instructions (ED)
 B.3 Bit instructions (CB)
 B.4 IX instructions (DD)
 B.5 IX bit instructions (DDCB)
 B.6 IY instructions (FD)
 B.7 IY bit instructions (FDCB)
C Z80 Opcodes Duration on CPC

1 Introduction

During the making of my first big demo, CRTC3, available assemblers on CPC were too slow and too limited for my needs: The source code consisted in 250’000 words (out of comments), 35’000 labels and 60’000 expressions. I needed a damn fast assembler with cartridge management, memory bank management and integrated crunched code and data sections, so i had to write a new assembler.

It was not my first attempt to write such a tool: 18 years ago, i had already written a small assembler. It was so limited, i couldn’t use it for CRTC3, but i’ve kept some aspects of its design, particularly the fact that the process of assembling was mono-pass.

RASM uses efficient algorithmic patterns, such as merkel trees, caches, and grouped memory allocation. Thanks to its linear conception, performances in real conditions are really high, it’s particularly fast, even with huge projects. Nowadays RASM is used on big projects such as:

1.1 Features

Rasm is licenced under MIT licence. This documentation is maintained by Stephane Sikora, please send any feedback to https://github.com/sikorama/rasm-doc

2 Usage

RASM is meant to be convenient to use. It selects automatically the correct file format (plan binary, snaphost or cartridge file)) depending on the selected ROMs, give a consistent name to generated files, looks for files in relatives path, allows multiple origin (ORG) directives, but will detect overlapping code blocks, and so on...

RASM preprocessor not only performs some checks (valid characters, strings), it also converts some operators into their C equivalent (for example XOR, AND,OR,MOD which are used by Maxam), so you can indiferently use AND or & in your expressions. And last, but not least, it is possible to use conditional expressions in order to change the way your program is assembled (like with C preprocessor), and you can even define macros and data structures!

2.1 Command line


  RASM.exe <file to assemble> [options]  

Without any option,

 rasm.exe myfile.asm 

produces rasmoutput.bin file.

2.2 Exported file names

These options are used for changing the name of the files produced by RASM:

2.3 Symbol exports

Symbols such as label’s addresses, constants, can be exported in a .sym file, using different formats. For example, it can be useful for debugging a program with Winape.


  RASM.exe test -o foo -s  
  Pre-processing [test.asm]  
  Write binary file foo.bin (25 bytes)  
  Write symbol file foo.sym (10 bytes)

The symbol file looks like this:

  LABEL1 #0 B0  
  LABEL2 #1 B0  
  LABEL3 #2 B0  
  LABEL4 #4 B0

With -sp option:

  LABEL1 EQU 00000H  
  LABEL2 EQU 00001H  
  LABEL3 EQU 00002H  
  LABEL4 EQU 00004H

With -sw, symbols are exported in Winape format:

  LABEL1 #0  
  LABEL2 #1  
  LABEL3 #2  
  LABEL4 #4

It is possible to disable symbol export for portion of codes with NOEXPORT directive.

2.4 Including files

Including source code or binary file can be achieved with INCBIN and READ directives. By default, included files are searched in the local folder, paths are relative, but it is possible to specify one ore more folder where to look for files. It is also possible to define or import symbols:

  RASM.exe test -l import1.sym -l import2.sym -l import3.sym

2.5 Dependencies options

If a filename for binary output is set (-ob option), it will be added to the dependances list, in first position.

2.6 Compatibility options

2.7 Debug options

These options are useful in rare occasions, it can sometime help for tracking bugs:

2.8 More options

Additional options are useful for some architectures only. Export options specific to the Amstrad CPC (Snapshot and cartridge generation) are documented in paragraph 7.4.3. Also remember -help option, which will display a complete list of all available command line arguments.

3 Source code format

RASM is meant to be easy to use, it offers some flexibility, concerning the syntax. For example:

Simply keep in mind you cannot use a reserved word (directive, register, Z80 instruction) as a label.

In this part,we’ll see general syntax of a z80 assembly file, as it can be commonly found in other assemblers. In the next parts, we’ll see some specific aspects of RASM.


Rasm uses semicolons to start a comment: Any character after a semicolon (until then end of the line) will be ignored. It also works possible to use C syntax, single line comments starting with a double slash (//), and multi lines comments delimited by /* and */.

3.2 Labels

Labels are used for naming a specific memory address.

ld HL,monlabel
call aFunction
; ...
monlabel db 0

We’ll see special labels later in this document: Some labels can be defined as locals to a Loop or macro (see local and proximity labels, 5.4.1). Also any label beginning with BRK or @BRK will generate a BREAKPOINT. (see section 7.4.2).

3.3 Z80 Instructions

The complete Z80 instruction set is supported, including undocumented ones. See Appendix B for the full opcode list.

3.3.1 IX, IY registers

IX and IY registers can be addressed as two 8 bit registers. For example, IX lower part can be addressed indifferently with LX, IXL or XL, and higher part with HX, IXH or XH:

ld A,IXL

Also, complex instructions with IX and IY are written with this syntax:

res 0,(IX+d),A
bit 0,(IX+d),A
sll 0,(IX+d),A
rl 0,(IX+d),A
rr 0,(IX+d),A

3.3.2 Undocumented opcodes syntax

out (<byte>),a
in a,(<byte>)
in 0,(c)
in f,(c)
sll <register>
sl1 <registre>

3.3.3 Shortcuts

Rasm allows some shortcuts. These are not real instrctions, but a convenient way to write shorter assembly code.