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