Looking to make some NES games

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Looking to make some NES games
by on (#41272)
I've wanted to make nes games for about a year and a half now, about as long as I've known about emulators. I have very limited experience with C coding and Visual Basics.

Where is a good starting point for making games in 6502?

by on (#41273)
For people in your situation (programming experience with something other than assembly) I usually recommend reading a lot about the 6502 until you get a grasp on how it works. This is a good starting pint.

While you study the 6502, you can use Michal Kowalski's 6502 simulator to code a few simple routines (such as multiplication and division) to make sure you understood things correctly and to study instructions don't yet understand completely. With this simulator you can study, among other things, how the flags work (flags can be confusing to newbies).

Once you have a basic understanding of 6502 it's time to read about the NES. It's no use looking into that before you know some assembly because nothing will make sense. It is a good idea though to use an emulator with strong debugging features (such as FCEUXD) to study what the PPU can do. Abuse the tile/palette viewer and the name table viewer and observe how things change in response to input. That you can do before learning 6502.

When you are ready, read all the NES docs you can find. The main NESDEV page and the wiki should have enough info. Once you haver an idea of how the PPU works, you can try using a good tutorial (hopefully someone can point one out!) and make your first demos.

by on (#41275)
Thanks for the info, I will start looking into that tongiht.

by on (#41276)
For 6502 assembly, there are few (if any) online tutorials that can compare to what's available in books. 6502 has been very widely-used since the '70s. It's a good idea to a invest a few bucks into an old book (check ebay and maybe amazon).

Here's a short, yet complete 6502 guide:
http://www.geocities.com/oneelkruns/asm1step.html

by on (#41323)
I've been using nesasm to compile a few test codes out and it seems to be working ok. I'm just wondering what programs should I use for compiling, making music, mappers etc.

by on (#41326)
For compiling it'll be a never ending debate, as it seems no assembler has an ideal all-features list. CA65 has a ton of features but is complicated to use for newbie because it needs extra files for linking, so it WLA-DX.

There is simpler assembler, but they may not have all features you'd want to have like align code, povisions for bankswitching code, relocatable code (copied to RAM before executed), have the same piece of code identical many times in the ROM so that it's immuned to bankswitching, etc...

Personally I can tell WLA-DX is very good but it's annoying you have to type .w about almost every opcode who use 16-bit argument, and it doesn't really have provisions for relocatable code. Also, it's a shame you can not align RAM sections, only ROM section can get aligned for some reason. Aside of that it's a great assembler/linker. The author used to be active and to answer all question and bug reports, which was a very good thing, but that's not the case any longer. Finally if you switch to SNESdev, GBdev, or anything like that you can still use the corresponding WLA-DX which is cool.

For making music everyone here will recommand Nerdtracker 2 which is an olg sluggish and terribly glitchy music tracker, and personally I recommand writing your own. I love writing music engines, and having to place music with .db statements is not as bad as using Nerdtracker's terrible interface.
There is other trackers arround, but personally I overall don't quite like trackers, that's too limited.

by on (#41328)
I use TASM (what the TI83 scene used for the Z80, also supports 6502), and Famitracker. But I couldn't get famitracker player's code to compile, so I just moved my program origin forward and included the binary.

by on (#41358)
NESASM is an OK assembler, but it's infamous for non-intuitive error messages (view the listing), and a few non-standard things (like making indirect addressing use [] instead of ()), and forced 8kB PRG banking. If it doesn't limit you yet, there's nothing wrong with using it.

YY-CHR and Tile Molester are a couple of nice tile editors, I use both those.

Get a hex editor. I use Frhed, and it's free.

For music, as a Nerdtracker user for 11? years, I'd recommend Famitracker. NT2 hasn't been updated since 2000 or so. FT has a more flexible instrument editor. A lot can be done with NT2 though, it's a real miracle program (and this site wouldn't have existed without it).

by on (#41364)
I like playing with Famitracker, but how useful is it for putting music into a game? I've seen tutorials for throwing together a quick program that just plays music for the chiptune sceners, but does it produce data efficient enough to use in a time critical environment? Or does its output not matter?

by on (#41381)
Quote:
but does it produce data efficient enough to use in a time critical environment?

Likely not. I use a format which uses one byte per note while still being flexible, and most existing trackers or music programms doesn't reach that level. Also I can come with more than one effect at a time, which trackers can't do. Finally it's possible to make channels not looping at the same time (Final Fantasy 5 does this in at least 3 songs) or to have triplets, all of this is not possible with trackers.

Quote:
NESASM is an OK assembler, but it's infamous for non-intuitive error messages (view the listing), and a few non-standard things (like making indirect addressing use [] instead of ()), and forced 8kB PRG banking. If it doesn't limit you yet, there's nothing wrong with using it.

Yeah, most assembler use [] because () are reserved for math priorities. But WLA-DX can optionally swap parenthesis so that [] are for math priorities and () for indirect adressing.

by on (#41394)
Bregalad wrote:
Yeah, most assembler use [] because () are reserved for math priorities.


Huh?

() is the standard syntax in pretty much all the 6502 documentation I've ever seen, and is commonly supported in most assemblers, as well as being the output of virtually all disassemblers and debuggers.

In fact I'm reasonably sure that the exact opposite is true. Most 65xx series assemblers use () for indirection because [] is used for long indirection (see 65c816).

And yeah -- this is one of the reasons I don't like nesasm. [] for indirection = blech.

by on (#41400)
I've always used [] for indirection. The () noation dates form the '70s, and that before common assembler had math pre-processor (I assume, I might be completely wrong).

Altough it's true that an assembler can detect if an expression is surrounded by () and have no math arround it it means indirection, but the leads confusion.

lda (3*4+12),X would mean using direct adressing (parenthesis are useless, but not an error)
lda (3*4+12),Y would be ambigus. Is it math parenthesis (useless) or indirection parenthesis ? Most likely it's the second because there is no point in putting parenthesis, but well...

In WLA (and I guess NESasm too), it makes it clear in the doccumentation that () are for math and [] for indirection, but they can be optionally inverted.

Anyway I don't think either way makes that much difference. A '[' it to a '(' what a 'Z' is to a 'z' if you see what I mean. The only real consern that comes into situation when comparing assembler is their features, such details shouldn't bother anyone who is at leastt *a little* open minded.

by on (#41403)
Bregalad wrote:
I've always used [] for indirection.


Could this be because you started with assemblers like nesasm that have funky syntax? I'm willing to bet that's why. Which is another reason why I don't like nesasm for this: it encourages people to fall into nonstandard practices.

My first introduction to 6502 came when I made my first NSF player, and in all documentation I read, in other sources I checked, and debuggers and trace logs I examined... not once did I ever see any indication that [] was for indirection.

This was my original point, actually. You said that "most" assemblers use [] for indirection, yet so far you've only listed two. I can list two that don't (ca65, x816) and can link you to countless other programs (debuggers, tracers, disassemblers) that don't, as well as page after page of documentation that don't.

Quote:
Altough it's true that an assembler can detect if an expression is surrounded by () and have no math arround it it means indirection, but the leads confusion.

[snip]

lda (3*4+12),Y would be ambigus. Is it math parenthesis (useless) or indirection parenthesis ? Most likely it's the second because there is no point in putting parenthesis, but well...


There's no perfect solution to this problem. But this is a somewhat unrealistic and not really that confusing. Nobody really encases entire expressions in parenthesis because there's no point (or at least, nobody should). Like you say, math parenthesis here is useless.

And this is the only way there could be this confusion. Either parenthesis are totally useless, or they're indirection. So the simple way to avoid this confusion is just to not have totally useless parenthesis.

Quote:
Anyway I don't think either way makes that much difference. A '[' it to a '(' what a 'Z' is to a 'z' if you see what I mean.


It actually kind of does matter, because in other areas of the 65xx series, [] means something else entirely (long indirection)

lda (blah),Y ; normal indirection
lda [blah],Y ; long indirection

Both are legal in 65c816, and they both mean something different. Normal indirection () reads a 2 byte pointer, and long indirection [] reads a 3 byte pointer.

Granted this isn't applicable to the NES. But it enforces my point that () is the standard.

Quote:
The only real consern that comes into situation when comparing assembler is their features, such details shouldn't bother anyone who is at leastt *a little* open minded.


There's a lot to be said for following standards. And there's a lot of grief to be had for needlessly breaking them. () is the standard for indirection pretty much everywhere in the 6502 universe. For an assembler to stubbornly go against the standard for no real reason other than to avoid potential confusion is somewhat silly, and a big turnoff to me, personally.

; is standard for comments
. is standard for assembler directives
() is standard for indirection

Standards are a good thing. Breaking them is bad.

Can you imagine the flack a C compiler would get if it started breaking syntax standards like this? What if a C compiler came out that flipped the functionality of the [] and () symbols? What if a web browser came out that used {} instead of <> for html tags? They'd be burned at the stake... nobody would use them.

by on (#41407)
Quote:
It actually kind of does matter, because in other areas of the 65xx series, [] means something else entirely (long indirection)

lda (blah),Y ; normal indirection

I wasn't aware of this. In that case yeah () makes more sence since you can only adress 64k with the 6502. It would encourage bad practice (?) when moving to 65816 for the SNES.
And WLA doesn't impose the usage of [], in fact it wors with both independantly. You can even write sta (pointer],Y it will comile fine.
The assembler where you could swap both options should have been another (maybe snowbro's discontinued assembler (the Xorcyst if I remember well) I used a couple of times ?)
I just took the habbit of using [] because I saw it at a lot of places.

Quote:
Can you imagine the flack a C compiler would get if it started breaking syntax standards like this? What if a C compiler came out that flipped the functionality of the [] and () symbols? What if a web browser came out that used {} instead of <> for html tags? They'd be burned at the stake... nobody would use them.

Definitely. And for some reason peopl still uses WLA-DX and Nesasm.

But there is a big difference : A C code is supposed to be written no matter who the compiler is. For assembly, unfortunately, there is a LOT of work to port a code so taht it assembles with another assembler. There is no really standard syntax, and things like .org are handled differently with about every assembler on earth.

by on (#41440)
Bregalad wrote:
You can even write sta (pointer],Y it will comile fine.


ugh

*shudders*

Bregalad wrote:
But there is a big difference : A C code is supposed to be written no matter who the compiler is. For assembly, unfortunately, there is a LOT of work to port a code so taht it assembles with another assembler.


Sad but true. Good point.

by on (#41451)
Disch wrote:
Can you imagine the flack a C compiler would get if it started breaking syntax standards like this? What if a C compiler came out that flipped the functionality of the [] and () symbols? What if a web browser came out that used {} instead of <> for html tags? They'd be burned at the stake... nobody would use them.


some funny facts on C :)
http://en.wikipedia.org/wiki/C_trigraph
http://en.wikipedia.org/wiki/Curly_brac ... l_concerns