Dr. Mario (NES)
Nintendo's 1990 falling-block game for the NES, in which two-colored pills clear viruses from a bottle, read through Nostaljipi's disassembly.
The atlas reads Dr. Mario through Nostaljipi’s dr-mario-disassembly. With its clean-up options off, it builds the No-Intro Rev 1 ROM byte for byte1. Its labels, such as speedCounterTable, are the disassembler’s names. Nothing here has been measured in the running game yet.
#Pills and viruses
A level’s virus count is (level + 1) × 4, up to 84 for player 12. They’re placed so that no virus has one of its own color two cells away in a straight line2. Pills aren’t picked as they’re needed. At the start of a level the piece randomizer deals a reserve of 128 pills from 9 color pairs3, each one a step from the last, and both players draw from the same reserve3. The 129th pill is the first again. The step makes repeats more likely than chance: a pill follows itself 1 time in 84, where a uniform pick would give 1 in 94.
#Falling
Drop speed comes from one table. The speed setting picks the starting point, 40, 20, or 14 frames per row at Low, Med, or Hi5, and every 10th pill moves a step further down the table, to as little as 4, 2, or 1 frames per row after 49 steps6. Holding Down alone drops the pill a row every 2 frames7. A pill that can’t fall locks at once8.
Delayed auto shift moves a held pill after 16 frames, then every 69, the numbers of NES Tetris10. A blocked shift leaves the pill charged11.
In one-player games each new pill waits for Mario to throw it into the bottle. The throw’s path has 2112 positions, and on Low it moves at half speed12.
#Clearing
Four or more cells of one color in a row or a column clear, viruses included13. Halves left without support then fall, and the checks run again, so one pill can set off a chain14. Each virus a pill clears is worth double the one before it, up to 32 times the first: 100, 200, 400, 800, 1,600, then 3,200 points at Low, through the 11th virus15, and twice or three times that at Med or Hi. Past the 11th virus the multiplier reads beyond its table15. In a two-player game a pill that makes two or more matches drops loose halves onto the other player’s bottle16.
Cartridge
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Drop speed | Piece ramp | Low, Med, or Hi sets the start, and every 10th pill speeds it up a step |
| Delayed auto shift | Delay, then repeat | 16 frames, then every 6; a blocked shift stays charged |
| Piece randomizer | Dealt in advance | 128 pills dealt at the start of each level, shared by both players and repeated in a loop |
| Entry delay | Animation | in one-player games each pill waits for Mario's throw, which runs at half speed on Low |
| Clearing | Line of four | four or more cells of one color in a row or a column |
| Chain | Cascade | freed halves fall and are checked again; each virus from one pill scores double the one before, up to 32 times the first |
| Garbage | Dropped on top | two or more matches from one pill drop 2 to 4 loose halves on the other bottle |
| Lock delay | None | a pill that can't fall locks at its next gravity step |
Every claim about this game, by concept (16)
References
- ^With
completeCleanup = 0andver_revA = 1, the disassembly builds the No-Intro Dr. Mario (Japan, USA) (Rev 1) ROM byte for byte, apart from its 16-byte header.CodeNostaljipi/dr-mario-disassembly · “Dr. Mario (Japan, USA) (Rev 1)”How we know
2completeCleanup = 1 ;Set to 1 to set all build config optionsbuild_config.asm line 2 at ecb9899 · upstream ↗ 24ver_revA = 1 ;Set only one of these to 1build_config.asm line 24 at ecb9899 · upstream ↗ In the cartridge (“Dr. Mario (Japan, USA) (Rev 1)”): the header the comparison skips. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abA 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.CodeNostaljipi/dr-mario-disassemblyrevised
How we know
133 lda p1_level ;Then perform some calculations to find how many viruses to add ⋮ 139 lda #selectableLvCap ;And use the level cap as basis for virus quantity ⋮ 141 clc ;Nb of virus = (lvNb + 1) * 4
prg/drmario_prg_level_init.asm lines 133–145 at ecb9899 · upstream ↗ 146 lda p2_level ;No need to check level cap for player 2prg/drmario_prg_level_init.asm line 146 at ecb9899 · upstream ↗ 3080 and #lastRow ;Maxout at 16 ⋮ 3083 lda addVirus_maxHeight_basedOnLvl,X ⋮ 3085 bcc @getValidHeight ;New random number if height is over the max
prg/drmario_prg_game_logic.asm lines 3080–3085 at ecb9899 · upstream ↗ 3099 lda currentP_virusToAdd ;This here is to ensure for evey 4 viruses, there are guaranteed 1 for each color. The 4th virus is random. 3100 and #virusRndMask 3101 sta virusColor 3102 cmp #virusRndColor
prg/drmario_prg_game_logic.asm lines 3099–3102 at ecb9899 · upstream ↗ 3290 dec currentP_virusToAddprg/drmario_prg_game_logic.asm line 3290 at ecb9899 · upstream ↗ 230yellow = $00 231red = $01 232blue = $02
defines/drmario_constants.asm lines 230–232 at ecb9899 · upstream ↗ 50virusRndMask = $02 + rndColorQtydefines/drmario_constants.asm lines 49–51 at ecb9899 · upstream ↗ 3224 cmp #%00000111 ⋮ 3232 and virusColorVerif ;If virus color is not present at 2 of distance in any direction, we have a valid virus to add ⋮ 3234 dec virusColor ;Otherwise, cycle through other colors
prg/drmario_prg_game_logic.asm lines 3224–3234 at ecb9899 · upstream ↗ selectableLvCap = $14
defines/drmario_constants.asm#L11 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^ abAt the start of each level
generatePillsReservedeals 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.CodeNostaljipi/dr-mario-disassemblyHow we know
170 lda #pillsReserveSize ;Equals to the number of pills to generate ⋮ 180 dex 181 lda rng0 ;Max the rng value at 15 182 and #$0F ⋮ 184 adc pillId ⋮ 187 cmp #colorCombination_right - colorCombination_left 188 bcc @storePill ;If within the array size (9), is a valid pill index ⋮ 191 sbc #colorCombination_right - colorCombination_left ⋮ 194 sta pillsReserve,X ;Starts from the end of the array
prg/drmario_prg_level_init.asm lines 169–194 at ecb9899 · upstream ↗ 124 jsr generatePillsReserve ;Same reserve used by both playersprg/drmario_prg_level_init.asm line 124 at ecb9899 · upstream ↗ 464 ldx currentP_pillsCounter ;If not demo, then use the player's pill reserve 465 lda pillsReserve,X ⋮ 472 inc currentP_pillsCounter ;Increase the pills counter ⋮ 474 and #pillsReserveSize-1 ;Wraparound over $7F because we have a maximum of 128 pills stored
prg/drmario_prg_game_logic.asm lines 464–475 at ecb9899 · upstream ↗ 824colorCombination_left: 825.db $00,$00,$00,$01,$01,$01,$02,$02 826.db $02 827colorCombination_right: 828.db $00,$01,$02,$00,$01,$02,$00,$01 829.db $02
data/drmario_data_game.asm lines 824–829 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abBecause 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.CodeNostaljipi/dr-mario-disassembly
How we know
182 and #$0F 183 clc ;Add to index of previous pill (probably as a means to improve random) 184 adc pillId ⋮ 187 cmp #colorCombination_right - colorCombination_left ⋮ 191 sbc #colorCombination_right - colorCombination_left 192 jmp @checkIfValidIndex
prg/drmario_prg_level_init.asm lines 182–192 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^
fallingPill_checkYMovecounts frames at the pill's row and drops it when the count passes an entry ofspeedCounterTable, 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.CodeNostaljipi/dr-mario-disassemblyHow we know
242 inc currentP_speedCounter ;Down not pressed, get amount of frames (speed counter) spent at this vertical position so far ⋮ 246 lda baseSpeedSettingValue,X ⋮ 248 adc currentP_speedIndex ⋮ 250 lda speedCounterTable,X 251 cmp currentP_speedCounter ;The speed counter must be over the data in the table for the gravity to occur 252 bcs @exit_fallingPill_checkYMove
prg/drmario_prg_game_logic.asm lines 242–252 at ecb9899 · upstream ↗ 254 dec currentP_fallingPillY ;Decrease the pill's y position 255 lda #$00 ;Reset the speed counter 256 sta currentP_speedCounter
prg/drmario_prg_game_logic.asm lines 253–256 at ecb9899 · upstream ↗ 423.db $0F,$19,$1F ;Low ($0F = $27), Med ($19 = $13), Hi ($1F = $0D)data/drmario_data_game.asm lines 422–423 at ecb9899 · upstream ↗ 778speedCounterTable: 779if !ver_EU 780 .db $45,$43,$41,$3F,$3D,$3B,$39,$37 781 .db $35,$33,$31,$2F,$2D,$2B,$29,$27 ;Slowest actually starts at $27 (index $0F) 782 .db $25,$23,$21,$1F,$1D,$1B,$19,$17 783 .db $15,$13,$12,$11,$10,$0F,$0E,$0D
data/drmario_data_game.asm lines 778–789 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^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.CodeNostaljipi/dr-mario-disassemblyHow we know
534 lda currentP_pillsCounter_decimal ⋮ 537 and #$0F ;Every 10 pills, check if we speed up ⋮ 542 cmp #speedUps_max ;Prevents speed increase after 49 increases ⋮ 545 inc currentP_speedUps ;We speed up, play the associated sfx,
prg/drmario_prg_game_logic.asm lines 532–546 at ecb9899 · upstream ↗ 14speedUps_max = $31 ;Prevents speed increase after $31 (49) increasesdefines/drmario_constants.asm line 14 at ecb9899 · upstream ↗ 121 lda lvlsOver20 122 sta currentP_speedUps ;Starts 1 step further in speed table for each level over 20
prg/drmario_prg_level_init.asm lines 121–122 at ecb9899 · upstream ↗ 784 .db $0C,$0B,$0A,$09,$09,$08,$08,$07 ⋮ 787 .db $04,$04,$04,$04,$03,$03,$03,$03 788 .db $03,$02,$02,$02,$02,$02,$01,$01 789 .db $01,$01,$01,$01,$01,$01,$01,$01 790 .db $00
data/drmario_data_game.asm lines 784–790 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^Holding Down, and no other direction, drops the pill a row on every other frame, and the drop resets the gravity count.CodeNostaljipi/dr-mario-disassembly
How we know
233 lda frameCounter 234 and #fast_drop_speed ⋮ 239 cmp #btn_down ;This implies that ONLY down must be pressed on the d-pad for the fast drop to occur 240 beq @lowerPillY
prg/drmario_prg_game_logic.asm lines 233–240 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^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.CodeNostaljipi/dr-mario-disassembly
How we know
257 jsr pillMoveValidation ;Checks if move is valid, returns zero if valid 258 bne @pillHasLanded ;If can't move down anymore, the pill has landed ⋮ 263 inc currentP_fallingPillY ;Returns Y to its previous value because it couldn't be lowered ⋮ 266 jsr confirmPlacement ;"Print" (or "cement") the pill in position
prg/drmario_prg_game_logic.asm lines 257–266 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^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.CodeNostaljipi/dr-mario-disassemblyHow we know
298 inc currentP_horVelocity ;If held, we increase the horizontal velocity ⋮ 300 cmp #hor_accel_speed ;Takes 16 frames for initial build up of speed ⋮ 302 lda #hor_accel_speed - hor_max_speed ;Then it takes 6 frames for subsequent movements ⋮ 306 lda #$00 ;If btn was instead pressed, reset horizontal velocity
prg/drmario_prg_game_logic.asm lines 291–308 at ecb9899 · upstream ↗ 85 hor_accel_speed = $0D 86 hor_max_speed = $05
defines/drmario_constants.asm lines 81–87 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^Holding Left or Right moves the piece at once, again 16 frames later, and then every 6 frames; the press zeroes
autorepeatX, each held frame adds 1, and atDAS_RESET(16) the piece moves and the count drops toDAS_DELAY(10).VerifiedCelestialAmber/TetrisNESDisasm · Birken, "Applying AI to Nintendo Tetris" · “Tetris (USA)”How we know
89DAS_DELAY := $0A 90DAS_RESET := $10
constants.asm lines 89–90 at 94581c0 · upstream ↗ 1622 lda newlyPressedButtons 1623 and #BUTTON_LEFT+BUTTON_RIGHT 1624 bne @resetAutorepeatX 1625 lda heldButtons 1626 and #BUTTON_LEFT+BUTTON_RIGHT 1627 beq @ret 1628 inc autorepeatX 1629 lda autorepeatX 1630 cmp #DAS_RESET 1631 bmi @ret 1632 lda #DAS_DELAY 1633 sta autorepeatX ⋮
main.asm lines 1622–1638 at 94581c0 · upstream ↗ holding down one of those direction buttons causes the game to automatically shift the piece every 6 frames after an initial delay of 16 frames.
Shifting Tetriminos · archived copy ↗ In the cartridge (“Tetris (USA)”): shift_tetrimino, CPU $89AE. We don't reproduce the bytes.
Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Tetris (USA) (SHA-1
3026d28b63d9…). It fails if the result disagrees with the claim.The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^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.CodeNostaljipi/dr-mario-disassembly
How we know
328 @cantMove_right: 329 dec currentP_fallingPillX ;Restore the previous x value 330 lda #hor_accel_speed-1 ;This makes so that as soon as the pill can move, it will move without delay with regard to velocity
prg/drmario_prg_game_logic.asm lines 326–331 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abIn a one-player game each new pill waits for Mario's throw:
action_sendPillsteps 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.CodeNostaljipi/dr-mario-disassemblyHow we know
3546 lda nbPlayers 3547 cmp #$01 3548 beq @checkFrame_pillThrown 3549 jmp @pillThrown_toField ⋮ 3551 lda currentP_speedSetting ⋮ 3560 lda frameCounter 3561 and #spr_mario_throw_speed_low ;On Low speed setting, pill rotates only every other frame 3562 beq @exit_action_sendPill
prg/drmario_prg_game_logic.asm lines 3546–3562 at ecb9899 · upstream ↗ 3564 inc pillThrownFrame ⋮ 3566 lda pillThrownAnim_XPos,X 3567 cmp #$FF ;This value ends the anim 3568 beq @pillThrown_toField 3569 and #$F0 ;These values mean we update Mario's sprite anim, not just the pill ⋮ 3573 lda pillThrownAnim_XPos,X ⋮ 3576 jmp @incFrame_pillThrown
prg/drmario_prg_game_logic.asm lines 3564–3576 at ecb9899 · upstream ↗ 482pillThrownAnim_XPos: 483.db $BE,$F1,$BE,$BC,$B8,$B4,$F2,$B0 484.db $AC,$A8,$A4,$A0,$9E,$98,$94,$90 485.db $8C,$88,$84,$80,$7C,$7A,$78,$F0 486.db $78 487.db $FF ;End of data
data/drmario_data_game.asm lines 482–487 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^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.CodeNostaljipi/dr-mario-disassembly
How we know
15match_length = $04 ;Length of color chain required for a matchdefines/drmario_constants.asm line 15 at ecb9899 · upstream ↗ 1141 @noMatchInMemory: 1142 lda #$00 1143 sta fieldPos ;Will check field pos from top left to bottom right, row after row ⋮ 1145 lda fieldPos ⋮ 1149 ldy fieldPos 1150 lda (currentP_fieldPointer),Y ⋮ 1157 and #mask_fieldobject_color ⋮ 1159 @checkHorColorChain_loop: 1160 inc fieldPos_tmp ;Checks next horizontal 1161 lda fieldPos_tmp 1162 and #lastColumn ;Check if reached right end of bottle 1163 beq @horColorChainBroken ⋮
prg/drmario_prg_game_logic.asm lines 1141–1170 at ecb9899 · upstream ↗ 1171 @horColorChainBroken: ⋮ 1173 cmp #match_length-1 ;Checks if enough for a match (does not include the starting color, which explains the "-1") ⋮ 1176 inc currentP_comboCounter ;Increase combo counter and store color chain length
prg/drmario_prg_game_logic.asm lines 1171–1176 at ecb9899 · upstream ↗ 27 .word checkDrop 28 .word resetMatchFlag 29 .word checkHorMatch 30 .word checkVerMatch 31 .word updateField
prg/drmario_prg_game_logic.asm lines 26–31 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-25.
Checked by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^When a clear happens,
updateFieldsends the placed pill's steps back tocheckDrop, which lets unsupported halves fall, and the match checks run again, so one pill can set off a chain of clears.CodeNostaljipi/dr-mario-disassemblyHow we know
1478 lda currentP_matchFlag ;Check if there was a match (and thus if we need to process drops and further field update) ⋮ 1481 lda #pillPlaced_nextStep1 ;If there was a match, we need to update the field again to process the impacts of this match (ex: pill drops) ⋮ 1485 sta currentP_pillPlacedStep
prg/drmario_prg_game_logic.asm lines 1478–1486 at ecb9899 · upstream ↗ 71checkDrop: ⋮ 80 ldy #lastFieldPos 81 sty fieldPointerOffset ;Starts at the end and goes backward ⋮ 83 ldy fieldPointerOffset 84 lda (currentP_fieldPointer),Y 85 cmp #fieldPosJustEmptied ;If not empty, then no drop possible ⋮ 90 sta (currentP_fieldPointer),Y ⋮ 101 sbc #rowSize ;Substract 1 row to check what's on top ⋮ 103 lda (currentP_fieldPointer),Y ⋮ 122 lda (currentP_fieldPointer),Y 123 cmp #fieldPosJustEmptied ;If not empty, then no drop possible ⋮ 128 lda (currentP_fieldPointer),Y ⋮
prg/drmario_prg_game_logic.asm lines 71–149 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-25.
Checked by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^ abIn 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.CodeNostaljipi/dr-mario-disassemblyrevised
How we know
694 bne @exit_scoreIncrease ;No score increase if 2 players 695 ldx currentP_scoreMultiplier ;Problem here is that the score combo multiplier is not capped, and so it can overflow 696 if bugfix ⋮ 702 lda scoreMultiplier_table,X ⋮ 705 lda currentP_speedSetting ;Score is impacted by speed setting (Low = 100, Med = 200, Hi = 300) ⋮ 716 inc currentP_scoreMultiplier
prg/drmario_prg_game_logic.asm lines 691–716 at ecb9899 · upstream ↗ 266scoreMultiplier_table: 267.db $01,$02,$04,$08,$10,$20,$20,$20 268.db $20,$20,$20
data/drmario_data_game.asm lines 266–268 at ecb9899 · upstream ↗ 40resetCombo: ⋮ 42 sta currentP_scoreMultiplier
prg/drmario_prg_game_logic.asm lines 39–44 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^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.CodeNostaljipi/dr-mario-disassembly
How we know
2875 lda currentP_comboCounter 2876 cmp #attackSize_min ;Threshold for an attack ⋮ 2879 adc currentP_attackSize ;Otherwise, add combo counter value to current attack size
prg/drmario_prg_game_logic.asm lines 2874–2879 at ecb9899 · upstream ↗ 1550 cmp #attackSize_max+1 ;Any combo that goes over 4 does not register any more attacks ⋮ 1554 lda startingColor ;Latest match color is used to send opponent 1555 sta currentP_attackColors,X
prg/drmario_prg_game_logic.asm lines 1550–1555 at ecb9899 · upstream ↗ 2902 lda p1_attackSize,X 2903 cmp #attackSize_min 2904 bcc @noAttack ;If attack size below minimum, no attack ⋮ 2907 lda frameCounter 2908 and #attackSize_2_pos ;Position of attack is based on frame
prg/drmario_prg_game_logic.asm lines 2902–2908 at ecb9899 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
Sources
Code
- Nostaljipi. 2021. “Dr. Mario (NES) Disassembly.” Commit ecb9899. Nostaljipi/dr-mario-disassembly @ ecb9899 · licence, all uses
- 1990. “Dr. Mario (Japan, USA) (Rev 1).” · licence, all uses
- (CelestialAmber), Amber Brault and contributors. 2024. “TetrisNESDisasm: a disassembly of Tetris (NES).” Commit 94581c0. CelestialAmber/TetrisNESDisasm @ 94581c0 · licence, all uses
- 1989. “Tetris (USA).” · licence, all uses
Secondary
- Birken, Michael. 2014. “Applying Artificial Intelligence to Nintendo Tetris.” original · archived · licence, all uses