Your source is most likely in ISO 8859-1 (or -15) encoded (*1), so the compiler has to do code conversion between character literals in your source and the designated target. Without a specifying a target CL65 uses, unlike all other tools, the C64 target by default (*2). As specified in target.c line 193, the C64 Target uses the PETSCII table at line 113, which shows exatly the conversations you noted.
Luckily there's a pragma called charmap to change this. So for example if you want to position the Umlauts at the classic 7 bit DIN 66003 positions simply add the following lines (*3):
/* Redefinition of 8859-1 codepoints for Umlauts ("ÄÖÜäöüß") */
/* to ISO-IR-21 aka ISO 646-DE aka DIN 66003 */
#pragma charmap (0xE4, 0x7B)
#pragma charmap (0xF6, 0x7C)
#pragma charmap (0xFC, 0x7D)
#pragma charmap (0xC4, 0x5B)
#pragma charmap (0xD6, 0x5C)
#pragma charmap (0xDC, 0x5D)
#pragma charmap (0xDF, 0x7E)
This is best put in some generic include for all sources (*4).
Also keep in mind that these changes are not global but only effective afterwards and can be overwritten again by a follow up pragma charmap reassigning any of these codes.
The default mapping maps the whole 0xC0..0xDF section onto 0x60..0x6F, whichare (mostly) the upper case letters.
At first glace this seems quite strange, really strange, until one realizes that this (0xC1..0xDA) is where the shifted letter keys are returned when reading the keyboard (*5). So in cases of keyboard read this might make some sense.
Still, I have no idea why it's done for character literals. My assumption would be some kind of compatibility situation, or a simple left over from such. So i'd say it was a situation of compatibility vs. support or chars that are not available on a standard PETSCII machine (*6) anyway, where they had to choose which foot to shoot ... and it did hit the Umlauts (*7).
*1 - The CC65 suite assumes ISO 8859-1. 8859-15 differs by the Euro symbol at 0xA4 and a few other characters.
*2 - Never trust defaults. Using defaults can result in many wasted ours to learn that different programs use different defaults or act on them different. So adding a -t c64
is always a good idea.
*3 - Just as example, you may of course use any other assignment.
*4 - Don't change any default files, as that would make your sources even less portable.
*5 - the lower case do show up at the standard positions of 0x41..0x5A.
*6 - Ignoring that real PET/CBM machines were sold in national variants, offering additional symbols by replacing certain graphic symbols, thus keeping full ASCII compatibility and national characters.
*7 - Which is really sad, as CC65 using ISO-8859-1 source would have allow to support all of them in a standardized fashion.
e4
,f6
, andfc
are not ASCII. ASCII is specifically 7-bit. So perhaps because of that there is undefined behaviour?