[HN Gopher] Documented source code for Elite on the NES
       ___________________________________________________________________
        
       Documented source code for Elite on the NES
        
       Author : ibobev
       Score  : 214 points
       Date   : 2023-10-07 04:03 UTC (18 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | abainbridge wrote:
       | Many years ago, when I worked at Frontier, David Braben told me a
       | fun anecdote about NES Elite. He said they initially got the game
       | working using the hardware timer in the NES to keep track of real
       | time so that the in-game physics progressed at a constant rate
       | regardless of the frame rate, which varied. When they submitted
       | the game to Nintendo for pre-release checks, Nintendo said they
       | couldn't use the hardware timer because a few of the earliest
       | NESs didn't have working ones. So Bell/Braben had to make the
       | functions in the game maintain their own estimate of how many
       | clock cycles they each took that frame. At the end of the frame
       | they were all added up and used as an estimate for how much real
       | time had elapsed.
       | 
       | Looking at the source github, it appears I misremembered, or
       | likely didn't even understand what Braben was saying. elite-
       | source-bank-7.asm has a comment saying, "Update the NMI timer,
       | which we can use in place of hardware timers (which the NES does
       | not support)". It looks like they somehow implemented their own
       | real time (ish) clock by counting non-maskable interrupts.
        
         | throw156754228 wrote:
         | Curious, what was it like working at Frontier, did you want to
         | share? I almost took a job there recently, but things didn't
         | work out in the end.
        
           | abainbridge wrote:
           | This was a long time ago, when I was only a baby programmer.
           | It's changed beyond all recognition since I was there. It was
           | sort of lovely. The "office" was a farm house in the Fens.
           | There were two dogs in the office. One was a big soft
           | greyhound called Tigger on account of his stripes. The other
           | was a whippet that had to be kept away from people because it
           | was a nervous creature that would occasionally snap at
           | people. I think there was probably about 15 people there when
           | I started. The software development was chaotic. The chaos
           | provided a lot of freedom and opportunity but caused some
           | serious problems too. Suffice to say that when I left after
           | three years to go and write Darwinia with Chris Delay, we
           | wrote a game engine of our own over about 3 months and once
           | we had that, I'd say we were 20x more productive at creating
           | game content than was possible at Frontier on the Dog's Life
           | team. That said, the Frontier tech at the time did have a
           | nice animation system capable of relatively convincing
           | quadruped animation. It could blend walk/trot/canter/gallop
           | animation loops, do inverse kinematics for foot placement and
           | I think it did vertex blending for polys near skeletal
           | joints. And the engine worked OK on a PS2. Darwinia could do
           | none of those things.
        
             | lttlrck wrote:
             | I had a lot of fun with Dog's Life!!
             | 
             | "The software development was chaotic. The chaos provided a
             | lot of freedom and opportunity but caused some serious
             | problems too."
             | 
             | Love this insight.
        
         | mattlondon wrote:
         | Any other insights about working at Frontier? Did you work on
         | Elite 2 or 3 at all?
        
           | abainbridge wrote:
           | Elite 3 (aka First Encounters) was before my time. Braben
           | kept wanting to get another Elite project going, but there
           | was barely enough resource to do a decent job of the two
           | games that were already in development at the time (Dog's
           | Life and Wallace & Gromit in Project Zoo). Most of the staff
           | had been promised that another Elite game was imminent when
           | they were hired. None of us could quite understand why we
           | were making two games about dogs when we owned the Elite
           | franchise. I still don't understand. Probably something to do
           | with Money and Business Deals.
        
         | mmsc wrote:
         | I heard the same thing from Andrew Davie of BEAM Software
         | (Melbourne House), who developed Super Glove Ball. Since
         | Nintendo refused to provide the company with any meaningful
         | documentation, they had to come up with various hacks for
         | framerate calculation or something similar.
         | 
         | When they were trying to get approval for Nintendo for some
         | game, it turned out that one specific version of the USA NES
         | wouldn't work, or the game was making the system overheat (I
         | don't remember exactly). Andrew told me that they had to fly
         | all the way to the Nintendo's HQ to deal with this since they
         | were on a tight window to release. It also turned out that
         | there were fewer than a hundred of that specific version of the
         | NES in circulation.
         | 
         | Ah, it was a bit different. I found the note in my
         | (unpublished) book:                 Tests for games were not
         | exclusive to gameplay either. Games had to be tested in each
         | possible NES console they would be played on. Beam Software's
         | Andrew Davie recalls flying to Nintendo's offices in
         | Washington, in response to the game "The Three Stooges" causing
         | problems on a NES system that they were testing it on. He
         | recalls there being "something like 23 variations of the
         | machine, with different chip manufacturers, etc." that the game
         | had to be tested on to pass Nintendo's tests. Once the problem
         | was diagnosed (the way Davie had programmed the game, due to
         | the lack of official documentation, made the NES run too hot,
         | which caused flickering sprites throughout the game; instead of
         | writing the sprite data into RAM as the official documentation
         | called for, Davie wrote the data every two seconds), the game
         | was fixed and accepted for release; after this, the problematic
         | NES console was removed from Nintendo's testing line-up, with
         | Davie being told that only around 5 consoles with that
         | combination of chips was in circulation in the entire USA.
        
         | NobodyNada wrote:
         | Yes, I bet you're misremembering something -- no released NES
         | has a "hardware timer", in any revision.
         | 
         | The earliest revisions of the NES CPU _do_ remnants of a buggy
         | and disabled programmable interval timer on the die: https://ww
         | w.nesdev.org/wiki/RP2A03_Programmable_Interval_Tim.... This was
         | fully removed in later revisions. Perhaps this was enabled on a
         | dev kit or something -- relying on functionality that never
         | worked on consumer units certainly would have led to Nintendo
         | rejecting it during testing.
         | 
         | But even if released consoles had a PIT, it would only be very
         | useful for sub-frame measurements for e.g. timing precise
         | raster effects. Counting NMIs would be by far the most sensible
         | way to measure real time. The NMI fires at the start of each
         | video frame, which is extremely consistent at 60.0988 Hz, and
         | not affected by in-game processing (i.e. game engine may run at
         | a slower/variable framerate if it can't keep up, but nothing
         | that happens CPU-side can affect the timing of the video signal
         | in any way; the rendering process runs off a fixed timer in
         | hardware).
         | 
         | (FWIW, the audio hardware also has the ability to generate
         | timer interrupts, and many expansion chips have scanline
         | counters that can generate timer interrupts if you need fine-
         | grained synchronization to the rendering process. There's no
         | shortage of ways to measure time on the NES if you need it).
        
           | abainbridge wrote:
           | Interesting stuff. I'm going on a 20 year old memory of a
           | conversation I probably didn't understand at the time, so I'm
           | very fuzzy on the details.
        
           | ndiddy wrote:
           | I believe what Braben was referring to is the IRQ the APU
           | sends when it's done playing an audio sample. This can be
           | used as a hardware timer by playing a silent sample (all
           | zeroes) and varying the sample length and pitch to adjust the
           | amount of time before the IRQ happens. There's a Twitter
           | thread (https://togetter.com/li/753345) from the programmer
           | of Guardian Legend (a game that uses the APU IRQ for
           | measuring when to switch from displaying the main gameplay to
           | displaying the HUD) that mentions something similar to
           | Braben's story. After the game came out, he started getting
           | reports that it wasn't working correctly on a small number of
           | consoles. It turned out out that Guardian Legend was the
           | first game to use the APU IRQ and Nintendo had never tested
           | that feature at manufacture. After this, Nintendo started
           | instructing developers to not use the APU IRQ.
        
             | joneholland wrote:
             | I randomly used that game as a test rom when I wrote my nes
             | emulator and was pulling my hair out in why the HUD wasn't
             | rendering until I realized I needed to implement the APU as
             | well.
             | 
             | What a fun era of development.
        
           | layer8 wrote:
           | > The NMI fires at the start of each video frame, which is
           | extremely consistent at 60.0988 Hz
           | 
           | Wouldn't that be different on a PAL NES? The parent mentioned
           | that they wanted "to keep track of real time [...] regardless
           | of the frame rate, which varied".
        
             | MarkMoxon wrote:
             | It is indeed different on PAL vs NTSC. The code relies on
             | the NMI being called at 50Hz - as a result a number of
             | timings are wrong on the NTSC version, so the music is too
             | fast, the combat demo auto-play doesn't work properly, the
             | time reported for completing the combat demo is wrong, and
             | so on. The NTSC version is unfinished, and this is just one
             | area where it shows.
        
           | MarkMoxon wrote:
           | Yes, no hardware timers are used in NES Elite, as there
           | aren't any.
           | 
           | Instead there's an NMI counter (nmiTimer) that counts every
           | VBlank and wraps around every 50 ticks, so it's effectively a
           | seconds counter on the 50Hz PAL version. And in the NMI
           | handler, they keep a running total of cycles spent so they
           | know when VBlank has finished and can stop sending data to
           | the PPU, picking up where they left off in the next VBlank
           | (see the NMI routine in bank 7).
           | 
           | They also use sprite 0 collision detection to flag when the
           | screen redraw has reached the icon bar, so it can force the
           | PPU to nametable and pattern table 0 (as the icon bar's tiles
           | are only in table 0, with table 1 being used for the vector
           | graphics). This is not unlike the original BBC Micro
           | version's split-screen mode, just without any hardware timers
           | (instead, the whole source is littered with macros that check
           | the collision flag - not very elegant, but it works).
           | 
           | Having hardware timers would have made things a lot easier!
        
       | Apocryphon wrote:
       | In contrast, here's the source code for Oolite, the open source
       | Elite clone written in Objective-C:
       | https://github.com/OoliteProject/oolite
       | 
       | https://oolite.space
       | 
       | https://news.ycombinator.com/item?id=7894145
        
       | anthk wrote:
       | Not libre. Too bad, if I were the Elite creator I'd put all the
       | game ports under a libre license. Anyway, nowadays you can play
       | Oolite on a cheap netbook and have the exact same fun, if not
       | more due to the huge addon list for it.
        
         | mattlondon wrote:
         | There is quite a lot of history around the releases that goes
         | back several decades.
         | 
         | Braben et al didn't want to weaken the copyright I guess since
         | they were doing Elite 4/Elite: Dangerous.
        
         | lstodd wrote:
         | That's Braben being a dick about copyright. Bell on the other
         | hand was a nice guy and released most that he himself wrote.
        
       | throaiej21834 wrote:
       | [dead]
        
       | ralferoo wrote:
       | I like how the start of every bank contains a bank switch shim
       | like this:                 SEI       INC $C006       JMP BEGIN
       | 
       | Then it goes into a lot of detail about how it does this to save
       | space, but it seems to me that the only reason the JMP is even
       | needed is because of the instruction pipeline, which could be
       | flushed with just a NOP. So here's my 2 byte optimisation to this
       | code:                 SEI       INC $FFFD ; use the C0 in the
       | instruction vector instead       NOP
        
         | qwery wrote:
         | > it seems to me that the only reason the JMP is even needed is
         | because of the instruction pipeline
         | 
         | It does also _make sense_ to a human -- execution begins in
         | bank 7, so jump to bank 7.
         | 
         | Side note: on Game Boy the entry point is in ROM0, a fixed bank
         | (at least on the common MBCs), so you don't have this problem
         | in the first place.
        
           | MarkMoxon wrote:
           | Also, the JMP BEGIN approach will still work even if you move
           | the BEGIN routine elsewhere in bank 7, so presumably it's
           | done this way so things won't break during development when
           | you're still trying to work out which bit of code goes where.
           | 
           | There are quite a few remnants of code in the NES version
           | that do nothing - I guess with 128K of ROM, the authors
           | didn't need to go hunting for every single optimisation,
           | unlike the BBC Micro version...
        
       | danielovichdk wrote:
       | All source code should be documented as this.
        
       | ttctciyf wrote:
       | I embarked on Elite: Dangerous, the successor game, recently. It
       | has its share of problems, granted, but nonetheless is a pretty
       | amazing experience.
       | 
       | Seeing the continuity of game elements from the 1984 version
       | (which I also sunk hours into) is weirdly moving. Seeing the same
       | game objects like the ships and especially the Coriolis station
       | transformed from vector graphics on a 16K memory-mapped screen
       | (SOTA at the time!) to fully rendered 3D at 4K/60fps was more of
       | an emotional ride for me than I expected. Finally experiencing
       | the detailed Coriolis interior complete with advertising
       | hoardings, plant and docking gear moistened my eyes somewhat I
       | don't mind admitting.
       | 
       | Despite current difficulties the game is a precious institution,
       | I really hope it sticks around in some form or other!
        
         | matheusmoreira wrote:
         | I really enjoyed Elite Dangerous as well. Haven't played it
         | since they dropped consoles. I really miss flying those ships
         | with friends despite all the grinding and shallowness. Manually
         | docking a spacecraft to the sound of Blue Danube is always a
         | relaxing experience.
         | 
         | I wonder why space simulators and games always end up being so
         | problematic. Elite Dangerous just seems to be going nowhere.
         | Star Citizen is apparently a perpetual beta. Even KSP2 turned
         | out to be a disappointment. Sigh.
        
           | NikkiA wrote:
           | > I wonder why space simulators and games always end up being
           | so problematic. Elite Dangerous just seems to be going
           | nowhere. Star Citizen is apparently a perpetual beta. Even
           | KSP2 turned out to be a disappointment. Sigh.
           | 
           | Feature creep.
           | 
           | Everyone wants a space simulator.... then it must have
           | atmospheric behaviour, and cities.... and well, we should be
           | able to walk around on the ground... and shoot things....
           | make it a first person shooter, oh, and lots of aliens, make
           | it a diplomacy simulator too.
           | 
           | And on it goes.
        
             | ethbr1 wrote:
             | Corollary: The type of designer who likes to build space
             | simulations also has little ability to self-regulate
             | feature inclusion.
             | 
             | Solution: Never let such a designer run a project
             | themselves, and instead pair them with a practical and
             | empowered project manager.
        
             | CaptainFever wrote:
             | The ultimate game genre has the ultimate allure.
        
             | jstarfish wrote:
             | No Man's Sky managed to pull most of that off. The
             | diplomacy stuff is a little lacking, but it's there.
        
           | xioxox wrote:
           | I enjoyed X3 and X4 quite a lot. However, I didn't like the
           | UI and lack of jump drive in X4. It also has its share of
           | bugs and the universe can get slow when the game progresses.
           | It's still a very engrossing game, however.
        
           | rideontime wrote:
           | I'm sorry to be That Guy, but Blue Danube only plays when
           | you're auto-docking.
        
           | ttctciyf wrote:
           | I think it's a mistake to call the game shallow, there's a
           | deep 9-year struggle for political dominance, for example,
           | that links up to many different game systems. If you take the
           | time to talk with time-served veterans it's astonishing what
           | depths are present in the game.
        
         | hypertexthero wrote:
         | I've spent a lot of time playing Elite: Dangerous since the
         | open beta. A beautiful game, with phenomenal sound design.
         | 
         | Some thoughts I wrote 9 years ago:
         | https://hypertexthero.com/elite-dangerous-education/
         | 
         | The Odyssey expansion is fun, too, and I hope they add EVA
         | space walks and 0-G missions at some point!
        
       | BrissyCoder wrote:
       | I played it on the C64 as an 8 year old. 30 years later I don't
       | understand this code.
        
       | Dwedit wrote:
       | Maybe someone can finally port it to run on NTSC consoles. Would
       | still take a lot of scanlines to cut out though.
        
         | djmips wrote:
         | Maybe try this NTSC version from Ian Bell's website?
         | 
         | http://www.iancgbell.clara.net/elite/nes/
        
           | MarkMoxon wrote:
           | Alas, the NTSC version doesn't actually work on NTSC
           | consoles. The NMI timings have been changed to work with some
           | (but not all) emulators in NTSC mode, but it isn't a full
           | NTSC conversion, it's an NTSC emulation (at least, that's
           | what the authors call it in that version's scroll text).
           | 
           | There's a full list of differences between the PAL and NTSC
           | versions here:
           | 
           | https://github.com/markmoxon/nes-elite-
           | beebasm/tree/main#dif...
        
           | Dwedit wrote:
           | "NTSC Emulation" Elite was intended to be used with Nesticle
           | only, as there was a "NES Timing" dialog where you could
           | change the number of scanlines during vblank time.
           | 
           | At the time, no emulators supported emulating the PAL NES.
        
       | raytopia wrote:
       | 18305 lines of assembly for bank 0... I have no clue how you'd
       | keep that in your head.
        
         | ajxs wrote:
         | I've done a bit of embedded development for 8-bit machines in
         | the modern era, and I sincerely tip my hat to the engineers who
         | were doing it in the 80s. Even with the best tooling available,
         | you'd have needed an enormous amount of organisation and
         | discipline to keep track of your code. I was doing some
         | research about the assemblers available for the Hitachi
         | 6303[0]/Motorola 6800[1] in the early 80s, and I'm amazed by
         | what people accomplished with the limitations of these tools.
         | Just to name one thing, the two assemblers I've linked to only
         | supported SIX character labels, and no local-only labels within
         | subroutines either. To compare, in my own work I was limiting
         | myself to FORTY characters for the sake of being descriptive.
         | 
         | Having said all this, the relative simplicity of these
         | architectures is really refreshing compared to embedded work on
         | modern systems. There's something to be said for being able to
         | roughly keep track of the whole system state in your head.
         | 
         | 0:
         | http://www.bitsavers.org/components/hitachi/_dataBooks/U24_H...
         | 
         | 1:
         | http://www.bitsavers.org/components/motorola/6800/exorciser/...
        
         | yetanotherloss wrote:
         | We were out better selves back then.
         | 
         | Seriously though any project of size almost had to involve
         | large amounts of code written or printed on paper. Lots and
         | lots of paper.
        
           | anthk wrote:
           | Well, it depends. On some environments such as Lucas Arts
           | they used Unix based OSes to develop SCUMM. With grep and
           | such, editing and porting the engine could have been a
           | breeze.
        
         | LeoPanthera wrote:
         | Back when I was writing 6502, you didn't keep it all in your
         | head, you kept it in reams of tractor-fed dot matrix paper,
         | usually with a lot of scribbled pencil notes and corrections.
        
         | chongli wrote:
         | This code is extremely well organized and documented. I don't
         | know what the original code would have looked like in terms of
         | documentation, but I imagine there was a lot of it printed on
         | paper with handwritten notes and stuff.
         | 
         | Overall though, assembly programming is much like any high
         | level language: you organize your code into functions and
         | blocks etc. Just writing one super long wall of code with a
         | rat's nest of jumps throughout is asking for serious trouble.
        
         | PUSH_AX wrote:
         | Can anyone explain this to a modern engineer? Why would you
         | need to hold this in your head?
        
           | imjonse wrote:
           | Possibly lack of tools that make code search/navigation easy.
        
       | vidarh wrote:
       | There's also Elite - The New Kind, a C version that is mostly
       | faithful to the original: https://github.com/fesh0r/newkind
       | 
       | It was done by Christian Pinder:
       | https://www.christianpinder.com/games/
       | 
       | People might also want to check out Ian Bell's Elite homepage,
       | which has a number of the original versions:
       | 
       | http://www.ianbellelite.com/
        
         | MarkMoxon wrote:
         | A shout-out is definitely due to Ian Bell and his website. This
         | is where you can find the original source code for the BBC
         | Micro version. Those original disks form the basis for all my
         | Elite commentaries, including the NES project we're talking
         | about here.
         | 
         | The core of the 1991 NES version (around 30% of the 128K ROM)
         | is essentially the 1986 BBC Master version, which itself is a
         | development of the original BBC Micro version from 1984. The
         | Commodore 64 and Apple II versions are also cut from the same
         | cloth (and they were developed on a BBC Micro, too).
         | 
         | Most of the code in banks 0, 1 and 2 is directly copied from
         | the original BBC version, with a bit more in bank 7. There are
         | new graphics, sound and controller routines bolted on the
         | front, but the beating heart is still the Beeb version...
        
       | LeoPanthera wrote:
       | Ian Bell, author of Elite, claimed that the NES version was his
       | personal favorite 8-bit version of Elite.
       | 
       | (He liked the 32-bit Archimedes port the best overall.)
        
         | dabeeeenster wrote:
         | Arch Elite is the pinnacle for sure.
        
         | helpfulContrib wrote:
         | The recent Oric Atmos fan make is pretty nice, too:
         | 
         | https://www.youtube.com/watch?v=kC1cJGLGlxo
        
         | MarkMoxon wrote:
         | The quote is:                 My greatest published
         | achievements technically would have to be fitting BBC Cassette
         | "Elite" into 32K of RAM including the screen, and later the
         | Nintendo Entertainment System conversion of "Elite" that used a
         | character mapped display and a single NES controller. The NES
         | is my favourite published conversion and was not thought
         | technically feasible until we'd done it.
         | 
         | See http://www.elitehomepage.org/archive/b5081501.htm for the
         | full interview
         | 
         | I interpret this as meaning his favourite version is the BBC
         | Micro cassette version, while his favourite conversion is the
         | NES one. But I'm a BBC fanboy, so that might just be me being
         | hopeful. :-)
        
         | pipes wrote:
         | But they removed trading slaves and narcotics! :)
         | 
         | (I think)
        
           | MarkMoxon wrote:
           | Indeed - "slaves" got changed to "robot slaves", while
           | "narcotics" became "rare species" and "liquor/wines" became
           | "beverages". You can still trade firearms, though, so its not
           | entirely squeaky clean...
        
             | toast0 wrote:
             | Nintendo would have had a hell of a time censoring firearms
             | from videogames. Nudity, slavery, narcotics, and alcohol
             | are easy; violence and firearms form the basis of many/most
             | popular video games.
             | 
             | Probotector is Contra @50Hz with all humans replaced by
             | robots, but still lots of firearms and violence.
        
       ___________________________________________________________________
       (page generated 2023-10-07 23:01 UTC)