Of all the 8/16 bit machines, which one to code for?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Of all the 8/16 bit machines, which one to code for?
by on (#48064)
So I've had some experience writing games in high level languages in OOP (using XNA with C#). I get the basics.

Of all the 8/16 bit machines (C64, NES, SNES, Genesis, TG16, etc) which one would be an easy one to start with?

I've had experience with the 6502 and Atmel AVR writing applications (not games), so I would think I just need to get familiar with the graphics chip.

If I were to use the NES, which PPU doc would you recommend?

by on (#48067)
I say start with NES, CHR-ROM makes things really easy and the NESDev wiki is probably the most complete resource for any console I've seen if only because of the NES' simplicity.

TG16's CPU speed is nice, it has a straight forward sound system but will take more production effort than NES and the two tile formats are a pain.

SNES' and Genesis' sound learning curves are high, otherwise pretty easy and powerful. Only a few new things to learn with the 65816 if you're comfortable with 6502. 68000 code won't be hard to hack out either but it might be hard to think like a 68000 programmer, I know I don't yet.

If you want to you can program reasonably performing games in C for TG16/GEN/SNES though.

by on (#48071)
I have to honestly say PCE/TG16 is the simplest of the SNES/SMS/NES/GEN systems when it comes to configuring and interfacing with the hardware - IMO and from my experience. It's very straight forward. Besides SF2, it has no mappers. All MMU is done via CPU and internal mapping registers. Audio is dead easy. Other than it has two different formats for sprites and tiles, the rest is a breeze for setup and usage. Sprites are straight forward and so is the tilemap. They can be located *anywhere* in vram. The system has 16 subpalettes for tiles and another 16 subpalettes just for sprites. I think the only hard time you'll have is trying to use all 32 subpalettes ;) The other nice thing is that VRAM can be read/write to at *any* time. It also has two independent read and write pointer counters. So reading vram doesn't effect the write counter, etc. No "waiting for vblank" situation either. Sprite table is buffered too, so you can update the table mid display without worry of corrupting the current set. Uhmm... you can embedded graphics as opcodes because the CPU has special/custom instructions for storing an immediate value directly to the video processor data port (st1 #$nn, st2 #$nn, etc). Comes with a 7khz timer for easy sample playback. Every channel can be independently turned into DAC write mode. The CPU is a comfortable 7.16mhz based on Rockwell's 65C02 (has the additional instructions missing from the 65816) and Hudson throw in block transfer instructions similar to the '816. Pros: Simple hardware and easy to learn. Cons: No second BG layer like other 16bit systems. Being a variant of the 65x - optimization for speed makes your code more complex ;)


The Genesis VDP is a bit complex, not as much as the SNES sPPU but still. I really hate the VDP reg command and argument system. It's a pain. The processor on the other hand is very nice to code for. Instruction times are slow, but working the linear address range is great as well as 16bit and 32bit regs. The instruction set is really nice too. Sound processor isn't difficult, but doing any kind of sample playback is (it lacks any sort of interrupt system or a self feeding DAC, so you have to use special timed z80 code to write to the DAC. Tends to produce jitter). FM in general is fairly simple once you understand it. Plus, people have posted patches for instruction sounds and such. Pros: nice processor. Cons: somewhat convoluted VDP usage/interfacing.


NES: Slow CPU relative to the 16bit systems (especially since you need to fit all tilemap updates in vblank area/time). Coming from a 'C02 or higher 65x to the original 6502 is annoying. No PHX,PHY and missing address modes. Mappers aren't hard to use, but there are a lot of 'em. PPU scrolling can be convoluted (having emulated this, I really hate it). The attribute (tile to palette association) is a PITA... IMO. Sound (APU) is easy to use. Pros: Puts hair on your chest. Some people might even think your badass for doing nes dev. Cons: Puts hair on your chest. And removes it from your head. Scrolling and/or FX. Tilemap palette association system <shakes fist>.

SNES: I don't have a lot of experience here, but I can say the sPPU is the most convoluted/complex of all of the systems listed. The CPU has this really funky (read:complex) memory layout.

Quote:
TG16's CPU speed is nice, it has a straight forward sound system but will take more production effort than NES and the two tile formats are a pain.


How would it take more effort? If anything, it would take less effort. The assembler supports importing of PCX files and can divvy them up into sprite format for you.

Quote:
If you want to you can program reasonably performing games in C for TG16/GEN/SNES though.


C on the TG16 (HuC) is horribly hindered by the fact that it treats all ram and constant mapped data as "far data". And its "system" for accessing far data is slower than it would be on a BASIC interpreter. It's something like 150 cycles to access (read/write) 1 byte/word via an array or pointer. LDA $nnnn,x is 5 cycles VS 150+ cycles for a=array[x]; (with the array being located in a static mapped bank of ram).

by on (#48078)
tomaitheous wrote:
How would it take more effort? If anything, it would take less effort. The assembler supports importing of PCX files and can divvy them up into sprite format for you.

What I mean is that more powerful hardware takes more effort to make use of, especially in the case of PCE where the PSG has a large emphasis on programability. You just have to develop more artistic content than you would on the NES, same goes for the increased color depth. Two tile formats isn't "hard" but I find it annoying, it means less reuse, memory wasting or time wasting for conversion.

HuC may be bad but there's still CC65 and I presume other compilers, granted they won't support all the 6280 instructions and you'll have to manually manage memory but I think it's doable.

by on (#48085)
Quote:
HuC may be bad but there's still CC65 and I presume other compilers, granted they won't support all the 6280 instructions and you'll have to manually manage memory but I think it's doable.


MagicKit (aka NESASM to most people here) also includes as TG assembler (PCEAS) among other things. And WLA-DX can also be used (wla-huc6280).

IIRC, there's some initialization code required on the TG to set up the hardware. Of course, if you're using some pre-made "dev kit" like MagicKit or HuC then you don't need to know any of that - but if you're coding something from scratch then you need to learn that stuff.

Quote:
Sound processor isn't difficult, but doing any kind of sample playback is (it lacks any sort of interrupt system or a self feeding DAC, so you have to use special timed z80 code to write to the DAC. Tends to produce jitter). FM in general is fairly simple once you understand it.


Yes the lack of a timer IRQ is very annoying. But except for PCM playback it's very easy to interface with both the YM2612 and the SN79489, as long as you know some Z80 assembly (sure you can control them from the 68k as well, but if you're coding a game you probably don't want to waste main CPU cycles on sound processing). There are a lot more settings for the FM channels compared to, say, making sounds with the 2a03. But there's a lot of information available on the YM2612 for those interested: less accurate (but easier to read). more accurate.

by on (#48089)
Quote:
IIRC, there's some initialization code required on the TG to set up the hardware. Of course, if you're using some pre-made "dev kit" like MagicKit or HuC then you don't need to know any of that - but if you're coding something from scratch then you need to learn that stuff.


True, but it's relatively small and simple. The Mkit docs even give you all the VDC reg numbers for the default 256x240 res. I use PCEAS from Magickit, but write all my own library code. Mkit's lib is too bloated and restrictive.




Quote:
Yes the lack of a timer IRQ is very annoying. But except for PCM playback it's very easy to interface with both the YM2612 and the SN79489, as long as you know some Z80 assembly (sure you can control them from the 68k as well, but if you're coding a game you probably don't want to waste main CPU cycles on sound processing).


I have a design for somewhat easy method of PCM playback on the Genesis. If you generate an H-int on all 224 active scanlines, write to the DAC on those scanlines, then you just need to do a small timed loop on the z80 end during vblank. Which is totally doable. It might not be the best/least resource method, but it gets the job done and at 15.7khz too. And the z80 is free to do other stuff outside of the vblank DAC loop.

by on (#48090)
tomaitheous wrote:
The CPU is a comfortable 7.16mhz based on Rockwell's 65C02 (has the additional instructions missing from the 65816) and Hudson throw in block transfer instructions similar to the '816.


It's worth noting that on TG16 7.16MHz is an optional high speed mode (normal is 3.58Mhz maybe?). Because of the higher-speed ROMs required. It seems NEC made memory chips, so they must have been unafraid. :) SNES also is often quoted as 3.58Mhz, but I'm guessing most games ran at 2.68Mhz (btw the speed slows down even more when you access $4016/$4017 - causing a code timing nightmare for my RS232 cable, maybe this applies to some other regs).

I haven't done any TG16 development yet (I might try a port or 2 from NES sometime), but I have made a super cheap card PCB for it. I could supply those if ever needed. If you're handy with a PLCC extractor, it makes an OK dev card.

Quote:
SNES: I don't have a lot of experience here, but I can say the sPPU is the most convoluted/complex of all of the systems listed.


I definitely agree to that, from my experience of trying to initialize the damn thing before I referred to (er, ripped) other code. The SNES PPU is definitely designed to appeal to everyone who's worked with the NES PPU. HDMA is a lot of fun, it's like the automatic way of doing the all graphics tricks that you can do on the NES, without having to work your code around the timing.

Anyone who's well experienced with 6502 will love it, for sure. The SEP and REP instructions can be tedious at times, but it's easy to appreciate a 16-bit index register. But what could be better than a relocatable zero-page? :D

Quote:
The CPU has this really funky (read:complex) memory layout.


Seems like the 2 modes are either the NES-like "LoROM" ($8000-$FFFF) or a native mode, I don't remember having any trouble with either. Making my NSF player I started LoROM, and later moved to HiROM after I realized it would max out (and not run at high-speed maybe? I forget).

SNES was cool, but I was more than ready to get back to the simplicity of the NES. Where there's only 8 PPU registers, half of which you touch once and forget about it. NES is easy, plus with it being more limited you have a better chance of pushing the limits of what it can do. For the NES too, you'll find a lot more help around here.

BTW regarding NES PPU docs, the Nestech doc (ndox200.txt) is pretty good, it's concise and an easy read. Brad Taylor's 2C02 Reference is particularly awesome if you want to know exactly what's going on for every clock cycle.
http://nesdev.com/ndox200.zip
http://nesdev.com/2C02%20technical%20reference.TXT

by on (#48096)
Memblers wrote:
It's worth noting that on TG16 7.16MHz is an optional high speed mode (normal is 3.58Mhz maybe?). Because of the higher-speed ROMs required. It seems NEC made memory chips, so they must have been unafraid. :)


Nah, it's always in 7.16mhz mode unless you're accessing BRAM (backup ram for save games and such) which NEC recommends at accessing at low speed (1.79mhz mode). There's no 3.58mhz mode.

Quote:
SNES also is often quoted as 3.58Mhz, but I'm guessing most games ran at 2.68Mhz (btw the speed slows down even more when you access $4016/$4017 - causing a code timing nightmare for my RS232 cable, maybe this applies to some other regs).


Or instructions that access/read/write WRAM. It has wait states on the cycles accessing it. I did some sample counts and it looks like it puts those instructions of WRAM read/writes at around ~3.05-3.15mhz average.

Quote:
I haven't done any TG16 development yet (I might try a port or 2 from NES sometime), but I have made a super cheap card PCB for it. I could supply those if ever needed. If you're handy with a PLCC extractor, it makes an OK dev card.


I did some NES to PCE stuff if you need any source to look at (1,2,3). Those include the source and everything ready to assemble as well (shameless plug, I know :oops:). The PPU and APU are emulated (in realtime), so the code is reusable. I have Dragon Warrior 1 and Robo Warrior projects as well.

Quote:
I haven't done any TG16 development yet (I might try a port or 2 from NES sometime), but I have made a super cheap card PCB for it. I could supply those if ever needed. If you're handy with a PLCC extractor, it makes an OK dev card.


Ohh? Some PCE/TG ones? What the address range?

by on (#48098)
tomaitheous wrote:

I did some NES to PCE stuff if you need any source to look at (1,2,3). Those include the source and everything ready to assemble as well (shameless plug, I know :oops:). The PPU and APU are emulated (in realtime), so the code is reusable. I have Dragon Warrior 1 and Robo Warrior projects as well.


Looks very cool! I saved that and will definitely look into the code there sometime.

Quote:
Quote:
I haven't done any TG16 development yet (I might try a port or 2 from NES sometime), but I have made a super cheap card PCB for it. I could supply those if ever needed. If you're handy with a PLCC extractor, it makes an OK dev card.


Ohh? Some PCE/TG ones? What the address range?


Actually I had no clue when I made it. It's 512kB, just hooked up in a straight-forward way. I know the game Mesopotamia worked, because I remember playing that. So whatever address range that one uses. :)
I didn't know what to do with pin 35 (HSM = Hi Speed mode?), it's left unconnected. I have a few prototypes, so it wouldn't be a big deal to revise it if I have more made.
Looks like this: http://www.flickr.com/photos/35865006@N00/1284713856/in/set-72157601784722145/

by on (#48154)
Memblers wrote:
Actually I had no clue when I made it. It's 512kB, just hooked up in a straight-forward way. I know the game Mesopotamia worked, because I remember playing that. So whatever address range that one uses. :)
I didn't know what to do with pin 35 (HSM = Hi Speed mode?), it's left unconnected. I have a few prototypes, so it wouldn't be a big deal to revise it if I have more made.
Looks like this: http://www.flickr.com/photos/35865006@N00/1284713856/in/set-72157601784722145/


I looked up some flash rom, didn't see any plcc packages larger than 512k. If you make any future boards, would you be up to doing DIP? Or PLCC + dip and some room for a demux'r for chip select? Or anything like that? It'd be great to be able to use it as a ram board too. Would have to be all DIP for both sockets though because there doesn't seem be any nice 512k sram for plcc package.

Also, on the NES to SNES project. If you were to handle it similar to like what I did with the PCE projects, how would you handle simulating/emulating the PRG mappers?

by on (#48157)
tomaitheous wrote:
I looked up some flash rom, didn't see any plcc packages larger than 512k. If you make any future boards, would you be up to doing DIP? Or PLCC + dip and some room for a demux'r for chip select? Or anything like that? It'd be great to be able to use it as a ram board too. Would have to be all DIP for both sockets though because there doesn't seem be any nice 512k sram for plcc package.


Sure, I would be up for a new design. You mean you want 1Mbyte, right? What would a board that was all RAM do? Or do you mean ROM+RAM.

BTW, when I peeked inside my TG16 I saw an unused DIP connection, do you know what that's for? I'd be happy if it was some kind of internal boot ROM, but I doubt I'd get that lucky.

Quote:
Also, on the NES to SNES project. If you were to handle it similar to like what I did with the PCE projects, how would you handle simulating/emulating the PRG mappers?


Basically I figured I'd cheat as much as possible. For UNROM the banks can be interleaved easily when generating the ROM. If there's 2 independent banks then I figured it would involve manually creating some tables that specify only the required bank combinations. The ROM would be larger, but that wouldn't seem to matter (up to a point, anyways).

by on (#48161)
I think it's for a built in game which would be selected when the HuCard detection signal is high.

by on (#48163)
Memblers wrote:

Sure, I would be up for a new design. You mean you want 1Mbyte, right? What would a board that was all RAM do? Or do you mean ROM+RAM.


rom+rom, rom+ram, ram+ram. If you have two DIP sockets, then it'd be pretty easy to do those configurations. An all ram board for a rom emulator (would need an additional cable/interface on the user side). Also, two dip sockets cause it's hard to find 8megabit flash in DIP anymore. Two DIP allows for ROM+RAM (512k+512k) too. Just something MooZ and I had been thinking about - for writing a tracker/music maker that runs complete on the PCE side of things (with an interface cable to a PC of course for dumping ram contents back to PC).



Quote:
BTW, when I peeked inside my TG16 I saw an unused DIP connection, do you know what that's for? I'd be happy if it was some kind of internal boot ROM, but I doubt I'd get that lucky.


Someone mentioned that TG was used as some demo'd paint system. But other than that, they never populated it. If I remember correctly, it fits 128k rom.

Quote:
Basically I figured I'd cheat as much as possible. For UNROM the banks can be interleaved easily when generating the ROM. If there's 2 independent banks then I figured it would involve manually creating some tables that specify only the required bank combinations. The ROM would be larger, but that wouldn't seem to matter (up to a point, anyways).


Ahh, I see.

For attribute table stuff, I cached the writes to a section/buffer. That way when the game reads from vram to modify it (which seems pretty popular from the projects I've worked on), the read can pull directly from the cache - since attribute system doesn't exist on hardware outside of NES. I don't think I've seen any games read anything else from vram - with the exception of SMB reading from vrom (but I cheated on that and just read from a section I stored in rom instead of emulating that).

Does the sPPU allow byte read/writes to vram? On the PCE, the video processor is only WORDs. It was annoying caching bytes to pair into words and such in real time. If so, that's going to be faster. That and actually having 8x8 sprite format faster too (converting two 16x16 on the fly was a pain and wasteful for vram).

by on (#48166)
tomaitheous wrote:
attribute system doesn't exist on hardware outside of NES.

The first result on Google for attribute clash is the ZX Spectrum.

by on (#48174)
tepples wrote:
tomaitheous wrote:
attribute system doesn't exist on hardware outside of NES.

The first result on Google for attribute clash is the ZX Spectrum.


"(nes) attribute system doesn't exist on hardware outside of NES." Unless you know of an attribute system works almost identical to nes?

by on (#48177)
It depends on what you mean by "almost identical to NES".
  1. A palette divided into smaller sections, where each part of a background plane has an "attribute" that designates which section of the palette will be used: Widespread.
  2. Pixel-mapped background plane with attributes, where attribute clash becomes a significant issue: Seen in at least Apple II, ZX Spectrum, and Super Game Boy.
  3. Tile-mapped background plane with attribute areas larger than a tile: Unique to the NES as far as I can tell.

by on (#48179)
tomaitheous wrote:
rom+rom, rom+ram, ram+ram. If you have two DIP sockets, then it'd be pretty easy to do those configurations. An all ram board for a rom emulator (would need an additional cable/interface on the user side). Also, two dip sockets cause it's hard to find 8megabit flash in DIP anymore. Two DIP allows for ROM+RAM (512k+512k) too.


Quote:
Just something MooZ and I had been thinking about - for writing a tracker/music maker that runs complete on the PCE side of things (with an interface cable to a PC of course for dumping ram contents back to PC).

Cool, very cool! A while back I made somewhat of an effort to port FamiTracker's replay code to PCE, didn't get very far though because it'd just be very hacky to use. I know some people that would definitely appreciate a TG16/PCE tracker.

So is this unused internal ROM only used on TG16, not PCE I'm guessing? Seems like it'd be relatively easy to put a custom BIOS in there, + a new chip select. Then with an interface cable, you've got a hucard programmer/reader, and no need for a ROM emulator. That was my plan for if I ever wanted to make a 1MB HuCard, to program it in-circuit like that. But it was speculation since I hadn't investigated the unpopulated internal ROM, nor having any cool stuff to burn yet.

I also have a ROM emulator (512kB), since it uses a 34-pin IDC cable I figured I could strip those and solder them to the PLCC pads. Might not be as hard as it sounds (wires/pads are same pitch, at least), but I didn't try it. But I guess that's why you'd want DIP (would make it easy for me to hook up also, heheh).


Quote:
Does the sPPU allow byte read/writes to vram? On the PCE, the video processor is only WORDs. It was annoying caching bytes to pair into words and such in real time. If so, that's going to be faster. That and actually having 8x8 sprite format faster too (converting two 16x16 on the fly was a pain and wasteful for vram).


Yeah, it looks like there's a configuration bit to set if it auto-incs when one or both of the sPPU data regs are accessed.

I totally didn't consider the NES games reading back from VRAM. Yeah, attribute tables would be the likely suspect (though it seems just far easier to buffer it in RAM, when I'm NES coding).

by on (#48501)
Alright, I'll give the NES a shot.

I'll try my usual approach,

1) init the screen
2) get something on the screen
3) get a sprite on the screen
4) move the sprite
5) collision detection, etc...

Scrolling sounds like the most difficult part.

Are there any similarities between the C64 and NES?
I remember C64 sprites were very easy to use.

by on (#48502)
drk421 wrote:
Scrolling sounds like the most difficult part.

Scrolling by itself isn't difficult at all: just tell the NES what part of the name tables you want visible and it just happens. Synchronizing name table updates to the position of the scroll is the hard part.

Quote:
I remember C64 sprites were very easy to use.

NES sprites are easy too. The only issue is that they are quite small, so you need a good number of them grouped together in order to display something meaningful.

by on (#48504)
I'm a relative newbie to console programming myself. The NES, as far as I can tell, has by far the largest amount of straightforward documentation, the most populated, active and helpful community, of all consoles. In fact, I've never seen a more civil online community in my life. Do yourself a favor and make a project on the NES, you won't regret it! :D

drk421, that's fun, that's pretty much the steps I took to learning the basics as well. Background, then sprites, then simple collision detection. Now I'm on scrolling/map data etc.

by on (#48507)
I'm just starting to get my feet wet, learning the BASICs of Commodore 64 and 128 programming. I would recommend the Commodore to any beginner wanting to program old systems. One thing that I've found helps for learning, is the availability of printed reference material.

You know what? If NESdev printed a book about NES programming, I would certainly order one. Especially if it contained a guide for beginners. It could use material from the wiki and raise funds for the site. What do you think? Is this a realistic idea?

Quote:
Of all the 8/16 bit machines (C64, NES, SNES, Genesis, TG16, etc) which one would be an easy one to start with?

You forgot to mention the Super A'Can. :lol:

by on (#48509)
naI wrote:
You know what? If NESdev printed a book about NES programming, I would certainly order one. Especially if it contained a guide for beginners. It could use material from the wiki and raise funds for the site. What do you think? Is this a realistic idea?


I've seriously thought about writing a NESdev book. It would be a lot of fun to do, but I would need a lot of help with the editing because I've never written a book before. And a lot of help with it otherwise, to make it really great.

by on (#48514)
We could write it collaboratively on the wiki. What happens after "Before the basics"? I'd imagine getting CC65 set up, and then compiling hello world. Then we get into chapters on 6502 assembly language, nametables, sprites, the input devices, scrolling, raster effects, audio, compact data representation (maps and music), etc.