<article>
<title>cc65 Users Guide
-<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">
-<date>2000-09-03, 2001-10-02, 2005-08-01
+<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
+<url url="mailto:gregdk@users.sf.net" name="Greg King">
+<date>2016-06-11
<abstract>
cc65 is a C compiler for 6502 targets. It supports several 6502 based home
<!-- Begin the document -->
-
<sect>Overview<p>
cc65 was originally a C compiler for the Atari 8-bit machines written by
Long options:
--add-source Include source as comment
+ --all-cdecl Make functions default to __cdecl__
--bss-name seg Set the name of the BSS segment
--check-stack Generate stack overflow checks
--code-name seg Set the name of the CODE segment
<descrip>
+ <tag><tt>--all-cdecl</tt></tag>
+
+ Tells the compiler that functions which aren't declared explicitly with
+ either the <tt/__cdecl__/ or <tt/__fastcall__/ calling conventions should
+ have the cdecl convention. (Normally, functions that aren't variadic are
+ fast-called.)
+
+
<label id="option-bss-name">
<tag><tt>--bss-name seg</tt></tag>
<item>lunix
<item>lynx
<item>nes
+ <item>osic1p
<item>pet (all CBM PET systems except the 2001)
<item>plus4
<item>sim6502
<label id="option-W">
- <tag><tt>-W name[,name]</tt></tag>
+ <tag><tt>-W name[,name,...]</tt></tag>
This option allows to control warnings generated by the compiler. It is
- followed by a comma separated list of warnings that should be enabled or
+ followed by a comma-separated list of warnings that should be enabled or
disabled. To disable a warning, its name is prefixed by a minus sign. If
no such prefix exists, or the name is prefixed by a plus sign, the warning
is enabled.
- The following warning names are currently recognized:
+ The following warning names currently are recognized:
<descrip>
<tag><tt/const-comparison/</tag>
Warn if the result of a comparison is constant.
Treat all warnings as errors.
<tag><tt/no-effect/</tag>
Warn about statements that don't have an effect.
+ <tag><tt/remap-zero/</tag>
+ Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/
+ that changes a character's code number from/to 0x00.
<tag><tt/struct-param/</tag>
Warn when passing structs by value.
<tag><tt/unknown-pragma/</tag>
- Warn about known #pragmas.
+ Warn about #pragmas that aren't recognized by cc65.
<tag><tt/unused-label/</tag>
Warn about unused labels.
<tag><tt/unused-param/</tag>
Warn about unused variables.
</descrip>
- The full list of available warning names may be retrieved by using the
+ The full list of available warning names can be retrieved by using the
option <tt><ref id="option-list-warnings" name="--list-warnings"></tt>.
- You may also use <tt><ref id="pragma-warn" name="#pragma warn"></tt> to
- control this setting for smaller pieces of code from within your code.
+ You may use also <tt><ref id="pragma-warn" name="#pragma warn"></tt> to
+ control this setting, for smaller pieces of code, from within your sources.
</descrip><p>
be passed as parameters by value. However, struct assignment *is*
possible.
<p>
-<item> Part of the C library is available only with fastcall calling
- conventions (see below). It means that you must not mix pointers to
- those functions with pointers to user-written, not-fastcall functions.
+<item> Most of the C library is available with only the fastcall calling
+ convention (<ref id="extension-fastcall" name="see below">). It means
+ that you must not mix pointers to those functions with pointers to
+ user-written, cdecl functions (the calling conventions are incompatible).
<p>
-<item> The <tt/volatile/ keyword doesn't have an effect. This is not as bad
+<item> The <tt/volatile/ keyword has almost no effect. That is not as bad
as it sounds, since the 6502 has so few registers that it isn't
possible to keep values in registers anyway.
<p>
file. The syntax is
<tscreen><verb>
- asm (<string literal>[, optional parameters]) ;
+ asm [optional volatile] (<string literal>[, optional parameters]) ;
</verb></tscreen>
or
<tscreen><verb>
- __asm__ (<string literal>[, optional parameters]) ;
+ __asm__ [optional volatile] (<string literal>[, optional parameters]) ;
</verb></tscreen>
- The first form is in the user namespace and is disabled if the <tt/-A/
+ The first form is in the user namespace; and, is disabled if the <tt/-A/
switch is given.
There is a whole section covering inline assembler statements,
<ref id="inline-asm" name="see there">.
<p>
-<item> There is a special calling convention named "fastcall".
- The syntax for a function declaration using fastcall is
+<label id="extension-fastcall">
+<item> The normal calling convention -- for non-variadic functions -- is
+ named "fastcall". The syntax for a function declaration that
+ <em/explicitly/ uses fastcall is
<tscreen><verb>
<return type> fastcall <function name> (<parameter list>)
</verb></tscreen>
or
<tscreen><verb>
- <return type> __fastcall__ <function name> (<parameter list>)
+ <return type> __fastcall__ <function name> (<parameter list>)
</verb></tscreen>
- An example would be
+ An example is
<tscreen><verb>
- void __fastcall__ f (unsigned char c)
+ void __fastcall__ f (unsigned char c)
</verb></tscreen>
The first form of the fastcall keyword is in the user namespace and can
therefore be disabled with the <tt><ref id="option--standard"
name="--standard"></tt> command line option.
- For functions declared as <tt/fastcall/, the rightmost parameter is not
+ For functions that are <tt/fastcall/, the rightmost parameter is not
pushed on the stack but left in the primary register when the function
- is called. This will reduce the cost when calling assembler functions
- significantly, especially when the function itself is rather small.
+ is called. That significantly reduces the cost of calling those functions.
+ <newline><newline>
<p>
+<item> There is another calling convention named "cdecl". Variadic functions
+ (their prototypes have an ellipsis [<tt/.../]) always use that
+ convention. The syntax for a function declaration using cdecl is
+
+ <tscreen><verb>
+ <return type> cdecl <function name> (<parameter list>)
+ </verb></tscreen>
+ or
+ <tscreen><verb>
+ <return type> __cdecl__ <function name> (<parameter list>)
+ </verb></tscreen>
+ An example is
+ <tscreen><verb>
+ int* __cdecl__ f (unsigned char c)
+ </verb></tscreen>
+
+ The first form of the cdecl keyword is in the user namespace;
+ and therefore, can be disabled with the <tt/<ref id="option--standard"
+ name="--standard">/ command-line option.
+
+ For functions that are <tt/cdecl/, the rightmost parameter is pushed
+ onto the stack before the function is called. That increases the cost
+ of calling those functions, especially when they are called from many
+ places.<newline><newline>
+ <p>
+
<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/.
Both refer to the primary register that is used by the compiler to
evaluate expressions or return function results. <tt/__AX__/ is of
<p>
+
<sect>Predefined macros<p>
The compiler defines several macros at startup:
Is defined if the compiler was called with the <tt/-Os/ command line option.
+ <tag><tt>__OSIC1P__</tt></tag>
+
+ This macro is defined if the target is the Ohio Scientific Challenger 1P
+ (-t osic1p).
+
<tag><tt>__PET__</tt></tag>
This macro is defined if the target is the PET family of computers (-t pet).
<sect1><tt>#pragma charmap (<index>, <code>)</tt><label id="pragma-charmap"><p>
Each literal string and each literal character in the source is translated
- by use of a translation table. This translation table is preset when the
- compiler is started depending on the target system, for example to map
- ISO-8859-1 characters into PETSCII if the target is a commodore machine.
+ by use of a translation table. That translation table is preset when the
+ compiler is started, depending on the target system; for example, to map
+ ISO-8859-1 characters into PETSCII if the target is a Commodore machine.
This pragma allows to change entries in the translation table, so the
translation for individual characters, or even the complete table may be
- adjusted.
+ adjusted. Both arguments are assumed to be unsigned characters with a valid
+ range of 0-255.
- Both arguments are assumed to be unsigned characters with a valid range of
- 1-255.
-
- Beware of two pitfalls:
-
- <itemize>
- <item>The character index is actually the code of the character in the
- C source, so character mappings do always depend on the source
- character set. This means that <tt/#pragma charmap/ is not
- portable -- it depends on the build environment.
- <item>While it is possible to use character literals as indices, the
- result may be somewhat unexpected, since character literals are
- itself translated. For this reason I would suggest to avoid
- character literals and use numeric character codes instead.
- </itemize>
+ Beware of some pitfalls:
+ <itemize>
+ <item>The character index is actually the code of the character in the
+ C source; so, character mappings do always depend on the source
+ character set. That means that <tt/#pragma charmap()/ is not
+ portable -- it depends on the build environment.
+ <item>While it is possible to use character literals as indices, the
+ result may be somewhat unexpected, since character literals are
+ themselves translated. For that reason, I would suggest to avoid
+ character literals, and use numeric character codes instead.
+ <item>It is risky to change index <tt/0x00/, because string functions depend
+ on it. If it is changed, then the <tt/'\0'/ at the end of string
+ literals will become non-zero. Functions that are used on those
+ literals won't stop at the end of them. cc65 will warn you if you do
+ change that code number. You can turn off that <tt/remap-zero/ warning
+ if you are certain that you know what you are doing (see <tt/<ref
+ id="pragma-warn" name="#pragma warn()">/).
+ </itemize>
Example:
<tscreen><verb>
- /* Use a space wherever an 'a' occurs in ISO-8859-1 source */
- #pragma charmap (0x61, 0x20);
+ /* Use a space wherever an 'a' occurs in ISO-8859-1 source */
+ #pragma charmap (0x61, 0x20);
</verb></tscreen>
Switch compiler warnings on or off. "name" is the name of a warning (see the
<tt/<ref name="-W" id="option-W">/ compiler option for a list). The name is
- either followed by "pop", which restores the last pushed state, or by "on" or
+ followed either by "pop", which restores the last pushed state, or by "on" or
"off", optionally preceeded by "push" to push the current state before
changing it.
#pragma warn (unused-param, pop)
</verb></tscreen>
+
<sect1><tt>#pragma writable-strings ([push,] on|off)</tt><label id="pragma-writable-strings"><p>
Changes the storage location of string literals. For historical reasons,
syntax is
<tscreen><verb>
- asm (<string literal>[, optional parameters]) ;
+ asm [optional volatile] (<string literal>[, optional parameters]) ;
</verb></tscreen>
or
<tscreen><verb>
- __asm__ (<string literal>[, optional parameters]) ;
+ __asm__ [optional volatile] (<string literal>[, optional parameters]) ;
</verb></tscreen>
<p>
-The first form is in the user namespace and is disabled by <tt><ref
+The first form is in the user namespace; and, is disabled by <tt><ref
id="option--standard" name="--standard"></tt> if the argument is not <tt/cc65/.
-The asm statement may be used inside a function and on global file level. An
-inline assembler statement is a primary expression, so it may also be used as
-part of an expression. Please note however that the result of an expression
-containing just an inline assembler statement is always of type <tt/void/.
+The <tt/asm/ statement can be used only inside a function. Please note that
+the result of an inline assembler expression is always of type <tt/void/.
-The contents of the string literal are preparsed by the compiler and inserted
-into the generated assembly output, so that the can be further processed by
-the backend and especially the optimizer. For this reason, the compiler does
-only allow regular 6502 opcodes to be used with the inline assembler. Pseudo
-instructions (like <tt/.import/, <tt/.byte/ and so on) are <em/not/ allowed,
+The contents of the string literal are preparsed by the compiler; and, inserted
+into the generated assembly output, so that it can be processed further by
+the backend -- and, especially the optimizer. For that reason, the compiler does
+allow only regular 6502 opcodes to be used with the inline assembler. Pseudo
+instructions (like <tt/.import/, <tt/.byte/, and so on) are <em/not/ allowed,
even if the ca65 assembler (which is used to translate the generated assembler
-code) would accept them. The builtin inline assembler is not a replacement for
-the full blown macro assembler which comes with the compiler.
+code) would accept them. The built-in inline assembler is not a replacement for
+the full-blown macro assembler which comes with the compiler.
Note: Inline assembler statements are subject to all optimizations done by the
-compiler. There is currently no way to protect an inline assembler statement
-from being moved or removed completely by the optimizer. If in doubt, check
-the generated assembler output, or disable optimizations.
+compiler. There currently is no way to protect an inline assembler statement
+-- alone -- from being moved or removed completely by the optimizer. If in
+doubt, check the generated assembler output; or, disable optimizations (for
+that function).
+
+As a shortcut, you can put the <tt/volatile/ qualifier in your <tt/asm/
+statements. It will disable optimization for the functions in which those
+<tt/asm volatile/ statements sit. The effect is the same as though you put
+</#pragma optimize(push, off)/ above those functions, and </#pragma
+optimize(pop)/ below those functions.
The string literal may contain format specifiers from the following list. For
each format specifier, an argument is expected which is inserted instead of
-the format specifier before passing the assembly code line to the backend.
+the format specifier, before passing the assembly code line to the backend.
<itemize>
<item><tt/%b/ - Numerical 8-bit value
<item><tt/%%/ - The % sign itself
</itemize><p>
-Using these format specifiers, you can access C <tt/#defines/, variables or
+Using those format specifiers, you can access C <tt/#defines/, variables, or
similar stuff from the inline assembler. For example, to load the value of
-a C <tt/#define/ into the Y register, one would use
+a C <tt/#define/ into the Y index register, one would use
<tscreen><verb>
- #define OFFS 23
- __asm__ ("ldy #%b", OFFS);
+ #define OFFS 23
+ __asm__ ("ldy #%b", OFFS);
</verb></tscreen>
Or, to access a struct member of a static variable:
<tscreen><verb>
- typedef struct {
- unsigned char x;
- unsigned char y;
- unsigned char color;
- } pixel_t;
- static pixel_t pixel;
- __asm__ ("ldy #%b", offsetof(pixel_t, color));
- __asm__ ("lda %v,y", pixel);
+ typedef struct {
+ unsigned char x;
+ unsigned char y;
+ unsigned char color;
+ } pixel_t;
+ static pixel_t pixel;
+ __asm__ ("ldy #%b", offsetof(pixel_t, color));
+ __asm__ ("lda %v,y", pixel);
</verb></tscreen>
<p>
The next example shows how to use global variables to exchange data between C
-an assembler and how to handle assembler jumps:
+and assembler; and, how to handle assembler jumps:
<tscreen><verb>
- unsigned char globalSubA, globalSubB, globalSubResult;
+ static unsigned char globalSubA, globalSubB, globalSubResult;
/* return a-b, return 255 if b>a */
unsigned char sub (unsigned char a, unsigned char b)
</verb></tscreen>
<p>
-Arrays can also be accessed:
+Arrays also can be accessed:
<tscreen><verb>
- unsigned char globalSquareTable[] = {
+ static const unsigned char globalSquareTable[] = {
0, 1, 4, 9, 16, 25, 36, 49, 64, 81,
100, 121, 144, 169, 196, 225
};
- unsigned char globalSquareA, globalSquareResult;
+ static unsigned char globalSquareA, globalSquareResult;
/* return a*a for a<16, else 255 */
unsigned char square (unsigned char a)
{
- if (a>15){
+ if (a > 15) {
return 255;
}
globalSquareA = a;
<p>
Note: Do not embed the assembler labels that are used as names of global
-variables or functions into your asm statements. Code like this
+variables or functions into your <tt/asm/ statements. Code such as this:
<tscreen><verb>
int foo;
- int bar () { return 1; }
- __asm__ ("lda _foo"); /* DON'T DO THAT! */
+ int bar (void) { return 1; }
+ ...
+ __asm__ ("lda _foo"); /* DON'T DO THAT! */
...
__asm__ ("jsr _bar"); /* DON'T DO THAT EITHER! */
</verb></tscreen>
<p>
-may stop working if the way, the compiler generates these names is changed in
-a future version. Instead use the format specifiers from the table above:
+might stop working if the way that the compiler generates those names is changed in
+a future version. Instead, use the format specifiers from the table above:
<tscreen><verb>
- __asm__ ("lda %v", foo); /* OK */
+ __asm__ ("lda %v", foo); /* OK */
...
__asm__ ("jsr %v", bar); /* OK */
</verb></tscreen>
<p>
+
<sect>Implementation-defined behavior<p>
This section describes the behavior of cc65 when the standard describes the
</enum>
</article>
-