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