    .ifndef WITH_REFINEMENTS
    .equ WITH_REFINEMENTS,0
    .endif
    .ifndef WITH_TRANSFERS
    .equ WITH_TRANSFERS,0
    .endif
    .equ TRANSFER_ROW_SHIFT,2*WITH_TRANSFERS
    .ifndef WITH_MOMENTUM
    .equ WITH_MOMENTUM,0
    .endif
    .ifndef WITH_FACEOFF_DOTS
    .equ WITH_FACEOFF_DOTS,0
    .endif
    .ifndef WITH_AI_SHOT_PLAN
    .equ WITH_AI_SHOT_PLAN,0
    .endif
    .ifndef WITH_STRICT_SO
    .equ WITH_STRICT_SO,0
    .endif
    .ifndef WITH_ALT_GOALIES
    .equ WITH_ALT_GOALIES,0
    .endif
    .ifndef WITH_PICKUP_DELAY
    .equ WITH_PICKUP_DELAY,0
    .endif
    .ifndef WITH_PASS_CHARGE
    .equ WITH_PASS_CHARGE,0
    .endif
    .ifndef WITH_PENALTY_RATE
    .equ WITH_PENALTY_RATE,0
    .endif
| Optional human B-input dispatch and continuous human receiver-cone geometry.
| CPU dopass, outlet and both CPU scan branches retain original r6 instructions.
| +0 input dispatcher, +4 cone, +8 custom human pass, +12 menu writer,
| +16 mapped load, +20 mapped record put, +24 human keeper fallback, +28 legacy cone.
| RAM F0FC/F0FE; existing complemented preference record1EEE/4D20.
    .equ MODE,0xFFFFF0FC
    .equ CONE,0xFFFFF0FE
    .equ HEIGHT,0xFFFFF0DC
    .equ SPEED,0xFFFFF0E8
    .equ VIEW,0xFFFFF06C
    .equ MAP,0xA130F1
    .text
    .globl _start
_start:
    bra.w input_dispatch
    bra.w cone
    bra.w custom_pass
    bra.w writer
    bra.w load
    bra.w put
    bra.w keeper_fallback
    bra.w legacy_cone
    .if WITH_PASS_CHARGE
    bra.w legacy_input_dispatch        | +32, private charging fall-through
    bra.w emit                         | +36, charged release
    .endif

human_allowed:                         | D0=0 allowed, -1 native; caller saves registers
    btst #3,0x62(%a3)
    beq.s not_human
    tst.w 0x34(%a3)
    bmi.s not_human
    btst #0,0xFFFFC2FA
    bne.s not_human
    btst #2,0xFFFFC2F2
    bne.s not_human
    moveq #0,%d0
    rts
not_human:
    moveq #-1,%d0
    rts

input_dispatch:                       | human input BC40; CPU calls BC64 directly
    .if WITH_PASS_CHARGE
    jmp 0x2E8204
legacy_input_dispatch:
    .endif
    btst #4,%d2
    bne.s emit
    btst #3,0xFFFFC2F6
    bne.s emit
    btst #3,%d0
    bne.w no_emit
    andi.w #7,%d0
    move.w %d0,0xFFFFBEDC
    bset #3,%d0
emit:
    .if WITH_PICKUP_DELAY
    jsr 0x220000                    | only an actual human release, never a held charge
    .endif
    move.w %sr,-(%sp)
    move.l %d0,-(%sp)
    bsr.w human_allowed
    bne.s native_emit
    btst #3,0xFFFFC2F6
    bne.s native_emit                 | native forced/special pass path retains its behavior
    cmpi.w #1,MODE
    beq.s directional_emit
    move.w CONE,%d0
    subq.w #1,%d0
    cmpi.w #2,%d0
    bhi.s native_emit
    move.w #-1,0xFFFFBEE0             | no stale target if this explicit cone finds nobody
native_emit:
    move.l (%sp)+,%d0
    move.w (%sp)+,%sr
    .if WITH_PASS_CHARGE
    jmp 0x2E8218
    .else
    jmp 0xBC64
    .endif
no_emit:
    jmp 0xBC3E

directional_emit:
    move.l (%sp)+,%d0
    move.w (%sp)+,%sr
    bra.w custom_pass

cone:
    move.w %sr,-(%sp)
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    bsr.w human_allowed
    bne.w native_cone
    move.w CONE,%d7
    subq.w #1,%d7
    cmpi.w #2,%d7
    bhi.w native_cone                  | Default or invalid: exact old human/co-op octant test
    | D1/D2 are actual dx/dy, before native angle quantization. Use the sign-only
    | 8-direction basis: dot/cross ratio does not depend on vector normalization.
    move.w 0xFFFFBEDC,%d0
    andi.w #7,%d0
    lsl.w #2,%d0
    lea vectors(%pc),%a0
    move.w (%a0,%d0.w),%d3
    move.w 2(%a0,%d0.w),%d4
    move.w %d1,%d0
    muls.w %d3,%d0
    move.w %d2,%d5
    muls.w %d4,%d5
    add.l %d5,%d0                     | forward dot, positive only
    ble.w reject
    move.w %d1,%d5
    muls.w %d4,%d5
    move.w %d2,%d6
    muls.w %d3,%d6
    sub.l %d6,%d5                     | cross
    bpl.s cross_positive
    neg.l %d5
cross_positive:
    | A positive dot can be65536 only at the extreme diagonal corner with cross0.
    | That exact on-axis case is accepted before16-bit MULU, avoiding truncation.
    tst.l %d5
    beq.s accept
    mulu.w #4096,%d5
    add.w %d7,%d7
    lea tangents(%pc),%a0
    mulu.w (%a0,%d7.w),%d0
    cmp.l %d0,%d5
    bhi.s reject
accept:
    andi.w #0xFFF0,60(%sp)            | preserve X and upper SR; Z=1 means pass native BHI
    ori.w #4,60(%sp)
    bra.s cone_done
reject:
    andi.w #0xFFF0,60(%sp)            | Z=0/C=0: native BHI rejects
cone_done:
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    move.w (%sp)+,%sr
    rts
native_cone:
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    move.w (%sp)+,%sr
    bra.w legacy_cone
vectors:
    .word 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1, -1,0, -1,1
tangents:
    .word 1097,2364,4096              | floor(4096*tan(15/30/45 degrees)), half-angle

legacy_cone:                          | exact r6 predicate for human Default/special callers
    btst #3,0x62(%a3)
    beq.s legacy_cpu
    btst #3,0x62(%a1)
    beq.s legacy_cpu
    cmp.l #0x40000,%d0
    rts
legacy_cpu:
    cmp.l #0x10000,%d0
    rts

keeper_fallback:                      | called only by the existing HUMAN-only branch
    move.w %sr,-(%sp)
    move.l %d0,-(%sp)
    bsr.w human_allowed
    bne.s old_keeper_score
    move.w CONE,%d0
    subq.w #1,%d0
    cmpi.w #2,%d0
    bhi.s old_keeper_score
    move.w #-1,0xFFFFBEE0
    move.l (%sp)+,%d0
    move.w (%sp)+,%sr
    jmp 0x2FF1EE                      | initial scan found none in cone: no blind angle override
old_keeper_score:
    move.l (%sp)+,%d0
    move.w (%sp)+,%sr
    btst #3,0x62(%a1)
    beq.s score_candidate
    lsr.l #8,%d2
score_candidate:
    jmp 0x2FF1E4

custom_pass:                          | alternate human-only dopass; standard native outer frame
    movem.l %d0-%d5/%a0-%a1,-(%sp)
    bclr #2,0xFFFFC2EC
    st.b 0xFFFFB7AA
    move.b #0x10,0x5E(%a3)
    move.w 0x52(%a3),0xFFFFBEDA
    bclr #3,0xFFFFC2F6                 | eligibility retained the original special path above
    moveq #8,%d0
    tst.w 0x34(%a3)
    beq.s pass_power
    move.b 0x6E(%a3),%d0
pass_power:
    asl.w #2,%d0
    asr.w #1,%d0
    addi.w #0xA0,%d0
    move.w %d0,0xFFFFBEDE
    btst #0,0x6E(%a3)
    beq.s power_ready
    asr.w #4,%d0
    add.w %d0,0xFFFFBEDE
power_ready:
    .if WITH_PASS_CHARGE
    jsr 0x2E8208
    .endif
    move.w #-1,0xFFFFBEE0
    move.w 0xFFFFBEDC,%d0
    andi.w #7,%d0
    asl.w #2,%d0
    lea 0x10E64,%a0
    move.w 2(%a0,%d0.w),%d1
    muls.w 0xFFFFBEDE,%d1
    moveq #10,%d2
    asl.l %d2,%d1
    divs.w #3000,%d1
    move.w %d1,0xFFFFB774
    move.w (%a0,%d0.w),%d1
    muls.w 0xFFFFBEDE,%d1
    asl.l %d2,%d1
    divs.w #3000,%d1
    move.w %d1,0xFFFFB772
    cmpi.w #1,SPEED
    bne.s free_lift
    move.w 0xFFFFB772,%d0
    muls.w #4,%d0
    divs.w #5,%d0
    move.w %d0,0xFFFFB772
    move.w 0xFFFFB774,%d0
    muls.w #4,%d0
    divs.w #5,%d0
    move.w %d0,0xFFFFB774
free_lift:
    move.w #0x600,0xFFFFB776
    cmpi.w #1,HEIGHT
    bne.s free_done
    move.w #0x300,0xFFFFB776
free_done:
    jmp 0xBDD8                        | native pose/sound/outer return; pure keeper D-pad too

record:
    lea 0x203DDD,%a0                 | logical1EEE, after slots' complete1EAC..1EED snapshot
    tst.w VIEW
    bne.s record_ready
    lea 0x209A41,%a0                 | logical4D20, excluded Light-bank profile gap
record_ready:
    rts
load:
    move.w %sr,-(%sp)
    movem.l %d0-%d2/%a0,-(%sp)
    bsr.s record
    .if WITH_REFINEMENTS
    move.w #1,HEIGHT
    .else
    clr.w HEIGHT
    .endif
    clr.w SPEED
    clr.w MODE
    clr.w CONE
    .if WITH_PENALTY_RATE
    .if WITH_REFINEMENTS
    move.w #1,0xFFFFF006
    .else
    clr.w 0xFFFFF006
    .endif
    .endif
    moveq #0,%d0
    move.b (%a0),%d0
    move.w %d0,%d1
    not.b %d1
    cmp.b 2(%a0),%d1
    bne.s loaded
    move.w %d0,%d1
    andi.w #0xFC,%d1
    cmpi.w #0x50,%d1                  | legacyr6 height/speed, new choices default0
    .if WITH_REFINEMENTS
    beq.s tagged_old_values
    .else
    beq.s old_values
    .endif
    move.w %d0,%d1
    .if WITH_PENALTY_RATE
    andi.w #0xE0,%d1
    cmpi.w #0x80,%d1
    bcs.s loaded
    cmpi.w #0xE0,%d1
    beq.s loaded                      | top bits11 are reserved/corrupt
    move.w %d0,%d1
    lsr.w #5,%d1
    andi.w #3,%d1
    move.w %d1,0xFFFFF006
    .else
    andi.w #0xE0,%d1
    cmpi.w #0x80,%d1
    bne.s loaded
    .endif
    move.w %d0,%d1
    lsr.w #2,%d1
    andi.w #1,%d1
    move.w %d1,MODE
    move.w %d0,%d1
    lsr.w #3,%d1
    andi.w #3,%d1
    move.w %d1,CONE
    .if WITH_REFINEMENTS
    bra.s old_values
tagged_old_values:
    clr.w 0xFFFFF006                   | a valid old-format100% selection remains100%
    .endif
old_values:
    move.w %d0,%d1
    andi.w #1,%d1
    move.w %d1,HEIGHT
    lsr.w #1,%d0
    andi.w #1,%d0
    move.w %d0,SPEED
loaded:
    .if WITH_REFINEMENTS
    jsr 0x258000
    .endif
    .if WITH_MOMENTUM
    jsr 0x226000
    .endif
    .if WITH_FACEOFF_DOTS
    jsr 0x224008
    .endif
    .if WITH_AI_SHOT_PLAN
    jsr 0x223010
    .endif
    .if WITH_STRICT_SO
    jsr 0x222010
    .endif
    .if WITH_ALT_GOALIES
    jsr 0x221010
    .endif
    .if WITH_PICKUP_DELAY
    jsr 0x220004
    .endif
    .if WITH_PASS_CHARGE
    jsr 0x2E820C
    .endif
    movem.l (%sp)+,%d0-%d2/%a0
    move.w (%sp)+,%sr
    rts
put:                                  | A0mapped record; retain old put's D0-only scratch contract
    move.l %d1,-(%sp)
    moveq #0,%d0
    cmpi.w #1,HEIGHT
    bne.s put_speed
    addq.w #1,%d0
put_speed:
    cmpi.w #1,SPEED
    bne.s put_mode
    addq.w #2,%d0
put_mode:
    cmpi.w #1,MODE
    bne.s put_cone
    addq.w #4,%d0
put_cone:
    move.w CONE,%d1
    cmpi.w #3,%d1
    bhi.s put_tag
    lsl.w #3,%d1
    or.w %d1,%d0
put_tag:
    .if WITH_PENALTY_RATE
    move.w 0xFFFFF006,%d1
    cmpi.w #2,%d1
    bhi.s put_rate_ready
    lsl.w #5,%d1
    or.w %d1,%d0
put_rate_ready:
    move.w %d0,%d1
    andi.w #0x7C,%d1
    .else
    move.w %d0,%d1
    andi.w #0x1C,%d1
    .endif
    bne.s new_tag
    ori.w #0x50,%d0                   | default new choices preserve exact r6 record encoding
    bra.s put_bytes
new_tag:
    ori.w #0x80,%d0
put_bytes:
    move.b %d0,(%a0)
    not.b %d0
    move.b %d0,2(%a0)
    .if WITH_PASS_CHARGE
    jsr 0x2E8210
    .endif
    .if WITH_PICKUP_DELAY
    jsr 0x220008
    .endif
    .if WITH_ALT_GOALIES
    jsr 0x221014
    .endif
    .if WITH_STRICT_SO
    jsr 0x222014
    .endif
    .if WITH_MOMENTUM
    jsr 0x226004
    .endif
    .if WITH_FACEOFF_DOTS
    jsr 0x22400C
    .endif
    .if WITH_AI_SHOT_PLAN
    jsr 0x223014
    .endif
    .if WITH_REFINEMENTS
    jsr 0x258004
    .endif
    move.l (%sp)+,%d1
    rts
writer:
    .if WITH_REFINEMENTS
    cmpi.w #48,%d7
    beq.s refinement_range
    cmpi.w #50,%d7
    bne.s original_range
refinement_range:
    cmpi.w #1,%d3
    bhi.w flags
    bra.w writer_lock
original_range:
    .endif
    .if WITH_MOMENTUM
    cmpi.w #48+TRANSFER_ROW_SHIFT-4*WITH_REFINEMENTS,%d7
    bne.s not_momentum_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.w writer_lock
not_momentum_range:
    .endif
    .if WITH_FACEOFF_DOTS && !WITH_REFINEMENTS
    cmpi.w #46+TRANSFER_ROW_SHIFT,%d7
    bne.s not_dots_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.w writer_lock
not_dots_range:
    .endif
    .if WITH_AI_SHOT_PLAN
    cmpi.w #44+TRANSFER_ROW_SHIFT-2*WITH_REFINEMENTS,%d7
    bne.s not_plan_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.w writer_lock
not_plan_range:
    .endif
    .if WITH_STRICT_SO && !WITH_REFINEMENTS
    cmpi.w #42+TRANSFER_ROW_SHIFT,%d7
    bne.s not_strict_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.s writer_lock
not_strict_range:
    .endif
    .if WITH_ALT_GOALIES
    cmpi.w #40+TRANSFER_ROW_SHIFT,%d7
    bne.s not_alt_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.s writer_lock
not_alt_range:
    .endif
    .if WITH_PICKUP_DELAY
    cmpi.w #38+TRANSFER_ROW_SHIFT,%d7
    bne.s not_pickup_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.s writer_lock
not_pickup_range:
    .endif
    .if WITH_PASS_CHARGE
    cmpi.w #36+TRANSFER_ROW_SHIFT,%d7
    bne.s not_charge_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.s writer_lock
not_charge_range:
    .endif
    cmpi.w #30+TRANSFER_ROW_SHIFT,%d7
    bne.s cone_range
    cmpi.w #1,%d3
    bhi.w flags
    bra.s writer_lock
cone_range:
    .if WITH_PENALTY_RATE
    cmpi.w #34+TRANSFER_ROW_SHIFT,%d7
    bne.s cone_range_old
    cmpi.w #2,%d3
    bhi.w flags
    bra.s writer_lock
cone_range_old:
    .endif
    cmpi.w #3,%d3
    bhi.w flags
writer_lock:
    tst.w VIEW
    beq.s writable
    tst.w 0xFFFFE3E8
    beq.s writable
    cmpi.w #1,0xFFFFE3F0
    beq.w flags
    cmpi.w #3,0xFFFFE3F0
    beq.w flags
    cmpi.w #4,0xFFFFE3F0
    beq.w flags
writable:
    move.w %sr,-(%sp)
    movem.l %d0-%d1/%a0-%a1,-(%sp)
    .if WITH_REFINEMENTS
    lea 0xFFFFF8D8,%a0
    cmpi.w #48,%d7
    beq.w selected_value
    lea 0xFFFFF8DA,%a0
    cmpi.w #50,%d7
    beq.w selected_value
    .endif
    .if WITH_MOMENTUM
    lea 0xFFFFF84A,%a0
    cmpi.w #48+TRANSFER_ROW_SHIFT-4*WITH_REFINEMENTS,%d7
    beq.w selected_value
    .endif
    .if WITH_FACEOFF_DOTS && !WITH_REFINEMENTS
    lea 0xFFFFF848,%a0
    cmpi.w #46+TRANSFER_ROW_SHIFT,%d7
    beq.w selected_value
    .endif
    .if WITH_AI_SHOT_PLAN
    lea 0xFFFFF810,%a0
    cmpi.w #44+TRANSFER_ROW_SHIFT-2*WITH_REFINEMENTS,%d7
    beq.w selected_value
    .endif
    .if WITH_STRICT_SO && !WITH_REFINEMENTS
    lea 0xFFFFF046,%a0
    cmpi.w #42+TRANSFER_ROW_SHIFT,%d7
    beq.s selected_value
    .endif
    .if WITH_ALT_GOALIES
    lea 0xFFFFF012,%a0
    cmpi.w #40+TRANSFER_ROW_SHIFT,%d7
    beq.s selected_value
    .endif
    .if WITH_PICKUP_DELAY
    lea 0xFFFFF010,%a0
    cmpi.w #38+TRANSFER_ROW_SHIFT,%d7
    beq.s selected_value
    .endif
    .if WITH_PASS_CHARGE
    lea 0xFFFFF008,%a0
    cmpi.w #36+TRANSFER_ROW_SHIFT,%d7
    beq.s selected_value
    .endif
    .if WITH_PENALTY_RATE
    lea 0xFFFFF006,%a0
    cmpi.w #34+TRANSFER_ROW_SHIFT,%d7
    beq.s selected_value
    .endif
    lea MODE,%a0
    cmpi.w #30+TRANSFER_ROW_SHIFT,%d7
    beq.s selected_value
    lea CONE,%a0
selected_value:
    cmp.w (%a0),%d3
    beq.s writer_done
    ori.w #0x700,%sr
    move.w %d3,(%a0)
    move.b #1,MAP
    bsr.w record
    bsr.w put
    lea 0x200001,%a0
    tst.w VIEW
    bne.s checksum
    lea 0x208001,%a0
checksum:
    moveq #0,%d0
    move.w #0x1FFE-1,%d1
sum:
    add.b (%a0),%d0
    addq.l #2,%a0
    dbra %d1,sum
    not.b %d0
    move.b %d0,(%a0)
    not.b %d0
    move.b %d0,2(%a0)
    move.b #0,MAP
writer_done:
    movem.l (%sp)+,%d0-%d1/%a0-%a1
    move.w (%sp)+,%sr
flags:
    tst.w %d2
    rts
