Kajar notes of ChronoRET, rebuilding Chrono Trigger one matched routine at a time

Last updated: October 9, 2026

Battle menu

The battle command menu in bank $C1 ($C1:0785–$C1:1C49, plus BattleMenu_BuildTargetList at $C1:1F79): the per-PC command windows, the tech and item lists, the input handlers for each window, the queue of PCs waiting for a command, and the cursor sprites. It runs with M=1, X=0, DP=0 and DB=$7E, like the rest of the battle.

See also: Battle targeting, Status bar & text, Battle engine.

The rebuild chain

The menu is not redrawn every frame: it rebuilds only on frames where !BattleMenu_Dirty is set. Three routines gate it the same way: BattleMenu_RefreshIfDirtyL ($C1:10E3, the JSL form), BattleMenu_RefreshIfDirtyAndTick ($C1:10FA, which also runs a per-frame service tick and is called after each frame wait of an action) and BattleSys_UpkeepTwoFrames (service 3). Each one clears the flag and runs the chain:

  1. BattleMenu_DequeueReadyBattler: take the next PC off the ready queue;
  2. BattleMenu_UpdateWindows ($C1:0C2D): window upkeep by submenu: the main command window (BattleMenu_UpdateMainWindow), the tech window (BattleMenu_UpdateTechWindow, with the MP check of each visible tech in BattleMenu_UpdateTechMpAvail), or the item window;
  3. BattleMenu_ProcessInput ($C1:1153): the command window's input;
  4. BattleMenu_UpdateCursorOverlay ($C1:17DD, 828 bytes): draw whichever cursor belongs on screen now: none, the target cursor(s), the tech-list cursor (a 2–3 sprite cluster over the partners for a double or triple tech) or the item-list cursor and scroll arrows.

The ready queue

Services 1 and 2 of the battle's service dispatcher manage the PCs waiting for a command: BattleMenu_EnqueueReadyBattler ($C1:1B19) marks the PC's command record "waiting for a command", appends it to !BattleMenu_ReadyQueue and plays sound $42 (inferred: the "turn ready" cue); BattleMenu_RemoveBattlerFromReady ($C1:1BAA) is its inverse. BattleMenu_DequeueReadyBattler pops the head (up to 3 deep) into the roster of PCs shown in the menu. BattleMenu_CycleActivePcPrev / Next switch between the roster's PCs.

Windows and lists

  • Command window: BattleMenu_DrawCommandList and BattleMenu_DrawCommandWindowFrames ($C1:0785–$C1:095C) draw each roster PC's commands; BattleMenu_LoadCommandWindowMap copies the window map from ROM. BattleMenu_CursorUp / Down move between rows; BattleMenu_ConfirmCommand dispatches row 0 (attack, BattleMenu_ChooseAttack), row 1 (tech, BattleMenu_OpenTechList) and row 2 (item, BattleMenu_OpenItemList).
  • Tech list (submenu 1): BattleMenu_RenderTechListRows / RenderTechRow copy tech names from the tables in bank $CC; BattleMenu_TechListInput ($C1:1320) with TechListPrev / Next, TechConfirm and TechListCancel.
  • Item list (submenu 2): BattleMenu_RenderItemListRows / RenderItemRow; BattleMenu_ItemListInput ($C1:143D) with cursor, page and scroll handlers, ItemConfirm and ItemListCancel.

Choosing a target and committing

Confirming an attack, tech or item builds the target list (BattleMenu_BuildTargetList, see Battle targeting) and switches to target selection, whose input is BattleMenu_TargetSelectInput ($C1:1561; BattleMenu_TargetNext / Prev cycle the cursor). Confirming a target runs BattleMenu_CommitAction ($C1:161A): it fills the PC's BattleCmd record (kind $80 attack, $20 tech, $40 item; the partners; the action id; the first selected target), consumes the partners of a double or triple tech (BattleMenu_ConsumePartnerSlot) so they do not act too, decrements the item's quantity, appends the PC to !Battle_CmdQueue and shows the next roster entry. The battle's turn handler later runs the command (see Battle engine).

63functions matched
5,046code bytes matched
63readable
63verified

Functions

AddressFunctionSizeStatusNotes
$C1:0785BattleMenu_DrawCommandList153verifiedDraw the command list of PC slot A (6 rows × 7 columns) into the status map at offset slot × 12, from one of two ROM tile tables: !BattleRom_CmdListTech — "Attack", "Tech", "Item" on rows 1/3/5...
$C1:081EBattleMenu_DrawCommandWindowFrames84verifiedDraw the 7×6 command-window frame of every PC in the roster into !BattleMenu_WindowMap, then highlight the shown PC's name and fall into BattleUI_ClearActivePanelColumn.
$C1:0929BattleMenu_DrawCommandWindowFrame52verifiedCopy one 7-column × 6-row command-window frame (corners, borders and fill) from !BattleRom_CommandWindowFrame into !BattleMenu_WindowMap at !BattleUI_MapOffset.
$C1:095DBattleMenu_RenderItemListRows83verifiedRenders the 3 visible item-list lines: 1.
$C1:09B0BattleMenu_RenderItemRow215verified, then its RTS BattleMenu_RenderItemRow_Exit (1 byte, $0A87) Renders one item-list line for the Item_BattleList record at !BattleMenu_ItemRecOffset into the item map at !BattleMenu_RowMapOffset.
$C1:0A87BattleMenu_RenderItemRow_Exit1verified
$C1:0A88BattleMenu_RenderTechListRows75verifiedRenders 4 tech-list lines (2 per outer loop pass) for the active PC into the tech text buffer (BattleMenu_TechTextTile).
$C1:0AD3BattleMenu_BuildTechAvailFlags56verifiedBuilds !Tech_ListAvail (20 entries, one per list line) for the active PC's tech list: line code $FB-$FF (blank, header or skip line) → 0, anything else → 1.
$C1:0B0BBattleMenu_RenderTechRow171verifiedRenders one tech-list line: blanks the text rows (!BattleMsg_TextTiles / TextTopTiles), fills them by the line code !Tech_ListCode[TechCodeIdx], and copies them into the tech text buffer at...
$C1:0BB6BattleMenu_DrawTechLowerRow29verifiedBlank-line / header exit path of BattleMenu_RenderTechRow: advances !BattleMenu_TechRowNum, blanks the lead cells, then copies 18 lower-row tiles from !BattleMsg_TextTiles into the line from col 3...
$C1:0BD3BattleMenu_BlankNameLeadCells45verifiedBlanks cols 3-5, the lead cells left of the name (which starts at col 6), on both rows of the tech-list line at !BattleMenu_RowMapOffset (blank tile, palette 3).
$C1:0C00BattleMenu_BlankNameTailCells45verifiedTech-name exit path of BattleMenu_RenderTechRow (reached by its tail JMP): blanks cols 17-20 (right of the 11-tile name) on both rows of the line (blank tile, palette 3); the mirror of...
$C1:0C2DBattleMenu_UpdateWindows25verifiedPer-frame window upkeep dispatcher.
$C1:0C46BattleMenu_UpdateWindows_Exit3verified
$C1:0C49BattleMenu_UpdateMainWindow58verifiedMain command-window upkeep (submenu 0): - If !BattleMenu_RosterIdx differs from !BattleMenu_RosterIdxDrawn: reload the command window map and rebuild the status bar.
$C1:0C83BattleMenu_UpdateTechWindow471verifiedTech-window refresh (submenu 1, after UpdateTechMpAvail): 1.
$C1:0E5ABattleMenu_DrawTechCursorRow96verifiedClears the cursor columns, then (unless a target is being selected) draws the 2×2 row cursor ($60-$63) at the shown PC's !Pc_TechRow, placed through !BattleRom_TechCursorCell.
$C1:0EBABattleMenu_ClearTechCursorTiles39verifiedBlanks cols 1-2 (the row-cursor columns) of all 6 tech-window rows.
$C1:0EE1BattleMenu_UpdateTechMpAvail348verifiedGrades the 3 visible tech-list lines (submenu 1) and colours each line in the window map: palette 2 = usable, palette 3 = greyed.
$C1:103DBattleMenu_Return1verifiedShared RTS, also the JMP target of BattleMenu_UpdateMainWindow, BattleMenu_DrawTechCursorRow and BattleMenu_UpdateWindows_Exit.
$C1:10E3BattleMenu_RefreshIfDirtyL23verifiedJSL-entry twin of BattleMenu_RefreshIfDirtyAndTick, reached via the bank's cross-bank entry-vector table: JSL $C10012 -> JMP $C110E3.
$C1:10FABattleMenu_RefreshIfDirtyAndTick27verifiedSame-bank JSR twin of BattleMenu_RefreshIfDirtyL — identical dirty- flag gate and menu rebuild chain, but always follows up with a cross-bank per-frame service tick (BattleSys_FrameTickVec) before...
$C1:1115BattleMenu_DrawCursorSprites62verifiedBuilds OAM sprites 0-3 (BattleOam) for the command cursor over the shown PC: each of the 4 template sprites in BattleRom_CursorSprite is offset by the PC's !Battler_ScreenX/Y, and its palette bits...
$C1:1153BattleMenu_ProcessInput142verifiedBattle command-window input handler.
$C1:11E1BattleMenu_CycleActivePcPrev55verifiedLeft D-pad: step !BattleMenu_RosterIdx back (wrap 0..2), skipping roster entries that are negative.
$C1:1218BattleMenu_CycleActivePcNext56verifiedRight D-pad: mirror of CycleActivePcPrev — steps !BattleMenu_RosterIdx forward (wrap at 3 back to 0) instead; the same sound 0 and the same cursor-memory handling.
$C1:1250BattleMenu_CursorUp20verifiedUp D-pad: step the shown PC's !Pc_MenuRow back (wrap 0..2) and flag the cursor redraw (!BattleUI_PanelRedraw).
$C1:1264BattleMenu_CursorDown23verifiedDown D-pad: step the shown PC's !Pc_MenuRow forward (wrap at 3 back to 0) and flag the cursor redraw (!BattleUI_PanelRedraw).
$C1:127BBattleMenu_ConfirmCommand33verifiedConfirm-button dispatch: sets !BattleUI_UnkA0D7 to $FF (compared by BattleUI_BuildStatusBarFrame with the first selected target), calls BattleFx_SetPtrA2FromTable for the shown PC, then tail-jumps...
$C1:129CBattleMenu_ChooseAttack32verifiedRow 0 (Attack) confirm: message call with "none", flags the cursor redraw, sets !BattleTgt_Mode = attack, !BattleMenu_CmdMenu = 0, builds the target list, sets !BattleMenu_TargetMoved (so...
$C1:12BCBattleMenu_OpenTechList49verifiedRow 1 (Tech) confirm: unless !BattleMenu_Lock bit 0 is set, renders the tech list lines, builds !Tech_ListAvail, switches to the tech list (!BattleMenu_Submenu = !BattleMenu_CmdMenu = 1) and...
$C1:12EDBattleMenu_OpenItemList51verifiedRow 2 (Item) confirm: unless !BattleMenu_Lock is non-zero, renders the item list at !BattleMenu_ItemScroll, queues the item map upload, copies the item box frame (!BattleRom_ItemBoxMap) into...
$C1:1320BattleMenu_TechListInput73verifiedPer-frame input handler while the tech list is open (submenu 1).
$C1:1369BattleMenu_TechConfirm38verifiedConfirms the highlighted tech: aborts unless the rows have been graded (!BattleMenu_TechAvailDone) and Tech_CursorEntry.Flags bit 7 is clear.
$C1:138FBattleMenu_TechListCancel30verifiedCloses the tech list: reload the command window, back to the main menu, force a window rebuild, and restore this PC's saved tech-list cursor (!Pc_SavedTechRow / SavedTechScroll -> !Pc_TechRow /...
$C1:13ADBattleMenu_TechListPrev71verifiedUp/Left in the tech list: walks backward from !BattleMenu_TechListIdx to the previous line whose !Tech_ListAvail is non-zero.
$C1:13F4BattleMenu_TechListNext73verifiedDown/Right in the tech list: mirror of TechListPrev — walks forward instead of backward, bounded by the list length (!Pc_TechCount) instead of the start of the list, and scrolls down instead of up...
$C1:143DBattleMenu_ItemListInput91verifiedPer-frame input handler while the item list is open (submenu 2).
$C1:1498BattleMenu_ItemConfirm67verifiedConfirms the highlighted item: record offset = (!BattleMenu_ItemScroll + !BattleMenu_ItemRow) * 5 into Item_BattleList (id, target mode, flags, quantity, PC mask).
$C1:14DBBattleMenu_ItemListCancel17verifiedCloses the item list: reload the command window, back to the main menu, force a window rebuild, and invalidate the scroll-arrow cache.
$C1:14ECBattleMenu_ItemCursorUp22verifiedUp/Left in the item list: decrement !BattleMenu_ItemRow, scrolling the list up via ItemListScrollUp when already at the top row.
$C1:1502BattleMenu_ItemCursorDown26verifiedDown/Right in the item list: increment !BattleMenu_ItemRow (max 2), scrolling the list down via ItemListScrollDown when already at the bottom row.
$C1:151CBattleMenu_ItemListPageDown27verifiedPage-down button: page the item list down 3 rows at once, clamped at scroll position $FA.
$C1:1537BattleMenu_ItemListPageUp20verifiedPage-up button: page the item list up 3 rows at once, clamped at 0.
$C1:154BBattleMenu_ItemListRefresh22verifiedRe-renders the item list rows, invalidates both draw caches and clears !BattleMenu_ItemRefresh.
$C1:1561BattleMenu_TargetSelectInput185verifiedPer-frame input handler while target selection runs (entered from BattleMenu_ProcessInput when !BattleMenu_TargetSelect != 0).
$C1:161ABattleMenu_CommitAction308verifiedConfirms the currently-selected target and builds the command record for the shown PC's chosen action (attack/tech/item), then queues it and hands the menu to the next ready PC.
$C1:174EBattleMenu_ConsumePartnerSlot30verifiedRemoves PC slot !BattleMenu_PartnerArg from the ready state as part of committing a double/triple tech: if it's in the roster, decrements !BattleMenu_ReadyCount; either way marks its roster entry...
$C1:176CBattleMenu_TargetNext26verifiedRight/Down while cycling targets: advance !BattleTgt_Cursor (wrap at 11), skipping empty candidate entries, and select the battler it lands on (!BattleTgt_Selected).
$C1:1786BattleMenu_TargetPrev22verifiedLeft/Up while cycling targets: mirror of TargetNext — steps !BattleTgt_Cursor back (wrap to 10) instead.
$C1:17A1BattleMenu_ItemListScrollUp16verifiedScrolls the item list up one row: decrements !BattleMenu_ItemScroll (min 0), then re-renders and invalidates both draw caches (row cursor, arrows).
$C1:17B1BattleMenu_ItemListScrollUp_SetScroll2verified
$C1:17B3BattleMenu_ItemListScrollUp_RenderTail3verified
$C1:17B6BattleMenu_ItemListScrollUp_SkipRender9verified
$C1:17BFBattleMenu_ItemListScrollDown18verifiedScrolls the item list down one row: increments !BattleMenu_ItemScroll (clamped at $FA), then re-renders and invalidates both draw caches.
$C1:17D1BattleMenu_ItemListScrollDown_RenderTail3verified
$C1:17D4BattleMenu_ItemListScrollDown_SkipRender9verified
$C1:17DDBattleMenu_UpdateCursorOverlay828verifiedCursor/overlay refresh at the end of the menu rebuild chain (after ProcessInput), so like it only on frames with !BattleMenu_Dirty set: JSR from BattleMenu_RefreshIfDirtyL...
$C1:1B19BattleMenu_EnqueueReadyBattler60verifiedService 1 of the $C10045 service dispatcher (dispatch table at $C10051: service 0 -> $0023, 1 -> here, 2 -> RemoveBattlerFromReady).
$C1:1B67BattleMenu_DequeueReadyBattler67verifiedPops the head of !BattleMenu_ReadyQueue (up to 3 deep, count in !BattleMenu_ReadyQueueLen) into the roster: clears its !Battle_Unk9F38, restores its tech-list cursor (!Pc_SavedTechRow /...
$C1:1BAABattleMenu_RemoveBattlerFromReady144verifiedService 2 of the $C10045 service dispatcher (dispatch table at $C10051; reached only by same-bank JSR from bank $C1, see BattleMenu_EnqueueReadyBattler).
$C1:1C3ABattleMenu_LoadCommandWindowMap16verifiedCopies the $180-byte command window map (!BattleRom_CommandWindowMap, bank $D1) into !BattleMenu_WindowMap.
$C1:1F79BattleMenu_BuildTargetList100verifiedRecords the requesting PC (!BattleTgt_Caster), resets the selection state (!BattleTgt_Result/CanCycle/TargetAll, two Unk bytes) and blanks !BattleTgt_Candidates and !BattleTgt_Selected (indices...

Generated from functions.csv. Do not edit.