| Season playoff statistics, kept apart from the league (jdc 2026-10-25-r21).
| SRAM (logical, free since User Records are off): $0002 "PO" magic, $0010 + 100*slot
| player rows (slots 0..15 = SEEDS order, 16 = scratch), $06B4 + 15*slot goalie records.
| season.s rowload/rowsave/gkput get their offset here; with POGAME set the rows are the
| playoff block, otherwise the league ($1220 / $E20) as before.
| Entries: +0 ROWOFF, +4 GKOFF, +8 clear (playoffs set up), +12 others (after one of your
| playoff games: one game for every other pairing of that round), +16 finish (you are out:
| the rest of the tree, winners as the game has already drawn them).
    .include "season-symbols.inc"
    .equ POGAME,0xFFF0D2
    .equ DELTA,0xFFF0F0
    .equ SHOTSV,0xFFF0F2
    .equ SEEDS,0xFFF6C0
    .equ PORG,0x2FC800
    .equ RND,0x11086
    .equ SRAM_RD,0x1A244
    .equ SRAM_WR,0x1A1E4
    .equ PO_P,0x0010
    .equ PO_G,0x06B4
    .equ PO_END,0x096A                 | 17 * 15 after PO_G ($07A3), then pim.s's playoff PIM $07C0..$0968
    .equ TREE,0xFFCEF4                 | 16 teams, then the winners 8 / 4 / 2 / 1
    .equ TMP,0xFFE780
    .equ BUFZ,0xFFE790                 | 64 zero/scratch bytes
    .equ SUMW,0xFFE7D0
    .equ SERIES,0xFFE7D2               | 0 = one game per pairing, 1 = best of seven
    .text
    .globl _start
_start:
    bra.w rowoff
    bra.w gkoff
    bra.w clear
    bra.w others
    bra.w finish

| d0 = team -> slot 0..15 in SEEDS (16 if not there); other registers kept
slot:
    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

rowoff:                                | d0 = team -> SRAM offset of its 100-byte row
    tst.b POGAME
    bne.s 1f
    mulu.w #100,%d0
    addi.l #0x1220,%d0
    rts
1:  bsr.s slot
    mulu.w #100,%d0
    addi.l #PO_P,%d0
    rts

gkoff:                                 | d0 = (team*3 + goalie)*5 -> SRAM offset of the record
    tst.b POGAME
    bne.s 1f
    addi.l #0xE20,%d0
    rts
1:  move.l %d1,-(%sp)
    andi.l #0xFFFF,%d0
    divu.w #15,%d0                     | team, remainder = goalie*5
    move.l %d0,%d1
    swap %d1
    bsr.s slot
    mulu.w #15,%d0
    add.w %d1,%d0
    andi.l #0xFFFF,%d0
    addi.l #PO_G,%d0
    move.l (%sp)+,%d1
    rts

| fixsum: add DELTA to the hack's checksum ($1FFF = sum, $1FFE = ~sum), clear DELTA
fixsum:
    movem.l %d0-%d1/%a0,-(%sp)
    lea SUMW,%a0
    move.l #0x1FFE,%d0
    moveq #2,%d1
    jsr SRAM_RD
    move.b SUMW+1,%d0
    add.b DELTA,%d0
    move.b %d0,SUMW+1
    not.b %d0
    move.b %d0,SUMW
    lea SUMW,%a0
    move.l #0x1FFE,%d0
    moveq #2,%d1
    jsr SRAM_WR
    clr.b DELTA
    movem.l (%sp)+,%d0-%d1/%a0
    rts

| clear: zero the playoff block (a new season's playoffs are set up), checksum kept
clear:
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    clr.b DELTA
    move.l #2,%d6                      | SRAM offset, $0002 .. PO_END
1:  lea BUFZ,%a0
    move.l %d6,%d0
    moveq #32,%d1
    jsr SRAM_RD
    lea BUFZ,%a0                       | subtract the old bytes, write zeros
    moveq #31,%d1
2:  move.b (%a0),%d0
    sub.b %d0,DELTA
    clr.b (%a0)+
    dbra %d1,2b
    cmpi.l #2,%d6
    bne.s 3f
    move.b #0x50,BUFZ                  | "PO" at $0002
    move.b #0x4F,BUFZ+1
    addi.b #0x9F,DELTA                 | + $50 + $4F
3:  lea BUFZ,%a0
    move.l %d6,%d0
    moveq #32,%d1
    jsr SRAM_WR
    addi.l #32,%d6
    cmpi.l #PO_END,%d6
    bcs.s 1b
    bsr.w fixsum
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    rts

| game: d4 = team A, d5 = team B, d6 = winner (A or B, else either) -> stats of one game
game:
    movem.l %d0-%d7/%a2-%a3,-(%sp)
    move.w %d4,%d0
    jsr GOALS_FN
    move.w %d0,%d2
    move.w %d5,%d0
    jsr GOALS_FN
    move.w %d0,%d3
    cmp.w %d3,%d2
    bne.s 1f
    moveq #2,%d0                       | tie: one more goal for a side
    jsr RND
    tst.w %d0
    beq.s 2f
    addq.w #1,%d2
    bra.s 1f
2:  addq.w #1,%d3
1:  cmp.w %d4,%d6                      | the drawn winner must win
    bne.s 3f
    cmp.w %d3,%d2
    bhi.s 5f
    exg %d2,%d3
    bra.s 5f
3:  cmp.w %d5,%d6
    bne.s 5f
    cmp.w %d2,%d3
    bhi.s 5f
    exg %d2,%d3
5:  movea.w %d2,%a2                    | A's goals
    movea.w %d3,%a3                    | B's goals
    move.w %d4,%d0
    move.w %d2,%d1
    jsr DIST_FN
    move.w SHOTSV,%d6                  | A's shots
    move.w %d5,%d0
    move.w %d3,%d1
    jsr DIST_FN
    move.w SHOTSV,%d7                  | B's shots
    moveq #0,%d3                       | A's goalie: B's goals and shots
    cmpa.w %a3,%a2
    ble.s 6f
    moveq #1,%d3
6:  move.w %d4,%d0
    move.w %a3,%d1
    move.w %d7,%d2
    jsr GKSIM_FN
    moveq #0,%d3                       | B's goalie: A's goals and shots
    cmpa.w %a2,%a3
    ble.s 7f
    moveq #1,%d3
7:  move.w %d5,%d0
    move.w %a2,%d1
    move.w %d6,%d2
    jsr GKSIM_FN
    movem.l (%sp)+,%d0-%d7/%a2-%a3
    rts

| setup: SEEDS valid, POGAME on, series format; Z clear = not the season's playoffs
setup:
    jsr PORG+8
    bne.s 9f
    st POGAME
    clr.b DELTA
    clr.w SERIES
    cmpi.b #7,0xFFCEEB                 | $CEEA = 7: one game per pairing, 0: best of seven
    beq.s 1f
    move.w #1,SERIES
1:  moveq #0,%d0
9:  rts
done:
    bsr.w fixsum
    clr.b POGAME
    rts

| level L (0..3) of the tree: a0 = its first team, d7 = number of teams
level:
    lea TREE,%a0
    moveq #16,%d7
    tst.w %d0
    beq.s 9f
    lea 16(%a0),%a0
    moveq #8,%d7
    subq.w #1,%d0
    beq.s 9f
    lea 8(%a0),%a0
    moveq #4,%d7
    subq.w #1,%d0
    beq.s 9f
    lea 4(%a0),%a0
    moveq #2,%d7
9:  rts

| others: after one of your season playoff games (home/away teams in $C331/$C333)
others:
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    bsr.s setup
    bne.w 9f
    moveq #0,%d1                       | find the level where you two are a pairing
    move.b 0xFFC331,%d1
    moveq #0,%d2
    move.b 0xFFC333,%d2
    moveq #0,%d3                       | level
1:  move.w %d3,%d0
    bsr.s level
    moveq #0,%d6
2:  moveq #0,%d4
    move.b (%a0,%d6.w),%d4
    moveq #0,%d5
    move.b 1(%a0,%d6.w),%d5
    cmp.w %d1,%d4
    bne.s 3f
    cmp.w %d2,%d5
    beq.s 4f
3:  cmp.w %d2,%d4
    bne.s 31f
    cmp.w %d1,%d5
    beq.s 4f
31: addq.w #2,%d6
    cmp.w %d7,%d6
    bcs.s 2b
    addq.w #1,%d3
    cmpi.w #4,%d3
    bcs.s 1b
    bra.w 8f                           | not found
4:  moveq #0,%d6                       | one game for each other pairing at this level
5:  moveq #0,%d4
    move.b (%a0,%d6.w),%d4
    moveq #0,%d5
    move.b 1(%a0,%d6.w),%d5
    cmp.w %d1,%d4
    beq.s 6f
    cmp.w %d2,%d4
    beq.s 6f
    cmpi.w #31,%d4
    bhi.s 6f
    cmpi.w #31,%d5
    bhi.s 6f
    move.l %d6,-(%sp)
    moveq #-1,%d6
    bsr.w game
    move.l (%sp)+,%d6
6:  addq.w #2,%d6
    cmp.w %d7,%d6
    bcs.s 5b
8:  bsr.w done
9:  movem.l (%sp)+,%d0-%d7/%a0-%a6
    rts

| finish: d0 = the round you went out in (0..3). Rounds after it: every pairing plays its
| series to the winner the game has drawn (one game, or best of seven: 0..3 losses, 4 wins).
finish:
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    move.w %d0,%d3
    bsr.w setup
    bne.w 9f
1:  addq.w #1,%d3                      | level of the pairings still to play
    cmpi.w #4,%d3
    bcc.w 8f
    move.w %d3,%d0
    bsr.w level                        | a0 / d7 = this round's teams
    lea (%a0,%d7.w),%a1                | the next level = their drawn winners
    moveq #0,%d2                       | pairing index (even)
2:  moveq #0,%d4
    move.b (%a0,%d2.w),%d4
    moveq #0,%d5
    move.b 1(%a0,%d2.w),%d5
    move.w %d2,%d0
    lsr.w #1,%d0
    moveq #0,%d6
    move.b (%a1,%d0.w),%d6
    cmpi.w #31,%d4
    bhi.s 7f
    cmpi.w #31,%d5
    bhi.s 7f
    moveq #1,%d1                       | the winner's games: 1, or 4
    clr.w TMP                          | the loser's wins
    tst.w SERIES
    beq.s 4f
    moveq #4,%d1
    moveq #4,%d0
    jsr RND
    move.w %d0,TMP
4:  move.w %d6,-(%sp)
    move.w %d4,%d6                     | loser = the other one
    cmp.w (%sp),%d4
    bne.s 41f
    move.w %d5,%d6
41: tst.w TMP
    beq.s 5f
    subq.w #1,TMP
    bsr.w game
    bra.s 41b
5:  move.w (%sp)+,%d6
51: bsr.w game
    subq.w #1,%d1
    bne.s 51b
7:  addq.w #2,%d2
    cmp.w %d7,%d2
    bcs.s 2b
    bra.w 1b
8:  bsr.w done
9:  movem.l (%sp)+,%d0-%d7/%a0-%a6
    rts
