

************
Data storage
************

This chapter discusses controlling data placement and its impact on
application efficiency.

.. index:: zero page

The 6502 features a 64K address range for code and data.
A key feature is the zero page, the first 256 bytes of memory, which the
6502 can address more quickly and efficiently than arbitrary addresses
within the full 64K memory space.

.. index:: registers; pseudo, pseudo registers, zero page; pseudo registers

Since the 6502 has only three single-byte registers, it quickly needs
to use external resources for data storage, traditionally the stack.
However, due to the small stack size and lack of efficient access to it, the C
compiler allocates a 48-byte fast-access register area in the zero
page. This area is evenly divided into two parts: one that survives a
function call and one that does not.

Consequently, the compiler has ample fast pseudo-registers and rarely
needs to allocate auto variables on the stack. This results in excellent
performance, as most auto variable accesses occur in the fast zero
page. All functions are also fully reentrant.

The downside is that some functions need to call a small runtime
library routine to move data between the register area and the
data stack to provide reentrant code.

.. index:: data stack, hardware stack, stack; hardware, stack; data
.. index:: nesting depth; functions, functions; nesting depth

This data stack is separate from the 6502 small hardware stack and
can be as large as addressable memory (64K).
However, you are still limited by the hardware stack for function return
addresses, permitting function call nesting to a depth of about 100
levels.

Ways to store data
==================

Data can be allocated as *auto*, *static*, or on the *heap*. Variable
scope and the need for allocation during runtime determine placement.

As a general rule, use auto-allocated variables whenever possible.
This offers the compiler maximum flexibility for resource allocation
closest to the core, which typically results in the most efficient
data access.

.. index:: variables; auto, auto variables
.. index:: local variables, variables; local

Auto variables
--------------

Auto variables include function parameters and local variables not
defined with ``static``. The compiler attempts to allocate these in
processor registers or zero page pseudo registers; otherwise, the stack is used.

Auto variables are allocated only when used. Their registers can be
reused for other auto variables or temporary data once no longer
needed. This reuse also applies to stack locations.

Auto variables can have multiple *live ranges*; a variable with the
same name might be used in distinct parts of a function. Internally,
these are treated as different variables and may be allocated to
various locations, potentially not existing between live ranges.

All auto variables associated with a function are deallocated upon
function exit.

.. note::

   If you take the address of an auto variable, you can pass its
   pointer to other functions, which is useful for temporary storage.
   However, avoid using such pointers outside their scope, as auto
   variables are deallocated on function exit. Be aware that taking an
   address allocates the variable on the stack, potentially increasing
   access cost compared to other auto variables.

.. index:: variables; static, static variables
.. index:: variables; global, global variables

Static variables
-----------------

Global, module, or function static variables are allocated in global
memory, occupying space for the application's duration.

Their visibility varies. A global variable is universally visible but
requires ``extern`` for use. A module static variable, declared with
``static`` at file scope, is visible within one compilation unit.
A static local variable within a function's scope is only visible
there, retaining its value across function calls. Use ``static`` to
differentiate it from an auto variable.

.. index:: variables; dynamic

Dynamically allocated
----------------------

A dynamically allocated variable is retrieved from a *heap* using the
*malloc* function. This is useful when the required data size is
unknown at program startup.

.. note::

   Dynamically allocated variables are a potential problem in memory
   constrained systems if the program is left running for a long time
   due to heap fragmentation.

.. index:: address spaces

Address spaces
==============

The compiler provides multiple *address spaces*, which are addressable
memory areas with specific properties:

* Address width for pointers

* Width of the associated integral index type

* Different instruction sequences for accessing various address spaces

* An extension keyword or type attribute name

* Section names tied to the address space for linking control

Address space attributes are always active in the compiler.

The Calypsi C compiler tool chain provides two address spaces, zero page and the default 16 bits
memory that can point to any address in the full 64K range.

All unqualified pointers are 16 bits wide. There is no keyword or
address space attribute provided to explicitly describe them.

.. index:: address space; zero page, zero page; address space

Zero page
----------

The zero page address space is the lowest 256 bytes of memory, using
the address range ``0x00-0xff``.
A zero page pointer is 8 bits wide and occupies a single byte when
stored in memory.

As it is only 256 bytes and shared with pseudo-registers, storage in the
zero page is somewhat limited. However, careful use of the zero page
can produce a more efficient application.

.. index:: address space; default page, default address space

Default memory
--------------

The default memory address space is the full 64K address range
``0x0000-0xffff``. A default memory pointer is 16 bits and occupies two
bytes when stored to memory.


.. index:: address space; far, far; address space

Far memory
----------

The Far memory address space addresses the full memory range beyond
64K and is available on the MEGA65 target.

.. index:: address space; huge, huge; address space

Huge memory
-----------

The Huge memory address space addresses the full memory range beyond
64K and is available on the MEGA65 target.

The size of a data object is limited only by available memory.

Summary
-------

The following table summarizes the available address spaces.

.. index:: keywords; address spaces, address spaces

.. _AddressSpaces:
.. table:: Address spaces
 :widths: 1 1 1 1 1
 :column-dividers: none single single single single none
 :column-alignment: left left left left left

 +-------------+------------+------------------+-------------+------------+
 |Memory type  |Keyword     |Address range     |Pointer size | Index type |
 +=============+============+==================+=============+============+
 | Zero page   | ``__zpage``|``0x00-0xff``     |8 bits       |``int8_t``  |
 +-------------+------------+------------------+-------------+------------+
 | Default     | N/A        |``0x0000-0xffff`` |16 bits      |``int16_t`` |
 +-------------+------------+------------------+-------------+------------+

When the 45GS02 for the MEGA65 is enabled, the following additional
data pointers are available:

.. table:: Additional MEGA65 address spaces
 :widths: 1 1 1 1 1
 :column-dividers: none single single single single none
 :column-alignment: left left left left left

 +-------------+------------+-------------------------+-------------+-------------+
 |Memory type  |Keyword     |Address range            |Pointer size | Index type  |
 +=============+============+=========================+=============+=============+
 | Far         | ``__far``  |``0x00000000-0xffffffff``|32 bits      |``int16_t``  |
 +-------------+------------+-------------------------+-------------+-------------+
 | Huge        | ``__huge`` |``0x00000000-0xffffffff``|32 bits      |``int32_t``  |
 +-------------+------------+-------------------------+-------------+-------------+


.. index:: address space; syntax, type qualifier

Syntax
------

An address space attribute keyword such as ``__zpage`` is
a type qualifier. Syntactically it works the same as other C language
defined type qualifier, e.g. ``const`` and ``volatile``.

The following declaration defines four variables in the
Zero page address space:

.. code-block:: C

   __zpage int a, b;
   int __zpage c, d;

The ``__zpage`` type qualifier applies to the closest type,
``int`` in this example. In C, the order between type qualifiers and
types does not matter; they convey the same meaning.

.. index:: pointers

Pointers
--------

A pointer in C points to something in memory. Both the pointer itself
and what it points to have types. As an example, the type ``char *``
is a pointer to a ``char``.

Pointer types are easier to understand if you read them from right to
left. The ``*`` is a pointer, so ``char *`` reads from right to left
as "pointer to char". This order of reading is especially useful when
you mix in type qualifiers in pointer types, as it makes it a lot
easier to read and understand  what the type means.

.. code-block:: C

   int __attribute__((zpage)) * p1;
   long * __attribute__((zpage)) p2;

Here, ``p1`` is a pointer stored in default memory that points to an
``int`` in Zero page memory. ``p2`` is a pointer stored
in Zero page memory that points to a ``long`` in default
memory.

Structures
----------

You can place a structure in a specified address space. This means
that all its members are in that address space. You cannot override
individual structure members using an address space keyword. It is
however possible to have members of the structure that point to a
different address space.

.. code-block:: C

   struct tag {
     int __zpage * p;
     int value;
   };

   struct tag __zpage myTag;

This is however not allowed:

.. code-block:: C

   struct tag {
     int * __zpage p;     /* incorrect */
     int __zpage value;   /* incorrect */
   };
