Just a note: I see that "As of march 2013 I have stopped maintaining cc65." (And by implication, CA65??) Looking at the FTP, it may take me a little bit to figure out where all the source code is located (CC65, CA65, LD65, and whatever else may be required to create a full toolset from the ground up.) There is an easy one that actually includes "source" in the .bz2 download filename. But I'll need to look inside to see what it has and doesn't have.
It's still under active development, with a mailing-list and everything.
Oliver Schmidt (a long time contributor) took over the project and moved it to Github (http://cc65.github.io/cc65/
I had a "patch" merged into the mainline codebase only a few weeks ago.
I've already taken a few minutes looking it over. I still need to read more, of course. But I've started the process. At this point, it is just a little bit more complex to use out of the box than Merlin32 is (my perception, knowing him.) However, I may move him off of Merlin32 and in this direction, as my time and his willingness allow.
The LD65 linker script is definitely something that took me a few hours to figure out. It provides complete flexibility in the linking, so that it can pretty-much output nearly-anything that you want ... but that that flexibility comes with the price of having to figure out the script so that you can get your first program written.
Here's what I wrote to help some guys in another forum ...
CC65/CA65 are working perfectly fine as a compiler/assembler.
I've built a test-rom with it to confirm that it compiles standard C code (a FAT32 library for reading the Everdrive's SD card).
It was easy to use and incredibly flexible once you've got your head around the power of its code-layout and startup options.
The point is that it's all
configurable and you
get to decide where the linker puts the startup-code/library-code/game-code/data.
The guy that was working on the PCE-port hasn't committed anything new in about 4 months. But that's not really a problem since he was definitely a novice on the PCE and was doing some things in a very strange (and wrong) way.
Because it's all "linked", we can just use the bits of his CC65-specific code that we like, and override anything else with new code.
Then, if you want to make a CD, you have to piece-together the .iso binary with something like 'bincat' and then modify the 2nd-sector with your particular
Here's my batch file for compiling the test code ...
# C files.
cc65 -O -t pce hello.c
cc65 -O -t pce fatfs/ff.c
cc65 -O -t pce fatfs/diskio.c
cc65 -O -t pce fatfs/option/unicode.c
ca65 -t pce -v hello.s
ca65 -t pce -v fatfs/ff.s
ca65 -t pce -v fatfs/diskio.s
ca65 -t pce -v fatfs/option/unicode.s
# ASM files.
ca65 -t pce -v crt0.s
ca65 -t pce -v text.s
ca65 -t pce -v sd.s
ld65 -o hello.pce -m hello.map -C pce.cfg hello.o text.o sd.o fatfs/ff.o fatfs/diskio.o fatfs/option/unicode.o crt0.o pce.lib
I decided to use the following layout for the HuCard ...
The STARTUP & library CODE go in bank $00 that lives at $E000-$FFFF.
The INIT code and the 'initialized' DATA (that get copied to RAM) goes in bank $01 that lives (temporarily) at $C000-$DFFF.
Once the HuCard starts up and my customized crt0.s runs the INIT code, and copies the 'initialized' DATA to RAM, then I map banks $02-$05 into $4000-$DFFF for my main code, and leave $C000-$DFFF for paging code/data as I need to.
Now I'm not saying that this is a particularly great way to lay out a HuCard, but I needed an uninterrupted 32KB for the FAT32 code, and the big point is that I was easily able to do that with CC65.
And here's my customized CC65 configuration file for that layout ...
__STACKSIZE__: type = weak, value = $0300; # 3 pages stack
# Preserve System Card standard ZP locations.
ZP: start = $00, size = $ec, type = rw, define = yes;
# reset-bank and hardware vectors
ROM0: start = $E000, size = $1FF6, file = %O, fill = yes, define = yes;
ROMV: start = $FFF6, size = $000A, file = %O, fill = yes;
ROM1: start = $C000, size = $2000, file = %O, fill = yes, define = yes;
ROM2: start = $4000, size = $8000, file = %O, fill = yes, define = yes;
ROM6: start = $C000, size = $2000, file = %O, fill = yes, define = yes;
ROM7: start = $C000, size = $2000, file = %O, fill = yes, define = yes;
# First RAM page (also contains stack and zeropage)
RAM: start = $2200, size = $1E00, define = yes;
STARTUP: load = ROM0, type = ro, define = yes;
INIT: load = ROM1, type = ro, define = yes, optional = yes;
CODE: load = ROM0, type = ro, define = yes;
RODATA: load = ROM0, type = ro, define = yes;
DATA: load = ROM1, type = rw, define = yes, run = RAM;
SDCODE: load = ROM2, type = ro, define = yes;
SDDATA: load = ROM2, type = ro, define = yes;
BSS: load = RAM, type = bss, define = yes;
VECTORS: load = ROMV, type = rw, define = yes;
ZEROPAGE: load = ZP, type = zp, define = yes;
EXTZP: load = ZP, type = zp, define = yes, optional = yes;
APPZP: load = ZP, type = zp, define = yes, optional = yes;
CONDES: type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__,
segment = INIT;
CONDES: type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__,
segment = RODATA;
CONDES: type = interruptor,
label = __INTERRUPTOR_TABLE__,
count = __INTERRUPTOR_COUNT__,
segment = RODATA,
import = __CALLIRQ__;
I guess that it would help to explain a couple of things in the configuration file (it's for the "LD65" linker).
The "MEMORY" section is basically just a list of areas (and their sizes) that get written to the output file ... in this case I'm having it create an 8 bank HuCard ROM image.
The actual names of the different sections in "MEMORY" can be anything ... I'm just using the name "ROM" + bank-offset for my own convenience.
The "SEGMENTS" section defines the names of the different segments in the C and ASM code (user-defined, but with a few defaults like CODE/DATA/RODATA/RAM), and it shows where in the output file those segments should be put.
That's it ... you have total flexibility to map your code/data into the output HuCard/ISO image in any way that you like.
As a separate aside given your knowledge of CA65, do you feel it should be very easy to use the toolset there (assembler and linker) to transition from hand-coded binary towards assembly source code that is readily (and trivially) patched into some working ROM for direct use immediately after the multi-module assemble-link step? (I'm trying to avoid complex link-input structures that require assumed prior knowledge of C compiler object code models that are often required when using tools designed for both C and asm.)
Well ... since you can split up your source files and create as many "MEMORY" and "SEGMENT" definitions as you like, then AFAIK you can make the binary output look like anything that you want.
But note ... I haven't actually tried to make it write out a file as a bunch of "header+chunk" sections, which sounds more like what you're after.