Mike Tyson's Punch-Out!!
Nintendo's 1987 NES boxing game, read here in its Rev 1 release through nmikstas's partial disassembly.
On this page
The atlas reads the NES Rev 1 release of Mike Tyson’s Punch-Out!! through Nick Mikstas’s Ophis disassembly. Assembled, it matches the ROM’s PRG byte for byte. It’s a work in progress: the opponent state machine, the engine bank, and Glass Joe’s data are labeled and commented, while much of the rest is raw. Labels and comments quoted here are his. Nothing has been measured in the ROM yet.
Each opponent move is an script of timed steps. One step marks the punch active and branches on the result: landed, blocked, ducked, or dodged1. A second list, read while the opponent waits, picks the next move. Some of its steps go by a roll against a random byte. The NMI handler rebuilds that byte from moved bits of the frame counter and of a running total of controller 1’s buttons2. Glass Joe’s right hook shows a whole move. It loads its pose, warns, waits a variable time, and throws the punch at Little Mac’s left with damage 7 added to his base of 43.
The warning is a telegraph: the script recolors the opponent’s outline for a few frames, from Glass Joe’s normal color to his dodge color4.
Little Mac’s hearts are his stamina. Against Glass Joe they start rounds 1 to 3 at 20, 20, and 15. A round never starts below its count, and at zero hearts Little Mac can’t punch5. When an opponent goes down in a knockdown, the game sets the count he’ll rise on, from his data or a roll on a table of eight; Glass Joe’s table runs from 2 to 86.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Attack pattern | Script and chance | each move is a script of timed steps that branches on block, duck, or dodge; a selector list picks the next, some steps by an n-in-16 roll |
| Telegraph | Color flash | a script recolors the opponent's outline before a punch; Glass Joe's right hook sets a count of 4, 4 frames by the comment |
| Stamina | Action cost | hearts drop by 1 or 3; at zero Little Mac can't punch, and each round starts at no less than a set count |
| Knockdown | Set count | a downed opponent's get-up count comes from his data or a roll on an eight-entry table |
Every claim about this game, by concept (6)
References
- ^In Mike Tyson's Punch-Out!! (NES, Rev 1), each opponent move is a script of state data that one interpreter, OppStateUpdate, steps through. A control byte's upper nibble picks a handler, and for upper nibbles
$Bto$Fthe lower nibble picks a sub-command from a second table. The commands, named by the disassembly's ST_ constants, load sprites and frame timers, call and return from shared sub-scripts, jump, branch when a zero-page byte holds a given value, repeat a step, mark the opponent as punching, and set the punch's side and damage. At a punch's active step the script waits until the punch is resolved. A landed punch goes on past the step's three index bytes; a blocked, ducked, or dodged one jumps to the first, second, or third index. A path through a move ends with ST_END, which marks the state STAT_FINISHED ("Indicate the end of the current state has been reached", per the comment), or with ST_WAIT_STATE, which stores$81in OppCurState: the opponent's wait state, in the comment's words.Codenmikstas/mike-tysons-punch-out-disassemblyrevisedHow we know
4654;This function is the entry point for updating the opponent's state. It uses the upper nibble of 4655;a control byte to pick a function to run from the table below. The function it calls may then 4656;call another set of functions with the lower nibble of the same control byte(or it may not). ⋮ 4664LC556: AND #$0F ;Keep lower nibble for later. ⋮ 4670LC55C: JSR Div16 ;($BF99)Shift upper nibble to lower nibble. 4671LC55F: JSR IndFuncJump ;($AED4)Indirect jump to desired function below. ⋮ 4673LC562: .word OppLoadSprites, SpritesNxtXYState, $C5B3, $C5B7 4674LC56A: .word $C5C8, $C5CE, SprtMove, OppMoveSprites 4675LC572: .word OppSetTimer, $C600, OppBigMove, OppStateUpdate1 4676LC57A: .word OppStateUpdate1, OppStateUpdate1, OppStateUpdate1, OppStateUpdate2
source_files/PRG_BankDEF.asm lines 4654–4676 at 60b2fa0 · upstream ↗ 4889OppStateUpdate1: 4890LC670: TXA ;Get index into table below. 4891LC671: JSR IndFuncJump ;($AED4)Indirect jump to desired function below. ⋮ 4893LC674: .word OppCallFunc, OppReturnFunc, NULL_PNTR, NULL_PNTR 4894LC67C: .word OppVarStTime, OppNotPunch, $C6CA, $C6D7 4895LC684: .word $C6DF, $C6EA, NULL_PNTR, NULL_PNTR 4896LC68C: .word InitAudio
source_files/PRG_BankDEF.asm lines 4889–4896 at 60b2fa0 · upstream ↗ 5017OppStateUpdate2: 5018LC720: TXA ;Get index into table below. 5019LC721: JSR IndFuncJump ;($AED4)Indirect jump to desired function below. ⋮ 5021LC724: .word PunchActive, OppStateJump, ChkMemAndBranch, ChkRepeatState 5022LC72C: .word OppWaitState, OppRepeat, OppPunchDirDmg, OppDefInline 5023LC734: .word $C7E1, OppPunch, WriteZPageByte, OppSpecTimer 5024LC73C: .word OppComboWait, $C816, $C81D, StateDone
source_files/PRG_BankDEF.asm lines 5017–5024 at 60b2fa0 · upstream ↗ 508.alias ST_SPRITES $00 ;Load sprite data for current opponent sub-state. ⋮ 513.alias ST_TIMER $80 ;Number of frames for sub-state to wait. ⋮ 515.alias ST_CALL_FUNC $E0 ;Call an opponent state subroutine. 516.alias ST_RETURN_FUNC $E1 ;Return from an opponent state subroutine. ⋮ 519.alias ST_PNCH_ACTIVE $F0 ;Indicates an opponent's punch is active. 520.alias ST_JUMP $F1 ;Jump to new state base address and index. 521.alias ST_CHK_BRANCH $F2 ;Check memory for value and branch in state data if value found. 522.alias ST_CHK_REPEAT $F3 ;Check if a sub-state needs to repeat. 523.alias ST_WAIT_STATE $F4 ;Put opponent into wait state. 524.alias ST_REPEAT $F5 ;Load a repeat value for this sub-state. 525.alias ST_PUNCH_SIDE $F6 ;Indicate what side of Little Mac a punch is approaching. ⋮ 527.alias ST_PUNCH $F9 ;Indicate the opponent is punching. ⋮
source_files/Mike_Tysons_Punchout_Defines.asm lines 508–531 at 60b2fa0 · upstream ↗ 5028PunchActive: 5029LC744: LDX OppPunchSts ;Is the punch initialized but not yet processed? 5030LC746: BMI OppStateWait ;If so, branch. ⋮ 5038LC74E: DEC OppStateIndex ;Stay on this state and exit. ⋮ 5042LC751: CPX #PUNCH_LANDED ;Was punch landed? 5043LC753: BEQ PunchLanded ;If so, branch. ⋮ 5045LC755: BCC PunchBlckDck ;Was punch blocked or ducked? If so, branch. ⋮ 5048LC757: DEX ;Dodged punch must have index increased by 2 (4-2=2). ⋮ 5051LC758: DEX ;Only decrement punch status by 1 for block/duck. 5052LC759: TXA ; 5053LC75A: CLC ; 5054LC75B: ADC OppStateIndex ;Get the index to jump to for blocked/ducked or dodged punches. ⋮
source_files/PRG_BankDEF.asm lines 5028–5072 at 60b2fa0 · upstream ↗ 540.alias PUNCH_BLOCKED $01 ;Punch blocked by Little Mac. 541.alias PUNCH_DUCKED $02 ;Punch is ducked by Little Mac. 542.alias PUNCH_LANDED $03 ;Punch hit Little Mac. 543.alias PUNCH_DODGED $04 ;Punch dodged by Little Mac.
source_files/Mike_Tysons_Punchout_Defines.asm lines 540–543 at 60b2fa0 · upstream ↗ 5147OppWaitState: 5148LC7B6: LDA #$81 ; 5149LC7B8: STA OppCurState ;Put the opponent into their wait state.
source_files/PRG_BankDEF.asm lines 5147–5150 at 60b2fa0 · upstream ↗ 5259StateDone: 5260LC821: DEC OppStateIndex ; 5261LC823: LDA #STAT_FINISHED ;Indicate the end of the current state has been reached. ⋮ 5264LC825: STA OppStateStatus ;
source_files/PRG_BankDEF.asm lines 5259–5264 at 60b2fa0 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^The NES Rev 1 picks an opponent's next move with a second, uncommented script reader at
$B196, run from the main game loop. While$38is nonzero and OppCurState is 1 (the wait state, in the atlas's reading of the defines), it decrements$39on each call and, when that reaches zero, reads a list of command bytes. In the atlas's reading of the code:0n ssets OppCurState tosand$39to n, the count of calls before the next command (n = 0 gives 256, as$39wraps to$FF);1n ijumps to list indexiwhen n is greater than the low four bits of a random byte, n/16 of the time (computed), and always when n is 15; and2nwith eight state bytes after it sets$39to n and starts one of the eight, chosen by the random byte's low three bits. The random byte is$18, which an uncommented routine at$85E9in bank 7 sets to the sum of two scrambles:$ED, bits of FrameCounter moved to new positions, and$EC, moved bits of$19with$19AND$81ORed in.$19is a running total, kept from call to call, to which each call adds moved bits of Joy1Buttons. Two paths of the NMI handler call the routine, each right after it increments FrameCounter.$AEF1rotates$18three times after each read. Bytes from$80up hold other commands, not read here.Codenmikstas/mike-tysons-punch-out-disassemblyrevisedHow we know
725MainGameEngine: ⋮ 752LA6A2: JSR $B196
source_files/PRG_BankDEF.asm lines 725–752 at 60b2fa0 · upstream ↗ 2213LB196: LDA $38 2214LB198: BEQ $B1CD 2215LB19A: LDX OppCurState 2216LB19C: DEX 2217LB19D: BNE $B1CD 2218LB19F: DEC $39 2219LB1A1: BNE $B1CD 2220LB1A3: INC $39 2221LB1A5: LDY $3A 2222LB1A7: LDA ($3B),Y 2223LB1A9: AND #$0F 2224LB1AB: TAX ⋮
source_files/PRG_BankDEF.asm lines 2213–2261 at 60b2fa0 · upstream ↗ 1731LAEAB: STA $EF 1732LAEAD: LDA #$0F 1733LAEAF: STA $EE 1734LAEB1: LDA $EF 1735LAEB3: CMP $EE 1736LAEB5: BEQ $AEC7 1737LAEB7: LDA $18 1738LAEB9: JSR $AEF1 1739LAEBC: AND $EE 1740LAEBE: STA $EE 1741LAEC0: LDA $EF 1742LAEC2: CMP $EE ⋮
source_files/PRG_BankDEF.asm lines 1731–1745 at 60b2fa0 · upstream ↗ 1783LAEF1: ROR $18 1784LAEF3: ROR $18 1785LAEF5: ROR $18 1786LAEF7: RTS
source_files/PRG_BankDEF.asm lines 1783–1786 at 60b2fa0 · upstream ↗ 725L85E9: LDA FrameCounter ;($1E) 726L85EB: ROR 727L85EC: STA $E8 ⋮ 733L85F5: AND #$08 734L85F7: STA $ED ⋮ 759L8625: STA $ED 760L8627: LDA Joy1Buttons ⋮ 789L865C: ORA $EC 790L865E: CLC 791L865F: ADC $19 792L8661: STA $19 793L8663: ROR ⋮
source_files/PRG_Bank007.asm lines 725–831 at 60b2fa0 · upstream ↗ 12L8012: JMP $85E9source_files/PRG_Bank007.asm line 12 at 60b2fa0 · upstream ↗ 705LA644: INC FrameCounter ;($1E) ⋮ 709LA64C: JSR PushPRGBank07 ;($AA3C) 710LA64F: JSR $8012
source_files/PRG_BankDEF.asm lines 705–710 at 60b2fa0 · upstream ↗ 802LA6F8: INC FrameCounter ;($1E) ⋮ 826LA724: JSR PushPRGBank07 ;($AA3C) 827LA727: JSR $8012
source_files/PRG_BankDEF.asm lines 802–827 at 60b2fa0 · upstream ↗ 53.alias OppCurState $90 ;Opponent's current state. Set MSB=initialize new state.source_files/Mike_Tysons_Punchout_Defines.asm line 53 at 60b2fa0 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^Glass Joe's right hook in the NES Rev 1 is the commented script GJRighHook. It loads defense values, shows sprite data
$0A("6 frames for this sub-state", per the comment), flags the opponent as punching, and writes OPP_RGHT_HOOK to$BB. It then sets OppOutlineTimer to$84, a count of 4 calls of SetOppOutlineClr (the comment: "Change outline color for 4 frames"), and waits a variable time, VariableStTime. At index$1E, ST_CHK_REPEAT jumps to index$24while its repeat counter, loaded as 1, hasn't run out; with 1 it falls through. If MacStatus holds MAC_SUPER_PUNCH, it branches to index$59; otherwise it starts the punch sound and sets the punch on Little Mac's left side with damage 7, which the comment says is added to base damage. Glass Joe's fight data sets that base damage at 4. At the punch's active step (index$32), a landed punch falls through to index$36: a 4-frame timer (per the comment), sprite moves, and ST_END at index$44. The step gives index$45for a block, which jumps into his straight punch's state at index$3B, and index$49for a duck or a dodge, which loads a special timer, sets his defense values to zero, moves his sprites, and waits for the combo timer before the wait state.Codenmikstas/mike-tysons-punch-out-disassemblyrevisedHow we know
634GJRighHook: ⋮ 637L8C4D: .byte ST_CALL_FUNC ;Call state data subroutine 638L8C4E: .word DefenseStats3 ;Defense data pointer. ⋮ 649L8C54: .byte ST_SPRITES_XY+6 ;Load sprites, change position, 6 frames for this sub-state. ⋮ 655L8C58: .byte ST_PUNCH ;Indicate opponent is punching. ⋮ 658L8C59: .byte ST_DEFENSE ;Load opponent's defense data from following 4 bytes. ⋮ 664L8C5F: .byte ST_WRITE_BYTE ;Write a byte to zero page memory. 665L8C60: .byte GameStatusBB ;address $BB. 666L8C61: .byte OPP_RGHT_HOOK ;Indicate a right hook is being thrown. ⋮ 678L8C67: .byte ST_WRITE_BYTE ;Write a byte to zero page memory. 679L8C68: .byte OppOutlineTimer ;Change opponent's outline color to indicate its time to dodge. 680L8C69: .byte $84 ;Change outline color for 4 frames. ⋮
source_files/PRG_Bank000.asm lines 634–709 at 60b2fa0 · upstream ↗ 641L8C50: .byte ST_REPEAT ;Load sub-state repeat. 642L8C51: .byte $01 ;No repeat for this sub-state.
source_files/PRG_Bank000.asm lines 641–642 at 60b2fa0 · upstream ↗ 685;Index #$1E. 686L8C6B: .byte ST_CHK_REPEAT ;Check if repeat counter is active. 687L8C6C: .byte $24 ;Jump to index #$24 is repeat counter is active.
source_files/PRG_Bank000.asm lines 685–687 at 60b2fa0 · upstream ↗ 5130ChkRepeatState: 5131LC7A7: DEC OppStRepeatCntr ;Decrement sub-state repeat counter. 5132LC7A9: BEQ ChkRepeatEnd ;Does state need to be repeated? If not, branch to exit.
source_files/PRG_BankDEF.asm lines 5130–5143 at 60b2fa0 · upstream ↗ 717;Index #$32. 718L8C7F: .byte ST_PNCH_ACTIVE ;Indicate a punch is active. ⋮ 723;Index #$36 - Punch landed. 724L8C83: .byte ST_TIMER ;Load timer for this sub-state. 725L8C84: .byte $04 ;This sub-state lasts 4 frames. ⋮ 728L8C85: .byte ST_SPRT_MV_NU+4 ;Move sprites. Sub-state lasts for 4 frames. ⋮ 744L8C8D: .byte ST_SPRT_MV_NU+15 ;Move sprites. Sub-state lasts for 15 frames. ⋮ 751;Index #$44. 752L8C91: .byte ST_END ;End of state.
source_files/PRG_Bank000.asm lines 717–752 at 60b2fa0 · upstream ↗ 718L8C7F: .byte ST_PNCH_ACTIVE ;Indicate a punch is active. 719L8C80: .byte $45 ;Index to jump to if punch was blocked. 720L8C81: .byte $49 ;Index to jump to if punch was ducked. 721L8C82: .byte $49 ;Index to jump to if punch was dodged. ⋮ 755L8C92: .byte ST_JUMP ;Jump to new state and index. 756L8C93: .word GJStrtPunch ;Base address of new state. 757L8C95: .byte $3B ;Index of new state. ⋮ 760L8C96: .byte ST_SPEC_TIMER ;Load a special timer value. ⋮ 763L8C97: .byte ST_CALL_FUNC ;Call state data subroutine 764L8C98: .word DefenseStats6 ;Defense data pointer. ⋮ 787L8CA4: .byte ST_COMBO_WAIT ;Wait for the combo timer to expire. ⋮ 790L8CA5: .byte ST_WAIT_STATE ;Put opponent into wait state.
source_files/PRG_Bank000.asm lines 710–790 at 60b2fa0 · upstream ↗ 1078DefenseStats6: 1079L92B0: .byte ST_DEFENSE ;Load opponent's defense data from following 4 bytes. 1080L92B1: .byte $00, $00 ;Face punch defense values. 1081L92B3: .byte $00, $00 ;Stomach punch defense values.
source_files/PRG_Bank000.asm lines 1078–1081 at 60b2fa0 · upstream ↗ 4938OppVarStTime: 4939LC6BD: LDA VariableStTime ; 4940LC6C0: STA OppStateTimer ;Set a varying amount of time for this opponent's state time.
source_files/PRG_BankDEF.asm lines 4938–4941 at 60b2fa0 · upstream ↗ 1100;Glass Joe Fight data. Loaded into $05A0 through $05FF. ⋮ 1113L9325: .byte $04 ;Base damage if opponent lands a hit on Little Mac.
source_files/PRG_Bank000.asm lines 1100–1113 at 60b2fa0 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^The NES Rev 1 cues a dodge by recoloring the opponent's outline. A script writes OppOutlineTimer with its high bit set; the main game loop calls SetOppOutlineClr, which then clears that bit, keeps the count, and writes the fight's dodge outline color into four sprite palette entries. Each later call counts the timer down, and at zero it writes the normal color back. Glass Joe's fight data gives palette values
$26for the dodge outline and$08for the normal one, and his right hook sets the timer to$84, a count of 4 later calls (4 frames by the comment), before its variable wait and the punch.Codenmikstas/mike-tysons-punch-out-disassemblyrevisedHow we know
66.alias OppOutlineTimer $9C ;Timer for dodge indicator outline color. MSB set=set timer.source_files/Mike_Tysons_Punchout_Defines.asm line 66 at 60b2fa0 · upstream ↗ 4493SetOppOutlineClr: 4494LC440: LDA OppOutlineTimer ;Is outline color timer active? 4495LC442: BEQ OppOutlineEnd ;If not, branch to exit. ⋮ 4497LC444: BMI SetOutlineTimer ;Does ouotline color timer need to be initialized? If so, branch. ⋮ 4499LC446: DEC OppOutlineTimer ;Decrement outline color timer. Has timer expired? 4500LC448: BNE OppOutlineEnd ;If not, branch to exit. ⋮ 4502LC44A: LDY #$01 ;Prepare to set normal outline color. ⋮ 4506LC44E: AND #$7F ;Clear MSB to indicate timer is running. 4507LC450: STA OppOutlineTimer ;Set outline color timer. 4508LC452: LDY #$00 ;Prepare to set dodge indicator outline color. ⋮ 4511LC454: LDA OppOutline,Y ;Get opponent outline color. 4512LC457: LDX #$04 ;Prepare to change 4 sprite palette bytes. ⋮
source_files/PRG_BankDEF.asm lines 4493–4530 at 60b2fa0 · upstream ↗ 725MainGameEngine: ⋮ 763LA6C3: JSR SetOppOutlineClr ;($C440)Set opponent outline color.
source_files/PRG_BankDEF.asm lines 725–763 at 60b2fa0 · upstream ↗ 224.alias OppOutline $05EC ;Base address for determining the opponent's outline color.source_files/Mike_Tysons_Punchout_Defines.asm line 224 at 60b2fa0 · upstream ↗ 1139L9363: .byte $26 ;Opponent outline color when Little Mac should dodge. 1140L9364: .byte $08 ;Normal opponent outline color.
source_files/PRG_Bank000.asm lines 1139–1140 at 60b2fa0 · upstream ↗ 678L8C67: .byte ST_WRITE_BYTE ;Write a byte to zero page memory. 679L8C68: .byte OppOutlineTimer ;Change opponent's outline color to indicate its time to dodge. 680L8C69: .byte $84 ;Change outline color for 4 frames. ⋮ 683L8C6A: .byte ST_VAR_TIME ;Set sub-state time to a variable amount.
source_files/PRG_Bank000.asm lines 677–683 at 60b2fa0 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^Little Mac's hearts in the NES Rev 1 are a two-digit decimal count. Glass Joe's fight data, in its comments, starts rounds 1, 2, and 3 at 20, 20, and 15 hearts, with normal recoveries of 15, 15, and 10 and reduced ones of 9, 9, and 5. The round setup routine, uncommented (it also loads the round's clock rate and starts the round timer), sets hearts to the table's value in round 1 and raises them to it in rounds 2 and 3 if they're lower, and it copies the two recovery values for the round. An uncommented routine at
$843Etakes hearts away, 1 or 3 at each of its six callers; when the count reaches zero or below it clears MacCanPunch, which the define reads as "Little Mac can't punch".Codenmikstas/mike-tysons-punch-out-disassemblyHow we know
1100;Glass Joe Fight data. Loaded into $05A0 through $05FF. ⋮ 1104L931C: .byte $20 ;Starting number of hearts, round 1(base 10). 1105L931D: .byte $15 ;Normal heart recovery, round 1(base 10). 1106L931E: .byte $09 ;Reduced heart recovery, round 1(base 10). 1107L931F: .byte $20 ;Starting number of hearts, round 2(base 10). 1108L9320: .byte $15 ;Normal heart recovery, round 2(base 10). 1109L9321: .byte $09 ;Reduced heart recovery, round 2(base 10). 1110L9322: .byte $15 ;Starting number of hearts, round 3(base 10). 1111L9323: .byte $10 ;Normal heart recovery, round 3(base 10). 1112L9324: .byte $05 ;Reduced heart recovery, round 3(base 10).
source_files/PRG_Bank000.asm lines 1100–1112 at 60b2fa0 · upstream ↗ 207.alias HeartTable $05A3 ;Table of heart values for this fight. (Indexing starts at 3)source_files/Mike_Tysons_Punchout_Defines.asm line 207 at 60b2fa0 · upstream ↗ 2733LB5A9: LDA #$01 2734LB5AB: STA MacCanPunch 2735LB5AD: LDA RoundNumber 2736LB5AF: CMP #$04 2737LB5B1: BCC $B5B6 2738LB5B3: JMP $B621 2739LB5B6: ASL 2740LB5B7: ADC RoundNumber 2741LB5B9: TAX 2742LB5BA: CMP #$03 2743LB5BC: BEQ $B5CB 2744LB5BE: LDA HeartTable,X ;($05A3) ⋮
source_files/PRG_BankDEF.asm lines 2733–2786 at 60b2fa0 · upstream ↗ 514L843E: TAX 515L843F: LDA CurHeartsLD 516L8442: ORA CurHeartsUD 517L8445: BEQ $849E 518L8447: TXA 519L8448: SEC 520L8449: STA $E7 521L844B: LDA CurHeartsLD 522L844E: SBC $E7 523L8450: BCS $8455 524L8452: ADC #$0A 525L8454: CLC ⋮
source_files/PRG_Bank007.asm lines 514–535 at 60b2fa0 · upstream ↗ 109L80D1: LDA #$01 110L80D3: JSR $843E
source_files/PRG_Bank007.asm lines 109–110 at 60b2fa0 · upstream ↗ 163L8143: LDA #$03 164L8145: JSR $843E
source_files/PRG_Bank007.asm lines 163–164 at 60b2fa0 · upstream ↗ 94.alias MacCanPunch $BC ;#$00=Little Mac can't punch, #$01=Little Mac can punch.source_files/Mike_Tysons_Punchout_Defines.asm line 94 at 60b2fa0 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^When KnockdownSts is 1 ("Opp down", per the define) in the NES Rev 1, uncommented code at
$B2EBcounts the knockdown in OppKDRound and OppKDFight, and at the third in a round it stops there. Otherwise, unless$BAheld$FF, it reads one entry from the opponent's table at OppRefillPtr (its index set by conditions not traced here). An entry of 0 sets nothing. An entry whose upper nibble n is nonzero sets OppGetUpCount to$99+ n, which the define reads as a count of n. An entry whose upper nibble is 0 picks one of the eight entries of OppGetUpTable with three bits of the random byte$18; Glass Joe's eight read, by the comment's encoding, 2, 3, 4, 5, 6, 8, 3, and 4.Codenmikstas/mike-tysons-punch-out-disassemblyHow we know
2386LB2EB: LDX $05 2387LB2ED: DEX 2388LB2EE: BNE $B2E7 ⋮ 2394LB2FB: INC OppKDRound ;($03CA) 2395LB2FE: INC OppKDFight ;($03D1) 2396LB301: LDA OppKDRound ;($03CA) 2397LB304: CMP #$03 2398LB306: BEQ $B2E2 2399LB308: LDA #$00 2400LB30A: LDX $BA 2401LB30C: STA $BA 2402LB30E: INX ⋮
source_files/PRG_BankDEF.asm lines 2386–2466 at 60b2fa0 · upstream ↗ 2380LB2E2: LDA #$00 2381LB2E4: STA $C0 2382LB2E6: RTS ⋮ 2385LB2EA: RTS
source_files/PRG_BankDEF.asm lines 2380–2385 at 60b2fa0 · upstream ↗ 14.alias KnockdownSts $05 ;Knockdown status #$01=Opp down, #$02=Mac downsource_files/Mike_Tysons_Punchout_Defines.asm line 14 at 60b2fa0 · upstream ↗ 100.alias OppGetUpCount $C4 ;Count opponent will get up on. #$9A=1 through #$A2=9.source_files/Mike_Tysons_Punchout_Defines.asm line 100 at 60b2fa0 · upstream ↗ 1134;Random opponent stand up times after knock down. #$9B=2 through #$A1=8. 1135L9356: .byte $9B, $9C, $9D, $9E, $9F, $A1, $9C, $9D
source_files/PRG_Bank000.asm lines 1134–1135 at 60b2fa0 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
Sources
Code
- (nmikstas), Nick Mikstas. 2020. “Mike Tyson's Punch-Out!! (NES), partial disassembly (nmikstas).” Commit 60b2fa0. nmikstas/mike-tysons-punch-out-disassembly @ 60b2fa0 · licence, all uses