experimental/transfers_ui.s

Download file

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

1    .ifndef WITH_COSMETIC_UI2    .equ WITH_COSMETIC_UI,03    .endif4    .ifndef WITH_REFINEMENTS5    .equ WITH_REFINEMENTS,06    .endif7| Actual preseason modal. Native controller input and native font/canvas.8| Persistent transactions use the independently checked234000 engine.9| WorkE000..E7FF, speculativeE800..EFFF. Modal-only state/textF100..F1FF,10| free-agent ownership bitsetF200..F267. Rebuild native menu context on exit.11    .equ WORK,0xFFFFE00012    .equ CLUB,0xFFFFF10013    .equ SCREEN,0xFFFFF10214    .equ SEL,0xFFFFF10415    .equ SOURCE,0xFFFFF10616    .equ LEAGUE,0xFFFFF10817    .equ ERROR,0xFFFFF10A18    .equ COUNT,0xFFFFF10C19    .equ PAGE,0xFFFFF10E20    .equ UID,0xFFFFF11021    .equ ENABLED,0xFFFFF11222    .equ TEXT,0xFFFFF16023    .equ USED,0xFFFFF20024    .equ OVR_SORTED,0x23BA0025    .equ POSX,0xFFFFB02826    .equ POSY,0xFFFFB02A27    .equ ATTR,0xFFFFB02C28    .equ VALUE,0xFFFFF85C29    .text30    .globl _start31_start:32    bra.w enter33    .if WITH_COSMETIC_UI34    bra.w money35    bra.w player_text36    .else37    .endif38enter:39    tst.w 0xFFFFF06C40    beq.w ordinary41    tst.w 0xFFFFF84C42    bne.w ordinary43    cmpi.l #0x5345534E,0xFFFFE3E044    bne.s empty_header45    tst.w 0xFFFFE3E846    bne.w ordinary47    bra.s eligible_header48empty_header:49    cmpi.w #2,0xFFFFE3F0          | Fresh native boot has no SESN header yet.50    bne.w ordinary51eligible_header:52    jsr 0x25400053    move.w VALUE,ENABLED54    move.w 0xFFFFF06A,LEAGUE55    move.w 0xFFFFD04C,CLUB56    cmpi.w #31,CLUB57    bhi.w ordinary58    tst.w ENABLED59    beq.s load_record60    jsr 0x2FC004                   | Native canvas writes E36A: BEFORE work load.61load_record:62    move.w LEAGUE,%d063    lea WORK,%a064    jsr 0x23401865    tst.l %d066    bmi.w load_error67    bne.s loaded68    tst.w ENABLED69    beq.w ordinary70    lea 0x238000,%a071    lea WORK,%a172    move.w #511,%d073initial_copy:74    move.l (%a0)+,(%a1)+75    dbra %d0,initial_copy76    move.w LEAGUE,%d077    move.b %d0,WORK+578    lea WORK,%a079    jsr 0x23400480    move.w %d0,WORK+1681    not.w %d082    move.w %d0,WORK+1883    bsr.w save84    beq.w load_error85loaded:86    moveq #0,%d087    move.b WORK+6,%d088    cmp.w ENABLED,%d089    beq.s enabled_ready90    move.w ENABLED,%d391    addq.w #3,%d392    move.w LEAGUE,%d093    lea WORK,%a094    moveq #0,%d495    jsr 0x23402096    cmpi.l #1,%d097    bne.w load_error98    bsr.w save99    beq.w load_error100enabled_ready:101    tst.w ENABLED102    beq.w continue_game103    clr.w SCREEN104    clr.w SEL105    clr.w SOURCE106    clr.w ERROR107    bsr.w redraw108    bclr #2,0xFFFFBF78109    move.w #0x18,0xFFFFBD26110    move.w #0x79,-(%sp)111    jsr 0x11156112release:113    jsr 0x175D8114    jsr 0x11340115    move.w %d3,-(%sp)             | D3 is held input; D0 includes idle direction8.116    jsr 0x11358117    or.w (%sp)+,%d3118    tst.w %d3119    bne.s release120    bra.w loop121load_error:122    | Fail closed. No invalid roster/funds are allowed into a native match.123    jsr MENU_FORCE124    jsr 0x236028125    moveq #1,%d0126    rts127ordinary:128    moveq #0,%d0129    rts130continue_game:131    jsr MENU_FORCE132    jsr 0x236028133    moveq #0,%d0134    rts135save:136    move.w LEAGUE,%d0137    lea WORK,%a0138    jsr 0x23401C139    tst.l %d0140    rts141keys:142    jsr 0x175D8143    jsr 0x11340144    move.w %d1,-(%sp)145    jsr 0x11358146    or.w (%sp)+,%d1147    rts148loop:149    bsr.s keys150    .if WITH_REFINEMENTS151    btst #4,%d1                    | Xbox A = native B: same back convention.152    bne.w back153    btst #7,%d1                    | Start finishes the root; backs out of lists.154    beq.s not_start155    tst.w SCREEN156    bne.w back157    bra.w ready158not_start:159    .endif160    btst #6,%d1161    bne.w back162    .if !WITH_REFINEMENTS163    btst #5,%d1164    bne.w back165    .endif166    btst #0,%d1167    bne.w up168    btst #1,%d1169    bne.w down170    tst.w SCREEN171    beq.s select_key172    cmpi.w #1,SCREEN173    bne.s select_key174    btst #2,%d1175    bne.w previous_source176    btst #3,%d1177    bne.w next_source178select_key:179    .if WITH_REFINEMENTS180    andi.w #0x20,%d1              | Xbox B = native C selects/buys/sells.181    .else182    andi.w #0x90,%d1              | Fresh Start or native pass B.183    .endif184    beq.s loop185    tst.w SCREEN186    bne.w trade187    move.w SEL,%d0188    cmpi.w #2,%d0189    beq.w ready190    addq.w #1,%d0191    move.w %d0,SCREEN192    clr.w SEL193    clr.w ERROR194    bra.w redraw_loop195back:196    tst.w SCREEN197    beq.w load_error198    clr.w SCREEN199    clr.w SEL200    clr.w ERROR201    bra.w redraw_loop202up:203    tst.w SEL204    beq.w loop205    subq.w #1,SEL206    bra.w redraw_loop207down:208    move.w COUNT,%d0209    subq.w #1,%d0210    cmp.w SEL,%d0211    bls.w loop212    addq.w #1,SEL213    bra.w redraw_loop214previous_source:215    subq.w #1,SOURCE216    bpl.s source_ready217    move.w #32,SOURCE218    bra.s source_ready219next_source:220    addq.w #1,SOURCE221    cmpi.w #33,SOURCE222    blo.s source_ready223    clr.w SOURCE224source_ready:225    clr.w SEL226    clr.w ERROR227    bra.w redraw_loop228trade:229    tst.w COUNT230    beq.w loop231    move.w SEL,%d0232    bsr.w uid_at233    cmpi.w #0xFFFF,%d0234    beq.w loop235    move.w %d0,UID236    move.w %d0,%d2237    move.w CLUB,%d1238    cmpi.w #2,SCREEN239    beq.s sell_action240    moveq #1,%d3241    bra.s perform_trade242sell_action:243    moveq #0,%d3244perform_trade:245    move.w LEAGUE,%d0246    moveq #0,%d4247    lea WORK,%a0248    jsr 0x234020249    cmpi.l #1,%d0250    bne.w refused251    bsr.w save252    beq.w load_error253    clr.w ERROR254    bra.w redraw_loop255refused:256    move.w #4,ERROR257    cmpi.w #1,SCREEN258    bne.w redraw_loop259    move.w CLUB,%d0260    cmp.w SOURCE,%d0261    bne.s not_owned262    move.w #5,ERROR263    bra.w redraw_loop264not_owned:265    mulu.w #52,%d0266    lea WORK+32,%a0267    adda.l %d0,%a0268    cmpi.w #0xFFFF,50(%a0)269    beq.s check_money270    move.w #2,ERROR271    bra.w redraw_loop272check_money:273    move.w UID,%d0274    jsr 0x234000275    move.w CLUB,%d1276    lsl.w #2,%d1277    lea WORK+1696,%a0278    cmp.l (%a0,%d1.w),%d0279    bls.w redraw_loop280    move.w #3,ERROR281    bra.w redraw_loop282ready:283    move.w LEAGUE,%d0284    moveq #2,%d3285    moveq #0,%d4286    lea WORK,%a0287    jsr 0x234020288    cmpi.l #2,%d0289    beq.w continue_game290    cmpi.l #1,%d0291    bne.w refused292    bsr.w save293    beq.w load_error294    bra.w continue_game295redraw_loop:296    bsr.w redraw297    bra.w loop298299| A2=actual source/user row, or free-agent map. No fictional placeholder slots.300row:301    move.w SOURCE,%d0302    cmpi.w #2,SCREEN303    bne.s source_row304    move.w CLUB,%d0305source_row:306    mulu.w #52,%d0307    lea WORK+32,%a2308    adda.l %d0,%a2309    rts310clear_membership:311    lea USED,%a0312    moveq #25,%d0313clear_used:314    clr.l (%a0)+315    dbra %d0,clear_used316    rts317build_used:318    bsr.s clear_membership319    lea WORK+32,%a1320    move.w #831,%d3321used_next:322    moveq #0,%d0323    move.w (%a1)+,%d0324    cmpi.w #831,%d0325    bhi.s used_skip326    move.w %d0,%d1327    lsr.w #3,%d0328    andi.w #7,%d1329    lea USED,%a0330    bset %d1,(%a0,%d0.w)331used_skip:332    dbra %d3,used_next333    rts334is_free:335    move.w %d0,%d1336    lsr.w #3,%d1337    move.w %d0,%d2338    andi.w #7,%d2339    lea USED,%a0340    btst %d2,(%a0,%d1.w)341    bne.s unavailable342    lea 0x239B80,%a0343    cmpi.b #0xFF,(%a0,%d0.w)344    rts345unavailable:346    cmp.w %d0,%d0                 | Z1 unavailable; Z0 means available.347    rts348count:349    clr.w COUNT350    tst.w SCREEN351    bne.s roster_count352    move.w #3,COUNT353    rts354roster_count:355    cmpi.w #1,SCREEN356    bne.s club_count357    cmpi.w #32,SOURCE358    bne.s club_count359    bsr.s build_used360    moveq #0,%d0361free_count:362    bsr.s is_free363    beq.s free_count_next364    addq.w #1,COUNT365free_count_next:366    addq.w #1,%d0367    cmpi.w #832,%d0368    blo.s free_count369    rts370club_count:371    bsr.w clear_membership372    bsr.w row373    moveq #25,%d3374club_count_next:375    moveq #0,%d0376    move.w (%a2)+,%d0377    cmpi.w #831,%d0378    bhi.s counted379    move.w %d0,%d1380    lsr.w #3,%d0381    andi.w #7,%d1382    lea USED,%a0383    bset %d1,(%a0,%d0.w)384    addq.w #1,COUNT385    dbra %d3,club_count_next386counted:387    rts388| Project the current source membership through a separate global OVR order.389| Never reorder WORK's persistent roster slots: native lineups/stat identities390| retain their role-aware layout. Equal OVR sorts by canonical UID.391uid_at:392    cmp.w COUNT,%d0393    bhs.s uid_missing394    move.w %d0,%d4395    moveq #0,%d5396    cmpi.w #1,SCREEN397    bne.s uid_scan_start398    cmpi.w #32,SOURCE399    bne.s uid_scan_start400    moveq #1,%d5401uid_scan_start:402    lea OVR_SORTED,%a3403    moveq #0,%d6404uid_scan:405    moveq #0,%d0406    move.w (%a3)+,%d0407    tst.w %d5408    beq.s uid_membership409    bsr.w is_free410    beq.s uid_scan_next411    bra.s uid_available412uid_membership:413    move.w %d0,%d1414    lsr.w #3,%d1415    move.w %d0,%d2416    andi.w #7,%d2417    lea USED,%a0418    btst %d2,(%a0,%d1.w)419    beq.s uid_scan_next420uid_available:421    subq.w #1,%d4422    bmi.s uid_done423uid_scan_next:424    addq.w #1,%d6425    cmpi.w #831,%d6426    blo.s uid_scan427uid_missing:428    move.w #0xFFFF,%d0429uid_done:430    rts431432redraw:433    bsr.w count434    move.w COUNT,%d0435    cmp.w SEL,%d0436    bhi.s selection_valid437    subq.w #1,%d0438    bpl.s clamp_selection439    moveq #0,%d0440clamp_selection:441    move.w %d0,SEL442selection_valid:443    move.w #0x8000,ATTR444    moveq #3,%d7445clear_line:446    move.w %d7,POSY447    move.w #1,POSX448    lea blank(%pc),%a1449    jsr 0x11BA4450    addq.w #1,%d7451    cmpi.w #27,%d7452    blo.s clear_line453    move.w #1,POSY454    move.w #10,POSX455    lea title(%pc),%a1456    jsr 0x11BA4457    move.w #3,POSY458    move.w #3,POSX459    lea budget(%pc),%a1460    jsr 0x11BA4461    move.w CLUB,%d0462    lsl.w #2,%d0463    lea WORK+1696,%a0464    move.l (%a0,%d0.w),%d0465    .if WITH_COSMETIC_UI466    lea TEXT,%a0467    bsr.w money468    .else469    lea TEXT+9,%a0470    moveq #7,%d1471    bsr.w decimal472    lea TEXT+2,%a0473    moveq #7,%d1474    bsr.w trim_zeroes475    move.w #9,TEXT476    .endif477    lea TEXT,%a1478    jsr 0x11BA4479    .if WITH_COSMETIC_UI480    move.w #4,POSY481    move.w #3,POSX482    lea club_label(%pc),%a1483    jsr 0x11BA4484    .else485    move.w #23,POSX486    .endif487    move.w CLUB,%d0488    bsr.w club_name489    tst.w SCREEN490    bne.w draw_roster491    moveq #0,%d7492draw_home:493    move.w %d7,%d0494    mulu.w #3,%d0495    addi.w #10,%d0496    move.w %d0,POSY497    move.w #8,POSX498    move.w #0x8000,ATTR499    cmp.w SEL,%d7500    bne.s home_colour501    move.w #0xE000,ATTR502home_colour:503    cmp.w SEL,%d7504    bne.s home_label505    move.w #6,POSX506    lea marker(%pc),%a1507    jsr 0x11BA4508    move.w #8,POSX509home_label:510    move.w %d7,%d0511    lsl.w #2,%d0512    lea home_labels(%pc),%a0513    movea.l (%a0,%d0.w),%a1514    jsr 0x11BA4515    addq.w #1,%d7516    cmpi.w #3,%d7517    blo.s draw_home518    bra.w draw_footer519draw_roster:520    move.w #5,POSY521    move.w #3,POSX522    lea selling(%pc),%a1523    cmpi.w #2,SCREEN524    beq.s roster_title525    lea buying(%pc),%a1526roster_title:527    jsr 0x11BA4528    move.w #6,POSY529    move.w #3,POSX530    move.w SOURCE,%d0531    cmpi.w #2,SCREEN532    bne.s source_name533    move.w CLUB,%d0534source_name:535    bsr.w club_name536    move.w #7,POSY537    move.w #3,POSX538    lea columns(%pc),%a1539    jsr 0x11BA4540    move.w SEL,%d0541    andi.w #0xFFF8,%d0542    move.w %d0,PAGE543    moveq #0,%d7544    tst.w COUNT545    bne.s draw_player546    move.w #10,POSY547    move.w #3,POSX548    lea empty(%pc),%a1549    jsr 0x11BA4550    bra.w draw_footer551draw_player:552    move.w PAGE,%d0553    add.w %d7,%d0554    cmp.w COUNT,%d0555    bhs.w draw_footer556    bsr.w uid_at557    bsr.w player_text558    move.w #0x8000,ATTR559    move.w PAGE,%d0560    add.w %d7,%d0561    cmp.w SEL,%d0562    bne.s player_colour563    move.w #0xE000,ATTR564player_colour:565    move.w %d7,%d0566    mulu.w #2,%d0567    addi.w #9,%d0568    move.w %d0,POSY569    move.w PAGE,%d0570    add.w %d7,%d0571    cmp.w SEL,%d0572    bne.s no_player_marker573    move.w #1,POSX574    lea marker(%pc),%a1575    jsr 0x11BA4576no_player_marker:577    move.w #3,POSX578    lea TEXT,%a1579    jsr 0x11BA4580    addq.w #1,%d7581    cmpi.w #8,%d7582    blo.s draw_player583draw_footer:584    move.w #0x8000,ATTR585    move.w #25,POSY586    move.w #1,POSX587    lea help(%pc),%a1588    .if WITH_REFINEMENTS589    tst.w SCREEN590    beq.s help_ready591    lea help_buy(%pc),%a1592    cmpi.w #1,SCREEN593    beq.s help_ready594    lea help_sell(%pc),%a1595help_ready:596    .endif597    jsr 0x25D004598    jsr 0x11BA4599    tst.w ERROR600    beq.s draw_done601    move.w #24,POSY602    move.w #1,POSX603    move.w ERROR,%d0604    subq.w #1,%d0605    lsl.w #2,%d0606    lea error_labels(%pc),%a0607    movea.l (%a0,%d0.w),%a1608    jsr 0x11BA4609draw_done:610    jsr 0x25D000611    rts612613club_name:614    cmpi.w #32,%d0615    bne.s actual_club616    lea free_agents(%pc),%a1617    jmp 0x11BA4618actual_club:619    lsl.w #2,%d0620    lea 0x30E,%a0621    movea.l (%a0,%d0.w),%a1622    adda.w 4(%a1),%a1623    jmp 0x11BA4624625player_text:626    move.w %d0,UID627    lea TEXT+2,%a0628    moveq #35,%d1629text_clear:630    move.b #32,(%a0)+631    dbra %d1,text_clear632    move.w #38,TEXT633    move.w UID,%d0634    lsl.w #2,%d0635    lea 0x238800,%a0636    movea.l (%a0,%d0.w),%a1637    move.w (%a1)+,%d1638    subq.w #3,%d1639    cmpi.w #19,%d1640    bls.s name_size641    moveq #19,%d1642name_size:643    lea TEXT+2,%a0644name_copy:645    move.b (%a1)+,%d2646    beq.s name_done647    move.b %d2,(%a0)+648    dbra %d1,name_copy649name_done:650    move.w UID,%d0651    lea 0x239B80,%a0652    moveq #0,%d1653    move.b (%a0,%d0.w),%d1654    lea roles(%pc),%a0655    move.b (%a0,%d1.w),TEXT+23656    lea 0x239EC0,%a0657    moveq #0,%d1658    move.b (%a0,%d0.w),%d1659    move.l %d1,%d0660    lea TEXT+27,%a0661    moveq #2,%d1662    .if WITH_COSMETIC_UI663    bsr.w decimal664    .else665    bsr.s decimal666    .endif667    lea TEXT+25,%a0668    moveq #2,%d1669    bsr.w trim_zeroes670    move.w UID,%d0671    jsr 0x234000672    .if WITH_COSMETIC_UI673    lea TEXT+48,%a0674    bsr.w money675    cmpi.w #10,%d1676    bhi.s price_overflow677    lea TEXT+38,%a0678    suba.w %d1,%a0679    lea TEXT+50,%a1680    subq.w #1,%d1681    bra.s price_copy682price_overflow:683    | Immutable OVR0..99 prices fit10. Fail visibly without touching adjacent684    | fields even if a diagnostic/corrupt price exceeds that declared bound.685    .else686    lea TEXT+33,%a0687    moveq #5,%d1688    bsr.s decimal689    .endif690    lea TEXT+28,%a0691    .if WITH_COSMETIC_UI692    lea money_overflow(%pc),%a1693    moveq #9,%d1694price_copy:695    move.b (%a1)+,(%a0)+696    dbra %d1,price_copy697    .else698    moveq #5,%d1699    bsr.w trim_zeroes700    .endif701    rts702    .if WITH_COSMETIC_UI703704    .else705    .endif706trim_zeroes:707    subq.w #2,%d1708trim_next:709    cmpi.b #48,(%a0)710    bne.s trim_done711    move.b #32,(%a0)+712    dbra %d1,trim_next713trim_done:714    rts715decimal:716    movem.l %d2-%d4,-(%sp)717    subq.w #1,%d1718decimal_digit:719    move.l %d0,%d2720    swap %d0721    andi.l #0xFFFF,%d0722    divu.w #10,%d0723    move.w %d0,%d3724    clr.w %d0725    move.w %d2,%d0726    divu.w #10,%d0727    move.w %d0,%d2728    swap %d0729    addi.b #48,%d0730    move.b %d0,-(%a0)731    move.w %d3,%d0732    swap %d0733    move.w %d2,%d0734    dbra %d1,decimal_digit735    movem.l (%sp)+,%d2-%d4736    rts737    .if WITH_COSMETIC_UI738| Unsigned32-bit internal units -> whole USD at1000 dollars per unit.739| No multiplication: group the units, then append .000. This supports even740| UINT32_MAX as $4.294.967.295.000 without overflowing32-bit arithmetic.741| D0=input preserved; A0=packet destination preserved (21bytes incl terminator).742| D1=payload length returned; all other registers preserved. No persistent RAM.743money:744    move.w %sr,-(%sp)745    movem.l %d0/%d2-%d6/%a0-%a2,-(%sp)746    move.l %d0,%d5747    movea.l %a0,%a2748    suba.w #12,%sp749    movea.l %sp,%a1750    lea 10(%sp),%a0751    moveq #10,%d1752    bsr.w decimal753    moveq #10,%d2754money_skip:755    cmpi.w #1,%d2756    beq.s money_digits757    cmpi.b #48,(%a1)758    bne.s money_digits759    addq.l #1,%a1760    subq.w #1,%d2761    bra.s money_skip762money_digits:763    lea 2(%a2),%a0764    move.b #36,(%a0)+765    tst.l %d5766    bne.s money_groups767    move.b #48,(%a0)+768    bra.s money_done769money_groups:770    move.l %d2,%d3771    divu.w #3,%d3772    swap %d3773    tst.w %d3774    bne.s money_copy775    moveq #3,%d3776money_copy:777    move.b (%a1)+,(%a0)+778    subq.w #1,%d2779    beq.s money_thousands780    subq.w #1,%d3781    bne.s money_copy782    move.b #46,(%a0)+783    moveq #3,%d3784    bra.s money_copy785money_thousands:786    move.b #46,(%a0)+787    move.b #48,(%a0)+788    move.b #48,(%a0)+789    move.b #48,(%a0)+790money_done:791    clr.b (%a0)792    move.l %a0,%d1793    sub.l %a2,%d1794    move.w %d1,(%a2)795    subq.w #2,%d1796    adda.w #12,%sp797    movem.l (%sp)+,%d0/%d2-%d6/%a0-%a2798    move.w (%sp)+,%sr799    rts800money_overflow: .ascii "$OVERFLOW "801    .even802club_label: .word 8803    .ascii "Club: "804805    .else806    .endif807roles: .ascii "GLCRFD"808    .even809home_labels: .long buy,sell,start810error_labels: .long blocked,full_roster,no_money,position_needed,already_owned811title: .word 22812    .ascii "PRESEASON TRANSFERS "813    .even814budget: .word 10815    .ascii "Budget: "816buy: .word 14817    .ascii "Buy players "818sell: .word 14819    .ascii "Sell players"820start: .word 18821    .ascii "Ready for season"822buying: .word 38823    .ascii "Buy: Left/Right changes source club "824    .even825selling: .word 20826    .ascii "Sell your players "827    .even828    .if WITH_COSMETIC_UI829columns: .word 38830    .ascii "PLAYER               P OVR PRICE USD"831    .if (.-columns)!=38832    .error "Currency column header must remain36 native characters"833    .endif834    .else835columns: .word 34836    .ascii "PLAYER               P OVR PRICE"837    .endif838    .even839help:840    .if WITH_REFINEMENTS841    .word 34842    .ascii "A Back B Select Start Ready     "843    .even844help_buy: .word 34845    .ascii "A/Start Back B Buy L/R Club     "846    .even847help_sell: .word 34848    .ascii "A/Start Back B Sell             "849    .even850    .else851    .word 32852    .ascii "Start/Pass: Select   A/C: Back"853    .endif854    .even855blocked: .word 42856    .ascii "Transfer blocked by budget/roster rules "857    .even858blank: .word 40859    .ascii "                                      "860    .even861862full_roster: .word 36863    .ascii "Roster full - sell a player first "864    .even865no_money: .word 34866    .ascii "Not enough money for this player"867    .even868position_needed: .word 36869    .ascii "Club needs this position or player"870    .even871already_owned: .word 30872    .ascii "Already plays for your club "873    .even874empty: .word 22875    .ascii "No available players"876    .even877free_agents: .word 14878    .ascii "Free agents "879marker: .word 4880    .ascii "* "881