One of the trickier things to manage on a NES (without additional hardware on the cartridge) was maintaining a static information panel on the bottom of the display - for the score and so forth - while the portion of the display devoted to gameplay scrolled freely around both vertically and horizontally.
The trick we used at Zippo (Wizard and Warriors II and 3, Solar Jetman etc.) a trick given to us by Rare, was to change the scroll registers and I think the character look up location at the moment the screen refresh cycle reached the appropriate point on the display. These registers would then need to be reset during the vertical blanking interval. So all in all either 100 or 120 times a second depending on the TV system.
Since we couldn't afford to keep the CPU hanging around doing nothing while we waited for the cathode ray tube gun to hit the right point on the screen the trick was a two parter.
First you would get the sound chip - such as it was - to play an inaudible sample of a determined length which would then trigger a CPU interrupt at more or less the right time, within say two or three scanlines of the position of our static panel. You would then position a spare sprite on top of a visible pixel at precisely the right point on the screen so that when it flipped its hardware collision detection bit this was precisely the right time to switch the scroll registers etc.
These were the kinds of shenanigans that made programming the NES intricate and time consuming, and also in later years I suspect made the job of emulator writers something of a misery.
> also in later years I suspect made the job of emulator writers something of a misery
Most certainly. These tricks force developers to emulate systems down to individual cycles in order to get the timing right because getting them wrong will result in visual glitches or worse.
Byuu, the author of bsnes, wrote some very detailed articles about this as well. I can't seem to find them anymore though. His domain has also been excluded from the internet archive for some reason.
> was to change the scroll registers and I think the character look up location at the moment the screen refresh cycle reached the appropriate point on the display. These registers would then need to be reset during the vertical blanking interval. So all in all either 100 or 120 times a second depending on the TV system.
That's a cool way to do it on the NES. While the NES did not have a raster interrupt, requiring such tricks (though you mentioned the later cartridges with the extra chip that added one), the Game Boy did have a raster interrupt, and the SNES essentially went all in on it. Switching the mode mid-frame became a very common method then.
By the way, PAL/NTSC is 50/60Hz, but a frame consists of two fields (odd/even lines), so 25 or 30 frames per second for PAL/NTSC respectively. So I guess this means you probably did the trick 50/60 times per second? (Unless you used more than two configs per frame maybe.)
When I hear stories like these, I always think that nobody is doing stuff like this these days; but in retrospect, I think it's just that I've never asked or seen it discussed.. so..
What are you guys doing these days that has this same hacker-ethos applied to it?
Very cool! Sounds a lot like all the tricks you had to employ for the Atari 2600. If someone is interested in this, I can highly recommend the book "Racing The Beam". It's hard to imagine these days how complicated even the simplest things were back then.
15 years back I did some hobbyist programming for the GameBoy. Drawing a status bar there was comparatively easy. The hardware allowed you to set some registers to define a "window region", overlaying the main background map.
No hblank interrupts? Game boy has them to make this sort of thing relatively easy. Hblank interrupts is also how "mode7" style pseudo 3d for a Mario kart style game can be made (on GBA or SNES).
I wrote an NES game as my senior project for college. It was a singular experience as the vast majority of my development experience had been web technologies.
I had the advantage of full-featured emulators, breakpoints, examining the code as it was running, and a very searchable community online. I have sometimes pondered on the challenges of writing 6502 assembly without any of these things. It’s really interesting to see some of what that was.
It certainly is so much easier to get documentation or read forum posts and ask questions today. Back then, we did have fairly decent dev systems though, could do breakpoints and examine code as it was running. It was also cross-development so you could edit and download from your computer onto the dev system attached to the console. To be fair, some people had much more primitive systems, I feel lucky since others could only test by burning EPROMs.
For NES there are many development environments now... Probably dozens. The main modern advantage is emulators. I do enjoy folks who take a different approach like this dev who is using Lisp to make a NES game.
http://www.dustmop.io/blog/2019/09/10/what-remains-technical...
I do it in C (good enough for most purposes, although a little slow and bloated - most people do it straigh in ASM with extensions).
I use Ubuntu, good old Sublime Text with C extension, FCEUX (Windows version on wine) and YY_CHR (for working with graphics). To compile, check out the awesome CC65 suite (it has a compiler, assembler, linker... the whole thing).
I used an emulator called NinTaco, a 6502 assembler, and VS Code. My game was very simple and completed in about 3 months (I didn’t have any sound and a very limited game)
I think the crucial piece is the assembler and documentation about the start up and loop processes.
What's the reason for using ASM? Were there no good compilers for higher level languages (like C) available for the platform, or were the developers simply accustomed to using ASM, or was the platform limitations such that developers simply had to use ASM?
6502 is just not that viable for C-like languages. Mostly because of its tiny hardcoded stack, so for C you need to either emulate the stack in software (slow) or figure out workarounds (mostly involving precious zero page.)
NES games were still pretty simple, so I can see how simple tools were more or less adequate.
I'm far more impressed that complex SNES games were also developed purely in assembly, like A Link to the Past (1991) or Super Metroid (1994). This is an era where PC game developers would mostly be using C.
You may be interested in this series on SNES hardware features and how they were exploited. The videos have very informative visual representations of memory/io/etc. (the other videos on the channel are also good)
On the other hand, there were pretty complex games on the vastly more simple NES. Less than on the SNES, they required elaborate tricks. (I guess that however mostly required more from the actual game code, and sometimes some extra hardware, than from the tools.)
[+] [-] yosser|4 years ago|reply
The trick we used at Zippo (Wizard and Warriors II and 3, Solar Jetman etc.) a trick given to us by Rare, was to change the scroll registers and I think the character look up location at the moment the screen refresh cycle reached the appropriate point on the display. These registers would then need to be reset during the vertical blanking interval. So all in all either 100 or 120 times a second depending on the TV system.
Since we couldn't afford to keep the CPU hanging around doing nothing while we waited for the cathode ray tube gun to hit the right point on the screen the trick was a two parter.
First you would get the sound chip - such as it was - to play an inaudible sample of a determined length which would then trigger a CPU interrupt at more or less the right time, within say two or three scanlines of the position of our static panel. You would then position a spare sprite on top of a visible pixel at precisely the right point on the screen so that when it flipped its hardware collision detection bit this was precisely the right time to switch the scroll registers etc.
These were the kinds of shenanigans that made programming the NES intricate and time consuming, and also in later years I suspect made the job of emulator writers something of a misery.
[+] [-] matheusmoreira|4 years ago|reply
Most certainly. These tricks force developers to emulate systems down to individual cycles in order to get the timing right because getting them wrong will result in visual glitches or worse.
https://mgba.io/2017/04/30/emulation-accuracy/
https://mgba.io/2017/07/31/holy-grail-bugs-2/
Byuu, the author of bsnes, wrote some very detailed articles about this as well. I can't seem to find them anymore though. His domain has also been excluded from the internet archive for some reason.
[+] [-] crmrc114|4 years ago|reply
[+] [-] anyfoo|4 years ago|reply
That's a cool way to do it on the NES. While the NES did not have a raster interrupt, requiring such tricks (though you mentioned the later cartridges with the extra chip that added one), the Game Boy did have a raster interrupt, and the SNES essentially went all in on it. Switching the mode mid-frame became a very common method then.
By the way, PAL/NTSC is 50/60Hz, but a frame consists of two fields (odd/even lines), so 25 or 30 frames per second for PAL/NTSC respectively. So I guess this means you probably did the trick 50/60 times per second? (Unless you used more than two configs per frame maybe.)
[+] [-] 0des|4 years ago|reply
What are you guys doing these days that has this same hacker-ethos applied to it?
[+] [-] phoboslab|4 years ago|reply
15 years back I did some hobbyist programming for the GameBoy. Drawing a status bar there was comparatively easy. The hardware allowed you to set some registers to define a "window region", overlaying the main background map.
[+] [-] ant6n|4 years ago|reply
[+] [-] agumonkey|4 years ago|reply
today everything seems so decoupled
[+] [-] psyc|4 years ago|reply
[+] [-] chrismcb|4 years ago|reply
[+] [-] Kye|4 years ago|reply
[+] [-] sircastor|4 years ago|reply
I had the advantage of full-featured emulators, breakpoints, examining the code as it was running, and a very searchable community online. I have sometimes pondered on the challenges of writing 6502 assembly without any of these things. It’s really interesting to see some of what that was.
[+] [-] djmips|4 years ago|reply
[+] [-] ec109685|4 years ago|reply
[+] [-] lwansbrough|4 years ago|reply
[+] [-] _Microft|4 years ago|reply
"The current version still has room for improvement and any suggestions will be listened too[sic!], and probably ignored."
Good to know that it was never any different ;)
[+] [-] nom|4 years ago|reply
https://youtu.be/ZWQ0591PAxM
[+] [-] djmips|4 years ago|reply
[+] [-] dormento|4 years ago|reply
I use Ubuntu, good old Sublime Text with C extension, FCEUX (Windows version on wine) and YY_CHR (for working with graphics). To compile, check out the awesome CC65 suite (it has a compiler, assembler, linker... the whole thing).
[+] [-] sircastor|4 years ago|reply
I think the crucial piece is the assembler and documentation about the start up and loop processes.
[+] [-] alkonaut|4 years ago|reply
[+] [-] dan_hawkins|4 years ago|reply
[+] [-] TillE|4 years ago|reply
I'm far more impressed that complex SNES games were also developed purely in assembly, like A Link to the Past (1991) or Super Metroid (1994). This is an era where PC game developers would mostly be using C.
[+] [-] emsy|4 years ago|reply
[+] [-] pdkl95|4 years ago|reply
You may be interested in this series on SNES hardware features and how they were exploited. The videos have very informative visual representations of memory/io/etc. (the other videos on the channel are also good)
[+] [-] anyfoo|4 years ago|reply