[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)