modemwars/annotations/30_game_unitStartTemplatesF000_F000.json
2026-08-23 02:09:40 -05:00

454 lines
23 KiB
JSON

{
"chunk": "game_unitStartTemplatesF000_F000",
"unit": "game/unitStartTemplatesF000",
"unitLabels": {
"game/unitStartTemplatesF000": {
"F064": "template0StartRow",
"F0C8": "template0StartFlags",
"F12C": "template0StartType",
"F1F4": "template1StartRow",
"F258": "template1StartFlags",
"F2BC": "template1StartType",
"F384": "template2StartRow",
"F3E8": "template2StartFlags",
"F44C": "template2StartType",
"F514": "template3StartRow",
"F578": "template3StartFlags",
"F5DC": "template3StartType"
}
},
"notes": {
"F000": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitCol[0-49]: side 0's starting map column, ten units per row; the last entry is the COMCEN"
},
"F032": {
"unit": "game/unitStartTemplatesF000",
"line": "unitCol[50-99]: side 1's columns; the last entry is unit 99, side 1's COMCEN"
},
"F064": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitRow[0-49]: side 0's rows, the bottom half of the field"
},
"F096": {
"unit": "game/unitStartTemplatesF000",
"line": "unitRow[50-99]: side 1's rows, the 39-row mirror of side 0's"
},
"F0C8": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitFlags[0-49]: side 0 - $00 loose, $40/$44/$48/$4C/$50/$54 = groups ALPHA..FOXTROT"
},
"F0FA": {
"unit": "game/unitStartTemplatesF000",
"line": "unitFlags[50-99]: side 1 - $21 loose, $61/$65/$69/$6D/$71/$75 = the same six groups"
},
"F12C": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitType[0-49]: side 0 - $10 GRUNT, $11 RIDER, $12 BOOMER, $13 SPY, $14 COMCEN; 28/12/6/3/1"
},
"F15E": {
"unit": "game/unitStartTemplatesF000",
"line": "unitType[50-99]: side 1 - $18 GRUNT .. $1C COMCEN; the same roster as side 0"
},
"F190": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitCol[0-49] of template 1: entries 28-45 are dead slots, entry 49 the COMCEN"
},
"F1C2": {
"unit": "game/unitStartTemplatesF000",
"line": "unitCol[50-99]: side 1's columns; entries 78-95 dead, entry 99 the COMCEN"
},
"F1F4": {
"unit": "game/unitStartTemplatesF000",
"line": "unitRow[0-49] (see $F064): rider line rows 22-23, spies row 21, COMCEN row 25"
},
"F226": {
"unit": "game/unitStartTemplatesF000",
"line": "unitRow[50-99]: side 1 - rider line 16-17, spies 18, COMCEN 14"
},
"F258": {
"unit": "game/unitStartTemplatesF000",
"line": "unitFlags[0-49] (see $F0C8): seven side-0 squads of four, $40 ALPHA .. $58 GROVER"
},
"F28A": {
"unit": "game/unitStartTemplatesF000",
"line": "unitFlags[50-99]: the same seven squads on side 1, $61 ALPHA .. $79 GROVER"
},
"F2BC": {
"unit": "game/unitStartTemplatesF000",
"line": "unitType[0-49] (see $F12C): 28 x $11 RIDER, 18 x $FF, 3 x $13 SPY, $14 COMCEN"
},
"F2EE": {
"unit": "game/unitStartTemplatesF000",
"line": "unitType[50-78]: side 1's 28 riders ($19) and the first empty slot"
},
"F30B": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitType[79-95] $FF empty, [96-98] $1B SPY, [99] $1C COMCEN"
},
"F320": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitCol[0-18]: the line of scrimmage (7,14,17,20,23,26,33), the quarterback and the two backs"
},
"F333": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitCol[19] = $06, unused"
},
"F334": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitCol[20] = $05, unused; entries 20-48 dead, entry 49 the COMCEN at column 20"
},
"F352": {
"unit": "game/unitStartTemplatesF000",
"line": "unitCol[50-99]: side 1's line at 33,26,23,20,17,14,7, quarterback 57, backs 58/59, COMCEN 99"
},
"F384": {
"unit": "game/unitStartTemplatesF000",
"line": "unitRow[0-49] (see $F064): row 21 the line, 23 the quarterback, 25 the backs and the COMCEN"
},
"F3B6": {
"unit": "game/unitStartTemplatesF000",
"line": "unitRow[50-99]: side 1's mirror - row 18 the line, 16 the quarterback, 14 the backs/COMCEN"
},
"F3E8": {
"unit": "game/unitStartTemplatesF000",
"line": "unitFlags[0-49]: $00 for every side-0 unit - nothing is in a group in these game types"
},
"F41A": {
"unit": "game/unitStartTemplatesF000",
"line": "unitFlags[50-99]: $21 for every side-1 unit (bit 5 side, bit 0 facing down), no groups"
},
"F44C": {
"unit": "game/unitStartTemplatesF000",
"line": "unitType[0-49] (see $F12C): $11, five $10, four $11, then $FF to unit 48 and $14 COMCEN"
},
"F47E": {
"unit": "game/unitStartTemplatesF000",
"line": "unitType[50-99]: the same eleven units on side 1 ($19 RIDER, $18 GRUNT, $1C COMCEN)"
},
"F4B0": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitCol[0-49] of template 3: three grunt squads, three rider squads, a boomer squad, then dead slots"
},
"F4E2": {
"unit": "game/unitStartTemplatesF000",
"line": "unitCol[50-99]: side 1's columns, the 39-column mirror of side 0's"
},
"F514": {
"unit": "game/unitStartTemplatesF000",
"line": "unitRow[0-49] (see $F064): riders 23-24, grunts 26-28, boomers 28-29, spies 22, COMCEN 30"
},
"F546": {
"unit": "game/unitStartTemplatesF000",
"line": "unitRow[50-99]: side 1's rows 9-17, the mirror of side 0's"
},
"F578": {
"unit": "game/unitStartTemplatesF000",
"line": "unitFlags[0-49] (see $F0C8): seven side-0 squads of four, $40 ALPHA .. $58 GROVER"
},
"F5AA": {
"unit": "game/unitStartTemplatesF000",
"line": "unitFlags[50-99]: the same seven squads on side 1, $61 ALPHA .. $79 GROVER"
},
"F5DC": {
"unit": "game/unitStartTemplatesF000",
"line": "unitType[0-35] (see $F12C): 12 x $10 GRUNT, 12 x $11 RIDER, 4 x $12 BOOMER, then $FF"
},
"F600": {
"unit": "game/unitStartTemplatesF000",
"block": [
"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."
],
"line": "unitType[36-45] $FF empty, [46-48] $13 SPY, [49] $14 COMCEN"
},
"F60E": {
"unit": "game/unitStartTemplatesF000",
"line": "unitType[50-99]: 12 x $18, 12 x $19, 4 x $1A, 18 x $FF, 3 x $1B and $1C - side 1's roster"
},
"F640": {
"unit": "game/unitStartTemplatesF000",
"block": [
"$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.)"
]
},
"F648": {
"unit": "game/unitStartTemplatesF000",
"line": "the old build's printOptionsList starts here; the shipped one is at $19F3"
},
"F685": {
"unit": "game/unitStartTemplatesF000",
"line": "'a game is running' branch: ABORT GAME / VOICE PAUSE / (EXIT)"
},
"F69B": {
"unit": "game/unitStartTemplatesF000",
"line": "the old build's miscTabAction starts here; the shipped one is at $1A49"
},
"F6D8": {
"unit": "game/unitStartTemplatesF000",
"line": "the ABORT GAME path: tell the opponent with command $8C and hang up (shipped $1A86)"
},
"F6FF": {
"unit": "game/unitStartTemplatesF000",
"line": "$20 = the opcode of a JSR whose address bytes fell outside the seven sectors"
}
},
"dataTypes": {
"F000": [
"grid",
50,
10
],
"F032": [
"grid",
50,
10
],
"F064": [
"grid",
50,
10
],
"F096": [
"grid",
50,
10
],
"F0C8": [
"grid",
50,
10
],
"F0FA": [
"grid",
50,
10
],
"F12C": [
"grid",
50,
10
],
"F15E": [
"grid",
50,
10
],
"F190": [
"grid",
50,
10
],
"F1C2": [
"grid",
50,
10
],
"F1F4": [
"grid",
50,
10
],
"F226": [
"grid",
50,
10
],
"F258": [
"grid",
50,
10
],
"F28A": [
"grid",
50,
10
],
"F2BC": [
"grid",
50,
10
],
"F2EE": [
"grid",
29,
10
],
"F30B": [
"grid",
21,
10
],
"F320": [
"grid",
19,
10
],
"F333": [
"grid",
1,
1
],
"F334": [
"grid",
30,
10
],
"F352": [
"grid",
50,
10
],
"F384": [
"grid",
50,
10
],
"F3B6": [
"grid",
50,
10
],
"F3E8": [
"grid",
50,
10
],
"F41A": [
"grid",
50,
10
],
"F44C": [
"grid",
50,
10
],
"F47E": [
"grid",
50,
10
],
"F4B0": [
"grid",
50,
10
],
"F4E2": [
"grid",
50,
10
],
"F514": [
"grid",
50,
10
],
"F546": [
"grid",
50,
10
],
"F578": [
"grid",
50,
10
],
"F5AA": [
"grid",
50,
10
],
"F5DC": [
"grid",
36,
10
],
"F600": [
"grid",
14,
10
],
"F60E": [
"grid",
50,
10
]
}
}