| CPU Hard coach chooses a stronger first forward unit from its existing normal
| lines. A temporary cache supplies BOTH native personnel and energy lookups;
| original lineups, saved profiles, attributes and native fatigue remain intact.
 .text
 .globl _start
_start:
 bra.w personnel
 bra.w energy
personnel:
 movem.l %d0-%d7/%a0/%a2-%a6,-(%sp)
 move.w 0x16(%a2),%d0
 bsr.w prepare
 movem.l (%sp)+,%d0-%d7/%a0/%a2-%a6
 move.w 0x16(%a2),%d0
 jmp 0x15854
energy:
 movem.l %d0-%d7/%a0/%a2-%a6,-(%sp)
 bsr.w prepare
 movem.l (%sp)+,%d0-%d7/%a0/%a2-%a6
 asl.w #3,%d0
 jmp 0x12EBE
prepare:
 lea 0x16A(%a2),%a1
 cmpi.w #2,%d0
 bhi.w prepare_done
 cmpa.w #0xC6CE,%a2
 beq.w home_team
 cmpa.w #0xCA32,%a2
 bne.w prepare_done
 moveq #2,%d2
 lea 0xFFFFF520,%a5
 bra.w team_ready
home_team:
 moveq #1,%d2
 lea 0xFFFFF500,%a5
team_ready:
 cmpi.w #1,0xFFFFF07A
 bne.w prepare_done
 btst #0,0xFFFFC2FA
 bne.w prepare_done
 btst #2,0xFFFFC2FA
 bne.w prepare_done
 btst #2,0xFFFFC2F2
 bne.w prepare_done
 lea 0xFFFFC328,%a0
 moveq #3,%d1
human_scan:
 cmp.w (%a0)+,%d2
 beq.w prepare_done
 dbra %d1,human_scan
 move.l 0x1E(%a2),%d0
 cmpi.l #0x200,%d0
 blo.w prepare_done
 cmpi.l #0x300000,%d0
 bhs.w prepare_done
 | Keep a private24-byte copy; never rewrite the game's own line arrays.
 movea.l %a1,%a0
 movea.l %a5,%a4
 moveq #5,%d0
copy_lines:
 move.l (%a0)+,(%a4)+
 dbra %d0,copy_lines
 link.w %a6,#-16
 clr.l -4(%a6)
 clr.w -6(%a6)
 moveq #0,%d7
choose_slot:
 moveq #-1,%d5                    | best score
 moveq #0,%d6                     | best one-based roster ID
 moveq #0,%d4                     | line0..2
scan_line:
 moveq #3,%d3                     | forward positions3..5
scan_forward:
 move.w %d4,%d0
 lsl.w #3,%d0
 add.w %d3,%d0
 moveq #0,%d2
 move.b (%a5,%d0.w),%d2
 beq.w scan_next
 cmpi.w #26,%d2
 bhi.w scan_next
 cmp.w -2(%a6),%d2
 beq.w scan_next
 cmp.w -4(%a6),%d2
 beq.w scan_next
 cmp.w -6(%a6),%d2
 beq.w scan_next
 move.w %d2,%d0
 subq.w #1,%d0
 add.w %d0,%d0
 move.w 0x66(%a2,%d0.w),%d1
 cmpi.w #-3,%d1
 beq.w scan_next
 cmpi.w #-4,%d1
 beq.w scan_next
 tst.w %d1
 bgt.w scan_next
 bsr.w score_forward
 cmp.w %d5,%d0
 ble.w scan_next
 move.w %d0,%d5
 move.w %d2,%d6
 move.w %d1,-8(%a6)              | handedness of best candidate
scan_next:
 addq.w #1,%d3
 cmpi.w #5,%d3
 bls.w scan_forward
 addq.w #1,%d4
 cmpi.w #2,%d4
 bls.w scan_line
 tst.w %d6
 beq.w no_three
 move.w %d7,%d0
 add.w %d0,%d0
 neg.w %d0
 move.w %d6,-2(%a6,%d0.w)
 moveq #4,%d3                    | strongest forward at centre
 tst.w %d7
 beq.w selected_slot
 cmpi.w #1,%d7
 bne.w remaining_wing
 moveq #5,%d3                    | left shooter on the right for a one-timer
 tst.w -8(%a6)
 beq.w wing_chosen
 moveq #3,%d3
wing_chosen:
 move.w %d3,-10(%a6)
 bra.w selected_slot
remaining_wing:
 moveq #8,%d3
 sub.w -10(%a6),%d3
selected_slot:
 moveq #0,%d2
 move.b (%a5,%d3.w),%d2          | displaced first-line player
 cmp.w %d2,%d6
 beq.w slot_done
 | Swap the two real roster IDs across all3normal lines. This keeps the other
 | units valid and lets the existing native energy/bench rules rotate players.
 moveq #0,%d4
swap_line:
 moveq #3,%d3
swap_forward:
 move.w %d4,%d0
 lsl.w #3,%d0
 add.w %d3,%d0
 move.b (%a5,%d0.w),%d1
 cmp.b %d2,%d1
 bne.w swap_selected
 move.b %d6,(%a5,%d0.w)
 bra.w swap_next
swap_selected:
 cmp.b %d6,%d1
 bne.w swap_next
 move.b %d2,(%a5,%d0.w)
swap_next:
 addq.w #1,%d3
 cmpi.w #5,%d3
 bls.w swap_forward
 addq.w #1,%d4
 cmpi.w #2,%d4
 bls.w swap_line
slot_done:
 addq.w #1,%d7
 cmpi.w #3,%d7
 blo.w choose_slot
 unlk %a6
 movea.l %a5,%a1
 rts
no_three:
 unlk %a6
 lea 0x16A(%a2),%a1
prepare_done:
 rts

| D2 = one-based real roster ID. Returns D0 score,D1 handedness; preserves
| every other working register. No attribute/energy/RNG writes.
score_forward:
 movem.l %d2-%d7/%a0,-(%sp)
 .if WITH_TRANSFERS
 jsr 0x23600C
 beq.s score_forward_original
 move.w 0x28(%a2),%d0
 move.w %d2,%d1
 subq.w #1,%d1
 jsr 0x236008
 bra.w attributes
score_forward_original:
 .endif
 movea.l 0x1E(%a2),%a0
 adda.w (%a0),%a0
 move.w %d2,%d0
 subq.w #1,%d0
 beq.w attributes
skip_record:
 adda.w (%a0),%a0
 addq.w #8,%a0
 subq.w #1,%d0
 bne.w skip_record
attributes:
 adda.w (%a0),%a0
 moveq #0,%d0
 move.b 1(%a0),%d0
 andi.w #15,%d0                  | native leg power
 moveq #0,%d1
 move.b 2(%a0),%d1
 move.w %d1,%d2
 andi.w #15,%d2
 add.w %d2,%d2                  |2*offensive awareness
 add.w %d2,%d0
 lsr.w #4,%d1
 mulu.w #3,%d1                  |3*speed
 add.w %d1,%d0
 moveq #0,%d1
 move.b 3(%a0),%d1
 andi.w #15,%d1
 add.w %d1,%d1                  |2*shot power
 add.w %d1,%d0
 moveq #0,%d1
 move.b 5(%a0),%d1
 move.w %d1,%d2
 andi.w #15,%d2
 mulu.w #3,%d2                  |3*shot accuracy
 add.w %d2,%d0
 lsr.w #4,%d1
 add.w %d1,%d0                  |stick handling
 moveq #0,%d1
 move.b 7(%a0),%d1
 lsr.w #4,%d1
 add.w %d1,%d0                  |passing
 moveq #0,%d1
 move.b 4(%a0),%d1
 andi.w #1,%d1
 movem.l (%sp)+,%d2-%d7/%a0
 rts
