mirror of
https://github.com/cc65/cc65.git
synced 2024-08-16 12:29:03 +00:00
372 lines
13 KiB
Plaintext
372 lines
13 KiB
Plaintext
<!doctype linuxdoc system>
|
|
|
|
<article>
|
|
|
|
<title>cc65 compiler intro
|
|
<author>Ullrich von Bassewitz, <htmlurl url="mailto:uz@cc65.org" name="uz@cc65.org"> and CbmNut <htmlurl url="mailto:cbmnut@hushmail.com" name="cbmnut@hushmail.com">
|
|
<date>07.13.2002
|
|
|
|
<abstract>
|
|
How to use the cc65 C compiler - an introduction.
|
|
</abstract>
|
|
|
|
<!-- Table of contents -->
|
|
<toc>
|
|
|
|
<!-- Begin the document -->
|
|
|
|
<sect>Overview<p>
|
|
|
|
This is a short intro of how to use the compiler and the binutils. It contains a
|
|
step-by-step example of how to build a complete application from one C and one
|
|
assembler module. This file does <em/not/ contain a complete reference for the
|
|
tools used in the process. There are separate files describing these tools in
|
|
detail.
|
|
|
|
You are assumed to have downloaded and extracted the executables and the
|
|
target specific files. For example, for Windows users targeting C64, you need
|
|
cc65-win32-2.8.0.zip and cc65-c64-2.8.0.zip (or whatever the current cc65
|
|
version is) extracted to the same directory. If you received the files as a
|
|
bzip2 archive (extension *.bz2), you will need to get the <htmlurl
|
|
url="http://sources.redhat.com/bzip2/#bzip2-latest" name="bzip2 package"> to
|
|
decompress it.
|
|
|
|
<bf>Note</bf>: There is a much simpler way to compile this example using the
|
|
cl65 compiler and link utility. However, it makes sense to understand how the
|
|
separate steps work. How to do the example with the cl65 utility is described
|
|
<ref id="using-cl65" name="later">.
|
|
|
|
|
|
<sect1>Before we start<p>
|
|
|
|
You will find a copy of the sample modules used in the next section in the
|
|
samples/tutorial directory. Windows users will also find a small batch file in
|
|
this directory named "cc65setup.bat". Be sure to examine and understand the
|
|
commands in this file, then adjust them for your setup, and execute the file.
|
|
|
|
|
|
<sect1>The sample modules<p>
|
|
|
|
To explain the development flow, I will use the following example modules:
|
|
|
|
hello.c:
|
|
|
|
<tscreen><code>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
extern const char text[]; /* In text.s */
|
|
|
|
int main (void)
|
|
{
|
|
printf ("%s\n", text);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
</code></tscreen>
|
|
|
|
text.s:
|
|
<tscreen><code>
|
|
.export _text
|
|
_text: .asciiz "Hello world!"
|
|
</code></tscreen>
|
|
|
|
|
|
<sect1>Translation phases<p>
|
|
|
|
We assume that the target file should be named "hello", and the target system
|
|
is the C64.
|
|
|
|
<tscreen><verb>
|
|
+---------+
|
|
| hello.c |
|
|
+---------+
|
|
|
|
|
cc65
|
|
\/
|
|
+---------+ +---------+
|
|
| hello.s | | text.s |
|
|
+---------+ +---------+
|
|
| |
|
|
ca65 ca65
|
|
\/ \/
|
|
+---------+ +---------+ +----------+ +---------+
|
|
| hello.o | | text.o | | c64.o | | c64.lib |
|
|
+---------+ +---------+ +----------+ +---------+
|
|
| \ / |
|
|
| \ / |
|
|
| \ / |
|
|
+----------------------->ld65<-------------------------+
|
|
\/
|
|
hello
|
|
</verb></tscreen>
|
|
|
|
<tt/c64.o/ (the startup code) and <tt/c64.lib/ (the c64 version of the runtime
|
|
and C library) are provided in binary form in the cc65 package.
|
|
|
|
|
|
|
|
<sect>The compiler<p>
|
|
|
|
The compiler translates one C source into one assembler source for each
|
|
invocation. It does <em/not/ create object files directly, and it is <em/not/
|
|
able to translate more than one file per run.
|
|
|
|
In the example above, we would use the following command line, to translate
|
|
<tt/hello.c/ into <tt/hello.s/:
|
|
|
|
<tscreen><verb>
|
|
cc65 -O -I ../include -t c64 hello.c
|
|
</verb></tscreen>
|
|
|
|
The <tt/-O/ switch tells the compiler to do an additional optimizer run, which
|
|
is usually a good idea, since it makes the code smaller. If you don't care
|
|
about the size, but want to have slightly faster code, use <tt/-Oi/ to inline
|
|
some runtime functions.
|
|
|
|
The <tt/-I/ switch gives a search path for the include files. You may also set
|
|
the environment variable CC65_INC to the search path.
|
|
|
|
The <tt/-t/ switch is followed by the target system.
|
|
|
|
If the compiler does not complain about errors in our hello world, we will
|
|
have a file named "<tt/hello.s/" in our directory that contains the assembler
|
|
source for the hello module.
|
|
|
|
For more information about the compiler see <htmlurl url="cc65.html"
|
|
name="cc65.html">.
|
|
|
|
|
|
|
|
<sect>The assembler<p>
|
|
|
|
The assembler translates one assembler source into an object file for each
|
|
invocation. The assembler is <tt/not/ able to translate more than one source
|
|
file per run.
|
|
|
|
Let's translate the hello.s and text.s files from our example:
|
|
|
|
<tscreen><verb>
|
|
ca65 hello.s
|
|
ca65 -t c64 text.s
|
|
</verb></tscreen>
|
|
|
|
The <tt/-t/ switch is needed when translating the <tt/text.s/ file, so the
|
|
text is converted from the input character set (usually ISO-8859-1) into the
|
|
target character set (PETSCII) by the assembler. The compiler generated file
|
|
<tt/hello.s/ does not contain any character constants, so specification of a
|
|
target is not necessary (it wouldn't do any harm, however).
|
|
|
|
If the assembler does not complain, we should now have two object files (named
|
|
<tt/hello.o/ and <tt/text.o/) in the current directory.
|
|
|
|
For more information about the assembler see <htmlurl url="ca65.html"
|
|
name="ca65.html">.
|
|
|
|
|
|
|
|
<sect>The linker<p>
|
|
|
|
The linker combines several object and library file into one output file. ld65
|
|
is very configurable, but fortunately has a builtin configuration for the C64,
|
|
so we don't need to mess with configuration files here.
|
|
|
|
The compiler uses small functions to do things that cannot be done inline
|
|
without big impact on code size. These runtime functions, together with the C
|
|
library are in an object file archive named after the system, in this case
|
|
"<tt/c64.lib/". We have to specify this file on the command line so that the
|
|
linker can resolve these functions.
|
|
|
|
A second file (this time an object file) needed, is the startup code that
|
|
prepares the grounds for the C program to run. The startup file must be
|
|
executed first, so it must be the first file on the linker command line.
|
|
|
|
Let's link our files to get the final executable:
|
|
|
|
<tscreen><verb>
|
|
ld65 -t c64 -o hello c64.o hello.o text.o c64.lib
|
|
</verb></tscreen>
|
|
|
|
The argument after <tt/-o/ specifies the name of the output file, the argument
|
|
after <tt/-t/ gives the target system. As discussed, the startup file must be
|
|
the first file on the command line (you may have to add a path here, if
|
|
<tt/c64.o/ is not in your current directory). Since the library resolves
|
|
imports in <tt/hello.o/ and <tt/text.o/, it must be specified <em/after/ these
|
|
files.
|
|
|
|
After a successful linker run, we have a file named "<tt/hello/", ready for
|
|
our C64!
|
|
|
|
For more information about the linker see <htmlurl url="ld65.html"
|
|
name="ld65.html">.
|
|
|
|
|
|
|
|
<sect>The easy way (using the cl65 utility)<label id="using-cl65"><p>
|
|
|
|
The cl65 utility is able to do all of the steps described above in just one
|
|
call, and it has defaults for some options that are very well suited for our
|
|
example.
|
|
|
|
To compile both files into one executable enter
|
|
|
|
<tscreen><verb>
|
|
cl65 -O -I ../include hello.c text.s
|
|
</verb></tscreen>
|
|
|
|
(The <tt/-I/ switch is not needed if you are working under Linux with the
|
|
include files in the default path, or the <tt/CC65_INC/ environment variable
|
|
is set correctly).
|
|
|
|
The cl65 utility knows, how to translate C files into object files (it will
|
|
call the compiler and then the assembler). It does also know how to create
|
|
object files from assembler files (it will call the assember for that). It
|
|
knows how to build an executable (it will pass all object files to the
|
|
linker). And, finally, it has the C64 as a default target and will supply the
|
|
correct startup file and runtime library names to the linker, so you don't
|
|
have to care about that.
|
|
|
|
The one-liner above should give you a C64 executable named "<tt/hello/" in the
|
|
current directory.
|
|
|
|
For more information about the compile & link utility see <htmlurl
|
|
url="cl65.html" name="cl65.html">.
|
|
|
|
<sect>Running The Executable<p>
|
|
|
|
<bf>Note: this section is incomplete!</bf>
|
|
|
|
Depending on the target, the compiler chooses several methods of making a
|
|
program available for execution. Here we list sample emulators and
|
|
instructions for running the program. Unless noted, similar instructions
|
|
would also apply to a real machine. One word of advice: we suggest you clear
|
|
the screen at the start, and wait for a keypress at the end of your program,
|
|
as each target varies in it's start and exit conditions.
|
|
|
|
<sect1>Apple<p>
|
|
|
|
<bf>AppleWin 1.10.4</bf> (available at
|
|
<url url="http://www.jantzer-schmidt.de/applewin/">): Emulates Apple II+/IIe
|
|
computer, with sound, video, joysticks, serial port, and disk images. Roms and
|
|
dos disk included. Includes monitor. Only for Windows. The package comes with
|
|
roms and dos3.3 disk (called master.dsk), however you will need a2tools
|
|
(available at <url url="http://hotel04.ausys.se/pausch/apple2/#a2tools">).
|
|
|
|
Compile the tutorial with
|
|
|
|
<tscreen><verb>
|
|
cl65 -O -t apple2 hello.c text.s
|
|
</verb></tscreen>
|
|
|
|
Then insert the file into an Apple disk image for use with an emulator. Copy
|
|
the master.dsk which comes with Applewin and rename it to cc65.dsk, then use
|
|
a2tools:
|
|
|
|
<tscreen><verb>
|
|
a2tools in -r b cc65.dsk TEST hello
|
|
</verb></tscreen>
|
|
|
|
Note that a convention in the Apple world is that hello is the file which is
|
|
automatically run upon booting a DOS disk, sort of like the Autoexec.bat of
|
|
the PC world. We've avoided this in the example however. Also, the TEST
|
|
parameter must be in caps, and is the name of the program as it will appear on
|
|
the Apple disk.
|
|
|
|
Start the emulator, click on the Disk 1 icon, and point to cc65.dsk, then
|
|
click the big Apple logo to boot the system. Then type this on the Apple:
|
|
|
|
<tscreen><verb>
|
|
BRUN TEST
|
|
</verb></tscreen>
|
|
|
|
You will see the "Hello, World!" appear on the same line. Thanks to Oliver
|
|
Schmidt, <htmlurl url="mailto:oliver@jantzer-schmidt.de"
|
|
name="oliver@jantzer-schmidt.de"> for his help in completing this section.
|
|
|
|
<sect1>Atari<p>
|
|
|
|
<bf>Atari800Win Plus 3.0</bf> (available at
|
|
<url url="http://www.a800win.atari-area.prv.pl">): Emulates Atari
|
|
400/800/65XE/130XE/800XL/1200XL/5200, with stereo sound, disk images, scanline
|
|
exact NTSC/PAL video, joysticks, mouse, cartridges and ram expansions.
|
|
Includes monitor. Unfortunately only for Windows. You will need the emulator,
|
|
atarixl.rom or atariosb.rom/ataribas.rom and dos25.xfd files (not supplied).
|
|
|
|
Compile the tutorial with
|
|
|
|
<tscreen><verb>
|
|
cl65 -O -t atari hello.c text.s
|
|
</verb></tscreen>
|
|
|
|
Start the emulator, choose File>Autoboot image or File>Load executable, and
|
|
point to the hello executable. It is customary to rename executables of this
|
|
type to hello.xex. The file has a 7 byte header meant to be loaded directly
|
|
from Atari DOS 2/2.5 or compatibles.
|
|
|
|
On a real Atari, you would need a disk drive and Atari Dos 2.5 or compatible.
|
|
Turn on the computer, type
|
|
|
|
<tscreen><verb>
|
|
DOS
|
|
</verb></tscreen>
|
|
|
|
at the basic prompt, then choose N. CREATE MEM.SAV then choose L. BINARY LOAD
|
|
and enter HELLO.
|
|
|
|
The emulation also supports this method. Look at Atari>Settings and check
|
|
Enable H: Patch for Hard Disk Devices, then Atari>Hard disks and set the path
|
|
of H1: to your executables directory, then use H0:HELLO.XEX in the above
|
|
proceedure (after pressing L) to access your hardrive directly.
|
|
|
|
<bf>Note:</bf> There is no delay after the program exits, as you are returned
|
|
to the DOS menu. Your C program should wait for a keypress if you want to see
|
|
any output.
|
|
|
|
<sect1>Commodore<p>
|
|
|
|
<bf>Vice 1.9</bf> (available at
|
|
<url url="ftp://ftp.funet.fi/pub/cbm/crossplatform/emulators/VICE/">):
|
|
Emulates Commodore 64/128/Vic 20/PET/CBM II computers. Missing is the Plus/4
|
|
and Commodore 16. Supports printer, serial port, stereo sound, disk drives and
|
|
images, ram expansions, cartridges, cycle exact NTSC/PAL video, mice,
|
|
joysticks. Includes monitor. Runs on Win9x/NT/2000/XP/ME/OS2/MSDOS, Beos x86,
|
|
Acorn RISC OS, and many Unixes.
|
|
|
|
Start the desired version of the emulator, choose File>Autoboot disk/tape
|
|
image, and choose your executable. The file has a 14 byte header which
|
|
corresponds to a PRG format BASIC program, consisting of a single line;
|
|
|
|
<tscreen><code>
|
|
1000 sys2061
|
|
</code></tscreen>
|
|
|
|
On a real Commodore with attached disk drive, you would type:
|
|
|
|
<tscreen><verb>
|
|
LOAD "HELLO",8
|
|
</verb></tscreen>
|
|
|
|
for Vic 20/C64, or
|
|
|
|
<tscreen><verb>
|
|
DLOAD "0:HELLO"
|
|
</verb></tscreen>
|
|
|
|
on PET/CBM II/C128, then type
|
|
|
|
<tscreen><verb>
|
|
RUN
|
|
</verb></tscreen>
|
|
|
|
The output will appear on a separate line, and you will be returned to a BASIC
|
|
prompt.
|
|
|
|
We need your help! Recommended emulators and instructions for other targets
|
|
are missing. We suggest an emulator with good compatibility. Also, being able
|
|
to run all computers in the target series is good for target compatibility
|
|
testing. A machine language monitor is almost essential for debugging, but a
|
|
native debugger could be used as well.
|
|
|
|
Finally, emulators which run on Unix/Windows would help reach a wider audience.
|
|
|
|
</article>
|