Release 2026-11-04-r2 · SHA256 3a6a8f4fddecb9f97054a2b81f73fe914e9862ab829ea272e36da33dc723a5d6 · Click a line number for a direct link.
1 .include "features.inc"2| Independent Full/Light/Mini save slots; each menu entry resumes its own league or playoffs.3| D048 retains native Regular Season/playoff modes. Slot identity is SRAM1EA6;4| header+12 is only the selected slot's pending new-season choice.5| Hooks: F7BAA display, F7ABA writer; native row callbacks may repeat for one key.67 .equ SRAM_OFF, 0x10008 .equ MAGIC, 0x5345534E9 .equ SRAM_RD, 0x1A24410 .equ HDR, 0xFFE3E0 | 16-byte copy of the season header11 .equ FORCED, 0xFFE3F0 | word: 1 while the menu is forced12 .equ SELV, 0xFFE3F2 | word: Regular Season selected (from the header)13 .equ USERW, 0xFFE3F4 | word: your team, shown in the "Team" row14 .equ NEXTK, 0xFFE3F6 | next game index (0-based)15 .equ NEXTOPP, 0xFFE3F8 | next opponent16 .equ NEXTAWAY, 0xFFE3FA | 1 = away game17 .equ GSTR, 0xFFE3A0 | "Game" row text: word 22 + 20 characters18 .equ EXITV, 0xFFE3B8 | long: where the stats screens return to (main menu); EXITM word = $4D41 when set19 .equ EXITM, 0xFFE3BC20 .equ MAININIT, 0xF739E | builds the whole main menu and runs its loop21 .equ STANDINGS,0x2F900022 .equ LEADERS, 0x2FA00023 .equ LABELS, 0xF8070 | the menu's label drawing routine24 .equ PLAYMODE, 0xFFD04825 .equ PLAYERS, 0xFFD04A26 .equ HOME, 0xFFD04C27 .equ AWAY, 0xFFD04E28 .equ HOOK8, 0x2FE000 | patch.py fix 8 (jsr $20961A + Fighting N/A)29 .equ WRITEVAL, 0x2095D63031 .equ SLOTS, 0x2AA00032 .equ SLOTID, 0xFFFFF06A33 .equ SLOTKEY, 0xFFFFF06E34 .equ SLOTVIEW, 0xFFFFF06C35 .equ PORG, 0x2FC800 | playoffs.s36 .equ NEWPICK, 0xFFE3FE | r39: $4E57 = "Start New ..." of a finished slot is shown37 .equ PICKED, 0x4E5738 .text39 .globl _start40_start: | replaces "jsr $20961A" at $F7BAA41 bsr.w force42 bra.w dispsel4344 .globl writehook | replaces "jsr $2095D6" at $F7ABA (_start + 8)45writehook:46 tst.w %d7 | Play Mode row: Regular Season shows as Continue Season / New Season47 bne.s 0f48 bra.w playmode490: | r22 (jdc): Fighting and Difficulty lock like every other row once50 .if WITH_ALLSTAR51 cmpi.w #1,0xFFFFF85052 bne.s not_allstar_row53 cmpi.w #4,%d754 beq.w blocked55 cmpi.w #6,%d756 beq.w blocked57not_allstar_row:58 .endif59 | the season has started (r15 left Difficulty open, r18 rows 8-10;60 | the r18 freeze was the adapter flag, fixed in slots.s restore)61 cmpi.w #3,FORCED | the season's playoffs: everything stays62 beq.w playoff_players63 cmpi.w #4,FORCED | completed season: review its own club, no editable fixture64 beq.w blocked65 cmpi.w #6,%d7 | apply a changed opponent after the caller has saved the old teams66 bne.s oppnot67 tst.w SELV68 beq.s oppnot69 bsr.w force | the original redraw now sees old -> new and refreshes the logos too70 bra.w blocked71oppnot:72 cmpi.w #2,%d7 | Players row in Whole Season: One <-> Two - Teammates, also mid-season73 bne.s plnot | (the game boots with One, so a co-op season must be switchable back)74 tst.w SELV75 beq.s plnot76 cmp.w PLAYERS,%d3 | the menu writes every row again after a change: same value = no press77 beq.s plw78 jsr 0x2EB008 | persistent per-slot One/Two/Three/Four - Teammates79plw: bra.w 1f | recalculate home/away before the caller compares/redraws logos80plnot: tst.w FORCED | 0 = not Regular Season, 1 = season running, 2 = before the first game81 beq.s 1f82 cmpi.w #1,FORCED | season running: everything else you chose at the start stays83 bne.s 5f84 bra.s 2f855:86 cmpi.w #2,%d7 | Players and Away are always locked87 beq.s 2f88 cmpi.w #6,%d789 beq.s 2f90 cmpi.w #4,%d7 | Home (your team) only before the season has started91 bne.s 1f92 cmpi.w #1,FORCED93 beq.s 2f941: jsr WRITEVAL95 tst.w SELV96 beq.s 3f97 bsr.w force | changing your team/Players must update its opponent now,98 | not during the later text redraw after logos were loaded993: tst.w %d2 | preserve the native writer's return flags100 rts1012:102blocked:103 tst.w %d2 | same flags as the original routine returns104 rts105playoff_players:106 cmpi.w #2,%d7 | only the Players row is editable in an active season playoff107 bne.s blocked108 cmp.w PLAYERS,%d3109 beq.s blocked110 jsr 0x2EB008111 bra.w 1b112113force: movem.l %d0-%d3/%a0-%a1,-(%sp)114 jsr SLOTS | migrate legacy save once, then keep selected slot active115 .if WITH_ALLSTAR116 cmpi.w #1,0xFFFFF850117 bne.s allstar_teams_ready118 cmpi.w #1,0xFFFFF84C119 bne.s allstar_teams_ready120 tst.w SLOTVIEW121 bne.s allstar_teams_ready122 clr.w HOME123 move.w #1,AWAY124allstar_teams_ready:125 .endif126 clr.w FORCED127 clr.w SELV128 lea HDR,%a0129 move.l #SRAM_OFF,%d0130 moveq #16,%d1131 jsr SRAM_RD132 tst.w SLOTVIEW133 beq.w 9f134 jsr 0x2E6004135 bne.s unfinished_menu136 move.w #1,SELV137 clr.w PLAYMODE138 bra.w complete_menu139unfinished_menu:140 lea HDR,%a0141 cmpi.l #MAGIC,(%a0) | the season's playoffs (season over, your team in): locked like the season142 bne.w 20f143 tst.w 12(%a0)144 bne.w 20f145 move.w 8(%a0),%d1146 cmp.w 10(%a0),%d1147 bcs.w 20f148 jsr PORG+20 | d0: -1 no, 0 set, 1/3 set Play Mode to this; d2 = your team149 bmi.w 20f150 move.w #3,FORCED151 tst.w %d0152 beq.s 23f153 move.w %d0,PLAYMODE154 move.w %d0,0xFFD074 | (the game keeps Play Mode here between games)155 move.w %d2,HOME156 cmpi.w #3,%d0157 beq.s 24f158 cmpi.w #2,%d0159 bne.s 22f16024:161 moveq #7,%d1 | Players in the playoff modes: 7 = One, 6 = Two - Teammates (the game keeps162 jsr 0x2EA404 | 7 - Players in its playoff state; Regular Season's 1 became garbage there)163 beq.s 24f164 cmpi.w #6,PLAYERS165 bne.s 25f16624: moveq #6,%d116725: move.w %d1,PLAYERS16821: jsr 0x17D16 | New Playoffs set-up (playoffs.s: the season's tree, your slot)169 bra.s 23f17022: jsr 0x17CA0 | Continue Playoffs: the game's saved state17123: jsr 0x2EB014 | use this slot's preferred count after native password decode172 move.w 0xFFCEEC,%d0 | Away = your opponent in this round: tree round r at $CEF4 + 0/16/24/28,173 cmpi.w #3,%d0 | your slot there = $CEEE >> r, the opponent's = that ^ 1174 bhi.w 9f175 move.w 0xFFCEEE,%d1176 lsr.w %d0,%d1177 eori.w #1,%d1178 add.w %d0,%d0179 lea roundoff,%a1180 add.w (%a1,%d0.w),%d1181 lea 0xFFCEF4,%a1182 moveq #0,%d0183 move.b (%a1,%d1.w),%d0184 cmpi.w #31,%d0185 bhi.w 9f186 move.w %d0,AWAY187 bra.w 9f18820: lea HDR,%a0189 tst.w PLAYMODE | Regular Season = the season190 bne.w 9f191 move.w #1,SELV192 cmpi.l #MAGIC,(%a0)193 bne.s 3f | no season block yet: before the first game194 tst.w 12(%a0) | New Season chosen: like before the first game195 bne.s 3f196 move.w 6(%a0),%d0 | your team + 1197 beq.s 3f198 subq.w #1,%d0199 move.w 8(%a0),%d1 | next game index200 cmp.w 10(%a0),%d1201 bcc.w complete_menu202 move.w #1,FORCED203 bra.s 4f2043: move.w HOME,%d0 | before the first game: your team = Home, game 0 of its schedule205 moveq #0,%d1206 move.w #2,FORCED2074:208 move.w %d0,-(%sp) | the user's team survives the round lookup209 jsr 0x2FD600 | chosen unplayed round, including saved opponent changes210 move.w %d0,%d2211 move.w (%sp)+,%d0212 .if WITH_DIVISION_MINI213 cmpi.w #3,SLOTID214 bne.s league_opponent215 jsr 0x2DBE00 | d0 club,d2 round -> d3 divisional opponent216 bra.s opponent_ready217league_opponent:218 .endif219 lea sched,%a1220 moveq #0,%d3221 move.b (%a1,%d2.w),%d3222 add.w %d0,%d3223 andi.w #31,%d3 | opponent224 .if WITH_DIVISION_MINI225opponent_ready:226 .endif227 move.w %d0,USERW228 move.w %d1,NEXTK229 move.w %d3,NEXTOPP230 clr.w NEXTAWAY231 jsr 0x2EA404 | Two - Teammates always controls the home team: play every game at home232 beq.s 51f233 btst #0,%d1234 bne.s 5f23551: move.w %d0,HOME | even game: at home236 move.w %d3,AWAY237 moveq #1,%d2238 bra.s 6f2395: move.w #1,NEXTAWAY240 move.w %d3,HOME | odd game: away241 move.w %d0,AWAY242 moveq #2,%d22436: jsr 0x2EA404 | co-op stays co-op244 beq.w 9f245 move.w %d2,PLAYERS | you control your own team (One - Home / One - Visitor)2469: movem.l (%sp)+,%d0-%d3/%a0-%a1247 rts248complete_menu:249 jsr 0x2E6010 | lock a finished slot to its saved club; no fictitious next game250 bra.s 9b251| row 0 shows "Whole Season" when chosen, everything else goes to fix 8 (jsr $20961A + Fighting N/A)252dispsel: | a0 = $FFD048 here (the value routine needs it): don't touch a0253 .if WITH_QUICKGAME254 tst.w 0xFFFFF84C255 beq.s not_quick_label256 tst.w %d7257 bne.s not_quick_label258 .if WITH_ALLSTAR259 cmpi.w #1,0xFFFFF850260 bne.s ordinary_quick_label261 pea allstarlabel262 bra.w 2f263ordinary_quick_label:264 .endif265 pea quicklabel266 bra.w 2f267not_quick_label:268 .endif269 cmpi.w #2,%d7270 bne.s ordinary_label271 tst.w SLOTVIEW272 beq.s ordinary_label273 jsr 0x2EB00C | show all four counts, even though native playoffs share one co-op value274 move.l %d0,-(%sp)275 bra.w 2f276ordinary_label:277 cmpi.w #3,FORCED278 bne.s 6f279 tst.w %d7280 bne.s 6f281 cmpi.w #1,PLAYMODE | after a playoff game, keep Continue Playoffs282 beq.s continuing_po283 pea playoffstr | completed season: enter its already-seeded playoff tree284 bra.w 2f285continuing_po:286 cmpi.w #3,SLOTID287 beq.s po_mini288 cmpi.w #2,SLOTID289 beq.s po_light290 pea fullpostr291 bra.w 2f292po_mini:293 pea minipostr294 bra.w 2f295po_light:296 pea lightpostr297 bra.w 2f2982996:300 tst.w SELV301 beq.w 1f302 tst.w %d7 | Play Mode in Regular Season: "Continue Season" / "New Season"303 bne.s 4f304 bsr.w hasseason305 beq.s newlabel306 tst.w HDR+12307 bne.s newlabel308 jsr 0x2E6004309 bne.s unfinished_label310 jmp 0x2E6008 | See Old Full/Light/Mini Season311unfinished_label:312 cmpi.w #3,SLOTID313 beq.s continuemini314 cmpi.w #2,SLOTID315 beq.s continuelight316 pea contstr317 bra.s 2f318continuemini:319 pea contmini320 bra.s 2f321continuelight:322 pea contlight323 bra.s 2f324newlabel:325 cmpi.w #3,SLOTID326 beq.s 7f327 cmpi.w #2,SLOTID328 beq.s 5f329 pea newstr330 bra.s 2f3317: pea ministr332 bra.s 2f3335: pea lightstr334 bra.s 2f3354: cmpi.w #2,%d7 | Players: "One" for One - Home / One - Visitor336 bne.s 1f337 jsr 0x2EA404 338 beq.s 1f339 pea onestr3402: jsr 0x20961A341 movea.l (%sp)+,%a1342 addq.l #4,%sp343 jmp 0x11BA43441: jmp HOOK8345346| team rows ($F7C72, replaces "movea.l #$FFFFD048,a1"): in Whole Season row Home shows your team, row Away is empty347 .globl teamrow348teamrow:349 movea.l #0xFFFFD048,%a1350 tst.w SELV351 beq.s 1f352 cmpi.w #6,%d7353 beq.s 2f354 cmpi.w #4,%d7355 bne.s 1f356 tst.w FORCED | finished season: native Home is free, USERW is no longer refreshed357 beq.s 1f | show the same selected club as the native logos/player card358 movea.l #USERW-4,%a1 | (a1,d7) = your team3591: rts3602: addq.l #4,%sp | Away row: "Game 2/82 at COL" and return from the row printer361 bsr.w gameinfo362 lea GSTR,%a1363 jmp 0x11BA4364365| GSTR = word 22 + "n/82 at ABC" / "n/82 vs ABC" padded to 20 characters366gameinfo:367 movem.l %d0-%d3/%a0-%a2,-(%sp)368 jsr 0x2E600C | completed slots show Season finished, never 1/8 vs a stale opponent369 beq.w 4f370 lea GSTR,%a0371 move.w #22,(%a0)+372 lea 20(%a0),%a2373 move.w NEXTK,%d2374 addq.w #1,%d2375 bsr.w num376 move.b #0x2F,(%a0)+ | "/"377 moveq #MINI_GAMES,%d2378 cmpi.w #3,HDR+12379 beq.s 1f380 moveq #31,%d2381 cmpi.w #2,HDR+12382 beq.s 1f383 moveq #84,%d2384 tst.w HDR+12385 bne.s 1f386 bsr.w hasseason | an empty old Mini/Light header is not a running season387 beq.s 1f | New Full Season uses the full default until a team is saved388 move.w HDR+10,%d2389 bne.s 1f390 moveq #84,%d23911: bsr.w num392 jsr 0x2EA404 | jdc r20: co-op plays every game at home, so no "at"/"vs":393 bne.s 5f | "84/84 FLA (co-op)"394 move.b #0x20,(%a0)+395 bsr.s opp396 lea coop,%a13976: move.b (%a1)+,(%a0)+398 bne.s 6b399 subq.l #1,%a0400 bra.s 3f4015: move.b #0x20,(%a0)+402 move.b #0x76,(%a0)+ | "vs"403 move.b #0x73,(%a0)+404 tst.w NEXTAWAY405 beq.s 2f406 move.b #0x61,-2(%a0) | "at"407 move.b #0x74,-1(%a0)4082: move.b #0x20,(%a0)+409 bsr.s opp4103: cmpa.l %a2,%a0411 bge.s 4f412 move.b #0x20,(%a0)+413 bra.s 3b4144: movem.l (%sp)+,%d0-%d3/%a0-%a2415 rts416opp: lea abbr,%a1 | the opponent's three letters417 move.w NEXTOPP,%d2418 mulu.w #3,%d2419 move.b (%a1,%d2.w),(%a0)+420 move.b 1(%a1,%d2.w),(%a0)+421 move.b 2(%a1,%d2.w),(%a0)+422 rts423coop: .asciz " (co-op)"424 .even425| d2 = 1..99 -> digits (no padding)426num: andi.l #0xFFFF,%d2427 divu.w #10,%d2428 tst.w %d2429 beq.s 1f430 addi.b #0x30,%d2431 move.b %d2,(%a0)+4321: swap %d2433 addi.b #0x30,%d2434 move.b %d2,(%a0)+435 rts436437| label loop ($F80BC, replaces "jsr $11A48"): "Home" -> "Team", "Away" -> empty in Whole Season438 .globl labelhook439labelhook:440 bsr.w checksel441 tst.w SELV442 beq.s 1f443 cmpa.l #0x20917A,%a1444 beq.s 2f445 cmpa.l #0x20918A,%a1446 beq.s 3f4471: jmp 0x11A484482: move.l %a1,-(%sp)449 lea teamlbl,%a1450 bra.s 4f4513: move.l %a1,-(%sp)452 lea blanklbl,%a14534: jsr 0x11A48454 movea.l (%sp)+,%a1455 adda.w (%a1),%a1 | continue with the next label456 rts457458| Main menu Left/Right ($F75C2): on the Game row, change the selected unplayed459| opponent. The Away value-write callback applies forcing after old teams were460| captured, so the original redraw refreshes team logos and the Game text.461 .globl mainlr462mainlr:463 tst.w %d7464 bne.s not_mode_key465 clr.w SLOTKEY | one slot transition per physical menu key event466not_mode_key:467 tst.w SELV468 beq.s 1f469 cmpi.w #6,%d7470 bne.s 1f471 cmpi.w #3,FORCED472 beq.s 1f473 jsr 0x2FD604 | D2 = -1/+1: choose another unplayed opponent4741: cmpi.w #4,PLAYMODE | preserve the original caller's flags and redraw path475 rts476| $1732C (replaces "jsr $FCC76", the Matchups screen after Start): in Whole Season go straight to the pre-game menu,477| where Season Standings and Scoring Leaders are (jdc wanted the stats one press from the main menu).478 .globl skipmatch479skipmatch:480 .if WITH_REFINEMENTS481 bsr.w checksel482 jmp 0xFCC76 | restore original Matchups before every actual match483 .endif484 bsr.w checksel485 tst.w SELV486 bne.s 1f487 jmp 0xFCC764881: rts489490| SELV from the battery header (labels are drawn before the value rows)491checksel: | SELV for the labels: the same as force (which may also switch to the playoffs)492 bra.w force493494| redraw the labels after Play Mode changed (keeps the text cursor of the caller)495relabel:496 movem.l %d0-%d7/%a0-%a6,-(%sp)497 move.l 0xFFB028,-(%sp)498 move.l 0xFFB02C,-(%sp)499 jsr LABELS500 move.l (%sp)+,0xFFB02C501 move.l (%sp)+,0xFFB028502 movem.l (%sp)+,%d0-%d7/%a0-%a6503 rts504505| Play Mode: d3 = the game's new value (0..4, from $D048 with wrap-around).506playmode:507 cmp.w PLAYMODE,%d3508 beq.w pmw | unchanged native redraw writes must keep the caller's font state509 tst.w SLOTKEY510 beq.s first_mode_write511 tst.w SLOTVIEW512 bne.w blocked | one season-slot transition per key513 bra.w original_modes | native retries must skip an empty Continue or re-enter a season514first_mode_write:515 move.w #1,SLOTKEY516 tst.w SLOTVIEW517 beq.w original_modes518 jsr 0x2E601C | r39 finished.s step: See Old <-> Start New of a finished slot519 bne.s cycle_slots | (Z = handled, stay on this slot)520 bsr.w relabel521 tst.w %d2522 rts523cycle_slots:524 move.w SLOTID,%d0525 tst.w %d2 | native skipping of unavailable modes can amplify the step526 bmi.s slot_left527 addq.w #1,%d0528 bra.s slot_step529slot_left:530 subq.w #1,%d0531slot_step:532 cmpi.w #1,%d0533 bcs.s leave_left534 cmpi.w #3,%d0535 bhi.s leave_right536select_slot:537 jsr SLOTS+4538 jsr 0x2E6020 | r39: from the right, a finished slot shows Start New539 bsr.w force | refresh actual clubs before native logo comparisons540 bsr.w relabel541 tst.w %d2542 rts543leave_left:544 clr.w NEWPICK545 jsr SLOTS+8 | preserve season before unrelated native playoff/shootout modes546 .if WITH_QUICKGAME547 .if WITH_ALLSTAR548 bra.w enter_allstar549 .else550 bra.w enter_quick551 .endif552 .else553 moveq #4,%d3554 bra.s pmwrite555 .endif556leave_right:557 clr.w NEWPICK558 jsr SLOTS+8559 moveq #1,%d3560 .if WITH_ALLSTAR561 bra.w pmwrite562 .else563 bra.s pmwrite564 .endif565original_modes:566 .if WITH_ALLSTAR567 cmpi.w #1,0xFFFFF850568 bne.s not_from_allstar569 jsr 0x22C004570 tst.w %d2571 bmi.w enter_quick572 clr.w 0xFFFFF84C573 moveq #1,%d0574 bra.w select_slot575not_from_allstar:576 .endif577 .if WITH_QUICKGAME578 tst.w 0xFFFFF84C579 beq.s from_native_modes580 .if WITH_ALLSTAR581 tst.w %d2582 bpl.w enter_allstar583 .endif584 clr.w 0xFFFFF84C585 tst.w %d2586 bpl.s quick_to_full587 moveq #4,%d3588 bra.s pmwrite589quick_to_full:590 moveq #1,%d0591 bra.w select_slot592from_native_modes:593 cmpi.w #4,PLAYMODE594 bne.s original_mode_cycle595 tst.w %d2596 bmi.s original_mode_cycle597 .if WITH_ALLSTAR598 bra.w enter_quick | native Shootout Right must not fall into the Allstar entry599enter_allstar:600 jsr 0x22C000601 bsr.w force602 bsr.w relabel603 tst.w %d2604 rts605 .endif606enter_quick:607 jsr 0x229000608 bsr.w force609 bsr.w relabel610 tst.w %d2611 rts612original_mode_cycle:613 .endif614 tst.w %d3615 bne.s pmwrite616 moveq #1,%d0 | Shootout -> Full617 cmpi.w #4,PLAYMODE618 .if WITH_QUICKGAME619 beq.w select_slot620 .else621 beq.s select_slot622 .endif623 moveq #3,%d0 | native Continue Playoffs -> Mini624 .if WITH_QUICKGAME625 bra.w select_slot626 .else627 bra.s select_slot628 .endif629pmwrite:630 jsr WRITEVAL631 bsr.w force632 bsr.w relabel633 tst.w %d2634 rts635pmw: jmp WRITEVAL636637| Z clear if a season is saved (header in HDR: magic and a team)638hasseason:639 cmpi.l #MAGIC,HDR640 bne.s 1f641 tst.w HDR+6642 rts6431: ori #4,%ccr | Z set644 rts645646newstr: .word 22647 .ascii "New Full Season "648lightstr:649 .word 22650 .ascii "New Season Light "651ministr:652 .word 22653 .ascii "New Season Mini "654playoffstr:655 .word 22656 .ascii "Continue to Playoffs"657contstr:658 .word 22659 .ascii "Continue Full Season"660contlight:661 .word 22662 .ascii "Continue Light "663contmini:664 .word 22665 .ascii "Continue Mini "666fullpostr:667 .word 22668 .ascii "Continue Full PO "669lightpostr:670 .word 22671 .ascii "Continue Light PO "672minipostr:673 .word 22674 .ascii "Continue Mini PO "675onestr: .word 22676 .ascii "One "677teamlbl:678 .word 16679 .ascii "Team "680blanklbl:681 .word 16682 .ascii "Game "683roundoff: .word 0,16,24,28684abbr: .ascii "ANABOSBUFCGYCARCHICOLCBJDALDETEDMFLALAKMINMTLNSHNJDNYINYROTTPHIPITSJSSEASTLTBLTORUTAVANVGKWASWPG"685 .even686687 .include "sched.inc"688689 .if WITH_QUICKGAME690quicklabel:691 .word 22692 .if WITH_QUICKGAME_CPU693 .ascii "Quickgame "694 .else695 .ascii "QUICKGAME "696 .endif697 .endif698699 .if WITH_ALLSTAR700allstarlabel:701 .word 22702 .ascii "ALLSTAR MODE "703 .endif704