3294 lines
No EOL
96 KiB
JSON
3294 lines
No EOL
96 KiB
JSON
{
|
|
"chunk": "game_mapGenerator6F00_7BB2",
|
|
"unit": "game/mapGenerator6F00",
|
|
"unitLabels": {
|
|
"game/mapGenerator6F00": {
|
|
"7BBC": "shuffleSwapLoop",
|
|
"7C03": "phaseSyncWaitLoop",
|
|
"7C54": "sideDefaultsLoop",
|
|
"7CA0": "removeQbSneakUnits",
|
|
"7CF4": "filmNameByteLoop",
|
|
"7D04": "filmSeedByteLoop",
|
|
"7D35": "filmMapIdByteLoop",
|
|
"7D72": "fillOrderListLoop",
|
|
"7D81": "placeNextUnit",
|
|
"7D9A": "removeNextUnit",
|
|
"7DC8": "waitSpaceLoop",
|
|
"7E63": "checkBamAllocatedLoop",
|
|
"7E9D": "filmDirectoryDiskError",
|
|
"7ECB": "printDirectoryEntryLoop",
|
|
"7F77": "loadFilmSectorLoop",
|
|
"7FBA": "addDirectoryPageOffsetLoop",
|
|
"7FEC": "saveMenuRedrawRow",
|
|
"801A": "saveMenuInputLoop",
|
|
"80B9": "saveMenuAccept",
|
|
"80E1": "padDirectoryNameLoop",
|
|
"80EB": "copyTypedNameLoop",
|
|
"8184": "writeFilmSectorLoop",
|
|
"81C7": "patchDiskNameLoop",
|
|
"81DD": "waitSpaceForDiskLoop",
|
|
"8202": "waitFramesLinkLoop"
|
|
}
|
|
},
|
|
"notes": {
|
|
"7BB2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"shuffleInitialUnitOrder - builds the order in which the 100 units are processed each round.",
|
|
"Re-seeds the scenario RNG from the shared 24-bit map seed, resets unitBaseOrder ($9164) and",
|
|
"unitProcessOrder ($90FD) to the identity permutation and then performs 51 random swaps of",
|
|
"unitBaseOrder. Because the RNG is seeded from the map seed both machines shuffle identically",
|
|
"without exchanging a single byte. Ends by jumping into the round-order rebuild at L_4657 (the",
|
|
"tail of finishRound), whose RTS returns to our caller.",
|
|
"In: mapSeed $0B95-$0B97; scenario RNG state zp_5A-zp_5C",
|
|
"Out: $9164 shuffled, $90FD reset to 0..99, RNG advanced, zp_18 used as the swap counter;",
|
|
" continues in L_4657 (recycle dead units, rebuild the group tables, age visibility)",
|
|
"Called from: $7B48 and $7B99, the two game-start paths of this overlay"
|
|
],
|
|
"line": "copy the 24-bit map seed $0B95-$0B97 into the scenario RNG state zp_5A-zp_5C"
|
|
},
|
|
"7BB5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start from the identity permutation 0..99 in both order lists"
|
|
},
|
|
"7BB8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$32 = 50, so the loop below runs 51 times (counter $32..$00)"
|
|
},
|
|
"7BBA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_18 = number of swaps still to do"
|
|
},
|
|
"7BBC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one swap: exchange two randomly chosen entries of unitBaseOrder ($47ED)"
|
|
},
|
|
"7BBF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "count this swap off"
|
|
},
|
|
"7BC1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "loop until the counter goes negative - 51 swaps in all"
|
|
},
|
|
"7BC3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "continue in the round-order rebuild at the end of finishRound; its RTS returns to our caller"
|
|
},
|
|
"7BC6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"patchOwnSideBranches - burns the local player's side into the engine's self-modifying",
|
|
"'is this unit mine?' tests. Each of those tests compares a unit index with $32 (50) and is",
|
|
"followed by a branch whose opcode byte is a variable: BCC ($90) means 'own units are 0-49'",
|
|
"(side 0), BCS ($B0) means 'own units are 50-99' (side 1). Seven sites get that opcode and four",
|
|
"sites, phrased the other way round ('skip if NOT mine'), get the inverted one. Finally caches",
|
|
"this side's comcen unit index.",
|
|
"In: playerSide $0B9F, perSideValueTable $0C8A ($31/$63 = unit 49/99)",
|
|
"Out: branch opcodes at $63E2 $2840 $3F9E $36D5 $379C $4783 $5BF7 and the inverted opcodes at",
|
|
" $206B $2084 $3B2C $3BD0; comcenUnit $9236",
|
|
"Called from: $798E (start of a normal game) and $7D20 (start of film playback)"
|
|
],
|
|
"line": "$90 = BCC: for side 0 'own unit' means index < 50"
|
|
},
|
|
"7BC8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "which side is the local player on?"
|
|
},
|
|
"7BCB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "side 0 keeps the BCC"
|
|
},
|
|
"7BCD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$B0 = BCS: for side 1 'own unit' means index >= 50"
|
|
},
|
|
"7BCF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "runGroupEditor $63E0 'cpy #$32': marks the picked unit with bit 7 when it is not ours"
|
|
},
|
|
"7BD2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "renderMapTile $283E 'cpy #$32': the other side's units are drawn in the enemy colour"
|
|
},
|
|
"7BD5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "initialFacingForUnit $3F9C 'cpx #$32': own units start facing up (0), enemies down (1)"
|
|
},
|
|
"7BD8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "scanVisibleEnemies $36D3 'cpy #$32': only units of the opposite side enter the spotted list"
|
|
},
|
|
"7BDB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$379C is two leftover bytes ($90 $FA) in front of collectAllUnitsInRadiusDead - a dead branch, this store changes nothing"
|
|
},
|
|
"7BDE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "moveUnitToCell $4781 'cpx #$32': the column is mirrored before scoring an end zone for the other side"
|
|
},
|
|
"7BE1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "buildOverviewQuadrant $5BF5: inverts the mini-map pattern for the other side (that test uses the map-cell form, 'cpy #$B2' = $80|50)"
|
|
},
|
|
"7BE4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$90 EOR $20 = $B0 and back - the four sites below test 'skip if NOT mine'"
|
|
},
|
|
"7BE6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "runMapMainLoop $2069 'cmp #$32': the info panel only opens for our own units"
|
|
},
|
|
"7BE9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "runMapMainLoop $2082 'cmp #$32': only our own units can be picked with the joystick"
|
|
},
|
|
"7BEC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "applyHitToUnit $3B2A 'cpy #$32': the spy/comcen hit reactions are for our units only"
|
|
},
|
|
"7BEF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "applyHitToUnit $3BCE 'cpy #$32': decides whether endGame is entered with X=0 (we lost) or X=1"
|
|
},
|
|
"7BF2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0C8A: comcen index of side Y - 49 for side 0, 99 for side 1"
|
|
},
|
|
"7BF5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "cache it in comcenUnit $9236 for the rest of the game"
|
|
},
|
|
"7BF8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "done"
|
|
},
|
|
"7BF9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"sendPhaseSyncAndWait - the 'I am ready' handshake that separates the setup phases. Queues the",
|
|
"1-byte command $9E and then keeps running frames until both ready bits of gamePhase zp_B1 are",
|
|
"clear: the $9E handler ($520C) clears the sending side's bit on both machines (bit 0 = us,",
|
|
"bit 1 = the opponent). While waiting it runs a full game frame during the battle, or only",
|
|
"services the link when gamePhase says we are in a menu/setup phase.",
|
|
"In: gamePhase zp_B1 (bits 0/1 = side not ready, bits 6/7 = not in the battle), the link",
|
|
"Out: zp_B1 low two bits cleared by the command handler, persistentMessageId $92A1 = 0",
|
|
"Called from: $79EC, $7B04 and $7B61 - the three setup-phase boundaries"
|
|
],
|
|
"line": "$9E = 'setup phase ready' (during the battle the same command means 'comcen repaired')"
|
|
},
|
|
"7BFB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "queue it for the opponent and count it as one of our own pending commands"
|
|
},
|
|
"7BFE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "pass the ready/pause bits to the message code in A"
|
|
},
|
|
"7C00": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "on a modem game with bit 0 still set this shows message $0B 'WAITING FOR OPPONENT'"
|
|
},
|
|
"7C03": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Wait loop: re-read the ready bits every frame until both sides have executed the $9E."
|
|
],
|
|
"line": "current ready/pause bits"
|
|
},
|
|
"7C05": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bits 6-7 set = menu or setup phase, the battle is not running"
|
|
},
|
|
"7C07": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "battle phase: run a whole game frame"
|
|
},
|
|
"7C09": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "setup phase: just service the link until the packet exchange is idle"
|
|
},
|
|
"7C0C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "and re-test"
|
|
},
|
|
"7C0F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "battle phase: one complete game update (input, movement, drawing, link)"
|
|
},
|
|
"7C12": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "read the ready bits again"
|
|
},
|
|
"7C14": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bit 0 = our $9E not executed yet, bit 1 = the opponent's not seen yet"
|
|
},
|
|
"7C16": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep waiting while either side is still not ready"
|
|
},
|
|
"7C18": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "A is 0 here: drop the 'WAITING FOR OPPONENT' status message"
|
|
},
|
|
"7C1B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "both sides are ready"
|
|
},
|
|
"7C1C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"waitForMapSeedCommand - waits until the map seed sent by the other machine has arrived.",
|
|
"gamePhase zp_B1 bit 7 is set by the caller and cleared by the handler of the map-seed commands",
|
|
"$8B / $A6 ($51EA), so this loop simply services the link until that command has been executed.",
|
|
"In: gamePhase zp_B1 bit 7, the link",
|
|
"Out: loops until zp_B1 bit 7 is clear; persistentMessageId $92A1 = 0",
|
|
"Called from: $79C2 (the side that waits for its opponent to choose the map)"
|
|
],
|
|
"line": "service the link until the current packet exchange goes idle"
|
|
},
|
|
"7C1F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bit 7 is only cleared by the $8B/$A6 map-seed command handler at $51EA"
|
|
},
|
|
"7C21": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep polling while the seed has not arrived"
|
|
},
|
|
"7C23": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the seed is in: clear the status message"
|
|
},
|
|
"7C25": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "persistentMessageId $92A1 = 0"
|
|
},
|
|
"7C28": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "both machines now hold the same map seed"
|
|
},
|
|
"7C29": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"setupPhaseModeTable - one byte per game-type class (the folded column 0-4 computed by",
|
|
"applyGameTypeDefaults), copied into setupPhaseMode $92C6: 0 = no setup phase at all",
|
|
"(SCRIMAGE, QB SNEAK), 1 = both sides deploy their units and terrain (THE BOMB, FACE-OFF,",
|
|
"SLUGGERS, FULL WAR), $80 = only side 0 deploys (DEFENDER)."
|
|
],
|
|
"line": "classes 0-4: 0, 0, 1, 1, $80"
|
|
},
|
|
"7C2E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"applyGameTypeDefaults - loads the per-side game parameters of the chosen game type from the two",
|
|
"5x5 default tables at $892C (side 0) and $8945 (side 1) in the $8800 overlay. The game type",
|
|
"$0BA3 bits 0-2 is first folded into a table column: 0 SCRIMAGE, 1 QB SNEAK, 2 THE BOMB /",
|
|
"FACE-OFF / SLUGGERS, 3 FULL WAR, 4 DEFENDER; the same column selects the setup-phase mode.",
|
|
"Table rows 0-1 (terrain points, recycler mode) are stored by absolute side, rows 2-4 (comcen",
|
|
"speed class, drones, missiles) by relative index (0 = us, 1 = the opponent). Afterwards the two",
|
|
"special rosters are applied: QB SNEAK takes units 0-6 out of play, THE BOMB takes out units",
|
|
"0-98, re-creates unit 49 as a COMCEN and gives each side an extra drone.",
|
|
"In: gameTypeOptions $0BA3 bits 0-2, playerSide $0B9F, tables $892C/$8945, setupPhaseModeTable",
|
|
"Out: setupPhaseMode $92C6; terrainPointsBySide $92AC and recyclerMode $92A6 per absolute side;",
|
|
" comcenSpeedClass $92B4, dronesLeft $92AE, missilesLeft $92B0 per relative index; unit slots",
|
|
" emptied in $F76C/$FAF0; zp_18, zp_48/zp_49; self-modifies $7C85+1 and $7CBF+1",
|
|
"Called from: $79E9, once, after the game type has been agreed"
|
|
],
|
|
"line": "the agreed game type and option bits"
|
|
},
|
|
"7C31": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bits 0-2 = type 0 SCRIMAGE .. 6 DEFENDER"
|
|
},
|
|
"7C33": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep the type in Y while it is folded into a table column"
|
|
},
|
|
"7C34": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "self-modifying: the raw game type becomes the operand of the LDA #$FF at $7C85"
|
|
},
|
|
"7C37": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "types 0 and 1 have a column of their own"
|
|
},
|
|
"7C39": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "SCRIMAGE and QB SNEAK: column = type"
|
|
},
|
|
"7C3B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "types 3-6 go straight to the common DEY"
|
|
},
|
|
"7C3D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "type 2 (THE BOMB) is bumped to 3 so the DEY puts it on column 2"
|
|
},
|
|
"7C3E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "types 2-6: one column less"
|
|
},
|
|
"7C3F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "columns 0-2 are final"
|
|
},
|
|
"7C41": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "THE BOMB and FACE-OFF share column 2"
|
|
},
|
|
"7C43": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "SLUGGERS, FULL WAR and DEFENDER lose one more: columns 2, 3 and 4"
|
|
},
|
|
"7C44": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "self-modifying: the column index becomes the LDY operand of readDefaultAndAdvanceRow ($7CC0)"
|
|
},
|
|
"7C47": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "setup-phase mode for this class of game"
|
|
},
|
|
"7C4A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92C6: 0 = no setup phase, 1 = both sides deploy, $80 = only side 0 deploys"
|
|
},
|
|
"7C4D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "first pass: X = the local player's absolute side"
|
|
},
|
|
"7C50": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "relative index 0 = us"
|
|
},
|
|
"7C52": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_18 = 0 (us) then 1 (the opponent)"
|
|
},
|
|
"7C54": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Two passes over the 5-row default table, ours first. Rows 0-1 are stored under the absolute",
|
|
"side number (they describe a side of the battlefield), rows 2-4 under the relative index",
|
|
"(they describe a player: 0 = this machine, 1 = the other one)."
|
|
],
|
|
"line": "point zp_48/zp_49 at the 5x5 default table of the side in X"
|
|
},
|
|
"7C57": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "row 0 of the selected column = terrain points"
|
|
},
|
|
"7C5A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92AC+side: terrain points this side may place in the setup phase"
|
|
},
|
|
"7C5D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "row 1 = recycler mode"
|
|
},
|
|
"7C60": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92A6+side: whether and how that side gets a recycler"
|
|
},
|
|
"7C63": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "rows 2-4 are indexed by the relative side instead"
|
|
},
|
|
"7C65": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "row 2 = comcen speed class"
|
|
},
|
|
"7C68": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92B4+rel (later mapped through comcenSpeedClassMap at $7B6E)"
|
|
},
|
|
"7C6B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "row 3 = number of drones"
|
|
},
|
|
"7C6E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92AE+rel; the D_7C6E label only exists because the comcen-screens overlay has code here"
|
|
},
|
|
"7C71": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "row 4 = number of missiles"
|
|
},
|
|
"7C74": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92B0+rel"
|
|
},
|
|
"7C77": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "second pass: the opponent's absolute side"
|
|
},
|
|
"7C7A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "side EOR 1"
|
|
},
|
|
"7C7C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "X = opponent side for the next pass"
|
|
},
|
|
"7C7D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "relative index 1 = the opponent"
|
|
},
|
|
"7C7F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "two passes only"
|
|
},
|
|
"7C81": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "0 = us, 1 = them"
|
|
},
|
|
"7C83": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "go round again for the opponent"
|
|
},
|
|
"7C85": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Roster adjustments for the two game types that are not played with all 50 units a side."
|
|
],
|
|
"line": "operand patched at $7C34: A = the raw game type 0-6"
|
|
},
|
|
"7C87": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "type 1 = QB SNEAK"
|
|
},
|
|
"7C89": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "QB SNEAK is played with a handful of units only"
|
|
},
|
|
"7C8B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "type 2 = THE BOMB"
|
|
},
|
|
"7C8D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "every other type keeps the full roster"
|
|
},
|
|
"7C8F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "THE BOMB: take units 0-98 out of play ($62 = 98)"
|
|
},
|
|
"7C91": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "empty those unit slots"
|
|
},
|
|
"7C94": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "type 4 = COMCEN"
|
|
},
|
|
"7C96": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$F79D = unitTypeTable+49: put side 0's comcen back into play"
|
|
},
|
|
"7C99": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one extra drone for us ..."
|
|
},
|
|
"7C9C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... and one for the opponent: THE BOMB is fought with comcens and drones alone"
|
|
},
|
|
"7C9F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "done"
|
|
},
|
|
"7CA0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "QB SNEAK: take units 0-6 out of play"
|
|
},
|
|
"7CA2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"removeUnitsUpToY - marks unit slots Y down to 0 as 'not in this game': unitTypeTable ($F76C)",
|
|
"= $FF (bit 7 = dead / no such unit) and unitTerrainUnderTable ($FAF0) = $FF ('not standing on",
|
|
"the map'). Entered with Y = 6 for QB SNEAK and Y = $62 for THE BOMB. The RTS at $7CAD is also",
|
|
"the shared exit of applyGameTypeDefaults.",
|
|
"In: Y = highest unit index to remove",
|
|
"Out: $F76C[0..Y] = $FAF0[0..Y] = $FF, Y = $FF",
|
|
"Called from: $7C91 (applyGameTypeDefaults) and by fall-through from $7CA0"
|
|
],
|
|
"line": "$FF = empty unit slot"
|
|
},
|
|
"7CA4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "unitTypeTable[Y] = $FF: bit 7 marks it dead, the whole byte marks it absent"
|
|
},
|
|
"7CA7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "unitTerrainUnderTable[Y] = $FF: this unit occupies no map cell"
|
|
},
|
|
"7CAA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next lower unit"
|
|
},
|
|
"7CAB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "down to unit 0"
|
|
},
|
|
"7CAD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "shared exit of applyGameTypeDefaults"
|
|
},
|
|
"7CAE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"selectSideDefaultsTable - points zp_48/zp_49 at the game-type default table of side X: $892C",
|
|
"for side 0 and $8945 for side 1. Both live in the $8800 modem-strings overlay and hold 5 rows",
|
|
"of 5 bytes; the row is the parameter and the column the game-type class.",
|
|
"In: X = side 0/1",
|
|
"Out: zp_48/zp_49 = address of row 0 of that table",
|
|
"Called from: $7C54 (applyGameTypeDefaults)"
|
|
],
|
|
"line": "low byte of $892C = side 0's defaults"
|
|
},
|
|
"7CB0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "high byte (the $8800 strings overlay)"
|
|
},
|
|
"7CB2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "side 0?"
|
|
},
|
|
"7CB4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "yes: keep $892C"
|
|
},
|
|
"7CB6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "low byte of $8945 = side 1's defaults, 25 bytes further on"
|
|
},
|
|
"7CB8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "high byte"
|
|
},
|
|
"7CBA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_48 = pointer to the current table row"
|
|
},
|
|
"7CBC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_49 = high byte"
|
|
},
|
|
"7CBE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "ready for readDefaultAndAdvanceRow"
|
|
},
|
|
"7CBF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"readDefaultAndAdvanceRow - reads the byte of the current 5-byte table row that belongs to the",
|
|
"chosen game-type column and then advances zp_48/zp_49 to the next row. The LDY operand at",
|
|
"$7CC0 is the column index, written by applyGameTypeDefaults at $7C44.",
|
|
"In: zp_48/zp_49 = current row, column index patched into $7CC0",
|
|
"Out: A = the table value, zp_48/zp_49 += 5",
|
|
"Called from: $7C57, $7C5D, $7C65, $7C6B, $7C71 (all inside applyGameTypeDefaults)"
|
|
],
|
|
"line": "operand patched at $7C44: Y = game-type column 0-4"
|
|
},
|
|
"7CC1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the default for this parameter and this game type"
|
|
},
|
|
"7CC3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "hold it while the pointer moves on"
|
|
},
|
|
"7CC4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "advance the row pointer ..."
|
|
},
|
|
"7CC6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "clear carry before the add"
|
|
},
|
|
"7CC7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... by 5 bytes = one table row"
|
|
},
|
|
"7CC9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "store it back"
|
|
},
|
|
"7CCB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no page crossing"
|
|
},
|
|
"7CCD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "carry into the high byte"
|
|
},
|
|
"7CCF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "get the value back"
|
|
},
|
|
"7CD0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "A = the default value"
|
|
},
|
|
"7CD1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"startFilmPlayback - the game-start path taken when WATCH GAME FILM was chosen ($0B9B bit 7).",
|
|
"Everything the film needs is in its 52-byte header in the RAM under I/O at $D000, written by",
|
|
"$7A78-$7AD8 when the game was recorded; this routine reads it back with readFilmByte and",
|
|
"rebuilds the game from it: link type, side, game type, both player names, map seed, map",
|
|
"orientation and who plays first. The battlefield itself is not stored - it is regenerated from",
|
|
"the seed and rotated if necessary. Then the recorded starting state is restored, the units are",
|
|
"placed, the screen is drawn and the common game-start tail at L_7B8F is entered.",
|
|
"In: film header at $D000 (zp_BC/zp_BD = $D000, left there by checkFilmInMemory)",
|
|
"Out: $0BA8=0, $92FC=0, $92FE, $0B9F, $0BA3, $FFDE-$FFF1, $0B95-$0B97, $0B9D, $0BA1, $0BA9-$0BAE,",
|
|
" $90FB=0, $92FA=$FF, map at $F000 regenerated, all units placed; jumps to L_7B8F",
|
|
"Called from: $7921 (JMP, from the game-start dispatcher)"
|
|
],
|
|
"line": "no game-over reason yet"
|
|
},
|
|
"7CD3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0BA8 = 0: the game has not ended"
|
|
},
|
|
"7CD6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92FC = 0: start the replay with the normal one-sided view"
|
|
},
|
|
"7CD9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "header byte 4"
|
|
},
|
|
"7CDB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Read the recorded game parameters out of the film header at $D000 (RAM under I/O)."
|
|
],
|
|
"line": "read one header byte through zp_BC/zp_BD with the ROMs and I/O banked out"
|
|
},
|
|
"7CDE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$92FE: was the recorded game played against the trainer or over a modem?"
|
|
},
|
|
"7CE1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "header byte 5"
|
|
},
|
|
"7CE2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "read it"
|
|
},
|
|
"7CE5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the side the film was recorded from - the replay is watched through that player's eyes"
|
|
},
|
|
"7CE8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "header byte $0C"
|
|
},
|
|
"7CEA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "read it"
|
|
},
|
|
"7CED": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0BA3: game type and option bits of the recorded game"
|
|
},
|
|
"7CF0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "header bytes $11-$24 = the two 10-byte player names"
|
|
},
|
|
"7CF2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "X walks the name block at $FFDE"
|
|
},
|
|
"7CF4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next name byte"
|
|
},
|
|
"7CF7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$FFDE = our name, $FFE8 = the opponent's"
|
|
},
|
|
"7CFA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next header offset"
|
|
},
|
|
"7CFB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next destination byte"
|
|
},
|
|
"7CFC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$14 = 20 bytes = two 10-character names"
|
|
},
|
|
"7CFE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep copying"
|
|
},
|
|
"7D00": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "header bytes $2B-$2D = the 24-bit map seed"
|
|
},
|
|
"7D02": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "X = seed byte 0-2"
|
|
},
|
|
"7D04": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next seed byte"
|
|
},
|
|
"7D07": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0B95-$0B97: the number the map name is written from"
|
|
},
|
|
"7D0A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next header offset"
|
|
},
|
|
"7D0B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next seed byte"
|
|
},
|
|
"7D0C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "three bytes"
|
|
},
|
|
"7D0E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep copying"
|
|
},
|
|
"7D10": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "header byte $2E packs two flags"
|
|
},
|
|
"7D13": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep the packed byte in X"
|
|
},
|
|
"7D14": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bit 0 = map orientation"
|
|
},
|
|
"7D16": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0B9D: the map was shown rotated 180 degrees"
|
|
},
|
|
"7D19": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the packed byte again"
|
|
},
|
|
"7D1A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "shift the orientation bit out"
|
|
},
|
|
"7D1B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bits 1-2 = who plays first"
|
|
},
|
|
"7D1D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0BA1"
|
|
},
|
|
"7D20": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Rebuild the battlefield: the film stores only the seed, never the 1600 map cells."
|
|
],
|
|
"line": "burn the film's side into the engine's self-modifying side tests"
|
|
},
|
|
"7D23": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "regenerate the identical 40x40 map from the seed"
|
|
},
|
|
"7D26": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the generator always builds the map for side 0 ..."
|
|
},
|
|
"7D29": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... so compare the viewing side with the recorded orientation"
|
|
},
|
|
"7D2C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "orientations agree: leave the map alone"
|
|
},
|
|
"7D2E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "turn the battlefield 180 degrees and mirror the direction-dependent terrain codes"
|
|
},
|
|
"7D31": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "header bytes 6-$0B = the 6-byte map-id text"
|
|
},
|
|
"7D33": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "X walks $0BA9-$0BAE"
|
|
},
|
|
"7D35": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next character of the map name"
|
|
},
|
|
"7D38": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "restore it: generateBattlefieldMap has just overwritten $0BA9 with its own copy"
|
|
},
|
|
"7D3B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next header offset"
|
|
},
|
|
"7D3C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next character"
|
|
},
|
|
"7D3D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "six characters"
|
|
},
|
|
"7D3F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep copying"
|
|
},
|
|
"7D41": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "restore the recorded starting state (unit arrays, scores, clock) from $D034 onwards"
|
|
},
|
|
"7D44": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the recorded option bits"
|
|
},
|
|
"7D47": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bit 6 = CUSTOM rules"
|
|
},
|
|
"7D49": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "standard rules: nothing to announce"
|
|
},
|
|
"7D4B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "put the 'CUSTOM: ...' summary on the status line"
|
|
},
|
|
"7D4E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Put the restored units on the map and draw the battlefield screen."
|
|
],
|
|
"line": "write $80|index into the map cell of every living unit"
|
|
},
|
|
"7D51": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "move the viewport over the player's own end of the field"
|
|
},
|
|
"7D54": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "screen id 0 ..."
|
|
},
|
|
"7D56": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... = the battlefield screen"
|
|
},
|
|
"7D59": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "clear the bitmap and redraw the frames, panels and console"
|
|
},
|
|
"7D5C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "draw the 20x20 overview map in the left panel"
|
|
},
|
|
"7D5F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bit 7 set ..."
|
|
},
|
|
"7D61": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... lets the status line keep the clock and score up to date ($C50D)"
|
|
},
|
|
"7D64": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "our side"
|
|
},
|
|
"7D67": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "EOR 1 = the opponent's side"
|
|
},
|
|
"7D69": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "drawRecyclerOnMap takes the side in Y"
|
|
},
|
|
"7D6A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "put the opponent's recycler glyph back on the map"
|
|
},
|
|
"7D6D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "join the common game-start tail (the film's own recycler is drawn there)"
|
|
},
|
|
"7D70": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"initUnitOrderLists - fills the two 100-entry unit order lists unitBaseOrder ($9164) and",
|
|
"unitProcessOrder ($90FD) with the identity permutation, 99 down to 0.",
|
|
"In: -",
|
|
"Out: $9164[i] = $90FD[i] = i for i = 0..99, Y = $FF",
|
|
"Called from: $7BB5 (shuffleInitialUnitOrder), before the base list is shuffled"
|
|
],
|
|
"line": "$63 = 99, the last unit index"
|
|
},
|
|
"7D72": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "entry Y gets the value Y"
|
|
},
|
|
"7D73": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$9164: the shuffled base order built by shuffleInitialUnitOrder"
|
|
},
|
|
"7D76": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$90FD: the working order the round loop walks"
|
|
},
|
|
"7D79": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next lower unit"
|
|
},
|
|
"7D7A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "down to unit 0"
|
|
},
|
|
"7D7C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "both lists are now 0..99"
|
|
},
|
|
"7D7D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"placeAllUnitsOnMap - runs placeUnitOnMap for every unit 99 down to 0, which resets the unit's",
|
|
"energy, move points and flags, saves the terrain under it and writes $80|index into its map",
|
|
"cell (a dead unit becomes an empty slot instead). The callee wants the index in zp_18 as well",
|
|
"as in X.",
|
|
"In: the unit column/row arrays, the map at $F000",
|
|
"Out: every living unit is on the map, zp_18 = $FF",
|
|
"Called from: $7B83 (game start) and $7D4E (film playback)"
|
|
],
|
|
"line": "start at unit 99"
|
|
},
|
|
"7D7F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "placeUnitOnMap reads the index from zp_18 as well as from X"
|
|
},
|
|
"7D81": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "X = the unit to place"
|
|
},
|
|
"7D83": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "reset the unit and write $80|index into its map cell, saving the terrain underneath"
|
|
},
|
|
"7D86": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next lower unit"
|
|
},
|
|
"7D88": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "down to unit 0"
|
|
},
|
|
"7D8A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "all 100 slots handled"
|
|
},
|
|
"7D8B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"setGameClockForType - looks the length of the game up in roundsByGameType ($78C3: 63, 63, 31,",
|
|
"127, 127, 254, 254 rounds for types 0-6) and starts the game clock with it.",
|
|
"In: gameTypeOptions $0BA3 bits 0-2",
|
|
"Out: gameClock $91CB = A = the number of rounds",
|
|
"Called from: $7B1A, $7B69, $7B86 and $7B9E (which shifts A right twice to get the quarter length)"
|
|
],
|
|
"line": "the game type and option bits"
|
|
},
|
|
"7D8E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bits 0-2 = type 0-6"
|
|
},
|
|
"7D90": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "index the length table"
|
|
},
|
|
"7D91": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$78C3: 63, 63, 31, 127, 127, 254, 254 rounds"
|
|
},
|
|
"7D94": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$91CB counts one down per round"
|
|
},
|
|
"7D97": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "A still holds the length for the caller"
|
|
},
|
|
"7D98": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"clearUnitsAndRecyclersFromMap - takes every unit 99..0 off the map (removeUnitFromMap puts the",
|
|
"terrain that was hidden under it back) and then blanks both recycler cells, leaving a map that",
|
|
"holds terrain only. Falls into clearRecyclerCell for side 1.",
|
|
"In: the unit arrays, recyclerCol/recyclerRow $92A8/$92AA",
|
|
"Out: the map at $F000-$F63F contains no units and no recyclers",
|
|
"Called from: $7B7A, just before the film snapshot is written and the units are re-placed"
|
|
],
|
|
"line": "start at unit 99"
|
|
},
|
|
"7D9A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "restore the terrain under the unit and mark it as not on the map"
|
|
},
|
|
"7D9D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next lower unit"
|
|
},
|
|
"7D9E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "down to unit 0"
|
|
},
|
|
"7DA0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "side 0 ..."
|
|
},
|
|
"7DA2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... blank its recycler cell"
|
|
},
|
|
"7DA5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "side 1: fall into the same code"
|
|
},
|
|
"7DA7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"clearRecyclerCell - blanks side X's recycler cell: if that side has a recycler (recyclerCol bit",
|
|
"7 clear) the map byte at (recyclerCol, recyclerRow) is set to the empty terrain code $40.",
|
|
"In: X = side 0/1, recyclerCol $92A8, recyclerRow $92AA",
|
|
"Out: one map cell = $40, zp_48/zp_49 point at it",
|
|
"Called from: $7DA2 and by fall-through from $7DA5"
|
|
],
|
|
"line": "$92A8+side; bit 7 set means this side has no recycler placed"
|
|
},
|
|
"7DAA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no recycler: nothing to blank"
|
|
},
|
|
"7DAC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "Y = recycler row"
|
|
},
|
|
"7DAF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "X = recycler column"
|
|
},
|
|
"7DB0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_48/zp_49 = address of that map cell; Y comes back as 0"
|
|
},
|
|
"7DB3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$40 = empty terrain"
|
|
},
|
|
"7DB5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "wipe the recycler out of the map"
|
|
},
|
|
"7DB7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "done"
|
|
},
|
|
"7DB8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"waitForSpaceKey - 'PRESS SPACE WHEN READY' wait used by the modem setup prompts. Clears the",
|
|
"keyboard and chat state and then loops servicing the link and stirring the game RNG until the",
|
|
"space bar ($A0) turns up in lastTypedKey; afterwards it empties the message queue and locks the",
|
|
"input out for half a second. Stirring the RNG on every pass is what makes the map seed depend",
|
|
"on how long the player took to press space.",
|
|
"In: lastTypedKey $9248 (written by the IRQ keyboard scan)",
|
|
"Out: $9248 = $FF, chatState $929C = 0, incomingChatLength $9277 = 0, inputLockoutTimer $0B7D =",
|
|
" 30 frames, message queue emptied, game RNG zp_57-zp_59 advanced",
|
|
"Called from: showModemSetupPrompt ($0C9D, JMP), so this RTS returns to that routine's caller"
|
|
],
|
|
"line": "$FF = no key pending"
|
|
},
|
|
"7DBA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "throw away whatever was typed before"
|
|
},
|
|
"7DBD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zero for the three variables below"
|
|
},
|
|
"7DBF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "leave chat entry mode"
|
|
},
|
|
"7DC2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no input lockout while we wait"
|
|
},
|
|
"7DC5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "discard a half-received chat line"
|
|
},
|
|
"7DC8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Wait loop: keep the link alive and stir the random generator until space is pressed."
|
|
],
|
|
"line": "service the lock-step command exchange"
|
|
},
|
|
"7DCB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "step the 24-bit game RNG - this is what randomises the map seed"
|
|
},
|
|
"7DCE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the last key the IRQ saw"
|
|
},
|
|
"7DD1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$A0 = the space bar"
|
|
},
|
|
"7DD3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep waiting"
|
|
},
|
|
"7DD5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "space pressed: empty the message queue and refresh the status line"
|
|
},
|
|
"7DD8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$1E = 30 frames"
|
|
},
|
|
"7DDA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "ignore input for half a second so the key is not seen twice"
|
|
},
|
|
"7DDD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$FF = no key pending"
|
|
},
|
|
"7DDF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "consume the space"
|
|
},
|
|
"7DE2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "returns into showModemSetupPrompt's caller"
|
|
},
|
|
"7DE3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"handleMainMenuChoice - acts on the item the player picked in the main menu. 0 COMPETE WITH",
|
|
"MODEM OPPONENT and 1 PRACTICE WITH SOLO TRAINER set the opponent-module flag and start a game;",
|
|
"2 WATCH GAME FILM needs a valid film in $D000 and starts the game in playback mode; 3 SAVE GAME",
|
|
"FILM (also needs a valid film) and 4 LOAD GAME FILM ask for the data disk, load its film",
|
|
"directory and run the save or load slot menu, then ask for the game disk again.",
|
|
"In: menuSelectedItem $91D5, isSoloTrainer $0BA5, the film buffer at $D000",
|
|
"Out: $0BA5, $0B9B, defaultMainMenuItem $92FD = 2, filmDirectoryPage $7FA1 = 0, filmMenuMode",
|
|
" $7FA2; items 0-2 leave through startGameFromSetup ($0AC8)",
|
|
"Called from: runMainMenu ($1C78, JMP)"
|
|
],
|
|
"line": "the item the selector returned"
|
|
},
|
|
"7DE6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "self-modifying: the item number becomes the operand of the LDA #$FF at $7E0E"
|
|
},
|
|
"7DE9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "items 0-2 start a game"
|
|
},
|
|
"7DEB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "handle those below"
|
|
},
|
|
"7DED": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 4 = LOAD GAME FILM: there is nothing in memory to check"
|
|
},
|
|
"7DEF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 3 = SAVE GAME FILM: refuse unless $D000 holds a valid film"
|
|
},
|
|
"7DF2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no film: 'NOT A GAME FILM!' has been shown, give up"
|
|
},
|
|
"7DF4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Save/load film: get the data disk in the drive and read its film directory."
|
|
],
|
|
"line": "show 'INSERT DATA DISK AND PRESS SPACE.'"
|
|
},
|
|
"7DF7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "pause the modem/trainer module - the fast loader runs with interrupts off"
|
|
},
|
|
"7DFA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "identify the disk and read the 30-entry film directory to $0300"
|
|
},
|
|
"7DFD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep the C flag across the resume"
|
|
},
|
|
"7DFE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "restart the comm module and clear the status line"
|
|
},
|
|
"7E01": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "get the result back"
|
|
},
|
|
"7E02": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no usable disk in the drive: the message has already been shown"
|
|
},
|
|
"7E04": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 2 = WATCH GAME FILM ..."
|
|
},
|
|
"7E06": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... becomes the pre-selected main-menu item next time round"
|
|
},
|
|
"7E09": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start on ..."
|
|
},
|
|
"7E0B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the first directory page"
|
|
},
|
|
"7E0E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "operand patched at $7DE6: A = the menu item (3 or 4)"
|
|
},
|
|
"7E10": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "prepare the subtraction"
|
|
},
|
|
"7E11": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 3 -> 0, item 4 -> 1"
|
|
},
|
|
"7E13": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$7FA2: 0 = save film, 1 = load film"
|
|
},
|
|
"7E16": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "draw the ten slots of the current page"
|
|
},
|
|
"7E19": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "which of the two menus?"
|
|
},
|
|
"7E1C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "1 = load"
|
|
},
|
|
"7E1E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "SAVE: pick a slot, type a name and write the film to disk"
|
|
},
|
|
"7E21": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "then ask for the game disk again"
|
|
},
|
|
"7E24": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "LOAD: pick a slot and read the film into $D000"
|
|
},
|
|
"7E27": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "then ask for the game disk again"
|
|
},
|
|
"7E2A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "nothing to do"
|
|
},
|
|
"7E2B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Items 0-2: choose the opponent module / playback mode and start a game."
|
|
],
|
|
"line": "item 2 = WATCH GAME FILM"
|
|
},
|
|
"7E2D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "items 0 and 1 below"
|
|
},
|
|
"7E2F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "a film can only be watched if one is loaded"
|
|
},
|
|
"7E32": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "invalid film: back to the menu"
|
|
},
|
|
"7E34": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep the current opponent module - a film can be watched either way"
|
|
},
|
|
"7E37": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0B9B = $82: bit 7 = playing a film back, bits 0-1 = 2 = show both sides"
|
|
},
|
|
"7E39": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"setModeFlagsAndStartGame - shared tail of handleMainMenuChoice: X becomes isSoloTrainer $0BA5",
|
|
"($FF = solo trainer, 0 = modem opponent) and A becomes filmPlaybackMode $0B9B, then the game is",
|
|
"started.",
|
|
"In: X = new $0BA5, A = new $0B9B",
|
|
"Out: $0BA5, $0B9B; jumps to startGameFromSetup ($0AC8)",
|
|
"Called from: $7E47 and $7E4D (branches), and by fall-through from $7E37"
|
|
],
|
|
"line": "$0BA5: $FF = play the solo trainer, 0 = play a modem opponent"
|
|
},
|
|
"7E3C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0B9B: bit 7 = watch a game film"
|
|
},
|
|
"7E3F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "leave the menu and start the game"
|
|
},
|
|
"7E42": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 0 COMPETE WITH MODEM OPPONENT: no film ..."
|
|
},
|
|
"7E44": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... and X = 0 = the modem driver"
|
|
},
|
|
"7E45": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 1 = PRACTICE WITH SOLO TRAINER?"
|
|
},
|
|
"7E47": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no: start the modem game"
|
|
},
|
|
"7E49": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "solo trainer: no film either"
|
|
},
|
|
"7E4B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$FF selects the trainer module at $E000"
|
|
},
|
|
"7E4D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "always taken (X is $FF)"
|
|
},
|
|
"7E4F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"checkDiskAndLoadFilmDirectory - works out which disk is in the drive and loads its film",
|
|
"directory. The game disk ('OZ') is tried first and silently, because films may also be kept on",
|
|
"it; otherwise a data disk ('EA') is required, and a data disk must additionally have every",
|
|
"block allocated in its BAM ($0203-$028F all zero) so that CBM DOS can never overwrite the raw",
|
|
"film tracks. diskIdIndex $92F0 is left at 0 for the game disk and 2 for a data disk, which",
|
|
"later decides whether the directory has one page or three. Falls into loadFilmDirectory.",
|
|
"In: the disk in the drive",
|
|
"Out: C=0 and the directory at $0300-$04FF, or C=1 with a message shown; $92F0, BAM at $0200",
|
|
"Called from: $7DFA (handleMainMenuChoice)"
|
|
],
|
|
"line": "X = 0: look for the 'OZ' game disk"
|
|
},
|
|
"7E51": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "bit 7 = fail silently, this is only a first guess"
|
|
},
|
|
"7E53": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "read the BAM and compare the disk id"
|
|
},
|
|
"7E56": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the game disk can hold films too: use it"
|
|
},
|
|
"7E58": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "X = 2: look for the 'EA' data disk"
|
|
},
|
|
"7E5A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "this time complain if it is not there"
|
|
},
|
|
"7E5C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "read the BAM and compare the disk id"
|
|
},
|
|
"7E5F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "neither disk: 'NOT A DATA DISK!' has been shown, return C=1"
|
|
},
|
|
"7E61": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the BAM's per-track allocation entries start at $0203"
|
|
},
|
|
"7E63": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"A real data disk has been fully allocated by the format utility, so every BAM entry must be",
|
|
"zero (no free blocks anywhere). Otherwise this is an ordinary CBM disk whose files would be",
|
|
"destroyed by writing raw tracks."
|
|
],
|
|
"line": "a byte of the BAM allocation map (the $0200 buffer, contourRuleTable's address)"
|
|
},
|
|
"7E66": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "any non-zero byte means free blocks exist: not a data disk"
|
|
},
|
|
"7E68": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next BAM byte"
|
|
},
|
|
"7E69": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0203-$028F covers all 35 tracks"
|
|
},
|
|
"7E6B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep checking"
|
|
},
|
|
"7E6D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the disk is usable: read its film directory"
|
|
},
|
|
"7E70": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "C=1: no usable disk"
|
|
},
|
|
"7E71": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "'NOT A DATA DISK!' ($0F81) and C=1"
|
|
},
|
|
"7E74": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"writeFilmDirectory - writes the 512-byte film directory (30 entries of 16 bytes plus slack)",
|
|
"from $0300-$04FF back to track 18 sectors 2-3. A write error ends in diskErrorExit.",
|
|
"In: the directory at $0300",
|
|
"Out: track 18 sectors 2-3 rewritten, C=0",
|
|
"Called from: $8164 (saveFilmToSlot), before the film itself is written"
|
|
],
|
|
"line": "8 frames ..."
|
|
},
|
|
"7E76": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... to let the drive settle after the previous access"
|
|
},
|
|
"7E79": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "destination low byte $00 ..."
|
|
},
|
|
"7E7B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $03: the buffer at $0300"
|
|
},
|
|
"7E7D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "tell the fast loader where the data is"
|
|
},
|
|
"7E80": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "2 sectors ..."
|
|
},
|
|
"7E82": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... starting at sector 2 ..."
|
|
},
|
|
"7E83": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... of track 18, the directory track"
|
|
},
|
|
"7E85": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the drive encrypts and writes both sectors"
|
|
},
|
|
"7E88": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "write failed"
|
|
},
|
|
"7E8A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "directory saved"
|
|
},
|
|
"7E8B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"loadFilmDirectory - reads track 18 sectors 2-3 (the 30 x 16-byte film names) into $0300-$04FF.",
|
|
"A read error ends in diskErrorExit. Tail of checkDiskAndLoadFilmDirectory.",
|
|
"In: -",
|
|
"Out: $0300-$04FF = film directory, C=0",
|
|
"Called from: $7E6D (JMP)"
|
|
],
|
|
"line": "destination low byte $00 ..."
|
|
},
|
|
"7E8D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $03: the buffer at $0300"
|
|
},
|
|
"7E8F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "tell the fast loader where to put the data"
|
|
},
|
|
"7E92": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "2 sectors ..."
|
|
},
|
|
"7E94": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... from sector 2 ..."
|
|
},
|
|
"7E95": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... of track 18"
|
|
},
|
|
"7E97": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "wait 8 frames, then read both sectors"
|
|
},
|
|
"7E9A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "read failed"
|
|
},
|
|
"7E9C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "directory loaded"
|
|
},
|
|
"7E9D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "show 'DISK ERROR.' and return C=1"
|
|
},
|
|
"7EA0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"drawFilmDirectoryPage - draws one page of the film menu: the centred title 'SAVE GAME FILM' or",
|
|
"'LOAD GAME FILM', then ten entries printed as a right-aligned slot number, a space and the",
|
|
"16-character film name, then ' (MORE)' when a three-page data disk is in the drive and finally",
|
|
"' (EXIT)'. Ends by setting up the menu selector: item count, window column 11 / width 18 (the",
|
|
"name field, so that the highlight bar and the redraws leave the slot numbers alone), first row",
|
|
"9 and the highlight EOR mask.",
|
|
"In: filmDirectoryPage $7FA1, filmMenuMode $7FA2, diskIdIndex $92F0, directory at $0300",
|
|
"Out: the menu drawn; menuItemCount $91D4, menuSelectedItem $91D5 = 0, menuFirstRow $91D6 = 9,",
|
|
" zp_3B = 11, zp_3C = 18, zp_3D = $60, zp_48/zp_49 = entry pointer, $90F8 and $9220 counters",
|
|
"Called from: $7E16 and $7FDA (nextFilmDirectoryPage, JMP)"
|
|
],
|
|
"line": "clear the menu window (screen column 2, 36 wide, from row 7)"
|
|
},
|
|
"7EA3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "'SAVE GAME FILM' at $CC66 ..."
|
|
},
|
|
"7EA5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... in the text overlay"
|
|
},
|
|
"7EA7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "0 = save, 1 = load"
|
|
},
|
|
"7EAA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "save: keep that title"
|
|
},
|
|
"7EAC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "'LOAD GAME FILM' at $CC75 ..."
|
|
},
|
|
"7EAE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... in the text overlay"
|
|
},
|
|
"7EB0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "centre the title in the 36-column menu window"
|
|
},
|
|
"7EB3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "indent the list ..."
|
|
},
|
|
"7EB5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... to screen column 9"
|
|
},
|
|
"7EB7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "down to the first list row (row 8)"
|
|
},
|
|
"7EBA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "22 columns: 'nn ' plus a 16-character name"
|
|
},
|
|
"7EBC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "also the wrap width used while printing"
|
|
},
|
|
"7EBE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "dead store: setFilmDirectoryPagePtr overwrites $90F8 two instructions later"
|
|
},
|
|
"7EC0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "(leftover initialisation of the slot number)"
|
|
},
|
|
"7EC3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_48/zp_49 = first entry of this page, $90F8 = the slot number it is called"
|
|
},
|
|
"7EC6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "9 ..."
|
|
},
|
|
"7EC8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... = ten entries per page (the counter runs 9..0); $9220 is only the drone fuel during a battle"
|
|
},
|
|
"7ECB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Entry loop: prints 'nn name' for the ten slots of this page, advancing zp_48/zp_49 by one",
|
|
"16-byte directory entry each time."
|
|
],
|
|
"line": "the slot number 1-30 printed in front of the name"
|
|
},
|
|
"7ECE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "numbers below 10 are one digit ..."
|
|
},
|
|
"7ED0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... two digits need no padding"
|
|
},
|
|
"7ED2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$A0 = space"
|
|
},
|
|
"7ED4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "pad one-digit numbers so all names start in the same column"
|
|
},
|
|
"7ED7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the slot number"
|
|
},
|
|
"7EDA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "Y = middle byte of the 24-bit value printDecimal takes (the top byte zp_7E is left at 0)"
|
|
},
|
|
"7EDC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "print it in decimal without leading zeros"
|
|
},
|
|
"7EDF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$A0 = space"
|
|
},
|
|
"7EE1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "separate the number from the name"
|
|
},
|
|
"7EE4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "pointer to this directory entry ..."
|
|
},
|
|
"7EE6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... low/high"
|
|
},
|
|
"7EE8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "print the 16-character name (its last byte carries bit 7)"
|
|
},
|
|
"7EEB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next screen line"
|
|
},
|
|
"7EEE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "advance the entry pointer ..."
|
|
},
|
|
"7EF0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "clear carry for the 16-bit add"
|
|
},
|
|
"7EF1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... by $10 = one 16-byte directory entry"
|
|
},
|
|
"7EF3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "store it back"
|
|
},
|
|
"7EF5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "high byte"
|
|
},
|
|
"7EF7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "carry only"
|
|
},
|
|
"7EF9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "store it back"
|
|
},
|
|
"7EFB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next slot number"
|
|
},
|
|
"7EFE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one entry done"
|
|
},
|
|
"7F01": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "ten entries per page"
|
|
},
|
|
"7F03": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Trailing menu items and the selector setup."
|
|
],
|
|
"line": "11 items ..."
|
|
},
|
|
"7F05": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... = ten slots plus (EXIT)"
|
|
},
|
|
"7F08": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "0 = the game disk, 2 = a data disk"
|
|
},
|
|
"7F0B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the game disk holds only one page of ten slots"
|
|
},
|
|
"7F0D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "a data disk has three pages, so there is a 12th item: (MORE)"
|
|
},
|
|
"7F10": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "three blank columns ..."
|
|
},
|
|
"7F12": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... so that '(MORE)' lines up with the names ($C0EF is printFillChars in the text overlay)"
|
|
},
|
|
"7F15": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "' (MORE)' at $EF81 ..."
|
|
},
|
|
"7F17": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... in the comm-module tail"
|
|
},
|
|
"7F19": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "print it (the string ends with a CR)"
|
|
},
|
|
"7F1C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "three blank columns ..."
|
|
},
|
|
"7F1E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... for the last item too"
|
|
},
|
|
"7F21": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "' (EXIT)' at $CAB2 ..."
|
|
},
|
|
"7F23": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the tail of the formation-menu string block"
|
|
},
|
|
"7F25": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "print it"
|
|
},
|
|
"7F28": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the selector window starts at screen column 11 ..."
|
|
},
|
|
"7F2A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... i.e. one column in front of the names"
|
|
},
|
|
"7F2C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "18 characters wide ..."
|
|
},
|
|
"7F2E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... = the space plus the 16-character name, and the width of the highlight bar"
|
|
},
|
|
"7F30": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the first slot sits on screen row 9 ..."
|
|
},
|
|
"7F32": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... menuFirstRow, to which the item number is added"
|
|
},
|
|
"7F35": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start the bar ..."
|
|
},
|
|
"7F37": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... on the first slot"
|
|
},
|
|
"7F3A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$60 = the EOR mask that flips a row between the two text colours"
|
|
},
|
|
"7F3C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_3D is both the plot colour and the highlight mask"
|
|
},
|
|
"7F3E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the page is ready for the selector"
|
|
},
|
|
"7F3F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"runLoadFilmMenu - LOAD GAME FILM. Runs the standard menu selector over the directory page;",
|
|
"(MORE) turns to the next page and starts again, (EXIT) leaves. Picking a slot converts it to",
|
|
"a disk track and reads that track's 16 sectors one at a time into $0200, copying each page into",
|
|
"the film buffer $D000-$DFFF that lives under the I/O area, and finally validates the header.",
|
|
"In: menuSelectedItem $91D5, diskIdIndex $92F0, filmDirectoryPage $7FA1, the disk",
|
|
"Out: $D000-$DFFF = the film, $91D5 = the track it came from, zp_18/zp_19, the copy pointers",
|
|
" $58C3/$58C4 (source) and $58C6/$58C7 (destination)",
|
|
"Called from: $7E24 (handleMainMenuChoice) and $7F54 (itself, after a page turn)"
|
|
],
|
|
"line": "C=1: ordinary menu behaviour (the bar pauses before it reaches the last row)"
|
|
},
|
|
"7F40": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "run the selector until fire or RETURN"
|
|
},
|
|
"7F43": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the chosen item"
|
|
},
|
|
"7F46": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "items 0-9 are film slots"
|
|
},
|
|
"7F48": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "load that slot"
|
|
},
|
|
"7F4A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 11 is always (EXIT)"
|
|
},
|
|
"7F4C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 10 is (MORE) only when a data disk is in the drive"
|
|
},
|
|
"7F4F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "on the game disk item 10 is (EXIT)"
|
|
},
|
|
"7F51": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "turn to the next page and redraw it"
|
|
},
|
|
"7F54": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "and run the selector again"
|
|
},
|
|
"7F57": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Load one film: 16 sectors of one track, each read into $0200 and then copied into the film",
|
|
"buffer under the I/O area at $D000."
|
|
],
|
|
"line": "pause the comm module for the disk access"
|
|
},
|
|
"7F5A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "slot -> track number"
|
|
},
|
|
"7F5D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_19 = the track to read"
|
|
},
|
|
"7F5F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "copyPageUnderIo destination low byte = $00 ..."
|
|
},
|
|
"7F61": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... (operand of the STA at $58C5)"
|
|
},
|
|
"7F64": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $D0: the film buffer under I/O"
|
|
},
|
|
"7F66": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the destination page walks $D000..$DF00"
|
|
},
|
|
"7F69": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "copyPageUnderIo source low byte = $00 ..."
|
|
},
|
|
"7F6B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... (operand of the LDA at $58C2)"
|
|
},
|
|
"7F6E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $02: the sector buffer at $0200"
|
|
},
|
|
"7F70": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the source stays at $0200 for every sector"
|
|
},
|
|
"7F73": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start with ..."
|
|
},
|
|
"7F75": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... sector 0 in zp_18"
|
|
},
|
|
"7F77": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "destination low byte $00 ..."
|
|
},
|
|
"7F79": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $02: read the sector to $0200"
|
|
},
|
|
"7F7B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "tell the fast loader where to put it"
|
|
},
|
|
"7F7E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one sector ..."
|
|
},
|
|
"7F80": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... from the film's track ..."
|
|
},
|
|
"7F82": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... at the current sector number"
|
|
},
|
|
"7F84": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "wait 8 frames, then read it"
|
|
},
|
|
"7F87": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "copy those 256 bytes into the film buffer with the I/O area banked out"
|
|
},
|
|
"7F8A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next destination page ($D000, $D100, ...)"
|
|
},
|
|
"7F8D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next sector"
|
|
},
|
|
"7F8F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "sector counter"
|
|
},
|
|
"7F91": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "16 sectors = the whole 4 KB film buffer"
|
|
},
|
|
"7F93": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep reading"
|
|
},
|
|
"7F95": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "restart the comm module and clear the status line"
|
|
},
|
|
"7F98": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "does the loaded data have a valid film header?"
|
|
},
|
|
"7F9B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "valid"
|
|
},
|
|
"7F9D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "invalid: checkFilmInMemory has already shown 'NOT A GAME FILM!'"
|
|
},
|
|
"7F9E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "valid: clear the message queue and return"
|
|
},
|
|
"7FA1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"filmDirectoryPage - which of the three directory pages is on screen (0-2). A game disk only",
|
|
"ever shows page 0; a data disk holds 30 films in three pages of ten."
|
|
],
|
|
"line": "current page 0-2"
|
|
},
|
|
"7FA2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"filmMenuMode - 0 = SAVE GAME FILM, 1 = LOAD GAME FILM (set from the main-menu item - 3)."
|
|
],
|
|
"line": "0 = save, 1 = load"
|
|
},
|
|
"7FA3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"filmPageFirstSlotTable - the slot number printed for the first entry of each page: page 0",
|
|
"starts at 1, page 1 at 11 and page 2 at 21, so the 30 slots are numbered 1-30 on screen."
|
|
],
|
|
"line": "first slot number of pages 0, 1 and 2"
|
|
},
|
|
"7FA6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"setFilmDirectoryPagePtr - points zp_48/zp_49 at the first directory entry of the current page",
|
|
"($0300 + page * $A0, ten entries of 16 bytes per page) and puts the slot number that entry is",
|
|
"shown as (1, 11 or 21) into $90F8 for the numbering loop.",
|
|
"In: filmDirectoryPage $7FA1, filmPageFirstSlotTable $7FA3",
|
|
"Out: zp_48/zp_49 = entry pointer, $90F8 = first slot number",
|
|
"Called from: $7EC3 (drawFilmDirectoryPage) and $7FDD (runSaveFilmMenu)"
|
|
],
|
|
"line": "low byte of $0300 ..."
|
|
},
|
|
"7FA8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the directory buffer"
|
|
},
|
|
"7FAA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "high byte $03 ..."
|
|
},
|
|
"7FAC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... zp_48/zp_49 = $0300"
|
|
},
|
|
"7FAE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "current page 0-2"
|
|
},
|
|
"7FB1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "1, 11 or 21"
|
|
},
|
|
"7FB4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$90F8 = the slot number of the first entry on this page"
|
|
},
|
|
"7FB7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "page number into A"
|
|
},
|
|
"7FB8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "page 0 needs no offset"
|
|
},
|
|
"7FBA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "add one page ..."
|
|
},
|
|
"7FBC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "clear carry for the 16-bit add"
|
|
},
|
|
"7FBD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... $A0 = 10 entries of 16 bytes"
|
|
},
|
|
"7FBF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "store it back"
|
|
},
|
|
"7FC1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "high byte"
|
|
},
|
|
"7FC3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "carry only"
|
|
},
|
|
"7FC5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "store it back"
|
|
},
|
|
"7FC7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one page done"
|
|
},
|
|
"7FC8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "repeat for each page skipped"
|
|
},
|
|
"7FCA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_48/zp_49 now points at entry 0 of the page"
|
|
},
|
|
"7FCB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"nextFilmDirectoryPage - steps filmDirectoryPage on modulo 3 and redraws the list.",
|
|
"In: filmDirectoryPage $7FA1",
|
|
"Out: $7FA1 advanced (wrapping 2 -> 0); jumps to drawFilmDirectoryPage",
|
|
"Called from: $7F51 (load menu) and $80CC (save menu), both on the (MORE) item"
|
|
],
|
|
"line": "step to the next page"
|
|
},
|
|
"7FCE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "read it back (the D_7FCE label only exists because the comcen-screens overlay has a table here)"
|
|
},
|
|
"7FD1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "three pages of ten slots"
|
|
},
|
|
"7FD3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "still in range"
|
|
},
|
|
"7FD5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "wrap ..."
|
|
},
|
|
"7FD7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... back to page 0"
|
|
},
|
|
"7FDA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "redraw the ten entries of the new page"
|
|
},
|
|
"7FDD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"runSaveFilmMenu - SAVE GAME FILM. A private copy of the generic menu selector",
|
|
"(runMenuLoopWatchUnit $5FDC) with a text field built into it: while a slot 0-9 is highlighted",
|
|
"every key goes to the line editor handleTextEntryKey (at most 16 characters into the buffer",
|
|
"$9278) and the typed text is echoed on that row with a block cursor behind it. Moving the bar",
|
|
"up or down throws the typed text away; fire or RETURN accepts. (MORE) turns the page, (EXIT)",
|
|
"leaves, and a slot with typed text gets the name copied into its 16-byte directory entry",
|
|
"(padded with spaces, bit 7 on the last byte) before saveFilmToSlot writes directory and film.",
|
|
"In: menuItemCount $91D4, menuSelectedItem $91D5, menuFirstRow $91D6, filmDirectoryPage $7FA1,",
|
|
" the keyboard through $90EA, the joystick zp_5D, the frame timers zp_6C and zp_6E",
|
|
"Out: Y = $91D5 (after a save that is the disk track, not the slot), filmNameLength $92E6 = 0,",
|
|
" $92C5, the typed name in $9278 and in the directory entry, the film on disk;",
|
|
" zp_4A/zp_4B = pointer to the selected directory entry; self-modifies $809B+1 and $809F+1",
|
|
"Called from: $7E1E (handleMainMenuChoice) and $80CF (itself, after a page turn)"
|
|
],
|
|
"line": "zp_48/zp_49 = the first entry of this page"
|
|
},
|
|
"7FE0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "number of menu items"
|
|
},
|
|
"7FE3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "count - 1 ..."
|
|
},
|
|
"7FE4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... - 1 = the row the bar has to slow down in front of"
|
|
},
|
|
"7FE5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "self-modifying: that row becomes the operand of the CMP #$FF at $809B"
|
|
},
|
|
"7FE8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$14 = 20 frames ..."
|
|
},
|
|
"7FEA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... of input lockout before the stick is read"
|
|
},
|
|
"7FEC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Entered again after every move of the bar: clear the typed text, work out the address of the",
|
|
"selected directory entry and draw the row highlighted."
|
|
],
|
|
"line": "start with ..."
|
|
},
|
|
"7FEE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... an empty name ..."
|
|
},
|
|
"7FF1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the row highlighted ($92C5 = 0) ..."
|
|
},
|
|
"7FF4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... and the high byte of the entry pointer cleared"
|
|
},
|
|
"7FF6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the selected item"
|
|
},
|
|
"7FF9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "items 0-9 are slots ..."
|
|
},
|
|
"7FFB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... (MORE) and (EXIT) have no directory entry"
|
|
},
|
|
"7FFD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "shift four times ..."
|
|
},
|
|
"7FFF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... to multiply the item number by 16 ..."
|
|
},
|
|
"8000": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... into A (low) and zp_4B (high)"
|
|
},
|
|
"8002": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "four shifts"
|
|
},
|
|
"8003": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep shifting"
|
|
},
|
|
"8005": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "add the page pointer ..."
|
|
},
|
|
"8006": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... low byte"
|
|
},
|
|
"8008": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_4A = address of the entry"
|
|
},
|
|
"800A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "high byte ..."
|
|
},
|
|
"800C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... plus the carry"
|
|
},
|
|
"800E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_4B = high byte of the entry pointer"
|
|
},
|
|
"8010": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "colour $01 = the highlighted row (black on white)"
|
|
},
|
|
"8012": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "draw the row (name, or (MORE)/(EXIT))"
|
|
},
|
|
"8015": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$9E = the line-editor terminator ..."
|
|
},
|
|
"8017": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... so the typed-name buffer starts out empty"
|
|
},
|
|
"801A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"Input loop: one pass per frame. Keys go into the name field, the highlight blinks every 20",
|
|
"frames and the joystick moves the bar or confirms the choice."
|
|
],
|
|
"line": "keep the lock-step command exchange running while the player types"
|
|
},
|
|
"801D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the selected item"
|
|
},
|
|
"8020": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "only slots 0-9 have a name to type"
|
|
},
|
|
"8022": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "(MORE)/(EXIT): skip the text field"
|
|
},
|
|
"8024": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "Y = current cursor position in the name buffer"
|
|
},
|
|
"8027": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "A = 16 = maximum length, bit 7 clear = beep instead of scrolling when full"
|
|
},
|
|
"8029": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "let the shared line editor handle one key press"
|
|
},
|
|
"802C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "nothing was accepted this frame"
|
|
},
|
|
"802E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "Y comes back with bit 7 set when RETURN was pressed"
|
|
},
|
|
"802F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "an ordinary character: echo the line"
|
|
},
|
|
"8031": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "RETURN accepts the entry just like the fire button"
|
|
},
|
|
"8034": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "remember the new cursor position"
|
|
},
|
|
"8037": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "colour $01 = the highlighted row ..."
|
|
},
|
|
"8039": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... but $92C5 tells which half of the blink we are in"
|
|
},
|
|
"803C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "row currently highlighted: keep $01"
|
|
},
|
|
"803E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$61 = the un-highlighted colour ($01 EOR the $60 mask)"
|
|
},
|
|
"8040": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the colour the text engine writes for each cell"
|
|
},
|
|
"8042": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "back to ..."
|
|
},
|
|
"8044": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... column 0 of the name field (screen column 11)"
|
|
},
|
|
"8046": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "recompute the bitmap and colour pointers for that cell"
|
|
},
|
|
"8049": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "erase the rest of the row"
|
|
},
|
|
"804C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$A0 = space"
|
|
},
|
|
"804E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one blank column in front of the name"
|
|
},
|
|
"8051": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the typed-name buffer $9278 ..."
|
|
},
|
|
"8053": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... low/high"
|
|
},
|
|
"8055": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "print what has been typed so far"
|
|
},
|
|
"8058": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the cell the cursor now sits in"
|
|
},
|
|
"805A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$11 = both colour nibbles white = a solid block"
|
|
},
|
|
"805C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "draw the block cursor behind the text"
|
|
},
|
|
"805E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "blink timer, counted down by the IRQ"
|
|
},
|
|
"8060": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "not time yet"
|
|
},
|
|
"8062": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$60 = the EOR mask ..."
|
|
},
|
|
"8064": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... used as the toggle colour"
|
|
},
|
|
"8066": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "flip the row between $01 and $61 and restart the 20-frame timer"
|
|
},
|
|
"8069": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the joystick direction latched by the IRQ (active low)"
|
|
},
|
|
"806B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0F = centred"
|
|
},
|
|
"806D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the stick is being pushed: do not test fire"
|
|
},
|
|
"806F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "edge-detect a new fire-button press"
|
|
},
|
|
"8072": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "fire pressed: accept the entry"
|
|
},
|
|
"8074": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "auto-repeat delay still running?"
|
|
},
|
|
"8076": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "yes: ignore the stick this frame"
|
|
},
|
|
"8078": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the joystick nibble again"
|
|
},
|
|
"807A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "mask the left/right bits out, only up and down move the bar"
|
|
},
|
|
"807C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "-1 = move up"
|
|
},
|
|
"807E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0E = up (bit 0 low)"
|
|
},
|
|
"8080": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "move up"
|
|
},
|
|
"8082": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "+1 = move down"
|
|
},
|
|
"8084": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$0D = down (bit 1 low)"
|
|
},
|
|
"8086": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "neither: nothing to do"
|
|
},
|
|
"8088": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "A = the step, -1 or +1"
|
|
},
|
|
"8089": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "self-modifying: the direction becomes the operand of the LDY #$FF at $809F"
|
|
},
|
|
"808C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "prepare the add"
|
|
},
|
|
"808D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "new selection = old selection + step"
|
|
},
|
|
"8090": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start the auto-repeat delay (16 frames first, then 6)"
|
|
},
|
|
"8093": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "past the last item?"
|
|
},
|
|
"8096": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no: take the new selection"
|
|
},
|
|
"8098": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "out of range: leave the bar where it is"
|
|
},
|
|
"809B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "operand patched at $7FE5: the row in front of the last one"
|
|
},
|
|
"809D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "an ordinary row: take it"
|
|
},
|
|
"809F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "operand patched at $8089: the direction we are moving in"
|
|
},
|
|
"80A1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "moving up: no extra delay"
|
|
},
|
|
"80A3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "moving down into the last-but-one row: pause ..."
|
|
},
|
|
"80A5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... 30 frames, so the bar does not run into (MORE)/(EXIT) by accident"
|
|
},
|
|
"80A7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "hold the new selection"
|
|
},
|
|
"80A8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$61 = the un-highlighted colour"
|
|
},
|
|
"80AA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "redraw the row we are leaving (this also wipes the typed text)"
|
|
},
|
|
"80AD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the new selection"
|
|
},
|
|
"80AE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "make it current"
|
|
},
|
|
"80B1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "sound 2 ..."
|
|
},
|
|
"80B3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the menu click"
|
|
},
|
|
"80B6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start again with an empty name field on the new row"
|
|
},
|
|
"80B9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"block": [
|
|
"The choice has been accepted with fire or RETURN: turn the page, leave, or write the film into",
|
|
"the selected slot."
|
|
],
|
|
"line": "8 frames ..."
|
|
},
|
|
"80BB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... so the button press is not seen twice"
|
|
},
|
|
"80BE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the accepted item"
|
|
},
|
|
"80C1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "items 0-9 are film slots"
|
|
},
|
|
"80C3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "save into that slot"
|
|
},
|
|
"80C5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 11 is always (EXIT)"
|
|
},
|
|
"80C7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "0 = game disk: item 10 is (EXIT) too"
|
|
},
|
|
"80CA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "leave the menu"
|
|
},
|
|
"80CC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "(MORE): turn to the next page ..."
|
|
},
|
|
"80CF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... and run the selector again"
|
|
},
|
|
"80D2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "how many characters were typed?"
|
|
},
|
|
"80D5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "nothing typed: keep the old name"
|
|
},
|
|
"80D7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "mask the RETURN bit off (it cannot be set here - defensive)"
|
|
},
|
|
"80D9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_18 = length of the typed name"
|
|
},
|
|
"80DB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start at the last byte of the 16-byte entry"
|
|
},
|
|
"80DD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$A0 = space"
|
|
},
|
|
"80DF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "always taken - enter the loop at the test"
|
|
},
|
|
"80E1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "pad this position with a space"
|
|
},
|
|
"80E3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next lower position"
|
|
},
|
|
"80E4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "pad everything from the end down to the typed length"
|
|
},
|
|
"80E6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep padding"
|
|
},
|
|
"80E8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "Y = length - 1"
|
|
},
|
|
"80E9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "nothing typed at all"
|
|
},
|
|
"80EB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "a character of the typed name"
|
|
},
|
|
"80EE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "into the directory entry"
|
|
},
|
|
"80F0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next lower character"
|
|
},
|
|
"80F1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "copy the whole name"
|
|
},
|
|
"80F3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the last byte of the entry ..."
|
|
},
|
|
"80F5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... gets ..."
|
|
},
|
|
"80F7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... bit 7 set: that is the string terminator"
|
|
},
|
|
"80F9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "store it back"
|
|
},
|
|
"80FB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "colour $01 = highlighted"
|
|
},
|
|
"80FD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "redraw the row from the directory entry, so the saved name is shown"
|
|
},
|
|
"8100": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "write the directory and the 16 sectors of the film to disk"
|
|
},
|
|
"8103": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "clear ..."
|
|
},
|
|
"8105": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the typed length"
|
|
},
|
|
"8108": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "Y = the selection ($91D5, which filmSlotToTrack has replaced with the track)"
|
|
},
|
|
"810B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "back to the main menu"
|
|
},
|
|
"810C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"printFilmSlotEntry - redraws the currently selected row of the film menu in colour A: moves the",
|
|
"cursor to menuFirstRow + menuSelectedItem, column 0 of the name window (screen column 11),",
|
|
"clears the rest of the line and prints a space followed by the entry text - the 16-byte name",
|
|
"at zp_4A/zp_4B for slots 0-9, ' (MORE)' for item 10 on a data disk, ' (EXIT)' otherwise.",
|
|
"The slot number printed by drawFilmDirectoryPage sits in columns 9-10 and is left alone.",
|
|
"In: A = colour byte, menuSelectedItem $91D5, menuFirstRow $91D6, diskIdIndex $92F0, zp_4A/zp_4B",
|
|
"Out: one menu row redrawn; zp_3D = A, zp_3F = 0",
|
|
"Called from: $8012, $80AA and $80FD (all in runSaveFilmMenu)"
|
|
],
|
|
"line": "the colour the text engine writes for each cell ($01 highlighted, $61 normal)"
|
|
},
|
|
"810E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the selected item"
|
|
},
|
|
"8111": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "clear carry for the add"
|
|
},
|
|
"8112": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "+ the first menu row = the screen row of this entry"
|
|
},
|
|
"8115": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "column 0 ..."
|
|
},
|
|
"8117": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... of the name window (screen column 11)"
|
|
},
|
|
"8119": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "move the cursor there and recompute the cell pointers"
|
|
},
|
|
"811C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "erase the old contents of the row"
|
|
},
|
|
"811F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$A0 = space"
|
|
},
|
|
"8121": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one blank column in front of the name"
|
|
},
|
|
"8124": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "' (EXIT)' at $CAB2 ..."
|
|
},
|
|
"8126": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the default text for the last item"
|
|
},
|
|
"8128": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the selected item"
|
|
},
|
|
"812B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "items 0-9 are film slots"
|
|
},
|
|
"812D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "print the name of the entry"
|
|
},
|
|
"812F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "item 11 is always (EXIT)"
|
|
},
|
|
"8131": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "0 = game disk"
|
|
},
|
|
"8134": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "on the game disk item 10 is (EXIT) as well"
|
|
},
|
|
"8136": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "' (MORE)' at $EF81 ..."
|
|
},
|
|
"8138": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... in the comm-module tail"
|
|
},
|
|
"813A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "always taken"
|
|
},
|
|
"813C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "pointer to the 16-byte directory entry ..."
|
|
},
|
|
"813E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... low/high"
|
|
},
|
|
"8140": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "print it and return through printString"
|
|
},
|
|
"8143": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"filmSlotToTrack - turns the selected directory slot into the disk track its film occupies:",
|
|
"page * 10 + item + 2, plus one more when the result would be the directory track 18. Slots",
|
|
"0-29 therefore live on tracks 2-17 and 19-32, sixteen sectors each. The track replaces",
|
|
"menuSelectedItem $91D5 and is also returned in A.",
|
|
"In: filmDirectoryPage $7FA1, menuSelectedItem $91D5",
|
|
"Out: A = $91D5 = track number 2-32",
|
|
"Called from: $7F5A (load) and $8161 (save)"
|
|
],
|
|
"line": "the page the slot is on"
|
|
},
|
|
"8146": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "page 0: no offset"
|
|
},
|
|
"8148": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "ten slots ..."
|
|
},
|
|
"814A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... per page; A comes back holding the low byte of page * 10"
|
|
},
|
|
"814D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "add ..."
|
|
},
|
|
"814E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the item number 0-9 ..."
|
|
},
|
|
"8151": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... and 2, because tracks 0 and 1 are not used for films"
|
|
},
|
|
"8153": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$12 = 18 = the directory track"
|
|
},
|
|
"8155": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "below it: use the track as it is"
|
|
},
|
|
"8157": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "at or above track 18 ..."
|
|
},
|
|
"8158": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... skip the directory track"
|
|
},
|
|
"815A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the selection now holds the track number"
|
|
},
|
|
"815D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "A = the track"
|
|
},
|
|
"815E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"saveFilmToSlot - writes the film in the buffer under I/O to the disk: rewrites the directory",
|
|
"(with the new name in it) and then copies the 16 pages of $D000-$DFFF one at a time into the",
|
|
"$0200 sector buffer and writes each as one sector 0-15 of the film's track.",
|
|
"In: menuSelectedItem $91D5 = slot, the film at $D000-$DFFF, the directory at $0300",
|
|
"Out: track sectors 0-15 written, $91D5 = the track used, zp_18/zp_19, the copy pointers",
|
|
" $58C3/$58C4 (source) and $58C6/$58C7 (destination)",
|
|
"Called from: $8100 (runSaveFilmMenu)"
|
|
],
|
|
"line": "pause the comm module for the disk access"
|
|
},
|
|
"8161": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "slot -> track number"
|
|
},
|
|
"8164": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "write the 2 directory sectors first, so the name is on disk even if the film write fails"
|
|
},
|
|
"8167": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "copyPageUnderIo source low byte = $00 ..."
|
|
},
|
|
"8169": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... (operand of the LDA at $58C2)"
|
|
},
|
|
"816C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $D0: the film buffer under I/O"
|
|
},
|
|
"816E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the source page walks $D000..$DF00"
|
|
},
|
|
"8171": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "copyPageUnderIo destination low byte = $00 ..."
|
|
},
|
|
"8173": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... (operand of the STA at $58C5)"
|
|
},
|
|
"8176": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $02: the sector buffer"
|
|
},
|
|
"8178": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the destination stays at $0200"
|
|
},
|
|
"817B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "start with ..."
|
|
},
|
|
"817D": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... sector 0 in zp_18"
|
|
},
|
|
"817F": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the track filmSlotToTrack worked out"
|
|
},
|
|
"8182": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "zp_19 = the track to write"
|
|
},
|
|
"8184": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "copy one page of the film into $0200 with the I/O area banked out"
|
|
},
|
|
"8187": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "source low byte $00 ..."
|
|
},
|
|
"8189": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... high byte $02: write from $0200"
|
|
},
|
|
"818B": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "tell the fast loader where the data is"
|
|
},
|
|
"818E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the film's track ..."
|
|
},
|
|
"8190": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... and the current sector number"
|
|
},
|
|
"8192": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "one sector at a time"
|
|
},
|
|
"8194": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the drive encrypts and writes it"
|
|
},
|
|
"8197": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next source page ($D000, $D100, ...)"
|
|
},
|
|
"819A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next sector"
|
|
},
|
|
"819C": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "sector counter"
|
|
},
|
|
"819E": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "16 sectors = the whole 4 KB film"
|
|
},
|
|
"81A0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep writing"
|
|
},
|
|
"81A2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "restart the comm module and clear the status line"
|
|
},
|
|
"81A5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"promptInsertGameDisk - end of the save/load film flow: shows 'INSERT GAME DISK AND PRESS",
|
|
"SPACE.', then makes sure the 'OZ' disk really is in the drive and restarts the comm module.",
|
|
"In: -",
|
|
"Out: the game disk is in the drive, the comm module runs again",
|
|
"Called from: $7E21 and $7E27 (JMP, after the save and load menus)"
|
|
],
|
|
"line": "low byte of 'GAME' at $EFD4 ..."
|
|
},
|
|
"81A7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... in the comm-module tail"
|
|
},
|
|
"81A9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "patch it into the message and wait for space"
|
|
},
|
|
"81AC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep asking until checkDiskId finds the 'OZ' disk"
|
|
},
|
|
"81AF": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "restart the comm module and clear the status line"
|
|
},
|
|
"81B2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"promptInsertDataDisk - entry of promptInsertDiskAndWaitSpace with the word 'DATA' ($EFD0).",
|
|
"In: -",
|
|
"Out: see promptInsertDiskAndWaitSpace",
|
|
"Called from: $7DF4 (handleMainMenuChoice)"
|
|
],
|
|
"line": "low byte of 'DATA' at $EFD0 ..."
|
|
},
|
|
"81B4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... in the comm-module tail; fall through"
|
|
},
|
|
"81B6": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"promptInsertDiskAndWaitSpace - shows 'INSERT xxxx DISK AND PRESS SPACE.' and waits for the",
|
|
"space bar. The four characters at $EFB6 inside the message template at $EFAF are overwritten",
|
|
"with the word passed in A/Y ('DATA' or 'GAME'), the template is installed as message slot $1E",
|
|
"and shown as the persistent status message; the link keeps being serviced while waiting.",
|
|
"In: A/Y = address of a 4-character disk name ($EFD0 'DATA' or $EFD4 'GAME')",
|
|
"Out: $EFB6-$EFB9 patched, message slot $1E = $EFAF, $92A1, lastTypedKey $9248 = $FF, the",
|
|
" message line erased; self-modifies the operand of the LDA at $81C7",
|
|
"Called from: $81A9 (promptInsertGameDisk) and by fall-through from promptInsertDataDisk"
|
|
],
|
|
"line": "self-modifying: the word's low byte becomes the operand of the LDA at $81C7 ..."
|
|
},
|
|
"81B9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... and its high byte the second operand byte"
|
|
},
|
|
"81BC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "message slot $1E is the free 'dynamic' slot"
|
|
},
|
|
"81BE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "'INSERT DATA DISK AND PRESS SPACE.' at $EFAF ..."
|
|
},
|
|
"81C0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... in the comm-module tail"
|
|
},
|
|
"81C2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "install that string as message $1E"
|
|
},
|
|
"81C5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "four characters to patch"
|
|
},
|
|
"81C7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "operand patched at $81B6/$81B9: reads 'DATA' or 'GAME' (assembled as an LDA $FFFF,y)"
|
|
},
|
|
"81CA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "overwrite the word inside the message template"
|
|
},
|
|
"81CD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "next character"
|
|
},
|
|
"81CE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "all four"
|
|
},
|
|
"81D0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "message $1E ..."
|
|
},
|
|
"81D2": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... becomes the persistent status message"
|
|
},
|
|
"81D5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "put it on the status line"
|
|
},
|
|
"81D8": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$FF = no key pending"
|
|
},
|
|
"81DA": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "forget the last key"
|
|
},
|
|
"81DD": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep the link alive while the player swaps disks"
|
|
},
|
|
"81E0": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the last key the IRQ saw"
|
|
},
|
|
"81E3": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "$A0 = the space bar"
|
|
},
|
|
"81E5": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep waiting"
|
|
},
|
|
"81E7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "sound 2 ..."
|
|
},
|
|
"81E9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... the acknowledging click"
|
|
},
|
|
"81EC": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "no persistent message ..."
|
|
},
|
|
"81EE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... any more"
|
|
},
|
|
"81F1": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "erase the message line and return"
|
|
},
|
|
"81F4": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"checkFilmInMemory - is the buffer under I/O at $D000 a valid game film? verifyFilmHeader",
|
|
"recomputes the header checksum, compares it with header byte $33 and checks the version byte",
|
|
"$2F against $0B94. A valid film returns C=0 (and leaves zp_BC/zp_BD = $D000 for the readers",
|
|
"that follow); otherwise message 9 'NOT A GAME FILM!' is shown for about four seconds and C=1",
|
|
"comes back.",
|
|
"In: the film header at $D000",
|
|
"Out: C=0 and A = header byte 4 when valid, C=1 otherwise; zp_BC/zp_BD = $D000",
|
|
"Called from: $7DEF, $7E2F (main menu) and $7F98 (after loading a film)"
|
|
],
|
|
"line": "check the header checksum and version byte"
|
|
},
|
|
"81F7": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "C=0: it is a film"
|
|
},
|
|
"81F9": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "message 9 = 'NOT A GAME FILM!'"
|
|
},
|
|
"81FB": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "queue it, then fall into the four-second wait"
|
|
},
|
|
"81FE": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"routine": [
|
|
"waitFramesServicingComm - waits about four seconds (240 IRQ frames counted down in zp_6C)",
|
|
"while still servicing the command exchange, then returns C=1. In this overlay it is only ever",
|
|
"reached by falling out of checkFilmInMemory, so that the 'NOT A GAME FILM!' message stays",
|
|
"readable before the caller carries on. (The main program's call at $563C is to the drone",
|
|
"routine that the comcen-screens overlay has at this same address, not to this code.)",
|
|
"In: -",
|
|
"Out: C=1, joyRepeatTimer zp_6C = 0",
|
|
"Called from: fall-through from $81FB"
|
|
],
|
|
"line": "$F0 = 240 frames ..."
|
|
},
|
|
"8200": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "... about four seconds in one of the IRQ's frame countdowns"
|
|
},
|
|
"8202": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "keep the link alive while the message is on screen"
|
|
},
|
|
"8205": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "the IRQ counts the timer down"
|
|
},
|
|
"8207": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "wait until it reaches zero"
|
|
},
|
|
"8209": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "C=1 = 'no usable film'"
|
|
},
|
|
"820A": {
|
|
"unit": "game/mapGenerator6F00",
|
|
"line": "shared RTS: also the C=0 exit of checkFilmInMemory"
|
|
}
|
|
},
|
|
"dataTypes": {
|
|
"7C29": [
|
|
"byte",
|
|
5
|
|
],
|
|
"7FA1": [
|
|
"byte",
|
|
1
|
|
],
|
|
"7FA2": [
|
|
"byte",
|
|
1
|
|
],
|
|
"7FA3": [
|
|
"byte",
|
|
3
|
|
]
|
|
},
|
|
"zpComments": {}
|
|
} |