experimental/strict_so.s

Download file

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