What it was like developing for NES back in 1990
twitter.com
twitter.com
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.
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.
If so, what approach are you taking for the toolchain? Keeping the existing version that had been used/modified? Updating to newer tools (and code changes that may go along with that)?
Can definitely see wanting to keep the compiler and code in a known state. Though modern SDCC generates code that's probably 50% faster in some cases and with 90% less bugs than versions from the early 2000s.
Lots of great Game Boy releases have been coming out.
Edit: add a little more.
https://en.wikipedia.org/wiki/Memory_management_controller#M...
today everything seems so decoupled
For instance, on Sinclair Spectrum the memory refresh and the keyboard matrix scanning were intimately coupled; tape I/O and screen border color circuits were also somehow coupled, which was easy to see with every tape operation.
They do more instructions per second than a whole 15min game play.
Imagine trying to coordinate all those interactions without abstractions.
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.)
Also I only just learned that because the NES does not actually output the half scanlines that make interlacing work, both fields are drawn on top of each other, effectively making it 50/60 actual frames per second anyway, instead of interlaced fields! (https://wiki.nesdev.com/w/index.php/NTSC_video)
However, older video game consoles (such as the NES and SNES) typically output a malformed NTSC signal, designed to trick the TV into drawing just the odd lines, over and over again, sometimes referred to as "240p". As a result, it's effectively 60 independent frames per second, not 30 frames of two fields.
It's been a long time!
There are two other mechanism I know off the top of my head.
One is to put some circuitry on the cartridge, and then arrange the usage of tiles such that all the background tiles are in one bank and all the foreground tiles are in another. If you do this right, you get an address line which cycles high and low once each scanline–and you can put a circuit on the cartridge which counts the scanlines, triggering an interrupt. This was only available if you could put that circuitry (usually, a “mapper”) on the cartridge.
The last method is to count cycles.
I would note that among other differences, this is much, much easier on a Game Boy. The Game Boy has a register you can read which tells you which row you are on. Not the only thing that’s easier on a Game Boy—there’s also a hblank interrupt, and the tilemap is larger than the screen. Anyone interested in NES programming but unsure about how much they like dealing with obscure technical problems may want to try Game Boy programming first to get a taste for it.
If you've ever noticed some "weird flickering" near status bars in NES games, this is probably the culprit: Few very skilled developers were able to pull it off cleanly.
Imagine a text file pushed out theough a serial port, all the data is just dumped on to the wire and the other end worries about interpreting carriage returns and line feeds. You just imagined how old line printers worked!
When the TV wasn't able to figure out the sync signal you'd get rolling [1] or tearing [2] where the picture was being displayed the best the TV could make out.
1: https://youtu.be/bGXEqzCS4nE?t=28 2: https://www.youtube.com/watch?v=FVOVk3psy-w
What are you guys doing these days that has this same hacker-ethos applied to it?
Also I'm aware of at least one game that uses an internal executable restart routine to reboot and reload data on PS4 and X1 since it's just easier than dynamically unloading all engine data and loading it again following an in-game update. While not forbidden by either 1st party, it's certainly somewhat unorthodox.
In general, I think that even with next(current) gen there is still a lot of the good old school hacker mentality going on, it's just that you can't hear about it because it's all NDAd. Wait 10-20 years and those stories will start to come out.
Microsoft put out a video soon after purchasing Bethesda where someone from that team mentioned doing a similar trick in the Xbox port of Morrowind. If the game was approaching the relatively tight 64MB RAM limit of the platform it could soft reboot the console during a loading screen and then reload to the current point.
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.
Because Byuu, who later went by "Near", tried to scrub as much personal information from the internet in the hopes of staying ahead of constant doxing attacks by an awful internet community called KiwiFarms. It didn't work. In the end, Near/Byuu committed suicide months ago to escape the constant harassment.
The free speech Alamo. It often leads to funny results, like lesbians finding it to be the only place they could complain about some psycho in Canada targeting women operating small businesses - Youtube and Twitter banned several people over it before the Canadian media started covering it. Sometimes it leads to not so funny results, because that is the cost of agency - its kinda crazy that even has to be pointed out... but we seem to be at that point.
I don't think there was an IRQ for sound, but it might have made sense to poll the audio unit rather than the graphics unit for some reason.
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.
"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 ;)
I think the crucial piece is the assembler and documentation about the start up and loop processes.
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'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)