[HN Gopher] What it was like developing for NES back in 1990 ___________________________________________________________________ What it was like developing for NES back in 1990 Author : _Microft Score : 166 points Date : 2021-08-07 17:48 UTC (5 hours ago) (HTM) web link (twitter.com) (TXT) w3m dump (twitter.com) | yosser wrote: | 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. | matheusmoreira wrote: | > 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. | | 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. | ant6n wrote: | 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). | jkarneges wrote: | We abused hblank to death in Infinity for Game Boy Color | (unpublished in 2001, later dumped on GitHub), for things | like parallax scrolling, tilted overworld map, screen | transitions, and scrolling inner text. | djmips wrote: | I looked for that, found it on github and then looked at | the build instructions, followed the link provided to GBDK | and saw my credit as one of the contributors. Totally | forgot about that... :) | aidenn0 wrote: | IIRC, SNES had those, NES did not. | city41 wrote: | You could get the equivalent of hblank interrupts with a | mapper, such as the mmc3 used in Super Mario Bros 3. That is | how SMB3 renders its hud. | | https://en.wikipedia.org/wiki/Memory_management_controller#M. | .. | anyfoo wrote: | > 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.) | janzer wrote: | My guess is the trick is needed four times per frame. For | every field you need it once to start the static portion | drawing, then once more to stop. | anyfoo wrote: | Ah, duh, you're completely right. I somehow hallucinated | another buffer between PPU-generated frames and video | output. Which would have been rather expensive at the | time... | | 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) | [deleted] | 0des wrote: | 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? | gambiting wrote: | It's semi-common on PS4 to abuse the audio coprocessor to do | things other than audio, just to eek out that little bit of | extra processing power. After all, it's programmable, so why | not? In fact Sony specifically made the PS5's audio processor | non programmable to make sure developers _don 't_ do this and | actually focus on its strengths and things that it can do | very well with 3D audio and such, rather than make it crunch | physics or whatever. | | 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. | crmrc114 wrote: | Your post is why I keep coming back to HN to read- thank you so | much for sharing. I love the undocumented stories from the | trenches. | agumonkey wrote: | man it must have been such a weird era where the screen was | part of the "system architecture" | | today everything seems so decoupled | nine_k wrote: | The hardware was so limited and expensive that rather | trickery paid off. | | 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. | agumonkey wrote: | I know, I mean the thought process when designing a program | in such constraints where any aspect of a system might be a | useful resource and you had almost no other choice (kinda | like abrash rotated texture trick on pentium) .. it's so at | odds with current processes where everything is split and | isolated as much as possible. | psyc wrote: | What mechanism existed for telling what scan line the TV was | on? | klodolph wrote: | That's what the "hardware collision" bit is about. You place | sprite 0 at a certain location on screen, and you can find | out when that sprite gets drawn (with some certain other | restrictions / assumptions). IIRC, the collision bit gets set | when a pixel from the sprite is drawn overlapping a | background pixel. This is how early games like Super Mario | Bros. drew the status bar, but Super Mario Bros. could just | spin the CPU waiting for this. | | 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. | FPGAhacker wrote: | And how would one know the bit was set... polling? | burnte wrote: | The TV syncs to the clock in the input signal that the | console generates. The console knows what line the TV was on | because it's the line that the console is currently | outputting. Analog TVs were very simple devices where the | signal coming in via the wire or antenna was basically pumped | directly to the CRT to manipulate the beam. While at the | user's end it looked like a raster, it's all analog tricks. | | 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 | phoboslab wrote: | 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. | sircastor wrote: | 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. | djmips wrote: | 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. | TillE wrote: | 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. | emsy wrote: | SMB3 will outshine a lot of games released today and I think | that's a good thing. Great game design is somewhat timeless. | anyfoo wrote: | 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.) | ec109685 wrote: | Reference point to what Mac development was at the time (Think C | from 1991): https://www.youtube.com/watch?v=zkhcBeK4V_4 | nom wrote: | Does anyone know how it is done today, like with Micro Mages? | | https://youtu.be/ZWQ0591PAxM | djmips wrote: | 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... | _Microft wrote: | From the title screen of the tool: | | _" 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 ;) ___________________________________________________________________ (page generated 2021-08-07 23:00 UTC)