Hello.
I am trying to use a custom character set whilst using CC65. I am aware of how the process is normally done, and I'd like to set the character data to $3000-$3800. However, it seems this is reserved/in use by CC65. I suspect I would have to use a custom cfg file to tell the linker to leave this area well enough alone, so I can memcpy to it in peace. How would I go about doing this? I've looked a bit at the c64.cfg file (Since I'm compiling for the C64), but I'm not sure how to do this.
Thanks.
CC65 Reserving Memory Area
Re: CC65 Reserving Memory Area
Welcome!
There's an issue on github which seems to contain a recipe:
There's an issue on github which seems to contain a recipe:
Re: CC65 Reserving Memory Area
Yes, I read through that thread. Unfortunately that seems to be just for storing a character set. As far as I'm aware there is no way to actually have the C64 read characters from that location. I'm looking here:
https://sta.c64.org/cbm64mem.html
and under $D018 there doesn't seem to be a configuration for pointing to $C800.
https://sta.c64.org/cbm64mem.html
and under $D018 there doesn't seem to be a configuration for pointing to $C800.
Re: CC65 Reserving Memory Area
Oops, sorry, I didn't notice that the person started out asking how to put data at 3800 and ended up placing it at c800.
There may well be a way to get cc65 to do what you want, but I don't know what it is. I get the impression the configuration is extremely flexible.
There may well be a way to get cc65 to do what you want, but I don't know what it is. I get the impression the configuration is extremely flexible.
Re: CC65 Reserving Memory Area
Yes. Interestingly enough I can write some data to $3000 onward before it throws a hissy-fit, which makes me suspect that CC65 is using this location for variables, etc. I agree that the linker configuration seems flexible, but the documentation is hard to understand, if not lacking in some areas.
All I want to do is to tell the linker/memory map to completely ignore addresses $3000-$3800, and pretend they don't exist.
EDIT:
So after some more digging I've come to the following conclusions. It's true that cc65 starts writing from $801 onwards. There are 2 configuration files, c64 and c64-asm. The former doesn't allow for changing the start address, but the latter only works on assembly files, not C files.
The c64 cfg file includes something that generates a BASIC SYS 2061 stub. This stub seems to always be SYS 2061, regardless of any settings in the cfg file. Obviously changing the start address does nothing, but strangely enough if I change the start value of the MAIN memory bit to, say, $1001, it will _still_ write data from $801. This can't be the stub either, since there is no "gap" between $800 and $1001.
However, it doesn't seem to write things identically, because while a SYS 2061 call successfully starts the program with the default settings, it does not do so if I change the start address of MAIN to e.g. $1001, even though _something_ has been written to the addresses between $801-$1001.
Compiled with:
cl65 -o foo.prg -t c64 -C c64.cfg foo.c
All I want to do is to tell the linker/memory map to completely ignore addresses $3000-$3800, and pretend they don't exist.
EDIT:
So after some more digging I've come to the following conclusions. It's true that cc65 starts writing from $801 onwards. There are 2 configuration files, c64 and c64-asm. The former doesn't allow for changing the start address, but the latter only works on assembly files, not C files.
The c64 cfg file includes something that generates a BASIC SYS 2061 stub. This stub seems to always be SYS 2061, regardless of any settings in the cfg file. Obviously changing the start address does nothing, but strangely enough if I change the start value of the MAIN memory bit to, say, $1001, it will _still_ write data from $801. This can't be the stub either, since there is no "gap" between $800 and $1001.
However, it doesn't seem to write things identically, because while a SYS 2061 call successfully starts the program with the default settings, it does not do so if I change the start address of MAIN to e.g. $1001, even though _something_ has been written to the addresses between $801-$1001.
Compiled with:
cl65 -o foo.prg -t c64 -C c64.cfg foo.c
Re: CC65 Reserving Memory Area
Lemuren wrote:
Yunder $D018 there doesn't seem to be a configuration for pointing to $C800.
Everything that VIC accesses must be in the same bank, so you couldn't have characters at $C800 and screen at its usual $0400.
Screen memory would have to move to $C400 (or somewhere else in $C000-$FFFF).
Re: CC65 Reserving Memory Area
John West wrote:
Lemuren wrote:
Yunder $D018 there doesn't seem to be a configuration for pointing to $C800.
Everything that VIC accesses must be in the same bank, so you couldn't have characters at $C800 and screen at its usual $0400.
Screen memory would have to move to $C400 (or somewhere else in $C000-$FFFF).
If I directly write to locations $C800-$C7FF everything works fine, characters print just like they should, however, the built-in functions e.g. cputc() seem to be hardcoded to write to $0400, i.e. the default screen memory location. Is there any way of changing these, or should I just re-write the printing functions on my own?
EDIT:
I managed to fix it. Changing the high-byte of the pointer to screen memory ($0288) to $C8 fixed it. Thanks again for all the help.
-
White Flame
- Posts: 704
- Joined: 24 Jul 2012
Re: CC65 Reserving Memory Area
I reduced all the address calculations to this snippet. Substitute the screenChars & screenPixels to whatever you need and reuse the expressions.
Of course, the pointers still have their standard alignment restrictions and must be in the same 16KB bank, but I got sick of all the manual juggling and made the math figure out the bits for me. 
Code: Select all
screenChars = $0400 ; the 40x25 buffer
screenPixels = $1000 ; the pixel data for font or bitmap ($1000 or $9000 are always charrom)
; Select VIC bank
lda # ((screenChars ^ $ffff) >> 14)
sta $dd00
; Set VIC screen and font pointers
lda # (((screenChars & $3fff) / $0400) << 4) + (((screenPixels & $3fff) / $0800) << 1)
sta $d018