I was working on a large program for the Atari 8 bit in the Action! language, which is a fine language in and of itself, and has been my favorite language for the platform. I ran into a couple of limitations that prompted me to look at alternatives.
One of those limitations comes into play when the Action! program is compiled into a stand alone application (ie: run without the cartridge present). In this form, you may only pass two bytes through a function call. There are some work arounds, but they would add to the code size and require many adaptations to the Action! library I’ve written.
The other limitation is the stack size. It is rather small. It can be expanded, but not large enough.
I looked at the Atari 8 bit pascal compilers and found that each one had something I didn’t care for. I then started looking at the C compilers. Of the ones that run natively on the Atari 8 bit, I again found something I didn’t care for in each one. Then I remembered CC65 (https://cc65.github.io) , a cross platform 6502 C compiler. I used this back in 2016 while working on a small game. I decided to look at it again.
The first hurdle was getting it running on an Apple M1 Mac. Previously I ran it on an Intel based Apple Mac but just downloading the source and compiling it. This doesn’t work straight up on the M1 Mac. I found the easiest way to get it running was to install Homebrew (https://brew.sh), then use Homebrew to install it with the command:
brew install cc65
Simple!
After browsing through the CC65 online documentation I set out to create a simple hello world application to test the build process. I will note that the CC65 documentation is incomplete, and noted as such. You can view the source code when you need more. The project also seeks volunteers to assist. For building, I am using Microsoft Visual Code (https://code.visualstudio.com), MacOS Terminal, and Atari800MacX (http://atarimac.com/atari800macx.php) Atari 8 bit emulator.
My hello world program prints a few more things than just hello world, and it waits for a keystroke before exiting. I wanted it to wait for a keystroke so when running the XEX executable directly from the MacOS Finder, it would pause before exiting the emulator.
In order to wait for a key, I either needed the peekpoke header so I could peek location 764 for a keystroke, or use the CC65 function kbhit() which needs the conio header. I chose the latter.
Here is the source:
// ------------------------------------------------------------
// Program: hello.c
// Desc...: Hello World CC65 demonstration
// Author.: Ripdubski
// Date...: 202208
// Notes..: cl65 -v -O -t atari hello.c -o hello.xex
// ------------------------------------------------------------
// Pull in include files
#include <stdio.h>
#include <conio.h>
#include <atari.h>
// ------------------------------------------------------------
// Func...: void main(void)
// Desc...: Main routine
// ------------------------------------------------------------
void main(void)
{
// Setup screen
clrscr();
printf("-[CC65 Hello World Test]----------------");
// Display hello world
printf("\nHello World from CC65!\n");
// Wait for a key
printf("\npress any key\n");
while (! kbhit()) {}
// Exit
return;
}
Simple enough!
To compile, I used the following command. This command does the compile and link. The “-v” parameter is the verbose flag. The “-O” parameter turns on optimization. The “-t” parameter tells CC65 which platform to target. The target can be either “atari” or “atarixl”, you can read up on the differences on the CC65 site. The “-o” parameter tells CC65 the name of the executable file to build:
cl65 -v -O -t atarixl hello.c -o hello.xex
The build process produced the following output:
$ cl65 -v -O -t atarixl hello.c -o hello.xex
Opened include file '/usr/local/share/cc65/include/stdio.h'
Opened include file '/usr/local/share/cc65/include/stddef.h'
Opened include file '/usr/local/share/cc65/include/stdarg.h'
Opened include file '/usr/local/share/cc65/include/conio.h'
Opened include file '/usr/local/share/cc65/include/atari.h'
Opened include file '/usr/local/share/cc65/include/_gtia.h'
Opened include file '/usr/local/share/cc65/include/_pbi.h'
Opened include file '/usr/local/share/cc65/include/_pokey.h'
Opened include file '/usr/local/share/cc65/include/_pia.h'
Opened include file '/usr/local/share/cc65/include/_antic.h'
Opened include file '/usr/local/share/cc65/include/atari.h'
0 errors, 0 warnings
Running optimizer for function 'main'
Opened output file 'hello.s'
Wrote output to 'hello.s'
Closed output file 'hello.s'
Opened 'hello.xex'...
Dumping 'HEADER'
Writing 'EXEHDR'
Dumping 'SYSCHKHDR'
Writing 'SYSCHKHDR'
Dumping 'SYSCHKCHNK'
Writing 'SYSCHK'
Dumping 'SYSCHKTRL'
Writing 'SYSCHKTRL'
Dumping 'SRPREPHDR'
Writing 'SRPREPHDR'
Dumping 'SRPREPCHNK'
Writing 'LOWBSS'
Writing 'SRPREP'
Writing 'SHADOW_RAM'
Writing 'SHADOW_RAM2'
Dumping 'SRPREPTRL'
Writing 'SRPREPTRL'
Dumping 'MAINHDR'
Writing 'MAINHDR'
Dumping 'MAIN'
Writing 'STARTUP'
Writing 'LOWCODE'
Writing 'ONCE'
Writing 'CODE'
Writing 'RODATA'
Writing 'DATA'
Writing 'BSS'
Dumping 'TRAILER'
Writing 'AUTOSTRT'
Here is a screenshot of the success:

In the next few posts I will document some more experiments I did with the language which helped me remember how pointers and arrays work in C. I have already started converting my Action! library to C (CC65), and will also document that with the end result being the release of the library for use with C (CC65).