I stumbled upon a divergence in the ASCII upper case/lower case handling when using assembler and linker of the cc65 suite separately (I used cc65 V2.15 on Win10).

For a test I made the following assembler file helloworld.s for the default target (C64):

           ;code for a BASIC line containing SYS2061
           .byte $0B,$08,$e3,$07,$9e,$32,$30,$36,$31,$00,$00,$00

           lda #<textout
           ldy #>textout
           jmp $AB1E

textout:   .asciiz "hello world"

When I assemble and link the file with the command cl65 -C c64-asm.cfg helloworld.s -o helloworld.prg I get a program that outputs "hello world" on the C64 - it appears with uppercase letters with the default charset.

However, when I assemble to an object file first with ca65 helloworld.s and then link the object file with cl65 -C c64-asm.cfg helloworld.o -o helloworld.prg, I get a program that outputs the respective PETSCII characters when viewed with the default charset or, in lower case mode, "HELLO WORLD".

So why is there a difference between the two ways of building? Both cl65 and ca65 are from the cc65 toolchain. Second, is there a way to annotate the source code or to instruct ca65 not to change the case of the ASCII text?

  • Thanks to Raffzahn's great answer, I can confirm that assembling with a specified target ca65 -t c64 helloworld.s enables the proper (C64-oriented) handling of characters.
    – Peter B.
    Oct 18, 2019 at 17:19
  • BTW your release is four years old, you should update.
    – Polluks
    Oct 23, 2019 at 0:09

1 Answer 1


Simple reason

CL65 is using "C64" target as default, while CA65 uses "none".

Adding a -t none should make this disappear.


The CL65 documentation for -t does clearly point out the difference:

-t sys, --target sys

The default for this option is different from the compiler and linker in the case that the option is missing: While the other tools (compiler, assembler and linker) will use the "none" system settings by default, cl65 will use the C64 as a target system by default. This was chosen since most people seem to use cc65 to develop for the C64.

It's always good to keep in mind that CL65 is 'just' a 'wrapper' to combine the various tools (in this case CA65 and LD65) to ease use. It should simplify handling by reducing what to type. Like any tool, meant to simplify things, it either cuts off abilities and/or replaces them by assumptions.


Since CC65 and it's tools are meant to support various systems, each with it's own charset, the handling of text is postponed until linking. Oly then LD65 will translate all (recognized) strings into the appropriate code set, depending on the target. A very nice structure, allowing not only machine independent source code, but object modules as well. So the one module can be compiled and then linked for an Apple II, as well as for Commodore PET, without the need for recompilation.

For the C64 the (C64-)PETSCII with only uppercase chars is used, as that guarantees working, independent of which of the default charsets is selected at runtime.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .