Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Minesweeper For the Gameboy

screenshot from bgb gameplay from bgb

Built mostly ground up in assembly, my take on the classic game of minesweeper. I followed the excellent "hello world" examples by Witchita State University. These begin with displaying a set of tiles on the Gameboy's screen and include moving a character on the screen and working with noise / music. They also include an introduction (by example) of RGBDS's asm and macro syntax.

Play minesweepGB

To play minesweepGB, simply load the file with your favorite emulator

Compile minesweepGB

To compile, run these commands (linux):

rgbasm -o play_minesweep.obj minesweepGB.asm
rgblink -o play_minesweep.obj
rgbfix -v -p0
rm play_minesweep.obj



Freakin' awesome macros. I've seen it said that RGBDS has amazing macro support. And it's true, but its syntax is very terse. Minesweep contains some powerful macros that make reading assembly MUCH easier. Check out to see some excellent macros that make readable assembly. My Favorite: IFA

ifa	<, 32,	ld a, 32

Which can be read as "if A < 32, load A with 32"

IFA is used (in this case) to run this psuedo-code: a = max(a, 32). In assembly, the above macro expands to:

cp	32
jr	nc, .skip
ld	a, 32

A nice, short article on writing readable assembly through macros

In addition, I've built several macros designed for making other macros more readable. Both and are built to enable the developer to test the type of inputs (register, register-pair, or number) each argument is. It's a readable way to fail (and let the developer know) if an argument is incorrectly supplied. (Because with macros, not checking arguments can lead to lots of silent bugs). An example of asserting an argument is a single register:

    IF STRIN("A.B.C.D.E.H.L", STRUPR("\2")) == 0
        FAIL    "arg2 needs to be a register. Got \2."

We can improve it using a string expansion macro from

        FAIL    "arg2 needs to be a register. Got \2."

or we can improve it further using an assertion from

ASSERT_IS_REGISTER \2, "arg2 needs to be a register. Got \2."

Responsive, silky-smooth gameplay

Minesweep uses hardware interrupts and careful state management to number crunch and reveal areas on the minefield without sacrificing player-input response time. The effect is split-second minefield reveal with no lag to keypresses. It's as "multi-threaded" as possible on a single-core cpu. The cursor remains responsive throughout and features smooth scrolling between locations.


Minesweeper is all about matrix-operations. The matrix.asm module makes it easy to use a block of memory as a matrix. A sub-matrix iterator can even be used to iterate over a subsection of a larger matrix (such as the minefield). Considering how the gameboy's own VRAM is really a 32x32 matrix, I've also used it extensively in writing to the screen.


A Test-Suite built to test the code and features I've written. Extensive (but not 100% coverage) testing of matrix operations, stack operations, math operations, and / macro features. I test some well-used macros such as negate, ifa, increment/decrement, and math_Mult to name a few.

To run the tests yourself, compile test_main.asm just like you would do with minesweepGB.asm, and then run within bgb. Once run, if all tests pass, you should see a screen partially-filled with #'s and letters indicating specific tests passed. If you should see a '-', then a test has failed, and the game has paused testing until a button is pressed (a gameboy-button, not just a random keyboard key. [Enter] ought to work).

No Music

(sorry guys). A feature planned in the distant future, perhaps.


minesweeper for the GameBoy (Color compatible), written in assembly







No releases published


No packages published