mirror of
https://github.com/cc65/cc65.git
synced 2024-12-22 12:30:41 +00:00
5686efcb4a
git-svn-id: svn://svn.cc65.org/cc65/trunk@2238 b7a2c559-68d2-44c3-8de9-860c34a00d81
2874 lines
90 KiB
Plaintext
2874 lines
90 KiB
Plaintext
<!doctype linuxdoc system>
|
|
|
|
<article>
|
|
<title>ca65 Users Guide
|
|
<author>Ullrich von Bassewitz, <htmlurl url="mailto:uz@cc65.org" name="uz@cc65.org">
|
|
<date>19.07.2000, 29.11.2000, 02.10.2001
|
|
|
|
<abstract>
|
|
ca65 is a powerful macro assembler for the 6502, 65C02 and 65816 CPUs. It is
|
|
used as a companion assembler for the cc65 crosscompiler, but it may also be
|
|
used as a standalone product.
|
|
</abstract>
|
|
|
|
<!-- Table of contents -->
|
|
<toc>
|
|
|
|
<!-- Begin the document -->
|
|
|
|
<sect>Overview<p>
|
|
|
|
ca65 is a replacement for the ra65 assembler that was part of the cc65 C
|
|
compiler, originally developed by John R. Dunning. I had some problems with
|
|
ra65 and the copyright does not permit some things which I wanted to be
|
|
possible, so I decided to write a completely new assembler/linker/archiver
|
|
suite for the cc65 compiler. ca65 is part of this suite.
|
|
|
|
Some parts of the assembler (code generation and some routines for symbol
|
|
table handling) are taken from an older crossassembler named a816 written
|
|
by me a long time ago.
|
|
|
|
|
|
<sect1>Design criteria<p>
|
|
|
|
Here's a list of the design criteria, that I considered important for the
|
|
development:
|
|
|
|
<itemize>
|
|
|
|
<item> The assembler must support macros. Macros are not essential, but they
|
|
make some things easier, especially when you use the assembler in the
|
|
backend of a compiler.
|
|
<item> The assembler must support the newer 65C02 and 65816 CPUs. I have been
|
|
thinking about a 65816 backend for the C compiler, and even my old
|
|
a816 assembler had support for these CPUs, so this wasn't really a
|
|
problem.
|
|
<item> The assembler must produce relocatable code. This is necessary for the
|
|
compiler support, and it is more convenient.
|
|
<item> Conditional assembly must be supported. This is a must for bigger
|
|
projects written in assembler (like Elite128).
|
|
<item> The assembler must support segments, and it must support more than
|
|
three segments (this is the count, most other assemblers support).
|
|
Having more than one code segments helps developing code for systems
|
|
with a divided ROM area (like the C64).
|
|
<item> The linker must be able to resolve arbitrary expressions. It should
|
|
be able to get things like
|
|
<tscreen><verb>
|
|
.import S1, S2
|
|
.export Special
|
|
Special = 2*S1 + S2/7
|
|
</verb></tscreen>
|
|
right.
|
|
<item> True lexical nesting for symbols. This is very convenient for larger
|
|
assembly projects.
|
|
<item> "Cheap" local symbols without lexical nesting for those quick, late
|
|
night hacks.
|
|
<item> I liked the idea of "options" as Anre Fachats .o65 format has it, so I
|
|
introduced the concept into the object file format use by the new cc65
|
|
binutils.
|
|
<item> The assembler will be a one pass assembler. There was no real need for
|
|
this decision, but I've written several multipass assemblers, and it
|
|
started to get boring. A one pass assembler needs much more elaborated
|
|
data structures, and because of that it's much more fun:-)
|
|
<item> Non-GPLed code that may be used in any project without restrictions or
|
|
fear of "GPL infecting" other code.
|
|
</itemize>
|
|
<p>
|
|
|
|
|
|
<sect>Usage<p>
|
|
|
|
|
|
<sect1>Command line option overview<p>
|
|
|
|
The assembler accepts the following options:
|
|
|
|
<tscreen><verb>
|
|
---------------------------------------------------------------------------
|
|
Usage: ca65 [options] file
|
|
Short options:
|
|
-D name[=value] Define a symbol
|
|
-I dir Set an include directory search path
|
|
-U Mark unresolved symbols as import
|
|
-V Print the assembler version
|
|
-W n Set warning level n
|
|
-g Add debug info to object file
|
|
-h Help (this text)
|
|
-i Ignore case of symbols
|
|
-l Create a listing if assembly was ok
|
|
-o name Name the output file
|
|
-s Enable smart mode
|
|
-t sys Set the target system
|
|
-v Increase verbosity
|
|
|
|
Long options:
|
|
--auto-import Mark unresolved symbols as import
|
|
--cpu type Set cpu type
|
|
--debug-info Add debug info to object file
|
|
--feature name Set an emulation feature
|
|
--help Help (this text)
|
|
--ignore-case Ignore case of symbols
|
|
--include-dir dir Set an include directory search path
|
|
--listing Create a listing if assembly was ok
|
|
--pagelength n Set the page length for the listing
|
|
--smart Enable smart mode
|
|
--target sys Set the target system
|
|
--verbose Increase verbosity
|
|
--version Print the assembler version
|
|
---------------------------------------------------------------------------
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>Command line options in detail<p>
|
|
|
|
Here is a description of all the command line options:
|
|
|
|
<descrip>
|
|
|
|
<tag><tt>--cpu type</tt></tag>
|
|
|
|
Set the default for the CPU type. The option takes a parameter, which
|
|
may be one of
|
|
|
|
6502, 65C02, 65816 and sunplus
|
|
|
|
The latter (sunplus) is not available in the freeware version, because the
|
|
instruction set of the sunplus CPU is "confidential".
|
|
|
|
|
|
<label id="option--feature">
|
|
<tag><tt>--feature name</tt></tag>
|
|
|
|
Enable an emulation feature. This is identical as using <tt/.FEATURE/
|
|
in the source with two exceptions: Feature names must be lower case, and
|
|
each feature must be specified by using an extra <tt/--feature/ option,
|
|
comma separated lists are not allowed.
|
|
|
|
See the discussion of the <tt><ref id=".FEATURE" name=".FEATURE"></tt>
|
|
command for a list of emulation features.
|
|
|
|
|
|
<label id="option-g">
|
|
<tag><tt>-g, --debug-info</tt></tag>
|
|
|
|
When this option (or the equivalent control command <tt/.DEBUGINFO/) is
|
|
used, the assembler will add a section to the object file that contains
|
|
all symbols (including local ones) together with the symbol values and
|
|
source file positions. The linker will put these additional symbols into
|
|
the VICE label file, so even local symbols can be seen in the VICE
|
|
monitor.
|
|
|
|
|
|
<tag><tt>-h, --help</tt></tag>
|
|
|
|
Print the short option summary shown above.
|
|
|
|
|
|
<tag><tt>-i, --ignore-case</tt></tag>
|
|
|
|
This option makes the assembler case insensitive on identifiers and labels.
|
|
This option will override the default, but may itself be overriden by the
|
|
<tt><ref id=".CASE" name=".CASE"></tt> control command.
|
|
|
|
|
|
<tag><tt>-l, --listing</tt></tag>
|
|
|
|
Generate an assembler listing. The listing file will always have the
|
|
name of the main input file with the extension replaced by ".lst". This
|
|
may change in future versions.
|
|
|
|
|
|
<tag><tt>-o name</tt></tag>
|
|
|
|
The default output name is the name of the input file with the extension
|
|
replaced by ".o". If you don't like that, you may give another name with
|
|
the -o option. The output file will be placed in the same directory as
|
|
the source file, or, if -o is given, the full path in this name is used.
|
|
|
|
|
|
<tag><tt>--pagelength n</tt></tag>
|
|
|
|
sets the length of a listing page in lines. See the <tt><ref
|
|
id=".PAGELENGTH" name=".PAGELENGTH"></tt> directive for more information.
|
|
|
|
|
|
<tag><tt>-s, --smart-mode</tt></tag>
|
|
|
|
In smart mode (enabled by -s or the <tt><ref id=".SMART" name=".SMART"></tt>
|
|
pseudo instruction) the assembler will track usage of the <tt/REP/ and
|
|
<tt/SEP/ instructions in 65816 mode and update the operand sizes
|
|
accordingly. If the operand of such an instruction cannot be evaluated by
|
|
the assembler (for example, because the operand is an imported symbol), a
|
|
warning is issued.
|
|
|
|
Beware: Since the assembler cannot trace the execution flow this may
|
|
lead to false results in some cases. If in doubt, use the .ixx and .axx
|
|
instructions to tell the assembler about the current settings. Smart
|
|
mode is off by default.
|
|
|
|
|
|
<label id="option-t">
|
|
<tag><tt>-t sys, --target sys</tt></tag>
|
|
|
|
Set the target system. This will enable translation of character strings
|
|
and character constants into the character set of the target platform.
|
|
The default for the target system is "none", which means that no translation
|
|
will take place. The assembler supports the same target systems as the
|
|
compiler, see there for a list.
|
|
|
|
|
|
<tag><tt>-v, --verbose</tt></tag>
|
|
|
|
Increase the assembler verbosity. Usually only needed for debugging
|
|
purposes. You may use this option more than one time for even more
|
|
verbose output.
|
|
|
|
|
|
<tag><tt>-D</tt></tag>
|
|
|
|
This option allows you to define symbols on the command line. Without a
|
|
value, the symbol is defined with the value zero. When giving a value,
|
|
you may use the '$' prefix for hexadecimal symbols. Please note
|
|
that for some operating systems, '$' has a special meaning, so
|
|
you may have to quote the expression.
|
|
|
|
|
|
<tag><tt>-I dir, --include-dir dir</tt></tag>
|
|
|
|
Name a directory which is searched for include files. The option may be
|
|
used more than once to specify more than one directory to search. The
|
|
current directory is always searched first before considering any
|
|
additional directores.
|
|
|
|
|
|
<tag><tt>-U, --auto-import</tt></tag>
|
|
|
|
Mark symbols that are not defined in the sources as imported symbols. This
|
|
should be used with care since it delays error messages about typos and such
|
|
until the linker is run. The compiler uses the equivalent of this switch
|
|
(<tt><ref id=".AUTOIMPORT" name=".AUTOIMPORT"></tt>) to enable auto imported
|
|
symbols for the runtime library. However, the compiler is supposed to
|
|
generate code that runs through the assembler without problems, something
|
|
which is not always true for assembler programmers.
|
|
|
|
|
|
<tag><tt>-V, --version</tt></tag>
|
|
|
|
Print the version number of the assembler. If you send any suggestions
|
|
or bugfixes, please include the version number.
|
|
|
|
|
|
<label id="option-W">
|
|
<tag><tt>-Wn</tt></tag>
|
|
|
|
Set the warning level for the assembler. Using -W2 the assembler will
|
|
even warn about such things like unused imported symbols. The default
|
|
warning level is 1, and it would probably be silly to set it to
|
|
something lower.
|
|
|
|
</descrip>
|
|
<p>
|
|
|
|
|
|
<sect>Input format<p>
|
|
|
|
The assembler accepts the standard 6502/65816 assembler syntax. One line may
|
|
contain a label (which is identified by a colon), and, in addition to the
|
|
label, an assembler mnemonic, a macro, or a control command (see section <ref
|
|
id="control-commands" name="Control Commands"> for supported control
|
|
commands). Alternatively, the line may contain a symbol definition using the
|
|
'=' token. Everything after a semicolon is handled as a comment (that is, it
|
|
is ignored).
|
|
|
|
Here are some examples for valid input lines:
|
|
|
|
<tscreen><verb>
|
|
Label: ; A label and a comment
|
|
lda #$20 ; A 6502 instruction plus comment
|
|
L1: ldx #$20 ; Same with label
|
|
L2: .byte "Hello world" ; Label plus control command
|
|
mymac $20 ; Macro expansion
|
|
MySym = 3*L1 ; Symbol definition
|
|
MaSym = Label ; Another symbol
|
|
</verb></tscreen>
|
|
|
|
The assembler accepts all valid 6502 mnemonics when in 6502 mode (the
|
|
default). The assembler accepts all valid 65SC02 mnemonics when in 65SC02 mode
|
|
(after a <tt><ref id=".PC02" name=".PC02"></tt> command is found). The
|
|
assembler accepts all valid 65816 mnemonics with a few exceptions after a
|
|
.P816 command is found. These exceptions are listed below.
|
|
|
|
In 65816 mode several aliases are accepted in addition to the official
|
|
mnemonics:
|
|
|
|
<tscreen><verb>
|
|
BGE is an alias for BCS
|
|
BLT is an alias for BCC
|
|
CPA is an alias for CMP
|
|
DEA is an alias for DEC A
|
|
INA is an alias for INC A
|
|
SWA is an alias for XBA
|
|
TAD is an alias for TCD
|
|
TAS is an alias for TCS
|
|
TDA is an alias for TDC
|
|
TSA is an alias for TSC
|
|
</verb></tscreen>
|
|
|
|
Evaluation of banked expressions in 65816 mode differs slightly from the
|
|
official syntax:
|
|
|
|
Instead of accepting a 24 bit address (something that is difficult for
|
|
the assembler to determine and would have required one more special
|
|
.import command), the bank and the absolute address in that bank are
|
|
separated by a dot:
|
|
|
|
<tscreen><verb>
|
|
jsl 3.$1234 ; Call subroutine at $1234 in bank 3
|
|
</verb></tscreen>
|
|
|
|
For literal values, the assembler accepts the widely used number formats:
|
|
A preceeding '$' denotes a hex value, a preceeding '%' denotes a
|
|
binary value, and a bare number is interpeted as a decimal. There are
|
|
currently no octal values and no floats.
|
|
<p>
|
|
|
|
|
|
<sect>Expressions<p>
|
|
|
|
|
|
<sect1>Expression evaluation<p>
|
|
|
|
All expressions are evaluated with (at least) 32 bit precision. An
|
|
expression may contain constant values and any combination of internal and
|
|
external symbols. Expressions that cannot be evaluated at assembly time
|
|
are stored inside the object file for evaluation by the linker.
|
|
Expressions referencing imported symbols must always be evaluated by the
|
|
linker.
|
|
|
|
|
|
<sect1>Size of an expressions result<p>
|
|
|
|
Sometimes, the assembler must know about the size of the value that is the
|
|
result of an expression. This is usually the case, if a decision has to be
|
|
made, to generate a zero page or an absolute memory references. In this
|
|
case, the assembler has to make some assumptions about the result of an
|
|
expression:
|
|
|
|
<itemize>
|
|
<item> If the result of an expression is constant, the actual value is
|
|
checked to see if it's a byte sized expression or not.
|
|
<item> If the expression is explicitly casted to a byte sized expression by
|
|
one of the '>'/'<' operators, it is a byte expression.
|
|
<item> If this is not the case, and the expression contains a symbol,
|
|
explicitly declared as zero page symbol (by one of the .importzp or
|
|
.exportzp instructions), then the whole expression is assumed to be
|
|
byte sized.
|
|
<item> If the expression contains symbols that are not defined, and these
|
|
symbols are local symbols, the enclosing scopes are searched for a
|
|
symbol with the same name. If one exists and this symbol is defined,
|
|
it's attributes are used to determine the result size.
|
|
<item> In all other cases the expression is assumed to be word sized.
|
|
</itemize>
|
|
|
|
Note: If the assembler is not able to evaluate the expression at assembly
|
|
time, the linker will evaluate it and check for range errors as soon as
|
|
the result is known.
|
|
|
|
|
|
<sect1>Boolean expressions<p>
|
|
|
|
In the context of a boolean expression, any non zero value is evaluated as
|
|
true, any other value to false. The result of a boolean expression is 1 if
|
|
it's true, and zero if it's false. There are boolean operators with extrem
|
|
low precedence with version 2.x (where x > 0). The <tt/.AND/ and <tt/.OR/
|
|
operators are shortcut operators. That is, if the result of the expression is
|
|
already known, after evaluating the left hand side, the right hand side is
|
|
not evaluated.
|
|
|
|
|
|
<sect1>Available operators<p>
|
|
|
|
Available operators sorted by precedence:
|
|
|
|
<tscreen><verb>
|
|
Op Description Precedence
|
|
-------------------------------------------------------------------
|
|
.CONCAT Builtin function 0
|
|
.LEFT Builtin function 0
|
|
.MID Builtin function 0
|
|
.RIGHT Builtin function 0
|
|
.STRING Builtin function 0
|
|
|
|
* Builtin pseudo variable (r/o) 1
|
|
.BLANK Builtin function 1
|
|
.CONST Builtin function 1
|
|
.CPU Builtin pseudo variable (r/o) 1
|
|
.DEFINED Builtin function 1
|
|
.MATCH Builtin function 1
|
|
.TCOUNT Builtin function 1
|
|
.TIME Builtin function 1
|
|
.XMATCH Builtin function 1
|
|
.PARAMCOUNT Builtin pseudo variable (r/o) 1
|
|
.REFERENCED Builtin function 1
|
|
:: Global namespace override 1
|
|
+ Unary plus 1
|
|
- Unary minus 1
|
|
~ Unary bitwise not 1
|
|
.BITNOT Unary bitwise not 1
|
|
< Low byte operator 1
|
|
> High byte operator 1
|
|
|
|
* Multiplication 2
|
|
/ Division 2
|
|
.MOD Modulo operation 2
|
|
& Bitwise and 2
|
|
.BITAND Bitwise and 2
|
|
^ Bitwise xor 2
|
|
.BITXOR Bitwise xor 2
|
|
<< Shift left operator 2
|
|
.SHL Shift left operator 2
|
|
>> Shift right operator
|
|
.SHR Shift right operator 2
|
|
|
|
+ Binary plus 3
|
|
- Binary minus 3
|
|
| Binary or 3
|
|
.BITOR Binary or 3
|
|
|
|
= Compare operation (equal) 4
|
|
<> Compare operation (not equal) 4
|
|
< Compare operation (less) 4
|
|
> Compare operation (greater) 4
|
|
<= Compare operation (less or equal) 4
|
|
>= Compare operation (greater or equal) 4
|
|
|
|
&& Boolean and 5
|
|
.AND Boolean and 5
|
|
.XOR Boolean xor 5
|
|
|
|
|| Boolean or 6
|
|
.OR Boolean or 6
|
|
|
|
! Boolean not 7
|
|
.NOT Boolean not 7
|
|
</verb></tscreen>
|
|
|
|
|
|
To force a specific order of evaluation, braces may be used as usual.
|
|
|
|
Some of the pseudo variables mentioned above need some more explanation:
|
|
|
|
<tscreen><verb>
|
|
* This symbol is replaced by the value of the program
|
|
counter at start of the current instruction. Note, that
|
|
'*' yields a rvalue, that means, you cannot assign to it.
|
|
Use <tt/.ORG/ to set the program counter in sections with
|
|
absolute code.
|
|
</verb></tscreen>
|
|
<p>
|
|
|
|
|
|
|
|
<sect>Symbols and labels<p>
|
|
|
|
The assembler allows you to use symbols instead of naked values to make
|
|
the source more readable. There are a lot of different ways to define and
|
|
use symbols and labels, giving a lot of flexibility.
|
|
|
|
|
|
<sect1>Numeric constants<p>
|
|
|
|
Numeric constants are defined using the equal sign. After doing
|
|
|
|
<tscreen><verb>
|
|
two = 2
|
|
</verb></tscreen>
|
|
|
|
may use the symbol "two" in every place where a number is expected, and it is
|
|
evaluated to the value 2 in this context. An example would be
|
|
|
|
<tscreen><verb>
|
|
four = two * two
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>Standard labels<p>
|
|
|
|
A label is defined by writing the name of the label at the start of the line
|
|
(before any instruction mnemonic, macro or pseudo directive), followed by a
|
|
colon. This will declare a symbol with the given name and the value of the
|
|
current program counter.
|
|
|
|
|
|
<sect1>Local labels and symbols<p>
|
|
|
|
Using the <tt><ref id=".PROC" name=".PROC"></tt> directive, it is possible to
|
|
create regions of code where the names of labels and symbols are local to this
|
|
region. They are not known outside of this region and cannot be accessed from
|
|
there. Such regions may be nested like PROCEDUREs in Pascal.
|
|
|
|
See the description of the <tt><ref id=".PROC" name=".PROC"></tt>
|
|
directive for more information.
|
|
|
|
|
|
<sect1>Cheap local labels<p>
|
|
|
|
Cheap local labels are defined like standard labels, but the name of the
|
|
label must begin with a special symbol (usually '@', but this can be
|
|
changed by the <tt><ref id=".LOCALCHAR" name=".LOCALCHAR"></tt>
|
|
directive).
|
|
|
|
Cheap local labels are visible only between two non cheap labels. As soon as a
|
|
standard symbol is encountered (this may also be a local symbol if inside a
|
|
region defined with the <tt><ref id=".PROC" name=".PROC"></tt> directive), the
|
|
cheap local symbol goes out of scope.
|
|
|
|
You may use cheap local labels as an easy way to reuse common label
|
|
names like "Loop". Here is an example:
|
|
|
|
<tscreen><verb>
|
|
Clear: lda #$00 ; Global label
|
|
ldy #$20
|
|
@Loop: sta Mem,y ; Local label
|
|
dey
|
|
bne @Loop ; Ok
|
|
rts
|
|
Sub: ... ; New global label
|
|
bne @Loop ; ERROR: Unknown identifier!
|
|
</verb></tscreen>
|
|
|
|
<sect1>Unnamed labels<p>
|
|
|
|
If you really want to write messy code, there are also unnamed
|
|
labels. These labels do not have a name (you guessed that already,
|
|
didn't you?). A colon is used to mark the absence of the name.
|
|
|
|
Unnamed labels may be accessed by using the colon plus several minus
|
|
or plus characters as a label designator. Using the '-' characters
|
|
will create a back reference (use the n'th label backwards), using
|
|
'+' will create a forward reference (use the n'th label in forward
|
|
direction). An example will help to understand this:
|
|
|
|
<tscreen><verb>
|
|
: lda (ptr1),y ; #1
|
|
cmp (ptr2),y
|
|
bne :+ ; -> #2
|
|
tax
|
|
beq :+++ ; -> #4
|
|
iny
|
|
bne :- ; -> #1
|
|
inc ptr1+1
|
|
inc ptr2+1
|
|
bne :- ; -> #1
|
|
|
|
: bcs :+ ; #2 -> #3
|
|
ldx #$FF
|
|
rts
|
|
|
|
: ldx #$01 ; #3
|
|
: rts ; #4
|
|
</verb></tscreen>
|
|
|
|
As you can see from the example, unnamed labels will make even short
|
|
sections of code hard to understand, because you have to count labels
|
|
to find branch targets (this is the reason why I for my part do
|
|
prefer the "cheap" local labels). Nevertheless, unnamed labels are
|
|
convenient in some situations, so it's your decision.
|
|
|
|
|
|
<sect1>Using macros to define labels and constants<p>
|
|
|
|
While there are drawbacks with this approach, it may be handy in some
|
|
situations. Using <tt><ref id=".DEFINE" name=".DEFINE"></tt>, it is
|
|
possible to define symbols or constants that may be used elsewhere. Since
|
|
the macro facility works on a very low level, there is no scoping. On the
|
|
other side, you may also define string constants this way (this is not
|
|
possible with the other symbol types).
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.DEFINE two 2
|
|
.DEFINE version "SOS V2.3"
|
|
|
|
four = two * two ; Ok
|
|
.byte version ; Ok
|
|
|
|
.PROC ; Start local scope
|
|
two = 3 ; Will give "2 = 3" - invalid!
|
|
.ENDPROC
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>Symbols and <tt>.DEBUGINFO</tt><p>
|
|
|
|
If <tt><ref id=".DEBUGINFO" name=".DEBUGINFO"></tt> is enabled (or <ref
|
|
id="option-g" name="-g"> is given on the command line), global, local and
|
|
cheap local labels are written to the object file and will be available in the
|
|
symbol file via the linker. Unnamed labels are not written to the object file,
|
|
because they don't have a name which would allow to access them.
|
|
|
|
|
|
|
|
<sect>Control commands<label id="control-commands">
|
|
|
|
<p>
|
|
Here's a list of all control commands and a description, what they do:
|
|
|
|
|
|
<sect1><tt>.A16</tt><label id=".A16"><p>
|
|
|
|
Valid only in 65816 mode. Switch the accumulator to 16 bit.
|
|
|
|
Note: This command will not emit any code, it will tell the assembler to
|
|
create 16 bit operands for immediate accumulator adressing mode.
|
|
|
|
See also: <tt><ref id=".SMART" name=".SMART"></tt>
|
|
|
|
|
|
<sect1><tt>.A8</tt><label id=".A8"><p>
|
|
|
|
Valid only in 65816 mode. Switch the accumulator to 8 bit.
|
|
|
|
Note: This command will not emit any code, it will tell the assembler to
|
|
create 8 bit operands for immediate accu adressing mode.
|
|
|
|
See also: <tt><ref id=".SMART" name=".SMART"></tt>
|
|
|
|
|
|
<sect1><tt>.ADDR</tt><label id=".ADDR"><p>
|
|
|
|
Define word sized data. In 6502 mode, this is an alias for <tt/.WORD/ and
|
|
may be used for better readability if the data words are address values. In
|
|
65816 mode, the address is forced to be 16 bit wide to fit into the current
|
|
segment. See also <tt><ref id=".FARADDR" name=".FARADDR"></tt>. The command
|
|
must be followed by a sequence of (not necessarily constant) expressions.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.addr $0D00, $AF13, _Clear
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".FARADDR" name=".FARADDR"></tt>, <tt><ref id=".WORD"
|
|
name=".WORD"></tt>
|
|
|
|
|
|
<sect1><tt>.ALIGN</tt><label id=".ALIGN"><p>
|
|
|
|
Align data to a given boundary. The command expects a constant integer
|
|
argument that must be a power of two, plus an optional second argument
|
|
in byte range. If there is a second argument, it is used as fill value,
|
|
otherwise the value defined in the linker configuration file is used
|
|
(the default for this value is zero).
|
|
|
|
Since alignment depends on the base address of the module, you must
|
|
give the same (or a greater) alignment for the segment when linking.
|
|
The linker will give you a warning, if you don't do that.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.align 256
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.ASCIIZ</tt><label id=".ASCIIZ"><p>
|
|
|
|
Define a string with a trailing zero.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
Msg: .asciiz "Hello world"
|
|
</verb></tscreen>
|
|
|
|
This will put the string "Hello world" followed by a binary zero into
|
|
the current segment. There may be more strings separated by commas, but
|
|
the binary zero is only appended once (after the last one).
|
|
|
|
|
|
<sect1><tt>.ASSERT</tt><label id=".ASSERT"><p>
|
|
|
|
Add an assertion. The command is followed by an expression, an action
|
|
specifier and a message that is output in case the assertion fails. The
|
|
action specifier may be one of <tt/warning/ or <tt/error/. The assertion
|
|
is passed to the linker and will be evaluated when segment placement has
|
|
been done.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.assert * = $8000, error, "Code not at $8000"
|
|
</verb></tscreen>
|
|
|
|
The example assertion will check that the current location is at $8000,
|
|
when the output file is written, and abort with an error if this is not
|
|
the case. More complex expressions are possible. The action specifier
|
|
<tt/warning/ outputs a warning, while the <tt/error/ specifier outputs
|
|
an error message. In the latter case, generation if the output file is
|
|
suppressed.
|
|
|
|
|
|
<sect1><tt>.AUTOIMPORT</tt><label id=".AUTOIMPORT"><p>
|
|
|
|
Is followed by a plus or a minus character. When switched on (using a
|
|
+), undefined symbols are automatically marked as import instead of
|
|
giving errors. When switched off (which is the default so this does not
|
|
make much sense), this does not happen and an error message is
|
|
displayed. The state of the autoimport flag is evaluated when the
|
|
complete source was translated, before outputing actual code, so it is
|
|
<em/not/ possible to switch this feature on or off for separate sections
|
|
of code. The last setting is used for all symbols.
|
|
|
|
You should probably not use this switch because it delays error
|
|
messages about undefined symbols until the link stage. The cc65
|
|
compiler (which is supposed to produce correct assembler code in all
|
|
circumstances, something which is not true for most assembler
|
|
programmers) will insert this command to avoid importing each and every
|
|
routine from the runtime library.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.autoimport + ; Switch on auto import
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.BLANK</tt><label id=".BLANK"><p>
|
|
|
|
Builtin function. The function evaluates its argument in braces and
|
|
yields "false" if the argument is non blank (there is an argument), and
|
|
"true" if there is no argument. As an example, the <tt/.IFBLANK/ statement
|
|
may be replaced by
|
|
|
|
<tscreen><verb>
|
|
.if .blank(arg)
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.BSS</tt><label id=".BSS"><p>
|
|
|
|
Switch to the BSS segment. The name of the BSS segment is always "BSS",
|
|
so this is a shortcut for
|
|
|
|
<tscreen><verb>
|
|
.segment "BSS"
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command.
|
|
|
|
|
|
<sect1><tt>.BYT, .BYTE</tt><label id=".BYTE"><p>
|
|
|
|
Define byte sized data. Must be followed by a sequence of (byte ranged)
|
|
expressions or strings.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.byte "Hello "
|
|
.byt "world", $0D, $00
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.CASE</tt><label id=".CASE"><p>
|
|
|
|
Switch on or off case sensitivity on identifiers. The default is off
|
|
(that is, identifiers are case sensitive), but may be changed by the
|
|
-i switch on the command line.
|
|
The command must be followed by a '+' or '-' character to switch the
|
|
option on or off respectively.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.case - ; Identifiers are not case sensitive
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.CHARMAP</tt><label id=".CHARMAP"><p>
|
|
|
|
Apply a custom mapping for characters. The command is followed by two
|
|
numbers in the range 1..255. The first one is the index of the source
|
|
character, the second one is the mapping. The mapping applies to all
|
|
character and string constants when they generate output, and overrides
|
|
a mapping table specified with the <tt><ref id="option-t" name="-t"></tt>
|
|
command line switch.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.charmap $41, $61 ; Map 'A' to 'a'
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.CODE</tt><label id=".CODE"><p>
|
|
|
|
Switch to the CODE segment. The name of the CODE segment is always
|
|
"CODE", so this is a shortcut for
|
|
|
|
<tscreen><verb>
|
|
.segment "CODE"
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command.
|
|
|
|
|
|
<sect1><tt>.CONDES</tt><label id=".CONDES"><p>
|
|
|
|
Export a symbol and mark it in a special way. The linker is able to build
|
|
tables of all such symbols. This may be used to automatically create a list
|
|
of functions needed to initialize linked library modules.
|
|
|
|
Note: The linker has a feature to build a table of marked routines, but it
|
|
is your code that must call these routines, so just declaring a symbol with
|
|
<tt/.CONDES/ does nothing by itself.
|
|
|
|
All symbols are exported as an absolute (16 bit) symbol. You don't need to
|
|
use an additional <tt><ref id=".EXPORT" name=".EXPORT"></tt> statement, this
|
|
is implied by <tt/.CONDES/.
|
|
|
|
<tt/.CONDES/ is followed by the type, which may be <tt/constructor/,
|
|
<tt/destructor/ or a numeric value between 0 and 6 (where 0 is the same as
|
|
specifiying <tt/constructor/ and 1 is equal to specifying <tt/destructor/).
|
|
The <tt><ref id=".CONSTRUCTOR" name=".CONSTRUCTOR"></tt> and <tt><ref
|
|
id=".DESTRUCTOR" name=".DESTRUCTOR"></tt> commands are actually shortcuts
|
|
for <tt/.CONDES/ with a type of <tt/constructor/ resp. <tt/destructor/.
|
|
|
|
After the type, an optional priority may be specified. If no priority is
|
|
given, the default priority of 7 is used. Be careful when assigning
|
|
priorities to your own module constructors so they won't interfere with the
|
|
ones in the cc65 library.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.condes ModuleInit, constructor
|
|
.condes ModInit, 0, 16
|
|
</verb></tscreen>
|
|
|
|
See the <tt><ref id=".CONSTRUCTOR" name=".CONSTRUCTOR"></tt> and <tt><ref
|
|
id=".DESTRUCTOR" name=".DESTRUCTOR"></tt> commands and the separate section
|
|
<ref id="condes" name="Module constructors/destructors"> explaining the
|
|
feature in more detail.
|
|
|
|
|
|
<sect1><tt>.CONCAT</tt><label id=".CONCAT"><p>
|
|
|
|
Builtin function. The function allows to concatenate a list of string
|
|
constants separated by commas. The result is a string constant that
|
|
is the concatentation of all arguments. This function is most useful
|
|
in macros and when used together with the <tt/.STRING/ builtin function.
|
|
The function may be used in any case where a string constant is
|
|
expected.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.include .concat ("myheader", ".", "inc")
|
|
</verb></tscreen>
|
|
|
|
This is the same as the command
|
|
|
|
<tscreen><verb>
|
|
.include "myheader.inc"
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.CONST</tt><label id=".CONST"><p>
|
|
|
|
Builtin function. The function evaluates its argument in braces and
|
|
yields "true" if the argument is a constant expression (that is, an
|
|
expression that yields a constant value at assembly time) and "false"
|
|
otherwise. As an example, the .IFCONST statement may be replaced by
|
|
|
|
<tscreen><verb>
|
|
.if .const(a + 3)
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.CONSTRUCTOR</tt><label id=".CONSTRUCTOR"><p>
|
|
|
|
Export a symbol and mark it as a module constructor. This may be used
|
|
together with the linker to build a table of constructor subroutines that
|
|
are called by the startup code.
|
|
|
|
Note: The linker has a feature to build a table of marked routines, but it
|
|
is your code that must call these routines, so just declaring a symbol as
|
|
constructor does nothing by itself.
|
|
|
|
A constructor is always exported as an absolute (16 bit) symbol. You don't
|
|
need to use an additional <tt/.export/ statement, this is implied by
|
|
<tt/.constructor/. It may have an optional priority that is separated by a
|
|
comma. If no priority is given, the default priority of 7 is used. Be
|
|
careful when assigning priorities to your own module constructors so they
|
|
won't interfere with the ones in the cc65 library.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.constructor ModuleInit
|
|
.constructor ModInit, 16
|
|
</verb></tscreen>
|
|
|
|
See the <tt><ref id=".CONDES" name=".CONDES"></tt> and <tt><ref
|
|
id=".DESTRUCTOR" name=".DESTRUCTOR"></tt> commands and the separate section
|
|
<ref id="condes" name="Module constructors/destructors"> explaining the
|
|
feature in more detail.
|
|
|
|
|
|
<sect1><tt>.CPU</tt><label id=".CPU"><p>
|
|
|
|
Reading this pseudo variable will give a constant integer value that
|
|
tells which instruction set is currently enabled. Possible values are:
|
|
|
|
<tscreen><verb>
|
|
0 --> 6502
|
|
1 --> 65SC02
|
|
2 --> 65SC816
|
|
3 --> SunPlus SPC
|
|
</verb></tscreen>
|
|
|
|
It may be used to replace the .IFPxx pseudo instructions or to construct
|
|
even more complex expressions.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.if (.cpu = 0) .or (.cpu = 1)
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
.else
|
|
phx
|
|
phy
|
|
.endif
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.DATA</tt><label id=".DATA"><p>
|
|
|
|
Switch to the DATA segment. The name of the DATA segment is always
|
|
"DATA", so this is a shortcut for
|
|
|
|
<tscreen><verb>
|
|
.segment "DATA"
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command.
|
|
|
|
|
|
<sect1><tt>.DBYT</tt><label id=".DBYT"><p>
|
|
|
|
Define word sized data with the hi and lo bytes swapped (use <tt/.WORD/ to
|
|
create word sized data in native 65XX format). Must be followed by a
|
|
sequence of (word ranged) expressions.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.dbyt $1234, $4512
|
|
</verb></tscreen>
|
|
|
|
This will emit the bytes
|
|
|
|
<tscreen><verb>
|
|
$12 $34 $45 $12
|
|
</verb></tscreen>
|
|
|
|
into the current segment in that order.
|
|
|
|
|
|
<sect1><tt>.DEBUGINFO</tt><label id=".DEBUGINFO"><p>
|
|
|
|
Switch on or off debug info generation. The default is off (that is,
|
|
the object file will not contain debug infos), but may be changed by the
|
|
-g switch on the command line.
|
|
The command must be followed by a '+' or '-' character to switch the
|
|
option on or off respectively.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.debuginfo + ; Generate debug info
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.DEFINE</tt><label id=".DEFINE"><p>
|
|
|
|
Start a define style macro definition. The command is followed by an
|
|
identifier (the macro name) and optionally by a list of formal arguments
|
|
in braces.
|
|
See section <ref id="macros" name="Macros">.
|
|
|
|
|
|
<sect1><tt>.DEF, .DEFINED</tt><label id=".DEFINED"><p>
|
|
|
|
Builtin function. The function expects an identifier as argument in braces.
|
|
The argument is evaluated, and the function yields "true" if the identifier
|
|
is a symbol that is already defined somewhere in the source file up to the
|
|
current position. Otherwise the function yields false. As an example, the
|
|
<tt><ref id=".IFDEF" name=".IFDEF"></tt> statement may be replaced by
|
|
|
|
<tscreen><verb>
|
|
.if .defined(a)
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.DESTRUCTOR</tt><label id=".DESTRUCTOR"><p>
|
|
|
|
Export a symbol and mark it as a module destructor. This may be used
|
|
together with the linker to build a table of destructor subroutines that
|
|
are called by the startup code.
|
|
|
|
Note: The linker has a feature to build a table of marked routines, but it
|
|
is your code that must call these routines, so just declaring a symbol as
|
|
constructor does nothing by itself.
|
|
|
|
A destructor is always exported as an absolute (16 bit) symbol. You don't
|
|
need to use an additional <tt/.export/ statement, this is implied by
|
|
<tt/.destructor/. It may have an optional priority that is separated by a
|
|
comma. If no priority is given, the default priority of 7 is used. Be
|
|
careful when assigning priorities to your own module destructors so they
|
|
won't interfere with the ones in the cc65 library.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.destructor ModuleDone
|
|
.destructor ModDone, 16
|
|
</verb></tscreen>
|
|
|
|
See the <tt><ref id=".CONDES" name=".CONDES"></tt> and <tt><ref
|
|
id=".CONSTRUCTOR" name=".CONSTRUCTOR"></tt> commands and the separate
|
|
section <ref id="condes" name="Module constructors/destructors"> explaining
|
|
the feature in more detail.
|
|
|
|
|
|
<sect1><tt>.DWORD</tt><label id=".DWORD"><p>
|
|
|
|
Define dword sized data (4 bytes) Must be followed by a sequence of
|
|
expressions.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.dword $12344512, $12FA489
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.ELSE</tt><label id=".ELSE"><p>
|
|
|
|
Conditional assembly: Reverse the current condition.
|
|
|
|
|
|
<sect1><tt>.ELSEIF</tt><label id=".ELSEIF"><p>
|
|
|
|
Conditional assembly: Reverse current condition and test a new one.
|
|
|
|
|
|
<sect1><tt>.END</tt><label id=".END"><p>
|
|
|
|
Forced end of assembly. Assembly stops at this point, even if the command
|
|
is read from an include file.
|
|
|
|
|
|
<sect1><tt>.ENDIF</tt><label id=".ENDIF"><p>
|
|
|
|
Conditional assembly: Close a <tt><ref id=".IF" name=".IF..."></tt> or
|
|
<tt><ref id=".ELSE" name=".ELSE"></tt> branch.
|
|
|
|
|
|
<sect1><tt>.ENDMAC, .ENDMACRO</tt><label id=".ENDMACRO"><p>
|
|
|
|
End of macro definition (see section <ref id="macros" name="Macros">).
|
|
|
|
|
|
<sect1><tt>.ENDPROC</tt><label id=".ENDPROC"><p>
|
|
|
|
End of local lexical level (see <tt><ref id=".PROC" name=".PROC"></tt>).
|
|
|
|
|
|
<sect1><tt>.ENDREP, .ENDREPEAT</tt><label id=".ENDREPEAT"><p>
|
|
|
|
End a <tt><ref id=".REPEAT" name=".REPEAT"></tt> block.
|
|
|
|
|
|
<sect1><tt>.ERROR</tt><label id=".ERROR"><p>
|
|
|
|
Force an assembly error. The assembler will output an error message
|
|
preceeded by "User error" and will <em/not/ produce an object file.
|
|
|
|
This command may be used to check for initial conditions that must be
|
|
set before assembling a source file.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.if foo = 1
|
|
...
|
|
.elseif bar = 1
|
|
...
|
|
.else
|
|
.error "Must define foo or bar!"
|
|
.endif
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".WARNING" name=".WARNING"></tt> and <tt><ref
|
|
id=".OUT" name=".OUT"></tt> directives.
|
|
|
|
|
|
<sect1><tt>.EXITMAC, .EXITMACRO</tt><label id=".EXITMACRO"><p>
|
|
|
|
Abort a macro expansion immidiately. This command is often useful in
|
|
recursive macros. See separate section <ref id="macros" name="Macros">.
|
|
|
|
|
|
<sect1><tt>.EXPORT</tt><label id=".EXPORT"><p>
|
|
|
|
Make symbols accessible from other modules. Must be followed by a comma
|
|
separated list of symbols to export.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.export foo, bar
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".EXPORTZP" name=".EXPORTZP"></tt>
|
|
|
|
|
|
<sect1><tt>.EXPORTZP</tt><label id=".EXPORTZP"><p>
|
|
|
|
Make symbols accessible from other modules. Must be followed by a comma
|
|
separated list of symbols to export. The exported symbols are explicitly
|
|
marked as zero page symols.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.exportzp foo, bar
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".EXPORT" name=".EXPORT"></tt>
|
|
|
|
|
|
<sect1><tt>.FARADDR</tt><label id=".FARADDR"><p>
|
|
|
|
Define far (24 bit) address data. The command must be followed by a
|
|
sequence of (not necessarily constant) expressions.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.faraddr DrawCircle, DrawRectangle, DrawHexagon
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".ADDR" name=".ADDR"></tt>
|
|
|
|
|
|
<sect1><tt>.FEATURE</tt><label id=".FEATURE"><p>
|
|
|
|
This directive may be used to enable one or more compatibility features
|
|
of the assembler. While the use of <tt/.FEATURE/ should be avoided when
|
|
possible, it may be useful when porting sources written for other
|
|
assemblers. There is no way to switch a feature off, once you have
|
|
enabled it, so using
|
|
|
|
<tscreen><verb>
|
|
.FEATURE xxx
|
|
</verb></tscreen>
|
|
|
|
will enable the feature until end of assembly is reached.
|
|
|
|
The following features are available:
|
|
|
|
<descrip>
|
|
|
|
<tag><tt>dollar_is_pc</tt></tag>
|
|
|
|
The dollar sign may be used as an alias for the star (`*'), which
|
|
gives the value of the current PC in expressions.
|
|
Note: Assignment to the pseudo variable is not allowed.
|
|
|
|
<tag><tt>labels_without_colons</tt></tag>
|
|
|
|
Allow labels without a trailing colon. These labels are only accepted,
|
|
if they start at the beginning of a line (no leading white space).
|
|
|
|
<tag><tt>loose_string_term</tt></tag>
|
|
|
|
Accept single quotes as well as double quotes as terminators for string
|
|
constants.
|
|
|
|
<tag><tt>loose_char_term</tt></tag>
|
|
|
|
Accept single quotes as well as double quotes as terminators for char
|
|
constants.
|
|
|
|
<tag><tt>at_in_identifiers</tt></tag>
|
|
|
|
Accept the at character (`@') as a valid character in identifiers. The
|
|
at character is not allowed to start an identifier, even with this
|
|
feature enabled.
|
|
|
|
<tag><tt>dollar_in_identifiers</tt></tag>
|
|
|
|
Accept the dollar sign (`$') as a valid character in identifiers. The
|
|
at character is not allowed to start an identifier, even with this
|
|
feature enabled.
|
|
|
|
<tag><tt>leading_dot_in_identifiers</tt></tag>
|
|
|
|
Accept the dot (`.') as the first character of an identifier. This may be
|
|
used for example to create macro names that start with a dot emulating
|
|
control directives of other assemblers. Note however, that none of the
|
|
reserved keywords built into the assembler, that starts with a dot, may be
|
|
overridden. When using this feature, you may also get into trouble if
|
|
later versions of the assembler define new keywords starting with a dot.
|
|
|
|
<tag><tt>pc_assignment</tt></tag>
|
|
|
|
Allow assignments to the PC symbol (`*' or `$' if <tt/dollar_is_pc/
|
|
is enabled). Such an assignment is handled identical to the <tt><ref
|
|
id=".ORG" name=".ORG"></tt> command (which is usually not needed, so just
|
|
removing the lines with the assignments may also be an option when porting
|
|
code written for older assemblers).
|
|
|
|
</descrip>
|
|
|
|
It is also possible to specify features on the command line using the
|
|
<tt><ref id="option--feature" name="--feature"></tt> command line option.
|
|
This is useful when translating sources written for older assemblers, when
|
|
you don't want to change the source code.
|
|
|
|
As an example, to translate sources written for Andre Fachats xa65
|
|
assembler, the features
|
|
|
|
<verb>
|
|
labels_without_colons, pc_assignment, loose_char_term
|
|
</verb>
|
|
|
|
may be helpful. They do not make ca65 completely compatible, so you may not
|
|
be able to translate the sources without changes, even when enabling these
|
|
features. However, I have found several sources that translate without
|
|
problems when enabling these features on the command line.
|
|
|
|
|
|
<sect1><tt>.FILEOPT, .FOPT</tt><label id=".FOPT"><p>
|
|
|
|
Insert an option string into the object file. There are two forms of
|
|
this command, one specifies the option by a keyword, the second
|
|
specifies it as a number. Since usage of the second one needs knowledge
|
|
of the internal encoding, its use is not recommended and I will only
|
|
describe the first form here.
|
|
|
|
The command is followed by one of the keywords
|
|
|
|
<tscreen><verb>
|
|
author
|
|
comment
|
|
compiler
|
|
</verb></tscreen>
|
|
|
|
a comma and a string. The option is written into the object file
|
|
together with the string value. This is currently unidirectional and
|
|
there is no way to actually use these options once they are in the
|
|
object file.
|
|
|
|
Examples:
|
|
|
|
<tscreen><verb>
|
|
.fileopt comment, "Code stolen from my brother"
|
|
.fileopt compiler, "BASIC 2.0"
|
|
.fopt author, "J. R. User"
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.FORCEIMPORT</tt><label id=".FORCEIMPORT"><p>
|
|
|
|
Import an absolute symbol from another module. The command is followed by a
|
|
comma separated list of symbols to import. The command is similar to <tt>
|
|
<ref id=".IMPORT" name=".IMPORT"></tt>, but the import reference is always
|
|
written to the generated object file, even if the symbol is never referenced
|
|
(<tt><ref id=".IMPORT" name=".IMPORT"></tt> will not generate import
|
|
references for unused symbols).
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.forceimport needthisone, needthistoo
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".IMPORT" name=".IMPORT"></tt>
|
|
|
|
|
|
<sect1><tt>.GLOBAL</tt><label id=".GLOBAL"><p>
|
|
|
|
Declare symbols as global. Must be followed by a comma separated list of
|
|
symbols to declare. Symbols from the list, that are defined somewhere in the
|
|
source, are exported, all others are imported. Additional <tt><ref
|
|
id=".IMPORT" name=".IMPORT"></tt> or <tt><ref id=".EXPORT"
|
|
name=".EXPORT"></tt> commands for the same symbol are allowed.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.global foo, bar
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.GLOBALZP</tt><label id=".GLOBALZP"><p>
|
|
|
|
Declare symbols as global. Must be followed by a comma separated list of
|
|
symbols to declare. Symbols from the list, that are defined somewhere in the
|
|
source, are exported, all others are imported. Additional <tt><ref
|
|
id=".IMPORTZP" name=".IMPORTZP"></tt> or <tt><ref id=".EXPORTZP"
|
|
name=".EXPORTZP"></tt> commands for the same symbol are allowed. The symbols
|
|
in the list are explicitly marked as zero page symols.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.globalzp foo, bar
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.I16</tt><label id=".I16"><p>
|
|
|
|
Valid only in 65816 mode. Switch the index registers to 16 bit.
|
|
|
|
Note: This command will not emit any code, it will tell the assembler to
|
|
create 16 bit operands for immediate operands.
|
|
|
|
See also the <tt><ref id=".I8" name=".I8"></tt> and <tt><ref id=".SMART"
|
|
name=".SMART"></tt> commands.
|
|
|
|
|
|
<sect1><tt>.I8</tt><label id=".I8"><p>
|
|
|
|
Valid only in 65816 mode. Switch the index registers to 8 bit.
|
|
|
|
Note: This command will not emit any code, it will tell the assembler to
|
|
create 8 bit operands for immediate operands.
|
|
|
|
See also the <tt><ref id=".I16" name=".I16"></tt> and <tt><ref id=".SMART"
|
|
name=".SMART"></tt> commands.
|
|
|
|
|
|
<sect1><tt>.IF</tt><label id=".IF"><p>
|
|
|
|
Conditional assembly: Evalute an expression and switch assembler output
|
|
on or off depending on the expression. The expression must be a constant
|
|
expression, that is, all operands must be defined.
|
|
|
|
A expression value of zero evaluates to FALSE, any other value evaluates
|
|
to TRUE.
|
|
|
|
|
|
<sect1><tt>.IFBLANK</tt><label id=".IFBLANK"><p>
|
|
|
|
Conditional assembly: Check if there are any remaining tokens in this line,
|
|
and evaluate to FALSE if this is the case, and to TRUE otherwise. If the
|
|
condition is not true, further lines are not assembled until an <tt><ref
|
|
id=".ELSE" name=".ESLE"></tt>, <tt><ref id=".ELSEIF" name=".ELSEIF"></tt> or
|
|
<tt><ref id=".ENDIF" name=".ENDIF"></tt> directive.
|
|
|
|
This command is often used to check if a macro parameter was given. Since an
|
|
empty macro parameter will evaluate to nothing, the condition will evaluate
|
|
to FALSE if an empty parameter was given.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.macro arg1, arg2
|
|
.ifblank arg2
|
|
lda #arg1
|
|
.else
|
|
lda #arg2
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
See also: <tt><ref id=".BLANK" name=".BLANK"></tt>
|
|
|
|
|
|
<sect1><tt>.IFCONST</tt><label id=".IFCONST"><p>
|
|
|
|
Conditional assembly: Evaluate an expression and switch assembler output
|
|
on or off depending on the constness of the expression.
|
|
|
|
A const expression evaluates to to TRUE, a non const expression (one
|
|
containing an imported or currently undefined symbol) evaluates to
|
|
FALSE.
|
|
|
|
See also: <tt><ref id=".CONST" name=".CONST"></tt>
|
|
|
|
|
|
<sect1><tt>.IFDEF</tt><label id=".IFDEF"><p>
|
|
|
|
Conditional assembly: Check if a symbol is defined. Must be followed by
|
|
a symbol name. The condition is true if the the given symbol is already
|
|
defined, and false otherwise.
|
|
|
|
See also: <tt><ref id=".DEFINED" name=".DEFINED"></tt>
|
|
|
|
|
|
<sect1><tt>.IFNBLANK</tt><label id=".IFNBLANK"><p>
|
|
|
|
Conditional assembly: Check if there are any remaining tokens in this line,
|
|
and evaluate to TRUE if this is the case, and to FALSE otherwise. If the
|
|
condition is not true, further lines are not assembled until an <tt><ref
|
|
id=".ELSE" name=".ELSE"></tt>, <tt><ref id=".ELSEIF" name=".ELSEIF"></tt> or
|
|
<tt><ref id=".ENDIF" name=".ENDIF"></tt> directive.
|
|
|
|
This command is often used to check if a macro parameter was given.
|
|
Since an empty macro parameter will evaluate to nothing, the condition
|
|
will evaluate to FALSE if an empty parameter was given.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.macro arg1, arg2
|
|
lda #arg1
|
|
.ifnblank arg2
|
|
lda #arg2
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
See also: <tt><ref id=".BLANK" name=".BLANK"></tt>
|
|
|
|
|
|
<sect1><tt>.IFNDEF</tt><label id=".IFNDEF"><p>
|
|
|
|
Conditional assembly: Check if a symbol is defined. Must be followed by
|
|
a symbol name. The condition is true if the the given symbol is not
|
|
defined, and false otherwise.
|
|
|
|
See also: <tt><ref id=".DEFINED" name=".DEFINED"></tt>
|
|
|
|
|
|
<sect1><tt>.IFNREF</tt><label id=".IFNREF"><p>
|
|
|
|
Conditional assembly: Check if a symbol is referenced. Must be followed
|
|
by a symbol name. The condition is true if if the the given symbol was
|
|
not referenced before, and false otherwise.
|
|
|
|
See also: <tt><ref id=".REFERENCED" name=".REFERENCED"></tt>
|
|
|
|
|
|
<sect1><tt>.IFP02</tt><label id=".IFP02"><p>
|
|
|
|
Conditional assembly: Check if the assembler is currently in 6502 mode
|
|
(see <tt><ref id=".P02" name=".P02"></tt> command).
|
|
|
|
|
|
<sect1><tt>.IFP816</tt><label id=".IFP816"><p>
|
|
|
|
Conditional assembly: Check if the assembler is currently in 65816 mode
|
|
(see <tt><ref id=".P816" name=".P816"></tt> command).
|
|
|
|
|
|
<sect1><tt>.IFPC02</tt><label id=".IFPC02"><p>
|
|
|
|
Conditional assembly: Check if the assembler is currently in 65C02 mode
|
|
(see <tt><ref id=".PC02" name=".PC02"></tt> command).
|
|
|
|
|
|
<sect1><tt>.IFREF</tt><label id=".IFREF"><p>
|
|
|
|
Conditional assembly: Check if a symbol is referenced. Must be followed
|
|
by a symbol name. The condition is true if if the the given symbol was
|
|
referenced before, and false otherwise.
|
|
|
|
This command may be used to build subroutine libraries in include files
|
|
(you may use separate object modules for this purpose too).
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.ifref ToHex ; If someone used this subroutine
|
|
ToHex: tay ; Define subroutine
|
|
lda HexTab,y
|
|
rts
|
|
.endif
|
|
</verb></tscreen>
|
|
|
|
See also: <tt><ref id=".REFERENCED" name=".REFERENCED"></tt>
|
|
|
|
|
|
<sect1><tt>.IMPORT</tt><label id=".IMPORT"><p>
|
|
|
|
Import a symbol from another module. The command is followed by a comma
|
|
separated list of symbols to import.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.import foo, bar
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".IMPORTZP" name=".IMPORTZP"></tt>
|
|
|
|
|
|
<sect1><tt>.IMPORTZP</tt><label id=".IMPORTZP"><p>
|
|
|
|
Import a symbol from another module. The command is followed by a comma
|
|
separated list of symbols to import. The symbols are explicitly imported
|
|
as zero page symbols (that is, symbols with values in byte range).
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.importzp foo, bar
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".IMPORT" name=".IMPORT"></tt>
|
|
|
|
|
|
<sect1><tt>.INCBIN</tt><label id=".INCBIN"><p>
|
|
|
|
Include a file as binary data. The command expects a string argument
|
|
that is the name of a file to include literally in the current segment.
|
|
In addition to that, a start offset and a size value may be specified,
|
|
separated by commas. If no size is specified, all of the file from the
|
|
start offset to end-of-file is used. If no start position is specified
|
|
either, zero is assume (which means that the whole file is inserted).
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
; Include whole file
|
|
.incbin "sprites.dat"
|
|
|
|
; Include file starting at offset 256
|
|
.incbin "music.dat", $100
|
|
|
|
; Read 100 bytes starting at offset 200
|
|
.incbin "graphics.dat", 200, 100
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.INCLUDE</tt><label id=".INCLUDE"><p>
|
|
|
|
Include another file. Include files may be nested up to a depth of 16.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.include "subs.inc"
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.LEFT</tt><label id=".LEFT"><p>
|
|
|
|
Builtin function. Extracts the left part of a given token list.
|
|
|
|
Syntax:
|
|
|
|
<tscreen><verb>
|
|
.LEFT (<int expr>, <token list>)
|
|
</verb></tscreen>
|
|
|
|
The first integer expression gives the number of tokens to extract from
|
|
the token list. The second argument is the token list itself.
|
|
|
|
Example:
|
|
|
|
To check in a macro if the given argument has a '#' as first token
|
|
(immidiate addressing mode), use something like this:
|
|
|
|
<tscreen><verb>
|
|
.macro ldax arg
|
|
...
|
|
.if (.match (.left (1, arg), #))
|
|
|
|
; ldax called with immidiate operand
|
|
...
|
|
|
|
.endif
|
|
...
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".MID" name=".MID"></tt> and <tt><ref id=".RIGHT"
|
|
name=".RIGHT"></tt> builtin functions.
|
|
|
|
|
|
<sect1><tt>.LINECONT</tt><label id=".LINECONT"><p>
|
|
|
|
Switch on or off line continuations using the backslash character
|
|
before a newline. The option is off by default.
|
|
Note: Line continuations do not work in a comment. A backslash at the
|
|
end of a comment is treated as part of the comment and does not trigger
|
|
line continuation.
|
|
The command must be followed by a '+' or '-' character to switch the
|
|
option on or off respectively.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.linecont + ; Allow line continuations
|
|
|
|
lda \
|
|
#$20 ; This is legal now
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.LIST</tt><label id=".LIST"><p>
|
|
|
|
Enable output to the listing. The command must be followed by a boolean
|
|
switch ("on", "off", "+" or "-") and will enable or disable listing
|
|
output.
|
|
The option has no effect if the listing is not enabled by the command line
|
|
switch -l. If -l is used, an internal counter is set to 1. Lines are output
|
|
to the listing file, if the counter is greater than zero, and suppressed if
|
|
the counter is zero. Each use of <tt/.LIST/ will increment or decrement the
|
|
counter.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.list on ; Enable listing output
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.LISTBYTES</tt><label id=".LISTBYTES"><p>
|
|
|
|
Set, how many bytes are shown in the listing for one source line. The
|
|
default is 12, so the listing will show only the first 12 bytes for any
|
|
source line that generates more than 12 bytes of code or data.
|
|
The directive needs an argument, which is either "unlimited", or an
|
|
integer constant in the range 4..255.
|
|
|
|
Examples:
|
|
|
|
<tscreen><verb>
|
|
.listbytes unlimited ; List all bytes
|
|
.listbytes 12 ; List the first 12 bytes
|
|
.incbin "data.bin" ; Include large binary file
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.LOCAL</tt><label id=".LOCAL"><p>
|
|
|
|
This command may only be used inside a macro definition. It declares a
|
|
list of identifiers as local to the macro expansion.
|
|
|
|
A problem when using macros are labels: Since they don't change their name,
|
|
you get a "duplicate symbol" error if the macro is expanded the second time.
|
|
Labels declared with <tt><ref id=".LOCAL" name=".LOCAL"></tt> have their
|
|
name mapped to an internal unique name (<tt/___ABCD__/) with each macro
|
|
invocation.
|
|
|
|
Some other assemblers start a new lexical block inside a macro expansion.
|
|
This has some drawbacks however, since that will not allow <em/any/ symbol
|
|
to be visible outside a macro, a feature that is sometimes useful. The
|
|
<tt><ref id=".LOCAL" name=".LOCAL"></tt> command is in my eyes a better way
|
|
to address the problem.
|
|
|
|
You get an error when using <tt><ref id=".LOCAL" name=".LOCAL"></tt> outside
|
|
a macro.
|
|
|
|
|
|
<sect1><tt>.LOCALCHAR</tt><label id=".LOCALCHAR"><p>
|
|
|
|
Defines the character that start "cheap" local labels. You may use one
|
|
of '@' and '?' as start character. The default is '@'.
|
|
|
|
Cheap local labels are labels that are visible only between two non
|
|
cheap labels. This way you can reuse identifiers like "<tt/loop/" without
|
|
using explicit lexical nesting.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.localchar '?'
|
|
|
|
Clear: lda #$00 ; Global label
|
|
?Loop: sta Mem,y ; Local label
|
|
dey
|
|
bne ?Loop ; Ok
|
|
rts
|
|
Sub: ... ; New global label
|
|
bne ?Loop ; ERROR: Unknown identifier!
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.MACPACK</tt><label id=".MACPACK"><p>
|
|
|
|
Insert a predefined macro package. The command is followed by an
|
|
identifier specifying the macro package to insert. Available macro
|
|
packages are:
|
|
|
|
<tscreen><verb>
|
|
generic Defines generic macros like add and sub.
|
|
longbranch Defines conditional long jump macros.
|
|
</verb></tscreen>
|
|
|
|
Including a macro package twice, or including a macro package that
|
|
redefines already existing macros will lead to an error.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.macpack longbranch ; Include macro package
|
|
|
|
cmp #$20 ; Set condition codes
|
|
jne Label ; Jump long on condition
|
|
</verb></tscreen>
|
|
|
|
Macro packages are explained in more detail in section <ref
|
|
id="macropackages" name="Macro packages">.
|
|
|
|
|
|
<sect1><tt>.MAC, .MACRO</tt><label id=".MAC"><p>
|
|
|
|
Start a classic macro definition. The command is followed by an identifier
|
|
(the macro name) and optionally by a comma separated list of identifiers
|
|
that are macro parameters.
|
|
|
|
See section <ref id="macros" name="Macros">.
|
|
|
|
|
|
<sect1><tt>.MATCH</tt><label id=".MATCH"><p>
|
|
|
|
Builtin function. Matches two token lists against each other. This is
|
|
most useful within macros, since macros are not stored as strings, but
|
|
as lists of tokens.
|
|
|
|
The syntax is
|
|
|
|
<tscreen><verb>
|
|
.MATCH(<token list #1>, <token list #2>)
|
|
</verb></tscreen>
|
|
|
|
Both token list may contain arbitrary tokens with the exception of the
|
|
terminator token (comma resp. right parenthesis) and
|
|
|
|
<itemize>
|
|
<item>end-of-line
|
|
<item>end-of-file
|
|
</itemize>
|
|
|
|
Often a macro parameter is used for any of the token lists.
|
|
|
|
Please note that the function does only compare tokens, not token
|
|
attributes. So any number is equal to any other number, regardless of the
|
|
actual value. The same is true for strings. If you need to compare tokens
|
|
<em/and/ token attributes, use the <tt><ref id=".XMATCH"
|
|
name=".XMATCH"></tt> function.
|
|
|
|
Example:
|
|
|
|
Assume the macro <tt/ASR/, that will shift right the accumulator by one,
|
|
while honoring the sign bit. The builtin processor instructions will allow
|
|
an optional "A" for accu addressing for instructions like <tt/ROL/ and
|
|
<tt/ROR/. We will use the <tt><ref id=".MATCH" name=".MATCH"></tt> function
|
|
to check for this and print and error for invalid calls.
|
|
|
|
<tscreen><verb>
|
|
.macro asr arg
|
|
|
|
.if (.not .blank(arg)) .and (.not .match (arg, a))
|
|
.error "Syntax error"
|
|
.endif
|
|
|
|
cmp #$80 ; Bit 7 into carry
|
|
lsr a ; Shift carry into bit 7
|
|
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
The macro will only accept no arguments, or one argument that must be the
|
|
reserved keyword "A".
|
|
|
|
See: <tt><ref id=".XMATCH" name=".XMATCH"></tt>
|
|
|
|
|
|
<sect1><tt>.MID</tt><label id=".MID"><p>
|
|
|
|
Builtin function. Takes a starting index, a count and a token list as
|
|
arguments. Will return part of the token list.
|
|
|
|
Syntax:
|
|
|
|
<tscreen><verb>
|
|
.MID (<int expr>, <int expr>, <token list>)
|
|
</verb></tscreen>
|
|
|
|
The first integer expression gives the starting token in the list (the
|
|
first token has index 0). The second integer expression gives the number
|
|
of tokens to extract from the token list. The third argument is the
|
|
token list itself.
|
|
|
|
Example:
|
|
|
|
To check in a macro if the given argument has a '<tt/#/' as first token
|
|
(immidiate addressing mode), use something like this:
|
|
|
|
<tscreen><verb>
|
|
.macro ldax arg
|
|
...
|
|
.if (.match (.mid (0, 1, arg), #))
|
|
|
|
; ldax called with immidiate operand
|
|
...
|
|
|
|
.endif
|
|
...
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".LEFT" name=".LEFT"></tt> and <tt><ref id=".RIGHT"
|
|
name=".RIGHT"></tt> builtin functions.
|
|
|
|
|
|
<sect1><tt>.ORG</tt><label id=".ORG"><p>
|
|
|
|
Start a section of absolute code. The command is followed by a constant
|
|
expression that gives the new PC counter location for which the code is
|
|
assembled. Use <tt><ref id=".RELOC" name=".RELOC"></tt> to switch back to
|
|
relocatable code.
|
|
|
|
Please note that you <em/do not need/ this command in most cases. Placing
|
|
code at a specific address is the job of the linker, not the assembler, so
|
|
there is usually no reason to assemble code to a specific address.
|
|
|
|
You may not switch segments while inside a section of absolute code.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.org $7FF ; Emit code starting at $7FF
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.OUT</tt><label id=".OUT"><p>
|
|
|
|
Output a string to the console without producing an error. This command
|
|
is similiar to <tt/.ERROR/, however, it does not force an assembler error
|
|
that prevents the creation of an object file.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.out "This code was written by the codebuster(tm)"
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".WARNING" name=".WARNING"></tt> and <tt><ref
|
|
id=".ERROR" name=".ERROR"></tt> directives.
|
|
|
|
|
|
<sect1><tt>.P02</tt><label id=".P02"><p>
|
|
|
|
Enable the 6502 instruction set, disable 65C02 and 65816 instructions.
|
|
This is the default if not overridden by the <tt/--cpu/ command line
|
|
option.
|
|
|
|
See: <tt><ref id=".PC02" name=".PC02"></tt> and <tt><ref id=".P816"
|
|
name=".P816"></tt>
|
|
|
|
|
|
<sect1><tt>.P816</tt><label id=".P816"><p>
|
|
|
|
Enable the 65816 instruction set. This is a superset of the 65C02 and
|
|
6502 instruction sets.
|
|
|
|
See: <tt><ref id=".P02" name=".P02"></tt> and <tt><ref id=".PC02"
|
|
name=".PC02"></tt>
|
|
|
|
|
|
<sect1><tt>.PAGELEN, .PAGELENGTH</tt><label id=".PAGELENGTH"><p>
|
|
|
|
Set the page length for the listing. Must be followed by an integer
|
|
constant. The value may be "unlimited", or in the range 32 to 127. The
|
|
statement has no effect if no listing is generated. The default value is -1
|
|
(unlimited) but may be overridden by the <tt/--pagelength/ command line
|
|
option. Beware: Since ca65 is a one pass assembler, the listing is generated
|
|
after assembly is complete, you cannot use multiple line lengths with one
|
|
source. Instead, the value set with the last <tt/.PAGELENGTH/ is used.
|
|
|
|
Examples:
|
|
|
|
<tscreen><verb>
|
|
.pagelength 66 ; Use 66 lines per listing page
|
|
|
|
.pagelength unlimited ; Unlimited page length
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.PARAMCOUNT</tt><label id=".PARAMCOUNT"><p>
|
|
|
|
This builtin pseudo variable is only available in macros. It is replaced by
|
|
the actual number of parameters that were given in the macro invocation.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.macro foo arg1, arg2, arg3
|
|
.if .paramcount <> 3
|
|
.error "Too few parameters for macro foo"
|
|
.endif
|
|
...
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
See section <ref id="macros" name="Macros">.
|
|
|
|
|
|
<sect1><tt>.PC02</tt><label id=".PC02"><p>
|
|
|
|
Enable the 65C02 instructions set. This instruction set includes all
|
|
6502 instructions.
|
|
|
|
See: <tt><ref id=".P02" name=".P02"></tt> and <tt><ref id=".P816"
|
|
name=".P816"></tt>
|
|
|
|
|
|
<sect1><tt>.POPSEG</tt><label id=".POPSEG"><p>
|
|
|
|
Pop the last pushed segment from the stack, and set it.
|
|
|
|
This command will switch back to the segment that was last pushed onto the
|
|
segment stack using the <tt><ref id=".PUSHSEG" name=".PUSHSEG"></tt>
|
|
command, and remove this entry from the stack.
|
|
|
|
The assembler will print an error message if the segment stack is empty
|
|
when this command is issued.
|
|
|
|
See: <tt><ref id=".PUSHSEG" name=".PUSHSEG"></tt>
|
|
|
|
|
|
<sect1><tt>.PROC</tt><label id=".PROC"><p>
|
|
|
|
Start a nested lexical level. All new symbols from now on are in the local
|
|
lexical level and are not accessible from outside. Symbols defined outside
|
|
this local level may be accessed as long as their names are not used for new
|
|
symbols inside the level. Symbols names in other lexical levels do not
|
|
clash, so you may use the same names for identifiers. The lexical level ends
|
|
when the <tt><ref id=".ENDPROC" name=".ENDPROC"></tt> command is read.
|
|
Lexical levels may be nested up to a depth of 16.
|
|
|
|
The command may be followed by an identifier, in this case the
|
|
identifier is declared in the outer level as a label having the value of
|
|
the program counter at the start of the lexical level.
|
|
|
|
Note: Macro names are always in the global level and in a separate name
|
|
space. There is no special reason for this, it's just that I've never
|
|
had any need for local macro definitions.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.proc Clear ; Define Clear subroutine, start new level
|
|
lda #$00
|
|
L1: sta Mem,y ; L1 is local and does not cause a
|
|
; duplicate symbol error if used in other
|
|
; places
|
|
dey
|
|
bne L1 ; Reference local symbol
|
|
rts
|
|
.endproc ; Leave lexical level
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".ENDPROC" name=".ENDPROC"></tt>
|
|
|
|
|
|
<sect1><tt>.PUSHSEG</tt><label id=".PUSHSEG"><p>
|
|
|
|
Push the currently active segment onto a stack. The entries on the stack
|
|
include the name of the segment and the segment type. The stack has a size
|
|
of 16 entries.
|
|
|
|
<tt/.PUSHSEG/ allows together with <tt><ref id=".POPSEG" name=".POPSEG"></tt>
|
|
to switch to another segment and to restore the old segment later, without
|
|
even knowing the name and type of the current segment.
|
|
|
|
The assembler will print an error message if the segment stack is already
|
|
full, when this command is issued.
|
|
|
|
See: <tt><ref id=".POPSEG" name=".POPSEG"></tt>
|
|
|
|
|
|
<sect1><tt>.REF, .REFERENCED</tt><label id=".REFERENCED"><p>
|
|
|
|
Builtin function. The function expects an identifier as argument in braces.
|
|
The argument is evaluated, and the function yields "true" if the identifier
|
|
is a symbol that has already been referenced somewhere in the source file up
|
|
to the current position. Otherwise the function yields false. As an example,
|
|
the <tt><ref id=".IFREF" name=".IFREF"></tt> statement may be replaced by
|
|
|
|
<tscreen><verb>
|
|
.if .referenced(a)
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".DEFINED" name=".DEFINED"></tt>
|
|
|
|
|
|
<sect1><tt>.REPEAT</tt><label id=".REPEAT"><p>
|
|
|
|
Repeat all commands between <tt/.REPEAT/ and <tt><ref id=".ENDREPEAT"
|
|
name=".ENDREPEAT"></tt> constant number of times. The command is followed by
|
|
a constant expression that tells how many times the commands in the body
|
|
should get repeated. Optionally, a comma and an identifier may be specified.
|
|
If this identifier is found in the body of the repeat statement, it is
|
|
replaced by the current repeat count (starting with zero for the first time
|
|
the body is repeated).
|
|
|
|
<tt/.REPEAT/ statements may be nested. If you use the same repeat count
|
|
identifier for a nested <tt/.REPEAT/ statement, the one from the inner
|
|
level will be used, not the one from the outer level.
|
|
|
|
Example:
|
|
|
|
The following macro will emit a string that is "encrypted" in that all
|
|
characters of the string are XORed by the value $55.
|
|
|
|
<tscreen><verb>
|
|
.macro Crypt Arg
|
|
.repeat .strlen(Arg), I
|
|
.byte .strat(Arg, I) .xor $55
|
|
.endrep
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".ENDREPEAT" name=".ENDREPEAT"></tt>
|
|
|
|
|
|
<sect1><tt>.RELOC</tt><label id=".RELOC"><p>
|
|
|
|
Switch back to relocatable mode. See the <tt><ref id=".ORG"
|
|
name=".ORG"></tt> command.
|
|
|
|
|
|
<sect1><tt>.RES</tt><label id=".RES"><p>
|
|
|
|
Reserve storage. The command is followed by one or two constant
|
|
expressions. The first one is mandatory and defines, how many bytes of
|
|
storage should be defined. The second, optional expression must by a
|
|
constant byte value that will be used as value of the data. If there
|
|
is no fill value given, the linker will use the value defined in the
|
|
linker configuration file (default: zero).
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
; Reserve 12 bytes of memory with value $AA
|
|
.res 12, $AA
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.RIGHT</tt><label id=".RIGHT"><p>
|
|
|
|
Builtin function. Extracts the right part of a given token list.
|
|
|
|
Syntax:
|
|
|
|
<tscreen><verb>
|
|
.RIGHT (<int expr>, <token list>)
|
|
</verb></tscreen>
|
|
|
|
The first integer expression gives the number of tokens to extract from
|
|
the token list. The second argument is the token list itself.
|
|
|
|
See also the <tt><ref id=".LEFT" name=".LEFT"></tt> and <tt><ref id=".MID"
|
|
name=".MID"></tt> builtin functions.
|
|
|
|
|
|
<sect1><tt>.RODATA</tt><label id=".RODATA"><p>
|
|
|
|
Switch to the RODATA segment. The name of the RODATA segment is always
|
|
"RODATA", so this is a shortcut for
|
|
|
|
<tscreen><verb>
|
|
.segment "RODATA"
|
|
</verb></tscreen>
|
|
|
|
The RODATA segment is a segment that is used by the compiler for
|
|
readonly data like string constants.
|
|
|
|
See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command.
|
|
|
|
|
|
<sect1><tt>.SEGMENT</tt><label id=".SEGMENT"><p>
|
|
|
|
Switch to another segment. Code and data is always emitted into a
|
|
segment, that is, a named section of data. The default segment is
|
|
"CODE". There may be up to 254 different segments per object file
|
|
(and up to 65534 per executable). There are shortcut commands for
|
|
the most common segments ("CODE", "DATA" and "BSS").
|
|
|
|
The command is followed by a string containing the segment name (there
|
|
are some constraints for the name - as a rule of thumb use only those
|
|
segment names that would also be valid identifiers). There may also be
|
|
an optional attribute separated by a comma. Valid attributes are
|
|
"<tt/zeropage/" and "<tt/absolute/".
|
|
|
|
When specifying a segment for the first time, "absolute" is the
|
|
default. For all other uses, the attribute specified the first time
|
|
is the default.
|
|
|
|
"absolute" means that this is a segment with absolute addressing. That
|
|
is, the segment will reside somewhere in core memory outside the zero
|
|
page. "zeropage" means the opposite: The segment will be placed in the
|
|
zero page and direct (short) addressing is possible for data in this
|
|
segment.
|
|
|
|
Beware: Only labels in a segment with the zeropage attribute are marked
|
|
as reachable by short addressing. The `*' (PC counter) operator will
|
|
work as in other segments and will create absolute variable values.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.segment "ROM2" ; Switch to ROM2 segment
|
|
.segment "ZP2", zeropage ; New direct segment
|
|
.segment "ZP2" ; Ok, will use last attribute
|
|
.segment "ZP2", absolute ; Error, redecl mismatch
|
|
</verb></tscreen>
|
|
|
|
See: <tt><ref id=".BSS" name=".BSS"></tt>, <tt><ref id=".CODE"
|
|
name=".CODE"></tt>, <tt><ref id=".DATA" name=".DATA"></tt> and <tt><ref
|
|
id=".RODATA" name=".RODATA"></tt>
|
|
|
|
|
|
<sect1><tt>.SMART</tt><label id=".SMART"><p>
|
|
|
|
Switch on or off smart mode. The command must be followed by a '+' or
|
|
'-' character to switch the option on or off respectively. The default
|
|
is off (that is, the assembler doesn't try to be smart), but this
|
|
default may be changed by the -s switch on the command line.
|
|
|
|
In smart mode the assembler will track usage of the <tt/REP/ and <tt/SEP/
|
|
instructions in 65816 mode and update the operand sizes accordingly. If
|
|
the operand of such an instruction cannot be evaluated by the assembler
|
|
(for example, because the operand is an imported symbol), a warning is
|
|
issued. Beware: Since the assembler cannot trace the execution flow this
|
|
may lead to false results in some cases. If in doubt, use the <tt/.Inn/ and
|
|
<tt/.Ann/ instructions to tell the assembler about the current settings.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.smart ; Be smart
|
|
.smart - ; Stop being smart
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.STRAT</tt><label id=".STRAT"><p>
|
|
|
|
Builtin function. The function accepts a string and an index as
|
|
arguments and returns the value of the character at the given position
|
|
as an integer value. The index is zero based.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.macro M Arg
|
|
; Check if the argument string starts with '#'
|
|
.if (.strat (Arg, 0) = '#')
|
|
...
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.STRING</tt><label id=".STRING"><p>
|
|
|
|
Builtin function. The function accepts an argument in braces and converts
|
|
this argument into a string constant. The argument may be an identifier, or
|
|
a constant numeric value.
|
|
|
|
Since you can use a string in the first place, the use of the function may
|
|
not be obvious. However, it is useful in macros, or more complex setups.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
; Emulate other assemblers:
|
|
.macro section name
|
|
.segment .string(name)
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.STRLEN</tt><label id=".STRLEN"><p>
|
|
|
|
Builtin function. The function accepts a string argument in braces and
|
|
eveluates to the length of the string.
|
|
|
|
Example:
|
|
|
|
The following macro encodes a string as a pascal style string with
|
|
a leading length byte.
|
|
|
|
<tscreen><verb>
|
|
.macro PString Arg
|
|
.byte .strlen(Arg), Arg
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.TCOUNT</tt><label id=".TCOUNT"><p>
|
|
|
|
Builtin function. The function accepts a token list in braces. The
|
|
function result is the number of tokens given as argument.
|
|
|
|
Example:
|
|
|
|
The <tt/ldax/ macro accepts the '#' token to denote immidiate addressing (as
|
|
with the normal 6502 instructions). To translate it into two separate 8 bit
|
|
load instructions, the '#' token has to get stripped from the argument:
|
|
|
|
<tscreen><verb>
|
|
.macro ldax arg
|
|
.if (.match (.mid (0, 1, arg), #))
|
|
; ldax called with immidiate operand
|
|
lda #<(.right (.tcount (arg)-1, arg))
|
|
ldx #>(.right (.tcount (arg)-1, arg))
|
|
.else
|
|
...
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.TIME</tt><label id=".TIME"><p>
|
|
|
|
Reading this pseudo variable will give a constant integer value that
|
|
represents the current time in POSIX standard (as seconds since the
|
|
Epoch).
|
|
|
|
It may be used to encode the time of translation somewhere in the created
|
|
code.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.dword .time ; Place time here
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.WARNING</tt><label id=".WARNING"><p>
|
|
|
|
Force an assembly warning. The assembler will output a warning message
|
|
preceeded by "User warning". This warning will always be output, even if
|
|
other warnings are disabled with the <tt><ref id="option-W" name="-W0"></tt>
|
|
command line option.
|
|
|
|
This command may be used to output possible problems when assembling
|
|
the source file.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.macro jne target
|
|
.local L1
|
|
.ifndef target
|
|
.warning "Forward jump in jne, cannot optimize!"
|
|
beq L1
|
|
jmp target
|
|
L1:
|
|
.else
|
|
...
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
See also the <tt><ref id=".ERROR" name=".ERROR"></tt> and <tt><ref id=".OUT"
|
|
name=".OUT"></tt> directives.
|
|
|
|
|
|
<sect1><tt>.WORD</tt><label id=".WORD"><p>
|
|
|
|
Define word sized data. Must be followed by a sequence of (word ranged,
|
|
but not necessarily constant) expressions.
|
|
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
.word $0D00, $AF13, _Clear
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.XMATCH</tt><label id=".XMATCH"><p>
|
|
|
|
Builtin function. Matches two token lists against each other. This is
|
|
most useful within macros, since macros are not stored as strings, but
|
|
as lists of tokens.
|
|
|
|
The syntax is
|
|
|
|
<tscreen><verb>
|
|
.XMATCH(<token list #1>, <token list #2>)
|
|
</verb></tscreen>
|
|
|
|
Both token list may contain arbitrary tokens with the exception of the
|
|
terminator token (comma resp. right parenthesis) and
|
|
|
|
<itemize>
|
|
<item>end-of-line
|
|
<item>end-of-file
|
|
</itemize>
|
|
|
|
Often a macro parameter is used for any of the token lists.
|
|
|
|
The function compares tokens <em/and/ token values. If you need a function
|
|
that just compares the type of tokens, have a look at the <tt><ref
|
|
id=".MATCH" name=".MATCH"></tt> function.
|
|
|
|
See: <tt><ref id=".MATCH" name=".MATCH"></tt>
|
|
|
|
|
|
<sect1><tt>.ZEROPAGE</tt><label id=".ZEROPAGE"><p>
|
|
|
|
Switch to the ZEROPAGE segment and mark it as direct (zeropage) segment.
|
|
The name of the ZEROPAGE segment is always "ZEROPAGE", so this is a
|
|
shortcut for
|
|
|
|
<tscreen><verb>
|
|
.segment "ZEROPAGE", zeropage
|
|
</verb></tscreen>
|
|
|
|
Because of the "zeropage" attribute, labels declared in this segment are
|
|
addressed using direct addressing mode if possible. You <em/must/ instruct
|
|
the linker to place this segment somewhere in the address range 0..$FF
|
|
otherwise you will get errors.
|
|
|
|
See: <tt><ref id=".SEGMENT" name=".SEGMENT"></tt>
|
|
|
|
|
|
|
|
<sect>Macros<label id="macros"><p>
|
|
|
|
|
|
<sect1>Introduction<p>
|
|
|
|
Macros may be thought of as "parametrized super instructions". Macros are
|
|
sequences of tokens that have a name. If that name is used in the source
|
|
file, the macro is "expanded", that is, it is replaced by the tokens that
|
|
were specified when the macro was defined.
|
|
|
|
|
|
<sect1>Macros without parameters<p>
|
|
|
|
In it's simplest form, a macro does not have parameters. Here's an
|
|
example:
|
|
|
|
<tscreen><verb>
|
|
.macro asr ; Arithmetic shift right
|
|
cmp #$80 ; Put bit 7 into carry
|
|
ror ; Rotate right with carry
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
The macro above consists of two real instructions, that are inserted into
|
|
the code, whenever the macro is expanded. Macro expansion is simply done
|
|
by using the name, like this:
|
|
|
|
<tscreen><verb>
|
|
lda $2010
|
|
asr
|
|
sta $2010
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>Parametrized macros<p>
|
|
|
|
When using macro parameters, macros can be even more useful:
|
|
|
|
<tscreen><verb>
|
|
.macro inc16 addr
|
|
clc
|
|
lda addr
|
|
adc #$01
|
|
sta addr
|
|
lda addr+1
|
|
adc #$00
|
|
sta addr+1
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
When calling the macro, you may give a parameter, and each occurence of
|
|
the name "addr" in the macro definition will be replaced by the given
|
|
parameter. So
|
|
|
|
<tscreen><verb>
|
|
inc16 $1000
|
|
</verb></tscreen>
|
|
|
|
will be expanded to
|
|
|
|
<tscreen><verb>
|
|
clc
|
|
lda $1000
|
|
adc #$01
|
|
sta $1000
|
|
lda $1000+1
|
|
adc #$00
|
|
sta $1000+1
|
|
</verb></tscreen>
|
|
|
|
A macro may have more than one parameter, in this case, the parameters
|
|
are separated by commas. You are free to give less parameters than the
|
|
macro actually takes in the definition. You may also leave intermediate
|
|
parameters empty. Empty parameters are replaced by empty space (that is,
|
|
they are removed when the macro is exanded). If you have a look at our
|
|
macro definition above, you will see, that replacing the "addr" parameter
|
|
by nothing will lead to wrong code in most lines. To help you, writing
|
|
macros with a variable parameter list, there are some control commands:
|
|
|
|
<tt><ref id=".IFBLANK" name=".IFBLANK"></tt> tests the rest of the line and
|
|
returns true, if there are any tokens on the remainder of the line. Since
|
|
empty parameters are replaced by nothing, this may be used to test if a given
|
|
parameter is empty. <tt><ref id=".IFNBLANK" name=".IFNBLANK"></tt> tests the
|
|
opposite.
|
|
|
|
Look at this example:
|
|
|
|
<tscreen><verb>
|
|
.macro ldaxy a, x, y
|
|
.ifnblank a
|
|
lda #a
|
|
.endif
|
|
.ifnblank x
|
|
ldx #x
|
|
.endif
|
|
.ifnblank y
|
|
ldy #y
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
This macro may be called as follows:
|
|
|
|
<tscreen><verb>
|
|
ldaxy 1, 2, 3 ; Load all three registers
|
|
|
|
ldaxy 1, , 3 ; Load only a and y
|
|
|
|
ldaxy , , 3 ; Load y only
|
|
</verb></tscreen>
|
|
|
|
There's another helper command for determining, which macro parameters are
|
|
valid: <tt><ref id=".PARAMCOUNT" name=".PARAMCOUNT"></tt> This command is
|
|
replaced by the parameter count given, <em/including/ intermediate empty macro
|
|
parameters:
|
|
|
|
<tscreen><verb>
|
|
ldaxy 1 ; .PARAMCOUNT = 1
|
|
ldaxy 1,,3 ; .PARAMCOUNT = 3
|
|
ldaxy 1,2 ; .PARAMCOUNT = 2
|
|
ldaxy 1, ; .PARAMCOUNT = 2
|
|
ldaxy 1,2,3 ; .PARAMCOUNT = 3
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>Recursive macros<p>
|
|
|
|
Macros may be used recursively:
|
|
|
|
<tscreen><verb>
|
|
.macro push r1, r2, r3
|
|
lda r1
|
|
pha
|
|
.if .paramcount > 1
|
|
push r2, r3
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
There's also a special macro to help writing recursive macros: <tt><ref
|
|
id=".EXITMACRO" name=".EXITMACRO"></tt> This command will stop macro expansion
|
|
immidiately:
|
|
|
|
<tscreen><verb>
|
|
.macro push r1, r2, r3, r4, r5, r6, r7
|
|
.ifblank r1
|
|
; First parameter is empty
|
|
.exitmacro
|
|
.else
|
|
lda r1
|
|
pha
|
|
.endif
|
|
push r2, r3, r4, r5, r6, r7
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
When expanding this macro, the expansion will push all given parameters
|
|
until an empty one is encountered. The macro may be called like this:
|
|
|
|
<tscreen><verb>
|
|
push $20, $21, $32 ; Push 3 ZP locations
|
|
push $21 ; Push one ZP location
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>Local symbols inside macros<p>
|
|
|
|
Now, with recursive macros, <tt><ref id=".IFBLANK" name=".IFBLANK"></tt> and
|
|
<tt><ref id=".PARAMCOUNT" name=".PARAMCOUNT"></tt>, what else do you need?
|
|
Have a look at the inc16 macro above. Here is it again:
|
|
|
|
<tscreen><verb>
|
|
.macro inc16 addr
|
|
clc
|
|
lda addr
|
|
adc #$01
|
|
sta addr
|
|
lda addr+1
|
|
adc #$00
|
|
sta addr+1
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
If you have a closer look at the code, you will notice, that it could be
|
|
written more efficiently, like this:
|
|
|
|
<tscreen><verb>
|
|
.macro inc16 addr
|
|
inc addr
|
|
bne Skip
|
|
inc addr+1
|
|
Skip:
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
But imagine what happens, if you use this macro twice? Since the label
|
|
"Skip" has the same name both times, you get a "duplicate symbol" error.
|
|
Without a way to circumvent this problem, macros are not as useful, as
|
|
they could be. One solution is, to start a new lexical block inside the
|
|
macro:
|
|
|
|
<tscreen><verb>
|
|
.macro inc16 addr
|
|
.proc
|
|
inc addr
|
|
bne Skip
|
|
inc addr+1
|
|
Skip:
|
|
.endproc
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
Now the label is local to the block and not visible outside. However,
|
|
sometimes you want a label inside the macro to be visible outside. To make
|
|
that possible, there's a new command that's only usable inside a macro
|
|
definition: <tt><ref id=".LOCAL" name=".LOCAL"></tt>. <tt/.LOCAL/ declares one
|
|
or more symbols as local to the macro expansion. The names of local variables
|
|
are replaced by a unique name in each separate macro expansion. So we could
|
|
also solve the problem above by using <tt/.LOCAL/:
|
|
|
|
<tscreen><verb>
|
|
.macro inc16 addr
|
|
.local Skip ; Make Skip a local symbol
|
|
clc
|
|
lda addr
|
|
adc #$01
|
|
sta addr
|
|
bcc Skip
|
|
inc addr+1
|
|
Skip: ; Not visible outside
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>C style macros<p>
|
|
|
|
Starting with version 2.5 of the assembler, there is a second macro type
|
|
available: C style macros using the <tt/.DEFINE/ directive. These macros are
|
|
similar to the classic macro type described above, but behaviour is sometimes
|
|
different:
|
|
|
|
<itemize>
|
|
|
|
<item> Macros defined with <tt><ref id=".DEFINE" name=".DEFINE"></tt> may not
|
|
span more than a line. You may use line continuation (see <tt><ref
|
|
id=".LINECONT" name=".LINECONT"></tt>) to spread the definition over
|
|
more than one line for increased readability, but the macro itself
|
|
may not contain an end-of-line token.
|
|
|
|
<item> Macros defined with <tt><ref id=".DEFINE" name=".DEFINE"></tt> share
|
|
the name space with classic macros, but they are detected and replaced
|
|
at the scanner level. While classic macros may be used in every place,
|
|
where a mnemonic or other directive is allowed, <tt><ref id=".DEFINE"
|
|
name=".DEFINE"></tt> style macros are allowed anywhere in a line. So
|
|
they are more versatile in some situations.
|
|
|
|
<item> <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros may take
|
|
parameters. While classic macros may have empty parameters, this is
|
|
not true for <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros.
|
|
For this macro type, the number of actual parameters must match
|
|
exactly the number of formal parameters.
|
|
|
|
To make this possible, formal parameters are enclosed in braces when
|
|
defining the macro. If there are no parameters, the empty braces may
|
|
be omitted.
|
|
|
|
<item> Since <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros may not
|
|
contain end-of-line tokens, there are things that cannot be done. They
|
|
may not contain several processor instructions for example. So, while
|
|
some things may be done with both macro types, each type has special
|
|
usages. The types complement each other.
|
|
|
|
</itemize>
|
|
|
|
Let's look at a few examples to make the advantages and disadvantages
|
|
clear.
|
|
|
|
To emulate assemblers that use "<tt/EQU/" instead of "<tt/=/" you may use the
|
|
following <tt/.DEFINE/:
|
|
|
|
<tscreen><verb>
|
|
.define EQU =
|
|
|
|
foo EQU $1234 ; This is accepted now
|
|
</verb></tscreen>
|
|
|
|
You may use the directive to define string constants used elsewhere:
|
|
|
|
<tscreen><verb>
|
|
; Define the version number
|
|
.define VERSION "12.3a"
|
|
|
|
; ... and use it
|
|
.asciiz VERSION
|
|
</verb></tscreen>
|
|
|
|
Macros with parameters may also be useful:
|
|
|
|
<tscreen><verb>
|
|
.define DEBUG(message) .out message
|
|
|
|
DEBUG "Assembling include file #3"
|
|
</verb></tscreen>
|
|
|
|
Note that, while formal parameters have to be placed in braces, this is
|
|
not true for the actual parameters. Beware: Since the assembler cannot
|
|
detect the end of one parameter, only the first token is used. If you
|
|
don't like that, use classic macros instead:
|
|
|
|
<tscreen><verb>
|
|
.macro message
|
|
.out message
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
(This is an example where a problem can be solved with both macro types).
|
|
|
|
|
|
<sect1>Characters in macros<p>
|
|
|
|
When using the <ref id="option-t" name="-t"> option, characters are translated
|
|
into the target character set of the specific machine. However, this happens
|
|
as late as possible. This means that strings are translated if they are part
|
|
of a <tt><ref id=".BYTE" name=".BYTE"></tt> or <tt><ref id=".ASCIIZ"
|
|
name=".ASCIIZ"></tt> command. Characters are translated as soon as they are
|
|
used as part of an expression.
|
|
|
|
This behaviour is very intuitive outside of macros but may be confusing when
|
|
doing more complex macros. If you compare characters against numeric values,
|
|
be sure to take the translation into account.
|
|
|
|
|
|
|
|
|
|
<sect>Macro packages<label id="macropackages"><p>
|
|
|
|
Using the <tt><ref id=".MACPACK" name=".MACPACK"></tt> directive, predefined
|
|
macro packages may be included with just one command. Available macro packages
|
|
are:
|
|
|
|
|
|
<sect1><tt>.MACPACK generic</tt><p>
|
|
|
|
This macro package defines macros that are useful in almost any program.
|
|
Currently, two macros are defined:
|
|
|
|
<tscreen><verb>
|
|
.macro add Arg
|
|
clc
|
|
adc Arg
|
|
.endmacro
|
|
|
|
.macro sub Arg
|
|
sec
|
|
sbc Arg
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>.MACPACK longbranch</tt><p>
|
|
|
|
This macro package defines long conditional jumps. They are named like the
|
|
short counterpart but with the 'b' replaced by a 'j'. Here is a sample
|
|
definition for the "<tt/jeq/" macro, the other macros are built using the same
|
|
scheme:
|
|
|
|
<tscreen><verb>
|
|
.macro jeq Target
|
|
.if .def(Target) .and ((*+2)-(Target) <= 127)
|
|
beq Target
|
|
.else
|
|
bne *+5
|
|
jmp Target
|
|
.endif
|
|
.endmacro
|
|
</verb></tscreen>
|
|
|
|
All macros expand to a short branch, if the label is already defined (back
|
|
jump) and is reachable with a short jump. Otherwise the macro expands to a
|
|
conditional branch with the branch condition inverted, followed by an absolute
|
|
jump to the actual branch target.
|
|
|
|
The package defines the following macros:
|
|
|
|
<tscreen><verb>
|
|
jeq, jne, jmi, jpl, jcs, jcc, jvs, jvc
|
|
</verb></tscreen>
|
|
|
|
|
|
|
|
<sect>Module constructors/destructors<label id="condes"><p>
|
|
|
|
<em>Note:</em> This section applies mostly to C programs, so the explanation
|
|
below uses examples from the C libraries. However, the feature may also be
|
|
useful for assembler programs.
|
|
|
|
|
|
<sect1>Module overview<p>
|
|
|
|
Using the <tt><ref id=".CONSTRUCTOR" name=".CONSTRUCTOR"></tt> and <tt><ref
|
|
id=".DESTRUCTOR" name=".DESTRUCTOR"></tt> keywords it it possible to export
|
|
functions in a special way. The linker is able to generate tables with all
|
|
functions of a specific type. Such a table will <em>only</em> include symbols
|
|
from object files that are linked into a specific executable. This may be used
|
|
to add initialization and cleanup code for library modules.
|
|
|
|
The C heap functions are an example where module initialization code is used.
|
|
All heap functions (<tt>malloc</tt>, <tt>free</tt>, ...) work with a few
|
|
variables that contain the start and the end of the heap, pointers to the free
|
|
list and so on. Since the end of the heap depends on the size and start of the
|
|
stack, it must be initialized at runtime. However, initializing these
|
|
variables for programs that do not use the heap are a waste of time and
|
|
memory.
|
|
|
|
So the central module defines a function that contains initialization code and
|
|
exports this function using the <tt/.CONSTRUCTOR/ statement. If (and only if)
|
|
this module is added to an executable by the linker, the initialization
|
|
function will be placed into the table of constructors by the linker. The C
|
|
startup code will call all constructors before <tt/main/ and all destructors
|
|
after <tt/main/, so without any further work, the heap initialization code is
|
|
called once the module is linked in.
|
|
|
|
While it would be possible to add explicit calls to initialization functions
|
|
in the startup code, the new approach has several advantages:
|
|
|
|
<enum>
|
|
<item>
|
|
If a module is not included, the initialization code is not linked in and not
|
|
called. So you don't pay for things you don't need.
|
|
|
|
<item>
|
|
Adding another library that needs initialization does not mean that the
|
|
startup code has to be changed. Before we had module constructors and
|
|
destructors, the startup code for all systems had to be adjusted to call the
|
|
new initialization code.
|
|
|
|
<item>
|
|
The feature saves memory: Each additional initialization function needs just
|
|
two bytes in the table (a pointer to the function).
|
|
|
|
</enum>
|
|
|
|
|
|
<sect1>Pitfalls<p>
|
|
|
|
When creating and using module constructors and destructors, please take care
|
|
of the following:
|
|
|
|
<itemize>
|
|
|
|
<item>
|
|
The linker will only generate function tables, it will not generate code to
|
|
call these functions. If you're using the feature in some other than the
|
|
existing C environments, you have to write code to call all functions in a
|
|
linker generated table yourself. See the <tt>condes</tt> module in the C
|
|
runtime for an example on how to do this.
|
|
|
|
<item>
|
|
The linker will only add addresses of functions that are in modules linked to
|
|
the executable. This means that you have to be careful where to place the
|
|
condes functions. If initialization is needed for a group of functions, be
|
|
sure to place the initialization function into a module that is linked in
|
|
regardless of which function is called by the user.
|
|
|
|
<item>
|
|
The linker will generate the tables only when requested to do so by the
|
|
<tt/FEATURE CONDES/ statement in the linker config file. Each table has to
|
|
be requested separately.
|
|
|
|
<item>
|
|
Constructors and destructors may have priorities. These priorities determine
|
|
the order of the functions in the table. If your intialization or cleanup code
|
|
does depend on other initialization or cleanup code, you have to choose the
|
|
priority for the functions accordingly.
|
|
|
|
<item>
|
|
Besides the <tt><ref id=".CONSTRUCTOR" name=".CONSTRUCTOR"></tt> and <tt><ref
|
|
id=".DESTRUCTOR" name=".DESTRUCTOR"></tt> statements, there is also a more
|
|
generic command: <tt><ref id=".CONDES" name=".CONDES"></tt>. This allows to
|
|
specify an additional type. Predefined types are 0 (constructor) and 1
|
|
(destructor). The linker generates a separate table for each type on request.
|
|
|
|
</itemize>
|
|
|
|
|
|
|
|
|
|
|
|
<sect>Bugs/Feedback<p>
|
|
|
|
If you have problems using the assembler, if you find any bugs, or if
|
|
you're doing something interesting with the assembler, I would be glad to
|
|
hear from you. Feel free to contact me by email
|
|
(<htmlurl url="mailto:uz@cc65.org" name="uz@cc65.org">).
|
|
|
|
|
|
|
|
<sect>Copyright<p>
|
|
|
|
ca65 (and all cc65 binutils) are (C) Copyright 1998-2001 Ullrich von
|
|
Bassewitz. For usage of the binaries and/or sources the following
|
|
conditions do apply:
|
|
|
|
This software is provided 'as-is', without any expressed or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
<enum>
|
|
<item> The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
<item> Altered source versions must be plainly marked as such, and must not
|
|
be misrepresented as being the original software.
|
|
<item> This notice may not be removed or altered from any source
|
|
distribution.
|
|
</enum>
|
|
|
|
|
|
|
|
</article>
|
|
|
|
|
|
|