Minimal NES example using ca65

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

User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: Minimal NES example using ca65

Post by DRW »

I have a suggestion concerning your config file:

The segment that you call "RAM" should actually be called "BSS".

The reason is: When you use the C compiler, it includes segments into its code by itself. And for variables that are not in the zeropage, it uses "BSS".
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Minimal NES example using ca65

Post by rainwarrior »

Yeah, sure. It doesn't make a functional difference, but it is the default name for the "main" RAM segment in cc65, sort of. I've changed it.

I wasn't concerned about compatibility with C configs for this example, since it's not a C example at all, but if you want an example cc65+C project to look at, here's one I made a while back that plays an old jazz tune: coltrane.nes, coltrane_src.zip
User avatar
samophlange
Posts: 50
Joined: Sun Apr 08, 2018 11:45 pm
Location: Southern California

Re: Minimal NES example using ca65

Post by samophlange »

I am wrapping up my first "Pong" project and I'm looking at this example so I can start my next project using ca65. One thing I liked about compiling with NESASM3 is that it would list out the "USED/FREE" bytes of each bank. Is there a way of getting something equivalent with ca65?

Having the python script to generate symbols for FCEUX is a huge bonus, thanks for including that!

edit: Just realized that compiling this project with ca65 generates a .DBG file which the Mesen emulator appears to be able to use to get symbols and whatnot, so that's another option.
Last edited by samophlange on Sat May 19, 2018 4:26 pm, edited 1 time in total.
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: Minimal NES example using ca65

Post by DRW »

samophlange wrote:One thing I liked about compiling with NESASM3 is that it would list out the "USED/FREE" bytes of each bank. Is there a way of getting something equivalent with ca65?
I don't know how to do this with ca65, but Shiru's NES Space Checker shows you a nice graphical representation of empty bytes (actually: bytes that have the value 0 or 255, depending on which one you choose) in any NES ROM:

https://shiru.untergrund.net/files/nessp.zip
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Minimal NES example using ca65

Post by tokumaru »

samophlange wrote:One thing I liked about compiling with NESASM3 is that it would list out the "USED/FREE" bytes of each bank. Is there a way of getting something equivalent with ca65?
In the .CFG file you can put "define = yes" in the segment definitions to generate symbols containing their size, which you can subtract from the total size to see how much space you have left.

Since this number is not a constant during assembly time, you can't easily print it using .out. You can either write it to a file in binary form using .word or .dword and read it using an hex editor, or use a macro to convert it into a string.

For example, here's what the segment definitions for my first PRG-ROM bank look like (the second one is aligned to the end of the bank, so I can reliably put the CPU vectors, reset stub and other stuff that needs to be in the same location in multiple banks):

Code: Select all

PROGRAM_ROM_LOWER_00: load = PROGRAM_ROM_LOWER_00, type = ro, define = yes;
PROGRAM_ROM_UPPER_00: load = PROGRAM_ROM_UPPER_LOAD_00, run = PROGRAM_ROM_UPPER_RUN_00, type = ro, define = yes;
Then, I have a macro that uses the SIZE symbols to calculate how much space I have left:

Code: Select all

;writes the amount of space left in a program ROM bank of the specified size to the debug file
.macro Assembler_DEBUG_BANK _Bank, _Size
		.import .ident(.sprintf("__PROGRAM_ROM_LOWER_%02d_SIZE__", _Bank))
		.import .ident(.sprintf("__PROGRAM_ROM_UPPER_%02d_SIZE__", _Bank))
		Assembler_START_DEBUG
			.byte .sprintf("Bytes left in bank %02d: ", _Bank)
			Assembler_WRITE_NUMBER (_Size) - .ident(.sprintf("__PROGRAM_ROM_LOWER_%02d_SIZE__", _Bank)) - .ident(.sprintf("__PROGRAM_ROM_UPPER_%02d_SIZE__", _Bank)), 10, 5
			.byte $0d, $0a
		Assembler_END_DEBUG
.endmacro
It makes use of 2 other macros to output the information to a debug file (anything in the DEBUG segment goes to a file named debug.txt):

Code: Select all

;starts a block of debug information
.macro Assembler_START_DEBUG
	.pushseg
	.segment "DEBUG"
.endmacro

;ends a block of debug information
.macro Assembler_END_DEBUG
	.popseg
.endmacro
And this is the macro that converts the number into an ASCII string:

Code: Select all

;writes the specified number of places of a non-constant number in the specified base to the active segment
.macro Assembler_WRITE_NUMBER _Number, _Base, _Places, _Divisor
	.ifblank _Divisor
		Assembler_WRITE_NUMBER _Number, _Base, _Places, 1
	.else
		.if _Places > 0
			.local __Digit
			__Digit = (_Number) / (_Divisor) .mod (_Base)
			Assembler_WRITE_NUMBER _Number, _Base, (_Places) - 1, (_Divisor) * (_Base)
			.lobytes __Digit + '0' * (__Digit < 10) + ('A' - 10) * (__Digit > 9)
		.endif
	.endif
.endmacro
Then, at the end of the .BAT file I use for assembling, I use type debug.txt to display whatever debug.txt contains, so I can see the amount of free space every time I assemble.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Minimal NES example using ca65

Post by unregistered »

At the bottom of Mesen's debug window it says PRG analysis: 4.15% (Code: 1.10%, Data: 3.04%, Unknown: 95.85%). Not sure how accurate that is... maybe it only represents the current banks being used... but, still, it sounds really unfair, to me. :)

edit: Maybe it counts bytes until the first .pad (00 byte) and then assumes the rest of the bank is "Unknown"? :?


final edit: rainwarrior, sorry to state my confusion in your thread about an unrelated topic. :oops:
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Minimal NES example using ca65

Post by koitsu »

unregistered wrote:At the bottom of Mesen's debug window it says PRG analysis: 4.15% (Code: 1.10%, Data: 3.04%, Unknown: 95.85%). Not sure how accurate that is... maybe it only represents the current banks being used... but, still, it sounds really unfair, to me. :)
FCEUX and Mesen both have this capability. They're only going to know what's code vs. data as you play the game (meaning the percentages for code and data will grow as you play the game more). If there are areas of the ROM that can't be accessed because, say, the code never reads from them or they're never used in CHR bank swapping, then they (obviously) will stay "unknown". I cover this in this post: viewtopic.php?p=216343#p216343
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Minimal NES example using ca65

Post by rainwarrior »

ca65, or rather ld65 can generate a "map" file which is very helpful for gauging how much space you have left. This example does so, you just have to look at the generated file. (-m)

It doesn't specifically say how many bytes are left, but will give you the "end" address of a segment, which is one step removed from bytes left, but if you just need a coarse estimate it's good enough to know that your PRG segment ended (and empty space began) at e.g. $E123.
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: Minimal NES example using ca65

Post by calima »

I use od65. "od65 -S *.o | grep mysegment" and then you can add the sizes with your favorite way.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Minimal NES example using ca65

Post by unregistered »

koitsu wrote:
unregistered wrote:At the bottom of Mesen's debug window it says PRG analysis: 4.15% (Code: 1.10%, Data: 3.04%, Unknown: 95.85%). Not sure how accurate that is... maybe it only represents the current banks being used... but, still, it sounds really unfair, to me. :)
FCEUX and Mesen both have this capability. They're only going to know what's code vs. data as you play the game (meaning the percentages for code and data will grow as you play the game more). If there are areas of the ROM that can't be accessed because, say, the code never reads from them or they're never used in CHR bank swapping, then they (obviously) will stay "unknown". I cover this in this post: viewtopic.php?p=216343#p216343
Thank you koitsu! :D
Post Reply