I've been musing about doing some NES dev lately, and went through the first few of Doug's tutorials. The last time I did any 6502 assembly or used cc65 was ~10 years ago, but it seems to be coming back pretty quick.

Just as an exercise try and understand all the tools and basics, I went back to the first tutorial and tried to rewrite it from scratch. I think I have a handle on everything except for the ld65 .cfg file. Basically my question is, where is the information that tells the cl65 linker to output the memory areas in the right order? I can't figure out how anything in the .cfg file informs the linker to output the iNES header, the PRG ROM, the vector table, and then the CHR ROM in the output file. My experience with other toolchains has always been that the linker already knows the executable or library format you intend to make (because the toolchain was built for your OS, or as a cross-compiler). The possibility of a linker being configurable to output into an arbitrary file(s) has never even occurred to me.

The ld65 docs mentioned that the order of the segment definitions determines their order in their output memory areas, but what determines the order (or existence) of the memory areas in the output file? If I rearrange the memory areas in the .cfg, it still works!? Similarly, how does it know not to write other memory areas to the output? Does it not write the RAM area because the only segment in it is type bss? I'm baffled how there is enough information to create a valid .nes file.

AFAIK, the order of the memory areas in the output file is the order in which they appear in the .cfg file, and the segments in each memory area are also output in the order they appear in the .cfg file.

slembcke wrote:

If I rearrange the memory areas in the .cfg, it still works!?

Depending on what your configuration is, it's possible that a little rearranging won't cause any problems. Some things should definitely result in an invalid ROM though, such as putting the header area after the PRG-ROM area.

Also, when testing this stuff, make sure you're actually using the .cfg file you think you are. This may sound stupid, but I can say that I have edited the wrong .cfg file in the past and it took me a while to realize why my changes weren't doing anything!

Quote:

Similarly, how does it know not to write other memory areas to the output? Does it not write the RAM area because the only segment in it is type bss?

I assume that the type = bssin the segment is indeed inhibiting the output of the memory area to file, but you can explicitly put file = "" in a memory definition if you don't want its contents to be written anywhere.

Similarly, how does it know not to write other memory areas to the output? Does it not write the RAM area because the only segment in it is type bss?

I assume that the type = bssin the segment is indeed inhibiting the output of the memory area to file, but you can explicitly put file = "" in a memory definition if you don't want its contents to be written anywhere.

Not directly. type = bss will stop you from placing any data in that segment (i.e. you can create labels and reservations/.res but any assembled data is an error), but if it's placed in a MEMORY block that is to be emitted, it will still take up space there. That file = "" statement in the MEMORY block is what omits the data from the file.

My makefile didn't reference the .cfg file, so it wasn't *actually* rebuilding anything. I think I spent like 2 hours trying to figure that out. All the other times I made a significant edit to the .cfg file I also changed the main assembly file to reference the new symbols and such. Apparently I never mixed and matched them with the memory area reordering. -_- derp derp derp...

Ok! Time for something fun, like a smooth scrolling... dissembler? Gotta do something to remember what all of those branch mnemonics stand for.

rainwarrior wrote:

tokumaru wrote:

Quote:

Similarly, how does it know not to write other memory areas to the output? Does it not write the RAM area because the only segment in it is type bss?

I assume that the type = bssin the segment is indeed inhibiting the output of the memory area to file, but you can explicitly put file = "" in a memory definition if you don't want its contents to be written anywhere.

Not directly. type = bss will stop you from placing any data in that segment (i.e. you can create labels and reservations/.res but any assembled data is an error), but if it's placed in a MEMORY block that is to be emitted, it will still take up space there. That file = "" statement in the MEMORY block is what omits the data from the file.

Hmm. Ok. I guess that's kinda where I was confused. My memory area defines were at the top of the list (before the header even), and I wasn't using file="". I experimented with this a bit more. If I put the RAM memory area first in the list, and change the BSS segment assigned to it to type 'rw', then it does put a zero byte before the iNES header (I only have one global variable, so I guess that makes sense). Setting 'fill=yes' on it's memory area adds several kb of zeros. Changing it back to 'bss' makes it go away. So I guess that's sort of important to know, but I think I get it now.

Who is online

Users browsing this forum: No registered users and 7 guests

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