modemwars/annotations/20_game_mapGenerator6F00_6F00.json
2026-08-23 02:09:40 -05:00

3244 lines
91 KiB
JSON

{
"chunk": "game_mapGenerator6F00_6F00",
"unit": "game/mapGenerator6F00",
"unitLabels": {
"game/mapGenerator6F00": {
"6F1A": "storeMapStyleFlags",
"6F2A": "storeMapSymmetryFlag",
"6F89": "joinRiverClearCentre",
"6F8E": "mapGeneratorDone",
"6F9D": "linkServiceNotNeeded",
"6FC4": "limitHillsForQbSneak",
"6FCB": "storeHillSiteCount",
"6FD2": "noHillSitesAtAll",
"6FD5": "setRowCandidateLimit",
"6FDE": "hillBlobSizeLoop",
"6FF5": "hillRowCandidateLoop",
"7010": "mirrorHillRowCandidates",
"7027": "startSitePlacement",
"702B": "tryRowCandidate",
"702F": "tryJitteredLaneColumn",
"7036": "jitterLaneColumn",
"7061": "rowCandidateWrapTest",
"706B": "hillSiteAccepted",
"7072": "advanceToNextHillSite",
"7085": "placeNextHillSite",
"7088": "storeHillSitesPlaced",
"708D": "hillSitesDone",
"7096": "laneIndexDone",
"709F": "rowCandidateDone",
"70A5": "laneIdentityLoop",
"70AC": "laneSwapLoop",
"70CC": "laneColumnFillLoop",
"70EA": "summitBlobLoop",
"7109": "summitsDone",
"7112": "lowerHillScanInit",
"7122": "lowerHillRowStart",
"7126": "lowerHillCellScan",
"7135": "lowerHillCellOccupied",
"7141": "lowerHillNorthClassTest",
"714C": "lowerHillTestWest",
"7161": "lowerHillTestEast",
"7163": "lowerHillReadEast",
"7176": "lowerHillTestSouth",
"718B": "growLowerHillHere",
"7194": "lowerHillNextColumn",
"719F": "lowerHillNextRow",
"71AA": "lowerHillScanDone",
"71DC": "blobPopStack",
"71E3": "blobResumeCell",
"721C": "blobGrowWest",
"721F": "blobTryWest",
"7204": "blobMarkNorthTried",
"7221": "blobStepWest",
"7243": "blobTryEast",
"725D": "blobTestEastBlank",
"7269": "blobTrySouth",
"7271": "blobSouthAlreadyTried",
"728A": "blobTestSouthChance",
"728F": "blobCellExhausted",
"7292": "blobPaintCell",
"72A1": "blobWriteTile",
"72B1": "blobPushCell",
"72B3": "blobSaveParentFlags",
"72D3": "blobStoreColumnBias",
"72D5": "blobRowBias",
"72E1": "blobMergeRowBias",
"72E5": "blobStoreChildFlags",
"72F2": "blobExpandChild",
"72F5": "blobFinished",
"7300": "forestBlockTestNw",
"730D": "forestBlockTestNe",
"7310": "forestBlockClassNe",
"7311": "forestBlockLookupNe",
"7316": "forestBlockCompareNe",
"731A": "forestBlockTestSw",
"731E": "forestBlockClassSw",
"7328": "forestBlockTestSe",
"7335": "forestBlockAccept",
"733D": "forestBlockAcceptRts",
"733E": "forestBlockReject",
"734C": "storeForestTile",
"7362": "limitForestForDefender",
"7369": "storeForestClusterCount",
"736B": "forestClusterLoop",
"736E": "forestCentreFromRandom",
"7387": "forestSeedRowRetry",
"7394": "forestSeedColumnRetry",
"7396": "jitterForestSeedColumn",
"73AC": "forestClustersDone",
"73B0": "forestSeedStepEast",
"73B7": "forestSeedPaintSouthEast",
"73BC": "forestSeedPaintSouth",
"73E4": "growForestSeedBlob",
"73ED": "forestSeedOffMap",
"7403": "contourScanCell",
"7412": "contourReadCell",
"741A": "contourCompareRingClass",
"741C": "contourCellIsOldRing",
"7426": "contourEraseOldRing",
"742A": "contourApplyRule",
"742F": "contourNextColumn",
"744A": "contourNeighbourLoop",
"7460": "contourNextNeighbour",
"746F": "contourClipRightEdge",
"7475": "contourClipTopEdge",
"747B": "contourClipBottomEdge",
"7481": "contourLookupRule",
"749E": "contourTakeRandomBit",
"74BD": "contourMaybeFillCell",
"74C3": "contourFillWithInterior",
"74C9": "contourBackUpScan",
"74D2": "contourStoreScanCol",
"74D6": "contourBackUpRow",
"74DD": "contourStoreScanRow",
"74E0": "contourRescanReturn",
"74E1": "contourRingTileFromRule",
"74E5": "contourWriteTile",
"74EC": "contourLeaveCell"
}
},
"notes": {
"6F00": {
"unit": "game/mapGenerator6F00",
"block": [
"laneColumnTable - the four vertical 'lanes' of the battlefield along which hill summits are",
"placed: columns 6, 15, 25 and 34 of the 40-column map. shuffleLaneColumns copies them into",
"$0329-$032C in a random order so successive summits land in different parts of the map.",
"(The label is only marked sub_6F00 because the comcen-screens overlay has code at this address.)"
],
"line": "lane columns 6, 15, 25, 34 (indexed 0-3 by the shuffled permutation)"
},
"6F04": {
"unit": "game/mapGenerator6F00",
"routine": [
"generateBattlefieldMap - entry point of the procedural battlefield generator. Derives the",
"map-style flags for the chosen game type, decides whether the map is point-symmetric, puts",
"'WORKING...' on the status line, blanks all 1600 map cells to $40 and re-seeds the scenario RNG",
"from the 24-bit map seed, then falls into runMapGeneratorPasses. The battlefield is never loaded",
"from disk: seed + game type completely determine the terrain, which is why both machines produce",
"the identical map and why a map can be named by its seed.",
"In: gameTypeOptions $0BA3 bits 0-2 = game type 0-6, mapSeed $0B95-$0B97; needs the contour rule",
" table at $0200 (track 18 s15) and the $EC00 comm-tail helpers resident",
"Out: $032E map style, $032D symmetry flags, map $F000-$F63F built, scenario RNG $5A-$5C advanced,",
" map name text $0BA9-$0BAD, generator scratch $0300-$032C, $0400-$04EF and $9025-$9028 clobbered",
"Called from: manualLookupCheck ($09E0) to show the map the manual asks about, and from the setup",
" screens of this overlay ($76AD map editor, $76FF, $7A02 game start, $7D23 film playback)"
],
"block": [
"Choose the map style from the game type: QB SNEAK and DEFENDER get special terrain."
],
"line": "gameTypeOptions from the settings block"
},
"6F07": {
"unit": "game/mapGenerator6F00",
"line": "bits 0-2 = game type (0 SCRIMAGE .. 6 DEFENDER)"
},
"6F09": {
"unit": "game/mapGenerator6F00",
"line": "keep the type in Y for the two comparisons below"
},
"6F0A": {
"unit": "game/mapGenerator6F00",
"line": "type 0 (SCRIMAGE): A is already 0 = ordinary random map"
},
"6F0C": {
"unit": "game/mapGenerator6F00",
"line": "style $40 = DEFENDER map (river always, exactly 4 hills, 1-4 forest clusters)"
},
"6F0E": {
"unit": "game/mapGenerator6F00",
"line": "game type 6 = DEFENDER?"
},
"6F10": {
"unit": "game/mapGenerator6F00",
"line": "yes - keep style $40"
},
"6F12": {
"unit": "game/mapGenerator6F00",
"line": "style $80 = QB SNEAK map (no river, at most 1 hill, 10 forest clusters)"
},
"6F14": {
"unit": "game/mapGenerator6F00",
"line": "game type 1 = QB SNEAK?"
},
"6F16": {
"unit": "game/mapGenerator6F00",
"line": "yes - keep style $80"
},
"6F18": {
"unit": "game/mapGenerator6F00",
"line": "every other game type: no special style"
},
"6F1A": {
"unit": "game/mapGenerator6F00",
"line": "$032E mapGenGameFlags: bit 7 = QB SNEAK style, bit 6 = DEFENDER style"
},
"6F1D": {
"unit": "game/mapGenerator6F00",
"block": [
"A map whose name ends in '=' (seed bits 0-4 all set) is built point-symmetric."
],
"line": "assume an asymmetric map"
},
"6F1F": {
"unit": "game/mapGenerator6F00",
"line": "low byte of the 24-bit map seed"
},
"6F22": {
"unit": "game/mapGenerator6F00",
"line": "bits 0-4 are the last character of the 5-letter map name"
},
"6F24": {
"unit": "game/mapGenerator6F00",
"line": "$1F = the alphabet's last symbol '='"
},
"6F26": {
"unit": "game/mapGenerator6F00",
"line": "not a symmetric map code - leave the flag clear"
},
"6F28": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 = build a point-symmetric battlefield"
},
"6F2A": {
"unit": "game/mapGenerator6F00",
"line": "$032D mapSymmetryFlags (bit 6 is set later if the river crosses the centre)"
},
"6F2D": {
"unit": "game/mapGenerator6F00",
"line": "show message 1 'WORKING...' - generating the map takes several seconds"
},
"6F30": {
"unit": "game/mapGenerator6F00",
"line": "fill the whole 40x40 map $F000-$F63F with blank terrain $40"
},
"6F33": {
"unit": "game/mapGenerator6F00",
"line": "scenario RNG $5A-$5C := mapSeed; returns the three seed bytes in A/Y/X"
},
"6F36": {
"unit": "game/mapGenerator6F00",
"routine": [
"runMapGeneratorPasses - the eight terrain passes, entered by fall-through from",
"generateBattlefieldMap. Order: map name from the seed; river with its keep-clear markers; hill",
"summit sites; summit blobs; erase the $80 markers; upper contour ring; lower hill bodies; erase",
"the $81 markers; lower contour ring; forest clusters. A symmetric map is finished by copying the",
"top half onto the bottom half rotated 180 degrees, with a three-cell patch that joins the two",
"halves of the river at the centre. The opponent link is serviced between passes.",
"In: A/Y/X = the three map seed bytes, $032D symmetry flags, $032E map style, RNG $5A-$5C",
"Out: the finished map at $F000-$F63F, map name text $0BA9-$0BAD, generator scratch $0300-$032C;",
" ends with JMP resetMessageQueue, which clears 'WORKING...' and returns to the caller",
"Called from: nothing in this overlay (fall-through only); the JSR $7125 the XREF lists belongs to",
" the comcen-screens overlay that shares this address range"
],
"block": [
"Pass 1-2: name the map, then carve the river."
],
"line": "write the seed as the 5-character map name at $0BA9 (A/Y/X still hold it)"
},
"6F39": {
"unit": "game/mapGenerator6F00",
"line": "carve the river ($55-$5C) and reserve its banks with the $80/$81 markers"
},
"6F3C": {
"unit": "game/mapGenerator6F00",
"block": [
"Pass 3-5: hill summits, then the upper slope ring around them."
],
"line": "choose how many summits to place in the top half and on which lanes"
},
"6F3F": {
"unit": "game/mapGenerator6F00",
"line": "give the modem/trainer link a turn - generation must not stall the exchange"
},
"6F42": {
"unit": "game/mapGenerator6F00",
"line": "paint each summit as a blob of tile $65/$66"
},
"6F45": {
"unit": "game/mapGenerator6F00",
"line": "$80 = the outer (wide) river keep-clear marker"
},
"6F47": {
"unit": "game/mapGenerator6F00",
"line": "turn those markers back into blank $40 before the contour pass reads them"
},
"6F4A": {
"unit": "game/mapGenerator6F00",
"line": "service the link again"
},
"6F4D": {
"unit": "game/mapGenerator6F00",
"line": "contour offset 0: rule-table tiles are used unchanged ($41-$54)"
},
"6F4F": {
"unit": "game/mapGenerator6F00",
"line": "$0324 = amount subtracted from every rule-table tile code"
},
"6F52": {
"unit": "game/mapGenerator6F00",
"line": "$65 = summit tile, terrain class 6"
},
"6F54": {
"unit": "game/mapGenerator6F00",
"line": "draw the upper slope contour $41-$54 around everything of class >= 6"
},
"6F57": {
"unit": "game/mapGenerator6F00",
"line": "service the link"
},
"6F5A": {
"unit": "game/mapGenerator6F00",
"block": [
"Pass 6-7: widen the hills into bodies and draw their lower contour ring."
],
"line": "grow lower-hill bodies ($61-$64) beside the upper slopes"
},
"6F5D": {
"unit": "game/mapGenerator6F00",
"line": "$81 = the inner river keep-clear marker"
},
"6F5F": {
"unit": "game/mapGenerator6F00",
"line": "erase those markers too - the banks are now safe from the lower ring"
},
"6F62": {
"unit": "game/mapGenerator6F00",
"line": "contour offset $20: rule tiles $41-$54 become the lower ring $21-$34"
},
"6F64": {
"unit": "game/mapGenerator6F00",
"line": "$0324"
},
"6F67": {
"unit": "game/mapGenerator6F00",
"line": "$61 = lower hill tile, terrain class 4"
},
"6F69": {
"unit": "game/mapGenerator6F00",
"line": "draw the lower contour around everything of class >= 4"
},
"6F6C": {
"unit": "game/mapGenerator6F00",
"line": "service the link"
},
"6F6F": {
"unit": "game/mapGenerator6F00",
"block": [
"Pass 8: forest, then the optional 180-degree mirror for symmetric maps."
],
"line": "scatter the forest clusters ($5D-$60)"
},
"6F72": {
"unit": "game/mapGenerator6F00",
"line": "mapSymmetryFlags"
},
"6F75": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 clear - asymmetric map, nothing more to do"
},
"6F77": {
"unit": "game/mapGenerator6F00",
"line": "overwrite the bottom half with the 180-degree rotation of the top half"
},
"6F7A": {
"unit": "game/mapGenerator6F00",
"line": "bit 6 = the river jogged up to row 19 at column 20 (set by chooseNextRiverSegment)"
},
"6F7D": {
"unit": "game/mapGenerator6F00",
"line": "the river does not meet itself at the centre - done"
},
"6F7F": {
"unit": "game/mapGenerator6F00",
"line": "$58 = river bend left/up"
},
"6F81": {
"unit": "game/mapGenerator6F00",
"line": "cell (19,20) = $F000 + 20*40 + 19"
},
"6F84": {
"unit": "game/mapGenerator6F00",
"line": "$55 = river bend down/right"
},
"6F86": {
"unit": "game/mapGenerator6F00",
"line": "cell (19,19) = $F000 + 19*40 + 19"
},
"6F89": {
"unit": "game/mapGenerator6F00",
"line": "$40 = blank terrain"
},
"6F8B": {
"unit": "game/mapGenerator6F00",
"line": "cell (20,20): erase the mirrored stub so the two river halves join cleanly"
},
"6F8E": {
"unit": "game/mapGenerator6F00",
"line": "clear the 'WORKING...' message and return to generateBattlefieldMap's caller"
},
"6F91": {
"unit": "game/mapGenerator6F00",
"routine": [
"serviceLinkWhileGenerating - lets the opponent link breathe during the long map build. Does",
"nothing while a game film is being replayed (no opponent) or while the battle loop is running",
"(the frame handler already services the link there); otherwise runs one command-exchange step.",
"In: filmPlaybackMode $0B9B bit 7, gamePhase zp_B1 bit 7",
"Out: whatever serviceCommandExchange ($4DA9) does - packets sent/received, messages updated",
"Called from: runMapGeneratorPasses ($6F3F, $6F4A, $6F57, $6F6C) and the map-name screen ($773A)"
],
"line": "filmPlaybackMode: bit 7 = watching a recorded game"
},
"6F94": {
"unit": "game/mapGenerator6F00",
"line": "film playback - there is nobody on the other end"
},
"6F96": {
"unit": "game/mapGenerator6F00",
"line": "gamePhase: bit 7 set in the setup/menu phases"
},
"6F98": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 clear = the battle loop is running and already services the link"
},
"6F9A": {
"unit": "game/mapGenerator6F00",
"line": "exchange one round of commands with the opponent (tail call)"
},
"6F9D": {
"unit": "game/mapGenerator6F00",
"line": "nothing to do"
},
"6F9E": {
"unit": "game/mapGenerator6F00",
"routine": [
"pickHillSummitSites - decides how many hill summits the map gets and finds a blank cell for each.",
"The count is rolled as (rnd AND 3) + (rnd AND 1), re-rolled to 1-4 if it came out exactly 1;",
"DEFENDER always gets 4 and QB SNEAK at most 1. Each site gets a blob size of 2-5 cells, and four",
"candidate rows in the range 7-14 are rolled. findBlankSitesOnLanes then places the top-half",
"sites; afterwards the count is doubled, the candidate rows are mirrored to 39-row and the same",
"routine runs again by fall-through, so every summit gets a point-mirrored twin in the bottom half.",
"In: $032E map style bits 6/7, scenario RNG",
"Out: $0300 = total number of sites placed, $0307[0..7] blob sizes, $0314[i]/$031C[i] site",
" column/row, $0325[0..3] candidate rows, $0329-$032C lane columns; zp_18, zp_28-zp_2B",
"Called from: runMapGeneratorPasses ($6F3C)"
],
"block": [
"Roll the number of summits for the top half of the map."
],
"line": "start the top-half pass at site 0"
},
"6FA0": {
"unit": "game/mapGenerator6F00",
"line": "zp_2A = index of the site being placed; the first pass starts at site 0"
},
"6FA2": {
"unit": "game/mapGenerator6F00",
"line": "DEFENDER gets exactly 4 summits"
},
"6FA4": {
"unit": "game/mapGenerator6F00",
"line": "mapGenGameFlags"
},
"6FA7": {
"unit": "game/mapGenerator6F00",
"line": "bit 6 (DEFENDER style) - keep the fixed count of 4"
},
"6FA9": {
"unit": "game/mapGenerator6F00",
"line": "first roll"
},
"6FAC": {
"unit": "game/mapGenerator6F00",
"line": "0-3"
},
"6FAE": {
"unit": "game/mapGenerator6F00",
"line": "remember it"
},
"6FB0": {
"unit": "game/mapGenerator6F00",
"line": "second roll"
},
"6FB3": {
"unit": "game/mapGenerator6F00",
"line": "0-1"
},
"6FB5": {
"unit": "game/mapGenerator6F00",
"line": "prepare the add"
},
"6FB6": {
"unit": "game/mapGenerator6F00",
"line": "count = (rnd AND 3) + (rnd AND 1) = 0-4, biased towards 1-3"
},
"6FB8": {
"unit": "game/mapGenerator6F00",
"line": "did it come out as a single lone summit?"
},
"6FBA": {
"unit": "game/mapGenerator6F00",
"line": "no - keep the count"
},
"6FBC": {
"unit": "game/mapGenerator6F00",
"line": "yes - re-roll rather than build a one-hill map"
},
"6FBF": {
"unit": "game/mapGenerator6F00",
"line": "0-3"
},
"6FC1": {
"unit": "game/mapGenerator6F00",
"line": "prepare the add"
},
"6FC2": {
"unit": "game/mapGenerator6F00",
"line": "1-4 summits instead"
},
"6FC4": {
"unit": "game/mapGenerator6F00",
"line": "mapGenGameFlags"
},
"6FC7": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 clear - not QB SNEAK, keep the count"
},
"6FC9": {
"unit": "game/mapGenerator6F00",
"line": "QB SNEAK: 0 or 1 summit only, the field has to stay open"
},
"6FCB": {
"unit": "game/mapGenerator6F00",
"line": "$0300 = summit count (the generator uses the $0200-$03FF setup block as scratch RAM)"
},
"6FCE": {
"unit": "game/mapGenerator6F00",
"line": "redundant: every path above already set Z from A"
},
"6FD0": {
"unit": "game/mapGenerator6F00",
"line": "at least one summit"
},
"6FD2": {
"unit": "game/mapGenerator6F00",
"line": "no hills at all - store 0 through the common exit and return"
},
"6FD5": {
"unit": "game/mapGenerator6F00",
"block": [
"Roll one blob size per site (mirrored to the twin) and four candidate rows 7-14."
],
"line": "zp_28 = highest index of the candidate-row list..."
},
"6FD7": {
"unit": "game/mapGenerator6F00",
"line": "...= count-1, so 0-3 (there are four candidate rows)"
},
"6FD9": {
"unit": "game/mapGenerator6F00",
"line": "Y walks the top-half sites 0..count-1"
},
"6FDB": {
"unit": "game/mapGenerator6F00",
"line": "X walks their bottom-half twins, which start at index count"
},
"6FDE": {
"unit": "game/mapGenerator6F00",
"line": "roll the size of this summit blob"
},
"6FE1": {
"unit": "game/mapGenerator6F00",
"line": "0-3"
},
"6FE3": {
"unit": "game/mapGenerator6F00",
"line": "prepare the add"
},
"6FE4": {
"unit": "game/mapGenerator6F00",
"line": "blob size 2-5 cells"
},
"6FE6": {
"unit": "game/mapGenerator6F00",
"line": "$0307[y] = size of top-half site y"
},
"6FE9": {
"unit": "game/mapGenerator6F00",
"line": "$0307[count+y] = the mirrored twin gets the same size"
},
"6FEC": {
"unit": "game/mapGenerator6F00",
"line": "next top-half site"
},
"6FED": {
"unit": "game/mapGenerator6F00",
"line": "next bottom-half twin"
},
"6FEE": {
"unit": "game/mapGenerator6F00",
"line": "all sites given a size?"
},
"6FF1": {
"unit": "game/mapGenerator6F00",
"line": "one size per site"
},
"6FF3": {
"unit": "game/mapGenerator6F00",
"line": "four candidate rows, filled backwards 3..0"
},
"6FF5": {
"unit": "game/mapGenerator6F00",
"line": "roll one candidate row"
},
"6FF8": {
"unit": "game/mapGenerator6F00",
"line": "0-7"
},
"6FFA": {
"unit": "game/mapGenerator6F00",
"line": "prepare the add"
},
"6FFB": {
"unit": "game/mapGenerator6F00",
"line": "row 7-14: summits stay clear of the top edge and of the centre line"
},
"6FFD": {
"unit": "game/mapGenerator6F00",
"line": "$0325[y] = candidate row list used by findBlankSitesOnLanes"
},
"7000": {
"unit": "game/mapGenerator6F00",
"line": "preload $031C[y] as well so an unplaced site still holds a sane row"
},
"7003": {
"unit": "game/mapGenerator6F00",
"line": "next candidate-row slot"
},
"7004": {
"unit": "game/mapGenerator6F00",
"line": "four candidate rows in all"
},
"7006": {
"unit": "game/mapGenerator6F00",
"block": [
"Place the top half, then mirror everything into the bottom half."
],
"line": "resolve the top-half sites onto the four lanes"
},
"7009": {
"unit": "game/mapGenerator6F00",
"line": "double the placed count - each site also gets a point-mirrored twin"
},
"700C": {
"unit": "game/mapGenerator6F00",
"line": "nothing could be placed - store 0 and return"
},
"700E": {
"unit": "game/mapGenerator6F00",
"line": "mirror the four candidate rows"
},
"7010": {
"unit": "game/mapGenerator6F00",
"line": "row of site y (the accepted row, or the preloaded candidate)"
},
"7013": {
"unit": "game/mapGenerator6F00",
"line": "39 - row: the same distance from the bottom edge"
},
"7016": {
"unit": "game/mapGenerator6F00",
"line": "candidate rows 25-32 for the bottom half"
},
"7019": {
"unit": "game/mapGenerator6F00",
"line": "next of the four candidate rows"
},
"701A": {
"unit": "game/mapGenerator6F00",
"line": "falls into findBlankSitesOnLanes for sites count..2*count-1"
},
"701C": {
"unit": "game/mapGenerator6F00",
"routine": [
"findBlankSitesOnLanes - gives every summit site from zp_2A to $0300-1 a column and a row. The",
"four lane columns are reshuffled first; each site then takes the next lane and the next candidate",
"row and tries up to 21 jittered columns (+/-6 around the lane) until it finds a blank ($40) cell.",
"If a whole row fails it moves on to the next candidate row, and if every row fails the site is",
"dropped ($0300 and zp_2A are decremented). Entered by JSR for the top half and by fall-through",
"for the mirrored bottom half, which is why zp_2A is not reset here.",
"In: zp_2A = first site index, $0300 = requested count, zp_28 = highest candidate-row index,",
" $0325[] candidate rows, map at $F000",
"Out: $0314[i] site column, $031C[i] site row, $0300 = sites actually placed, $0329-$032C lanes;",
" zp_1D/zp_1E/zp_1F/zp_29/zp_2B scratch",
"Called from: pickHillSummitSites ($7006, and by fall-through from $701A)"
],
"line": "randomise the order of the four lane columns 6/15/25/34"
},
"701F": {
"unit": "game/mapGenerator6F00",
"line": "lane index 3 = the last entry of the shuffled lane list"
},
"7021": {
"unit": "game/mapGenerator6F00",
"line": "zp_2B = lane index; advanceLaneIndex counts down 3,2,1,0,3,..."
},
"7023": {
"unit": "game/mapGenerator6F00",
"line": "highest valid candidate-row index (= count-1)"
},
"7025": {
"unit": "game/mapGenerator6F00",
"line": "zp_29 = start at the top of the candidate-row list"
},
"7027": {
"unit": "game/mapGenerator6F00",
"block": [
"Per site: try candidate rows in turn until a blank cell is found."
],
"line": "current candidate-row index"
},
"7029": {
"unit": "game/mapGenerator6F00",
"line": "zp_1F remembers which candidate row this site started with"
},
"702B": {
"unit": "game/mapGenerator6F00",
"line": "21 column attempts per candidate row (counter $14 down through 0)"
},
"702D": {
"unit": "game/mapGenerator6F00",
"line": "zp_1E = attempts left"
},
"702F": {
"unit": "game/mapGenerator6F00",
"line": "current lane"
},
"7031": {
"unit": "game/mapGenerator6F00",
"line": "its column: 6, 15, 25 or 34"
},
"7034": {
"unit": "game/mapGenerator6F00",
"line": "Y = 3 jitter steps, i.e. an offset of 0, +/-2, +/-4 or +/-6 columns"
},
"7036": {
"unit": "game/mapGenerator6F00",
"line": "scatter the site sideways around its lane column"
},
"7039": {
"unit": "game/mapGenerator6F00",
"line": "still inside the 40-column map?"
},
"703B": {
"unit": "game/mapGenerator6F00",
"line": "off the map - roll again (a rejected roll does not use up an attempt)"
},
"703D": {
"unit": "game/mapGenerator6F00",
"line": "index of the site being placed"
},
"703F": {
"unit": "game/mapGenerator6F00",
"line": "$0314[i] = provisional column"
},
"7042": {
"unit": "game/mapGenerator6F00",
"line": "X = column for readMapCell"
},
"7043": {
"unit": "game/mapGenerator6F00",
"line": "current candidate-row slot"
},
"7045": {
"unit": "game/mapGenerator6F00",
"line": "the candidate row for this attempt"
},
"7048": {
"unit": "game/mapGenerator6F00",
"line": "zp_1D keeps it until the cell is known to be free"
},
"704A": {
"unit": "game/mapGenerator6F00",
"line": "Y = row for readMapCell"
},
"704B": {
"unit": "game/mapGenerator6F00",
"line": "zp_48/49 -> map cell (column,row)"
},
"704E": {
"unit": "game/mapGenerator6F00",
"line": "offset 0 = the cell itself"
},
"7050": {
"unit": "game/mapGenerator6F00",
"line": "what is already there"
},
"7052": {
"unit": "game/mapGenerator6F00",
"line": "$40 = blank terrain (the river and its markers are not)"
},
"7054": {
"unit": "game/mapGenerator6F00",
"line": "free - take this site"
},
"7056": {
"unit": "game/mapGenerator6F00",
"line": "one attempt used up"
},
"7058": {
"unit": "game/mapGenerator6F00",
"line": "try another column on the same row"
},
"705A": {
"unit": "game/mapGenerator6F00",
"line": "this row is hopeless - step to the next candidate row"
},
"705D": {
"unit": "game/mapGenerator6F00",
"line": "the candidate row we have wrapped round to"
},
"705F": {
"unit": "game/mapGenerator6F00",
"line": "have we cycled back to the row we started on?"
},
"7061": {
"unit": "game/mapGenerator6F00",
"line": "no - give that row its own 21 attempts"
},
"7063": {
"unit": "game/mapGenerator6F00",
"line": "every candidate row failed: drop this site from the count"
},
"7066": {
"unit": "game/mapGenerator6F00",
"line": "and let the next site re-use its index"
},
"7068": {
"unit": "game/mapGenerator6F00",
"line": "site dropped - skip the accept path"
},
"706B": {
"unit": "game/mapGenerator6F00",
"line": "index of the site just placed"
},
"706D": {
"unit": "game/mapGenerator6F00",
"line": "the row that worked"
},
"706F": {
"unit": "game/mapGenerator6F00",
"line": "$031C[i] = site row"
},
"7072": {
"unit": "game/mapGenerator6F00",
"block": [
"Advance lane and row candidate so consecutive summits are spread out."
],
"line": "next site uses the next lane column"
},
"7075": {
"unit": "game/mapGenerator6F00",
"line": "the candidate row this site started from"
},
"7077": {
"unit": "game/mapGenerator6F00",
"line": "restore the candidate row this site started from..."
},
"7079": {
"unit": "game/mapGenerator6F00",
"line": "...then step it once, so the next site starts on a different row"
},
"707C": {
"unit": "game/mapGenerator6F00",
"line": "next site index"
},
"707E": {
"unit": "game/mapGenerator6F00",
"line": "site index just used"
},
"7080": {
"unit": "game/mapGenerator6F00",
"line": "all requested sites handled?"
},
"7083": {
"unit": "game/mapGenerator6F00",
"line": "all sites handled - store the real count"
},
"7085": {
"unit": "game/mapGenerator6F00",
"line": "place the next site"
},
"7088": {
"unit": "game/mapGenerator6F00",
"line": "zp_2A = number of sites actually placed"
},
"708A": {
"unit": "game/mapGenerator6F00",
"line": "$0300 corrected, so the painters only walk real sites"
},
"708D": {
"unit": "game/mapGenerator6F00",
"line": "returns with $0300 = the number of sites that really exist"
},
"708E": {
"unit": "game/mapGenerator6F00",
"routine": [
"advanceLaneIndex - steps the lane cursor zp_2B down through the four shuffled lane columns in",
"$0329-$032C, wrapping 0 back to 3.",
"In: zp_2B",
"Out: zp_2B = next lane index 0-3",
"Called from: findBlankSitesOnLanes ($7072)"
],
"line": "next lane"
},
"7090": {
"unit": "game/mapGenerator6F00",
"line": "still a valid index"
},
"7092": {
"unit": "game/mapGenerator6F00",
"line": "lane index 3"
},
"7094": {
"unit": "game/mapGenerator6F00",
"line": "wrap round to the last of the four lanes"
},
"7096": {
"unit": "game/mapGenerator6F00",
"line": "return the wrapped lane index"
},
"7097": {
"unit": "game/mapGenerator6F00",
"routine": [
"advanceRowCandidate - steps the candidate-row cursor zp_29 down through $0325[0..zp_28],",
"wrapping 0 back to zp_28 (= summit count - 1).",
"In: zp_29, zp_28",
"Out: zp_29 = next candidate-row index",
"Called from: findBlankSitesOnLanes ($705A, $7079)"
],
"line": "next candidate row"
},
"7099": {
"unit": "game/mapGenerator6F00",
"line": "still a valid index"
},
"709B": {
"unit": "game/mapGenerator6F00",
"line": "highest candidate index"
},
"709D": {
"unit": "game/mapGenerator6F00",
"line": "wrap round to the top of the list"
},
"709F": {
"unit": "game/mapGenerator6F00",
"line": "return the wrapped candidate-row index"
},
"70A0": {
"unit": "game/mapGenerator6F00",
"routine": [
"shuffleLaneColumns - builds a random permutation of 0-3 (identity, then four random transpositions)",
"in the sprite build buffer $9025-$9028, which is free while the map is generated, and writes",
"laneColumnTable[perm[y]] into $0329-$032C. Summits are therefore distributed over the four",
"vertical lanes of the map in a different order for every map.",
"In: scenario RNG, laneColumnTable $6F00",
"Out: $0329-$032C = the four lane columns in random order; $9025-$9028 and zp_18 clobbered",
"Called from: findBlankSitesOnLanes ($701C)"
],
"line": "load the swap count"
},
"70A2": {
"unit": "game/mapGenerator6F00",
"line": "zp_18 = swap counter: 3,2,1,0 = four swaps"
},
"70A4": {
"unit": "game/mapGenerator6F00",
"line": "Y = 3"
},
"70A5": {
"unit": "game/mapGenerator6F00",
"line": "A = Y"
},
"70A6": {
"unit": "game/mapGenerator6F00",
"line": "$9025[y] = y: start from the identity permutation"
},
"70A9": {
"unit": "game/mapGenerator6F00",
"line": "next slot"
},
"70AA": {
"unit": "game/mapGenerator6F00",
"line": "four entries 3..0"
},
"70AC": {
"unit": "game/mapGenerator6F00",
"line": "pick the first index..."
},
"70AF": {
"unit": "game/mapGenerator6F00",
"line": "0-3"
},
"70B1": {
"unit": "game/mapGenerator6F00",
"line": "Y = first slot to swap"
},
"70B2": {
"unit": "game/mapGenerator6F00",
"line": "...and the second (may be the same, which is a no-op swap)"
},
"70B5": {
"unit": "game/mapGenerator6F00",
"line": "0-3"
},
"70B7": {
"unit": "game/mapGenerator6F00",
"line": "X = second slot to swap (may be the same)"
},
"70B8": {
"unit": "game/mapGenerator6F00",
"line": "perm[y]"
},
"70BB": {
"unit": "game/mapGenerator6F00",
"line": "save it on the stack"
},
"70BC": {
"unit": "game/mapGenerator6F00",
"line": "perm[x]"
},
"70BF": {
"unit": "game/mapGenerator6F00",
"line": "perm[y] = perm[x]"
},
"70C2": {
"unit": "game/mapGenerator6F00",
"line": "the old perm[y]"
},
"70C3": {
"unit": "game/mapGenerator6F00",
"line": "exchange perm[y] and perm[x]"
},
"70C6": {
"unit": "game/mapGenerator6F00",
"line": "one swap done"
},
"70C8": {
"unit": "game/mapGenerator6F00",
"line": "four swaps in all"
},
"70CA": {
"unit": "game/mapGenerator6F00",
"line": "Y = 3: fill the lane list backwards"
},
"70CC": {
"unit": "game/mapGenerator6F00",
"line": "permuted index 0-3"
},
"70CF": {
"unit": "game/mapGenerator6F00",
"line": "lane column 6, 15, 25 or 34"
},
"70D2": {
"unit": "game/mapGenerator6F00",
"line": "$0329-$032C = shuffled lane columns"
},
"70D5": {
"unit": "game/mapGenerator6F00",
"line": "next lane slot"
},
"70D6": {
"unit": "game/mapGenerator6F00",
"line": "four lanes"
},
"70D8": {
"unit": "game/mapGenerator6F00",
"line": "the four lane columns are ready"
},
"70D9": {
"unit": "game/mapGenerator6F00",
"routine": [
"paintHillSummits - paints every site chosen by pickHillSummitSites as a blob of summit tiles.",
"Each blob is 2-5 cells of tile $65 (randomTileVariant may pick $66) grown from the site with a",
"horizontal spread of 200/256 and a vertical spread of 32/256, so summits are wide and flat rather",
"than round. Does nothing when no sites were placed.",
"In: $0300 site count, $0307[] blob sizes, $0314[]/$031C[] site coordinates",
"Out: summit tiles written to the map; $0301 = $65, $0304 = 0, zp_2A, zp_A7/zp_A8",
"Called from: runMapGeneratorPasses ($6F42)"
],
"line": "number of summit sites"
},
"70DC": {
"unit": "game/mapGenerator6F00",
"line": "no hills on this map"
},
"70DE": {
"unit": "game/mapGenerator6F00",
"line": "clear A for the two stores below"
},
"70E0": {
"unit": "game/mapGenerator6F00",
"line": "$0304 blob flags = 0: no 2x2 block constraint"
},
"70E3": {
"unit": "game/mapGenerator6F00",
"line": "start at site 0"
},
"70E5": {
"unit": "game/mapGenerator6F00",
"line": "$65 = summit tile, terrain class 6"
},
"70E7": {
"unit": "game/mapGenerator6F00",
"line": "$0301 = the tile growTerrainBlob paints"
},
"70EA": {
"unit": "game/mapGenerator6F00",
"line": "index of the site being painted"
},
"70EC": {
"unit": "game/mapGenerator6F00",
"line": "site column"
},
"70EF": {
"unit": "game/mapGenerator6F00",
"line": "zp_A7 = blob origin column"
},
"70F1": {
"unit": "game/mapGenerator6F00",
"line": "site row"
},
"70F4": {
"unit": "game/mapGenerator6F00",
"line": "zp_A8 = blob origin row"
},
"70F6": {
"unit": "game/mapGenerator6F00",
"line": "A = 2-5 cells to place"
},
"70F9": {
"unit": "game/mapGenerator6F00",
"line": "X = horizontal spread 200/256 - summits stretch east/west"
},
"70FB": {
"unit": "game/mapGenerator6F00",
"line": "Y = vertical spread 32/256 - and stay thin north/south"
},
"70FD": {
"unit": "game/mapGenerator6F00",
"line": "paint this summit"
},
"7100": {
"unit": "game/mapGenerator6F00",
"line": "next site"
},
"7102": {
"unit": "game/mapGenerator6F00",
"line": "site index just painted"
},
"7104": {
"unit": "game/mapGenerator6F00",
"line": "all sites painted?"
},
"7107": {
"unit": "game/mapGenerator6F00",
"line": "every site, top-half original and mirrored twin alike"
},
"7109": {
"unit": "game/mapGenerator6F00",
"line": "no more sites"
},
"710A": {
"unit": "game/mapGenerator6F00",
"routine": [
"growLowerHillsBesideSlopes - second terrain layer. Scans every interior cell (column and row",
"1-38) and, when a blank cell touches an upper slope tile (terrain class 5, $41-$54), grows a",
"5-cell blob of lower-hill tile $61 from it. The chance is 1 in 4 for the north and south",
"neighbours and 1 in 2 for west and east, so the hill bodies spread sideways like the summits.",
"The first matching neighbour wins. Skipped entirely when the map has no hills.",
"In: $0300 summit count, the map, terrainClassTable $077E, scenario RNG",
"Out: lower-hill tiles written to the map; $0301 = $61, $0304 = 0, zp_A7/zp_A8 = the scan cell",
"Called from: runMapGeneratorPasses ($6F5A)"
],
"line": "were any summits placed?"
},
"710D": {
"unit": "game/mapGenerator6F00",
"line": "there are hills to widen"
},
"710F": {
"unit": "game/mapGenerator6F00",
"line": "no hills - nothing to widen"
},
"7112": {
"unit": "game/mapGenerator6F00",
"line": "clear A for the two stores below"
},
"7114": {
"unit": "game/mapGenerator6F00",
"line": "$0304 blob flags = 0: no 2x2 block constraint"
},
"7117": {
"unit": "game/mapGenerator6F00",
"line": "clears zp_2A as a side effect; nothing in this routine reads it"
},
"7119": {
"unit": "game/mapGenerator6F00",
"line": "$61 = lower hill tile ($61-$64 variants), terrain class 4"
},
"711B": {
"unit": "game/mapGenerator6F00",
"line": "$0301 = the tile growTerrainBlob paints"
},
"711E": {
"unit": "game/mapGenerator6F00",
"line": "row 1"
},
"7120": {
"unit": "game/mapGenerator6F00",
"line": "scan starts at row 1 (the outermost ring is never used)"
},
"7122": {
"unit": "game/mapGenerator6F00",
"block": [
"Scan loop over the interior cells. zp_A7/zp_A8 hold the cell; zp_48/49 is set to the top-left",
"corner of its 3x3 block so the neighbours are at fixed offsets $01 N, $28 W, $29 self, $2A E,",
"$51 S."
],
"line": "column 1"
},
"7124": {
"unit": "game/mapGenerator6F00",
"line": "each row starts at column 1"
},
"7126": {
"unit": "game/mapGenerator6F00",
"line": "X = column..."
},
"7128": {
"unit": "game/mapGenerator6F00",
"line": "...minus 1"
},
"7129": {
"unit": "game/mapGenerator6F00",
"line": "Y = row..."
},
"712B": {
"unit": "game/mapGenerator6F00",
"line": "...minus 1"
},
"712C": {
"unit": "game/mapGenerator6F00",
"line": "zp_48/49 -> cell (col-1,row-1), the top-left of the 3x3 block"
},
"712F": {
"unit": "game/mapGenerator6F00",
"line": "offset $29 = the cell itself"
},
"7131": {
"unit": "game/mapGenerator6F00",
"line": "the terrain code of the scan cell"
},
"7133": {
"unit": "game/mapGenerator6F00",
"line": "only blank cells can start a lower hill"
},
"7135": {
"unit": "game/mapGenerator6F00",
"line": "occupied - move on"
},
"7137": {
"unit": "game/mapGenerator6F00",
"line": "offset $01 = north neighbour (col,row-1)"
},
"7139": {
"unit": "game/mapGenerator6F00",
"line": "north neighbour's cell"
},
"713B": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 set = a unit or a river keep-clear marker, not terrain"
},
"713D": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"713E": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of the north neighbour"
},
"7141": {
"unit": "game/mapGenerator6F00",
"line": "class 5 = upper slope contour $41-$54"
},
"7143": {
"unit": "game/mapGenerator6F00",
"line": "not a slope - try the west neighbour"
},
"7145": {
"unit": "game/mapGenerator6F00",
"line": "roll for the north slope"
},
"7148": {
"unit": "game/mapGenerator6F00",
"line": "1 chance in 4 for a north slope"
},
"714A": {
"unit": "game/mapGenerator6F00",
"line": "won - grow a hill body here"
},
"714C": {
"unit": "game/mapGenerator6F00",
"line": "offset $28 = west neighbour (col-1,row)"
},
"714E": {
"unit": "game/mapGenerator6F00",
"line": "west neighbour's cell"
},
"7150": {
"unit": "game/mapGenerator6F00",
"line": "unit or marker - skip"
},
"7152": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"7153": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of the west neighbour"
},
"7156": {
"unit": "game/mapGenerator6F00",
"line": "upper slope?"
},
"7158": {
"unit": "game/mapGenerator6F00",
"line": "no - try the east neighbour"
},
"715A": {
"unit": "game/mapGenerator6F00",
"line": "roll for the west slope"
},
"715D": {
"unit": "game/mapGenerator6F00",
"line": "1 chance in 2 for a side slope - hills widen east/west"
},
"715F": {
"unit": "game/mapGenerator6F00",
"line": "won - grow a hill body here"
},
"7161": {
"unit": "game/mapGenerator6F00",
"line": "offset $2A = east neighbour (col+1,row)"
},
"7163": {
"unit": "game/mapGenerator6F00",
"line": "east neighbour's cell"
},
"7165": {
"unit": "game/mapGenerator6F00",
"line": "unit or marker - skip"
},
"7167": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"7168": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of the east neighbour"
},
"716B": {
"unit": "game/mapGenerator6F00",
"line": "upper slope?"
},
"716D": {
"unit": "game/mapGenerator6F00",
"line": "no - try the south neighbour"
},
"716F": {
"unit": "game/mapGenerator6F00",
"line": "roll for the east slope"
},
"7172": {
"unit": "game/mapGenerator6F00",
"line": "1 chance in 2"
},
"7174": {
"unit": "game/mapGenerator6F00",
"line": "won - grow a hill body here"
},
"7176": {
"unit": "game/mapGenerator6F00",
"line": "offset $51 = south neighbour (col,row+1)"
},
"7178": {
"unit": "game/mapGenerator6F00",
"line": "south neighbour's cell"
},
"717A": {
"unit": "game/mapGenerator6F00",
"line": "unit or marker - give up on this cell"
},
"717C": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"717D": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of the south neighbour"
},
"7180": {
"unit": "game/mapGenerator6F00",
"line": "upper slope?"
},
"7182": {
"unit": "game/mapGenerator6F00",
"line": "no - nothing to do at this cell"
},
"7184": {
"unit": "game/mapGenerator6F00",
"line": "roll for the south slope"
},
"7187": {
"unit": "game/mapGenerator6F00",
"line": "1 chance in 4 (inverted test: falls through to grow)"
},
"7189": {
"unit": "game/mapGenerator6F00",
"line": "lost the roll"
},
"718B": {
"unit": "game/mapGenerator6F00",
"line": "X = horizontal spread 64/256"
},
"718D": {
"unit": "game/mapGenerator6F00",
"line": "Y = vertical spread 16/256 - the body hugs the slope"
},
"718F": {
"unit": "game/mapGenerator6F00",
"line": "A = 5 cells"
},
"7191": {
"unit": "game/mapGenerator6F00",
"line": "zp_A7/zp_A8 already hold the scan cell = the blob origin"
},
"7194": {
"unit": "game/mapGenerator6F00",
"line": "next column"
},
"7196": {
"unit": "game/mapGenerator6F00",
"line": "the column just finished"
},
"7198": {
"unit": "game/mapGenerator6F00",
"line": "columns 1-38 only"
},
"719A": {
"unit": "game/mapGenerator6F00",
"line": "row finished"
},
"719C": {
"unit": "game/mapGenerator6F00",
"line": "scan the next cell of this row"
},
"719F": {
"unit": "game/mapGenerator6F00",
"line": "next row"
},
"71A1": {
"unit": "game/mapGenerator6F00",
"line": "the row just finished"
},
"71A3": {
"unit": "game/mapGenerator6F00",
"line": "rows 1-38 only"
},
"71A5": {
"unit": "game/mapGenerator6F00",
"line": "whole map scanned"
},
"71A7": {
"unit": "game/mapGenerator6F00",
"line": "scan the next row"
},
"71AA": {
"unit": "game/mapGenerator6F00",
"line": "the whole interior has been scanned"
},
"71AB": {
"unit": "game/mapGenerator6F00",
"block": [
"unusedBitTable71AB - $08,$04,$02,$01,$00. Dead in this overlay: nothing between $6F00 and $87FF",
"reads it (the $71AC reference in XREF belongs to the comcen-screens overlay). It looks like a",
"leftover direction-bit table for growTerrainBlob, which builds the same bits with immediate",
"operands instead."
],
"line": "unused direction-bit constants"
},
"71B0": {
"unit": "game/mapGenerator6F00",
"routine": [
"growTerrainBlob - the generic random blob painter used by every terrain pass. Starting at",
"(zp_A7,zp_A8) it performs a depth-first walk with an explicit 80-entry stack in page 4 ($0400",
"columns, $0450 rows, $04A0 tried-direction flags) and paints tile $0301 - passed through",
"randomTileVariant - on blank ($40) cells until A cells have been placed, the stack empties or the",
"stack overflows. From each cell the four directions are tried once (flag bits 0 N, 1 W, 2 E,",
"3 S in zp_6B); a neighbour is taken when it is on the map, blank, and a scenario random byte is",
"below the X (west/east) or Y (north/south) threshold, so X and Y control the horizontal and",
"vertical spread out of 256. A newly pushed cell has the direction back towards the origin",
"pre-marked as tried, which keeps the blob growing outwards. With $0304 bit 6 set (forest) a cell",
"is only painted when checkAlignedBlockForForest approves its 2x2 block.",
"In: A = cells to paint, X = horizontal spread 0-255, Y = vertical spread 0-255,",
" zp_A7/zp_A8 = origin, $0301 = base tile, $0304 = blob flags",
"Out: map cells painted; zp_18, zp_1A, zp_6B, zp_A5/zp_A6, zp_B2 stack level, zp_B3 painted count,",
" $91DA/$91DB and $0400-$04EF clobbered. NOTE: $0400-$04EF is the page that also holds the",
" copy-protection answer table at $0401 - harmless, because manualLookupCheck reads its answer",
" before it calls the generator",
"Called from: paintHillSummits ($70FD), growLowerHillsBesideSlopes ($7191), paintForestBlobAt ($73EA)"
],
"block": [
"Set up the walk: thresholds, counters and stack entry 0 = the origin cell."
],
"line": "X = horizontal accept threshold, parked in the engine's currentUnitCol (free here)"
},
"71B3": {
"unit": "game/mapGenerator6F00",
"line": "Y = vertical accept threshold, parked in currentUnitRow"
},
"71B6": {
"unit": "game/mapGenerator6F00",
"line": "zp_18 = how many cells this blob should get"
},
"71B8": {
"unit": "game/mapGenerator6F00",
"line": "clear A for the three stores below"
},
"71BA": {
"unit": "game/mapGenerator6F00",
"line": "zp_B3 = cells painted so far"
},
"71BC": {
"unit": "game/mapGenerator6F00",
"line": "$04A0[0] = tried-direction flags of the origin entry"
},
"71BF": {
"unit": "game/mapGenerator6F00",
"line": "zp_B2 = stack fill level (index of the next free entry)"
},
"71C1": {
"unit": "game/mapGenerator6F00",
"line": "blob flags: bit 6 = only paint inside a clean 2x2 block"
},
"71C4": {
"unit": "game/mapGenerator6F00",
"line": "zp_6B = flags of the cell currently being expanded"
},
"71C6": {
"unit": "game/mapGenerator6F00",
"line": "the walk starts at the blob origin"
},
"71C8": {
"unit": "game/mapGenerator6F00",
"line": "zp_A5 = column of the current cell"
},
"71CA": {
"unit": "game/mapGenerator6F00",
"line": "$0400[0] = origin column"
},
"71CD": {
"unit": "game/mapGenerator6F00",
"line": "origin row"
},
"71CF": {
"unit": "game/mapGenerator6F00",
"line": "zp_A6 = row of the current cell"
},
"71D1": {
"unit": "game/mapGenerator6F00",
"line": "$0450[0] = origin row"
},
"71D4": {
"unit": "game/mapGenerator6F00",
"line": "zp_48/49 -> the origin cell (copes with negative coordinates)"
},
"71D7": {
"unit": "game/mapGenerator6F00",
"line": "offset 0 = the cell itself"
},
"71D9": {
"unit": "game/mapGenerator6F00",
"line": "paint the origin, then push it as the first stack entry"
},
"71DC": {
"unit": "game/mapGenerator6F00",
"block": [
"Pop the top stack entry and try its four directions in turn. zp_48/49 is aimed one row above",
"the cell, so N/W/E/S are at offsets $00/$27/$29/$50."
],
"line": "drop the fill level to the entry on top of the stack"
},
"71DE": {
"unit": "game/mapGenerator6F00",
"line": "there is still an entry to expand"
},
"71E0": {
"unit": "game/mapGenerator6F00",
"line": "stack empty - this blob is finished"
},
"71E3": {
"unit": "game/mapGenerator6F00",
"line": "y = the entry now on top of the stack"
},
"71E5": {
"unit": "game/mapGenerator6F00",
"line": "$04A0[y] = directions already tried from this cell"
},
"71E8": {
"unit": "game/mapGenerator6F00",
"line": "re-apply the global blob flags (bit 6 survives every push/pop)"
},
"71EB": {
"unit": "game/mapGenerator6F00",
"line": "zp_6B = the flags of the cell being expanded"
},
"71ED": {
"unit": "game/mapGenerator6F00",
"line": "$0400[y] = its column"
},
"71F0": {
"unit": "game/mapGenerator6F00",
"line": "$0450[y] = its row"
},
"71F3": {
"unit": "game/mapGenerator6F00",
"line": "A -> Y so it can be decremented"
},
"71F4": {
"unit": "game/mapGenerator6F00",
"line": "aim one row above the cell..."
},
"71F5": {
"unit": "game/mapGenerator6F00",
"line": "...so the north neighbour sits at offset 0"
},
"71F7": {
"unit": "game/mapGenerator6F00",
"line": "zp_A5 = the cell's column"
},
"71F9": {
"unit": "game/mapGenerator6F00",
"line": "zp_48/49 -> (column, row-1)"
},
"71FC": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"71FE": {
"unit": "game/mapGenerator6F00",
"line": "bit 0 = north already tried"
},
"7200": {
"unit": "game/mapGenerator6F00",
"line": "yes - go on to the west neighbour"
},
"7202": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"7204": {
"unit": "game/mapGenerator6F00",
"line": "bit 0 = north"
},
"7206": {
"unit": "game/mapGenerator6F00",
"line": "mark north as tried"
},
"7208": {
"unit": "game/mapGenerator6F00",
"line": "row-1 above the top edge of the map?"
},
"720A": {
"unit": "game/mapGenerator6F00",
"line": "yes - try west"
},
"720C": {
"unit": "game/mapGenerator6F00",
"line": "offset $00 = north neighbour"
},
"720E": {
"unit": "game/mapGenerator6F00",
"line": "the north neighbour's cell"
},
"7210": {
"unit": "game/mapGenerator6F00",
"line": "only blank terrain can be painted"
},
"7212": {
"unit": "game/mapGenerator6F00",
"line": "not blank - cannot grow there"
},
"7214": {
"unit": "game/mapGenerator6F00",
"line": "roll for the vertical spread"
},
"7217": {
"unit": "game/mapGenerator6F00",
"line": "accept while the random byte is below the vertical spread"
},
"721A": {
"unit": "game/mapGenerator6F00",
"line": "lost the roll - try west"
},
"721C": {
"unit": "game/mapGenerator6F00",
"line": "grow into the north neighbour (zp_A5/zp_A6 and Y already point at it)"
},
"721F": {
"unit": "game/mapGenerator6F00",
"line": "undo the -1: back to the cell's own row"
},
"7221": {
"unit": "game/mapGenerator6F00",
"line": "step one column west"
},
"7223": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"7225": {
"unit": "game/mapGenerator6F00",
"line": "bit 1 = west already tried"
},
"7227": {
"unit": "game/mapGenerator6F00",
"line": "west already tried from this cell"
},
"7229": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"722B": {
"unit": "game/mapGenerator6F00",
"line": "bit 1 = west"
},
"722D": {
"unit": "game/mapGenerator6F00",
"line": "mark west as tried"
},
"722F": {
"unit": "game/mapGenerator6F00",
"line": "column-1 off the left edge?"
},
"7231": {
"unit": "game/mapGenerator6F00",
"line": "column -1 is off the map"
},
"7233": {
"unit": "game/mapGenerator6F00",
"line": "offset $27 = west neighbour (-1 column, +1 row from the pointer)"
},
"7235": {
"unit": "game/mapGenerator6F00",
"line": "the west neighbour's cell"
},
"7237": {
"unit": "game/mapGenerator6F00",
"line": "blank?"
},
"7239": {
"unit": "game/mapGenerator6F00",
"line": "not blank"
},
"723B": {
"unit": "game/mapGenerator6F00",
"line": "roll for the horizontal spread"
},
"723E": {
"unit": "game/mapGenerator6F00",
"line": "accept while the random byte is below the horizontal spread"
},
"7241": {
"unit": "game/mapGenerator6F00",
"line": "grow into the west neighbour"
},
"7243": {
"unit": "game/mapGenerator6F00",
"line": "back to the cell's own column..."
},
"7245": {
"unit": "game/mapGenerator6F00",
"line": "two columns east: the cell's column + 1"
},
"7247": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"7249": {
"unit": "game/mapGenerator6F00",
"line": "bit 2 = east already tried"
},
"724B": {
"unit": "game/mapGenerator6F00",
"line": "east already tried"
},
"724D": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"724F": {
"unit": "game/mapGenerator6F00",
"line": "bit 2 = east"
},
"7251": {
"unit": "game/mapGenerator6F00",
"line": "mark east as tried"
},
"7253": {
"unit": "game/mapGenerator6F00",
"line": "the column the east neighbour sits in"
},
"7255": {
"unit": "game/mapGenerator6F00",
"line": "column 40 is off the right edge"
},
"7257": {
"unit": "game/mapGenerator6F00",
"line": "column 40 is off the map"
},
"7259": {
"unit": "game/mapGenerator6F00",
"line": "offset $29 = east neighbour (+1 column, +1 row)"
},
"725B": {
"unit": "game/mapGenerator6F00",
"line": "the east neighbour's cell"
},
"725D": {
"unit": "game/mapGenerator6F00",
"line": "blank?"
},
"725F": {
"unit": "game/mapGenerator6F00",
"line": "not blank"
},
"7261": {
"unit": "game/mapGenerator6F00",
"line": "roll for the horizontal spread"
},
"7264": {
"unit": "game/mapGenerator6F00",
"line": "horizontal spread again"
},
"7267": {
"unit": "game/mapGenerator6F00",
"line": "grow into the east neighbour"
},
"7269": {
"unit": "game/mapGenerator6F00",
"line": "back to the cell's own column"
},
"726B": {
"unit": "game/mapGenerator6F00",
"line": "step one row south"
},
"726D": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"726F": {
"unit": "game/mapGenerator6F00",
"line": "bit 3 = south already tried"
},
"7271": {
"unit": "game/mapGenerator6F00",
"line": "south already tried"
},
"7273": {
"unit": "game/mapGenerator6F00",
"line": "tried-direction flags"
},
"7275": {
"unit": "game/mapGenerator6F00",
"line": "bit 3 = south"
},
"7277": {
"unit": "game/mapGenerator6F00",
"line": "mark south as tried"
},
"7279": {
"unit": "game/mapGenerator6F00",
"line": "the row the south neighbour sits in"
},
"727B": {
"unit": "game/mapGenerator6F00",
"line": "row 40 is off the bottom edge"
},
"727D": {
"unit": "game/mapGenerator6F00",
"line": "row 40 is off the map"
},
"727F": {
"unit": "game/mapGenerator6F00",
"line": "offset $50 = south neighbour (+2 rows)"
},
"7281": {
"unit": "game/mapGenerator6F00",
"line": "the south neighbour's cell"
},
"7283": {
"unit": "game/mapGenerator6F00",
"line": "blank?"
},
"7285": {
"unit": "game/mapGenerator6F00",
"line": "not blank"
},
"7287": {
"unit": "game/mapGenerator6F00",
"line": "roll for the vertical spread"
},
"728A": {
"unit": "game/mapGenerator6F00",
"line": "vertical spread again"
},
"728D": {
"unit": "game/mapGenerator6F00",
"line": "grow into the south neighbour"
},
"728F": {
"unit": "game/mapGenerator6F00",
"line": "all four directions used up - pop the next cell"
},
"7292": {
"unit": "game/mapGenerator6F00",
"block": [
"Paint the accepted cell (Y = its offset from zp_48/49) and push it on the stack."
],
"line": "the candidate cell"
},
"7294": {
"unit": "game/mapGenerator6F00",
"line": "blank terrain?"
},
"7296": {
"unit": "game/mapGenerator6F00",
"line": "not blank (only possible for the origin) - push it without painting"
},
"7298": {
"unit": "game/mapGenerator6F00",
"line": "bit 6 = the 2x2 forest constraint"
},
"729A": {
"unit": "game/mapGenerator6F00",
"line": "bit 6 clear - paint unconditionally"
},
"729C": {
"unit": "game/mapGenerator6F00",
"line": "forest: the aligned 2x2 block must contain only blank and forest"
},
"729F": {
"unit": "game/mapGenerator6F00",
"line": "block rejected - do not paint, but still expand from here"
},
"72A1": {
"unit": "game/mapGenerator6F00",
"line": "base tile for this pass"
},
"72A4": {
"unit": "game/mapGenerator6F00",
"line": "add a random variant (Y is preserved through a self-modified LDY at $7891+1)"
},
"72A7": {
"unit": "game/mapGenerator6F00",
"line": "paint the cell"
},
"72A9": {
"unit": "game/mapGenerator6F00",
"line": "one more cell of this blob placed"
},
"72AB": {
"unit": "game/mapGenerator6F00",
"line": "cells placed so far"
},
"72AD": {
"unit": "game/mapGenerator6F00",
"line": "reached the requested number of cells?"
},
"72AF": {
"unit": "game/mapGenerator6F00",
"line": "yes - blob finished"
},
"72B1": {
"unit": "game/mapGenerator6F00",
"line": "y = the parent entry that is being expanded"
},
"72B3": {
"unit": "game/mapGenerator6F00",
"line": "the parent's flags with the direction just used marked as tried"
},
"72B5": {
"unit": "game/mapGenerator6F00",
"line": "$04A0[parent] = its updated tried-direction flags"
},
"72B8": {
"unit": "game/mapGenerator6F00",
"line": "the child entry goes one slot higher"
},
"72B9": {
"unit": "game/mapGenerator6F00",
"line": "the accepted cell's column"
},
"72BB": {
"unit": "game/mapGenerator6F00",
"line": "$0400[child] = column"
},
"72BE": {
"unit": "game/mapGenerator6F00",
"line": "and its row"
},
"72C0": {
"unit": "game/mapGenerator6F00",
"line": "$0450[child] = row"
},
"72C3": {
"unit": "game/mapGenerator6F00",
"block": [
"Pre-mark the direction back towards the blob origin as already tried, so a blob never folds",
"back on itself."
],
"line": "clear A"
},
"72C5": {
"unit": "game/mapGenerator6F00",
"line": "zp_1A = the child's preset flags"
},
"72C7": {
"unit": "game/mapGenerator6F00",
"line": "$02 = 'west already tried'"
},
"72C9": {
"unit": "game/mapGenerator6F00",
"line": "the child's column"
},
"72CB": {
"unit": "game/mapGenerator6F00",
"line": "child column against the blob origin column"
},
"72CD": {
"unit": "game/mapGenerator6F00",
"line": "same column - no horizontal bias"
},
"72CF": {
"unit": "game/mapGenerator6F00",
"line": "child is east of the origin - block growth back west"
},
"72D1": {
"unit": "game/mapGenerator6F00",
"line": "$04 = 'east already tried' (child is west of the origin)"
},
"72D3": {
"unit": "game/mapGenerator6F00",
"line": "horizontal bias"
},
"72D5": {
"unit": "game/mapGenerator6F00",
"line": "$01 = 'north already tried'"
},
"72D7": {
"unit": "game/mapGenerator6F00",
"line": "the child's row"
},
"72D9": {
"unit": "game/mapGenerator6F00",
"line": "child row against the blob origin row"
},
"72DB": {
"unit": "game/mapGenerator6F00",
"line": "same row - no vertical bias"
},
"72DD": {
"unit": "game/mapGenerator6F00",
"line": "child is below the origin - block growth back north"
},
"72DF": {
"unit": "game/mapGenerator6F00",
"line": "$08 = 'south already tried' (child is above the origin)"
},
"72E1": {
"unit": "game/mapGenerator6F00",
"line": "combine with the horizontal bias"
},
"72E3": {
"unit": "game/mapGenerator6F00",
"line": "zp_1A = the child's preset tried-direction flags"
},
"72E5": {
"unit": "game/mapGenerator6F00",
"line": "the child's preset tried-direction flags"
},
"72E7": {
"unit": "game/mapGenerator6F00",
"line": "$04A0[child] = its preset flags"
},
"72EA": {
"unit": "game/mapGenerator6F00",
"line": "point one past the child entry"
},
"72EB": {
"unit": "game/mapGenerator6F00",
"line": "zp_B2 = new fill level = child + 1"
},
"72ED": {
"unit": "game/mapGenerator6F00",
"line": "80 entries is all that fits ($0400/$0450/$04A0 x 80 = $0400-$04EF)"
},
"72EF": {
"unit": "game/mapGenerator6F00",
"line": "still room on the stack"
},
"72F1": {
"unit": "game/mapGenerator6F00",
"line": "stack full - abandon this blob"
},
"72F2": {
"unit": "game/mapGenerator6F00",
"line": "expand the cell just pushed"
},
"72F5": {
"unit": "game/mapGenerator6F00",
"line": "blob finished: cell count reached, or the stack ran dry"
},
"72F6": {
"unit": "game/mapGenerator6F00",
"routine": [
"checkAlignedBlockForForest - constrains forest to whole 2x2 blocks on an even grid. It takes the",
"block containing (zp_A5,zp_A6) - both coordinates rounded down to even - and returns C = 0 only if",
"all four cells are terrain class 0 (blank $40) or class 2 (forest $5D-$60). On success zp_48/49",
"is re-pointed at the caller's own cell with Y = 0, so the caller can store straight through it.",
"Note that the river keep-clear markers $80/$81 index past terrainClassTable into the zero filler",
"at $07F3, so they read as class 0 here; growTerrainBlob's own $40 test still refuses to paint them.",
"In: zp_A5/zp_A6 = the cell, map, terrainClassTable $077E",
"Out: C = 0 accept / C = 1 reject; zp_48/49, A/X/Y clobbered",
"Called from: growTerrainBlob ($729C) when $0304 bit 6 is set"
],
"line": "column of the cell about to be painted"
},
"72F8": {
"unit": "game/mapGenerator6F00",
"line": "round the column down to the even grid"
},
"72FA": {
"unit": "game/mapGenerator6F00",
"line": "X = block column"
},
"72FB": {
"unit": "game/mapGenerator6F00",
"line": "its row"
},
"72FD": {
"unit": "game/mapGenerator6F00",
"line": "round the row down as well"
},
"72FF": {
"unit": "game/mapGenerator6F00",
"line": "Y = block row"
},
"7300": {
"unit": "game/mapGenerator6F00",
"line": "A = the block's top-left cell, zp_48/49 -> it, Y = 0"
},
"7303": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"7304": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of that cell"
},
"7307": {
"unit": "game/mapGenerator6F00",
"line": "class 0 = blank: acceptable"
},
"7309": {
"unit": "game/mapGenerator6F00",
"line": "class 2 = forest: also acceptable"
},
"730B": {
"unit": "game/mapGenerator6F00",
"line": "anything else (river, hill, contour, unit) rejects the block"
},
"730D": {
"unit": "game/mapGenerator6F00",
"line": "offset 1 = top-right cell"
},
"730E": {
"unit": "game/mapGenerator6F00",
"line": "the top-right cell of the block"
},
"7310": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"7311": {
"unit": "game/mapGenerator6F00",
"line": "its terrain class"
},
"7314": {
"unit": "game/mapGenerator6F00",
"line": "blank"
},
"7316": {
"unit": "game/mapGenerator6F00",
"line": "or forest"
},
"7318": {
"unit": "game/mapGenerator6F00",
"line": "not blank or forest - reject the block"
},
"731A": {
"unit": "game/mapGenerator6F00",
"line": "offset $28 = bottom-left cell"
},
"731C": {
"unit": "game/mapGenerator6F00",
"line": "the bottom-left cell of the block"
},
"731E": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"731F": {
"unit": "game/mapGenerator6F00",
"line": "its terrain class"
},
"7322": {
"unit": "game/mapGenerator6F00",
"line": "blank"
},
"7324": {
"unit": "game/mapGenerator6F00",
"line": "or forest"
},
"7326": {
"unit": "game/mapGenerator6F00",
"line": "not blank or forest - reject the block"
},
"7328": {
"unit": "game/mapGenerator6F00",
"line": "offset $29 = bottom-right cell"
},
"7329": {
"unit": "game/mapGenerator6F00",
"line": "the bottom-right cell of the block"
},
"732B": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"732C": {
"unit": "game/mapGenerator6F00",
"line": "its terrain class"
},
"732F": {
"unit": "game/mapGenerator6F00",
"line": "blank"
},
"7331": {
"unit": "game/mapGenerator6F00",
"line": "or forest"
},
"7333": {
"unit": "game/mapGenerator6F00",
"line": "not blank or forest - reject the block"
},
"7335": {
"unit": "game/mapGenerator6F00",
"line": "the caller's own column"
},
"7337": {
"unit": "game/mapGenerator6F00",
"line": "and row"
},
"7339": {
"unit": "game/mapGenerator6F00",
"line": "re-point zp_48/49 at the caller's own cell (leaves Y = 0)"
},
"733C": {
"unit": "game/mapGenerator6F00",
"line": "C = 0: this block may be forested"
},
"733D": {
"unit": "game/mapGenerator6F00",
"line": "C = 0 from $733C"
},
"733E": {
"unit": "game/mapGenerator6F00",
"line": "C = 1: the block holds something else"
},
"733F": {
"unit": "game/mapGenerator6F00",
"line": "C = 1 set at $733E"
},
"7340": {
"unit": "game/mapGenerator6F00",
"routine": [
"placeForestClusters - the last terrain pass. Rolls a number of forest clusters (3-10 normally,",
"with a 1-in-32 chance of no forest at all; exactly 10 for QB SNEAK; 1-4 for DEFENDER), gives each",
"cluster a random centre at column/row 4-35 and scatters 6 seed points around it (+/-16 columns,",
"+/-8 rows, re-rolled while off the map). Every seed becomes a 4x2 patch of small blobs through",
"paintForestClusterSeeds. Blob flags $40 make all of it respect the 2x2 forest grid.",
"In: $032E map style, scenario RNG",
"Out: forest tiles $5D-$60 in the map; $0301, $0302, $0304, zp_2A cluster counter, zp_2B seed",
" counter, zp_92-zp_95, zp_A5/zp_A6",
"Called from: runMapGeneratorPasses ($6F6F)"
],
"line": "blob flag bit 6: forest only grows inside a clean aligned 2x2 block"
},
"7342": {
"unit": "game/mapGenerator6F00",
"line": "$0304 blob flags"
},
"7345": {
"unit": "game/mapGenerator6F00",
"line": "$41 = upper contour tile"
},
"7347": {
"unit": "game/mapGenerator6F00",
"line": "dead store: nothing in this overlay ever reads $0302 (XREF has no reader)"
},
"734A": {
"unit": "game/mapGenerator6F00",
"line": "$5D = forest tile ($5D-$60 variants), terrain class 2"
},
"734C": {
"unit": "game/mapGenerator6F00",
"line": "$0301 = the tile growTerrainBlob paints"
},
"734F": {
"unit": "game/mapGenerator6F00",
"line": "QB SNEAK: 9 -> ten clusters, a deliberately cluttered field"
},
"7351": {
"unit": "game/mapGenerator6F00",
"line": "mapGenGameFlags"
},
"7354": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 = QB SNEAK style - keep the fixed count"
},
"7356": {
"unit": "game/mapGenerator6F00",
"line": "roll the cluster count"
},
"7359": {
"unit": "game/mapGenerator6F00",
"line": "0-31"
},
"735B": {
"unit": "game/mapGenerator6F00",
"line": "1 chance in 32 of a completely bare map"
},
"735D": {
"unit": "game/mapGenerator6F00",
"line": "0-7..."
},
"735F": {
"unit": "game/mapGenerator6F00",
"line": "prepare the add"
},
"7360": {
"unit": "game/mapGenerator6F00",
"line": "...+2, so 3-10 clusters in total"
},
"7362": {
"unit": "game/mapGenerator6F00",
"line": "mapGenGameFlags"
},
"7365": {
"unit": "game/mapGenerator6F00",
"line": "bit 6 clear - not DEFENDER"
},
"7367": {
"unit": "game/mapGenerator6F00",
"line": "DEFENDER: at most 3, i.e. 1-4 clusters (the map has to stay open)"
},
"7369": {
"unit": "game/mapGenerator6F00",
"line": "zp_2A = clusters left minus one"
},
"736B": {
"unit": "game/mapGenerator6F00",
"block": [
"Per cluster: pick a centre, then scatter six seed patches around it."
],
"line": "roll the cluster centre column"
},
"736E": {
"unit": "game/mapGenerator6F00",
"line": "0-31"
},
"7370": {
"unit": "game/mapGenerator6F00",
"line": "prepare the add"
},
"7371": {
"unit": "game/mapGenerator6F00",
"line": "cluster centre column 4-35"
},
"7373": {
"unit": "game/mapGenerator6F00",
"line": "zp_95 = centre column, the base for the column jitter"
},
"7375": {
"unit": "game/mapGenerator6F00",
"line": "vestigial: growTerrainBlob overwrites zp_A6 at once, and this is a column, not a row"
},
"7377": {
"unit": "game/mapGenerator6F00",
"line": "roll the cluster centre row"
},
"737A": {
"unit": "game/mapGenerator6F00",
"line": "0-31"
},
"737C": {
"unit": "game/mapGenerator6F00",
"line": "prepare the add"
},
"737D": {
"unit": "game/mapGenerator6F00",
"line": "cluster centre row 4-35"
},
"737F": {
"unit": "game/mapGenerator6F00",
"line": "zp_94 = centre row, the base for the row jitter"
},
"7381": {
"unit": "game/mapGenerator6F00",
"line": "vestigial in the same way (a row written to the view-origin column)"
},
"7383": {
"unit": "game/mapGenerator6F00",
"line": "six seeds per cluster (5 down through 0)"
},
"7385": {
"unit": "game/mapGenerator6F00",
"line": "zp_2B = six seed points per cluster (5 down through 0)"
},
"7387": {
"unit": "game/mapGenerator6F00",
"line": "centre row"
},
"7389": {
"unit": "game/mapGenerator6F00",
"line": "Y = 4 jitter steps = an offset of 0, +/-2, +/-4, +/-6 or +/-8 rows"
},
"738B": {
"unit": "game/mapGenerator6F00",
"line": "scatter the seed row around the cluster centre"
},
"738E": {
"unit": "game/mapGenerator6F00",
"line": "still on the map?"
},
"7390": {
"unit": "game/mapGenerator6F00",
"line": "off the map - roll the row again"
},
"7392": {
"unit": "game/mapGenerator6F00",
"line": "zp_92 = seed row"
},
"7394": {
"unit": "game/mapGenerator6F00",
"line": "centre column"
},
"7396": {
"unit": "game/mapGenerator6F00",
"line": "Y = 8 jitter steps = up to +/-16 columns, so clusters are wide"
},
"7398": {
"unit": "game/mapGenerator6F00",
"line": "scatter the seed column around the cluster centre"
},
"739B": {
"unit": "game/mapGenerator6F00",
"line": "still on the map?"
},
"739D": {
"unit": "game/mapGenerator6F00",
"line": "off the map - roll the column again"
},
"739F": {
"unit": "game/mapGenerator6F00",
"line": "zp_93 = seed column"
},
"73A1": {
"unit": "game/mapGenerator6F00",
"line": "paint the 4x2 patch of blobs around this seed"
},
"73A4": {
"unit": "game/mapGenerator6F00",
"line": "one seed done"
},
"73A6": {
"unit": "game/mapGenerator6F00",
"line": "six seeds per cluster"
},
"73A8": {
"unit": "game/mapGenerator6F00",
"line": "one cluster done"
},
"73AA": {
"unit": "game/mapGenerator6F00",
"line": "next cluster"
},
"73AC": {
"unit": "game/mapGenerator6F00",
"line": "all forest placed"
},
"73AD": {
"unit": "game/mapGenerator6F00",
"routine": [
"paintForestClusterSeeds - paints eight small forest blobs covering the 4x2 cell block from",
"column zp_93-2 to zp_93+1 and rows zp_92 to zp_92+1, walking it in the order (c,r), (c+1,r),",
"(c+1,r+1), (c,r+1), (c-2,r), (c-1,r), (c-1,r+1) and finally (c-2,r+1) by fall-through. Because",
"the block is four columns wide it always covers two whole 2x2 forest blocks.",
"In: zp_93 = seed column, zp_92 = seed row, $0301/$0304 from placeForestClusters",
"Out: forest painted; on exit zp_93 = c-2 and zp_92 = r+1 (they are not restored - the caller",
" re-rolls both for the next seed)",
"Called from: placeForestClusters ($73A1)"
],
"line": "seed (c,r)"
},
"73B0": {
"unit": "game/mapGenerator6F00",
"line": "-> column c+1"
},
"73B2": {
"unit": "game/mapGenerator6F00",
"line": "(c+1,r)"
},
"73B5": {
"unit": "game/mapGenerator6F00",
"line": "-> row r+1"
},
"73B7": {
"unit": "game/mapGenerator6F00",
"line": "(c+1,r+1)"
},
"73BA": {
"unit": "game/mapGenerator6F00",
"line": "-> column c"
},
"73BC": {
"unit": "game/mapGenerator6F00",
"line": "(c,r+1)"
},
"73BF": {
"unit": "game/mapGenerator6F00",
"line": "-> column c-1"
},
"73C1": {
"unit": "game/mapGenerator6F00",
"line": "-> column c-2"
},
"73C3": {
"unit": "game/mapGenerator6F00",
"line": "-> row r"
},
"73C5": {
"unit": "game/mapGenerator6F00",
"line": "(c-2,r)"
},
"73C8": {
"unit": "game/mapGenerator6F00",
"line": "-> column c-1"
},
"73CA": {
"unit": "game/mapGenerator6F00",
"line": "(c-1,r)"
},
"73CD": {
"unit": "game/mapGenerator6F00",
"line": "-> row r+1"
},
"73CF": {
"unit": "game/mapGenerator6F00",
"line": "(c-1,r+1)"
},
"73D2": {
"unit": "game/mapGenerator6F00",
"line": "-> column c-2, then fall through for the eighth seed (c-2,r+1)"
},
"73D4": {
"unit": "game/mapGenerator6F00",
"routine": [
"paintForestBlobAt - grows one 4-cell forest blob at (zp_93,zp_92) if both coordinates are inside",
"the 40x40 map; out-of-range coordinates (including the $FF a DEC produced at column 0) are",
"silently ignored. Spread is 220/256 in both axes, so the blobs are compact and round.",
"In: zp_93 column, zp_92 row, $0301 tile, $0304 flags",
"Out: up to 4 forest cells; zp_A7/zp_A8 = the blob origin",
"Called from: paintForestClusterSeeds (all eight seeds, $73AD-$73D2 and by fall-through)"
],
"line": "seed column"
},
"73D6": {
"unit": "game/mapGenerator6F00",
"line": "columns 0-39 only"
},
"73D8": {
"unit": "game/mapGenerator6F00",
"line": "off the map (or wrapped to $FF by a DEC) - ignore this seed"
},
"73DA": {
"unit": "game/mapGenerator6F00",
"line": "zp_A7 = blob origin column"
},
"73DC": {
"unit": "game/mapGenerator6F00",
"line": "seed row"
},
"73DE": {
"unit": "game/mapGenerator6F00",
"line": "rows 0-39 only"
},
"73E0": {
"unit": "game/mapGenerator6F00",
"line": "off the map - ignore"
},
"73E2": {
"unit": "game/mapGenerator6F00",
"line": "zp_A8 = blob origin row"
},
"73E4": {
"unit": "game/mapGenerator6F00",
"line": "Y = vertical spread 220/256"
},
"73E6": {
"unit": "game/mapGenerator6F00",
"line": "X = horizontal spread 220/256 - forest grows evenly in all directions"
},
"73E8": {
"unit": "game/mapGenerator6F00",
"line": "A = 4 cells per seed"
},
"73EA": {
"unit": "game/mapGenerator6F00",
"line": "grow the blob"
},
"73ED": {
"unit": "game/mapGenerator6F00",
"line": "seed outside the map, or blob finished"
},
"73EE": {
"unit": "game/mapGenerator6F00",
"routine": [
"applyContourTiles - draws the contour ring around a hill layer. A is the layer's interior tile",
"($65 summit or $61 lower hill); zp_8E becomes its terrain class (6 or 4) and zp_91 the class of",
"its ring (5 or 3). All 1600 cells are scanned in order: a cell that already holds a ring tile of",
"this layer is erased to blank and re-evaluated, cells of the interior class or higher and river",
"cells (class 1) are left alone, and everything else is handed to applyContourRuleAtCell. When",
"that returns C = 1 it has changed a cell that earlier cells depended on, so the scan is backed up",
"two columns and two rows and continues from there until the whole map is stable.",
"In: A = interior tile, $0324 = contour offset (0 for $41-$54, $20 for $21-$34), contour rule",
" table at $0200, terrainClassTable $077E, map",
"Out: contour tiles in the map; $0312 = interior tile, zp_8E, zp_91, zp_2D/zp_2E scan position,",
" zp_8C/zp_8D random-bit state, zp_21",
"Called from: runMapGeneratorPasses ($6F54 with $65, $6F69 with $61)"
],
"line": "$0312 = the interior tile this pass belongs to"
},
"73F1": {
"unit": "game/mapGenerator6F00",
"line": "use the tile code as the class-table index"
},
"73F2": {
"unit": "game/mapGenerator6F00",
"line": "its terrain class: 6 for the summit, 4 for the lower hill"
},
"73F5": {
"unit": "game/mapGenerator6F00",
"line": "zp_8E = the 'high ground' class for the neighbour test"
},
"73F7": {
"unit": "game/mapGenerator6F00",
"line": "zp_91 starts as the interior class..."
},
"73F9": {
"unit": "game/mapGenerator6F00",
"line": "zp_91 = class of this layer's contour ring (5 or 3)"
},
"73FB": {
"unit": "game/mapGenerator6F00",
"line": "clear A for the three stores below"
},
"73FD": {
"unit": "game/mapGenerator6F00",
"line": "zp_8C = 0: force a fresh random byte on the first irregular rule"
},
"73FF": {
"unit": "game/mapGenerator6F00",
"line": "column 0"
},
"7401": {
"unit": "game/mapGenerator6F00",
"line": "start the scan at cell (0,0)"
},
"7403": {
"unit": "game/mapGenerator6F00",
"block": [
"Scan every cell of the map. zp_2E/zp_2D are the cell; zp_48/49 addresses the top-left corner of",
"its 3x3 block, so the cell itself is at offset $29."
],
"line": "X = scan column"
},
"7405": {
"unit": "game/mapGenerator6F00",
"line": "Y = scan row"
},
"7407": {
"unit": "game/mapGenerator6F00",
"line": "step back one column to the block corner"
},
"7408": {
"unit": "game/mapGenerator6F00",
"line": "address the block corner (column-1,row-1)"
},
"7409": {
"unit": "game/mapGenerator6F00",
"line": "zp_A5 = column-1"
},
"740B": {
"unit": "game/mapGenerator6F00",
"line": "zp_A6 = row-1"
},
"740D": {
"unit": "game/mapGenerator6F00",
"line": "zp_48/49 -> the corner, clipped correctly for negative coordinates"
},
"7410": {
"unit": "game/mapGenerator6F00",
"line": "offset $29 = the cell itself"
},
"7412": {
"unit": "game/mapGenerator6F00",
"line": "the cell's terrain code"
},
"7414": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 = a unit or a river keep-clear marker - never touched"
},
"7416": {
"unit": "game/mapGenerator6F00",
"line": "use it as the class-table index"
},
"7417": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of the cell"
},
"741A": {
"unit": "game/mapGenerator6F00",
"line": "is it already a ring tile of this layer?"
},
"741C": {
"unit": "game/mapGenerator6F00",
"line": "yes - erase it so the rule table can redraw it"
},
"741E": {
"unit": "game/mapGenerator6F00",
"line": "class above the ring = hill interior or higher - leave it"
},
"7420": {
"unit": "game/mapGenerator6F00",
"line": "class 1 = river"
},
"7422": {
"unit": "game/mapGenerator6F00",
"line": "not the river - run the rule"
},
"7424": {
"unit": "game/mapGenerator6F00",
"line": "river cells are never overwritten by a contour"
},
"7426": {
"unit": "game/mapGenerator6F00",
"line": "$40 = blank"
},
"7428": {
"unit": "game/mapGenerator6F00",
"line": "erase the stale ring tile"
},
"742A": {
"unit": "game/mapGenerator6F00",
"line": "let the neighbourhood rule table decide what this cell becomes"
},
"742D": {
"unit": "game/mapGenerator6F00",
"line": "C = 1: a neighbour changed, restart from the backed-up position"
},
"742F": {
"unit": "game/mapGenerator6F00",
"line": "next column"
},
"7431": {
"unit": "game/mapGenerator6F00",
"line": "the column just finished"
},
"7433": {
"unit": "game/mapGenerator6F00",
"line": "columns 0-39"
},
"7435": {
"unit": "game/mapGenerator6F00",
"line": "not at the right edge yet"
},
"7437": {
"unit": "game/mapGenerator6F00",
"line": "next row"
},
"7439": {
"unit": "game/mapGenerator6F00",
"line": "column 0 of the next row"
},
"743B": {
"unit": "game/mapGenerator6F00",
"line": "back to column 0"
},
"743D": {
"unit": "game/mapGenerator6F00",
"line": "the row just finished"
},
"743F": {
"unit": "game/mapGenerator6F00",
"line": "rows 0-39"
},
"7441": {
"unit": "game/mapGenerator6F00",
"line": "not at the bottom yet"
},
"7443": {
"unit": "game/mapGenerator6F00",
"line": "the whole map is stable"
},
"7444": {
"unit": "game/mapGenerator6F00",
"routine": [
"applyContourRuleAtCell - decides what one cell becomes, from which of its eight neighbours are",
"high ground. It builds an 8-bit mask (bit 0 NW, 1 N, 2 NE, 3 W, 4 E, 5 SW, 6 S, 7 SE) of the",
"neighbours whose terrain class is >= zp_8E, clears the bits that would point off the map, and uses",
"the mask as the index into the 256-byte rule table at $0200 (track 18 sector 15):",
" $00 leave the cell alone, C = 0",
" $01-$7F paint that tile minus the contour offset $0324, with a random variant, C = 0",
" $80-$8F irregular: 50% chance (bit taken from a random byte, 7 bits per byte) to erase the",
" neighbour named by the low 3 bits when it is of the interior class; otherwise fill",
" the cell with the interior tile. Either way C = 1",
" $90-$FE same 50% erase attempt, but if it does not fire the cell is left alone, C = 0",
" $FF fill the cell with the interior tile $0312, C = 1",
"C = 1 also backs the scan position zp_2E/zp_2D up by two columns and two rows (floored at 0) so",
"applyContourTiles re-examines the cells around the change.",
"In: zp_2E/zp_2D = the cell, zp_48/49 -> its 3x3 block corner, zp_8E interior class, $0312",
" interior tile, $0324 contour offset, rule table $0200, terrainClassTable $077E",
"Out: C flag, map cells changed, zp_2D/zp_2E, zp_21 mask, zp_18 rule value, zp_8C/zp_8D random bits",
"Called from: applyContourTiles ($742A)"
],
"block": [
"Build the high-ground neighbour mask, bit 7 (SE) down to bit 0 (NW)."
],
"line": "clear the neighbour mask"
},
"7446": {
"unit": "game/mapGenerator6F00",
"line": "zp_21 = neighbour mask"
},
"7448": {
"unit": "game/mapGenerator6F00",
"line": "walk the eight neighbours backwards: 7 = SE .. 0 = NW"
},
"744A": {
"unit": "game/mapGenerator6F00",
"line": "offset of neighbour X from the block corner"
},
"744D": {
"unit": "game/mapGenerator6F00",
"line": "that neighbour's terrain code"
},
"744F": {
"unit": "game/mapGenerator6F00",
"line": "bit 7 = unit or keep-clear marker - not high ground"
},
"7451": {
"unit": "game/mapGenerator6F00",
"line": "use it as the class-table index"
},
"7452": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of the neighbour"
},
"7455": {
"unit": "game/mapGenerator6F00",
"line": "high ground = class >= the interior class of this pass"
},
"7457": {
"unit": "game/mapGenerator6F00",
"line": "lower - leave the bit clear"
},
"7459": {
"unit": "game/mapGenerator6F00",
"line": "mask built so far"
},
"745B": {
"unit": "game/mapGenerator6F00",
"line": "bit X: NW,N,NE,W,E,SW,S,SE = bits 0-7"
},
"745E": {
"unit": "game/mapGenerator6F00",
"line": "zp_21 = mask so far"
},
"7460": {
"unit": "game/mapGenerator6F00",
"line": "next neighbour"
},
"7461": {
"unit": "game/mapGenerator6F00",
"line": "all eight neighbours"
},
"7463": {
"unit": "game/mapGenerator6F00",
"block": [
"Clear the mask bits that point off the edge of the 40x40 map."
],
"line": "the cell's own column"
},
"7465": {
"unit": "game/mapGenerator6F00",
"line": "its row"
},
"7467": {
"unit": "game/mapGenerator6F00",
"line": "the raw mask"
},
"7469": {
"unit": "game/mapGenerator6F00",
"line": "on the left edge?"
},
"746B": {
"unit": "game/mapGenerator6F00",
"line": "not on the left edge"
},
"746D": {
"unit": "game/mapGenerator6F00",
"line": "$D6 clears bits 0/3/5 = NW, W, SW"
},
"746F": {
"unit": "game/mapGenerator6F00",
"line": "on the right edge (column 39)?"
},
"7471": {
"unit": "game/mapGenerator6F00",
"line": "not on the right edge"
},
"7473": {
"unit": "game/mapGenerator6F00",
"line": "$6B clears bits 2/4/7 = NE, E, SE"
},
"7475": {
"unit": "game/mapGenerator6F00",
"line": "on the top edge?"
},
"7477": {
"unit": "game/mapGenerator6F00",
"line": "not on the top edge"
},
"7479": {
"unit": "game/mapGenerator6F00",
"line": "$F8 clears bits 0/1/2 = NW, N, NE"
},
"747B": {
"unit": "game/mapGenerator6F00",
"line": "on the bottom edge (row 39)?"
},
"747D": {
"unit": "game/mapGenerator6F00",
"line": "not on the bottom edge"
},
"747F": {
"unit": "game/mapGenerator6F00",
"line": "$1F clears bits 5/6/7 = SW, S, SE"
},
"7481": {
"unit": "game/mapGenerator6F00",
"line": "zp_21 = the clipped mask"
},
"7483": {
"unit": "game/mapGenerator6F00",
"line": "use it as the rule-table index"
},
"7484": {
"unit": "game/mapGenerator6F00",
"block": [
"Look the neighbourhood up in the 256-byte contour rule table loaded to $0200 from track 18",
"sector 15."
],
"line": "rule byte for this exact neighbourhood"
},
"7487": {
"unit": "game/mapGenerator6F00",
"line": "$00 = this neighbourhood needs no contour - leave the cell (C = 0)"
},
"7489": {
"unit": "game/mapGenerator6F00",
"line": "$01-$7F = a contour tile code - paint it"
},
"748B": {
"unit": "game/mapGenerator6F00",
"line": "$FF = the cell is surrounded, fill it with the hill interior"
},
"748D": {
"unit": "game/mapGenerator6F00",
"line": "fill the cell with the interior tile and force a rescan"
},
"748F": {
"unit": "game/mapGenerator6F00",
"line": "$80-$FE: irregular rule; zp_18 keeps the value"
},
"7491": {
"unit": "game/mapGenerator6F00",
"line": "any random bits left in zp_8D?"
},
"7493": {
"unit": "game/mapGenerator6F00",
"line": "yes"
},
"7495": {
"unit": "game/mapGenerator6F00",
"line": "seven bits per random byte: counter 6 down through 0"
},
"7497": {
"unit": "game/mapGenerator6F00",
"line": "seven bits are taken from each random byte"
},
"7499": {
"unit": "game/mapGenerator6F00",
"line": "fetch a fresh batch of random bits"
},
"749C": {
"unit": "game/mapGenerator6F00",
"line": "zp_8D = fresh random bits"
},
"749E": {
"unit": "game/mapGenerator6F00",
"line": "shift out the next bit"
},
"74A0": {
"unit": "game/mapGenerator6F00",
"line": "bit clear - do not erase a neighbour this time"
},
"74A2": {
"unit": "game/mapGenerator6F00",
"line": "the rule value"
},
"74A4": {
"unit": "game/mapGenerator6F00",
"line": "low 3 bits of the rule value = which neighbour it wants removed"
},
"74A6": {
"unit": "game/mapGenerator6F00",
"line": "neighbour index 0-7"
},
"74A7": {
"unit": "game/mapGenerator6F00",
"line": "its offset from the block corner"
},
"74AA": {
"unit": "game/mapGenerator6F00",
"line": "that neighbour's terrain code"
},
"74AC": {
"unit": "game/mapGenerator6F00",
"line": "unit or marker - leave it alone"
},
"74AE": {
"unit": "game/mapGenerator6F00",
"line": "use the terrain code as the class-table index"
},
"74AF": {
"unit": "game/mapGenerator6F00",
"line": "terrain class of that neighbour"
},
"74B2": {
"unit": "game/mapGenerator6F00",
"line": "only a cell of the interior class may be nibbled away"
},
"74B4": {
"unit": "game/mapGenerator6F00",
"line": "not a cell of the hill interior - leave it alone"
},
"74B6": {
"unit": "game/mapGenerator6F00",
"line": "$40 = blank"
},
"74B8": {
"unit": "game/mapGenerator6F00",
"line": "erase the neighbour - this is what makes hill edges irregular"
},
"74BA": {
"unit": "game/mapGenerator6F00",
"line": "C = 1 and back the scan up"
},
"74BD": {
"unit": "game/mapGenerator6F00",
"line": "the rule value again"
},
"74BF": {
"unit": "game/mapGenerator6F00",
"line": "rule values $90-$FE..."
},
"74C1": {
"unit": "game/mapGenerator6F00",
"line": "...leave the cell untouched when the erase did not fire (C = 0)"
},
"74C3": {
"unit": "game/mapGenerator6F00",
"line": "values $80-$8F (and $FF): fill the cell with the hill interior tile"
},
"74C6": {
"unit": "game/mapGenerator6F00",
"line": "write it into the centre cell"
},
"74C9": {
"unit": "game/mapGenerator6F00",
"block": [
"A cell changed under the scan: back up two columns and two rows so applyContourTiles",
"re-evaluates the neighbourhood, and return C = 1."
],
"line": "current scan column"
},
"74CB": {
"unit": "game/mapGenerator6F00",
"line": "prepare the subtract"
},
"74CC": {
"unit": "game/mapGenerator6F00",
"line": "two columns back"
},
"74CE": {
"unit": "game/mapGenerator6F00",
"line": "still positive"
},
"74D0": {
"unit": "game/mapGenerator6F00",
"line": "but never before column 0"
},
"74D2": {
"unit": "game/mapGenerator6F00",
"line": "zp_2E = backed-up scan column"
},
"74D4": {
"unit": "game/mapGenerator6F00",
"line": "current scan row"
},
"74D6": {
"unit": "game/mapGenerator6F00",
"line": "prepare the subtract"
},
"74D7": {
"unit": "game/mapGenerator6F00",
"line": "two rows back"
},
"74D9": {
"unit": "game/mapGenerator6F00",
"line": "still positive"
},
"74DB": {
"unit": "game/mapGenerator6F00",
"line": "but never before row 0"
},
"74DD": {
"unit": "game/mapGenerator6F00",
"line": "zp_2D = backed-up scan row"
},
"74DF": {
"unit": "game/mapGenerator6F00",
"line": "C = 1: applyContourTiles restarts its scan here"
},
"74E0": {
"unit": "game/mapGenerator6F00",
"line": "C = 1 set at $74DF"
},
"74E1": {
"unit": "game/mapGenerator6F00",
"line": "prepare the subtract"
},
"74E2": {
"unit": "game/mapGenerator6F00",
"line": "tile = rule value - $0324: offset 0 keeps $41-$54, offset $20 gives $21-$34"
},
"74E5": {
"unit": "game/mapGenerator6F00",
"line": "offset $29 = the cell itself"
},
"74E7": {
"unit": "game/mapGenerator6F00",
"line": "pick a random variant of the tile (Y is preserved)"
},
"74EA": {
"unit": "game/mapGenerator6F00",
"line": "paint the contour tile"
},
"74EC": {
"unit": "game/mapGenerator6F00",
"line": "C = 0: the scan carries on normally"
},
"74ED": {
"unit": "game/mapGenerator6F00",
"line": "C = 0 set at $74EC"
}
},
"dataTypes": {
"6F00": [
"byte",
4
],
"71AB": [
"byte",
5
]
},
"zpComments": {
"1D": "general scratch: bounds mode flag of computeGroupBounds (bit 7 = use destinations), division remainder (hi); the map generator holds the candidate row of the hill site being placed",
"1E": "general scratch: running terrain height in the line-of-sight walk, decimal digit index, group destination centre column; the map generator counts the column attempts left for a hill site",
"1F": "general scratch: line-of-sight rise flag, divide bit counter, group destination centre row; the map generator remembers which candidate row a hill site started on",
"28": "map row of point B (the centre/reference point) for distanceSquared and cellDistance; the map generator reuses it as the highest valid index of the hill row-candidate list $0325",
"29": "index of the last entry written to the area-scan result lists at $0400/$0432/$0464 ($FF = empty); the map generator reuses it as the current index into the hill row-candidate list $0325",
"8E": "line stepper: length of the line along its major axis, max(|dRow|,|dCol|); the contour passes reuse it as the terrain class that counts as high ground (6 summit, 4 lower hill)",
"91": "line stepper: steps still to walk (0 = finished); returned in A by initLineStepper/stepLine; the contour passes reuse it as the terrain class of the ring being redrawn (5 or 3)",
"B3": "high byte of glyphPtr; growTerrainBlob reuses it as the count of cells painted so far",
"A5": "map column of the left edge of the 7x5 battlefield view (may be negative); the cursor cell is viewOriginCol+3; the map generator reuses it as the column of the cell being painted or scanned",
"A6": "map row of the top edge of the battlefield view; the cursor cell is viewOriginRow+2; the map generator reuses it as the row of the cell being painted or scanned"
}
}