{ "_comment": "generated by tools/mergeSurvey.py from survey/*.json - do not edit by hand", "notes": { "EE00": { "routine": [ "flyTrainerDroneStep - One flight step of the solo-trainer AI's drone. The communications module build 1 (T35) JSRs here from $E0A5 once per command exchange, but only while this track-29 s4-5 page is the resident $EE00 image (droneOverlayState $8977 bit 7 set). It returns at once when droneFlags $92F9 bit 7 says the drone has already arrived or been shot down; otherwise it decrements the drone's fuel counter $8973 and, when that goes negative, fabricates the 1-byte command $8F (drone released) in the received-packet buffer and returns. Any other case falls through into pickDroneAimPointAndDecide.", "In: $92F9 droneFlags, $8973 aiDroneFuel, $8974/$8975 drone cell, $8976 target unit index, $8978 detonate threshold, map/unit arrays $F640/$F6A4/$F960", "Out: fabricated opponent packet in rxPacketBuffer $E020.. with rxPacketLength $E01E = 1 ($8F), 3 ($8E col row) or 4 ($8D heading col row); $8973 decremented; on the move path $896F, $8974, $8975 updated; zp_18,zp_19,zp_1C,zp_1D,zp_22,zp_24,zp_27,zp_28,zp_92-zp_95 clobbered" ], "unit": "game/droneAiEE00" }, "EE15": { "routine": [ "pickDroneAimPointAndDecide - Fall-through block (branch target of $EE08 only): decides between blowing the drone up here and flying one more cell. It measures the distance from the drone to its target unit ($8976); inside 6 cells and with both drone coordinates on the map it scores the 2x2 block under the drone with scoreTargetBlock ($E9A6) and detonates when the score reaches aiDroneDetonateThreshold $8978, or only 3/4 of it when the target unit is stunned ($F960 low nibble non-zero). Otherwise it scores the four 2x2 blocks that touch the target's cell, leaves the best corner in zp_95/zp_94, sets the line-stepper start from the drone position (clamping a negative coordinate to 0 and shifting the end point by the same amount) and calls getStepDirection ($E80E); a stepper that finds no direction (drone already on the aim cell) also detonates.", "In: $8976, $F640/$F6A4 unit col/row, $8974/$8975 drone cell, $8978, $F960, zp_1C = 0 on entry", "Out: zp_1C best block score, zp_1D best player unit, zp_94/zp_95 aim cell, zp_92/zp_93 line start, Y = heading 0-7 from getStepDirection; falls into emitDroneDetonateCommand or maybeJinkDroneHeading" ], "unit": "game/droneAiEE00" }, "EE2D": { "routine": [ "midCheckDroneOnMapEE2D - NOT an entry point in this image: $EE2D is the middle of pickDroneAimPointAndDecide (the 'ldx $8974 / bmi' on-map test before scoreTargetBlock). The sub_ prefix is imported from the other code images that share these addresses (comm build 2 has a real routine at $EE2D).", "In: -", "Out: -" ], "unit": "game/droneAiEE00" }, "EE55": { "routine": [ "midStoreDetonateThresholdEE55 - NOT an entry point in this image: $EE55 is the 'sta zp_18' that stores the 3/4 detonate threshold for a stunned target inside pickDroneAimPointAndDecide. The label comes from the other images of this page.", "In: -", "Out: -" ], "unit": "game/droneAiEE00" }, "EE85": { "routine": [ "midScanDiagonalBlockEE85 - NOT an entry point in this image: $EE85 is the 'dey' inside the four-block scan around the target cell (scoring the block at col-1,row-1). The label is an artifact of the T35/T34 images of this page.", "In: -", "Out: -" ], "unit": "game/droneAiEE00" }, "EEED": { "routine": [ "midCheckFuelForJinkEEED - NOT an entry point in this image: $EEED is the 'lda $8973 / cmp #$0C' fuel test inside maybeJinkDroneHeading. The label is an artifact of the other images of this page.", "In: -", "Out: -" ], "unit": "game/droneAiEE00" }, "EEB6": { "routine": [ "emitDroneDetonateCommand - Detonation path (branch target of $EE3F and $EE5B): writes command $8E plus the drone's current cell, mirrored with mirrorBlockCornerForOpponent ($EA38), into the fake received packet and sets its length to 3. The engine's cmdDroneDetonate ($5336) mirrors the coordinates back and plays the blast.", "In: $8974/$8975 drone cell", "Out: $E020=$8E, $E021/$E022 = mirrored col/row, $E01E=3; X/Y clobbered; returns" ], "unit": "game/droneAiEE00" }, "EED0": { "routine": [ "maybeJinkDroneHeading - Flight path (branch target of $EEB4): stores the heading returned by getStepDirection in zp_19 and then, only when the human player still has missiles ($92B0), the drone's cell falls inside the radar window drawn around the human's comcen (mapCellToRadarGrid $7A13 with $9236 unchanged), the radar/drone screen is the one on show ($90FB = 1), the drone still has at least 12 fuel and is at least 3 cells away from its aim point, replaces the heading 2 times in 3 (nextGameRandom >= $56) with a random 0-7 value. Inferred purpose: an evasive weave while the player can watch the drone and shoot it down with a missile strike (confidence medium).", "In: Y = heading from $E80E, $92B0 missilesLeft, $8974/$8975, $9236 comcenUnit, $90FB currentScreen, $8973, zp_94/zp_95 aim cell", "Out: zp_19 = desired heading 0-7; zp_22/zp_24/zp_27/zp_28 clobbered; falls into steerDroneAndEmitMove", "(confidence: medium)" ], "unit": "game/droneAiEE00" }, "EF0F": { "routine": [ "steerDroneAndEmitMove - Turns the drone one step toward the desired heading and reports the move. The code is a copy of overlay B's steerDrone ($731E) with the AI's variables and without the turn sound: $896F is rotated by +1 or -1 (the short way round, then AND #$07) toward zp_19, converted through headingToDirectionTable ($7316), directionDeltaTable ($20F0) and diagonalDirectionTable ($1FB2) into dx/dy and added to $8974/$8975. It then emits command $8D with (heading+4)&7 - the heading as the mirrored map sees it - and the new cell mirrored by $EA38, length 4. Note that neither coordinate is clamped, so the drone can walk off the map.", "In: zp_19 desired heading, $896F current heading, $8974/$8975 drone cell", "Out: $896F, $8974, $8975 updated; $E020=$8D, $E021=(heading+4)&7, $E022/$E023 mirrored col/row, $E01E=4; returns" ], "unit": "game/droneAiEE00" }, "EF9E": { "routine": [ "droneDistanceToCell - Helper called at $EE26 and $EEFC: copies the drone's cell $8974/$8975 into the distance routine's second point zp_27/zp_28 and tail-jumps to cellDistance ($E82A), which returns the integer distance between (zp_22,zp_24) and the drone in A and X. Y is preserved, which is what lets the caller keep the target unit index in Y across the call.", "In: zp_22/zp_24 = cell to measure against, $8974/$8975 drone cell", "Out: A = X = distance 0-16, zp_27/zp_28 = drone cell; Y preserved" ], "unit": "game/droneAiEE00" }, "EFAB": { "unit": "game/droneAiEE00", "block": [ "staleCommTailBytes: unknown, 37 bytes. $EFAB-$EFCF: 37 bytes that are byte-for-byte identical in all four images of this address range (comm build 1 T35, comm build 2 T34, the track-29 s0-3 $EC00 sub-overlay and this one). In build 1 they are the tail of the AI's drone target picker (inc zp_1F / cmp #$0F / ... / sta $8979 / rts) and in build 2 they are the middle of the message 'INSERT DATA DISK AND PRESS SPACE.' ($EFAF, with the 4-character disk name patched into $EFB6). Nothing in this image reaches them - they are carried along only so that the shared strings below land at their fixed addresses." ] }, "EFD0": { "unit": "game/droneAiEE00", "block": [ "msgDataDiskName: text, 4 bytes. 'DATA' - the 4-character disk name that overlay A's promptInsertDataDisk ($81B2) patches into the INSERT-DISK message. The disassembler merges $EFD0-$EFE1 into one label msgDatagamecustomOff4; it is really three strings." ] }, "EFD4": { "unit": "game/droneAiEE00", "block": [ "msgGameDiskName: text, 4 bytes. 'GAME' - the disk name used by overlay A's promptInsertGameDisk ($81A5)." ] }, "EFD8": { "unit": "game/droneAiEE00", "block": [ "msgCustomOff: text, 10 bytes. 'CUSTOM OF','F'|$80 - installed as message slot $1E by overlay A ($EFD8), which also points its ON/OFF patch at $EFDF ('OFF')." ] }, "EFE2": { "unit": "game/droneAiEE00", "block": [ "msgDestroyOff: text, 11 bytes. 'DESTROY OF','F'|$80 - message slot $1E for the DESTROY toggle; overlay A patches ON/OFF at $EFEA." ] }, "EFED": { "unit": "game/droneAiEE00", "block": [ "msgAccepted: text, 8 bytes. 'ACCEPTE','D'|$80 - printed centred on row 15 by overlay A when the fire button confirms a value." ] }, "EFF5": { "unit": "game/droneAiEE00", "block": [ "trailingPadEFF5: unknown, 11 bytes. $C0,$DF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$FF - unreferenced trailing bytes, the same in every image of this page except the last byte ($FF here and in build 1, $00 in build 2). Probably padding left by the mastering system." ] } } }