; ============================================================================
; $F000-$F6FF - unit start-position templates (track 18 sectors 8-14)
; ============================================================================
; What is STORED here is four 400-byte templates at $F000, $F190, $F320 and $F4B0; each is four parallel
; 100-entry arrays - starting column, starting row, flags (facing in bits 0-1, side in bit 5, grouped in
; bit 6, group id in bits 2-4) and unit type. One template is chosen per game type and copied into the
; live unit arrays. The standard roster is 28 GRUNT, 12 RIDER, 6 BOOMER, 3 SPY and 1 COMCEN per side.
; What the same addresses hold at RUN TIME is different: $F000-$F63F becomes the 40x40 battlefield map
; (one byte per cell) and the unit record arrays start at $F640 in 100-byte slices, so the templates are
; overwritten as soon as a game starts.
; The 192 bytes at $F640-$F6FF are not used at all: they are a fragment of an older build of the game's
; own options-list printer, left in the sector by the development system.

        .setcpu "6502"
        .include "c64.inc"
        .include "zeropage.inc"

        .org $F000


; unitStartTemplatesF000 - the whole file.  Track 18 sectors 8-14 hold pure data: four 400-byte unit
; start-position templates at $F000, $F190, $F320 and $F4B0, followed by 192 bytes at $F640-$F6FF that
; are not data at all but a fragment of an older build's code (see the note there).  Nothing in this
; file is a battlefield: the 40x40 map that occupies $F000-$F63F at run time is built from the 24-bit
; map seed by generateBattlefieldMap ($6F04) and overwrites all four templates before the first frame.
; Loaded by loadMapAndSetup ($10AB): setLoadDest $F000, then 7 sectors from track 18 sector 8, once
; per session from startGameFromSetup ($0B35). Read by exactly one routine, loadUnitStartTemplate
; ($ECF3, in the comm tail that track 34 sectors 12-15 put at $EC00), which overlay A calls at $79E6
; and $82FD: n = unitLayoutByGameType[$78B8 + (gameTypeOptions $0BA3 & 7)] = 2,2,2,1,3,0,0 for game
; types 0-6, and it then copies two whole pages (512 bytes) from $F000 + 400*n to $F640, where the
; live unit records begin.  Only the first 400 bytes are the template; the extra 112 bytes overwrite
; unitDestCol ($F7D0-$F833) and the first twelve entries of unitDestRow ($F834-$F83F), which
; initAllUnits rewrites at once, so the spill is harmless.  For templates 0-2 the spill is the head of
; the next template; for template 3 the source ($F4B0-$F6AF) overlaps the destination ($F640-$F83F)
; and, because the copy runs upwards, it re-reads what it has just written and duplicates template 3's
; own first 112 bytes - which is also why the leftover code at $F640-$F6AF is destroyed before it
; could ever be read as data. The copy is guarded by 'bit 7 of $F640 set' = 'the arrays still hold the
; disk image'.  As loaded from disk $F640 is $0A (an opcode of the leftover code), which fails that
; test, so startGameSession stores $FF there first ($78E4). Game type -> template: 0 SCRIMAGE, 1 QB
; SNEAK, 2 THE BOMB -> template 2; 3 FACE-OFF -> template 1; 4 SLUGGERS -> template 3; 5 FULL WAR, 6
; DEFENDER -> template 0.  (There is no game type 7; it would index $78BF = $04 and copy from $F000 +
; 1600 = $F640.) Each template is four parallel 100-entry arrays - +$000 starting column, +$064
; starting row, +$0C8 flags, +$12C type - i.e. exactly the first four of the fourteen 100-byte
; unit-record arrays that live from $F640 upwards $64 apart.  Entry i describes unit i: 0-49 side 0,
; 50-99 side 1, 49 and 99 the two COMCENs.  Coordinates are cells of the 40x40 field: columns 3-36,
; side 0 in the bottom half (rows 20-33), side 1 in the top half (rows 6-19).  Player 1's machine
; rotates the map and every unit coordinate to 39-x (rotateMapAndMirrorCodes $EC58,
; mirrorAllUnitCoordinates $EC91), so both players see their own army at the bottom. How much of a
; template survives the copy: initAllUnits ($3D8A) -> initUnitRecord ($3DA0) keeps the column, the
; row, flags bits 2-4 (group id) and bit 6 (belongs to a group), and type bits 0-2 (the unit type)
; plus bit 7 ($FF = empty slot).  It rebuilds the facing (flags bits 0-1) and the side (flags bit 5)
; from the unit index and clears type bits 3-4, so those bits of the stored data are consistent with
; the rest but are never actually used. unitStartTemplate0 ($F000-$F18F) - the full roster, used by
; game types 5 FULL WAR and 6 DEFENDER.  All 100 slots are in play: per side 28 GRUNT (units 0-27), 12
; RIDER (28-39), 6 BOOMER (40-45), 3 SPY (46-48) and 1 COMCEN (49).  Three wings, each an eleven-unit
; group of nine grunts and two boomers in rows 25-28 with a four-rider group in front of it in rows
; 30-31.  Side 0: group 3 DELTA = units 4,7,10,11,14,15,18,19,20,40,44 on the left (columns 3-7),
; group 4 EASY = 1,2,3,13,16,17,22,23,27,41,45 in the centre (17-21), group 5 FOXTROT =
; 0,5,8,9,12,21,24,25,26,42,43 on the right (32-36); rider group 0 ALPHA = 28,29,30,32 (columns 5-6),
; 1 BAKER = 31,33,34,37 (19-20), 2 CHARLIE = 35,36,38,39 (33-34).  Loose (flags $00): the three spies
; 46-48 in row 23, and in the back row 33 the COMCEN 49 at column 20 with one GRUNT, unit 6, beside it
; at column 19.  Side 1 is the exact 180-degree mirror of side 0 as a formation - every
; (column,row,type,group) of side 0 occurs on side 1 as (39-column, 39-row, same type, same group) -
; but the indices within a group are not mirrored, so unit i+50 is not the mirror image of unit i.
unitStartTemplate0:
        .byte   $22,$13,$11,$13,$04,$23,$13,$03,$24,$21; F000  "....#..$!  unitCol[0-49]: side 0's starting map column, ten units per row; the last entry is the COMCEN
        .byte   $05,$07,$21,$12,$06,$05,$14,$13,$04,$06; F00A  ..!.......
        .byte   $05,$22,$14,$12,$22,$20,$23,$15,$06,$05; F014  .".." #...
        .byte   $06,$13,$05,$13,$14,$22,$22,$14,$21,$21; F01E  ....."".!!
        .byte   $06,$14,$21,$23,$04,$12,$13,$22,$05,$14; F028  ..!#..."..
        .byte   $06,$07,$23,$05,$04,$03,$22,$22,$06,$12; F032  ..#...""..  unitCol[50-99]: side 1's columns; the last entry is unit 99, side 1's COMCEN
        .byte   $15,$16,$13,$14,$21,$13,$04,$24,$14,$23; F03C  ....!..$.#
        .byte   $22,$21,$20,$15,$05,$14,$05,$14,$22,$21; F046  "! ....."!
        .byte   $14,$13,$14,$22,$21,$05,$05,$06,$06,$13; F050  ..."!.....
        .byte   $13,$23,$21,$15,$04,$06,$22,$14,$05,$13; F05A  .#!..."...

; unitRow - array 2 of 4 ($F064-$F0C7): the starting map row 0-39 of each unit, copied to unitRowTable
; $F6A4.  Side 0 occupies rows 23-33 in this template and side 1 the mirrored rows 6-16.
template0StartRow:
        .byte   $1B,$19,$1B,$1A,$1A,$1B,$21,$1B,$1B,$1A; F064  ......!...  unitRow[0-49]: side 0's rows, the bottom half of the field
        .byte   $19,$1B,$1B,$1A,$1B,$1A,$1A,$1B,$1B,$1A; F06E  ..........
        .byte   $1B,$19,$1B,$1B,$1A,$1B,$1A,$1B,$1F,$1E; F078  ..........
        .byte   $1E,$1F,$1F,$1E,$1E,$1F,$1E,$1F,$1F,$1E; F082  ..........
        .byte   $1C,$1C,$1C,$1C,$1C,$1C,$17,$17,$17,$21; F08C  .........!
        .byte   $0D,$0C,$0D,$0C,$0D,$0C,$0E,$0D,$0C,$0C; F096  ..........  unitRow[50-99]: side 1's rows, the 39-row mirror of side 0's
        .byte   $0C,$0C,$0D,$0C,$0D,$0C,$0C,$0C,$06,$0C; F0A0  ..........
        .byte   $0C,$0C,$0C,$0D,$0D,$0E,$0E,$0D,$09,$09; F0AA  ..........
        .byte   $08,$09,$09,$08,$08,$09,$08,$09,$08,$08; F0B4  ..........
        .byte   $0B,$0B,$0B,$0B,$0B,$0B,$10,$10,$10,$06; F0BE  ..........

; unitFlags - array 3 of 4 ($F0C8-$F12B): bits 0-1 facing (0 = up, 1 = down), bits 2-4 group id 0-6 =
; ALPHA, BAKER, CHARLIE, DELTA, EASY, FOXTROT, GROVER (names at $C92C), bit 5 side, bit 6 = belongs to
; a group, bit 7 (the blitz charge at run time) always 0 here.  So a side-0 entry is $00 when loose
; and $40 + 4*g in group g; a side-1 entry is $21 when loose and $61 + 4*g in group g.  Copied to
; unitFlagsTable $F708; initUnitRecord ($3DC6) keeps only bits 2-4 and 6 and rebuilds facing and side
; from the unit index, so the group id and the group-member bit are the only part that matters.
template0StartFlags:
        .byte   $54,$50,$50,$50,$4C,$54,$00,$4C,$54,$54; F0C8  TPPPLT.LTT  unitFlags[0-49]: side 0 - $00 loose, $40/$44/$48/$4C/$50/$54 = groups ALPHA..FOXTROT
        .byte   $4C,$4C,$54,$50,$4C,$4C,$50,$50,$4C,$4C; F0D2  LLTPLLPPLL
        .byte   $4C,$54,$50,$50,$54,$54,$54,$50,$40,$40; F0DC  LTPPTTTP@@
        .byte   $40,$44,$40,$44,$44,$48,$48,$44,$48,$48; F0E6  @D@DDHHDHH
        .byte   $4C,$50,$54,$54,$4C,$50,$00,$00,$00,$00; F0F0  LPTTLP....
        .byte   $75,$75,$6D,$75,$75,$75,$6D,$6D,$75,$71; F0FA  uumuuummuq  unitFlags[50-99]: side 1 - $21 loose, $61/$65/$69/$6D/$71/$75 = the same six groups
        .byte   $71,$71,$71,$71,$6D,$71,$75,$6D,$21,$6D; F104  qqqqmqum!m
        .byte   $6D,$6D,$6D,$71,$75,$71,$75,$71,$61,$61; F10E  mmmququqaa
        .byte   $65,$65,$65,$61,$61,$69,$69,$69,$69,$65; F118  eeeaaiiiie
        .byte   $71,$6D,$6D,$71,$75,$75,$21,$21,$21,$21; F122  qmmquu!!!!

; unitType - array 4 of 4 ($F12C-$F18F): $10 + type for a side-0 unit and $18 + type for a side-1
; unit, type 0 GRUNT, 1 RIDER, 2 BOOMER, 3 SPY, 4 COMCEN (names at $C964); $FF marks a slot that is
; not in play.  Copied to unitTypeTable $F76C.  At run time bits 3-4 of this byte are the 'has already
; scored that end zone' markers and bit 6 is 'dug in', but initUnitRecord ($3DB9) clears bits 3-4
; while it resets each unit, so of the stored value only bits 0-2 and the $FF (bit 7 =
; destroyed/empty, tested by placeUnitOnMap at $3E11) ever reach the engine.
template0StartType:
        .byte   $10,$10,$10,$10,$10,$10,$10,$10,$10,$10; F12C  ..........  unitType[0-49]: side 0 - $10 GRUNT, $11 RIDER, $12 BOOMER, $13 SPY, $14 COMCEN; 28/12/6/3/1
        .byte   $10,$10,$10,$10,$10,$10,$10,$10,$10,$10; F136  ..........
        .byte   $10,$10,$10,$10,$10,$10,$10,$10,$11,$11; F140  ..........
        .byte   $11,$11,$11,$11,$11,$11,$11,$11,$11,$11; F14A  ..........
        .byte   $12,$12,$12,$12,$12,$12,$13,$13,$13,$14; F154  ..........
        .byte   $18,$18,$18,$18,$18,$18,$18,$18,$18,$18; F15E  ..........  unitType[50-99]: side 1 - $18 GRUNT .. $1C COMCEN; the same roster as side 0
        .byte   $18,$18,$18,$18,$18,$18,$18,$18,$18,$18; F168  ..........
        .byte   $18,$18,$18,$18,$18,$18,$18,$18,$19,$19; F172  ..........
        .byte   $19,$19,$19,$19,$19,$19,$19,$19,$19,$19; F17C  ..........
        .byte   $1A,$1A,$1A,$1A,$1A,$1A,$1B,$1B,$1B,$1C; F186  ..........

; unitStartTemplate1 ($F190-$F31F) - used by game type 3 FACE-OFF only.  Roster per side: 28 RIDER
; (units 0-27), 3 SPY (46-48), 1 COMCEN (49); slots 28-45 are empty ($FF in the type array).  The
; riders form seven 2x2 squads, one per group name, drawn up in a single line: side 0 groups 0 ALPHA
; .. 6 GROVER occupy rows 22-23 at columns 22-23, 19-20, 16-17, 13-14, 10-11, 7-8 and 4-5, with the
; three spies in row 21 at columns 5, 14 and 23 and the COMCEN at (14,25).  Side 1 is the exact
; per-index 180-degree mirror: unit i+50 stands at (39-column, 39-row) of unit i and carries the same
; type and the same group id. The 18 empty slots on each side still carry column and row bytes, which
; are dead data - they are verbatim runs of template 0: entries 28-45 repeat template 0's entries 7-24
; and entries 78-95 repeat template 0's entries 57-74, in both the column and the row array.  Their
; flag bytes were cleaned to $00 / $21.  Only the $FF in the type array is read.
unitStartTemplate1:
        .byte   $16,$17,$16,$17,$13,$14,$13,$14,$10,$11; F190  ..........  unitCol[0-49] of template 1: entries 28-45 are dead slots, entry 49 the COMCEN
        .byte   $10,$11,$0D,$0E,$0D,$0E,$0A,$0B,$0A,$0B; F19A  ..........
        .byte   $07,$08,$07,$08,$04,$05,$04,$05,$03,$24; F1A4  .........$
        .byte   $21,$05,$07,$21,$12,$06,$05,$14,$13,$04; F1AE  !..!......
        .byte   $06,$05,$22,$14,$12,$22,$05,$0E,$17,$0E; F1B8  ..".."....
        .byte   $11,$10,$11,$10,$14,$13,$14,$13,$17,$16; F1C2  ..........  unitCol[50-99]: side 1's columns; entries 78-95 dead, entry 99 the COMCEN
        .byte   $17,$16,$1A,$19,$1A,$19,$1D,$1C,$1D,$1C; F1CC  ..........
        .byte   $20,$1F,$20,$1F,$23,$22,$23,$22,$22,$06; F1D6   . .#"#"".
        .byte   $12,$15,$16,$13,$14,$21,$13,$04,$24,$14; F1E0  .....!..$.
        .byte   $23,$22,$21,$20,$15,$05,$22,$19,$10,$19; F1EA  #"! .."...
template1StartRow:
        .byte   $16,$16,$17,$17,$16,$16,$17,$17,$16,$16; F1F4  ..........  unitRow[0-49] (see $F064): rider line rows 22-23, spies row 21, COMCEN row 25
        .byte   $17,$17,$16,$16,$17,$17,$16,$16,$17,$17; F1FE  ..........
        .byte   $16,$16,$17,$17,$16,$16,$17,$17,$1B,$1B; F208  ..........
        .byte   $1A,$19,$1B,$1B,$1A,$1B,$1A,$1A,$1B,$1B; F212  ..........
        .byte   $1A,$1B,$19,$1B,$1B,$1A,$15,$15,$15,$19; F21C  ..........
        .byte   $11,$11,$10,$10,$11,$11,$10,$10,$11,$11; F226  ..........  unitRow[50-99]: side 1 - rider line 16-17, spies 18, COMCEN 14
        .byte   $10,$10,$11,$11,$10,$10,$11,$11,$10,$10; F230  ..........
        .byte   $11,$11,$10,$10,$11,$11,$10,$10,$0D,$0C; F23A  ..........
        .byte   $0C,$0C,$0C,$0D,$0C,$0D,$0C,$0C,$0C,$06; F244  ..........
        .byte   $0C,$0C,$0C,$0C,$0D,$0D,$12,$12,$12,$0E; F24E  ..........
template1StartFlags:
        .byte   $40,$40,$40,$40,$44,$44,$44,$44,$48,$48; F258  @@@@DDDDHH  unitFlags[0-49] (see $F0C8): seven side-0 squads of four, $40 ALPHA .. $58 GROVER
        .byte   $48,$48,$4C,$4C,$4C,$4C,$50,$50,$50,$50; F262  HHLLLLPPPP
        .byte   $54,$54,$54,$54,$58,$58,$58,$58,$00,$00; F26C  TTTTXXXX..
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F276  ..........
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F280  ..........
        .byte   $61,$61,$61,$61,$65,$65,$65,$65,$69,$69; F28A  aaaaeeeeii  unitFlags[50-99]: the same seven squads on side 1, $61 ALPHA .. $79 GROVER
        .byte   $69,$69,$6D,$6D,$6D,$6D,$71,$71,$71,$71; F294  iimmmmqqqq
        .byte   $75,$75,$75,$75,$79,$79,$79,$79,$21,$21; F29E  uuuuyyyy!!
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F2A8  !!!!!!!!!!
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F2B2  !!!!!!!!!!
template1StartType:
        .byte   $11,$11,$11,$11,$11,$11,$11,$11,$11,$11; F2BC  ..........  unitType[0-49] (see $F12C): 28 x $11 RIDER, 18 x $FF, 3 x $13 SPY, $14 COMCEN
        .byte   $11,$11,$11,$11,$11,$11,$11,$11,$11,$11; F2C6  ..........
        .byte   $11,$11,$11,$11,$11,$11,$11,$11,$FF,$FF; F2D0  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F2DA  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$13,$13,$13,$14; F2E4  ..........
        .byte   $19,$19,$19,$19,$19,$19,$19,$19,$19,$19; F2EE  ..........  unitType[50-78]: side 1's 28 riders ($19) and the first empty slot
        .byte   $19,$19,$19,$19,$19,$19,$19,$19,$19,$19; F2F8  ..........
        .byte   $19,$19,$19,$19,$19,$19,$19,$19,$FF; F302  .........

; Template 1's unitType[79-99]: the rest of the empty slots, then the three SPYs ($1B) and the COMCEN
; ($1C) of side 1.  The label here has nothing to do with the template - it is the RUN-TIME meaning of
; the address: map cell (19,19) = $F000 + 40*19 + 19, which the map generator writes at $6F86 ($55, a
; river bend) when a point-symmetric map needs its two river halves joined at the centre.
D_F30B:
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F30B  ..........  unitType[79-95] $FF empty, [96-98] $1B SPY, [99] $1C COMCEN
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$1B,$1B,$1B; F315  ..........
        .byte   $1C                     ; F31F  .

; unitStartTemplate2 ($F320-$F4AF) - used by game types 0 SCRIMAGE, 1 QB SNEAK and 2 THE BOMB.  Eleven
; units a side and no groups at all (flags $00 / $21 throughout).  It is a football formation: units
; 0-6 are the line of scrimmage in row 21 - a RIDER split out at column 7, GRUNTs at 14, 17, 20, 23
; and 26, a RIDER split out at column 33 - unit 7 is the RIDER 'quarterback' at (20,23), units 8 and 9
; the two RIDER backs at (18,25) and (22,25), and unit 49 the COMCEN at (20,25).  Slots 10-48 are
; empty ($FF). Side 1 is the same formation reflected in the rows (side-1 row = 39 - side-0 row) but
; its columns are 40 - column instead of 39 - column, so on player 1's mirrored display side 1's line
; sits one cell to the left of side 0's; both COMCENs are stored at column 20. applyGameTypeDefaults
; ($7C85, in the map generator overlay) trims this roster once it has been copied: QB SNEAK deletes
; units 0-6, leaving only the quarterback, the two backs and the COMCEN, and THE BOMB deletes units
; 0-98 and puts unit 49 back as a COMCEN, so that game is fought by the two command centres and one
; extra drone each. The 39 empty slots a side are dead data: their column and row bytes are template
; 0's own entries at the same index, so this template was edited from a copy of template 0.  The two
; exceptions are slots 10 (33,20) and 60 (27,19), which are not template-0 values - the formation
; evidently had a twelfth unit a side at some point.
unitStartTemplate2:
        .byte   $07,$0E,$11,$14,$17,$1A,$21,$14,$12,$16; F320  ......!...  unitCol[0-18]: the line of scrimmage (7,14,17,20,23,26,33), the quarterback and the two backs
        .byte   $21,$07,$21,$12,$06,$05,$14,$13,$04; F32A  !.!......

; Template 2's unitCol[19] - part of an empty slot, dead data.  The label is the RUN-TIME meaning of
; the address: map cell (19,20) = $F000 + 40*20 + 19, written with $58 by the map generator at $6F81.
D_F333:
        .byte   $06                     ; F333  .  unitCol[19] = $06, unused

; Template 2's unitCol[20-49], all of them empty slots except the COMCEN at the end.  The label is
; again the run-time meaning: map cell (20,20), cleared to $40 at $6F8B so that the two halves of a
; mirrored river join cleanly.
D_F334:
        .byte   $05,$22,$14,$12,$22,$20,$23,$15,$06,$05; F334  .".." #...  unitCol[20] = $05, unused; entries 20-48 dead, entry 49 the COMCEN at column 20
        .byte   $06,$13,$05,$13,$14,$22,$22,$14,$21,$21; F33E  ....."".!!
        .byte   $06,$14,$21,$23,$04,$12,$13,$22,$05,$14; F348  ..!#..."..
        .byte   $21,$1A,$17,$14,$11,$0E,$07,$14,$16,$12; F352  !.........  unitCol[50-99]: side 1's line at 33,26,23,20,17,14,7, quarterback 57, backs 58/59, COMCEN 99
        .byte   $1B,$16,$13,$14,$21,$13,$04,$24,$14,$23; F35C  ....!..$.#
        .byte   $22,$21,$20,$15,$05,$14,$05,$14,$22,$21; F366  "! ....."!
        .byte   $14,$13,$14,$22,$21,$05,$05,$06,$06,$13; F370  ..."!.....
        .byte   $13,$23,$21,$15,$04,$06,$22,$14,$05,$14; F37A  .#!..."...
template2StartRow:
        .byte   $15,$15,$15,$15,$15,$15,$15,$17,$19,$19; F384  ..........  unitRow[0-49] (see $F064): row 21 the line, 23 the quarterback, 25 the backs and the COMCEN
        .byte   $14,$1B,$1B,$1A,$1B,$1A,$1A,$1B,$1B,$1A; F38E  ..........
        .byte   $1B,$19,$1B,$1B,$1A,$1B,$1A,$1B,$1F,$1E; F398  ..........
        .byte   $1E,$1F,$1F,$1E,$1E,$1F,$1E,$1F,$1F,$1E; F3A2  ..........
        .byte   $1C,$1C,$1C,$1C,$1C,$1C,$17,$17,$17,$19; F3AC  ..........
        .byte   $12,$12,$12,$12,$12,$12,$12,$10,$0E,$0E; F3B6  ..........  unitRow[50-99]: side 1's mirror - row 18 the line, 16 the quarterback, 14 the backs/COMCEN
        .byte   $13,$0C,$0D,$0C,$0D,$0C,$0C,$0C,$06,$0C; F3C0  ..........
        .byte   $0C,$0C,$0C,$0D,$0D,$0E,$0E,$0D,$09,$09; F3CA  ..........
        .byte   $08,$09,$09,$08,$08,$09,$08,$09,$08,$08; F3D4  ..........
        .byte   $0B,$0B,$0B,$0B,$0B,$0B,$10,$10,$10,$0E; F3DE  ..........
template2StartFlags:
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F3E8  ..........  unitFlags[0-49]: $00 for every side-0 unit - nothing is in a group in these game types
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F3F2  ..........
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F3FC  ..........
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F406  ..........
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F410  ..........
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F41A  !!!!!!!!!!  unitFlags[50-99]: $21 for every side-1 unit (bit 5 side, bit 0 facing down), no groups
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F424  !!!!!!!!!!
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F42E  !!!!!!!!!!
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F438  !!!!!!!!!!
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F442  !!!!!!!!!!
template2StartType:
        .byte   $11,$10,$10,$10,$10,$10,$11,$11,$11,$11; F44C  ..........  unitType[0-49] (see $F12C): $11, five $10, four $11, then $FF to unit 48 and $14 COMCEN
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F456  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F460  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F46A  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$14; F474  ..........
        .byte   $19,$18,$18,$18,$18,$18,$19,$19,$19,$19; F47E  ..........  unitType[50-99]: the same eleven units on side 1 ($19 RIDER, $18 GRUNT, $1C COMCEN)
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F488  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F492  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F49C  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$1C; F4A6  ..........

; unitStartTemplate3 ($F4B0-$F63F) - used by game type 4 SLUGGERS.  Roster per side: 12 GRUNT (units
; 0-11), 12 RIDER (12-23), 4 BOOMER (24-27), 3 SPY (46-48) and 1 COMCEN (49); slots 28-45 are empty.
; Every combat unit is in a 2x2 squad of four, one squad per group name: side 0 has the grunt squads 0
; ALPHA at columns 19-20 rows 26-27, 1 BAKER at 17-18 rows 27-28 and 2 CHARLIE at 21-22 rows 27-28
; packed around the COMCEN at (20,30); the rider squads 3 DELTA at columns 9-10, 4 EASY at 19-20 and 5
; FOXTROT at 29-30, all in rows 23-24; and the boomer squad 6 GROVER at 19-20 rows 28-29.  The three
; spies stand loose in row 22 at columns 9, 20 and 30.  Side 1 is the exact per-index 180-degree
; mirror (unit i+50 = (39-column, 39-row) of unit i, same type, same group). As in template 1 the 18
; empty slots a side keep dead column and row bytes copied from template 0 (entries 28-45 = template
; 0's 7-24, entries 78-95 = template 0's 57-74); only their $FF type matters. This is also the one
; template whose 512-byte copy reads past its own end, into $F640-$F6AF - see the note there.
unitStartTemplate3:
        .byte   $13,$14,$13,$14,$11,$12,$11,$12,$15,$16; F4B0  ..........  unitCol[0-49] of template 3: three grunt squads, three rider squads, a boomer squad, then dead slots
        .byte   $15,$16,$09,$0A,$09,$0A,$13,$14,$13,$14; F4BA  ..........
        .byte   $1D,$1E,$1D,$1E,$13,$14,$13,$14,$03,$24; F4C4  .........$
        .byte   $21,$05,$07,$21,$12,$06,$05,$14,$13,$04; F4CE  !..!......
        .byte   $06,$05,$22,$14,$12,$22,$09,$14,$1E,$14; F4D8  ..".."....
        .byte   $14,$13,$14,$13,$16,$15,$16,$15,$12,$11; F4E2  ..........  unitCol[50-99]: side 1's columns, the 39-column mirror of side 0's
        .byte   $12,$11,$1E,$1D,$1E,$1D,$14,$13,$14,$13; F4EC  ..........
        .byte   $0A,$09,$0A,$09,$14,$13,$14,$13,$22,$06; F4F6  ........".
        .byte   $12,$15,$16,$13,$14,$21,$13,$04,$24,$14; F500  .....!..$.
        .byte   $23,$22,$21,$20,$15,$05,$1E,$13,$09,$13; F50A  #"! ......
template3StartRow:
        .byte   $1A,$1A,$1B,$1B,$1B,$1B,$1C,$1C,$1B,$1B; F514  ..........  unitRow[0-49] (see $F064): riders 23-24, grunts 26-28, boomers 28-29, spies 22, COMCEN 30
        .byte   $1C,$1C,$17,$17,$18,$18,$17,$17,$18,$18; F51E  ..........
        .byte   $17,$17,$18,$18,$1C,$1C,$1D,$1D,$1B,$1B; F528  ..........
        .byte   $1A,$19,$1B,$1B,$1A,$1B,$1A,$1A,$1B,$1B; F532  ..........
        .byte   $1A,$1B,$19,$1B,$1B,$1A,$16,$16,$16,$1E; F53C  ..........
        .byte   $0D,$0D,$0C,$0C,$0C,$0C,$0B,$0B,$0C,$0C; F546  ..........  unitRow[50-99]: side 1's rows 9-17, the mirror of side 0's
        .byte   $0B,$0B,$10,$10,$0F,$0F,$10,$10,$0F,$0F; F550  ..........
        .byte   $10,$10,$0F,$0F,$0B,$0B,$0A,$0A,$0D,$0C; F55A  ..........
        .byte   $0C,$0C,$0C,$0D,$0C,$0D,$0C,$0C,$0C,$06; F564  ..........
        .byte   $0C,$0C,$0C,$0C,$0D,$0D,$11,$11,$11,$09; F56E  ..........
template3StartFlags:
        .byte   $40,$40,$40,$40,$44,$44,$44,$44,$48,$48; F578  @@@@DDDDHH  unitFlags[0-49] (see $F0C8): seven side-0 squads of four, $40 ALPHA .. $58 GROVER
        .byte   $48,$48,$4C,$4C,$4C,$4C,$50,$50,$50,$50; F582  HHLLLLPPPP
        .byte   $54,$54,$54,$54,$58,$58,$58,$58,$00,$00; F58C  TTTTXXXX..
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F596  ..........
        .byte   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00; F5A0  ..........
        .byte   $61,$61,$61,$61,$65,$65,$65,$65,$69,$69; F5AA  aaaaeeeeii  unitFlags[50-99]: the same seven squads on side 1, $61 ALPHA .. $79 GROVER
        .byte   $69,$69,$6D,$6D,$6D,$6D,$71,$71,$71,$71; F5B4  iimmmmqqqq
        .byte   $75,$75,$75,$75,$79,$79,$79,$79,$21,$21; F5BE  uuuuyyyy!!
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F5C8  !!!!!!!!!!
        .byte   $21,$21,$21,$21,$21,$21,$21,$21,$21,$21; F5D2  !!!!!!!!!!
template3StartType:
        .byte   $10,$10,$10,$10,$10,$10,$10,$10,$10,$10; F5DC  ..........  unitType[0-35] (see $F12C): 12 x $10 GRUNT, 12 x $11 RIDER, 4 x $12 BOOMER, then $FF
        .byte   $10,$10,$11,$11,$11,$11,$11,$11,$11,$11; F5E6  ..........
        .byte   $11,$11,$11,$11,$12,$12,$12,$12,$FF,$FF; F5F0  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF ; F5FA  ......

; Template 3's unitType[36-49]: the last empty slots, the three SPYs ($13) and the COMCEN ($14) of
; side 0. The label is the RUN-TIME meaning of the address: $F600 is where the 40x40 map's last 64
; cells begin (cells 1536-1599), the tail that clearMapMarkers walks separately at $7536/$7541 after
; its six full pages.
D_F600:
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F600  ..........  unitType[36-45] $FF empty, [46-48] $13 SPY, [49] $14 COMCEN
        .byte   $13,$13,$13,$14         ; F60A  ....
        .byte   $18,$18,$18,$18,$18,$18,$18,$18,$18,$18; F60E  ..........  unitType[50-99]: 12 x $18, 12 x $19, 4 x $1A, 18 x $FF, 3 x $1B and $1C - side 1's roster
        .byte   $18,$18,$19,$19,$19,$19,$19,$19,$19,$19; F618  ..........
        .byte   $19,$19,$19,$19,$1A,$1A,$1A,$1A,$FF,$FF; F622  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF; F62C  ..........
        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$1B,$1B,$1B,$1C; F636  ..........

; $F640-$F6FF - 192 bytes that belong to no template and that the game never uses.  They are a
; fragment of 6502 code from an OLDER build of the game, left in the mastering machine's memory when
; this block was written to the disk; the loader reads all seven sectors, so it comes along for the
; ride.
; Nothing ever reads it as data: the only reader of this file, loadUnitStartTemplate ($ECF3), copies
; at most $F4B0-$F6AF (template 3), and because that copy writes 400 bytes ahead of its own read
; pointer it has already replaced $F640-$F6AF with template 3's data before it gets there.  The one
; byte that IS read is $F640 itself, as the 'the arrays still hold the disk image' flag - and it holds
; $0A, bit 7 clear, which would mean 'already loaded', so startGameSession stores $FF over it first
; ($78E4). Once a game starts this area is the live unitCol[0-99] ($F640) and unitRow[0-99] ($F6A4)
; arrays, which is what the labels below name; the bytes printed under them are the leftover code, not
; array data, and the labels fall in the middle of its instructions. Disassembled, the fragment is the
; tail of one routine plus two complete ones, each with a recognisable counterpart in the shipped
; build at a different address:
;   $F640  asl a / sta $3F / lda #$14 / jmp $C097
;          the tail of setRepairMessageWindow, which in the shipped build ($19E1) ends 'lda #$0A /
;          sta textCursorCol / lda #$14 / jmp setCursorRow': cursor to row 20, column 2*A.
;   $F648  lda #$0C sta $3B / lda #$09 sta $39 sta $40 / lda #$12 sta $3C / lda #$00 sta $3F /
;          jsr $C099 / lda #$61 sta $3D / lda #$B2 ldy #$CA jsr $C133
;          printOptionsList: text window left column 12, rows 9-18, width 18, colour $61, then the
;          heading from $CAB2.  The shipped printOptionsList ($19F3) is the same code with column 6,
;          width $1D and the heading at $CB13.
;   $F668  lda $92CD bne / lda $0881 beq
;          'is a game running?' - $92CD is the old build's gameEndCountdown and $0881 its
;          gameEndReason; the shipped test at $1A13 uses $92C9 and $0BA8.
;   $F672  lda #$10 ldy #$66 jsr $C133 / jsr $C137 / lda $E03B beq / jsr $C137 / rts
;          no game: print the main menu from $6610, then LOAD GAME FILM, then DISCONNECT/SET VOICE if
;          the link flag $E03B is set.  Shipped: the same sequence at $1A36 with the text at $CC1F.
;   $F685  lda #$98 ldy #$66 jsr $C133 / lda $0876 bmi / jsr $C137 / lda #$53 ldy #$CA jmp $C133
;          a game is running: ABORT GAME from $6698, VOICE PAUSE unless the film-playback flag
;          $0876 is set, then ' (EXIT)' from $CA53.  Shipped ($1A1B): $CCA6, two flag tests, $CAB2.
;   $F69B  lda #$FF sta $924A / lda $0881 bne $F711 / jsr $1648 / ldy #$02 / lda $0876 bmi /
;          lda $087F bmi / iny / sty $91D5 / dey / sty $91D6 / dec $3B / lda $3B sta $3F /
;          lda #$0B sta $91D7 / jsr $C097 / jsr $5F41 / ldy $91D6 beq / jsr $1205 / jmp $1648
;          miscTabAction, the MISC-tab options menu: two items, three in a modem game that is not a
;          replay, highlight bar from row 11, run the selector, and on '(EXIT)' reprint the list.  The
;          shipped miscTabAction ($1A49) is instruction for instruction the same, with the menu state
;          one byte lower ($91D4/$91D5/$91D6 instead of $91D5/$91D6/$91D7).
;   $F6D8  jsr $0CD8 / lda $E03B beq / lda $0877 bmi,beq / lda #$00 sta $73 sta $9164 /
;          lda $E044 bmi / jsr $C7FF / lda #$8C jsr $5178 / lda #$26 sta $7F / (jsr, cut off)
;          the ABORT GAME path: if the link is up and a game session is agreed, clear the exchange
;          throttle, skip the handshake when the opponent module is the trainer ($E044 = the old
;          build's commBuildId), show 'WORKING...', queue command $8C reason 0, wait $26 ticks.
;          Shipped: $1A86-$1AAE, with commBuildId $E030, showWorkingMessage $C853, queueCmd2 $561F.
; The block ends in the middle of that last JSR: only its $20 opcode fits in the seven sectors. What
; dates the fragment to a different build is that every one of its own addresses differs from the
; shipped equivalent - printOptionsList $1648 vs $19F3, setMenuTextWindow $1205 vs $1575,
; runInGameOptionsMenu $5F41 vs $65A0, queueCmd2 $5178 vs $561F, showWorkingMessage $C7FF vs $C853,
; the mode flags $0876/$0877/$087F/$0881 vs $0B9B/$0B9C/$0BA5/$0BA8, the menu text $6610/$6698/$CA53
; vs $CC1F/$CCA6/$CAB2, linkPollDelay $9164 vs $9163, commBuildId $E044 vs $E030 - while the low-level
; text engine entries it calls ($C097 setCursorRow, $C099 updateCursorPointers, $C133 printString,
; $C137 printStringAtPointer) and the link-active flag $E03B are at exactly the addresses the shipped
; build uses.  So it is the same program a few hundred bytes shorter, before the $0800 and $C000
; blocks were rearranged.  (Confidence: high that it is leftover code and that these are the matching
; routines; which build it came from cannot be pinned down further.)
unitColTable:
        .byte   $0A                     ; F640  map column of each of the 100 units; the parallel unit arrays follow every $64 bytes (0-49 side 0, 50-99 side 1, 49/99 = the comcens)
        .byte   $85,$3F,$A9,$14,$4C,$97,$C0; F641  .?..L..
        .byte   $A9                     ; F648  the old build's printOptionsList starts here; the shipped one is at $19F3
        .byte   $0C,$85,$3B,$A9,$09,$85,$39,$85; F649  ..;...9.
        .byte   $40,$A9,$12,$85,$3C,$A9,$00,$85; F651  @...<...
        .byte   $3F,$20,$99,$C0,$A9,$61,$85,$3D; F659  ? ...a.=
        .byte   $A9,$B2,$A0,$CA,$20,$33,$C1,$AD; F661  .... 3..
        .byte   $CD,$92,$D0,$05,$AD,$81,$08,$F0; F669  ........
side0ComcenCol:
        .byte   $13                     ; F671  unitColTable[49]: column of side 0's COMCEN
side1UnitColTable:
        .byte   $A9                     ; F672  unitColTable+50: the columns of side 1's units, indexed by that side's ordinal 0-49
        .byte   $10,$A0,$66,$20,$33,$C1,$20,$37; F673  ..f 3. 7
        .byte   $C1,$AD,$3B,$E0,$F0,$03,$20,$37; F67B  ..;... 7
        .byte   $C1,$60                 ; F683  .`
        .byte   $A9                     ; F685  'a game is running' branch: ABORT GAME / VOICE PAUSE / (EXIT)
        .byte   $98,$A0                 ; F686  ..
unitFlagsTableAlias:
        .byte   $66                     ; F688  unitFlagsTable - $80, so it can be indexed with a raw map byte ($80 | unit)
        .byte   $20,$33,$C1,$AD,$76,$08,$30,$03; F689   3..v.0.
        .byte   $20,$37,$C1,$A9,$53,$A0,$CA,$4C; F691   7..S..L
        .byte   $33,$C1                 ; F699  3.
        .byte   $A9                     ; F69B  the old build's miscTabAction starts here; the shipped one is at $1A49
        .byte   $FF,$8D,$4A,$92,$AD,$81,$08; F69C  ..J....
side1ComcenCol:
        .byte   $D0                     ; F6A3  unitColTable[99]: column of side 1's COMCEN
unitRowTable:
        .byte   $6C                     ; F6A4  map row of each of the 100 units
        .byte   $20,$48,$16,$A0,$02,$AD,$76,$08; F6A5   H....v.
        .byte   $30,$06,$AD,$7F,$08,$30,$01,$C8; F6AD  0....0..
        .byte   $8C,$D5,$91,$88,$8C,$D6,$91,$C6; F6B5  ........
        .byte   $3B,$A5,$3B,$85,$3F,$A9,$0B,$8D; F6BD  ;.;.?...
        .byte   $D7,$91,$20,$97,$C0,$20,$41,$5F; F6C5  .. .. A_
        .byte   $AC,$D6,$91,$F0,$06,$20,$05,$12; F6CD  ..... ..
side0ComcenRow:
        .byte   $4C                     ; F6D5  unitRowTable[49]: row of side 0's COMCEN
side1UnitRowTable:
        .byte   $48                     ; F6D6  unitRowTable+50: the rows of side 1's units
        .byte   $16                     ; F6D7  .
        .byte   $20                     ; F6D8  the ABORT GAME path: tell the opponent with command $8C and hang up (shipped $1A86)
        .byte   $D8,$0C,$AD,$3B,$E0,$F0,$2E,$AD; F6D9  ...;....
        .byte   $77,$08,$30,$29,$F0,$24,$A9,$00; F6E1  w.0).$..
        .byte   $85,$73,$8D             ; F6E9  .s.
unitTypeTableAlias:
        .byte   $64                     ; F6EC  unitTypeTable - $80, so it can be indexed with a raw map byte ($80 | unit)
        .byte   $91,$AD,$44,$E0,$30,$18,$20,$FF; F6ED  ..D.0. .
        .byte   $C7,$A9,$8C,$20,$78,$51,$A9,$26; F6F5  ... xQ.&
        .byte   $85,$7F                 ; F6FD  ..
        .byte   $20                     ; F6FF  $20 = the opcode of a JSR whose address bytes fell outside the seven sectors
