Live data from Hacker News

How to program an NES game in C

nesdoug.com

11–20 of 70 posts

Re: How to program an NES game in C

#11
post #3

IMHO a 6502 is too limited to be effectively programmed in C; even this part of the article gives all the limitations: https://nesdoug.com/2015/11/15/2-how-cc65-works/ With this important note: "clean unaltered C code will compile into very slow code that takes up too much of the limited memory space." In other words, "C" written for such a CPU will be in a vastly different style from more "normal" C, so that it migh…

I feel like handling ROM banking would be the most challenging part of coding in C. You have to swap portions of your program in and out constantly (unless you manage to fit it all in a single bank). It seems hard to abstract that efficiently from a high level language. I heard there were C compilers for the Game Boy as well but as far I know they were never widely used.

It's just linker magic and tagging sections on everything.

They had the same features up until at least Xbox 360; they're just called 'overlays' on non execute from ROM systems. It doesn't really take an esoteric compiler or environment.

Re: How to program an NES game in C

#12
post #3

Earlier quoted context omitted.

I feel like handling ROM banking would be the most challenging part of coding in C. You have to swap portions of your program in and out constantly (unless you manage to fit it all in a single bank). It seems hard to abstract that efficiently from a high level language. I heard there were C compilers for the Game Boy as well but as far I know they were never widely used.

Yeah, C generally assumes a 'linear' memory space, so memory banks don't really fit into it extremely well. That said, with a little work you could likely coax the linker into doing a lot of the work for you. You would have to be a little careful though, as code in different banks could not effectively call each-other directly, even though the compiler would likely not yell at you. But you could just organize your co…

My impression is that the banking was more often used for graphics rather than logic.

Re: How to program an NES game in C

#13
post #5

Earlier quoted context omitted.

Even a 8080 would be problematic, given near and far segments and the memory tricks we used to do to fit everything into the available memory. Then it also depends on the IO and video architecture. The PC ones were a bit of a pain.

No segments in the 8080: https://en.wikipedia.org/wiki/Intel_8080#Programming_model

I mixed it up with 8086.

Re: How to program an NES game in C

#14
post #5

Earlier quoted context omitted.

Even a 8080 would be problematic, given near and far segments and the memory tricks we used to do to fit everything into the available memory. Then it also depends on the IO and video architecture. The PC ones were a bit of a pain.

A 8080 has a linear 64K address space, like the 8085 and the Z80. Perhaps you were thinking of 8086? In any case, 64K address space is not the real limiter with a 6502 --- it's other things, like the tiny number of registers, relative shortage of 16-bit addressing modes, and fixed(!) 256-byte stack which make it difficult to program in C. Even the 6800, with its 16-bit index and stack pointer registers, would be easi…

Yeah, I thought 8086 also had segments, did not bother to cross-check it.

Re: How to program an NES game in C

#15

Yeah, making an NES game is on my bucket list. I'm very new at (complex) programming, but I think I might just do it in assembly. If you're going to run a marathon, why not actually do a triathlon?

Your marathon/triathlon comparison, as someone who has done them, makes little sense.

Re: How to program an NES game in C

#16

Earlier quoted context omitted.

Yeah, C generally assumes a 'linear' memory space, so memory banks don't really fit into it extremely well. That said, with a little work you could likely coax the linker into doing a lot of the work for you. You would have to be a little careful though, as code in different banks could not effectively call each-other directly, even though the compiler would likely not yell at you. But you could just organize your co…

My impression is that the banking was more often used for graphics rather than logic.

It's used for both. Take for instance Super Mario Bros 3, different banks holds different data for the various enemies, and the same banks also contains the subroutines of logic for those enemies.

That's why, even if you hacked so that Goomba's death behavior should point to the same as that of a Drybones, it would fail as the subroutine for that behavior isn't in the same bank as the Goomba.

Re: How to program an NES game in C

#17
post #3

IMHO a 6502 is too limited to be effectively programmed in C; even this part of the article gives all the limitations: https://nesdoug.com/2015/11/15/2-how-cc65-works/ With this important note: "clean unaltered C code will compile into very slow code that takes up too much of the limited memory space." In other words, "C" written for such a CPU will be in a vastly different style from more "normal" C, so that it migh…

I feel like handling ROM banking would be the most challenging part of coding in C. You have to swap portions of your program in and out constantly (unless you manage to fit it all in a single bank). It seems hard to abstract that efficiently from a high level language. I heard there were C compilers for the Game Boy as well but as far I know they were never widely used.

C programmers used to handle banks of EMS RAM, on the PC. Ditto with program overlays. I'd assume that NES ROM banks could be handled similarly.

Re: How to program an NES game in C

#18

IMHO a 6502 is too limited to be effectively programmed in C; even this part of the article gives all the limitations: https://nesdoug.com/2015/11/15/2-how-cc65-works/ With this important note: "clean unaltered C code will compile into very slow code that takes up too much of the limited memory space." In other words, "C" written for such a CPU will be in a vastly different style from more "normal" C, so that it migh…

From that page, "use ++g instead of g++ (it’s faster)"

I've seen people say this a repeatedly when talking about "embedded" environments, but never understood why - won't it end up compiling to the same thing either way?

Re: How to program an NES game in C

#19

Yeah, making an NES game is on my bucket list. I'm very new at (complex) programming, but I think I might just do it in assembly. If you're going to run a marathon, why not actually do a triathlon?

I'd start with https://en.m.wikipedia.org/wiki/CHIP-8 first. It won't take too long, and you'll be much better prepared for nes.

Re: How to program an NES game in C

#20

IMHO a 6502 is too limited to be effectively programmed in C; even this part of the article gives all the limitations: https://nesdoug.com/2015/11/15/2-how-cc65-works/ With this important note: "clean unaltered C code will compile into very slow code that takes up too much of the limited memory space." In other words, "C" written for such a CPU will be in a vastly different style from more "normal" C, so that it migh…

From that page, "use ++g instead of g++ (it’s faster)" I've seen people say this a repeatedly when talking about "embedded" environments, but never understood why - won't it end up compiling to the same thing either way?

In a moderately sophisticated compiler, yes they should be the same thing.

The difference in the two is that the latter has to produce the original value, presumably by keeping it in a temporary variable. A compiler which looks at all the code in a function when optimising, rather than just blindly emitting code for each individual operation, will see that the value is not needed, and delete the temporary.

I guess cc65 is a bit more basic. Compilers for more unusual embedded environments are often a bit more basic, hence the general advice for the embedded context.

I think you could probably fix the compiler for this trivial case in the time it takes you to write down the advice though.

Post reply on HN