Behind the Code Examines The NES Punch-Out!! Boxer Engine

Here’s another of those deep-dive NES internal videos from Behind the Code, possibly the most complex one they’ve done to date. Most game engines, when you examine their basic logic, are basically physics simulations, with some AI included to determine how actors behave.

Not so with the Punch-Out!! games. They are essentially entirely different kinds of games from that. You have certain things you can do moment to moment, and opposing boxers do too. Each of those opponents basically runs a big script, made out of byte code, that determines their behavior throughout each round of each fight. I am struck both by the simplicity (no need to simulate gravity) and the complexity (boxers take all kinds of things into account) of the system.

One of the interesting things shown is that the engine can affect more than just the boxers, but can also subtly affect the crowd, which is how the previously-revealed fact that a specific camera person in the crowd uses his flash right at the moment the player must counter Bald Bull’s charge move. It turns out that this isn’t the only instance of this happening in the game!

You don’t need to know 6502 assembly code to get what the narrator is talking about, but a lot of code is shown, so those of you who understand it may get a bit more out of it. Here are a few basics to help you follow along.

The 6502 has only three registers (bits of memory internal to the CPU that can be accessed quickly), the Accumulator (sometimes called just A), the X register, and the Y register. Each is only one byte long. The Accumulator is by far the most flexible, but all three are general-purpose registers. The most common instructions are Loads (LDA, LDX, LDY), Stores (STA, STX, STY), Transfers between registers (TAX, TAY), Incrementing and Decrementing (INX, INY, DEX, DEY), Adding (ADC), Subtracting (SBC), Comparing (CMP), Branches (some of them, Branch Not-Equal to Zero: BNE, Branch Equal to Zero: BEQ, Branch of Carry Set: BCS, Branch on Carry Clear: BCC), Jump (JMP), Jump to Subroutine (JSR), and Return from Subroutine (RTS). While some instructions are just one byte long, the longest any 6502 instruction can be is three bytes, and the opcode (the command itself) is always just one.

(I wrote all of that from memory. I figured, I have all of this in my head from my coding youth, I might as well use some of it.)

The 6502 can only address 64K of memory, so often systems will use bank switching to connect various memories to it within that space. The great majority of NES/Famicom games had to do this. Punch-Out!! was unique on the NES in that it was the only game to use Nintendo’s MMC2 chip. (I wonder if the chip was designed ahead of time, and they made this game as an excuse to use it?) Punch-Out!! uses MMC2 to bank in each boxer’s large data script as needed.

Behind The Code: How Do Boxers Work in Mike Tyson’s Punch-Out!!? (Youtube, 20 minutes)

Vision BASIC for the Commodore 64

The Commodore 64 was, for its time, quite a wonder, an inexpensive home computer with 64K of RAM and excellent for its time graphics and sound capabilities. Sadly, it came with one of the more limited versions of Microsoft BASIC out there.

Microsoft BASIC had its strengths, but many of them were not a good match for its hardware. The C64 had no commands to take advantage of any of its terrific features. To do nearly anything on the machine besides PRINTing and manipulating data, you had to refer to a small number of cryptic-yet-essential commands: POKE for putting values into arbitrary memory addresses, PEEK for reading values out of them, READ and DATA to read in lists of numbers representing machine language routines, and SYS to activate them.

And getting the values to do those things required obtaining and poring over manuals and the venerable C64 Programmer’s Reference Guide. Even then, Microsoft BASIC was notably slow, especially when doing work with numbers, due to its dogged insistence of converting all values, including integers, into floating point before doing any math on them. So while BASIC supported integers, which required less memory to store, actually slowed the machine down due to the need to convert to and from floating point whenever an operation needed to be performed on them. This doesn’t even begin to get into the many inefficiencies of being an interpreted language.

Vision BASIC, an upcoming commercial compiled language for the Commodore 64, looks to remedy many of these faults. The above video is a nearly 40-minute explainer and demonstration of the system. It requires the purchase of a memory expansion unit in order to be used on a physical machine, but it can produce executable code that can be run on a stock C64 as it came out of the box.

It’s not free, and at $59 for the basic package it may seem a little high for a system for developing software on a 40-year-old computer, but that price includes the software on floppy disk and a USB drive. It’s certainly capable, and runs much faster than many other compiled languages on the system. It’s definitely something to look into for people looking to make games on the system without digging deep into assembly, and if you have a desire to do that it has a built-in assembler for producing in-line machine code too! It is an intriguing new option for Commodore development.