data/claims/tetris-nes.yamlTetris (NES) (CelestialAmber/TetrisNESDisasm, and the USA ROM in Mesen)
Game: Tetris (NES).
Nintendo released Tetris for the NES in North America in November 1989. tetris-nes/release
Value: 1989-11
WikiTetris (NES, Nintendo) ·leadTetris for Nintendo Entertainment System was released in November, 1989 in North America and published by Nintendo.Wikidata (Q67387683) dates it 1988-12-22, the release date archive.org's scans give for Bullet-Proof Software's Famicom Tetris, a different game.
Cited by: Tetris (NES)
"Classic Tetris" usually means this NES version, and the Classic Tetris World Championship plays it on original consoles. tetris-nes/ctwc-version
section on CTWC"Classic Tetris" usually refers to the NES port of the game. It's considered the gold standard original and is the version played in the CTWC tournaments.How Gen Z is pushing NES Tetris to its limits · section on CTWCThis means original NES consoles, controllers and big old CRT TVs.Cited by: Tetris (NES)
The disassembly builds the No-Intro Tetris (USA) ROM exactly; with the iNES header tetris.asm writes in place of the ROM's NES 2.0 header, the file's SHA-1 is the one in tetris.sha1. tetris-nes/rom-is-disassembly
Value: 77747840541bfc62a28a5957692a98c550bd6b2b
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·tetris.sha1#L177747840541bfc62a28a5957692a98c550bd6b2b tetris.nesTetrisNESDisasm: a disassembly of Tetris (NES) · tetris.asm#L14-L19.byte 'N', 'E', 'S', $1A ; ID
.byte $02 ; 16k PRG chunk count
.byte $02 ; 8k CHR chunk count
.byte INES_MIRROR | (INES_SRAM << 1) | ((INES_MAPPER & $f) << 4)Tetris (USA) · 0x0-0xF — the NES 2.0 header the probe replacesChecked by claude, 2026-10-20 — read tetris.asm's header and tetris.sha1 at the pinned commit; the probe swaps the ROM's 16-byte header for that one and gets the same SHA-1Probe: probes/tetris/tetris-nes.mjsSo every line cited from the disassembly is code in this ROM, not a revision of it.
Cited by: Tetris (NES)
Gravity comes from framesPerDropTable; a piece falls one row every 48 frames at level 0, never more slowly at a higher level, holding steady across levels 10–12, 13–15, and 16–18, down to 2 frames at levels 19–28, and 1 frame from level 29 on. tetris-nes/frames-per-row
About: Tetris (NES) Drop speed
Value
[ 48, 43, 38, 33, 28, 23, 18, 13, 8, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
main.asm#L1607-L1611.else
.byte $30,$2B,$26,$21,$1C,$17,$12,$0D
.byte $08,$06,$05,$05,$05,$04,$04,$04
.byte $03,$03,$03,$02,$02,$02,$02,$02
.byte $02,$02,$02,$02,$02,$01TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1584-L1595@lookupDropSpeed:
lda #$01
ldx levelNumber
cpx #$1D
bcs @noTableLookup
lda framesPerDropTable,xApplying Artificial Intelligence to Nintendo Tetris · Dropping TetriminosThe table only contains 30 entries. Above level 29, the frames per drop is locked at 1.Tetris (USA) · 0x99E-0x9BB — framesPerDropTable, CPU $898ETetris (NES, Nintendo) · DetailsThe following table of gravity speeds was observed and later found to be stored at $898E (offset $099E in the iNES format ROM)Checked by claude, 2026-10-20 — read the NTSC table and @lookupDropSpeed at the pinned commit; the probe started a game at every level 0-19 through the menus, and one at 19 with the level set to 29 in RAM, and timed four rows of the first piece's fall at eachProbe: probes/tetris/tetris-nes.mjsValues are the table's bytes in decimal, indexed by level. Levels 20–28 can't be chosen on the menu, so they weren't measured; the table gives 2 for each.
Cited by: Drop speed, Tetris (NES)
From level 29 ($1D) on, the game skips the table and drops the piece a row every frame. tetris-nes/level-29-gravity
About: Tetris (NES) Drop speed
Value: 1 frame/row
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L1584-L1591lda #$01
ldx levelNumber
cpx #$1D
bcs @noTableLookup
…
@noTableLookup:
sta dropSpeedChecked by claude, 2026-10-20 — read @lookupDropSpeed; the probe measured 1 frame per row with the level set to 29Probe: probes/tetris/tetris-nes.mjsCited by: Delayed auto shift, Tetris (NES)
fallTimer counts frames, and when it reaches the level's value the piece moves down a row; if that row is blocked, the piece locks where it is, so a resting piece locks after one gravity interval. tetris-nes/fall-timer
About: Tetris (NES) Drop speed
CodeTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L1441-L1449gameModeState_updateCountersAndNonPlayerState:
…
inc player1_fallTimerTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1570-L1594@drop: lda #$00
sta fallTimer
lda tetriminoY
sta originalY
inc tetriminoY
jsr isPositionValid
beq @ret
lda originalY
sta tetriminoY
lda #$02
sta playState
…
…Applying Artificial Intelligence to Nintendo Tetris · Dropping TetriminosThis means that the lock delay—the maximum number of frames that a Tetrimino waits while supported before locking—is equal to the drop delay.Checked by claude, 2026-10-20 — read the counter update and drop_tetrimino at the pinned commitCited by: Lock delay, Tetris (NES)
The first piece of a game hangs at the top for 96 frames before gravity starts, because autorepeatY starts at $A0 (−96) and gravity waits until it counts up to 0; pressing Down ends the wait. tetris-nes/opening-delay
Value: 96 frames
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·constants.asm#L94INITIAL_AUTOREPEAT_Y := $A0TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1239-L1240lda #INITIAL_AUTOREPEAT_Y
sta player1_autorepeatYTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1530-L1537drop_tetrimino:
lda autorepeatY
bpl @notBeginningOfGame
lda newlyPressedButtons
and #BUTTON_DOWN
beq @incrementAutorepeatYApplying Artificial Intelligence to Nintendo Tetris · Gamepad VersionThe first spawned piece has an opening entry delay of 96 frames. A soft drop will cancel it, but shifting and rotating won’t.Checked by claude, 2026-10-20 — read the constant and drop_tetrimino; the probe measured 96 frames before the first drop at every start levelProbe: probes/tetris/tetris-nes.mjsBirken's text gives the initial value as $0A; the code has $A0, which is the −96 he describes.
Cited by: Entry delay, Tetris (NES)
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). tetris-nes/das
About: Tetris (NES) Delayed auto shift
Value
{
"delay": 16,
"repeat": 6
}constants.asm#L89-L90DAS_DELAY := $0A
DAS_RESET := $10TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1622-L1638lda newlyPressedButtons
and #BUTTON_LEFT+BUTTON_RIGHT
bne @resetAutorepeatX
lda heldButtons
and #BUTTON_LEFT+BUTTON_RIGHT
beq @ret
inc autorepeatX
lda autorepeatX
cmp #DAS_RESET
bmi @ret
lda #DAS_DELAY
sta autorepeatX
…Applying Artificial Intelligence to Nintendo Tetris · Shifting Tetriminosholding down one of those direction buttons causes the game to automatically shift the piece every 6 frames after an initial delay of 16 frames.Tetris (USA) · 0x9BE-0xA19 — shift_tetrimino, CPU $89AEChecked by claude, 2026-10-20 — read the constants and shift_tetrimino at the pinned commit; the probe held Right, then Left, on a level-0 game and the piece moved on frames 0, 16, 22, … until the wallProbe: probes/tetris/tetris-nes.mjsThe names are the disassembly's. DAS_RESET is the threshold and DAS_DELAY the value the count restarts from.
Cited by: Delayed auto shift, Dr. Mario (NES), Tetris (Game Boy), Tetris (NES)
A blocked shift sets autorepeatX to 16, so a piece held against a wall or the stack keeps DAS charged and moves on the first frame the way is clear. tetris-nes/das-wall-charge
About: Tetris (NES) Delayed auto shift
Value: 16
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L1661-L1665@restoreX:
lda originalY
sta tetriminoX
lda #DAS_RESET
sta autorepeatXChecked by claude, 2026-10-20 — read @restoreX; the probe read autorepeatX as 16 after holding a piece against the right wallProbe: probes/tetris/tetris-nes.mjsCited by: Delayed auto shift, Tetris (NES)
Spawning a piece leaves autorepeatX alone, so a charge carries over; with the direction held through the entry delay, the new piece moves on its first frame and every 6 frames after. tetris-nes/das-carry
About: Tetris (NES) Delayed auto shift
Value
[ 0, 6, 12, 18 ]
main.asm#L2920-L2945@spawnPiece:
lda #$00
sta twoPlayerPieceDelayCounter
sta fallTimer
sta tetriminoY
lda #$01
sta playState
lda #$05
sta tetriminoX
…
@resetDownHold:
lda #$00
…TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L489-L492 — the shift code runs only in play state 1, so the count holds still between piecesplayState_playerControlsActiveTetrimino:
jsr shift_tetriminoTetris (NES, Nintendo) · DetailsThis means that any DAS charge left over from the previous piece can be redirected during ARE.Checked by claude, 2026-10-20 — read the spawn routine (it resets the fall timer, row, play state, column, piece, and autorepeatY, not autorepeatX); in the probe a piece charged against the left wall, Left held through the lock, and the next piece moved on frames 0, 6, 12, and 18Probe: probes/tetris/tetris-nes.mjsCited by: Delayed auto shift, Tetris (NES)
While Down is held the piece can't shift; shift_tetrimino returns before reading Left or Right. tetris-nes/down-blocks-shift
About: Tetris (NES) Delayed auto shift
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L1616-L1621shift_tetrimino:
lda tetriminoX
sta originalY
lda heldButtons
and #BUTTON_DOWN
bne @retChecked by claude, 2026-10-20 — read shift_tetrimino; the probe held Down and Right for 30 frames and the piece never moved sidewaysProbe: probes/tetris/tetris-nes.mjsCited by: Delayed auto shift, Tetris (NES)
A soft drop can't start while Left or Right is held. tetris-nes/shift-blocks-soft-drop
main.asm#L1540-L1543@playing:
lda heldButtons
and #BUTTON_LEFT+BUTTON_RIGHT
bne @lookupDropSpeedApplying Artificial Intelligence to Nintendo Tetris · Gamepad VersionWhen Left or Right is pressed, it is not possible to soft drop.Checked by claude, 2026-10-20 — read drop_tetrimino at the pinned commitCited by: Tetris (NES)
Holding Down drops the piece a row on its 3rd frame and then every 2nd frame, and each piece needs a fresh press, because spawning zeroes autorepeatY and only a new press starts the count. tetris-nes/soft-drop
Value
{
"first": 3,
"repeat": 2
}main.asm#L1544-L1569lda newlyPressedButtons
and #BUTTON_DPAD
cmp #BUTTON_DOWN
bne @lookupDropSpeed
lda #$01
sta autorepeatY
…
@downPressed:
inc autorepeatY
lda autorepeatY
cmp #$03
bcc @lookupDropSpeed
…Applying Artificial Intelligence to Nintendo Tetris · Gamepad VersionHolding Down triggers a soft drop every other frame after an initial delay of 3 frames.Checked by claude, 2026-10-20 — read drop_tetrimino and the spawn routine's @resetDownHold at the pinned commitCited by: Tetris (NES)
The game has no hard drop; the only fast drop is the soft drop on Down. tetris-nes/no-hard-drop
Dropping TetriminosNintendo Tetris does not support hard drops.Tetris (NES, Nintendo) · DetailsLock delay, wall kick, and hard drop are not present.In the disassembly, Up is read only on the menus and the high-score screen (main.asm L719, L981, L4400), never during play.
Cited by: Tetris (NES)
Every new press of Left or Right zeroes the DAS count and moves the piece at once, so pressing on every other frame moves it every 2 frames. tetris-nes/tap-rate
About: Tetris (NES) Delayed auto shift
Value: 2 frames
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L1622-L1624lda newlyPressedButtons
and #BUTTON_LEFT+BUTTON_RIGHT
bne @resetAutorepeatXApplying Artificial Intelligence to Nintendo Tetris · Dropping Tetriminosas long as the horizontal direction button is released exactly every other frame, it is possible to shift the Tetrimino at half the rate that it drops on levels 29 and above.Checked by claude, 2026-10-20 — the probe pressed Right on every other frame and Left on every third; the piece moved on every pressProbe: probes/tetris/tetris-nes.mjsCited by: Delayed auto shift, Tetris (NES)
Pieces spawn centered on column 5 of 0–9; in spawn orientation T, J, Z, S, and L cover columns 4–6, O 4–5, and I 3–6, so most pieces need 3 shifts to reach the right wall and 4 to reach the left. tetris-nes/spawn-columns
Value
{
"right": 3,
"left": 4
}main.asm#L2927-L2928lda #$05
sta tetriminoXTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1760-L1785; y offset, tile ID, x offset per mino per orientation
…
.byte 0, tile1,-1, 0, tile1, 0, 0, tile1, 1, 1, tile1, 0 ; $02 t down (spawn)
…
.byte 0, tile1,-1, 0, tile1, 0, 1, tile1,-1, 1, tile1, 0 ; $0A o (spawn)
…
.byte 0, tile1,-2, 0, tile1,-1, 0, tile1, 0, 0, tile1, 1 ; $12 i horizontal (spawn)Checked by claude, 2026-10-20 — read the spawn routine and every spawn row of orientationTable at the pinned commitCited by: Delayed auto shift, Tetris (NES)
At level 29 on an empty board, a piece is under control for 19 frames; held from spawn it shifts 2 columns, with DAS charged 4, and tapped it shifts once every 2 frames. tetris-nes/level-29-reach
About: Tetris (NES) Delayed auto shift
Value
{
"frames": 19,
"held": 2,
"charged": 4,
"tapEvery": 2
}main.asm#L1584-L1591 — 1 frame per row from level 29lda #$01
ldx levelNumber
cpx #$1D
bcs @noTableLookupTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1622-L1665 — the DAS countinc autorepeatX
lda autorepeatX
cmp #DAS_RESET
bmi @ret
lda #DAS_DELAY
sta autorepeatXChecked by claude-agent, 2026-10-25 — Read the drop-speed lookup (main.asm L1584-1591: 1 frame per row from level $1D) and the DAS counter (L1622-1665) at the pinned commit; the 19 frames and the shifts are the probe's measurement in the game.Probe: probes/tetris/tetris-nes.mjsThe 19 frames run from the first frame of control to the lock, for a piece falling the full height of the empty well.
Cited by: Delayed auto shift, Drop speed, Tetris (NES)
A rotation that would overlap a wall or the stack is undone; the game tries no other position. tetris-nes/no-wall-kick
main.asm#L1476-L1501inx
lda rotationTable,x
sta currentPiece
jsr isPositionValid
bne @restoreOrientationID
…
@restoreOrientationID:
lda originalY
sta currentPieceChecked by claude, 2026-10-20 — read rotate_tetrimino at the pinned commitCited by: Tetris (NES)
Select shows or hides the next piece. tetris-nes/next-preview
main.asm#L1453-L1460lda newlyPressedButtons_player1
and #BUTTON_SELECT
beq @ret
lda displayNextPiece
…
eor #$01
sta displayNextPieceChecked by claude, 2026-10-20 — read gameModeState_updateCountersAndNonPlayerState at the pinned commitCited by: Tetris (NES)
The random number generator is a 16-bit linear feedback shift register at $0017; each step shifts it right and feeds bit 1 XOR bit 9 into the top bit, and from its seed, $8988, it repeats after 32,767 steps. tetris-nes/lfsr
About: Tetris (NES) Piece randomizer
Value
{
"period": 32767,
"seed": "$8988"
}main.asm#L5468-L5483generateNextPseudorandomNumber:
lda tmp1,x
and #$02
sta tmp1
lda tmp2,x
and #$02
eor tmp1TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L347-L351@continueWarmBootInit:
ldx #$89
stx rng_seed
dex
stx rng_seed+1Applying Artificial Intelligence to Nintendo Tetris · Picking TetriminosThis PRNG repeatedly and deterministically generates 32,767 distinct values, each cycle starting with the original seed.Tetris (USA) · 0x2B57-0x2B6D — generateNextPseudorandomNumber, CPU $AB47Checked by claude, 2026-10-20 — read the routine and the seed; the probe steps it from $8988 until it returns, 32,767 stepsProbe: probes/tetris/tetris-nes.mjsCited by: Piece randomizer, Tetris (NES)
The NMI handler steps the generator every frame, so the time a player takes to place a piece changes which piece comes next. tetris-nes/rng-every-frame
About: Tetris (NES) Piece randomizer
CodeTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L270-L274.if NWC <> 1
ldx #rng_seed
ldy #$02
jsr generateNextPseudorandomNumber
.endifApplying Artificial Intelligence to Nintendo Tetris · Picking TetriminosMeaning, the number of frames that it takes the player to position a piece actually affects which piece comes up next.Checked by claude, 2026-10-20 — read the NMI handler at the pinned commitThe Nintendo World Championships build (NWC=1) steps it once per pick instead.
Cited by: Piece randomizer, Tetris (NES)
pickRandomTetrimino adds a pick counter to the generator's high byte and keeps the low 3 bits; a result of 7, or the same piece as last time, makes it step the generator and take the high byte's low 3 bits plus the previous piece's orientation id, modulo 7, with no further check. tetris-nes/randomizer-roll
About: Tetris (NES) Piece randomizer
CodedisputedTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L2974-L3002inc spawnCount
lda rng_seed
clc
adc spawnCount
and #$07
cmp #$07
beq @invalidIndex
tax
lda spawnTable,x
cmp spawnID
bne useNewSpawnID
@invalidIndex:
…TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3013-L3014spawnTable:
.byte tDown, jDown, zHoriz, oFixed, sHoriz, lDown, iHorizApplying Artificial Intelligence to Nintendo Tetris · Picking TetriminosOtherwise, the next pseudorandom number is generated and a mask is applied to retain the lower 3 bits of the high byte before adding the prior spawn orientation ID.Checked by claude, 2026-10-20 — read pickRandomTetrimino and spawnTable at the pinned commitDisputed: The Tetris Wiki's NES page says the second roll "generates a value 0-6 and deals that piece", which reads as a uniform pick; the code adds the previous orientation id to a 3-bit value, so one piece gets two of the eight values (reroll-bias).
The pick fills the preview; the piece that spawns is the previous pick. spawnCount is zeroed only at power-on, while spawnID (the previous pick) is zeroed when a game starts (main.asm L1234).
Cited by: Piece randomizer, Tetris (NES, Tengen), Tetris (NES)
The reroll adds the previous piece's orientation id, not its index, so one of its eight results is doubled; after an O ($0A) or an S ($0B) the doubled result is the same piece again. tetris-nes/reroll-bias
About: Tetris (NES) Piece randomizer
CodeTetrisNESDisasm: a disassembly of Tetris (NES) ·constants.asm#L121-L139tDown = $02
…
jDown = $07
zHoriz = $08
…
oFixed = $0A
sHoriz = $0B
…
lDown = $0E
…
iHoriz = $12Applying Artificial Intelligence to Nintendo Tetris · Picking TetriminosUsing the prior spawn orientation ID in the sum as opposed to the prior Tetrimino type introduces a bias because the spawn orientation ID values are not evenly distributed.Checked by claude, 2026-10-20 — read the orientation constants; $0A mod 7 = 3 and $0B mod 7 = 4 are O's and S's own places in spawnTable, while T, J, Z, L, and I double Z, T, J, T, and SThe reroll's 3 bits take 8 values and land on 7 pieces, so the value 0 and the value 7 give the same piece, the previous id modulo 7.
Cited by: Piece randomizer, Tetris (NES)
Run over every state of the generator and every pick count, the routine repeats a T, J, Z, L, or I with probability 1/32 and an O or S with 1/16, so 4.0% of the pieces in a long game repeat the one before. tetris-nes/randomizer-exact
About: Tetris (NES) Piece randomizer
Value
{
"repeat": {
"T": 0.0313,
"J": 0.0313,
"Z": 0.0313,
"O": 0.0625,
"S": 0.0625,
"L": 0.0313,
"I": 0.0313
},
"frequency": {
"T": 0.1467,
"J": 0.1429,
"Z": 0.143,
"O": 0.1429,
"S": 0.1468,
"L": 0.1389,
"I": 0.1389
},
"repeatRate": 0.0403
}main.asm#L2974-L3002 — pickRandomTetriminoinc spawnCount
lda rng_seed
clc
adc spawnCount
and #$07
cmp #$07
beq @invalidIndex
tax
lda spawnTable,x
cmp spawnID
bne useNewSpawnID
@invalidIndex:
…Checked by claude-agent, 2026-10-25 — Read pickRandomTetrimino (main.asm L2974-3002) at the pinned commit: the seed plus the spawn count, masked to 0-7, picks the piece unless it is 7 or the same piece, and only then a second roll, added to the previous id modulo 7, decides; the probabilities are the probe's computation over every state, and its run in the ROM checks picks against this routine.Probe: probes/tetris/tetris-nes.mjsDisputed: Birken gives T and S 14.73% and L and I 13.84%, from 3/4 uniform picks plus 1/4 from his table of reroll results. That averages the reroll over all seven previous pieces equally and lets the first roll pick the previous piece; the exact chain gives 14.67%, 14.68%, and 13.89%.
This assumes the generator's state at a pick is uniform over its cycle, which the frame-by- frame stepping makes close to true in play. The chance of a repeat is 1/4 × 1/8 (1/4 × 2/8 for O and S): a reroll happens on a 7 or a match, 2 of 8 first results.
Cited by: Piece randomizer, Tetris (NES)
In a long game the routine deals T and S most often (14.67% and 14.68%) and L and I least (13.89% each); J, Z, and O come 14.29–14.30% of the time. tetris-nes/piece-frequency
About: Tetris (NES) Piece randomizer
Value
{
"T": 0.1467,
"J": 0.1429,
"Z": 0.143,
"O": 0.1429,
"S": 0.1468,
"L": 0.1389,
"I": 0.1389
}main.asm#L2974-L3002 — pickRandomTetriminoinc spawnCount
lda rng_seed
clc
adc spawnCount
and #$07
cmp #$07
beq @invalidIndex
tax
lda spawnTable,x
cmp spawnID
bne useNewSpawnID
@invalidIndex:
…Applying Artificial Intelligence to Nintendo Tetris · Picking TetriminosT and S appear more frequently and L and I less frequently.Checked by claude-agent, 2026-10-25 — Read pickRandomTetrimino (main.asm L2974-3002) at the pinned commit: the seed plus the spawn count, masked to 0-7, picks the piece unless it is 7 or the same piece, and only then a second roll, added to the previous id modulo 7, decides; the shares are the long-run distribution the probe computes from it.Probe: probes/tetris/tetris-nes.mjsCited by: Piece randomizer, Tetris (NES)
Over a long game, 4.03% of pieces repeat the one before, against 14.3% (1 in 7) for a uniform, memoryless pick. tetris-nes/repeat-rate
About: Tetris (NES) Piece randomizer
Value: 0.0403
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L2974-L3002 — pickRandomTetriminoinc spawnCount
lda rng_seed
clc
adc spawnCount
and #$07
cmp #$07
beq @invalidIndex
tax
lda spawnTable,x
cmp spawnID
bne useNewSpawnID
@invalidIndex:
…Checked by claude-agent, 2026-10-25 — Read pickRandomTetrimino (main.asm L2974-3002) at the pinned commit: the seed plus the spawn count, masked to 0-7, picks the piece unless it is 7 or the same piece, and only then a second roll, added to the previous id modulo 7, decides, so a repeat needs the first roll to match and the second to land on it; the rate is the probe's long-run computation.Probe: probes/tetris/tetris-nes.mjsFive pieces repeat at 1/32 and two at 1/16, weighted by how often each is dealt; O and S together come 28.97% of the time, a little over 2/7, so the rate is a little above 9/224 (4.02%).
Cited by: Piece randomizer, Tetris (NES)
In 4,800 pieces dealt by the running game, 4.46% repeated the piece before, against 4.03% simulated and 14.3% for a uniform pick; 6.29% of O and S pieces repeated (simulated 6.25%) and 3.76% of the others (3.13%). tetris-nes/randomizer-measured
About: Tetris (NES) Piece randomizer
Value
{
"pieces": 4800,
"repeatRate": 4.46,
"repeatOS": 6.29,
"repeatOthers": 3.76
}0x1917-0x194A — pickRandomTetrimino, CPU $9907Tetris (USA) · 0x2B57-0x2B6D — generateNextPseudorandomNumber, CPU $AB47TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L2974-L3002 — pickRandomTetriminoinc spawnCount
lda rng_seed
clc
adc spawnCount
and #$07
cmp #$07
beq @invalidIndex
tax
lda spawnTable,x
cmp spawnID
bne useNewSpawnID
@invalidIndex:
…Checked by claude-agent, 2026-10-25 — Read pickRandomTetrimino (main.asm L2974-3002) at the pinned commit: the seed plus the spawn count, masked to 0-7, picks the piece unless it is 7 or the same piece, and only then a second roll, added to the previous id modulo 7, decides; the 4,800-piece rates are the probe's games played in the ROM.Probe: probes/tetris/tetris-nes-sample.mjsThe board was emptied in RAM whenever the stack passed row 8, so the games never ended; the randomizer reads none of that memory. The rates are reproducible: the same inputs give the same pieces. Piece shares were T 15.10%, J 14.58%, Z 14.31%, O 14.04%, S 13.77%, L 14.06%, and I 14.12%.
Cited by: Piece randomizer, Tetris (NES)
Clearing 1, 2, 3, or 4 lines at once scores 40, 100, 300, or 1,200 points times one more than the level. tetris-nes/points
Value
[ 40, 100, 300, 1200 ]
main.asm#L3529-L3531pointsTable:
.word $0000,$0040,$0100,$0300
.word $1200TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3460-L3469addLineClearPoints:
lda #$00
sta holdDownPoints
lda levelNumber
sta generalCounter
inc generalCounter
L9C37: lda completedLines
asl a
tax
lda pointsTable,xChecked by claude, 2026-10-20 — read pointsTable (BCD) and the loop that adds it level + 1 times; the probe compared the score before and after each of its clears at every start level and at 29Probe: probes/tetris/tetris-nes.mjsThe table is binary-coded decimal, and the loop adds the entry level + 1 times rather than multiplying.
Cited by: Tetris (NES)
The clear that raises the level scores at the new level, because the lines and the level go up before the points are added. tetris-nes/points-new-level
main.asm#L3422-L3430@incrementLevel:
inc levelNumber
…
L9BFB: dex
bne incrementLinesTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3460-L3465addLineClearPoints:
…
lda levelNumberChecked by claude, 2026-10-20 — read playState_updateLinesAndStatistics; in the probe every clear that crossed a level boundary scored at the level after itProbe: probes/tetris/tetris-nes.mjsCited by: Tetris (NES)
The score stops at 999,999; when its top digit would pass 9, the code writes 99 99 99. tetris-nes/score-cap
Value: 999999 points
VerifiedTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L3508-L3515L9C84: lda score+2
and #$F0
cmp #$A0
bcc L9C94
lda #$99
sta score
sta score+1
sta score+2Checked by claude, 2026-10-20 — read the overflow check; in the probe, a game with the level set to 29 cleared lines until the score stopped at 999,999Probe: probes/tetris/tetris-nes.mjsCited by: Tetris (NES)
The level first rises at 10 × (start level + 1) lines from start levels 0–9, at 100 lines from 10–15, and at 110, 120, 130, and 140 lines from 16, 17, 18, and 19; after that it rises every 10 lines. tetris-nes/level-transition
Value
{
"0": 10,
"1": 20,
"2": 30,
"3": 40,
"4": 50,
"5": 60,
"6": 70,
"7": 80,
"8": 90,
"9": 100,
"10": 100,
"11": 100,
"12": 100,
"13": 100,
"14": 100,
"15": 100,
"16": 110,
"17": 120,
"18": 130,
"19": 140
}main.asm#L3395-L3423L9BC7: lda lines
and #$0F
…
L9BD0: lda lines+1
sta generalCounter2
lda lines
sta generalCounter
lsr generalCounter2
ror generalCounter
…
lda levelNumber
cmp generalCounter
…Applying Artificial Intelligence to Nintendo Tetris · Lines and Statistics — his table of actual transitions gives the same lines for all twenty start levelsConsequentially, if the player decided to start at level 17, the level would actually advance at 120 lines because 18 exceeds 17.Checked by claude, 2026-10-20 — read the line counter and the level check at the pinned commit; the probe started a game at each level 0-19 and cleared 4, 4, and 2 lines in turn until the level had risen twiceProbe: probes/tetris/tetris-nes.mjsStart levels 10–19 are reached by holding A on the level menu (start-plus-10).
Cited by: Tetris (NES)
Each time the lines' ones digit turns 0, the level goes up by 1 if it is below the hundreds and tens digits read as one hexadecimal byte; 130 lines gives $13, which is 19. tetris-nes/level-transition-rule
main.asm#L3406-L3420L9BD0: lda lines+1
sta generalCounter2
lda lines
sta generalCounter
lsr generalCounter2
ror generalCounter
lsr generalCounter2
ror generalCounter
lsr generalCounter2
ror generalCounter
lsr generalCounter2
ror generalCounter
…Applying Artificial Intelligence to Nintendo Tetris · Lines and StatisticsHowever, at $9BEA the level number is directly compared against the packed BCD value in $00A8. A table lookup to convert the BCD value to decimal is missing, an apparent bug.Checked by claude, 2026-10-20 — read incrementLines at the pinned commit; lines is BCD, shifted right 4 bits and compared with the binary levelCited by: Tetris (NES)
Holding A while pressing Start on the level menu adds 10 to the chosen level, so games can start at levels 10–19. tetris-nes/start-plus-10
main.asm#L867-L876lda newlyPressedButtons_player1
cmp #BUTTON_START
bne @checkBPressed
lda heldButtons_player1
cmp #BUTTON_A+BUTTON_START
bne @startAndANotPressed
lda player1_startLevel
clc
adc #$0AChecked by claude, 2026-10-20 — read gameMode_levelMenu; the probe started games at 10-19 this way and read the level from RAMProbe: probes/tetris/tetris-nes.mjsCited by: Tetris (NES)
The next piece spawns 10 frames after a lock with the piece's center on row 18 or 19, and 2 frames later for every 4 rows higher, up to 18 frames. tetris-nes/entry-delay
About: Tetris (NES) Entry delay
Value
{
"0-5": 18,
"6-9": 16,
"10-13": 14,
"14-17": 12,
"18-19": 10
}main.asm#L2484-L2492@playStateNotDisplayLineClearingAnimation:
lda player1_vramRow
sta vramRow
lda #>playfield
sta playfieldAddr+1
jsr copyPlayfieldRowToVRAM
jsr copyPlayfieldRowToVRAM
jsr copyPlayfieldRowToVRAM
jsr copyPlayfieldRowToVRAMTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3532-L3542updatePlayfield:
ldx tetriminoY
dex
dex
…
sta vramRowTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3074-L3077@notGameOver:
lda vramRow
cmp #$20
bmi @retTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3263-L3264lda #$00
sta vramRowTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L2896-L2899playState_spawnNextTetrimino:
lda vramRow
cmp #$20
bmi @retTetris (NES, Nintendo) · Detailspieces that lock in the bottom two rows are followed by 10 frames of entry delay, and each group of 4 rows above that has an entry delay 2 frames longer than the last.Checked by claude, 2026-10-20 — read the render, lock, row-check, and spawn code at the pinned commit; the probe stacked nine pieces in the middle of a level-19 game and timed lock to spawn at rows 18 down to 3Probe: probes/tetris/tetris-nes.mjsCounted from the frame the piece locks to the frame the next one spawns; the new piece first moves on the frame after. The lock and the spawn each wait for the screen copy, which redraws 4 rows a frame: first from 2 rows above the piece to the floor, then, after the row check resets it, the whole well.
Cited by: Entry delay, Tetris (NES)
A line clear adds 17 to 20 frames to the entry delay, for the animation that blanks two columns of each cleared row every 4th frame, in 5 steps. tetris-nes/line-clear-delay
About: Tetris (NES) Entry delay
Value
{
"min": 17,
"max": 20
}main.asm#L2757-L2760updateLineClearingAnimation:
lda frameCounter
and #$03
bne @retTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L2821-L2825inc rowY
lda rowY
cmp #$05
bmi @ret
inc playStateTetris (NES, Nintendo) · Detailsline clear delay is an additional 17~20 frames depending on the frame that the piece locks; the animation has 5 steps that advance when the global frame counter modulo 4 equals 0.Checked by claude, 2026-10-20 — read updateLineClearingAnimation at the pinned commit; the probe filled 1-4 rows at 48 locks on level-18 and level-19 games, on floors of different heights so the locks fell on every phase of the 4-frame cycle, and each clear added 17, 18, 19, or 20 frames to the entry delay for its rowProbe: probes/tetris/tetris-nes.mjsThe first step waits for the frame counter to reach a multiple of 4 (0 to 3 frames), four more steps follow at 4-frame intervals, and the well is redrawn before the next piece spawns. The number of lines doesn't matter.
Cited by: Entry delay, Tetris (NES)
The PAL build's DAS waits 12 frames and then repeats every 4. tetris-nes/pal-das
About: Tetris (NES) Delayed auto shift
Value
{
"delay": 12,
"repeat": 4
}constants.asm#L72-L75.if PAL = 1
DAS_DELAY := $08
DAS_RESET := $0CChecked by claude, 2026-10-20 — read constants.asm at the pinned commitThe PAL ROM is not in the research set, so this wasn't measured. PAL consoles run at 50 frames per second, not 60.
Cited by: Delayed auto shift, Tetris (NES)
The PAL build's gravity table starts at 36 frames per row at level 0 and reaches 1 frame at level 19. tetris-nes/pal-gravity
About: Tetris (NES) Drop speed
Value
[ 36, 32, 29, 25, 22, 18, 15, 11, 7, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
main.asm#L1601-L1606framesPerDropTable:
.if PAL = 1
.byte $24,$20,$1D,$19,$16,$12,$0F,$0B
.byte $07,$05,$04,$04,$04,$03,$03,$03
.byte $02,$02,$02,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01Checked by claude, 2026-10-20 — read the PAL half of framesPerDropTable at the pinned commitCited by: Tetris (NES)
The NES draws 60.0988 frames per second. tetris-nes/ntsc-frame-rate
Value: 60.0988 frames/s
WebApplying Artificial Intelligence to Nintendo Tetris ·Dropping TetriminosSince the NES runs at 60.0988 frames/sec, the period between drops and the speed can be computed.The NTSC console's rate; frame counts on this page assume it.
Players call level 29 the "kill screen", although the game goes on. tetris-nes/kill-screen-name
The Kill Screenmost players cannot endure the drop speed of level 29, which swiftly brings the game to an end. For this reason, it has become associated with the notation of a kill screen.How Gen Z is pushing NES Tetris to its limits · section on the maxoutbeating level 29 (aka the "kill screen")Cited by: Kill screen, Tetris (NES)
Engadget describes the level 29 kill screen as a wall for players who hold the D-pad, because DAS can't carry pieces to either edge in time. tetris-nes/kill-screen-das
About: Tetris (NES) Delayed auto shift
MagazineHow Gen Z is pushing NES Tetris to its limits ·section on the kill screenDAS simply cannot move the pieces to either edge fast enough, meaning that once the "stack" is above a certain height math takes over and failure is guaranteed.Applying Artificial Intelligence to Nintendo Tetris · Dropping TetriminosAt that drop speed, the DAS does not permit the piece to reach the edges of the playfield before lock, quickly ending the game for most humans.Cited by: Tetris (NES)
Birken reports that the game itself breaks down around 1,550 lines, usually freezing, sometimes resetting or going black, because the scoring loop runs once per level and takes longer than a frame at high levels. tetris-nes/crash-around-1550-lines
The Kill ScreenThe actual kill screen occurs around 1550 lines. It manifests itself in different ways. Sometimes the game resets. Other times, the screen just goes black. Usually, the game freezes just after clearing a lineApplying Artificial Intelligence to Nintendo Tetris · The Kill ScreenFor high levels, the large number of iterations affects the timing of the game as each frame takes longer than 1/60th of a second to generate.Not measured here. The loop is the one points cites, which adds the points level + 1 times.
Cited by: Tetris (NES)
In competitive classic Tetris, holding the D-pad to move pieces is called DAS, for delayed auto shift. tetris-nes/das-term
About: Tetris (NES) Delayed auto shift
MagazineHow Gen Z is pushing NES Tetris to its limits ·section on Neubauer and Saeleeholding down the D-pad to move the pieces (a technique called "delayed auto shift/DAS" in competitive Tetris lingo)Applying Artificial Intelligence to Nintendo Tetris · Shifting TetriminosNintendo Tetris provides Delayed Auto Shift (DAS).Cited by: Delayed auto shift
Birken names Thor Aackerlund as a player who beat DAS at level 29 by vibrating the D-pad. tetris-nes/vibrating-dpad
About: Tetris (NES) Delayed auto shift
WebApplying Artificial Intelligence to Nintendo Tetris ·Dropping TetriminosHowever, some players, most notably Thor Aackerlund, overcome the DAS by rapidly vibrating the D-pad.Cited by: Delayed auto shift, Tetris (NES)
Hypertapping is moving pieces with many quick presses of the D-pad instead of holding it; it spread in competition after a hypertapping player won the 2018 Classic Tetris World Championship. tetris-nes/hypertapping
About: Tetris (NES) Delayed auto shift
MagazineNES Tetris Players Call It 'Rolling,' And They're Setting New World Records ·paragraph 4But another way to play is called “hypertapping.” This involves hitting the d-pad with lots of quick presses, resulting in faster movement.NES Tetris Players Call It 'Rolling,' And They're Setting New World Records · paragraph 4It wasn’t until 2018, after a young player won a prestigious competition using hypertapping, that more players starting using it.How Gen Z is pushing NES Tetris to its limits · section on Neubauer and SaeleeHe used a style called "hypertapping" – a contorted mix of fingers and thumbs designed to sidestep the game's built-in speed limit – and it allows you to move pieces much faster than DAS.How Gen Z is pushing NES Tetris to its limits · section on SaeleeSaelee's victory at the 2018 CTWC finals may have surprised everyoneEngadget names the 2018 winner as Joseph Saelee and says he didn't invent the technique.
Cited by: Delayed auto shift, Tetris (NES)
Rolling, which the player Cheez worked out in late 2020, keeps light pressure on the D-pad while the fingers roll across the back of the controller, and moves pieces faster than hypertapping. tetris-nes/rolling
About: Tetris (NES) Delayed auto shift
MagazineNES Tetris Players Call It 'Rolling,' And They're Setting New World Records ·paragraph 6Eventually, in November 2020, Cheez_Fish figured out that they could roll their fingers on the back of the controller while pressing the d-pad buttons in the desired direction using a slight amount of pressure.How Gen Z is pushing NES Tetris to its limits · section on rollingyou can move pieces left and right even faster than with hypertapping.Cited by: Delayed auto shift, Tetris (NES)