More questions about ca65 .cfg file

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
battagline
Posts: 152
Joined: Wed Sep 05, 2018 11:13 am
Location: Colorado
Contact:

More questions about ca65 .cfg file

Post by battagline »

Ok, so I thought I understood this from a previous thread I created on this topic, but I'm going back through my .cfg file and I'm a little confused about a few things.

1. Is there any difference between

Code: Select all

file = ""
and

Code: Select all

file = %O
? Rainwarrior's example file used both of those, so I assume there's some difference, but looking through the ld65 configuration file docs seems to indicate that not having a file or having file = %0 both result in it going to the -o specified file.

2. The following line goes into the MEMORY section of the config file:

Code: Select all

CHR:    start = $0000,  size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
How does that line tell the linker to put the CHR code into PPU memory and not CPU memory?

Thanks for your help,
Rick
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: More questions about ca65 .cfg file

Post by Memblers »

1: Don't think there's a difference, not that I'm aware of. edit - corrected in reply

2: In the MEMORY section, it's the order that you list them in that determines the order in which it is output to the file. The linker of course doesn't know about PRG or CHR, so the only thing stopping it from going to PRG is you having the correct amount of memory preceding it, and it matching the size in the .NES header.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: More questions about ca65 .cfg file

Post by koitsu »

The documentation you want is for ld65 (the linker), section 5: https://cc65.github.io/doc/ld65.html#s5

1. file="" means don't create a file, i.e. do not make a separate file with output from this MEMORY block. This is important for defining areas of memory that don't need to be written to disk; ZP and RAM areas, as well as the stack (if defined separately) are good examples, e.g. things that are not going to be part of the resulting ROM.

file=%O means create a file based on the output filename of what's passed via -o flag to the linker. You can likewise say file="myfile.bin" and so on. In "simple cases" this is usually the resulting .NES file, but every project differs.

2. The line in question, which is in the MEMORY section, ends up going into the resulting ROM file because of the file=%O directive.

How this ends up being the PPU pattern table (PPU RAM $0000-1FFF) is purely due to the .NES file format itself. The file format is, summarised:

First: a 16-byte header (which includes the number of 16KB PRG banks, and the number of 8KB CHR-ROM banks)
Second: all of the PRG banks
Third: all of the CHR banks

This is why for MEMORY, you'll see things like HEADER with file=%O, ROMn with file=%O, and CHR with file=%O. %O essentially means "the resulting .NES file".

Your SEGMENTS section will have references to things in the MEMORY section using directives like load=THING_IN_MEMORY_BLOCK, e.g. CODE: load=ROMn, type=ro and VECTORS: load=ROMn, type=ro, start=$FFFA.

For games that are CHR-RAM, there are no CHR banks (the header will have 0 for the CHR bank count, and there will be no CHR data at the end of the .NES file). Those games use native 6502 code to copy the CHR data (from somewhere in PRG ROM space) into PPU RAM $0000-1FFF (because it's actually RAM on the cartridge, not ROM on the cartridge).

I still maintain this aspect of the ca65 suite is one of the biggest stumbling blocks about the assembler. The old classic concatenation method, e.g. copy /b header.bin+prg.bin+chr.bin mygame.nes makes a lot more sense to people when they see it.
User avatar
battagline
Posts: 152
Joined: Wed Sep 05, 2018 11:13 am
Location: Colorado
Contact:

Re: More questions about ca65 .cfg file

Post by battagline »

So does it always assume that the .chr comes first? Like if I changed the 6th byte of my header from $01 to $02, but didn't import a second 8K chr file would it grab the program code I wrote and think it was a .chr?

So I use 2 16K PRG Rom banks. So in the rom file does it just always have the .chr after the header and the prg rom after that? If you use a mapper does it appear the same way in the rom file?

Thanks
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: More questions about ca65 .cfg file

Post by tepples »

If CHR ROM is used, CHR ROM always comes after PRG ROM. With 32 KiB PRG ROM and 8 KiB CHR ROM, your ROM is arranged as follows:
  1. $0000-$000F: Header
  2. $0010-$800F: PRG ROM mapped to CPU $8000-$FFFF
  3. $8010-$A00F: CHR ROM mapped to $0000-$1FFF
User avatar
battagline
Posts: 152
Joined: Wed Sep 05, 2018 11:13 am
Location: Colorado
Contact:

Re: More questions about ca65 .cfg file

Post by battagline »

tepples wrote:If CHR ROM is used, CHR ROM always comes after PRG ROM. With 32 KiB PRG ROM and 8 KiB CHR ROM, your ROM is arranged as follows:
  1. $0000-$000F: Header
  2. $0010-$800F: PRG ROM mapped to CPU $8000-$FFFF
  3. $8010-$A00F: CHR ROM mapped to $0000-$1FFF

Why does rainwarrior's ca65 example have this in his config file memory:

Code: Select all

    HDR:    start = $0000,  size = $0010, type = ro, file = %O, fill = yes, fillval = $00;
    PRG:    start = $8000,  size = $8000, type = ro, file = %O, fill = yes, fillval = $00;
    CHR:    start = $0000,  size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
Doesn't that indicate:
$0000-$000F: Header
$0000-$1FFF: CHR
$8000-$FFFF: PRG

What am I missing here?
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: More questions about ca65 .cfg file

Post by tepples »

The config file states the order in which the memory areas are stored in the output file. This may not necessarily correspond to increasing values of the addresses at which they appear in the address space of the NES CPU or NES PPU. The header, PRG ROM, and CHR ROM are completely separate (or disjoint) address spaces; addresses in PRG ROM and CHR ROM are not comparable (or commensurable). It'd be like saying addresses in the file are "less than" your computer's IP address in some sense. Despite having numerically smaller addresses, the CHR ROM still comes after the PRG ROM in the iNES format.

If you want, you can think of the header as occupying 64-bit addresses $0000000000000000-$000000000000000F, the PRG ROM at $0000000100008000-$000000010000FFFF, and the CHR ROM at $0000000200000000-$0000000200001FFF.
User avatar
battagline
Posts: 152
Joined: Wed Sep 05, 2018 11:13 am
Location: Colorado
Contact:

Re: More questions about ca65 .cfg file

Post by battagline »

I'm still not following. I mean, the iNES format can read from where ever it wants, but somehow ca65 has to be configured to put a chunk of binary data somewhere that iNES is expecting it. I guess what I'm missing is how ca65 knows where to put that data. I assumed that this line:

Code: Select all

    CHR:    start = $0000,  size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
in the .cfg told ca65 where to put the chr data into the file. If not, how does ca65 know where to put that data?

Thanks
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: More questions about ca65 .cfg file

Post by rainwarrior »

The MEMORY blocks are put into the file in the order they're listed. If CHR comes after PRG in the list, that's where it comes in the file too.
User avatar
battagline
Posts: 152
Joined: Wed Sep 05, 2018 11:13 am
Location: Colorado
Contact:

Re: More questions about ca65 .cfg file

Post by battagline »

rainwarrior wrote:The MEMORY blocks are put into the file in the order they're listed. If CHR comes after PRG in the list, that's where it comes in the file too.
Ok, so for every file = %0, that block of memory is going to be put into the file in that order.

That makes sense.

Thanks Everyone
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Post Reply