Release 2026-11-04-r2 · SHA256 a238c4775e88bdb6afe65d9b3b9b307cb574a89305878e1006f0208fb9556ee6 · Click a line number for a direct link.
1 .ifndef WITH_REFINEMENTS2 .equ WITH_REFINEMENTS,03 .endif4| Optional reach21 and native save/rebound alternatives. Off is the default.5| All four native gameplay entry contracts preserve registers, SR and stack.6| Only a real shot release records provenance. Only its first saved loose contact7| chooses a new outcome. Native keeper animation, stats, pickup and physics remain.8 .equ VALUE,0xFFFFF0129 .equ SHOT,0xFFFFF01410 .equ ACTOR,0xFFFFF01611 .equ DISTANCE,0xFFFFF01812 .equ TRAFFIC,0xFFFFF01A13 .equ EVENT,0xFFFFF01C14 .equ VARIANT,0xFFFFF01E15 .text16 .globl _start17_start:18 bra.w shot19 bra.w reach20 bra.w decision21 bra.w velocity22 bra.w load23 bra.w put24 bra.w reset25 bra.w policy26 bra.w filter_sog27 bra.w accepted_pickup2829| Internal ordinary-play guard, D0=1/0; callers retain their whole ABI.30live:31 moveq #0,%d032 tst.w 0xFFFFD41233 bne.s live_done34 move.b 0xFFFFC2EA,%d035 andi.w #0x11,%d036 bne.s live_no37 move.b 0xFFFFC2EC,%d038 andi.w #0x81,%d039 bne.s live_no40 move.b 0xFFFFC2FA,%d041 andi.w #5,%d042 bne.s live_no43 btst #2,0xFFFFC2F244 bne.s live_no45 btst #3,0xFFFFC2F646 bne.s live_no47 moveq #1,%d048 rts49live_no:50 moveq #0,%d051live_done:52 rts5354shot:55 jsr 0x2FF300 | original blue-line RNG/distance/CCR, always first56 move.w %sr,-(%sp)57 cmpi.w #1,VALUE58 beq.s shot_enabled59 move.w (%sp)+,%sr60 rts61shot_enabled:62 movem.l %d0-%d7/%a0-%a6,-(%sp)63 clr.w SHOT64 clr.l EVENT65 bsr.w live66 tst.w %d067 beq.w shot_done68 tst.w 0x34(%a3)69 bmi.w shot_done70 move.w 0x52(%a3),%d071 cmpi.w #11,%d072 bhi.w shot_done73 move.w %d0,ACTOR74 move.w 0xFFFFF000,DISTANCE75 ble.w shot_done76 clr.w TRAFFIC77 move.w #264,%d678 btst #7,0x62(%a3)79 bne.s shot_end80 neg.w %d681shot_end:82 move.w 0x52(%a3),%d583 lea 0xFFFFB04A,%a084 moveq #11,%d785screen:86 tst.w 0x34(%a0)87 ble.s next_screen88 cmp.w 0x52(%a0),%d589 beq.s next_screen90 move.w (%a0),%d091 cmpi.w #24,%d092 bgt.s next_screen93 cmpi.w #-24,%d094 blt.s next_screen95 move.w %d6,%d096 sub.w 0x14(%a0),%d097 tst.w %d698 bpl.s screen_depth99 neg.w %d0100screen_depth:101 tst.w %d0102 bmi.s next_screen103 cmpi.w #48,%d0104 bgt.s next_screen105 cmpi.w #3,TRAFFIC106 bcc.s next_screen107 addq.w #1,TRAFFIC108next_screen:109 adda.w #128,%a0110 dbra %d7,screen111 move.w #0x4752,SHOT112shot_done:113 movem.l (%sp)+,%d0-%d7/%a0-%a6114 move.w (%sp)+,%sr115 rts116117reach:118 move.w %sr,-(%sp)119 cmpi.w #1,VALUE120 beq.s reach_enabled121 move.w (%sp)+,%sr122 bra.w reach_height123reach_enabled:124 movem.l %d0-%d7/%a0-%a6,-(%sp)125 bsr.w live126 tst.w %d0127 beq.s reach_done128 tst.w 0x34(%a2)129 bne.s reach_done130 cmpi.w #11,0x52(%a2)131 bhi.s reach_done132 btst #1,0xFFFFC2F8 | retain the native special radius12 override133 bne.s reach_done134 move.w #21,0xFFFFBF64135 move.l #441,0xFFFFBF66136 move.w #-21,0xFFFFBF6A137reach_done:138 movem.l (%sp)+,%d0-%d7/%a0-%a6139 move.w (%sp)+,%sr140reach_height:141 cmpi.w #15,0xFFFFB762 | displaced native height limit and flags142 jmp 0x1503A143144| Policy inputs: D0 roll0..99, D1 shot distance, D2 capped screen count.145| Outputs D0 category0catch,1corner,2short-rink,3long-rink,4slow-goal,5fast-goal.146| Experimental probabilities, never claimed as measured real-hockey frequencies.147policy:148 moveq #20,%d3 | long shots:20catch/40corner/15short/10long/10slow/5fast149 cmpi.w #160,%d1150 bcc.s distance_ready151 moveq #10,%d3 | close shots:10catch/40corner/15short/15long/15slow/5fast152 distance_ready:153 tst.w %d2154 beq.s catch_threshold155 subq.w #5,%d3 | traffic transfers5catch and5corner points to slow leaks156 catch_threshold:157 cmp.w %d3,%d0158 bcs.s caught159 addi.w #40,%d3160 tst.w %d2161 beq.s corner_threshold162 subq.w #5,%d3163 corner_threshold:164 cmp.w %d3,%d0165 bcs.s corner166 addi.w #15,%d3167 cmp.w %d3,%d0168 bcs.s short_rink169 cmpi.w #160,%d1170 bcc.s long_distance171 addi.w #15,%d3172 bra.s long_threshold173 long_distance:174 addi.w #10,%d3175 long_threshold:176 cmp.w %d3,%d0177 bcs.s long_rink178 cmpi.w #95,%d0179 bcs.s slow_goal180 moveq #5,%d0181 rts182 caught: moveq #0,%d0183 rts184 corner: moveq #1,%d0185 rts186 short_rink: moveq #2,%d0187 rts188 long_rink: moveq #3,%d0189 rts190 slow_goal: moveq #4,%d0191 rts192193decision:194 move.w %sr,-(%sp)195 cmpi.w #1,VALUE196 beq.s decision_enabled197 move.w (%sp)+,%sr198 bra.w native_compare199decision_enabled:200 movem.l %d0-%d7/%a0-%a6,-(%sp)201 clr.l EVENT202 bsr.w live203 tst.w %d0204 beq.w original_decision205 tst.w 0x34(%a2)206 bne.w original_decision207 tst.w 0xFFFFB7AA208 bpl.w original_decision209 cmpi.w #0x4752,SHOT210 bne.w original_decision211 move.w DISTANCE,%d0212 ble.w original_decision213 cmp.w 0xFFFFF000,%d0214 bne.w original_decision215 move.w ACTOR,%d0216 cmp.w 0xFFFFBED8,%d0217 bne.w original_decision218 cmp.w 0xFFFFBEDA,%d0 | a later pass or stick deflection is no longer this shot219 bne.w original_decision220 clr.w SHOT | consume the first eligible provenance, even for a slow native catch221 move.w 0xFFFFB772,%d1222 ext.l %d1223 bpl.s input_x224 neg.l %d1225input_x:226 move.w 0xFFFFB774,%d2227 ext.l %d2228 bpl.s input_y229 neg.l %d2230input_y:231 cmp.l %d2,%d1232 bcc.s input_max233 move.l %d2,%d1234input_max:235 cmpi.l #32766,%d1236 bls.s input_bounded237 move.l #32766,%d1238input_bounded:239 andi.w #0xFFFE,%d1240 cmpi.w #0x0800,%d1241 bcs.w original_decision | very slow pucks keep the native catch/rebound decision242 move.w %d1,%d4 | conservative speed cap; output L1 never exceeds input max243 move.w #100,%d0244 jsr 0x11086 | bounded native draw, only after a real eligible save245 move.w DISTANCE,%d1246 move.w TRAFFIC,%d2247 bsr.w policy248 move.w %d0,EVENT249 beq.s chosen_catch250 move.w #0x474C,SHOT | this untouched parry has already counted its SOG251 move.w ACTOR,%d1252 lsl.w #7,%d1253 lea 0xFFFFB04A,%a0254 adda.w %d1,%a0255 moveq #0,%d1256 move.b 0x66(%a0),%d1257 move.w %d1,TRAFFIC | pending state retains the credited roster instead of screen count258 moveq #2,%d0259 jsr 0x11086260 or.w %d4,%d0261 move.w %d0,VARIANT | even incoming speed cap, low bit is left/right variation262 movem.l (%sp)+,%d0-%d7/%a0-%a6263 move.w (%sp)+,%sr264 jmp 0x1555A | native detachment, cooldown, save phase and puck animation265chosen_catch:266 movem.l (%sp)+,%d0-%d7/%a0-%a6267 move.w (%sp)+,%sr268 jmp 0x15628 | native catch, ownership and co-op keeper control269original_decision:270 movem.l (%sp)+,%d0-%d7/%a0-%a6271 move.w (%sp)+,%sr272native_compare:273 cmp.w 0xFFFFB772,%d0274 blt.w native_rebound275 jmp 0x15604276native_rebound:277 jmp 0x1555A278279velocity:280 move.b %d0,0x28(%a3) | both displaced native stores, including their flags281 move.b %d1,0x2A(%a3)282 move.w %sr,-(%sp)283 cmpi.w #1,VALUE284 beq.s velocity_enabled285 move.w (%sp)+,%sr286 rts287velocity_enabled:288 movem.l %d0-%d7/%a0-%a6,-(%sp)289 move.w EVENT,%d4290 clr.w EVENT291 subq.w #1,%d4292 cmpi.w #4,%d4293 bhi.w velocity_done294 bsr.w live295 tst.w %d0296 beq.w velocity_done297 move.w #1,%d5 | defending net sign from actual keeper world position298 tst.w 0x14(%a2)299 bpl.s net_sign300 neg.w %d5301net_sign:302 moveq #1,%d6303 move.w VARIANT,%d3304 move.w %d3,%d2305 andi.w #0xFFFE,%d2306 cmpi.w #0x0800,%d2307 bcs.w velocity_done308 btst #0,%d3309 beq.s x_sign310 neg.w %d6311x_sign:312 tst.w %d4313 bne.s not_corner314 move.w #0x2000,%d0315 move.w #0x0800,%d1316 bra.s apply_vector317not_corner:318 cmpi.w #1,%d4319 bne.s not_short320 move.w #0x0800,%d0321 move.w #-0x1000,%d1322 bra.s apply_vector323not_short:324 cmpi.w #2,%d4325 bne.s not_long326 move.w #0x1400,%d0327 move.w #-0x2000,%d1328 bra.s apply_vector329not_long:330 cmpi.w #3,%d4331 bne.s fast_leak332 move.w #0x0100,%d0333 move.w #0x0C00,%d1334 cmpi.b #64,0x5E(%a2)335 bcc.s apply_vector336 move.b #64,0x5E(%a2)337 bra.s apply_vector338fast_leak:339 move.w #0x0200,%d0340 move.w #0x2000,%d1341 cmpi.b #24,0x5E(%a2)342 bcc.s apply_vector343 move.b #24,0x5E(%a2)344apply_vector:345 move.w %d1,%d3346 bpl.s desired_y347 neg.w %d3348desired_y:349 add.w %d0,%d3350 cmp.w %d3,%d2351 bcc.s signs352 mulu.w %d2,%d0353 divu.w %d3,%d0354 muls.w %d2,%d1355 divs.w %d3,%d1356signs:357 muls.w %d6,%d0358 muls.w %d5,%d1359 move.w %d0,0x28(%a3)360 move.w %d1,0x2A(%a3)361 clr.w 0x2C(%a3)362velocity_done:363 movem.l (%sp)+,%d0-%d7/%a0-%a6364 move.w (%sp)+,%sr365 rts366367record:368 lea 0x209A65,%a0 | native / Full / Light / Mini, logical4D32..39369 tst.w 0xFFFFF06C370 beq.s record_done371 move.w 0xFFFFF06A,%d0372 subq.w #1,%d0373 cmpi.w #2,%d0374 bhi.s record_done375 addq.w #1,%d0376 lsl.w #2,%d0377 adda.w %d0,%a0378record_done:379 rts380load:381 move.w %sr,-(%sp)382 movem.l %d0-%d1/%a0,-(%sp)383 .if WITH_REFINEMENTS384 move.w #1,VALUE385 .else386 clr.w VALUE387 .endif388 clr.l SHOT389 clr.l DISTANCE390 clr.l EVENT391 bsr.s record392 moveq #0,%d0393 move.b (%a0),%d0394 move.w %d0,%d1395 andi.w #0xFE,%d1396 cmpi.w #0x72,%d1397 bne.s loaded398 not.b %d0399 cmp.b 2(%a0),%d0400 bne.s loaded401 not.b %d0402 andi.w #1,%d0403 move.w %d0,VALUE404loaded:405 movem.l (%sp)+,%d0-%d1/%a0406 move.w (%sp)+,%sr407 rts408put:409 move.w %sr,-(%sp)410 movem.l %d0-%d1/%a0,-(%sp)411 bsr.w record412 moveq #0x72,%d0413 cmpi.w #1,VALUE414 bne.s write415 addq.w #1,%d0416write:417 move.b %d0,(%a0)418 not.b %d0419 move.b %d0,2(%a0)420 lea 0x208001,%a0421 moveq #0,%d0422 move.w #0x1FFD,%d1423sum:424 add.b (%a0),%d0425 addq.l #2,%a0426 dbra %d1,sum427 not.b %d0428 move.b %d0,(%a0)429 not.b %d0430 move.b %d0,2(%a0)431 movem.l (%sp)+,%d0-%d1/%a0432 move.w (%sp)+,%sr433 rts434reset:435 move.w 0xFFFFF06C,-(%sp)436 move.w #1,0xFFFFF06C437 .if WITH_REFINEMENTS438 move.w #1,VALUE439 .else440 clr.w VALUE441 .endif442 clr.l SHOT443 clr.l DISTANCE444 clr.l EVENT445 bsr.w put446 move.w (%sp)+,0xFFFFF06C447 rts448449450| Existing shootout.s normal-shot dispatch. A model parry already counted SOG.451| The same untouched puck entering that same club's goal must not add another.452| New releases, pickups, changed last touch, changed scorer and other clubs keep453| the complete native path. Goal/assist/GA bookkeeping is already native1496A.454filter_sog:455 move.w %sr,-(%sp)456 cmpi.w #1,VALUE457 beq.s filter_enabled458 move.w (%sp)+,%sr459 bra.w native_sog460filter_enabled:461 movem.l %d0-%d7/%a0-%a6,-(%sp)462 cmpi.w #0x474C,SHOT463 bne.w filter_original464 btst #0,0xFFFFC2F4465 beq.w filter_original466 bsr.w live467 tst.w %d0468 beq.w filter_original469 move.w DISTANCE,%d0470 ble.w filter_original471 tst.w 0xFFFFF000 | native body contact can clear distance without possession472 beq.s filter_distance473 cmp.w 0xFFFFF000,%d0474 bne.w filter_original475filter_distance:476 move.w ACTOR,%d0477 cmpi.w #11,%d0478 bhi.w filter_original479 cmp.w 0xFFFFBED8,%d0480 bne.w filter_original481 cmp.w 0xFFFFBEDA,%d0482 bne.w filter_original483 lsl.w #7,%d0484 lea 0xFFFFB04A,%a0485 adda.w %d0,%a0486 movea.w #0xC6CE,%a1487 btst #6,0x62(%a0)488 beq.s filter_side489 adda.w #0x364,%a1490filter_side:491 cmpa.l %a1,%a2492 bne.s filter_original493 move.w TRAFFIC,%d0494 cmpi.w #25,%d0495 bhi.s filter_original496 cmp.w 0x18(%a2),%d0497 bne.s filter_original498 clr.w SHOT499 bclr #4,0xFFFFC2EE500 bclr #3,0xFFFFC2FE | native completed goal-SOG gate, without duplicate increments501 movem.l (%sp)+,%d0-%d7/%a0-%a6502 move.w (%sp)+,%sr503 rts504filter_original:505 movem.l (%sp)+,%d0-%d7/%a0-%a6506 move.w (%sp)+,%sr507native_sog:508 btst #0,0xFFFFC2EA | exact original normal-shot dispatch509 beq.s live_sog510 jmp 0x15464511live_sog:512 jmp 0x12F3A513514| Universal native accepted possession entry. Body contacts do not reach here.515| Replay both displaced ownership instructions first, retaining exact native CCR.516accepted_pickup:517 move.w 0x52(%a2),%d0518 move.w %d0,0xFFFFB7AA519 move.w %sr,-(%sp)520 cmpi.w #1,VALUE521 bne.s pickup_done522 clr.w SHOT523pickup_done:524 move.w (%sp)+,%sr525 rts526