    .ifndef WITH_STRICT_SO
    .equ WITH_STRICT_SO,0
    .endif
    .ifndef WITH_ALT_GOALIES
    .equ WITH_ALT_GOALIES,0
    .endif
    .ifndef LEGACY_OVERTIME
    .equ LEGACY_OVERTIME,0
    .endif
| Selected-period OT in league/playoffs, then native on-rink shootout with rotating co-op pads.
| Three attempts each, early clinch, paired sudden death. Normal match stats stay intact.
    .equ S,0xFFFFF090             | 0idle,1shootout,2finish pending; scratch throughF0AF
    .equ SIDES,S+2              | originalP1/P2 sides
    .equ SCORES,S+6             | tied normal home/away goals
    .equ FLAGS,S+10             | originalC2EA side bit
    .equ ATT,S+12               | attempts home/away
    .equ WIN,S+16               |1home,2away
    .equ LINES,S+18             | native line, manpower and pulled-goalie words for both clubs
    .equ EXTRA_SIDES,0xFFFFF0CC | P3/P4 saved only during a shootout; fourgoalie ends atF0CB
    .text
    .globl _start
_start:
    bra.w timer
    bra.w expiry
    bra.w frame
    bra.w setup
    bra.w advance
    bra.w goalstats
    bra.w shots
    bra.w fresh
    bra.w stars

timer:
    jsr 0x784E
    .if LEGACY_OVERTIME
    cmpi.w #3,0xFFFFC466
    bne.s timer_done
    move.w #600,%d0
    .endif
timer_done:
    jmp 0x782E
fresh:
    clr.w S
    clr.w WIN
    st.b 0xFFFFD6B4
    clr.l 0xFFFFDEA4
    jmp 0x774A                  | replay native match initialization

frame:
    cmpi.w #2,S
    beq.w finish
    tst.w S
    bne.w idle
    btst #0,0xFFFFC2EA
    bne.w idle
    tst.w 0xFFFFC468
    bne.w idle
    jmp 0x7B42
idle:
    jmp 0xA9D4

expiry:
    cmpi.w #3,0xFFFFC466
    bne.w period_over
    btst #4,0xFFFFC2EA
    bne.w native_expiry
    btst #0,0xFFFFC2FA
    bne.w native_expiry
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    move.w #1,S
    move.l 0xFFFFC328,SIDES
    move.l 0xFFFFC32C,EXTRA_SIDES
    clr.l 0xFFFFC32C            | only the existing P1/P2 shooter/keeper rotation has actors
    move.w 0xFFFFC6DA,SCORES
    move.w 0xFFFFCA3E,SCORES+2
    move.w 0xFFFFC2EA,FLAGS
    clr.l ATT
    clr.w WIN
    move.b #1,0xFFFFC2FA
    .if WITH_STRICT_SO
    jsr 0x222000                 | capture native eligibility before occupancy normalization
    .endif
    jsr 0xFC47C                  | native shot actors/rosters; team/player match statistics are elsewhere
    lea 0xFFFFC6CE,%a0
    lea LINES,%a1
    bsr.w shot_line
    lea 0xFFFFCA32,%a0
    bsr.w shot_line
    move.b #1,0xFFFFC2EA
    clr.w 0xFFFFC2F2
    clr.l 0xFFFFF058             | discard transient goalie-pass/crit visual state
    clr.l 0xFFFFF05C
    clr.l 0xFFFFF060
    clr.l 0xFFFFF064
    clr.w 0xFFFFC466
    lea 0xFFFFC3A4,%a0
    moveq #31,%d0
clear_events:
    clr.w (%a0)+
    dbra %d0,clear_events
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    jmp 0x7866
| Native actor assignment must use a full, valid line. A late penalty/automatic
| change can leave +16=5 and +24=5: native shootout then tries roster255 for the
| next keeper. Clear active penalties/bench occupancy, retaining G/A/SOG/PIM.
shot_line:
    move.w 0x16(%a0),(%a1)+
    move.w 0x24(%a0),(%a1)+
    move.w 0x26(%a0),(%a1)+
    clr.w 0x16(%a0)
    move.w #6,0x24(%a0)
    clr.w 0x26(%a0)
    lea 0x66(%a0),%a2
    moveq #25,%d0
clear_occupancy:
    move.w #-2,(%a2)+
    dbra %d0,clear_occupancy
    rts
native_expiry:
    tst.w 0xFFFFD048
    beq.s native_tie
period_over:
    moveq #2,%d0
    jmp 0x11F62
native_tie:
    jmp 0x7C16

setup:
    tst.w S
    beq.w native_setup
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    move.w 0xFFFFD594,%d0
    addq.w #1,%d0                | shooting side1/2
    moveq #-1,%d4
    cmp.w SIDES,%d0
    bne.s not_p1
    moveq #0,%d4
not_p1:
    cmp.w SIDES+2,%d0
    bne.s selected_pad
    tst.w %d4
    bmi.s only_p2
    move.w 0xFFFFD594,%d1
    add.w %d1,%d1
    lea ATT,%a0
    btst #0,1(%a0,%d1.w)       | own-side attempt index: P1,P2,P1,P2...
    beq.s selected_pad
only_p2:
    moveq #2,%d4
selected_pad:
    tst.w %d4
    bpl.s choose_shooter
    clr.l 0xFFFFC328
    move.w SIDES,0xFFFFC328      | one defending pad only; no second skater exists in a shootout
    tst.w SIDES
    bne.s sides_ready
    move.w SIDES+2,0xFFFFC32A
    bra.s sides_ready
choose_shooter:
    clr.l 0xFFFFC328
    tst.w %d4
    bmi.s sides_ready
    lea 0xFFFFC328,%a0
    move.w %d0,(%a0,%d4.w)
sides_ready:
    clr.l 0xFFFFC32C            | no P3/P4 may claim a two-actor shootout participant
    movem.l (%sp)+,%d0-%d7/%a0-%a6
native_setup:
    .if WITH_STRICT_SO
    jmp 0x222004
    .else
    jmp 0xFC4C0
    .endif

advance:
    tst.w S
    beq.w native_advance
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    cmpi.w #1,S
    bne.w advance_done
    move.w 0xFFFFD594,%d0
    add.w %d0,%d0
    lea ATT,%a0
    addq.w #1,(%a0,%d0.w)
    move.w 0xFFFFD574,%d2
    move.w 0xFFFFD576,%d3
    cmpi.w #3,ATT
    bcs.s regular_clinch
    cmpi.w #3,ATT+2
    bcs.s regular_clinch
    move.w ATT,%d0
    cmp.w ATT+2,%d0
    bne.w next_attempt
    cmp.w %d3,%d2
    bgt.w home_wins
    blt.w away_wins
    bra.w next_attempt
regular_clinch:
    moveq #3,%d0
    sub.w ATT,%d0               | home attempts still available in first3
    bpl.s home_remaining
    moveq #0,%d0
home_remaining:
    moveq #3,%d1
    sub.w ATT+2,%d1
    bpl.s away_remaining
    moveq #0,%d1
away_remaining:
    add.w %d3,%d1
    cmp.w %d1,%d2
    bgt.s home_wins
    add.w %d2,%d0
    cmp.w %d0,%d3
    bgt.s away_wins
    cmpi.w #3,ATT
    bcs.s next_attempt
    move.w ATT,%d0
    cmp.w ATT+2,%d0
    bne.s next_attempt
    cmp.w %d3,%d2
    bgt.s home_wins
    blt.s away_wins
next_attempt:
    eori.w #1,0xFFFFD594
    bne.s advance_done
    addq.w #1,0xFFFFD586
    cmpi.w #5,0xFFFFD586
    bcs.s roster_ready
    clr.w 0xFFFFD586
roster_ready:
    addq.w #1,0xFFFFD578
    bra.s advance_done
home_wins:
    move.w #1,WIN
    bra.s winner
away_wins:
    move.w #2,WIN
winner:
    move.w #2,S                 | finish at next main-frame boundary, after goal handler unwinds
advance_done:
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    rts
native_advance:
    jmp 0xFC516

goalstats:
    movea.w #0xC6CE,%a2
    lea 0x364(%a2),%a1
    tst.w S
    beq.s normal_goal_stats
    tst.w 0x14(%a3)
    bpl.s goal_side
    exg %a2,%a1
goal_side:
    btst #1,0xFFFFC2EA
    beq.s goal_side_ready
    exg %a2,%a1
goal_side_ready:
    bclr #4,0xFFFFC2FA
    bclr #7,0xFFFFC2FE
    jmp 0x149C2                 | retain goal celebration/attempt end, omit normal scoring log/stats
normal_goal_stats:
    jmp 0x14866
shots:
    tst.w S
    beq.s native_shots
    bclr #4,0xFFFFC2EE
    rts
native_shots:
    .if WITH_ALT_GOALIES
    jmp 0x221020
    .else
    btst #0,0xFFFFC2EA
    beq.s live_shots
    jmp 0x15464
live_shots:
    jmp 0x12F3A

    .endif

finish:
    lea 0xFFFFC6CE,%a0
    lea LINES,%a1
    bsr.w restore_line
    lea 0xFFFFCA32,%a0
    bsr.w restore_line
    move.l SIDES,0xFFFFC328
    move.l EXTRA_SIDES,0xFFFFC32C
    move.w SCORES,0xFFFFC6DA
    move.w SCORES+2,0xFFFFCA3E
    cmpi.w #1,WIN
    bne.s won_away
    addq.w #1,0xFFFFC6DA
    bra.s result_ready
won_away:
    addq.w #1,0xFFFFCA3E
result_ready:
    bclr #0,0xFFFFC2FA
    bclr #1,0xFFFFC2FA
    bclr #2,0xFFFFC2FA
    bclr #3,0xFFFFC2FA
    bclr #1,0xFFFFC2EA
    btst #1,FLAGS
    beq.s orientation_ready
    bset #1,0xFFFFC2EA
orientation_ready:
    clr.w S
    move.w #3,0xFFFFC466
    clr.w 0xFFFFC468
    jmp 0x7C16

restore_line:
    move.w (%a1)+,0x16(%a0)
    move.w (%a1)+,0x24(%a0)
    move.w (%a1)+,0x26(%a0)
    rts

| Native Three Stars gives the last logged scorer an overtime bonus. Shootout
| deciders have no normal goal-log entry: never read a stale/absent last scorer.
stars:
    tst.w WIN
    bne.s no_ot_star
    cmpi.w #3,0xFFFFC466
    bne.s no_ot_star
    jmp 0x1864C
no_ot_star:
    jmp 0x1867C
