<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
+<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
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 necessary for the
+<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).
---------------------------------------------------------------------------
Usage: ca65 [options] file
Short options:
- -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
-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
+ -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
+ --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
+ --listing Create a listing if assembly was ok
--pagelength n Set the page length for the listing
- --smart Enable smart mode
+ --smart Enable smart mode
--target sys Set the target system
- --verbose Increase verbosity
+ --verbose Increase verbosity
--version Print the assembler version
---------------------------------------------------------------------------
</verb></tscreen>
<descrip>
+ <label id="option--cpu">
<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
+ 6502, 65SC02, 65C02, 65816 and sunplus
- The latter (sunplus) is not available in the freeware version, because the
- instruction set of the sunplus CPU is "confidential".
+ The last one (sunplus) is not available in the freeware version, because the
+ instruction set of the sunplus CPU is "proprietary and confidential".
<label id="option--feature">
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
<sect>Input format<p>
+<sect1>Assembler syntax<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
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.
+The assembler accepts
+
+<itemize>
+<item>all valid 6502 mnemonics when in 6502 mode (the default or after the
+ <tt><ref id=".P02" name=".P02"></tt> command was given).
+<item>all valid 65SC02 mnemonics when in 65SC02 mode (after the
+ <tt><ref id=".PSC02" name=".PSC02"></tt> command was given).
+<item>all valid 65C02 mnemonics when in 65C02 mode (after the
+ <tt><ref id=".PC02" name=".PC02"></tt> command was given).
+<item>all valid 65618 mnemonics when in 65816 mode (after the
+ <tt><ref id=".P816" name=".P816"></tt> command was given).
+<item>all valid SunPlus mnemonics when in SunPlus mode (after the
+ <tt><ref id=".SUNPLUS" name=".SUNPLUS"></tt> command was given).
+</itemize>
+
+
+<sect1>65816 mode<p>
In 65816 mode several aliases are accepted in addition to the official
mnemonics:
jsl 3.$1234 ; Call subroutine at $1234 in bank 3
</verb></tscreen>
+<sect1>Number format<p>
+
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>
+
+
+<sect1>Conditional assembly<p>
+
+Please note that when using the conditional directives (<tt/.IF/ and friends),
+the input must consist of valid assembler tokens, even in <tt/.IF/ branches
+that are not assembled. The reason for this behaviour is that the assembler
+must still be able to detect the ending tokens (like <tt/.ENDIF/), so
+conversion of the input stream into tokens still takes place. As a consequence
+conditional assembly directives may <bf/not/ be used to prevent normal text
+(used as a comment or similar) from being assembled. <p>
<sect>Expressions<p>
not evaluated.
-<sect1>Available operators<p>
+<sect1>Available operators<label id="operators"><p>
Available operators sorted by precedence:
.DEFINED Builtin function 1
.MATCH Builtin function 1
.TCOUNT Builtin function 1
+ .TIME Builtin function 1
+ .VERSION Builtin function 1
.XMATCH Builtin function 1
.PARAMCOUNT Builtin pseudo variable (r/o) 1
.REFERENCED Builtin function 1
.BITAND Bitwise and 2
^ Bitwise xor 2
.BITXOR Bitwise xor 2
- << Shift left operator 2
+ << Shift left operator 2
.SHL Shift left operator 2
>> Shift right operator
.SHR Shift right operator 2
<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 know outside and cannot be accessed from
+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>
changed by the <tt><ref id=".LOCALCHAR" name=".LOCALCHAR"></tt>
directive).
-Cheap local labels are visible only between two no 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.
+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:
dey
bne @Loop ; Ok
rts
- Sub: ... ; New global label
- bne @Loop ; ERROR: Unknown identifier!
+ Sub: ... ; New global label
+ bne @Loop ; ERROR: Unknown identifier!
</verb></tscreen>
<sect1>Unnamed labels<p>
<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/.FARADDR/. The command must be followed by a
- sequence of (not necessarily constant) expressions.
+ 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:
.addr $0D00, $AF13, _Clear
</verb></tscreen>
- See: <tt><ref id=".FARADDR" name=".FARADDR"></tt>
+ See: <tt><ref id=".FARADDR" name=".FARADDR"></tt>, <tt><ref id=".WORD"
+ name=".WORD"></tt>
<sect1><tt>.ALIGN</tt><label id=".ALIGN"><p>
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 followd by a plus or a minus character. When switched on (using a
+ 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
See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command.
-<sect1><tt>.BYTE</tt><label id=".BYTE"><p>
+<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 world", $0D, $00
+ .byte "Hello "
+ .byt "world", $0D, $00
</verb></tscreen>
Example:
<tscreen><verb>
- .case - ; Identifiers are not case sensitive
+ .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>
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.
+ After the type, an optional priority may be specified. Higher numeric values
+ mean higher priority. 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
+ .condes ModuleInit, constructor
+ .condes ModInit, 0, 16
</verb></tscreen>
See the <tt><ref id=".CONSTRUCTOR" name=".CONSTRUCTOR"></tt> and <tt><ref
Example:
<tscreen><verb>
- .include .concat ("myheader", ".", "inc)
+ .include .concat ("myheader", ".", "inc")
</verb></tscreen>
This is the same as the command
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.
+ comma. Higher numeric values mean a higher priority. 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:
<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>
+ tells which CPU is currently enabled. It can also tell which instruction
+ set the CPU is able to translate. The value read from the pseudo variable
+ should be further examined by using one of the constants defined by the
+ "cpu" macro package (see <tt/<ref id=".MACPACK" name=".MACPACK">/).
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
+ .macpack cpu
+ .if (.cpu .bitand CPU_ISET_65816)
+ phx
+ phy
+ .else
+ txa
+ pha
+ tya
+ pha
+ .endif
</verb></tscreen>
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.
+ comma. Higher numerical values mean a higher priority. 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:
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/
</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
(see <tt><ref id=".PC02" name=".PC02"></tt> command).
+<sect1><tt>.IFPSC02</tt><label id=".IFPSC02"><p>
+
+ Conditional assembly: Check if the assembler is currently in 65SC02 mode
+ (see <tt><ref id=".PSC02" name=".PSC02"></tt> command).
+
+
<sect1><tt>.IFREF</tt><label id=".IFREF"><p>
Conditional assembly: Check if a symbol is referenced. Must be followed
Example:
<tscreen><verb>
- .includezp foo, bar
+ .importzp foo, bar
</verb></tscreen>
See: <tt><ref id=".IMPORT" name=".IMPORT"></tt>
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>
- .incbin "sprites.dat"
+ ; 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>
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.
+ cbm Defines the scrcode macro
+ cpu Defines constants for the .CPU variable
+ </verb></tscreen>
Including a macro package twice, or including a macro package that
redefines already existing macros will lead to an error.
jne Label ; Jump long on condition
</verb></tscreen>
- See section <ref id="macros" name="Macros">).
+ Macro packages are explained in more detail in section <ref
+ id="macropackages" name="Macro packages">.
<sect1><tt>.MAC, .MACRO</tt><label id=".MAC"><p>
(the macro name) and optionally by a comma separated list of identifiers
that are macro parameters.
- See section <ref id="macros" name="Macros">).
+ See section <ref id="macros" name="Macros">.
<sect1><tt>.MATCH</tt><label id=".MATCH"><p>
.endif
cmp #$80 ; Bit 7 into carry
- lsr a ; Shit carry into bit 7
+ lsr a ; Shift carry into bit 7
.endmacro
</verb></tscreen>
<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.
+ Enable the 6502 instruction set, disable 65SC02, 65C02 and 65816
+ instructions. This is the default if not overridden by the
+ <tt><ref id="option--cpu" name="--cpu"></tt> command line option.
- See: <tt><ref id=".PC02" name=".PC02"></tt> and <tt><ref id=".P816"
- name=".P816"></tt>
+ See: <tt><ref id=".PC02" name=".PC02"></tt>, <tt><ref id=".PSC02"
+ name=".PSC02"></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
+ Enable the 65816 instruction set. This is a superset of the 65SC02 and
6502 instruction sets.
- See: <tt><ref id=".P02" name=".P02"></tt> and <tt><ref id=".PC02"
- name=".PC02"></tt>
+ See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02"
+ name=".PSC02"></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 but may be overridden by the <tt/--pagelength/ command line option.
- Beware: Since 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.
+ 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:
.endmacro
</verb></tscreen>
- See section <ref id="macros" name="Macros">).
+ 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.
+ 6502 and 65SC02 instructions.
+
+ See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02"
+ name=".PSC02"></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.
- See: <tt><ref id=".P02" name=".P02"></tt> and <tt><ref id=".P816"
- name=".P816"></tt>
+ 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>
dey
bne L1 ; Reference local symbol
rts
- .endproc ; Leave lexical level
+ .endproc ; Leave lexical level
</verb></tscreen>
See: <tt><ref id=".ENDPROC" name=".ENDPROC"></tt>
+<sect1><tt>.PSC02</tt><label id=".PSC02"><p>
+
+ Enable the 65SC02 instructions set. This instruction set includes all
+ 6502 instructions.
+
+ See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PC02"
+ name=".PC02"></tt> and <tt><ref id=".P816" name=".P816"></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.
<tscreen><verb>
.macro Crypt Arg
- .repeat strlen(Arg), I
- .byte strat(Arg, I) .xor $55
+ .repeat .strlen(Arg), I
+ .byte .strat(Arg, I) .xor $55
.endrep
.endmacro
</verb></tscreen>
id=".RODATA" name=".RODATA"></tt>
+<sect1><tt>.SETCPU</tt><label id=".SETCPU"><p>
+
+ Switch the CPU instruction set. The command is followed by a string that
+ specifies the CPU. Possible values are those that can also be supplied to
+ the <tt><ref id="option--cpu" name="--cpu"></tt> command line option,
+ namely: 6502, 65SC02, 65C02, 65816 and sunplus. Please note that support
+ for the sunplus CPU is not available in the freeware version, because the
+ instruction set of the sunplus CPU is "proprietary and confidential".
+
+ See: <tt><ref id=".CPU" name=".CPU"></tt>,
+ <tt><ref id=".IFP02" name=".IFP02"></tt>,
+ <tt><ref id=".IFP816" name=".IFP816"></tt>,
+ <tt><ref id=".IFPC02" name=".IFPC02"></tt>,
+ <tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
+ <tt><ref id=".P02" name=".P02"></tt>,
+ <tt><ref id=".P816" name=".P816"></tt>,
+ <tt><ref id=".PC02" name=".PC02"></tt>,
+ <tt><ref id=".PSC02" name=".PSC02"></tt>
+
+
<sect1><tt>.SMART</tt><label id=".SMART"><p>
Switch on or off smart mode. The command must be followed by a '+' or
</verb></tscreen>
+<sect1><tt>.SUNPLUS</tt><label id=".SUNPLUS"><p>
+
+ Enable the SunPlus instructions set. This command will not work in the
+ freeware version of the assembler, because the instruction set is
+ "proprietary and confidential".
+
+ See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02"
+ name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, and
+ <tt><ref id=".P816" name=".P816"></tt>
+
+
<sect1><tt>.TCOUNT</tt><label id=".TCOUNT"><p>
Builtin function. The function accepts a token list in braces. The
<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
+ .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>.VERSION</tt><label id=".VERSION"><p>
+
+ Reading this pseudo variable will give the assembler version according to
+ the following formula:
+
+ VER_MAJOR*$100 + VER_MINOR*$10 + VER_PATCH
+
+ It may be used to encode the assembler version or check the assembler for
+ special features not available with older versions.
+
+ Example:
+
+ Version 2.11.1 of the assembler will return $2B1 as numerical constant when
+ reading the pseudo variable <tt/.VERSION/.
+
+
<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/-W0/ command line option.
+ 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.
<tscreen><verb>
.macro inc16 addr
clc
- lda addr
+ lda addr
adc #$01
sta addr
lda addr+1
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
+ .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
- clc
- lda addr
- adc #$01
- sta addr
- bcc Skip
- inc addr+1
- Skip:
- .endmacro
+ .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
<tscreen><verb>
.macro inc16 addr
.proc
- clc
- lda addr
- adc #$01
- sta addr
- bcc Skip
- inc addr+1
+ inc addr
+ bne Skip
+ inc addr+1
Skip:
.endproc
.endmacro
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 speified above, but behaviour is sometimes
+similar to the classic macro type described above, but behaviour is sometimes
different:
<itemize>
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
- does not contain an end-of-line token.
+ 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
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. With macros, it will
-lead sometimes to problems, since the exact time of translation depends on the
-exact use.
-
+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<p>
+<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
+<sect1><tt>.MACPACK cbm</tt><p>
+
+The cbm macro package will define a macro named <tt/scrcode/. It takes a
+string as argument and places this string into memory translated into screen
+codes.
+
+
+<sect1><tt>.MACPACK cpu</tt><p>
+
+This macro package does not define any macros but constants used to examine
+the value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable. For
+each supported CPU a constant similar to
+
+<tscreen><verb>
+ CPU_6502
+ CPU_65SC02
+ CPU_65C02
+ CPU_65816
+ CPU_SUNPLUS
+</verb></tscreen>
+
+is defined. These constants may be used to determine the exact type of the
+currently enabled CPU. In addition to that, for each CPU instruction set,
+another constant is defined:
+
+<tscreen><verb>
+ CPU_ISET_6502
+ CPU_ISET_65SC02
+ CPU_ISET_65C02
+ CPU_ISET_65816
+ CPU_ISET_SUNPLUS
+</verb></tscreen>
+
+The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may
+be checked with <tt/<ref id="operators" name=".BITAND">/ to determine if the
+currently enabled CPU supports a specific instruction set. For example the
+65C02 supports all instructions of the 65SC02 CPU, so it has the
+<tt/CPU_ISET_65SC02/ bit set in addition to its native <tt/CPU_ISET_65C02/
+bit. Using
+
+<tscreen><verb>
+ .if (.cpu .bitand CPU_ISET_65SC02)
+ lda (sp)
+ .else
+ ldy #$00
+ lda (sp),y
+ .endif
+</verb></tscreen>
+
+it is possible to determine if the
+
+<tscreen><verb>
+ lda (sp)
+</verb></tscreen>
+
+instruction is supported, which is the case for the 65SC02, 65C02 and 65816
+CPUs (the latter two are upwards compatible to the 65SC02).
+
+
+
<sect>Module constructors/destructors<label id="condes"><p>
<em>Note:</em> This section applies mostly to C programs, so the explanation
useful for assembler programs.
-<sect1>Overview<p>
+<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
</enum>
+<sect1>Calling order<p>
+
+Both, constructors and destructors are sorted in increasing priority order by
+the linker when using one of the builtin linker configurations, so the
+functions with lower priorities come first and are followed by those with
+higher priorities. The C library runtime subroutine that walks over the
+constructor and destructor tables calls the functions starting from the top of
+the table - which means that functions with a high priority are called first.
+
+So when using the C runtime, both constructors and destructors are called with
+high priority functions first, followed by low priority functions.
+
+
<sect1>Pitfalls<p>
When creating and using module constructors and destructors, please take care
<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 intiialization or cleanup code, you have to choose the
+does depend on other initialization or cleanup code, you have to choose the
priority for the functions accordingly.
<item>
</itemize>
+<sect>Porting sources from other assemblers<p>
+
+Sometimes it is necessary to port code written for older assemblers to ca65.
+In some cases, this can be done without any changes to the source code by
+using the emulation features of ca65 (see <tt><ref id=".FEATURE"
+name=".FEATURE"></tt>). In other cases, it is necessary to make changes to the
+source code.
+
+Probably the biggest difference is the handling of the <tt><ref id=".ORG"
+name=".ORG"></tt> directive. ca65 generates relocatable code, and placement is
+done by the linker. Most other assemblers generate absolute code, placement is
+done within the assembler and there is no external linker.
+
+In general it is not a good idea to write new code using the emulation
+features of the assembler, but there may be situations where even this rule is
+not valid.
+
+<sect1>TASS<p>
+
+You need to use some of the ca65 emulation features to simulate the behaviour
+of such simple assemblers.
+
+<enum>
+<item>Prepare your sourcecode like this:
+
+<tscreen><verb>
+ ; if you want TASS style labels without colons
+ .feature labels_without_colons
+ ; if you want TASS style character constants
+ ; ("a" instead of the default 'a')
+ .feature loose_char_term
+
+ .word *+2 ; the cbm load address
+
+ [yourcode here]
+</verb></tscreen>
+
+notice that the two emulation features are mostly useful for porting
+sources originally written in/for TASS, they are not needed for the
+actual "simple assembler operation" and are not recommended if you are
+writing new code from scratch.
+
+<item>Replace all program counter assignments (which are not possible in ca65
+by default, and the respective emulation feature works different from what
+you'd expect) by another way to skip to another memory location, for example
+the <tt><ref id=".RES" name=".RES"></tt>directive.
+
+<tscreen><verb>
+ ; *=$2000
+ .res $2000-* ; reserve memory up to $2000
+</verb></tscreen>
+
+notice that other than the original TASS, ca65 can never move the
+programmcounter backwards - think of it as if you are assembling to disc with
+TASS.
+
+<item>Conditional assembly (<tt/.ifeq//<tt/.endif//<tt/.gogo/ etc.) must be
+rewritten to match ca65 syntax. Most importantly notice that due to the lack
+of <tt/.goto/, everything involving loops must be replaced by
+<tt><ref id=".REPEAT" name=".REPEAT"></tt>.
+
+<item>To assemble code to a different address than it is executed at, use the
+<tt><ref id=".ORG" name=".ORG"></tt> directive instead of
+<tt/.offs/-constructs.
+
+<tscreen><verb>
+ .org $1800
+
+ [floppy code here]
+
+ .reloc ; back to normal
+</verb></tscreen>
+
+<item>Then assemble like this:
+
+<tscreen><verb>
+ cl65 --start-addr 0x0ffe -t none myprog.s -o myprog.prg
+</verb></tscreen>
+
+notice that you need to use the actual start address minus two, since two
+bytes are used for the cbm load address.
+
+</enum>
<sect>Bugs/Feedback<p>
<sect>Copyright<p>
-ca65 (and all cc65 binutils) are (C) Copyright 1998-2000 Ullrich von
+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: