<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">
<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>
linker.
-<sect1>Size of an expressions result<p>
+<sect1>Size of an expression 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
<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.
+ one of the '>', '<' or '^' 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
not evaluated.
-<sect1>Available operators<p>
+<sect1>Constant expressions<p>
+
+Sometimes an expression must evaluate to a constant without looking at any
+further input. One such example is the <tt/<ref id=".IF" name=".IF">/ command
+that decides if parts of the code are assembled or not. An expression used in
+the <tt/.IF/ command cannot reference a symbol defined later, because the
+decision about the <tt/.IF/ must be made at the point when it is read. If the
+expression used in such a context contains only constant numerical values,
+there is no problem. When unresolvable symbols are involved it may get harder
+for the assembler to determine if the expression is actually constant, and it
+is even possible to create expressions that aren't recognized as constant.
+Simplifying the expressions will often help.
+
+In cases where the result of the expression is not needed immediately, the
+assembler will delay evaluation until all input is read, at which point all
+symbols are known. So using arbitrary complex constant expressions is no
+problem in most cases.
+
+
+
+<sect1>Available operators<label id="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
- .XMATCH Builtin function 1
- .PARAMCOUNT Builtin pseudo variable (r/o) 1
- .REFERENCED Builtin function 1
- :: Global namespace override 1
+ Builtin string functions 0
+
+ Builtin pseudo variables 1
+ Builtin pseudo functions 1
+ Unary plus 1
- Unary minus 1
~ Unary bitwise not 1
.BITNOT Unary bitwise not 1
< Low byte operator 1
> High byte operator 1
+ ^ Bank byte operator 1
* Multiplication 2
/ Division 2
.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
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>
<sect1>Numeric constants<p>
-Numeric constants are defined using the equal sign. After doing
+Numeric constants are defined using the equal sign or the label assignment
+operator. 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
+evaluated to the value 2 in this context. The label assignment operator causes
+the same, but causes the symbol to be marked as a label, which may cause a
+different handling in the debugger:
+
+<tscreen><verb>
+ io := $d000
+</verb></tscreen>
+
+The right side can of course be an expression:
<tscreen><verb>
four = two * two
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>
-<sect>Control commands<label id="control-commands">
+<sect>Scopes<label id="scopes"><p>
-<p>
-Here's a list of all control commands and a description, what they do:
+ca65 implements several sorts of scopes for symbols.
+<sect1>Global scope<p>
-<sect1><tt>.A16</tt><label id=".A16"><p>
+All (non cheap local) symbols that are declared outside of any nested scopes
+are in global scope.
- 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.
+<sect1>A special scope: cheap locals<p>
- See also: <tt><ref id=".SMART" name=".SMART"></tt>
+A special scope is the scope for cheap local symbols. It lasts from one non
+local symbol to the next one, without any provisions made by the programmer.
+All other scopes differ in usage but use the same concept internally.
-<sect1><tt>.A8</tt><label id=".A8"><p>
+<sect1>Generic nested scopes<p>
- Valid only in 65816 mode. Switch the accumulator to 8 bit.
+A nested scoped for generic use is started with <tt/<ref id=".SCOPE"
+name=".SCOPE">/ and closed with <tt/<ref id=".ENDSCOPE" name=".ENDSCOPE">/.
+The scope can have a name, in which case it is accessible from the outside by
+using <ref id="scopesyntax" name="explicit scopes">. If the scope does not
+have a name, all symbols created within the scope are local to the scope, and
+aren't accessible from the outside.
- Note: This command will not emit any code, it will tell the assembler to
- create 8 bit operands for immediate accu adressing mode.
+A nested scope can access symbols from the local or from enclosing scopes by
+name without using explicit scope names. In some cases there may be
+ambiguities, for example if there is a reference to a local symbol that is not
+yet defined, but a symbol with the same name exists in outer scopes:
- See also: <tt><ref id=".SMART" name=".SMART"></tt>
+<tscreen><verb>
+ .scope outer
+ foo = 2
+ .scope inner
+ lda #foo
+ foo = 3
+ .endscope
+ .endscope
+</verb></tscreen>
+In the example above, the <tt/lda/ instruction will load the value 3 into the
+accumulator, because <tt/foo/ is redefined in the scope. However:
-<sect1><tt>.ADDR</tt><label id=".ADDR"><p>
+<tscreen><verb>
+ .scope outer
+ foo = $1234
+ .scope inner
+ lda foo,x
+ foo = $12
+ .endscope
+ .endscope
+</verb></tscreen>
- 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.
+Here, <tt/lda/ will still load from <tt/$12,x/, but since it is unknown to the
+assembler that <tt/foo/ is a zeropage symbol when translating the instruction,
+absolute mode is used instead. In fact, the assembler will not use absolute
+mode by default, but it will search through the enclosing scopes for a symbol
+with the given name. If one is found, the address size of this symbol is used.
+This may lead to errors:
+
+<tscreen><verb>
+ .scope outer
+ foo = $12
+ .scope inner
+ lda foo,x
+ foo = $1234
+ .endscope
+ .endscope
+</verb></tscreen>
+
+In this case, when the assembler sees the symbol <tt/foo/ in the <tt/lda/
+instruction, it will search for an already defined symbol <tt/foo/. It will
+find <tt/foo/ in scope <tt/outer/, and a close look reveals that it is a
+zeropage symbol. So the assembler will use zeropage addressing mode. If
+<tt/foo/ is redefined later in scope <tt/inner/, the assembler tries to change
+the address in the <tt/lda/ instruction already translated, but since the new
+value needs absolute addressing mode, this fails, and an error message "Range
+error" is output.
+
+Of course the most simple solution for the problem is to move the definition
+of <tt/foo/ in scope <tt/inner/ upwards, so it preceeds its use. There may be
+rare cases when this cannot be done. In these cases, you can use one of the
+address size override operators:
+
+<tscreen><verb>
+ .scope outer
+ foo = $12
+ .scope inner
+ lda a:foo,x
+ foo = $1234
+ .endscope
+ .endscope
+</verb></tscreen>
+
+This will cause the <tt/lda/ instruction to be translated using absolute
+addressing mode, which means changing the symbol reference later does not
+cause any errors.
+
+
+<sect1>Nested procedures<p>
+
+A nested procedure is created by use of <tt/<ref id=".PROC" name=".PROC">/. It
+differs from a <tt/<ref id=".SCOPE" name=".SCOPE">/ in that it must have a
+name, and a it will introduce a symbol with this name in the enclosing scope.
+So
+
+<tscreen><verb>
+ .proc foo
+ ...
+ .endscope
+</verb></tscreen>
+
+is actually the same as
+
+<tscreen><verb>
+ foo:
+ .scope foo
+ ...
+ .endscope
+</verb></tscreen>
+
+This is the reason why a procedure must have a name. If you want a scope
+without a name, use <tt/<ref id=".SCOPE" name=".SCOPE">/.
+
+<bf/Note:/ As you can see from the example above, scopes and symbols live in
+different namespaces. There can be a symbol named <tt/foo/ and a scope named
+<tt/foo/ without any conflicts (but see the section titled <ref
+id="scopesearch" name=""Scope search order"">).
+
+
+<sect1>Structs, unions and enums<p>
+
+Structs, unions and enums are explained in a <ref id="structs" name="separate
+section">, I do only cover them here, because if they are declared with a
+name, they open a nested scope, similar to <tt/<ref id=".SCOPE"
+name=".SCOPE">/. However, when no name is specified, the behaviour is
+different: In this case, no new scope will be opened, symbols declared within
+a struct, union, or enum declaration will then be added to the enclosing scope
+instead.
+
+
+<sect1>Explicit scope specification<label id="scopesyntax"><p>
+
+Accessing symbols from other scopes is possible by using an explicit scope
+specification, provided that the scope where the symbol lives in has a name.
+The namespace token (<tt/::/) is used to access other scopes:
+
+<tscreen><verb>
+ .scope foo
+ bar: .word 0
+ .endscope
+
+ ...
+ lda foo::bar ; Access foo in scope bar
+</verb></tscreen>
+
+The only way to deny access to a scope from the outside is to declare a scope
+without a name (using the <tt/<ref id=".SCOPE" name=".SCOPE">/ command).
+
+A special syntax is used to specify the global scope: If a symbol or scope is
+preceeded by the namespace token, the global scope is searched:
+
+<tscreen><verb>
+ bar = 3
+
+ .scope foo
+ bar = 2
+ lda #::bar ; Access the global bar (which is 3)
+ .endscope
+</verb></tscreen>
+
+
+<sect1>Scope search order<label id="scopesearch"><p>
+
+The assembler searches for a scope in a similar way as for a symbol. First, it
+looks in the current scope, and then it walks up the enclosing scopes until
+the scope is found.
+
+However, one important thing to note when using explicit scope syntax is, that
+a symbol may be accessed before it is defined, but a scope may <bf/not/ be
+used without a preceeding definition. This means that in the following
+example:
+
+<tscreen><verb>
+ .scope foo
+ bar = 3
+ .endscope
+
+ .scope outer
+ lda #foo::bar ; Will load 3, not 2!
+ .scope foo
+ bar = 2
+ .endscope
+ .endscope
+</verb></tscreen>
+
+the reference to the scope <tt/foo/ will use the global scope, and not the
+local one, because the local one is not visible at the point where it is
+referenced.
+
+Things get more complex if a complete chain of scopes is specified:
+
+<tscreen><verb>
+ .scope foo
+ .scope outer
+ .scope inner
+ bar = 1
+ .endscope
+ .endscope
+ .scope another
+ .scope nested
+ lda #outer::inner::bar ; 1
+ .endscope
+ .endscope
+ .endscope
+
+ .scope outer
+ .scope inner
+ bar = 2
+ .endscope
+ .endscope
+</verb></tscreen>
+
+When <tt/outer::inner::bar/ is referenced in the <tt/lda/ instruction, the
+assembler will first search in the local scope for a scope named <tt/outer/.
+Since none is found, the enclosing scope (<tt/another/) is checked. There is
+still no scope named <tt/outer/, so scope <tt/foo/ is checked, and finally
+scope <tt/outer/ is found. Within this scope, <tt/inner/ is searched, and in
+this scope, the assembler looks for a symbol named <tt/bar/.
+
+Please note that once the anchor scope is found, all following scopes
+(<tt/inner/ in this case) are expected to be found exactly in this scope. The
+assembler will search the scope tree only for the first scope (if it is not
+anchored in the root scope). Starting from there on, there is no flexibility,
+so if the scope named <tt/outer/ found by the assembler does not contain a
+scope named <tt/inner/, this would be an error, even if such a pair does exist
+(one level up in global scope).
+
+Ambiguities that may be introduced by this search algorithm may be removed by
+anchoring the scope specification in the global scope. In the example above,
+if you want to access the "other" symbol <tt/bar/, you would have to write:
+
+<tscreen><verb>
+ .scope foo
+ .scope outer
+ .scope inner
+ bar = 1
+ .endscope
+ .endscope
+ .scope another
+ .scope nested
+ lda #::outer::inner::bar ; 2
+ .endscope
+ .endscope
+ .endscope
+
+ .scope outer
+ .scope inner
+ bar = 2
+ .endscope
+ .endscope
+</verb></tscreen>
+
+
+<sect>Address sizes<label id="address-sizes"><p>
+
+
+
+<sect>Pseudo variables<label id="pseudo-variables"><p>
+
+Pseudo variables are readable in all cases, and in some special cases also
+writable.
+
+<sect1><tt>*</tt><p>
+
+ Reading this pseudo variable will return the program counter at the start
+ of the current input line.
+
+ Assignment to this variable is possible when <tt/<ref id=".FEATURE"
+ name=".FEATURE pc_assignment">/ is used. Note: You should not use
+ assignments to <tt/*/, use <tt/<ref id=".ORG" name=".ORG">/ instead.
+
+
+<sect1><tt>.CPU</tt><label id=".CPU"><p>
+
+ Reading this pseudo variable will give a constant integer value that
+ 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>
- .addr $0D00, $AF13, _Clear
+ .macpack cpu
+ .if (.cpu .bitand CPU_ISET_65816)
+ phx
+ phy
+ .else
+ txa
+ pha
+ tya
+ pha
+ .endif
</verb></tscreen>
- See: <tt><ref id=".FARADDR" name=".FARADDR"></tt>, <tt><ref id=".WORD"
- name=".WORD"></tt>
+<sect1><tt>.PARAMCOUNT</tt><label id=".PARAMCOUNT"><p>
-<sect1><tt>.ALIGN</tt><label id=".ALIGN"><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.
- 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).
+ Example:
- 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.
+ <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>.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>
- .align 256
+ .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/.
+
+
+
+<sect>Pseudo functions<label id="pseudo-functions"><p>
+
+Pseudo functions expect their arguments in parenthesis, and they have a result,
+either a string or an expression.
+
+
+<sect1><tt>.BANKBYTE</tt><label id=".BANKBYTE"><p>
+
+ The function returns the bank byte (that is, bits 16-23) of its argument.
+ It works identical to the '^' operator.
+
+ See: <tt><ref id=".HIBYTE" name=".HIBYTE"></tt>,
+ <tt><ref id=".LOBYTE" name=".LOBYTE"></tt>
+
+
+<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>.CONCAT</tt><label id=".CONCAT"><p>
+
+ Builtin string 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>.HIBYTE</tt><label id=".HIBYTE"><p>
+
+ The function returns the high byte (that is, bits 8-15) of its argument.
+ It works identical to the '>' operator.
+
+ See: <tt><ref id=".LOBYTE" name=".LOBYTE"></tt>,
+ <tt><ref id=".BANKBYTE" name=".BANKBYTE"></tt>
+
+
+<sect1><tt>.HIWORD</tt><label id=".HIWORD"><p>
+
+ The function returns the high word (that is, bits 16-31) of its argument.
+
+ See: <tt><ref id=".LOWORD" name=".LOWORD"></tt>
+
+
+<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>.LOBYTE</tt><label id=".LOBYTE"><p>
+
+ The function returns the low byte (that is, bits 0-7) of its argument.
+ It works identical to the '<' operator.
+
+ See: <tt><ref id=".HIBYTE" name=".HIBYTE"></tt>,
+ <tt><ref id=".BANKBYTE" name=".BANKBYTE"></tt>
+
+
+<sect1><tt>.LOWORD</tt><label id=".LOWORD"><p>
+
+ The function returns the low word (that is, bits 0-15) of its argument.
+
+ See: <tt><ref id=".HIWORD" name=".HIWORD"></tt>
+
+
+<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>.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>.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>.SIZEOF</tt><label id=".SIZEOF"><p>
+
+ <tt/.SIZEOF/ is a pseudo function that returns the size of its argument. The
+ argument can be a struct/union, a struct member, a procedure, or a label. In
+ case of a procedure or label, its size is defined by the amount of data
+ placed in the segment where the label is relative to. If a line of code
+ switches segments (for example in a macro) data placed in other segments
+ does not count for the size.
+
+ Please note that a symbol or scope must exist, before it is used together with
+ <tt/.SIZEOF/ (this may get relaxed later, but will always be true for scopes).
+ A scope has preference over a symbol with the same name, so if the last part
+ of a name represents both, a scope and a symbol, the scope is choosen over the
+ symbol.
+
+ After the following code:
+
+ <tscreen><verb>
+ .struct Point ; Struct size = 4
+ xcoord .word
+ xcoord .word
+ .endstruct
+
+ P: .tag Point ; Declare a point
+ @P: .tag Point ; Declare another point
+
+ .code
+ .proc Code
+ nop
+ .proc Inner
+ nop
+ .endproc
+ nop
+ .endproc
+
+ .proc Data
+ .data ; Segment switch!!!
+ .res 4
+ .endproc
+ </verb></tscreen>
+
+ <descrip>
+ <tag><tt/.sizeof(Point)/</tag>
+ will have the value 4, because this is the size of struct <tt/Point/.
+
+ <tag><tt/.sizeof(Point::xcoord)/</tag>
+ will have the value 2, because this is the size of the member <tt/xcoord/
+ in struct <tt/Point/.
+
+ <tag><tt/.sizeof(P)/</tag>
+ will have the value 4, this is the size of the data declared on the same
+ source line as the label <tt/P/, which is in the same segment that <tt/P/
+ is relative to.
+
+ <tag><tt/.sizeof(@P)/</tag>
+ will have the value 4, see above. The example demonstrates that <tt/.SIZEOF/
+ does also work for cheap local symbols.
+
+ <tag><tt/.sizeof(Code)/</tag>
+ will have the value 3, since this is amount of data emitted into the code
+ segment, the segment that was active when <tt/Code/ was entered. Note that
+ this value includes the amount of data emitted in child scopes (in this
+ case <tt/Code::Inner/).
+
+ <tag><tt/.sizeof(Code::Inner)/</tag>
+ will have the value 1 as expected.
+
+ <tag><tt/.sizeof(Data)/</tag>
+ will have the value 0. Data is emitted within the scope <tt/Data/, but since
+ the segment is switched after entry, this data is emitted into another
+ segment.
+ </descrip>
+
+
+<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>.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>
+
+
+
+<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>.ASCIIZ</tt><label id=".ASCIIZ"><p>
+<sect1><tt>.ASSERT</tt><label id=".ASSERT"><p>
- Define a string with a trailing zero.
+ 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>
- Msg: .asciiz "Hello world"
+ .assert * = $8000, error, "Code not at $8000"
</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).
+ 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>
</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",
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
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
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:
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
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:
is read from an include file.
+<sect1><tt>.ENDENUM</tt><label id=".ENDENUM"><p>
+
+ End a <tt><ref id=".ENUM" name=".ENUM"></tt> declaration.
+
+
<sect1><tt>.ENDIF</tt><label id=".ENDIF"><p>
Conditional assembly: Close a <tt><ref id=".IF" name=".IF..."></tt> or
End a <tt><ref id=".REPEAT" name=".REPEAT"></tt> block.
+<sect1><tt>.ENDSCOPE</tt><label id=".ENDSCOPE"><p>
+
+ End of local lexical level (see <tt/<ref id=".SCOPE" name=".SCOPE">/).
+
+
+<sect1><tt>.ENDSTRUCT</tt><label id=".ENDSTRUCT"><p>
+
+ Ends a struct definition. See the <tt/<ref id=".STRUCT" name=".STRUCT">/
+ command and the separate section named <ref id="structs" name=""Structs
+ and unions"">.
+
+
+<sect1><tt>.ENUM</tt><label id=".ENUM"><p>
+
+ Start an enumeration. This directive is very similar to the C <tt/enum/
+ keyword. If a name is given, a new scope is created for the enumeration,
+ otherwise the enumeration members are placed in the enclosing scope.
+
+ In the enumeration body, symbols are declared. The first symbol has a value
+ of zero, and each following symbol will get the value of the preceeding plus
+ one. This behaviour may be overriden by an explicit assignment. Two symbols
+ may have the same value.
+
+ Example:
+
+ <tscreen><verb>
+ .enum errorcodes
+ no_error
+ file_error
+ parse_error
+ .endenum
+ </verb></tscreen>
+
+ Above example will create a new scope named <tt/errorcodes/ with three
+ symbols in it that get the values 0, 1 and 2 respectively. Another way
+ to write this would have been:
+
+ <tscreen><verb>
+ .scope errorcodes
+ no_error = 0
+ file_error = 1
+ parse_error = 2
+ .endscope
+ </verb></tscreen>
+
+ Please note that explicit scoping must be used to access the identifiers:
+
+ <tscreen><verb>
+ .word errorcodes::no_error
+ </verb></tscreen>
+
+ A more complex example:
+
+ <tscreen><verb>
+ .enum
+ EUNKNOWN = -1
+ EOK
+ EFILE
+ EBUSY
+ EAGAIN
+ EWOULDBLOCK = EAGAIN
+ .endenum
+ </verb></tscreen>
+
+ In this example, the enumeration does not have a name, which means that the
+ members will be visible in the enclosing scope and can be used in this scope
+ without explicit scoping. The first member (<tt/EUNKNOWN/) has the value -1.
+ The value for the following members is incremented by one, so <tt/EOK/ would
+ be zero and so on. <tt/EWOULDBLOCK/ is an alias for <tt/EGAIN/, so it has an
+ override for the value using an already defined symbol.
+
+
<sect1><tt>.ERROR</tt><label id=".ERROR"><p>
Force an assembly error. The assembler will output an error message
</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
</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
<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
</verb></tscreen>
Macro packages are explained in more detail in section <ref
- id="macropackages" name="Macro packages">).
+ 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">.
-
-
-<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.
-
+ See section <ref id="macros" name="Macros">.
+
<sect1><tt>.ORG</tt><label id=".ORG"><p>
<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>
</verb></tscreen>
-<sect1><tt>.PARAMCOUNT</tt><label id=".PARAMCOUNT"><p>
+<sect1><tt>.PC02</tt><label id=".PC02"><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.
+ Enable the 65C02 instructions set. This instruction set includes all
+ 6502 and 65SC02 instructions.
- Example:
+ See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02"
+ name=".PSC02"></tt> and <tt><ref id=".P816" name=".P816"></tt>
- <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>.POPSEG</tt><label id=".POPSEG"><p>
+ Pop the last pushed segment from the stack, and set it.
-<sect1><tt>.PC02</tt><label id=".PC02"><p>
+ 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.
- Enable the 65C02 instructions set. This instruction set includes all
- 6502 instructions.
+ The assembler will print an error message if the segment stack is empty
+ when this command is issued.
- See: <tt><ref id=".P02" name=".P02"></tt> and <tt><ref id=".P816"
- name=".P816"></tt>
+ 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.
+ Start a nested lexical level with the given name and adds a symbol with this
+ name to the enclosing scope. All new symbols from now on are in the local
+ lexical level and are accessible from outside only via <ref id="scopesyntax"
+ name="explicit scope specification">. 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 (this is an artificial limit to protect
+ against errors in the source).
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
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>
+ See: <tt/<ref id=".ENDPROC" name=".ENDPROC">/ and <tt/<ref id=".SCOPE"
+ name=".SCOPE">/
-<sect1><tt>.REF, .REFERENCED</tt><label id=".REFERENCED"><p>
+<sect1><tt>.PSC02</tt><label id=".PSC02"><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
+ Enable the 65SC02 instructions set. This instruction set includes all
+ 6502 instructions.
- <tscreen><verb>
- .if .referenced(a)
- </verb></tscreen>
+ See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PC02"
+ name=".PC02"></tt> and <tt><ref id=".P816" name=".P816"></tt>
- See: <tt><ref id=".DEFINED" name=".DEFINED"></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>.REPEAT</tt><label id=".REPEAT"><p>
<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>)
+ .res 12, $AA
</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>
See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command.
+<sect1><tt>.SCOPE</tt><label id=".SCOPE"><p>
+
+ Start a nested lexical level with the given name. All new symbols from now
+ on are in the local lexical level and are accessible from outside only via
+ <ref id="scopesyntax" name="explicit scope specification">. 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=".ENDSCOPE" name=".ENDSCOPE"></tt> command is
+ read. Lexical levels may be nested up to a depth of 16 (this is an
+ artificial limit to protect against errors in the source).
+
+ 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>
+ .scope Error ; Start new scope named Error
+ None = 0 ; No error
+ File = 1 ; File error
+ Parse = 2 ; Parse error
+ .endproc ; Close lexical level
+
+ ...
+ lda #Error::File ; Use symbol from scope Error
+ </verb></tscreen>
+
+ See: <tt/<ref id=".ENDSCOPE" name=".ENDSCOPE">/ and <tt/<ref id=".PROC"
+ name=".PROC">/
+
+
<sect1><tt>.SEGMENT</tt><label id=".SEGMENT"><p>
Switch to another segment. Code and data is always emitted into a
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
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.
+ In smart mode the assembler will do the following:
+
+ <itemize>
+ <item>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.
+ <item>In 65816 mode, replace a <tt/RTS/ instruction by <tt/RTL/ if it is
+ used within a procedure declared as <tt/far/, or if the procedure has
+ no explicit address specification, but it is <tt/far/ because of the
+ memory model used.
+ </itemize>
Example:
.smart - ; Stop being smart
</verb></tscreen>
+ See: <tt><ref id=".A16" name=".A16"></tt>,
+ <tt><ref id=".A8" name=".A8"></tt>,
+ <tt><ref id=".I16" name=".I16"></tt>,
+ <tt><ref id=".I8" name=".I8"></tt>
-<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>.STRUCT</tt><label id=".STRUCT"><p>
+ Starts a struct definition. Structs are covered in a separate section named
+ <ref id="structs" name=""Structs and unions"">.
-<sect1><tt>.STRING</tt><label id=".STRING"><p>
+ See: <tt><ref id=".ENDSTRUCT" name=".ENDSTRUCT"></tt>
- 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.
+<sect1><tt>.SUNPLUS</tt><label id=".SUNPLUS"><p>
- Example:
+ 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".
- <tscreen><verb>
- ; Emulate other assemblers:
- .macro section name
- .segment .string(name)
- .endmacro
- </verb></tscreen>
+ 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>.STRLEN</tt><label id=".STRLEN"><p>
+<sect1><tt>.TAG</tt><label id=".TAG"><p>
- Builtin function. The function accepts a string argument in braces and
- eveluates to the length of the string.
+ Allocate space for a struct or union.
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:
+ .struct Point
+ xcoord .word
+ ycoord .word
+ .endstruct
- <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
+ .bss
+ .tag Point ; Allocate 4 bytes
</verb></tscreen>
</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.
</verb></tscreen>
+<sect1>Detecting parameter types<p>
+
+Sometimes it is nice to write a macro that acts differently depending on the
+type of the argument supplied. An example would be a macro that loads a 16 bit
+value from either an immediate operand, or from memory. The <tt/<ref
+id=".MATCH" name=".MATCH">/ and <tt/<ref id=".XMATCH" name=".XMATCH">/
+functions will allow you to do exactly this:
+
+<tscreen><verb>
+ .macro ldax arg
+ .if (.match (.left (1, arg), #))
+ ; immediate mode
+ lda #<(.right (.tcount (arg)-1, arg))
+ ldx #>(.right (.tcount (arg)-1, arg))
+ .else
+ ; assume absolute or zero page
+ lda arg
+ ldx 1+(arg)
+ .endif
+ .endmacro
+</verb></tscreen>
+
+Using the <tt/<ref id=".MATCH" name=".MATCH">/ function, the macro is able to
+check if its argument begins with a hash mark. If so, two immediate loads are
+emitted, Otherwise a load from an absolute zero page memory location is
+assumed. So this macro can be used as
+
+<tscreen><verb>
+ foo: .word $5678
+ ...
+ ldax #$1234 ; X=$12, A=$34
+ ...
+ ldax foo ; X=$56, A=$78
+</verb></tscreen>
+
+
<sect1>Recursive macros<p>
Macros may be used recursively:
+<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>Structs and unions<label id="structs"><p>
+
+Structs and unions are special forms of <ref id="scopes" name="scopes">. They
+are to some degree comparable to their C counterparts. Both have a list of
+members. Each member allocates storage and may optionally have a name, which,
+in case of a struct, is the offset from the beginning and, in case of a union,
+is always zero.
+
+Here is an example for a very simple struct with two members and a total size
+of 4 bytes:
+
+<tscreen><verb>
+ .struct Point
+ xcoord .word
+ ycoord .word
+ .endstruct
+</verb></tscreen>
+
+A union shares the total space between all its members, its size is the same
+as that of the largest member.
+
+A struct or union must not necessarily have a name. If it is anonymous, no
+local scope is opened, the identifiers used to name the members are placed
+into the current scope instead.
+
+A struct may contain unnamed members and definitions of local structs. The
+storage allocators may contain a multiplier, as in the example below:
+
+<tscreen><verb>
+ .struct Circle
+ .struct Point
+ .word 2 ; Allocate two words
+ .endstruct
+ Radius .word
+ .endstruct
+</verb></tscreen>
+
+Using the <ref id=".TAG" name=".TAG"> keyword, it is possible to embedd
+already defined structs or unions in structs:
+
+<tscreen><verb>
+ .struct Point
+ xcoord .word
+ ycoord .word
+ .endstruct
+
+ .struct Circle
+ Origin .tag Point
+ Radius .byte
+ .endstruct
+</verb></tscreen>
+
+Space for a struct or union may be allocated using the <ref id=".TAG"
+name=".TAG"> directive.
+
+<tscreen><verb>
+ C: .tag Circle
+</verb></tscreen>
+
+Currently, members are just offsets from the start of the struct or union. To
+access a field of a struct, the member offset has to be added to the address
+of the struct itself:
+
+<tscreen><verb>
+ lda C+Circle::Radius ; Load circle radius into A
+</verb></tscreen>
+
+This may change in a future version of the assembler.
+
+
<sect>Module constructors/destructors<label id="condes"><p>
<em>Note:</em> This section applies mostly to C programs, so the explanation
</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/.goto/ 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-2001 Ullrich von
+ca65 (and all cc65 binutils) are (C) Copyright 1998-2003 Ullrich von
Bassewitz. For usage of the binaries and/or sources the following
conditions do apply: