season/season.s

Download file

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

1| Season mode, step 1: record the result of every finished game in battery RAM (SRAM).2| Hooked at $7C2E (jsr $FF88E) on the game-over path ($7C16), so it runs once per finished game.3|4| SRAM block at logical offset $1000 (free in the hack), copied to/from the RAM buffer $FFE000:5|   +0  'SESN'          magic6|   +4  word            games recorded7|   +6  word            your team + 1 (0 = no season yet; set by the first Regular Season game a human plays)8|   +8  word            your games played (= index of the next game in the schedule)9|   +10 word            season length (84, 31 or 8; legacy saves may keep 82)10|   +12 word            1 = New Season, 2 = New Season Light, 3 = New Season Mini; the next game starts that season11|   +14 word            2 = player stats block valid, 3 = player and goalie stats valid (format 3)12| Player stats: SRAM offset $1220, 32 teams x 25 roster slots (1..25; slot 0 is always a goalie) x13| (goals byte, assists byte, shots word) = 3200 bytes, team stride 100.14|   +16 + 16*team       per team (0..31): GP, W, L, OTL, GF, GA, T, OTW   all words (W includes OTW; OTW from 2026-10-22)15| Goalie stats: SRAM offset $E20 (free in the hack: it uses $0-$E1F and $1EF6-$1FFF), 32 teams x 3 goalies (roster16| index 0..2) x 5 bytes: GP, W, then GA (12 bits) and SA (12 bits) packed big-endian = 480 bytes.17| The game's per-slot arrays hold the goalie in slot 0: goals +$B4 = goals against, shots +$E8 = shots against.18| The goalie in net is line 1's G in the team block (+$16A, 1-based roster index).1920        .equ    SRAM_OFF, 0x100021        .equ    BUF,      0xFFE00022        .equ    NBYTES,   16+32*1623        .equ    MAGIC,    0x5345534E24        .equ    SRAM_RD,  0x1A244        | d0 offset, d1 count, a0 dest25        .equ    SRAM_WR,  0x1A1E4        | d0 offset, d1 count, a0 source26        .equ    SRAM_SUM, 0x1A206        | recompute + write the hack's checksum27        .equ    HOME_T,   0xFFC331       | team index (byte)28        .equ    AWAY_T,   0xFFC33329        .equ    HOME_G,   0xFFC6DA       | goals (word)30        .equ    AWAY_G,   0xFFCA3E31        .equ    PERIOD,   0xFFC466       | 0..2 regulation, 3 overtime32        .equ    STATE,    0xFFC2EA       | bit 4 set = intermission highlight / replay, not a real game33        .equ    PLAYMODE, 0xFFD048       | 0 = Regular Season34        .equ    PLAYERS,  0xFFD04A       | 0 Demo, 1 One - Home, 2 One - Visitor, ...35        .equ    SUMBUF,   0xFFE300       | 2 checksum bytes ($1FFE = ~sum, $1FFF = sum)36        .equ    LIST,     0xFFE310       | 32 bytes: teams to pair up37        .equ    PSTAT_OFF,0x122038        .equ    PSTAT_N,  320039        .equ    ROWBUF,   0xFFF100       | one team's player row (100 bytes); $FFF000-$FFF005 are the blue-line variables40        .equ    DELTA,    0xFFF0F0       | byte: checksum change of the player rows written so far41        .equ    ROWOFF,   0x2E2000       | postats.s +0 / +4 (experimental builder installs it)42        .equ    GKOFF,    0x2E200443        .equ    POGAME,   0xFFF0D2       | byte: this save is a season playoff game (no round, no league; jdc r18)44        .equ    ROWLEN,   10045        .equ    GOALS,    0xB4           | per-player goals in the game's team stat blocks ($C6CE home, $CA32 away)46        .equ    ASSISTS,  0xCE47        .equ    SHOTS,    0xE848        .equ    RND,      0x11086        | d0 = n -> d0 = 0..n-1, other registers kept49        .equ    GK_OFF,   0xE2050        .equ    GK_N,     48051        .equ    SHOTSV,   0xFFF0F2       | word: shots of the last dist call52        .equ    GKREC,    0xFFF0F4       | 5 bytes: one goalie record53        .equ    OTF,      0xFFF0FA       | word: simulated game went to overtime54        .equ    GKBUF,    0xFFF200       | 480 bytes, only while clearing (the team screen's RAM, free during a game)55        .equ    LINEG,    0x16A          | team block: line 1, G (1-based roster index)5657        .equ    PORG,     0x2FC800       | playoffs.s58        .include "features.inc"59        .text60        .globl  _start61_start:62        jsr     0xFF88E                 | the instruction we replaced63        movem.l %d0-%d7/%a0-%a6,-(%sp)64        btst    #4,STATE                | highlights from other games use the same game-over path65        bne.w   done66        tst.w   PLAYMODE                | only Regular Season games count67        beq.s   6f68        cmpi.w  #4,PLAYMODE             | a playoff game: playoffs.s notes it (the season's playoffs go on)69        beq.w   done70        jsr     PORG+32                 | d0 = 0: one of the season's playoff games (checked before played)71        move.w  %d0,-(%sp)72        jsr     PORG+2473        tst.w   (%sp)+74        bne.w   done75        lea     BUF,%a0                 | jdc r18: playoff goals/assists/shots/goalies also go into the season's76        move.l  #SRAM_OFF,%d0           | player rows (whole-run statistics); team rows, rounds and the league stay77        move.l  #NBYTES,%d178        jsr     SRAM_RD79        bsr.w   blocksum80        move.b  %d7,%d681        clr.b   DELTA82        st      POGAME83        lea     BUF,%a084        bra.w   save856:86        jsr     0x2FD608                 | capture the chosen round before a new season clears the header8788        lea     BUF,%a0                 | read the season block89        move.l  #SRAM_OFF,%d090        move.l  #NBYTES,%d191        jsr     SRAM_RD92        bsr.w   blocksum                | d7 = 8-bit sum of the block as stored93        move.b  %d7,%d694        lea     BUF,%a095        clr.w   %d5                     | pending season type (0/1 = 84 games, 2 = 31 games, 3 = 8 games)96        cmpi.l  #MAGIC,(%a0)97        beq.s   1f98        move.w  #NBYTES/2-1,%d2         | first game ever: clear and stamp the block99        movea.l %a0,%a11002:      clr.w   (%a1)+101        dbra    %d2,2b102        move.l  #MAGIC,(%a0)1031:      move.w  12(%a0),%d5104        tst.w   %d5                     | a new season was chosen in the menu105        beq.s   3f106        move.w  #NBYTES/2-1,%d2107        movea.l %a0,%a11084:      clr.w   (%a1)+109        dbra    %d2,4b110        move.l  #MAGIC,(%a0)1113:      clr.b   DELTA112        cmpi.w  #3,14(%a0)              | player + goalie blocks in this format yet?113        beq.s   have114        cmpi.w  #2,14(%a0)              | players only (before goalie stats): keep them, start the goalie table115        bne.s   5f116        bsr.w   gkclear117        bra.s   have1185:      bsr.w   clearall                | otherwise clear everything (all 32 rows)119have:120        moveq   #0,%d0121        moveq   #0,%d1122        move.b  HOME_T,%d0123        move.b  AWAY_T,%d1124        cmpi.w  #31,%d0125        bhi.w   done126        cmpi.w  #31,%d1127        bhi.w   done128        move.w  6(%a0),%d2              | your team + 1129        bne.s   haveuser130        move.w  PLAYERS,%d3             | no season yet: start one with the team a human plays131        beq.s   record                  | demo / Two - Head to Head: just record the game132        cmpi.w  #4,%d3133        beq.s   record134        cmpi.w  #2,%d3                  | One - Visitor: the away team; One - Home, Two / Three /135        bne.s   homeuser                | Four - Teammates (r16 4-Way Play): the home team136        move.w  %d1,%d2137        bra.s   newseason138homeuser:139        move.w  %d0,%d2140newseason:141        jsr     PORG+16                 | playoffs.s: the playoffs may start again at the end of this season142        addq.w  #1,%d2143        move.w  %d2,6(%a0)144        clr.w   8(%a0)145        move.w  #84,10(%a0)146        cmpi.w  #3,%d5147        bne.s   8f148        move.w  #MINI_GAMES,10(%a0)149        bra.s   7f1508:      cmpi.w  #2,%d5151        bne.s   7f152        move.w  #31,10(%a0)1537:154        bsr.w   clearall155        bra.s   counted156haveuser:157        subq.w  #1,%d2158        cmp.w   %d0,%d2159        beq.s   9f160        cmp.w   %d1,%d2161        bne.w   done                    | not your game: not part of the season1629:      move.w  8(%a0),%d2              | jdc r18: a finished season (missed playoffs) takes no163        cmp.w   10(%a0),%d2             | more games (a real Start Game made it 45/31)164        bcc.w   done165counted:166        addq.w  #1,8(%a0)167record:168        addq.w  #1,4(%a0)169        lsl.w   #4,%d0170        lsl.w   #4,%d1171        lea     16(%a0,%d0.w),%a1       | home row172        lea     16(%a0,%d1.w),%a2       | away row173        move.w  HOME_G,%d2174        move.w  AWAY_G,%d3175        addq.w  #1,(%a1)                | GP176        addq.w  #1,(%a2)177        add.w   %d2,8(%a1)              | GF / GA178        add.w   %d3,10(%a1)179        add.w   %d3,8(%a2)180        add.w   %d2,10(%a2)181        cmp.w   %d3,%d2182        beq.s   tie183        bhi.s   homewin184        addq.w  #1,2(%a2)               | away win185        movea.l %a1,%a3                 | loser = home186        movea.l %a2,%a4                 | winner = away187        bra.s   loser188homewin:189        addq.w  #1,2(%a1)190        movea.l %a2,%a3191        movea.l %a1,%a4192loser:193        cmpi.w  #3,PERIOD194        bne.s   reg195        addq.w  #1,6(%a3)               | overtime loss196        addq.w  #1,14(%a4)              | overtime win197        bra.s   save198reg:    addq.w  #1,4(%a3)               | regulation loss199        bra.s   save200tie:    addq.w  #1,12(%a1)201        addq.w  #1,12(%a2)202save:203        bsr.w   addreal                 | goals and assists from this game204        bsr.w   gkreal                  | and both goalies205        jsr     0x2EE000                | and penalty minutes (pim.s, 2026-10-28)206        tst.b   POGAME207        bne.s   1f208        jsr     0x2FD60C                 | mark this round used and persist the next unplayed choice209        bsr.w   simleague               | the other 30 teams play one game each2101:      clr.b   POGAME211        lea     BUF,%a0212        move.l  #SRAM_OFF,%d0213        move.l  #NBYTES,%d1214        jsr     SRAM_WR215        | update the hack's checksum without touching RAM $FF0000 (its own routine reloads all 8 KB there,216        | which corrupts the replay data and crashed the post-game screens)217        bsr.w   blocksum                | d7 = new sum of the block218        add.b   DELTA,%d7               | + the change of the player rows (already written)219        lea     SUMBUF,%a0220        move.l  #0x1FFE,%d0221        moveq   #2,%d1222        jsr     SRAM_RD223        lea     SUMBUF,%a0224        move.b  1(%a0),%d0              | old total225        sub.b   %d6,%d0226        add.b   %d7,%d0227        move.b  %d0,1(%a0)228        not.b   %d0229        move.b  %d0,(%a0)230        move.l  #0x1FFE,%d0231        moveq   #2,%d1232        jsr     SRAM_WR233done:234        movem.l (%sp)+,%d0-%d7/%a0-%a6235        rts236237| d7.b = 8-bit sum of the NBYTES bytes in BUF238blocksum:239        lea     BUF,%a1240        moveq   #0,%d7241        move.w  #NBYTES-1,%d2242bs:     add.b   (%a1)+,%d7243        dbra    %d2,bs244        rts245246| ---- simulate one game for every team except the two that just played247| Mini and Light use a circle schedule: in round k, your team faces sched[k], and the248| other 30 pair as sched[k+i] vs sched[k-i] (indices modulo 31). Across 31249| rounds every unordered pair meets once. Mini chooses eight distinct rounds.250| The full mode (84 new / 82 legacy) keeps its shuffle for the other clubs.251| Goals per team: 8 tries, each scores if rnd(256) < 60 + strength/4.252simleague:253        movem.l %d0-%d7/%a0-%a4,-(%sp)254        lea     LIST,%a2255        cmpi.w  #MINI_GAMES,BUF+10256        .if WITH_DIVISION_MINI257        bne.s   not_mini_round258        move.w  0xFFF00C,%d5259        jsr     0x2DBE04                | all four divisions, excluding the real fixture260        bmi.w   slrandom                | captured legacy match: pair all remaining clubs once261        bra.w   sl4262not_mini_round:263        .else264        beq.s   slcircle265        .endif266        cmpi.w  #31,BUF+10267        bne.s   slrandom268slcircle:269        move.w  BUF+6,%d4               | your team + 1270        subq.w  #1,%d4271        move.w  0xFFF00C,%d5             | chosen round, captured before recording this match272        moveq   #0,%d6                  | list position273        moveq   #1,%d7                  | i = 1..15274slpair: move.w  %d5,%d0275        add.w   %d7,%d0276        cmpi.w  #31,%d0277        blt.s   1f278        subi.w  #31,%d02791:      lea     sched,%a0280        moveq   #0,%d1281        move.b  (%a0,%d0.w),%d1282        add.w   %d4,%d1283        andi.w  #31,%d1284        move.b  %d1,(%a2,%d6.w)285        addq.w  #1,%d6286        move.w  %d5,%d0287        sub.w   %d7,%d0288        bpl.s   2f289        addi.w  #31,%d02902:      moveq   #0,%d1291        move.b  (%a0,%d0.w),%d1292        add.w   %d4,%d1293        andi.w  #31,%d1294        move.b  %d1,(%a2,%d6.w)295        addq.w  #1,%d6296        addq.w  #1,%d7297        cmpi.w  #16,%d7298        blt.s   slpair299        bra.w   sl4300slrandom:301        moveq   #0,%d4302        moveq   #0,%d5303        move.b  HOME_T,%d4304        move.b  AWAY_T,%d5305        moveq   #0,%d0306        moveq   #0,%d6                  | count307sl1:    cmp.b   %d4,%d0308        beq.s   sl2309        cmp.b   %d5,%d0310        beq.s   sl2311        move.b  %d0,(%a2,%d6.w)312        addq.w  #1,%d6313sl2:    addq.w  #1,%d0314        cmpi.w  #32,%d0315        blt.s   sl1316        | shuffle (Fisher-Yates)317        move.w  %d6,%d7318        subq.w  #1,%d7319sl3:    tst.w   %d7320        ble.s   sl4321        move.w  %d7,%d0322        addq.w  #1,%d0323        jsr     RND                     | 0..i324        move.b  (%a2,%d7.w),%d1325        move.b  (%a2,%d0.w),(%a2,%d7.w)326        move.b  %d1,(%a2,%d0.w)327        subq.w  #1,%d7328        bra.s   sl3329sl4:    moveq   #0,%d7                  | pair index330sl5:    move.w  %d7,%d0331        addq.w  #1,%d0332        cmp.w   %d6,%d0333        bge.w   sldone334        moveq   #0,%d4335        moveq   #0,%d5336        move.b  (%a2,%d7.w),%d4         | team A337        move.b  1(%a2,%d7.w),%d5        | team B338        move.w  %d4,%d0339        bsr.w   goals340        move.w  %d0,%d2                 | goals A341        move.w  %d5,%d0342        bsr.w   goals343        move.w  %d0,%d3                 | goals B344        lea     BUF+16,%a0345        move.w  %d4,%d0346        lsl.w   #4,%d0347        lea     (%a0,%d0.w),%a1348        move.w  %d5,%d0349        lsl.w   #4,%d0350        lea     (%a0,%d0.w),%a3351        moveq   #0,%d1                  | overtime flag352        cmp.w   %d3,%d2353        bne.s   sl6354        moveq   #1,%d1                  | tie: one goal in overtime, coin flip355        moveq   #2,%d0356        jsr     RND357        tst.w   %d0358        beq.s   sl7359        addq.w  #1,%d2360        bra.s   sl6361sl7:    addq.w  #1,%d3362sl6:    move.w  %d1,OTF                 | (d1 is the goals argument of dist below)363        move.w  %d4,%d0                 | scorers, assists and shots for both teams (final score, overtime included)364        move.w  %d2,%d1365        bsr.w   dist366        move.w  SHOTSV,-(%sp)           | A's shots367        move.w  %d5,%d0368        move.w  %d3,%d1369        bsr.w   dist370        movem.l %d0-%d7,-(%sp)          | goalies: A faces B's goals and shots, B faces A's371        moveq   #0,%d6372        cmp.w   %d3,%d2373        bls.s   1f374        moveq   #1,%d63751:      move.w  %d4,%d0376        move.w  %d3,%d1377        move.w  SHOTSV,%d2378        move.w  %d6,%d3379        bsr.w   gksim380        movem.l (%sp),%d0-%d7381        moveq   #0,%d6382        cmp.w   %d2,%d3383        bls.s   2f384        moveq   #1,%d63852:      move.w  %d5,%d0386        move.w  %d2,%d1387        move.w  32(%sp),%d2388        move.w  %d6,%d3389        bsr.w   gksim390        movem.l (%sp)+,%d0-%d7391        addq.l  #2,%sp392        addq.w  #1,(%a1)393        addq.w  #1,(%a3)394        add.w   %d2,8(%a1)395        add.w   %d3,10(%a1)396        add.w   %d3,8(%a3)397        add.w   %d2,10(%a3)398        cmp.w   %d3,%d2399        bhi.s   sl8400        addq.w  #1,2(%a3)               | B won401        movea.l %a1,%a4                 | a4 = loser, a0 = winner402        movea.l %a3,%a0403        bra.s   sl9404sl8:    addq.w  #1,2(%a1)               | A won405        movea.l %a3,%a4406        movea.l %a1,%a0407sl9:    tst.w   OTF408        beq.s   sl10409        addq.w  #1,14(%a0)              | overtime win410        addq.w  #1,6(%a4)411        bra.s   sl11412sl10:   addq.w  #1,4(%a4)413sl11:   addq.w  #2,%d7414        bra.w   sl5415sldone: movem.l (%sp)+,%d0-%d7/%a0-%a4416        rts417418| d0 = team -> d0 = goals419goals:  movem.l %d1-%d3/%a0,-(%sp)420        lea     strength,%a0421        moveq   #0,%d2422        move.b  (%a0,%d0.w),%d2423        lsr.w   #2,%d2424        addi.w  #60,%d2                 | chance out of 256425        moveq   #0,%d1                  | goals426        bsr.w   lenix                   | tries follow Per. Length: 4/6/8/16 for 5/7/10/20 min427        lea     tries,%a0               | (measured from CPU-vs-CPU games, 2026-10-25)428        move.b  (%a0,%d3.w),%d3429        ext.w   %d3430        subq.w  #1,%d3431g1:     move.w  #256,%d0432        jsr     RND433        cmp.w   %d2,%d0434        bge.s   g2435        addq.w  #1,%d1436g2:     dbra    %d3,g1437        move.w  %d1,%d0438        movem.l (%sp)+,%d1-%d3/%a0439        rts440441| ---- player stats: SRAM rows of 100 bytes per team, slots 1..25 x (goals, assists, shots word)442| rowload: d0 = team -> ROWBUF, DELTA -= sum of the stored bytes443rowload:444        movem.l %d0-%d2/%a0-%a1,-(%sp)445        jsr     ROWOFF                  | d0 = SRAM offset (league $1220 + 100*team, or the playoff block, jdc r21)446        nop447        nop448        lea     ROWBUF,%a0449        moveq   #ROWLEN,%d1450        jsr     SRAM_RD451        bsr.w   rowsum452        sub.b   %d2,DELTA453        movem.l (%sp)+,%d0-%d2/%a0-%a1454        rts455| rowsave: d0 = team <- ROWBUF, DELTA += sum of the new bytes456rowsave:457        movem.l %d0-%d2/%a0-%a1,-(%sp)458        bsr.w   rowsum459        add.b   %d2,DELTA460        jsr     ROWOFF461        nop462        nop463        lea     ROWBUF,%a0464        moveq   #ROWLEN,%d1465        jsr     SRAM_WR466        movem.l (%sp)+,%d0-%d2/%a0-%a1467        rts468rowsum: lea     ROWBUF,%a1              | d2.b = sum of ROWBUF469        moveq   #0,%d2470        moveq   #ROWLEN-1,%d14711:      add.b   (%a1)+,%d2472        dbra    %d1,1b473        rts474| clearall: zero all 32 rows, mark the block valid (BUF+14 = 2)475clearall:476        movem.l %d0-%d1/%a1,-(%sp)477        moveq   #0,%d04781:      bsr.s   rowload479        lea     ROWBUF,%a1480        moveq   #ROWLEN/2-1,%d14812:      clr.w   (%a1)+482        dbra    %d1,2b483        bsr.s   rowsave484        addq.w  #1,%d0485        cmpi.w  #32,%d0486        blt.s   1b487        bsr.w   gkclear                 | and the goalie table (sets BUF+14 = 3)488        jsr     0x2EE004                | and the penalty minutes (pim.s)489        movem.l (%sp)+,%d0-%d1/%a1490        rts491492| ---- goalie stats (SRAM $E20, see the top) ----493| gkclear: zero the goalie table, BUF+14 = 3494gkclear:495        movem.l %d0-%d2/%a0-%a1,-(%sp)496        lea     GKBUF,%a0497        move.l  #GK_OFF,%d0498        move.l  #GK_N,%d1499        jsr     SRAM_RD500        lea     GKBUF,%a1501        move.w  #GK_N-1,%d15021:      move.b  (%a1),%d0503        sub.b   %d0,DELTA504        clr.b   (%a1)+505        dbra    %d1,1b506        lea     GKBUF,%a0507        move.l  #GK_OFF,%d0508        move.l  #GK_N,%d1509        jsr     SRAM_WR510        move.w  #3,BUF+14511        movem.l (%sp)+,%d0-%d2/%a0-%a1512        rts513514| gkput: d0 = team, d1 = goalie (roster index 0..2), d2 = goals against, d3 = shots against, d4 = 1 if his team won515gkput:  movem.l %d0-%d7/%a0-%a1,-(%sp)516        cmpi.w  #2,%d1517        bhi.w   9f518        move.w  %d2,%d6                 | GA519        mulu.w  #3,%d0520        add.w   %d1,%d0521        mulu.w  #5,%d0522        jsr     GKOFF                   | + $E20, or the playoff block's goalie records (jdc r21)523        move.l  %d0,%d7                 | SRAM offset of the record524        lea     GKREC,%a0525        moveq   #5,%d1526        jsr     SRAM_RD527        bsr.w   gksum528        sub.b   %d2,DELTA529        lea     GKREC,%a0530        addq.b  #1,(%a0)                | GP531        add.b   %d4,1(%a0)              | W532        moveq   #0,%d0                  | d0 = GA (12 bits)533        move.b  2(%a0),%d0534        lsl.w   #4,%d0535        moveq   #0,%d1536        move.b  3(%a0),%d1537        move.w  %d1,%d2538        lsr.w   #4,%d1539        or.w    %d1,%d0540        andi.w  #15,%d2                 | d2 = SA (12 bits)541        lsl.w   #8,%d2542        move.b  4(%a0),%d2543        add.w   %d6,%d0544        cmpi.w  #0xFFF,%d0545        bls.s   1f546        move.w  #0xFFF,%d05471:      add.w   %d3,%d2548        cmpi.w  #0xFFF,%d2549        bls.s   2f550        move.w  #0xFFF,%d25512:      move.w  %d0,%d1552        lsr.w   #4,%d1553        move.b  %d1,2(%a0)554        move.w  %d0,%d1555        lsl.w   #4,%d1556        move.w  %d2,%d5557        lsr.w   #8,%d5558        or.w    %d5,%d1559        move.b  %d1,3(%a0)560        move.b  %d2,4(%a0)561        bsr.w   gksum562        add.b   %d2,DELTA563        move.l  %d7,%d0564        lea     GKREC,%a0565        moveq   #5,%d1566        jsr     SRAM_WR5679:      movem.l (%sp)+,%d0-%d7/%a0-%a1568        rts569gksum:  lea     GKREC,%a1               | d2.b = sum of the 5 record bytes570        moveq   #0,%d2571        moveq   #4,%d15721:      add.b   (%a1)+,%d2573        dbra    %d1,1b574        rts575576| gksim: d0 = team, d1 = GA, d2 = SA, d3 = won -> the starter plays 4 games in 5, the backup the rest (gk.inc)577gksim:  movem.l %d0-%d4/%a0,-(%sp)578        move.w  %d3,%d4579        move.w  %d2,%d3580        move.w  %d1,%d2581        lea     gktab,%a0582        .if WITH_TRANSFERS583        move.l  %d0,-(%sp)584        lsl.w   #2,%d0585        jsr     0x23602C586        move.l  (%sp)+,%d0587        .endif588        move.w  %d0,%d1589        lsl.w   #2,%d1590        adda.w  %d1,%a0591        move.w  %d0,%d1592        moveq   #100,%d0593        jsr     RND594        exg     %d0,%d1                 | d0 = team, d1 = roll595        cmpi.w  #80,%d1596        bcs.s   1f597        moveq   #0,%d1598        move.b  1(%a0),%d1              | backup599        bra.s   2f6001:      moveq   #0,%d1601        move.b  (%a0),%d1               | starter6022:      bsr.w   gkput603        movem.l (%sp)+,%d0-%d4/%a0604        rts605606| gkreal: the goalies of the game just played (goalie in net = line 1 G; slot 0 = goals / shots against)607.if WITH_GK_SEASON_STATS608gkreal: jmp 0x2D8C80609.else610gkreal: movem.l %d0-%d4/%a1,-(%sp)611        movea.l #0xFFFFC6CE,%a1612        moveq   #0,%d0613        move.b  HOME_T,%d0614        moveq   #0,%d4615        move.w  HOME_G,%d1616        cmp.w   AWAY_G,%d1617        bls.s   1f618        moveq   #1,%d46191:      bsr.s   3f620        movea.l #0xFFFFCA32,%a1621        moveq   #0,%d0622        move.b  AWAY_T,%d0623        moveq   #0,%d4624        move.w  AWAY_G,%d1625        cmp.w   HOME_G,%d1626        bls.s   2f627        moveq   #1,%d46282:      bsr.s   3f629        movem.l (%sp)+,%d0-%d4/%a1630        rts6313:      moveq   #0,%d1632        move.b  LINEG(%a1),%d1633        subq.w  #1,%d1                  | 1-based -> roster index (0 = no goalie: -1, skipped by gkput)634        moveq   #0,%d2635        move.b  GOALS(%a1),%d2636        moveq   #0,%d3637        move.b  SHOTS(%a1),%d3638        bra.w   gkput639640.endif641642| add the goals/assists/shots of the game just played (home block $C6CE, away $CA32; slot 0 = team total, skipped)643addreal:644        movem.l %d0-%d3/%a0-%a2,-(%sp)645        moveq   #0,%d0646        move.b  HOME_T,%d0647        movea.l #0xFFFFC6CE,%a1648        bsr.s   1f649        moveq   #0,%d0650        move.b  AWAY_T,%d0651        movea.l #0xFFFFCA32,%a1652        bsr.s   1f653        movem.l (%sp)+,%d0-%d3/%a0-%a2654        rts6551:      bsr.w   rowload656        lea     ROWBUF,%a2657.if WITH_GK_SEASON_STATS658        lea     gktab,%a0659        .if WITH_TRANSFERS660        move.l  %d0,-(%sp)661        lsl.w   #2,%d0662        jsr     0x23602C663        move.l  (%sp)+,%d0664        .endif665        move.w  %d0,%d1666        lsl.w   #2,%d1667        moveq   #0,%d3668        move.b  2(%a0,%d1.w),%d3669.endif670        lea     GOALS(%a1),%a1671        moveq   #1,%d16722:673.if WITH_GK_SEASON_STATS674        cmp.w   %d3,%d1675        bhs.s   real_skater676        clr.l   (%a2)                   | goalie GA/SA must never become skater G/SOG677        bra.s   real_player_next678real_skater:679.endif680        moveq   #0,%d2681        move.b  (%a1,%d1.w),%d2682        add.b   %d2,(%a2)683        move.b  ASSISTS-GOALS(%a1,%d1.w),%d2684        add.b   %d2,1(%a2)685        move.b  SHOTS-GOALS(%a1,%d1.w),%d2686        add.w   %d2,2(%a2)687.if WITH_GK_SEASON_STATS688real_player_next:689.endif690        addq.l  #4,%a2691        addq.w  #1,%d1692        cmpi.w  #26,%d1693        blt.s   2b694        bra.w   rowsave695696| dist: d0 = team, d1 = goals -> scorer + up to two assists per goal, then the team's other shots697| (22-37 shots in all, each goal is a shot by its scorer). Weights from pweights.inc.698dist:   movem.l %d0-%d7/%a0-%a3,-(%sp)699        .if WITH_TRANSFERS700        lea     pw_goal,%a0701        lea     pw_ast,%a1702        jsr     0x236084703        .endif704        move.w  %d0,%d6705        move.w  %d1,%d7706        bsr.w   rowload707        lea     ROWBUF-4,%a3            | slot k is at ROWBUF + (k-1)*4708        bsr.w   lenix                   | shots this game: base + rnd(range) by Per. Length709        lea     shotb,%a0710        moveq   #0,%d0711        move.b  (%a0,%d3.w),%d0712        move.w  %d0,-(%sp)713        move.b  4(%a0,%d3.w),%d0714        jsr     RND715        add.w   %d0,(%sp)716        move.w  (%sp),SHOTSV717        bra.s   9f7181:      lea     pw_goal,%a0719        bsr.w   pick                    | d0 = scorer slot720        move.w  %d0,%d4721        lsl.w   #2,%d0722        addq.b  #1,(%a3,%d0.w)          | goal723        addq.w  #1,2(%a3,%d0.w)         | and a shot724        subq.w  #1,(%sp)725        moveq   #-1,%d5726        moveq   #1,%d3                  | up to two assists7272:      move.w  #100,%d0728        jsr     RND729        cmpi.w  #82,%d0730        bge.s   8f731        lea     pw_ast,%a0732        bsr.w   pick733        cmp.w   %d4,%d0734        beq.s   7f735        cmp.w   %d5,%d0736        beq.s   7f737        move.w  %d0,%d5738        lsl.w   #2,%d0739        addq.b  #1,1(%a3,%d0.w)         | assist7407:      dbra    %d3,2b7418:7429:      dbra    %d7,1b743        move.w  (%sp)+,%d7              | the rest of the shots744        bra.s   11f74510:     lea     pw_goal,%a0746        bsr.w   pick747        lsl.w   #2,%d0748        addq.w  #1,2(%a3,%d0.w)74911:     subq.w  #1,%d7750        bpl.s   10b751        move.w  %d6,%d0752        bsr.w   rowsave753        movem.l (%sp)+,%d0-%d7/%a0-%a3754        rts755| pick: a0 = weight table base, d6 = team -> d0 = slot (0..25), weighted756pick:757        .if WITH_TRANSFERS758        jmp     0x236078759        .endif760        movem.l %d1-%d3/%a0,-(%sp)761        move.w  %d6,%d1762        mulu.w  #28,%d1                 | per team: word total + 26 byte weights763        adda.w  %d1,%a0764        move.w  (%a0)+,%d0              | total765        jsr     RND                     | 0..total-1766        moveq   #0,%d17671:      moveq   #0,%d2768        move.b  (%a0,%d1.w),%d2769        sub.w   %d2,%d0770        bmi.s   2f771        addq.w  #1,%d1772        cmpi.w  #25,%d1773        blt.s   1b7742:      move.w  %d1,%d0775        movem.l (%sp)+,%d1-%d3/%a0776        rts777778| lenix: d3 = Per. Length index ($D050: 0=5 1=7 2=10 3=20 min); unknown -> 2 (the old 8-try model)779lenix:  move.w  0xFFD050,%d3780        cmpi.w  #3,%d3781        bls.s   1f782        moveq   #2,%d37831:      rts784tries:  .byte   4,6,8,16785shotb:  .byte   5,9,15,39               | shot base; mean goals/team 1.40/2.10/2.81/5.61 vs measured 1.32/1.93/2.82/5.70786        .byte   14,16,20,22             | shot range; mean 11.5/16.5/24.5/49.5 vs measured 11.7/16.8/24.8/49.5787        .even788789        .include "strength.inc"790        .include "pweights.inc"791        .include "gk.inc"792        .include "sched.inc"793