Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Test Build

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run tests
run: ./build.sh test
3 changes: 0 additions & 3 deletions .travis.yml

This file was deleted.

83 changes: 52 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
# Super Mario Bros. 2, Discombobulated

[![Logo](tools/logo.png "Logo")](https://xkeeper0.github.io/smb2)\
A disassembly of Super Mario Bros. 2.

This project is intended to fully disassemble, comment, and understand
everything about the game *Super Mario Bros. 2* on the NES. In addition to the
everything about the game _Super Mario Bros. 2_ on the NES. In addition to the
disassembly, there is also [documentation about the game's formats](https://xkeeper0.github.io/smb2),
though those are more of a work in progress than the disassembly.

As an added bonus, a fully understood disassembly will also make modifying and
changing the game easier!

----
---

## Building

This is designed for use with [asm6f](https://github.com/freem/asm6f/).
For your convenience, binaries of that have been included. (Windows/Linux)
For your convenience, Windows and Linux binaries of that have been included.

[![Build Status](https://travis-ci.com/Xkeeper0/smb2.svg?branch=asm6)](https://travis-ci.com/Xkeeper0/smb2)
[![Build Status](https://github.com/kmck/smb2/actions/workflows/test.yml/badge.svg)](https://github.com/kmck/smb2/actions/workflows/test.yml)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[![Build Status](https://github.com/kmck/smb2/actions/workflows/test.yml/badge.svg)](https://github.com/kmck/smb2/actions/workflows/test.yml)
[![Build Status](https://github.com/Xkeeper0/smb2/actions/workflows/test.yml/badge.svg)](https://github.com/Xkeeper0/smb2/actions/workflows/test.yml)

if you wanted to make sure the badge reflected with the main upstream, but nbd if you leave it as-is


### Windows

Open a command prompt window and run:

build (builds PRG0)
Expand All @@ -31,56 +33,75 @@ It will then output the SHA-256 hashes of PRG0 and PRG1, as well as the SHA-256
hash of the assembled ROM, useful if you intend to keep a one-to-one build.

### Linux, etc

A version of `asm6f` built under Ubuntu has been included under `tools/`.
To build, run the following command:

./build.sh (builds PRG0)
./build.sh -dREV_A (builds PRG1)
./build.sh -dSM_USA (builds Super Mario USA)
./build.sh test (builds both PRG0 and PRG1, verifying they match)
./build.sh (builds PRG0)
./build.sh -dREV_A (builds PRG1)
./build.sh -dSM_USA (builds Super Mario USA)
./build.sh test (builds both PRG0 and PRG1, verifying they match)

The build script will also display a message if the built ROM's SHA-256 hash
matches either PRG0 or PRG1.

#### macOS

Since there is no readily-available distrubition of `asm6f`, the most
straightforward thing is is to clone the repo and build from source.

```shell
# Get the source code
cd ~/Code # or wherever you like to organize your projects
git clone git@github.com:freem/asm6f.git
cd asm6f
# Build the binary--you might to run xcode-select --install
make
# Assuming build succeeded, symlink to a convenient spot in your PATH
ln -s ~/Code/asm6f/asm6f /usr/local/bin/asm6f
```

### Output

The build process will generate a few files:

* `bin/smb2.nes`, your assembled ROM.
* `bin/smb2.lst`, the assembler listing. Use this to see how the code assembled.
* `bin/assembler.txt`, the log from the assembler
* `bin/smb2.*.nl`, name-listing files for FCEUX's debugger.
* Some other cruft, probably. welp
- `bin/smb2.nes`, your assembled ROM.
- `bin/smb2.lst`, the assembler listing. Use this to see how the code assembled.
- `bin/assembler.txt`, the log from the assembler
- `bin/smb2.*.nl`, name-listing files for FCEUX's debugger.
- Some other cruft, probably. welp

**By default, the build script will create a byte-for-byte copy of the game**,
matching these two SHA-256 hashes:

* PRG0: `47ba60fad332fdea5ae44b7979fe1ee78de1d316ee027fea2ad5fe3c0d86f25a`
* PRG1: `6ca47e9da206914730895e45fef4f7393e59772c1c80e9b9befc1a01d7ecf724`
- PRG0: `47ba60fad332fdea5ae44b7979fe1ee78de1d316ee027fea2ad5fe3c0d86f25a`
- PRG1: `6ca47e9da206914730895e45fef4f7393e59772c1c80e9b9befc1a01d7ecf724`

You can edit `config.asm` to change some build options; see that file for details.

## Assembly

The "source" lives in the `src` directory:

* `prg-x-x.asm` are the program banks. They are grouped in pairs, as that is how
- `prg-x-x.asm` are the program banks. They are grouped in pairs, as that is how
SMB2 loads them. If you want to change this, you will need to split them apart again.
* `defs.asm` defines various enums and identifiers.
* `ram.asm` contains labels and definitions for RAM addresses.
* `extras/` contains some additional fun things (see `config.asm`).
* `levels/` contains level and enemy data.
* `music/` contains music and sound data.
* This list is growing as we split the disassembly into smaller parts.

- `defs.asm` defines various enums and identifiers.
- `ram.asm` contains labels and definitions for RAM addresses.
- `extras/` contains some additional fun things (see `config.asm`).
- `levels/` contains level and enemy data.
- `music/` contains music and sound data.
- This list is growing as we split the disassembly into smaller parts.

## Contributing
* Fork the repository.
* Make changes.
* Submit a pull request!
* You are also encouraged to visit the [Discord server](https://discord.gg/TsWMMeV)
if you have any questions.

- Fork the repository.
- Make changes.
- Submit a pull request!
- You are also encouraged to visit the [Discord server](https://discord.gg/TsWMMeV)
if you have any questions.

## See Also
* [Data Crystal's SMB2 page](http://datacrystal.romhacking.net/wiki/Super_Mario_Bros._2)
* [CaptainSouthbird's SMB3 disassembly](https://github.com/Drakim/smb3) and [Drakim's asm6f version](https://github.com/Drakim/smb3)
* [Our Discord server](https://discord.gg/TsWMMeV)

- [Data Crystal's SMB2 page](http://datacrystal.romhacking.net/wiki/Super_Mario_Bros._2)
- [CaptainSouthbird's SMB3 disassembly](https://github.com/Drakim/smb3) and [Drakim's asm6f version](https://github.com/Drakim/smb3)
- [Our Discord server](https://discord.gg/TsWMMeV)
13 changes: 11 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,20 @@ SM_USA="c63bacd07cf0d2336e8a4f9b9c556d0758629f102211d989d92495e117a8b3a0"


compareHash() {
echo $1 $2 | sha256sum --check > /dev/null 2>&1
expected_hash="$1"
file="$2"
actual_hash=$(sha256sum "$file" 2>/dev/null | cut -d' ' -f1)
[ "$expected_hash" = "$actual_hash" ]
}

build() {
tools/asm6f smb2.asm -n -c -L bin/smb2.nes "$@" > bin/assembler.log
# Try to use asm6f from PATH first (local/macOS)
if command -v asm6f > /dev/null 2>&1 ; then
asm6f smb2.asm -n -c -L bin/smb2.nes "$@" > bin/assembler.log
# Fall back to tools/asm6f (Linux-only)
else
tools/asm6f smb2.asm -n -c -L bin/smb2.nes "$@" > bin/assembler.log
fi
}


Expand Down
10 changes: 7 additions & 3 deletions src/defs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ TransitionType_Rocket = $05

; ---------------------------------------------------------------------------

CrouchJumpTimerMax = $3C

; ---------------------------------------------------------------------------

; enum Characters
Character_Mario = $00
Character_Princess = $01
Expand Down Expand Up @@ -183,7 +187,7 @@ ScreenUpdateBuffer_RAM_EraseBonusMessageTextUnused = $11
ScreenUpdateBuffer_WarpToWorld = $12
ScreenUpdateBuffer_RAM_ContinueRetryBullets = $13
ScreenUpdateBuffer_RAM_EndOfLevelDoor = $14
ScreenUpdateBuffer_TitleCardLeftover = $15
ScreenUpdateBuffer_TitleCardCharacterSelectMask = $15
ScreenUpdateBuffer_PauseExtraLife = $16
ScreenUpdateBuffer_RAM_BonusChanceLayout = $17

Expand Down Expand Up @@ -258,7 +262,8 @@ SpriteAnimation_WalkingCarrying = $01
SpriteAnimation_Standing = $02
SpriteAnimation_StandingCarrying = $03
SpriteAnimation_Ducking = $04
SpriteAnimation_5 = $05
SpriteAnimation_DuckingCarrying = $05
SpriteAnimation_5 = $05 ; Ducking while carrying...?
SpriteAnimation_Jumping = $06
SpriteAnimation_Dead = $07
SpriteAnimation_Pulling = $08
Expand Down Expand Up @@ -311,7 +316,6 @@ Stack100_Gameplay = %11000000 ; normal gameplay
; ---------------------------------------------------------------------------

; enum PPUControl (bitfield) (width 1 byte)
PPUCtrl_BaseAddress = $03
PPUCtrl_Base2000 = $00
PPUCtrl_Base2400 = $01
PPUCtrl_Base2800 = $02
Expand Down
Loading