data/claims/tetris-demo.yamlTetris (NES) demo (CelestialAmber/TetrisNESDisasm)
Game: Tetris (NES).
Tetris (NES, US build) starts its demo when the title screen has waited for Start until the frame counter's high byte, cleared as the title appears, reaches 5: between 1,025 and 1,280 frames (computed), about 17 to 21 seconds. The demo stores 0 as the game type, which the disassembly's comment names A-type, and 0 as the start level. tetris-demo/start
About: Tetris (NES) Demo playback
Value
{
"counterHighByte": 5,
"framesMin": 1025,
"framesMax": 1280
}main.asm#L603-L633lda #$00
sta frameCounter+1
…
@waitForStartButton:
jsr updateAudioWaitForNmiAndResetOamStaging
lda newlyPressedButtons_player1
cmp #BUTTON_START
beq @startButtonPressed
lda frameCounter+1
cmp #$05
beq @timeout
…
…TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L263-L269lda frameCounter
clc
adc #$01
sta frameCounter
lda #$00
adc frameCounter+1
sta frameCounter+1TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3735-L3743gameMode_startDemo:
lda #$00
sta gameType
sta player1_startLevel
…
lda #$05
sta gameModeTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L132-L133gameMode := $00C0 ; 0=legal, 1=title, 2=type menu, 3=level menu, 4=play and ending and high score, 5=demo, 6=start demo
gameType := $00C1 ; A=0, B=1Checked by claude, 2026-10-22 — read the title screen's wait loop, the NMI's 16-bit frame counter, and gameMode_startDemo at the pinned commit; only the high byte is cleared, so the low byte's start sets where in 1,025-1,280 frames the timeout falls; the frame rate (60.1 Hz NTSC) scales the secondsCited by: Demo playback
The demo's pieces come from a fixed list, not the randomizer: in demo mode chooseNextTetrimino reads the next byte of the 256-byte demoTetriminoTypeTable, from 0 at each game start, and takes bits 4-6 as an index into the 7-entry spawn table. An index of 7 reads the byte after the table, $02, the T piece's spawn orientation, so 2 of the 8 index values give a T; 45 of the table's 256 bytes carry a 7 (computed). tetris-demo/pieces
About: Tetris (NES) Demo playback
Value
{
"tableBytes": 256,
"bits": "4-6",
"indexSevenBytes": 45
}main.asm#L2949-L2962lda gameMode
cmp #$05
bne pickRandomTetrimino
ldx demoIndex
inc demoIndex
lda demoTetriminoTypeTable,x
lsr a
lsr a
lsr a
lsr a
and #$07
tax
…TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3013-L3020spawnTable:
.byte tDown, jDown, zHoriz, oFixed, sHoriz, lDown, iHoriz
; unused portion of spawnTable:
.if NWC = 1
.byte $12
.else
.byte $02TetrisNESDisasm: a disassembly of Tetris (NES) · constants.asm#L123tDown = $02TetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L1229-L1236sta allegro
sta demo_heldButtons
sta demo_repeats
sta demoIndexTetrisNESDisasm: a disassembly of Tetris (NES) · data/demo_data.asm#L136-L137demoTetriminoTypeTable:
.byte $00,$14,$8A,$45,$22,$11,$88,$44Checked by claude, 2026-10-22 — read chooseNextTetrimino, spawnTable and the byte after it, and the demo resets in gameModeState_initGameState at the pinned commit; the zeroed bytes are stored from A = 0 (the stores begin with `lda #$00`); counted (byte >> 4) & 7 == 7 over the 256 bytes of data/demo_data.asm L137-L167; how many of the 256 the demo uses before it ends isn't readCited by: Demo playback
The demo stores 1 as the game mode, which the disassembly's comment names the title screen, when the button table runs out, its read address reaching the piece table's page, or when Start is pressed. The game-over routine has no demo case: a one-player game over, in the demo as in play, stores $03, which the comment names the level menu. tetris-demo/end
About: Tetris (NES) Demo playback
CodeTetrisNESDisasm: a disassembly of Tetris (NES) ·main.asm#L412-L424@checkForDemoDataExhaustion:
lda gameMode
cmp #$05
bne @continue
lda demoButtonsAddr+1
cmp #>demoTetriminoTypeTable
bne @continue
…
lda #$01
sta gameModeTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3642-L3644lda newlyPressedButtons_player1
cmp #BUTTON_START
beq @startButtonPressedTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3678-L3684@startButtonPressed:
lda #>demoButtonsTable
sta demoButtonsAddr+1
lda #$00
sta frameCounter+1
lda #$01
sta gameModeTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L3545-L3591gameModeState_handleGameOver:
…
@onePlayerGameOver:
…
jsr handleHighScoreIfNecessary
…
lda #$03
sta gameModeTetrisNESDisasm: a disassembly of Tetris (NES) · main.asm#L132gameMode := $00C0 ; 0=legal, 1=title, 2=type menu, 3=level menu, 4=play and ending and high score, 5=demo, 6=start demoChecked by claude, 2026-10-22 — read the main loop's exhaustion test, pollControllerButtons' Start test, and gameModeState_handleGameOver at the pinned commit; the game-over routine never reads gameMode; whether the shipped demo ever tops out isn't readCited by: Demo playback