    .ifndef WITH_REFINEMENTS
    .equ WITH_REFINEMENTS,0
    .endif
| End of a season (jdc 2026-10-25): after the game that ends your season (and after the
| game's own playoff tree / Champions page), a season summary (record, points, goals, how it ended) and the
| team's player statistics (teamstats.s: regular season + playoffs). Each waits for Start.
| Hook $172E4 (move.w #$78,-(a7) / bsr.w $11156) -> jmp _start / nop; RAM still holds the game.
| Cases: missed the playoffs (last league game, not seeded), out of the playoffs, champion.
| SRAM flag $1210 (playoffs.s +28): 5 missed / 3 out / 4 champion = shown once, season over.
    .equ PORG,0x2FC800                 | playoffs.s: +8 seeds, +28 setflag
    .equ SEEDS,0xFFF6C0
    .equ TEAMSTATS,0x2FB000
    .equ SRAM_RD,0x1A244
    .equ HDR,0xFFE500                  | season header (16 bytes)
    .equ FLAG,0xFFE510
    .equ ROW,0xFFE520                  | your team's table row (16 bytes)
    .equ CASE,0xFFE530                 | 1 missed, 2 out, 3 champion
    .equ TEAM,0xFFE532
    .equ ROUND,0xFFE534
    .equ DIRECT,0xFFE536               | r11, set by finished.s: 1 club page, 2 scoring leaders first;
                                       | Start then returns to its menu at once (0: end-of-season flow)
    .equ STR,0xFFE540                  | text for $11BA4 (length word + text + 0)
    .equ PROW,0xFFE600                 | your 25 player records: goals, assists, shots (word)
    .equ GKR,0xFFE668                  | your 3 goalie records (5 bytes: GP, W, GA:12 | SA:12)
    .equ LST,0xFFE680                  | skaters: slot, jersey, key (points*256 + goals)
    .equ NSK,0xFFE6F0
    .equ PG,0xFFE6F2
    .equ TAB,0xFFE6F4                  | 0 all, 1 league, 2 playoffs
    .equ SORT,0xFFE6F6                 | 0 points, 1 goals, 2 assists
    .equ NTEAM,0xFFE6F8                | team for names / records
    .equ BTEAM,0xFFE6FC               | club selected in the end-of-season browser (TEAM stays your club)
    .equ SCREEN,0xFFE6FE               | 0 club statistics, 1 scoring leaders
    .equ NLD,0xFFE6FA
    .equ LROWB,0xFFE400                | league row (100), league goalies (15), playoff row, playoff goalies
    .equ LGKB,0xFFE464
    .equ PROWB,0xFFE474
    .equ PGKB,0xFFE4D8
    .equ LDR,0xFFE860                  | r12: 100 x 8 bytes, $E860..$EB7F ($E800..$E85F = slots.s;
                                       | $EA40.. is leaders.s scratch, never active with this browser)
    .equ LMAX,100
    .equ PIMR,0xFFE7E0                 | 2026-10-28: your 25 players' penalty minutes for TAB (bytes)
    .equ PIMB,0xFFE7FA                 | 25 bytes: one block read from SRAM (pim.s)
    .equ LPG,0xFFE538                  | leaders page (18 rows each)
    .text
    .globl _start
_start:
    bra.w main
    bra.w fromsim
    bra.w players                     | +8 read-only results browser, including already finished seasons
fromsim:                               | simulate.s result screen, Start (replaces its jmp $172FA)
    bsr.w classify
    beq.s 1f
    bsr.w screens
1:  jmp 0x172FA
main:
    jsr PORG+32                        | one of the season's playoff games in progress?
    bne.s 1f
    jsr 0x2E200C                       | postats: the other pairings of this round play one game
1:  bsr.w classify
    beq.w tail
    bsr.w screens
tail:
    move.w #0x78,-(%sp)                | replayed: wait, then the native game-RAM reset
    jsr 0x11156
    jmp 0x172FA

screens:                               | (a Cup win first shows the game's own Champions page with the cup)
    jsr 0x2E6018                       | table.s screen set-up: background, palettes, scroll, no sprites
    bsr.w summarytext
    bclr #2,0xFFBF78                   | fade in (as table.s)
    move.w #0x18,0xFFBD26
    move.w #0x79,-(%sp)
    jsr 0x11156
1:  jsr 0x175D8                        | Start on either pad
    jsr 0x11340
    move.w %d1,-(%sp)
    jsr 0x11358
    or.w (%sp)+,%d1
    btst #7,%d1
    beq.s 1b
    clr.w DIRECT
    bra.w players

| classify: CASE/TEAM/ROUND set, Z clear when a screen is due; the flag is written here
classify:
    clr.w CASE
    tst.w 0xFFFFF06C                   | season view only (standalone native modes: nothing)
    beq.w 9f
    lea HDR,%a0
    move.l #0x1000,%d0
    moveq #16,%d1
    jsr SRAM_RD
    cmpi.l #0x5345534E,HDR
    bne.w 9f
    tst.w HDR+12
    bne.w 9f
    move.w HDR+6,%d0
    beq.w 9f
    subq.w #1,%d0
    move.w %d0,TEAM
    move.w HDR+8,%d0
    cmp.w HDR+10,%d0
    bcs.w 9f                           | season not finished
    lea FLAG,%a0
    move.l #0x1210,%d0
    moveq #2,%d1
    jsr SRAM_RD
    move.w 0xFFD048,%d0
    bne.s 3f
    tst.w FLAG                         | Regular Season: the last game, first time
    bne.w 9f
    jsr PORG+8                         | seeds
    bne.w 9f
    lea SEEDS,%a0
    moveq #15,%d1
    move.w TEAM,%d0
1:  cmp.b (%a0)+,%d0
    beq.w 9f                           | in the playoffs: they come next
    dbra %d1,1b
    move.w #1,CASE
    moveq #5,%d0
    bra.s 8f
3:  cmpi.w #2,FLAG                     | the season's playoffs were on and the game has now
    bne.w 9f                           | switched back to New Playoffs: they are over
    cmpi.w #2,%d0
    beq.s 4f
    cmpi.w #3,%d0
    bne.w 9f
4:  move.w 0xFFCEEC,%d0                | the game has already moved to the next round: lost in CEEC-1
    subq.w #1,%d0
    bpl.s 41f
    moveq #0,%d0
41: move.w %d0,ROUND
    jsr 0x2E2010                       | postats: the rest of the tree plays out (stats for everyone)
    moveq #0,%d0                       | did your team win this game?
    move.b 0xFFC331,%d0
    move.w 0xFFC6DA,%d1                | your goals - theirs
    sub.w 0xFFCA3E,%d1
    cmp.w TEAM,%d0
    beq.s 5f
    neg.w %d1
5:  move.w #2,CASE
    moveq #3,%d0
    tst.w %d1
    ble.s 8f
    move.w #3,CASE
    moveq #4,%d0
8:  jsr PORG+28                        | setflag d0
    tst.w CASE
    rts
9:  clr.w CASE
    rts

| ---- statistics after the summary (jdc r21): your team, then the scoring leaders.
| Club page: Left/Right = team, A = tab; leaders: Left/Right or A = tab. C = sort,
| Up/Down = page (your team: page 2 = the rest + goalies), Start = next / main menu.
| League rows: SRAM $1220 + 100*team, goalies $E20 + 15*team; playoffs (postats.s):
| $0010 + 100*slot, $06B4 + 15*slot, slot = place in SEEDS (not there: no playoff stats).
players:
    .if WITH_TRANSFERS
    jsr 0x236028
    .endif
    jsr 0x2E6014                       | finished.s hush: the music stops on the statistics (r8; moved r9)
    jsr PORG+8                         | SEEDS for the playoff slots
    clr.w TAB
    clr.w SORT
    clr.w PG
    move.w TEAM,BTEAM
    cmpi.w #2,DIRECT
    beq.w 6f
resume_players:
    clr.w SCREEN
1:  move.w BTEAM,%d0
    bsr.w loadteam
    move.w BTEAM,NTEAM
    bsr.w build
    jsr 0x2E6018
    bsr.w ppage
    bsr.w fadein
2:  bsr.w keys
    btst #7,%d1
    bne.w 5f
    btst #0,%d1                        | Up
    beq.w 3f
    tst.w PG
    beq.w 2b                           | already at the top: no redraw/fade
    clr.w PG
    bra.w 1b
3:  btst #1,%d1                        | Down
    beq.w 4f
    tst.w PG
    bne.w 2b                           | already at the bottom: no redraw/fade
    move.w #1,PG
    bra.w 1b
4:  btst #5,%d1                        | C = sort (r8): same rows reordered, written over the
    beq.w 41f                          | page in place, no screen set-up and fade
    bsr.w nextsort
    bsr.w build
    bsr.w ppage
    bra.w 2b
41: move.w PG,%d5                       | r9: team / tab change written in place (as the sort)
    move.w NSK,%d4                     | when the old and the new page 1 both fill all 18 rows;
    bsr.w teamkeys                     | page 2 or a shorter list: the full redraw as before
    beq.w 2b
    tst.w %d5
    bne.w 1b
    cmpi.w #18,%d4
    bcs.w 1b
    move.w BTEAM,%d0
    bsr.w loadteam
    move.w BTEAM,NTEAM
    bsr.w build
    cmpi.w #18,NSK
    bcs.w 1b
    bsr.w ppage
    bra.w 2b
5:  bsr.w release
    tst.w DIRECT
    bne.w 9f
6:  move.w #1,SCREEN
    clr.w LPG
    bsr.w leaders                      | the whole league, top 100
    jsr 0x2E6018
    bsr.w lpage
    bsr.w fadein
7:  bsr.w keys
    btst #7,%d1
    bne.w 9f
    btst #4,%d1                        | B returns to the selected club, with tab/sort preserved
    bne.w resume_players
    btst #0,%d1                        | Up / Down: pages of 18 (r12), written in place
    beq.w 72f
    tst.w LPG
    beq.w 7b
    subq.w #1,LPG
    bra.w 74f
72: btst #1,%d1
    beq.w 73f
    move.w LPG,%d0
    addq.w #1,%d0
    mulu.w #18,%d0
    cmp.w NLD,%d0
    bcc.w 7b
    addq.w #1,LPG
    bra.w 74f
73: bsr.w tabsort                      | C sort, A / Left / Right tab: rebuilt in place (r12)
    beq.w 7b
    clr.w LPG
    bsr.w leaders
74: bsr.w lpage
    bra.w 7b
9:  bsr.w release
    rts

fadein:
    bclr #2,0xFFBF78
    move.w #0x18,0xFFBD26
    move.w #-1,-(%sp)                  | r8: no sound ID ($79 restarted the menu music on every
    jsr 0x11156                        | statistics page; jdc wants them silent)
    rts
keys:                                  | d1 = new presses, both pads (frame wait)
    jsr 0x175D8
    jsr 0x11340
    move.w %d1,-(%sp)
    move.w %d3,-(%sp)
    jsr 0x11358
    or.w (%sp)+,%d3
    or.w (%sp)+,%d1
    .if WITH_REFINEMENTS
    tst.w SCREEN
    bne.s endstats_keys_ready
    jsr 0x25B028
endstats_keys_ready:
    .endif
    rts
release:                               | wait until Start is up again
    bsr.w keys                         | both pads: a held P2 Start must not also skip the next page
    btst #7,%d3
    bne.s release
    rts
teamkeys:                              | club browser: circular32-team selection, independent of tab
    btst #3,%d1
    beq.s 1f
    addq.w #1,BTEAM
    andi.w #31,BTEAM
    bra.s changed_team
1:  btst #2,%d1
    beq.s tabsort
    subq.w #1,BTEAM
    andi.w #31,BTEAM
changed_team:
    clr.w PG
    moveq #1,%d0
    rts
tabsort:                               | d1 presses -> Z clear when TAB or SORT changed
    btst #6,%d1                        | A cycles combined / league / playoffs on either screen
    bne.s next_tab
    btst #3,%d1                        | Right
    beq.s 1f
next_tab:
    addq.w #1,TAB
    cmpi.w #3,TAB
    bcs.s 8f
    clr.w TAB
    bra.s 8f
1:  btst #2,%d1                        | Left
    beq.s 2f
    subq.w #1,TAB
    bpl.s 8f
    move.w #2,TAB
    bra.s 8f
2:  btst #5,%d1                        | C
    beq.s 9f
    bsr.s nextsort
8:  moveq #1,%d0
    rts
9:  moveq #0,%d0
    rts

nextsort:                              | G -> A -> PTS -> G
    addq.w #1,SORT
    cmpi.w #3,SORT
    bcs.s 1f
    clr.w SORT
1:  rts

slot:                                  | d0 = team -> d0 = slot in SEEDS, 16 if not there
    movem.l %d1/%a0,-(%sp)
    lea SEEDS,%a0
    moveq #0,%d1
1:  cmp.b (%a0,%d1.w),%d0
    beq.s 2f
    addq.w #1,%d1
    cmpi.w #16,%d1
    bcs.s 1b
2:  move.w %d1,%d0
    movem.l (%sp)+,%d1/%a0
    rts

| loadteam: d0 = team -> PROW (25 x G, A, SOG) and GKR (3 goalie records) for TAB
loadteam:
    movem.l %d0-%d7/%a0-%a3,-(%sp)
    move.w %d0,%d7
    bsr.w loadpim                      | 2026-10-28: penalty minutes
    lea LROWB,%a0                      | league
    moveq #0,%d0
    move.w %d7,%d0
    mulu.w #100,%d0
    addi.l #0x1220,%d0
    moveq #100,%d1
    jsr SRAM_RD
    lea LGKB,%a0
    moveq #0,%d0
    move.w %d7,%d0
    mulu.w #15,%d0
    addi.l #0xE20,%d0
    moveq #15,%d1
    jsr SRAM_RD
    lea PROWB,%a0                      | playoffs (zeros if not in them): PROWB + PGKB, 116 bytes
    moveq #57,%d1
1:  clr.w (%a0)+
    dbra %d1,1b
    move.w %d7,%d0
    bsr.w slot
    cmpi.w #16,%d0
    bcc.s 2f
    move.w %d0,%d6
    lea PROWB,%a0
    moveq #0,%d0
    move.w %d6,%d0
    mulu.w #100,%d0
    addi.l #0x10,%d0
    moveq #100,%d1
    jsr SRAM_RD
    lea PGKB,%a0
    moveq #0,%d0
    move.w %d6,%d0
    mulu.w #15,%d0
    addi.l #0x6B4,%d0
    moveq #15,%d1
    jsr SRAM_RD
2:  lea LROWB,%a0                      | combine: a0 league, a1 playoffs -> a2
    lea PROWB,%a1
    lea PROW,%a2
    moveq #24,%d1
3:  moveq #0,%d2
    moveq #0,%d3
    moveq #0,%d4
    cmpi.w #2,TAB
    beq.s 4f
    move.b (%a0),%d2
    move.b 1(%a0),%d3
    move.w 2(%a0),%d4
4:  cmpi.w #1,TAB
    beq.s 5f
    add.b (%a1),%d2
    add.b 1(%a1),%d3
    add.w 2(%a1),%d4
5:  move.b %d2,(%a2)+
    move.b %d3,(%a2)+
    move.w %d4,(%a2)+
    addq.l #4,%a0
    addq.l #4,%a1
    dbra %d1,3b
    lea LGKB,%a0                       | goalies: GP, W, GA:12 | SA:12
    lea PGKB,%a1
    lea GKR,%a2
    moveq #2,%d1
6:  moveq #0,%d2                       | GP
    moveq #0,%d3                       | W
    moveq #0,%d4                       | GA
    moveq #0,%d5                       | SA
    cmpi.w #2,TAB
    beq.s 7f
    movea.l %a0,%a3
    bsr.w gkadd
7:  cmpi.w #1,TAB
    beq.s 71f
    movea.l %a1,%a3
    bsr.w gkadd
71: move.b %d2,(%a2)+
    move.b %d3,(%a2)+
    move.w %d4,%d6
    lsr.w #4,%d6
    move.b %d6,(%a2)+
    move.w %d4,%d6
    lsl.w #4,%d6
    move.w %d5,%d0
    lsr.w #8,%d0
    andi.w #15,%d0
    or.w %d0,%d6
    move.b %d6,(%a2)+
    move.b %d5,(%a2)+
    addq.l #5,%a0
    addq.l #5,%a1
    dbra %d1,6b
    movem.l (%sp)+,%d0-%d7/%a0-%a3
    rts
gkadd:                                 | a3 = record -> d2 += GP, d3 += W, d4 += GA, d5 += SA
    moveq #0,%d0
    move.b (%a3),%d0
    add.w %d0,%d2
    move.b 1(%a3),%d0
    add.w %d0,%d3
    moveq #0,%d0
    move.b 2(%a3),%d0
    lsl.w #4,%d0
    moveq #0,%d6
    move.b 3(%a3),%d6
    lsr.b #4,%d6
    or.w %d6,%d0
    add.w %d0,%d4
    moveq #0,%d0
    move.b 3(%a3),%d0
    andi.w #15,%d0
    lsl.w #8,%d0
    move.b 4(%a3),%d0
    add.w %d0,%d5
    rts

teamrec:                               | a1 = NTEAM's ROM record
    move.w NTEAM,%d0
    lsl.w #2,%d0
    movea.l #0x30E,%a1
    movea.l (%a1,%d0.w),%a1
    rts
| key: a0 = player record (G, A, SOG) -> d2 = sort key for SORT (main*256 + points/goals)
key:
    moveq #0,%d1                       | goals
    move.b (%a0),%d1
    moveq #0,%d0                       | assists
    move.b 1(%a0),%d0
    move.w %d1,%d2                     | points
    add.w %d0,%d2
    tst.w SORT
    bne.s 1f
    lsl.w #8,%d2                       | points, then goals
    add.w %d1,%d2
    rts
1:  move.w %d2,%d3
    cmpi.w #1,SORT
    bne.s 2f
    move.w %d1,%d2                     | goals, then points
    bra.s 3f
2:  move.w %d0,%d2                     | assists, then points
3:  lsl.w #8,%d2
    add.w %d3,%d2
    rts
| skater: a3 = the player's jersey byte in the team record -> Z set for a goalie
skater:
    move.b 5(%a3),%d0
    bne.s 1f
    move.b 4(%a3),%d0
    andi.b #0xF0,%d0
1:  rts

build:                                 | LST/NSK: your skaters by the sort key
    bsr.w teamrec
    move.w (%a1),%d0
    adda.w %d0,%a1
    lea LST,%a2
    moveq #0,%d4
    moveq #0,%d5
1:
    .if WITH_TRANSFERS
    jsr 0x23600C
    beq.s end_build_original
    move.w NTEAM,%d0
    move.w %d5,%d1
    jsr 0x23607C
    tst.l %d0
    beq.w end_build_skip
    move.w NTEAM,%d0
    move.w %d5,%d1
    jsr 0x236080
end_build_original:
    .endif
    move.w (%a1),%d1
    lea (%a1,%d1.w),%a3                | jersey byte
    tst.w %d5
    beq.s 3f
    bsr.s skater
    beq.s 3f
    move.b %d5,(%a2)+
    move.b (%a3),(%a2)+
    lea PROW-4,%a0
    move.w %d5,%d0
    lsl.w #2,%d0
    lea (%a0,%d0.w),%a0
    movem.l %d0-%d1/%d3,-(%sp)
    bsr.w key
    movem.l (%sp)+,%d0-%d1/%d3
    move.w %d2,(%a2)+
    addq.w #1,%d4
3:  lea 8(%a3),%a1
    .if WITH_TRANSFERS
end_build_skip:
    .endif
    addq.w #1,%d5
    cmpi.w #26,%d5
    .if WITH_TRANSFERS
    blt.w 1b
    .else
    blt.s 1b
    .endif
    move.w %d4,NSK
    lea LST,%a0
    moveq #4,%d1                       | entry size
    bra.w sortlist

| sortlist: a0 = list, d4 = entries, d1 = entry size (key word at +2) -> highest key first
sortlast:
    movem.l %d0-%d7/%a0-%a2,-(%sp)
    move.w %d4,%d6
    subq.w #1,%d6
    bgt.s 5f
    moveq #1,%d6
    bra.s 5f
sortlist:
    movem.l %d0-%d7/%a0-%a2,-(%sp)
    moveq #1,%d6
5:  cmp.w %d4,%d6
    bge.s 9f
    move.w %d6,%d7
6:  tst.w %d7
    beq.s 8f
    move.w %d7,%d0
    mulu.w %d1,%d0
    lea (%a0,%d0.w),%a1                | entry j
    movea.l %a1,%a2
    suba.w %d1,%a2                     | entry j-1
    move.w 2(%a1),%d2
    cmp.w 2(%a2),%d2
    bls.s 8f
    move.w %d1,%d3                     | swap the two entries
    subq.w #1,%d3
7:  move.b (%a1),%d0
    move.b (%a2),(%a1)+
    move.b %d0,(%a2)+
    dbra %d3,7b
    subq.w #1,%d7
    bra.s 6b
8:  addq.w #1,%d6
    bra.s 5b
9:  movem.l (%sp)+,%d0-%d7/%a0-%a2
    rts

| leaders: LDR = the league's top LMAX (100) skaters for TAB / SORT (8 bytes: team, slot, key, G, A, SOG)
leaders:
    movem.l %d0-%d7/%a0-%a4,-(%sp)
    clr.w NLD
    moveq #0,%d7                       | team
1:  move.w %d7,%d0
    bsr.w loadteam
    move.w %d7,NTEAM
    bsr.w teamrec
    move.w (%a1),%d0
    adda.w %d0,%a1
    moveq #0,%d5                       | slot
2:
    .if WITH_TRANSFERS
    jsr 0x23600C
    beq.s end_leader_original
    move.w NTEAM,%d0
    move.w %d5,%d1
    jsr 0x23607C
    tst.l %d0
    beq.w end_leader_skip
    move.w NTEAM,%d0
    move.w %d5,%d1
    jsr 0x236080
end_leader_original:
    .endif
    move.w (%a1),%d1
    lea (%a1,%d1.w),%a3
    tst.w %d5
    beq.s 6f
    bsr.w skater
    beq.s 6f
    lea PROW-4,%a0
    move.w %d5,%d0
    lsl.w #2,%d0
    lea (%a0,%d0.w),%a0
    tst.b (%a0)                        | nothing at all: not a leader
    bne.s 21f
    tst.b 1(%a0)
    beq.s 6f
21: bsr.w key
    lea LDR,%a4                        | append or replace the last of LMAX
    move.w NLD,%d0
    cmpi.w #LMAX,%d0
    bcs.s 3f
    cmp.w (LMAX-1)*8+2(%a4),%d2
    bls.s 6f
    moveq #LMAX-1,%d0
    bra.s 4f
3:  addq.w #1,NLD
4:  lsl.w #3,%d0
    lea (%a4,%d0.w),%a4
    move.b %d7,(%a4)
    move.b %d5,1(%a4)
    move.w %d2,2(%a4)
    move.b (%a0),4(%a4)
    move.b 1(%a0),5(%a4)
    move.w 2(%a0),6(%a4)
    movem.l %d1/%d4,-(%sp)
    lea LDR,%a0
    move.w NLD,%d4
    moveq #8,%d1
    bsr.w sortlast                     | the list is sorted: only the new last entry moves up
    movem.l (%sp)+,%d1/%d4
6:  lea 8(%a3),%a1
    .if WITH_TRANSFERS
end_leader_skip:
    .endif
    addq.w #1,%d5
    cmpi.w #26,%d5
    blt.w 2b
    addq.w #1,%d7
    cmpi.w #32,%d7
    bcs.w 1b
    movem.l (%sp)+,%d0-%d7/%a0-%a4
    rts

name:                                  | d6 = slot of NTEAM -> name (max 16, '_' = space, padded) at a1
    movem.l %d0-%d2/%a0,-(%sp)
    move.l %a1,-(%sp)
    move.l %a1,-(%sp)
    .if WITH_TRANSFERS
    jsr 0x23600C
    beq.s end_name_original
    move.w NTEAM,%d0
    move.w %d6,%d1
    jsr 0x236080
    movea.l %a1,%a0
    movea.l (%sp)+,%a1
    bra.s end_name_record
end_name_original:
    .endif
    bsr.w teamrec
    movea.l %a1,%a0
    movea.l (%sp)+,%a1
    move.w (%a0),%d1
    adda.w %d1,%a0
    move.w %d6,%d2
    bra.s 2f
1:  move.w (%a0),%d1
    adda.w %d1,%a0
    addq.l #8,%a0
2:  dbra %d2,1b
    .if WITH_TRANSFERS
end_name_record:
    .endif
    move.w (%a0)+,%d1
    subq.w #2,%d1
    cmpi.w #16,%d1
    ble.s 3f
    moveq #16,%d1
3:  subq.w #1,%d1
    bmi.s 6f
4:  move.b (%a0)+,%d0
    beq.s 6f
    cmpi.b #0x5F,%d0
    bne.s 5f
    moveq #0x20,%d0
5:  move.b %d0,(%a1)+
    dbra %d1,4b
6:  move.l %a1,%d0
    sub.l (%sp)+,%d0
7:  cmpi.w #16,%d0
    bge.s 8f
    move.b #0x20,(%a1)+
    addq.w #1,%d0
    bra.s 7b
8:  movem.l (%sp)+,%d0-%d2/%a0
    rts
numpad:                                | d2 right-aligned in 4 characters at a1
    movem.l %d0-%d3,-(%sp)
    moveq #1,%d3
    move.w %d2,%d0
1:  cmpi.w #10,%d0
    bcs.s 2f
    andi.l #0xFFFF,%d0
    divu.w #10,%d0
    addq.w #1,%d3
    bra.s 1b
2:  moveq #4,%d0
    sub.w %d3,%d0
    bra.s 4f
3:  move.b #0x20,(%a1)+
4:  dbra %d0,3b
    movem.l (%sp)+,%d0-%d3
    bra.w num

heading:                               | title row (tab name), sort line, footer
    .if WITH_REFINEMENTS
    moveq #25,%d0
    moveq #1,%d1
    bsr.w at
    lea endstats_back(%pc),%a0
    bsr.w copy0
    bsr.w out
    .endif
    moveq #26,%d0
    moveq #3,%d1
    bsr.w at
    lea t_xbox(%pc),%a0
    bsr.w copy0
    bsr.w out
    move.w TAB,%d0
    add.w %d0,%d0
    lea tabs(%pc),%a0
    adda.w (%a0,%d0.w),%a0
    move.l %a0,-(%sp)
    moveq #0,%d0
    moveq #9,%d1
    bsr.w at
    movea.l (%sp)+,%a0
    bsr.w copy0
    bsr.w out
    moveq #2,%d0
    moveq #24,%d1
    bsr.w at
    move.w SORT,%d0
    add.w %d0,%d0
    lea sorts(%pc),%a0
    adda.w (%a0,%d0.w),%a0
    bsr.w copy0
    bsr.w out
    moveq #27,%d0
    moveq #0,%d1
    bsr.w at
    lea t_keys(%pc),%a0
    tst.w SCREEN
    beq.s 1f
    lea t_lkeys(%pc),%a0
1:  bsr.w copy0
    bra.w out

ppage:                                 | your team: tab name, banner, header, rows
    bsr.w heading
    move.w BTEAM,%d1
    bsr.w banner
    moveq #6,%d0                       | keep row25 empty above the button help
    moveq #1,%d1
    bsr.w at
    lea t_head(%pc),%a0
    bsr.w copy0
    bsr.w out
    bsr.w highlight
    moveq #0,%d7
    move.w PG,%d6
    mulu.w #18,%d6
1:  move.w %d6,%d5
    add.w %d7,%d5
    cmp.w NSK,%d5
    bge.w 5f
    moveq #7,%d0
    add.w %d7,%d0
    moveq #1,%d1
    bsr.w at
    lea LST,%a2
    lsl.w #2,%d5
    lea (%a2,%d5.w),%a2
    move.b 1(%a2),%d0                  | jersey (BCD)
    bsr.w jersey
    moveq #0,%d6
    move.b (%a2),%d6
    bsr.w name
    lea PROW-4,%a3
    move.w %d6,%d0
    lsl.w #2,%d0
    lea (%a3,%d0.w),%a3
    bsr.w gaps
    lea PIMR-1,%a3                     | PIM (2026-10-28), 3 wide: the row ends at column 39
    moveq #0,%d2
    move.b (%a3,%d6.w),%d2
    bsr.w numpad
    move.b -3(%a1),%d0                 | drop numpad's leading space
    move.b -2(%a1),-3(%a1)
    move.b -1(%a1),-2(%a1)
    subq.l #1,%a1
    bsr.w out
    move.w PG,%d6
    mulu.w #18,%d6
    addq.w #1,%d7
    cmpi.w #18,%d7
    bcs.w 1b
5:  tst.w PG                           | page 2: goalies under the rest
    beq.w 8f
    moveq #8,%d0
    add.w %d7,%d0
    move.w %d0,%d7
    moveq #1,%d1
    bsr.w at
    lea t_ghead(%pc),%a0
    bsr.w copy0
    bsr.w out
    moveq #0,%d5
6:  lea GKR,%a3
    move.w %d5,%d0
    mulu.w #5,%d0
    lea (%a3,%d0.w),%a3
    tst.b (%a3)
    beq.w 7f
    addq.w #1,%d7
    move.w %d7,%d0
    moveq #1,%d1
    bsr.w at
    move.b #0x20,(%a1)+
    move.b #0x20,(%a1)+
    move.b #0x20,(%a1)+
    move.w %d5,%d6
    bsr.w name
    moveq #0,%d2
    move.b (%a3),%d2
    bsr.w numpad
    moveq #0,%d2
    move.b 1(%a3),%d2
    bsr.w numpad
    moveq #0,%d2
    move.b 2(%a3),%d2
    lsl.w #4,%d2
    move.b 3(%a3),%d0
    lsr.b #4,%d0
    or.b %d0,%d2
    bsr.w numpad
    moveq #0,%d2
    move.b 3(%a3),%d2
    andi.w #15,%d2
    lsl.w #8,%d2
    move.b 4(%a3),%d2
    bsr.w numpad
    bsr.w out
7:  addq.w #1,%d5
    cmpi.w #3,%d5
    bcs.w 6b
8:  rts

jersey:                                | d0 = BCD number -> 2 characters and a space at a1
    move.b %d0,%d2
    lsr.b #4,%d2
    beq.s 1f
    addi.b #0x30,%d2
    move.b %d2,(%a1)+
    bra.s 2f
1:  move.b #0x20,(%a1)+
2:  andi.b #15,%d0
    addi.b #0x30,%d0
    move.b %d0,(%a1)+
    move.b #0x20,(%a1)+
    rts
gaps:                                  | a3 = G, A, SOG -> "   G   A PTS SOG" at a1
    moveq #0,%d2
    move.b (%a3),%d2
    bsr.w numpad
    moveq #0,%d2
    move.b 1(%a3),%d2
    bsr.w numpad
    moveq #0,%d2
    move.b (%a3),%d2
    moveq #0,%d0
    move.b 1(%a3),%d0
    add.w %d0,%d2
    bsr.w numpad
    move.w 2(%a3),%d2
    bra.w numpad

| loadpim: d0 = team -> PIMR = league and/or playoff minutes for TAB (pim.s blocks)
loadpim:
    movem.l %d0-%d4/%a0-%a1,-(%sp)
    lea PIMR,%a0
    moveq #24,%d1
1:  clr.b (%a0)+
    dbra %d1,1b
    move.w %d0,%d4
    moveq #0,%d3                       | 0 league, 1 playoffs
2:  cmpi.w #1,TAB
    bne.s 3f
    tst.w %d3
    bne.s 6f                           | league tab: no playoff minutes
3:  cmpi.w #2,TAB
    bne.s 4f
    tst.w %d3
    beq.s 6f                           | playoff tab: no league minutes
4:  moveq #0,%d0
    move.w %d4,%d0
    move.w %d3,%d1
    jsr 0x2EE008                       | pim.s offset (-1: not in the playoffs)
    tst.l %d0
    bmi.s 6f
    lea PIMB,%a0
    moveq #25,%d1
    jsr SRAM_RD
    lea PIMB,%a0
    lea PIMR,%a1
    moveq #24,%d1
5:  moveq #0,%d0
    move.b (%a0)+,%d0
    moveq #0,%d2
    move.b (%a1),%d2
    add.w %d0,%d2
    cmpi.w #255,%d2
    bls.s 51f
    move.w #255,%d2
51: move.b %d2,(%a1)+
    dbra %d1,5b
6:  addq.w #1,%d3
    cmpi.w #2,%d3
    bcs.s 2b
    movem.l (%sp)+,%d0-%d4/%a0-%a1
    rts

lpage:                                 | scoring leaders: rank, player, team, G A PTS SOG
    bsr.w heading
    moveq #4,%d0
    moveq #9,%d1
    bsr.w at
    lea t_lead(%pc),%a0
    bsr.w copy0
    bsr.w out
    moveq #6,%d0
    moveq #0,%d1
    bsr.w at
    lea t_lhead(%pc),%a0
    bsr.w copy0
    bsr.w out
    bsr.w highlight
    moveq #0,%d7                       | screen row 0..17; entry = LPG*18 + row
1:  cmpi.w #18,%d7
    bcc.w 9f
    moveq #7,%d0
    add.w %d7,%d0
    moveq #0,%d1
    bsr.w at
    move.w LPG,%d2
    mulu.w #18,%d2
    add.w %d7,%d2
    cmp.w NLD,%d2
    bcs.s 0f
    moveq #38,%d0                      | past the list: a blank row (the front plane's spaces are
11: move.b #0x20,(%a1)+                | see-through, so it clears an old row)
    dbra %d0,11b
    bsr.w out
    bra.s 8f
0:  move.w %d2,%d5                     | entry
    addq.w #1,%d2                      | rank: " 9 ", "10 ", "100 "
    cmpi.w #10,%d2
    bcc.s 2f
    move.b #0x20,(%a1)+
2:  bsr.w num
    move.b #0x20,(%a1)+                | "100 " too: the space after the (padded) name goes instead
3:  lea LDR,%a3
    move.w %d5,%d0
    lsl.w #3,%d0
    lea (%a3,%d0.w),%a3
    moveq #0,%d0
    move.b (%a3),%d0
    move.w %d0,NTEAM
    moveq #0,%d6
    move.b 1(%a3),%d6
    bsr.w name
    cmpi.w #LMAX-1,%d5                 | rank 100: no space after the name (same width)
    beq.s 4f
    move.b #0x20,(%a1)+
4:  lea abbr(%pc),%a0                  | team
    moveq #0,%d0
    move.b (%a3),%d0
    mulu.w #3,%d0
    move.b (%a0,%d0.w),(%a1)+
    move.b 1(%a0,%d0.w),(%a1)+
    move.b 2(%a0,%d0.w),(%a1)+
    addq.l #4,%a3
    bsr.w gaps
    bsr.w out
8:  addq.w #1,%d7
    bra.w 1b
9:  rts

| Copy only the selected header glyph(s) to three spare end-screen tiles.
| Font foreground1 -> palette0 colour14 (orange); shadow/shape stay unchanged.
| Native fonts, other header columns and all four font palettes are retained.
highlight:
    move.w %sr,-(%sp)
    move.w #0x2700,%sr
    movem.l %d0-%d7/%a0-%a4,-(%sp)
    move.w #0x006E,0xFFBD44          | end-screen palette0 colour14; setup resets it on exit/redraw
    moveq #0,%d0
    move.w SORT,%d0
    add.w %d0,%d0
    lea hcols(%pc),%a0
    move.w (%a0,%d0.w),%d0
    tst.w SCREEN
    beq.s 1f
    addq.w #3,%d0                    | leaders' numeric columns are three tiles farther right
1:  add.w %d0,%d0
    addi.w #0xE600,%d0               | front-plane row6 (r10),128 cells per row
    movea.l %d0,%a0
    movea.l %a0,%a3
    addq.l #2,%a3
    tst.w SORT
    bne.s 2f
    addq.l #4,%a3                    | PTS has three glyphs; G/A have one
2:  movea.l #0xB040,%a2              | tiles582..584, unused window area (window disabled)
    movea.l #0x582,%a4
3:  move.l %a0,%d0
    bsr.w vread
    move.w 0xC00000,%d5
    move.w %d5,%d0
    andi.l #0x7FF,%d0
    lsl.l #5,%d0
    movea.l %d0,%a1
    moveq #15,%d7
4:  move.l %a1,%d0
    bsr.s vread
    move.w 0xC00000,%d2
    moveq #0,%d3
    moveq #3,%d6
5:  rol.w #4,%d2
    move.w %d2,%d4
    andi.w #15,%d4
    cmpi.w #1,%d4
    bne.s 6f
    moveq #14,%d4
6:  lsl.w #4,%d3
    or.w %d4,%d3
    dbra %d6,5b
    move.l %a2,%d0
    bsr.s vwrite
    move.w %d3,0xC00000
    addq.l #2,%a1
    addq.l #2,%a2
    dbra %d7,4b
    andi.w #0xF800,%d5
    move.w %a4,%d2
    or.w %d2,%d5
    move.l %a0,%d0
    bsr.s vwrite
    move.w %d5,0xC00000
    addq.l #1,%a4
    addq.l #2,%a0
    cmpa.l %a3,%a0
    bcs.s 3b
    movem.l (%sp)+,%d0-%d7/%a0-%a4
    move.w (%sp)+,%sr
    rts
vread:
    moveq #0,%d1
    bra.s vcommand
vwrite:
    move.l #0x40000000,%d1
vcommand:
    move.w %d0,%d4
    andi.l #0x3FFF,%d0
    swap %d0
    lsr.w #8,%d4
    lsr.w #6,%d4
    or.w %d4,%d0
    or.l %d1,%d0
    move.l %d0,0xC00004
    rts
hcols: .word 29,23,27                | right-aligned PTS,G,A; leaders' columns are +3

| ---- text as table.s: STR = length word + text + 0, at (POSX, POSY) on the back plane
at:                                    | d0 row, d1 column; a1 = STR+2
    move.w %d1,0xFFB028
    move.w %d0,0xFFB02A
    lea STR+2,%a1
    rts
out:                                   | print STR+2 .. a1
    clr.b (%a1)+
    move.l %a1,%d0
    btst #0,%d0
    beq.s 1f
    clr.b (%a1)+
1:  lea STR,%a0
    move.l %a1,%d0
    sub.l %a0,%d0
    move.w %d0,(%a0)
    movea.l %a0,%a1
    cmpi.w #25,0xFFB02A
    blo.s grey_help_positioned
    jsr 0x25D004
grey_help_positioned:
    clr.w 0xFFB02E                   | front plane (r10): no dark box behind each glyph
    clr.w 0xFFB02C
    movem.l %d2-%d7/%a2-%a3,-(%sp)
    jsr 0x11BA4
    movem.l (%sp)+,%d2-%d7/%a2-%a3
    rts
copy0:                                 | a0 text (0-terminated) -> a1
    move.b (%a0)+,(%a1)+
    bne.s copy0
    subq.l #1,%a1
    rts
num:                                   | d2.w unsigned -> decimal at a1
    movem.l %d2-%d3,-(%sp)
    andi.l #0xFFFF,%d2
    moveq #0,%d3
1:  divu.w #10,%d2
    swap %d2
    addi.w #0x30,%d2
    move.w %d2,-(%sp)
    addq.w #1,%d3
    clr.w %d2
    swap %d2
    tst.w %d2
    bne.s 1b
2:  move.w (%sp)+,%d2
    move.b %d2,(%a1)+
    subq.w #1,%d3
    bne.s 2b
    movem.l (%sp)+,%d2-%d3
    rts
line:                                  | d0 row, a0 label: printed at column 5; then a1 = value at column 25
    move.w %d0,-(%sp)
    moveq #5,%d1
    bsr.w at
    bsr.w copy0
    bsr.w out
    move.w (%sp)+,%d0
    moveq #25,%d1
    bra.w at
banner:                                | your team's banner at column 5, row 4 (as table.s)
    move.w #5,0xFFB028
    move.w #4,0xFFB02A
    add.w %d1,%d1
    movea.l #0x1DD366,%a1
    adda.l 4(%a1),%a1
    movea.l #0x30A,%a2
    clr.w %d0
    move.w (%a1),%d2
    moveq #2,%d3
    moveq #2,%d4
    moveq #0,%d5
    jmp 0x1169A

summarytext:
    lea ROW,%a0                        | your row: GP W L OTL GF GA T OTW
    moveq #0,%d0
    move.w TEAM,%d0
    lsl.w #4,%d0
    addi.l #0x1010,%d0
    moveq #16,%d1
    jsr SRAM_RD
    moveq #0,%d0
    moveq #9,%d1
    bsr.w at
    lea t_summary(%pc),%a0
    bsr.w copy0
    bsr.w out
    move.w TEAM,%d1
    bsr.w banner
    moveq #9,%d0
    lea s_rec(%pc),%a0
    bsr.w line
    move.w ROW+2,%d2
    bsr.w num
    move.b #0x2D,(%a1)+
    move.w ROW+4,%d2
    bsr.w num
    move.b #0x2D,(%a1)+
    move.w ROW+6,%d2
    add.w ROW+12,%d2
    bsr.w num
    bsr.w out
    moveq #11,%d0
    lea s_pts(%pc),%a0
    bsr.w line
    move.w ROW+2,%d2                   | 2 per win + 1 per OT loss / tie
    add.w %d2,%d2
    add.w ROW+6,%d2
    add.w ROW+12,%d2
    bsr.w num
    bsr.w out
    moveq #13,%d0
    lea s_goals(%pc),%a0
    bsr.w line
    move.w ROW+8,%d2
    bsr.w num
    move.b #0x2D,(%a1)+
    move.w ROW+10,%d2
    bsr.w num
    bsr.w out
    moveq #17,%d0
    move.w %d0,-(%sp)
    lea s_missed(%pc),%a0
    cmpi.w #1,CASE
    beq.s 2f
    lea s_champ(%pc),%a0
    cmpi.w #3,CASE
    beq.s 2f
    move.w ROUND,%d1                   | out in round 0..3
    cmpi.w #3,%d1
    bls.s 1f
    moveq #3,%d1
1:  add.w %d1,%d1
    lea outs(%pc),%a0
    adda.w (%a0,%d1.w),%a0
2:  move.w (%sp)+,%d0
    moveq #5,%d1
    bsr.w at
    bsr.w copy0
    bsr.w out
    moveq #26,%d0
    moveq #5,%d1
    bsr.w at
    lea s_stats(%pc),%a0
    bsr.w copy0
    bra.w out

t_summary: .asciz "Season Summary"
t_head:    .asciz " # Player             G   A PTS SOG PM"
t_ghead:   .asciz "   Goalie            GP   W  GA  SA"
t_lead:    .asciz "Scoring Leaders"
t_lhead:   .asciz " # Player           Tm    G   A PTS SOG"
t_keys:
    .if WITH_REFINEMENTS
    .asciz "L/R Team X Tab B Sort U/D Page"
    .else
    .asciz "L/R team A tab C sort U/D page Start"
    .endif
t_lkeys:
    .if WITH_REFINEMENTS
    .asciz "U/D Page X Tab B Sort A Team Back"
    .else
    .asciz "U/D page A tab C sort B teams Start"
    .endif
    .if WITH_REFINEMENTS
endstats_back: .asciz "A Back / Start Done"
    .endif
t_xbox:    .asciz "Sort: Xbox B / Mega Drive C"
    .even
tabs:      .word tb0-tabs,tb1-tabs,tb2-tabs
tb0:       .asciz "Season + Playoffs"
tb1:       .asciz "Regular Season   "
tb2:       .asciz "Playoffs         "
    .even
sorts:     .word so0-sorts,so1-sorts,so2-sorts
so0:       .asciz "Sort: points "
so1:       .asciz "Sort: goals  "
so2:       .asciz "Sort: assists"
    .even
abbr:      .ascii "ANABOSBUFCGYCARCHICOLCBJDALDETEDMFLALAKMINMTLNSHNJDNYINYROTTPHIPITSJSSEASTLTBLTORUTAVANVGKWASWPG"
s_rec:     .asciz "Record (W-L-OTL)"
s_pts:     .asciz "Points"
s_goals:   .asciz "Goals for-against"
s_missed:  .asciz "Missed the playoffs"
s_champ:   .asciz "Stanley Cup champions"
s_stats:   .asciz "Start = statistics"
    .even
outs:      .word o1-outs,o2-outs,o3-outs,o4-outs
o1:        .asciz "Out in the first round"
o2:        .asciz "Out in the second round"
o3:        .asciz "Out in the conference final"
o4:        .asciz "Lost the Stanley Cup final"
    .even
