Cite as
Nostaljipi/dr-mario-disassembly
Original
https://github.com/Nostaljipi/dr-mario-disassembly
Pinned
Nostaljipi/dr-mario-disassembly @ ecb9899554d6d4c0c866be5dd6c0f40b7b117806
Accessed
2026-10-21
Licence
none stated
Credit
Disassembly by Nostaljipi. Its README thanks Sour, author of the Mesen emulator, and the contributors to the Dr. Mario articles on Data Crystal and The Cutting Room Floor.
Notes
Builds with asm6f. build_config.asm selects the Rev A, Japan/USA, or European build, and ships with completeCleanup = 1, which switches on the author's bug fixes and optimizations. With completeCleanup = 0 and ver_revA = 1 it builds the No-Intro Rev 1 ROM byte for byte apart from the 16-byte header (checked 2026-10-21 by building with asm6f from .cache/repos/asm6f). Claims follow that original build, so `if !optimize` and `if !bugfix` paths are the ones in the ROM. Line numbers refer to files under prg/, data/, and defines/ at the pinned commit. The labels (generatePillsReserve, speedCounterTable, hor_accel_speed, …) and the comments are the disassembler's, not Nintendo's.

Cited on

Claims (16)

Dr. Mario's cartridge ROM, counted by part of the game: each stretch of code or data goes to the part the disassembly's labels and comments say it serves, and the value sums the bytes of each part.drmario.asmCode notes
With completeCleanup = 0 and ver_revA = 1, the disassembly builds the No-Intro Dr. Mario (Japan, USA) (Rev 1) ROM byte for byte, apart from its 16-byte header.build_config.asm L2build_config.asm L24Code
fallingPill_checkYMove counts frames at the pill's row and drops it when the count passes an entry of speedCounterTable, so a row takes the entry plus one frame. The speed setting picks the starting entry, index 15, 25, or 31 for Low, Med, and Hi, which is 40, 20, or 14 frames per row; entries 0 to 14 are never reached.prg/drmario_prg_game_logic.asm L242–252prg/drmario_prg_game_logic.asm L253–256data/drmario_data_game.asm L422–423data/drmario_data_game.asm L778–789Code
Every 10th pill moves the speed one step further along speedCounterTable, up to 49 steps, and each level past 20 starts a step further. After 49 steps a row takes 4 frames at Low, 2 at Med, and 1 at Hi, the table's last entry.prg/drmario_prg_game_logic.asm L532–546defines/drmario_constants.asm L14prg/drmario_prg_level_init.asm L121–122data/drmario_data_game.asm L784–790Code
Holding Down, and no other direction, drops the pill a row on every other frame, and the drop resets the gravity count.prg/drmario_prg_game_logic.asm L233–240Code
When a drop is blocked, the pill moves back up and is placed in the bottle at once, so a pill resting on the stack locks at its next gravity step.prg/drmario_prg_game_logic.asm L257–266Code
A press of Left or Right moves the pill at once and zeroes currentP_horVelocity; held, the count rises each frame and at 16 the pill moves and the count restarts at 10, so it moves again 16 frames after the press and then every 6. The European build uses 13 and 5.prg/drmario_prg_game_logic.asm L291–308defines/drmario_constants.asm L81–87Code
A blocked shift sets the count to 15, so a pill held against a wall or the stack moves on the first frame the way is clear.prg/drmario_prg_game_logic.asm L326–331Code
At the start of each level generatePillsReserve deals 128 pills, shared by both players. Each pill is one of 9 color pairs, found by adding a random 0 to 15 to the previous pill's index and subtracting 9 until it fits; the game reads the reserve in a loop, so the same 128 pills come round again.prg/drmario_prg_level_init.asm L169–194prg/drmario_prg_level_init.asm L124prg/drmario_prg_game_logic.asm L464–475data/drmario_data_game.asm L824–829Code
Because the 16 random values wrap at 9, steps of 0 to 6 from the previous pill's index each come from two values and steps of 7 and 8 from one, so the same pill follows itself with chance 2/16, where a uniform pick would give 1/9.prg/drmario_prg_level_init.asm L182–192Code
A level holds (level + 1) × 4 viruses; for player 1 levels past 20 count as 20, while player 2's count is uncapped. The count of viruses still to add runs down, and its low two bits pick the color (0 yellow, 1 red, 2 blue, 3 a color from a 16-entry table), so each run of four from a multiple of 4 goes yellow, random, blue, red. Each virus goes at a random height no higher than the level allows and a random column, moving on to the next free cell, and takes another color if one of its own lies two cells away in a straight line.prg/drmario_prg_level_init.asm L133–145prg/drmario_prg_level_init.asm L146prg/drmario_prg_game_logic.asm L3080–3085prg/drmario_prg_game_logic.asm L3099–3102prg/drmario_prg_game_logic.asm L3290defines/drmario_constants.asm L230–232defines/drmario_constants.asm L49–51prg/drmario_prg_game_logic.asm L3224–3234defines/drmario_constants.asm L11Code
After a pill lands the game scans the bottle row by row for 4 or more cells of one color in a row, then column by column for 4 or more in a column, and clears every run it finds.defines/drmario_constants.asm L15prg/drmario_prg_game_logic.asm L1141–1170prg/drmario_prg_game_logic.asm L1171–1176prg/drmario_prg_game_logic.asm L26–31Code
When a clear happens, updateField sends the placed pill's steps back to checkDrop, which lets unsupported halves fall, and the match checks run again, so one pill can set off a chain of clears.prg/drmario_prg_game_logic.asm L1478–1486prg/drmario_prg_game_logic.asm L71–149Code
In a one-player game each virus cleared scores 100, 200, or 300 points at Low, Med, or Hi, times 1, 2, 4, 8, 16, then 32 for the 6th to 11th virus cleared by the same pill. The multiplier isn't capped (the clamp is one of the disassembler's bugfix options, not in the original build), so from the 12th virus on it indexes bytes past the end of the 11-entry table.prg/drmario_prg_game_logic.asm L691–716data/drmario_data_game.asm L266–268prg/drmario_prg_game_logic.asm L39–44Code
In a two-player game, 2 or more matches from one pill send that many half-pills, at most 4, in the colors of the matches, to the other player's bottle, where they land at its top row in a frame-dependent column.prg/drmario_prg_game_logic.asm L2874–2879prg/drmario_prg_game_logic.asm L1550–1555prg/drmario_prg_game_logic.asm L2902–2908Code
In a one-player game each new pill waits for Mario's throw: action_sendPill steps the pill along a table of 21 positions, once a frame at Med and Hi and on every other frame at Low, and puts it in the bottle when the table ends. In a two-player game the pill goes straight to the bottle.prg/drmario_prg_game_logic.asm L3546–3562prg/drmario_prg_game_logic.asm L3564–3576data/drmario_data_game.asm L482–487Code