GOPHERSPACE.DE - P H O X Y
gophering on hngopher.com
HN Gopher Feed (2017-10-16) - page 1 of 10
 
___________________________________________________________________
A Comprehensive Super Mario Bros. Disassembly
238 points by shubhamjain
https://gist.github.com/1wErt3r/4048722
___________________________________________________________________
 
camhenlin - 3 hours ago
For people interested in the SMB disassembly, you may also be
interested in this one: http://bisqwit.iki.fi/jutut/megamansource/
NES MegaMan disassembly, with some comments
 
binarymax - 2 hours ago
I love that this is just a gist.  Like 'hey just needed to copy and
paste this for a minute'
 
khedoros1 - 4 hours ago
There's also a Legend of Zelda disassembly, but it's not as
nice:https://github.com/camthesaxman/zeldasourceIt's a much larger
game, though.I haven't checked, but I'm assuming that a lot of the
giant chunks of statically-defined data are just graphics and audio
(unlike many games, LoZ stored graphics interspersed with the
program code and copied data over to an in-cartridge RAM chip,
instead of storing the complete graphics data in a ROM chip.)
 
  derefr - 3 hours ago
  > unlike many games, LoZ stored graphics interspersed with the
  program code and copied data over to an in-cartridge RAM chip,
  instead of storing the complete graphics data in a ROM chipThis
  is because Zelda 1 was a port from the Famicom Disk System?no
  memory-mapped ROM chip to rely on, so you've got to load
  everything you're going to use to RAM. (Also like this:
  Metroid.)I believe this is why both LoZ's and Metroid's maps are
  built out of individual "screens" with a "pause to transition"
  effect between them: in the FDD version, the game would be
  reading the new map from disk, and there'd (sometimes, if the
  load took long enough) be a loading screen involved. (You can see
  the screen for LoZ here:
  http://tcrf.net/The_Legend_of_Zelda/Console_Differences#Load...)
 
segmondy - 4 hours ago
The entire game in 16,000 lines of assembly code. :-)
 
webXL - 3 hours ago
I love stuff like this. Seeing the disassembly somehow adds to the
nostalgia for a childhood pastime.What's this endlessloop for:
https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L712(Yes,
please ;)
 
  jepler - 3 hours ago
  You can see that just above the endless loop, the code will
  "enable NMIs".  I'm not sure about the nomenclature here (because
  normally NMI stands for non-maskable interrupts, meaning you
  can't disable them) but basically the game at this point becomes
  event (interrupt) driven, probably from the vertical retrace
  interrupt or another kind of timer interrupt.  When no event is
  being handled, the CPU idles within this endless loop.
 
    jepler - 3 hours ago
    https://wiki.nesdev.com/w/index.php/PPU_registers#Controller...
    states that bit 7 of the register at $2000 (which they call
    PPUCTRL, and this disassembly calls PPU_CTRL_REG1) will
    "generate an NMI at the start of the vertical blanking
    interval"
 
1zael - 5 hours ago
This is insane.
 
MBCook - 1 hours ago
Is there a version of this somewhere that people have changed it to
C or some other higher level language for easier skimming? I?d love
to see that.(Yes, I know it was written in ASM).
 
wgrover - 4 hours ago
Looks like data for the various songs
here:https://gist.github.com/1wErt3r/4048722#file-smbdis-
asm-L160...I'd love to see the process of extracting actual audio
from that.
 
  earenndil - 2 hours ago
  There're tools that can extract audio from snes roms, I'm sure
  there's something similar for nes.
 
  strangecasts - 3 hours ago
  The NES had a memory-mapped APU[1], so the game just sets sound
  registers to play the appropriate notes, and ticks down a timer
  until it's time to switch to the next note:
  https://gist.github.com/1wErt3r/4048722#file-smbdis-
  asm-L156...[1] https://wiki.nesdev.com/w/index.php/APU
 
DonHopkins - 2 hours ago
I wrote this earlier on another forum but I'll repost it here:I've
seen Shigeru Miyamoto speak at several game developer conferences
over the years. He's absolutely brilliant, a really nice guy, and
there's so much to learn by studying his work and listening to him
talk. Will Wright calls him the Stephen Spielberg of games.At one
of his earlier talks, he explained that he starts designing games
by thinking about how you touch, manipulate and interact with the
input device in the real world, instead of thinking about the
software and models inside the virtual world of the computer first.
The instantaneous response of Mario 64 and how you can run and jump
around is a great example of that.Shigeru Miyamoto GDC 1999 Keynote
(Full): https://www.youtube.com/watch?v=LC2Pf5F2acIAt a later talk
about how he designed the Wii, he said that he now starts designing
games by thinking about what kind of expression he wants it to
evoke on the player's faces, and how to make the players themselves
entertain the other people in the room who aren't even playing the
game themselves. That's why the Wii has so many great party games,
like Wii Sports. Then he showed a video of a little girl sitting in
her grandfather's lap playing a game --
http://youtu.be/SY3a4dCBQYs?t=12m29s , with a delighted expression
on her face. The grandfather was delighted and entertained by
watching his granddaughter enjoy the game.This photo --
https://i.imgur.com/zSbOYbk.jpg -- perfectly illustrates exactly
what he means!Shigeru Miyamoto 2007 GDC Keynote - Part 1:
https://www.youtube.com/watch?v=En9OXg7lZoEShigeru Miyamoto 2007
GDC Keynote - Part 2:
https://www.youtube.com/watch?v=jer1KCPTcdEShigeru Miyamoto 2007
GDC Keynote - Part 3:
https://www.youtube.com/watch?v=SY3a4dCBQYsShigeru Miyamoto 2007
GDC Keynote - Part 4:
https://www.youtube.com/watch?v=jqBee2YlDPgShigeru Miyamoto 2007
GDC Keynote - Part 5:
https://www.youtube.com/watch?v=WI3DB3tYiOwShigeru Miyamoto 2007
GDC Keynote - Part 6:
https://www.youtube.com/watch?v=XvwYBSkzevwShigeru Miyamoto Keynote
GDC 07 - Wife-o-meter: https://www.youtube.com/watch?v=6GMybmWHzfU
 
looperhacks - 3 hours ago
You might also be interested in the dissambly of the first pokemon
games:https://github.com/pret/pokeredAnd some other pokemon
games:https://github.com/pret/pokered#see-also
 
  DarkTree - 1 hours ago
  I loved this article regarding the algorithm used for capturing
  pokemon: http://www.dragonflycave.com/mechanics/gen-i-capturing
 
raldi - 3 hours ago
Check out the section under "DemoActionData": this is where it
stores (and plays) the demo you see when you don't push Start and
Mario runs around on his own volition.It just simulates player
input and runs it through the regular game engine. (The
alternative, playing a recorded video, would have been laughably
data intensive.)
 
  dEnigma - 3 hours ago
  Same thing goes for Super Mario 64. The popular TASer pannenkoek
  actually explored whether it was possible to manipulate Demo-
  Mario's starting position in such a way that he collects a star
  with the demo input (this was for the purposes of special
  "A-Button Challenge" speedruns, where pressing the A-Button must
  be kept to a minimum, but since the demo input isn't actual
  player input it isn't counted) Sadly I think there was no
  conceivable way to do it. (i.e. manipulating the starting
  position is possible, but not in a way that leads to collecting a
  star)https://youtu.be/-0emgkIEobI
 
    opdahl - 52 minutes ago
    That's an amazing youtube channel. Here [1] the creator
    describes in an over seven-minute long video the intricacies of
    Mario falling asleep.[1] https://www.youtube.com/watch?v=7OtW-
    LLZ2OA
 
zxy_xyz - 5 hours ago
Is the gameplay logic in a different file or did i miss something?
 
  psyc - 5 hours ago
  It's all in there. Probably start with PlayerCtrlRoutine.
 
DonHopkins - 2 hours ago
How I love the sleek smooth razor sharp columns of three letter
6502 opcodes. The right edge of columns of opcodes in other
instruction sets look so rough and jagged like sandpaper in
comparison. That's what I've always hated about x86 code. It looks
rough and torn.
 
jordigh - 5 hours ago
https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L601...I
think this is where the real gems start. The biggest contribution
that SMB had was the "physics engine", to retrofit a modern term.
The friction, the jumping, the inertia. If you compare it with the
primitive physics in Donkey Kong or Mario Brothers, you can really
grasp the groundbreaking novelty that was SMB. You can change
direction in mid-air, but not too much. When you run, you skid if
you try to run in the opposite direction. The height of your jumps
is affected by your running speed.It's all of these little details
combined, barely noticed in tandem, which made the game new and
fun.
 
  davidscolgan - 5 hours ago
  I once read that the way SMB was able to pull off the physics
  engine on such limited hardware was that it used lookup tables
  for physics instead of actually calculating velocity.  My
  assembly-fu is weak but it looks like your link is to the section
  that contains all the lookup tables.  I think JumpMForceData for
  example is a series of offsets for each successive frame after
  you hit the jump button.https://gist.github.com/1wErt3r/4048722
  #file-smbdis-asm-L611...This line shows the calculation that
  makes use of the JumpMForceData.
 
    bluedino - 3 hours ago
    You can also fine-tune the feel of a jump when you're directly
    editing a handful of values vs trying to find a function that
    describes your desired results.
 
      goialoq - 2 hours ago
      How so? "Trying to find a function" is editing a handful of
      parameters to a polynomial+exponential model -- the same
      thing
 
        chii - 2 hours ago
        i'd say a lookup table is more easily edited than a
        parameter in a function (provided that you are editing a
        function with less parameters than the entries in the
        lookup table).
 
        Orangeair - 1 hours ago
        When you edit one coefficient of a polynomial, you change
        its behavior everywhere. When you change one value in a
        lookup table, you're only changing the value for one point
        in time.
 
    dieterrams - 4 hours ago
    Lookup tables were indeed a common technique used by games in
    the past.
 
      asveikau - 3 hours ago
      And present, too, right?  It's not the same reason as it
      would have been in the 80s, but today in performance critical
      code it is not uncommon to reduce the number of conditionals
      for better CPU pipelining, and lookup tables are a very
      common tool for this.
 
        vardump - 2 hours ago
        > it is not uncommon to reduce the number of conditionals
        for better CPU pipelining, and lookup tables are a very
        common tool for this.On modern CPUs, data dependency, such
        as lookup tables often cause pipeline stalls ? worse
        pipelining.L1 cache is at a premium as well, you rarely
        want to waste it to access LUTs.You can compute a lot in 12
        cycles caused by L2 hit (L1 miss). In theory up to 32 * 12
        = 384 floating point operations.
 
        derefr - 3 hours ago
        I have a strong feeling that Super Mario Maker always has
        the same physics engine going, but just has four different
        lookup tables that it switches between depending on the
        level theme. Anyone want to partially disassemble it for
        comparison?
 
        simooooo - moments ago
        Yes I recall a Forza motorsport physics guy saying they
        used a simple lookup table for the chart which holds the
        curve for the limit if grip on a tyre. Beats the crab out
        if calculating it every time.
 
        white-flame - 1 hours ago
        I think the biggest difference is that modern games tend to
        be written for variable frame rates, stuffing floating
        point time deltas through equations.A lookup table meshes
        much better with fixed frame rate gameplay, either with one
        entry per frame, or quantizing countdown timers of how many
        frames to wait to go to the next state.
 
          usernam - 39 minutes ago
          Actually, modern (and not so modern) physics engines as
          used in games generally use a fixed time delta for each
          step, and just iterate faster/slower to keep the
          simulation in sync[1]. This is done for many reasons, but
          predominantly numerical stability.[1] not the full story
 
  corysama - 3 hours ago
  I'll plug the book http://www.game-feel.com/ here because it has
  a 28-page chapter devoted to the physics of SMB.
 
salqadri - 3 hours ago
Tu tu tu turuturu turuturutururur...
 
tomduncalf - 5 hours ago
This seems like a really impressive effort to make sense of all
this!Would the original game have been written in assembly? And if
so, would the source have looked similar to this?Having never
touched assembly language (aside from learning some very basic
cracking many years ago swapping JE for JNE in the serial check
routine, haha), it seems like a true dark art to me, so I?m really
curious to know!
 
  Kelbit - 5 hours ago
  Yes, the original game would have been written in 6502 assembly,
  and probably would have looked something like this. The label
  names and defines would have been different, since the ones in
  this file are the interpretation of the person who did the
  disassembly.
 
  bluedino - 4 hours ago
  Yes, the original NES games were written in assembler. However,
  the source probably didn't look quite like this. I'd guess the
  assembler of the time didn't have as many features or things like
  long label names.Here's some  actual Atari 7800 (a less popular
  console from the same generation) code that was found on disks in
  a dumpster when some Atari offices closed. They both use a
  6052-based CPU but have very different sound/graphics chips. I'd
  bet the NES code looked a lot more like this -
  https://github.com/OpenSourcedGames/Atari-7800
 
  aquova - 4 hours ago
  Yes, all old NES games were written in 6502 assembly (named after
  the NES's 6502 processor), and even most games into the Super
  Nintendo and Game Boy days were written using assembly
  language.The source would've looked very similar to this,
  although I can assume the original labels would've been in
  Japanese. The difficulty in creating a disassembly like this
  isn't converting the machine code back into assembly, which can
  be done rather simply, but instead re-adding all the label names,
  which are lost when the game is built. It's quite the
  undertaking, and the author must know the complete game back to
  front.
 
    gp2000 - 2 hours ago
    I imagine the original labels would have been in English.  The
    assembly source code I've seen for Japanese games has variables
    and labels in English with Japanese comments in Shift-JIS.  I
    would guess the choice was forced because the assembler,
    linker, debugger or other tools did not support Shift-JIS
    properly.  Often labels are restricted to 6 bytes which would
    be 3 Japanese characters.  Perhaps such a limit was also a
    factor.
 
    bluedino - 3 hours ago
    For another interesting read there's the guy that disassembled
    Robotron, and traced the code out by hand across 512 printed
    pages of assembly and fixed 2 long-standing bugs.http://www.rob
    otron2084guidebook.com/technical/christianging...
 
    Pulcinella - 4 hours ago
    Yes I believe on the Genesis most games were written in
    assembly as well. Sonic Spinball was written in a ?high level
    language? (i.e. C) and so it only runs at 30 FPS instead of 60.
 
  khedoros1 - 4 hours ago
  > Would the original game have been written in assembly? And if
  so, would the source have looked similar to this?Yes, and
  probably somewhat. The programmers were Japanese, so variable
  names would almost certainly be different, and the assembler this
  code was written for is actually for the CPU in the Super
  Famicom/SNES, so although I'm not sure when the assembler was
  written, it certainly wasn't around in 1984 when this game was
  being written. I think that the notation style is based on
  Nintendo's system development documentation, though.The NES would
  actually be a good place to look at some assembly, at least to
  get a basic idea of how it works. There aren't many operations,
  they're pretty easy to understand. There are only a few
  registers, and no layers of historic cruft layered on top ofit.
  The same (well, very close) CPU was used in a lot of computers
  from the same era:
  https://en.wikipedia.org/wiki/MOS_Technology_6502#Computers_...
 
justin_ - 1 hours ago
I remember using this disassembly many years ago when writing a
little NES emulator. Having a reference available for a popular
game is incredibly useful.Here's one of my favorite parts:
https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L942The
byte here is for the BIT instruction, but why is it just a lonely
byte? Well, the BIT instruction in this case also includes the two
following bytes. When the game processes that instruction, the `ldy
#$04` is swallowed up as part of the BIT instruction, effectively
skipping over it. IIRC this was a pretty common trick used among
6502 programmers. It allows you to jump ahead over the next (2byte)
instruction with just a single byte!