| Season mode, step 4: "Season Standings" screen, reached from the pause/post-game menus (replaces "Other Scores").
| Reads the table from battery RAM (see season.s), sorts by points, shows 16 teams per page (Left/Right = page,
| Start = back). Text is drawn with the game's own routines; codes: fc row, fd column, f9 01/00 colour on/off.

        .equ    SRAM_OFF, 0x1000
        .equ    NBYTES,   16+32*16
        .equ    MAGIC,    0x5345534E
        .equ    SRAM_RD,  0x1A244
        .equ    TBL,      0xFFE400       | season block copy
        .equ    ORDER,    0xFFE620       | 32 team indices, sorted
        .equ    PTS,      0xFFE640       | 32 words: sort key
        .equ    PAGE,     0xFFE6C0       | division shown: 0 Atlantic, 1 Metropolitan, 2 Central, 3 Pacific
        .equ    PORD,     0xFFE6C8       | the 8 teams of this division, best first
        .equ    SEL,      0xFFE6C2       | selected rank (0..31), C opens that team
        .equ    PREVUD,   0xFFE6C4       | up/down bits last frame (one step per press)
        .equ    FIRST,    0xFFE6C6       | 1 on entry: pick your team's division
        .equ    TEAMSTATS,0x2FB000
        .equ    STR,      0xFFE700       | text built here (word length + codes)

        .text
        .globl  _start
_start:
        clr.w   PAGE
        clr.w   SEL
        move.w  #1,FIRST
redo:   moveq   #10,%d0                 | open the panel like "Scoring Summary" does
        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  "Season Standings"
        .byte   0xBD,0x07,0x01

        lea     TBL,%a0                 | load the table from battery RAM
        move.l  #SRAM_OFF,%d0
        move.l  #NBYTES,%d1
        jsr     SRAM_RD
        lea     TBL,%a0
        cmpi.l  #MAGIC,(%a0)
        bne.s   3f
        tst.w   12(%a0)                 | "New Season" chosen: show the new (empty) season, not the old one
        beq.s   1f
3:      move.w  #NBYTES/2-1,%d2         | no season yet: show an empty table
2:      clr.w   (%a0)+
        dbra    %d2,2b
1:      bsr.w   sortteams
        tst.w   FIRST
        beq.s   5f
        clr.w   FIRST
        move.w  TBL+6,%d0               | start on your team's division
        beq.s   5f
        subq.w  #1,%d0
        lea     divs,%a2
        moveq   #0,%d1
        move.b  (%a2,%d0.w),%d1
        move.w  %d1,PAGE
5:      bsr.w   draw

loop:   moveq   #0,%d0
        jsr     0x80BA
        jsr     0xA41E                  | pad: d3 = new presses, d1 = held/dir (as in Record Holders)
        jsr     0x11318
        btst    #7,%d3
        beq.s   3f
        cmpi.w  #0x4D41,0xFFE3BC        | opened from the main menu? go back there
        bne.s   88f
        movea.l 0xFFE3B8,%a0
        jmp     (%a0)
88:     jmp     0x9CD8                  | Start: back to the menu
3:      move.b  %d3,%d4                 | up/down: only on the frame the button goes down
        andi.b  #3,%d4
        move.b  PREVUD,%d5
        move.b  %d4,PREVUD
        not.b   %d5
        and.b   %d5,%d4
        btst    #0,%d4                  | up
        beq.s   32f
        tst.w   SEL
        beq.w   loop
        subq.w  #1,SEL
        bra.s   34f
32:     btst    #1,%d4                  | down
        beq.s   35f
        cmpi.w  #7,SEL
        beq.w   loop
        addq.w  #1,SEL
34:     bsr.w   draw
        bra.w   loop
35:     btst    #5,%d3                  | C alone: the selected team's players
        beq.s   36f
        btst    #6,%d3
        bne.s   36f
        lea     PORD,%a2
        move.w  SEL,%d1
        moveq   #0,%d0
        move.b  (%a2,%d1.w),%d0
        jsr     TEAMSTATS
        bra.w   redo                    | rebuild this screen
36:     btst    #6,%d3                  | A + C: new season (clear the table)
        beq.s   31f
        btst    #5,%d3
        beq.s   31f
        bsr.w   newseason
        bsr.w   sortteams
        bsr.w   draw
        bra.w   loop
31:     btst    #3,%d1                  | right: next division
        beq.s   4f
        move.w  PAGE,%d0
        addq.w  #1,%d0
        andi.w  #3,%d0
        move.w  %d0,PAGE
        bsr.w   draw
        bra.w   loop
4:      btst    #2,%d1                  | left: previous division
        beq.w   loop
        move.w  PAGE,%d0
        subq.w  #1,%d0
        andi.w  #3,%d0
        move.w  %d0,PAGE
        bsr.w   draw
        bra.w   loop

| ---- sort: key = points*256 + (GF-GA+128), highest first; teams with GP 0 still listed (alphabetical order kept on ties)
sortteams:
        lea     TBL+16,%a0
        lea     PTS,%a1
        lea     ORDER,%a2
        moveq   #0,%d0
5:      move.b  %d0,(%a2)+
        move.w  2(%a0),%d1              | W
        add.w   %d1,%d1
        add.w   6(%a0),%d1              | + OTL
        add.w   12(%a0),%d1             | + T
        lsl.w   #8,%d1
        move.w  8(%a0),%d2              | GF - GA, clamped to -128..127
        sub.w   10(%a0),%d2
        cmpi.w  #127,%d2
        ble.s   6f
        moveq   #127,%d2
6:      cmpi.w  #-128,%d2
        bge.s   7f
        move.w  #-128,%d2
7:      addi.w  #128,%d2
        add.w   %d2,%d1
        move.w  %d1,(%a1)+
        lea     16(%a0),%a0
        addq.w  #1,%d0
        cmpi.w  #32,%d0
        blt.s   5b
        | selection sort on ORDER by PTS (descending, stable)
        moveq   #0,%d4                  | i
8:      move.w  %d4,%d5                 | best = i
        move.w  %d4,%d6
        addq.w  #1,%d6                  | j
9:      cmpi.w  #32,%d6
        bge.s   11f
        lea     ORDER,%a2
        moveq   #0,%d0
        moveq   #0,%d1
        move.b  (%a2,%d6.w),%d0
        move.b  (%a2,%d5.w),%d1
        lea     PTS,%a1
        add.w   %d0,%d0
        add.w   %d1,%d1
        move.w  (%a1,%d0.w),%d2
        cmp.w   (%a1,%d1.w),%d2
        bls.s   10f
        move.w  %d6,%d5
10:     addq.w  #1,%d6
        bra.s   9b
11:     cmp.w   %d4,%d5                 | move best to position i by shifting (keeps it stable)
        beq.s   13f
        lea     ORDER,%a2
        move.b  (%a2,%d5.w),%d0
12:     move.b  -1(%a2,%d5.w),(%a2,%d5.w)
        subq.w  #1,%d5
        cmp.w   %d4,%d5
        bgt.s   12b
        move.b  %d0,(%a2,%d4.w)
13:     addq.w  #1,%d4
        cmpi.w  #31,%d4
        blt.s   8b
        rts

| ---- draw the current page
draw:
        lea     STR+2,%a0
        move.b  #0xF8,(%a0)+            | start code as in the hack's own tables
        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                 | header line
14:     move.b  (%a1)+,(%a0)+
        bne.s   14b
        subq.l  #1,%a0
        lea     ORDER,%a2               | PORD = this division's teams in table order
        lea     PORD,%a3
        lea     divs,%a1
        moveq   #31,%d2
        moveq   #0,%d1
16:     move.b  (%a2)+,%d1
        move.b  (%a1,%d1.w),%d3
        cmp.b   PAGE+1,%d3
        bne.s   17f
        move.b  %d1,(%a3)+
17:     dbra    %d2,16b
        moveq   #0,%d7
        moveq   #0,%d4                  | row counter
15:     move.w  %d7,%d0
        add.w   %d4,%d0                 | place-1 in the division
        move.b  #0xFC,(%a0)+            | row
        move.w  %d4,%d1
        addi.w  #9,%d1
        move.b  %d1,(%a0)+
        moveq   #1,%d1                  | rank (cols 1-3, the digit at col 3)
        bsr.w   col
        move.w  %d0,%d2
        addq.w  #1,%d2
        bsr.w   num3
        moveq   #1,%d1                  | selection marker over the rank's leading blank
        bsr.w   col
        move.b  #0x20,(%a0)+
        cmp.w   SEL,%d0
        bne.s   37f
        move.b  #0x5D,-1(%a0)           | "]" (shows as an arrow)
37:
        lea     PORD,%a2
        moveq   #0,%d5
        move.b  (%a2,%d0.w),%d5         | team index
        moveq   #5,%d1                  | team abbreviation
        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)+
        lea     TBL+16,%a3
        lsl.w   #4,%d5
        adda.w  %d5,%a3                 | team row
        moveq   #8,%d1
        bsr.w   col
        move.w  (%a3),%d2               | GP
        bsr.w   num3
        moveq   #12,%d1
        bsr.w   col
        move.w  2(%a3),%d2              | W in regulation = W - OTW
        sub.w   14(%a3),%d2
        bsr.w   num3
        moveq   #16,%d1
        bsr.w   col
        move.w  14(%a3),%d2             | OTW
        bsr.w   num3
        moveq   #20,%d1
        bsr.w   col
        move.w  6(%a3),%d2              | OTL
        add.w   12(%a3),%d2             | + ties (shown together)
        bsr.w   num3
        moveq   #24,%d1
        bsr.w   col
        move.w  4(%a3),%d2              | L
        bsr.w   num3
        moveq   #28,%d1
        bsr.w   col
        move.w  8(%a3),%d2              | GF
        bsr.w   num3
        moveq   #32,%d1
        bsr.w   col
        move.w  10(%a3),%d2             | GA
        bsr.w   num3
        moveq   #36,%d1
        bsr.w   col
        move.w  2(%a3),%d2              | PTS
        add.w   %d2,%d2
        add.w   6(%a3),%d2
        add.w   12(%a3),%d2
        bsr.w   num3
        addq.w  #1,%d4
        cmpi.w  #8,%d4
        blt.w   15b
        move.b  #0xFC,(%a0)+            | division name
        move.b  #18,(%a0)+
        move.b  #0xFD,(%a0)+
        move.b  #12,(%a0)+
        lea     divname,%a1
        move.w  PAGE,%d0
        mulu.w  #20,%d0
        adda.w  %d0,%a1
        moveq   #19,%d0
18:     move.b  (%a1)+,(%a0)+
        dbra    %d0,18b
        lea     foot,%a1                | footer
16:     move.b  (%a1)+,(%a0)+
        bne.s   16b
        subq.l  #1,%a0
18:     move.l  %a0,%d0                 | even total length: pad with a space before the colour-off code
        btst    #0,%d0
        beq.s   19f
        move.b  #0x20,(%a0)+
19:     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                 | print (a1 = length word)
        rts

| clear the season table in battery RAM (keeps the hack's checksum right without touching RAM $FF0000)
newseason:
        movem.l %d0-%d7/%a0-%a1,-(%sp)
        lea     TBL,%a0                 | the block as it is stored now (for the checksum)
        move.l  #SRAM_OFF,%d0
        move.l  #NBYTES,%d1
        jsr     SRAM_RD
        bsr.w   tsum
        move.b  %d7,%d6                 | old sum of the stored block
        lea     TBL,%a0
        move.w  #NBYTES/2-1,%d2
23:     clr.w   (%a0)+
        dbra    %d2,23b
        move.l  #MAGIC,TBL
        move.w  #1,TBL+12               | stay in Whole Season
        lea     TBL,%a0
        move.l  #SRAM_OFF,%d0
        move.l  #NBYTES,%d1
        jsr     0x1A1E4
        bsr.w   tsum
        lea     STR,%a0
        move.l  #0x1FFE,%d0
        moveq   #2,%d1
        jsr     SRAM_RD
        lea     STR,%a0
        move.b  1(%a0),%d0
        sub.b   %d6,%d0
        add.b   %d7,%d0
        move.b  %d0,1(%a0)
        not.b   %d0
        move.b  %d0,(%a0)
        move.l  #0x1FFE,%d0
        moveq   #2,%d1
        jsr     0x1A1E4
        movem.l (%sp)+,%d0-%d7/%a0-%a1
        rts
| d7.b = sum of the table bytes in TBL
tsum:   lea     TBL,%a1
        moveq   #0,%d7
        move.w  #NBYTES-1,%d2
24:     add.b   (%a1)+,%d7
        dbra    %d2,24b
        rts

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

| d2 = 0..999 -> 3 characters, right aligned
num3:   movem.l %d0-%d3,-(%sp)
        andi.l  #0xFFFF,%d2
        divu.w  #100,%d2
        move.w  %d2,%d0                 | hundreds
        swap    %d2
        andi.l  #0xFFFF,%d2
        divu.w  #10,%d2
        move.w  %d2,%d1                 | tens
        swap    %d2                     | ones
        moveq   #0x20,%d3
        tst.w   %d0
        beq.s   20f
        move.b  %d0,%d3
        addi.b  #0x30,%d3
20:     move.b  %d3,(%a0)+
        moveq   #0x20,%d3
        tst.w   %d0
        bne.s   21f
        tst.w   %d1
        beq.s   22f
21:     move.b  %d1,%d3
        addi.b  #0x30,%d3
22:     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,4
        .ascii  "Team"
        .byte   0xFD,8
        .ascii  " GP"
        .byte   0xFD,12
        .ascii  "  W"
        .byte   0xFD,16
        .ascii  "OTW"
        .byte   0xFD,20
        .ascii  "OTL"
        .byte   0xFD,24
        .ascii  "  L"
        .byte   0xFD,28
        .ascii  " GF"
        .byte   0xFD,32
        .ascii  " GA"
        .byte   0xFD,36
        .ascii  "PTS"
        .byte   0
foot:   .byte   0xFC,0x19,0xFD,2
        .ascii  "OTL incl. ties       A+C: new season"
        .byte   0xFC,0x1A,0xFD,0x10
        .ascii  "[ Division ]"
        .byte   0
| division per team (ANA..WPG): 0 Atlantic, 1 Metropolitan, 2 Central, 3 Pacific
divs:   .byte   3,0,0,3,1,2,2,1,2,0,3,0,3,2,0,2,1,1,1,0,1,1,3,3,2,0,0,2,3,3,1,2
divname:
        .ascii  "  Atlantic Division "
        .ascii  " Metropolitan Div.  "
        .ascii  "  Central Division  "
        .ascii  "  Pacific Division  "
abbr:   .ascii  "ANABOSBUFCGYCARCHICOLCBJDALDETEDMFLALAKMINMTLNSHNJDNYINYROTTPHIPITSJSSEASTLTBLTORUTAVANVGKWASWPG"
        .even
