{ "chunk": "data_map_F000", "unit": "game/map_F000", "routines": [], "variables": [], "dataBlocks": [ { "addr": "F000", "length": 400, "type": "byteTable", "name": "unitStartTemplate0", "description": "Unit start-position template 0 (400 bytes = four parallel 100-entry arrays, one entry per unit 0-99): +0 unitCol (values 3-36), +100 unitRow (side 0 units 0-49 in rows 20-33, side 1 units 50-99 in rows 6-19), +200 unitFlags (bits 0-1 facing - 0 for side 0, 1 for side 1; bit 5 set on every side-1 unit; bit 6 = 'belongs to a group'; bits 2-4 = group id 0-7, so $40+4*g on side 0 and $61+4*g on side 1, and $00/$21 for ungrouped units), +300 unitType ($10+type for side 0 and $18+type for side 1, type 0 GRUNT .. 4 COMCEN, $FF = slot not in play). FULL WAR / DEFENDER roster: 28 GRUNT, 12 RIDER, 6 BOOMER, 3 SPY, 1 COMCEN per side (all 50 slots used). Groups 0-5 are populated (flags $40,$44,$48,$4C,$50,$54 on side 0), 22 units are ungrouped. loadUnitStartTemplate ($ECF3, in the comm-module tail) copies 512 bytes from $F000 + 400*n to $F640 once per session, where n = unitLayoutByGameType[$78B8 + gameType & 7] = 2,2,2,1,3,0,0." }, { "addr": "F190", "length": 400, "type": "byteTable", "name": "unitStartTemplate1", "description": "Unit start-position template 1 (400 bytes = four parallel 100-entry arrays, one entry per unit 0-99): +0 unitCol (values 3-36), +100 unitRow (side 0 units 0-49 in rows 20-33, side 1 units 50-99 in rows 6-19), +200 unitFlags (bits 0-1 facing - 0 for side 0, 1 for side 1; bit 5 set on every side-1 unit; bit 6 = 'belongs to a group'; bits 2-4 = group id 0-7, so $40+4*g on side 0 and $61+4*g on side 1, and $00/$21 for ungrouped units), +300 unitType ($10+type for side 0 and $18+type for side 1, type 0 GRUNT .. 4 COMCEN, $FF = slot not in play). FACE-OFF roster: 28 RIDER, 3 SPY, 1 COMCEN per side, 18 slots marked $FF (not in play). Groups 0-7 used. loadUnitStartTemplate ($ECF3, in the comm-module tail) copies 512 bytes from $F000 + 400*n to $F640 once per session, where n = unitLayoutByGameType[$78B8 + gameType & 7] = 2,2,2,1,3,0,0." }, { "addr": "F320", "length": 400, "type": "byteTable", "name": "unitStartTemplate2", "description": "Unit start-position template 2 (400 bytes = four parallel 100-entry arrays, one entry per unit 0-99): +0 unitCol (values 3-36), +100 unitRow (side 0 units 0-49 in rows 20-33, side 1 units 50-99 in rows 6-19), +200 unitFlags (bits 0-1 facing - 0 for side 0, 1 for side 1; bit 5 set on every side-1 unit; bit 6 = 'belongs to a group'; bits 2-4 = group id 0-7, so $40+4*g on side 0 and $61+4*g on side 1, and $00/$21 for ungrouped units), +300 unitType ($10+type for side 0 and $18+type for side 1, type 0 GRUNT .. 4 COMCEN, $FF = slot not in play). SCRIMAGE / QB SNEAK / THE BOMB roster: 5 GRUNT, 5 RIDER and 1 COMCEN per side, 39 slots $FF. No unit belongs to a group (flags $00 on side 0, $21 on side 1). applyGameTypeDefaults then removes units 0-6 for QB SNEAK and everything except the two comcens for THE BOMB. loadUnitStartTemplate ($ECF3, in the comm-module tail) copies 512 bytes from $F000 + 400*n to $F640 once per session, where n = unitLayoutByGameType[$78B8 + gameType & 7] = 2,2,2,1,3,0,0." }, { "addr": "F4B0", "length": 400, "type": "byteTable", "name": "unitStartTemplate3", "description": "Unit start-position template 3 (400 bytes = four parallel 100-entry arrays, one entry per unit 0-99): +0 unitCol (values 3-36), +100 unitRow (side 0 units 0-49 in rows 20-33, side 1 units 50-99 in rows 6-19), +200 unitFlags (bits 0-1 facing - 0 for side 0, 1 for side 1; bit 5 set on every side-1 unit; bit 6 = 'belongs to a group'; bits 2-4 = group id 0-7, so $40+4*g on side 0 and $61+4*g on side 1, and $00/$21 for ungrouped units), +300 unitType ($10+type for side 0 and $18+type for side 1, type 0 GRUNT .. 4 COMCEN, $FF = slot not in play). SLUGGERS roster: 12 GRUNT, 12 RIDER, 4 BOOMER, 3 SPY, 1 COMCEN per side, 18 slots $FF. Groups 0-7 used. loadUnitStartTemplate ($ECF3, in the comm-module tail) copies 512 bytes from $F000 + 400*n to $F640 once per session, where n = unitLayoutByGameType[$78B8 + gameType & 7] = 2,2,2,1,3,0,0." }, { "addr": "F640", "length": 192, "type": "unknown", "name": "mapBlockTail", "description": "The last 192 bytes of track 18 sectors 8-14 are not part of any template - they are a fragment of 6502 code left in the mastering machine's memory. Disassembled it is an EARLIER version of printOptionsList ($19F3 in the shipped build): it sets a text window at column $0C rows 9-$12 with colour $61, prints a string at $CAB2, tests $92CD and $0881, prints $6610, checks the link flag $E03B, prints $6698 and $CA53, then falls into a film-slot routine that writes $91D5/$91D6/$91D7, calls $C097, $5F41, $1205 and jumps to $1648. The shipped build keeps the same flags at $0B94-$0BA8 and the same strings at $CC.. instead of $0876../$66.., so this code is from a different (older) build. At run time the area is unitCol[0..99] ($F640) and unitRow[0..99] ($F6A4), and startGameSession deliberately stores $FF into $F640 before calling loadUnitStartTemplate so the copy always happens. (confidence: high that it is leftover code, medium on which build)" } ], "misclassified": [], "insights": [ "Track 18 sectors 8-14 = four canned starting deployments of 400 bytes each at $F000, $F190, $F320, $F4B0, plus 192 bytes of leftover. Each is four 100-entry arrays: unitCol, unitRow, unitFlags, unitType - exactly the first four of the fourteen 100-byte unit-record arrays that live at $F640, $F6A4, $F708 and $F76C at run time.", "unitLayoutByGameType ($78B8 in overlay A) maps the seven game types to these templates: SCRIMAGE, QB SNEAK and THE BOMB -> template 2 (11 units a side), FACE-OFF -> template 1 (all riders), SLUGGERS -> template 3, FULL WAR and DEFENDER -> template 0 (the full 50-unit roster 28/12/6/3/1).", "The standard full roster is 28 GRUNT + 12 RIDER + 6 BOOMER + 3 SPY + 1 COMCEN = 50 units per side, and unit 49 / unit 99 really are the two command centres in the shipped data.", "unitFlags encoding read straight off the templates: bits 0-1 facing, bit 5 set for every side-1 unit, bit 6 'is in a group', bits 2-4 the group id 0-7 (matching the seven group names ALPHA..GROVER at $C92C). Side 0 values are $40+4*g and side 1 values $61+4*g, with $00/$21 for ungrouped units.", "The templates place side 0 (units 0-49) in map rows 20-33 and side 1 (units 50-99) in rows 6-19, i.e. each side starts inside its own half of the 40x40 field, and columns span 3-36.", "The 192-byte tail at $F640 is a fragment of an older build of the game's own options-menu code (an earlier printOptionsList that uses flags at $0876-$0881 and strings at $6610/$6698 instead of the shipped $0B94-$0BA8 / $CCxx), which dates this disk block to a snapshot taken on the development machine.", "Nothing on the disk is a battlefield map: the map is always generated from a 24-bit seed by generateBattlefieldMap, which overwrites $F000-$F63F before the first frame.", "battlefieldMapF000.s is headed '$F000-$F63F is the 40x40 map, one byte per cell', and the loader routine is called loadMapAndSetup_10AB. That describes the RUN-TIME use of the memory, not the disk contents: track 18 sectors 8-14 hold four 400-byte unit start-position templates, not a map. Proof: (1) 80 percent (1279 of 1600) of the 1600 bytes are outside the legal terrain range $21-$6B (many are $00-$20, and $6D/$71/$75/$79 are above the top code $6B), so rendering it through terrainClassTable produces noise; (2) the 100-byte structure is exact - four repetitions of col/row/flags/type, with the type arrays containing only $10-$14, $18-$1C and $FF; (3) loadUnitStartTemplate ($ECF3) copies from $F000 + 400*n; (4) the destination-column and destination-row halves of solo-trainer play 0 ($0232/$0264 in the track 29 playbook) appear verbatim inside template 2 at $F360 and $F3C8.", "The labels in battlefieldMapF000.s from $F640 on (unitColTable, side0ComcenCol $F671, side1UnitColTable $F672, unitFlagsTableAlias $F688, side1ComcenCol $F6A3, unitRowTable $F6A4, side0ComcenRow $F6D5, side1UnitRowTable $F6D6, unitTypeTableAlias $F6EC - and the older D_F640/D_F671/... names still in XREF.txt) describe the RUN-TIME unit-record arrays, which is right; but the bytes printed under them are the leftover code fragment, not array data. Likewise D_F30B/D_F333/D_F334 (written by the map generator at $6F81-$6F8B) and D_F600 (read/written at $7536/$7541) are run-time map cells that happen to fall inside unit start-position templates 1 and 3 on the disk." ] }