CC65 Reserving Memory Area

Building your first 6502-based project? We'll help you get started here.
Post Reply
Lemuren
Posts: 4
Joined: 21 Aug 2020

CC65 Reserving Memory Area

Post by Lemuren »

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.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: CC65 Reserving Memory Area

Post by BigEd »

Welcome!

There's an issue on github which seems to contain a recipe:
Lemuren
Posts: 4
Joined: 21 Aug 2020

Re: CC65 Reserving Memory Area

Post by Lemuren »

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.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: CC65 Reserving Memory Area

Post by BigEd »

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.
Lemuren
Posts: 4
Joined: 21 Aug 2020

Re: CC65 Reserving Memory Area

Post by Lemuren »

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
John West
Posts: 383
Joined: 03 Sep 2002

Re: CC65 Reserving Memory Area

Post by John West »

Lemuren wrote:
Yunder $D018 there doesn't seem to be a configuration for pointing to $C800.
That's because VIC can only see 16K of memory at a time, and the default is $0000-$3FFF. However, have a look at $DD00: the bottom two bits choose which 16K bank VIC uses. To have your character set at $C800, you'd clear the bottom two bits of $DD00 and set the bottom 3 bits of $d018 to 001.

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).
Lemuren
Posts: 4
Joined: 21 Aug 2020

Re: CC65 Reserving Memory Area

Post by Lemuren »

John West wrote:
Lemuren wrote:
Yunder $D018 there doesn't seem to be a configuration for pointing to $C800.
That's because VIC can only see 16K of memory at a time, and the default is $0000-$3FFF. However, have a look at $DD00: the bottom two bits choose which 16K bank VIC uses. To have your character set at $C800, you'd clear the bottom two bits of $DD00 and set the bottom 3 bits of $d018 to 001.

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).
Thanks, you're a life-saver! That did the trick (almost!). I decided to put my character information in $C000-$C7FF and put the screen memory location at $C800-$CBFF. I don't know how familiar you are with cc65, but I've run into another issue now.

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

Post by White Flame »

I reduced all the address calculations to this snippet. Substitute the screenChars & screenPixels to whatever you need and reuse the expressions.

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
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. ;)
Post Reply