Introduction
So, you have come to the conclusion that it is time to leave Devpac/GenST behind and use rmac instead. Congratulations!
You have probably already heard about how rmac is incredibly fast, because it was written by Landon “Dadhacker” Dwyer to be used on 1980s machines. The project has since passed thru multiple hands, and more processor architectures and platforms have been added.
Today, rmac supports
- 6502
- 68000
- 68020
- 68030
- 68040
- 68060
- 68881
- 68882
- 56001
- The Atari Jaguar GPU, DSP and Object Processor
It is also very mature, and in active development.
Resources
The official rmac website
The rmac manual
For when you’ve read this document and want to go more in-depth
http://rmac.is-slick.com/manual/rmac.html
Quickstart
To assemble your source file example.s into the Atari ST executable example.tos:
rmac -p -v example.s -o example.tos
(technically, the -v switch isn’t necessary, but it outputs interesting verbose information after assembly)
General stuff
Directives and periods
All rmac directives have have a “.” prefix. However, rmac will often (but not always) accept directives without the period. Prefix assembler directives with “.” when in doubt.
Example
; Devpac
dc.b 1,2,3
even
; rmac
.dc.b 1,2,3
.even
Labels
All rmac labels are suffixed with a colon (”:“). This lets rmac have labels indented, which is not possible in Devpac.
Example
; Devpac
loop
nop
bra loop
; rmac
loop:
nop
bra loop
Assembler specific stuff
Forced errors
; Devpac
fail This code went BOINK!
; rmac
.error "This code went BOINK!""
Structs
; Devpac
rsreset
symbol1: rs.l 1
symbol2: rs.w 5
struct_size equ rscount
; rmac
.abs
symbol1: ds.l 1
symbol2: ds.w 5
struct_size .equ ^^abscount
.text
Conditional assembly
If not 0
;Devpac
one_nop_please equ 1
ifne one_nop_please
nop
endc
;rmac
one_nop_please .equ 1
.if one_nop_please
nop
.endif
If 0
;Devpac
dont_nop_here .equ 1
ifeq dont_nop_here
nop
endc
;rmac
dont_nop_here .equ 1
.if dont_nop_here=0
nop
.endif
As you probably already know, Devpac interprets “ifne” as “if not equal to zero”, and “ifeq” as “if equal to zero”. In rmac, things are a bit more sane.
If defined
;Devpac
ifd MY_DEFINE
; do some stuff
endc
;rmac
.if ^^defined MY_DEFINE
; do some stuff
.endif
If not defined
;Devpac
ifnd MY_DEFINE
; do some stuff
endc
;rmac
.if !(^^defined MY_DEFINE)
; do some stuff
.endif
String equality
; Devpac
ifc "string1", "string2"
; strings are identical
endc
ifnc "string1", "string2"
; strings are not identical
endc
;rmac
.if ^^streq "string1", "string2"
; strings are identical
.endif
.if !(^^streq "string1", "string2")
; strings are not identical
.endif
Macros
Macro with parameters
As long as the parameters aren’t named:
;Devpac
mWaitForTimer macro
move.w #\1,d0
jsr waitforvblwaiter
endm
;rmac
.macro mWaitForTimer
move.w #\1,d0
jsr waitforvblwaiter
.endm
Macro with named parameters
Simply can’t be done in Devpac. Replace with numbered parameters.
;rmac
.macro mWaitForTimer time, timezone, day
move.w #\{time},d0
move.w #\{timezone},d1
move.w #\{day},d2
jsr waitforvblwaiter
.endm
;Devpac
mWaitForTimer macro
move.w #\1,d0
move.w #\2,d1
move.w #\3,d2
jsr waitforvblwaiter
endm
Macro with parameters treated as hexadecimal in rmac
;rmac - will not work!
.macro PutValInD0
move.l #$\1,d0
.endm
PutValInD0 1000
Because parameters are always converted to hex internally, this fails. The solution is to not re-interpret it as hex inside the macro, but to pass the parameter as hex, like this:
;rmac - works fine
.macro PutValInD0
move.l #\1,d0
.endm
PutValInD0 $1000
Sections
In rmac, the target CPU is set using what is basically a section. In Devpac, it’s done using command-line parameters or the GUI.
Because rmac supports so many different CPUs and architectures, we need to start our source code with that LOOKS like a section (“.68000” or “.6502”), but it’s actually a directive for what code to generate, see below
;Devpac
section code
nop
section data
dc.b 13,10
section bss
ds.l 4
;rmac
.68000 ; Sets target CPU to 68000, not used in Devpac
.text
nop
.data
dc.b 13,10
.bss
ds.l 4
Rept/Endr
rmac can have nested .rept/.endr directives, Devpac can not. There’s really no workaround, except for a special case where what is being repeated is a single dc.x value - in which case we could use a dcb.x (which would also work in rmac, btw):
;Devpac
rept 4
dcb.b 1,7 ; byte value 1, repeated 7 times
dcb.b 5,7 ; byte value 5, repeated 7 times
endr
;rmac
.rept 4
.rept 7
.dc.b 1
.endr
.rept 7
.dc.b 5
.endr
.endr
Other
Order of evaluations in rmac
In rmac, expressions are evaluated from left to right and without respect to operator precedence. Two workarounds are available:
Workaround A
Use parentheses to force the order of evaluation you want
Workaround B
Use the -4 commandline parameter to force C-style order of evaluation.