    .ifndef WITH_PLAYER_BLUE_LINE
    .equ WITH_PLAYER_BLUE_LINE,0
    .endif
    .ifndef WITH_STRICT_SO
    .equ WITH_STRICT_SO,0
    .endif
| Attempt execution only: forward puck progress before a shot, native endings.
| +0 watches native F2F4; +4 starts each native attempt without input shortcuts.
| Twenty private transient bytes, never SRAM or controller assignments.
    .equ MAGIC,0xFFFFF65C
    .equ ACTOR,MAGIC+2
    .equ PHASE,MAGIC+4
    .equ STILL,MAGIC+6
    .equ HIGH,MAGIC+8
    .equ STARTX,MAGIC+12
    .equ STARTY,MAGIC+14
    .equ LAST,MAGIC+16
    .text
    .globl _start
_start:
    bra.w enforce
    bra.w fresh
fresh:
    .if WITH_ATTEMPT_RULES
    movem.l %d0-%d1/%a0,-(%sp)
    move.w 0xFFFFD406,%d0
    cmpi.w #11,%d0
    bhi.w fresh_invalid
    move.w %d0,ACTOR
    lsl.w #7,%d0
    lea 0xFFFFB04A,%a0
    adda.w %d0,%a0
    tst.w 0x34(%a0)
    ble.w fresh_invalid
    move.w (%a0),STARTX
    move.w 0x14(%a0),STARTY
    .if WITH_PLAYER_BLUE_LINE
    move.l 0x14(%a0),%d1              | actual shooter body centre, signed16.16
    .else
    move.l 0xFFFFB75E,%d1
    .endif
    btst #7,0x62(%a0)
    bne.s fresh_direction
    neg.l %d1
fresh_direction:
    move.l %d1,HIGH
    move.l %d1,LAST
    clr.l PHASE
    move.w #0x5352,MAGIC
    bra.s fresh_restore
fresh_invalid:
    clr.w MAGIC
fresh_restore:
    movem.l (%sp)+,%d0-%d1/%a0
    .endif
    .if WITH_STRICT_SO
    jsr 0x22200C                    | per-attempt turn history only, native setup/countdown retained
    .endif
    .if WITH_AUTO_START
    move.w #60,0xFFFFC31A
    .else
    move.w #400,0xFFFFC31A
    .endif
    rts

    .if WITH_PLAYER_BLUE_LINE

| Player-position rule, jdc2026-11-04. STILL is a per-attempt blue-entry latch,
| HIGH/LAST are normalized16.16 shooter positions. No puck progress/still filter.
| Native blue-line coordinate88 is used by E4F0/E4F4/E502/EC28.
| Strictly beyond88 activates; returning to/even fractionally toward the line
| then queues the existing native miss. No input, velocity, score or SRAM writes.
enforce:
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    move.w %sr,-(%sp)
    .if WITH_ATTEMPT_RULES
    btst #2,0xFFFFC2F2
    beq.w clear
    btst #4,0xFFFFC2F2
    bne.w restore
    btst #6,0xFFFFC2F2
    bne.w restore
    tst.w 0xFFFFC31A
    bpl.w restore
    move.b 0xFFFFC2EA,%d0
    andi.b #0x50,%d0
    bne.w restore
    move.b 0xFFFFC2EC,%d0
    andi.b #0x81,%d0
    bne.w restore
    move.w 0xFFFFD406,%d0
    cmpi.w #11,%d0
    bhi.w clear
    move.w %d0,%d1
    lsl.w #7,%d1
    lea 0xFFFFB04A,%a0
    adda.w %d1,%a0
    tst.w 0x34(%a0)
    ble.w clear
    move.l 0x14(%a0),%d2
    btst #7,0x62(%a0)
    bne.s normalized
    neg.l %d2
normalized:
    cmpi.w #0x5352,MAGIC
    bne.s initialize
    cmp.w ACTOR,%d0
    beq.s dispatch
initialize:
    move.w #0x5352,MAGIC
    move.w %d0,ACTOR
    clr.l PHASE
    move.l %d2,HIGH
    move.l %d2,LAST
    move.w (%a0),STARTX
    move.w 0x14(%a0),STARTY
 dispatch:
    cmpi.w #3,PHASE
    beq.w restore
    tst.w STILL
    bne.s crossed
    cmpi.l #0x00580000,%d2            | exactly on the line is not past it
    ble.s remember
    move.w #1,STILL                  | cannot clear by retreating across blue
    cmpi.w #2,PHASE
    beq.s crossed
    move.w #1,PHASE
crossed:
    cmp.l LAST,%d2
    blt.w fail                       | any actual centreward motion, including fractions
remember:
    move.l %d2,LAST
    cmp.l HIGH,%d2
    ble.s check_shot
    move.l %d2,HIGH
check_shot:
    cmpi.w #2,PHASE
    beq.w restore                    | puck/native flight stays native; shooter rule above still applies
    btst #5,0xFFFFC2F2
    bne.w flight
    .if WITH_STRICT_SO
    tst.w STILL
    beq.s no_spin_check              | requested unrestricted movement before blue overrides spin there
    jsr 0x222008
    tst.w %d0
    bne.w fail
no_spin_check:
    .endif
    | Retain the existing pre-shot outside-goal-mouth ending. This is a
    | spatial goal-line guard, not a new puck backwards/progress rule.
    move.w 0xFFFFB74A,%d3
    bpl.s xpositive
    neg.w %d3
xpositive:
    cmpi.w #21,%d3
    bls.w restore
    move.l 0xFFFFB75E,%d3
    btst #7,0x62(%a0)
    bne.s puck_normalized
    neg.l %d3
puck_normalized:
    cmpi.l #0x01080000,%d3
    bgt.s fail
    bra.s restore
flight:
    move.w #2,PHASE
    bra.s restore
fail:
    move.w #3,PHASE
    bset #4,0xFFFFC2F2                 | one existing native miss, no result/stat writes
    bra.s restore
clear:
    clr.w MAGIC
    .endif
restore:
    move.w (%sp)+,%sr
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    movem.w %d0,-(%sp)
    move.w 0xFFFFB7AA,%d0
    jmp 0xF2FC

    .else

enforce:
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    move.w %sr,-(%sp)
    .if WITH_ATTEMPT_RULES
    btst #2,0xFFFFC2F2
    beq.w clear
    btst #4,0xFFFFC2F2
    bne.w restore
    btst #6,0xFFFFC2F2
    bne.w restore
    tst.w 0xFFFFC31A
    bpl.w restore                     | announce/setup is not part of the approach
    move.b 0xFFFFC2EA,%d0
    andi.b #0x50,%d0                   | attempt clock uses C2FA: native C2EA stop bit stays set
    bne.w restore
    move.b 0xFFFFC2EC,%d0
    andi.b #0x81,%d0
    bne.w restore                     | pause/foreign view never charges the still counter
    move.w 0xFFFFD406,%d0
    cmpi.w #11,%d0
    bhi.w clear
    move.w %d0,%d1
    lsl.w #7,%d1
    lea 0xFFFFB04A,%a0
    adda.w %d1,%a0
    tst.w 0x34(%a0)
    ble.w clear                       | only a real designated skater
    move.l 0xFFFFB75E,%d2              | signed16.16 native puck Y, including sub-pixel motion
    btst #7,0x62(%a0)
    bne.s normalized
    neg.l %d2
normalized:
    cmpi.w #0x5352,MAGIC
    bne.s initialize
    cmp.w ACTOR,%d0
    beq.s dispatch
initialize:
    move.w #0x5352,MAGIC
    move.w %d0,ACTOR
    clr.l PHASE
    move.l %d2,HIGH
    move.l %d2,LAST
    move.w (%a0),STARTX
    move.w 0x14(%a0),STARTY
 dispatch:
    tst.w PHASE
    bne.s armed
    btst #5,0xFFFFC2F2
    bne.w flight                      | shot already released before this first observation
    cmp.w 0xFFFFB7AA,%d0
    bne.w restore                     | stationary centre puck before the first touch is legal
    move.l 0x28(%a0),%d1
    bne.s begin_approach
    move.w (%a0),%d1
    cmp.w STARTX,%d1
    bne.s begin_approach
    move.w 0x14(%a0),%d1
    cmp.w STARTY,%d1
    beq.w restore                     | native auto-possession is not a voluntary first touch
begin_approach:
    move.w #1,PHASE
    clr.w STILL
armed:
    cmpi.w #2,PHASE
    beq.w restore                     | do not cancel a shot's native flight/post/keeper deflection
    cmpi.w #3,PHASE
    beq.w restore
    .if WITH_STRICT_SO
    jsr 0x222008
    tst.w %d0
    bne.w fail                     | existing single native miss, no goal/stat writes
    .endif
    move.l HIGH,%d3
    subi.l #0x00080000,%d3             | stick/deke dead band:8 world units
    cmp.l %d3,%d2
    blt.w fail
    btst #5,0xFFFFC2F2
    bne.w flight
    move.w 0xFFFFB74A,%d3
    bpl.s xpositive
    neg.w %d3
xpositive:
    cmpi.w #21,%d3
    bls.s progress
    cmpi.l #0x01080000,%d2             | beyond the goal line outside the mouth: no wraparound retry
    bgt.s fail
progress:
    cmp.l HIGH,%d2
    ble.s compare_last
    move.l %d2,HIGH
compare_last:
    cmp.l LAST,%d2
    bgt.s advanced
    move.l %d2,LAST
    addq.w #1,STILL
    cmpi.w #12,STILL                   | tolerate render/update quantization, not a stopped attempt
    bcc.s fail
    bra.s restore
advanced:
    move.l %d2,LAST
    clr.w STILL
    bra.s restore
flight:
    move.w #2,PHASE
    clr.w STILL
    bra.s restore
fail:
    move.w #3,PHASE
    bset #4,0xFFFFC2F2                 | native watcher queues the existing miss exactly once
    bra.s restore
clear:
    clr.w MAGIC
    .endif
restore:
    move.w (%sp)+,%sr
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    movem.w %d0,-(%sp)                 | original first two native F2F4 instructions
    move.w 0xFFFFB7AA,%d0
    jmp 0xF2FC

    .endif
