cc7800

cc7800 implements a subset of C compiler for Atari 7800. The main goal of cc7800 is to enable making games for the Atari 7800 using C language, including fast filling of Maria display lists, not to provide full C support for the 6502 (have a look at cc65 if this is what you are looking for). Any code written for cc7800 can be compiled with gcc, but not the other way round... The 6502 processor is famous for being an inefficient target for C compilers, due to its poor stack support, its infamous indexing modes and its lack of registers. cc7800 tries to cope with these limitations by not strictly implementing all C features but mapping C syntax to the specifics of 6502, in particular 6502 X/Y indexing modes.

cc7800 is implemented in the Rust programming language, a touch of modernity for an almost 40 years old console... The C language grammar has been handwritten from scratch as a PEG grammar, so don't expect any ANSI or ISO C compliance.

Main features

Known limitations

How to install

Installing from source is quite straightforward when Rust Cargo is available on your platform. If this is not the case, please use rustup to install it, then use cargo install --path . in the root directory to compile and install cc7800 locally.

You can install the binary directly using Cargo by typing cargo install cc7800

If you definitely don't want to install Rust (quite a shame), a Windows installer will be provided in the coming years.

Examples of code using cc7800

A few examples are available in the examples directory. To compile HelloWorld, please type in the root directory :

cc7800 -Iheaders examples/test_helloworld.c

This will produce out.a, which is a DASM compatible source code.

Type dasm out.a -f3 -v4 -oout.bin -lout.lst -sout.sym to make out.bin.

Now use 7800header to create a .a78 file from out.bin (with the command save out.a78)

The out.a78 can be executed with the a7800 emulator by typing a7800 a7800 -cart out.a78, or copied directly on a Concerto cart.

Technical details

Intrinsics

cc7800 supports a few intrinsics to help making ASM-like tuned code :

16-bits arithmetics support

16-bits arithmetics is supported, BUT beware to use only simple expressions (like a simple addition, or +=, not multiple additions on the same line of code), since carry propagation is not ensured (maybe will it be in the future). In particular 16-bits operations are not supported in comparisons. Use short to declare a 16-bits variable. char * are also 16-bits variables, since address space on 6502 is 16-bits wide.

In order to convert from 16-bits to 8-bits, use the >> 8 special operation to get the higher byte of a short, and use nothing to get the lower byte.

Optimizations

X and Y are unsigned char typed, BUT in order to optimize the loops, they are considered signed char when compared to 0. Hence the code do { something; Y-- } while (Y >= 0); will be implemented with a BPL (branch if plus) instruction, just like you would do in assembler. Beware then that if Y > 128, due to the complement-to-2 binary representation, it will be considered negative number and the loop will exit immediately.

TODO