Sign in to follow this  

What were SNES games programmed in?

This topic is 4459 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, I was reading on the SNES today (article on Digg) and it mentionned that the CPU was 3.52 MHz and there were 128 kb of RAM. Considering those very small technical specs, I naturally began wondering about programming games for that platform. What were they written in? The various documents I was able to find seem to suggest that most games were written directly in Assembly. Is that correct? Or were they mostly programmed in C, Basic or a SNES-specific higher-level language (higher meaning higher than assembly). I would think that a language such as Forth would have been a better choice as it's higher level than assembly while still being very efficient speed-wise and even more so memory-wise. Forth also has other advantages such as being interactive, allowing inline assembly code and allowing advanced programming methods. Thanks for the input guys, Vincent.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
3.52 MHz and 128kb RAM? That's...incredible! I can't really believe you could run something like Secret of Mana/FFs on that...guess I'm jaded from this age of 2GHz+ processors.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
3.52 MHz and 128kb RAM? That's...incredible! I can't really believe you could run something like Secret of Mana/FFs on that...guess I'm jaded from this age of 2GHz+ processors.


That's why I'm asking, I'm a Ruby programmer mostly, and this machine couldn't even run the simplest Ruby "hello world" program :) Kudos to the guys who knew how to program back then.

Share this post


Link to post
Share on other sites
They were written in 65C816 assembly. I don't know if there were any C compilers for that CPU, but if they did exist they most likely weren't good enough. And yes, while the SNES had 128KB of RAM, most of the code was executed directly from the cartridge ROM, not copied to RAM like you might be familiar with on a PC.

I don't know anything about Forth, but from skimming Wikipedia it seems to be you'd end up with something that resembles a macro assembler. Anyway, I doubt anyone at Nintendo was concerned with such things in 1990.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Yup, snes games were coded in pure assembly.

The reason why snes could still do so nice graphics, despite the weak cpu, is the sweet 2D graphics chip allowing for a lot of cool effects with clever coding.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Yup, snes games were coded in pure assembly.

The reason why snes could still do so nice graphics, despite the weak cpu, is the sweet 2D graphics chip allowing for a lot of cool effects with clever coding.


Thank you. Well, I have to raise my hat to the people who wrote all those cool games. I must have been hell to debug!

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
The reason why snes could still do so nice graphics, despite the weak cpu, is the sweet 2D graphics chip allowing for a lot of cool effects with clever coding.
Don't forget the awesome mode 7...

I love oldschool programming - if you look in my journal, you can see I'm currently developing a game for the Sega Game Gear in Z80 assembly.

If you're looking to develop for the SNES, I'd highly reccomend digging out a good debugging emulator (so you can look at the sprite tables/all memory locations/whatever) and a decent assembler (WLA-DX is my weapon of choice).

Share this post


Link to post
Share on other sites
C was probably a possibility, though I don't know for sure. I've done some limited Gameboy (original) homebrew using a C compiler and its specs are even more limited than the SNES... I also know that the same company that produced the SNES CPU offers a C compiler for it as well.

Also, while we tend to think of things like ASM as being instruction-level languages, theres no reason that an assembler can't impliment some higher-level constructs such as functions and loops. These systems are called high-level assemblers(also: Macro Assemblers.)

Probably most SNES games were done much as PC games were when limited capabilities were more of an issue than it is today. That is: speed critical elements were surely ASM, while some of the less critical code was written in an easier-to-maintain language such as C or high-level assembly.

If you'd like to see an excelent example of a high-level assembler, check out bripro.com, a custom HLA development tool by the creator of Grand Theftendo and other neat technical stuff.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
There's some info and tutorials in the Super NES Programming wikibook.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Anonymous Poster
Yup, snes games were coded in pure assembly.

The reason why snes could still do so nice graphics, despite the weak cpu, is the sweet 2D graphics chip allowing for a lot of cool effects with clever coding.

True dat. Then, of course, there were those enhanced cartridges which granted some games even greater graphics capabilities, such as true 3D.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ravyne
Also, while we tend to think of things like ASM as being instruction-level languages, theres no reason that an assembler can't impliment some higher-level constructs such as functions and loops. These systems are called high-level assemblers(also: Macro Assemblers.)


Yeah, you can probably implement those in Assembler, but the logic of the game remains hidden behind all these MOV, ADD, JMP, etc. With a language that's higher level, like C or Forth already mentionned, you can talk about the elements of the games (NPC's, items, enemies, etc.) with words that make sense. That's why I'm so impressed that among all these instructions, the programmers were able to keep track of the game.

Share this post


Link to post
Share on other sites
I don't see how
move_and_draw_player(3,43);

function move_and_draw_player(dx, dy) {
player_x += player_dx;
player_y += player_dy;
draw_player_sprite(player_x, player_y);
}
is really any different in terms of "remembering" as

ld b,3
ld c,43
call move_and_draw_player

move_and_draw_player:
ld a,(player_x)
add a,b
ld (player_x),a
ld b,a
ld a,(player_y)
add a,c
ld (player_y),a
call draw_player_sprite ; Assumes routine takes b,a as args
ret
Just because it's assembly doesn't mean you can't use sensible variable names and routine names! Structured code in ASM is entirely possible, and if anything more important than in other languages where you need to be able to keep track easily.
Unless you mean an object-orientated system, which is easy enough to implement through arrays and such.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
A fair few well built Macros helped me in my Snes coding days, arr fun days, dug out my source code to Street Racer to remind myself what it was like. Mode 7 was very cool indeed :)

Share this post


Link to post
Share on other sites
I'm pretty sure that spec is for the original Nintendo. Genesis had a combination of a Z-80 and a 68000. A CPU speed of 3.52 MHz suggests likely an Intel 8088 or something along those lines, and the 68000 kicked the ass of that (and Genesis wasn't that much ahead of SNES AFAIK) - ran 7.83 MHz IIRC and was more bang for the buck - er, clock cycle - besides. (I should know, I grew up on the Macs running 68000s :) )

But anyway. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
I'm pretty sure that spec is for the original Nintendo. Genesis had a combination of a Z-80 and a 68000. A CPU speed of 3.52 MHz suggests likely an Intel 8088 or something along those lines, and the 68000 kicked the ass of that (and Genesis wasn't that much ahead of SNES AFAIK) - ran 7.83 MHz IIRC and was more bang for the buck - er, clock cycle - besides. (I should know, I grew up on the Macs running 68000s :) )
Nope, it was 'only' a 3.52 MHz system, though some games with slow rom chips only ran at about 2 MHz instead. The original NES ran at about 1.78 MHz (I should know, I'm currently coding for it).
There's a big difference between the RISC-like 6502 (65816 in this case) and a 68000 though. Most 68000 took between 4-20 cycles to execute while the 6502 could handle them in about 2-7 instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by doynax
There's a big difference between the RISC-like 6502 (65816 in this case) and a 68000 though. Most 68000 took between 4-20 cycles to execute while the 6502 could handle them in about 2-7 instead.


I don't know if its accurate to call the 65816 'risc-like' If I remember correctly It supported memory modes not usually associated with a risc system, also it only had a couple general purpose regs. It only really seems to hold the risc ideal in that it basically executed 'simple' instructions quickly. The 68000, on the other hand, has 16 registers and IIRC, was closer to the classic risc load-store ideal. On the other hand, as you stated, cycle times were quite long for a risc system.

In the end its probably a wash as to which system is more or less RISC. Suffice it to say that they were probably equally powerful, give or take. What really set the SNES apart from the Genesis, was the GPU and sound quality of the SNES.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
move_and_draw_player:
ld a,(player_x)
add a,b
ld (player_x),a
ld b,a
ld a,(player_y)
add a,c
ld (player_y),a
call draw_player_sprite ; Assumes routine takes b,a as args
ret


You can cut off this "ret" instruction from this routine and "jmp draw_player_sprite" instead of calling it. You spend 1 byte less and some good 10 cycles less than your usual. (Experience from programming for MSX computers and Sega Master System)

Some guy up there said about how hard is programming for SNES with only 128KB RAM. He would go nuts if he gets to know that NES and SMS had only about 4KB RAM and could address only up to 64KB RAM/ROM (SNES could address up to 4Mbits if I am not mistaken) and had to rely heavily on mapped memory (with some games having more than 16 pages on SMS at least).

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Some guy up there said about how hard is programming for SNES with only 128KB RAM. He would go nuts if he gets to know that NES and SMS had only about 4KB RAM and could address only up to 64KB RAM/ROM (SNES could address up to 4Mbits if I am not mistaken) and had to rely heavily on mapped memory (with some games having more than 16 pages on SMS at least).


128k is pretty nice, especially considering that code, graphics and other resources could be accessed directly off the rom. The NES had only 2K built in ram, with cartridges containing up to an additional 8K. If the game used battery backed game saves, a portion of this extra ram was reserved for save files as well. Various memory mapping shemes would allow for a maximum of 4 Megabits of data for each of the program and Character rom, IIRC. NES graphics were stored in the Character rom, which was on a seperate bus wired directly to the Graphics unit.

The 65816 used by the SNES supports up to 16 megs of address space directly, although the SNES used a custom version that may have been slightly different, or possibly nintendo decided 4 megs was enough and simply left the upper two address pins unconnected to reduce PCB complexity. I honeslty am not sure of this.

Share this post


Link to post
Share on other sites
The real limitation in coding for a system like the snes (I'm extrapolating from my gb/z80 experience here) is doing anything with 16 bit registers. Floats? forget it, 32 bit fixed point? forget that too. 16 bit fixed point? Try implementing an 8.8 divide. That was the true genius in coding of these systems, IMHO.

Share this post


Link to post
Share on other sites
Agreed. The chip in the SNES doesn't even have any built in multiply functionality what-so-ever. Every multiply or divide on the SNES was a subroutine of some sort, so you would do whatever you could to avoid needing multiplies in the first place. I don't even want to think about trig or sqrt functions on a SNES, Probably where these were needed there was a look up table of some sort, possibly built into the platform's firmware ( I recall reading that at least one system had this). Power-of-2s and incrimental algorithms were very important then (and still in some spaces such as GBA/Cell phone/embedded systems.)

I wish I would have caught that wave. Although, I'm about to start some contract work on some new hardware that has some pretty retro elements to it. Cool stuff to play with.

Share this post


Link to post
Share on other sites

This topic is 4459 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this