mirror of
https://github.com/cc65/cc65.git
synced 2024-11-12 07:07:19 +00:00
1965 lines
71 KiB
Plaintext
1965 lines
71 KiB
Plaintext
<!doctype linuxdoc system>
|
|
|
|
<article>
|
|
<title>cc65 Users Guide
|
|
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
|
|
<url url="mailto:gregdk@users.sf.net" name="Greg King">
|
|
|
|
<abstract>
|
|
cc65 is a C compiler for 6502 targets. It supports several 6502-based home
|
|
computers such as the Commodore and Atari machines, but it easily is
|
|
retargetable.
|
|
</abstract>
|
|
|
|
<!-- Table of contents -->
|
|
<toc>
|
|
|
|
<!-- Begin the document -->
|
|
|
|
<sect>Overview<p>
|
|
|
|
cc65 was originally a C compiler for the Atari 8-bit machines written by
|
|
John R. Dunning. In prior releases I've described the compiler by listing
|
|
up the changes made by me. I have made many more changes in the meantime
|
|
(and rewritten major parts of the compiler), so I will no longer do that,
|
|
since the list would be too large and of no use to anyone. Instead I will
|
|
describe the compiler in respect to the ANSI/ISO C standard.
|
|
|
|
There are separate documents named <url url="library.html"> and <url
|
|
url="funcref.html"> that cover the library that is available for the compiler.
|
|
If you know C, and are interested in doing actual programming, the library
|
|
documentation is probably of much more use than this document.
|
|
|
|
If you need some hints for getting the best code out of the compiler, you
|
|
may have a look at <url url="coding.html"> which covers some code generation
|
|
issues.
|
|
|
|
|
|
|
|
<sect>Usage<p>
|
|
|
|
The compiler translates C files into files containing assembly code that
|
|
may be translated by the ca65 macroassembler (for more information about
|
|
the assembler, have a look at <url url="ca65.html">).
|
|
|
|
|
|
<sect1>Command line option overview<p>
|
|
|
|
The compiler may be called as follows:
|
|
|
|
<tscreen><verb>
|
|
---------------------------------------------------------------------------
|
|
Usage: cc65 [options] file
|
|
Short options:
|
|
-Cl Make local variables static
|
|
-Dsym[=defn] Define a symbol
|
|
-E Stop after the preprocessing stage
|
|
-I dir Set an include directory search path
|
|
-O Optimize code
|
|
-Oi Optimize code, inline more code
|
|
-Or Enable register variables
|
|
-Os Inline some standard functions
|
|
-T Include source as comment
|
|
-V Print the compiler version number
|
|
-W warning[,...] Suppress warnings
|
|
-d Debug mode
|
|
-g Add debug info to object file
|
|
-h Help (this text)
|
|
-j Default characters are signed
|
|
-mm model Set the memory model
|
|
-o name Name the output file
|
|
-r Enable register variables
|
|
-t sys Set the target system
|
|
-v Increase verbosity
|
|
|
|
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
|
|
--codesize x Accept larger code by factor x
|
|
--cpu type Set cpu type (6502, 65c02)
|
|
--create-dep name Create a make dependency file
|
|
--create-full-dep name Create a full make dependency file
|
|
--data-name seg Set the name of the DATA segment
|
|
--debug Debug mode
|
|
--debug-info Add debug info to object file
|
|
--debug-opt name Configure optimizations with a file
|
|
--debug-opt-output Debug output of each optimization step
|
|
--dep-target target Use this dependency target
|
|
--disable-opt name Disable an optimization step
|
|
--eagerly-inline-funcs Eagerly inline some known functions
|
|
--enable-opt name Enable an optimization step
|
|
--help Help (this text)
|
|
--include-dir dir Set an include directory search path
|
|
--inline-stdfuncs Inline some standard functions
|
|
--list-opt-steps List all optimizer steps and exit
|
|
--list-warnings List available warning types for -W
|
|
--local-strings Emit string literals immediately
|
|
--memory-model model Set the memory model
|
|
--register-space b Set space available for register variables
|
|
--register-vars Enable register variables
|
|
--rodata-name seg Set the name of the RODATA segment
|
|
--signed-chars Default characters are signed
|
|
--standard std Language standard (c89, c99, cc65)
|
|
--static-locals Make local variables static
|
|
--target sys Set the target system
|
|
--verbose Increase verbosity
|
|
--version Print the compiler version number
|
|
--writable-strings Make string literals writable
|
|
---------------------------------------------------------------------------
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1>Command line options in detail<p>
|
|
|
|
Here is a description of all the command line options:
|
|
|
|
<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>
|
|
|
|
Set the name of the bss segment. See also <tt/<ref id="pragma-bss-name"
|
|
name="#pragma bss-name">/.
|
|
|
|
|
|
<label id="option-check-stack">
|
|
<tag><tt>--check-stack</tt></tag>
|
|
|
|
Tells the compiler to generate code that checks for stack overflows. See
|
|
<tt/<ref id="pragma-check-stack" name="#pragma check-stack">/ for an
|
|
explanation of this feature.
|
|
|
|
|
|
<label id="option-code-name">
|
|
<tag><tt>--code-name seg</tt></tag>
|
|
|
|
Set the name of the code segment. See also <tt/<ref id="pragma-code-name"
|
|
name="#pragma code-name">/
|
|
|
|
|
|
<label id="option-codesize">
|
|
<tag><tt>--codesize x</tt></tag>
|
|
|
|
This options allows finer control about speed vs. size decisions in the code
|
|
generation and optimization phases. It gives the allowed size increase
|
|
factor (in percent). The default is 100 when not using <tt/-Oi/ and 200 when
|
|
using <tt/-Oi/ (<tt/-Oi/ is the same as <tt/-O --codesize 200/).
|
|
|
|
|
|
<label id="option--cpu">
|
|
<tag><tt>--cpu CPU</tt></tag>
|
|
|
|
Set the CPU, the compiler generates code for. You may specify "6502" or
|
|
"65C02" as the CPU. The default depends on the selected target (see option
|
|
<tt/<ref id="option-t" name="-t">/). It is the 6502 CPU for most targets or
|
|
if no target has been set. Specifying 65C02 will use a few 65C02
|
|
instructions when generating code. Don't expect too much from this option:
|
|
In most cases the difference in size and speed is just 1-2%.
|
|
|
|
|
|
<label id="option-create-dep">
|
|
<tag><tt>--create-dep name</tt></tag>
|
|
|
|
Tells the compiler to generate a file containing the dependency list for the
|
|
compiled module in makefile syntax. The output is written to a file with the
|
|
given name. The output does not include system include files (in angle
|
|
brackets).
|
|
|
|
|
|
<label id="option-create-full-dep">
|
|
<tag><tt>--create-full-dep name</tt></tag>
|
|
|
|
Tells the compiler to generate a file containing the dependency list for the
|
|
compiled module in makefile syntax. The output is written to a file with the
|
|
given name. The output does include system include files (in angle
|
|
brackets).
|
|
|
|
|
|
<label id="option-data-name">
|
|
<tag><tt>--data-name seg</tt></tag>
|
|
|
|
Set the name of the data segment. See also <tt/<ref id="pragma-data-name"
|
|
name="#pragma data-name">/
|
|
|
|
|
|
<tag><tt>-d, --debug</tt></tag>
|
|
|
|
Enables debug mode, for debugging the behavior of cc65.
|
|
|
|
|
|
<tag><tt>--debug-tables name</tt></tag>
|
|
|
|
Writes symbol table information to a file, which includes details on structs, unions
|
|
functions, and global variables. For example, given the following code:
|
|
|
|
<tscreen><verb>
|
|
struct l {
|
|
unsigned char m;
|
|
unsigned char n;
|
|
};
|
|
|
|
struct hello {
|
|
unsigned char j;
|
|
unsigned char k;
|
|
struct l l;
|
|
};
|
|
|
|
struct sub {
|
|
unsigned char x;
|
|
unsigned char y;
|
|
};
|
|
|
|
union xy {
|
|
struct sub xy;
|
|
unsigned int mem;
|
|
};
|
|
|
|
typedef struct hello thingy;
|
|
|
|
unsigned char single;
|
|
|
|
unsigned char test_local_vars_main(void) {
|
|
static unsigned char wahoo;
|
|
static unsigned char bonanza = 0x42;
|
|
unsigned char i;
|
|
unsigned int j;
|
|
unsigned int *random;
|
|
unsigned char *lol;
|
|
signed char whoa;
|
|
struct hello wow;
|
|
thingy *cool;
|
|
union xy xy;
|
|
|
|
return 0;
|
|
}
|
|
</verb></tscreen>
|
|
|
|
The following output would be produced:
|
|
|
|
<tscreen><verb>
|
|
SC_FUNC: _test_local_vars_main: Symbol table
|
|
============================================
|
|
__fixargs__:
|
|
Flags: SC_CONST SC_DEF
|
|
Type: unsigned int
|
|
__argsize__:
|
|
Flags: SC_CONST SC_DEF
|
|
Type: unsigned char
|
|
wahoo:
|
|
AsmName: M0001
|
|
Flags: SC_STATIC SC_DEF SC_REF
|
|
Type: unsigned char
|
|
bonanza:
|
|
AsmName: M0002
|
|
Flags: SC_STATIC SC_DEF SC_REF
|
|
Type: unsigned char
|
|
i:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: unsigned char
|
|
j:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: unsigned int
|
|
random:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: unsigned int *
|
|
lol:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: unsigned char *
|
|
whoa:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: signed char
|
|
wow:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: struct hello
|
|
cool:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: struct hello *
|
|
xy:
|
|
Flags: SC_AUTO SC_DEF SC_REF
|
|
Type: union xy
|
|
|
|
|
|
|
|
|
|
Global symbol table
|
|
===================
|
|
thingy:
|
|
AsmName: _thingy
|
|
Flags: SC_TYPEDEF 0x100000
|
|
Type: struct hello
|
|
single:
|
|
AsmName: _single
|
|
Flags: SC_STATIC SC_EXTERN SC_STORAGE SC_DEF SC_REF 0x100000
|
|
Type: unsigned char
|
|
test_local_vars_main:
|
|
AsmName: _test_local_vars_main
|
|
Flags: SC_FUNC SC_STATIC SC_EXTERN SC_DEF 0x100000
|
|
Type: unsigned char (void)
|
|
|
|
|
|
|
|
|
|
Global tag table
|
|
================
|
|
l:
|
|
Flags: SC_STRUCT SC_DEF
|
|
Type: (none)
|
|
hello:
|
|
Flags: SC_STRUCT SC_DEF
|
|
Type: (none)
|
|
sub:
|
|
Flags: SC_STRUCT SC_DEF
|
|
Type: (none)
|
|
xy:
|
|
Flags: SC_UNION SC_DEF
|
|
Type: (none)
|
|
|
|
|
|
|
|
|
|
Global struct and union definitions
|
|
=========================
|
|
|
|
SC_STRUCT: l
|
|
============
|
|
m:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: unsigned char
|
|
n:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: unsigned char
|
|
|
|
|
|
|
|
|
|
SC_STRUCT: hello
|
|
================
|
|
j:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: unsigned char
|
|
k:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: unsigned char
|
|
l:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: struct l
|
|
|
|
|
|
|
|
|
|
SC_STRUCT: sub
|
|
==============
|
|
x:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: unsigned char
|
|
y:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: unsigned char
|
|
|
|
|
|
|
|
|
|
SC_UNION: xy
|
|
============
|
|
xy:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: struct sub
|
|
mem:
|
|
Flags: SC_STRUCTFIELD
|
|
Type: unsigned int
|
|
</verb></tscreen>
|
|
|
|
|
|
<tag><tt>--debug-opt name</tt></tag>
|
|
|
|
The named file contains a list of specific optimization steps to enable or disable.
|
|
Each line contains the name of an optimization step with either a
|
|
<tt>+</tt> (enable) or <tt>-</tt> (disable) prefix.
|
|
The name <tt>all</tt> can be used to enable or disable all optimizations.
|
|
Comment lines may begin with <tt>#</tt> or <tt>;</tt>.
|
|
|
|
Use <tt>--list-opt-steps</tt> to generate a complete list of available optimization steps.
|
|
|
|
Use <tt>--debug</tt> to see a list of optimizations applied during compilation.
|
|
|
|
|
|
<tag><tt>--debug-opt-output</tt></tag>
|
|
|
|
For debugging the output of each optimization pass, step by step.
|
|
Generates a <tt>name.opt</tt> output listing for each optimized function <tt>name</tt>.
|
|
|
|
|
|
<label id="option-dep-target">
|
|
<tag><tt>--dep-target target</tt></tag>
|
|
|
|
When generating a dependency file, don't use the actual output file as the
|
|
target of the dependency, but the file specified with this option. The
|
|
option has no effect if neither <tt/<ref id="option-create-dep"
|
|
name="--create-dep">/ nor <tt/<ref id="option-create-full-dep"
|
|
name="--create-full-dep">/ is specified.
|
|
|
|
|
|
<tag><tt>-D sym[=definition]</tt></tag>
|
|
|
|
Define a macro on the command line. If no definition is given, the macro
|
|
is defined to the value "1".
|
|
|
|
|
|
<tag><tt>-g, --debug-info</tt></tag>
|
|
|
|
This will cause the compiler to insert a <tt/.DEBUGINFO/ command into the
|
|
generated assembler code. This will cause the assembler to include all
|
|
symbols in a special section in the object file.
|
|
|
|
|
|
<label id="option-eagerly-inline-funcs">
|
|
<tag><tt>--eagerly-inline-funcs</tt></tag>
|
|
|
|
Have the compiler eagerly inline these functions from the C library:
|
|
<itemize>
|
|
<item><tt/memcpy()/
|
|
<item><tt/memset()/
|
|
<item><tt/strcmp()/
|
|
<item><tt/strcpy()/
|
|
<item><tt/strlen()/
|
|
</itemize>
|
|
|
|
Note: This has two consequences:
|
|
<itemize>
|
|
<item>You may not use names of standard C functions for your own functions.
|
|
If you do that, your program is not standard-compliant anyway; but,
|
|
using <tt/--eagerly-inline-funcs/ actually will break things.
|
|
<p>
|
|
<item>The inlined string and memory functions will not handle strings or
|
|
memory areas larger than 255 bytes.
|
|
<p>
|
|
</itemize>
|
|
|
|
<tt/--eagerly-inline-funcs/ implies the <tt><ref id="option-inline-stdfuncs"
|
|
name="--inline-stdfuncs"></tt> command line option.
|
|
|
|
See also <tt><ref id="pragma-allow-eager-inline" name="#pragma allow-eager-inline"></tt>.
|
|
|
|
|
|
<tag><tt>-h, --help</tt></tag>
|
|
|
|
Print the short option summary shown above.
|
|
|
|
|
|
<label id="option-inline-stdfuncs">
|
|
<tag><tt>--inline-stdfuncs</tt></tag>
|
|
|
|
Allow the compiler to inline some standard functions from the C library like
|
|
strlen. This will not only remove the overhead for a function call, but will
|
|
make the code visible for the optimizer. See also the <tt><ref id="option-O"
|
|
name="-Os"></tt> command line option and <tt><ref id="pragma-inline-stdfuncs"
|
|
name="#pragma inline-stdfuncs"></tt>.
|
|
|
|
|
|
<label id="option-list-warnings">
|
|
<tag><tt>--list-warnings</tt></tag>
|
|
|
|
List the names of warning types available for use with <tt><ref
|
|
id="option-W" name="-W"></tt>.
|
|
|
|
|
|
<label id="option-local-strings">
|
|
<tag><tt>--local-strings</tt></tag>
|
|
|
|
Emit string literals into the rodata segment as soon as they're encountered
|
|
in the source (even if you do nothing but get the sizeof those strings). The
|
|
default is to keep string literals until end of assembly, merge read only
|
|
literals if possible, and then output the literals into the data or rodata
|
|
segment that is active at that point. Use of this option prevents merging of
|
|
duplicate strings, but the options that change the name of one of the data
|
|
segments will work.
|
|
|
|
You can also use <tt><ref id="pragma-local-strings"
|
|
name="#pragma local-strings"></tt> for fine grained control.
|
|
|
|
|
|
<tag><tt>-o name</tt></tag>
|
|
|
|
Specify the name of the output file. If you don't specify a name, the
|
|
name of the C input file is used, with the extension replaced by ".s".
|
|
|
|
|
|
<label id="option-register-vars">
|
|
<tag><tt>-r, --register-vars</tt></tag>
|
|
|
|
<tt/-r/ will make the compiler honor the <tt/register/ keyword. Local
|
|
variables may be placed in registers (which are actually zero page
|
|
locations). There is some overhead involved with register variables, since
|
|
the old contents of the registers must be saved and restored. Since register
|
|
variables are of limited use without the optimizer, there is also a combined
|
|
switch: <tt/-Or/ will enable both, the optimizer and register variables.
|
|
|
|
For more information about register variables see <ref id="register-vars"
|
|
name="register variables">.
|
|
|
|
The compiler setting can also be changed within the source file by using
|
|
<tt/<ref id="pragma-register-vars" name="#pragma register-vars">/.
|
|
|
|
|
|
<label id="option-register-space">
|
|
<tag><tt>--register-space</tt></tag>
|
|
|
|
This option takes a numeric parameter and is used to specify, how much
|
|
zero page register space is available. Please note that just giving this
|
|
option will not increase or decrease by itself, it will just tell the
|
|
compiler about the available space. You will have to allocate that space
|
|
yourself using an assembler module with the necessary allocations, and a
|
|
linker configuration that matches the assembler module. The default value
|
|
for this option is 6 (bytes).
|
|
|
|
If you don't know what all this means, please don't use this option.
|
|
|
|
|
|
<label id="option-rodata-name">
|
|
<tag><tt>--rodata-name seg</tt></tag>
|
|
|
|
Set the name of the rodata segment (the segment used for readonly data).
|
|
See also <tt/<ref id="pragma-rodata-name" name="#pragma rodata-name">/
|
|
|
|
<label id="option-signed-chars">
|
|
<tag><tt>-j, --signed-chars</tt></tag>
|
|
|
|
Using this option, you can make the default characters signed. Since the
|
|
6502 has no provisions for sign extending characters (which is needed on
|
|
almost any load operation), this will make the code larger and slower. A
|
|
better way is to declare characters explicitly as "signed" if needed. You
|
|
can also use <tt><ref id="pragma-signed-chars"
|
|
name="#pragma signed-chars"></tt> for better control of this option.
|
|
|
|
|
|
<label id="option--standard">
|
|
<tag><tt>--standard std</tt></tag>
|
|
|
|
This option allows to set the language standard supported. The argument is
|
|
one of
|
|
<descrip>
|
|
<tag/c89/
|
|
This disables anything that is illegal in C89/C90. Among those things
|
|
are <tt>//</tt> comments and the non-standard keywords without
|
|
underscores. Please note that cc65 is not a fully C89 compliant compiler
|
|
despite this option. A few more things (like floats) are missing.
|
|
|
|
<tag/c99/
|
|
This enables a few features from the C99 standard. With this option,
|
|
<tt>//</tt> comments are allowed. It will also cause warnings and even
|
|
errors in a few situations that are allowed with <tt/--standard c89/.
|
|
For example, a call to a function without a prototype is an error in
|
|
this mode.
|
|
|
|
<tag/cc65/
|
|
This is the default mode. It is like c99 mode, but additional features
|
|
are enabled. Among these are "void data", non-standard keywords without
|
|
the underlines, unnamed function parameters and the requirement for
|
|
main() to return an int.
|
|
</descrip>
|
|
|
|
Please note that the compiler does not support the C99 standard and never
|
|
will. c99 mode is actually c89 mode with a few selected C99 extensions.
|
|
|
|
|
|
<label id="option-t">
|
|
<tag><tt>-t target, --target target</tt></tag>
|
|
|
|
This option is used to set the target system. The target system determines
|
|
the character set that is used for strings and character constants and the
|
|
default CPU. The CPU setting can be overridden by use of the <tt/<ref
|
|
id="option--cpu" name="--cpu">/ option.
|
|
|
|
The following target systems are supported:
|
|
|
|
<itemize>
|
|
<item>none
|
|
<item>apple2
|
|
<item>apple2enh
|
|
<item>atari
|
|
<item>atarixl
|
|
<item>atmos
|
|
<item>c16 (works also for the c116 with memory up to 32K)
|
|
<item>c64
|
|
<item>c128
|
|
<item>cbm510 (CBM-II series with 40 column video)
|
|
<item>cbm610 (all CBM-II II computers with 80 column video)
|
|
<item>geos-apple
|
|
<item>geos-cbm
|
|
<item>lunix
|
|
<item>lynx
|
|
<item>nes
|
|
<item>osic1p
|
|
<item>pet (all CBM PET systems except the 2001)
|
|
<item>plus4
|
|
<item>sim6502
|
|
<item>sim65c02
|
|
<item>supervision
|
|
<item>telestrat
|
|
<item>vic20
|
|
</itemize>
|
|
|
|
<tag><tt>-v, --verbose</tt></tag>
|
|
|
|
Using this option, the compiler will be somewhat more verbose if errors
|
|
or warnings are encountered.
|
|
|
|
|
|
<label id="option-writable-strings">
|
|
<tag><tt>--writable-strings</tt></tag>
|
|
|
|
Make string literals writable by placing them into the data segment instead
|
|
of the rodata segment. You can also use <tt><ref id="pragma-writable-strings"
|
|
name="#pragma writable-strings"></tt> to control this option from within
|
|
the source file.
|
|
|
|
|
|
<label id="option-static-locals">
|
|
<tag><tt>-Cl, --static-locals</tt></tag>
|
|
|
|
Use static storage for local variables instead of storage on the stack.
|
|
Since the stack is emulated in software, this gives shorter and usually
|
|
faster code, but the code is no longer reentrant as required for recursion.
|
|
The difference between <tt/-Cl/ and declaring local variables as static
|
|
yourself is, that initializer code is executed each time, the function is
|
|
entered. So when using
|
|
|
|
<tscreen><verb>
|
|
void f (void)
|
|
{
|
|
unsigned a = 1;
|
|
...
|
|
}
|
|
</verb></tscreen>
|
|
|
|
the variable <tt/a/ will always have the value <tt/1/ when entering the
|
|
function and using <tt/-Cl/, while in
|
|
|
|
<tscreen><verb>
|
|
void f (void)
|
|
{
|
|
static unsigned a = 1;
|
|
....
|
|
}
|
|
</verb></tscreen>
|
|
|
|
the variable <tt/a/ will have the value <tt/1/ only the first time that the
|
|
function is entered, and will keep the old value from one call of the
|
|
function to the next.
|
|
|
|
You may also use <tt><ref id="pragma-static-locals"
|
|
name="#pragma static-locals"></tt> to change this setting in your
|
|
sources.
|
|
|
|
|
|
<label id="option-include-dir">
|
|
<tag><tt>-I dir, --include-dir dir</tt></tag>
|
|
|
|
Set a directory where the compiler searches for include files. You may
|
|
use this option multiple times to add more than one directory to the
|
|
search list.
|
|
|
|
|
|
<label id="option-O">
|
|
<tag><tt>-O, -Oi, -Or, -Os</tt></tag>
|
|
|
|
Enable an optimizer run over the produced code.
|
|
|
|
Using <tt/-Oi/, the code generator will inline some code where otherwise a
|
|
runtime functions would have been called, even if the generated code is
|
|
larger. This will not only remove the overhead for a function call, but will
|
|
make the code visible for the optimizer. <tt/-Oi/ is an alias for
|
|
<tt/-O --codesize 200/.
|
|
|
|
<tt/-Or/ will make the compiler honor the <tt/register/ keyword. Local
|
|
variables may be placed in registers (which are actually zero page
|
|
locations). See also the <tt/<ref id="option-register-vars"
|
|
name="--register-vars">/ command line option, and the <ref
|
|
id="register-vars" name="discussion of register variables"> below.
|
|
|
|
Using <tt/-Os/ will allow the compiler to inline some standard functions
|
|
from the C library like strlen. This will not only remove the overhead
|
|
for a function call, but will make the code visible for the optimizer.
|
|
See also the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/
|
|
command line option.
|
|
|
|
It is possible to concatenate the modifiers for <tt/-O/. For example, to
|
|
enable register variables and inlining of standard functions, you may use
|
|
<tt/-Ors/.
|
|
|
|
|
|
<tag><tt>-T, --add-source</tt></tag>
|
|
|
|
This include the source code as comments in the generated code. This is
|
|
normally not needed.
|
|
|
|
|
|
<tag><tt>-V, --version</tt></tag>
|
|
|
|
Print the version number of the compiler. When submitting a bug report,
|
|
please include the operating system you're using, and the compiler
|
|
version.
|
|
|
|
|
|
<label id="option-W">
|
|
<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
|
|
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 currently are recognized:
|
|
<descrip>
|
|
<tag><tt/const-comparison/</tag>
|
|
Warn if the result of a comparison is constant.
|
|
<tag><tt/error/</tag>
|
|
Treat all warnings as errors.
|
|
<tag><tt/no-effect/</tag>
|
|
Warn about statements that don't have an effect.
|
|
<tag><tt/pointer-sign/</tag>
|
|
Warn if a pointer assignment changes the signedness of the target
|
|
of a pointer value, and the new signedness wasn't cast explicitly.
|
|
<tag><tt/pointer-types/</tag>
|
|
Warn if a pointer assignment changes the type of the target
|
|
of a pointer value, and the new type wasn't cast explicitly.
|
|
<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/return-type/</tag>
|
|
Warn about no return statement in function returning non-void.
|
|
<tag><tt/struct-param/</tag>
|
|
Warn when passing structs by value. (Disabled by default.)
|
|
<tag><tt/unknown-pragma/</tag>
|
|
Warn about #pragmas that aren't recognized by cc65.
|
|
<tag><tt/unreachable-code/</tag>
|
|
Warn about unreachable code in cases of comparing constants, etc.
|
|
<tag><tt/unused-func/</tag>
|
|
Warn about unused functions.
|
|
<tag><tt/unused-label/</tag>
|
|
Warn about unused labels.
|
|
<tag><tt/unused-param/</tag>
|
|
Warn about unused function parameters.
|
|
<tag><tt/unused-var/</tag>
|
|
Warn about unused variables.
|
|
<tag><tt/const-overflow/</tag>
|
|
Warn if numerical constant conversion implies overflow. (Disabled by default.)
|
|
</descrip>
|
|
|
|
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 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>
|
|
|
|
|
|
|
|
<sect>Input and output<p>
|
|
|
|
The compiler will accept one C file per invocation and create a file with
|
|
the same base name, but with the extension replaced by ".s". The output
|
|
file contains assembler code suitable for use with the ca65 macro
|
|
assembler.
|
|
|
|
Include files in quotes are searched in the following places:
|
|
<enum>
|
|
<item>The current file's directory.
|
|
<item>Any directory added with the <tt/-I/ option on the command line.
|
|
<item>The value of the environment variable <tt/CC65_INC/ if it is defined.
|
|
</enum>
|
|
|
|
Include files in angle brackets are searched in the following places:
|
|
<enum>
|
|
<item>Any directory added with the <tt/-I/ option on the command line.
|
|
<item>The value of the environment variable <tt/CC65_INC/ if it is defined.
|
|
<item>A subdirectory named <tt/include/ of the directory defined in the
|
|
environment variable <tt/CC65_HOME/, if it is defined.
|
|
<item>An optionally compiled-in directory.
|
|
</enum>
|
|
|
|
|
|
|
|
<sect>Differences to the ISO standard<p>
|
|
|
|
Apart from the things listed below, the compiler does support additional
|
|
keywords, has several functions in the standard headers with names outside the
|
|
reserved namespace and a few syntax extensions. All these can be disabled with
|
|
the <tt><ref id="option--standard" name="--standard"></tt> command line
|
|
option. Its use for maximum standards compatibility is advised.
|
|
|
|
Here is a list of differences between the language, the compiler accepts,
|
|
and the one defined by the ISO standard:
|
|
|
|
<itemize>
|
|
|
|
<item> The datatypes "float" and "double" are not available.
|
|
Floating point constants may be used, though they will have to be
|
|
converted and stored into integer values.
|
|
Floating point arithmetic expressions are not supported.
|
|
<p>
|
|
<item> C Functions may pass and return structs (or unions) by value, but only
|
|
of 1, 2 or 4 byte sizes.
|
|
<p>
|
|
<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 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>
|
|
</itemize>
|
|
|
|
There may be some more minor differences I'm currently not aware of. The
|
|
biggest problem is the missing float data type. With this limitation in
|
|
mind, you should be able to write fairly portable code.
|
|
|
|
|
|
|
|
<sect>Extensions<p>
|
|
|
|
This cc65 version has some extensions to the ISO C standard.
|
|
|
|
<itemize>
|
|
|
|
<item> The compiler allows to insert inline assembler code in the form of the
|
|
<tt/asm/ expression into the output file. The syntax is
|
|
|
|
<tscreen><verb>
|
|
asm [optional volatile] (<string literal>[, optional parameters])
|
|
</verb></tscreen>
|
|
or
|
|
<tscreen><verb>
|
|
__asm__ [optional volatile] (<string literal>[, optional parameters])
|
|
</verb></tscreen>
|
|
|
|
The first form is in the user namespace; and, is disabled if the <tt/-A/
|
|
switch is given.
|
|
|
|
There is a whole section covering the inline assembler,
|
|
<ref id="inline-asm" name="see there">.
|
|
<p>
|
|
|
|
<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>)
|
|
</verb></tscreen>
|
|
An example is
|
|
<tscreen><verb>
|
|
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 that are <tt/fastcall/, the rightmost parameter is not
|
|
pushed on the stack but left in the primary register when the function
|
|
is called. That significantly reduces the cost of calling those functions.
|
|
<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.
|
|
<p>
|
|
|
|
<item> There are three pseudo variables named <tt/__A__/, <tt/__AX__/ and
|
|
<tt/__EAX__/. They all refer to the primary register that is used
|
|
by the compiler to evaluate expressions or return function results.
|
|
<tt/__A__/ is of type <tt/unsigned char/, <tt/__AX__/ is of type
|
|
<tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/
|
|
respectively. The pseudo variables may be used as lvalue and rvalue
|
|
as every other variable. They are most useful together with short
|
|
sequences of assembler code. For example, the macro
|
|
|
|
<tscreen><verb>
|
|
#define hi(x) \
|
|
(__AX__ = (x), \
|
|
asm ("txa"), \
|
|
asm ("ldx #$00"), \
|
|
__AX__)
|
|
</verb></tscreen>
|
|
|
|
will give the high byte of any unsigned value.
|
|
<p>
|
|
|
|
<item> Inside a function, the identifier <tt/__func__/ gives the name of the
|
|
current function as a string. Outside of functions, <tt/__func__/ is
|
|
undefined.
|
|
Example:
|
|
|
|
<tscreen><verb>
|
|
#define PRINT_DEBUG(s) printf ("%s: %s\n", __func__, s);
|
|
</verb></tscreen>
|
|
|
|
The macro will print the name of the current function plus a given
|
|
string.
|
|
<p>
|
|
|
|
<item> cc65 allows the initialization of <tt/void/ variables. This may be
|
|
used to create arbitrary structures that are more compatible with
|
|
interfaces written for assembler languages. Here is an example:
|
|
|
|
<tscreen><verb>
|
|
void GCmd = { (char)3, (unsigned)0x2000, (unsigned)0x3000 };
|
|
</verb></tscreen>
|
|
|
|
That will be translated as follows:
|
|
|
|
<tscreen><verb>
|
|
_GCmd:
|
|
.byte 3
|
|
.word $2000
|
|
.word $3000
|
|
</verb></tscreen>
|
|
|
|
Since the variable is of type <tt/void/, you may not use it as-is.
|
|
However, taking the address of the variable results in a <tt/void*/
|
|
which may be passed to any function expecting a pointer. Also, the
|
|
<tt/sizeof/ operator will give the length of the initializer:
|
|
|
|
<tscreen><verb>
|
|
GLen = sizeof GCmd;
|
|
</verb></tscreen>
|
|
|
|
will assign the value 5 to <tt/GLen/.
|
|
|
|
See the <url url="geos.html" name="GEOS library document"> for examples
|
|
on how to use that feature.
|
|
<p>
|
|
|
|
<item> cc65 implements flexible array struct members as defined in the C99 ISO
|
|
standard. As an extension, these fields may be initialized. There are
|
|
several exceptions, however (which is probably the reason why the
|
|
standard does not define this feature, because it is highly
|
|
unorthogonal). Flexible array members cannot be initialized ...
|
|
|
|
<itemize>
|
|
<item>... when defining an array of structs with flexible
|
|
members.
|
|
<item>... if such a struct is a member field of another struct
|
|
which is not the last field.
|
|
<item>... if the struct which contains a flexible array member is
|
|
declared as <tt/register/, and the size and compiler settings
|
|
do allow the compiler actually to place the struct into the
|
|
register bank in the zero page.
|
|
</itemize>
|
|
|
|
Please note that -- as defined in the ISO C standard -- the <tt/sizeof/
|
|
operator returns the struct size with the flexible array member having
|
|
size zero, even if it is initialized.
|
|
<p>
|
|
|
|
<item> cc65 supports <tt/_Static_assert/ from C11 and C2X. This is similar
|
|
to <tt/#error/ but happens at a later stage of translation, so types
|
|
can be used.
|
|
|
|
<tscreen><verb>
|
|
/* C11 version with message. */
|
|
_Static_assert (sizeof (int) == 2, "Expected 2-bytes ints.");
|
|
|
|
/* C2X version without message. */
|
|
_Static_assert (sizeof (int) == 2);
|
|
</verb></tscreen>
|
|
|
|
<tt/_Static_assert/ is also available as the macro <tt/static_assert/ in
|
|
<tt/assert.h/.
|
|
|
|
Note: The string literal as the message in the <tt/_Static_assert/
|
|
declaration is not subject to string literal translation (see
|
|
<tt/<ref id="pragma-charmap" name="#pragma charmap()">/) and will
|
|
always be in the host encoding. On the other hand, any character or
|
|
string literals present in the condition expression of the
|
|
<tt/_Static_assert/ declaration will be translated as usual.
|
|
|
|
<item> cc65 supports bit-fields of any integral type that is int-sized or
|
|
smaller, and enumerated types with those types as their underlying
|
|
type. (Only <tt/int/, <tt/signed int/, and <tt/unsigned int/ are
|
|
required by the standard.)
|
|
|
|
<item> Computed gotos, a GCC extension, has limited support. With it you can
|
|
use fast jump tables from C. You can take the address of a label with
|
|
a double ampersand, putting them in a static const array of type void *.
|
|
Then you can jump to one of these labels as follows:
|
|
|
|
<tscreen><verb>
|
|
static const void * const jumptable[] = {
|
|
&&add,
|
|
&&sub
|
|
};
|
|
goto *jumptable[somevar];
|
|
|
|
add:
|
|
...code...
|
|
</verb></tscreen>
|
|
|
|
In the jump table, no expressions are supported. The array index
|
|
used in the goto must be a simple variable or a constant.
|
|
|
|
<item> Binary literals, a C++14 feature and a GCC C extension, are accepted.
|
|
They can be disabled with the <tt><ref id="option--standard"
|
|
name="--standard"></tt> option.
|
|
|
|
<tscreen><verb>
|
|
unsigned char foo = 0b101; // sets it to 5
|
|
</verb></tscreen>
|
|
|
|
</itemize>
|
|
<p>
|
|
|
|
|
|
|
|
<sect>Predefined macros<p>
|
|
|
|
The compiler defines several macros at startup:
|
|
|
|
<descrip>
|
|
<tag><tt>__APPLE2__</tt></tag>
|
|
|
|
This macro is defined if the target is the Apple ][ (-t apple2) or the enhanced Apple //e (-t apple2enh).
|
|
|
|
<tag><tt>__APPLE2ENH__</tt></tag>
|
|
|
|
This macro is defined if the target is the enhanced Apple //e (-t apple2enh).
|
|
|
|
<tag><tt>__ATARI2600__</tt></tag>
|
|
|
|
This macro is defined if the target is the Atari 2600 game console.
|
|
|
|
<tag><tt>__ATARI5200__</tt></tag>
|
|
|
|
This macro is defined if the target is the Atari 5200 game console.
|
|
|
|
<tag><tt>__ATARI__</tt></tag>
|
|
|
|
This macro is defined if the target is the Atari 400/800 (-t atari) or the Atari 800XL/130XE (-t atarixl).
|
|
|
|
<tag><tt>__ATARIXL__</tt></tag>
|
|
|
|
This macro is defined if the target is the Atari 800XL/130XE (-t atarixl).
|
|
|
|
<tag><tt>__ATMOS__</tt></tag>
|
|
|
|
This macro is defined if the target is the Oric Atmos (-t atmos).
|
|
|
|
<tag><tt>__C128__</tt></tag>
|
|
|
|
This macro is defined if the target is the Commodore 128 (-t c128).
|
|
|
|
<tag><tt>__C16__</tt></tag>
|
|
|
|
This macro is defined if the target is the Commodore 16/116 (-t c16) or the Commodore Plus/4 (-t plus4).
|
|
|
|
<tag><tt>__C64__</tt></tag>
|
|
|
|
This macro is defined if the target is the Commodore 64 (-t c64).
|
|
|
|
<tag><tt>__CBM__</tt></tag>
|
|
|
|
This macro is defined if the target system is one of the CBM targets.
|
|
|
|
<tag><tt>__CBM510__</tt></tag>
|
|
|
|
This macro is defined if the target is the CBM 500 series of computers.
|
|
|
|
<tag><tt>__CBM610__</tt></tag>
|
|
|
|
This macro is defined if the target is one of the CBM 600/700 family of
|
|
computers (called B series in the US).
|
|
|
|
<tag><tt>__CC65__</tt></tag>
|
|
|
|
This macro is always defined. Its value is the version number of the
|
|
compiler in hex: <tt>(VER_MAJOR * 0x100) + VER_MINOR</tt>. The upper 8 bits
|
|
are the major-, the lower 8 bits are the minor version. For example, version
|
|
47.11 of the compiler would have this macro defined as <tt/0x2f0b/.
|
|
|
|
Note: until 2.19 this macro was defined as <tt>(VER_MAJOR * 0x100) + VER_MINOR * 0x10</tt> -
|
|
which resulted in broken values starting at version 2.16 of the compiler. For
|
|
this reason the value of this macro is considered purely informal - you should
|
|
not use it to check for a specific compiler version and use different code
|
|
according to the detected version - please update your code to work with the
|
|
recent version of the compiler instead (There is very little reason to not use
|
|
the most recent version - and even less to support older versions in your code).
|
|
|
|
Should you still insist on doing this for some reason - look at <tt>checkversion.c</tt>
|
|
in the samples directory for some preprocessor kludges that might help.
|
|
|
|
<tag><tt>__CC65_STD__</tt></tag>
|
|
|
|
This macro is defined to one of the following depending on the <tt><ref
|
|
id="option--standard" name="--standard"></tt> command line option:
|
|
<itemize>
|
|
<item><tt/__CC65_STD_C89__/
|
|
<item><tt/__CC65_STD_C99__/
|
|
<item><tt/__CC65_STD_CC65__/
|
|
</itemize>
|
|
|
|
<tag><tt>__CX16__</tt></tag>
|
|
|
|
This macro is defined if the target is the Commander X16 (-t cx16).
|
|
|
|
<tag><tt>__DATE__</tt></tag>
|
|
|
|
This macro expands to the date of translation of the preprocessing
|
|
translation unit in the form "Mmm dd yyyy".
|
|
|
|
<tag><tt>__EAGERLY_INLINE_FUNCS__</tt></tag>
|
|
|
|
Is defined if the compiler was called with the <tt><ref id="option-eagerly-inline-funcs"
|
|
name="--eagerly-inline-funcs"></tt> command line option.
|
|
|
|
<tag><tt>__FILE__</tt></tag>
|
|
|
|
This macro expands to a string containing the name of the C source file.
|
|
|
|
<tag><tt>__GEOS__</tt></tag>
|
|
|
|
This macro is defined if you are compiling for one of the GEOS systems.
|
|
|
|
<tag><tt>__GEOS_APPLE__</tt></tag>
|
|
|
|
This macro is defined if you are compiling for the Apple GEOS system (-t geos-apple).
|
|
|
|
<tag><tt>__GEOS_CBM__</tt></tag>
|
|
|
|
This macro is defined if you are compiling for the GEOS 64/128 system (-t geos-cbm).
|
|
|
|
<tag><tt>__LINE__</tt></tag>
|
|
|
|
This macro expands to the current line number.
|
|
|
|
<tag><tt>__LUNIX__</tt></tag>
|
|
|
|
This macro is defined if you are compiling for the LUnix system (-t lunix).
|
|
|
|
<tag><tt>__LYNX__</tt></tag>
|
|
|
|
This macro is defined if the target is the Atari Lynx (-t lynx).
|
|
|
|
<tag><tt>__NES__</tt></tag>
|
|
|
|
This macro is defined if the target is the Nintendo Entertainment System (-t nes).
|
|
|
|
<tag><tt>__OPT__</tt></tag>
|
|
|
|
Is defined if the compiler was called with the <tt/-O/ command line option.
|
|
|
|
<tag><tt>__OPT_i__</tt></tag>
|
|
|
|
Is defined if the compiler was called with the <tt/-Oi/ command line option.
|
|
|
|
<tag><tt>__OPT_r__</tt></tag>
|
|
|
|
Is defined if the compiler was called with the <tt/-Or/ command line option.
|
|
|
|
<tag><tt>__OPT_s__</tt></tag>
|
|
|
|
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).
|
|
|
|
<tag><tt>__PLUS4__</tt></tag>
|
|
|
|
This macro is defined if the target is the Commodore Plus/4 (-t plus4).
|
|
|
|
<tag><tt>__SIM6502__</tt></tag>
|
|
|
|
This macro is defined if the target is sim65 in 6502 mode (-t sim6502).
|
|
|
|
<tag><tt>__SIM65C02__</tt></tag>
|
|
|
|
This macro is defined if the target is sim65 in 65C02 mode (-t sim65c02).
|
|
|
|
<tag><tt>__STDC_HOSTED__</tt></tag>
|
|
|
|
This macro expands to the integer constant 1.
|
|
|
|
<tag><tt>__STDC_NO_ATOMICS__</tt></tag>
|
|
|
|
This macro expands to the integer constant 1 if the language standard is cc65 (--standard cc65).
|
|
|
|
<tag><tt>__STDC_NO_COMPLEX__</tt></tag>
|
|
|
|
This macro expands to the integer constant 1 if the language standard is cc65 (--standard cc65).
|
|
|
|
<tag><tt>__STDC_NO_THREADS__</tt></tag>
|
|
|
|
This macro expands to the integer constant 1 if the language standard is cc65 (--standard cc65).
|
|
|
|
<tag><tt>__STDC_NO_VLA__</tt></tag>
|
|
|
|
This macro expands to the integer constant 1 if the language standard is cc65 (--standard cc65).
|
|
|
|
<tag><tt>__SUPERVISION__</tt></tag>
|
|
|
|
This macro is defined if the target is the Supervision (-t supervision).
|
|
|
|
<tag><tt>__SYM1__</tt></tag>
|
|
|
|
This macro is defined if the target is the Sym-1 (-t sym1).
|
|
|
|
<tag><tt>__TELESTRAT__</tt></tag>
|
|
|
|
This macro is defined if the target is the Telestrat (-t telestrat).
|
|
|
|
<tag><tt>__TIME__</tt></tag>
|
|
|
|
This macro expands to the time of translation of the preprocessing
|
|
translation unit in the form "hh:mm:ss".
|
|
|
|
<tag><tt>__VIC20__</tt></tag>
|
|
|
|
This macro is defined if the target is the Commodore VIC20 (-t vic20).
|
|
</descrip>
|
|
|
|
|
|
|
|
<sect>#pragmas<label id="pragmas"><p>
|
|
|
|
The compiler understands some pragmas that may be used to change code
|
|
generation and other stuff. Some of these pragmas understand a special form:
|
|
If the first parameter is <tt/push/, the old value is saved onto a stack
|
|
before changing it. The value may later be restored by using the <tt/pop/
|
|
parameter with the <tt/#pragma/.
|
|
|
|
|
|
<sect1><tt>#pragma allow-eager-inline ([push,] on|off)</tt><label id="pragma-allow-eager-inline"><p>
|
|
|
|
Allow eager inlining of known functions. If the argument is "off", eager
|
|
inlining is disabled, otherwise it is enabled. Please note that (in contrast
|
|
to the <tt><ref id="option-eagerly-inline-funcs" name="--eagerly-inline-funcs"></tt>
|
|
command line option) this pragma does not imply the <tt><ref id="option-inline-stdfuncs"
|
|
name="--inline-stdfuncs"></tt> command line option. Rather it marks code to be safe for
|
|
eager inlining of known functions if inlining of standard functions is enabled.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma bss-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-bss-name"><p>
|
|
|
|
This pragma changes the name used for the BSS segment (the BSS segment is
|
|
used to store variables with static storage duration and no explicit
|
|
initializers). The <tt/name/ argument is a string enclosed in quotation
|
|
marks.
|
|
|
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
|
width of address numbers that point into that segment. Only words that
|
|
are known to ca65 are allowed:
|
|
<enum>
|
|
<item>"zp", "zeropage", "direct"
|
|
<item>"abs", "absolute", "near", "default"
|
|
<item>"far"
|
|
<item>"long", "dword"
|
|
</enum>
|
|
|
|
Note: The default linker configuration file maps only the standard segments.
|
|
If you use other segments, you must create a new linker configuration file.
|
|
|
|
Beware: The start-up code will zero only the default BSS segment. If you use
|
|
another BSS segment, then you must do that yourself; otherwise, variables
|
|
with static storage duration and no explicit initializer will not have the
|
|
value zero.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
|
|
|
Examples:
|
|
<tscreen><verb>
|
|
#pragma bss-name ("MyBSS")
|
|
#pragma bss-name (push, "MyBSS")
|
|
#pragma bss-name ("MyBSS", "zp")
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma charmap (<index>, <code>)</tt><label id="pragma-charmap"><p>
|
|
|
|
Each literal string and each literal character in the preprocessed source,
|
|
except when used in an <tt/asm/ expression as the inline assembler code or
|
|
in a <tt/_Static_assert/ declaration as the failure message, is translated
|
|
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. Both arguments are assumed to be unsigned characters with a valid
|
|
range of 0-255.
|
|
|
|
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);
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma check-stack ([push,] on|off)</tt><label id="pragma-check-stack"><p>
|
|
|
|
Tells the compiler to insert calls to a stack checking subroutine to detect
|
|
stack overflows. The stack checking code will lead to somewhat larger and
|
|
slower programs, so you may want to use this pragma when debugging your
|
|
program and switch it off for the release version. If a stack overflow is
|
|
detected, the program is aborted.
|
|
|
|
If the argument is "off", stack checks are disabled (the default), otherwise
|
|
they're enabled.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma code-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-code-name"><p>
|
|
|
|
This pragma changes the name used for the CODE segment (the CODE segment is
|
|
used to store executable code). The <tt/name/ argument is a string enclosed
|
|
in quotation marks.
|
|
|
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
|
width of address numbers that point into that segment. Only words that
|
|
are known to ca65 are allowed:
|
|
<enum>
|
|
<item>"zp", "zeropage", "direct"
|
|
<item>"abs", "absolute", "near", "default"
|
|
<item>"far"
|
|
<item>"long", "dword"
|
|
</enum>
|
|
|
|
Note: The default linker configuration file maps only the standard segments.
|
|
If you use other segments, you must create a new linker configuration file.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
|
|
|
Examples:
|
|
<tscreen><verb>
|
|
#pragma code-name ("MyCODE")
|
|
#pragma code-name (push, "MyCODE")
|
|
#pragma code-name (push, "MyCODE", "far")
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma codesize ([push,] <int>)</tt><label id="pragma-codesize"><p>
|
|
|
|
This pragma allows finer control about speed vs. size decisions in the code
|
|
generation and optimization phase. It gives the allowed size increase factor
|
|
(in percent). The default is can be changed by use of the <tt/<ref
|
|
id="option-codesize" name="--codesize">/ compiler option.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma data-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-data-name"><p>
|
|
|
|
This pragma changes the name used for the DATA segment (the DATA segment is
|
|
used to store initialized data). The <tt/name/ argument is a string enclosed
|
|
in quotation marks.
|
|
|
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
|
width of address numbers that point into that segment. Only words that
|
|
are known to ca65 are allowed:
|
|
<enum>
|
|
<item>"zp", "zeropage", "direct"
|
|
<item>"abs", "absolute", "near", "default"
|
|
<item>"far"
|
|
<item>"long", "dword"
|
|
</enum>
|
|
|
|
Note: The default linker configuration file maps only the standard segments.
|
|
If you use other segments, you must create a new linker configuration file.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
|
|
|
Examples:
|
|
<tscreen><verb>
|
|
#pragma data-name ("MyDATA")
|
|
#pragma data-name (push, "MyDATA")
|
|
#pragma data-name ("MyDATA", "zeropage")
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma inline-stdfuncs ([push,] on|off)</tt><label id="pragma-inline-stdfuncs"><p>
|
|
|
|
Allow the compiler to inline some standard functions from the C library like
|
|
strlen. If the argument is "off", inlining is disabled, otherwise it is enabled.
|
|
|
|
See also the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/
|
|
command line option.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma local-strings ([push,] on|off)</tt><label id="pragma-local-strings"><p>
|
|
|
|
When "on", emit string literals to the data segment when they're encountered
|
|
in the source. The default ("off") is to keep string literals until end of
|
|
assembly, merge read only literals if possible, and then output the literals
|
|
into the data or rodata segment that is active at that point.
|
|
|
|
Using this <tt/#pragma/ it is possible to control the behaviour from within
|
|
the source. When <tt/#pragma local-strings/ is active, string literals are
|
|
output immediately, which means that they go into the currently active data
|
|
or rodata segment, but cannot be merged. When inactive, string literals are
|
|
remembered and output as a whole when translation is finished.
|
|
|
|
|
|
<sect1><tt>#pragma message (<message>)</tt><label id="pragma-message"><p>
|
|
|
|
This pragma is used to display informational messages at compile-time.
|
|
|
|
The message intended to be displayed must be a string literal.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
#pragma message ("in a bottle")
|
|
</verb></tscreen>
|
|
|
|
Results in the compiler outputting the following to stderr:
|
|
<tscreen><verb>
|
|
example.c(42): Note: in a bottle
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma optimize ([push,] on|off)</tt><label id="pragma-optimize"><p>
|
|
|
|
Switch optimization on or off. If the argument is "off", optimization is
|
|
disabled, otherwise it is enabled. Please note that this pragma only effects
|
|
whole functions. The setting in effect when the function is encountered will
|
|
determine if the generated code is optimized or not.
|
|
|
|
Optimization and code generation is also controlled by the <ref
|
|
id="pragma-codesize" name="codesize pragma">.
|
|
|
|
The default is "off", but may be changed with the <tt/<ref name="-O"
|
|
id="option-O">/ compiler option.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma rodata-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-rodata-name"><p>
|
|
|
|
This pragma changes the name used for the RODATA segment (the RODATA segment
|
|
is used to store read-only data). The <tt/name/ argument is a string enclosed
|
|
in quotation marks.
|
|
|
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
|
width of address numbers that point into that segment. Only words that
|
|
are known to ca65 are allowed:
|
|
<enum>
|
|
<item>"zp", "zeropage", "direct"
|
|
<item>"abs", "absolute", "near", "default"
|
|
<item>"far"
|
|
<item>"long", "dword"
|
|
</enum>
|
|
|
|
Note: The default linker configuration file maps only the standard segments.
|
|
If you use other segments, you must create a new linker configuration file.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
|
|
|
Examples:
|
|
<tscreen><verb>
|
|
#pragma rodata-name ("MyRODATA")
|
|
#pragma rodata-name (push, "MyRODATA")
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma regvaraddr ([push,] on|off)</tt><label id="pragma-regvaraddr"><p>
|
|
|
|
The compiler does not allow to take the address of register variables.
|
|
The regvaraddr pragma changes this. Taking the address of a register
|
|
variable is allowed after using this pragma with "on" as argument.
|
|
Using "off" as an argument switches back to the default behaviour.
|
|
|
|
Beware: The C standard does not allow taking the address of a variable
|
|
declared as register. So your programs become non-portable if you use
|
|
this pragma. In addition, your program may not work. This is usually the
|
|
case if a subroutine is called with the address of a register variable,
|
|
and this subroutine (or a subroutine called from there) uses
|
|
register variables. So be careful with this #pragma.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
#pragma regvaraddr(on) /* Allow taking the address
|
|
* of register variables
|
|
*/
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma register-vars ([push,] on|off)</tt><label id="pragma-register-vars"><p>
|
|
|
|
Enables or disables use of register variables. If register variables are
|
|
disabled (the default), the <tt/register/ keyword is ignored. Register
|
|
variables are explained in more detail in <ref id="register-vars" name="a separate
|
|
chapter">.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma signed-chars ([push,] on|off)</tt><label id="pragma-signed-chars"><p>
|
|
|
|
Changes the signedness of the default character type. If the argument is
|
|
"on", default characters are signed, otherwise characters are unsigned. The
|
|
compiler default is to make characters unsigned since this creates a lot
|
|
better code. This default may be overridden by the <tt/<ref
|
|
name="--signed-chars" id="option-signed-chars">/ command line option.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma static-locals ([push,] on|off)</tt><label id="pragma-static-locals"<p>
|
|
|
|
Use variables in the bss segment instead of variables on the stack. This
|
|
pragma changes the default set by the compiler option <tt/<ref
|
|
name="--static-locals" id="option-static-locals">/. If the argument is "on",
|
|
local variables are allocated in the BSS segment, leading to shorter and in
|
|
most cases faster, but non-reentrant code.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma warn (name, [push,] on|off)</tt><label id="pragma-warn"><p>
|
|
|
|
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
|
|
followed either by "pop", which restores the last pushed state, or by "on" or
|
|
"off", optionally preceded by "push" to push the current state before
|
|
changing it.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
/* Don't warn about the unused parameter in function func */
|
|
#pragma warn (unused-param, push, off)
|
|
static int func (int unused)
|
|
{
|
|
return 0;
|
|
}
|
|
#pragma warn (unused-param, pop)
|
|
</verb></tscreen>
|
|
|
|
|
|
<sect1><tt>#pragma wrapped-call (push, <name>, <identifier>)</tt><label id="pragma-wrapped-call"><p>
|
|
|
|
This pragma sets a wrapper for functions, often used for trampolines.
|
|
|
|
The <tt/name/ is a wrapper function returning <tt/void/, and taking no parameters.
|
|
It must preserve the CPU's <tt/A/ and <tt/X/ registers if it wraps any
|
|
<tt/__fastcall__/ functions that have parameters. It must preserve
|
|
the <tt/Y/ register if it wraps any variadic functions (they have "<tt/.../"
|
|
in their prototypes).
|
|
|
|
The <tt/identifier/ is an 8-bit number that's set into <tt/tmp4/. If the <tt/identifier/
|
|
is "bank", then ca65's <tt><url url="ca65.html#.BANK" name=".bank"></tt> function will be used
|
|
to determine the number from the bank attribute defined in the linker config,
|
|
see <url url="ld65.html#MEMORY" name="Other MEMORY area attributes">. Note that
|
|
this currently implies that only the least significant 8 bits of the bank attribute
|
|
can be used.
|
|
|
|
The address of a wrapped function is passed in <tt/ptr4/. The wrapper can
|
|
call that function by using "<tt/jsr callptr4/".
|
|
|
|
All functions ever declared or defined when this pragma is in effect will be wrapped
|
|
when they are called explicitly by their names later in the same translation unit.
|
|
Invocation of these functions in any other ways, for example, that via a function
|
|
pointer or in inline assembly code, will not be wrapped.
|
|
|
|
This feature is useful, for example, with banked memory, to switch banks
|
|
automatically to where a wrapped function resides, and then to restore the
|
|
previous bank when it returns.
|
|
|
|
The <tt/#pragma/ requires the push or pop argument as explained above.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
/* Note that this code can be in a header. */
|
|
void mytrampoline(void); /* Doesn't corrupt __AX__ */
|
|
|
|
#pragma wrapped-call (push, mytrampoline, 5)
|
|
void somefunc1(void);
|
|
void somefunc2(int, char *);
|
|
#pragma wrapped-call (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,
|
|
the C standard defines that string literals are of type "char[]", but
|
|
writing to such a literal causes undefined behaviour. Most compilers
|
|
(including cc65) place string literals in the read-only data segment, which
|
|
may cause problems with old C code that writes to string literals.
|
|
|
|
Using this pragma (or the corresponding command line option <tt/<ref
|
|
name="--writable-strings" id="option-writable-strings">/) causes the
|
|
literals to be placed in the data segment so they can be written to without
|
|
worry.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
|
|
<sect1><tt>#pragma zpsym (<name>)</tt><p>
|
|
|
|
Tell the compiler that the -- previously as external declared -- symbol with
|
|
the given name is a zero page symbol (usually from an assembler file).
|
|
The compiler will create a matching import declaration for the assembler.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
extern int foo;
|
|
#pragma zpsym ("foo"); /* foo is in the zeropage */
|
|
</verb></tscreen>
|
|
|
|
|
|
|
|
<sect>Register variables<label id="register-vars"><p>
|
|
|
|
The runtime for all supported platforms has 6 bytes of zero page space
|
|
available for register variables (this could be increased, but I think it's a
|
|
good value). So you can declare register variables up to a total size of 6 per
|
|
function. The compiler will allocate register space on a "first come, first
|
|
served" base and convert any <tt/register/ declarations that exceed the
|
|
available register space silently to <tt/auto/. Parameters can also be
|
|
declared as <tt/register/, this will in fact give slightly shorter code than
|
|
using a register variable.
|
|
|
|
Since a function must save the current values of the registers on entry and
|
|
restore them on exit, there is an overhead associated with register variables,
|
|
and this overhead is quite high (about 20 bytes per variable). This means that
|
|
just declaring anything as <tt/register/ is not a good idea.
|
|
|
|
The best use for register variables are pointers, especially those that point
|
|
to structures. The magic number here is about 3 uses of a struct field: If the
|
|
function contains this number or even more, the generated code will be usually
|
|
shorter and faster when using a register variable for the struct pointer. The
|
|
reason for this is that the register variable can in many cases be used as a
|
|
pointer directly. Having a pointer in an auto variable means that this pointer
|
|
must first be copied into a zero page location, before it can be dereferenced.
|
|
|
|
Second best use for register variables are counters. However, there is not
|
|
much difference in the code generated for counters, so you will need at least
|
|
100 operations on this variable (for example in a loop) to make it worth the
|
|
trouble. The only savings you get here are by the use of a zero page variable
|
|
instead of one on the stack or in the data segment.
|
|
|
|
Register variables must be explicitly enabled, either by using <tt/<ref
|
|
name="-Or" id="option-O">/ or <tt/<ref name="--register-vars"
|
|
id="option-register-vars">/ on the command line or by use of <tt/<ref
|
|
name="#pragma register-vars" id="pragma-register-vars">/. Register variables
|
|
are only accepted on function top level, register variables declared in
|
|
interior blocks are silently converted to <tt/auto/. With register variables
|
|
disabled, all variables declared as <tt/register/ are actually auto variables.
|
|
|
|
Please take care when using register variables: While they are helpful and can
|
|
lead to a tremendous speedup when used correctly, improper usage will cause
|
|
bloated code and a slowdown.
|
|
|
|
|
|
|
|
<sect>Inline assembler<label id="inline-asm"><p>
|
|
|
|
The compiler allows to insert inline assembler code in the form of the <tt/asm/
|
|
expression into the output file. The syntax is
|
|
|
|
<tscreen><verb>
|
|
asm [optional volatile] (<string literal>[, optional parameters])
|
|
</verb></tscreen>
|
|
or
|
|
<tscreen><verb>
|
|
__asm__ [optional volatile] (<string literal>[, optional parameters])
|
|
</verb></tscreen>
|
|
<p>
|
|
|
|
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 <tt/asm/ expression can be used only inside a function. The result of an
|
|
<tt/asm/ 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 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 built-in inline assembler is not a replacement for
|
|
the full-blown macro assembler which comes with the compiler.
|
|
|
|
Note: Inline assembler expressions are subject to all optimizations done by the
|
|
compiler. There currently is no way to protect an inline assembler expression
|
|
-- 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/
|
|
expressions. It will disable optimization for the functions in which those
|
|
<tt/asm volatile/ expressions sit. The effect is the same as though you put
|
|
<tt/#pragma optimize(push, off)/ above those functions, and <tt/#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.
|
|
|
|
Note: The string literal as the inline assembler code itself in the <tt/asm/
|
|
expression is not subject to string literal translation (see
|
|
<tt/<ref id="pragma-charmap" name="#pragma charmap()">/) and will always
|
|
be in the host encoding. On the other hand, all character and string literals
|
|
as the arguments for replacing the format specifiers will be translated as
|
|
usual.
|
|
|
|
<itemize>
|
|
<item><tt/%b/ - Numerical 8-bit value
|
|
<item><tt/%w/ - Numerical 16-bit value
|
|
<item><tt/%l/ - Numerical 32-bit value
|
|
<item><tt/%v/ - Assembler name of a global variable or function
|
|
<item><tt/%o/ - Stack offset of a local variable
|
|
<item><tt/%g/ - Assembler name of a C label
|
|
<item><tt/%s/ - The argument is converted to a string
|
|
<item><tt/%%/ - The % sign itself
|
|
</itemize><p>
|
|
|
|
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 index register, one would use
|
|
|
|
<tscreen><verb>
|
|
#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;
|
|
unsigned char data[32];
|
|
} pixel_t;
|
|
static pixel_t pixel;
|
|
__asm__ ("ldy #%b", offsetof(pixel_t, color));
|
|
__asm__ ("lda %v,y", pixel);
|
|
|
|
/* or to access an array member */
|
|
static unsigned char i;
|
|
__asm__ ("ldy %v", i);
|
|
__asm__ ("lda %v+%b,y", pixel, offsetof(pixel_t, data));
|
|
</verb></tscreen>
|
|
<p>
|
|
The next example shows how to use global variables to exchange data between C
|
|
and assembler; and, how to handle assembler jumps:
|
|
|
|
<tscreen><verb>
|
|
static unsigned char globalSubA, globalSubB, globalSubResult;
|
|
|
|
/* return a-b, return 255 if b>a */
|
|
unsigned char sub (unsigned char a, unsigned char b)
|
|
{
|
|
globalSubA = a;
|
|
globalSubB = b;
|
|
__asm__ ("sec");
|
|
__asm__ ("lda %v", globalSubA);
|
|
__asm__ ("sbc %v", globalSubB);
|
|
__asm__ ("bcs %g", jumpSubNoError);
|
|
__asm__ ("lda #$FF");
|
|
jumpSubNoError:
|
|
__asm__ ("sta %v", globalSubResult);
|
|
return globalSubResult;
|
|
}
|
|
</verb></tscreen>
|
|
<p>
|
|
|
|
Arrays also can be accessed:
|
|
|
|
<tscreen><verb>
|
|
static const unsigned char globalSquareTable[] = {
|
|
0, 1, 4, 9, 16, 25, 36, 49, 64, 81,
|
|
100, 121, 144, 169, 196, 225
|
|
};
|
|
static unsigned char globalSquareA, globalSquareResult;
|
|
|
|
/* return a*a for a<16, else 255 */
|
|
unsigned char square (unsigned char a)
|
|
{
|
|
if (a > 15) {
|
|
return 255;
|
|
}
|
|
globalSquareA = a;
|
|
__asm__ ("ldx %v", globalSquareA);
|
|
__asm__ ("lda %v,x", globalSquareTable);
|
|
__asm__ ("sta %v", globalSquareResult);
|
|
return globalSquareResult;
|
|
}
|
|
</verb></tscreen>
|
|
<p>
|
|
|
|
Note: Do not embed the assembler labels that are used as names of global
|
|
variables or functions into your <tt/asm/ expressions. Code such as this:
|
|
|
|
<tscreen><verb>
|
|
int foo;
|
|
int bar (void) { return 1; }
|
|
...
|
|
__asm__ ("lda _foo"); /* DON'T DO THAT! */
|
|
...
|
|
__asm__ ("jsr _bar"); /* DON'T DO THAT EITHER! */
|
|
</verb></tscreen>
|
|
<p>
|
|
|
|
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__ ("jsr %v", bar); /* OK */
|
|
</verb></tscreen>
|
|
<p>
|
|
|
|
|
|
|
|
<sect>Implementation-defined behavior<p>
|
|
|
|
This section describes the behavior of cc65 when the standard describes the
|
|
behavior as implementation-defined.
|
|
|
|
(to be done)
|
|
|
|
<sect>Copyright<p>
|
|
|
|
This is the original compiler copyright:
|
|
|
|
<tscreen><verb>
|
|
--------------------------------------------------------------------------
|
|
-*- Mode: Text -*-
|
|
|
|
This is the copyright notice for RA65, LINK65, LIBR65, and other
|
|
Atari 8-bit programs. Said programs are Copyright 1989, by John R.
|
|
Dunning. All rights reserved, with the following exceptions:
|
|
|
|
Anyone may copy or redistribute these programs, provided that:
|
|
|
|
1: You don't charge anything for the copy. It is permissible to
|
|
charge a nominal fee for media, etc.
|
|
|
|
2: All source code and documentation for the programs is made
|
|
available as part of the distribution.
|
|
|
|
3: This copyright notice is preserved verbatim, and included in
|
|
the distribution.
|
|
|
|
You are allowed to modify these programs, and redistribute the
|
|
modified versions, provided that the modifications are clearly noted.
|
|
|
|
There is NO WARRANTY with this software, it comes as is, and is
|
|
distributed in the hope that it may be useful.
|
|
|
|
This copyright notice applies to any program which contains
|
|
this text, or the refers to this file.
|
|
|
|
This copyright notice is based on the one published by the Free
|
|
Software Foundation, sometimes known as the GNU project. The idea
|
|
is the same as theirs, ie the software is free, and is intended to
|
|
stay that way. Everybody has the right to copy, modify, and re-
|
|
distribute this software. Nobody has the right to prevent anyone
|
|
else from copying, modifying or redistributing it.
|
|
|
|
--------------------------------------------------------------------------
|
|
</verb></tscreen>
|
|
|
|
Small parts of the compiler (parts of the preprocessor and main parser) are
|
|
still covered by this copyright. The main portion is covered by the usual
|
|
cc65 license, which reads:
|
|
|
|
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>
|