data/claims/super-c.yamlSuper C (vermiceli's annotated disassembly of the US NES release)
Game: Super C.
The US NES Super C checks a different code from Contra's on its title screen: six presses, Right Left Down Up A B, against Contra's ten-press Up Up Down Down Left Right Left Right B A. Like Contra, a wrong press locks the check out. The code raises the starting lives byte from 2 to 9, where Contra's raises it from 2 to 29. super-c/cheat-code
About: Super C Cheat code
Value: 9 lives byte
CodeSuper C (US), annotated disassembly (vermiceli) ·src/bank-1.asm#L539-L565; checks for 10 extra lives cheat, i.e. right left down up a b
extra_lives_cheat_input_check:
ldy EXTRA_LIVES_CHEAT_NUM_CORRECT ; load number of correct inputs to 10 extra lives cheat
bmi @exit ; exit if failed inputting
…
cmp extra_lives_code_tbl,y ; compare input to next valid input for 10 lives cheat
bne @mark_failure ; branch if incorrect to mark failure
…
lda #$01
sta CHEAT_CODE_STATUS ; successfully entered full cheat code, mark success
…
@mark_failure:
…Super C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L1154jsr load_banks_extra_lives_cheat_input_check ; still animating intro, check for 10 extra lives cheatSuper C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L1504-L1515lda #$02 ; default to 3 lives
ldy CHEAT_CODE_STATUS ; check if 10 lives cheat entered
beq @continue ; branch if not entered
…
lda #$09 ; 10 lives cheat entered, set number of lives to 10
…
sta PLAYER_NUM_LIVES,x ; set player number of livesContra (US), annotated disassembly (vermiceli) · src/bank7.asm#L930-L955konami_input_check:
…
lda #$ff ; incorrect sequence for Konami code
sta KONAMI_CODE_NUM_CORRECT ; since incorrect set KONAMI_CODE_NUM_CORRECT (number of successful inputs) to $ff
…
konami_code_lookup_table:
.byte $08,$08,$04,$04,$02,$01,$02,$01,$40,$80Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L1165-L1169init_player_lives:
lda #$02 ; start off with #$02 lives
ldy KONAMI_CODE_STATUS ; 30-lives code switch ($01 = code activated)
beq init_player_num_lives ; if KONAMI_CODE_STATUS is not set, then just set 2 lives
lda #$1d ; KONAMI_CODE_STATUS active so set lives to #$1d (29 decimal)Checked by claude, 2026-10-21 — read extra_lives_cheat_input_check and its table, its call on the intro screen, and the lives setup in init_player_vars, then Contra's konami_input_check and init_player_lives, at the pinned commitsBoth tables use the same bit layout (Right $01, Left $02, Down $04, Up $08, B $40, A $80). Super C's table ends in a 0 that marks its length. Its success path falls through to the failure store, which only stops further checking. The PAL Probotector II build gives $1D instead (L1507-L1508). The disassembly's comments call 9 "10 lives" and 2 "3 lives"; Super C takes a life when a player spawns (bank-0.asm L1208-L1212), so the atlas hasn't turned the byte into a ship count.
Cited by: Cheat code, Super C
The US NES Super C allows 2 continues a game, where Contra allows 3: the count is set to 2 at the start, and each game over spends one before offering CONTINUE/END. super-c/lives
Value
{
"continues": 2
}src/bank-f.asm#L1484-L1490init_player_for_level_a:
…
lda #$02
sta NUM_CONTINUESSuper C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L2465-L2470level_routine_06:
dec LEVEL_ROUTINE_DELAY ; decrement level routine delay
bne game_over_exit ; exit if level delay hasn't elapsed
dec NUM_CONTINUES ; decrement number of continues
bmi restart_game ; branch if no more continues to reset the game
lda #$0a ; store "CONTINUE END" in CPU_GRAPHICS_BUFFERSuper C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L1322-L1323jsr clear_mid_high_ram
jsr init_player_level_1 ; set level 1, initialize player state, number of lives, player count, player mode, etc.Super C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L1478-L1479init_player_level_1:
lda #$00Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L1143-L1147init_score_player_lives:
…
lda #$03 ; a = #$03
sta NUM_CONTINUES ; continues remainingContra (US), annotated disassembly (vermiceli) · src/bank7.asm#L3301-L3302dec NUM_CONTINUES ; subtract from number of continues remaining
bmi @no_continues_remaining ; if run out of continues, jumpChecked by claude, 2026-10-21 — read the game start's call to init_player_level_1, which falls into init_player_for_level_a, and level_routine_06 in Super C, and Contra's init_score_player_lives and show_game_over_screen, at the pinned commitsCONTINUE runs init_player_vars (L2496), which skips the continue count. Super C takes a life when a player spawns, the level 1 helicopter drop included (bank-0.asm L1208-L1212), so the atlas doesn't yet say how many ships the starting byte of 2 gives; the disassembly's comment says 3.
The US NES Super C awards its first extra life at 30,000 points and each later one 20,000 points past the last threshold, the reverse of Contra's 20,000 and 30,000, and caps lives at 99 as Contra does. super-c/extra-life
About: Super C Extra life
Value
{
"first": 30000,
"every": 20000,
"max_lives": 99
}src/bank-f.asm#L1516-L1519lda #$30
sta NEXT_1_UP_SCORE_MID,x
lda #$00
sta NEXT_1_UP_SCORE_HI,x ; sets initial score to obtain to get an extra life to 0030000Super C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L1757-L1763@give_1_up:
…
ldx #$20
lda NEXT_1_UP_SCORE_MID,y
clc ; adding 0020000 to the required score to get the next 1-upSuper C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L1777-L1781lda PLAYER_NUM_LIVES,x
cmp #$63 ; see if at max number of lives (99 in decimal)
bcc @inc_num_lives
lda #$63
sta PLAYER_NUM_LIVES,x ; set number of lives to #$63 if #$63 or greaterContra (US), annotated disassembly (vermiceli) · src/bank7.asm#L1177-L1178lda #$c8 ; set default high score. #$c8 is 200 decimal
sta EXTRA_LIFE_SCORE_LOW ; starting score for extra life (20,000)Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L1283-L1296; every time an extra life is obtained, #$12c is added to points required to get next extra life (300 decimal, 30,000 in game score)
…
lda #$2c ; a = #$2c (12c = 300 decimal) (high byte will be set to #$01 a few lines down)
@set_extra_life_inc_num_lives:
adc EXTRA_LIFE_SCORE_LOW,y ; add 300 decimal to low byte of score required to get extra life
sta EXTRA_LIFE_SCORE_LOW,y ; player score for extra life - low byte
lda #$01 ; a = #$01Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L1312-L1314cmp #$63 ; compare to #$63 (99 decimal)
bcc @set_num_lives ; can't have more than 99 lives
lda #$63 ; a = #$63 (63 = 99 decimal)Checked by claude, 2026-10-25 — read the 1-up setup in init_player_vars and @give_1_up in Super C, and Contra's extra-life setup, @extra_life_logic, and the 99 cap, at the pinned commits; Contra adds $12C (300) to the threshold at bank7 L1291-L1296Super C keeps its 1-up threshold in binary-coded decimal, so $30 in the middle byte is 30,000 and adding $20 is 20,000.
Cited by: Extra life, Super C
The US NES Super C dispatches a weapon item on its type: M, S, L, and F replace the gun, R sets rapid fire, B sets an invincibility timer to $80, and the falcon destroys the enemies. A new gun drops rapid fire even when it's the gun already held, where Contra keeps it for the same gun. super-c/weapon-pickup
About: Super C Weapon pickup
CodeSuper C (US), annotated disassembly (vermiceli) ·src/bank-3.asm#L411-L445weapon_item_pickup_tbl:
.addr weapon_item_pickup ; machine (M)
.addr weapon_item_pickup ; spray (S)
.addr weapon_item_pickup ; laser (L)
.addr weapon_item_pickup ; flame (F)
.addr r_weapon_item_pickup ; rapid fire (R)
.addr b_weapon_item_pickup ; barrier (B)
.addr falcon_weapon_item_pickup ; falcon
…
lda #$80
sta INVINCIBILITY_TIMER,y ; set player invincible timer to #$80 frames
…
…Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L6933-L6945@compare_and_set_weapon:
ldy #$f0 ; y = #$f0 (keep rapid fire flag)
…
beq @set_player_weapon ; keep rapid fire flag (if set) when picking up same weapon
ldy #$e0 ; remove rapid fire flag since picking up different weapon
…
and P1_CURRENT_WEAPON,x ; strip/set rapid fire flag
ora $08 ; merge in rapid fire flag with weapon being picked up
sta P1_CURRENT_WEAPON,x ; set current player's weaponChecked by claude, 2026-10-21 — read weapon_item_pickup_tbl through set_weapon_remove_weapon_item in Super C and @compare_and_set_weapon in Contra at the pinned commits; Super C's gun pickup stores the new gun number with no rapid-fire bitThe disassembly's comment calls the barrier's $80 frames; Super C counts the timer down every 4 frames (bank-0.asm L1057, by its comment), which the atlas hasn't read. Contra's comment gives every 8.
Cited by: Super C, Weapon pickup
The US NES Super C takes 16 off the delay between random enemies once the game has been beaten and 4 for each living player holding the spread gun. The delay's start is read from an eight-entry per-level table with an index that isn't the level; the disassembly reads it as always $80, a value the table doesn't hold, and the atlas hasn't confirmed it. Where Contra counts loops up to 3, Super C keeps a beaten-once flag that stays at 1; where Contra reads every gun's strength, Super C counts only the spread gun. super-c/rank
Value
{
"beaten": 16,
"per_spread_player": 4
}src/bank-0.asm#L3755-L3779enemy_gen_routine_00:
lda CURRENT_LEVEL ; !(BUG) a is immediately overwritten
; this should probably have been ldy CURRENT_LEVEL
lda level_enemy_gen_delay_tbl,y ; y is actually PRG bank number, e.g. #$33 and not current level
; this causes the delay to always be #$80
…
ldy GAME_COMPLETED ; load whether or not the game has been completed
beq @adj_for_difficulty ; branch if haven't beaten the game yet
…
lda #$10
jsr @set_enemy_gen_delay ; subtract #$10 * GAME_COMPLETED from ENEMY_GEN_DELAY
…
…Super C (US), annotated disassembly (vermiceli) · src/bank-0.asm#L4286-L4287level_enemy_gen_delay_tbl:
.byte $7b,$53,$53,$53,$53,$53,$53,$53Super C (US), annotated disassembly (vermiceli) · src/bank-0.asm#L165-L181; calculate ENEMY_DIFFICULTY based on number of active players with S weapon
…
lda PLAYER_CURRENT_WEAPON,x ; 0 = Regular, 1 = M, 2 = S, 3 = L, 4 = F
and #$0f ; strip rapid fire flag
cmp #$02 ; compare to S weapon
bne @next_player ; move to next player if current player doesn't have S weapon
iny ; increment number of players in normal state that have the S weapon
…
sty ENEMY_DIFFICULTY ; set enemy difficultySuper C (US), annotated disassembly (vermiceli) · src/bank-f.asm#L2421-L2431lda GAME_COMPLETED ; load whether or not the game has been completed
adc #$00 ; increment game completion count (carry is set)
cmp #$02 ; see if game already completed
bcc @continue ; branch if first time completing game to set value to #$01
lda #$01 ; game already beaten at least once, keep value of #$01 (don't set to #$02)Contra (US), annotated disassembly (vermiceli) · src/bank2.asm#L1736-L1757adjust_generation_timer:
…
cmp #$04 ; compare GAME_COMPLETION_COUNT to #$04
bcc @continue ; branch if GAME_COMPLETION_COUNT < #$04
ldy #$03 ; maximum multiplier of increase chance for generating soldier is #$03
…
ldy PLAYER_WEAPON_STRENGTH ; load player weapon strength (damage strength)Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L4111-L4116weapon_strength:
.byte $00 ; Regular = Weak
.byte $02 ; M = Strong
.byte $01 ; F = Medium
.byte $03 ; S = Very Strong
.byte $02 ; L = StrongChecked by claude, 2026-10-21 — read enemy_gen_routine_00, the ENEMY_DIFFICULTY count, and the GAME_COMPLETED update in Super C, and Contra's adjust_generation_timer and weapon_strength, at the pinned commitsThe disassembly says Y holds a PRG bank number such as $33 there, which reads past the table's eight bytes (L3756-L3759). A probe reading ENEMY_GEN_DELAY on level 1 would settle the start. Vermiceli's docs/Game Completion Modifier.md lists further changes after a win.
The US NES Super C keeps Contra's outdoor jump: a take-off speed of $FB.$F0 (4.06 px/frame up) and gravity of $23 a frame. Super C caps a fall at 5 px/frame and jumps out of water at $FD.$00 (3 px/frame). super-c/jump
Value: 1040 1/256 px/frame
CodeSuper C (US), annotated disassembly (vermiceli) ·src/bank-0.asm#L1538-L1573ldy #$00 ; default jump velocity index (-4.0625)
lda PLAYER_SURFACE,x ; load the kind of surface the player is standing on
cmp #$04 ; see if player in water
bne @set_init_jump_y_vel ; branch if player not in water
ldy #$02 ; player in water, set Y fractional velocity index
…
@apply_gravity:
lda PLAYER_Y_FRACT_VELOCITY,x
clc ; clear carry in preparation for addition
adc #$23
…
cmp #$05
…Super C (US), annotated disassembly (vermiceli) · src/bank-0.asm#L1755-L1757player_jump_initial_y_vel_tbl:
.byte $f0,$fb ; player not in water (-4.0625)
.byte $00,$fd ; jumping from water (-3)Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L4547-L4550lda #$fb ; a = #$fb (-5)
ldy #$f0 ; y = #$f0 (.94)The atlas reads this differently: The fraction byte is unsigned and carries into the whole byte, so $FB.$F0 is −5 + 240/256 = −4.0625 px/frame and $FC.$90 is −3.4375, not −5.94 and −4.56. (contra/jump)Contra (US), annotated disassembly (vermiceli) · src/bank7.asm#L5139-L5142apply_gravity:
clc
lda PLAYER_Y_FRACT_VELOCITY,x ; load player's Y fractional velocity
adc #$23 ; add #$23 to Y fractional velocity (.1367 decimal)Checked by claude, 2026-10-21 — read the jump start, gravity, and fall cap in Super C's player routine and its take-off table, and Contra's set_jump_status_and_y_velocity and apply_gravity, at the pinned commitsSuper C's comments read $FB.$F0 as −4.0625, as the atlas does for Contra (contra/jump).
Cited by: Super C