{ "_comment": "generated by tools/mergeSurvey.py from survey/*.json - do not edit by hand", "notes": { "8800": { "unit": "game/messages8800", "block": [ "msgGetOpponentOnPhoneAnd: text, 28 bytes. Bit-7-terminated message text \"GET OPPONENT ON PHONE AND...\". Message slot $20 while a modem game is being set up: main $0B1D patches messagePtrLoTable/HiTable entry $20 to point here (A=$00, Y=$88) right before waitForAnswerOriginateKey." ] }, "881C": { "unit": "game/messages8800", "block": [ "msgPressAOrOAndSetModem: text, 27 bytes. Bit-7-terminated message text \"PRESS A OR O AND SET MODEM.\". Message slot $21, patched next to it at $0B26 (A=$1C, Y=$88). Tells the player to press A(nswer) or O(riginate)." ] }, "8837": { "unit": "game/messages8800", "block": [ "msgPressSpaceWhenReady: text, 23 bytes. Bit-7-terminated message text \"PRESS SPACE WHEN READY.\". Message slot $21 set by showModemSetupPrompt ($0C8C, called from overlay A $79E3), which puts the caller's string in slot $20 and this one in slot $21." ] }, "884E": { "unit": "game/messages8800", "block": [ "msgTrainerName: text, 10 bytes. Bit-7-terminated message text \"TRAINER \". Ten characters, read by exchangePlayerNamesAndSettings ($ED4A in the modem-driver build): in solo-trainer mode ($0BA5 bit 7) the whole name handshake is skipped and this string is copied into opponentName $FFE8 instead." ] }, "8858": { "unit": "game/messages8800", "block": [ "msgOpponentReady: text, 15 bytes. Bit-7-terminated message text \"OPPONENT READY.\". Message id $04 (messagePtrLoTable[$04]=$58, HiTable[$04]=$88)." ] }, "8867": { "unit": "game/messages8800", "block": [ "msgWaitingForOpponent: text, 23 bytes. Bit-7-terminated message text \"WAITING FOR OPPONENT...\". Message id $0B." ] }, "887E": { "unit": "game/messages8800", "block": [ "msgWaitingForConnection: text, 25 bytes. Bit-7-terminated message text \"WAITING FOR CONNECTION...\". Message id $10." ] }, "8897": { "unit": "game/messages8800", "block": [ "msgPickUpPhoneThenPressSpace: text, 31 bytes. Bit-7-terminated message text \"PICK UP PHONE THEN PRESS SPACE.\". Message id $17." ] }, "88B6": { "unit": "game/messages8800", "block": [ "msgPressSpaceWaitHangupPhone: text, 32 bytes. Bit-7-terminated message text \"PRESS SPACE, WAIT, HANGUP PHONE.\". Message id $18." ] }, "88D6": { "unit": "game/messages8800", "block": [ "msgOpponentPickingGameMap: text, 26 bytes. Bit-7-terminated message text \"OPPONENT PICKING GAME/MAP.\". Message id $1A - shown to player 1 while it waits for player 0's map seed." ] }, "88F0": { "unit": "game/messages8800", "block": [ "msgOpponentReadyForNewGame: text, 28 bytes. Bit-7-terminated message text \"OPPONENT READY FOR NEW GAME.\". Message id $1F." ] }, "895E": { "unit": "game/messages8800", "block": [ "msgOpponentUsingNonStandardGame: text, 33 bytes. Bit-7-terminated message text \"OPPONENT USING NON-STANDARD GAME.\". Shown when the program-checksum byte exchanged during the identity handshake does not match: overlay A stores the expected value $DB at $79CC, compares it after exchangePlayerNamesAndSettings and, on a mismatch, does LDA #$5E / LDY #$89 / JSR showModemSetupPrompt ($79DF-$79E3), which puts this string in message slot $20 and \"PRESS SPACE WHEN READY.\" ($8837) in slot $21. Because the address is built from two immediates the disassembler produced no reference, which is why XREF shows only trainer writes here." ] }, "890C": { "unit": "game/messages8800", "block": [ "mapNameAlphabet: byteTable, 32 bytes. The 32-character alphabet ' ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/=' used to convert between a five-character map name and the 24-bit map seed. The map-name editor in overlay A searches it backwards from index $1F at $779B to validate a typed character, and packs the name at $7804 by shifting zp_5A/5B/5C left five times per character and ORing in the index, so name = seed in base 32 (5 chars x 5 bits). $785D uses the same table to print a seed back as a name. This is also what makes the copy-protection work: the 32 x 3-byte table at $0401 holds seed triples, and the player types the matching name out of the manual." ] }, "892C": { "unit": "game/messages8800", "block": [ "gameTypeDefaultsSide0: byteTable, 25 bytes. Side 0 half of the game-type parameter defaults: five rows of five bytes, read through selectSideDefaultsTable ($7CAE) and applied by applyGameTypeDefaults ($7C2E). Rows are TERRAIN PTS (-> $92AC), RECYCLER (-> $92A6), COMCEN SPEED (-> $92B4), DRONES (-> $92AE) and MISSILES (-> $92B0); columns are the game type folded to 0-4 (0 SCRIMAGE, 1 QB SNEAK, 2 THE BOMB/FACE-OFF/SLUGGERS, 3 FULL WAR, 4 DEFENDER). Values: 01 00 01 01 01 / 02 02 02 01 02 / 02 03 02 01 00 / 00 00 03 05 02 / 00 08 0C 14 14, i.e. SCRIMAGE has no drones and no missiles while FULL WAR gives 5 drones and 20 missiles." ] }, "8945": { "unit": "game/messages8800", "block": [ "gameTypeDefaultsSide1: byteTable, 25 bytes. Side 1 half of the same 5x5 table: 01 01 01 01 00 / 02 02 02 01 01 / 02 02 02 01 01 / 00 00 03 05 05 / 00 08 0C 14 08. The only asymmetric column is DEFENDER (4), where side 0 gets 2 drones and 20 missiles (the attacker) and side 1 gets 5 drones and 8 missiles (the defender). Note that the trainer AI's buildDirectionFan ($E7E3) later reads its eight compass offsets from $894A, which is the middle of this table and is never rewritten - see the insight below." ] }, "897F": { "unit": "game/messages8800", "block": [ "messageBlockTail: unknown, 129 bytes. 129 unreferenced bytes to the end of track 29 sector 10. They are a 50 percent dither: pairs of $00/$FF whose phase flips every eight bytes, plus a few stray values ($03,$F3,$BF,$0C,$DC,$B3,$3F,$C0,$CC,$01,$DF). The tail of the $9300 graphics block ($9FD1-$9FFF, track 28 sector 12) contains the same pattern, so both look like the same stale bitmap fragment from the mastering machine rather than game data. (confidence: medium)" ] } } }