Release 2026-11-04-r2 · SHA256 d89db59f273e40999ad6a5b1b890379516a3c0a9ef0d0fe22bca8740d24176a5 · Click a line number for a direct link.
1 .ifndef WITH_REFINEMENTS2 .equ WITH_REFINEMENTS,03 .endif4| Optional additional shootout rules. Default Off. No normal-match frame hook.5| Native available skaters rotate before repeats; continuous full turns are misses.6| Full native participant loading, attempts, scoring and keeper paths remain native.7 .include "season-symbols.inc"8 .equ VALUE,0xFFFFF0469 .equ MAGIC,0xFFFFF82010 .equ HOME,0xFFFFF82211 .equ AWAY,0xFFFFF82612 .equ LIMIT,0xFFFFF82A13 .equ LASTACTOR,0xFFFFF82C14 .equ LASTDIR,0xFFFFF82E15 .equ ROTATION,0xFFFFF83216 .equ TEAMS,0xFFFFF83617 .equ INFO,0xFFFFF83E | packed roster counts5+5bits, keeper counts3+3bits18 .equ CHECK,0xFFFFF83A19 .equ INVERSE,0xFFFFF83C20 .text21 .globl _start22_start:23 bra.w capture24 bra.w setup25 bra.w spin26 bra.w fresh27 bra.w load28 bra.w put29 bra.w reset30 bra.w pick3132| D0=1 only for the shootout this block was captured from. No RNG or writes.33valid:34 moveq #0,%d035 cmpi.w #1,VALUE36 bne.s invalid37 cmpi.w #1,0xFFFFF09038 bne.s invalid39 btst #0,0xFFFFC2FA40 beq.s invalid41 cmpi.w #0x5355,MAGIC42 bne.s invalid43 move.l TEAMS,%d044 cmp.l 0xFFFFC330,%d045 bne.s invalid46 move.w CHECK,%d047 not.w %d048 cmp.w INVERSE,%d049 bne.s invalid50 bsr.w checksum51 cmp.w CHECK,%d052 bne.s invalid53 cmpi.w #1,LIMIT54 bcs.s invalid55 cmpi.w #26,LIMIT56 bhi.s invalid57 moveq #1,%d058 rts59invalid:60 moveq #0,%d061 rts6263| Eight static words, excluding actor plus two full16.16 mutable turn longs. D0 sum, A0/D1 scratch.64checksum:65 moveq #0,%d066 lea HOME,%a067 moveq #4,%d168sum_first:69 add.w (%a0)+,%d070 dbra %d1,sum_first71 lea TEAMS,%a072 moveq #1,%d173sum_second:74 add.w (%a0)+,%d075 dbra %d1,sum_second76 add.w INFO,%d077 rts7879| A2 real club stats. D0 eligible32-bit mask, D1 count, D2 roster size, D3 keepers.80| The native game has injury states -3/-4 but no NHL misconduct-type exclusion.81mask:82 move.l 0x1E(%a2),%d083 cmpi.l #0x200,%d084 bcs.w bad_mask85 cmpi.l #0x300000,%d086 bcc.w bad_mask87 move.l %d0,%d5 | require the actual current club header, not a stale foreign pointer88 lea 0xFFFFC330,%a089 cmpa.w #0xC6CE,%a290 beq.s keeper_team91 cmpa.w #0xCA32,%a292 bne.w bad_mask93 addq.w #2,%a094keeper_team:95 moveq #0,%d096 move.w (%a0),%d097 cmpi.w #31,%d098 bhi.w bad_mask99 lsl.w #2,%d0100 lea 0x30E,%a0101 cmp.l (%a0,%d0.w),%d5102 bne.w bad_mask103 lea GK_TAB,%a0104 .if WITH_TRANSFERS105 jsr 0x23602C106 .endif107 moveq #0,%d4108 move.b 2(%a0,%d0.w),%d4 | actual roster-derived keeper count, independent of historical header discrepancies109 cmpi.w #1,%d4110 bcs.w bad_mask111 cmpi.w #4,%d4112 bhi.w bad_mask113 jsr 0x9F9A114 cmpi.w #26,%d0115 bhi.w bad_mask116 cmp.w %d4,%d0117 bls.w bad_mask118 move.w %d0,%d5119 move.w %d4,%d3120 moveq #0,%d1121 moveq #0,%d2122mask_next:123 move.w %d3,%d0124 add.w %d0,%d0125 move.w 0x66(%a2,%d0.w),%d0126 cmpi.w #-3,%d0127 beq.s mask_skip128 cmpi.w #-4,%d0129 beq.s mask_skip130 bset %d3,%d2131 addq.w #1,%d1132mask_skip:133 addq.w #1,%d3134 cmp.w %d5,%d3135 bcs.s mask_next136 move.l %d2,%d0137 move.w %d5,%d2138 move.w %d4,%d3139 rts140bad_mask:141 moveq #0,%d0142 moveq #0,%d1143 moveq #0,%d2144 moveq #0,%d3145 rts146147capture:148 move.w %sr,-(%sp)149 cmpi.w #1,VALUE150 bne.w capture_restore151 movem.l %d0-%d7/%a0-%a6,-(%sp)152 clr.w MAGIC153 cmpi.w #1,0xFFFFF090154 bne.w capture_done155 btst #0,0xFFFFC2FA156 beq.w capture_done157 cmpi.w #31,0xFFFFC330158 bhi.w capture_done159 cmpi.w #31,0xFFFFC332160 bhi.w capture_done161 move.l 0xFFFFC330,TEAMS162 lea 0xFFFFC6CE,%a2163 bsr.w mask164 move.l %d0,HOME165 move.w %d2,INFO166 lsl.w #8,%d3167 lsl.w #2,%d3168 or.w %d3,INFO169 move.w %d1,%d6170 lea 0xFFFFCA32,%a2171 bsr.w mask172 move.l %d0,AWAY173 lsl.w #5,%d2174 or.w %d2,INFO175 lsl.w #8,%d3176 lsl.w #5,%d3177 or.w %d3,INFO178 cmp.w %d6,%d1179 bcc.s common_limit180 move.w %d1,%d6181common_limit:182 move.w %d6,LIMIT183 beq.s capture_done | degenerate/no eligible pool retains bounded native fallback184 move.w #-1,LASTACTOR185 clr.l LASTDIR186 clr.l ROTATION187 bsr.w checksum188 move.w %d0,CHECK189 not.w %d0190 move.w %d0,INVERSE191 move.w #0x5355,MAGIC192capture_done:193 movem.l (%sp)+,%d0-%d7/%a0-%a6194capture_restore:195 move.w (%sp)+,%sr196 rts197198| Public pure selector: D0 own attempt index, D1 side0/1 -> D0 roster/-1.199| All other registers preserved. No RNG, outcome, actor or attribute writes.200pick:201 movem.l %d1-%d7/%a0-%a6,-(%sp)202 move.w %d0,%d6203 move.w %d1,%d7204 bsr.w choose205 movem.l (%sp)+,%d1-%d7/%a0-%a6206 tst.w %d0207 rts208choose:209 cmpi.w #1,%d7210 bhi.w no_choice211 bsr.w valid212 tst.w %d0213 beq.w no_choice214 andi.l #0xFFFF,%d6215 divu.w LIMIT,%d6216 swap %d6217 andi.l #0xFFFF,%d6218 lea 0xFFFFD57A,%a0219 move.l HOME,%d2220 tst.w %d7221 beq.s preferred_ready222 lea 0xFFFFD588,%a0223 move.l AWAY,%d2224preferred_ready:225 moveq #0,%d5 | seen roster IDs, avoid duplicates in native preferred five226 moveq #4,%d4227preferred:228 move.w (%a0)+,%d0229 cmpi.w #25,%d0230 bhi.s preferred_skip231 btst %d0,%d2232 beq.s preferred_skip233 bset %d0,%d5234 bne.s preferred_skip235 tst.w %d6236 beq.s chosen237 subq.w #1,%d6238preferred_skip:239 dbra %d4,preferred240 moveq #0,%d0241bench:242 btst %d0,%d2243 beq.s bench_skip244 btst %d0,%d5245 bne.s bench_skip246 tst.w %d6247 beq.s chosen248 subq.w #1,%d6249bench_skip:250 addq.w #1,%d0251 cmpi.w #26,%d0252 bcs.s bench253no_choice:254 moveq #-1,%d0255chosen:256 rts257258setup:259 jsr 0xFC4C0 | all original setup/presentation/outputs first260 move.w %sr,-(%sp)261 cmpi.w #1,VALUE262 bne.s setup_restore263 movem.l %d0-%d7/%a0-%a6,-(%sp)264 move.w 0xFFFFD594,%d7265 cmpi.w #1,%d7266 bhi.s setup_done267 move.w %d7,%d0268 add.w %d0,%d0269 lea 0xFFFFF09C,%a0270 move.w (%a0,%d0.w),%d6271 bsr.w choose272 tst.w %d0273 bmi.s setup_done274 move.w %d0,0xFFFFD40A | native1592C loads this actual roster through15AA4275setup_done:276 movem.l (%sp)+,%d0-%d7/%a0-%a6277setup_restore:278 move.w (%sp)+,%sr279 rts280281fresh:282 move.w %sr,-(%sp)283 cmpi.w #1,VALUE284 bne.s fresh_restore285 movem.l %d0-%d7/%a0-%a6,-(%sp)286 bsr.w valid287 tst.w %d0288 beq.s fresh_done289 move.w #-1,LASTACTOR290 clr.l LASTDIR291 clr.l ROTATION292fresh_done:293 movem.l (%sp)+,%d0-%d7/%a0-%a6294fresh_restore:295 move.w (%sp)+,%sr296 rts297298| Called only within the protected pre-shot approach observer. D0=1 means miss.299| Native facing changes are sampled, not direction-button commands. Exact300| ambiguous half-turns reset the turn history; ordinary cuts/oscillations stay legal.301spin:302 movem.l %d1-%d7/%a0-%a6,-(%sp)303 bsr.w valid304 tst.w %d0305 beq.w spin_done306 btst #5,0xFFFFC2F2307 bne.w spin_legal308 move.w 0xFFFFD406,%d1309 cmpi.w #11,%d1310 bhi.w spin_legal311 move.w %d1,%d2312 lsl.w #7,%d2313 lea 0xFFFFB04A,%a0314 adda.w %d2,%a0315 tst.w 0x34(%a0)316 ble.w spin_legal317 move.l 0x54(%a0),%d2 | native108B0 updates the complete16.16 body angle318 cmpi.l #0x00080000,%d2319 bcc.w spin_legal320 cmp.w LASTACTOR,%d1321 beq.s spin_existing322 move.w %d1,LASTACTOR323 move.l %d2,LASTDIR324 clr.l ROTATION325 bra.s spin_legal326spin_existing:327 move.l %d2,%d3328 sub.l LASTDIR,%d3329 move.l %d2,LASTDIR330 cmpi.l #0x00040000,%d3331 ble.s lower_wrap332 subi.l #0x00080000,%d3333lower_wrap:334 cmpi.l #-0x00040000,%d3335 bge.s turn_step336 addi.l #0x00080000,%d3337turn_step:338 cmpi.l #0x00040000,%d3339 beq.s ambiguous | an exact half-turn has no observable rotation direction340 cmpi.l #-0x00040000,%d3341 beq.s ambiguous342 add.l %d3,ROTATION343 move.l ROTATION,%d1344 cmpi.l #0x00080000,%d1345 bge.s spin_miss346 cmpi.l #-0x00080000,%d1347 ble.s spin_miss348 bra.s spin_legal349ambiguous:350 clr.l ROTATION351spin_legal:352 moveq #0,%d0353 bra.s spin_done354spin_miss:355 moveq #1,%d0356spin_done:357 movem.l (%sp)+,%d1-%d7/%a0-%a6358 tst.w %d0359 rts360361record:362 lea 0x209A75,%a0 | native/Full/Light/Mini logical4D3A..4D41363 tst.w 0xFFFFF06C364 beq.s record_done365 move.w 0xFFFFF06A,%d0366 subq.w #1,%d0367 cmpi.w #2,%d0368 bhi.s record_done369 addq.w #1,%d0370 lsl.w #2,%d0371 adda.w %d0,%a0372record_done:373 rts374load:375 move.w %sr,-(%sp)376 movem.l %d0-%d1/%a0,-(%sp)377 .if WITH_REFINEMENTS378 move.w #1,VALUE379 .else380 clr.w VALUE381 .endif382 clr.w MAGIC383 bsr.s record384 moveq #0,%d0385 move.b (%a0),%d0386 move.w %d0,%d1387 andi.w #0xFE,%d1388 cmpi.w #0x74,%d1389 bne.s loaded390 not.b %d0391 cmp.b 2(%a0),%d0392 bne.s loaded393 not.b %d0394 andi.w #1,%d0395 move.w %d0,VALUE396loaded:397 .if WITH_REFINEMENTS398 move.w #1,VALUE | permanent user-selected rule; old saved Off cannot disable it399 .endif400 movem.l (%sp)+,%d0-%d1/%a0401 move.w (%sp)+,%sr402 rts403put:404 move.w %sr,-(%sp)405 movem.l %d0-%d1/%a0,-(%sp)406 bsr.w record407 moveq #0x74,%d0408 cmpi.w #1,VALUE409 bne.s write410 addq.w #1,%d0411write:412 move.b %d0,(%a0)413 not.b %d0414 move.b %d0,2(%a0)415 lea 0x208001,%a0416 moveq #0,%d0417 move.w #0x1FFD,%d1418sum:419 add.b (%a0),%d0420 addq.l #2,%a0421 dbra %d1,sum422 not.b %d0423 move.b %d0,(%a0)424 not.b %d0425 move.b %d0,2(%a0)426 movem.l (%sp)+,%d0-%d1/%a0427 move.w (%sp)+,%sr428 rts429reset:430 move.w 0xFFFFF06C,-(%sp)431 move.w #1,0xFFFFF06C432 .if WITH_REFINEMENTS433 move.w #1,VALUE434 .else435 clr.w VALUE436 .endif437 clr.w MAGIC438 bsr.w put439 move.w (%sp)+,0xFFFFF06C440 rts441