

***************
Getting started
***************

This chapter provides an overview of using the compiler and its related
tools.

.. index:: C language

C language
==========

C is a widely used programming language. It is well-suited for
hardware-level programming and also functions as a powerful,
generic high-level language. It offers powerful abstractions over
target machines, enabling efficient application development and
precise control.

This implementation uses the ISO/IEC 9899:1999 standard, commonly
known as C99. In this guide, it is referred to as *Standard C*.

.. index:: cross compiler

Cross compiler
--------------

The compiler is a cross-compiler, running on a modern workstation but
producing applications for more constrained target machines.

.. index:: supported devices, devices; supported

Supported devices
------------------

This Calypsi C compiler tool chain supports the Western Design Center 65816.


File extensions
===============

The following table shows the file extensions normally used with
the Calypsi C compiler tool chain.

.. index:: file extensions

.. _FileExtensions:

.. table:: File extensions
 :widths: 1 5
 :column-dividers: none single none
 :column-alignment: right left

 +----------------+---------------------------------------------------+
 |Extension       |Purpose                                            |
 +================+===================================================+
 | ``.c``         | C source                                          |
 +----------------+---------------------------------------------------+
 | ``.h``         | C header source                                   |
 +----------------+---------------------------------------------------+
 | ``.s``         | Assembler source                                  |
 +----------------+---------------------------------------------------+
 | ``.o``         | ELF/DWARF object file                             |
 +----------------+---------------------------------------------------+
 | ``.a``         | Library (collection of object files)              |
 +----------------+---------------------------------------------------+
 |``.lst``        |List file                                          |
 +----------------+---------------------------------------------------+
 |``.scm``        |Linker rules                                       |
 +----------------+---------------------------------------------------+
 | ``.elf``       | ELF/DWARF output (executable file)                |
 +----------------+---------------------------------------------------+
 | ``.hex``       | Intel-hex output                                  |
 +----------------+---------------------------------------------------+
 | ``.srec``      | Motorola S-record output                          |
 +----------------+---------------------------------------------------+
 | ``.s19``       | Motorola S-record output, 16-bit address records  |
 +----------------+---------------------------------------------------+
 | ``.s28``       | Motorola S-record output, 24-bit address records  |
 +----------------+---------------------------------------------------+
 | ``.s37``       | Motorola S-record output, 32-bit address records  |
 +----------------+---------------------------------------------------+
 | ``.raw``       | Raw output                                        |
 +----------------+---------------------------------------------------+
 | ``.pgz``       | Foenix binary format                              |
 +----------------+---------------------------------------------------+
 | ``.prg``       | Commodore 64 binary format                        |
 +----------------+---------------------------------------------------+

Building applications
=====================

Applications can be built from source files and libraries. Source files,
written in C or assembly language, are compiled into object files:
C source files use ``cc65816``, and assembly source files use
``as65816``.

A library is a collection of object files produced by the ``nlib``
tool, combining them with an index into a single file.
The C runtime library is provided as an example; third-party libraries
are also supported.

The ``ln65816`` takes object files, libraries, and placement rules as
input to construct the executable application.

Compiler
--------

The compiler command-line interface processes a single source file
to produce an object file::

$ cc65816 source.c

The object file produced will have the same base name as the input
but with a ``.o`` file extension.

.. note::

   You typically need command-line options to select the CPU core,
   runtime models, and other settings.


Assembler
---------

C projects do not require knowledge of assembly language. C simplifies
programming and enables portability across architectures.

However, for highly specific target code, deep-level control, or
critical routines, the assembler is indispensable.

The assembler command-line interface is similar to the compiler,
with the main difference being the file extension::

$ as65816 source.s

The produced object file has the same ``.o`` extension as the compiler.

.. note::

   You may need to provide a ``--core`` option for the assembler to
   recognize the target exact machine instructions.

Linker
-------

The linker combines object files and libraries to create an
executable application.

A rules file is required by the linker to describe the memory system,
including placement rules for code and data. Stack and heap sizes
can also be specified in this file.

You can run the linker from the command line as::

$ ln65816 myfile1.o myfile2.o rules.scm

This simplified command produces ``aout.elf``, an ELF binary.

There are many ways to tailor the output:

* Using hex output, in either Intel HEX or Motorola S-record file
  format

* RAW output, which is just plain binary output of a single memory area

* Foenix program files, which are segmented binary files with start address

* The ``--debug`` option includes DWARF debugging information in the ELF executable.

The linker can produce a list file with cross-reference information,
showing memory usage, placement, and why certain library contents were included.

Configuring
===========

Tune compiler code generation using various command-line options.

The most basic settings to consider are:

* The CPU core (``--core``) in use. This controls the exact
  instruction set.

* The data model, which affects how data are placed and accessed in
  memory.

* The size of the ``double`` floating point type.

* Optimization settings.

Core
----

The Calypsi C compiler tool chain supports the WDC65816 core.

.. index:: code model
.. _code-model:

Code model
----------

The code model governs default function placement and function pointer
size.

.. index:: code model; large, large; code model
.. index:: code model; small, small; code model
.. index:: code model; compact, compact; code model

The available code models are Small, Compact and Large. If not
specified the compiler uses the Large code model which allows
addressing functions in the entire memory range.

The Small and Compact code models restricts the code to a single
64K bank. In the Small code this is the first bank (low 64K) while
the Compact code model allows the use any bank.

.. table:: Code models
 :widths: 2 3 2
 :column-dividers: none single single none
 :column-alignment: left left left

 +-------------+----------------------+------------+
 |Code model   |Function pointer size |Size limit  |
 +=============+======================+============+
 | Small       | 16 bits              |64K bytes   |
 +-------------+----------------------+------------+
 | Compact     | 16 bits              |64K bytes   |
 +-------------+----------------------+------------+
 | Large       | 24 bits              |16M bytes   |
 +-------------+----------------------+------------+

.. index:: data model
.. _data-model:

Data model
----------

The data model dictates default global data placement and defines the
*default pointer* type (a data pointer without specific address
attributes).

The available data models are Small, Medium Large and Huge. If not
specified the compiler uses the Small data model.

Generally, smaller data models result in
smaller and faster applications. Larger data models are primarily used for very
large applications where avoiding explicit memory attributes is desired.

.. index:: data model; small, small; data model

Small
^^^^^

In the small data model all default data is located in the first 64K
of memory. This allows for using efficient 16 bits pointers, also for
functions provided in the C library runtime.

You can still have data outside the first 64K, but you have to use
keywords on such objects and pointers to them. This makes it possible
to use 24 bits addressing to reach such data.

.. note::

   In the Small data model, the ``near`` attribute is
   disabled because only a single 64K data bank (bank ``00``) is used.

.. index:: data model; medium, medium; data model

Medium
^^^^^^

The Medium data model uses a designated 64K area
(other than bank ``00``) for static data by default. While default
pointers to this data are 24 bits, you can achieve efficient 16-bit
addressing using a typed ``near`` pointer.

The Medium data model is useful for static data,
such as tables or string literals, that do not fit within the limitations
of the Small data model.

.. index:: data model; large, large; data model

Large
^^^^^

In the Large data model all pointers and data have the ``far`` attribute
by default. This means that you can have data that span the entire
16MB memory range without using any keywords.
Data object size is limited to 64K minus one byte.
For larger objects, you must use the ``huge`` attribute or switch
to the Huge data model.

For fast access, you can still use the ``tiny`` or ``near`` attribute
on such objects.

.. index:: data model; huge, huge; data model

Huge
^^^^

In the Huge data model all limitations are removed and you can address
the entire memory range using 24 bits addressing with no limitation on
object sizes. This also means that the code size will grow as the
compiler is forced to generate code that is less efficient.


.. table:: Default pointer behavior in different data models
 :widths: 2 2 2 2 2
 :column-dividers: none single single single single none
 :column-alignment: left left left left left

 +-------------+----------------------+------------------+----------------+-------------------+
 |Data model   |Default pointer size  |Default attribute |Max object size |Total size limit   |
 +=============+======================+==================+================+===================+
 | Small       | 16 bits              |Bank ``00``       |64K bytes       |64K bytes          |
 +-------------+----------------------+------------------+----------------+-------------------+
 | Medium      | 24 bits              |``near``          |64K bytes       |64K bytes          |
 +-------------+----------------------+------------------+----------------+-------------------+
 | Large       | 24 bits              |``far``           |16M bytes       |16M bytes          |
 +-------------+----------------------+------------------+----------------+-------------------+
 | Huge        | 24 bits              |``huge``          |16M bytes       |16M bytes          |
 +-------------+----------------------+------------------+----------------+-------------------+

.. note::

   The total size limit applies to static or global objects
   without explicit memory attributes. You can go beyond the size limit imposed by
   the default pointer by using explicit memory attributes, e.g ``far``.

.. note::

   For shorter addressing you can always use the ``tiny`` attribute
   which uses the direct page.

.. note::

   In the Small, Medium and Large data models, the ``huge`` attribute is
   disabled by default. This is because ``huge`` is seldom needed, and
   enabling it requires ``size_t`` to be 32 bits instead of the more
   efficient 16 bits on the 65816. If enabled with these data models,
   you will also need to rebuild the C runtime library.
   See :ref:`library-rebuild` for how to build your own C runtime library.

.. index:: floating point; types, floating point; setting,
.. index:: size; of float, size; of double

Size of double
--------------

The ``double`` floating-point type uses IEEE 754 format and can be
set to either 32 or 64 bits using ``--32bit-doubles`` or
``--64bit-doubles``. It defaults to 32 bits if not specified.

The ``float`` type is always 32 bits, and the ``long double`` type is
always 64 bits.

.. index:: optimizer

Optimization
-------------

Select the optimization level using the ``-O`` command-line option,
which accepts a numeric argument of ``1`` or ``2``.

The compiler applies a number of techniques to reduce the width
of expressions, select efficient code sequences and dead code
elimination, regardless of optimization settings.

The ``-O`` option enables further optimization to reduce the
code memory footprint and typically increase execution speed.

Low level control
=================

This section provides a brief overview of controlling access to
specific memory and built-in functions, also known as intrinsics.

Extended keywords
-----------------

The 65816 has a *direct page* short address area which can be accessed
more efficiently than other memory addresses. This
area has a single-byte address size.

You can specify that something is allocated in the direct page using
extension keywords, either as ``__tiny`` or
``__attribute__((tiny))``.

Additional data space is available in the *near* address area which
uses a 16 bits address (two bytes). In the Small data model that uses
a default pointer of 16 bits, this data area must be bank ``00``.
The hardware stack also resides in this bank.
In the other larger data models, the near address area can be any
fixed 64K bank and does not have to be in bank ``00``. However, it
must be tied to a designated 64K bank and cannot change during
execution.
You can specify that something is allocated in the near area using
extension keywords, either as ``__near`` or
``__attribute__((near))``.

The next data attribute is the *far* address area which can cover the
entire memory space. The only limitation for data in the far
area is that a single object cannot exceed 65535
bytes (64K minus one).
You can specify that something is allocated in the far area using
extension keywords, either as ``__far`` or
``__attribute__((far))``.

Finally the *huge* address area covers the entire memory space and has
no limitation on object size.
You can specify that something is allocated in the far area using
extension keywords, either as ``__huge`` or
``__attribute__((huge))``.

Apart from different capability on how much and large objects that can
be stored in a given address area, the compiler code that the compiler
generates to access the different data areas differs. Accessing
objects in larger, more general address spaces requires more
instructions and executes slower than in smaller ones. Thus, it makes
sense to plan where data objects are located and use the smallest
possible one. You can of course put different objects in different
address spaces, taking advantage of the performance of the tiny area
for small frequently access objects while large and seldom used
objects can be allocated in the larger address spaces.

The function attribute ``__saveds`` can be used on API and interrupt
functions that may be called from another run-time context. It will
set up the direct page and data bank when the function is called and
restore the previous direct page and data bank on return. This is
typically useful for entry points to an operating system that may be
called by applications that operate with another direct page or data
bank.

.. note::

   For ``saveds`` API calls, you should generally prevent arguments
   from being passed on the direct page. Use either a single register
   argument or the ``simple_call`` calling convention to force arguments
   onto the stack. Direct page differences when using ``saveds`` mean
   accessing caller-placed arguments there will not work.

.. note::

   When using ``saveds`` for API functions you most likely want to use
   the ``saveds`` attribute on C written ``interrupt`` functions as
   well, as interrupts may be triggered at any time.

.. index:: intrinsics

Intrinsics
----------

Intrinsics functions appear as ordinary calls but are special compiler
constructs, emitting specific instruction sequences. To enable them,
include the ``calypsi/intrinsics65816.h`` header file.

Assembly code
-------------

You can write functions in assembly language by following the
C calling convention. These functions can be called from C in the same
way as any C function.


