| Optional human B hold/release power. No CPU pass or physics hook.
| Exports begin, input, scale, load, put, reserved, assisted, reset.
| F008 option; F110..F12F four transient physical-pad records, menu scratch.
| SRAM logical4D22..4D29: four complemented records, native/Full/Light/Mini.
| This is inside Light's excluded shared-profile gap4D20..4E1F, not goalie data.
    .equ VALUE,0xFFFFF008
    .equ RECORDS,0xFFFFF110
    .equ MAP,0xA130F1
    .text
    .globl _start
_start:
    bra.w begin
    bra.w input
    bra.w scale
    bra.w load
    bra.w put
    bra.w reset
    bra.w assisted
    bra.w reset

| A0=record, D0=0 valid; all callers save scratch registers/SR.
pad_record:
    move.w %d4,%d0
    andi.w #0xFFFD,%d0
    bne.w invalid
    move.w %d4,%d0
    tst.w 0xFFFFC318
    bmi.s first_bank
    addq.w #4,%d0
first_bank:
    lsl.w #2,%d0
    lea RECORDS,%a0
    adda.w %d0,%a0
    moveq #0,%d0
    rts
eligible:
    cmpi.w #1,VALUE
    bne.w invalid
    btst #3,0x62(%a3)
    beq.w invalid
    tst.w 0x34(%a3)
    bmi.w invalid
    move.w 0x52(%a3),%d0
    cmp.w 0xFFFFB7AA,%d0
    bne.w invalid
    tst.w 0xFFFFD412
    bne.w invalid
    btst #0,0xFFFFC2FA
    bne.w invalid
    btst #2,0xFFFFC2F2
    bne.w invalid
    btst #3,0xFFFFC2F6
    bne.w invalid
    move.b 0xFFFFC2EA,%d0
    andi.b #0x11,%d0
    bne.w invalid
    move.b 0xFFFFC2EC,%d0
    andi.b #0x81,%d0
    bne.w invalid
    btst #0,0x63(%a3)
    bne.w invalid
    moveq #0,%d0
    rts
invalid:
    moveq #-1,%d0
    rts

begin:                               | exact original B-press accounting first
    jsr 0xFEE60
    move.w %sr,-(%sp)
    movem.l %d0/%a0,-(%sp)
    bsr.w pad_record
    bne.s begin_done
    clr.l (%a0)
    clr.l 4(%a0)
    bsr.w eligible
    bne.s begin_done
    move.l %a3,(%a0)
    move.w #1,6(%a0)
begin_done:
    movem.l (%sp)+,%d0/%a0
    move.w (%sp)+,%sr
    rts

input:
    move.w %sr,-(%sp)
    movem.l %d0/%a0,-(%sp)
    bsr.w pad_record
    bne.w legacy_input
    cmp.l (%a0),%a3
    bne.w legacy_input
    cmpi.w #1,6(%a0)
    bne.w legacy_input
    bsr.w eligible
    bne.s cancel
    | Native D0 bit3 means no directional key. Retain last aim in that case.
    move.l (%sp),%d0
    btst #3,%d0
    bne.s aim_ready
    andi.w #7,%d0
    move.w %d0,0xFFFFBEDC
aim_ready:
    btst #4,%d3                     | actual held mask, not the edge mask
    beq.s release
    cmpi.w #30,4(%a0)
    bcc.s wait
    addq.w #1,4(%a0)
wait:
    movem.l (%sp)+,%d0/%a0
    move.w (%sp)+,%sr
    jmp 0xBC3E
release:
    move.w #2,6(%a0)                | consumed once by the human power path
    movem.l (%sp)+,%d0/%a0
    move.w (%sp)+,%sr
    jmp 0x2E6824                    | existing human emit/cone/mode dispatch
cancel:
    clr.l (%a0)
    clr.l 4(%a0)
legacy_input:
    movem.l (%sp)+,%d0/%a0
    move.w (%sp)+,%sr
    jmp 0x2E6820                    | exact original r9 input gate

| Called only inside a human native/custom pass, before native intercept solve.
| D4 is still the physical input bank at both human-only call sites.
scale:
    move.w %sr,-(%sp)
    movem.l %d0-%d1/%a0,-(%sp)
    bsr.w pad_record
    bne.s scaled
    cmp.l (%a0),%a3
    bne.s scaled
    cmpi.w #2,6(%a0)
    bne.s scaled
    cmpi.w #1,VALUE
    bne.s scaled
    moveq #0,%d1
    move.w 4(%a0),%d1
    cmpi.w #30,%d1
    bhi.s scaled
    addi.w #10,%d1
    moveq #0,%d0
    move.w 0xFFFFBEDE,%d0
    mulu.w %d1,%d0
    divu.w #40,%d0                  | 25% tap ..100% after30 held input ticks
    move.w %d0,0xFFFFBEDE
    clr.l (%a0)
    clr.l 4(%a0)
scaled:
    movem.l (%sp)+,%d0-%d1/%a0
    move.w (%sp)+,%sr
    rts

assisted:                            | called after restoring original input D0/SR
    move.w %sr,-(%sp)
    movem.l %d0/%a0,-(%sp)
    bsr.w pad_record
    bne.s native_pass
    cmp.l (%a0),%a3
    bne.s native_pass
    cmpi.w #2,6(%a0)
    bne.s native_pass
    cmpi.w #1,VALUE
    bne.s native_pass
    movem.l (%sp)+,%d0/%a0
    move.w (%sp)+,%sr
    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
    moveq #8,%d0
    tst.w 0x34(%a3)
    beq.s power
    move.b 0x6E(%a3),%d0
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:
    bsr.w scale
    jmp 0xBCD8                      | actual native receiver search/solver/outlet
native_pass:
    movem.l (%sp)+,%d0/%a0
    move.w (%sp)+,%sr
    jmp 0xBC64

record:
    lea 0x209A45,%a0                | logical4D22 native, then per season1/2/3
    tst.w 0xFFFFF06C
    beq.s record_done
    move.w 0xFFFFF06A,%d0
    subq.w #1,%d0
    cmpi.w #2,%d0
    bhi.s record_done
    addq.w #1,%d0
    lsl.w #2,%d0
    adda.w %d0,%a0
record_done:
    rts
load:                                | mapper already enabled by existing menu load
    move.w %sr,-(%sp)
    movem.l %d0-%d1/%a0,-(%sp)
    clr.w VALUE
    clr.l RECORDS
    clr.l RECORDS+4
    clr.l RECORDS+8
    clr.l RECORDS+12
    clr.l RECORDS+16
    clr.l RECORDS+20
    clr.l RECORDS+24
    clr.l RECORDS+28
    bsr.s record
    moveq #0,%d0
    move.b (%a0),%d0
    move.w %d0,%d1
    andi.w #0xFE,%d1
    cmpi.w #0x60,%d1
    bne.s loaded
    not.b %d0
    cmp.b 2(%a0),%d0
    bne.s loaded
    not.b %d0
    andi.w #1,%d0
    move.w %d0,VALUE
loaded:
    movem.l (%sp)+,%d0-%d1/%a0
    move.w (%sp)+,%sr
    rts
put:                                 | mapper already on; checksum only Light's bank
    move.w %sr,-(%sp)
    movem.l %d0-%d1/%a0,-(%sp)
    bsr.w record
    moveq #0x60,%d0
    cmpi.w #1,VALUE
    bne.s write
    addq.w #1,%d0
write:
    move.b %d0,(%a0)
    not.b %d0
    move.b %d0,2(%a0)
    lea 0x208001,%a0
    moveq #0,%d0
    move.w #0x1FFD,%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)
    movem.l (%sp)+,%d0-%d1/%a0
    move.w (%sp)+,%sr
    rts
reset:
    move.w 0xFFFFF06C,-(%sp)
    move.w #1,0xFFFFF06C             | fresh season from native must not clear native preference
    clr.w VALUE
    bsr.w put
    move.w (%sp)+,0xFFFFF06C
    rts
