It is currently Tue Nov 20, 2018 8:58 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sun Nov 04, 2018 6:59 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
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:
file = ""
and
Code:
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:
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


Top
 Profile  
 
PostPosted: Sun Nov 04, 2018 7:20 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3584
Location: Indianapolis
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.


Top
 Profile  
 
PostPosted: Sun Nov 04, 2018 7:38 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3694
Location: Mountain View, CA
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.


Top
 Profile  
 
PostPosted: Mon Nov 05, 2018 8:58 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
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


Top
 Profile  
 
PostPosted: Mon Nov 05, 2018 9:16 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20791
Location: NE Indiana, USA (NTSC)
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


Top
 Profile  
 
PostPosted: Mon Nov 05, 2018 10:51 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
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:
    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


Top
 Profile  
 
PostPosted: Mon Nov 05, 2018 11:17 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20791
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Mon Nov 05, 2018 3:37 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
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:
    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


Top
 Profile  
 
PostPosted: Mon Nov 05, 2018 3:58 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6961
Location: Canada
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.


Top
 Profile  
 
PostPosted: Mon Nov 05, 2018 4:18 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Nicole and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group