What do we want in a tutorial?
Moderator: Moderators
Re: What do we want in a tutorial?
C is easier once you want to see what the program is trying to do rather than how. It's just that it's way too slow and memory hungry to be usable on the 6502, at least for a NES game which is intended to perform well.
Re: What do we want in a tutorial?
Re:cc65, coding NES in C
I downloaded Shiru and thefox's cc65 example files, and I noticed that thefox uses makefiles to compile the code. Does cc65 (or ca65) need an external program like 'make' to do a finalcompile compilation?
I downloaded Shiru and thefox's cc65 example files, and I noticed that thefox uses makefiles to compile the code. Does cc65 (or ca65) need an external program like 'make' to do a final
nesdoug.com -- blog/tutorial on programming for the NES
Re: What do we want in a tutorial?
You can mostly just use "cl65", but given the effort that the cc65 suite put into looking like a "real" computer's C compiler suite, a lot of people end up using Makefiles for more complex projects.
Re: What do we want in a tutorial?
In addition, correct use of a makefile avoids A. having to re-run the PNG to CHR converter on all graphics every time you build the program or B. forgetting to manually re-run the PNG to CHR converter when something has in fact changed.
Re: What do we want in a tutorial?
I spent 4+ hours testing out cc65, and concluded that it's junk and nearly incompatible with NES architecture.
I downloaded 3 different versions of cc65, etc. Because I was getting all kinds of error messages, even with Shiru and thefoxs lib files, even editing cfg files. When I finally got it working... I wrote a simple test program that declares two variables, initializes them, adds them, and stores them to the name table...
Initializing them took up about 10 lines of ASM. Adding them over a dozen lines of ASM, and similar with storing to the name table. It doesn't seem to know how to use the registers. All math is 16 bit, even with 8 bit numbers (it just shoves a 0 in the upper byte for the math). New versions of cc65 are incompatible with older versions. Shirus runtime.lib wasn't working with 2 of 3. The standard NES.cfg is all wrong.
And, now I go back to using ASM6.
Edit, I redacted my statement, as using 'unsigned char' does use 8-bit math, and you can write optimized subroutines in ASM.
I downloaded 3 different versions of cc65, etc. Because I was getting all kinds of error messages, even with Shiru and thefoxs lib files, even editing cfg files. When I finally got it working... I wrote a simple test program that declares two variables, initializes them, adds them, and stores them to the name table...
And, now I go back to using ASM6.
Edit, I redacted my statement, as using 'unsigned char' does use 8-bit math, and you can write optimized subroutines in ASM.
Last edited by dougeff on Thu Aug 27, 2015 10:18 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES
- rainwarrior
- Posts: 8732
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: What do we want in a tutorial?
It's entirely compatible with NES architecture.dougeff wrote:I spent 4+ hours testing out cc65, and concluded that it's junk and nearly incompatible with NES architecture.
Use the version of CC65 it was built with, or rebuild the runtime lib with a newer version. It's not very productive to play a game of "is this still compatible?" with the libraries. (Though the problem here may just have been that shiru didn't document which version should be used, or how to rebuild the runtime? This is a problem with shiru's documentation though, not CC65.)I downloaded 3 different versions of cc65, etc. Because I was getting all kinds of error messages, even with Shiru and thefoxs lib files, even editing cfg files.
Variable initialization is just a block copy operation, it would be the same amount of code whether it was 2 variables or 200, so it's reasonably efficient for use at scale.I wrote a simple test program that declares two variables, initializes them, adds them, and stores them to the name table...
Initializing them took up about 10 lines of ASM. Adding them over a dozen lines of ASM, and similar with storing to the name table.
The C language shouldn't know how to use the registers. That's something a runtime library does, not a C language extension. Register manipulation needs to be done in assembly. Shiru's runtime library knows about the registers and has the appropriate functions for manipulating them via C calls.It doesn't seem to know how to use the registers.
CC65 is capable of doing 8 bit math. If you're sure you haven't implicitly converted to int by accident, it's possible that you've run into an unlucky case that is doing it improperly. If it's an error in the compiler you might share the problem code to the mailing lists so that it can be improved. You might be able to get what you want by inserting some explicit casts to unsigned char to combat implicit conversion to int?All math is 16 bit, even with 8 bit numbers (it just shoves a 0 in the upper byte for the math).
The advantage of C is not having to think about the underlying code, though. It's going to be inefficient, this is a given. In the cases where you need efficiency, you can always write that part of your program in assembly, too, it's not like that's been taken away from you.
Yes, you should not use that, or the standard runtime libraries. They are designed for an entirely different purpose than NES game development. If you're using shiru's runtime library, you should use his supplied CFG file with it.The standard NES.cfg is all wrong.
CC65 is very much usable for NES development. Maybe the existing tutorials have some documentation/usability problems, but that's its own issue. You've run into problems, but you can contact the people responsible for those issues to help get them fixed. Maybe you can help the next person who wants to try.
Re: What do we want in a tutorial?
This implicit conversion is mandated by the standard, although admittedly add is one of those operations where you can just forget the higher bits so it should be optimizable. Are optimizations turned on? If so then probably CC65 isn't being clever enough. Also I bet that using += would work around the issue (but then again that's something you shouldn't have to rely on).rainwarrior wrote:CC65 is capable of doing 8 bit math. If you're sure you haven't implicitly converted to int by accident, it's possible that you've run into an unlucky case that is doing it improperly.
- rainwarrior
- Posts: 8732
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: What do we want in a tutorial?
Yeah, it's easy to envision a string of arithmetic operations producing some implicit casts to int that the optimizer just can't keep up with. It's a very weak optimizer.
Again, though, it's C, it's already expected to be inefficient. If the code is correct, what we're talking about is whether you have to do workarounds for some marginal gain. Most of the time there isn't much to gain with this kind of workaround.
My approach is to just code normally until an actual performance problem occurs (e.g. I get slowdown somewhere in my game) before I start looking for tricks to make the compiler more efficient, or rewriting parts in assembly. It doesn't really matter to me if there was some wasted calculation if I'm not exceeding my frame's timing budget yet.
If there's some use case that is common and intuitive, and should be easy to optimize but isn't, though, that kind of stuff is totally worth bringing up on the mailing list as a suggestion for future improvement to the compiler.
Again, though, it's C, it's already expected to be inefficient. If the code is correct, what we're talking about is whether you have to do workarounds for some marginal gain. Most of the time there isn't much to gain with this kind of workaround.
My approach is to just code normally until an actual performance problem occurs (e.g. I get slowdown somewhere in my game) before I start looking for tricks to make the compiler more efficient, or rewriting parts in assembly. It doesn't really matter to me if there was some wasted calculation if I'm not exceeding my frame's timing budget yet.
If there's some use case that is common and intuitive, and should be easy to optimize but isn't, though, that kind of stuff is totally worth bringing up on the mailing list as a suggestion for future improvement to the compiler.
Re: What do we want in a tutorial?
I was declaring them with 'int', because that's what I'm used to doing with small integers.
nesdoug.com -- blog/tutorial on programming for the NES
Re: What do we want in a tutorial?
"int" is required by the C standard to be at least 16 bits.
Re: What do we want in a tutorial?
My philosophy is "technology should just work". When you turn the key in your car, it should start. When you press the back button on a browser, it should go back. And when you create a C environment specifically to function on an 8-bit 6502 processor, it should just do that. I shouldn't have to spend 4 hours trying to configure this or get the runtime library to do that, or trick the compiler into forcing a variable into 8-bits. And software updates should be backwards compatible. Anyway, I'm done bitching.
I was just trying to see if it would be easier to learn NES programming in C. I think the answer is 'no'. You still need to work with ASM at some point...for your start up code...for optimization when updating the PPU...for debugging the game later in FCEUX...etc.
I think I'll try ca65 next (ie, entirely in ASM), but I'll spare you my frustrated commentary if I can't get it to work right away.
I was just trying to see if it would be easier to learn NES programming in C. I think the answer is 'no'. You still need to work with ASM at some point...for your start up code...for optimization when updating the PPU...for debugging the game later in FCEUX...etc.
I think I'll try ca65 next (ie, entirely in ASM), but I'll spare you my frustrated commentary if I can't get it to work right away.
nesdoug.com -- blog/tutorial on programming for the NES
Re: What do we want in a tutorial?
unsigned char -- and optimize -- seemed to produce much more efficient code.
nesdoug.com -- blog/tutorial on programming for the NES
- mikejmoffitt
- Posts: 1353
- Joined: Sun May 27, 2012 8:43 pm
Re: What do we want in a tutorial?
For that I'd recommend a types.h with some typedefs to save time:
So on and so forth.
Code: Select all
typedef unsigned char u8;
typedef signed char s8;
Re: What do we want in a tutorial?
But huh, int isn't the type meant for small integers, short int is (and indeed short int is 8-bit on many old systems, no idea if that's what happens here though).dougeff wrote:I was declaring them with 'int', because that's what I'm used to doing with small integers.
EDIT: tt'd because why not
Re: What do we want in a tutorial?
Do these systems predate the C standard? Because in the standard, short int is at least -32767 to 32767, which means at least 16-bit.Sik wrote:and indeed short int is 8-bit on many old systems