mirror of
https://github.com/cc65/cc65.git
synced 2024-12-28 22:30:12 +00:00
0cb60439c8
git-svn-id: svn://svn.cc65.org/cc65/trunk@5361 b7a2c559-68d2-44c3-8de9-860c34a00d81
1386 lines
50 KiB
Plaintext
1386 lines
50 KiB
Plaintext
<!doctype linuxdoc system>
|
|
|
|
<article>
|
|
<title>cc65 Users Guide
|
|
<author>Ullrich von Bassewitz, <htmlurl url="mailto:uz@cc65.org" name="uz@cc65.org">
|
|
<date>2000-09-03, 2001-10-02, 2005-08-01
|
|
|
|
<abstract>
|
|
cc65 is a C compiler for 6502 targets. It supports several 6502 based home
|
|
computers like the Commodore and Atari machines, but it is easily 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 known 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
|
|
--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 Debug optimization steps
|
|
--dep-target target Use this dependency target
|
|
--disable-opt name Disable an optimization step
|
|
--enable-opt name Enable an optimization step
|
|
--forget-inc-paths Forget include search paths
|
|
--help Help (this text)
|
|
--include-dir dir Set an include directory search path
|
|
--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>
|
|
|
|
<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, something that should not be needed for mere
|
|
mortals:-)
|
|
|
|
|
|
<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>--forget-inc-paths</tt></tag>
|
|
|
|
Forget the builtin include paths. This is most useful when building
|
|
customized C or runtime libraries, in which case the standard header
|
|
files should be ignored.
|
|
|
|
|
|
<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.
|
|
|
|
|
|
<tag><tt>-h, --help</tt></tag>
|
|
|
|
Print the short option summary shown above.
|
|
|
|
|
|
<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 to the data segment when they're encountered in the
|
|
source. 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 overriden 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>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>pet (all CBM PET systems except the 2001)
|
|
<item>plus4
|
|
<item>supervision
|
|
<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. 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 force the compiler to inline some known functions from
|
|
the C library like strlen. Note: This has two consequences:
|
|
<p>
|
|
<itemize>
|
|
<item>You may not use names of standard C functions in your own code. If you
|
|
do that, your program is not standard compliant anyway, but using
|
|
<tt/-Os/ will actually break things.
|
|
<p>
|
|
<item>The inlined string and memory functions will not handle strings or
|
|
memory areas larger than 255 bytes. Similarly, the inlined <tt/is..()/
|
|
functions will not work with values outside the char. range (such as
|
|
<tt/EOF/).
|
|
<p>
|
|
</itemize>
|
|
<p>
|
|
It is possible to concatenate the modifiers for <tt/-O/. For example, to
|
|
enable register variables and inlining of known 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 are currently 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/struct-param/</tag>
|
|
Warn when passing structs by value.
|
|
<tag><tt/unknown-pragma/</tag>
|
|
Warn about known #pragmas.
|
|
<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.
|
|
</descrip>
|
|
|
|
The full list of available warning names may 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.
|
|
|
|
</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 the use with the ca65 macro
|
|
assembler.
|
|
|
|
Include files in single quotes are searched in the following places:
|
|
<enum>
|
|
<item>The current directory.
|
|
<item>The value of the environment variable <tt/CC65_INC/ if it is defined.
|
|
<item>Any directory added with the <tt/-I/ option on the command line.
|
|
</enum>
|
|
|
|
Include files in angle brackets are searched in the following places:
|
|
<enum>
|
|
<item>A compiled in directory which is often <tt>/usr/lib/cc65/include</tt> on
|
|
Linux systems.
|
|
<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>Any directory added with the <tt/-I/ option on the command line.
|
|
</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.
|
|
<p>
|
|
<item> C Functions may not return structs (or unions), and structs may not
|
|
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.
|
|
<p>
|
|
<item> The <tt/volatile/ keyword doesn't have an effect. This 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 assembler statements into the output
|
|
file. The syntax is
|
|
|
|
<tscreen><verb>
|
|
asm (<string literal>[, optional parameters]) ;
|
|
</verb></tscreen>
|
|
or
|
|
<tscreen><verb>
|
|
__asm__ (<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 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
|
|
|
|
<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 would be
|
|
<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 declared as <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.
|
|
<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
|
|
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 variable 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>
|
|
|
|
This 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.
|
|
|
|
See the <url url="geos.html" name="GEOS library document"> for examples
|
|
on how to use this 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>
|
|
|
|
</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).
|
|
|
|
<tag><tt>__APPLE2ENH__</tt></tag>
|
|
|
|
This macro is defined if the target is the enhanced Apple //e (-t apple2enh).
|
|
|
|
<tag><tt>__ATARI__</tt></tag>
|
|
|
|
This macro is defined if the target is one of the Atari computers
|
|
(400/800/130XL/800XL).
|
|
|
|
<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 c128 (-t c128).
|
|
|
|
<tag><tt>__C16__</tt></tag>
|
|
|
|
This macro is defined if the target is the c16 (-t c16).
|
|
|
|
<tag><tt>__C64__</tt></tag>
|
|
|
|
This macro is defined if the target is the c64 (-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. For example, version 2.10.1 of the compiler has this macro
|
|
defined as <tt/0x02A1/.
|
|
|
|
<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>__DATE__</tt></tag>
|
|
|
|
This macro expands to the date of translation of the preprocessing
|
|
translation unit in the form "Mmm dd yyyy".
|
|
|
|
<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 the GEOS system (-t geos).
|
|
|
|
<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 NES (-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>__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 plus/4 (-t plus4).
|
|
|
|
<tag><tt>__STDC_HOSTED__</tt></tag>
|
|
|
|
This macro is expands to the integer constant 1.
|
|
|
|
<tag><tt>__SUPERVISION__</tt></tag>
|
|
|
|
This macro is defined if the target is the supervision (-t supervision).
|
|
|
|
<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 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 bss-name ([push,] <name>)</tt><label id="pragma-bss-name"><p>
|
|
|
|
This pragma changes the name used for the BSS segment (the BSS segment
|
|
is used to store uninitialized data). The argument is a string enclosed
|
|
in double quotes.
|
|
|
|
Note: The default linker configuration file does only map the standard
|
|
segments. If you use other segments, you have to create a new linker
|
|
configuration file.
|
|
|
|
Beware: The startup code will zero only the default BSS segment. If you
|
|
use another BSS segment, you have to do that yourself, otherwise
|
|
uninitialized variables do not have the value zero.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
#pragma bss-name ("MyBSS")
|
|
</verb></tscreen>
|
|
|
|
|
|
<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.
|
|
|
|
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
|
|
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>
|
|
|
|
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>)</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 argument is a string enclosed in
|
|
double quotes.
|
|
|
|
Note: The default linker configuration file does only map the standard
|
|
segments. If you use other segments, you have to create a new linker
|
|
configuration file.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
#pragma code-name ("MyCODE")
|
|
</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>)</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 argument is a string enclosed in
|
|
double quotes.
|
|
|
|
Note: The default linker configuration file does only map the standard
|
|
segments. If you use other segments, you have to create a new linker
|
|
configuration file.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
#pragma data-name ("MyDATA")
|
|
</verb></tscreen>
|
|
|
|
|
|
<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 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>)</tt><label id="pragma-rodata-name"><p>
|
|
|
|
This pragma changes the name used for the RODATA segment (the RODATA
|
|
segment is used to store readonly data). The argument is a string
|
|
enclosed in double quotes.
|
|
|
|
Note: The default linker configuration file does only map the standard
|
|
segments. If you use other segments, you have to create a new linker
|
|
configuration file.
|
|
|
|
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
|
|
|
Example:
|
|
<tscreen><verb>
|
|
#pragma rodata-name ("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
|
|
either followed 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.
|
|
|
|
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 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 assembler statements into the output file. The
|
|
syntax is
|
|
|
|
<tscreen><verb>
|
|
asm (<string literal>[, optional parameters]) ;
|
|
</verb></tscreen>
|
|
or
|
|
<tscreen><verb>
|
|
__asm__ (<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 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 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,
|
|
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.
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
<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 these 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
|
|
|
|
<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;
|
|
} 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:
|
|
|
|
<tscreen><verb>
|
|
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 can also be accessed:
|
|
|
|
<tscreen><verb>
|
|
unsigned char globalSquareTable[] = {
|
|
0, 1, 4, 9, 16, 25, 36, 49, 64, 81,
|
|
100, 121, 144, 169, 196, 225
|
|
};
|
|
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 asm statements. Code like this
|
|
|
|
<tscreen><verb>
|
|
int foo;
|
|
int bar () { 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:
|
|
|
|
<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>Bugs/Feedback<p>
|
|
|
|
If you have problems using the compiler, 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 (<htmlurl url="mailto:uz@cc65.org"
|
|
name="uz@cc65.org">).
|
|
|
|
|
|
|
|
<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 permissable 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>
|
|
|