season/playoffs.s

Download file

Release 2026-11-04-r2 · SHA256 faadcee94f832b770cc472742be4c7f11f684a396c458940e3ceea7fbc75b288 · Click a line number for a direct link.

1        .include "features.inc"2| Season mode: playoffs after the season, NHL format. Mini/Light use one game per pairing; full season uses best of 7.3| 16 teams: the top 3 of each division and 2 wild cards per conference (the best of the rest). East = Atlantic +4| Metropolitan (tree slots 8-15, right side), West = Central + Pacific (slots 0-7, left side). In each conference the5| better division winner meets the second wild card, the other winner the first; 2nd meets 3rd in each division.6| Pairs in the tree: (0,1) (2,3) (4,5) (6,7), the winners of (0,1)/(2,3) and (4,5)/(6,7) meet in round 2.7|8| The game's playoffs: $CEF4 = the 16 teams, copied from the ROM table $5576 + 16 * $CEE8 (32 presets) by $17D80;9| New Playoffs ($17D16) picks a preset with your team (Home) in it and stores your slot in $CEEE. State is kept as the10| game's password at $D088 (saved with the settings in battery RAM), so Continue Playoffs works across power-offs.11| Hooks: $17D8E (movea.l #$5576,a1 / adda.w d1,a1) -> jsr fetch / nop: the season's 16 teams instead of a preset;12| $17D4A (move.w d1,$CEEE / move.w d0,$CEE8) -> jsr newpo / nop: your slot in the season's tree.13| "Season playoffs" = a valid season block, not New Season, and your games played >= the season length.14| SRAM $1210 (word, free): 0 not started, 1 set up (New Playoffs or New Playoffs/7 games, no game yet), 2 a playoff game was played15| (the game's own state is then in its password, Continue Playoffs), 3 over (the game ended the playoffs: menu free);16| jdc r18: 3 = out, 4 = champion, 5 = missed the playoffs; 3..5 = over, the season summary has been shown.1718        .equ    SRAM_OFF, 0x100019        .equ    NBYTES,   16+32*1620        .equ    MAGIC,    0x5345534E21        .equ    SRAM_RD,  0x1A24422        .equ    SRAM_WR,  0x1A1E423        .equ    FLAG_OFF, 0x121024        .equ    PBUF,     0xFFF400       | season block (528 bytes)25        .equ    KEYS,     0xFFF620       | 32 longs: (points*256 + goal difference + 128) * 32 + (31 - team)26        .equ    TAKEN,    0xFFF6A0       | 32 bytes27        .equ    SEEDS,    0xFFF6C0       | 16 teams in tree order28        .equ    QUAL,     0xFFF6D0       | 32 bytes: 1 = top 3 of the division, 2 = wild card, 0 = out29        .equ    DR,       0xFFF6F0       | 4 divisions x 3 teams30        .equ    TMP,      0xFFF700       | 4 bytes31        .equ    HOME,     0xFFD04C3233        .text34        .globl  _start35_start: bra.w   fetch                   | +0  hook $17D8E36        bra.w   newpo                   | +4  hook $17D4A37        bra.w   seeds                   | +8  d0 = 0 (and Z) when SEEDS / QUAL are valid38        bra.w   autopo                  | +12 season over, first time: d0 = 0 when the playoffs should start now39        bra.w   clrflag                 | +16 a new season starts40        bra.w   spcheck                 | +20 season menu: are the season's playoffs on? (see there)41        bra.w   played                  | +24 a playoff game was played (season.s)42        bra.w   setflag                 | +28 d0 -> SRAM flag (seasonend.s: 3 out, 4 champion, 5 missed, summary shown)43        bra.w   poseason                | +32 d0 = 0: this game is one of the season's playoff games in progress4445| ---- $17D8E: a1 = the 16 teams of this tree46fetch:  movem.l %d0-%d7/%a0/%a2-%a6,-(%sp)47        bsr.w   active48        movem.l (%sp)+,%d0-%d7/%a0/%a2-%a6   | (movem to registers keeps the flags)49        bne.s   1f50        lea     SEEDS,%a151        rts521:      movea.l #0x5576,%a153        adda.w  %d1,%a154        rts5556| ---- $17D4A: New Playoffs has picked a preset (d0) and your slot (d1)57newpo:  move.w  %d1,0xFFCEEE58        move.w  %d0,0xFFCEE859        movem.l %d0-%d7/%a0-%a6,-(%sp)60        bsr.w   active61        bne.s   9f62        move.w  HOME,%d063        bsr.w   slotof64        bmi.s   9f65        move.w  %d1,0xFFCEEE66        clr.w   0xFFCEE8679:      movem.l (%sp)+,%d0-%d7/%a0-%a668        rts6970| slotof: d0 = team -> d1 = slot in SEEDS (N flag set if not there)71slotof: lea     SEEDS,%a072        moveq   #0,%d1731:      cmp.b   (%a0,%d1.w),%d074        beq.s   2f75        addq.w  #1,%d176        cmpi.w  #16,%d177        blt.s   1b78        moveq   #-1,%d179        rts802:      tst.w   %d181        rts8283| active: season playoffs? d0 = 0 (Z) and SEEDS filled, else d0 = -184active: tst.w   0xFFFFF06C             | standalone native modes must not modify a suspended season85        beq.w   8f86        bsr.w   seeds87        bne.w   8f88        move.w  PBUF+8,%d0              | your games played89        cmp.w   PBUF+10,%d0             | season length90        bcs.s   8f91        tst.w   PBUF+6                  | a season with your team92        beq.s   8f93        moveq   #0,%d094        rts958:      moveq   #-1,%d096        rts9798| ---- autopo: called by the season menu when your season is over. d0 = 0 when it should switch to the playoffs now99| (first time only, and your team made it); the flag is set here.100autopo: movem.l %d1-%d7/%a0-%a6,-(%sp)101        lea     TMP,%a0102        move.l  #FLAG_OFF,%d0103        moveq   #2,%d1104        jsr     SRAM_RD105        tst.w   TMP106        bne.s   8f                      | already switched once107        bsr.w   active108        bne.s   8f109        move.w  PBUF+6,%d0110        subq.w  #1,%d0111        bsr.w   slotof112        bmi.s   8f                      | your team did not make it113        moveq   #1,%d0114        bsr.w   setflag115        moveq   #0,%d0116        bra.s   9f1178:      moveq   #-1,%d01189:      movem.l (%sp)+,%d1-%d7/%a0-%a6119        tst.w   %d0120        rts121122| ---- spcheck: d0 = -1 not the season's playoffs (menu as usual); 0 = they are on and the menu is already set;123| 1 / 2 / 3 = they are on and Play Mode must be set to this (1 Continue, 2 single game, 3 best of 7). d2 = your team.124spcheck:125        movem.l %d1/%d3-%d7/%a0-%a6,-(%sp)126        bsr.w   active127        bne.w   8f128        move.w  PBUF+6,%d0129        subq.w  #1,%d0130        move.w  %d0,%d2                 | your team131        bsr.w   slotof132        .if MINI_GAMES != 8133        bmi.w   8f                      | preserve reach after adding current and legacy Mini lengths134        .else135        bmi.s   8f                      | not in the playoffs136        .endif137        lea     TMP,%a0138        move.l  #FLAG_OFF,%d0139        moveq   #2,%d1140        jsr     SRAM_RD141        move.w  TMP,%d4142        cmpi.w  #3,%d4143        bcc.s   8f                      | over (3 out, 4 champion)144        moveq   #3,%d3                  | New Playoffs/7 games145        .if MINI_GAMES != 8146        cmpi.w  #MINI_GAMES,PBUF+10147        beq.s   7f148        .endif149        cmpi.w  #8,PBUF+10150        beq.s   7f151        cmpi.w  #31,PBUF+10152        bne.s   6f1537:      moveq   #2,%d3                  | New Playoffs: one game decides the pairing1546:155        cmpi.w  #2,%d4156        bne.s   2f157        move.w  0xFFD048,%d0            | after a game the game sets 1 (go on) or 2/3 (the playoffs are over)158        cmpi.w  #2,%d0159        beq.s   1f160        cmpi.w  #3,%d0161        bne.s   3f1621:      moveq   #3,%d0163        bsr.w   setflag164        bra.s   8f1653:      moveq   #1,%d3                  | Continue Playoffs166        bra.s   4f1672:      tst.w   %d4168        bne.s   4f169        moveq   #1,%d0170        bsr.w   setflag1714:      moveq   #0,%d0172        cmp.w   0xFFD048,%d3173        bne.s   5f174        cmp.w   HOME,%d2175        beq.s   9f1765:      move.w  %d3,%d0177        bra.s   9f1788:      moveq   #-1,%d01799:      movem.l (%sp)+,%d1/%d3-%d7/%a0-%a6180        tst.w   %d0181        rts182183| ---- played: a game in a playoff mode is over (season.s): flag 2 if these are the season's playoffs184played: movem.l %d0-%d7/%a0-%a6,-(%sp)185        bsr.w   active186        bne.s   1f187        lea     TMP,%a0                 | jdc r18: the season's playoffs are over (3..5): a later standalone188        move.l  #FLAG_OFF,%d0           | New Playoffs must not reopen them189        moveq   #2,%d1190        jsr     SRAM_RD191        cmpi.w  #3,TMP192        bcc.s   1f193        moveq   #2,%d0194        bsr.w   setflag1951:      movem.l (%sp)+,%d0-%d7/%a0-%a6196        rts197198| ---- poseason (season.s at game over, before played): d0 = 0 when the season's playoffs are in progress (flag 1/2)199| and your team plays this game; else -1. Keeps all other registers.200poseason:201        movem.l %d1-%d7/%a0-%a6,-(%sp)202        bsr.w   active203        bne.s   8f204        move.w  PBUF+6,%d2205        subq.w  #1,%d2206        moveq   #0,%d0207        move.b  0xFFC331,%d0208        cmp.w   %d0,%d2209        beq.s   1f210        move.b  0xFFC333,%d0211        cmp.w   %d0,%d2212        bne.s   8f2131:      lea     TMP,%a0214        move.l  #FLAG_OFF,%d0215        moveq   #2,%d1216        jsr     SRAM_RD217        move.w  TMP,%d0218        beq.s   8f219        cmpi.w  #3,%d0220        bcc.s   8f221        moveq   #0,%d0222        bra.s   9f2238:      moveq   #-1,%d02249:      movem.l (%sp)+,%d1-%d7/%a0-%a6225        tst.w   %d0226        rts227228clrflag:229        movem.l %d0-%d7/%a0-%a6,-(%sp)230        moveq   #0,%d0231        bsr.s   setflag232        movem.l (%sp)+,%d0-%d7/%a0-%a6233        rts234235| setflag: d0 = value -> SRAM $1210 (word), the hack's checksum ($1FFE = ~sum, $1FFF = sum) kept right236setflag:237        cmpi.w  #1,%d0                  | jdc r21: the playoffs are set up: clear their statistics block238        bne.s   0f239        jsr     0x2E20082400:      movem.l %d0-%d7/%a0-%a6,-(%sp)241        move.w  %d0,%d7242        lea     TMP,%a0243        move.l  #FLAG_OFF,%d0244        moveq   #2,%d1245        jsr     SRAM_RD246        move.b  TMP,%d6                 | d6 = - old bytes + new bytes247        add.b   TMP+1,%d6248        neg.b   %d6249        move.w  %d7,%d0250        add.b   %d0,%d6251        lsr.w   #8,%d0252        add.b   %d0,%d6253        move.w  %d7,TMP254        lea     TMP,%a0255        move.l  #FLAG_OFF,%d0256        moveq   #2,%d1257        jsr     SRAM_WR258        lea     TMP,%a0259        move.l  #0x1FFE,%d0260        moveq   #2,%d1261        jsr     SRAM_RD262        move.b  TMP+1,%d0263        add.b   %d6,%d0264        move.b  %d0,TMP+1265        not.b   %d0266        move.b  %d0,TMP267        lea     TMP,%a0268        move.l  #0x1FFE,%d0269        moveq   #2,%d1270        jsr     SRAM_WR271        movem.l (%sp)+,%d0-%d7/%a0-%a6272        rts273274| ---- seeds: the tree and who is in, from the season table in battery RAM275seeds:  movem.l %d1-%d7/%a0-%a6,-(%sp)276        lea     PBUF,%a0277        move.l  #SRAM_OFF,%d0278        move.l  #NBYTES,%d1279        jsr     SRAM_RD280        cmpi.l  #MAGIC,PBUF281        bne.w   90f282        tst.w   PBUF+12                 | New Season chosen283        bne.w   90f284        | keys285        lea     PBUF+16,%a0286        lea     KEYS,%a1287        lea     TAKEN,%a2288        lea     QUAL,%a3289        moveq   #0,%d02901:      move.w  2(%a0),%d1              | 2 W + OTL + T291        add.w   %d1,%d1292        add.w   6(%a0),%d1293        add.w   12(%a0),%d1294        lsl.w   #8,%d1295        move.w  8(%a0),%d2              | goal difference, clamped296        sub.w   10(%a0),%d2297        cmpi.w  #127,%d2298        ble.s   2f299        moveq   #127,%d23002:      cmpi.w  #-128,%d2301        bge.s   3f302        move.w  #-128,%d23033:      addi.w  #128,%d2304        add.w   %d2,%d1305        andi.l  #0xFFFF,%d1306        lsl.l   #5,%d1307        moveq   #31,%d2308        sub.w   %d0,%d2309        or.w    %d2,%d1                 | equal: the lower team index first (as in the tables)310        bset    #31,%d1                 | never 0 (pick starts from 0)311        move.l  %d1,(%a1)+312        clr.b   (%a2)+313        clr.b   (%a3)+314        lea     16(%a0),%a0315        addq.w  #1,%d0316        cmpi.w  #32,%d0317        blt.s   1b318        | top 3 of each division319        lea     DR,%a4320        moveq   #0,%d3                  | division3214:      moveq   #2,%d43225:      moveq   #0,%d5                  | 0 = by division323        bsr.w   pick324        move.b  %d0,(%a4)+325        lea     QUAL,%a0326        move.b  #1,(%a0,%d0.w)327        dbra    %d4,5b328        addq.w  #1,%d3329        cmpi.w  #4,%d3330        blt.s   4b331        | each conference: two wild cards, then the tree (conference 1 = West -> slots 0-7, 0 = East -> 8-15)332        moveq   #0,%d33336:      moveq   #1,%d5                  | by conference334        bsr.w   pick335        move.w  %d0,%d6                 | WC1336        lea     QUAL,%a0337        move.b  #2,(%a0,%d0.w)338        bsr.w   pick339        move.w  %d0,%d7                 | WC2340        move.b  #2,(%a0,%d0.w)341        lea     DR,%a4342        move.w  %d3,%d0                 | divisions 2c and 2c+1343        add.w   %d0,%d0344        mulu.w  #3,%d0345        lea     (%a4,%d0.w),%a5         | a5 = first division's 3, a6 = second's346        lea     3(%a5),%a6347        lea     KEYS,%a0348        moveq   #0,%d0349        move.b  (%a5),%d0350        lsl.w   #2,%d0351        move.l  (%a0,%d0.w),%d1352        moveq   #0,%d0353        move.b  (%a6),%d0354        lsl.w   #2,%d0355        cmp.l   (%a0,%d0.w),%d1356        bhi.s   7f357        exg     %a5,%a6                 | the second division's winner is better3587:      lea     SEEDS+8,%a1             | East359        tst.w   %d3360        beq.s   8f361        lea     SEEDS,%a1               | West3628:      move.b  (%a5),(%a1)+            | better winner vs WC2363        move.b  %d7,(%a1)+364        move.b  1(%a5),(%a1)+           | 2nd vs 3rd365        move.b  2(%a5),(%a1)+366        move.b  (%a6),(%a1)+            | other winner vs WC1367        move.b  %d6,(%a1)+368        move.b  1(%a6),(%a1)+369        move.b  2(%a6),(%a1)+370        addq.w  #1,%d3371        cmpi.w  #2,%d3372        blt.w   6b373        moveq   #0,%d0374        bra.s   99f37590:     moveq   #-1,%d037699:     movem.l (%sp)+,%d1-%d7/%a0-%a6377        tst.w   %d0378        rts379380| pick: the best team not taken yet in division d3 (d5 = 0) or conference d3 (d5 = 1; 0 East, 1 West) -> d0, taken381pick:   movem.l %d1-%d4/%a0-%a2,-(%sp)382        lea     KEYS,%a0383        lea     TAKEN,%a1384        lea     divs,%a2385        moveq   #-1,%d0                 | best team386        moveq   #0,%d1                  | best key387        moveq   #0,%d2                  | team3881:      tst.b   (%a1,%d2.w)389        bne.s   3f390        moveq   #0,%d4391        move.b  (%a2,%d2.w),%d4392        tst.w   %d5393        beq.s   2f394        lsr.w   #1,%d4                  | conference3952:      cmp.w   %d3,%d4396        bne.s   3f397        move.w  %d2,%d4398        lsl.w   #2,%d4399        cmp.l   (%a0,%d4.w),%d1400        bcc.s   3f401        move.l  (%a0,%d4.w),%d1402        move.w  %d2,%d04033:      addq.w  #1,%d2404        cmpi.w  #32,%d2405        blt.s   1b406        tst.w   %d0407        bmi.s   4f408        move.b  #1,(%a1,%d0.w)4094:      movem.l (%sp)+,%d1-%d4/%a0-%a2410        rts411412| division per team (ANA..WPG): 0 Atlantic, 1 Metropolitan, 2 Central, 3 Pacific (conference = division / 2)413divs:   .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,2414        .even415