Hi! I'm new here, this is my first post.
I'm not too good at Assembler, which is the language in which almost all NES programming tutorials seem to be.
So I'd like to develop in C.
I've downloaded the CC65 and built the Hello World app.
It even runs in my MP4 player ( Wiiiiiiiiiiiiii
)
Ok, so, I know that as I already know C, I could take tutorials or references, and knowing memory addresses, interrupts and ports, It should be easy, and I will do that, but, in the meanwhile, if you know some C tutorials, reference, etc. I would preciate it very much!
thanks in advance.
Welcome to the NESDev community
.
Are you looking for C tutorials in general? Not just NES-Specific ones?
Well, one, if you're looking for NES-specific C tutorials, I don't think you'll find any. Maybe someone wrote one about CC65, but I don't know because I don't use that assembler.
And also, if you're looking just for C tutorials about the NES, I really advise against that. Ultimately, the NES processes 6502 code only. CC65 turns C into 6502 (I believe that's what it does). So if you write in C for the NES, it will merely translate it into 6502. So I really really recommend learning 6502. There aren't that many instructions, and once you get the hang of it, it's not so hard to work with.
You might want to look at Nestech; it's a really informative document about the NES's registers. There are several 6502 tutorials on the internet, but one that really got me going was GBAGuy's tutorials which are NES specific. I warn you, they are not so accurate. They will really get you going I think, though.
It is possible to make C code for the NES with CC65 (wich makes asm code which itself can be assembled with CA65), but I haven't explored much of it yet. It seems the output is very unoptimal unless you do lot of tricks. And as long you're doing lots of trick, that will make the code less portable, you can then directly write in assembly. Oh the libraries that they have seems to suck too, and there is so many files splaterred arround it's a real headache, and making the task to recompile them hard.
Even if you're going to code everything in C, you will need to recompile assembly libraries and to write assembly interrupt code (and maybe timed code) so you should at least know the basics of assembly.
Maybe someone will one day come up with a lot of C libraries (and a very optimised compiler ?) that allow you do directly code video games, but that's not the case yet.
Thanks, yes I actually want C tutorials or examples specific to building NES apps and games.
I know, CC65 just translates C code into asm which then I compile with ca65, but I'm really comfortable with this and not needing to even look at the asm code
Ok, ifI really have to, I will, but I don't think programming in C for the NES will make the code so unefficient that can't run.
What I want to learn is specific things like making the main loop, waiting for vertical retrace, and memory addresses or whatever, to write to in order to draw things in the screen and make sounds, and to read from to capture the input.
Eventually I will end using a lot of asm{} blocks into C, but I really think I will save time writing flow control and statements in C rather than revisiting my long lost knowledge of assembler.
Thanks anyway!
You'd be surprised at what's inefficient on the NES. It really doesn't take a lot for your game to run really really slow. Even making a program that displays a scrollable, compressed RPG map like Final Fantasy is hard to do without having code spill over to run at < 60 FPS (games on the NES really should run at 60 FPS).
I see where you're coming from wanting to code with C, because it's a lot easier and intuitive. But the problem with coding in C is you'll want to do something like this:
B = A / 13
And that may take a very long time to execute. Also, the concept of local variables that act like a stack is great, but hard to execute on the NES without taking up lots of time. There is the hardware stack, but I don't think CC65 uses this.
If you plan on counting cycles (which every NES programmer will at one point realize they should do), you should know 6502. If we, who program in 6502, are nickel and diming for cycles, you can guarantee that the C code is going to cause you timing issues.
This isn't really true for all cases, like simple maze games, but for something like a platformer with lots of logic going on, you will at least want to know 6502 so you can look at the code it assembles so you can optimize it.
CC65 is usable, but not the NES libraries last time I looked at them, need to be rewritten. They might work on some emulators, but not the real system.
The compiler is fine, if you're prepared to write all your own functions, then you could make a fully working program. Or someone needs to fix the libraries. I tried once, it seemed like it'd be simple, but I just didn't have enough interest in it myself.
I believe NESHLA is partially C oriented. I don't know much about it, though.
Looks interesting!
Celius wrote:
This isn't really true for all cases, like simple maze games, but for something like a platformer with lots of logic going on, you will at least want to know 6502 so you can look at the code it assembles so you can optimize it.
Maybe he's planning on overclocking his NES 8X?
If you want to program on a system with a similar CPU and in C, I heard that PC-Engine/Turbografx 16 can be programmed in C and it has a much faster CPU.
Well NESHLA looked very interesting but its development seems to be lost in time, and there is no good tutorial or sample code to work with.
The first thing I wanna do, is a metronome application.
A metronome is the little apparatus that ticks at regular intervals so you can play your music instrument in tempo.
I have a MP4 player ( PMP ) which emulates NES, and that's why I wanna program for the NES, to use my PMP as a metronome.
For this program I don't need very good performance as it is not a game.
Just need to grab the joystick input and make some sounds at some times for which I need to measure time.
It would be nice to use sprites, but I can use characters instead, which I already managed to do with cc65 and conio.h functions.
Unfortunately, the time() function doesn't work, so I don't know how to measure time with cc65.
If anyone can help me with this, I'll be very thankful.
I'd set up a counter in RAM, have the NMI handler add 1 to the counter, turn on NMI at the start of vertical blanking (in $2000) and then treat 60 ticks of the counter as one second.
Quote:
If you want to program on a system with a similar CPU and in C, I heard that PC-Engine/Turbografx 16 can be programmed in C and it has a much faster CPU.
Hey, the NES *can* be programmed in C.
If one dares to rewrite the libraries, and make them not ISO compatible but more optimised, and write C code with optimisaiton in mind using bytes for most variables, and using a lot of global variables to avoid slow acess to the stack, I bet you can write something that can be almost as efficient as ASM code. If you want to do B = A / 13, it will be a headache to do in assembly (altough not that complicated) as you have to do a routine that does the division in column with a loop and so on. If you use CC65, it will do it for you and that's a great thing.
Also, it would be awesome if CC65 could be told to use indexed adressing ($700,X) for the stack instead of indirect ([stack],Y). It would limit the stack to 256 bytes, but it would fast things up A LOT. If I ever get good enough I would write a C compiler that does that, but then I'd have to write an assembler too and I'm sure not skilled enough to do that.
Eventually since I plan to write stategy games for the NES it would be great if they could be written in C, because that would make the AI and stuff like that simpler to mantain.
Well, despite asm freaks frightening me not to code in C for the NES
I'm doing it anyway.
I'm writing a small library for cc65 to ease the NES dev, who knows, maybe you can write a game in c with decent fps.
So far I made a joypad reading function, and started to make some random sounds... does anyone know a simple tutorial or doc with how to produce sound in the NES? I've read Brad Taylor's docs but I find all the technical sound jargon a little hard to understand.
Tetramino 0.33 has a simplistic sound effect engine in "src/sound.s". If you want it explained, I can add more comments.
I would love to, where can I get Tetramino?
Thanks!
Petruza wrote:
I'm writing a small library for cc65 to ease the NES dev, who knows, maybe you can write a game in c with decent fps.
It really depends on the type of the game. If you mean a platformer with fast scrolling and many active entities, you probably can't do it in C. A simpler game with a static camera and a controlled number of entities can probably be done in C if a proper library in ASM is available.
Petruza wrote:
where can I get Tetramino?
About Tetramino, check tepples' profile for a link to his page.
Hi, I wrote this test program, which will be a metronome.
It makes a beep every 3rd of a second.
I'm relying on vertical retrace being 60hz because it's NTSC, as I don't know any other way to measure time in the NES. ( do you? )
It works fine in emulators, but it hangs my PMP after some beeps.
Am I doing something wrong or is just my PMP that is buggy?
It runs most of commercial games very well, although others crash.
PS: I figuerd out how to make sounds somewhat randomly, but it works.
Code:
#include <nes.h>
#define addr(_addr) (*(unsigned char*) (_addr))
void main()
{
unsigned char a = 0;
addr(0x4015) = 1; // init sound
addr(0x4001) = 0;
while(1)
{
waitvblank();
++a;
if( a == 20 )
{
a = 0;
addr(0x4003) = 2; // make a beep
}
}
}
I think you should initialize registers $4000 and $4002. $4002 holds the 8 least significant bits of the pitch value, and $4000 determines whether or not it sweeps up, the volume, etc. I don't actually know much about hardware volume decay, because I do volume decay manually to have more control over it. I would just advise against assuming $4000 or $4002 have any value, so just initialize them.
Also, it looks like your code is waiting for Vblank in an infinite loop. It would be best to put the code that's executed once every frame in the NMI routine, which is fired up every Vblank.
We'd have to see the ROM or assembly. But if your PMP crashes with some games, that doesn't sound very promising.
Celius: I don't know how to use the NMI routine, can it be accessed in c?
Or is it like a callback or something only feasible in asm?
Memblers: It's strange, but I added a clrscr() and cprintf() calls, and now it doesn't crash.
NMI should be a function in the NES library.
The NMI is an interrupt fired every Vblank, and the starting address of the NMI is located at $FFFA (I think) in the fixed bank. If you're doing just an NROM 16 or 32k PRG game, the address for the NMI will be located just at $FFFA. So if bit 7 of $2000 is set, the NMI will be fired every Vblank. Otherwise if bit 7 of $2000 is 0 then it won't fire.
I don't know how you set that up in C though. Just set it up so $FFFA/$FFFB of the fixed bank holds the address of the start of the NMI routine. Then make sure you end the NMI routine with RTI. Though I don't know how you say "RTI" in C, unless you can just type "RTI".
I think you should be able to access it in C. I don't see why you wouldn't be able to. If you can't, then you're missing one of the most (if not the most) essential things in programming the NES.
Celius wrote:
Then make sure you end the NMI routine with RTI. Though I don't know how you say "RTI" in C, unless you can just type "RTI".
In some dialects of C, you can add a keyword before the definition of a function to get it to generate different calling conventions. For example, a compiler might generate RTI instead of RTS at the end of a function declared this way:
Code:
__interrupt__ void isr() {
/* blah */
}
I don't know whether CC65 implements anything like this, but it does have inline assembly as
one of its extensions.
Still, I'd recommend writing your ISRs in assembly language. NMI in particular only
has to increment a variable and then return.