| Live season Scoring Leaders: top32 by Points/Goals/Assists,16 per page.
| C (Xbox B) cycles sorting; Left/Right pages; Start returns via the native modal exit.
| Keys keep raw G/A; a bitmap marks selected entries so zero/max stats remain valid.
| Ranking compares LONG scores (points may exceed255). Names use the ROM roster.

        .include "features.inc"

        .equ    SRAM_OFF, 0x1000
        .equ    MAGIC,    0x5345534E
        .equ    SRAM_RD,  0x1A244
        .equ    PSTAT_OFF,0x1220
        .equ    ROWLEN,   100
        .equ    KEYS,     0xFFE400       | 800 packed G/A words, never used as a sentinel
        .equ    TAKEN,    0xFFEA40       | 800 selection bits,100 bytes
        .equ    LORD,     0xFFEAA4       | 32 x (team byte,slot byte,raw G/A word)
        .equ    PAGE,     0xFFEB24
        .equ    SORT,     0xFFEB26       | 0 points,1 goals,2 assists
        .equ    HDRB,     0xFFEB28       | 16-byte header copy
        .equ    STR,      0xFFEB40       | ends before protected gameplay globals F000
        .equ    PALCOPY,  0xFFF180       | saved palette3, beyond ROWBUF F100..F163
        .equ    ROWBUF,   0xFFF100

        .text
        .globl  _start
_start:
        .if WITH_TRANSFERS
        jsr     0x236028
        .endif
        moveq   #10,%d0
        moveq   #26,%d1
        jsr     0x9BD8
        jsr     0x11B92
        .word   6
        .byte   0xBD,0x04,0x01,0x00
        moveq   #0x20,%d0
        moveq   #6,%d1
        jsr     0x119B8
        jsr     0x11DE2
        .word   24
        .byte   0xBD,0x06,0x04
        .ascii  "Scoring  Leaders"
        .byte   0xBD,0x07,0x01

        lea     HDRB,%a0                | season header: player block in format 2?
        move.l  #SRAM_OFF,%d0
        moveq   #16,%d1
        jsr     SRAM_RD
        clr.w   SORT
        bsr.w   colour
        bsr.w   keys
        bsr.w   rank
        clr.w   PAGE
        bsr.w   draw

loop:   moveq   #0,%d0
        jsr     0x80BA
        jsr     0x2FD500
        jsr     0x11318
        .if WITH_REFINEMENTS
        jsr     0x25B040
        jsr     0x25B028
        .endif
        btst    #7,%d3
        beq.s   4f
        bsr.w   uncolour
        bclr    #1,0xFFFFC2F6           | modal exit needs caller redraw; never inherit no-redraw
        jmp     0x9CD8                  | always return to the native caller; no stale indirect exit pointer
4:      btst    #5,%d3                | new C press, not held: one sort per click
        beq.s   41f
        addq.w  #1,SORT
        cmpi.w  #3,SORT
        bcs.s   40f
        clr.w   SORT
40:     clr.w   PAGE
        bsr.w   rank
        bsr.w   draw
        bra.w   loop
41:     btst    #3,%d1
        beq.s   5f
        tst.w   PAGE
        bne.w   loop
        move.w  #1,PAGE
        bsr.w   draw
        bra.w   loop
5:      btst    #2,%d1
        beq.w   loop
        tst.w   PAGE
        beq.w   loop
        clr.w   PAGE
        bsr.w   draw
        bra.w   loop

| Native statistics are bytes G/A. Store them without lossy derived keys.
keys:   lea     TAKEN,%a2
        moveq   #24,%d0
0:      clr.l   (%a2)+
        dbra    %d0,0b
        lea     KEYS,%a2
        moveq   #0,%d4
1:      moveq   #0,%d0
        move.w  %d4,%d0
        mulu.w  #ROWLEN,%d0
        addi.l  #PSTAT_OFF,%d0
        lea     ROWBUF,%a0
        moveq   #ROWLEN,%d1
        jsr     SRAM_RD
        lea     ROWBUF,%a0
        moveq   #24,%d5
2:      moveq   #0,%d0
        cmpi.l  #MAGIC,HDRB
        bne.s   3f
        cmpi.w  #2,HDRB+14
        bcs.s   3f
        tst.w   HDRB+12
        bne.s   3f
        move.w  (%a0),%d0               | G high byte,A low byte
3:      move.w  %d0,(%a2)+
        addq.l  #4,%a0
        dbra    %d5,2b
        addq.w  #1,%d4
        cmpi.w  #32,%d4
        blt.s   1b
        rts

| D0 packed G/A -> D1 LONG sort score. Secondary keys match the finished browser:
| points then goals; goals then points (same as assists); assists then points.
score:  moveq   #0,%d1
        move.b  %d0,%d1
        andi.l  #0xFFFF,%d0
        lsr.w   #8,%d0
        tst.w   SORT
        bne.s   1f
        add.w   %d0,%d1
        lsl.l   #8,%d1
        add.w   %d0,%d1
        rts
1:      cmpi.w  #1,SORT
        bne.s   2f
        move.l  %d0,%d2
        lsl.l   #8,%d2
        add.w   %d1,%d2
        move.l  %d2,%d1
        rts
2:      lsl.l   #8,%d1
        add.w   %d0,%d1
        rts

| rank (r35, jdc: Start needed twice): one pass, each player scored once and inserted into a
| sorted top 32 (scores in STR, free until draw). Ties keep the first found, as before. The
| r34 selection scanned all 800 players 32 times (~1.5 s with no input: Start was lost).
rank:   lea     KEYS,%a1
        lea     STR,%a3
        lea     LORD,%a2
        moveq   #0,%d7                  | entries so far
        moveq   #0,%d6                  | player * 2
1:
        .if WITH_TRANSFERS
        moveq   #0,%d0
        move.w  %d6,%d0
        lsr.w   #1,%d0
        divu.w  #25,%d0
        move.l  %d0,%d1
        swap    %d1
        addq.w  #1,%d1
        jsr     0x23607C
        tst.l   %d0
        beq.w   8f
        .endif
        moveq   #0,%d0
        move.w  (%a1,%d6.w),%d0
        bsr.w   score
        move.l  %d1,%d3
        move.w  %d7,%d4
        lsl.w   #2,%d4                  | entries * 4
        cmpi.w  #128,%d4
        bcs.s   11f
        cmp.l   124(%a3),%d3            | full: not above the 32nd -> next
        ble.s   8f
11:     moveq   #0,%d5                  | insert position * 4
2:      cmp.w   %d4,%d5
        bcc.s   3f
        cmp.l   (%a3,%d5.w),%d3
        bgt.s   3f
        addq.w  #4,%d5
        bra.s   2b
3:      move.w  %d4,%d2                 | shift [p, last) down one
        cmpi.w  #124,%d2
        bls.s   4f
        move.w  #124,%d2
4:      subq.w  #4,%d2
5:      cmp.w   %d5,%d2
        blt.s   6f
        move.l  (%a3,%d2.w),4(%a3,%d2.w)
        move.l  (%a2,%d2.w),4(%a2,%d2.w)
        subq.w  #4,%d2
        bra.s   5b
6:      move.l  %d3,(%a3,%d5.w)
        moveq   #0,%d0
        move.w  %d6,%d0
        lsr.w   #1,%d0
        divu.w  #25,%d0
        move.b  %d0,(%a2,%d5.w)
        swap    %d0
        addq.b  #1,%d0
        move.b  %d0,1(%a2,%d5.w)
        move.w  (%a1,%d6.w),2(%a2,%d5.w)
        cmpi.w  #32,%d7
        bcc.s   8f
        addq.w  #1,%d7
8:      addq.w  #2,%d6
        cmpi.w  #1600,%d6
        blt.w   1b
        rts

| Selected heading uses palette3, cloned from the normal font palette2.
| Preserve all32 bytes and restore before the native exit rebuilds the caller.
colour: lea     0xFFBD88,%a0
        lea     PALCOPY,%a1
        lea     0xFFBD68,%a2
        moveq   #15,%d0
1:      move.w  (%a0),(%a1)+
        move.w  (%a2)+,(%a0)+
        dbra    %d0,1b
        move.w  #0x006E,0xFFBD8A
        rts
uncolour:
        lea     PALCOPY,%a0
        lea     0xFFBD88,%a1
        moveq   #15,%d0
1:      move.w  (%a0)+,(%a1)+
        dbra    %d0,1b
        rts

selected:
        move.b  #0xFE,(%a0)+
        move.b  #7,(%a0)+
        move.w  SORT,%d0
        add.w   %d0,%d0
        lea     heads(%pc),%a1
        move.w  (%a1,%d0.w),%d0
        adda.w  %d0,%a1
1:      move.b  (%a1)+,(%a0)+
        bne.s   1b
        subq.l  #1,%a0
        move.b  #0xFE,(%a0)+
        move.b  #6,(%a0)+
        rts

draw:   lea     STR+2,%a0
        move.b  #0xF8,(%a0)+
        move.b  #0x06,(%a0)+
        move.b  #0x03,(%a0)+
        move.b  #0x01,(%a0)+
        move.b  #0x05,(%a0)+
        move.b  #0xF9,(%a0)+
        move.b  #0x01,(%a0)+
        lea     hdr,%a1
1:      move.b  (%a1)+,(%a0)+
        bne.s   1b
        subq.l  #1,%a0
        bsr.w   selected
        move.w  PAGE,%d7
        mulu.w  #16,%d7
        moveq   #0,%d4
2:      move.w  %d7,%d0
        add.w   %d4,%d0                 | rank-1
        move.b  #0xFC,(%a0)+
        move.w  %d4,%d1
        addq.w  #8,%d1
        move.b  %d1,(%a0)+
        moveq   #1,%d1
        bsr.w   col
        move.w  %d0,%d2
        addq.w  #1,%d2
        bsr.w   num3
        lea     LORD,%a2
        lsl.w   #2,%d0
        moveq   #0,%d5
        moveq   #0,%d6
        move.b  (%a2,%d0.w),%d5         | team
        move.b  1(%a2,%d0.w),%d6        | slot
        move.w  2(%a2,%d0.w),TAKEN      | raw G/A (r35: not KEYS, a sort re-ranks without re-reading)
        moveq   #5,%d1
        bsr.w   col
        bsr.w   name                    | name, max 16 characters
        moveq   #22,%d1
        bsr.w   col
        lea     abbr,%a2
        move.w  %d5,%d2
        mulu.w  #3,%d2
        move.b  (%a2,%d2.w),(%a0)+
        move.b  1(%a2,%d2.w),(%a0)+
        move.b  2(%a2,%d2.w),(%a0)+
        moveq   #0,%d3
        moveq   #0,%d0
        move.b  TAKEN,%d3               | goals
        move.b  TAKEN+1,%d0             | assists
        moveq   #27,%d1
        bsr.w   col
        move.w  %d3,%d2
        bsr.w   num3
        moveq   #31,%d1
        bsr.w   col
        move.w  %d0,%d2
        bsr.w   num3
        moveq   #35,%d1
        bsr.w   col
        move.w  %d3,%d2
        add.w   %d0,%d2
        bsr.w   num3
        addq.w  #1,%d4
        cmpi.w  #16,%d4
        blt.w   2b
        lea     foot,%a1
3:      move.b  (%a1)+,(%a0)+
        bne.s   3b
        subq.l  #1,%a0
        tst.w   PAGE
        bne.s   4f
        move.b  #0x20,-8(%a0)
        bra.s   5f
4:      move.b  #0x20,-1(%a0)
5:      move.l  %a0,%d0
        btst    #0,%d0
        beq.s   6f
        move.b  #0x20,(%a0)+
6:      move.b  #0xF9,(%a0)+
        move.b  #0x00,(%a0)+
        lea     STR,%a1
        move.l  %a0,%d0
        sub.l   %a1,%d0
        move.w  %d0,(%a1)
        jsr     0x11A48
        rts

| name: d5 = team, d6 = slot -> copy the player's name (max 16 chars, '_' -> ' ') to (a0)+
name:   movem.l %d0-%d2/%a1,-(%sp)
        .if WITH_TRANSFERS
        jsr     0x23600C
        beq.s   90f
        move.w  %d5,%d0
        move.w  %d6,%d1
        jsr     0x236080
        bra.s   91f
90:
        .endif
        move.w  %d5,%d0
        lsl.w   #2,%d0
        movea.l #0x30E,%a1              | team table at $30E
        movea.l (%a1,%d0.w),%a1         | team record
        move.w  (%a1),%d1               | offset to the players
        adda.w  %d1,%a1
        move.w  %d6,%d2
        bra.s   2f
1:      move.w  (%a1),%d1               | skip one player: length word + name, then 8 bytes
        adda.w  %d1,%a1
        addq.l  #8,%a1
2:      dbra    %d2,1b
        .if WITH_TRANSFERS
91:
        .endif
        move.l  %a0,%d2                 | start: the name is padded to 16 (in-place sort redraw)
        move.w  (%a1)+,%d1
        subq.w  #2,%d1                  | name length (may end in a 0 pad byte)
        cmpi.w  #16,%d1
        ble.s   3f
        moveq   #16,%d1
3:      subq.w  #1,%d1
        bmi.s   6f
4:      move.b  (%a1)+,%d0
        beq.s   6f
        cmpi.b  #0x5F,%d0
        bne.s   5f
        moveq   #0x20,%d0
5:      move.b  %d0,(%a0)+
        dbra    %d1,4b
6:      move.l  %a0,%d0
        sub.l   %d2,%d0
7:      cmpi.w  #16,%d0
        bcc.s   8f
        move.b  #0x20,(%a0)+
        addq.w  #1,%d0
        bra.s   7b
8:      movem.l (%sp)+,%d0-%d2/%a1
        rts

col:    move.b  #0xFD,(%a0)+
        move.b  %d1,(%a0)+
        rts

num3:   movem.l %d0-%d3,-(%sp)
        andi.l  #0xFFFF,%d2
        divu.w  #100,%d2
        move.w  %d2,%d0
        swap    %d2
        andi.l  #0xFFFF,%d2
        divu.w  #10,%d2
        move.w  %d2,%d1
        swap    %d2
        moveq   #0x20,%d3
        tst.w   %d0
        beq.s   1f
        move.b  %d0,%d3
        addi.b  #0x30,%d3
1:      move.b  %d3,(%a0)+
        moveq   #0x20,%d3
        tst.w   %d0
        bne.s   2f
        tst.w   %d1
        beq.s   3f
2:      move.b  %d1,%d3
        addi.b  #0x30,%d3
3:      move.b  %d3,(%a0)+
        addi.b  #0x30,%d2
        move.b  %d2,(%a0)+
        movem.l (%sp)+,%d0-%d3
        rts

hdr:    .byte   0xFC,7,0xFD,1
        .ascii  "  #"
        .byte   0xFD,5
        .ascii  "Player"
        .byte   0xFD,22
        .ascii  "Team"
        .byte   0xFD,27
        .ascii  "  G"
        .byte   0xFD,31
        .ascii  "  A"
        .byte   0xFD,35
        .ascii  "PTS"
        .byte   0
        .even
heads:  .word hp-heads,hg-heads,ha-heads
hp:     .byte 0xFD,35
        .asciz "PTS"
hg:     .byte 0xFD,27
        .asciz "  G"
ha:     .byte 0xFD,31
        .asciz "  A"
foot:   .byte   0xFC,25,0xFD,3
        .ascii  "Sort: Xbox B / Mega Drive C"
        .byte   0xFC,0x1A,0xFD,0x10
        .if WITH_REFINEMENTS
        .ascii  "L/R Page"
        .byte   0xFC,27,0xFD,3
        .ascii  "A/Start Back  B Sort"
        .else
        .ascii  "[ More ]"
        .endif
        .byte   0
abbr:   .ascii  "ANABOSBUFCGYCARCHICOLCBJDALDETEDMFLALAKMINMTLNSHNJDNYINYROTTPHIPITSJSSEASTLTBLTORUTAVANVGKWASWPG"
        .even
