On this page
  1. Pills and viruses
  2. Falling
  3. Clearing
  4. Cartridge
  5. Related
  6. Mechanics
  7. References
  8. Sources

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

Interactive: rom-parts (needs JavaScript)

64 KB, a cell per 512 bytes, from 263 mapped regions

Mechanics

MechanicKindHow
Drop speedPiece rampLow, Med, or Hi sets the start, and every 10th pill speeds it up a step
Delayed auto shiftDelay, then repeat16 frames, then every 6; a blocked shift stays charged
Piece randomizerDealt in advance128 pills dealt at the start of each level, shared by both players and repeated in a loop
Entry delayAnimationin one-player games each pill waits for Mario's throw, which runs at half speed on Low
ClearingLine of fourfour or more cells of one color in a row or a column
ChainCascadefreed halves fall and are checked again; each virus from one pill scores double the one before, up to 32 times the first
GarbageDropped on toptwo or more matches from one pill drop 2 to 4 loose halves on the other bottle
Lock delayNonea pill that can't fall locks at its next gravity step
Every claim about this game, by concept (16)
generalDr. 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.Code 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.Code
ChainWhen 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.Code
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.Code
ClearingAfter 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.Code
Delayed auto shiftA 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.Code
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.Code
Drop speedfallingPill_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.Code
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.Code
Holding Down, and no other direction, drops the pill a row on every other frame, and the drop resets the gravity count.Code
Entry delayIn 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.Code
GarbageIn 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.Code
Lock delayWhen 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.Code
Piece randomizerAt 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.Code
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.Code
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.Code

References

  1. ^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.CodeNostaljipi/dr-mario-disassembly · “Dr. Mario (Japan, USA) (Rev 1)”
    How we know
    2completeCleanup     = 1         ;Set to 1 to set all build config options
    
    build_config.asm line 2 at ecb9899 · upstream ↗
    24ver_revA            = 1         ;Set only one of these to 1
    
    build_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.

    In the claim ledger

  2. ^ 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 2     
    
    prg/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_virusToAdd
    
    prg/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 + rndColorQty
    
    defines/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.

    In the claim ledger

  3. ^ abAt 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.CodeNostaljipi/dr-mario-disassembly
    How 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 players
    
    prg/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.

    In the claim ledger

  4. ^ 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.

    In the claim ledger

  5. ^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.CodeNostaljipi/dr-mario-disassembly
    How 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.

    In the claim ledger

  6. ^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-disassembly
    How 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) increases
    
    defines/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.

    In the claim ledger

  7. ^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.

    In the claim ledger

  8. ^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.

    In the claim ledger

  9. ^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-disassembly
    How 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.

    In the claim ledger

  10. ^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 at DAS_RESET (16) the piece moves and the count drops to DAS_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.

    In the claim ledger

  11. ^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.

    In the claim ledger

  12. ^ abIn 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.CodeNostaljipi/dr-mario-disassembly
    How 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.

    In the claim ledger

  13. ^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 match
    
    defines/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.

    In the claim ledger

  14. ^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.CodeNostaljipi/dr-mario-disassembly
    How 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.

    In the claim ledger

  15. ^ 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 the claim ledger

  16. ^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.

    In the claim ledger

Sources

Code

Secondary