Variables

Without a symbol table from the original source code, this list is presented as speculation (but with some pretty solid investigation into the nature of some!)

AddressTypeVariableX-refNotesConfidence
400wGameBoardCellColumn (X position)28c74
28c74
292c8
2934e
29ce8
2d6fa
2d74e
2d774
2d7a2
2db8e
2deb8
2e018
2e3ae
3871c
38724
38784
5ad90
5b4f0
This is the entity’s grid X/column (tile or logical column), also persisted to the portal column table per slot. (Position % 40)
Persisted into TBLPortalColumn_26DF2

Read/modified as a column index during pixel/plot logic and per-step updates: e.g. LAB_PlotPixelAndStep_2D74E reads it (move.w …,D0), other paths add D7 into it (add.w D7,(EntityCOLUMN) at 2D774/2D7A2), and subtract it from D5 (2D6FA).
Stored into a per-portal table indexed by an entity/portal slot: move.w (EntityCOLUMN),(0,A3,D4*1) => TBLPortalColumn_26DF2 (2E018).
Captured/restored around stack saves (292C8/2934E) and loaded from an entity table via (0,A5,D4*1) (29CE8).
High
402wGameBoardCellRow (Y position)292ce
29348
29cf0
2d71a
2d754
2d780
2d796
2dec6
2e026
2e3a6
Entity’s grid Y/row (Position  / 40)
persisted into TBLPortalRow_26F1E

Used as the paired index to $400: read into D1/D4 (2D754/2DEC6), subtracted from D6 (2D71A), stepped with add.w D7,(EntityROW) (2D780/2D796).
Stored into TBLPortalRow_26F1E at (0,A3,D4*1) (2E026).
Saved/restored on the stack (292CE/29348) and initialised from (0x2,A5,D4*1) (29CF0).
High
404wGameBoardCellTypeFlags292bc
2935a
29ba2
29bae
2af54
2db8e
2dc46
2dd74
2dd86
2dd9e
2de26
2de5e
2de72
2dea4
2ded8
2e02e
2e246
2e26e
2e342
2e34e
2e364
2e376
2e386
A type/flags word for the active entity/portal:
Bits 7–4 function as a growth type identifier (e.g. circular, diamond, cross), bits 3–0 represent growth size; the increment pattern (7→8→9→A) in the 2×2 stamp sequence strongly suggests the size of the growth.
Upper bit15 selects flagged/portal flag (bit15 set at 2DE72), a control flag for execution paths.
Bit 15 clear (0): Takes the LSL #5 path, likely a simpler operation (e.g., scaling position).
Bit 15 set (1): Takes the table-driven path, possibly involving complex growth or portal logic

Sometimes used as a small counter/phase via addq.
Written with small constants in “life” render paths: #0x40 (29BA2) and #0x41 (29BAE).
Used as a typed/flagged field in control logic: pushed/popped (2DD74/2DE26), copied, ORed and incremented (or.w D5,(EntityTYPE) at 2E34E; addq.w three times at 2E364/376/386).
High bit explicitly set: ori.w #-0x8000,(EntityTYPE) (2DE72).
Also receives “PortalType_D6” (2E02E) and other small constants (#0x7 at 2E342).

Bit-15 is asserted either by building D0=$8000|byte then MOVE.W D0,$404 (0002DE56–0002DE5E) or by ORI.W #$8000,$404 (0002DE72); the very next consumer is MOVE.W $404,-(A7) at 0002DD74 inside SUB_ProcessPortalGrowthUpdate_2DD46.
In SUB_UpdateGameBoards_2DE80, $404 is copied to D2 and branched on sign (BPL at 0002DEDE): with bit-15 clear it follows a simple LSL #5 index path (0002DF0C); with bit-15 set it takes a table-driven path (0002DEE8–0002DF0A).
During 2×2 bitmap placement (0002E300+), it’s set to #$007 then ORed with (D5 & $0F0) (0002E342–0002E34E), and subsequently incremented alongside the position (0002E364/0002E376/0002E386), showing low-nibble as size and upper nibble as type.
Also written with small constants #$40 / #$41 in life-render code (00029BA2/00029BAE), confirming its general “type/flags” role.
High
40Aw 
GameBoardCellIndex
292c2
29354
29bbe
2af5a
2dd5c
2dd6e
2ddc4
2ddd0
2dddc
2dde6
2ddf0
2ddfc
2de06
2de12
2de1c
2de2c
2de3a
2de8c
2e008
2e240
2e27c
2e33c
2e35e
2e36e
2e380
2e39c
A linear position index into the playfield/map (row-major), used for adjacency and as the canonical “position” of the entity/portal.
Used as a single index for 3×3 square neighbourhood scan.

ProcessAdjacentSquares_2DDD0 applies a fixed pattern: -0x29, +1, +1, +0x26, +2, +0x26, +1, +1, later +0x27 elsewhere (2E36E). That’s the classic 3×3 sweep with a fixed row stride (≈0x27/0x26).
Frequently copied to/from D-regs (2DD5C, 2DD6E, 2DDC4, 2DE8C) and saved/restored (2DE2C).
Used as the base for “growth” calc (2DE3A) and portal position writes (2E008/2E240/2E27C/2E33C).
High
40CwCurrentWorking
GameBoardCellIndex
2d89e
2dff6
2e0ce
2e390
A working/cursor index used during iterative operations on the current entity/portal (scratch/cursor board index during growth scan)

Loaded/stored as the “current” location in workflows: move.w D0,(…40C) (2D89E), move.w PortalLocationData_D5w,(…40C) (2DFF6), later read into D1 (2E0CE) and written back again (2E390 “StoreCursorAndRepeat”).
High
40EwRenderModeShadow2da54
2da74
2dcda
A latched copy of the current render config for inner routines (avoids re-reading the global or passes as a cheap “parameter”).

Mirrored from RenderConfigMode_410 (2DA54), sometimes overwritten from D0 (2DA74), and then read by SUB_2DCDA.
Med–High
410wRenderConfigMode2d9a8
2d9b0
2da2c
2da54
2da6e
2db76
2dbb4
Global rendering mode/state selector used to dispatch different draw paths.

Written from a mode table ((0,A0,D0*1)=> DAT_33A78, 2D9A8).
Checked/cmp’ed in render paths (2D9B0, 2DA2C, 2DA6E, 2DB76, 2DBB4).
Mirrored to $40E.
High
412wRenderPhaseTimer28ebc
28ee4
28f36
28f5e
29004
2902c
2daa2
2db4e
2dbf2
2dc06
2dc5a
2dcd0
 A general-purpose phase/countdown timer used across title/game render phases.

Loaded with various durations (e.g., #0xAF, #0x64, #0x40, #0x1) then repeatedly decremented (subq.w #1 at many sites: 28EE4/28F5E/2902C/2DB4E/2DCD0).
Re-initialised when switching render types (2DAA2, 2DC5A, 2DBF2, 2DC06).
High
414lSubphaseTicks2dab2
2db1c
2dc62
2dcbc
A tiny subphase tick counter
Set to #4 (2DAB2, 2DC62) and decremented each tick/frame (2DB1C, 2DCBC).
High
418lDelayCounter2dbe4
2dc2e
Another short delay counter
Set to #0x20 then decremented (2DBE4/2DC2E)
High
41Aaddr MaskedFrameTick29292
2929e
Per-VBlank tick that’s AND-masked by WinLevel_4D6 to throttle work/gate the copper-list update path.

Increments every non-title-screen frame (29292).
Immediately ANDed with WinLevel_4D6 (2929E); non-zero => take copper update path (292A4).

A timing/phase accumulator with a level-dependent mask.
Med–High
420wCurrentGrowthValue 2dc46
2e050
2e088
A per-row growth value / presence flag fetched from a growth table (A3 base, D6 row)

Cleared during a structure init (move.l #0,(A0)+ at 2DC46).
Later loaded from a row-indexed table (0,A3,D6*1) (2E050) and immediately tested (2E088 “GrowthRow1_2E088”: tst.w (Growth_420))
Med–High
422wA0EndPtr2db66
2db6c
2dbc6
2dbcc
2dc3c
An end pointer for a copy/fill loop (sentinel = start + size).
Set from A0, then a constant added (+$400 or +$420) and later compared against A0 as a loop bound (cmpa.l (0422),A0, 2DC3C), with A0 presumably walking the block.
High
42EwGrowthWriteOffset_ScreenA2ce44
2ce62
2ce8e
2df0e
2df56
A word address/offset cursor into a growth-related table with long-sized (4-byte) entries (since it advances by 4)

Per-buffer growth write cursor for SCREEN A. When the active screen is ScreenA it uses $42E first, then uses $430 for the second pass (0002CE78).

Used as an address/offset source: movea.w (…42E),A4 (2CE44/2CE62).
Cleared (2CE8E), read (2DF0E), and stepped by 4 (2DF56).
High
430wGrowthWriteOffset_ScreenB2ce2e
2ce5a
2ce78
2df22
2df4e
Per-buffer growth write cursor (word offset) for the other screen buffer (SCREEN B), advanced by 4 bytes per cell write and cleared after use

In SUB_UpdateOrganicGrowth_2CE20, when the active screen is not ScreenA it loads A4 from $430 (0002CE2E), renders a growth pass, then clears $430 (0002CE5A).
In the writeout path, SUB_UpdateGameBoards_2DE80 tail), if the active screen is not ScreenA it reads $430 into D4 (0002DF22), performs stores, then advances it by 4 (0002DF4E). The $42E path mirrors this for ScreenA.
High
432wBitmapGraphicSpinAngle29e0c
2b3c6
2b3e2
2d992
2d9d4
2da18
2da9a
 An angle/phase accumulator for bitmap “spin” (+2 per tick)

Read in graphics process (2D992/2DA18), zeroed at resets (29E0C, 2B3C6/E2/2D9D4), incremented by 2 per tick (2DA9A).
High
434wFaceAnimationCounter28d12
29e12
29e8a
2b1da
2b2da
2b312
2b39a
2b3cc
2b3e8
2cff4
2d00e
2d034
2d072
2d922
2da08
Global face animation frame/phase counter (+2 per tick)

Polled often (28D12, 29E8A, 2B1DA, 2D922, 2CFF4), advanced by 2 (2D00E), reset (2D034).
Compared to a large threshold ($292 at 2B2DA).
Saved/restored via $438 (2D072/2DA0E)
High
438wFaceAnimationCounter_Save2d072
2da0e
Save slot for the above.High
43AaddrActiveCentralFaceGfxPtr28e00
2905c
2908e
2b37c
2cffe
2d03a
2d99a
Active/selected central face graphic pointer (resource currently being loaded/displayed)

Set to several face asset addresses (#0x5D546, #0x5E546, #0x60546) and used by LAB_LoadDefaultFace_2CFFE as A0.
Also gets assigned from $43E in a couple of paths (2D03A/2D99A).
High
43EaddrFrontGfxBufferPtr25e20
2607c
26e58
28162
285cc
2865e
28df6
29052
29084
29e18
29e2e
2b376
2d03a
2d7cc
2d7d2
2d99a
2da4e
Double-buffer pointer pair – front/current graphics buffer (or render base) – “current” graphics buffer base; swapped with $442

Both 43E and 442 get initialised to various addresses; one is often _graphicsY (28162 → 043E) or from D2 (28168/2B382 → 0442).
Swapped as a pair in SUB_SwapScreenBuffers_2D7CC:
A3 ← (043E); then (043E) ← (0442); then (0442) ← A3 (2D7CC/2D7D2/2D7DC).
Many render paths read (043E) into A3 for further graphics work (2D7CC, 2DA4E).
High
442addrBackGfxBufferPtr28168
285d6
28668
2b382
2d7d2
2d7dc
Back/next graphics buffer
(see above) – “other” graphics buffer base; swapped with $43E
High
446w GameState28ccc
28ce2
29e6e
29e7a
29ede
2b30c
2b394
2b3d2
2b3ee
2d02a
2d8d6
2d906
2d92a
2d9b8
2d9da
2da5e
Global game state enum
Set to small enumerated values (0..5) in multiple places, tested by control logic and render dispatch (2D02A, 2D8D6, 2D92A, 2D9B8, 2DA5E), cleared on reset (2D9DA). Possibly… (need to check)
0: Reset or inactive state.
1: Day/night transition state or initial demo state.
2: Demo instructions state.
3: Post-level completion state or index.
4: Tarot event or special graphics state.
5: Additional index from the table.
LAB_33E3C provides a cyclic sequence (1, 3, 2, 5, 1, 3)
The value 4 is unique to $2B3EE and not in the table, suggesting it’s a special case (e.g., tarot event)
High
44Aw StateFrameIndex2d8e0
2d8e6
2d8fc
A per-state frame counter/index – counts ticks since entering the current GameState. Increments then cleared on state change.

Incremented each tick within the state manager (2D8E0), read (2D8E6), and cleared (2D8FC)
Med–High
44CaddrCurrentScreenDescPtr26e84
26f64
283f2
284f2
28524
2856a
285ae
2864c
28782
287ca
287d8
295d4
29e5a
29f3a
2c9e0
2cb42
Pointer to the current screen/scene descriptor (fed into A5 as the working base for the code that follows)

Initialised to many constants (#0x343EA, #0x3560A, #0x35AA6, …), then used as an address source for A5 in WhichScreen_2C9E0/2CB42.
High
450wLarge Eyeball Bitmap X28462
2c69c
2c6fa
2c788
2c79c
2c7b8
2c7d4
Base X for a 4-sprite eye layer (“group 1”); low byte feeds four sprite X bytes.

Init: move.w #-0x8000,(Eye_450) (28462).
Step pairs: subi.w #$66 (2C69C) / addi.w #$66 (2C6FA).
Low byte copied to four sprite param bytes at $356A7, $356CD, $356F3, $35719 (2C788/79C/7B8/7D4).
High
452wLarge Eyeball Bitmap Y2846a
2c63e
2c758
2c792
2c7ae
2c7ca
2c7e6
Base Y for the same 4-sprite layer as $450.

Init: move.w #$5500,(EyeXY_452) (2846A).
Step pairs: subi.w #51 (2C63E) / addi.w #$33 (=51) (2C758).
Low byte copied to $356A9, $356CF, $356F5, $3571B (2C792/7AE/7CA/7E6).
High
454wMed Eyeball Bitmap X28472
2c6a4
2c702
2c7f0
2c804
2c820
Base X for a 3-sprite eye layer (“group 2”).

Init: move.w #-0x7800 (28472).
Step pairs: subi.w #$8E (2C6A4) / addi.w #$8E (2C702).
Low byte → $3573F, $35765, $3578B (2C7F0/804/820).
High
456wMed Eyeball Bitmap Y2847a
2c646
2c760
2c7fa
2c816
2c832
 Base Y for group 2.

Init: move.w #$5700 (2847A).
Step pairs: subi.w #71 (2C646) / addi.w #$47 (=71) (2C760).
Low byte → $35741, $35767, $3578D (2C7FA/816/832).
High
458wSmall Eyeball Bitmap X28482
2c6ac
2c70a
2c83c
2c850
2c86c
 Base X for a 3-sprite eye layer (“group 3”).

Init: move.w #-0x7400 (28482).
Step pairs: subi.w #$AC (2C6AC) / addi.w #$AC (2C70A).
Low byte → $357B1, $357D7, $357FD (2C83C/850/86C).
High
45AwSmall Eyeball Bitmap Y2848a
2c64e
2c768
2c846
2c862
2c87e
 Base Y for group 3.

Init: move.w #$5900 (2848A).
Step pairs: subi.w #86 (2C64E) / addi.w #$56 (=86) (2C768).
Low byte → $357B3, $357D9, $357FF (2C846/862/87E).
High
45CwEye? Unused? 28492Set to $9000 at 28492. No reads or other uses.Med
45EwEye?  Unused?2849aSet to $5B00 at 2849a. No reads or other uses.Med
460wMed Iris Bitmap X284aa
2c6bc
2c71a
2c8b8
2c8cc
Base X for a 2-sprite eye layer (“group 5”).

Init: move.w #-0x6D00 (284AA).
Step pairs: subi.w #$1A6 (2C6BC) / addi.w #$1A6 (2C71A).
Low byte → $3586F, $35895 (2C8B8/8CC).
High
462wMed Iris Bitmap Y284ca
2c65e
2c778
2c8c2
2c8de
Base Y for group 5.

Init: move.w #$5600 (284CA).
Step pairs: subi.w #211 (2C65E) / addi.w #$D3 (=211) (2C778).
Low byte → $35871, $35897 (2C8C2/8DE).
High
464wLarge Iris Bitmap X284a2
2c6b4
2c712
2c888
2c89c
Base X for a 2-sprite eye layer (“group 4”).

Init: move.w #-0x7000 (284A2).
Step pairs: subi.w #$14C (2C6B4) / addi.w #$14C (2C712).
Low byte → $35823, $35849 (2C888/89C).
High
466wLarge Iris Bitmap Y284c2
2c656
2c770
2c892
2c8ae
Base Y for group 4.

Init: move.w #-0x6B00 (284B2).
Step pairs: subi.w #$1E2 (2C6C4) / addi.w #$1E2 (2C722).
Low byte → $358BB, $358E1 (2C8E8/8FC).
High
468wSmall Iris Bitmap X284b2
2c6c4
2c722
2c8e8
2c8fc
Base X for a 2-sprite eye layer (“group 6”).

Init: move.w #-0x6B00 (284B2).
Step pairs: subi.w #$1E2 (2C6C4) / addi.w #$1E2 (2C722).
Low byte → $358BB, $358E1 (2C8E8/8FC).
High
46AwSmall Iris Bitmap Y284d2
2c666
2c780
2c8f2
2c90e
Base Y for group 6.

Init: move.w #$5900 (284D2).
Step pairs: subi.w #241 (2C666) / addi.w #$F1 (=241) (2C780).
Low byte → $358BD, $358E3 (2C8F2/90E).
High
46CwGlobal Eye Position X284ba
2c678
2c696
2c6d6
2c6f4
2c918
Global eye base X (accumulator), also mirrored to a UI/debug byte at $35907

Init: move.w #-0x6800 (284BA).
Read/modify/write cycles at 2C678→2C696 and 2C6D6→2C6F4; low byte copied to $35907 (2C918).
High
46EwGlobal Eye Position Y284da
2c616
2c620
2c638
2c734
2c752
2c922
Global eye base Y (accumulator), also mirrored to a UI/debug byte at $35909.

Init: move.w #$5B00 (284DA); read/compare (cmpi.w #22528) (2C620).
Read/modify/write cycles at 2C616→2C638 and 2C734→2C752; low byte copied to $35909 (2C922).
High
470wEyeBlinkPhase2c92c
2c944
2c94e
2c968
Blink state/phase in steps of $10; reset at end of blink

Read, then addi.w #$10,(Eye_470) (2C92C/944/94E), then cleared (2C968).
Values 00→10→20→30→40→50→00.
High
472wJoystickX296d4
2b700
2b748
2bfbc
2bfc8
2c058
2c070
2c0b6
2c0ca
2c0de
2c1b8
2c1ce
2c3cc
2c3e2
Discrete horizontal joystick direction (−1/0/+1), source for follower/filtered X and star-chart input.

Read as the primary X input in LAB_ReadJoystick_2B700 and SUB_ProcessJoystickInput_2BFBC (move.w (…472),D2). Mirrored to multiple consumers (JoyX1 at 2B748/2C3CC/2C3E2; _JoystickX at 2C0CA). Explicitly written as 0, -1, +1 (2BFC8, 2C058, 2C070). Polled for change/compare (tst.w at 2C0B6, cmp.w at 2C0DE). Also read for clamping/flow at 2C1B8/2C1CE.
High
474wJoystickY2b706
2b74e
2bfc2
2bfce
2c08e
2c0a6
2c0c0
2c0d4
2c0f2
2c1be
2c1f6
2c3d2
2c40e
2c4ca
Discrete vertical joystick direction (−1/0/+1), fanned out to multiple systems (UI/star-chart/gameplay).

Read as Y input into several game and UI sinks (directionjoystick 2B706, _joysticky 2B74E, _JoystickY 2C0D4). Explicit writes to 0, −1, +1 (2BFCE, 2C08E, 2C0A6). Tested/compared (tst.w 2C0C0; cmp.w 2C0F2). Mixed into D0 with OR at 2C1BE and reused by star-chart paths (2C3D2/2C40E/2C4CA).
High
476wJoystickXFollower2812a
2ab0e
2c0ca
A tracking or filtered sample of X (with a slight initial offset), applied where a smooth or delayed-response X is required

Initialised to #4 at 2812A. Updated from the raw X (move.w (JoystickX),( _JoystickX ) at 2C0CA). Tested (tst.w (_JoystickX) at 2AB0E).
Low
478wJoystickYFollower2ab24
2c0d4
Follower/filtered Y sample
Updated from raw Y at 2C0D4; tested at 2AB24
Low
47AwLastKeycode288e2
288ee
288fa
28916
2892c
2c152
Last keycode latch used by menu/flow logic (compared against specific rawkey values).
Cleared in several places (288E2/288FA/2892C). Compared against #$74 and #$7E (288EE/28916). Written from D1 in LAB_StoreKeycode_2C152 (2C152)
Med
47Cw InputArmedFlag28a54
2c042
2c49c
Polled (tst.w at 28A54). Set to #1 at 2C042 and 2C49C.Low
47EwJoystickFIRE2884c
288ce
288d4
28c94
28cd8
28cf2
28d08
28d22
28d58
28d6a
28d74
28e3a
28e66
28eaa
28ed0
28eda
28ef4
28f26
28f4a
28f54
28f6e
28fa2
28fc0
28ff0
29018
29022
2903c
2906e
290a0
290be
29134
29152
29170
2918e
291ac
291f2
29204
29568
2aa56
2b73e
2bfd4
2c002
2c26e
2c292
2c436
009fe2c2
009fe2e2
 Joystick fire button latch

Extensively tested across demo, instructions, and gameplay (many tst.w sites). Asserted with #1 (2C002). Cleared frequently (2884C/288CE/291F2/29568/2BFD4/2C292). Also present in a short absolute‐word mirror (9FE2C2/9FE2E2).
High
482w ActionCooldown2aa44
2aa4c
2aac0
2aad4
2aaf6
 Small countdown used in the 2AAxx input/action cluster (debounce/cooldown/sequence step)

Polled/decremented (2AA44/2AA4C), preset to #6 or #3 (2AAC0/2AAD4), cleared (2AAF6).
Low
484wPortalListIndex297ea
2982c
2b47e
2d874
2df86
2dfee
2e182
Loaded into a loop index before scanning the portal-location list: MOVE.W (PortalCounter_484).l,D3 at 2E182, then iterated backwards in steps of 2 with SUBQ.W #2,D3 while comparing the current candidate slot against a position: CMP.W 0(A6,D3.W),D1 (loop at 2E190–2E19C). When a match is found, the slot is cleared: CLR.W 0(A6,D3.W) at 2E19E (i.e., remove portal). Elsewhere it’s read to size list-driven logic (D6 at 297EA/2D874, D5 at 2982C, D4 at 2DF86). It is incremented by 2 on updates: ADDQ.W #2,(PortalCounter_484).l at 2DFEE – matching the word (2-byte) granularity of each portal entry in the A6 table.Med
486wGrowthColumnCounter2e04a
2e058
2e05e
2e06a
 Column loop index (1..40) for growth row processing

Cleared at row loop start (2E04A), incremented per column (2E058), compared against #1 and #$28 (2E05E/2E06A).
Med
488wStarMapScrollCounter2a102
2a1a6
2a1ac
2a1b8
2c440
 Star-map horizontal scroll counter / tick

Read/incremented/compared/reset in 2A102/2A1A6/2A1AC/2A1B8; also tested in star-chart path 2C440.
High
48Aaddrpointstoadd26994
292da
2996a
29d30
2adae
2adf6
2d4c8
Pending score
Zeroed at scene start: MOVE.L #0,(pointstoadd) (292DA). Accumulates diverse score deltas across gameplay: ADDI.L #$BB8 (+3000) at 2996A, ADDI.L #175 at 29D30, ADDQ.L #3 at 2ADAE, and ADD.L D2,(pointstoadd) at 2ADF6. Polled via MOVE.L (pointstoadd).l,D0 at 2D4C8 (used by the score update/commit routine in that region).
High
48Eaddr PaletteStreamPtr293e2
293f0
Word-step stream pointer (cursor) into a colour/palette data sequence.

Added into A0 (adda.l (…48E),A0 at 293E2), then advanced by 2 (addq.l #2,(…48E) at 293F0). In the same code region, a word is fetched from (A0) into $496 and written to COLOR00 (293F6/293A6).
Low
496w Color00Latch293a6
293f6
Current COLOR00 value latch (staging between table read and hardware write).

Latched from (A0) (293F6), then written to CustomChips.COLOR[0] (293A6)
Med
498b PaletteControlByte293bcOnly observed as a byte read into D0 (293BC).
Byte control/state value used in the same palette/IRQ block (exact role unclear with a single read).
Low
49Cb FrameToggleByte293c8
293d0
Frame/parity toggle byte to perturb an index/value (e.g., flicker/alternator).

Toggled with eori.b #$1,(…49C) (293C8), then added into D0b (293D0).
Med
49EwSunsetCompleteFlag2948e
295b4
295c2
Explicitly set to 0 / 1 (2948E/295B4). Tested in flow (295C2).Low
4A0w SunsetFadeCounter29500
29506
29512
 Increments, compared to #2, then cleared (29500/29506/29512).
2-step cycle counter (0→1→(>=2?)→0)
Low
4A2wSunsetBlitterCounter2946c
29472
294f2
295bc
Sunset effect blitter tick (even-step counter)
Read/incremented by 2 in two paths, cleared at 295BC (2946C/29472/294F2/295BC).
Med
4A4addr StarChartPtr_Pending2d0be
2d0c8
Pending/new star-chart data pointer (staged before activation).
Written from A0 (2D0C8). Later copied into $4A8 (2D0BE).
Low
4A8addr StarChartPtr_Active2d0b4
2d0be
Active star-chart data pointer
Compared against A0 to detect change (2D0B4). Updated from $4A4 (2D0BE).
Low
4B2wGuardianType2821c
28e50
29d6a
2a622
2a65c
2a868
2b17a
2bc66
2bd30
Guardian type selector (0..6)

0 = Devil, 0001 = Blades, 0002 = Hand, 0003 = Hydra, 0004 = Spider, 0005 = Firefly, 0006 = Giant Maggot
High
4B4wEnergy2a37e
2a3a2
2b324
2be8c
2be92
Energy. Values 0 < 47 > 95 (0, 2f00, 5f00 bit shifted 8 bits to the right, so divided by 256) in 0x20 steps, byte-significant for UI

Written from energylevel (2A3A2), read/subtracted/updated in gameplay (2A37E/2BE8C/2BE92), and byte-read at 2B324 (UI).
High
4B8wDay/Night Timer2b3a4
2b3aa
2b3b8
 Incremented, read, then cleared in a regular cadence (2B3A4/2B3AA/2B3B8).High
4BAwDay/Night Flag28158
2ad6a
2ada4
2b36a
2b424
2b454
2d9ea
0 = Night, 1 = DayHigh
4C4w MovementEnabled2835a
2b67e
2b698
2bf86
2c0e8
Movement-allowed flag set by input layer
Set/cleared in joystick handling (2835A/2B698/2BF86/2C0E8) and polled (2B67E).
Med
4C6w CarryingGoodSporeFlag298cc
298e0
2aa60
2aab0
2aaba
2b7e4
2bdf6
2be18
Tested by pickup/use sites (2AA60/2BDF6), read for logic (298CC/2AAB0/2B7E4), cleared at state changes (298E0/2AABA), assigned from A2w on pickup (2BE18)Med
4C8wEvilSporeLaunchTimer2b4fa
2b504
2b5cc
Polled/decremented in flight logic (2B4FA/2B504), loaded from D3 at 2B5CC
dec by 1 from BD to 00
Low
4CAwSporeLaunchDelayTimer2b514
2b51e
2b528
2b5d2
 Launch delay countdown for evil spore

Preset #8, then tested/decremented, then cleared (2B514/2B51E/2B528/2B5D2).
Med
4CCw EvilSporeInFlight Flag2b532
2b53a
2b572
2b5d8
 In-flight state flag for evil spore

Set to #1 on launch (2B532), tested (2B53A), cleared at completion/abort (2B572/2B5D8).
Med
4D0w UIBlitStartOffset28384
285e0
28656
2d0d4
52a00
Initialised to different constants (28384/285E0/28656). Read at 2D0D4Low
4D2addrForbiddenCellBitmapPTR2837a
285e8
2878c
2e0f6
Stores the address of the forbidden cells bitmap that cannot be written into during growth.
Runtime pointer to a 1-bit bitmap used as a write-forbid mask for both growth and portal writes.
It is set to 33EEE at $2837A for in-game
It is set to 33FE8 at $285E8 for demo/instructions
High
4D6wWinLevelFlag2816e
285fc
28686
28d8e
29298
292e8
29ac6
29e82
29ece
 Written 0/1 at multiple flow points (2816E/285FC/28686/28D8E/29AC6/29E82/29ECE). Read/tested for gating (29298/292E8). Also masks the IRQ tick at 2929E via AND with $41AMed
4D8wTrigger to change day/night2b3be
2d9e0
2da02
One-shot trigger to flip/render day-night transition.
Set to #1 (2B3BE), polled then cleared in the render/state path (2D9E0/2DA02).
High
4DAw EnergyUpdateTimer2b32e
2b33c
2b346
2b34c
Energy update timer/phase used to pace energy gain/loss

Compared to D1, dec/inc around energy update (2B32E/2B33C/2B346/2B34C)
Low
4DCw EnergyStepCounter2b2f6
2b302
2b31c
 0..7 step counter for energy animation or staged updates
Compared to #7, incremented each step, cleared on wrap/reset (2B2F6/2B302/2B31C).
Low
4DEw TwoFrameDelay2c53a
2c544
2c592
Tiny 2-frame delay used in the 2C53x cluster (UI/input)
tst.w, subq.w #1, preset to #2 (2C53A/2C544/2C592).
Low
4E0wSunsetPhase27098
2a072
2a07e
Sunset effect phase accumulator.
Incremented and read as phase (2A072/2A07E). Also appears in a data table ref at 27098.
Low
4E2wSunsetOffset2a092
2a0ca
Sunset effect position/offset accumulator (coarse step)
Read and increased by #$A0 (2A092/2A0CA)
Low
4E4wSunsetActiveFlag2a064
2a0d8
Polled (2A064) and set to #1 (2A0D8).Low
4E6wSunsetEnableFlag2940c
29488
2a042
2a05a
Sunset effect enable/armed flag (used by animation manager).
Polled (2940C/2A05A), set and cleared (2A042/29488).
Low
4E8wSunsetSunYOffset28af4
29416
2a016
2a02e
2a036
Sunset object position (with range checks)
Initialised to #$60; read; incremented by #$A0; compared to two bounds #$293F and #$1A40 (28AF4/2A016/2A02E/29416/2A036).
High
4EAwSunsetCopperEffectTimer28afc
29f76
29f80
2a04a
Title-screen timer for the duration of the sunset copper effect.
Preset #$3F; polled/loaded; decremented each tick (28AFC/29F76/29F80/2A04A)
High
4ECwSunset Frame Counter 28afc
29f76
29f80
2a04a
Modulo-3 tick for the sunset sun descending (sub-frame cadence used to pace the sun descnding animation/blits independently of the main phase/position counters)
Tight 0..2 frame cycle: ADDQ.W #1,(…4EC) (29FFE), compare CMPI.W #3,(…4EC) (2A004), then reset CLR.W (…4EC) (2A010). This sits alongside the sunset system where other state includes SunsetPhase_04E0, SunsetOffset_04E2, SunsetActiveFlag_04E4, SunsetEnable_04E6, and position SunsetY_04E8; the modulo-3 cadence gates per-frame sub-stepping of the effect.
High
4F0w CurrentFirePowerMode28e0a
29ad8
2aac8
2ab4e
2ab5a
2ab84
2b6bc
2b6e4
2b80e
2b840
2b8d0
2bbae
2be48
2be54
2bed0
2beda
2bee4
2bf28
2bf6e
2d4a6
2d81c
2d8b2
The current firepower mode derived from the tarot system; also gates other mechanics (growth suppression at 7).
Written from the active tarot card and then incremented by 1 on pickup; later used as an index into a timer table to seed PowerUpTimer_528.
MOVE.W Tarot,CurrentTarotCard_4F0 / ADDQ.W #1,CurrentTarotCard_4F0 / table lookup into PowerUpTimer_528 at 2BED0–2BEF2.
Drives bullet patterns (double/triple shot) in the fire routine, via compares against 8 and 9 (and 6 for a special behaviour).
Consulted during growth to suppress evil growth when firepower is 7.

Read in the bullet-fire routine to alter shot patterns: 2×shot if value==6, 3×shot if value==9, by offsetting D5/D6 (bullet X/Y) and spawning extra bullets.
Also copied from Tarot ($526) during card changes: move.w (tarot_526).l,(CurrentTarotCard_4F0).l
4F2wPlayerX296de
2b862
2b87c
Player’s X position.

Joystick read maps to movement tables, but PlayerX itself is sourced from a level/init table at PlayerXPosition_347CA and copied into PlayerXFollower.
Title/init paths set PlayerXPosition_347CA then various sprite updates consume it.
4F4wPlayerY2b86c
2b882
Player’s Y position
Same pattern as X: copied into PlayerYFollower; written from PlayerYPosition_347CC during setup.
4F6wPlayerXFollower2b824
2b862
Smoothed/lagged copies of player position used by several subsystems
Read by input/render glue (used where immediate player X isn’t desired), and kept in lockstep with PlayerX.
4F8wPlayerYFollower2b834
2b86c
Paired latch for Y; updated with PlayerY. (Same update pattern as X follower.)
lags $4F4 by 1 vbl?
4FCw EnergyUpdateInhibitFlag2a5c8
2ad60
2bf3e
Checked before converting spore value to energy in the spore processing loop; if non-zero, the energy update path is skipped.
Tested as a boolean guard in multiple energy/update paths (tst.w (…4FC)). No writes in those blocks – only gate checks.
Low
4FEwLevelRoutinePtr28370
284e8
285f2
29e64
29f44
2b888
Runtime pointer to a movement/script table used by demo/win-level sequences
Holds different long pointers written in multiple places; later read into A0 just before a demo “skip movement” path.
Used as an indirect data source (movement/sequence script) for demo paths.
Low
502wGameOver28898
28942
29920
2cfca
Boolean Global “game over” flag.
Polled in the main loop to branch into the Game Over flow; set to 1 when the game ends. (tst.w GameOver → branch to grave/ending; later move.w #1,GameOver.)
H
504wBulletFiringCounter2ab90
2ab96
2aba2
2bf8e
Per-frame range counter for bullet.
Incremented each frame while firing; when it reaches 9, resets to 0 and allocates/updates bullet slots using A0/A1/A2 patterns tables. The counter is explicitly compared with #9 and gated.
506wEvilPortalsRemaining28ffa
2dfd0
2e1aa
Incremented when portals are created; decremented when portals are destroyed/overrun. Gate for level completion logic.
508wGoodPortalsRemaining2dfba
2e1d6
Incremented/decremented alongside evil portal counterpart, checked during portal overrun to decide loss.
50AwLevelWonFlag292f6
29e52
2b102
2b4f0
A separate “win flag” polled in a few logic spots and set on success. It’s distinct from $516 (LevelComplete tri-state) but used similarly in some paths (likely mode-local). (usage pattern matches a boolean gate.)
50Cw29ed6Only used in move.w #0x1,(EXT_50c).l
immediately after the victory branch is taken (the same block also flips audio/state for the win sequence)
Low
50EwCellByteTEMP292d4
29342
2dd62
2dd90
2ddba
 Scratch “current cell type/size” byte for growth logic
Byte copy of the GameBoardB cell at the active portal position used to decide growth/portal behaviour; saved/restored across routines. It’s read, masked, and compared in growth update.
Low
510w SunsetColorPhaseIndex28222
29fd4
2af30
Loaded from table data and read during sunset/title colour sequencing routines
512w FollowerOrbitIndex2bbd2
2bbd8
2bbe0
Incremented by 2, masked with #0xF, then used as an index in follower logic.
514wPowerCrystalFlightTimer2b230
2b236
2b240
Power Crystal-in-flight lifespan timer
Loaded from D1 when crystal starts moving; then polled and decremented until zero to gate motion/effect.
516wLevelComplete2890c
28932
297da
29e22
29eac
29f00
29f64
2b03a
2d088
2d7e4
2df60
2e1bc
2e1de
Canonical tri-state: set +1 on all evil portals cleared; set −1 on all good portals cleared; used by game logic to trigger win/lose events ($11/$12).
-1 = Level lost, 0 = Level running, +1 = Level won
518wGrowthType2822e
2825e
282ce
28630
2b0ce
Written from level data; read and added/masked to select a growth behaviour/pathfinding pattern.
0 = Circular, 0001 = Diamond, 0002 = Cross, 0003 = Octagonal
51AwGrowthStepPendingFlag297d0
297e4
2b0d6
2e03e
2e188
Sticky “portal growth occurred” flag used during growth pass.
Set to 1 in several paths that mark a “portal growth” event (e.g., when a portal is overrun). Cleared on entry to growth pathfinding.
51Caddr TarotEffectPtr2b410
2d94a
Long pointer written from 333BA[Tarot*4] and later loaded into A5 during tarot effect handling.
Long computed from a table via (0,A0,D1.w) then later movea.l (…51C),A5 to execute/apply a tarot effect.
520wGrowthAllowedFlag28d3c
28d7e
29300
295de
29622
2cf9c
2cfc4
2dd46
2de6a
2de80
2deaa
Master growth enable/disable flag
Hot gate for almost every growth write/update path (tst.w GrowthAllowed early-out). When clear, routines that would alter gameboard exit.
522wTitleFlameAccumulator28d34
295ee
2cfac
2cfe2
Initialised with 0x90, added to itself (add.w D0,(…522)) during the title sun/flame effect to drive a palette/position ramp.
524w StarMapScrollEventFlag2a1be
2a1c8
2a1d0
Set to 1 when the star map should begin scrolling; polled by the scroller entry, then cleared after handling.
526wTarot2b400
2be3c
2be60
2be7c
2bea4
2bed0
Used to branch to Death/Wheel/Hanged Man/Star handlers; also copied into CurrentTarotCard_4F0 when a crystal is picked up.

0 = The Lion, 0001 = Death, 0002 = The Moon, 0003 = Hanged Man, 0004 = Wheel of Fortune, 0005 = The Sun, 0006 = Tower, 0007 = The Star
528w PowerUpDurationTimer2b1c2
2b1cc
2bef2
2d4ae
 Loaded from a small table (DAT_333EC), indexed by CurrentTarotCard_4F0, decremented each tick to time power-up duration, with a hard set to $4B in another path.
52AwTitleDemoAdvanceFlag28d2c
295e6
2cfdc
Title/demo state selector
Small state flag read by the flame animation update; written to 1/2 in title control; used to select animation branch
52CaddrLevelMemoryAddress28216
2a790
2a94c
Base pointer to level data, read into A3/A1 by level loaders
530wGrowthRateThreshold28268
28636
28f0c
2b0de
2e096
Probability/threshold governing growth attempts
Compared against random samples to to decide whether a row grows this tick (growth gating) (cmp.b (growthrate),D1b inside growth selection). Also forced to $FFFF in some modes to “force allow”
532wGuardianRespawnTimer29d20
2a5b4
2b19a
2b1a4
2b1ae
2bcae
Standard countdown with compares to 0x41 etc to schedule (servant?); reset to 0x1E in another path (shorter retry).
 
(SendGuardianToPandaemonium sets to 325, then decreases by 1 at address 2b1a4)
Med
536wJoystickInputCooldownTimer2b38e
2d854
2d85c
Frame-based input timer used to gate directional joystick movement, simulating player responsiveness (inertia). Compared and subtracted from D0, which is loaded from a table (at $2E802) modified by GameBias
increases by 2 to 24, then back to 02.
538wInputDelayTimer2b388
2d7f2
2d7fe
Frame tick accumulator used to inhibit/reactivate input. Same pattern as 536, but used by a different input path; read as D1 and decremented by D0
inc by 2 from 00 to 08, then 01 to 07
53Aw MovementAllowedFlag28eb4
28f30
291f8
2d804
2d862
2d892
This flag determines whether a new directional input has been accepted for movement or control. It is toggled by SUB_HandleInputCooldown_2D7E4.
A value of $001 means movement/input is permitted. It is reset to $000 after a move is registered and cooldown is applied.
Low
53EwGuardianPhaseTimer281ba
29d28
2a5dc
2a5e6
2a5ec
2a634
2a69a
2a6b4
2a6d0
2a6ec
2a708
2a724
Guardian phase/hold timer
Written with many small constants (0x19, 0x7D, 0xAF, …) and then decremented/polled in guardian logic – fits a phase/hold timer used by multiple guardian states. (See guardian setup path that branches by GuardianType and primes data/timers.)
dec by 1 from 7D to 00 (SendGuardianToPandaemonium sets to 25)
542wScreenFlags2b0f2
2b10c
2b118
2cc04
2d488
Bitfield where individual bits are set/cleared with bset.b / bclr.b and tested with btst.b to gate screen/UI behaviour (e.g., spore-related rendering and level-lost signalling clears/set bits 1/2).Low
544wEnergyUpdateGate298c0
2a5be
2b68e
2bd62
2bf34
2d490
 “Don’t modify energy now”/tarot-side-effect gate.
Polled as a gate in the spore→energy path; cleared on level-lost, set when tarot/energy handling is active.
Low
546wSunsetStepCounter29422
29428
29434
A 0–2 modulo step index that paces the inner phases of the sunset effect (e.g., which mini-step to do this frame).
In SUB_ManageSunsetAnimation_2940C it’s incremented and then compared to #3; when it reaches 3, it’s cleared – a small repeating sub-phase counter:
addq.w #1,(WORD_00000546).lcmpi.w #3,(WORD_00000546).lclr.w (WORD_00000546).l
548w SunsetTransitionCounter2943a
29450
The broader “progress” counter for the sunset animation (number of transition ticks so far). Often used with the step counter to decide when to advance colours/positions.
Same routine increments it every update (addq.w #1,(WORD_00000548).l) and also reads it into D0 for transition logic, i.e., move.w (WORD_00000548).l,D0w. It’s the longer-period counter the stepper above consults while evolving the effect.
54Aw InGamePhaseIndex2b656
2b66a
2b678
Small step index for an in-game sub-loop (probably animation/update stride)
Read/cleared/incremented by 4 inside the in-game logic frame – likely a ring index stepping through a small table/phase (mod 4 or mod 8).
inc by 4 to 30, then reset to 04
Low
54Cw CollisionReboundOffsetX2b8ac
2b8f6
2b902
2b940
2b94a
2baec
2baf6
 Written from D0 in collision detection, then negated and applied symmetrically to response: adds/subtracts to D3/D6 and to D0 in X/Y resolution helpers. This is a “penetration depth” that gets applied to push entities apart or adjust velocities.Low
54Ew CollisionReboundOffsetY2b8b2
2b91a
2b926
2b99e
2b9a8
2bb26
2bb30
 Same as X: written/negated and added/subtracted to Y-accumulators (D6/D2) during response.Low
550w CooldownTimer2aa14
2b130
2b13a
A general-purpose short countdown used to delay/pace a following action
the common pattern is tst.w (Timer_550) then subq.w #1,(Timer_550) until it expires; e.g., LAB_CheckTimerEXT550_2B130 gates a chunk of logic behind this countdown. Elsewhere it’s set from D2 (move.w D2,(Timer_550)).
552wLevelTimerMAIN2b06a
2b076
2b0a4
2beb0
2bec0
Course timing
counts frames and is compared against thresholds 75 and 95 to flip timer state or trigger effects. Also read and re-written in tarot (Hanged Man) time-adjustment logic.
inc by 1
554wLevelTimerTICK2b04e
2b054
2b064
Fine timing – Tick accumulator that rolls up into the main timer.
inc by 1 to 2F then reset to 00
556wGrowthDisabledFlag29ae4
2ae1c
2b044
2b0c6
2d80c
2d828
2d8be
2df6a
Global “freeze growth” switch (disables spores/growth updates and also pauses the level timer pipeline that depends on growth ticks).

Checked before the level timer advances and before growth logic runs: tst.w (GrowthDisabled_556) at 2B044 short-circuits the in-game timer progression; the same flag is tested again in the growth/portal eligibility flow to skip growth entirely when set.
558w GuardianAnimIndexTEMP2a9e2
2bcb6
Temporary stash for the guardian animation/frame index (kept in D7 across helper calls) during guardian update.
Stored with move.w D7,(WORD_00000558).l (e.g., 2A9E2), then later restored move.w (WORD_00000558).l,D7w inside the guardian/amoeba logic block (2BCB6). This sits in the middle of guardian sprite and position updates.
55Aw LevelTickThreshold2824a
2b05a
GameBias-scaled tick threshold that paces how often LevelTimerMAIN increments (i.e., game speed/tempo derived from level data and bias mode).
During level init, a timer value from level data (word at 6(A1)) is scaled by GameBias (tactical/normal/arcade) and stored here: MOVE.W D0,ModifiedByGameBias_55A (2824A). At runtime the per-frame “tick” counter $554 is compared against this threshold to decide when to advance the main level timer: CMP.W (ModifiedByGameBias_55A),D0 (2B05A).
55CwHighScoreValue2c260
2c28c
2c388
2d5e2
Read for UI, incremented by 8 on certain events, and overwritten when a new high score is stored.
55EwHighScoreIndex28c8a
2c1ac
2c278
2c2c0
2d5f6
Upper bound of high-score table length/position: compared to 5, incremented, and reset to 5 in “no high score” path.
560addrHighScoreTablePTR2c27e
2d5e8
 holds a pointer to the active high-score table
564w HighScoreCharStepIndex28bb8
2c302
2c326
2c34c
Per-step UI state index for the Ouija/Grave screen logic
Used as a small step/index in the Ouija/“grave” UI flow: compared to 5, read into D0, then incremented each tick inside the same control block (CMP.W #5, EXT_564; MOVE.W EXT_564,D0; ADDQ.W #1,EXT_564). This lives alongside the other two state words $566/$568 in the same handler.
566w GraveScreenActiveFlag28bb0
2c2f8
One-shot “armed/active” flag enabling the Ouija/Grave UI stepper
Set to 1 at the start of the same sequence (MOVE.W #1,EXT_566) and polled as a gate (TST.W EXT_566) before the $564/$568 tickers run.
568w GraveAnimStep2c30e
2c314
2c320
 0..2 subphase counter for the Ouija/Grave UI
Ticked every frame (ADDQ.W #1,EXT_568), compared to 3, then cleared back to 0 on hitting the threshold – classic tiny sub-phase timer used next to $564.
56Aw GraveScreenAnimActive28c28
28c38
2c2ee
2c374
 “Sprite anim in-progress”/guard flag for this screen flow.
Enabled early (MOVE.W #1,EXT_56A), tested both in the “wait for sprite anim” and the “grave” handler, then explicitly cleared when the sequence finishes.
56Cw ColourTimer22a3d4
2a406
2c2c6
2c2d0
Enable/hold-off timer for a colour-cycle effect #2
Polled as a gate before a colour effect, explicitly cleared, set to 1 to re-arm; coupled with $56E as the corresponding index for the same effect path.
56Ew ColourIndex22a3de
2a3f6
2c2d8
Phase/index accumulator for colour effect #2
Read into D0, incremented by 2 per update, and reset – paired with $56C’s gating
570w ColourTimer328a5e
2a40c
2a43e
2c016
2c034
2c57c
Enable/hold-off timer for a colour-cycle effect #3
Tested as a gate in several places and set/cleared to control updates to $572
572w ColourIndex32a416
2a434
2c03c
Phase/index accumulator for colour effect #3
Read into D0, incremented by 1 per update, cleared on re-arm – paired with $570
574w EyeTearTimer2845c
2af9e
2afa8
2b016
Inter-tear delay for Eye of Infinity.
Seeded from <D1>, then repeatedly tested and decremented; later reloaded with #$AF as a delay – drives the Eye-of-Infinity tear cadence
Set to $7F, once it hits zero, the eye cries a tear, then reset to $AF
576w GuardianRespawnFlag2a8b6
2bc82
2bc8c
“Respawn occurred/allowed” flag for Guardian logic
Cleared on entry, tested during guardian logic, then set to 1 when a respawn condition is met.
578w EyeMovePhase2c5be
2c5ce
2c5e2
Eye movement phase/tick (horizontal/overall) used to pace the eye logic
Used as a small counter for the eye movement routine: read into D0 as input, cleared, then bumped by +2 each tick.
57Aw EyeDesiredXDirection2c600
2c66e
2c6cc
Desired X-direction for the eye: −1 left / +1 right
Loaded from D2 (the computed X direction), then compared against −1 and +1 in “CheckLeft/RightMovement”.
57CwEyeDesiredYDirection2c606
2c60c
2c72a
Desired Y-direction for the eye: −1 up / +1 down
Written from D3 (the computed Y direction), then checked against −1 and +1 in “CheckUp/Down”.
57Ew EyeXFlipToggle2c5e8
2c68a
2c6e8
Horizontal-move parity/flip flag for eye logic
A toggle bit flipped with EORI #1 on left/right branches and polled at decision points. Acts as a parity/flip tracker during horizontal moves.
580w EyeYFlipToggle2c5f4
2c62c
2c746
Vertical-move parity/flip flag for eye logic
Tested at “CheckYDirection” and toggled with EORI #1 in the up/down paths – mirrors $57E but for vertical motion.
582w EyeStateToggle2c5a6
2c5ae
Eye state toggle (e.g., gating a sub-effect/branch)
Simple EORI #1 toggle and TST.W gate in the eye state check – used as an on/off eye-state flag.
584w ControlAckFlag28a86
29266
2939a
Generic “armed/ack” flag for that mid-game control path (purpose local to that routine)
et to 1, polled in the 0x29266 path, then cleared at 0x2939A; used as a simple gate/ack in that control flow
586w ColourTimer12813a
28dee
2a3b8
2a3c2
2a3ce
Enable/hold-off timer for colour effect #1
Seeded from D0 or forced to 2; used as a gate (TST.W / MOVE.W …,D0) and cleared – drives the first colour-cycle.
588wSelectedConstellation2c4ac
2c4b6
2c50a
 Currently selected constellation index
58Ew FiringFinishedFlag2abfa
2ac06
2ac98
One-frame “fire completed” latch for the bullet system
Set to 1 when a shot finishes, then explicitly cleared at the next update pass before returning
594w LocalControlFlag29254
2925e
292b4
Local control flag (exact role is confined to that small flow)
Written 0→1, polled, then cleared as a simple flag in a short control region (~0x2925x).
598w PowerCrystalDataIndex2b294
2b29a
2b9e8
2e43c
Index for current Power-Crystal / special-object data in table.
Read to D1/D2 by crystal/“special object” logic, cleared after use, and written from D1 in Special_2E43C – a working index into that object’s data table.
59Aw GlobalTickStep2b082
2b092
2b09e
2b5e0
2b5f6
2b600
Shared cadence value (even-step tick) used as a divider/limit in timing checks.
Initialised to 38, compared against 6, decremented by 2 per tick, and used to compare/subtract against D0 inside timing/level-end checks.
59Cw TimingCounter2b5ea
2b5f0
2b606
Free-running small counter used in those timing calculations.
Incremented each pass, copied to D0, then written back – simple running counter used alongside $59A in the same timing block.
59Ew AddToScoreTemp2d504
2d504
2d50a
Per-char temp for “ADD SCORE” text update in Hi-Score UI.
Used in the high-score formatter loop as a scratch byte compared to _score and then updated – part of table/string construction during score insert.
5A6wFaceAnimActiveFlag2cfd2
2cfec
2d058
Set to 1 and tested in the face animation paths; re-set again on another branch – behaves as a simple “face anim enabled/armed” flag.
5AAw JoystickRepeatDelay2bf96
2bfa0
2c298
Joystick repeat/cooldown timer
Set to 14 as a delay, then ticked down and polled in the joystick routine – input repeat/holdoff.
5ACwEyeAnimFrameCounter2af84
2af8a
Incremented every frame and compared to 0x12 in the Eye logic.
5AEwEyeScreenActive2af96
2bfb4
Set to 1 during eye setup, then polled from the general joystick routine – used to gate input while eye screen is active
5B2wGameControlMode280dc
280dc
28132
28180
2840a
28518
2855e
285a2
28640
28776
287be
2885c
288a6
288b2
28900
28922
28a1e
28a3c
28a48
28a68
28a6e
28a7a
28aaa
28b3e
28c62
290c8
290d4
291e6
2920c
29220
29286
292a8
295cc
299d0
29e02
29ff4
2a0f6
2a300
2a30c
2a546
2a8c4
2aa3a
2af78
2b01e
2b030
2b170
2b418
2b640
2bb74
2bd58
2bfa8
2bff6
2c00a
2c194
2c1a0
2c518
2c524
2c530
2cf80
2d04e
2d4ea
2d86a
2d90c
2d916
2da7c
2e542
2e6d4
2e72c
009fe346
Master game mode enum

0 = In game
1 = Eye of Infinity screen
2 = Star chart screen
3 = Title screen (sunset and shadow)
4 = Demo/Instructions
5 = Hi-Score (Ouija)
6 = Grave screen
7 = Select game bias screen
8 = Ending screen – Well done

Global mode enum – set/tst/cmp all over to dispatch Title/Eye/Star-Chart/Hi-Score/Grave/etc. (0..8).
5B6addrAddress to screen29586
29648
296f4
299bc
2a01e
2a0a8
2a28e
2a2e8
2a2f2
2a318
2a33a
2a35c
2a456
2c9f6
2ca30
2cc70
2ce20
2cf48
2d0ce
2df14
2df40
Which screen are we working on? $10000/$18000

Holds the active screen base ($10000 or $18000); many branches compare it to choose Copper lists and to swap bitplane pointers.
5BAaddrBPL1PT Address to screen269f0
29590
29652
299c6
2a026
2a2e2
2a2e8
Shadow for bitplane-1 pointer during buffer switching
Holds the current bitplane 1 pointer shadow; written during buffer swaps and read when issuing BPL1PT into custom chips.
10000/18000
5C0wCurrent Constellation2814c
28806
28956
28a12
28a2a
28a30
299d8
29c98
29ccc
2a214
2b5aa
2c026
2c54e
2c586
2d832
 Current constellation index: incremented, polled for limits, mirrored to D-regs across star-chart and bias screens.
5C2addrStarPositions Pointer28200
299e8
29e40
2a226
2c44a
Active star-position table pointer.
Pointer to the star-position table; loaded to A0/A1 and replaced when switching datasets.
2EC6A, 2E874
5C6wCurrent Star281f8
299e0
29e38
2c496
Initialised to 0 when entering the title/selection flow: MOVE.W #$000,CurrentStar at 299E0. This happens alongside setting the constellation index and the star-position table pointer, i.e., part of constellation-selection setup.
During constellation selection, the code iterates the star-position table at Addr_5C2, checks each entry’s status and proximity to the player sprite (reads sprite X/Y from the sprite flag block), and when the cursor overlaps a selectable star it writes that loop index D3 into CurrentStar at 2C 496:
Table walk & status test (TST.W (A0) then CMPI.W #$001,(A0));
Distance checks against sprite position (abs |ΔX|, |ΔY| < 12);
On hit, MOVE.W D3,CurrentStar (select star).
On level completion, the selected star is marked “captured” by using CurrentStar as an index: MOVE.W CurrentStar,D0LSL.W #3,D0 (8-byte stride per entry) → MOVEA.L Addr_5C2,A0MOVE.W #$002,0(A0,D0.W) (set status=2) and decrement “stars remaining”.
5C8wLives281c4
281e0
287fc
29916
2993c
2994c
29958
29962
Remaining lives, initially set to 2, dec/inc, read for UI and bounds checks
5CAwStars Remaining In Constellation2894c
29e4c
2a1d6
2a24e
 Stars left to complete the current constellation.
5CClScore259b0
2882a
2898a
2d4d4
2d4da
2d52c
2e1b2
32-bit score – written/added to in multiple spots; also fed into Hi-Score code.
5D0addrGameRenderWork Pointer28176
2b672
2cb84
General render/work buffer pointer (initialised to a game screen asset).
Written with a screen/asset address early; later used as A0 in a render path. One path also reuses it as a temporary longword (stores _joysticky) – so it’s a general render workspace pointer in practice.
inc by 24 (0x18) from 4E64C to 4E6C4
5D4w GuardianCounter in Demo28e50
28e70
28e76
28e82
Demo-mode guardian type rotator.
Demo guardian selector: ++ each pass, wrapped at 6, mirrored into guardianType.
5D6wGuardianPhase2a668
2a66e
0..3 looping phase (used in guardian animation timing). Small 2-bit phase counter: ADDQ.W #1 then ANDI.W #3.
5D8wCollisionResponseSign28276
2bb98
2bb9e
±1 sign used in collision/response maths.
1 or -1
Set to +1, negated later, and algebraically added into position maths – used as a sign term.
5DAwFrameStepParity2bb7e
2bb84
Frame/step parity toggle
Toggled 0 or 1 with ADDQ + ANDI #1 – a parity bit for alternating branches.
5DCwHighestConstellationSelect28822
28960
2896a
29a12
2c572
Upper bound for selectable constellation index.
Initialised to 2; compared against selector inputs and updated; checked wherever constellation selection is clamped.
5DEwGameBias28822
28960
2896a
29a12
2c572
Selected game bias enum.
0 = Tactical Bias
Slower, more manoeuvrable player, More intelligent growth, Less aggressive Guardians.
1 = Normal Bias (Balanced)
2 = Arcade Bias
Faster, more intertia (less control) for player, Less intelligent growth, more agressive Guardians.
5E0wJoystickDirectionInMenu291ba
291d2
291de
2d7ec
 Encoded joystick direction for menus.
On the bias screen it’s force-written to 9/7/11 and later read during input cooldown – encodes discrete direction selection.
5E2wJoystickDirection2bfda
2c060
2c078
2c096
2c0ae
2c554
Primary joystick direction code (1..4) for game/Eye/Ouija.
Cleared, then written 1..4 by low-level joystick paths; read back when composing higher-level decisions (e.g., eye/ouija input).
0 = no movement
1 = up
2 = down
3 = left
4 = right
High
5E4w ClearScreen Flag280bc
28852
288c6
288dc
289a6
28a0c
28a8e
28b4a
28b7c
28d86
28e20
29270
29640
297b6
29ee6
29f4e
 “Clear screen on next frame” flag.
Set/cleared at every mode transition; polled before issuing full screen clears. Also asserted during exception setup (stack at $800, set ClearScreenBOOL).
349de???Hand Eye sprite X coordoffset +6 from Hand sprite
349e0???Hand Eye sprite Y coordoffset +30 from Hand sprite

Leave a comment

Create a website or blog at WordPress.com

Up ↑