10. Running the compiler

The compiler is run from the command line, or from an IDE that interfaces with the compiler using the command line.

10.1. Basic invocation

The compiler is invoked in the following way:

$ cc65816 [options] sourcefile [options]

As an example, to compile a source file with debugging information and a list file, you can use:

$ cc65816 --debug source.c -l

Command line options are optional arguments that tune the behavior of the compiler. They always start with a dash character. There are two variants, single letter options (-l to instruct the compiler to create a list file) starts with a single dash. The other variant is long descriptive options that starts with two dashes.

Some options require arguments. These follow the option, separated by a space or an equals sign (=). For single-argument options, the separator is optional:

$ cc65816 -Iinclude source.c -D VERBOSE=2 --list-file=tiny-source.lst

In this case the -I option adds include as a directory to scan for header files. The symbol VERBOSE is defined in the preprocessor with value 2. A list file with a specific name is also produced.

The order in which the options appear normally do matter, except for the -I option that adds directories to search for header files. Such directories are searched in the order in which they appear on the command line.

To display the version of the compiler, use --version:

$ cc65816 --version
Calypsi ISO C compiler for 65816 version 5.16

Command line options are described in Command line options.

10.2. Include search path

Header files are included by surrounding the filename with either double quotes or angled brackets:

#include "myheader.h"
#include <stdio.h>

Angled brackets are typically for system header files, while double quotes are for application-specific header files.

The search order for include files is as follows:

  1. Relative to compilation directory (double quote include only)

  2. In directories specified in the -I option in the order they appear on the command line

  3. The system directory, which is the installation directory

Header files specified in angle brackets are not searched relative to the compilation directory. Otherwise, they behave identically. The system header file directory is located within the installation directory.

Note

More precisely, the system header file directory is relative to the cc65816 executable. If an installation is moved, it will still find the correct system header file directory.

10.3. Compiler output

The compiler outputs one or two files, an object file that can be linked with other object files and libraries by ln65816 to produce an executable file, and optionally a list file.

Object file

The object file is in ELF format, optionally including DWARF debugging information if --debug (or -g) is specified.

It contains:

  • A symbol table

  • Relocatable sections for code and data

  • Relocations, allowing linker to modify address values after section placement

  • DWARF-formatted source-level debugging information (if --debug was specified)

  • Vendor-specific data, including runtime attributes and additional the Calypsi C compiler tool chain-specific information not covered by ELF/DWARF, used by the linker and debugger, with section types 0x8000000a and 0x8000000b.

Note

DWARF version 5 is used. The implementation covers the needs of the Calypsi C compiler tool chain and includes vendor extensions.

List file

The list file is a text file meant to be shown with a fixed width font. It contains a header that shows compiler, version, time when it was created and the command line used. The C source file follows intermixed with generated assembly code. Finally there is a summary of the code and data sizes.

The following simple summation function:

int sum(int a, int b, int c) {
  if (a < b) {
    return a + c;
  } else {
    return b + c;
  }
}

Compiling with the -l option produces a list file:

###############################################################################
#                                                                             #
# Calypsi ISO C compiler for 65816                               version 5.16 #
#                                                       14/Apr/2026  16:42:18 #
# Command line: sum.c -l                                                      #
#                                                                             #
###############################################################################

    \ 000000                      .rtmodel version,"1"
    \ 000000                      .rtmodel codeModel,"large"
    \ 000000                      .rtmodel dataModel,"small"
    \ 000000                      .rtmodel core,"65816"
    \ 000000                      .rtmodel huge,"0"
    \ 000000                      .rtmodel target,"none-specified"
    \ 000000                      .extern _Dp
    \ 000000                      .extern _Vfp
0001                  int sum(int a, int b, int c) {
    \ 000000                      .section farcode,text
    \ 000000                      .public sum
    \ 000000 5a       sum:        phy
    \ 000001 5a                   phy
    \ 000002 aa                   tax
    \ 000003 a5..                 lda     dp:.tiny _Dp
    \ 000005 8301                 sta     1,s
    \ 000007 a5..                 lda     dp:.tiny (_Dp+2)
    \ 000009 8303                 sta     3,s
0002                    if (a < b) {
    \ 00000b 8a                   txa
    \ 00000c 38                   sec
    \ 00000d e301                 sbc     1,s
    \ 00000f 5003                 bvc     `?L9`
    \ 000011 490080               eor     ##-32768
    \ 000014 1006     `?L9`:      bpl     `?L4`
0003                      return a + c;
    \ 000016 8a                   txa
    \ 000017 18                   clc
    \ 000018 6303                 adc     3,s
    \ 00001a 8005                 bra     `?L3`
    \ 00001c          `?L4`:
0004                    } else {
0005                      return b + c;
    \ 00001c a303                 lda     3,s
    \ 00001e 18                   clc
    \ 00001f 6301                 adc     1,s
    \ 000021          `?L3`:
0006                    }
0007                  }
    \ 000021 7a                   ply
    \ 000022 7a                   ply
    \ 000023 6b                   rtl

##########################
#                        #
# Memory sizes (decimal) #
#                        #
##########################

Executable  (Text): 36 bytes

Assembly source

The compiler can generate assembly source output, which is similar to a list file, except that this output file is actual source code that can be given to the assembler. This can be used to generate a starting point for an assembly source file. By providing suitable declarations and simplified C functions you can study what the compiler does and build upon it.

10.4. Diagnostics

Compiler diagnostic messages identify problems that either must or should be addressed.

Errors

An error identifies a problem in the code that prevents the compiler from producing a valid output file.

Warnings

A warning identifies a potential problem in the code that you probably want to take a look at and possibly rectify. The compiler is still able to produce a valid output file.

Internal errors

An internal error indicates an unexpected problem within the compiler product.

Controlling warnings

Diagnostic can be controlled using the -W option that takes a wide range of possible alternatives. It is beyond the scope of this guide to list them all. A complete reference can be found at https://clang.llvm.org/docs/DiagnosticsReference.html as the parser and diagnostics engine is the same as in the Clang project.

Consider the following code:

 int test(int x)
 {
   if (x = 6) {
     return 10;
   } else {
     return 0;
   }
}

In the code, an assignment is used in a comparison, a common C error. While legally testing a non-zero assignment expression, this often indicates an intended use of ==. The compiler cannot know your intent, but flags a potential problem. Compiling this code results in warnings:

w.c:3:10: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
   if (x = 6) {
       ~~^~~
w.c:3:10: note: place parentheses around the assignment to silence this warning
   if (x = 6) {
         ^
       (    )
w.c:3:10: note: use '==' to turn this assignment into an equality comparison
   if (x = 6) {
         ^
         ==

The warnings point out that there may be a problem in the code. The name of the warning that triggered is also given (-Wparentheses). Finally, it makes suggestions on how you can change the code.

If you think the warning is of no use to you and you do not want to see this particular warning again, you can add the option -Wno-parentheses to the command line to silence it.

Adding an extra pair of parentheses around the assignment is a common way to indicate an intentional assignment within a test expression:

 int test(int x)
 {
   if ((x = 6)) {
     return 10;
   } else {
     return 0;
   }
}

Finally, if the intention with the code was to use the equality operator, you should change it to use the correct operator:

 int test(int x)
 {
   if (x == 6) {
     return 10;
   } else {
     return 0;
   }
}

10.5. Command line options

This section covers the cc65816 command-line options in detail.

Options overview

If you run the compiler from the command line without any arguments it will complain that the input source file is missing and then shows a short form help:

$ cc65816
Missing: FILE

Usage: cc65816 [--version] [-o|--output-file OUTPUT-FILE] [-l]
               [--list-file LIST-FILE] [-I DIRECTORY] [-D IDENTIFIER]
               [-U IDENTIFIER] [-g|--debug] ([--32bit-doubles] |
               [--64bit-doubles]) ([--char-is-signed] | [--char-is-unsigned])
               [-E] [--print-macro-definitions] [--align-functions ALIGNMENT]
               [-O LEVEL] ([--space] | [--speed]) [--no-cross-call]
               [--no-interprocedural-cross-jump] ([--no-inline] |
               [--always-inline]) [--only-marked-as-inline] [--strong-inline]
               [--inline-on-matching-custom-text-section] [--rtattr NAME=VALUE]
               [--weak-symbols] [--no-vector-sections] [-c]
               [--assembly-source ASSEMBLY-FILE] [-S] [--force-switch STRATEGY]
               [-W ARG] [--dependencies] [-M ARG] [--pedantic-errors]
               [--include-system DIRECTORY] [--include-system-after DIRECTORY]
               [--core CORE] [--target TARGET] [--code-model NAME]
               [--data-model NAME] [--pascal-strings] [--enable-huge-attribute]
               [--no-ppu-mul] FILE
  use 'cc65816 --help' for detailed help

For more detailed help, use the --help option:

$ cc65816 --help
Calypsi ISO C compiler for 65816 version 5.16

Usage: cc65816 [--version] [-o|--output-file OUTPUT-FILE] [-l]
               [--list-file LIST-FILE] [-I DIRECTORY] [-D IDENTIFIER]
               [-U IDENTIFIER] [-g|--debug] ([--32bit-doubles] |
               [--64bit-doubles]) ([--char-is-signed] | [--char-is-unsigned])
               [-E] [--print-macro-definitions] [--align-functions ALIGNMENT]
               [-O LEVEL] ([--space] | [--speed]) [--no-cross-call]
               [--no-interprocedural-cross-jump] ([--no-inline] |
               [--always-inline]) [--only-marked-as-inline] [--strong-inline]
               [--inline-on-matching-custom-text-section] [--rtattr NAME=VALUE]
               [--weak-symbols] [--no-vector-sections] [-c]
               [--assembly-source ASSEMBLY-FILE] [-S] [--force-switch STRATEGY]
               [-W ARG] [--dependencies] [-M ARG] [--pedantic-errors]
               [--include-system DIRECTORY] [--include-system-after DIRECTORY]
               [--core CORE] [--target TARGET] [--code-model NAME]
               [--data-model NAME] [--pascal-strings] [--enable-huge-attribute]
               [--no-ppu-mul] FILE
  use 'cc65816 --help' for detailed help

Available options:
  --version                Display version number
  -o,--output-file OUTPUT-FILE
                           Name of output file
  -l                       Generate a list file, named by appending '.lst' to
                           input file
  --list-file LIST-FILE    Generate list file, using given name
  -I DIRECTORY             Include directory
  -D IDENTIFIER            Predefine a macro
  -U IDENTIFIER            #undef a predefined macro
  -g,--debug               Produce debugging information
  --32bit-doubles          Make the 'double' data type 32-bits (this is the
                           default)
  --64bit-doubles          Make the 'double' data type 64-bits
  --char-is-signed         Treat 'char' as a signed type
  --char-is-unsigned       Treat 'char' as an unsigned type (this is the
                           default)
  -E                       Stop after preprocessing
  --print-macro-definitions
                           Print macro definitions in -E mode in addition to
                           normal output
  --align-functions ALIGNMENT
                           Align the start of functions to given alignment
  -O LEVEL                 Enable optimizer, -O0, -O1 or -O2
  --space                  Optimize for space (this is the default, use together
                           with -O)
  --speed                  Optimize for speed (use together with -O)
  --no-cross-call          Disable cross call optimization
  --no-interprocedural-cross-jump
                           Disable interprocedural cross jump optimization
  --no-inline              Disable all function inlining
  --always-inline          Always inline functions
  --only-marked-as-inline  Only consider inlining functions marked as 'inline'
  --strong-inline          Always (try to) inline functions marked as 'inline'
  --inline-on-matching-custom-text-section
                           Only inline custom text section functions when the
                           section names match
  --rtattr NAME=VALUE      Define a runtime attribute (identifier or quoted
                           string value accepted)
  --weak-symbols           Make all public symbols entries weak
  --no-vector-sections     Discard auto generated interrupt vector sections
  -c                       Generate object file and do not try to link
  --assembly-source ASSEMBLY-FILE
                           Generate an assembly source file, using given name
  -S                       Generate an assembly source file, named by appending
                           '.s' to input file
  --force-switch STRATEGY  Switch strategy, one of 'if-else', 'jump-table' or
                           'value-table'
  -W ARG                   Warning control
  --dependencies           Generate dependencies to stdout
  -M ARG                   Dependency file control
  --pedantic-errors        Error on language extensions
  --include-system DIRECTORY
                           Add system include directory
  --include-system-after DIRECTORY
                           Add system include directory after
  --core CORE              Core, one of '65816' (defaults to '65816')
  --target TARGET          Target system, one of 'C256', 'F256' or 'SNES'
                           (defaults to embedded/ROM use, if omitted)
  --code-model NAME        Code model, one of 'small', 'compact' or 'large'
                           (defaults to 'large')
  --data-model NAME        Data model, one of 'small', 'medium', 'large' or
                           'huge' (defaults to 'small')
  --pascal-strings         Generate Pascal strings on leading \p character
  --enable-huge-attribute  Enable the huge data memory attribute, also makes
                           size_t 32 bits wide
  --no-ppu-mul             Do not use the PPU multiplier (SNES target only)
  -h,--help                Show this help text

Options in detail

--version

Displays the name and version of the compiler.

--output-file, -o

Specify the output object file name. If omitted, the output file is derived from the input file name (excluding path) with a .o extension, written to the current directory by default.

This option can also alter the output file name and provide a directory path. The specified directory must already exist.

-l

Generate a list file. The name used is the name of the input file (ignoring any directory path) with a .lst file extension. See also --list-file.

--list-file

Generate a list file. The name of the list file is given as argument to this option. See also -l to generate a list file based on the source filename.

-I

Add a directory to the current include search path. This option can be used multiple times on a command line. The order in which they appear specifies the search order between the directories.

The system include directory is always added last to the search order list.

--include-system

Add a directory to the current system include search path before the provided system include directories. This option can be used multiple times on a command line. The order in which they appear specifies the search order between the directories.

--include-system-after

Add a directory to the current system include search path after the provided system include directories. This option can be used multiple times on a command line. The order in which they appear specifies the search order between the directories.

-D

Define a macro. This takes an argument with the symbol name and optionally an assignment value -Dsymbol[=value]. If no value is given, the macro is given the value 1.

-U

Undefine a macro. This takes an argument with the symbol name to be undefined.

--debug

Generate DWARF symbolic debugging information. In order to get debugging information all the way to the debugger, the linker must also be given this option.

When debugging information is enabled the __CALYPSI_DEBUG__ macro is also defined and set to 1.

-g

Synonym for --debug.

-S

Generate an assembly source file as output. The name used is the name of the input file (ignoring any directory path) with a .s file extension. No object file is generated. See also --assembly-source.

--assembly-source

Generate an assembly source file as output. The name of the output file is given as an argument to this option. See also -S to generate an assembly source file based on the C source filename. No object file is generated.

--32bit-doubles

The double floating point data type has 32 bits precision.

--64bit-doubles

The double floating point data type has 64 bits precision.

--char-is-signed

Makes the char data type signed. The default is unsigned.

--char-is-unsigned

Makes the char data type unsigned. This is also the default.

-E

Stop after running the preprocessor. The output from the preprocessor is written to standard output (stdout).

-O

Runs the optimizer, expecting an argument of 0, 1, or 2. -O0 (the default) performs no additional optimization passes but still produces good code. -O1 enables additional passes to further improve code, and -O2 enables all optimizer passes.

--space

Optimize for space, this is the default. Use -O to enable optimizations.

--speed

Optimize for speed. Use -O to enable optimizations. This option controls decisions about tradeoffs and will balance towards making the code run faster at the expense of additional code space. See also --no-cross-call below.

--no-cross-call

Disables the cross-call optimizer, normally enabled at -O2. The cross-call optimizer extracts common code sequences into small subroutines, which can significantly reduce code space, so it is also enabled by default with --speed.

--no-inline

Disable all function inlining which is normally enabled at -O1.

--always-inline

Enable function inlining regardless of optimization level setting.

--only-marked-as-inline

Only considers functions marked with the inline keyword for inlining. This disregards small functions and single-use static functions for inlining.

--strong-inline

Regard functions marked with the inline keyword as a strong hint that they should be inlined. The compiler may still decide not to do it.

--rtattr NAME=VALUE

This defines a runtime attribute which is written to the object file. This is used to specify runtime attribute value that can be used in the linker for checking object file consistency.

--weak-symbols

Makes all public symbols in the object file weak. This is normally not needed, but can provide a default library function implementation that is used if no replacement is provided.

--no-vector-sections

Do not generate vector table entries for interrupt functions. This is useful when writing interrupt functions that are going to be installed using some other mechanism.

-c

Generate an object file without linking. This is a no-operation, as the compiler always generates an object file. This option is provided due to its common use with many compilers.

--force-switch

Forces the compiler to use a specific strategy for generating switch tables. The compiler normally uses heuristics, but this option overrides them to force a particular variant.

Available variants are: series of “if-else” tests, a jump table, or a table with value and label pairs. “If-else” is often best for very small switches. A jump table is typically fastest for a decent number of close entries. Value and label pairs work well for larger tables with spread-out values, using a binary search lookup that scales fairly well.

In big O notation: “if-else” is O(n), a jump table is O(1), and value and label pairs are O(log(n)).

-MD

Write a dependency file that contains user and system headers.

--dependencies

Like -MD, but also implies -E and writes to stdout by default.

-MF<file>

Write dependency file output from -MMD, -MD, -MM, or -M to <file>.

-MG

Add missing headers to the dependency file.

-MJ<arg>

Write a compilation database entry for each input.

-MM

Like -MMD, but also implies -E and writes to stdout by default.

-MMD

Write a dependency file containing user headers.

-MP

Create phony target for each dependency (other than main file).

-MQ<arg>

Specify name of main file output to quote in dependency file.

-MT<arg>

Specify name of main file output in dependency file.

-MV

Use NMake/Jom format for the dependency file.

-W

Control warnings, see Controlling warnings.

--pedantic-errors

Generates errors when language extensions are used. The supported language includes relaxations to the strict C standard for increased flexibility; use this option to disable such extensions.

--align-functions

Aligns the start of all functions to the provided alignment.

--core

This option is mostly available for symmetry with other tool chains from Calypsi and future expansion. At the moment only the 65816 core is recognized.

--target

This tells the compiler that the code is intended for a certain target platform.

When the C256 target is enabled it tells the compiler to generate code for the hardware math unit and enables hosted behavior.

For the F256 target is enables hosted behavior.

When the SNES target is enabled it tells the compiler to generate code for the hardware math unit as well as utilizing the PPU hardware multiplier. The use of the PPU multiplier can not be used when rendering in Mode 7. You can disable the use of the PPU multiplier using the --no-ppu-mul option..

--code-model

This options tells the compiler which code model to use. See Code model for more information.

--data-model

This options tells the compiler which data model to use. See Data model for more information.