modemwars/survey/game_ovl_6F00_A_844F.json
2026-08-23 02:09:40 -05:00

651 lines
No EOL
30 KiB
JSON
Generated

{
"chunk": "game_ovl_6F00_A_844F",
"unit": "game/ovl_6F00_A",
"routines": [
{
"addr": "8451",
"name": "editValueWithJoystick",
"summary": "Generic numeric option editor used by the custom-scenario setup. A = exclusive upper limit (patched into the CMP at $8492), Y = display multiplier (patched into $8469). Loops: un-highlights the one-row menu, prints editValue*Y in decimal at column 1 of the value window (multiply8x8 $FCCD -> A=lo/Y=hi, then $C17D), clears the rest of the line, services the link (serviceCommandExchange), blinks the row, and applies joystick up/down as +1/-1 (rejecting values >= limit or below 0, playing sound 2 on a change, auto-repeat via setJoystickRepeatDelay). Returns when the fire button is pressed (checkFirePressed).",
"inputs": "A = limit (value must stay < A), Y = multiplier for display, D_844F initial value, zp_5D joystick, zp_6C repeat timer, zp_6E blink timer, menu window set up by beginValueEdit",
"outputs": "D_844F = edited value; D_92C5 = 1; text printed in the info panel; sounds 2",
"confidence": "high"
},
{
"addr": "84AA",
"name": "applyHandicapPoints",
"summary": "Tail of runGameStartOptions (reached by JMP from $85B9). Computes the default handicap for the asymmetric scenarios: game type 1 (QB SNEAK) gives side 0 a handicap of 2 (20 points), game type 6 (DEFENDER) gives side 1 a handicap of $14 (200 points), everything else 0. When the custom toggle (D_92F3 bit 7) is set the player edits the value instead ('HANDICAP', 0..50 shown x10) starting from that default. A nonzero result is sent as command $A5 kind 0 (value*10 points for the sender's side, cmdSetupOption); zero is not sent.",
"inputs": "D_0BA3 bits 0-2 game type, D_0B9F playerSide, D_92F3 bit 7 custom flag",
"outputs": "command $A5 00 value queued via queueCmd3 (zp_74 = 0, zp_75 = value); info panel used",
"confidence": "high"
},
{
"addr": "84EC",
"name": "editTerrainPoints",
"summary": "Custom option 'TERRAIN PTS': starts from D_92AC[opponent side] (points awarded for entering the enemy zone), lets the player pick 0..2 with editValueWithJoystick and sends command $A5 kind 1 (cmdSetupOption stores it in $92AC of the other side).",
"inputs": "D_0B9F playerSide, D_92AC",
"outputs": "command $A5 01 value queued (zp_74 = 1, zp_75 = value)",
"confidence": "medium"
},
{
"addr": "84F1",
"name": "editTerrainPointsForSide",
"summary": "Entry into editTerrainPoints with the side index already in A (A -> Y, X = D_92AC[Y]). In variant A nothing calls it; the XREF caller at $83DE belongs to overlay variant B, where $84F1 is a different routine.",
"inputs": "A = side index 0/1",
"outputs": "as editTerrainPoints",
"confidence": "medium"
},
{
"addr": "8511",
"name": "editDronesAndMissiles",
"summary": "Custom options 'DRONES' (0..9, from D_92AE) and 'MISSILES' (label $CC9E, 0..36, from D_92B0), each edited with beginValueEdit + editValueWithJoystick. The two results are sent as one command $90 x=drones y=missiles; in the setup phase cmdMissileStrike ($53C0) stores them as dronesLeft/missilesLeft for the sender.",
"inputs": "D_92AE dronesLeft, D_92B0 missilesLeft",
"outputs": "command $90 drones missiles queued (zp_74 = drones, zp_75 = missiles)",
"confidence": "medium"
},
{
"addr": "8518",
"name": "editDronesAndMissilesBody",
"summary": "Not a real entry point in variant A: it is the JSR beginValueEdit inside editDronesAndMissiles (A/Y/X must already hold the label and value). The label exists because the main program calls $8518 at $1460/$14D3, which is a routine of overlay variant B (menu screen).",
"inputs": "A/Y = label, X = value (must be preset)",
"outputs": "as editDronesAndMissiles",
"confidence": "high"
},
{
"addr": "8547",
"name": "runGameStartOptions",
"summary": "Called once from the new-game start sequence ($7AF7) after the setup has been saved and before unit placement. Sets gamePhase $7F, hides the viewport (sub_8364), draws the overview (side 0: drawOverviewMap, side 1: clearScreenAndRedrawGameScreen), shows the 'STANDARD/CUSTOM <type> SCENARIO - PRESS BUTTON WHEN READY.' banner (showScenarioBannerAndWaitForButton), copies gameTypeOptions bit 6 into D_8450 and (shifted to bit 7) into D_92F3. If CUSTOM rules are on it shows the custom summary message, prints the game type name and a 2-item STANDARD/CUSTOM menu (rows at column 28, width 10, runMenuLoopWithFlag); choosing CUSTOM (D_8450 = 1) runs editComcenSpeed, editTerrainPoints and editDronesAndMissiles. Then, for game types 4-6 (SLUGGERS, FULL WAR, DEFENDER), sub_8378 sets up the recycler, and finally it jumps to applyHandicapPoints.",
"inputs": "D_0BA3 gameTypeOptions, D_0B9F playerSide, menu/text engine state",
"outputs": "zp_B1 = $7F, D_8450, D_92F3, setup commands $A5/$90/$9C queued, screen redrawn",
"confidence": "medium"
},
{
"addr": "85BC",
"name": "editComcenSpeed",
"summary": "Custom option 'COMCEN SPEED': starts from D_92B4 (own comcen speed setting 0..3), edits it with editValueWithJoystick (limit 4) and sends command $A5 kind 3 (cmdSetupOption writes $92B4 of the sender's side; $7B6E later maps the setting through the table at $78BF).",
"inputs": "D_92B4",
"outputs": "command $A5 03 value queued (zp_74 = 3, zp_75 = value)",
"confidence": "medium"
},
{
"addr": "85DB",
"name": "beginValueEdit",
"summary": "Common prologue of the value editors: stores the label pointer (patched into $85EA/$85EC), sets editValue = X, clears the info panel in colour 8 and sets row 15 (sub_8441), prints the label centred, moves the text window left edge to column 29, starts a new line and records that row as menuFirstRow with menuSelectedItem = 0. Falls into the tail at $8601 which sets selectedUnit = $FE (plain menu, no unit) and the window width to 5 for the highlight bar.",
"inputs": "A/Y = label string (bit-7 terminated), X = initial value",
"outputs": "D_844F = X, D_91D5 = 0, D_91D6 = row, D_90F8 = $FE, zp_3B = $1D, zp_3C = 5, label printed",
"confidence": "high"
},
{
"addr": "8601",
"name": "setValueEditWindow",
"summary": "Tail of beginValueEdit: selectedUnit = $FE and textWindowWidth = 5. The sub_ label only exists because $8601 is a routine entry in overlay variant B; in A it is only reached by fall-through.",
"inputs": "-",
"outputs": "D_90F8 = $FE, zp_3C = 5",
"confidence": "high"
},
{
"addr": "860B",
"name": "editOptionBitOnOff",
"summary": "Two-row OFF/ON menu for one bit of gameTypeOptions, used by the scenario setup screen for 'UNIT MENUS' (mask $08, $82B3) and 'DAMAGE' (mask $10, $82BC). Stores the label pointer and mask in self-modifying operands, hides the viewport, clears the panel to row 14, prints the label centred with the current state pre-selected (row 0 = OFF from $064D, row 1 = ON via sub_C137), runs runMenuLoopWithFlag with width 5 at column 27 and then clears or sets the mask bit in D_0BA3 according to the chosen row.",
"inputs": "A/Y = label string, X = bit mask, D_0BA3",
"outputs": "D_0BA3 bit updated; D_91D4 = 2, D_91D5 = choice",
"confidence": "high"
},
{
"addr": "862D",
"name": "runOnOffMenuAndApplyBit",
"summary": "Tail of editOptionBitOnOff (menuItemCount = 2, print OFF/ON, run the menu, apply the mask at $8621+1). Only an entry point in overlay variant B.",
"inputs": "label already printed, mask operand at $8622",
"outputs": "D_0BA3 updated",
"confidence": "high"
},
{
"addr": "8632",
"name": "printOnOffMenuAndApplyBit",
"summary": "Inner tail of editOptionBitOnOff starting at the OFF/ON printing. The main program's JSR $8632 at $176B targets overlay variant B's routine of the same address, not this code.",
"inputs": "menu state, mask operand at $8622",
"outputs": "D_0BA3 updated",
"confidence": "high"
},
{
"addr": "8658",
"name": "handleStarKeyToggle",
"summary": "Per-frame hook called while overlay A is resident in non-battle phases (battlefield loop via the trampoline $25C4 when zp_B1 != 0, and runMenuLoop at $6002 when zp_B1 == $FF). If no chat entry is pending (D_929C bit 7 clear) and the last key is '*' ($AA) it consumes the key, toggles bit 7 of D_92F3 and falls into showToggleStateMessage (returns C = 1). Otherwise returns C = 0. During unit placement the flag means DESTROY mode (clicking an own unit sends $91 self destruct, $209F); on the scenario setup screen it means CUSTOM rules.",
"inputs": "D_929C chatState, D_9248 lastKeyCode, D_92F3",
"outputs": "C = 1 and D_92F3 bit 7 toggled when '*' was pressed (D_9248 = $FF), else C = 0",
"confidence": "high"
},
{
"addr": "8673",
"name": "showToggleStateMessage",
"summary": "Shows the state of the '*' toggle: empties the message queue (tail = head), patches the word 'ON' ($0650) or 'OFF' ($064D) into the message text (3 bytes copied to the address patched at $869A/$869B: $EFDF inside 'CUSTOM OFF' or $EFEA inside 'DESTROY OFF'), sets persistentMessageId to $1E while the mode is on (or to the operand at $868D when off: 0 on the setup screen, 10 = 'SETUP UNITS...' during placement), clears the message timer and queues message $1E. Returns C = 1. Also called directly from the setup screen ($8253) to show 'CUSTOM ON' initially.",
"inputs": "D_92F3 bit 7, operands patched by $820B/$821F or setDestroyModeMessage",
"outputs": "D_9252 = D_9251, D_92A1, zp_72 = 0, message $1E queued, C = 1, zp_48/49 = word pointer",
"confidence": "high"
},
{
"addr": "86AA",
"name": "setDestroyModeMessage",
"summary": "Prepares the '*' toggle for the unit-placement phase (called at $7B4B before the placement loop): off-state persistent message = 10 ('SETUP UNITS. PRESS F 1 WHEN DONE.'), message slot $1E -> 'DESTROY OFF' ($EFE2 in the T34 $EC00 sub-overlay), and the ON/OFF patch address = $EFEA (the 'OFF' inside that string). The setup-screen code at $820B/$821F does the same with 'CUSTOM OFF' ($EFD8/$EFDF) and off-message 0.",
"inputs": "-",
"outputs": "$868D = $0A, message slot $1E (D_0500/D_0524 index $1E) = $EFE2, $869A/$869B = $EFEA",
"confidence": "high"
},
{
"addr": "86C3",
"name": "showCustomSummaryMessage",
"summary": "Builds the status line 'CUSTOM:' [+ 'MAP,' when D_0BA3 bit 7 is set] + ' MENUS OFF,/ON, DAMAGE OFF./ON.' into the buffer at $0332 (prefix from $CC19 'CUSTOM' and $EF77 'MAP TYPE'; the option part is filled into the template at $0636 ' MENUS XXXX DAMAGE XXX.' by appendOnOffWord with bits 3 and 4 of gameTypeOptions) and registers it as the persistent message $1E (setPersistentMessage). Called when a game starts or resumes with CUSTOM rules ($7D4B, $856D).",
"inputs": "D_0BA3 bits 3, 4, 7; templates at $0636 and $064D; strings $CC19, $EF77",
"outputs": "$0332.. text, $0636 template overwritten, message slot $1E = $0332, D_92A1 = $1E, message queued",
"confidence": "high"
},
{
"addr": "8722",
"name": "setPersistentMessage",
"summary": "Registers the string A/Y as message slot $1E (sub_C924 writes the pointer tables at $0500/$0524), makes $1E the persistent status message (D_92A1) and queues it with sub_C566. Used for 'PRESS BUTTON WHEN READY.' and the custom summary; the entry at $8722 is also the tail of showCustomSummaryMessage.",
"inputs": "A/Y = string pointer",
"outputs": "D_0500[$1E]/D_0524[$1E], D_92A1 = $1E, message queued, X = $1E",
"confidence": "high"
},
{
"addr": "872E",
"name": "appendOnOffWord",
"summary": "Writes 'OFF,' (A = 0) or 'ON, ' (A != 0) into the template at $0636 starting at index X: copies the bit-7 terminated word from $064D (OFF) or $0650 (ON), adds a comma, and for ON adds a trailing space so both forms are 4 characters; returns X pointing at the comma.",
"inputs": "A = option state (0 = off), X = destination index in $0636",
"outputs": "$0636+X.. written, X = index of the comma",
"confidence": "high"
},
{
"addr": "8756",
"name": "showScenarioBannerAndWaitForButton",
"summary": "Clears the info panel (row 15) and prints, centred in 13 columns, 'STANDARD' or 'CUSTOM' (table $CC11, chosen by D_0BA3 bit 6), the game type name (table $CCC8, bits 0-2) and the string ' SCENARIO' ($CC04). Sets 'PRESS BUTTON WHEN READY.' ($CBBE) as persistent message $1E, then loops on serviceCommandExchange until checkFirePressed reports a click, and finally clears the status line (sub_C39F).",
"inputs": "D_0BA3, fire button, link",
"outputs": "info panel text, D_92A1 = $1E, status line cleared",
"confidence": "high"
},
{
"addr": "8795",
"name": "printCentredTableEntry",
"summary": "Sets textCentreWidth (D_90EF) to 13 and prints entry X of a table of 8-byte bit-7 terminated strings at A/Y through sub_C100 (used for the STANDARD/CUSTOM words and the game type names).",
"inputs": "A/Y = table base, X = entry index",
"outputs": "text printed, D_90EF = $0D",
"confidence": "high"
}
],
"variables": [
{
"addr": "844F",
"scope": "abs",
"name": "editValue",
"meaning": "value being edited by editValueWithJoystick (initialised by beginValueEdit from X, read back by the option editors)",
"confidence": "high"
},
{
"addr": "8450",
"scope": "abs",
"name": "customSetupChosen",
"meaning": "nonzero while custom options are being set at game start: first D_0BA3 & $40, then the STANDARD(0)/CUSTOM(1) menu choice; sub_8378 only offers the recycler mode menu when it is set",
"confidence": "high"
},
{
"addr": "87FF",
"scope": "abs",
"name": "overlayVariantFlag",
"meaning": "last byte of the $6F00 overlay: $00 in variant A, $FF in variant B; bit 7 is tested by the main program ($1036, $1080) to decide whether variant B must be (re)loaded",
"confidence": "high"
},
{
"addr": "92F3",
"scope": "abs",
"name": "setupToggleFlag",
"meaning": "bit 7 = state of the '*' key toggle handled by handleStarKeyToggle: CUSTOM rules on the scenario setup screen (mirrors D_0BA3 bit 6 << 1), DESTROY mode during unit placement (clicking an own unit sends $91 and clears it)",
"confidence": "high"
},
{
"addr": "0BA3",
"scope": "abs",
"name": "gameTypeOptions",
"meaning": "bits 0-2 game type (0 SCRIMAGE .. 6 DEFENDER, names at $CCC8), bit 3 UNIT MENUS, bit 4 DAMAGE (both edited by editOptionBitOnOff), bit 6 CUSTOM rules, bit 7 custom MAP (adds 'MAP,' to the custom summary)",
"confidence": "medium"
},
{
"addr": "0B9F",
"scope": "abs",
"name": "playerSide",
"meaning": "local side 0/1; EOR 1 = opponent (index into the per-side tables $92A6/$92AC)",
"confidence": "high"
},
{
"addr": "0BA5",
"scope": "abs",
"name": "commBuildFlag",
"meaning": "bit 7 = comm build 1 (T35, solo trainer) resident: sub_8378 then forces recycler mode NONE for both sides",
"confidence": "medium"
},
{
"addr": "92A1",
"scope": "abs",
"name": "persistentMessageId",
"meaning": "id of the status-line message that stays/returns after transient messages (0 none, $0A 'SETUP UNITS...', $1E the dynamic slot used by this code)",
"confidence": "high"
},
{
"addr": "92A6",
"scope": "abs",
"name": "recyclerModeBySide",
"meaning": "2 bytes: recycler setting per side, 0 FULL, 1 HALF, 2 NONE (words at $0652); chosen in sub_8378 and sent with command $9C",
"confidence": "high"
},
{
"addr": "92AC",
"scope": "abs",
"name": "terrainPointsBySide",
"meaning": "2 bytes: 'TERRAIN PTS' (0..2) per side, edited by editTerrainPoints for the opponent index and sent as $A5 kind 1",
"confidence": "medium"
},
{
"addr": "92AE",
"scope": "abs",
"name": "dronesLeft",
"meaning": "2 bytes (own, opponent): number of drones, 'DRONES' custom option 0..9, sent as the x byte of command $90 during setup",
"confidence": "high"
},
{
"addr": "92B0",
"scope": "abs",
"name": "missilesLeft",
"meaning": "2 bytes: number of missiles, 'MISSILES' custom option 0..36, sent as the y byte of command $90 during setup",
"confidence": "high"
},
{
"addr": "92B4",
"scope": "abs",
"name": "comcenSpeedSetting",
"meaning": "2 bytes per side: 'COMCEN SPEED' option 0..3 at setup time (sent as $A5 kind 3), later replaced by the speed class looked up at $7B6E",
"confidence": "medium"
},
{
"addr": "91D4",
"scope": "abs",
"name": "menuItemCount",
"meaning": "number of rows of the current menu (2 for OFF/ON and STANDARD/CUSTOM, 3 for the recycler mode menu)",
"confidence": "high"
},
{
"addr": "91D5",
"scope": "abs",
"name": "menuSelectedItem",
"meaning": "highlighted/chosen menu row; the value editors keep it at 0 (single row)",
"confidence": "high"
},
{
"addr": "91D6",
"scope": "abs",
"name": "menuFirstRow",
"meaning": "screen row of menu row 0 (the value editors use the row below the label)",
"confidence": "high"
},
{
"addr": "91D8",
"scope": "abs",
"name": "pickedCellX",
"meaning": "map column returned by runTargetCursorLoop in free-pick mode (recycler location)",
"confidence": "high"
},
{
"addr": "91D9",
"scope": "abs",
"name": "pickedCellY",
"meaning": "map row returned by runTargetCursorLoop in free-pick mode",
"confidence": "high"
},
{
"addr": "92C5",
"scope": "abs",
"name": "menuBlinkState",
"meaning": "0 while the menu row is drawn highlighted, 1 normal; editValueWithJoystick sets 1 before redrawing the value",
"confidence": "high"
},
{
"addr": "9248",
"scope": "abs",
"name": "lastKeyCode",
"meaning": "last typed key with bit 7 set ($AA = '*'), $FF = none; consumed by handleStarKeyToggle",
"confidence": "high"
},
{
"addr": "929C",
"scope": "abs",
"name": "chatState",
"meaning": "bit 7 set = chat text entry in progress; handleStarKeyToggle ignores keys then",
"confidence": "medium"
},
{
"addr": "9251",
"scope": "abs",
"name": "messageQueueHead",
"meaning": "message queue index; showToggleStateMessage copies it to the tail to flush the queue",
"confidence": "medium"
},
{
"addr": "9252",
"scope": "abs",
"name": "messageQueueTail",
"meaning": "message queue index (8-entry queue at $9249)",
"confidence": "medium"
},
{
"addr": "9242",
"scope": "abs",
"name": "unitDrawOverride",
"meaning": "set to $FE by sub_8364 together with selectedUnit while the viewport is hidden",
"confidence": "low"
},
{
"addr": "90F8",
"scope": "abs",
"name": "selectedUnit",
"meaning": "unit the menus act on; $FE = plain menu without a unit (set by beginValueEdit and sub_8364)",
"confidence": "high"
},
{
"addr": "90FB",
"scope": "abs",
"name": "currentScreen",
"meaning": "0 = battlefield screen; sub_8364 forces it to 0",
"confidence": "high"
},
{
"addr": "90EF",
"scope": "abs",
"name": "textCentreWidth",
"meaning": "nonzero = the next string is centred in this many columns (13 for the banner words, zp_3C via sub_C121)",
"confidence": "high"
},
{
"addr": "9022",
"scope": "abs",
"name": "spriteEnableShadow",
"meaning": "shadow of $D015; cleared after the recycler has been located",
"confidence": "high"
},
{
"addr": "FA70",
"scope": "abs",
"name": "unitUnderCellAlias",
"meaning": "terrain under a unit indexed by the raw map byte ($80|unit); sub_8378 uses it so a cell occupied by a unit counts as its underlying terrain when checking for a plain ($40) recycler site",
"confidence": "high"
},
{
"addr": "0332",
"scope": "abs",
"name": "customSummaryText",
"meaning": "text buffer (in the $0200 setup block area) that receives 'CUSTOM:[MAP,] MENUS xxx, DAMAGE xxx.' built by showCustomSummaryMessage; registered as message slot $1E",
"confidence": "high"
},
{
"addr": "0636",
"scope": "abs",
"name": "optionSummaryTemplate",
"meaning": "23-byte template ' MENUS XXXX DAMAGE XXX.' (bit-7 terminated) whose XXXX/XXX fields are filled with OFF,/ON, by appendOnOffWord",
"confidence": "high"
},
{
"addr": "064D",
"scope": "abs",
"name": "wordOff",
"meaning": "'OFF' (bit-7 terminated), followed by 'ON' at $0650 and the option words FULL/HALF/NONE at $0652",
"confidence": "high"
},
{
"addr": "0650",
"scope": "abs",
"name": "wordOn",
"meaning": "'ON' (bit-7 terminated); 3 bytes from here (O, N|$80, F) are copied over the OFF in the CUSTOM/DESTROY message",
"confidence": "high"
},
{
"addr": "0500",
"scope": "abs",
"name": "messagePtrLo",
"meaning": "low bytes of the status message pointer table indexed by message id (high bytes at $0524); slot $1E is rewritten at run time by sub_C924 from this overlay",
"confidence": "high"
},
{
"addr": "EFDF",
"scope": "abs",
"name": "customOnOffWord",
"meaning": "the 'OFF' inside 'CUSTOM OFF' ($EFD8, T34 $EC00 sub-overlay), overwritten with ON/OFF by showToggleStateMessage while the setup screen uses it",
"confidence": "high"
},
{
"addr": "EFEA",
"scope": "abs",
"name": "destroyOnOffWord",
"meaning": "the 'OFF' inside 'DESTROY OFF' ($EFE2), overwritten with ON/OFF by showToggleStateMessage during unit placement",
"confidence": "high"
},
{
"addr": "3B",
"scope": "zp",
"name": "textWindowLeft",
"meaning": "text window left column (28 for the OFF/ON and STANDARD/CUSTOM menus, 29 for the value editors, 30 for the recycler menu; decremented once more before the menu loop)",
"confidence": "high"
},
{
"addr": "3C",
"scope": "zp",
"name": "textWindowWidth",
"meaning": "text window width = width of the menu highlight bar (5 value editor / OFF-ON, 10 STANDARD/CUSTOM, 6 recycler) and centring width for sub_C121",
"confidence": "high"
},
{
"addr": "3D",
"scope": "zp",
"name": "textColour",
"meaning": "text colour byte (8 for all panels drawn by this code)",
"confidence": "high"
},
{
"addr": "3F",
"scope": "zp",
"name": "textCursorCol",
"meaning": "text cursor column relative to the window (1 for the value)",
"confidence": "high"
},
{
"addr": "40",
"scope": "zp",
"name": "textCursorRow",
"meaning": "text cursor row; copied into menuFirstRow",
"confidence": "high"
},
{
"addr": "42",
"scope": "zp",
"name": "textPadColour",
"meaning": "colour of centring padding, kept equal to textColour (8)",
"confidence": "high"
},
{
"addr": "48",
"scope": "zp",
"name": "wordPtr",
"meaning": "in this chunk: pointer (lo) to the ON/OFF word copied by showToggleStateMessage (general fill/map pointer elsewhere)",
"confidence": "high"
},
{
"addr": "49",
"scope": "zp",
"name": "wordPtrHi",
"meaning": "high byte of wordPtr",
"confidence": "high"
},
{
"addr": "5D",
"scope": "zp",
"name": "joyDirection",
"meaning": "joystick direction bits, active low, $0F centred; the value editor ORs with $0C and maps up/down to +1/-1",
"confidence": "high"
},
{
"addr": "6C",
"scope": "zp",
"name": "joyRepeatTimer",
"meaning": "frame countdown gating joystick auto-repeat in the value editor",
"confidence": "high"
},
{
"addr": "6E",
"scope": "zp",
"name": "menuBlinkTimer",
"meaning": "frame countdown; when 0 the value editor toggles the row highlight",
"confidence": "high"
},
{
"addr": "72",
"scope": "zp",
"name": "messageTimer",
"meaning": "status message countdown, cleared by showToggleStateMessage so the new message appears at once",
"confidence": "medium"
},
{
"addr": "73",
"scope": "zp",
"name": "cmdParam0",
"meaning": "first parameter of an outgoing command (recycler mode for $9C)",
"confidence": "high"
},
{
"addr": "74",
"scope": "zp",
"name": "cmdParam1",
"meaning": "second command parameter (option kind for $A5, drones for $90, x for $9C)",
"confidence": "high"
},
{
"addr": "75",
"scope": "zp",
"name": "cmdParam2",
"meaning": "third command parameter (option value for $A5, missiles for $90, y for $9C)",
"confidence": "high"
},
{
"addr": "A5",
"scope": "zp",
"name": "viewOriginCol",
"meaning": "map column of the viewport's left edge; sub_8364 parks it at 45 (off the map) to blank the viewport",
"confidence": "high"
},
{
"addr": "A6",
"scope": "zp",
"name": "viewOriginRow",
"meaning": "map row of the viewport's top edge; 45 = viewport blanked",
"confidence": "high"
},
{
"addr": "B1",
"scope": "zp",
"name": "gamePhase",
"meaning": "0 battle; $7F during the game-start option dialogs (runGameStartOptions), $3F/$FF during unit placement where handleStarKeyToggle is polled",
"confidence": "high"
},
{
"addr": "BB",
"scope": "zp",
"name": "cursorTargetMode",
"meaning": "$FF = free cell pick for runTargetCursorLoop (recycler location)",
"confidence": "high"
},
{
"addr": "18",
"scope": "zp",
"name": "productLo",
"meaning": "low byte of the multiply8x8 product (unused here; A already holds it)",
"confidence": "medium"
}
],
"dataBlocks": [
{
"addr": "844F",
"length": 1,
"type": "byteTable",
"name": "editValue",
"description": "current value of the joystick value editor"
},
{
"addr": "8450",
"length": 1,
"type": "byteTable",
"name": "customSetupChosen",
"description": "nonzero = CUSTOM options chosen at game start"
},
{
"addr": "879F",
"length": 13,
"type": "text",
"name": "msgWonOnPointsTail",
"description": "'ON ON POINTS!' - the tail of message $12 'WE WON ON POINTS!' whose first four bytes ($879B-$879E) are overlaid by code in variant A (pla / jmp sub_C100); overlay variant B holds the complete string at $879B. Message pointer table slots $11-$16 ($0500/$0524) point to $8789, $879B, $87AC, $87BA, $87CE, $87E3 and are only valid with variant B resident."
},
{
"addr": "87AC",
"length": 14,
"type": "text",
"name": "msgItWasADraw",
"description": "'IT WAS A DRAW.' = message $13 (game result)"
},
{
"addr": "87BA",
"length": 20,
"type": "text",
"name": "msgWeWereKnockedOut",
"description": "'WE WERE KNOCKED OUT!' = message $14"
},
{
"addr": "87CE",
"length": 21,
"type": "text",
"name": "msgWeWonByKnockout",
"description": "'WE WON BY A KNOCKOUT!' = message $15. Comm build 1 (T35, solo trainer) reuses $87CE+unit as a per-unit work table ($EB29/$EB53 store the game clock there), so with the trainer resident these strings are clobbered."
},
{
"addr": "87E3",
"length": 10,
"type": "text",
"name": "msgGameOver",
"description": "'GAME OVER.' = message $16"
},
{
"addr": "87ED",
"length": 12,
"type": "text",
"name": "msgDroneAlert",
"description": "'DRONE ALERT!' - installed as message slot $20 by overlay A at $7BA6 (sub_C924 X=$20)"
},
{
"addr": "87F9",
"length": 6,
"type": "unknown",
"name": "overlayTailPadding",
"description": "six zero bytes of padding before the variant flag"
},
{
"addr": "87FF",
"length": 1,
"type": "byteTable",
"name": "overlayVariantFlag",
"description": "$00 = variant A, $FF = variant B (bit 7 tested by the main program at $1036/$1080)"
}
],
"misclassified": [],
"insights": [
"Chunk location: the task quoted file lines 2896-3677 but in disassembly/game/ovl_6F00_A.s the address range $844F-$87FF is at lines 3198-3676 (lines 2896-3197 hold $820B-$844E); this survey covers the address range.",
"This chunk is the custom-scenario option dialog of overlay A, run once per new game from $7AF7 (runGameStartOptions). Dialog order: banner 'STANDARD/CUSTOM <game type> SCENARIO' + 'PRESS BUTTON WHEN READY.'; if CUSTOM rules are on: STANDARD/CUSTOM menu, then COMCEN SPEED (0-3), TERRAIN PTS (0-2), DRONES (0-9) and MISSILES (0-36); for game types 4-6 the recycler (mode FULL/HALF/NONE only in custom mode, then 'LOCATING RECYCLER' free cell pick on a plain cell, command $9C mode x y); finally the handicap (default 2 = 20 points for side 0 in QB SNEAK, 20 = 200 points for side 1 in DEFENDER, or custom 0-500 step 10) as command $A5 kind 0. The values reach both machines only through the lock-step commands $A5 kind/value, $90 drones/missiles and $9C.",
"Value editor pattern: beginValueEdit(A/Y label, X start) + editValueWithJoystick(A limit, Y display multiplier) -> D_844F. The editor is a one-row 'menu' (width 5 at column 29) so it reuses the menu highlight/blink code (sub_60E5/sub_60EA, D_92C5, zp_6E). The display multiplies with multiply8x8 ($FCCD), which returns A = product low byte and Y = high byte (the game_high_FBB8 survey's description 'A = Y = high byte' is inverted) and prints via sub_C17D(A=lo, Y=hi).",
"The '*' key toggle (handleStarKeyToggle, $8658) is the overlay-A hook behind the main program's trampoline sub_25C4 and the runMenuLoop call at $6002. D_92F3 bit 7 is reused for two meanings: CUSTOM rules on the scenario setup screen ($821F initialises it from D_0BA3 bit 6 and message text 'CUSTOM OFF' $EFD8) and DESTROY mode during unit placement (setDestroyModeMessage $86AA selects 'DESTROY OFF' $EFE2; with the flag set a click on an own unit sends $91 self destruct at $209F). The ON/OFF word is patched directly into the string in the T34 $EC00 sub-overlay ($EFDF / $EFEA) using the words at $064D/$0650, and the message is always slot $1E, which is a run-time slot (pointer $FFFF on disk) rewritten with sub_C924; persistentMessageId D_92A1 decides what the status line falls back to.",
"Message slot $1E is the overlay's scratch message: 'PRESS BUTTON WHEN READY.' ($CBBE), the 'CUSTOM:MAP, MENUS ON, DAMAGE OFF.' summary built at $0332 from the template at $0636, 'CUSTOM ON/OFF' or 'DESTROY ON/OFF'. Slot $20 is set to 'DRONE ALERT!' ($87ED) at $7BA6.",
"gameTypeOptions D_0BA3 bit map as used here: bits 0-2 game type, bit 3 UNIT MENUS (editOptionBitOnOff with label $EF9B), bit 4 DAMAGE (label $EFA7), bit 6 CUSTOM rules (banner word, D_8450, D_92F3), bit 7 custom MAP (adds 'MAP,' to the summary; corresponds to the $A6 custom map seed command / D_0B9D).",
"Labels sub_84F1, sub_8518, sub_8601, sub_862D and sub_8632 are entry points of overlay variant B only (the main program's JSR $8518 at $1460/$14D3 and JSR $8632 at $176B target variant B code); in variant A they fall in the middle of editTerrainPoints, editDronesAndMissiles, beginValueEdit and editOptionBitOnOff. Likewise the XREF callers 83A1/83DE listed for $84B2/$84F1 are variant-B call sites.",
"The game-result strings at $879B-$87EC (message ids $11-$16 via the pointer table at $0500/$0524) and the variant flag $87FF are the shared tail of both overlay variants; variant A's code runs through $879E, so message $11 ($8789) and the first four bytes of message $12 are code in A. They are only displayed during battle when variant B is resident, so no visible corruption results. The $0332 buffer used for the custom summary lives in the $0200-$03FF setup block area and is not referenced by anything else (XREF)."
]
}