454 lines
23 KiB
JSON
454 lines
23 KiB
JSON
{
|
|
"chunk": "game_unitStartTemplatesF000_F000",
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"unitLabels": {
|
|
"game/unitStartTemplatesF000": {
|
|
"F064": "template0StartRow",
|
|
"F0C8": "template0StartFlags",
|
|
"F12C": "template0StartType",
|
|
"F1F4": "template1StartRow",
|
|
"F258": "template1StartFlags",
|
|
"F2BC": "template1StartType",
|
|
"F384": "template2StartRow",
|
|
"F3E8": "template2StartFlags",
|
|
"F44C": "template2StartType",
|
|
"F514": "template3StartRow",
|
|
"F578": "template3StartFlags",
|
|
"F5DC": "template3StartType"
|
|
}
|
|
},
|
|
"notes": {
|
|
"F000": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"unitStartTemplatesF000 - the whole file. Track 18 sectors 8-14 hold pure data: four 400-byte unit start-position templates at $F000, $F190, $F320 and $F4B0, followed by 192 bytes at $F640-$F6FF that are not data at all but a fragment of an older build's code (see the note there). Nothing in this file is a battlefield: the 40x40 map that occupies $F000-$F63F at run time is built from the 24-bit map seed by generateBattlefieldMap ($6F04) and overwrites all four templates before the first frame.",
|
|
"Loaded by loadMapAndSetup ($10AB): setLoadDest $F000, then 7 sectors from track 18 sector 8, once per session from startGameFromSetup ($0B35).",
|
|
"Read by exactly one routine, loadUnitStartTemplate ($ECF3, in the comm tail that track 34 sectors 12-15 put at $EC00), which overlay A calls at $79E6 and $82FD: n = unitLayoutByGameType[$78B8 + (gameTypeOptions $0BA3 & 7)] = 2,2,2,1,3,0,0 for game types 0-6, and it then copies two whole pages (512 bytes) from $F000 + 400*n to $F640, where the live unit records begin. Only the first 400 bytes are the template; the extra 112 bytes overwrite unitDestCol ($F7D0-$F833) and the first twelve entries of unitDestRow ($F834-$F83F), which initAllUnits rewrites at once, so the spill is harmless. For templates 0-2 the spill is the head of the next template; for template 3 the source ($F4B0-$F6AF) overlaps the destination ($F640-$F83F) and, because the copy runs upwards, it re-reads what it has just written and duplicates template 3's own first 112 bytes - which is also why the leftover code at $F640-$F6AF is destroyed before it could ever be read as data.",
|
|
"The copy is guarded by 'bit 7 of $F640 set' = 'the arrays still hold the disk image'. As loaded from disk $F640 is $0A (an opcode of the leftover code), which fails that test, so startGameSession stores $FF there first ($78E4).",
|
|
"Game type -> template: 0 SCRIMAGE, 1 QB SNEAK, 2 THE BOMB -> template 2; 3 FACE-OFF -> template 1; 4 SLUGGERS -> template 3; 5 FULL WAR, 6 DEFENDER -> template 0. (There is no game type 7; it would index $78BF = $04 and copy from $F000 + 1600 = $F640.)",
|
|
"Each template is four parallel 100-entry arrays - +$000 starting column, +$064 starting row, +$0C8 flags, +$12C type - i.e. exactly the first four of the fourteen 100-byte unit-record arrays that live from $F640 upwards $64 apart. Entry i describes unit i: 0-49 side 0, 50-99 side 1, 49 and 99 the two COMCENs. Coordinates are cells of the 40x40 field: columns 3-36, side 0 in the bottom half (rows 20-33), side 1 in the top half (rows 6-19). Player 1's machine rotates the map and every unit coordinate to 39-x (rotateMapAndMirrorCodes $EC58, mirrorAllUnitCoordinates $EC91), so both players see their own army at the bottom.",
|
|
"How much of a template survives the copy: initAllUnits ($3D8A) -> initUnitRecord ($3DA0) keeps the column, the row, flags bits 2-4 (group id) and bit 6 (belongs to a group), and type bits 0-2 (the unit type) plus bit 7 ($FF = empty slot). It rebuilds the facing (flags bits 0-1) and the side (flags bit 5) from the unit index and clears type bits 3-4, so those bits of the stored data are consistent with the rest but are never actually used.",
|
|
"unitStartTemplate0 ($F000-$F18F) - the full roster, used by game types 5 FULL WAR and 6 DEFENDER. All 100 slots are in play: per side 28 GRUNT (units 0-27), 12 RIDER (28-39), 6 BOOMER (40-45), 3 SPY (46-48) and 1 COMCEN (49). Three wings, each an eleven-unit group of nine grunts and two boomers in rows 25-28 with a four-rider group in front of it in rows 30-31. Side 0: group 3 DELTA = units 4,7,10,11,14,15,18,19,20,40,44 on the left (columns 3-7), group 4 EASY = 1,2,3,13,16,17,22,23,27,41,45 in the centre (17-21), group 5 FOXTROT = 0,5,8,9,12,21,24,25,26,42,43 on the right (32-36); rider group 0 ALPHA = 28,29,30,32 (columns 5-6), 1 BAKER = 31,33,34,37 (19-20), 2 CHARLIE = 35,36,38,39 (33-34). Loose (flags $00): the three spies 46-48 in row 23, and in the back row 33 the COMCEN 49 at column 20 with one GRUNT, unit 6, beside it at column 19. Side 1 is the exact 180-degree mirror of side 0 as a formation - every (column,row,type,group) of side 0 occurs on side 1 as (39-column, 39-row, same type, same group) - but the indices within a group are not mirrored, so unit i+50 is not the mirror image of unit i."
|
|
],
|
|
"line": "unitCol[0-49]: side 0's starting map column, ten units per row; the last entry is the COMCEN"
|
|
},
|
|
"F032": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitCol[50-99]: side 1's columns; the last entry is unit 99, side 1's COMCEN"
|
|
},
|
|
"F064": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"unitRow - array 2 of 4 ($F064-$F0C7): the starting map row 0-39 of each unit, copied to unitRowTable $F6A4. Side 0 occupies rows 23-33 in this template and side 1 the mirrored rows 6-16."
|
|
],
|
|
"line": "unitRow[0-49]: side 0's rows, the bottom half of the field"
|
|
},
|
|
"F096": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitRow[50-99]: side 1's rows, the 39-row mirror of side 0's"
|
|
},
|
|
"F0C8": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"unitFlags - array 3 of 4 ($F0C8-$F12B): bits 0-1 facing (0 = up, 1 = down), bits 2-4 group id 0-6 = ALPHA, BAKER, CHARLIE, DELTA, EASY, FOXTROT, GROVER (names at $C92C), bit 5 side, bit 6 = belongs to a group, bit 7 (the blitz charge at run time) always 0 here. So a side-0 entry is $00 when loose and $40 + 4*g in group g; a side-1 entry is $21 when loose and $61 + 4*g in group g. Copied to unitFlagsTable $F708; initUnitRecord ($3DC6) keeps only bits 2-4 and 6 and rebuilds facing and side from the unit index, so the group id and the group-member bit are the only part that matters."
|
|
],
|
|
"line": "unitFlags[0-49]: side 0 - $00 loose, $40/$44/$48/$4C/$50/$54 = groups ALPHA..FOXTROT"
|
|
},
|
|
"F0FA": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitFlags[50-99]: side 1 - $21 loose, $61/$65/$69/$6D/$71/$75 = the same six groups"
|
|
},
|
|
"F12C": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"unitType - array 4 of 4 ($F12C-$F18F): $10 + type for a side-0 unit and $18 + type for a side-1 unit, type 0 GRUNT, 1 RIDER, 2 BOOMER, 3 SPY, 4 COMCEN (names at $C964); $FF marks a slot that is not in play. Copied to unitTypeTable $F76C. At run time bits 3-4 of this byte are the 'has already scored that end zone' markers and bit 6 is 'dug in', but initUnitRecord ($3DB9) clears bits 3-4 while it resets each unit, so of the stored value only bits 0-2 and the $FF (bit 7 = destroyed/empty, tested by placeUnitOnMap at $3E11) ever reach the engine."
|
|
],
|
|
"line": "unitType[0-49]: side 0 - $10 GRUNT, $11 RIDER, $12 BOOMER, $13 SPY, $14 COMCEN; 28/12/6/3/1"
|
|
},
|
|
"F15E": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitType[50-99]: side 1 - $18 GRUNT .. $1C COMCEN; the same roster as side 0"
|
|
},
|
|
"F190": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"unitStartTemplate1 ($F190-$F31F) - used by game type 3 FACE-OFF only. Roster per side: 28 RIDER (units 0-27), 3 SPY (46-48), 1 COMCEN (49); slots 28-45 are empty ($FF in the type array). The riders form seven 2x2 squads, one per group name, drawn up in a single line: side 0 groups 0 ALPHA .. 6 GROVER occupy rows 22-23 at columns 22-23, 19-20, 16-17, 13-14, 10-11, 7-8 and 4-5, with the three spies in row 21 at columns 5, 14 and 23 and the COMCEN at (14,25). Side 1 is the exact per-index 180-degree mirror: unit i+50 stands at (39-column, 39-row) of unit i and carries the same type and the same group id.",
|
|
"The 18 empty slots on each side still carry column and row bytes, which are dead data - they are verbatim runs of template 0: entries 28-45 repeat template 0's entries 7-24 and entries 78-95 repeat template 0's entries 57-74, in both the column and the row array. Their flag bytes were cleaned to $00 / $21. Only the $FF in the type array is read."
|
|
],
|
|
"line": "unitCol[0-49] of template 1: entries 28-45 are dead slots, entry 49 the COMCEN"
|
|
},
|
|
"F1C2": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitCol[50-99]: side 1's columns; entries 78-95 dead, entry 99 the COMCEN"
|
|
},
|
|
"F1F4": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitRow[0-49] (see $F064): rider line rows 22-23, spies row 21, COMCEN row 25"
|
|
},
|
|
"F226": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitRow[50-99]: side 1 - rider line 16-17, spies 18, COMCEN 14"
|
|
},
|
|
"F258": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitFlags[0-49] (see $F0C8): seven side-0 squads of four, $40 ALPHA .. $58 GROVER"
|
|
},
|
|
"F28A": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitFlags[50-99]: the same seven squads on side 1, $61 ALPHA .. $79 GROVER"
|
|
},
|
|
"F2BC": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitType[0-49] (see $F12C): 28 x $11 RIDER, 18 x $FF, 3 x $13 SPY, $14 COMCEN"
|
|
},
|
|
"F2EE": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitType[50-78]: side 1's 28 riders ($19) and the first empty slot"
|
|
},
|
|
"F30B": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"Template 1's unitType[79-99]: the rest of the empty slots, then the three SPYs ($1B) and the COMCEN ($1C) of side 1. The label here has nothing to do with the template - it is the RUN-TIME meaning of the address: map cell (19,19) = $F000 + 40*19 + 19, which the map generator writes at $6F86 ($55, a river bend) when a point-symmetric map needs its two river halves joined at the centre."
|
|
],
|
|
"line": "unitType[79-95] $FF empty, [96-98] $1B SPY, [99] $1C COMCEN"
|
|
},
|
|
"F320": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"unitStartTemplate2 ($F320-$F4AF) - used by game types 0 SCRIMAGE, 1 QB SNEAK and 2 THE BOMB. Eleven units a side and no groups at all (flags $00 / $21 throughout). It is a football formation: units 0-6 are the line of scrimmage in row 21 - a RIDER split out at column 7, GRUNTs at 14, 17, 20, 23 and 26, a RIDER split out at column 33 - unit 7 is the RIDER 'quarterback' at (20,23), units 8 and 9 the two RIDER backs at (18,25) and (22,25), and unit 49 the COMCEN at (20,25). Slots 10-48 are empty ($FF).",
|
|
"Side 1 is the same formation reflected in the rows (side-1 row = 39 - side-0 row) but its columns are 40 - column instead of 39 - column, so on player 1's mirrored display side 1's line sits one cell to the left of side 0's; both COMCENs are stored at column 20.",
|
|
"applyGameTypeDefaults ($7C85, in the map generator overlay) trims this roster once it has been copied: QB SNEAK deletes units 0-6, leaving only the quarterback, the two backs and the COMCEN, and THE BOMB deletes units 0-98 and puts unit 49 back as a COMCEN, so that game is fought by the two command centres and one extra drone each.",
|
|
"The 39 empty slots a side are dead data: their column and row bytes are template 0's own entries at the same index, so this template was edited from a copy of template 0. The two exceptions are slots 10 (33,20) and 60 (27,19), which are not template-0 values - the formation evidently had a twelfth unit a side at some point."
|
|
],
|
|
"line": "unitCol[0-18]: the line of scrimmage (7,14,17,20,23,26,33), the quarterback and the two backs"
|
|
},
|
|
"F333": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"Template 2's unitCol[19] - part of an empty slot, dead data. The label is the RUN-TIME meaning of the address: map cell (19,20) = $F000 + 40*20 + 19, written with $58 by the map generator at $6F81."
|
|
],
|
|
"line": "unitCol[19] = $06, unused"
|
|
},
|
|
"F334": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"Template 2's unitCol[20-49], all of them empty slots except the COMCEN at the end. The label is again the run-time meaning: map cell (20,20), cleared to $40 at $6F8B so that the two halves of a mirrored river join cleanly."
|
|
],
|
|
"line": "unitCol[20] = $05, unused; entries 20-48 dead, entry 49 the COMCEN at column 20"
|
|
},
|
|
"F352": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitCol[50-99]: side 1's line at 33,26,23,20,17,14,7, quarterback 57, backs 58/59, COMCEN 99"
|
|
},
|
|
"F384": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitRow[0-49] (see $F064): row 21 the line, 23 the quarterback, 25 the backs and the COMCEN"
|
|
},
|
|
"F3B6": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitRow[50-99]: side 1's mirror - row 18 the line, 16 the quarterback, 14 the backs/COMCEN"
|
|
},
|
|
"F3E8": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitFlags[0-49]: $00 for every side-0 unit - nothing is in a group in these game types"
|
|
},
|
|
"F41A": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitFlags[50-99]: $21 for every side-1 unit (bit 5 side, bit 0 facing down), no groups"
|
|
},
|
|
"F44C": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitType[0-49] (see $F12C): $11, five $10, four $11, then $FF to unit 48 and $14 COMCEN"
|
|
},
|
|
"F47E": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitType[50-99]: the same eleven units on side 1 ($19 RIDER, $18 GRUNT, $1C COMCEN)"
|
|
},
|
|
"F4B0": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"unitStartTemplate3 ($F4B0-$F63F) - used by game type 4 SLUGGERS. Roster per side: 12 GRUNT (units 0-11), 12 RIDER (12-23), 4 BOOMER (24-27), 3 SPY (46-48) and 1 COMCEN (49); slots 28-45 are empty. Every combat unit is in a 2x2 squad of four, one squad per group name: side 0 has the grunt squads 0 ALPHA at columns 19-20 rows 26-27, 1 BAKER at 17-18 rows 27-28 and 2 CHARLIE at 21-22 rows 27-28 packed around the COMCEN at (20,30); the rider squads 3 DELTA at columns 9-10, 4 EASY at 19-20 and 5 FOXTROT at 29-30, all in rows 23-24; and the boomer squad 6 GROVER at 19-20 rows 28-29. The three spies stand loose in row 22 at columns 9, 20 and 30. Side 1 is the exact per-index 180-degree mirror (unit i+50 = (39-column, 39-row) of unit i, same type, same group).",
|
|
"As in template 1 the 18 empty slots a side keep dead column and row bytes copied from template 0 (entries 28-45 = template 0's 7-24, entries 78-95 = template 0's 57-74); only their $FF type matters. This is also the one template whose 512-byte copy reads past its own end, into $F640-$F6AF - see the note there."
|
|
],
|
|
"line": "unitCol[0-49] of template 3: three grunt squads, three rider squads, a boomer squad, then dead slots"
|
|
},
|
|
"F4E2": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitCol[50-99]: side 1's columns, the 39-column mirror of side 0's"
|
|
},
|
|
"F514": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitRow[0-49] (see $F064): riders 23-24, grunts 26-28, boomers 28-29, spies 22, COMCEN 30"
|
|
},
|
|
"F546": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitRow[50-99]: side 1's rows 9-17, the mirror of side 0's"
|
|
},
|
|
"F578": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitFlags[0-49] (see $F0C8): seven side-0 squads of four, $40 ALPHA .. $58 GROVER"
|
|
},
|
|
"F5AA": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitFlags[50-99]: the same seven squads on side 1, $61 ALPHA .. $79 GROVER"
|
|
},
|
|
"F5DC": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitType[0-35] (see $F12C): 12 x $10 GRUNT, 12 x $11 RIDER, 4 x $12 BOOMER, then $FF"
|
|
},
|
|
"F600": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"Template 3's unitType[36-49]: the last empty slots, the three SPYs ($13) and the COMCEN ($14) of side 0. The label is the RUN-TIME meaning of the address: $F600 is where the 40x40 map's last 64 cells begin (cells 1536-1599), the tail that clearMapMarkers walks separately at $7536/$7541 after its six full pages."
|
|
],
|
|
"line": "unitType[36-45] $FF empty, [46-48] $13 SPY, [49] $14 COMCEN"
|
|
},
|
|
"F60E": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "unitType[50-99]: 12 x $18, 12 x $19, 4 x $1A, 18 x $FF, 3 x $1B and $1C - side 1's roster"
|
|
},
|
|
"F640": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"block": [
|
|
"$F640-$F6FF - 192 bytes that belong to no template and that the game never uses. They are a fragment of 6502 code from an OLDER build of the game, left in the mastering machine's memory when this block was written to the disk; the loader reads all seven sectors, so it comes along for the ride.",
|
|
"Nothing ever reads it as data: the only reader of this file, loadUnitStartTemplate ($ECF3), copies at most $F4B0-$F6AF (template 3), and because that copy writes 400 bytes ahead of its own read pointer it has already replaced $F640-$F6AF with template 3's data before it gets there. The one byte that IS read is $F640 itself, as the 'the arrays still hold the disk image' flag - and it holds $0A, bit 7 clear, which would mean 'already loaded', so startGameSession stores $FF over it first ($78E4).",
|
|
"Once a game starts this area is the live unitCol[0-99] ($F640) and unitRow[0-99] ($F6A4) arrays, which is what the labels below name; the bytes printed under them are the leftover code, not array data, and the labels fall in the middle of its instructions.",
|
|
"Disassembled, the fragment is the tail of one routine plus two complete ones, each with a recognisable counterpart in the shipped build at a different address:",
|
|
" $F640 asl a / sta $3F / lda #$14 / jmp $C097",
|
|
" the tail of setRepairMessageWindow, which in the shipped build ($19E1) ends 'lda #$0A /",
|
|
" sta textCursorCol / lda #$14 / jmp setCursorRow': cursor to row 20, column 2*A.",
|
|
" $F648 lda #$0C sta $3B / lda #$09 sta $39 sta $40 / lda #$12 sta $3C / lda #$00 sta $3F /",
|
|
" jsr $C099 / lda #$61 sta $3D / lda #$B2 ldy #$CA jsr $C133",
|
|
" printOptionsList: text window left column 12, rows 9-18, width 18, colour $61, then the",
|
|
" heading from $CAB2. The shipped printOptionsList ($19F3) is the same code with column 6,",
|
|
" width $1D and the heading at $CB13.",
|
|
" $F668 lda $92CD bne / lda $0881 beq",
|
|
" 'is a game running?' - $92CD is the old build's gameEndCountdown and $0881 its",
|
|
" gameEndReason; the shipped test at $1A13 uses $92C9 and $0BA8.",
|
|
" $F672 lda #$10 ldy #$66 jsr $C133 / jsr $C137 / lda $E03B beq / jsr $C137 / rts",
|
|
" no game: print the main menu from $6610, then LOAD GAME FILM, then DISCONNECT/SET VOICE if",
|
|
" the link flag $E03B is set. Shipped: the same sequence at $1A36 with the text at $CC1F.",
|
|
" $F685 lda #$98 ldy #$66 jsr $C133 / lda $0876 bmi / jsr $C137 / lda #$53 ldy #$CA jmp $C133",
|
|
" a game is running: ABORT GAME from $6698, VOICE PAUSE unless the film-playback flag",
|
|
" $0876 is set, then ' (EXIT)' from $CA53. Shipped ($1A1B): $CCA6, two flag tests, $CAB2.",
|
|
" $F69B lda #$FF sta $924A / lda $0881 bne $F711 / jsr $1648 / ldy #$02 / lda $0876 bmi /",
|
|
" lda $087F bmi / iny / sty $91D5 / dey / sty $91D6 / dec $3B / lda $3B sta $3F /",
|
|
" lda #$0B sta $91D7 / jsr $C097 / jsr $5F41 / ldy $91D6 beq / jsr $1205 / jmp $1648",
|
|
" miscTabAction, the MISC-tab options menu: two items, three in a modem game that is not a",
|
|
" replay, highlight bar from row 11, run the selector, and on '(EXIT)' reprint the list. The",
|
|
" shipped miscTabAction ($1A49) is instruction for instruction the same, with the menu state",
|
|
" one byte lower ($91D4/$91D5/$91D6 instead of $91D5/$91D6/$91D7).",
|
|
" $F6D8 jsr $0CD8 / lda $E03B beq / lda $0877 bmi,beq / lda #$00 sta $73 sta $9164 /",
|
|
" lda $E044 bmi / jsr $C7FF / lda #$8C jsr $5178 / lda #$26 sta $7F / (jsr, cut off)",
|
|
" the ABORT GAME path: if the link is up and a game session is agreed, clear the exchange",
|
|
" throttle, skip the handshake when the opponent module is the trainer ($E044 = the old",
|
|
" build's commBuildId), show 'WORKING...', queue command $8C reason 0, wait $26 ticks.",
|
|
" Shipped: $1A86-$1AAE, with commBuildId $E030, showWorkingMessage $C853, queueCmd2 $561F.",
|
|
"The block ends in the middle of that last JSR: only its $20 opcode fits in the seven sectors.",
|
|
"What dates the fragment to a different build is that every one of its own addresses differs from the shipped equivalent - printOptionsList $1648 vs $19F3, setMenuTextWindow $1205 vs $1575, runInGameOptionsMenu $5F41 vs $65A0, queueCmd2 $5178 vs $561F, showWorkingMessage $C7FF vs $C853, the mode flags $0876/$0877/$087F/$0881 vs $0B9B/$0B9C/$0BA5/$0BA8, the menu text $6610/$6698/$CA53 vs $CC1F/$CCA6/$CAB2, linkPollDelay $9164 vs $9163, commBuildId $E044 vs $E030 - while the low-level text engine entries it calls ($C097 setCursorRow, $C099 updateCursorPointers, $C133 printString, $C137 printStringAtPointer) and the link-active flag $E03B are at exactly the addresses the shipped build uses. So it is the same program a few hundred bytes shorter, before the $0800 and $C000 blocks were rearranged. (Confidence: high that it is leftover code and that these are the matching routines; which build it came from cannot be pinned down further.)"
|
|
]
|
|
},
|
|
"F648": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "the old build's printOptionsList starts here; the shipped one is at $19F3"
|
|
},
|
|
"F685": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "'a game is running' branch: ABORT GAME / VOICE PAUSE / (EXIT)"
|
|
},
|
|
"F69B": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "the old build's miscTabAction starts here; the shipped one is at $1A49"
|
|
},
|
|
"F6D8": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "the ABORT GAME path: tell the opponent with command $8C and hang up (shipped $1A86)"
|
|
},
|
|
"F6FF": {
|
|
"unit": "game/unitStartTemplatesF000",
|
|
"line": "$20 = the opcode of a JSR whose address bytes fell outside the seven sectors"
|
|
}
|
|
},
|
|
"dataTypes": {
|
|
"F000": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F032": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F064": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F096": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F0C8": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F0FA": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F12C": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F15E": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F190": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F1C2": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F1F4": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F226": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F258": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F28A": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F2BC": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F2EE": [
|
|
"grid",
|
|
29,
|
|
10
|
|
],
|
|
"F30B": [
|
|
"grid",
|
|
21,
|
|
10
|
|
],
|
|
"F320": [
|
|
"grid",
|
|
19,
|
|
10
|
|
],
|
|
"F333": [
|
|
"grid",
|
|
1,
|
|
1
|
|
],
|
|
"F334": [
|
|
"grid",
|
|
30,
|
|
10
|
|
],
|
|
"F352": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F384": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F3B6": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F3E8": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F41A": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F44C": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F47E": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F4B0": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F4E2": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F514": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F546": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F578": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F5AA": [
|
|
"grid",
|
|
50,
|
|
10
|
|
],
|
|
"F5DC": [
|
|
"grid",
|
|
36,
|
|
10
|
|
],
|
|
"F600": [
|
|
"grid",
|
|
14,
|
|
10
|
|
],
|
|
"F60E": [
|
|
"grid",
|
|
50,
|
|
10
|
|
]
|
|
}
|
|
}
|